From 139e7713865d78529d5eb359e9e31f862d7f27d3 Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Wed, 30 Jul 2025 19:25:58 -0700 Subject: [PATCH 01/28] sql-create-tables-and-migrations.sp - add stylerankings table --- .../include/shavit/sql-create-tables-and-migrations.sp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/addons/sourcemod/scripting/include/shavit/sql-create-tables-and-migrations.sp b/addons/sourcemod/scripting/include/shavit/sql-create-tables-and-migrations.sp index 99530982..0d555649 100644 --- a/addons/sourcemod/scripting/include/shavit/sql-create-tables-and-migrations.sp +++ b/addons/sourcemod/scripting/include/shavit/sql-create-tables-and-migrations.sp @@ -182,6 +182,11 @@ public void SQL_CreateTables(Database hSQL, const char[] prefix, int driver) gS_SQLPrefix, sOptionalINNODB); AddQueryLog(trans, sQuery); + FormatEx(sQuery, sizeof(sQuery), + "CREATE TABLE IF NOT EXISTS `%sstylerankings` (`auth` INT NOT NULL, `style` TINYINT NOT NULL, `points` FLOAT NOT NULL DEFAULT 0, PRIMARY KEY (`auth`, `style`));", + gS_SQLPrefix); + AddQueryLog(trans, sQuery); + // //// shavit-stats // From 89b92d4313158402a3cc3cc1e9d9b18b34e47c7b Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Wed, 30 Jul 2025 20:36:15 -0700 Subject: [PATCH 02/28] shavit-rankings.phrases.txt - add UnrankedOnStyle translation --- addons/sourcemod/translations/shavit-rankings.phrases.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/addons/sourcemod/translations/shavit-rankings.phrases.txt b/addons/sourcemod/translations/shavit-rankings.phrases.txt index 0b6a83b2..1794c57f 100644 --- a/addons/sourcemod/translations/shavit-rankings.phrases.txt +++ b/addons/sourcemod/translations/shavit-rankings.phrases.txt @@ -21,6 +21,11 @@ "#format" "{1:s},{2:N},{3:s}" "en" "{1}{2}{3} is unranked." } + "UnrankedOnStyle" + { + "#format" "{1:s},{2:N},{3:s},{4:s},{5:s},{6:s}" + "en" "{1}{2}{3} is unranked on {4}{5}{6}." + } // ---------- Menus ---------- // "Top100" { @@ -30,4 +35,4 @@ { "en" "No ranked players found." } -} \ No newline at end of file +} From 025324c3cb0bd8dbb7241dbcb556a40ba5f12814 Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Wed, 30 Jul 2025 20:44:43 -0700 Subject: [PATCH 03/28] shavit-rankings.phrases.txt - add StyleRank translation --- addons/sourcemod/translations/shavit-rankings.phrases.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/addons/sourcemod/translations/shavit-rankings.phrases.txt b/addons/sourcemod/translations/shavit-rankings.phrases.txt index 1794c57f..68fe097a 100644 --- a/addons/sourcemod/translations/shavit-rankings.phrases.txt +++ b/addons/sourcemod/translations/shavit-rankings.phrases.txt @@ -16,6 +16,11 @@ "#format" "{1:s},{2:N},{3:s},{4:s},{5:d},{6:s},{7:d},{8:s},{9:.1f},{10:s}" "en" "{1}{2}{3} is ranked {4}{5}{6} out of {7} with {8}{9}{10} points." } + "StyleRank" + { + "#format" "{1:s},{2:N},{3:s},{4:s},{5:d},{6:s},{7:d},{8:s},{9:.1f},{10:s},{11:s},{12:s},{13:s}" + "en" "{1}{2}{3} is ranked {4}{5}{6} out of {7} with {8}{9}{10} points. ({11}{12}{13})" + } "Unranked" { "#format" "{1:s},{2:N},{3:s}" From 8b54f4b1ad65d04bc3c5e91c07e0638b723dd956 Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Wed, 30 Jul 2025 21:00:24 -0700 Subject: [PATCH 04/28] shavit-rankings.phrases.txt - add StyleTop100 translation --- addons/sourcemod/translations/shavit-rankings.phrases.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/addons/sourcemod/translations/shavit-rankings.phrases.txt b/addons/sourcemod/translations/shavit-rankings.phrases.txt index 68fe097a..b286282b 100644 --- a/addons/sourcemod/translations/shavit-rankings.phrases.txt +++ b/addons/sourcemod/translations/shavit-rankings.phrases.txt @@ -36,6 +36,11 @@ { "en" "Top 100 ranked players:" } + "StyleTop100" + { + "#format" "{1:s}" + "en" "Top 100 ranked players ({1}):" + } "NoRankedPlayers" { "en" "No ranked players found." From 61ee8f5d4bb4a696754c247fa23c40d0143d6a5c Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Wed, 30 Jul 2025 21:33:17 -0700 Subject: [PATCH 05/28] shavit-rankings.sp - wip --- addons/sourcemod/scripting/shavit-rankings.sp | 172 +++++++++++++++++- 1 file changed, 165 insertions(+), 7 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-rankings.sp b/addons/sourcemod/scripting/shavit-rankings.sp index 34dcafc7..924a016a 100644 --- a/addons/sourcemod/scripting/shavit-rankings.sp +++ b/addons/sourcemod/scripting/shavit-rankings.sp @@ -59,7 +59,9 @@ enum struct ranking_t { int iRank; + int iStyleRank[STYLE_LIMIT]; float fPoints; + float fStylePoints[STYLE_LIMIT]; int iWRAmountAll; int iWRAmountCvar; int iWRHolderRankAll; @@ -68,6 +70,15 @@ enum struct ranking_t int iWRHolderRank[STYLE_LIMIT*2]; } +enum struct stylerankcache_t +{ + int iLastStyle; + int iLastTrack; + int iPagePosition; + bool bForceStyle; + bool bPendingMenu; +} + char gS_MySQLPrefix[32]; Database gH_SQL = null; bool gB_SQLWindowFunctions = false; @@ -99,6 +110,7 @@ Convar gCV_DefaultTier = null; ranking_t gA_Rankings[MAXPLAYERS+1]; int gI_RankedPlayers = 0; +int gI_StyleRankedPlayers[STYLE_LIMIT] = {0, ...}; Menu gH_Top100Menu = null; Handle gH_Forwards_OnTierAssigned = null; @@ -107,6 +119,11 @@ Handle gH_Forwards_OnRankAssigned = null; // Timer settings. chatstrings_t gS_ChatStrings; int gI_Styles = 0; +stylestrings_t gS_StyleStrings[STYLE_LIMIT]; + +// Cache +StringMap gSM_StyleCommands = null; +stylerankcache_t gA_StyleRankCache[MAXPLAYERS+1]; bool gB_WorldRecordsCached = false; bool gB_WRHolderTablesMade = false; @@ -119,7 +136,7 @@ int gI_WRHoldersCvar; public Plugin myinfo = { name = "[shavit] Rankings", - author = "shavit, rtldg", + author = "shavit, rtldg, olivia", description = "A fair and competitive ranking system for shavit's bhoptimer.", version = SHAVIT_VERSION, url = "https://github.com/shavitush/bhoptimer" @@ -130,8 +147,11 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max CreateNative("Shavit_GetMapTier", Native_GetMapTier); CreateNative("Shavit_GetMapTiers", Native_GetMapTiers); CreateNative("Shavit_GetPoints", Native_GetPoints); + CreateNative("Shavit_GetStylePoints", Native_GetStylePoints); CreateNative("Shavit_GetRank", Native_GetRank); + CreateNative("Shavit_GetStyleRank", Native_GetStyleRank); CreateNative("Shavit_GetRankedPlayers", Native_GetRankedPlayers); + CreateNative("Shavit_GetStyleRankedPlayers", Native_GetStyleRankedPlayers); CreateNative("Shavit_Rankings_DeleteMap", Native_Rankings_DeleteMap); CreateNative("Shavit_GetWRCount", Native_GetWRCount); CreateNative("Shavit_GetWRHolders", Native_GetWRHolders); @@ -152,11 +172,15 @@ public void OnPluginStart() gH_Forwards_OnTierAssigned = CreateGlobalForward("Shavit_OnTierAssigned", ET_Event, Param_String, Param_Cell); gH_Forwards_OnRankAssigned = CreateGlobalForward("Shavit_OnRankAssigned", ET_Event, Param_Cell, Param_Cell, Param_Cell, Param_Cell); + gSM_StyleCommands = new StringMap(); + RegConsoleCmd("sm_tier", Command_Tier, "Prints the map's tier to chat."); RegConsoleCmd("sm_maptier", Command_Tier, "Prints the map's tier to chat. (sm_tier alias)"); RegConsoleCmd("sm_rank", Command_Rank, "Show your or someone else's rank. Usage: sm_rank [name]"); RegConsoleCmd("sm_top", Command_Top, "Show the top 100 players."); + RegConsoleCmd("sm_stylerank", Command_StyleRank, "Show your or someone else's rank on a style. Usage: sm_stylerank [name]"); + RegConsoleCmd("sm_styletop", Command_StyleTop, "Show the top 100 players for a style."); RegAdminCmd("sm_settier", Command_SetTier, ADMFLAG_RCON, "Change the map's tier. Usage: sm_settier [map]"); RegAdminCmd("sm_setmaptier", Command_SetTier, ADMFLAG_RCON, "Change the map's tier. Usage: sm_setmaptier [map] (sm_settier alias)"); @@ -201,8 +225,47 @@ public void Shavit_OnChatConfigLoaded() Shavit_GetChatStringsStruct(gS_ChatStrings); } +void RegisterStyleRankCommands(int style) +{ + char sStyleCommands[32][32]; + int iCommands = ExplodeString(gS_StyleStrings[style].sChangeCommand, ";", sStyleCommands, 32, 32, false); + + char sDescription[128]; + FormatEx(sDescription, 128, "View the top players of style %s.", gS_StyleStrings[style].sStyleName); + + for (int x = 0; x < iCommands; x++) + { + TrimString(sStyleCommands[x]); + StripQuotes(sStyleCommands[x]); + + if (strlen(sStyleCommands[x]) < 1) + { + continue; + } + + + char sCommand[40]; + FormatEx(sCommand, sizeof(sCommand), "sm_rank%s", sStyleCommands[x]); + gSM_StyleCommands.SetValue(sCommand, style); + RegConsoleCmd(sCommand, Command_Rank_Style, sDescription); + + FormatEx(sCommand, sizeof(sCommand), "sm_top%s", sStyleCommands[x]); + gSM_StyleCommands.SetValue(sCommand, style); + RegConsoleCmd(sCommand, Command_Top_Style, sDescription); + } +} + public void Shavit_OnStyleConfigLoaded(int styles) { + for (int i = 0; i < STYLE_LIMIT; i++) + { + if (i < styles) + { + Shavit_GetStyleStringsStruct(i, gS_StyleStrings[i]); + RegisterStyleRankCommands(i); + } + } + gI_Styles = styles; } @@ -310,6 +373,9 @@ public void OnClientConnected(int client) { ranking_t empty_ranking; gA_Rankings[client] = empty_ranking; + + stylerankcache_t empty_cache; + gA_StyleRankCache[client] = empty_cache; } public void OnClientAuthorized(int client, const char[] auth) @@ -565,44 +631,136 @@ public Action Command_Tier(int client, int args) return Plugin_Handled; } +public Action Command_StyleRank(int client, int args) +{ + //Create a style menu + //Call Command_Rank with the client's selected style + + return Plugin_Handled; +} + +public Action Command_Rank_Style(int client, int args) +{ + char sCommand[128]; + GetCmdArg(0, sCommand, sizeof(sCommand)); + + int style = 0; + + if (gSM_StyleCommands.GetValue(sCommand, style)) + { + gA_StyleRankCache[client].bForceStyle = true; + gA_StyleRankCache[client].iLastStyle = style; + Command_Rank(client, args); + } + + return Plugin_Handled; +} + public Action Command_Rank(int client, int args) { int target = client; + int style = -1; - if(args > 0) + if (args > 0) { char sArgs[MAX_TARGET_LENGTH]; GetCmdArgString(sArgs, MAX_TARGET_LENGTH); target = FindTarget(client, sArgs, true, false); - if(target == -1) + if (target == -1) { return Plugin_Handled; } } - if(gA_Rankings[target].fPoints == 0.0) + if (gA_StyleRankCache[client].bForceStyle) + { + style = gA_StyleRankCache[client].iLastStyle; + gA_StyleRankCache[client].bForceStyle = false; + } + + if (gA_Rankings[target].fPoints == 0.0) { Shavit_PrintToChat(client, "%T", "Unranked", client, gS_ChatStrings.sVariable2, target, gS_ChatStrings.sText); return Plugin_Handled; } + else if (style > -1 && gA_Rankings[target].fStylePoints[style] == 0.0) + { + Shavit_PrintToChat(client, "%T", "UnrankedOnStyle", client, gS_ChatStrings.sVariable2, target, gS_ChatStrings.sText, gS_ChatStrings.sStyle, gS_StyleStrings[style].sStyleName, gS_ChatStrings.sText); + return Plugin_Handled; + } + + if (style == -1) + { Shavit_PrintToChat(client, "%T", "Rank", client, gS_ChatStrings.sVariable2, target, gS_ChatStrings.sText, gS_ChatStrings.sVariable, (gA_Rankings[target].iRank > gI_RankedPlayers)? gI_RankedPlayers:gA_Rankings[target].iRank, gS_ChatStrings.sText, gI_RankedPlayers, gS_ChatStrings.sVariable, gA_Rankings[target].fPoints, gS_ChatStrings.sText); + } + else + { + Shavit_PrintToChat(client, "%T", "StyleRank", client, gS_ChatStrings.sVariable2, target, gS_ChatStrings.sText, + gS_ChatStrings.sVariable, (gA_Rankings[target].iStyleRank[style] > gI_RankedStylePlayers[style])? gI_RankedStylePlayers[style]:gA_Rankings[target].iStyleRank[style], gS_ChatStrings.sText, + gI_RankedStylePlayers[style], + gS_ChatStrings.sVariable, gA_Rankings[target].fPoints, gS_ChatStrings.sText, + gS_ChatStrings.sStyle, gS_StyleStrings[style].sStyleName, gS_ChatStrings.sText); + } return Plugin_Handled; } public Action Command_Top(int client, int args) { - if(gH_Top100Menu != null) + int style = -1; + + if (gA_StyleRankCache[client].bForceStyle) { - gH_Top100Menu.SetTitle("%T (%d)\n ", "Top100", client, gI_RankedPlayers); - gH_Top100Menu.Display(client, MENU_TIME_FOREVER); + style = gA_StyleRankCache[client].iLastStyle; + gA_StyleRankCache[client].bForceStyle = false; + } + + if (style == -1) + { + if(gH_Top100Menu != null) + { + gH_Top100Menu.SetTitle("%T (%d)\n ", "Top100", client, gI_RankedPlayers); + gH_Top100Menu.Display(client, MENU_TIME_FOREVER); + } + } + else + { + if(gH_StyleTop100Menu != null) + { + gH_StyleTop100Menu.SetTitle("%T (%d)\n ", "Top100", client, gS_StyleStrings[style].sStyleName, gI_RankedStylePlayers[style]); + gH_StyleTop100Menu.Display(client, style, MENU_TIME_FOREVER); + } + } + + return Plugin_Handled; +} + +public Action Command_StyleTop(int client, int args) +{ + //Create style menu + + return Plugin_Handled; +} + +public Action Command_Top_Style(int client, int args) +{ + char sCommand[128]; + GetCmdArg(0, sCommand, sizeof(sCommand)); + + int style = 0; + + if (gSM_StyleCommands.GetValue(sCommand, style)) + { + gA_StyleRankCache[client].bForceStyle = true; + gA_StyleRankCache[client].iLastStyle = style; + Command_Top(client, args); } return Plugin_Handled; From 858c489a5edd3d1d9e58f127ac82d14ab5e12212 Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Thu, 31 Jul 2025 07:44:30 -0700 Subject: [PATCH 06/28] rankings.inc - add forward and natives --- .../scripting/include/shavit/rankings.inc | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/addons/sourcemod/scripting/include/shavit/rankings.inc b/addons/sourcemod/scripting/include/shavit/rankings.inc index 1670c9bf..3e4793fc 100644 --- a/addons/sourcemod/scripting/include/shavit/rankings.inc +++ b/addons/sourcemod/scripting/include/shavit/rankings.inc @@ -47,6 +47,19 @@ forward void Shavit_OnTierAssigned(const char[] map, int tier); */ forward void Shavit_OnRankAssigned(int client, int rank, float points, bool first); +/** + * Gets called when the server acknowledges the client's ranking status for a style. + * It is called after OnClientPostAdminCheck and at forced rank recalculations. + * + * @param client Client index. + * @param style Style index. + * @param rank Client's rank. (0 if unranked or unassigned) + * @param points Client's points. (0.0 if unranked or unassigned) + * @param first True if the forward is called after the initial connection, false if it is caused by recalculation. + * @noreturn + */ +forward void Shavit_OnStyleRankAssigned(int client, int style, int rank, float points, bool first); + /** * Gets the map tier for a specified map. * Use the map's display name. @@ -72,6 +85,15 @@ native StringMap Shavit_GetMapTiers(); */ native float Shavit_GetPoints(int client); +/** + * Gets player points on a style. + * + * @param client Client index. + * @param style Style index. + * @return Points. 0.0 if unranked. + */ +native float Shavit_GetStylePoints(int client, int style); + /** * Gets player rank. * @@ -80,6 +102,15 @@ native float Shavit_GetPoints(int client); */ native int Shavit_GetRank(int client); +/** + * Gets player rank on a style. + * + * @param client Client index. + * @param style Style index. + * @return Rank. 0 if unranked. + */ +native int Shavit_GetStyleRank(int client, int style); + /** * Gets the amount of players with over 0 points. * @@ -87,6 +118,14 @@ native int Shavit_GetRank(int client); */ native int Shavit_GetRankedPlayers(); +/** + * Gets the amount of players with over 0 points on a style. + * + * @param style Style index. + * @return Amount of ranked players. + */ +native int Shavit_GetStyleRankedPlayers(int style); + /** * Deletes tier setting for the specified map. * Points recalculation will run right after this is finished. @@ -164,8 +203,11 @@ public void __pl_shavit_rankings_SetNTVOptional() MarkNativeAsOptional("Shavit_GetMapTier"); MarkNativeAsOptional("Shavit_GetMapTiers"); MarkNativeAsOptional("Shavit_GetPoints"); + MarkNativeAsOptional("Shavit_GetStylePoints"); MarkNativeAsOptional("Shavit_GetRank"); + MarkNativeAsOptional("Shavit_GetStyleRank"); MarkNativeAsOptional("Shavit_GetRankedPlayers"); + MarkNativeAsOptional("Shavit_GetStyleRankedPlayers"); MarkNativeAsOptional("Shavit_Rankings_DeleteMap"); MarkNativeAsOptional("Shavit_GetWRCount"); MarkNativeAsOptional("Shavit_GetWRHolders"); From 88e0a78b08e9a0f94fa5a02ea8599f6524f74799 Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Thu, 31 Jul 2025 08:36:36 -0700 Subject: [PATCH 07/28] sql-create-tables-and-migrations.sp - rename table --- .../include/shavit/sql-create-tables-and-migrations.sp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/include/shavit/sql-create-tables-and-migrations.sp b/addons/sourcemod/scripting/include/shavit/sql-create-tables-and-migrations.sp index 0d555649..7df355ca 100644 --- a/addons/sourcemod/scripting/include/shavit/sql-create-tables-and-migrations.sp +++ b/addons/sourcemod/scripting/include/shavit/sql-create-tables-and-migrations.sp @@ -183,7 +183,7 @@ public void SQL_CreateTables(Database hSQL, const char[] prefix, int driver) AddQueryLog(trans, sQuery); FormatEx(sQuery, sizeof(sQuery), - "CREATE TABLE IF NOT EXISTS `%sstylerankings` (`auth` INT NOT NULL, `style` TINYINT NOT NULL, `points` FLOAT NOT NULL DEFAULT 0, PRIMARY KEY (`auth`, `style`));", + "CREATE TABLE IF NOT EXISTS `%sstylepoints` (`auth` INT NOT NULL, `style` TINYINT NOT NULL, `points` FLOAT NOT NULL DEFAULT 0, PRIMARY KEY (`auth`, `style`));", gS_SQLPrefix); AddQueryLog(trans, sQuery); From aab9f9c27104353c181cfe36bf231145291b9e4c Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Thu, 31 Jul 2025 11:57:55 -0700 Subject: [PATCH 08/28] sql-create-tables-and-migrations.sp - AddStylePoints migration --- .../include/shavit/sql-create-tables-and-migrations.sp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/addons/sourcemod/scripting/include/shavit/sql-create-tables-and-migrations.sp b/addons/sourcemod/scripting/include/shavit/sql-create-tables-and-migrations.sp index 7df355ca..f4703ec9 100644 --- a/addons/sourcemod/scripting/include/shavit/sql-create-tables-and-migrations.sp +++ b/addons/sourcemod/scripting/include/shavit/sql-create-tables-and-migrations.sp @@ -55,6 +55,7 @@ enum Migration_FixSQLiteMapzonesROWID, Migration_AddUsersFirstLogin, // 30 Migration_MoreFirstLoginStuff, + Migration_AddStylePoints, MIGRATIONS_END }; @@ -91,6 +92,7 @@ char gS_MigrationNames[][] = { "FixSQLiteMapzonesROWID", "AddUsersFirstLogin", "MoreFirstLoginStuff", + "AddStylePoints", }; static Database gH_SQL; @@ -380,6 +382,7 @@ void ApplyMigration(int migration) case Migration_FixSQLiteMapzonesROWID: ApplyMigration_FixSQLiteMapzonesROWID(); case Migration_AddUsersFirstLogin: ApplyMigration_AddUsersFirstLogin(); case Migration_MoreFirstLoginStuff: ApplyMigration_MoreFirstLoginStuff(); + case Migration_AddStylePoints: ApplyMigration_AddStylePoints(); } } @@ -773,6 +776,13 @@ public void ApplyMigration_MoreFirstLoginStuff() gH_SQL.Execute(trans, Trans_MigrationSimple, TransMigrationSimple_Error, Migration_MoreFirstLoginStuff); } +void ApplyMigration_AddStylePoints() +{ + char sQuery[256]; + FormatEx(sQuery, sizeof(sQuery), "INSERT INTO %sstylepoints (auth, style) SELECT UNIQUE auth, style FROM %splayertimes;", gS_SQLPrefix, gS_SQLPrefix); + QueryLog(gH_SQL, SQL_TableMigrationSingleQuery_Callback, sQuery, Migration_AddStylePoints, DBPrio_High); +} + public void SQL_TableMigrationSingleQuery_Callback(Database db, DBResultSet results, const char[] error, any data) { InsertMigration(data); From 799f34bfdd461752f233dec984a9a40cb411789a Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Thu, 31 Jul 2025 13:05:02 -0700 Subject: [PATCH 09/28] shavit-rankings.phrases.txt - add Overall translation --- addons/sourcemod/translations/shavit-rankings.phrases.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/addons/sourcemod/translations/shavit-rankings.phrases.txt b/addons/sourcemod/translations/shavit-rankings.phrases.txt index b286282b..099ccb70 100644 --- a/addons/sourcemod/translations/shavit-rankings.phrases.txt +++ b/addons/sourcemod/translations/shavit-rankings.phrases.txt @@ -41,6 +41,10 @@ "#format" "{1:s}" "en" "Top 100 ranked players ({1}):" } + "Overall" + { + "en" "Overall" + } "NoRankedPlayers" { "en" "No ranked players found." From 62477e4072cf0ec8e5348d41f154d07a957392c9 Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Thu, 31 Jul 2025 20:07:06 -0700 Subject: [PATCH 10/28] shavit-rankings.phrases.txt - last translations --- .../sourcemod/translations/shavit-rankings.phrases.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/addons/sourcemod/translations/shavit-rankings.phrases.txt b/addons/sourcemod/translations/shavit-rankings.phrases.txt index 099ccb70..276bc739 100644 --- a/addons/sourcemod/translations/shavit-rankings.phrases.txt +++ b/addons/sourcemod/translations/shavit-rankings.phrases.txt @@ -41,6 +41,15 @@ "#format" "{1:s}" "en" "Top 100 ranked players ({1}):" } + "StyleRankTitle" + { + "#format" "{1:s}" + "en" "{1}'s rank:" + } + "StyleTopTitle" + { + "en" "Top Players Menu:" + } "Overall" { "en" "Overall" From 0b597f1be140070ce365175b5802cb2ca76598ca Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Thu, 31 Jul 2025 20:08:55 -0700 Subject: [PATCH 11/28] Update shavit-rankings.sp --- addons/sourcemod/scripting/shavit-rankings.sp | 703 ++++++++++++++---- 1 file changed, 561 insertions(+), 142 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-rankings.sp b/addons/sourcemod/scripting/shavit-rankings.sp index 924a016a..6f9bf259 100644 --- a/addons/sourcemod/scripting/shavit-rankings.sp +++ b/addons/sourcemod/scripting/shavit-rankings.sp @@ -72,11 +72,31 @@ enum struct ranking_t enum struct stylerankcache_t { - int iLastStyle; - int iLastTrack; - int iPagePosition; - bool bForceStyle; - bool bPendingMenu; + int iMenuPosition; + int iStyle; + int iTarget; +} + +enum struct styletop_t +{ + ArrayList sName; + int iSteamID[100]; + float fPoints[100]; + + void Init() + { + if(this.sName != null) + { + delete this.sName; + } + + this.sName = new ArrayList(ByteCountToCells(33), 100); + + for(int x = 0; x < this.sName.Length; x++) + { + this.sName.SetString(x, ""); + } + } } char gS_MySQLPrefix[32]; @@ -111,18 +131,20 @@ ranking_t gA_Rankings[MAXPLAYERS+1]; int gI_RankedPlayers = 0; int gI_StyleRankedPlayers[STYLE_LIMIT] = {0, ...}; + Menu gH_Top100Menu = null; +styletop_t gA_StyleTop[STYLE_LIMIT]; Handle gH_Forwards_OnTierAssigned = null; Handle gH_Forwards_OnRankAssigned = null; +Handle gH_Forwards_OnStyleRankAssigned = null; // Timer settings. chatstrings_t gS_ChatStrings; -int gI_Styles = 0; stylestrings_t gS_StyleStrings[STYLE_LIMIT]; +int gI_Styles = 0; // Cache -StringMap gSM_StyleCommands = null; stylerankcache_t gA_StyleRankCache[MAXPLAYERS+1]; bool gB_WorldRecordsCached = false; @@ -167,20 +189,24 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max public void OnPluginStart() { + for (int i = 0; i < sizeof(gA_StyleTop); i++) + { + gA_StyleTop[i].Init(); + } + gEV_Type = GetEngineVersion(); gH_Forwards_OnTierAssigned = CreateGlobalForward("Shavit_OnTierAssigned", ET_Event, Param_String, Param_Cell); gH_Forwards_OnRankAssigned = CreateGlobalForward("Shavit_OnRankAssigned", ET_Event, Param_Cell, Param_Cell, Param_Cell, Param_Cell); - - gSM_StyleCommands = new StringMap(); + gH_Forwards_OnStyleRankAssigned = CreateGlobalForward("Shavit_OnStyleRankAssigned", ET_Event, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell); RegConsoleCmd("sm_tier", Command_Tier, "Prints the map's tier to chat."); RegConsoleCmd("sm_maptier", Command_Tier, "Prints the map's tier to chat. (sm_tier alias)"); RegConsoleCmd("sm_rank", Command_Rank, "Show your or someone else's rank. Usage: sm_rank [name]"); RegConsoleCmd("sm_top", Command_Top, "Show the top 100 players."); - RegConsoleCmd("sm_stylerank", Command_StyleRank, "Show your or someone else's rank on a style. Usage: sm_stylerank [name]"); - RegConsoleCmd("sm_styletop", Command_StyleTop, "Show the top 100 players for a style."); + RegConsoleCmd("sm_stylerank", Command_Rank, "Show your or someone else's rank on a style. Usage: sm_stylerank [name]"); + RegConsoleCmd("sm_styletop", Command_Top, "Show the top 100 players for a style."); RegAdminCmd("sm_settier", Command_SetTier, ADMFLAG_RCON, "Change the map's tier. Usage: sm_settier [map]"); RegAdminCmd("sm_setmaptier", Command_SetTier, ADMFLAG_RCON, "Change the map's tier. Usage: sm_setmaptier [map] (sm_settier alias)"); @@ -201,6 +227,7 @@ public void OnPluginStart() Convar.AutoExecConfig(); LoadTranslations("common.phrases"); + LoadTranslations("shavit-core.phrases"); LoadTranslations("shavit-common.phrases"); LoadTranslations("shavit-rankings.phrases"); @@ -225,48 +252,17 @@ public void Shavit_OnChatConfigLoaded() Shavit_GetChatStringsStruct(gS_ChatStrings); } -void RegisterStyleRankCommands(int style) -{ - char sStyleCommands[32][32]; - int iCommands = ExplodeString(gS_StyleStrings[style].sChangeCommand, ";", sStyleCommands, 32, 32, false); - - char sDescription[128]; - FormatEx(sDescription, 128, "View the top players of style %s.", gS_StyleStrings[style].sStyleName); - - for (int x = 0; x < iCommands; x++) - { - TrimString(sStyleCommands[x]); - StripQuotes(sStyleCommands[x]); - - if (strlen(sStyleCommands[x]) < 1) - { - continue; - } - - - char sCommand[40]; - FormatEx(sCommand, sizeof(sCommand), "sm_rank%s", sStyleCommands[x]); - gSM_StyleCommands.SetValue(sCommand, style); - RegConsoleCmd(sCommand, Command_Rank_Style, sDescription); - - FormatEx(sCommand, sizeof(sCommand), "sm_top%s", sStyleCommands[x]); - gSM_StyleCommands.SetValue(sCommand, style); - RegConsoleCmd(sCommand, Command_Top_Style, sDescription); - } -} - public void Shavit_OnStyleConfigLoaded(int styles) { + gI_Styles = styles; + for (int i = 0; i < STYLE_LIMIT; i++) { if (i < styles) { Shavit_GetStyleStringsStruct(i, gS_StyleStrings[i]); - RegisterStyleRankCommands(i); } } - - gI_Styles = styles; } public void OnLibraryAdded(const char[] name) @@ -351,6 +347,31 @@ void CreateGetWeightedPointsFunction() "RETURN total; " ... "END;;", gS_MySQLPrefix, sWeightingLimit, gCV_WeightingMultiplier.FloatValue); + AddQueryLog(trans, sQuery); + + FormatEx(sQuery, sizeof(sQuery), + "CREATE FUNCTION GetStyleWeightedPoints(steamid INT, istyle INT) " ... + "RETURNS FLOAT " ... + "READS SQL DATA " ... + "BEGIN " ... + "DECLARE p FLOAT; " ... + "DECLARE total FLOAT DEFAULT 0.0; " ... + "DECLARE mult FLOAT DEFAULT 1.0; " ... + "DECLARE done INT DEFAULT 0; " ... + "DECLARE cur CURSOR FOR SELECT points FROM %splayertimes WHERE auth = steamid AND style = istyle AND points > 0.0 ORDER BY points DESC %s; " ... + "DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; " ... + "OPEN cur; " ... + "iter: LOOP " ... + "FETCH cur INTO p; " ... + "IF done THEN " ... + "LEAVE iter; " ... + "END IF; " ... + "SET total = total + (p * mult); " ... + "SET mult = mult * %f; " ... + "END LOOP; " ... + "CLOSE cur; " ... + "RETURN total; " ... + "END;;", gS_MySQLPrefix, sWeightingLimit, gCV_WeightingMultiplier.FloatValue); AddQueryLog(trans, sQuery); @@ -382,6 +403,33 @@ public void OnClientAuthorized(int client, const char[] auth) { if (gH_SQL && !IsFakeClient(client)) { + int iSteamID = GetSteamAccountID(client); + + if(iSteamID == 0) + { + return; + } + + char sQuery[512]; + + for (int i = 0; i < gI_Styles; i++) + { + if (gI_Driver == Driver_mysql) + { + FormatEx(sQuery, 512, + "INSERT IGNORE INTO %sstylepoints (auth, style, points) VALUES (%d, %d, 0);", + gS_MySQLPrefix, iSteamID, i); + } + else // postgresql & sqlite + { + FormatEx(sQuery, 512, + "INSERT INTO %susers (auth, style, points) VALUES (%d, %d, 0) ON CONFLICT DO NOTHING;", + gS_MySQLPrefix, iSteamID, i); + } + + QueryLog(gH_SQL, SQL_InsertUser_Callback, sQuery, GetClientSerial(client)); + } + if (gB_WRHolderTablesMade) { UpdateWRs(client); @@ -391,6 +439,25 @@ public void OnClientAuthorized(int client, const char[] auth) } } +public void SQL_InsertUser_Callback(Database db, DBResultSet results, const char[] error, any data) +{ + if(results == null) + { + int client = GetClientFromSerial(data); + + if(client == 0) + { + LogError("Timer error! (rankings) Failed to insert a disconnected player's data to the table. Reason: %s", error); + } + else + { + LogError("Timer error! (rankings) Failed to insert \"%N\"'s data to the table. Reason: %s", client, error); + } + + return; + } +} + public void OnMapStart() { GetLowercaseMapName(gS_Map); @@ -631,35 +698,9 @@ public Action Command_Tier(int client, int args) return Plugin_Handled; } -public Action Command_StyleRank(int client, int args) -{ - //Create a style menu - //Call Command_Rank with the client's selected style - - return Plugin_Handled; -} - -public Action Command_Rank_Style(int client, int args) -{ - char sCommand[128]; - GetCmdArg(0, sCommand, sizeof(sCommand)); - - int style = 0; - - if (gSM_StyleCommands.GetValue(sCommand, style)) - { - gA_StyleRankCache[client].bForceStyle = true; - gA_StyleRankCache[client].iLastStyle = style; - Command_Rank(client, args); - } - - return Plugin_Handled; -} - public Action Command_Rank(int client, int args) { int target = client; - int style = -1; if (args > 0) { @@ -674,96 +715,209 @@ public Action Command_Rank(int client, int args) } } - if (gA_StyleRankCache[client].bForceStyle) + if(IsValidClient(client)) { - style = gA_StyleRankCache[client].iLastStyle; - gA_StyleRankCache[client].bForceStyle = false; - } - - if (gA_Rankings[target].fPoints == 0.0) - { - Shavit_PrintToChat(client, "%T", "Unranked", client, gS_ChatStrings.sVariable2, target, gS_ChatStrings.sText); - - return Plugin_Handled; - } - else if (style > -1 && gA_Rankings[target].fStylePoints[style] == 0.0) - { - Shavit_PrintToChat(client, "%T", "UnrankedOnStyle", client, gS_ChatStrings.sVariable2, target, gS_ChatStrings.sText, gS_ChatStrings.sStyle, gS_StyleStrings[style].sStyleName, gS_ChatStrings.sText); - - return Plugin_Handled; - } - - if (style == -1) - { - Shavit_PrintToChat(client, "%T", "Rank", client, gS_ChatStrings.sVariable2, target, gS_ChatStrings.sText, - gS_ChatStrings.sVariable, (gA_Rankings[target].iRank > gI_RankedPlayers)? gI_RankedPlayers:gA_Rankings[target].iRank, gS_ChatStrings.sText, - gI_RankedPlayers, - gS_ChatStrings.sVariable, gA_Rankings[target].fPoints, gS_ChatStrings.sText); - } - else - { - Shavit_PrintToChat(client, "%T", "StyleRank", client, gS_ChatStrings.sVariable2, target, gS_ChatStrings.sText, - gS_ChatStrings.sVariable, (gA_Rankings[target].iStyleRank[style] > gI_RankedStylePlayers[style])? gI_RankedStylePlayers[style]:gA_Rankings[target].iStyleRank[style], gS_ChatStrings.sText, - gI_RankedStylePlayers[style], - gS_ChatStrings.sVariable, gA_Rankings[target].fPoints, gS_ChatStrings.sText, - gS_ChatStrings.sStyle, gS_StyleStrings[style].sStyleName, gS_ChatStrings.sText); + gA_StyleRankCache[client].iTarget = target; + OpenRankMenu(client, 0); } return Plugin_Handled; } +void OpenRankMenu(int client, int position = 0) +{ + if(!IsValidClient(gA_StyleRankCache[client].iTarget)) + { + return; + } + + Menu menu = new Menu(MenuHandler_Rank); + + char sDisplay[32]; + GetClientName(gA_StyleRankCache[client].iTarget, sDisplay, sizeof(sDisplay)); + + SetMenuTitle(menu, "%T\n ", "StyleRankTitle", client, sDisplay); + + FormatEx(sDisplay, 32, "%T\n ", "Overall", client); + menu.AddItem("-1", sDisplay); + + int[] iOrderedStyles = new int[gI_Styles]; + Shavit_GetOrderedStyles(iOrderedStyles, gI_Styles); + + for(int i = 0; i < gI_Styles; i++) + { + int iStyle = iOrderedStyles[i]; + + if(Shavit_GetStyleSettingInt(iStyle, "enabled") == -1) + { + continue; + } + + char sStyle[8]; + IntToString(iStyle, sStyle, sizeof(sStyle)); + menu.AddItem(sStyle, gS_StyleStrings[iStyle].sStyleName); + } + + menu.ExitButton = true; + DisplayMenuAtItem(menu, client, position, MENU_TIME_FOREVER); +} + +public void MenuHandler_Rank(Menu menu, MenuAction action, int param1, int param2) +{ + if(action == MenuAction_Select) + { + if(!IsValidClient(gA_StyleRankCache[param1].iTarget)) + { + return; + } + + char sStyle[8]; + menu.GetItem(param2, sStyle, sizeof(sStyle)); + int iStyle = StringToInt(sStyle); + int target = gA_StyleRankCache[param1].iTarget; + + if (iStyle < 0 || iStyle >= gI_Styles) + { + iStyle = -1; + } + + if (gA_Rankings[target].fPoints == 0.0) + { + Shavit_PrintToChat(param1, "%T", "Unranked", param1, gS_ChatStrings.sVariable2, target, gS_ChatStrings.sText); + } + else if (iStyle > -1 && gA_Rankings[target].fStylePoints[iStyle] == 0.0) + { + Shavit_PrintToChat(param1, "%T", "UnrankedOnStyle", param1, gS_ChatStrings.sVariable2, target, gS_ChatStrings.sText, gS_ChatStrings.sStyle, gS_StyleStrings[iStyle].sStyleName, gS_ChatStrings.sText); + } + else + { + if (iStyle == -1) + { + Shavit_PrintToChat(param1, "%T", "Rank", param1, gS_ChatStrings.sVariable2, target, gS_ChatStrings.sText, + gS_ChatStrings.sVariable, (gA_Rankings[target].iRank > gI_RankedPlayers)? gI_RankedPlayers:gA_Rankings[target].iRank, gS_ChatStrings.sText, + gI_RankedPlayers, + gS_ChatStrings.sVariable, gA_Rankings[target].fPoints, gS_ChatStrings.sText); + } + else + { + Shavit_PrintToChat(param1, "%T", "StyleRank", param1, gS_ChatStrings.sVariable2, target, gS_ChatStrings.sText, + gS_ChatStrings.sVariable, (gA_Rankings[target].iStyleRank[iStyle] > gI_StyleRankedPlayers[iStyle])? gI_StyleRankedPlayers[iStyle]:gA_Rankings[target].iStyleRank[iStyle], gS_ChatStrings.sText, + gI_StyleRankedPlayers[iStyle], + gS_ChatStrings.sVariable, gA_Rankings[target].fStylePoints[iStyle], gS_ChatStrings.sText, + gS_ChatStrings.sStyle, gS_StyleStrings[iStyle].sStyleName, gS_ChatStrings.sText); + } + } + + OpenRankMenu(param1, GetMenuSelectionPosition()); + } + else if (action == MenuAction_End) + delete menu; +} + public Action Command_Top(int client, int args) { - int style = -1; - - if (gA_StyleRankCache[client].bForceStyle) + if(IsValidClient(client)) { - style = gA_StyleRankCache[client].iLastStyle; - gA_StyleRankCache[client].bForceStyle = false; + OpenTopMainMenu(client, 0); } - if (style == -1) + return Plugin_Handled; +} + +void OpenTopMainMenu(int client, int position = 0) +{ + Menu menu = new Menu(MenuHandler_TopMain); + + char sDisplay[32]; + + SetMenuTitle(menu, "%T\n ", "StyleTopTitle", client); + + FormatEx(sDisplay, 32, "%T\n ", "Overall", client); + menu.AddItem("-1", sDisplay); + + int[] iOrderedStyles = new int[gI_Styles]; + Shavit_GetOrderedStyles(iOrderedStyles, gI_Styles); + + for(int i = 0; i < gI_Styles; i++) { - if(gH_Top100Menu != null) + int iStyle = iOrderedStyles[i]; + + if(Shavit_GetStyleSettingInt(iStyle, "enabled") == -1) { - gH_Top100Menu.SetTitle("%T (%d)\n ", "Top100", client, gI_RankedPlayers); - gH_Top100Menu.Display(client, MENU_TIME_FOREVER); + continue; } + + char sStyle[8]; + IntToString(iStyle, sStyle, sizeof(sStyle)); + menu.AddItem(sStyle, gS_StyleStrings[iStyle].sStyleName); + } + + menu.ExitButton = true; + DisplayMenuAtItem(menu, client, position, MENU_TIME_FOREVER); +} + +public void MenuHandler_TopMain(Menu menu, MenuAction action, int param1, int param2) +{ + if(action == MenuAction_Select) + { + gA_StyleRankCache[param1].iMenuPosition = GetMenuSelectionPosition(); + char sStyle[8]; + menu.GetItem(param2, sStyle, sizeof(sStyle)); + int iStyle = StringToInt(sStyle); + + if (iStyle < 0 || iStyle >= gI_Styles) + { + iStyle = -1; + } + + if(iStyle == -1) + { + if(gH_Top100Menu != null) + { + gH_Top100Menu.SetTitle("%T (%d)\n ", "Top100", param1, gI_RankedPlayers); + gH_Top100Menu.Display(param1, MENU_TIME_FOREVER); + } + } + else + { + gA_StyleRankCache[param1].iStyle = iStyle; + OpenStyleTopMenu(param1); + } + } + else if (action == MenuAction_End) + delete menu; +} + +void OpenStyleTopMenu(int client) +{ + int iStyle = gA_StyleRankCache[client].iStyle; + char sDisplay[96]; + + Menu menu = new Menu(MenuHandler_Top); + + menu.SetTitle("%T (%d)\n ", "StyleTop100", client, gS_StyleStrings[iStyle].sStyleName, gI_StyleRankedPlayers[iStyle]); + + if (gI_StyleRankedPlayers[iStyle] == 0) + { + FormatEx(sDisplay, 64, "%T", "NoRankedPlayers", client); + menu.AddItem("-1", sDisplay, ITEMDRAW_DISABLED); } else { - if(gH_StyleTop100Menu != null) + char sName[33]; + char sSteamID[33]; + for (int i = 0; i < 100; i++) { - gH_StyleTop100Menu.SetTitle("%T (%d)\n ", "Top100", client, gS_StyleStrings[style].sStyleName, gI_RankedStylePlayers[style]); - gH_StyleTop100Menu.Display(client, style, MENU_TIME_FOREVER); + gA_StyleTop[iStyle].sName.GetString(i, sName, sizeof(sName)); + IntToString(gA_StyleTop[iStyle].iSteamID[i], sSteamID, sizeof(sSteamID)); + FormatEx(sDisplay, 96, "#%d - %s (%.2f)", i+1, sName, gA_StyleTop[iStyle].fPoints[i]); + menu.AddItem(sSteamID, sDisplay); } } - return Plugin_Handled; -} - -public Action Command_StyleTop(int client, int args) -{ - //Create style menu - - return Plugin_Handled; -} - -public Action Command_Top_Style(int client, int args) -{ - char sCommand[128]; - GetCmdArg(0, sCommand, sizeof(sCommand)); - - int style = 0; - - if (gSM_StyleCommands.GetValue(sCommand, style)) - { - gA_StyleRankCache[client].bForceStyle = true; - gA_StyleRankCache[client].iLastStyle = style; - Command_Top(client, args); - } - - return Plugin_Handled; + menu.ExitBackButton = true; + menu.ExitButton = true; + DisplayMenu(menu, client, MENU_TIME_FOREVER); } public int MenuHandler_Top(Menu menu, MenuAction action, int param1, int param2) @@ -778,6 +932,11 @@ public int MenuHandler_Top(Menu menu, MenuAction action, int param1, int param2) FakeClientCommand(param1, "sm_profile [U:1:%s]", sInfo); } } + else if(action == MenuAction_Cancel) + { + if(param2 == MenuCancel_ExitBack) + OpenTopMainMenu(param1, gA_StyleRankCache[param1].iMenuPosition); + } return 0; } @@ -1033,6 +1192,8 @@ public Action Command_RecalcAll(int client, int args) AddQueryLog(trans, sQuery); FormatEx(sQuery, sizeof(sQuery), "UPDATE %susers SET points = 0;", gS_MySQLPrefix); AddQueryLog(trans, sQuery); + FormatEx(sQuery, sizeof(sQuery), "UPDATE %sstylepoints SET points = 0;", gS_MySQLPrefix); + AddQueryLog(trans, sQuery); for(int i = 0; i < gI_Styles; i++) { @@ -1059,7 +1220,7 @@ public void Trans_OnRecalcSuccess(Database db, any data, int numQueries, DBResul SetCmdReplySource(SM_REPLY_TO_CONSOLE); } - ReplyToCommand(client, "- Finished recalculating all points. Recalculating user points, top 100 and user cache."); + ReplyToCommand(client, "- Finished recalculating all points. Recalculating user points, top 100 and user cache for all styles."); UpdateAllPoints(true); } @@ -1171,13 +1332,22 @@ void UpdatePointsForSinglePlayer(int client) { int auth = GetSteamAccountID(client); - char sQuery[1024]; + char sQuery[1024], sStyleQuery[1024]; if (gCV_WeightingMultiplier.FloatValue == 1.0 || gB_SqliteHatesPOW) { FormatEx(sQuery, sizeof(sQuery), "UPDATE %susers SET points = (SELECT SUM(points) FROM %splayertimes WHERE auth = %d) WHERE auth = %d;", gS_MySQLPrefix, gS_MySQLPrefix, auth, auth); + + for (int i = 0; i < gI_Styles; i++) + { + FormatEx(sStyleQuery, sizeof(sStyleQuery), + "UPDATE %sstylepoints SET points = (SELECT SUM(points) FROM %splayertimes WHERE auth = %d AND style = %d) WHERE auth = %d AND style = %d;", + gS_MySQLPrefix, gS_MySQLPrefix, auth, i, auth, i); + + QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); + } } else if (gB_SQLWindowFunctions) { @@ -1201,12 +1371,43 @@ void UpdatePointsForSinglePlayer(int client) sLimit, auth ); + + for (int i = 0; i < gI_Styles; i++) + { + FormatEx(sStyleQuery, sizeof(sStyleQuery), + "UPDATE %sstylepoints SET points = (\n" + ... " SELECT SUM(points2) FROM (\n" + ... " SELECT (points * POW(%f, ROW_NUMBER() OVER (ORDER BY points DESC) - 1)) as points2\n" + ... " FROM %splayertimes\n" + ... " WHERE auth = %d AND points > 0 AND style = %d\n" + ... " ORDER BY points DESC %s\n" + ... " ) as t\n" + ... ") WHERE auth = %d AND style = %d;", + gS_MySQLPrefix, + gCV_WeightingMultiplier.FloatValue, + gS_MySQLPrefix, + auth, i, + sLimit, + auth, i + ); + + QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); + } } else // We should only be here if mysql :) { FormatEx(sQuery, sizeof(sQuery), "UPDATE %susers SET points = GetWeightedPoints(auth) WHERE auth = %d;", gS_MySQLPrefix, auth); + + for (int i = 0; i < gI_Styles; i++) + { + FormatEx(sStyleQuery, sizeof(sStyleQuery), + "UPDATE %sstylepoints SET points = GetWeightedPoints(auth, %d) WHERE auth = %d and style = %d;", + gS_MySQLPrefix, i, auth, i); + + QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); + } } QueryLog(gH_SQL, SQL_UpdateAllPoints_Callback, sQuery, GetClientSerial(client)); @@ -1218,7 +1419,7 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1) LogError("DEBUG: 6 (UpdateAllPoints)"); #endif - char sQuery[1024]; + char sQuery[1024], sStyleQuery[1024]; char sLastLogin[69], sLimit[30], sMapWhere[512], sTrackWhere[64]; if (track != -1) @@ -1242,6 +1443,16 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1) "UPDATE %susers AS U SET points = P.total FROM (SELECT auth, SUM(points) AS total FROM %splayertimes GROUP BY auth) P WHERE U.auth = P.auth %s %s;", gS_MySQLPrefix, gS_MySQLPrefix, (sLastLogin[0] != 0) ? "AND " : "", sLastLogin); + + for (int i = 0; i < gI_Styles; i++) + { + FormatEx(sStyleQuery, sizeof(sStyleQuery), + "UPDATE %sstylepoints AS S SET points = P.total FROM (SELECT auth, SUM(points) AS total FROM %splayertimes WHERE style = %d GROUP BY auth) P WHERE S.auth = P.auth %s %s;", + gS_MySQLPrefix, gS_MySQLPrefix, i, + (sLastLogin[0] != 0) ? "AND " : "", sLastLogin); + + QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); + } } else { @@ -1249,6 +1460,16 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1) "UPDATE %susers AS U INNER JOIN (SELECT auth, SUM(points) AS total FROM %splayertimes GROUP BY auth) P ON U.auth = P.auth SET U.points = P.total %s %s;", gS_MySQLPrefix, gS_MySQLPrefix, (sLastLogin[0] != 0) ? "WHERE" : "", sLastLogin); + + for (int i = 0; i < gI_Styles; i++) + { + FormatEx(sStyleQuery, sizeof(sStyleQuery), + "UPDATE %sstylepoints AS S INNER JOIN (SELECT auth, SUM(points) AS total FROM %splayertimes WHERE style = %d GROUP BY auth) P ON S.auth = P.auth SET S.points = P.total %s %s;", + gS_MySQLPrefix, gS_MySQLPrefix, i, + (sLastLogin[0] != 0) ? "WHERE" : "", sLastLogin); + + QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); + } } } else if (gB_SQLWindowFunctions && gI_Driver == Driver_mysql) @@ -1282,6 +1503,38 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1) (sMapWhere[0] && sTrackWhere[0]) ? "AND" : "", sTrackWhere, sLimit); // TODO: Remove/move sLimit? + + for (int i = 0; i < gI_Styles; i++) + { + FormatEx(sStyleQuery, sizeof(sStyleQuery), + "UPDATE %sstylepoints AS s, (\n" + ... " SELECT auth, SUM(t.points2) as pp FROM (\n" + ... " SELECT p.auth, (p.points * POW(%f, ROW_NUMBER() OVER (PARTITION BY p.auth ORDER BY p.points DESC) - 1)) as points2\n" + ... " FROM %splayertimes AS p\n" + ... " JOIN %sstylepoints AS s2\n" + ... " ON s2.auth = p.auth %s %s\n" + ... " WHERE p.points > 0 AND p.style = %d AND p.auth IN (SELECT DISTINCT auth FROM %splayertimes WHERE style = %d %s %s %s %s)\n" + ... " ORDER BY p.points DESC %s\n" + ... " ) AS t\n" + ... " GROUP by auth\n" + ... ") AS a\n" + ... "SET s.points = a.pp\n" + ... "WHERE s.auth = a.auth and s.style = %d;", + gS_MySQLPrefix, + gCV_WeightingMultiplier.FloatValue, + gS_MySQLPrefix, + gS_MySQLPrefix, + sLastLogin[0] ? "AND" : "", sLastLogin, + i, gS_MySQLPrefix, i, + sMapWhere[0] ? "AND" : "", + sMapWhere, + sTrackWhere[0] ? "AND" : "", + sTrackWhere, + sLimit, // TODO: Remove/move sLimit? + i); + + QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); + } } else if (gB_SQLWindowFunctions) { @@ -1306,6 +1559,34 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1) sMapWhere, (sMapWhere[0] && sTrackWhere[0]) ? "AND" : "", sTrackWhere); + + for (int i = 0; i < gI_Styles; i++) + { + FormatEx(sStyleQuery, sizeof(sStyleQuery), + "UPDATE %sstylepoints AS s\n" + ... "SET points = (\n" + ... " SELECT SUM(points2) FROM (\n" + ... " SELECT (points * POW(%f, ROW_NUMBER() OVER (ORDER BY points DESC) - 1)) AS points2\n" + ... " FROM %splayertimes\n" + ... " WHERE auth = s.auth AND points > 0 AND style = %d\n" + ... " ORDER BY points DESC %s\n" + ... " ) AS t\n" + ... ") WHERE %s %s auth IN\n" + ... " (SELECT DISTINCT auth FROM %splayertimes WHERE style = %d %s %s %s %s);", + gS_MySQLPrefix, + gCV_WeightingMultiplier.FloatValue, + gS_MySQLPrefix, + i, + sLimit, // TODO: Remove/move sLimit? + sLastLogin, sLastLogin[0] ? "AND" : "", + gS_MySQLPrefix, i, + sMapWhere[0] ? "AND" : "", + sMapWhere, + sTrackWhere[0] ? "AND" : "", + sTrackWhere); + + QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); + } } else // !gB_SQLWindowFunctions && gI_Driver == Driver_mysql { @@ -1318,6 +1599,21 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1) sMapWhere, (sMapWhere[0] && sTrackWhere[0]) ? "AND" : "", sTrackWhere); + + for (int i = 0; i < gI_Styles; i++) + { + FormatEx(sQuery, sizeof(sQuery), + "UPDATE %sstylepoints SET points = GetWeightedStylePoints(auth, %d) WHERE %s %s auth IN (SELECT DISTINCT auth FROM %splayertimes WHERE style = %d %s %s %s %s);", + gS_MySQLPrefix, i, + sLastLogin, (sLastLogin[0] != 0) ? "AND" : "", + gS_MySQLPrefix, i, + sMapWhere[0] ? "AND" : "", + sMapWhere, + sTrackWhere[0] ? "AND" : "", + sTrackWhere); + + QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); + } } QueryLog(gH_SQL, SQL_UpdateAllPoints_Callback, sQuery); @@ -1343,6 +1639,14 @@ public void SQL_UpdateAllPoints_Callback(Database db, DBResultSet results, const } } +public void SQL_UpdateAllStylePoints_Callback(Database db, DBResultSet results, const char[] error, any data) +{ + if(results == null) + { + LogError("Timer (rankings, update all style points) error! Reason: %s", error); + } +} + void UpdatePlayerRank(int client, bool first) { int iSteamID = 0; @@ -1360,6 +1664,19 @@ void UpdatePlayerRank(int client, bool first) hPack.WriteCell(first); QueryLog(gH_SQL, SQL_UpdatePlayerRank_Callback, sQuery, hPack, DBPrio_Low); + + for (int i = 0; i < gI_Styles; i++) + { + FormatEx(sQuery, 512, "SELECT s2.points, COUNT(*) FROM %sstylepoints s1 JOIN (SELECT points FROM %sstylepoints WHERE auth = %d AND style = %d) s2 WHERE style = %d AND s1.points >= s2.points;", + gS_MySQLPrefix, gS_MySQLPrefix, iSteamID, i, i); + + DataPack hStylePack = new DataPack(); + hStylePack.WriteCell(GetClientSerial(client)); + hStylePack.WriteCell(first); + hStylePack.WriteCell(i); + + QueryLog(gH_SQL, SQL_UpdatePlayerStyleRank_Callback, sQuery, hStylePack, DBPrio_Low); + } } } @@ -1400,6 +1717,45 @@ public void SQL_UpdatePlayerRank_Callback(Database db, DBResultSet results, cons } } +public void SQL_UpdatePlayerStyleRank_Callback(Database db, DBResultSet results, const char[] error, any data) +{ + DataPack hPack = view_as(data); + hPack.Reset(); + + int iSerial = hPack.ReadCell(); + bool bFirst = view_as(hPack.ReadCell()); + int iStyle = hPack.ReadCell(); + delete hPack; + + if(results == null) + { + LogError("Timer (rankings, update player style rank) error! Reason: %s", error); + + return; + } + + int client = GetClientFromSerial(iSerial); + + if(client == 0) + { + return; + } + + if(results.FetchRow()) + { + gA_Rankings[client].fStylePoints[iStyle] = results.FetchFloat(0); + gA_Rankings[client].iStyleRank[iStyle] = (gA_Rankings[client].fStylePoints[iStyle] > 0.0)? results.FetchInt(1):0; + + Call_StartForward(gH_Forwards_OnStyleRankAssigned); + Call_PushCell(client); + Call_PushCell(iStyle); + Call_PushCell(gA_Rankings[client].iStyleRank[iStyle]); + Call_PushCell(gA_Rankings[client].fStylePoints[iStyle]); + Call_PushCell(bFirst); + Call_Finish(); + } +} + void UpdateTop100() { char sQuery[512]; @@ -1410,6 +1766,21 @@ void UpdateTop100() gS_MySQLPrefix, gS_MySQLPrefix); QueryLog(gH_SQL, SQL_UpdateTop100_Callback, sQuery, 0, DBPrio_High); + + for (int i = 0; i < gI_Styles; i++) + { + FormatEx(sQuery, sizeof(sQuery), + "SELECT COUNT(*) as c, '' as auth, '' as name, '' as points FROM %sstylepoints as s WHERE style = %d AND points > 0.0 \ + UNION ALL \ + SELECT '' as c, %sstylepoints.auth, %susers.name, %sstylepoints.points \ + FROM %sstylepoints \ + INNER JOIN %susers \ + ON %sstylepoints.auth = %susers.auth \ + WHERE %sstylepoints.points > 0 AND %sstylepoints.style = %d ORDER BY c DESC, CAST(points AS FLOAT) DESC LIMIT 101;", + gS_MySQLPrefix, i, gS_MySQLPrefix, gS_MySQLPrefix,gS_MySQLPrefix, gS_MySQLPrefix, gS_MySQLPrefix, gS_MySQLPrefix, gS_MySQLPrefix, gS_MySQLPrefix, gS_MySQLPrefix, i); + + QueryLog(gH_SQL, SQL_UpdateStyleTop100_Callback, sQuery, i, DBPrio_High); + } } public void SQL_UpdateTop100_Callback(Database db, DBResultSet results, const char[] error, any data) @@ -1457,9 +1828,42 @@ public void SQL_UpdateTop100_Callback(Database db, DBResultSet results, const ch gH_Top100Menu.AddItem("-1", sDisplay); } + gH_Top100Menu.ExitBackButton = true; gH_Top100Menu.ExitButton = true; } +public void SQL_UpdateStyleTop100_Callback(Database db, DBResultSet results, const char[] error, any data) +{ + if (results == null) + { + LogError("Timer (rankings, update style top 100) error! Reason: %s", error); + + return; + } + + if (!results.FetchRow()) + { + LogError("Timer (rankings, update style top 100 b) error! Reason: failed to fetch first row"); + return; + } + + int iStyle = data; + gI_StyleRankedPlayers[iStyle] = results.FetchInt(0); + + int row = 0; + char sName[33]; + while (results.FetchRow()) + { + gA_StyleTop[iStyle].iSteamID[row] = results.FetchInt(1); + + results.FetchString(2, sName, 33); + gA_StyleTop[iStyle].sName.SetString(row, sName); + + gA_StyleTop[iStyle].fPoints[row] = results.FetchFloat(3); + row++; + } +} + bool DoWeHaveWindowFunctions(const char[] sVersion) { char buf[100][2]; @@ -1801,16 +2205,31 @@ public int Native_GetPoints(Handle handler, int numParams) return view_as(gA_Rankings[GetNativeCell(1)].fPoints); } +public int Native_GetStylePoints(Handle handler, int numParams) +{ + return view_as(gA_Rankings[GetNativeCell(1)].fStylePoints[GetNativeCell(2)]); +} + public int Native_GetRank(Handle handler, int numParams) { return gA_Rankings[GetNativeCell(1)].iRank; } +public int Native_GetStyleRank(Handle handler, int numParams) +{ + return gA_Rankings[GetNativeCell(1)].iStyleRank[GetNativeCell(2)]; +} + public int Native_GetRankedPlayers(Handle handler, int numParams) { return gI_RankedPlayers; } +public int Native_GetStyleRankedPlayers(Handle handler, int numParams) +{ + return gI_StyleRankedPlayers[GetNativeCell(1)]; +} + public int Native_Rankings_DeleteMap(Handle handler, int numParams) { char sMap[PLATFORM_MAX_PATH]; From 56c6cd35db8bacd0519b48bf3255d5757b2e6063 Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Thu, 31 Jul 2025 20:12:33 -0700 Subject: [PATCH 12/28] shavit-rankings.sp - remove unnecessary translation file --- addons/sourcemod/scripting/shavit-rankings.sp | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/sourcemod/scripting/shavit-rankings.sp b/addons/sourcemod/scripting/shavit-rankings.sp index 6f9bf259..ffc579e9 100644 --- a/addons/sourcemod/scripting/shavit-rankings.sp +++ b/addons/sourcemod/scripting/shavit-rankings.sp @@ -227,7 +227,6 @@ public void OnPluginStart() Convar.AutoExecConfig(); LoadTranslations("common.phrases"); - LoadTranslations("shavit-core.phrases"); LoadTranslations("shavit-common.phrases"); LoadTranslations("shavit-rankings.phrases"); From 8b571296c0e7c51b8c2b4a772272cbebf7c9d0dc Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Thu, 31 Jul 2025 22:10:30 -0700 Subject: [PATCH 13/28] shavit-rankings.sp - change UPDATE to UPDATE IGNORE to prevent null errors when value being set to default 0 --- addons/sourcemod/scripting/shavit-rankings.sp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-rankings.sp b/addons/sourcemod/scripting/shavit-rankings.sp index ffc579e9..7e070856 100644 --- a/addons/sourcemod/scripting/shavit-rankings.sp +++ b/addons/sourcemod/scripting/shavit-rankings.sp @@ -1342,7 +1342,7 @@ void UpdatePointsForSinglePlayer(int client) for (int i = 0; i < gI_Styles; i++) { FormatEx(sStyleQuery, sizeof(sStyleQuery), - "UPDATE %sstylepoints SET points = (SELECT SUM(points) FROM %splayertimes WHERE auth = %d AND style = %d) WHERE auth = %d AND style = %d;", + "UPDATE IGNORE %sstylepoints SET points = (SELECT SUM(points) FROM %splayertimes WHERE auth = %d AND style = %d) WHERE auth = %d AND style = %d;", gS_MySQLPrefix, gS_MySQLPrefix, auth, i, auth, i); QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); @@ -1374,7 +1374,7 @@ void UpdatePointsForSinglePlayer(int client) for (int i = 0; i < gI_Styles; i++) { FormatEx(sStyleQuery, sizeof(sStyleQuery), - "UPDATE %sstylepoints SET points = (\n" + "UPDATE IGNORE %sstylepoints SET points = (\n" ... " SELECT SUM(points2) FROM (\n" ... " SELECT (points * POW(%f, ROW_NUMBER() OVER (ORDER BY points DESC) - 1)) as points2\n" ... " FROM %splayertimes\n" @@ -1402,7 +1402,7 @@ void UpdatePointsForSinglePlayer(int client) for (int i = 0; i < gI_Styles; i++) { FormatEx(sStyleQuery, sizeof(sStyleQuery), - "UPDATE %sstylepoints SET points = GetWeightedPoints(auth, %d) WHERE auth = %d and style = %d;", + "UPDATE IGNORE %sstylepoints SET points = GetWeightedPoints(auth, %d) WHERE auth = %d and style = %d;", gS_MySQLPrefix, i, auth, i); QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); @@ -1446,7 +1446,7 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1) for (int i = 0; i < gI_Styles; i++) { FormatEx(sStyleQuery, sizeof(sStyleQuery), - "UPDATE %sstylepoints AS S SET points = P.total FROM (SELECT auth, SUM(points) AS total FROM %splayertimes WHERE style = %d GROUP BY auth) P WHERE S.auth = P.auth %s %s;", + "UPDATE IGNORE %sstylepoints AS S SET points = P.total FROM (SELECT auth, SUM(points) AS total FROM %splayertimes WHERE style = %d GROUP BY auth) P WHERE S.auth = P.auth %s %s;", gS_MySQLPrefix, gS_MySQLPrefix, i, (sLastLogin[0] != 0) ? "AND " : "", sLastLogin); @@ -1463,7 +1463,7 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1) for (int i = 0; i < gI_Styles; i++) { FormatEx(sStyleQuery, sizeof(sStyleQuery), - "UPDATE %sstylepoints AS S INNER JOIN (SELECT auth, SUM(points) AS total FROM %splayertimes WHERE style = %d GROUP BY auth) P ON S.auth = P.auth SET S.points = P.total %s %s;", + "UPDATE IGNORE %sstylepoints AS S INNER JOIN (SELECT auth, SUM(points) AS total FROM %splayertimes WHERE style = %d GROUP BY auth) P ON S.auth = P.auth SET S.points = P.total %s %s;", gS_MySQLPrefix, gS_MySQLPrefix, i, (sLastLogin[0] != 0) ? "WHERE" : "", sLastLogin); @@ -1506,7 +1506,7 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1) for (int i = 0; i < gI_Styles; i++) { FormatEx(sStyleQuery, sizeof(sStyleQuery), - "UPDATE %sstylepoints AS s, (\n" + "UPDATE IGNORE %sstylepoints AS s, (\n" ... " SELECT auth, SUM(t.points2) as pp FROM (\n" ... " SELECT p.auth, (p.points * POW(%f, ROW_NUMBER() OVER (PARTITION BY p.auth ORDER BY p.points DESC) - 1)) as points2\n" ... " FROM %splayertimes AS p\n" @@ -1562,7 +1562,7 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1) for (int i = 0; i < gI_Styles; i++) { FormatEx(sStyleQuery, sizeof(sStyleQuery), - "UPDATE %sstylepoints AS s\n" + "UPDATE IGNORE %sstylepoints AS s\n" ... "SET points = (\n" ... " SELECT SUM(points2) FROM (\n" ... " SELECT (points * POW(%f, ROW_NUMBER() OVER (ORDER BY points DESC) - 1)) AS points2\n" @@ -1602,7 +1602,7 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1) for (int i = 0; i < gI_Styles; i++) { FormatEx(sQuery, sizeof(sQuery), - "UPDATE %sstylepoints SET points = GetWeightedStylePoints(auth, %d) WHERE %s %s auth IN (SELECT DISTINCT auth FROM %splayertimes WHERE style = %d %s %s %s %s);", + "UPDATE IGNORE %sstylepoints SET points = GetWeightedStylePoints(auth, %d) WHERE %s %s auth IN (SELECT DISTINCT auth FROM %splayertimes WHERE style = %d %s %s %s %s);", gS_MySQLPrefix, i, sLastLogin, (sLastLogin[0] != 0) ? "AND" : "", gS_MySQLPrefix, i, From 832528bc015fa48327de9e721f74ee7c5c95f985 Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Fri, 1 Aug 2025 10:23:45 -0700 Subject: [PATCH 14/28] shavit-rankings.sp - fix styles < 100 ranked players displaying 0s through to 100 entries in the menu --- addons/sourcemod/scripting/shavit-rankings.sp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/shavit-rankings.sp b/addons/sourcemod/scripting/shavit-rankings.sp index 7e070856..85a72051 100644 --- a/addons/sourcemod/scripting/shavit-rankings.sp +++ b/addons/sourcemod/scripting/shavit-rankings.sp @@ -905,7 +905,7 @@ void OpenStyleTopMenu(int client) { char sName[33]; char sSteamID[33]; - for (int i = 0; i < 100; i++) + for (int i = 0; i < (gI_StyleRankedPlayers[iStyle] < 100 ? gI_StyleRankedPlayers[iStyle] : 100); i++) { gA_StyleTop[iStyle].sName.GetString(i, sName, sizeof(sName)); IntToString(gA_StyleTop[iStyle].iSteamID[i], sSteamID, sizeof(sSteamID)); From bd740d8504a6f47262475e9b569a2e4c4de6ef3e Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Fri, 1 Aug 2025 11:28:08 -0700 Subject: [PATCH 15/28] shavit-chat.sp - add style rank chatranks support --- addons/sourcemod/scripting/shavit-chat.sp | 53 +++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/addons/sourcemod/scripting/shavit-chat.sp b/addons/sourcemod/scripting/shavit-chat.sp index 28c7527e..9455a5ba 100644 --- a/addons/sourcemod/scripting/shavit-chat.sp +++ b/addons/sourcemod/scripting/shavit-chat.sp @@ -108,12 +108,16 @@ char gS_CustomName[MAXPLAYERS+1][128]; char gS_CustomMessage[MAXPLAYERS+1][16]; chatstrings_t gS_ChatStrings; +stylestrings_t gS_StyleStrings[STYLE_LIMIT]; // chat procesor bool gB_Protobuf = false; bool gB_NewMessage[MAXPLAYERS+1]; StringMap gSM_Messages = null; +//style ranks +int gI_Styles = 0; + char gS_ControlCharacters[][] = {"\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", "\x08", "\x09", "\x0A", "\x0B", "\x0C", "\x0D", "\x0E", "\x0F", "\x10" }; @@ -215,6 +219,19 @@ public void Shavit_OnChatConfigLoaded() Shavit_GetChatStringsStruct(gS_ChatStrings); } +public void Shavit_OnStyleConfigLoaded(int styles) +{ + gI_Styles = styles; + + for (int i = 0; i < STYLE_LIMIT; i++) + { + if (i < styles) + { + Shavit_GetStyleStringsStruct(i, gS_StyleStrings[i]); + } + } +} + public void OnMapStart() { if(!LoadChatConfig()) @@ -1319,6 +1336,24 @@ void FormatChat(int client, char[] buffer, int size) IntToString(iRank, temp, 32); ReplaceString(buffer, size, "{rank}", temp); + int iStyleRank; + char sStyleRank[16]; + char sStyleBuf[32]; + for (int i = 0; i < gI_Styles; i++) + { + iStyleRank = Shavit_GetStyleRank(client, i); + if(iStyleRank == 0) + { + strcopy(sStyleRank, 16, "Unranked"); + } + else + { + IntToString(iStyleRank, sStyleRank, 16); + } + FormatEx(sStyleBuf, 32, "{style%drank}", i); + ReplaceString(buffer, size, sStyleBuf, sStyleRank); + } + int iRanked = Shavit_GetRankedPlayers(); if(iRanked == 0) @@ -1558,6 +1593,24 @@ public int Native_GetPlainChatrank(Handle handler, int numParams) IntToString(iRank, sRank, 16); ReplaceString(buf, sizeof(buf), "{rank}", sRank); + int iStyleRank; + char sStyleRank[16]; + char sStyleBuf[32]; + for (int i = 0; i < gI_Styles; i++) + { + iStyleRank = Shavit_GetStyleRank(client, i); + if(iStyleRank == 0) + { + strcopy(sStyleRank, 16, "Unranked"); + } + else + { + IntToString(iStyleRank, sStyleRank, 16); + } + FormatEx(sStyleBuf, 32, "{style%drank}", i); + ReplaceString(buf, sizeof(buf), sStyleBuf, sStyleRank); + } + int iRanked = Shavit_GetRankedPlayers(); if (iRanked == 0) From 3032818408885b900f645bd5308ca6855676ddb6 Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Fri, 1 Aug 2025 13:56:30 -0700 Subject: [PATCH 16/28] shavit-rankings.sp - fix queries --- addons/sourcemod/scripting/shavit-rankings.sp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-rankings.sp b/addons/sourcemod/scripting/shavit-rankings.sp index 85a72051..c2f50b3c 100644 --- a/addons/sourcemod/scripting/shavit-rankings.sp +++ b/addons/sourcemod/scripting/shavit-rankings.sp @@ -1402,7 +1402,7 @@ void UpdatePointsForSinglePlayer(int client) for (int i = 0; i < gI_Styles; i++) { FormatEx(sStyleQuery, sizeof(sStyleQuery), - "UPDATE IGNORE %sstylepoints SET points = GetWeightedPoints(auth, %d) WHERE auth = %d and style = %d;", + "UPDATE IGNORE %sstylepoints SET points = GetStyleWeightedPoints(auth, %d) WHERE auth = %d and style = %d;", gS_MySQLPrefix, i, auth, i); QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); @@ -1446,8 +1446,8 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1) for (int i = 0; i < gI_Styles; i++) { FormatEx(sStyleQuery, sizeof(sStyleQuery), - "UPDATE IGNORE %sstylepoints AS S SET points = P.total FROM (SELECT auth, SUM(points) AS total FROM %splayertimes WHERE style = %d GROUP BY auth) P WHERE S.auth = P.auth %s %s;", - gS_MySQLPrefix, gS_MySQLPrefix, i, + "UPDATE IGNORE %sstylepoints AS S SET points = P.total FROM (SELECT auth, SUM(points) AS total FROM %splayertimes WHERE style = %d GROUP BY auth) P WHERE S.auth = P.auth AND style = %d %s %s;", + gS_MySQLPrefix, gS_MySQLPrefix, i, i, (sLastLogin[0] != 0) ? "AND " : "", sLastLogin); QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); @@ -1463,8 +1463,8 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1) for (int i = 0; i < gI_Styles; i++) { FormatEx(sStyleQuery, sizeof(sStyleQuery), - "UPDATE IGNORE %sstylepoints AS S INNER JOIN (SELECT auth, SUM(points) AS total FROM %splayertimes WHERE style = %d GROUP BY auth) P ON S.auth = P.auth SET S.points = P.total %s %s;", - gS_MySQLPrefix, gS_MySQLPrefix, i, + "UPDATE IGNORE %sstylepoints AS S INNER JOIN (SELECT auth, SUM(points) AS total FROM %splayertimes WHERE style = %d GROUP BY auth) P ON S.auth = P.auth SET S.points = P.total WHERE style = %d %s %s;", + gS_MySQLPrefix, gS_MySQLPrefix, i, i, (sLastLogin[0] != 0) ? "WHERE" : "", sLastLogin); QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); From b0359f02e33e769e12ed96c9eb32c12f510597cc Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Fri, 1 Aug 2025 15:51:11 -0700 Subject: [PATCH 17/28] shavit-chat.sp - add dynamic {currentstylerank} variable and prepend '#' to style ranks --- addons/sourcemod/scripting/shavit-chat.sp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-chat.sp b/addons/sourcemod/scripting/shavit-chat.sp index 9455a5ba..4dd5ca99 100644 --- a/addons/sourcemod/scripting/shavit-chat.sp +++ b/addons/sourcemod/scripting/shavit-chat.sp @@ -1350,8 +1350,14 @@ void FormatChat(int client, char[] buffer, int size) { IntToString(iStyleRank, sStyleRank, 16); } - FormatEx(sStyleBuf, 32, "{style%drank}", i); + FormatEx(sStyleBuf, 32, "#{style%drank}", i); ReplaceString(buffer, size, sStyleBuf, sStyleRank); + + if(i == Shavit_GetBhopStyle(client)) + { + FormatEx(sStyleBuf, 32, "%s%s %s", iStyleRank > 0 ? "#" : "", sStyleRank, gS_StyleStrings[i].sStyleName); + ReplaceString(buffer, size, "{currentstylerank}", sStyleBuf); + } } int iRanked = Shavit_GetRankedPlayers(); @@ -1607,8 +1613,14 @@ public int Native_GetPlainChatrank(Handle handler, int numParams) { IntToString(iStyleRank, sStyleRank, 16); } - FormatEx(sStyleBuf, 32, "{style%drank}", i); + FormatEx(sStyleBuf, 32, "#{style%drank}", i); ReplaceString(buf, sizeof(buf), sStyleBuf, sStyleRank); + + if(i == Shavit_GetBhopStyle(client)) + { + FormatEx(sStyleBuf, 32, "%s%s %s", iStyleRank > 0 ? "#" : "", sStyleRank, gS_StyleStrings[i].sStyleName); + ReplaceString(buf, sizeof(buf), "{currentstylerank}", sStyleBuf); + } } int iRanked = Shavit_GetRankedPlayers(); From 828ed9485729447a2df486ee13e6377f9f2451b4 Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Fri, 1 Aug 2025 16:08:53 -0700 Subject: [PATCH 18/28] shavit-chat.sp - fix replace variables --- addons/sourcemod/scripting/shavit-chat.sp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-chat.sp b/addons/sourcemod/scripting/shavit-chat.sp index 4dd5ca99..5d8b72b8 100644 --- a/addons/sourcemod/scripting/shavit-chat.sp +++ b/addons/sourcemod/scripting/shavit-chat.sp @@ -1349,8 +1349,9 @@ void FormatChat(int client, char[] buffer, int size) else { IntToString(iStyleRank, sStyleRank, 16); + Format(sStyleRank, 16, "#%s", sStyleRank); } - FormatEx(sStyleBuf, 32, "#{style%drank}", i); + FormatEx(sStyleBuf, 32, "{style%drank}", i); ReplaceString(buffer, size, sStyleBuf, sStyleRank); if(i == Shavit_GetBhopStyle(client)) @@ -1612,8 +1613,9 @@ public int Native_GetPlainChatrank(Handle handler, int numParams) else { IntToString(iStyleRank, sStyleRank, 16); + Format(sStyleRank, 16, "#%s", sStyleRank); } - FormatEx(sStyleBuf, 32, "#{style%drank}", i); + FormatEx(sStyleBuf, 32, "{style%drank}", i); ReplaceString(buf, sizeof(buf), sStyleBuf, sStyleRank); if(i == Shavit_GetBhopStyle(client)) From 5391c32d3d02c5317bbd78fd82c5a59eaf5fec3d Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Fri, 1 Aug 2025 16:17:39 -0700 Subject: [PATCH 19/28] shavit-chat.sp - remove duplicate '#' --- addons/sourcemod/scripting/shavit-chat.sp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-chat.sp b/addons/sourcemod/scripting/shavit-chat.sp index 5d8b72b8..29a21707 100644 --- a/addons/sourcemod/scripting/shavit-chat.sp +++ b/addons/sourcemod/scripting/shavit-chat.sp @@ -1356,7 +1356,7 @@ void FormatChat(int client, char[] buffer, int size) if(i == Shavit_GetBhopStyle(client)) { - FormatEx(sStyleBuf, 32, "%s%s %s", iStyleRank > 0 ? "#" : "", sStyleRank, gS_StyleStrings[i].sStyleName); + FormatEx(sStyleBuf, 32, "%s %s", sStyleRank, gS_StyleStrings[i].sStyleName); ReplaceString(buffer, size, "{currentstylerank}", sStyleBuf); } } @@ -1620,7 +1620,7 @@ public int Native_GetPlainChatrank(Handle handler, int numParams) if(i == Shavit_GetBhopStyle(client)) { - FormatEx(sStyleBuf, 32, "%s%s %s", iStyleRank > 0 ? "#" : "", sStyleRank, gS_StyleStrings[i].sStyleName); + FormatEx(sStyleBuf, 32, "%s %s", sStyleRank, gS_StyleStrings[i].sStyleName); ReplaceString(buf, sizeof(buf), "{currentstylerank}", sStyleBuf); } } From 5ca54463543f9a1560afc7862e218df46f6e7f41 Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Mon, 11 Aug 2025 09:58:09 -0700 Subject: [PATCH 20/28] shavit-rankings.sp - first attempt at optimizing queries using GROUP BY style instead of running a query for each style ID --- addons/sourcemod/scripting/shavit-rankings.sp | 135 ++++++++---------- 1 file changed, 58 insertions(+), 77 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-rankings.sp b/addons/sourcemod/scripting/shavit-rankings.sp index c2f50b3c..e7caed29 100644 --- a/addons/sourcemod/scripting/shavit-rankings.sp +++ b/addons/sourcemod/scripting/shavit-rankings.sp @@ -1339,14 +1339,11 @@ void UpdatePointsForSinglePlayer(int client) "UPDATE %susers SET points = (SELECT SUM(points) FROM %splayertimes WHERE auth = %d) WHERE auth = %d;", gS_MySQLPrefix, gS_MySQLPrefix, auth, auth); - for (int i = 0; i < gI_Styles; i++) - { - FormatEx(sStyleQuery, sizeof(sStyleQuery), - "UPDATE IGNORE %sstylepoints SET points = (SELECT SUM(points) FROM %splayertimes WHERE auth = %d AND style = %d) WHERE auth = %d AND style = %d;", - gS_MySQLPrefix, gS_MySQLPrefix, auth, i, auth, i); + FormatEx(sStyleQuery, sizeof(sStyleQuery), + "UPDATE IGNORE %sstylepoints AS S SET points = P.total (SELECT SUM(points) as total FROM %splayertimes WHERE auth = %d GROUP BY style) P WHERE auth = %d AND S.style = P.style;", + gS_MySQLPrefix, gS_MySQLPrefix, auth, auth); - QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); - } + QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); } else if (gB_SQLWindowFunctions) { @@ -1371,24 +1368,22 @@ void UpdatePointsForSinglePlayer(int client) auth ); - for (int i = 0; i < gI_Styles; i++) - { - FormatEx(sStyleQuery, sizeof(sStyleQuery), - "UPDATE IGNORE %sstylepoints SET points = (\n" - ... " SELECT SUM(points2) FROM (\n" - ... " SELECT (points * POW(%f, ROW_NUMBER() OVER (ORDER BY points DESC) - 1)) as points2\n" - ... " FROM %splayertimes\n" - ... " WHERE auth = %d AND points > 0 AND style = %d\n" - ... " ORDER BY points DESC %s\n" - ... " ) as t\n" - ... ") WHERE auth = %d AND style = %d;", - gS_MySQLPrefix, - gCV_WeightingMultiplier.FloatValue, - gS_MySQLPrefix, - auth, i, - sLimit, - auth, i - ); + FormatEx(sStyleQuery, sizeof(sStyleQuery), + "UPDATE IGNORE %sstylepoints AS S SET points = (\n" + ... " SELECT SUM(points2) FROM (\n" + ... " SELECT (points * POW(%f, ROW_NUMBER() OVER (ORDER BY points DESC) - 1)) as points2\n" + ... " FROM %splayertimes\n" + ... " WHERE auth = %d AND points > 0 GROUP BY style\n" + ... " ORDER BY points DESC %s\n" + ... " ) as t\n" + ... ") P WHERE auth = %d AND S.style = P.style;", + gS_MySQLPrefix, + gCV_WeightingMultiplier.FloatValue, + gS_MySQLPrefix, + auth, + sLimit, + auth + ); QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); } @@ -1443,15 +1438,12 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1) gS_MySQLPrefix, gS_MySQLPrefix, (sLastLogin[0] != 0) ? "AND " : "", sLastLogin); - for (int i = 0; i < gI_Styles; i++) - { - FormatEx(sStyleQuery, sizeof(sStyleQuery), - "UPDATE IGNORE %sstylepoints AS S SET points = P.total FROM (SELECT auth, SUM(points) AS total FROM %splayertimes WHERE style = %d GROUP BY auth) P WHERE S.auth = P.auth AND style = %d %s %s;", - gS_MySQLPrefix, gS_MySQLPrefix, i, i, - (sLastLogin[0] != 0) ? "AND " : "", sLastLogin); + FormatEx(sStyleQuery, sizeof(sStyleQuery), + "UPDATE IGNORE %sstylepoints AS S SET points = P.total FROM (SELECT auth, SUM(points) AS total FROM %splayertimes GROUP BY auth, style) P WHERE S.auth = P.auth AND S.style = P.style %s %s;", + gS_MySQLPrefix, gS_MySQLPrefix, + (sLastLogin[0] != 0) ? "AND " : "", sLastLogin); - QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); - } + QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); } else { @@ -1460,15 +1452,12 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1) gS_MySQLPrefix, gS_MySQLPrefix, (sLastLogin[0] != 0) ? "WHERE" : "", sLastLogin); - for (int i = 0; i < gI_Styles; i++) - { - FormatEx(sStyleQuery, sizeof(sStyleQuery), - "UPDATE IGNORE %sstylepoints AS S INNER JOIN (SELECT auth, SUM(points) AS total FROM %splayertimes WHERE style = %d GROUP BY auth) P ON S.auth = P.auth SET S.points = P.total WHERE style = %d %s %s;", - gS_MySQLPrefix, gS_MySQLPrefix, i, i, - (sLastLogin[0] != 0) ? "WHERE" : "", sLastLogin); + FormatEx(sStyleQuery, sizeof(sStyleQuery), + "UPDATE IGNORE %sstylepoints AS S INNER JOIN (SELECT auth, SUM(points) AS total FROM %splayertimes GROUP BY auth, style) P ON S.auth = P.auth SET S.points = P.total WHERE S.style = P.style %s %s;", + gS_MySQLPrefix, gS_MySQLPrefix, + (sLastLogin[0] != 0) ? "WHERE" : "", sLastLogin); - QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); - } + QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); } } else if (gB_SQLWindowFunctions && gI_Driver == Driver_mysql) @@ -1503,8 +1492,6 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1) sTrackWhere, sLimit); // TODO: Remove/move sLimit? - for (int i = 0; i < gI_Styles; i++) - { FormatEx(sStyleQuery, sizeof(sStyleQuery), "UPDATE IGNORE %sstylepoints AS s, (\n" ... " SELECT auth, SUM(t.points2) as pp FROM (\n" @@ -1512,28 +1499,26 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1) ... " FROM %splayertimes AS p\n" ... " JOIN %sstylepoints AS s2\n" ... " ON s2.auth = p.auth %s %s\n" - ... " WHERE p.points > 0 AND p.style = %d AND p.auth IN (SELECT DISTINCT auth FROM %splayertimes WHERE style = %d %s %s %s %s)\n" - ... " ORDER BY p.points DESC %s\n" + ... " WHERE p.points > 0 AND p.auth IN (SELECT DISTINCT auth FROM %splayertimes %s %s %s %s)\n" + ... " ORDER BY p.points DESC GROUP BY style %s\n" ... " ) AS t\n" - ... " GROUP by auth\n" + ... " GROUP by auth, style\n" ... ") AS a\n" ... "SET s.points = a.pp\n" - ... "WHERE s.auth = a.auth and s.style = %d;", + ... "WHERE s.auth = a.auth and s.style = a.style;", gS_MySQLPrefix, gCV_WeightingMultiplier.FloatValue, gS_MySQLPrefix, gS_MySQLPrefix, sLastLogin[0] ? "AND" : "", sLastLogin, - i, gS_MySQLPrefix, i, + gS_MySQLPrefix, sMapWhere[0] ? "AND" : "", sMapWhere, sTrackWhere[0] ? "AND" : "", sTrackWhere, - sLimit, // TODO: Remove/move sLimit? - i); + sLimit); // TODO: Remove/move sLimit? QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); - } } else if (gB_SQLWindowFunctions) { @@ -1559,33 +1544,29 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1) (sMapWhere[0] && sTrackWhere[0]) ? "AND" : "", sTrackWhere); - for (int i = 0; i < gI_Styles; i++) - { - FormatEx(sStyleQuery, sizeof(sStyleQuery), - "UPDATE IGNORE %sstylepoints AS s\n" - ... "SET points = (\n" - ... " SELECT SUM(points2) FROM (\n" - ... " SELECT (points * POW(%f, ROW_NUMBER() OVER (ORDER BY points DESC) - 1)) AS points2\n" - ... " FROM %splayertimes\n" - ... " WHERE auth = s.auth AND points > 0 AND style = %d\n" - ... " ORDER BY points DESC %s\n" - ... " ) AS t\n" - ... ") WHERE %s %s auth IN\n" - ... " (SELECT DISTINCT auth FROM %splayertimes WHERE style = %d %s %s %s %s);", - gS_MySQLPrefix, - gCV_WeightingMultiplier.FloatValue, - gS_MySQLPrefix, - i, - sLimit, // TODO: Remove/move sLimit? - sLastLogin, sLastLogin[0] ? "AND" : "", - gS_MySQLPrefix, i, - sMapWhere[0] ? "AND" : "", - sMapWhere, - sTrackWhere[0] ? "AND" : "", - sTrackWhere); + FormatEx(sStyleQuery, sizeof(sStyleQuery), + "UPDATE IGNORE %sstylepoints AS s\n" + ... "SET points = (\n" + ... " SELECT SUM(points2) FROM (\n" + ... " SELECT (points * POW(%f, ROW_NUMBER() OVER (ORDER BY points DESC) - 1)) AS points2\n" + ... " FROM %splayertimes\n" + ... " WHERE auth = s.auth AND points > 0\n" + ... " ORDER BY points DESC GROUP BY style %s\n" + ... " ) AS t\n" + ... ") p WHERE %s %s auth IN\n" + ... " (SELECT DISTINCT auth FROM %splayertimes WHERE style = t.style %s %s %s %s);", + gS_MySQLPrefix, + gCV_WeightingMultiplier.FloatValue, + gS_MySQLPrefix, + sLimit, // TODO: Remove/move sLimit? + sLastLogin, sLastLogin[0] ? "AND" : "", + gS_MySQLPrefix, + sMapWhere[0] ? "AND" : "", + sMapWhere, + sTrackWhere[0] ? "AND" : "", + sTrackWhere); - QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); - } + QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); } else // !gB_SQLWindowFunctions && gI_Driver == Driver_mysql { From d140506194fb0762907cedee5f695ee2f2822e7d Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Mon, 11 Aug 2025 10:02:46 -0700 Subject: [PATCH 21/28] shavit-rankings.sp - remove extra } --- addons/sourcemod/scripting/shavit-rankings.sp | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/sourcemod/scripting/shavit-rankings.sp b/addons/sourcemod/scripting/shavit-rankings.sp index e7caed29..b8380c17 100644 --- a/addons/sourcemod/scripting/shavit-rankings.sp +++ b/addons/sourcemod/scripting/shavit-rankings.sp @@ -1386,7 +1386,6 @@ void UpdatePointsForSinglePlayer(int client) ); QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); - } } else // We should only be here if mysql :) { From 54ea76ecf9b100be5ddf89978fe6dd5fcae1846e Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Mon, 11 Aug 2025 18:35:22 -0700 Subject: [PATCH 22/28] shavit-rankings.sp - fix rankings by adding 'style' to the select statements --- addons/sourcemod/scripting/shavit-rankings.sp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-rankings.sp b/addons/sourcemod/scripting/shavit-rankings.sp index b8380c17..638195d9 100644 --- a/addons/sourcemod/scripting/shavit-rankings.sp +++ b/addons/sourcemod/scripting/shavit-rankings.sp @@ -1340,7 +1340,7 @@ void UpdatePointsForSinglePlayer(int client) gS_MySQLPrefix, gS_MySQLPrefix, auth, auth); FormatEx(sStyleQuery, sizeof(sStyleQuery), - "UPDATE IGNORE %sstylepoints AS S SET points = P.total (SELECT SUM(points) as total FROM %splayertimes WHERE auth = %d GROUP BY style) P WHERE auth = %d AND S.style = P.style;", + "UPDATE IGNORE %sstylepoints AS S SET points = P.total (SELECT style, SUM(points) as total FROM %splayertimes WHERE auth = %d GROUP BY style) P WHERE auth = %d AND S.style = P.style;", gS_MySQLPrefix, gS_MySQLPrefix, auth, auth); QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); @@ -1371,12 +1371,12 @@ void UpdatePointsForSinglePlayer(int client) FormatEx(sStyleQuery, sizeof(sStyleQuery), "UPDATE IGNORE %sstylepoints AS S SET points = (\n" ... " SELECT SUM(points2) FROM (\n" - ... " SELECT (points * POW(%f, ROW_NUMBER() OVER (ORDER BY points DESC) - 1)) as points2\n" + ... " SELECT style, (points * POW(%f, ROW_NUMBER() OVER (ORDER BY points DESC) - 1)) as points2\n" ... " FROM %splayertimes\n" ... " WHERE auth = %d AND points > 0 GROUP BY style\n" ... " ORDER BY points DESC %s\n" ... " ) as t\n" - ... ") P WHERE auth = %d AND S.style = P.style;", + ... ") P WHERE auth = %d AND S.style = t.style;", gS_MySQLPrefix, gCV_WeightingMultiplier.FloatValue, gS_MySQLPrefix, @@ -1438,7 +1438,7 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1) (sLastLogin[0] != 0) ? "AND " : "", sLastLogin); FormatEx(sStyleQuery, sizeof(sStyleQuery), - "UPDATE IGNORE %sstylepoints AS S SET points = P.total FROM (SELECT auth, SUM(points) AS total FROM %splayertimes GROUP BY auth, style) P WHERE S.auth = P.auth AND S.style = P.style %s %s;", + "UPDATE IGNORE %sstylepoints AS S SET points = P.total FROM (SELECT auth, style, SUM(points) AS total FROM %splayertimes GROUP BY auth, style) P WHERE S.auth = P.auth AND S.style = P.style %s %s;", gS_MySQLPrefix, gS_MySQLPrefix, (sLastLogin[0] != 0) ? "AND " : "", sLastLogin); @@ -1452,7 +1452,7 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1) (sLastLogin[0] != 0) ? "WHERE" : "", sLastLogin); FormatEx(sStyleQuery, sizeof(sStyleQuery), - "UPDATE IGNORE %sstylepoints AS S INNER JOIN (SELECT auth, SUM(points) AS total FROM %splayertimes GROUP BY auth, style) P ON S.auth = P.auth SET S.points = P.total WHERE S.style = P.style %s %s;", + "UPDATE IGNORE %sstylepoints AS S INNER JOIN (SELECT auth, style, SUM(points) AS total FROM %splayertimes GROUP BY auth, style) P ON S.auth = P.auth SET S.points = P.total WHERE S.style = P.style %s %s;", gS_MySQLPrefix, gS_MySQLPrefix, (sLastLogin[0] != 0) ? "WHERE" : "", sLastLogin); From 14c3a4a4be80a7fdebb36c63e9ffe7e17b2438b8 Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Mon, 11 Aug 2025 20:23:46 -0700 Subject: [PATCH 23/28] shavit-rankings.sp - fix query --- addons/sourcemod/scripting/shavit-rankings.sp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-rankings.sp b/addons/sourcemod/scripting/shavit-rankings.sp index 638195d9..b4d3bf77 100644 --- a/addons/sourcemod/scripting/shavit-rankings.sp +++ b/addons/sourcemod/scripting/shavit-rankings.sp @@ -1340,8 +1340,8 @@ void UpdatePointsForSinglePlayer(int client) gS_MySQLPrefix, gS_MySQLPrefix, auth, auth); FormatEx(sStyleQuery, sizeof(sStyleQuery), - "UPDATE IGNORE %sstylepoints AS S SET points = P.total (SELECT style, SUM(points) as total FROM %splayertimes WHERE auth = %d GROUP BY style) P WHERE auth = %d AND S.style = P.style;", - gS_MySQLPrefix, gS_MySQLPrefix, auth, auth); + "UPDATE IGNORE %sstylepoints AS S INNER JOIN (SELECT auth, style, SUM(points) AS total FROM %splayertimes WHERE auth = %d GROUP BY style) P ON S.auth = P.auth SET S.points = P.total WHERE S.style = P.style;", + gS_MySQLPrefix, gS_MySQLPrefix, auth); QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery); } From e7a0e66ec49b1204ab2805a491e8ea6c689799c3 Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Tue, 12 Aug 2025 07:38:40 -0700 Subject: [PATCH 24/28] shavit-chat.cfg - add style rank examples --- addons/sourcemod/configs/shavit-chat.cfg | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/addons/sourcemod/configs/shavit-chat.cfg b/addons/sourcemod/configs/shavit-chat.cfg index 99455dfc..bc23f64c 100644 --- a/addons/sourcemod/configs/shavit-chat.cfg +++ b/addons/sourcemod/configs/shavit-chat.cfg @@ -106,4 +106,20 @@ "name" "{rand}WRTOP10% {name}" "display" "WRTOP10%Top 10% of players by WRs held." } + + "11" + { + "free" "1" + "name" "{rand}[{currentstylerank}] {name}" + "message" "{default}" + "display" "[#Rank Current Style]Show your rank on your current style!" + } + + "12" + { + "free" "1" + "name" "{rand}[{style0rank}] Normal {name}" + "message" "{default}" + "display" "[#Rank Normal]Display your normal rank!" + } } From 69b13bce5a9a764ab62faeb85b6dcf10d18be3e4 Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Tue, 12 Aug 2025 09:38:15 -0700 Subject: [PATCH 25/28] shavit-rankings.sp - fix table name in pg/sqlite query --- addons/sourcemod/scripting/shavit-rankings.sp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/shavit-rankings.sp b/addons/sourcemod/scripting/shavit-rankings.sp index b4d3bf77..487ea8ca 100644 --- a/addons/sourcemod/scripting/shavit-rankings.sp +++ b/addons/sourcemod/scripting/shavit-rankings.sp @@ -422,7 +422,7 @@ public void OnClientAuthorized(int client, const char[] auth) else // postgresql & sqlite { FormatEx(sQuery, 512, - "INSERT INTO %susers (auth, style, points) VALUES (%d, %d, 0) ON CONFLICT DO NOTHING;", + "INSERT INTO %sstylepoints (auth, style, points) VALUES (%d, %d, 0) ON CONFLICT DO NOTHING;", gS_MySQLPrefix, iSteamID, i); } From dbe8e9a99f49be5094fbbd2aa52480a2cd6e76d7 Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Tue, 12 Aug 2025 09:46:36 -0700 Subject: [PATCH 26/28] shavit-chat.cfg - mentally disabled. fixed example --- addons/sourcemod/configs/shavit-chat.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sourcemod/configs/shavit-chat.cfg b/addons/sourcemod/configs/shavit-chat.cfg index bc23f64c..aeb74ad0 100644 --- a/addons/sourcemod/configs/shavit-chat.cfg +++ b/addons/sourcemod/configs/shavit-chat.cfg @@ -118,7 +118,7 @@ "12" { "free" "1" - "name" "{rand}[{style0rank}] Normal {name}" + "name" "{rand}[{style0rank} Normal] {name}" "message" "{default}" "display" "[#Rank Normal]Display your normal rank!" } From 068dcff7982dc4f9147c8aaa4373bf807667d043 Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Tue, 12 Aug 2025 09:49:33 -0700 Subject: [PATCH 27/28] shavit-chat.cfg - add new variables to the list in top comments --- addons/sourcemod/configs/shavit-chat.cfg | 2 ++ 1 file changed, 2 insertions(+) diff --git a/addons/sourcemod/configs/shavit-chat.cfg b/addons/sourcemod/configs/shavit-chat.cfg index aeb74ad0..158562bf 100644 --- a/addons/sourcemod/configs/shavit-chat.cfg +++ b/addons/sourcemod/configs/shavit-chat.cfg @@ -20,6 +20,8 @@ // {rank1} - player rank in percentage (1 decimal point) // {rank2} - player rank in percentage (2 decimal points) // {rank3} - player rank in percentage (3 decimal points) +// {styleXrank} - player rank on style X (X replaced with style ID) ie. "{style0rank}" +// {currentstylerank} - player rank on the style they are currently on, includes style name at the end ie. "#2 Normal" // {pts} - how many points a player has // {wrs} - how many wrs a player has // {wrrank} - player rank out of wrs held From 2a3907171a87541564bf8b8ca8854b8cef4c7808 Mon Sep 17 00:00:00 2001 From: mourningsickness Date: Tue, 12 Aug 2025 09:51:19 -0700 Subject: [PATCH 28/28] shavit-rankings.sp - <3 --- addons/sourcemod/scripting/shavit-rankings.sp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/shavit-rankings.sp b/addons/sourcemod/scripting/shavit-rankings.sp index 487ea8ca..2fb93319 100644 --- a/addons/sourcemod/scripting/shavit-rankings.sp +++ b/addons/sourcemod/scripting/shavit-rankings.sp @@ -1,6 +1,6 @@ /* * shavit's Timer - Rankings - * by: shavit, rtldg + * by: shavit, rtldg, olivia * * This file is part of shavit's Timer (https://github.com/shavitush/bhoptimer) *