From 4cab7f997f6adcc1267e6a29ee410fa3db40e468 Mon Sep 17 00:00:00 2001 From: shavit Date: Sat, 9 Mar 2019 16:33:39 +0200 Subject: [PATCH 01/39] Removed useless lines. --- addons/sourcemod/scripting/shavit-hud.sp | 2 -- 1 file changed, 2 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-hud.sp b/addons/sourcemod/scripting/shavit-hud.sp index 0a11240f3..509ae99ec 100644 --- a/addons/sourcemod/scripting/shavit-hud.sp +++ b/addons/sourcemod/scripting/shavit-hud.sp @@ -1095,7 +1095,6 @@ int AddHUDToBuffer_Source2013(int client, huddata_t data, char[] buffer, int max { char sTrack[32]; GetTrackName(client, data.iTrack, sTrack, 32); - Format(sTrack, 32, "%s", sTrack); AddHUDLine(buffer, maxlen, sTrack, iLines); iLines++; @@ -1206,7 +1205,6 @@ int AddHUDToBuffer_CSGO(int client, huddata_t data, char[] buffer, int maxlen) { char sTrack[32]; GetTrackName(client, data.iTrack, sTrack, 32); - Format(sTrack, 32, "%s", sTrack); AddHUDLine(buffer, maxlen, sTrack, iLines); iLines++; From 04e1a6fb644650f473e2d99613011d4652c8a35e Mon Sep 17 00:00:00 2001 From: shavit Date: Sat, 9 Mar 2019 17:21:20 +0200 Subject: [PATCH 02/39] Improved cvar enforcing for replay plugin. --- addons/sourcemod/scripting/shavit-replay.sp | 113 ++++++++++++++------ 1 file changed, 82 insertions(+), 31 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-replay.sp b/addons/sourcemod/scripting/shavit-replay.sp index 06b0ab1b1..0aac6a9f0 100644 --- a/addons/sourcemod/scripting/shavit-replay.sp +++ b/addons/sourcemod/scripting/shavit-replay.sp @@ -77,6 +77,24 @@ enum iBotShooting_Attack2 = (1 << 1) } +// custom cvar settings +char gS_ForcedCvars[][][] = +{ + { "bot_quota", "{expected_bots}" }, + { "tf_bot_quota", "{expected_bots}" }, + { "bot_stop", "1" }, + { "bot_quota_mode", "normal" }, + { "tf_bot_quota_mode", "normal" }, + { "mp_limitteams", "0" }, + { "bot_join_after_player", "0" }, + { "tf_bot_join_after_player", "0" }, + { "bot_chatter", "off" }, + { "bot_flipout", "1" }, + { "bot_zombie", "1" }, + { "mp_autoteambalance", "0" }, + { "bot_controllable", "0" } +}; + // game type EngineVersion gEV_Type = Engine_Unknown; @@ -109,7 +127,6 @@ Handle gH_OnReplayEnd = null; float gF_Tickrate = 0.0; char gS_Map[160]; int gI_ExpectedBots = 0; -ConVar bot_quota = null; centralbot_cache_t gA_CentralCache; // how do i call this @@ -213,6 +230,29 @@ public void OnPluginStart() gEV_Type = GetEngineVersion(); gF_Tickrate = (1.0 / GetTickInterval()); + FindConVar((gEV_Type != Engine_TF2)? "bot_quota":"tf_bot_quota").Flags &= ~FCVAR_NOTIFY; + FindConVar("bot_stop").Flags &= ~FCVAR_CHEAT; + + for(int i = 0; i < sizeof(gS_ForcedCvars); i++) + { + ConVar hCvar = FindConVar(gS_ForcedCvars[i][0]); + + if(hCvar != null) + { + if(StrEqual(gS_ForcedCvars[i][1], "{expected_bots}")) + { + UpdateBotQuota(0); + } + + else + { + hCvar.SetString(gS_ForcedCvars[i][1]); + } + + hCvar.AddChangeHook(OnForcedConVarChanged); + } + } + // late load for(int i = 1; i <= MaxClients; i++) { @@ -267,6 +307,42 @@ public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] n OnMapStart(); } +void UpdateBotQuota(int quota) +{ + ConVar hCvar = FindConVar("bot_quota"); + + if(hCvar == null) + { + hCvar = FindConVar("tf_bot_quota"); + } + + hCvar.IntValue = gI_ExpectedBots = quota; +} + +public void OnForcedConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue) +{ + char sName[32]; + convar.GetName(sName, 32); + + for(int i = 0; i < sizeof(gS_ForcedCvars); i++) + { + if(StrEqual(sName, gS_ForcedCvars[i][0])) + { + if(StrEqual(gS_ForcedCvars[i][1], "{expected_bots}")) + { + convar.IntValue = gI_ExpectedBots; + } + + else if(!StrEqual(newValue, gS_ForcedCvars[i][1])) + { + convar.SetString(gS_ForcedCvars[i][1]); + } + + break; + } + } +} + public void OnAdminMenuCreated(Handle topmenu) { if(gH_AdminMenu == null || (topmenu == gH_AdminMenu && gH_TimerCommands != INVALID_TOPMENUOBJECT)) @@ -447,7 +523,7 @@ public int Native_ReloadReplay(Handle handler, int numParams) if(gI_ReplayBotClient[style] == 0) { ServerCommand((gEV_Type != Engine_TF2)? "bot_add":"tf_bot_add"); - gI_ExpectedBots++; + UpdateBotQuota(gI_ExpectedBots + 1); } if(loaded && restart) @@ -670,17 +746,11 @@ public Action Cron(Handle Timer) { if(!gCV_Enabled.BoolValue) { - bot_quota.IntValue = 0; + UpdateBotQuota(0); return Plugin_Continue; } - // make sure there are enough bots - else if(bot_quota != null && bot_quota.IntValue != gI_ExpectedBots) - { - bot_quota.IntValue = gI_ExpectedBots; - } - for(int i = 0; i < gI_Styles; i++) { for(int j = 0; j < ((gCV_CentralBot.BoolValue)? TRACKS_SIZE:1); j++) @@ -798,27 +868,8 @@ public void OnMapStart() return; } - ConVar bot_controllable = FindConVar("bot_controllable"); - - if(bot_controllable != null) - { - bot_controllable.BoolValue = false; - } - - FindConVar((gEV_Type != Engine_TF2)? "bot_quota":"tf_bot_quota").Flags &= ~FCVAR_NOTIFY; - FindConVar("bot_stop").Flags &= ~FCVAR_CHEAT; - FindConVar("bot_stop").BoolValue = true; - FindConVar((gEV_Type != Engine_TF2)? "bot_quota_mode":"tf_bot_quota_mode").SetString("normal"); - FindConVar("mp_limitteams").IntValue = 0; - FindConVar((gEV_Type != Engine_TF2)? "bot_join_after_player":"tf_bot_join_after_player").BoolValue = false; - FindConVar("bot_chatter").SetString("off"); - FindConVar("bot_flipout").BoolValue = true; - FindConVar("bot_zombie").BoolValue = true; - FindConVar("mp_autoteambalance").BoolValue = false; - ServerCommand((gEV_Type != Engine_TF2)? "bot_kick":"tf_bot_kick all"); - - gI_ExpectedBots = 0; + UpdateBotQuota(0); if(!DirExists(gS_ReplayFolder)) { @@ -861,7 +912,7 @@ public void OnMapStart() if(!gCV_CentralBot.BoolValue) { ServerCommand((gEV_Type != Engine_TF2)? "bot_add":"tf_bot_add"); - gI_ExpectedBots++; + UpdateBotQuota(gI_ExpectedBots + 1); if(loaded) { @@ -876,7 +927,7 @@ public void OnMapStart() if(gCV_CentralBot.BoolValue) { - gI_ExpectedBots = 1; + UpdateBotQuota(1); ServerCommand((gEV_Type != Engine_TF2)? "bot_add":"tf_bot_add"); } From da656d0f5d4aa268d96c10e9e79657b0546d5ace Mon Sep 17 00:00:00 2001 From: shavit Date: Sat, 9 Mar 2019 17:21:34 +0200 Subject: [PATCH 03/39] Bumped version number. --- addons/sourcemod/scripting/include/shavit.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/include/shavit.inc b/addons/sourcemod/scripting/include/shavit.inc index 6a07e4408..f3bbefcab 100644 --- a/addons/sourcemod/scripting/include/shavit.inc +++ b/addons/sourcemod/scripting/include/shavit.inc @@ -23,7 +23,7 @@ #endif #define _shavit_included -#define SHAVIT_VERSION "2.4.1" +#define SHAVIT_VERSION "2.4.2" #define STYLE_LIMIT 256 #define MAX_ZONES 64 #define MAX_NAME_LENGTH_SQL 32 From 3784ab969b151f084a4651fe663b6cb8bac5b3b6 Mon Sep 17 00:00:00 2001 From: shavit Date: Sat, 23 Mar 2019 05:48:31 +0200 Subject: [PATCH 04/39] Added foreign keys (#758). --- addons/sourcemod/scripting/shavit-chat.sp | 4 +++- addons/sourcemod/scripting/shavit-wr.sp | 10 +++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-chat.sp b/addons/sourcemod/scripting/shavit-chat.sp index 7c6602a7c..06d91a18c 100644 --- a/addons/sourcemod/scripting/shavit-chat.sp +++ b/addons/sourcemod/scripting/shavit-chat.sp @@ -1329,7 +1329,9 @@ void SQL_DBConnect() bool bMySQL = StrEqual(sDriver, "mysql", false); char sQuery[512]; - FormatEx(sQuery, 512, "CREATE TABLE IF NOT EXISTS `%schat` (`auth` CHAR(32) NOT NULL, `name` INT NOT NULL DEFAULT 0, `ccname` CHAR(128) COLLATE 'utf8mb4_unicode_ci', `message` INT NOT NULL DEFAULT 0, `ccmessage` CHAR(16) COLLATE 'utf8mb4_unicode_ci', PRIMARY KEY (`auth`))%s;", gS_MySQLPrefix, (bMySQL)? " ENGINE=INNODB":""); + FormatEx(sQuery, 512, + "CREATE TABLE IF NOT EXISTS `%schat` (`auth` CHAR(32) NOT NULL, `name` INT NOT NULL DEFAULT 0, `ccname` CHAR(128) COLLATE 'utf8mb4_unicode_ci', `message` INT NOT NULL DEFAULT 0, `ccmessage` CHAR(16) COLLATE 'utf8mb4_unicode_ci', PRIMARY KEY (`auth`), CONSTRAINT `ch_auth` FOREIGN KEY (`auth`) REFERENCES `users` (`auth`) ON UPDATE CASCADE ON DELETE CASCADE)%s;", + gS_MySQLPrefix, (bMySQL)? " ENGINE=INNODB":""); gH_SQL.Query(SQL_CreateTable_Callback, sQuery, 0, DBPrio_High); } diff --git a/addons/sourcemod/scripting/shavit-wr.sp b/addons/sourcemod/scripting/shavit-wr.sp index 63cd09b4c..7508985b5 100644 --- a/addons/sourcemod/scripting/shavit-wr.sp +++ b/addons/sourcemod/scripting/shavit-wr.sp @@ -2125,16 +2125,20 @@ void SQL_DBConnect() gH_SQL.Driver.GetIdentifier(sDriver, 8); gB_MySQL = StrEqual(sDriver, "mysql", false); - char sQuery[512]; + char sQuery[1024]; if(gB_MySQL) { - FormatEx(sQuery, 512, "CREATE TABLE IF NOT EXISTS `%splayertimes` (`id` INT NOT NULL AUTO_INCREMENT, `auth` CHAR(32), `map` CHAR(128), `time` FLOAT, `jumps` INT, `style` TINYINT, `date` CHAR(16), `strafes` INT, `sync` FLOAT, `points` FLOAT NOT NULL DEFAULT 0, `track` TINYINT NOT NULL DEFAULT 0, `perfs` FLOAT DEFAULT 0, PRIMARY KEY (`id`), INDEX `map` (`map`, `style`, `track`), INDEX `auth` (`auth`, `date`, `points`), INDEX `time` (`time`)) ENGINE=INNODB;", gS_MySQLPrefix); + FormatEx(sQuery, 1024, + "CREATE TABLE IF NOT EXISTS `%splayertimes` (`id` INT NOT NULL AUTO_INCREMENT, `auth` CHAR(32), `map` CHAR(128), `time` FLOAT, `jumps` INT, `style` TINYINT, `date` CHAR(16), `strafes` INT, `sync` FLOAT, `points` FLOAT NOT NULL DEFAULT 0, `track` TINYINT NOT NULL DEFAULT 0, `perfs` FLOAT DEFAULT 0, PRIMARY KEY (`id`), INDEX `map` (`map`, `style`, `track`), INDEX `auth` (`auth`, `date`, `points`), INDEX `time` (`time`), CONSTRAINT `pt_auth` FOREIGN KEY (`auth`) REFERENCES `users` (`auth`) ON UPDATE CASCADE ON DELETE CASCADE) ENGINE=INNODB;", + gS_MySQLPrefix); } else { - FormatEx(sQuery, 512, "CREATE TABLE IF NOT EXISTS `%splayertimes` (`id` INTEGER PRIMARY KEY, `auth` CHAR(32), `map` CHAR(128), `time` FLOAT, `jumps` INT, `style` TINYINT, `date` CHAR(16), `strafes` INT, `sync` FLOAT, `points` FLOAT NOT NULL DEFAULT 0, `track` TINYINT NOT NULL DEFAULT 0, `perfs` FLOAT DEFAULT 0);", gS_MySQLPrefix); + FormatEx(sQuery, 1024, + "CREATE TABLE IF NOT EXISTS `%splayertimes` (`id` INTEGER PRIMARY KEY, `auth` CHAR(32), `map` CHAR(128), `time` FLOAT, `jumps` INT, `style` TINYINT, `date` CHAR(16), `strafes` INT, `sync` FLOAT, `points` FLOAT NOT NULL DEFAULT 0, `track` TINYINT NOT NULL DEFAULT 0, `perfs` FLOAT DEFAULT 0);", + gS_MySQLPrefix); } gH_SQL.Query(SQL_CreateTable_Callback, sQuery, 0, DBPrio_High); From 4aa6365b0132d6b9fa4f665cf467b565f7bca478 Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 24 Mar 2019 01:12:06 +0200 Subject: [PATCH 05/39] Added missing no-speed-limit text for CS:S HUD. --- addons/sourcemod/scripting/shavit-hud.sp | 8 ++++++++ addons/sourcemod/translations/shavit-hud.phrases.txt | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/addons/sourcemod/scripting/shavit-hud.sp b/addons/sourcemod/scripting/shavit-hud.sp index 8b6c605b7..bb26db657 100644 --- a/addons/sourcemod/scripting/shavit-hud.sp +++ b/addons/sourcemod/scripting/shavit-hud.sp @@ -1089,6 +1089,14 @@ int AddHUDToBuffer_Source2013(int client, huddata_t data, char[] buffer, int max AddHUDLine(buffer, maxlen, sLine, iLines); iLines++; + + if(gA_StyleSettings[data.iStyle].fVelocityLimit > 0.0 && Shavit_InsideZone(data.iTarget, Zone_NoVelLimit, -1)) + { + FormatEx(sLine, 128, "%T", "HudNoSpeedLimit", client); + + AddHUDLine(buffer, maxlen, sLine, iLines); + iLines++; + } } if(data.iTimerStatus != Timer_Stopped && data.iTrack != Track_Main && (gI_HUD2Settings[client] & HUD2_TRACK) == 0) diff --git a/addons/sourcemod/translations/shavit-hud.phrases.txt b/addons/sourcemod/translations/shavit-hud.phrases.txt index b266d17a2..cc53345f8 100644 --- a/addons/sourcemod/translations/shavit-hud.phrases.txt +++ b/addons/sourcemod/translations/shavit-hud.phrases.txt @@ -79,6 +79,10 @@ { "en" "[PRACTICE]" } + "HudNoSpeedLimit" + { + "en" "No Speed Limit" + } // ---------- Menus ---------- // "HUDMenuTitle" { From 1a5cfd6fbc8cc7f338fd067cf053791ea524688b Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 24 Mar 2019 01:18:21 +0200 Subject: [PATCH 06/39] Structified rankings. --- addons/sourcemod/scripting/shavit-rankings.sp | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-rankings.sp b/addons/sourcemod/scripting/shavit-rankings.sp index f77c6542f..f1d2ace6f 100644 --- a/addons/sourcemod/scripting/shavit-rankings.sp +++ b/addons/sourcemod/scripting/shavit-rankings.sp @@ -49,6 +49,12 @@ // uncomment when done // #define DEBUG +enum struct ranking_t +{ + int iRank; + float fPoints; +} + char gS_MySQLPrefix[32]; Database gH_SQL = null; @@ -66,8 +72,7 @@ StringMap gA_MapTiers = null; ConVar gCV_PointsPerTier = null; ConVar gCV_WeightingMultiplier = null; -int gI_Rank[MAXPLAYERS+1]; -float gF_Points[MAXPLAYERS+1]; +ranking_t gA_Rankings[MAXPLAYERS+1]; int gI_RankedPlayers = 0; Menu gH_Top100Menu = null; @@ -381,8 +386,8 @@ void RunLongFastQuery(bool &success, const char[] func, const char[] query, any public void OnClientConnected(int client) { - gI_Rank[client] = 0; - gF_Points[client] = 0.0; + gA_Rankings[client].iRank = 0; + gA_Rankings[client].fPoints = 0.0; } public void OnClientPostAdminCheck(int client) @@ -568,7 +573,7 @@ public Action Command_Rank(int client, int args) } } - if(gF_Points[target] == 0.0) + if(gA_Rankings[target].fPoints == 0.0) { Shavit_PrintToChat(client, "%T", "Unranked", client, gS_ChatStrings.sVariable2, target, gS_ChatStrings.sText); @@ -576,9 +581,9 @@ public Action Command_Rank(int client, int args) } Shavit_PrintToChat(client, "%T", "Rank", client, gS_ChatStrings.sVariable2, target, gS_ChatStrings.sText, - gS_ChatStrings.sVariable, (gI_Rank[target] > gI_RankedPlayers)? gI_RankedPlayers:gI_Rank[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, gF_Points[target], gS_ChatStrings.sText); + gS_ChatStrings.sVariable, gA_Rankings[target].fPoints, gS_ChatStrings.sText); return Plugin_Handled; } @@ -800,8 +805,8 @@ public void SQL_UpdateAllPoints_Callback(Database db, DBResultSet results, const void UpdatePlayerRank(int client, bool first) { - gI_Rank[client] = 0; - gF_Points[client] = 0.0; + gA_Rankings[client].iRank = 0; + gA_Rankings[client].fPoints = 0.0; char sAuthID[32]; @@ -846,13 +851,13 @@ public void SQL_UpdatePlayerRank_Callback(Database db, DBResultSet results, cons if(results.FetchRow()) { - gF_Points[client] = results.FetchFloat(0); - gI_Rank[client] = (gF_Points[client] > 0.0)? results.FetchInt(1):0; + gA_Rankings[client].fPoints = results.FetchFloat(0); + gA_Rankings[client].iRank = (gA_Rankings[client].fPoints > 0.0)? results.FetchInt(1):0; Call_StartForward(gH_Forwards_OnRankAssigned); Call_PushCell(client); - Call_PushCell(gI_Rank[client]); - Call_PushCell(gF_Points[client]); + Call_PushCell(gA_Rankings[client].iRank); + Call_PushCell(gA_Rankings[client].fPoints); Call_PushCell(bFirst); Call_Finish(); } @@ -976,12 +981,12 @@ public int Native_GetMapTiers(Handle handler, int numParams) public int Native_GetPoints(Handle handler, int numParams) { - return view_as(gF_Points[GetNativeCell(1)]); + return view_as(gA_Rankings[GetNativeCell(1)].fPoints); } public int Native_GetRank(Handle handler, int numParams) { - return gI_Rank[GetNativeCell(1)]; + return gA_Rankings[GetNativeCell(1)].iRank; } public int Native_GetRankedPlayers(Handle handler, int numParams) From 2799f00b310b28e09072fa0d9291abb39588c5d9 Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 24 Mar 2019 01:30:32 +0200 Subject: [PATCH 07/39] Changed chat settings to be only saved at player disconnection. (#758) Database optimization. --- addons/sourcemod/scripting/shavit-chat.sp | 47 +++++++++++++---------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-chat.sp b/addons/sourcemod/scripting/shavit-chat.sp index 06d91a18c..8ec1d0bf0 100644 --- a/addons/sourcemod/scripting/shavit-chat.sp +++ b/addons/sourcemod/scripting/shavit-chat.sp @@ -382,7 +382,7 @@ public Action Hook_SayText2(UserMsg msg_id, any msg, const int[] players, int pl char sName[MAXLENGTH_NAME]; char sCMessage[MAXLENGTH_CMESSAGE]; - if((gCV_CustomChat.IntValue > 0 && (CheckCommandAccess(client, "shavit_chat", ADMFLAG_CHAT) || gCV_CustomChat.IntValue == 2)) && gI_ChatSelection[client] == -1) + if(HasCustomChat(client) && gI_ChatSelection[client] == -1) { if(gB_NameEnabled[client]) { @@ -614,11 +614,19 @@ public void OnClientCookiesCached(int client) public void OnClientPutInServer(int client) { - gB_NameEnabled[client] = false; - strcopy(gS_CustomName[client], 128, ""); + gB_NameEnabled[client] = true; + strcopy(gS_CustomName[client], 128, "{team}{name}"); - gB_MessageEnabled[client] = false; - strcopy(gS_CustomMessage[client], 128, ""); + gB_MessageEnabled[client] = true; + strcopy(gS_CustomMessage[client], 128, "{default}"); +} + +public void OnClientDisconnect(int client) +{ + if(HasCustomChat(client)) + { + SaveToDatabase(client); + } } public void OnClientPostAdminCheck(int client) @@ -669,7 +677,7 @@ public Action Command_CCName(int client, int args) return Plugin_Handled; } - if(!(gCV_CustomChat.IntValue > 0 && (CheckCommandAccess(client, "shavit_chat", ADMFLAG_CHAT) || gCV_CustomChat.IntValue == 2))) + if(!HasCustomChat(client)) { Shavit_PrintToChat(client, "%T", "NoCommandAccess", client); @@ -694,8 +702,6 @@ public Action Command_CCName(int client, int args) gB_NameEnabled[client] = false; - SaveToDatabase(client); - return Plugin_Handled; } @@ -704,8 +710,6 @@ public Action Command_CCName(int client, int args) gB_NameEnabled[client] = true; strcopy(gS_CustomName[client], 128, sArgs); - SaveToDatabase(client); - return Plugin_Handled; } @@ -718,7 +722,7 @@ public Action Command_CCMessage(int client, int args) return Plugin_Handled; } - if(!(gCV_CustomChat.IntValue > 0 && (CheckCommandAccess(client, "shavit_chat", ADMFLAG_CHAT) || gCV_CustomChat.IntValue == 2))) + if(!HasCustomChat(client)) { Shavit_PrintToChat(client, "%T", "NoCommandAccess", client); @@ -743,8 +747,6 @@ public Action Command_CCMessage(int client, int args) gB_MessageEnabled[client] = false; - SaveToDatabase(client); - return Plugin_Handled; } @@ -753,8 +755,6 @@ public Action Command_CCMessage(int client, int args) gB_MessageEnabled[client] = true; strcopy(gS_CustomMessage[client], 16, sArgs); - SaveToDatabase(client); - return Plugin_Handled; } @@ -777,7 +777,7 @@ Action ShowChatRanksMenu(int client, int item) FormatEx(sDisplay, MAXLENGTH_DISPLAY, "%T\n ", "AutoAssign", client); menu.AddItem("-2", sDisplay, (gI_ChatSelection[client] == -2)? ITEMDRAW_DISABLED:ITEMDRAW_DEFAULT); - if(gCV_CustomChat.IntValue > 0 && (CheckCommandAccess(client, "shavit_chat", ADMFLAG_CHAT) || gCV_CustomChat.IntValue == 2)) + if(HasCustomChat(client)) { FormatEx(sDisplay, MAXLENGTH_DISPLAY, "%T\n ", "CustomChat", client); menu.AddItem("-1", sDisplay, (gI_ChatSelection[client] == -1)? ITEMDRAW_DISABLED:ITEMDRAW_DEFAULT); @@ -1058,12 +1058,15 @@ void PreviewChat(int client, int rank) EndMessage(); } -bool HasRankAccess(int client, int rank) +bool HasCustomChat(int client) { - bool bAllowCustom = gCV_CustomChat.IntValue > 0 && (CheckCommandAccess(client, "shavit_chat", ADMFLAG_CHAT) || gCV_CustomChat.IntValue == 2); + return (gCV_CustomChat.IntValue > 0 && (CheckCommandAccess(client, "shavit_chat", ADMFLAG_CHAT) || gCV_CustomChat.IntValue == 2)); +} +bool HasRankAccess(int client, int rank) +{ if(rank == -2 || - (rank == -1 && bAllowCustom)) + (rank == -1 && HasCustomChat(client))) { return true; } @@ -1378,9 +1381,11 @@ void SaveToDatabase(int client) gH_SQL.Escape(gS_CustomMessage[client], sEscapedMessage, iLength); char sQuery[512]; - FormatEx(sQuery, 512, "REPLACE INTO %schat (auth, name, ccname, message, ccmessage) VALUES ('%s', %d, '%s', %d, '%s');", gS_MySQLPrefix, sAuthID3, gB_NameEnabled[client], sEscapedName, gB_MessageEnabled[client], sEscapedMessage); + FormatEx(sQuery, 512, + "REPLACE INTO %schat (auth, name, ccname, message, ccmessage) VALUES ('%s', %d, '%s', %d, '%s');", + gS_MySQLPrefix, sAuthID3, gB_NameEnabled[client], sEscapedName, gB_MessageEnabled[client], sEscapedMessage); - gH_SQL.Query(SQL_UpdateUser_Callback, sQuery, 0, DBPrio_High); + gH_SQL.Query(SQL_UpdateUser_Callback, sQuery, 0, DBPrio_Low); } public void SQL_UpdateUser_Callback(Database db, DBResultSet results, const char[] error, any data) From 4a88a0ec8b0cda87df334c5695ea018c80cea40b Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 24 Mar 2019 01:35:05 +0200 Subject: [PATCH 08/39] Fixed chat module when running SQLite. --- addons/sourcemod/scripting/shavit-chat.sp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-chat.sp b/addons/sourcemod/scripting/shavit-chat.sp index 8ec1d0bf0..02872160c 100644 --- a/addons/sourcemod/scripting/shavit-chat.sp +++ b/addons/sourcemod/scripting/shavit-chat.sp @@ -1332,9 +1332,20 @@ void SQL_DBConnect() bool bMySQL = StrEqual(sDriver, "mysql", false); char sQuery[512]; - FormatEx(sQuery, 512, - "CREATE TABLE IF NOT EXISTS `%schat` (`auth` CHAR(32) NOT NULL, `name` INT NOT NULL DEFAULT 0, `ccname` CHAR(128) COLLATE 'utf8mb4_unicode_ci', `message` INT NOT NULL DEFAULT 0, `ccmessage` CHAR(16) COLLATE 'utf8mb4_unicode_ci', PRIMARY KEY (`auth`), CONSTRAINT `ch_auth` FOREIGN KEY (`auth`) REFERENCES `users` (`auth`) ON UPDATE CASCADE ON DELETE CASCADE)%s;", - gS_MySQLPrefix, (bMySQL)? " ENGINE=INNODB":""); + + if(bMySQL) + { + FormatEx(sQuery, 512, + "CREATE TABLE IF NOT EXISTS `%schat` (`auth` CHAR(32) NOT NULL, `name` INT NOT NULL DEFAULT 0, `ccname` CHAR(128) COLLATE 'utf8mb4_unicode_ci', `message` INT NOT NULL DEFAULT 0, `ccmessage` CHAR(16) COLLATE 'utf8mb4_unicode_ci', PRIMARY KEY (`auth`), CONSTRAINT `ch_auth` FOREIGN KEY (`auth`) REFERENCES `users` (`auth`) ON UPDATE CASCADE ON DELETE CASCADE) ENGINE=INNODB;", + gS_MySQLPrefix); + } + + else + { + FormatEx(sQuery, 512, + "CREATE TABLE IF NOT EXISTS `%schat` (`auth` CHAR(32) NOT NULL, `name` INT NOT NULL DEFAULT 0, `ccname` CHAR(128), `message` INT NOT NULL DEFAULT 0, `ccmessage` CHAR(16), PRIMARY KEY (`auth`), CONSTRAINT `ch_auth` FOREIGN KEY (`auth`) REFERENCES `users` (`auth`) ON UPDATE CASCADE ON DELETE CASCADE);", + gS_MySQLPrefix); + } gH_SQL.Query(SQL_CreateTable_Callback, sQuery, 0, DBPrio_High); } From 90227dd1e7783abe5100de075dd09db5ddfe5b78 Mon Sep 17 00:00:00 2001 From: sneak_it <> Date: Sat, 23 Mar 2019 21:52:56 -0400 Subject: [PATCH 09/39] change default zone modifier to 16 units --- addons/sourcemod/scripting/shavit-zones.sp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/shavit-zones.sp b/addons/sourcemod/scripting/shavit-zones.sp index 541adb120..adb1a3967 100644 --- a/addons/sourcemod/scripting/shavit-zones.sp +++ b/addons/sourcemod/scripting/shavit-zones.sp @@ -1437,7 +1437,7 @@ public int Select_Type_MenuHandler(Menu menu, MenuAction action, int param1, int void Reset(int client) { gI_ZoneTrack[client] = Track_Main; - gF_Modifier[client] = 10.0; + gF_Modifier[client] = 16.0; gI_MapStep[client] = 0; gI_GridSnap[client] = 16; gB_SnapToWall[client] = false; From 4efb36e5f66991ff0fb8247cd3cb621a64f2dbef Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 24 Mar 2019 22:32:52 +0200 Subject: [PATCH 10/39] Bumped version number. When I'm done with this pull request, this should have a fair amount of new features.. so I figured this would be 2.5 rather than 2.4.2 --- addons/sourcemod/scripting/include/shavit.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/include/shavit.inc b/addons/sourcemod/scripting/include/shavit.inc index f3bbefcab..118c60e96 100644 --- a/addons/sourcemod/scripting/include/shavit.inc +++ b/addons/sourcemod/scripting/include/shavit.inc @@ -23,7 +23,7 @@ #endif #define _shavit_included -#define SHAVIT_VERSION "2.4.2" +#define SHAVIT_VERSION "2.5.0" #define STYLE_LIMIT 256 #define MAX_ZONES 64 #define MAX_NAME_LENGTH_SQL 32 From 96e856fe2911d25284115879e884065c8f667bf1 Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 24 Mar 2019 22:37:00 +0200 Subject: [PATCH 11/39] When !replay fails, display menu will display at the same item. (#763) --- addons/sourcemod/scripting/shavit-misc.sp | 8 ++++---- addons/sourcemod/scripting/shavit-replay.sp | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-misc.sp b/addons/sourcemod/scripting/shavit-misc.sp index 98d3e2ead..43c890c0f 100644 --- a/addons/sourcemod/scripting/shavit-misc.sp +++ b/addons/sourcemod/scripting/shavit-misc.sp @@ -440,7 +440,7 @@ public void Shavit_OnStyleChanged(int client, int oldstyle, int newstyle, int tr if(StrContains(gS_StyleStrings[newstyle].sSpecialString, "segments") != -1) { - OpenCheckpointsMenu(client, 0); + OpenCheckpointsMenu(client); Shavit_PrintToChat(client, "%T", "MiscSegmentedCommand", client, gS_ChatStrings.sVariable, gS_ChatStrings.sText); } } @@ -1442,7 +1442,7 @@ public Action Command_Checkpoints(int client, int args) return Plugin_Handled; } - return OpenCheckpointsMenu(client, 0); + return OpenCheckpointsMenu(client); } public Action Command_Save(int client, int args) @@ -1533,7 +1533,7 @@ public Action Command_Tele(int client, int args) return Plugin_Handled; } -public Action OpenCheckpointsMenu(int client, int item) +public Action OpenCheckpointsMenu(int client) { bool bSegmented = CanSegment(client); @@ -1676,7 +1676,7 @@ public int MenuHandler_Checkpoints(Menu menu, MenuAction action, int param1, int } } - OpenCheckpointsMenu(param1, GetMenuSelectionPosition()); + OpenCheckpointsMenu(param1); } else if(action == MenuAction_DisplayItem && param2 >= 5) diff --git a/addons/sourcemod/scripting/shavit-replay.sp b/addons/sourcemod/scripting/shavit-replay.sp index 0aac6a9f0..43c69f0f6 100644 --- a/addons/sourcemod/scripting/shavit-replay.sp +++ b/addons/sourcemod/scripting/shavit-replay.sp @@ -2247,7 +2247,7 @@ public int MenuHandler_Replay(Menu menu, MenuAction action, int param1, int para return 0; } -void OpenReplaySubMenu(int client, int track) +void OpenReplaySubMenu(int client, int track, int item = 0) { gI_Track[client] = track; @@ -2311,7 +2311,7 @@ void OpenReplaySubMenu(int client, int track) } menu.ExitBackButton = true; - menu.Display(client, 60); + menu.DisplayAt(client, item, 60); } public int MenuHandler_ReplaySubmenu(Menu menu, MenuAction action, int param1, int param2) @@ -2340,7 +2340,7 @@ public int MenuHandler_ReplaySubmenu(Menu menu, MenuAction action, int param1, i { Shavit_PrintToChat(param1, "%T", "CentralReplayPlaying", param1); - OpenReplaySubMenu(param1, gI_Track[param1]); + OpenReplaySubMenu(param1, gI_Track[param1], GetMenuSelectionPosition()); } else From 79a6fef09c8c395cadd9e54f22d5462940e4bb2e Mon Sep 17 00:00:00 2001 From: shavit Date: Sun, 24 Mar 2019 23:10:00 +0200 Subject: [PATCH 12/39] Added "enabled" and "inaccessible" style settings. (#761) --- addons/sourcemod/configs/shavit-styles.cfg | 4 +++ addons/sourcemod/scripting/include/shavit.inc | 4 ++- addons/sourcemod/scripting/shavit-core.sp | 25 ++++++++++++++++++- addons/sourcemod/scripting/shavit-stats.sp | 2 +- addons/sourcemod/scripting/shavit-wr.sp | 14 +++++++++-- 5 files changed, 44 insertions(+), 5 deletions(-) diff --git a/addons/sourcemod/configs/shavit-styles.cfg b/addons/sourcemod/configs/shavit-styles.cfg index 8f322b432..9cc5d7148 100644 --- a/addons/sourcemod/configs/shavit-styles.cfg +++ b/addons/sourcemod/configs/shavit-styles.cfg @@ -7,6 +7,10 @@ { "0" { + // Accessibility + "enabled" "1" // When disabled, style will be unusable. -1 to also make the style not show in menus. + "inaccessible" "0" // This setting makes it so you can't manually switch to this style but only by functionality from timer modules. + // Strings "name" "Normal" // Style name. "shortname" "NM" // Short style name. diff --git a/addons/sourcemod/scripting/include/shavit.inc b/addons/sourcemod/scripting/include/shavit.inc index 118c60e96..752009cbe 100644 --- a/addons/sourcemod/scripting/include/shavit.inc +++ b/addons/sourcemod/scripting/include/shavit.inc @@ -157,6 +157,8 @@ enum struct stylesettings_t float fRankingMultiplier; int iSpecial; int iOrdering; + bool bInaccessible; + int iEnabled; } enum struct chatstrings_t @@ -701,7 +703,7 @@ native void Shavit_Rankings_DeleteMap(const char[] map); * * @param client Client index. * @param style Style. - * @param force Ignore style permissions. + * @param force Ignore style permissions. This being true will bypass the `inaccessible` style setting as well. * @param manual Is it a manual style change? (Was it caused by user interaction?) * @param noforward Bypasses the call to `Shavit_OnStyleChanged`. * @return False if failed due to lack of access, true otherwise. diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index 63990a3a5..ff427aacd 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -904,6 +904,14 @@ public Action Command_Style(int client, int args) { int iStyle = gI_OrderedStyles[i]; + // this logic will prevent the style from showing in !style menu if it's specifically inaccessible + // or just completely disabled + if((gA_StyleSettings[iStyle].bInaccessible && gA_StyleSettings[iStyle].iEnabled == 1) || + gA_StyleSettings[iStyle].iEnabled == -1) + { + continue; + } + char sInfo[8]; IntToString(iStyle, sInfo, 8); @@ -1210,6 +1218,11 @@ public int Native_HasStyleAccess(Handle handler, int numParams) { int style = GetNativeCell(2); + if(gA_StyleSettings[style].bInaccessible || gA_StyleSettings[style].iEnabled <= 0) + { + return false; + } + return CheckCommandAccess(GetNativeCell(1), (strlen(gS_StyleOverride[style]) > 0)? gS_StyleOverride[style]:"", gI_StyleFlag[style]); } @@ -1887,8 +1900,18 @@ bool LoadStyles() gA_StyleSettings[i].fRankingMultiplier = kv.GetFloat("rankingmultiplier", 1.00); gA_StyleSettings[i].iSpecial = kv.GetNum("special", 0); gA_StyleSettings[i].iOrdering = kv.GetNum("ordering", i); + gA_StyleSettings[i].bInaccessible = view_as(kv.GetNum("inaccessible", false)); + gA_StyleSettings[i].iEnabled = kv.GetNum("enabled", 1); + + // if this style is disabled, we will force certain settings + if(gA_StyleSettings[i].iEnabled <= 0) + { + gA_StyleSettings[i].bNoReplay = true; + gA_StyleSettings[i].fRankingMultiplier = 0.0; + gA_StyleSettings[i].bInaccessible = true; + } - if(!gB_Registered && strlen(gS_StyleStrings[i].sChangeCommand) > 0) + if(!gB_Registered && strlen(gS_StyleStrings[i].sChangeCommand) > 0 && !gA_StyleSettings[i].bInaccessible) { char sStyleCommands[32][32]; int iCommands = ExplodeString(gS_StyleStrings[i].sChangeCommand, ";", sStyleCommands, 32, 32, false); diff --git a/addons/sourcemod/scripting/shavit-stats.sp b/addons/sourcemod/scripting/shavit-stats.sp index 6311054d6..5dd914243 100644 --- a/addons/sourcemod/scripting/shavit-stats.sp +++ b/addons/sourcemod/scripting/shavit-stats.sp @@ -469,7 +469,7 @@ public void OpenStatsMenuCallback(Database db, DBResultSet results, const char[] { int iStyle = styles[i]; - if(gA_StyleSettings[iStyle].bUnranked) + if(gA_StyleSettings[iStyle].bUnranked || gA_StyleSettings[iStyle].iEnabled <= 0) { continue; } diff --git a/addons/sourcemod/scripting/shavit-wr.sp b/addons/sourcemod/scripting/shavit-wr.sp index 7508985b5..e3b8215de 100644 --- a/addons/sourcemod/scripting/shavit-wr.sp +++ b/addons/sourcemod/scripting/shavit-wr.sp @@ -752,6 +752,11 @@ void DeleteSubmenu(int client) { int iStyle = styles[i]; + if(gA_StyleSettings[iStyle].iEnabled == -1) + { + continue; + } + char sInfo[8]; IntToString(iStyle, sInfo, 8); @@ -820,6 +825,11 @@ public int MenuHandler_DeleteAll_First(Menu menu, MenuAction action, int param1, { int iStyle = styles[i]; + if(gA_StyleSettings[iStyle].iEnabled == -1) + { + continue; + } + char sStyle[64]; strcopy(sStyle, 64, gS_StyleStrings[iStyle].sStyleName); @@ -947,7 +957,7 @@ public Action Command_DeleteStyleRecords(int client, int args) { int iStyle = styles[i]; - if(gA_StyleSettings[iStyle].bUnranked) + if(gA_StyleSettings[iStyle].bUnranked || gA_StyleSettings[iStyle].iEnabled == -1) { continue; } @@ -1502,7 +1512,7 @@ Action ShowWRStyleMenu(int client, int track) { int iStyle = styles[i]; - if(gA_StyleSettings[iStyle].bUnranked) + if(gA_StyleSettings[iStyle].bUnranked || gA_StyleSettings[iStyle].iEnabled == -1) { continue; } From 5ec325aa35bc61732f3410a09f88c598a35440d0 Mon Sep 17 00:00:00 2001 From: shavit Date: Mon, 25 Mar 2019 02:19:35 +0200 Subject: [PATCH 13/39] Added checkpoint forwards (#759). --- addons/sourcemod/scripting/include/shavit.inc | 14 ++++++++ addons/sourcemod/scripting/shavit-misc.sp | 32 ++++++++++++++++--- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/addons/sourcemod/scripting/include/shavit.inc b/addons/sourcemod/scripting/include/shavit.inc index 752009cbe..f50120a33 100644 --- a/addons/sourcemod/scripting/include/shavit.inc +++ b/addons/sourcemod/scripting/include/shavit.inc @@ -497,6 +497,20 @@ forward void Shavit_OnDatabaseLoaded(); */ forward void Shavit_OnChatConfigLoaded(); +/** + * Called when a player teleports with checkpoints. + * + * @return Plugin_Continue to allow teleporting, anything else to prevent. + */ +forward Action Shavit_OnTeleport(int client); + +/** + * Called when a player teleports with checkpoints. + * + * @return Plugin_Continue to allow teleporting, anything else to prevent. + */ +forward Action Shavit_OnSave(int client); + /** * Called when a player enters a zone. * diff --git a/addons/sourcemod/scripting/shavit-misc.sp b/addons/sourcemod/scripting/shavit-misc.sp index 43c890c0f..3e6855807 100644 --- a/addons/sourcemod/scripting/shavit-misc.sp +++ b/addons/sourcemod/scripting/shavit-misc.sp @@ -150,6 +150,8 @@ ConVar gCV_MaxCP_Segmented = null; // forwards Handle gH_Forwards_OnClanTagChangePre = null; Handle gH_Forwards_OnClanTagChangePost = null; +Handle gH_Forwards_OnSave = null; +Handle gH_Forwards_OnTeleport = null; // cached cvars int gI_HumanTeam = 0; @@ -180,10 +182,6 @@ public Plugin myinfo = public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) { - // forwards - gH_Forwards_OnClanTagChangePre = CreateGlobalForward("Shavit_OnClanTagChangePre", ET_Event, Param_Cell, Param_String, Param_Cell); - gH_Forwards_OnClanTagChangePost = CreateGlobalForward("Shavit_OnClanTagChangePost", ET_Event, Param_Cell, Param_String, Param_Cell); - gB_Late = late; return APLRes_Success; @@ -191,6 +189,12 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max public void OnPluginStart() { + // forwards + gH_Forwards_OnClanTagChangePre = CreateGlobalForward("Shavit_OnClanTagChangePre", ET_Event, Param_Cell, Param_String, Param_Cell); + gH_Forwards_OnClanTagChangePost = CreateGlobalForward("Shavit_OnClanTagChangePost", ET_Event, Param_Cell, Param_String, Param_Cell); + gH_Forwards_OnSave = CreateGlobalForward("Shavit_OnSave", ET_Event, Param_Cell); + gH_Forwards_OnTeleport = CreateGlobalForward("Shavit_OnTeleport", ET_Event, Param_Cell); + // cache gEV_Type = GetEngineVersion(); @@ -1732,6 +1736,16 @@ bool SaveCheckpoint(int client, int index, bool overflow = false) return false; } + Action result = Plugin_Continue; + Call_StartForward(gH_Forwards_OnSave); + Call_PushCell(client); + Call_Finish(result); + + if(result != Plugin_Continue) + { + return false; + } + char sKey[32]; int iSerial = GetClientSerial(client); FormatEx(sKey, 32, "%d_%d", iSerial, index); @@ -1955,6 +1969,16 @@ void TeleportToCheckpoint(int client, int index, bool suppressMessage) return; } + Action result = Plugin_Continue; + Call_StartForward(gH_Forwards_OnTeleport); + Call_PushCell(client); + Call_Finish(result); + + if(result != Plugin_Continue) + { + return; + } + if(Shavit_InsideZone(client, Zone_Start, -1)) { Shavit_StopTimer(client); From 655d41ef41d6a5036e8c8a9e0870a00156706b58 Mon Sep 17 00:00:00 2001 From: shavit Date: Mon, 25 Mar 2019 02:20:29 +0200 Subject: [PATCH 14/39] Fixed bug that allowed teleporting to deleted checkpoints. --- addons/sourcemod/scripting/shavit-misc.sp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/shavit-misc.sp b/addons/sourcemod/scripting/shavit-misc.sp index 3e6855807..1410a3195 100644 --- a/addons/sourcemod/scripting/shavit-misc.sp +++ b/addons/sourcemod/scripting/shavit-misc.sp @@ -1940,7 +1940,7 @@ void TeleportToCheckpoint(int client, int index, bool suppressMessage) cp_cache_t cpcache; - if(!GetCheckpoint(client, index, cpcache)) + if(!GetCheckpoint(client, index, cpcache) || index > gA_CheckpointsCache[client].iCheckpoints) { Shavit_PrintToChat(client, "%T", "MiscCheckpointsEmpty", client, index, gS_ChatStrings.sWarning, gS_ChatStrings.sText); From 7365cbcb53a0def477f24d2927443d212a882234 Mon Sep 17 00:00:00 2001 From: shavit Date: Mon, 25 Mar 2019 02:48:50 +0200 Subject: [PATCH 15/39] Added "kzcheckpoints" mode (#759). --- addons/sourcemod/configs/shavit-styles.cfg | 1 + addons/sourcemod/scripting/include/shavit.inc | 1 + addons/sourcemod/scripting/shavit-core.sp | 1 + addons/sourcemod/scripting/shavit-misc.sp | 225 +++++++++++++++--- .../translations/shavit-misc.phrases.txt | 8 + 5 files changed, 198 insertions(+), 38 deletions(-) diff --git a/addons/sourcemod/configs/shavit-styles.cfg b/addons/sourcemod/configs/shavit-styles.cfg index 9cc5d7148..7dd613a60 100644 --- a/addons/sourcemod/configs/shavit-styles.cfg +++ b/addons/sourcemod/configs/shavit-styles.cfg @@ -45,6 +45,7 @@ "block_pleft" "0" // Block +left. 2 to stop timer. "block_pright" "0" // Block +right. 2 to stop timer. "block_pstrafe" "0" // Prevent button inconsistencies (including +pstrafe). May have false positives when players lag. Will prevent some strafe hacks too. Set this to 2 to also stop the timer. + "kzcheckpoints" "0" // KZ styled checkpoints. They reset upon timer start and you don't get reverted to a save state, and you cannot save when airborne or someone else's checkpoints. // Feature excluding "unranked" "0" // Unranked style. No ranking points and no records. diff --git a/addons/sourcemod/scripting/include/shavit.inc b/addons/sourcemod/scripting/include/shavit.inc index f50120a33..a4591562e 100644 --- a/addons/sourcemod/scripting/include/shavit.inc +++ b/addons/sourcemod/scripting/include/shavit.inc @@ -159,6 +159,7 @@ enum struct stylesettings_t int iOrdering; bool bInaccessible; int iEnabled; + bool bKZCheckpoints; } enum struct chatstrings_t diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index ff427aacd..003237fdc 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -1902,6 +1902,7 @@ bool LoadStyles() gA_StyleSettings[i].iOrdering = kv.GetNum("ordering", i); gA_StyleSettings[i].bInaccessible = view_as(kv.GetNum("inaccessible", false)); gA_StyleSettings[i].iEnabled = kv.GetNum("enabled", 1); + gA_StyleSettings[i].bKZCheckpoints = view_as(kv.GetNum("kzcheckpoints", 0)); // if this style is disabled, we will force certain settings if(gA_StyleSettings[i].iEnabled <= 0) diff --git a/addons/sourcemod/scripting/shavit-misc.sp b/addons/sourcemod/scripting/shavit-misc.sp index 1410a3195..1fa5f6885 100644 --- a/addons/sourcemod/scripting/shavit-misc.sp +++ b/addons/sourcemod/scripting/shavit-misc.sp @@ -1538,6 +1538,118 @@ public Action Command_Tele(int client, int args) } public Action OpenCheckpointsMenu(int client) +{ + if(gA_StyleSettings[gI_Style[client]].bKZCheckpoints) + { + OpenKZCPMenu(client); + } + + else + { + OpenNormalCPMenu(client); + } + + return Plugin_Handled; +} + +void OpenKZCPMenu(int client) +{ + // if we're segmenting, resort to the normal checkpoints instead + if(CanSegment(client)) + { + OpenNormalCPMenu(client); + + return; + } + + Menu menu = new Menu(MenuHandler_KZCheckpoints, MENU_ACTIONS_DEFAULT|MenuAction_DisplayItem); + menu.SetTitle("%T\n", "MiscCheckpointMenu", client); + + char sDisplay[64]; + FormatEx(sDisplay, 64, "%T", "MiscCheckpointSave", client, (gA_CheckpointsCache[client].iCheckpoints + 1)); + menu.AddItem("save", sDisplay, (gA_CheckpointsCache[client].iCheckpoints < gCV_MaxCP.IntValue)? ITEMDRAW_DEFAULT:ITEMDRAW_DISABLED); + + if(gA_CheckpointsCache[client].iCheckpoints > 0) + { + FormatEx(sDisplay, 64, "%T", "MiscCheckpointTeleport", client, gA_CheckpointsCache[client].iCurrentCheckpoint); + menu.AddItem("tele", sDisplay, ITEMDRAW_DEFAULT); + } + + else + { + FormatEx(sDisplay, 64, "%T", "MiscCheckpointTeleport", client, 1); + menu.AddItem("tele", sDisplay, ITEMDRAW_DISABLED); + } + + FormatEx(sDisplay, 64, "%T", "MiscCheckpointPrevious", client); + menu.AddItem("prev", sDisplay); + + FormatEx(sDisplay, 64, "%T", "MiscCheckpointNext", client); + menu.AddItem("next", sDisplay); + + menu.ExitButton = true; + menu.Display(client, MENU_TIME_FOREVER); +} + +public int MenuHandler_KZCheckpoints(Menu menu, MenuAction action, int param1, int param2) +{ + if(action == MenuAction_Select) + { + if(CanSegment(param1) || !gA_StyleSettings[gI_Style[param1]].bKZCheckpoints) + { + return 0; + } + + int iCurrent = gA_CheckpointsCache[param1].iCurrentCheckpoint; + int iMaxCPs = GetMaxCPs(param1); + + char sInfo[8]; + menu.GetItem(param2, sInfo, 8); + + if(StrEqual(sInfo, "save")) + { + if(gA_CheckpointsCache[param1].iCheckpoints < iMaxCPs && + SaveCheckpoint(param1, gA_CheckpointsCache[param1].iCheckpoints + 1)) + { + gA_CheckpointsCache[param1].iCurrentCheckpoint = ++gA_CheckpointsCache[param1].iCheckpoints; + } + } + + else if(StrEqual(sInfo, "tele")) + { + TeleportToCheckpoint(param1, iCurrent, true); + } + + else if(StrEqual(sInfo, "prev")) + { + if(iCurrent > 1) + { + gA_CheckpointsCache[param1].iCurrentCheckpoint--; + } + } + + else if(StrEqual(sInfo, "next")) + { + cp_cache_t cpcache; + + if(iCurrent++ < iMaxCPs && GetCheckpoint(param1, iCurrent, cpcache)) + { + gA_CheckpointsCache[param1].iCurrentCheckpoint++; + } + } + + OpenCheckpointsMenu(param1); + } + + else if(action == MenuAction_End) + { + delete menu; + } + + return 0; +} + +void OpenNormalCPMenu(int client) { bool bSegmented = CanSegment(client); @@ -1545,7 +1657,7 @@ public Action OpenCheckpointsMenu(int client) { Shavit_PrintToChat(client, "%T", "FeatureDisabled", client, gS_ChatStrings.sWarning, gS_ChatStrings.sText); - return Plugin_Handled; + return; } Menu menu = new Menu(MenuHandler_Checkpoints, MENU_ACTIONS_DEFAULT|MenuAction_DisplayItem); @@ -1600,8 +1712,6 @@ public Action OpenCheckpointsMenu(int client) menu.Pagination = MENU_NO_PAGINATION; menu.ExitButton = true; menu.Display(client, MENU_TIME_FOREVER); - - return Plugin_Handled; } public int MenuHandler_Checkpoints(Menu menu, MenuAction action, int param1, int param2) @@ -1716,6 +1826,7 @@ bool SaveCheckpoint(int client, int index, bool overflow = false) int iObserverMode = GetEntProp(client, Prop_Send, "m_iObserverMode"); int iObserverTarget = GetEntPropEnt(client, Prop_Send, "m_hObserverTarget"); + int iFlags = GetEntityFlags(client); if(IsClientObserver(client) && IsValidClient(iObserverTarget) && 3 <= iObserverMode <= 5) { @@ -1736,6 +1847,14 @@ bool SaveCheckpoint(int client, int index, bool overflow = false) return false; } + if(gA_StyleSettings[gI_Style[client]].bKZCheckpoints && + ((iFlags & FL_ONGROUND) == 0 || client != target)) + { + Shavit_PrintToChat(client, "%T", "CommandSaveCPKZInvalid", client); + + return false; + } + Action result = Plugin_Continue; Call_StartForward(gH_Forwards_OnSave); Call_PushCell(client); @@ -1797,8 +1916,6 @@ bool SaveCheckpoint(int client, int index, bool overflow = false) cpcache.fGravity = GetEntityGravity(target); cpcache.fSpeed = GetEntPropFloat(target, Prop_Send, "m_flLaggedMovementValue"); - int iFlags = GetEntityFlags(target); - if(IsFakeClient(target)) { iFlags |= FL_CLIENT; @@ -1954,6 +2071,16 @@ void TeleportToCheckpoint(int client, int index, bool suppressMessage) return; } + timer_snapshot_t snapshot; + CopyArray(cpcache.aSnapshot, snapshot, sizeof(timer_snapshot_t)); + + if(gA_StyleSettings[gI_Style[client]].bKZCheckpoints != gA_StyleSettings[snapshot.bsStyle].bKZCheckpoints) + { + Shavit_PrintToChat(client, "%T", "CommandTeleCPInvalid", client); + + return; + } + float pos[3]; CopyArray(cpcache.fPosition, pos, 3); @@ -1984,14 +2111,49 @@ void TeleportToCheckpoint(int client, int index, bool suppressMessage) Shavit_StopTimer(client); } - timer_snapshot_t snapshot; - CopyArray(cpcache.aSnapshot, snapshot, sizeof(timer_snapshot_t)); - Shavit_LoadSnapshot(client, snapshot); - Shavit_ResumeTimer(client); + MoveType mt = cpcache.iMoveType; + + if(mt == MOVETYPE_LADDER || mt == MOVETYPE_WALK) + { + SetEntityMoveType(client, mt); + } + + SetEntityFlags(client, cpcache.iFlags); + SetEntPropFloat(client, Prop_Send, "m_flLaggedMovementValue", cpcache.fSpeed); + SetEntPropEnt(client, Prop_Data, "m_hGroundEntity", cpcache.iGroundEntity); + + if(gEV_Type != Engine_TF2) + { + SetEntPropFloat(client, Prop_Send, "m_flStamina", cpcache.fStamina); + SetEntProp(client, Prop_Send, "m_bDucked", cpcache.bDucked); + SetEntProp(client, Prop_Send, "m_bDucking", cpcache.bDucking); + } + + if(gEV_Type == Engine_CSS) + { + SetEntPropFloat(client, Prop_Send, "m_flDucktime", cpcache.fDucktime); + } + + else if(gEV_Type == Engine_CSGO) + { + SetEntPropFloat(client, Prop_Send, "m_flDuckAmount", cpcache.fDucktime); + SetEntPropFloat(client, Prop_Send, "m_flDuckSpeed", cpcache.fDuckSpeed); + } float ang[3]; CopyArray(cpcache.fAngles, ang, 3); + // this is basically the same as normal checkpoints except much less data is used + if(gA_StyleSettings[gI_Style[client]].bKZCheckpoints) + { + TeleportEntity(client, pos, ang, view_as({ 0.0, 0.0, 0.0 })); + + return; + } + + Shavit_LoadSnapshot(client, snapshot); + Shavit_ResumeTimer(client); + float vel[3]; if((gI_CheckpointsSettings[client] & CP_VELOCITY) > 0 || cpcache.bSegmented) @@ -2033,36 +2195,7 @@ void TeleportToCheckpoint(int client, int index, bool suppressMessage) Shavit_SetPracticeMode(client, true, true); } - MoveType mt = cpcache.iMoveType; - - if(mt == MOVETYPE_LADDER || mt == MOVETYPE_WALK) - { - SetEntityMoveType(client, mt); - } - SetEntityGravity(client, cpcache.fGravity); - SetEntityFlags(client, cpcache.iFlags); - - SetEntPropFloat(client, Prop_Send, "m_flLaggedMovementValue", cpcache.fSpeed); - SetEntPropEnt(client, Prop_Data, "m_hGroundEntity", cpcache.iGroundEntity); - - if(gEV_Type != Engine_TF2) - { - SetEntPropFloat(client, Prop_Send, "m_flStamina", cpcache.fStamina); - SetEntProp(client, Prop_Send, "m_bDucked", cpcache.bDucked); - SetEntProp(client, Prop_Send, "m_bDucking", cpcache.bDucking); - } - - if(gEV_Type == Engine_CSS) - { - SetEntPropFloat(client, Prop_Send, "m_flDucktime", cpcache.fDucktime); - } - - else if(gEV_Type == Engine_CSGO) - { - SetEntPropFloat(client, Prop_Send, "m_flDuckAmount", cpcache.fDucktime); - SetEntPropFloat(client, Prop_Send, "m_flDuckSpeed", cpcache.fDuckSpeed); - } if(cpcache.bSegmented && gB_Replay) { @@ -2256,6 +2389,11 @@ public Action Shavit_OnStart(int client) SetEntPropString(client, Prop_Data, "m_iClassname", "player"); } + if(gA_StyleSettings[gI_Style[client]].bKZCheckpoints) + { + ResetCheckpoints(client); + } + return Plugin_Continue; } @@ -2313,6 +2451,11 @@ public void Shavit_OnWorldRecord(int client, int style, float time, int jumps, i public void Shavit_OnRestart(int client, int track) { + if(gA_StyleSettings[gI_Style[client]].bKZCheckpoints && GetClientMenu(client, null) == MenuSource_None) + { + OpenKZCPMenu(client); + } + if(!gCV_RespawnOnRestart.BoolValue) { return; @@ -2425,6 +2568,12 @@ public void Player_Spawn(Event event, const char[] name, bool dontBroadcast) } UpdateClanTag(client); + + // refreshes kz cp menu if there is nothing open + if(gA_StyleSettings[gI_Style[client]].bKZCheckpoints && GetClientMenu(client, null) == MenuSource_None) + { + OpenKZCPMenu(client); + } } if(gCV_NoBlock.BoolValue) diff --git a/addons/sourcemod/translations/shavit-misc.phrases.txt b/addons/sourcemod/translations/shavit-misc.phrases.txt index 8920cf7cc..ba998581e 100644 --- a/addons/sourcemod/translations/shavit-misc.phrases.txt +++ b/addons/sourcemod/translations/shavit-misc.phrases.txt @@ -11,6 +11,14 @@ "#format" "{1:s},{2:s},{3:s},{4:s}" "en" "You have to be {1}alive{2} or {3}spectate a player{4} to use this command." } + "CommandSaveCPKZInvalid" + { + "en" "You cannot perform this when airborne or while watching another player." + } + "CommandTeleCPInvalid" + { + "en" "You may not teleport to this checkpoint due to setting mismatch." + } "CommandNoPause" { "#format" "{1:s},{2:s}" From 6f2e5e7c4f0c1226953f80ec1f68ed3a5b0b273b Mon Sep 17 00:00:00 2001 From: shavit Date: Mon, 25 Mar 2019 08:42:12 +0200 Subject: [PATCH 16/39] Fixed rare bug with replay playback. --- addons/sourcemod/scripting/shavit-replay.sp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-replay.sp b/addons/sourcemod/scripting/shavit-replay.sp index 43c69f0f6..05ea7c32e 100644 --- a/addons/sourcemod/scripting/shavit-replay.sp +++ b/addons/sourcemod/scripting/shavit-replay.sp @@ -1719,6 +1719,7 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3 buttons &= ~IN_USE; } + bool bWalk = false; MoveType mt = MOVETYPE_NOCLIP; if(gA_FrameCache[style][track].iReplayVersion >= 0x02) @@ -1735,10 +1736,15 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3 MoveType movetype = gA_Frames[style][track].Get(gI_ReplayTick[style], 7); - if(movetype == MOVETYPE_LADDER || (movetype == MOVETYPE_WALK && (iReplayFlags & FL_ONGROUND) > 0)) + if(movetype == MOVETYPE_LADDER) { mt = movetype; } + + else if(movetype == MOVETYPE_WALK && (iReplayFlags & FL_ONGROUND) > 0) + { + bWalk = true; + } } SetEntityMoveType(client, mt); @@ -1752,7 +1758,7 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3 (GetVectorLength(vecVelocity) > 50000.0 || // bot is on ground.. if the distance between the previous position is much bigger (1.5x) than the expected according // to the bot's velocity, teleport to avoid sync issues - (mt == MOVETYPE_WALK && GetVectorDistance(vecCurrentPosition, vecPosition) > GetVectorLength(vecVelocity) / gF_Tickrate * 1.5))) + (bWalk && GetVectorDistance(vecCurrentPosition, vecPosition) > GetVectorLength(vecVelocity) / gF_Tickrate * 1.5))) { TeleportEntity(client, vecPosition, vecAngles, NULL_VECTOR); From 1d78ee7bf064d50343b7f73915196d575c4ec8fe Mon Sep 17 00:00:00 2001 From: shavit Date: Mon, 25 Mar 2019 08:57:28 +0200 Subject: [PATCH 17/39] Fixed WR count query being inaccurate (#760). --- addons/sourcemod/scripting/shavit-stats.sp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-stats.sp b/addons/sourcemod/scripting/shavit-stats.sp index 5dd914243..183181cd3 100644 --- a/addons/sourcemod/scripting/shavit-stats.sp +++ b/addons/sourcemod/scripting/shavit-stats.sp @@ -284,16 +284,22 @@ void UpdateWRs(int client) if(GetClientAuthId(client, AuthId_Steam3, sAuthID, 32)) { - char sQuery[256]; + char sQuery[512]; + // default style only if(gCV_MVPRankOnes.IntValue == 2) { - FormatEx(sQuery, 256, "SELECT COUNT(*) FROM %splayertimes a JOIN (SELECT MIN(time) time FROM %splayertimes WHERE style = 0 %sGROUP by map) b ON a.time = b.time WHERE auth = '%s';", gS_MySQLPrefix, gS_MySQLPrefix, (gCV_MVPRankOnes_Main.BoolValue)? "AND track = 0 ":"", sAuthID); + FormatEx(sQuery, 512, + "SELECT COUNT(*) FROM %splayertimes a JOIN (SELECT MIN(time) time, map FROM %splayertimes WHERE style = 0 %sGROUP by map, track) b ON a.time = b.time AND a.map = b.map AND style = 0 %sWHERE auth = '%s';", + gS_MySQLPrefix, gS_MySQLPrefix, (gCV_MVPRankOnes_Main.BoolValue)? "AND track = 0 ":"", (gCV_MVPRankOnes_Main.BoolValue)? "AND track = 0 ":"", sAuthID); } + // all styles else { - FormatEx(sQuery, 256, "SELECT COUNT(*) FROM %splayertimes a JOIN (SELECT MIN(time) time FROM %splayertimes %sGROUP by map) b ON a.time = b.time WHERE auth = '%s';", gS_MySQLPrefix, gS_MySQLPrefix, (gCV_MVPRankOnes_Main.BoolValue)? "WHERE track = 0 ":"", sAuthID); + FormatEx(sQuery, 512, + "SELECT COUNT(*) FROM %splayertimes a JOIN (SELECT MIN(time) time, map, style FROM %splayertimes %sGROUP by map, style, track) b ON a.time = b.time AND a.map = b.map AND a.style = b.style %sWHERE auth = '%s';", + gS_MySQLPrefix, gS_MySQLPrefix, (gCV_MVPRankOnes_Main.BoolValue)? "WHERE track = 0 ":"", (gCV_MVPRankOnes_Main.BoolValue)? "AND track = 0 ":"", sAuthID); } gH_SQL.Query(SQL_GetWRs_Callback, sQuery, GetClientSerial(client)); @@ -369,7 +375,7 @@ Action OpenStatsMenu(int client, const char[] authid) FormatEx(sQuery, 2048, "SELECT a.clears, b.maps, c.wrs, d.name, d.country, d.lastlogin, d.points, e.rank FROM " ... "(SELECT COUNT(*) clears FROM (SELECT id FROM %splayertimes WHERE auth = '%s' AND track = 0 GROUP BY map) s) a " ... "JOIN (SELECT COUNT(*) maps FROM (SELECT id FROM %smapzones WHERE track = 0 AND type = 0 GROUP BY map) s) b " ... - "JOIN (SELECT COUNT(*) wrs FROM %splayertimes a JOIN (SELECT MIN(time) time FROM %splayertimes WHERE style = 0 AND track = 0 GROUP by map) b ON a.time = b.time WHERE auth = '%s') c " ... + "JOIN (SELECT COUNT(*) wrs FROM %splayertimes a JOIN (SELECT MIN(time) time, map FROM %splayertimes WHERE style = 0 AND track = 0 GROUP by map, style, track) b ON a.time = b.time AND a.map = b.map AND track = 0 AND style = 0 WHERE auth = '%s') c " ... "JOIN (SELECT name, country, lastlogin, FORMAT(points, 2) points FROM %susers WHERE auth = '%s' LIMIT 1) d " ... "JOIN (SELECT FORMAT(COUNT(*), 0) rank FROM %susers WHERE points >= (SELECT points FROM %susers WHERE auth = '%s' LIMIT 1) ORDER BY points DESC) e " ... "LIMIT 1;", gS_MySQLPrefix, authid, gS_MySQLPrefix, gS_MySQLPrefix, gS_MySQLPrefix, authid, gS_MySQLPrefix, authid, gS_MySQLPrefix, gS_MySQLPrefix, authid); @@ -380,7 +386,7 @@ Action OpenStatsMenu(int client, const char[] authid) FormatEx(sQuery, 2048, "SELECT a.clears, b.maps, c.wrs, d.name, d.country, d.lastlogin FROM " ... "(SELECT COUNT(*) clears FROM (SELECT id FROM %splayertimes WHERE auth = '%s' AND track = 0 GROUP BY map) s) a " ... "JOIN (SELECT COUNT(*) maps FROM (SELECT id FROM %smapzones WHERE track = 0 AND type = 0 GROUP BY map) s) b " ... - "JOIN (SELECT COUNT(*) wrs FROM %splayertimes a JOIN (SELECT MIN(time) time FROM %splayertimes WHERE style = 0 AND track = 0 GROUP by map) b ON a.time = b.time WHERE auth = '%s') c " ... + "JOIN (SELECT COUNT(*) wrs FROM %splayertimes a JOIN (SELECT MIN(time) time, map FROM %splayertimes WHERE style = 0 AND track = 0 GROUP by map, style, track) b ON a.time = b.time AND a.map = b.map AND track = 0 AND style = 0 WHERE auth = '%s') c " ... "JOIN (SELECT name, country, lastlogin FROM %susers WHERE auth = '%s' LIMIT 1) d " ... "LIMIT 1;", gS_MySQLPrefix, authid, gS_MySQLPrefix, gS_MySQLPrefix, gS_MySQLPrefix, authid, gS_MySQLPrefix, authid); } From 463b8a857b1437db00d80a173a0934594c52636f Mon Sep 17 00:00:00 2001 From: shavit Date: Mon, 25 Mar 2019 09:33:34 +0200 Subject: [PATCH 18/39] Major optimizations to database structure. * in table `playertimes` add `time` to the `map` index - it should look like this: ```sql INDEX `map` (`map`, `style`, `track`, `time`) ``` * in all tables, change all CHAR(x) to VARCHAR(x). the following are the changes: - `chat.auth VARCHAR(32)` - `chat.ccname VARCHAR(128)` - `chat.ccmessage VARCHAR(16)` - `users.auth VARCHAR(32)` - `users.country VARCHAR(32)` - `users.ip VARCHAR(64)` - `maptiers.map VARCHAR(128)` - `playertimes.auth VARCHAR(32)` - `playertimes.map VARCHAR(128)` - `playertimes.date VARCHAR(16)` - `mapzones.map VARCHAR(128)` --- addons/sourcemod/scripting/shavit-chat.sp | 4 ++-- addons/sourcemod/scripting/shavit-core.sp | 4 ++-- addons/sourcemod/scripting/shavit-rankings.sp | 6 +++--- addons/sourcemod/scripting/shavit-wr.sp | 6 +++--- addons/sourcemod/scripting/shavit-zones.sp | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-chat.sp b/addons/sourcemod/scripting/shavit-chat.sp index 02872160c..6b32a1fa5 100644 --- a/addons/sourcemod/scripting/shavit-chat.sp +++ b/addons/sourcemod/scripting/shavit-chat.sp @@ -1336,14 +1336,14 @@ void SQL_DBConnect() if(bMySQL) { FormatEx(sQuery, 512, - "CREATE TABLE IF NOT EXISTS `%schat` (`auth` CHAR(32) NOT NULL, `name` INT NOT NULL DEFAULT 0, `ccname` CHAR(128) COLLATE 'utf8mb4_unicode_ci', `message` INT NOT NULL DEFAULT 0, `ccmessage` CHAR(16) COLLATE 'utf8mb4_unicode_ci', PRIMARY KEY (`auth`), CONSTRAINT `ch_auth` FOREIGN KEY (`auth`) REFERENCES `users` (`auth`) ON UPDATE CASCADE ON DELETE CASCADE) ENGINE=INNODB;", + "CREATE TABLE IF NOT EXISTS `%schat` (`auth` VARCHAR(32) NOT NULL, `name` INT NOT NULL DEFAULT 0, `ccname` VARCHAR(128) COLLATE 'utf8mb4_unicode_ci', `message` INT NOT NULL DEFAULT 0, `ccmessage` VARCHAR(16) COLLATE 'utf8mb4_unicode_ci', PRIMARY KEY (`auth`), CONSTRAINT `ch_auth` FOREIGN KEY (`auth`) REFERENCES `users` (`auth`) ON UPDATE CASCADE ON DELETE CASCADE) ENGINE=INNODB;", gS_MySQLPrefix); } else { FormatEx(sQuery, 512, - "CREATE TABLE IF NOT EXISTS `%schat` (`auth` CHAR(32) NOT NULL, `name` INT NOT NULL DEFAULT 0, `ccname` CHAR(128), `message` INT NOT NULL DEFAULT 0, `ccmessage` CHAR(16), PRIMARY KEY (`auth`), CONSTRAINT `ch_auth` FOREIGN KEY (`auth`) REFERENCES `users` (`auth`) ON UPDATE CASCADE ON DELETE CASCADE);", + "CREATE TABLE IF NOT EXISTS `%schat` (`auth` VARCHAR(32) NOT NULL, `name` INT NOT NULL DEFAULT 0, `ccname` VARCHAR(128), `message` INT NOT NULL DEFAULT 0, `ccmessage` VARCHAR(16), PRIMARY KEY (`auth`), CONSTRAINT `ch_auth` FOREIGN KEY (`auth`) REFERENCES `users` (`auth`) ON UPDATE CASCADE ON DELETE CASCADE);", gS_MySQLPrefix); } diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index 003237fdc..b16667358 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -2123,12 +2123,12 @@ void SQL_DBConnect() if(gB_MySQL) { - FormatEx(sQuery, 512, "CREATE TABLE IF NOT EXISTS `%susers` (`auth` CHAR(32) NOT NULL, `name` VARCHAR(32) COLLATE 'utf8mb4_general_ci', `country` CHAR(32), `ip` CHAR(64), `lastlogin` INT NOT NULL DEFAULT -1, `points` FLOAT NOT NULL DEFAULT 0, PRIMARY KEY (`auth`), INDEX `points` (`points`)) ENGINE=INNODB;", gS_MySQLPrefix); + FormatEx(sQuery, 512, "CREATE TABLE IF NOT EXISTS `%susers` (`auth` VARCHAR(32) NOT NULL, `name` VARCHAR(32) COLLATE 'utf8mb4_general_ci', `country` VARCHAR(32), `ip` VARCHAR(64), `lastlogin` INT NOT NULL DEFAULT -1, `points` FLOAT NOT NULL DEFAULT 0, PRIMARY KEY (`auth`), INDEX `points` (`points`)) ENGINE=INNODB;", gS_MySQLPrefix); } else { - FormatEx(sQuery, 512, "CREATE TABLE IF NOT EXISTS `%susers` (`auth` CHAR(32) NOT NULL PRIMARY KEY, `name` VARCHAR(32), `country` CHAR(32), `ip` CHAR(64), `lastlogin` INTEGER NOT NULL DEFAULT -1, `points` FLOAT NOT NULL DEFAULT 0);", gS_MySQLPrefix); + FormatEx(sQuery, 512, "CREATE TABLE IF NOT EXISTS `%susers` (`auth` VARCHAR(32) NOT NULL PRIMARY KEY, `name` VARCHAR(32), `country` VARCHAR(32), `ip` VARCHAR(64), `lastlogin` INTEGER NOT NULL DEFAULT -1, `points` FLOAT NOT NULL DEFAULT 0);", gS_MySQLPrefix); } // CREATE TABLE IF NOT EXISTS diff --git a/addons/sourcemod/scripting/shavit-rankings.sp b/addons/sourcemod/scripting/shavit-rankings.sp index f1d2ace6f..fa37d905f 100644 --- a/addons/sourcemod/scripting/shavit-rankings.sp +++ b/addons/sourcemod/scripting/shavit-rankings.sp @@ -277,7 +277,7 @@ void SQL_DBConnect() } char sQuery[256]; - FormatEx(sQuery, 256, "CREATE TABLE IF NOT EXISTS `%smaptiers` (`map` CHAR(128), `tier` INT NOT NULL DEFAULT 1, PRIMARY KEY (`map`)) ENGINE=INNODB;", gS_MySQLPrefix); + FormatEx(sQuery, 256, "CREATE TABLE IF NOT EXISTS `%smaptiers` (`map` VARCHAR(128), `tier` INT NOT NULL DEFAULT 1, PRIMARY KEY (`map`)) ENGINE=INNODB;", gS_MySQLPrefix); gH_SQL.Query(SQL_CreateTable_Callback, sQuery, 0); } @@ -310,7 +310,7 @@ public void SQL_CreateTable_Callback(Database db, DBResultSet results, const cha bool bSuccess = true; RunLongFastQuery(bSuccess, "CREATE GetWeightedPoints", - "CREATE FUNCTION GetWeightedPoints(authid CHAR(32)) " ... + "CREATE FUNCTION GetWeightedPoints(authid VARCHAR(32)) " ... "RETURNS FLOAT " ... "READS SQL DATA " ... "BEGIN " ... @@ -334,7 +334,7 @@ public void SQL_CreateTable_Callback(Database db, DBResultSet results, const cha "END;;", gS_MySQLPrefix, gCV_WeightingMultiplier.FloatValue); RunLongFastQuery(bSuccess, "CREATE GetRecordPoints", - "CREATE FUNCTION GetRecordPoints(rstyle INT, rtrack INT, rtime FLOAT, rmap CHAR(128), pointspertier FLOAT, stylemultiplier FLOAT) " ... + "CREATE FUNCTION GetRecordPoints(rstyle INT, rtrack INT, rtime FLOAT, rmap VARCHAR(128), pointspertier FLOAT, stylemultiplier FLOAT) " ... "RETURNS FLOAT " ... "READS SQL DATA " ... "BEGIN " ... diff --git a/addons/sourcemod/scripting/shavit-wr.sp b/addons/sourcemod/scripting/shavit-wr.sp index e3b8215de..efee41a49 100644 --- a/addons/sourcemod/scripting/shavit-wr.sp +++ b/addons/sourcemod/scripting/shavit-wr.sp @@ -2140,14 +2140,14 @@ void SQL_DBConnect() if(gB_MySQL) { FormatEx(sQuery, 1024, - "CREATE TABLE IF NOT EXISTS `%splayertimes` (`id` INT NOT NULL AUTO_INCREMENT, `auth` CHAR(32), `map` CHAR(128), `time` FLOAT, `jumps` INT, `style` TINYINT, `date` CHAR(16), `strafes` INT, `sync` FLOAT, `points` FLOAT NOT NULL DEFAULT 0, `track` TINYINT NOT NULL DEFAULT 0, `perfs` FLOAT DEFAULT 0, PRIMARY KEY (`id`), INDEX `map` (`map`, `style`, `track`), INDEX `auth` (`auth`, `date`, `points`), INDEX `time` (`time`), CONSTRAINT `pt_auth` FOREIGN KEY (`auth`) REFERENCES `users` (`auth`) ON UPDATE CASCADE ON DELETE CASCADE) ENGINE=INNODB;", + "CREATE TABLE IF NOT EXISTS `%splayertimes` (`id` INT NOT NULL AUTO_INCREMENT, `auth` VARCHAR(32), `map` VARCHAR(128), `time` FLOAT, `jumps` INT, `style` TINYINT, `date` VARCHAR(16), `strafes` INT, `sync` FLOAT, `points` FLOAT NOT NULL DEFAULT 0, `track` TINYINT NOT NULL DEFAULT 0, `perfs` FLOAT DEFAULT 0, PRIMARY KEY (`id`), INDEX `map` (`map`, `style`, `track`, `time`), INDEX `auth` (`auth`, `date`, `points`), INDEX `time` (`time`), CONSTRAINT `pt_auth` FOREIGN KEY (`auth`) REFERENCES `users` (`auth`) ON UPDATE CASCADE ON DELETE CASCADE) ENGINE=INNODB;", gS_MySQLPrefix); } else { FormatEx(sQuery, 1024, - "CREATE TABLE IF NOT EXISTS `%splayertimes` (`id` INTEGER PRIMARY KEY, `auth` CHAR(32), `map` CHAR(128), `time` FLOAT, `jumps` INT, `style` TINYINT, `date` CHAR(16), `strafes` INT, `sync` FLOAT, `points` FLOAT NOT NULL DEFAULT 0, `track` TINYINT NOT NULL DEFAULT 0, `perfs` FLOAT DEFAULT 0);", + "CREATE TABLE IF NOT EXISTS `%splayertimes` (`id` INTEGER PRIMARY KEY, `auth` VARCHAR(32), `map` VARCHAR(128), `time` FLOAT, `jumps` INT, `style` TINYINT, `date` VARCHAR(16), `strafes` INT, `sync` FLOAT, `points` FLOAT NOT NULL DEFAULT 0, `track` TINYINT NOT NULL DEFAULT 0, `perfs` FLOAT DEFAULT 0);", gS_MySQLPrefix); } @@ -2179,7 +2179,7 @@ public void SQL_CreateTable_Callback(Database db, DBResultSet results, const cha if(gB_MySQL) // this isn't possible in sqlite { - FormatEx(sQuery, 64, "ALTER TABLE %splayertimes MODIFY date CHAR(16);", gS_MySQLPrefix); + FormatEx(sQuery, 64, "ALTER TABLE %splayertimes MODIFY date VARCHAR(16);", gS_MySQLPrefix); gH_SQL.Query(SQL_AlterTable2_Callback, sQuery); } diff --git a/addons/sourcemod/scripting/shavit-zones.sp b/addons/sourcemod/scripting/shavit-zones.sp index adb1a3967..7b582d383 100644 --- a/addons/sourcemod/scripting/shavit-zones.sp +++ b/addons/sourcemod/scripting/shavit-zones.sp @@ -2312,7 +2312,7 @@ void SQL_DBConnect() gB_MySQL = StrEqual(sDriver, "mysql", false); char sQuery[1024]; - FormatEx(sQuery, 1024, "CREATE TABLE IF NOT EXISTS `%smapzones` (`id` INT AUTO_INCREMENT, `map` CHAR(128), `type` INT, `corner1_x` FLOAT, `corner1_y` FLOAT, `corner1_z` FLOAT, `corner2_x` FLOAT, `corner2_y` FLOAT, `corner2_z` FLOAT, `destination_x` FLOAT NOT NULL DEFAULT 0, `destination_y` FLOAT NOT NULL DEFAULT 0, `destination_z` FLOAT NOT NULL DEFAULT 0, `track` INT NOT NULL DEFAULT 0, PRIMARY KEY (`id`))%s;", gS_MySQLPrefix, (gB_MySQL)? " ENGINE=INNODB":""); + FormatEx(sQuery, 1024, "CREATE TABLE IF NOT EXISTS `%smapzones` (`id` INT AUTO_INCREMENT, `map` VARCHAR(128), `type` INT, `corner1_x` FLOAT, `corner1_y` FLOAT, `corner1_z` FLOAT, `corner2_x` FLOAT, `corner2_y` FLOAT, `corner2_z` FLOAT, `destination_x` FLOAT NOT NULL DEFAULT 0, `destination_y` FLOAT NOT NULL DEFAULT 0, `destination_z` FLOAT NOT NULL DEFAULT 0, `track` INT NOT NULL DEFAULT 0, PRIMARY KEY (`id`))%s;", gS_MySQLPrefix, (gB_MySQL)? " ENGINE=INNODB":""); gH_SQL.Query(SQL_CreateTable_Callback, sQuery); } From b1106d7c972670fff167a938ec44ba35a98a0ccb Mon Sep 17 00:00:00 2001 From: shavit Date: Mon, 25 Mar 2019 09:48:03 +0200 Subject: [PATCH 19/39] Optimized GetWeightedPoints to only update users with records. (#758) --- 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 fa37d905f..ed2442d79 100644 --- a/addons/sourcemod/scripting/shavit-rankings.sp +++ b/addons/sourcemod/scripting/shavit-rankings.sp @@ -787,8 +787,8 @@ void UpdateAllPoints() #endif char sQuery[128]; - FormatEx(sQuery, 128, "UPDATE %susers SET points = GetWeightedPoints(auth);", - gS_MySQLPrefix); + FormatEx(sQuery, 128, "UPDATE %susers SET points = GetWeightedPoints(auth) WHERE auth IN (SELECT auth FROM %splayertimes GROUP BY auth);", + gS_MySQLPrefix, gS_MySQLPrefix); gH_SQL.Query(SQL_UpdateAllPoints_Callback, sQuery); } From bbccdcf28a115f076bdaf191bd37604419a3a724 Mon Sep 17 00:00:00 2001 From: shavit Date: Mon, 25 Mar 2019 10:18:44 +0200 Subject: [PATCH 20/39] Removed ancient table migration code (#758). Should speed up initial load after map change by a lot! I believe this is now useless. --- addons/sourcemod/scripting/shavit-core.sp | 53 +-------- addons/sourcemod/scripting/shavit-wr.sp | 130 +-------------------- addons/sourcemod/scripting/shavit-zones.sp | 80 +------------ 3 files changed, 5 insertions(+), 258 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index b16667358..eeb3f64fd 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -2144,13 +2144,6 @@ public void SQL_CreateTable_Callback(Database db, DBResultSet results, const cha return; } - char sQuery[192]; - FormatEx(sQuery, 192, "SELECT lastlogin FROM %susers LIMIT 1;", gS_MySQLPrefix); - gH_SQL.Query(SQL_TableMigration1_Callback, sQuery, 0, DBPrio_High); - - FormatEx(sQuery, 192, "SELECT points FROM %susers LIMIT 1;", gS_MySQLPrefix); - gH_SQL.Query(SQL_TableMigration2_Callback, sQuery, 0, DBPrio_High); - char sTables[][] = { "maptiers", @@ -2163,58 +2156,18 @@ public void SQL_CreateTable_Callback(Database db, DBResultSet results, const cha DataPack dp = new DataPack(); dp.WriteString(sTables[i]); + char sQuery[192]; FormatEx(sQuery, 192, "SELECT map FROM %s%s WHERE map LIKE 'workshop%%' GROUP BY map;", gS_MySQLPrefix, sTables[i]); - gH_SQL.Query(SQL_TableMigration3_Callback, sQuery, dp, DBPrio_Low); + gH_SQL.Query(SQL_TableMigration_Callback, sQuery, dp, DBPrio_High); } Call_StartForward(gH_Forwards_OnDatabaseLoaded); Call_Finish(); } -public void SQL_TableMigration1_Callback(Database db, DBResultSet results, const char[] error, any data) -{ - if(results == null) - { - char sQuery[128]; - FormatEx(sQuery, 128, "ALTER TABLE `%susers` ADD %s;", gS_MySQLPrefix, (gB_MySQL)? "(`lastlogin` INT NOT NULL DEFAULT -1)":"COLUMN `lastlogin` INTEGER NOT NULL DEFAULT -1"); - gH_SQL.Query(SQL_AlterTable1_Callback, sQuery); - } -} - -public void SQL_AlterTable1_Callback(Database db, DBResultSet results, const char[] error, any data) -{ - if(results == null) - { - LogError("Timer error! Table alteration 1 (core) failed. Reason: %s", error); - - return; - } -} - -public void SQL_TableMigration2_Callback(Database db, DBResultSet results, const char[] error, any data) -{ - if(results == null) - { - char sQuery[128]; - FormatEx(sQuery, 128, "ALTER TABLE `%susers` ADD %s;", gS_MySQLPrefix, (gB_MySQL)? "(`points` FLOAT NOT NULL DEFAULT 0)":"COLUMN `points` FLOAT NOT NULL DEFAULT 0"); - gH_SQL.Query(SQL_AlterTable2_Callback, sQuery); - } -} - -public void SQL_AlterTable2_Callback(Database db, DBResultSet results, const char[] error, any data) -{ - if(results == null) - { - LogError("Timer error! Table alteration 2 (core) failed. Reason: %s", error); - - return; - } -} - -public void SQL_TableMigration3_Callback(Database db, DBResultSet results, const char[] error, DataPack data) +public void SQL_TableMigration_Callback(Database db, DBResultSet results, const char[] error, DataPack data) { char sTable[16]; - data.Reset(); data.ReadString(sTable, 16); delete data; diff --git a/addons/sourcemod/scripting/shavit-wr.sp b/addons/sourcemod/scripting/shavit-wr.sp index efee41a49..5e6734d3b 100644 --- a/addons/sourcemod/scripting/shavit-wr.sp +++ b/addons/sourcemod/scripting/shavit-wr.sp @@ -2173,136 +2173,8 @@ public void SQL_CreateTable_Callback(Database db, DBResultSet results, const cha gB_Late = false; } - char sQuery[64]; - FormatEx(sQuery, 64, "SELECT strafes FROM %splayertimes LIMIT 1;", gS_MySQLPrefix); - gH_SQL.Query(SQL_TableMigration1_Callback, sQuery); - - if(gB_MySQL) // this isn't possible in sqlite - { - FormatEx(sQuery, 64, "ALTER TABLE %splayertimes MODIFY date VARCHAR(16);", gS_MySQLPrefix); - gH_SQL.Query(SQL_AlterTable2_Callback, sQuery); - } - - FormatEx(sQuery, 64, "SELECT points FROM %splayertimes LIMIT 1;", gS_MySQLPrefix); - gH_SQL.Query(SQL_TableMigration3_Callback, sQuery); - - FormatEx(sQuery, 64, "SELECT track FROM %splayertimes LIMIT 1;", gS_MySQLPrefix); - gH_SQL.Query(SQL_TableMigration4_Callback, sQuery); - - FormatEx(sQuery, 64, "SELECT perfs FROM %splayertimes LIMIT 1;", gS_MySQLPrefix); - gH_SQL.Query(SQL_TableMigration5_Callback, sQuery, 0, DBPrio_Low); -} - -public void SQL_TableMigration1_Callback(Database db, DBResultSet results, const char[] error, any data) -{ - if(results == null) - { - char sQuery[256]; - - if(gB_MySQL) - { - FormatEx(sQuery, 256, "ALTER TABLE `%splayertimes` ADD (`strafes` INT NOT NULL DEFAULT 0, `sync` FLOAT NOT NULL DEFAULT 0);", gS_MySQLPrefix); - gH_SQL.Query(SQL_AlterTable1_Callback, sQuery); - } - - else - { - FormatEx(sQuery, 256, "ALTER TABLE `%splayertimes` ADD COLUMN `strafes` INT NOT NULL DEFAULT 0;", gS_MySQLPrefix); - gH_SQL.Query(SQL_AlterTable1_Callback, sQuery); - - FormatEx(sQuery, 256, "ALTER TABLE `%splayertimes` ADD COLUMN `sync` FLOAT NOT NULL DEFAULT 0;", gS_MySQLPrefix); - gH_SQL.Query(SQL_AlterTable1_Callback, sQuery); - } - } -} - -public void SQL_AlterTable1_Callback(Database db, DBResultSet results, const char[] error, any data) -{ - if(results == null) - { - LogError("Timer (WR module) error! Times' table migration (1) failed. Reason: %s", error); - } -} - -public void SQL_AlterTable2_Callback(Database db, DBResultSet results, const char[] error, any data) -{ - if(results == null) - { - LogError("Timer (WR module) error! Times' table migration (2) failed. Reason: %s", error); - } -} - -public void SQL_TableMigration3_Callback(Database db, DBResultSet results, const char[] error, any data) -{ - if(results == null) - { - char sQuery[256]; - FormatEx(sQuery, 256, "ALTER TABLE `%splayertimes` ADD %s;", gS_MySQLPrefix, (gB_MySQL)? "(`points` FLOAT NOT NULL DEFAULT 0)":"COLUMN `points` FLOAT NOT NULL DEFAULT 0"); - gH_SQL.Query(SQL_AlterTable3_Callback, sQuery); - } -} - -public void SQL_AlterTable3_Callback(Database db, DBResultSet results, const char[] error, any data) -{ - if(results == null) - { - LogError("Timer (WR module) error! Times' table migration (3) failed. Reason: %s", error); - } -} - -public void SQL_TableMigration4_Callback(Database db, DBResultSet results, const char[] error, any data) -{ - if(results == null) - { - char sQuery[256]; - FormatEx(sQuery, 256, "ALTER TABLE `%splayertimes` ADD %s;", gS_MySQLPrefix, (gB_MySQL)? "(`track` INT NOT NULL DEFAULT 0)":"COLUMN `track` INT NOT NULL DEFAULT 0"); - gH_SQL.Query(SQL_AlterTable4_Callback, sQuery); - } -} - -public void SQL_AlterTable4_Callback(Database db, DBResultSet results, const char[] error, any data) -{ - if(results == null) - { - LogError("Timer (WR module) error! Times' table migration (4) failed. Reason: %s", error); - } -} - -public void SQL_TableMigration5_Callback(Database db, DBResultSet results, const char[] error, any data) -{ - if(results == null) - { - char sQuery[256]; - - if(gB_MySQL) - { - FormatEx(sQuery, 256, "ALTER TABLE `%splayertimes` ADD (`perfs` FLOAT DEFAULT 0);", gS_MySQLPrefix); - } - - else - { - FormatEx(sQuery, 256, "ALTER TABLE `%splayertimes` ADD COLUMN `perfs` FLOAT DEFAULT 0;", gS_MySQLPrefix); - } - - gH_SQL.Query(SQL_AlterTable5_Callback, sQuery); - - return; - } - - gB_Connected = true; - OnMapStart(); -} - -public void SQL_AlterTable5_Callback(Database db, DBResultSet results, const char[] error, any data) -{ - if(results == null) - { - LogError("Timer (WR module) error! Times' table migration (5) failed. Reason: %s", error); - - return; - } - gB_Connected = true; + OnMapStart(); } diff --git a/addons/sourcemod/scripting/shavit-zones.sp b/addons/sourcemod/scripting/shavit-zones.sp index 7b582d383..fd6b8fc95 100644 --- a/addons/sourcemod/scripting/shavit-zones.sp +++ b/addons/sourcemod/scripting/shavit-zones.sp @@ -2327,86 +2327,8 @@ public void SQL_CreateTable_Callback(Database db, DBResultSet results, const cha return; } - char sQuery[64]; - FormatEx(sQuery, 64, "SELECT destination_x FROM %smapzones LIMIT 1;", gS_MySQLPrefix); - gH_SQL.Query(SQL_TableMigration1_Callback, sQuery); - - FormatEx(sQuery, 64, "SELECT track FROM %smapzones LIMIT 1;", gS_MySQLPrefix); - gH_SQL.Query(SQL_TableMigration2_Callback, sQuery, 0, DBPrio_Low); -} - -public void SQL_TableMigration1_Callback(Database db, DBResultSet results, const char[] error, any data) -{ - if(results == null) - { - char sQuery[256]; - - if(gB_MySQL) - { - FormatEx(sQuery, 256, "ALTER TABLE `%smapzones` ADD (`destination_x` FLOAT NOT NULL DEFAULT 0, `destination_y` FLOAT NOT NULL DEFAULT 0, `destination_z` FLOAT NOT NULL DEFAULT 0);", gS_MySQLPrefix); - gH_SQL.Query(SQL_AlterTable1_Callback, sQuery); - } - - else - { - char sAxis[4]; - strcopy(sAxis, 4, "xyz"); - - for(int i = 0; i < 3; i++) - { - FormatEx(sQuery, 256, "ALTER TABLE `%smapzones` ADD COLUMN `destination_%c` FLOAT NOT NULL DEFAULT 0;", gS_MySQLPrefix, sAxis[i]); - gH_SQL.Query(SQL_AlterTable1_Callback, sQuery); - } - } - } -} - -public void SQL_AlterTable1_Callback(Database db, DBResultSet results, const char[] error, any data) -{ - if(results == null) - { - LogError("Timer (zones module) error! Map zones' table migration (1) failed. Reason: %s", error); - - return; - } -} - -public void SQL_TableMigration2_Callback(Database db, DBResultSet results, const char[] error, any data) -{ - if(results == null) - { - char sQuery[256]; - - if(gB_MySQL) - { - FormatEx(sQuery, 256, "ALTER TABLE `%smapzones` ADD (`track` INT NOT NULL DEFAULT 0);", gS_MySQLPrefix); - } - - else - { - FormatEx(sQuery, 256, "ALTER TABLE `%smapzones` ADD COLUMN `track` INTEGER NOT NULL DEFAULT 0;", gS_MySQLPrefix); - } - - gH_SQL.Query(SQL_AlterTable2_Callback, sQuery); - - return; - } - - gB_Connected = true; - OnMapStart(); -} - - -public void SQL_AlterTable2_Callback(Database db, DBResultSet results, const char[] error, any data) -{ - if(results == null) - { - LogError("Timer (zones module) error! Map zones' table migration (2) failed. Reason: %s", error); - - return; - } - gB_Connected = true; + OnMapStart(); } From 73742083fbc01dea7d67de0c72f4866e24afb6f4 Mon Sep 17 00:00:00 2001 From: shavit Date: Mon, 25 Mar 2019 10:20:13 +0200 Subject: [PATCH 21/39] Fixed bug where chat plugin would query for bots (#758). --- addons/sourcemod/scripting/shavit-chat.sp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/addons/sourcemod/scripting/shavit-chat.sp b/addons/sourcemod/scripting/shavit-chat.sp index 6b32a1fa5..e8a354f46 100644 --- a/addons/sourcemod/scripting/shavit-chat.sp +++ b/addons/sourcemod/scripting/shavit-chat.sp @@ -1411,6 +1411,11 @@ public void SQL_UpdateUser_Callback(Database db, DBResultSet results, const char void LoadFromDatabase(int client) { + if(IsFakeClient(client)) + { + return; + } + char sAuthID3[32]; if(!GetClientAuthId(client, AuthId_Steam3, sAuthID3, 32)) From 937491d4ee6df5aeceb799fa8e024c06f58af80e Mon Sep 17 00:00:00 2001 From: shavit Date: Mon, 25 Mar 2019 10:35:03 +0200 Subject: [PATCH 22/39] Optimized maps left query so it runs over 15 times faster (#758). on default mariadb setup! --- addons/sourcemod/scripting/shavit-stats.sp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-stats.sp b/addons/sourcemod/scripting/shavit-stats.sp index 183181cd3..3073d454d 100644 --- a/addons/sourcemod/scripting/shavit-stats.sp +++ b/addons/sourcemod/scripting/shavit-stats.sp @@ -602,12 +602,16 @@ void ShowMaps(int client) if(gI_MapType[client] == MAPSDONE) { - FormatEx(sQuery, 512, "SELECT a.map, a.time, a.jumps, a.id, COUNT(b.map) + 1 rank, a.points FROM %splayertimes a LEFT JOIN %splayertimes b ON a.time > b.time AND a.map = b.map AND a.style = b.style AND a.track = b.track WHERE a.auth = '%s' AND a.style = %d AND a.track = %d GROUP BY a.map ORDER BY a.%s;", gS_MySQLPrefix, gS_MySQLPrefix, gS_TargetAuth[client], gBS_Style[client], gI_Track[client], (gB_Rankings)? "points DESC":"map"); + FormatEx(sQuery, 512, + "SELECT a.map, a.time, a.jumps, a.id, COUNT(b.map) + 1 rank, a.points FROM %splayertimes a LEFT JOIN %splayertimes b ON a.time > b.time AND a.map = b.map AND a.style = b.style AND a.track = b.track WHERE a.auth = '%s' AND a.style = %d AND a.track = %d GROUP BY a.map ORDER BY a.%s;", + gS_MySQLPrefix, gS_MySQLPrefix, gS_TargetAuth[client], gBS_Style[client], gI_Track[client], (gB_Rankings)? "points DESC":"map"); } else { - FormatEx(sQuery, 512, "SELECT DISTINCT m.map FROM %smapzones m LEFT JOIN %splayertimes r ON r.map = m.map AND r.auth = '%s' AND r.style = %d AND m.track = %d WHERE r.map IS NULL AND m.track = %d ORDER BY m.map;", gS_MySQLPrefix, gS_MySQLPrefix, gS_TargetAuth[client], gBS_Style[client], gI_Track[client], gI_Track[client]); + FormatEx(sQuery, 512, + "SELECT DISTINCT map FROM %smapzones WHERE type = 0 AND map NOT IN (SELECT DISTINCT map FROM %splayertimes WHERE auth = '%s' AND style = %d AND track = %d) ORDER BY map;", + gS_MySQLPrefix, gS_MySQLPrefix, gS_TargetAuth[client], gBS_Style[client], gI_Track[client]); } gH_SQL.Query(ShowMapsCallback, sQuery, GetClientSerial(client), DBPrio_High); From 538429e36c6d61c3624780fa28a2a056e0441355 Mon Sep 17 00:00:00 2001 From: shavit Date: Mon, 25 Mar 2019 13:52:16 +0200 Subject: [PATCH 23/39] Changed !style to show records per track (#754). --- addons/sourcemod/scripting/shavit-core.sp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index eeb3f64fd..4a73ec4e2 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -928,7 +928,7 @@ public Action Command_Style(int client, int args) if(gB_WR) { - time = Shavit_GetWorldRecord(iStyle, Track_Main); + time = Shavit_GetWorldRecord(iStyle, gA_Timers[client].iTrack); } if(time > 0.0) @@ -936,7 +936,15 @@ public Action Command_Style(int client, int args) char sTime[32]; FormatSeconds(time, sTime, 32, false); - FormatEx(sDisplay, 64, "%s - WR: %s", gS_StyleStrings[iStyle].sStyleName, sTime); + char sWR[8]; + strcopy(sWR, 8, "WR"); + + if(gA_Timers[client].iTrack == Track_Bonus) + { + strcopy(sWR, 8, "BWR"); + } + + FormatEx(sDisplay, 64, "%s - %s: %s", gS_StyleStrings[iStyle].sStyleName, sWR, sTime); } else From 5fca6ded0cc8c50e5203781df16be74375460216 Mon Sep 17 00:00:00 2001 From: shavit Date: Mon, 25 Mar 2019 14:00:20 +0200 Subject: [PATCH 24/39] Added decreasing grid snap button (#743). --- addons/sourcemod/scripting/shavit-zones.sp | 17 +++++++++++++++-- .../translations/shavit-zones.phrases.txt | 8 ++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-zones.sp b/addons/sourcemod/scripting/shavit-zones.sp index fd6b8fc95..01e3b0259 100644 --- a/addons/sourcemod/scripting/shavit-zones.sp +++ b/addons/sourcemod/scripting/shavit-zones.sp @@ -1486,7 +1486,10 @@ void ShowPanel(int client, int step) pPanel.DrawItem(sPanelItem); char sDisplay[64]; - FormatEx(sDisplay, 64, "%T", "GridSnap", client, gI_GridSnap[client]); + FormatEx(sDisplay, 64, "%T", "GridSnapPlus", client, gI_GridSnap[client]); + pPanel.DrawItem(sDisplay); + + FormatEx(sDisplay, 64, "%T", "GridSnapMinus", client); pPanel.DrawItem(sDisplay); FormatEx(sDisplay, 64, "%T", "WallSnap", client, (gB_SnapToWall[client])? "ZoneSetYes":"ZoneSetNo", client); @@ -1524,6 +1527,16 @@ public int ZoneCreation_Handler(Menu menu, MenuAction action, int param1, int pa } case 3: + { + gI_GridSnap[param1] /= 2; + + if(gI_GridSnap[param1] < 1) + { + gI_GridSnap[param1] = 64; + } + } + + case 4: { gB_SnapToWall[param1] = !gB_SnapToWall[param1]; @@ -1538,7 +1551,7 @@ public int ZoneCreation_Handler(Menu menu, MenuAction action, int param1, int pa } } - case 4: + case 5: { gB_CursorTracing[param1] = !gB_CursorTracing[param1]; diff --git a/addons/sourcemod/translations/shavit-zones.phrases.txt b/addons/sourcemod/translations/shavit-zones.phrases.txt index 860342255..a9cc95b0f 100644 --- a/addons/sourcemod/translations/shavit-zones.phrases.txt +++ b/addons/sourcemod/translations/shavit-zones.phrases.txt @@ -48,10 +48,14 @@ { "en" "Abort zone creation" } - "GridSnap" + "GridSnapPlus" { "#format" "{1:d}" - "en" "Grid snap: x{1}" + "en" "Grid snap + (x{1})" + } + "GridSnapMinus" + { + "en" "Grid snap -" } "WallSnap" { From 0038c0d9e78c963be563131cfe4f5ee7864bf946 Mon Sep 17 00:00:00 2001 From: shavit Date: Mon, 25 Mar 2019 14:28:18 +0200 Subject: [PATCH 25/39] Added !mapsdone/!mapsleft (#704). --- addons/sourcemod/scripting/shavit-stats.sp | 135 ++++++++++++++++-- .../translations/shavit-stats.phrases.txt | 14 ++ 2 files changed, 141 insertions(+), 8 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-stats.sp b/addons/sourcemod/scripting/shavit-stats.sp index 3073d454d..494bcf016 100644 --- a/addons/sourcemod/scripting/shavit-stats.sp +++ b/addons/sourcemod/scripting/shavit-stats.sp @@ -46,7 +46,7 @@ char gS_MySQLPrefix[32]; // cache bool gB_AllowStats[MAXPLAYERS+1]; int gI_MapType[MAXPLAYERS+1]; -int gBS_Style[MAXPLAYERS+1]; +int gI_Style[MAXPLAYERS+1]; int gI_Track[MAXPLAYERS+1]; char gS_TargetAuth[MAXPLAYERS+1][32]; char gS_TargetName[MAXPLAYERS+1][MAX_NAME_LENGTH]; @@ -109,6 +109,8 @@ public void OnPluginStart() // player commands RegConsoleCmd("sm_profile", Command_Profile, "Show the player's profile. Usage: sm_profile [target]"); RegConsoleCmd("sm_stats", Command_Profile, "Show the player's profile. Usage: sm_profile [target]"); + RegConsoleCmd("sm_mapsdone", Command_MapsDoneLeft, "Show maps that the player has finished. Usage: sm_mapsdone [target]"); + RegConsoleCmd("sm_mapsleft", Command_MapsDoneLeft, "Show maps that the player has not finished yet. Usage: sm_mapsleft [target]"); // translations LoadTranslations("common.phrases"); @@ -332,9 +334,126 @@ public void SQL_GetWRs_Callback(Database db, DBResultSet results, const char[] e gI_WRAmount[client] = iWRs; } +public Action Command_MapsDoneLeft(int client, int args) +{ + if(client == 0) + { + return Plugin_Handled; + } + + int target = client; + + if(args > 0) + { + char sArgs[64]; + GetCmdArgString(sArgs, 64); + + target = FindTarget(client, sArgs, true, false); + + if(target == -1) + { + return Plugin_Handled; + } + } + + GetClientAuthId(target, AuthId_Steam3, gS_TargetAuth[client], 32); + + char sCommand[16]; + GetCmdArg(0, sCommand, 16); + + char sName[MAX_NAME_LENGTH]; + GetClientName(target, sName, MAX_NAME_LENGTH); + ReplaceString(sName, MAX_NAME_LENGTH, "#", "?"); + + Menu menu = new Menu(MenuHandler_MapsDoneLeft); + + if(StrEqual(sCommand, "sm_mapsdone")) + { + gI_MapType[client] = MAPSDONE; + menu.SetTitle("%T\n ", "MapsDoneOnStyle", client, sName); + } + + else + { + gI_MapType[client] = MAPSLEFT; + menu.SetTitle("%T\n ", "MapsLeftOnStyle", client, sName); + } + + int[] styles = new int[gI_Styles]; + Shavit_GetOrderedStyles(styles, gI_Styles); + + for(int i = 0; i < gI_Styles; i++) + { + int iStyle = styles[i]; + + if(gA_StyleSettings[iStyle].bUnranked || gA_StyleSettings[iStyle].iEnabled == -1) + { + continue; + } + + char sInfo[8]; + IntToString(iStyle, sInfo, 8); + menu.AddItem(sInfo, gS_StyleStrings[iStyle].sStyleName); + } + + menu.Display(client, 30); + + return Plugin_Handled; +} + +public int MenuHandler_MapsDoneLeft(Menu menu, MenuAction action, int param1, int param2) +{ + if(action == MenuAction_Select) + { + char sInfo[8]; + menu.GetItem(param2, sInfo, 8); + gI_Style[param1] = StringToInt(sInfo); + + Menu submenu = new Menu(MenuHandler_MapsDoneLeft_Track); + submenu.SetTitle("%T\n ", "SelectTrack", param1); + + for(int i = 0; i < TRACKS_SIZE; i++) + { + IntToString(i, sInfo, 8); + + char sTrack[32]; + GetTrackName(param1, i, sTrack, 32); + submenu.AddItem(sInfo, sTrack); + } + + submenu.Display(param1, 30); + } + + else if(action == MenuAction_End) + { + delete menu; + } + + return 0; +} + +public int MenuHandler_MapsDoneLeft_Track(Menu menu, MenuAction action, int param1, int param2) +{ + if(action == MenuAction_Select) + { + char sInfo[8]; + menu.GetItem(param2, sInfo, 8); + gI_Track[param1] = StringToInt(sInfo); + + ShowMaps(param1); + } + + else if(action == MenuAction_End) + { + delete menu; + } + + return 0; +} + public Action Command_Profile(int client, int args) { - if(!IsValidClient(client)) + if(client == 0) { return Plugin_Handled; } @@ -511,10 +630,10 @@ public int MenuHandler_ProfileHandler(Menu menu, MenuAction action, int param1, char sInfo[32]; menu.GetItem(param2, sInfo, 32); - gBS_Style[param1] = StringToInt(sInfo); + gI_Style[param1] = StringToInt(sInfo); Menu submenu = new Menu(MenuHandler_TypeHandler); - submenu.SetTitle("%T", "MapsMenu", param1, gS_StyleStrings[gBS_Style[param1]].sShortName); + submenu.SetTitle("%T", "MapsMenu", param1, gS_StyleStrings[gI_Style[param1]].sShortName); for(int j = 0; j < TRACKS_SIZE; j++) { @@ -604,14 +723,14 @@ void ShowMaps(int client) { FormatEx(sQuery, 512, "SELECT a.map, a.time, a.jumps, a.id, COUNT(b.map) + 1 rank, a.points FROM %splayertimes a LEFT JOIN %splayertimes b ON a.time > b.time AND a.map = b.map AND a.style = b.style AND a.track = b.track WHERE a.auth = '%s' AND a.style = %d AND a.track = %d GROUP BY a.map ORDER BY a.%s;", - gS_MySQLPrefix, gS_MySQLPrefix, gS_TargetAuth[client], gBS_Style[client], gI_Track[client], (gB_Rankings)? "points DESC":"map"); + gS_MySQLPrefix, gS_MySQLPrefix, gS_TargetAuth[client], gI_Style[client], gI_Track[client], (gB_Rankings)? "points DESC":"map"); } else { FormatEx(sQuery, 512, "SELECT DISTINCT map FROM %smapzones WHERE type = 0 AND map NOT IN (SELECT DISTINCT map FROM %splayertimes WHERE auth = '%s' AND style = %d AND track = %d) ORDER BY map;", - gS_MySQLPrefix, gS_MySQLPrefix, gS_TargetAuth[client], gBS_Style[client], gI_Track[client]); + gS_MySQLPrefix, gS_MySQLPrefix, gS_TargetAuth[client], gI_Style[client], gI_Track[client]); } gH_SQL.Query(ShowMapsCallback, sQuery, GetClientSerial(client), DBPrio_High); @@ -642,12 +761,12 @@ public void ShowMapsCallback(Database db, DBResultSet results, const char[] erro if(gI_MapType[client] == MAPSDONE) { - menu.SetTitle("%T (%s)", "MapsDoneFor", client, gS_StyleStrings[gBS_Style[client]].sShortName, gS_TargetName[client], rows, sTrack); + menu.SetTitle("%T (%s)", "MapsDoneFor", client, gS_StyleStrings[gI_Style[client]].sShortName, gS_TargetName[client], rows, sTrack); } else { - menu.SetTitle("%T (%s)", "MapsLeftFor", client, gS_StyleStrings[gBS_Style[client]].sShortName, gS_TargetName[client], rows, sTrack); + menu.SetTitle("%T (%s)", "MapsLeftFor", client, gS_StyleStrings[gI_Style[client]].sShortName, gS_TargetName[client], rows, sTrack); } while(results.FetchRow()) diff --git a/addons/sourcemod/translations/shavit-stats.phrases.txt b/addons/sourcemod/translations/shavit-stats.phrases.txt index 6e3e47348..8c373d64e 100644 --- a/addons/sourcemod/translations/shavit-stats.phrases.txt +++ b/addons/sourcemod/translations/shavit-stats.phrases.txt @@ -7,6 +7,10 @@ "en" "{1}ERROR: {2}Could not open the stats menu." } // ---------- Map Completions ---------- // + "SelectTrack" + { + "en" "Select timer track:" + } "MapsDone" { "en" "Maps done" @@ -16,6 +20,11 @@ "#format" "{1:s},{2:s},{3:d}" "en" "[{1}] Maps done for {2}: ({3})" } + "MapsDoneOnStyle" + { + "#format" "{1:s}" + "en" "Maps done for {1} on style:" + } "MapsLeft" { "en" "Maps left" @@ -25,6 +34,11 @@ "#format" "{1:s},{2:s},{3:d}" "en" "[{1}] Maps left for {2}: ({3})" } + "MapsLeftOnStyle" + { + "#format" "{1:s}" + "en" "Maps done for {1} on style:" + } "MapsMenu" { "#format" "{1:s}" From 079c71bfa12c637785ee30d7257968887b0a2909 Mon Sep 17 00:00:00 2001 From: shavit Date: Mon, 25 Mar 2019 14:32:14 +0200 Subject: [PATCH 26/39] Fixed mapsleft for bonus track. --- addons/sourcemod/scripting/shavit-stats.sp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-stats.sp b/addons/sourcemod/scripting/shavit-stats.sp index 494bcf016..bd7be5bfa 100644 --- a/addons/sourcemod/scripting/shavit-stats.sp +++ b/addons/sourcemod/scripting/shavit-stats.sp @@ -729,8 +729,8 @@ void ShowMaps(int client) else { FormatEx(sQuery, 512, - "SELECT DISTINCT map FROM %smapzones WHERE type = 0 AND map NOT IN (SELECT DISTINCT map FROM %splayertimes WHERE auth = '%s' AND style = %d AND track = %d) ORDER BY map;", - gS_MySQLPrefix, gS_MySQLPrefix, gS_TargetAuth[client], gI_Style[client], gI_Track[client]); + "SELECT DISTINCT map FROM %smapzones WHERE type = 0 AND track = %d AND map NOT IN (SELECT DISTINCT map FROM %splayertimes WHERE auth = '%s' AND style = %d AND track = %d) ORDER BY map;", + gS_MySQLPrefix, gI_Track[client], gS_MySQLPrefix, gS_TargetAuth[client], gI_Style[client], gI_Track[client]); } gH_SQL.Query(ShowMapsCallback, sQuery, GetClientSerial(client), DBPrio_High); From 26eda8b8826b2b5c10461a073ab43f5d03e378df Mon Sep 17 00:00:00 2001 From: shavit Date: Mon, 25 Mar 2019 14:48:09 +0200 Subject: [PATCH 27/39] Added tier to mapsleft (#704). and squashed a bug with the menu title --- addons/sourcemod/scripting/shavit-stats.sp | 38 +++++++++++++++++----- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-stats.sp b/addons/sourcemod/scripting/shavit-stats.sp index bd7be5bfa..400bbe2a8 100644 --- a/addons/sourcemod/scripting/shavit-stats.sp +++ b/addons/sourcemod/scripting/shavit-stats.sp @@ -361,22 +361,21 @@ public Action Command_MapsDoneLeft(int client, int args) char sCommand[16]; GetCmdArg(0, sCommand, 16); - char sName[MAX_NAME_LENGTH]; - GetClientName(target, sName, MAX_NAME_LENGTH); - ReplaceString(sName, MAX_NAME_LENGTH, "#", "?"); + GetClientName(target, gS_TargetName[client], MAX_NAME_LENGTH); + ReplaceString(gS_TargetName[client], MAX_NAME_LENGTH, "#", "?"); Menu menu = new Menu(MenuHandler_MapsDoneLeft); if(StrEqual(sCommand, "sm_mapsdone")) { gI_MapType[client] = MAPSDONE; - menu.SetTitle("%T\n ", "MapsDoneOnStyle", client, sName); + menu.SetTitle("%T\n ", "MapsDoneOnStyle", client, gS_TargetName[client]); } else { gI_MapType[client] = MAPSLEFT; - menu.SetTitle("%T\n ", "MapsLeftOnStyle", client, sName); + menu.SetTitle("%T\n ", "MapsLeftOnStyle", client, gS_TargetName[client]); } int[] styles = new int[gI_Styles]; @@ -728,9 +727,19 @@ void ShowMaps(int client) else { - FormatEx(sQuery, 512, - "SELECT DISTINCT map FROM %smapzones WHERE type = 0 AND track = %d AND map NOT IN (SELECT DISTINCT map FROM %splayertimes WHERE auth = '%s' AND style = %d AND track = %d) ORDER BY map;", - gS_MySQLPrefix, gI_Track[client], gS_MySQLPrefix, gS_TargetAuth[client], gI_Style[client], gI_Track[client]); + if(gB_Rankings) + { + FormatEx(sQuery, 512, + "SELECT DISTINCT m.map, t.tier FROM %smapzones m LEFT JOIN %smaptiers t ON m.map = t.map WHERE m.type = 0 AND m.track = %d AND m.map NOT IN (SELECT DISTINCT map FROM %splayertimes WHERE auth = '%s' AND style = %d AND track = %d) ORDER BY m.map;", + gS_MySQLPrefix, gS_MySQLPrefix, gI_Track[client], gS_MySQLPrefix, gS_TargetAuth[client], gI_Style[client], gI_Track[client]); + } + + else + { + FormatEx(sQuery, 512, + "SELECT DISTINCT map FROM %smapzones WHERE type = 0 AND track = %d AND map NOT IN (SELECT DISTINCT map FROM %splayertimes WHERE auth = '%s' AND style = %d AND track = %d) ORDER BY map;", + gS_MySQLPrefix, gI_Track[client], gS_MySQLPrefix, gS_TargetAuth[client], gI_Style[client], gI_Track[client]); + } } gH_SQL.Query(ShowMapsCallback, sQuery, GetClientSerial(client), DBPrio_High); @@ -805,6 +814,19 @@ public void ShowMapsCallback(Database db, DBResultSet results, const char[] erro else { strcopy(sDisplay, 192, sMap); + + if(gB_Rankings) + { + int iTier = results.FetchInt(1); + + if(results.IsFieldNull(1) || iTier == 0) + { + iTier = 1; + } + + Format(sDisplay, 192, "%s (Tier %d)", sMap, iTier); + } + strcopy(sRecordID, 16, "nope"); } From f2c351794398aa4e455fb6b04cd9aa919c50ad0e Mon Sep 17 00:00:00 2001 From: shavit Date: Mon, 25 Mar 2019 14:50:35 +0200 Subject: [PATCH 28/39] Added "shavit_misc_hidechatcmds" (#650). --- addons/sourcemod/scripting/shavit-misc.sp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/shavit-misc.sp b/addons/sourcemod/scripting/shavit-misc.sp index 1fa5f6885..173c49fa7 100644 --- a/addons/sourcemod/scripting/shavit-misc.sp +++ b/addons/sourcemod/scripting/shavit-misc.sp @@ -146,6 +146,7 @@ ConVar gCV_JointeamHook = null; ConVar gCV_SpectatorList = null; ConVar gCV_MaxCP = null; ConVar gCV_MaxCP_Segmented = null; +ConVar gCV_HideChatCommands = null; // forwards Handle gH_Forwards_OnClanTagChangePre = null; @@ -306,6 +307,7 @@ public void OnPluginStart() gCV_SpectatorList = CreateConVar("shavit_misc_speclist", "1", "Who to show in !specs?\n0 - everyone\n1 - all admins (admin_speclisthide override to bypass)\n2 - players you can target", 0, true, 0.0, true, 2.0); gCV_MaxCP = CreateConVar("shavit_misc_maxcp", "1000", "Maximum amount of checkpoints.\nNote: Very high values will result in high memory usage!", 0, true, 1.0, true, 10000.0); gCV_MaxCP_Segmented = CreateConVar("shavit_misc_maxcp_seg", "10", "Maximum amount of segmented checkpoints. Make this less or equal to shavit_misc_maxcp.\nNote: Very high values will result in HUGE memory usage!", 0, true, 1.0, true, 50.0); + gCV_HideChatCommands = CreateConVar("shavit_misc_hidechatcmds", "1", "Hide commands from chat?\n0 - Disabled\n1 - Enabled", 0, true, 0.0, true, 1.0); AutoExecConfig(); @@ -1154,7 +1156,7 @@ public void OnPreThink(int client) public Action OnClientSayCommand(int client, const char[] command, const char[] sArgs) { - if(IsChatTrigger()) + if(IsChatTrigger() && gCV_HideChatCommands.BoolValue) { // hide commands return Plugin_Handled; From e4fabd493fe1d9c3274cd473679529e650a10423 Mon Sep 17 00:00:00 2001 From: shavit Date: Tue, 26 Mar 2019 01:39:51 +0200 Subject: [PATCH 29/39] oops --- addons/sourcemod/translations/shavit-stats.phrases.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sourcemod/translations/shavit-stats.phrases.txt b/addons/sourcemod/translations/shavit-stats.phrases.txt index 8c373d64e..9c0616f0d 100644 --- a/addons/sourcemod/translations/shavit-stats.phrases.txt +++ b/addons/sourcemod/translations/shavit-stats.phrases.txt @@ -37,7 +37,7 @@ "MapsLeftOnStyle" { "#format" "{1:s}" - "en" "Maps done for {1} on style:" + "en" "Maps left for {1} on style:" } "MapsMenu" { From 648eb17d57199e2570e2cbbe088016e4e7205dce Mon Sep 17 00:00:00 2001 From: shavit Date: Tue, 26 Mar 2019 02:26:04 +0200 Subject: [PATCH 30/39] Removed ancient sm_deletestylerecords command. sm_deleteall should be used instead --- addons/sourcemod/scripting/shavit-wr.sp | 187 ------------------ .../translations/shavit-wr.phrases.txt | 4 - 2 files changed, 191 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-wr.sp b/addons/sourcemod/scripting/shavit-wr.sp index 5e6734d3b..b6540aa38 100644 --- a/addons/sourcemod/scripting/shavit-wr.sp +++ b/addons/sourcemod/scripting/shavit-wr.sp @@ -159,7 +159,6 @@ public void OnPluginStart() RegAdminCmd("sm_deleterecord", Command_Delete, ADMFLAG_RCON, "Opens a record deletion menu interface."); RegAdminCmd("sm_deleterecords", Command_Delete, ADMFLAG_RCON, "Opens a record deletion menu interface."); RegAdminCmd("sm_deleteall", Command_DeleteAll, ADMFLAG_RCON, "Deletes all the records for this map."); - RegAdminCmd("sm_deletestylerecords", Command_DeleteStyleRecords, ADMFLAG_RCON, "Deletes all the records for a style."); // cvars gCV_RecordsLimit = CreateConVar("shavit_wr_recordlimit", "50", "Limit of records shown in the WR menu.\nAdvised to not set above 1,000 because scrolling through so many pages is useless.\n(And can also cause the command to take long time to run)", 0, true, 1.0); @@ -222,7 +221,6 @@ public void OnAdminMenuReady(Handle topmenu) gH_AdminMenu.AddItem("sm_deleteall", AdminMenu_DeleteAll, gH_TimerCommands, "sm_deleteall", ADMFLAG_RCON); gH_AdminMenu.AddItem("sm_delete", AdminMenu_Delete, gH_TimerCommands, "sm_delete", ADMFLAG_RCON); - gH_AdminMenu.AddItem("sm_deletestylerecords", AdminMenu_DeleteStyleRecords, gH_TimerCommands, "sm_deletestylerecords", ADMFLAG_RCON); } } @@ -252,19 +250,6 @@ public void AdminMenu_DeleteAll(Handle topmenu, TopMenuAction action, TopMenuOb } } -public void AdminMenu_DeleteStyleRecords(Handle topmenu, TopMenuAction action, TopMenuObject object_id, int param, char[] buffer, int maxlength) -{ - if(action == TopMenuAction_DisplayOption) - { - FormatEx(buffer, maxlength, "%t", "DeleteStyleRecords"); - } - - else if(action == TopMenuAction_SelectOption) - { - Command_DeleteStyleRecords(param, 0); - } -} - public void OnLibraryAdded(const char[] name) { if(StrEqual(name, "shavit-rankings")) @@ -940,178 +925,6 @@ public int MenuHandler_DeleteAll(Menu menu, MenuAction action, int param1, int p return 0; } -public Action Command_DeleteStyleRecords(int client, int args) -{ - if(!IsValidClient(client)) - { - return Plugin_Handled; - } - - Menu menu = new Menu(MenuHandler_DeleteStyleRecords); - menu.SetTitle("%T\n ", "DeleteStyleRecordsRecordsMenuTitle", client, gS_Map); - - int[] styles = new int[gI_Styles]; - Shavit_GetOrderedStyles(styles, gI_Styles); - - for(int i = 0; i < gI_Styles; i++) - { - int iStyle = styles[i]; - - if(gA_StyleSettings[iStyle].bUnranked || gA_StyleSettings[iStyle].iEnabled == -1) - { - continue; - } - - char sInfo[8]; - IntToString(iStyle, sInfo, 8); - - char sDisplay[64]; - FormatEx(sDisplay, 64, "%s (%d %T)", gS_StyleStrings[iStyle].sStyleName, gI_RecordAmount[iStyle], "WRRecord", client); - - int iTotalAmount = 0; - - for(int j = 0; j < TRACKS_SIZE; j++) - { - iTotalAmount += gI_RecordAmount[iStyle][j]; - } - - menu.AddItem(sInfo, sDisplay, (iTotalAmount > 0)? ITEMDRAW_DEFAULT:ITEMDRAW_DISABLED); - } - - if(menu.ItemCount == 0) - { - char sNoRecords[64]; - FormatEx(sNoRecords, 64, "%T", "WRMapNoRecords", client); - menu.AddItem("-1", sNoRecords); - } - - menu.ExitButton = true; - menu.Display(client, 20); - - return Plugin_Handled; -} - -public int MenuHandler_DeleteStyleRecords(Menu menu, MenuAction action, int param1, int param2) -{ - if(action == MenuAction_Select) - { - char info[16]; - menu.GetItem(param2, info, 16); - - int style = StringToInt(info); - int iTotalAmount = 0; - - for(int j = 0; j < TRACKS_SIZE; j++) - { - iTotalAmount += gI_RecordAmount[style][j]; - } - - if(iTotalAmount == 0) - { - return 0; - } - - char sMenuItem[128]; - - Menu submenu = new Menu(MenuHandler_DeleteStyleRecords_Confirm); - submenu.SetTitle("%T\n ", "DeleteConfirmStyle", param1, gS_StyleStrings[style].sStyleName); - - for(int i = 1; i <= GetRandomInt(1, 4); i++) - { - FormatEx(sMenuItem, 128, "%T", "MenuResponseNo", param1); - submenu.AddItem("-1", sMenuItem); - } - - FormatEx(sMenuItem, 128, "%T", "MenuResponseYesStyle", param1, gS_StyleStrings[style].sStyleName); - - IntToString(style, info, 16); - submenu.AddItem(info, sMenuItem); - - for(int i = 1; i <= GetRandomInt(1, 3); i++) - { - FormatEx(sMenuItem, 128, "%T", "MenuResponseNo", param1); - submenu.AddItem("-1", sMenuItem); - } - - submenu.ExitButton = true; - submenu.Display(param1, 20); - } - - else if(action == MenuAction_End) - { - delete menu; - } - - return 0; -} - -public int MenuHandler_DeleteStyleRecords_Confirm(Menu menu, MenuAction action, int param1, int param2) -{ - if(action == MenuAction_Select) - { - char info[16]; - menu.GetItem(param2, info, 16); - - int style = StringToInt(info); - - if(style == -1) - { - Shavit_PrintToChat(param1, "%T", "DeletionAborted", param1); - - return 0; - } - - Shavit_LogMessage("%L - deleted all %s style records from map `%s`.", param1, gS_StyleStrings[style].sStyleName, gS_Map); - - char sQuery[256]; - FormatEx(sQuery, 256, "DELETE FROM %splayertimes WHERE map = '%s' AND style = %d;", gS_MySQLPrefix, gS_Map, style); - - DataPack pack = new DataPack(); - pack.WriteCell(GetClientSerial(param1)); - pack.WriteCell(style); - - gH_SQL.Query(DeleteStyleRecords_Callback, sQuery, pack, DBPrio_High); - } - - else if(action == MenuAction_End) - { - delete menu; - } - - return 0; -} - -public void DeleteStyleRecords_Callback(Database db, DBResultSet results, const char[] error, DataPack data) -{ - data.Reset(); - int serial = data.ReadCell(); - int style = data.ReadCell(); - delete data; - - if(results == null) - { - LogError("Timer (WR DeleteStyleRecords) SQL query failed. Reason: %s", error); - - return; - } - - UpdateWRCache(); - - for(int i = 1; i <= MaxClients; i++) - { - OnClientPutInServer(i); - } - - int client = GetClientFromSerial(serial); - - if(client == 0) - { - return; - } - - Shavit_PrintToChat(client, "%T", "DeletedRecordsStyle", client, gS_ChatStrings.sStyle, gS_StyleStrings[style].sStyleName, gS_ChatStrings.sText); -} - public int MenuHandler_Delete(Menu menu, MenuAction action, int param1, int param2) { if(action == MenuAction_Select) diff --git a/addons/sourcemod/translations/shavit-wr.phrases.txt b/addons/sourcemod/translations/shavit-wr.phrases.txt index 528fc2cd1..9739f3399 100644 --- a/addons/sourcemod/translations/shavit-wr.phrases.txt +++ b/addons/sourcemod/translations/shavit-wr.phrases.txt @@ -80,10 +80,6 @@ { "en" "YES!!! DELETE ALL THE RECORDS!!! THIS ACTION IS IRREVERSIBLE!" } - "DeleteStyleRecords" - { - "en" "Delete ALL map records for a style" - } "DeleteStyleRecordsRecordsMenuTitle" { "#format" "{1:s}" From 4d2308ef1f9bd36144910ea6b17d05288c2c56e5 Mon Sep 17 00:00:00 2001 From: shavit Date: Tue, 26 Mar 2019 02:47:20 +0200 Subject: [PATCH 31/39] Fixed shavit-misc not respecting mp_humanteam properly (#716). --- addons/sourcemod/scripting/shavit-misc.sp | 49 ++++++++++------------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-misc.sp b/addons/sourcemod/scripting/shavit-misc.sp index 173c49fa7..06c176fa7 100644 --- a/addons/sourcemod/scripting/shavit-misc.sp +++ b/addons/sourcemod/scripting/shavit-misc.sp @@ -154,9 +154,6 @@ Handle gH_Forwards_OnClanTagChangePost = null; Handle gH_Forwards_OnSave = null; Handle gH_Forwards_OnTeleport = null; -// cached cvars -int gI_HumanTeam = 0; - // dhooks Handle gH_GetPlayerMaxSpeed = null; @@ -318,8 +315,6 @@ public void OnPluginStart() mp_humanteam = FindConVar("mp_humans_must_join_team"); } - mp_humanteam.AddChangeHook(OnConVarChanged); - // crons if(gEV_Type != Engine_TF2) { @@ -451,27 +446,6 @@ public void Shavit_OnStyleChanged(int client, int oldstyle, int newstyle, int tr } } -public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue) -{ - if(convar == mp_humanteam) - { - if(StrEqual(newValue, "t", false) || StrEqual(newValue, "red", false)) - { - gI_HumanTeam = 2; - } - - else if(StrEqual(newValue, "ct", false) || StrEqual(newValue, "blue", false)) - { - gI_HumanTeam = 3; - } - - else - { - gI_HumanTeam = 0; - } - } -} - public void OnConfigsExecuted() { if(sv_disable_immunity_alpha != null) @@ -614,6 +588,24 @@ public void OnLibraryRemoved(const char[] name) } } +int GetHumanTeam() +{ + char sTeam[8]; + mp_humanteam.GetString(sTeam, 8); + + if(StrEqual(sTeam, "t", false) || StrEqual(sTeam, "red", false)) + { + return 2; + } + + else if(StrEqual(sTeam, "ct", false) || StrContains(sTeam, "blu", false) != -1) + { + return 3; + } + + return 0; +} + public Action Command_Jointeam(int client, const char[] command, int args) { if(!IsValidClient(client) || !gCV_JointeamHook.BoolValue) @@ -630,10 +622,11 @@ public Action Command_Jointeam(int client, const char[] command, int args) GetCmdArg(1, arg1, 8); int iTeam = StringToInt(arg1); + int iHumanTeam = GetHumanTeam(); - if(gI_HumanTeam == 0 && !(0 <= iTeam <= 1)) + if(iHumanTeam != 0) { - iTeam = gI_HumanTeam; + iTeam = iHumanTeam; } bool bRespawn = false; From 12005e8c1881aa2dae03b7c92fe259aaff2860de Mon Sep 17 00:00:00 2001 From: shavit Date: Wed, 27 Mar 2019 10:27:50 +0200 Subject: [PATCH 32/39] Rewrote queries to support ONLY_FULL_GROUP_BY (#764). --- addons/sourcemod/scripting/shavit-chat.sp | 2 +- addons/sourcemod/scripting/shavit-core.sp | 39 +++++----- addons/sourcemod/scripting/shavit-rankings.sp | 4 +- addons/sourcemod/scripting/shavit-stats.sp | 16 ++-- addons/sourcemod/scripting/shavit-wr.sp | 75 +++++++++---------- 5 files changed, 66 insertions(+), 70 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-chat.sp b/addons/sourcemod/scripting/shavit-chat.sp index e8a354f46..0828bac42 100644 --- a/addons/sourcemod/scripting/shavit-chat.sp +++ b/addons/sourcemod/scripting/shavit-chat.sp @@ -1347,7 +1347,7 @@ void SQL_DBConnect() gS_MySQLPrefix); } - gH_SQL.Query(SQL_CreateTable_Callback, sQuery, 0, DBPrio_High); + gH_SQL.Query(SQL_CreateTable_Callback, sQuery); } } diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index 4a73ec4e2..f48742f8a 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -698,14 +698,14 @@ void DeleteUserData(int client, const char[] sAuthID3) { char sQueryGetWorldRecords[256]; FormatEx(sQueryGetWorldRecords, 256, - "SELECT map, id, style, track FROM %splayertimes WHERE auth = '%s' GROUP BY map, style, track;", + "SELECT map, id, style, track FROM %splayertimes WHERE auth = '%s';", gS_MySQLPrefix, sAuthID3); - DataPack pack = new DataPack(); - pack.WriteCell(client); - pack.WriteString(sAuthID3); + DataPack hPack = new DataPack(); + hPack.WriteCell(client); + hPack.WriteString(sAuthID3); - gH_SQL.Query(SQL_DeleteUserData_GetRecords_Callback, sQueryGetWorldRecords, pack, DBPrio_High); + gH_SQL.Query(SQL_DeleteUserData_GetRecords_Callback, sQueryGetWorldRecords, hPack, DBPrio_High); } else @@ -725,13 +725,13 @@ void DeleteUserData(int client, const char[] sAuthID3) public void SQL_DeleteUserData_GetRecords_Callback(Database db, DBResultSet results, const char[] error, any data) { - DataPack pack = view_as(data); - pack.Reset(); - int client = pack.ReadCell(); + DataPack hPack = view_as(data); + hPack.Reset(); + int client = hPack.ReadCell(); char sAuthID3[32]; - pack.ReadString(sAuthID3, 32); - delete pack; + hPack.ReadString(sAuthID3, 32); + delete hPack; if(results == null) { @@ -740,7 +740,7 @@ public void SQL_DeleteUserData_GetRecords_Callback(Database db, DBResultSet resu return; } - Transaction trans = new Transaction(); + Transaction hTransaction = new Transaction(); while(results.FetchRow()) { @@ -756,20 +756,20 @@ public void SQL_DeleteUserData_GetRecords_Callback(Database db, DBResultSet resu "SELECT id FROM %splayertimes WHERE map = '%s' AND style = %d AND track = %d ORDER BY time LIMIT 1;", gS_MySQLPrefix, map, style, track); - DataPack transPack = new DataPack(); - transPack.WriteString(map); - transPack.WriteCell(id); - transPack.WriteCell(style); - transPack.WriteCell(track); + DataPack hTransPack = new DataPack(); + hTransPack.WriteString(map); + hTransPack.WriteCell(id); + hTransPack.WriteCell(style); + hTransPack.WriteCell(track); - trans.AddQuery(sQueryGetWorldRecordID, transPack); + hTransaction.AddQuery(sQueryGetWorldRecordID, hTransPack); } DataPack steamPack = new DataPack(); steamPack.WriteString(sAuthID3); steamPack.WriteCell(client); - gH_SQL.Execute(trans, Trans_OnRecordCompare, INVALID_FUNCTION, steamPack, DBPrio_High); + gH_SQL.Execute(hTransaction, Trans_OnRecordCompare, INVALID_FUNCTION, steamPack, DBPrio_High); } public void Trans_OnRecordCompare(Database db, any data, int numQueries, DBResultSet[] results, any[] queryData) @@ -2139,8 +2139,7 @@ void SQL_DBConnect() FormatEx(sQuery, 512, "CREATE TABLE IF NOT EXISTS `%susers` (`auth` VARCHAR(32) NOT NULL PRIMARY KEY, `name` VARCHAR(32), `country` VARCHAR(32), `ip` VARCHAR(64), `lastlogin` INTEGER NOT NULL DEFAULT -1, `points` FLOAT NOT NULL DEFAULT 0);", gS_MySQLPrefix); } - // CREATE TABLE IF NOT EXISTS - gH_SQL.Query(SQL_CreateTable_Callback, sQuery); + gH_SQL.Query(SQL_CreateTable_Callback, sQuery, 0, DBPrio_High); } public void SQL_CreateTable_Callback(Database db, DBResultSet results, const char[] error, any data) diff --git a/addons/sourcemod/scripting/shavit-rankings.sp b/addons/sourcemod/scripting/shavit-rankings.sp index ed2442d79..46ec24747 100644 --- a/addons/sourcemod/scripting/shavit-rankings.sp +++ b/addons/sourcemod/scripting/shavit-rankings.sp @@ -787,7 +787,7 @@ void UpdateAllPoints() #endif char sQuery[128]; - FormatEx(sQuery, 128, "UPDATE %susers SET points = GetWeightedPoints(auth) WHERE auth IN (SELECT auth FROM %splayertimes GROUP BY auth);", + FormatEx(sQuery, 128, "UPDATE %susers SET points = GetWeightedPoints(auth) WHERE auth IN (SELECT DISTINCT auth FROM %splayertimes);", gS_MySQLPrefix, gS_MySQLPrefix); gH_SQL.Query(SQL_UpdateAllPoints_Callback, sQuery); @@ -815,7 +815,7 @@ void UpdatePlayerRank(int client, bool first) // if there's any issue with this query, // add "ORDER BY points DESC " before "LIMIT 1" char sQuery[512]; - FormatEx(sQuery, 512, "SELECT p.points, COUNT(*) rank FROM %susers u JOIN (SELECT points FROM %susers WHERE auth = '%s' LIMIT 1) p WHERE u.points >= p.points LIMIT 1;", + FormatEx(sQuery, 512, "SELECT u2.points, COUNT(*) FROM %susers u1 JOIN (SELECT points FROM %susers WHERE auth = '%s') u2 WHERE u1.points >= u2.points;", gS_MySQLPrefix, gS_MySQLPrefix, sAuthID); DataPack hPack = new DataPack(); diff --git a/addons/sourcemod/scripting/shavit-stats.sp b/addons/sourcemod/scripting/shavit-stats.sp index 400bbe2a8..82c9bcbea 100644 --- a/addons/sourcemod/scripting/shavit-stats.sp +++ b/addons/sourcemod/scripting/shavit-stats.sp @@ -491,21 +491,21 @@ Action OpenStatsMenu(int client, const char[] authid) if(gB_Rankings) { FormatEx(sQuery, 2048, "SELECT a.clears, b.maps, c.wrs, d.name, d.country, d.lastlogin, d.points, e.rank FROM " ... - "(SELECT COUNT(*) clears FROM (SELECT id FROM %splayertimes WHERE auth = '%s' AND track = 0 GROUP BY map) s) a " ... - "JOIN (SELECT COUNT(*) maps FROM (SELECT id FROM %smapzones WHERE track = 0 AND type = 0 GROUP BY map) s) b " ... + "(SELECT COUNT(*) clears FROM (SELECT map FROM %splayertimes WHERE auth = '%s' AND track = 0 GROUP BY map) s) a " ... + "JOIN (SELECT COUNT(*) maps FROM (SELECT map FROM %smapzones WHERE track = 0 AND type = 0 GROUP BY map) s) b " ... "JOIN (SELECT COUNT(*) wrs FROM %splayertimes a JOIN (SELECT MIN(time) time, map FROM %splayertimes WHERE style = 0 AND track = 0 GROUP by map, style, track) b ON a.time = b.time AND a.map = b.map AND track = 0 AND style = 0 WHERE auth = '%s') c " ... - "JOIN (SELECT name, country, lastlogin, FORMAT(points, 2) points FROM %susers WHERE auth = '%s' LIMIT 1) d " ... - "JOIN (SELECT FORMAT(COUNT(*), 0) rank FROM %susers WHERE points >= (SELECT points FROM %susers WHERE auth = '%s' LIMIT 1) ORDER BY points DESC) e " ... + "JOIN (SELECT name, country, lastlogin, FORMAT(points, 2) points FROM %susers WHERE auth = '%s') d " ... + "JOIN (SELECT COUNT(*) rank FROM %susers u1 JOIN (SELECT points FROM %susers WHERE auth = '%s') u2 WHERE u1.points >= u2.points) e " ... "LIMIT 1;", gS_MySQLPrefix, authid, gS_MySQLPrefix, gS_MySQLPrefix, gS_MySQLPrefix, authid, gS_MySQLPrefix, authid, gS_MySQLPrefix, gS_MySQLPrefix, authid); } else { FormatEx(sQuery, 2048, "SELECT a.clears, b.maps, c.wrs, d.name, d.country, d.lastlogin FROM " ... - "(SELECT COUNT(*) clears FROM (SELECT id FROM %splayertimes WHERE auth = '%s' AND track = 0 GROUP BY map) s) a " ... - "JOIN (SELECT COUNT(*) maps FROM (SELECT id FROM %smapzones WHERE track = 0 AND type = 0 GROUP BY map) s) b " ... + "(SELECT COUNT(*) clears FROM (SELECT map FROM %splayertimes WHERE auth = '%s' AND track = 0 GROUP BY map) s) a " ... + "JOIN (SELECT COUNT(*) maps FROM (SELECT map FROM %smapzones WHERE track = 0 AND type = 0 GROUP BY map) s) b " ... "JOIN (SELECT COUNT(*) wrs FROM %splayertimes a JOIN (SELECT MIN(time) time, map FROM %splayertimes WHERE style = 0 AND track = 0 GROUP by map, style, track) b ON a.time = b.time AND a.map = b.map AND track = 0 AND style = 0 WHERE auth = '%s') c " ... - "JOIN (SELECT name, country, lastlogin FROM %susers WHERE auth = '%s' LIMIT 1) d " ... + "JOIN (SELECT name, country, lastlogin FROM %susers WHERE auth = '%s') d " ... "LIMIT 1;", gS_MySQLPrefix, authid, gS_MySQLPrefix, gS_MySQLPrefix, gS_MySQLPrefix, authid, gS_MySQLPrefix, authid); } @@ -721,7 +721,7 @@ void ShowMaps(int client) if(gI_MapType[client] == MAPSDONE) { FormatEx(sQuery, 512, - "SELECT a.map, a.time, a.jumps, a.id, COUNT(b.map) + 1 rank, a.points FROM %splayertimes a LEFT JOIN %splayertimes b ON a.time > b.time AND a.map = b.map AND a.style = b.style AND a.track = b.track WHERE a.auth = '%s' AND a.style = %d AND a.track = %d GROUP BY a.map ORDER BY a.%s;", + "SELECT a.map, a.time, a.jumps, a.id, COUNT(b.map) + 1 rank, a.points FROM %splayertimes a LEFT JOIN %splayertimes b ON a.time > b.time AND a.map = b.map AND a.style = b.style AND a.track = b.track WHERE a.auth = '%s' AND a.style = %d AND a.track = %d GROUP BY a.map, a.time, a.jumps, a.id, a.points ORDER BY a.%s;", gS_MySQLPrefix, gS_MySQLPrefix, gS_TargetAuth[client], gI_Style[client], gI_Track[client], (gB_Rankings)? "points DESC":"map"); } diff --git a/addons/sourcemod/scripting/shavit-wr.sp b/addons/sourcemod/scripting/shavit-wr.sp index b6540aa38..1091194cf 100644 --- a/addons/sourcemod/scripting/shavit-wr.sp +++ b/addons/sourcemod/scripting/shavit-wr.sp @@ -467,18 +467,22 @@ public void SQL_UpdateCache_Callback(Database db, DBResultSet results, const cha void UpdateWRCache() { char sQuery[512]; - // thanks Ollie Jones from stackoverflow! http://stackoverflow.com/a/36239523/5335680 - // was a bit confused with this one :s - + if(gB_MySQL) { - FormatEx(sQuery, 512, "SELECT p.style, p.id, TRUNCATE(LEAST(s.time, p.time), 3), u.name, p.track FROM %splayertimes p JOIN(SELECT style, MIN(time) time, map, track FROM %splayertimes WHERE map = '%s' GROUP BY style, track ORDER BY date ASC) s ON p.style = s.style AND p.time = s.time AND p.map = s.map JOIN %susers u ON p.auth = u.auth GROUP BY p.style, p.track ORDER BY date ASC;", gS_MySQLPrefix, gS_MySQLPrefix, gS_Map, gS_MySQLPrefix); + FormatEx(sQuery, 512, + "SELECT p1.id, p1.style, p1.track, p1.time, u.name FROM %splayertimes p1 " ... + "JOIN (SELECT style, track, MIN(time) time FROM %splayertimes WHERE map = '%s' GROUP BY style, track) p2 " ... + "JOIN %susers u ON p1.style = p2.style AND p1.track = p2.track AND p1.time = p2.time AND u.auth = p1.auth " ... + "WHERE p1.map = '%s';", + gS_MySQLPrefix, gS_MySQLPrefix, gS_Map, gS_MySQLPrefix, gS_Map); } - // sorry, LEAST() isn't available for SQLITE! else { - FormatEx(sQuery, 512, "SELECT p.style, p.id, s.time, u.name, p.track FROM %splayertimes p JOIN(SELECT style, MIN(time) time, map, track FROM %splayertimes WHERE map = '%s' GROUP BY style, track) s ON p.style = s.style AND p.time = s.time AND p.map = s.map AND s.track = p.track JOIN %susers u ON p.auth = u.auth GROUP BY p.style, p.track;", gS_MySQLPrefix, gS_MySQLPrefix, gS_Map, gS_MySQLPrefix); + FormatEx(sQuery, 512, + "SELECT p.id, p.style, p.track, s.time, u.name FROM %splayertimes p JOIN(SELECT style, MIN(time) time, map, track FROM %splayertimes WHERE map = '%s' GROUP BY style, track) s ON p.style = s.style AND p.time = s.time AND p.map = s.map AND s.track = p.track JOIN %susers u ON p.auth = u.auth GROUP BY p.style, p.track;", + gS_MySQLPrefix, gS_MySQLPrefix, gS_Map, gS_MySQLPrefix); } gH_SQL.Query(SQL_UpdateWRCache_Callback, sQuery, 0, DBPrio_Low); @@ -507,19 +511,18 @@ public void SQL_UpdateWRCache_Callback(Database db, DBResultSet results, const c // setup cache again, dynamically and not hardcoded while(results.FetchRow()) { - int style = results.FetchInt(0); + int iStyle = results.FetchInt(1); + int iTrack = results.FetchInt(2); - if(style >= gI_Styles || style < 0 || gA_StyleSettings[style].bUnranked) + if(iStyle >= gI_Styles || iStyle < 0 || gA_StyleSettings[iStyle].bUnranked) { continue; } - int track = results.FetchInt(4); - - gI_WRRecordID[style][track] = results.FetchInt(1); - gF_WRTime[style][track] = results.FetchFloat(2); - results.FetchString(3, gS_WRName[style][track], MAX_NAME_LENGTH); - ReplaceString(gS_WRName[style][track], MAX_NAME_LENGTH, "#", "?"); + gI_WRRecordID[iStyle][iTrack] = results.FetchInt(0); + gF_WRTime[iStyle][iTrack] = results.FetchFloat(3); + results.FetchString(4, gS_WRName[iStyle][iTrack], MAX_NAME_LENGTH); + ReplaceString(gS_WRName[iStyle][iTrack], MAX_NAME_LENGTH, "#", "?"); } UpdateLeaderboards(); @@ -635,7 +638,7 @@ public Action Command_Junk(int client, int args) char sAuth[32]; GetClientAuthId(client, AuthId_Steam3, sAuth, 32); - FormatEx(sQuery, 256, "INSERT INTO %splayertimes (auth, map, time, jumps, date, style, strafes, sync) VALUES ('%s', '%s', %.03f, %d, %d, 0, %d, %.02f);", gS_MySQLPrefix, sAuth, gS_Map, GetRandomFloat(10.0, 20.0), GetRandomInt(5, 15), GetTime(), GetRandomInt(5, 15), GetRandomFloat(50.0, 99.99)); + FormatEx(sQuery, 256, "INSERT INTO %splayertimes (auth, map, time, jumps, date, style, strafes, sync) VALUES ('%s', '%s', %f, %d, %d, 0, %d, %.02f);", gS_MySQLPrefix, sAuth, gS_Map, GetRandomFloat(10.0, 20.0), GetRandomInt(5, 15), GetTime(), GetRandomInt(5, 15), GetRandomFloat(50.0, 99.99)); SQL_LockDatabase(gH_SQL); SQL_FastQuery(gH_SQL, sQuery); @@ -1566,10 +1569,10 @@ public Action Command_RecentRecords(int client, int args) char sQuery[512]; FormatEx(sQuery, 512, - "SELECT a.id, a.map, u.name, a.time, a.jumps, a.style, a.points, a.track FROM %splayertimes a " ... - "JOIN (SELECT MIN(time) time, map, style, track FROM %splayertimes GROUP by map, style, track) b " ... - "JOIN %susers u ON a.time = b.time AND a.auth = u.auth AND a.map = b.map AND a.style = b.style AND a.track = b.track " ... - "ORDER BY date DESC LIMIT 100;", gS_MySQLPrefix, gS_MySQLPrefix, gS_MySQLPrefix); + "SELECT a.id, a.map, u.name, a.time, a.style, a.track FROM %splayertimes a " ... + "JOIN (SELECT MIN(time) time, map, style, track FROM %splayertimes GROUP by map, style, track ORDER BY date DESC) b " ... + "JOIN %susers u ON a.time = b.time AND a.auth = u.auth AND a.map = b.map AND a.style = b.style AND a.track = b.track " ... + "LIMIT 100;", gS_MySQLPrefix, gS_MySQLPrefix, gS_MySQLPrefix); gH_SQL.Query(SQL_RR_Callback, sQuery, GetClientSerial(client), DBPrio_Low); @@ -1607,33 +1610,27 @@ public void SQL_RR_Callback(Database db, DBResultSet results, const char[] error char sName[MAX_NAME_LENGTH]; results.FetchString(2, sName, 10); - if(strlen(sName) == 9) + if(strlen(sName) >= 9) { Format(sName, MAX_NAME_LENGTH, "%s...", sName); } char sTime[16]; - float time = results.FetchFloat(3); - FormatSeconds(time, sTime, 16); - - int jumps = results.FetchInt(4); - int style = results.FetchInt(5); - float fPoints = results.FetchFloat(6); - - char sTrack[32]; - GetTrackName(client, results.FetchInt(7), sTrack, 32); + float fTime = results.FetchFloat(3); + FormatSeconds(fTime, sTime, 16); - char sDisplay[192]; + int iStyle = results.FetchInt(4); - if(gB_Rankings && fPoints > 0.0) + if(iStyle >= gI_Styles || iStyle < 0 || gA_StyleSettings[iStyle].bUnranked) { - FormatEx(sDisplay, 192, "[%s, %c] %s - %s @ %s (%.03f %T)", gS_StyleStrings[style].sShortName, sTrack[0], sMap, sName, sTime, fPoints, "WRPoints", client); + continue; } - else - { - FormatEx(sDisplay, 192, "[%s, %c] %s - %s @ %s (%d %T)", gS_StyleStrings[style].sShortName, sTrack[0], sMap, sName, sTime, jumps, "WRJumps", client); - } + char sTrack[32]; + GetTrackName(client, results.FetchInt(5), sTrack, 32); + + char sDisplay[192]; + FormatEx(sDisplay, 192, "[%s/%c] %s - %s @ %s", gS_StyleStrings[iStyle].sShortName, sTrack[0], sMap, sName, sTime); char sInfo[192]; FormatEx(sInfo, 192, "%d;%s", results.FetchInt(0), sMap); @@ -1964,7 +1961,7 @@ void SQL_DBConnect() gS_MySQLPrefix); } - gH_SQL.Query(SQL_CreateTable_Callback, sQuery, 0, DBPrio_High); + gH_SQL.Query(SQL_CreateTable_Callback, sQuery); } public void SQL_CreateTable_Callback(Database db, DBResultSet results, const char[] error, any data) @@ -2088,14 +2085,14 @@ public void Shavit_OnFinish(int client, int style, float time, int jumps, int st return; } - FormatEx(sQuery, 512, "INSERT INTO %splayertimes (auth, map, time, jumps, date, style, strafes, sync, points, track, perfs) VALUES ('%s', '%s', %.03f, %d, %d, %d, %d, %.2f, 0.0, %d, %.2f);", gS_MySQLPrefix, sAuthID, gS_Map, time, jumps, GetTime(), style, strafes, sync, track, perfs); + FormatEx(sQuery, 512, "INSERT INTO %splayertimes (auth, map, time, jumps, date, style, strafes, sync, points, track, perfs) VALUES ('%s', '%s', %f, %d, %d, %d, %d, %.2f, 0.0, %d, %.2f);", gS_MySQLPrefix, sAuthID, gS_Map, time, jumps, GetTime(), style, strafes, sync, track, perfs); } else // update { Shavit_PrintToChatAll("%s[%s]%s %T", gS_ChatStrings.sVariable, sTrack, gS_ChatStrings.sText, "NotFirstCompletion", LANG_SERVER, gS_ChatStrings.sVariable2, client, gS_ChatStrings.sText, gS_ChatStrings.sStyle, gS_StyleStrings[style].sStyleName, gS_ChatStrings.sText, gS_ChatStrings.sVariable2, sTime, gS_ChatStrings.sText, gS_ChatStrings.sVariable, iRank, gS_ChatStrings.sText, jumps, strafes, sSync, gS_ChatStrings.sText, gS_ChatStrings.sWarning, sDifference); - FormatEx(sQuery, 512, "UPDATE %splayertimes SET time = %.03f, jumps = %d, date = %d, strafes = %d, sync = %.02f, points = 0.0, perfs = %.2f WHERE map = '%s' AND auth = '%s' AND style = %d AND track = %d;", gS_MySQLPrefix, time, jumps, GetTime(), strafes, sync, perfs, gS_Map, sAuthID, style, track); + FormatEx(sQuery, 512, "UPDATE %splayertimes SET time = %f, jumps = %d, date = %d, strafes = %d, sync = %.02f, points = 0.0, perfs = %.2f WHERE map = '%s' AND auth = '%s' AND style = %d AND track = %d;", gS_MySQLPrefix, time, jumps, GetTime(), strafes, sync, perfs, gS_Map, sAuthID, style, track); } gH_SQL.Query(SQL_OnFinish_Callback, sQuery, GetClientSerial(client), DBPrio_High); From ee1dddc8c74dfb2b016c244e33bd93bea2f037fe Mon Sep 17 00:00:00 2001 From: shavit Date: Wed, 27 Mar 2019 11:31:43 +0200 Subject: [PATCH 33/39] Changed track changing in zones menu to be easier (#597). --- addons/sourcemod/scripting/shavit-zones.sp | 86 +++++++++++-------- .../translations/shavit-zones.phrases.txt | 11 +-- 2 files changed, 58 insertions(+), 39 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-zones.sp b/addons/sourcemod/scripting/shavit-zones.sp index 01e3b0259..8ee3fb981 100644 --- a/addons/sourcemod/scripting/shavit-zones.sp +++ b/addons/sourcemod/scripting/shavit-zones.sp @@ -1091,20 +1091,18 @@ public Action Command_Zones(int client, int args) Reset(client); - Menu menu = new Menu(Select_Type_MenuHandler); - menu.SetTitle("%T", "ZoneMenuTitle", client); + Menu menu = new Menu(MenuHandler_SelectZoneTrack); + menu.SetTitle("%T", "ZoneMenuTrack", client); - for(int i = 0; i < sizeof(gS_ZoneNames); i++) + for(int i = 0; i < TRACKS_SIZE; i++) { - if(i == Zone_CustomSpawn) - { - continue; - } - char sInfo[8]; IntToString(i, sInfo, 8); - menu.AddItem(sInfo, gS_ZoneNames[i]); + char sDisplay[16]; + GetTrackName(client, i, sDisplay, 16); + + menu.AddItem(sInfo, sDisplay); } menu.ExitButton = true; @@ -1113,9 +1111,46 @@ public Action Command_Zones(int client, int args) return Plugin_Handled; } +public int MenuHandler_SelectZoneTrack(Menu menu, MenuAction action, int param1, int param2) +{ + if(action == MenuAction_Select) + { + char sInfo[8]; + menu.GetItem(param2, sInfo, 8); + gI_ZoneTrack[param1] = StringToInt(sInfo); + + char sTrack[16]; + GetTrackName(param1, gI_ZoneTrack[param1], sTrack, 16); + + Menu submenu = new Menu(MenuHandler_SelectZoneType); + submenu.SetTitle("%T", "ZoneMenuTitle", param1, sTrack); + + for(int i = 0; i < sizeof(gS_ZoneNames); i++) + { + if(i == Zone_CustomSpawn) + { + continue; + } + + IntToString(i, sInfo, 8); + submenu.AddItem(sInfo, gS_ZoneNames[i]); + } + + submenu.ExitButton = true; + submenu.Display(param1, 20); + } + + else if(action == MenuAction_End) + { + delete menu; + } + + return 0; +} + Action OpenEditMenu(int client) { - Menu menu = new Menu(ZoneEdit_MenuHandler); + Menu menu = new Menu(MenuHandler_ZoneEdit); menu.SetTitle("%T\n ", "ZoneEditTitle", client); char sDisplay[64]; @@ -1157,7 +1192,7 @@ Action OpenEditMenu(int client) return Plugin_Handled; } -public int ZoneEdit_MenuHandler(Menu menu, MenuAction action, int param1, int param2) +public int MenuHandler_ZoneEdit(Menu menu, MenuAction action, int param1, int param2) { if(action == MenuAction_Select) { @@ -1220,7 +1255,7 @@ public Action Command_DeleteZone(int client, int args) Action OpenDeleteMenu(int client) { - Menu menu = new Menu(DeleteZone_MenuHandler); + Menu menu = new Menu(MenuHandler_DeleteZone); menu.SetTitle("%T\n ", "ZoneMenuDeleteTitle", client); char sDisplay[64]; @@ -1261,7 +1296,7 @@ Action OpenDeleteMenu(int client) return Plugin_Handled; } -public int DeleteZone_MenuHandler(Menu menu, MenuAction action, int param1, int param2) +public int MenuHandler_DeleteZone(Menu menu, MenuAction action, int param1, int param2) { if(action == MenuAction_Select) { @@ -1339,7 +1374,7 @@ public Action Command_DeleteAllZones(int client, int args) return Plugin_Handled; } - Menu menu = new Menu(DeleteAllZones_MenuHandler); + Menu menu = new Menu(MenuHandler_DeleteAllZones); menu.SetTitle("%T", "ZoneMenuDeleteALLTitle", client); char sMenuItem[64]; @@ -1365,7 +1400,7 @@ public Action Command_DeleteAllZones(int client, int args) return Plugin_Handled; } -public int DeleteAllZones_MenuHandler(Menu menu, MenuAction action, int param1, int param2) +public int MenuHandler_DeleteAllZones(Menu menu, MenuAction action, int param1, int param2) { if(action == MenuAction_Select) { @@ -1414,7 +1449,7 @@ public void SQL_DeleteAllZones_Callback(Database db, DBResultSet results, const Shavit_PrintToChat(client, "%T", "ZoneDeleteAllSuccessful", client); } -public int Select_Type_MenuHandler(Menu menu, MenuAction action, int param1, int param2) +public int MenuHandler_SelectZoneType(Menu menu, MenuAction action, int param1, int param2) { if(action == MenuAction_Select) { @@ -1772,12 +1807,6 @@ public int CreateZoneConfirm_Handler(Menu menu, MenuAction action, int param1, i UpdateTeleportZone(param1); CreateEditMenu(param1); } - - else if(StrEqual(info, "track")) - { - gI_ZoneTrack[param1] = CycleTracks(gI_ZoneTrack[param1]); - CreateEditMenu(param1); - } } else if(action == MenuAction_End) @@ -1788,16 +1817,6 @@ public int CreateZoneConfirm_Handler(Menu menu, MenuAction action, int param1, i return 0; } -int CycleTracks(int track) -{ - if(++track >= TRACKS_SIZE) - { - return 0; - } - - return track; -} - void GetTrackName(int client, int track, char[] output, int size) { if(track < 0 || track >= TRACKS_SIZE) @@ -1877,10 +1896,9 @@ void CreateEditMenu(int client) FormatEx(sMenuItem, 64, "%T", "ZoneSetNo", client); menu.AddItem("no", sMenuItem); + FormatEx(sMenuItem, 64, "%T", "ZoneSetAdjust", client); menu.AddItem("adjust", sMenuItem); - FormatEx(sMenuItem, 64, "%T", "ZoneChangeTrack", client); - menu.AddItem("track", sMenuItem); menu.ExitButton = true; menu.Display(client, 600); diff --git a/addons/sourcemod/translations/shavit-zones.phrases.txt b/addons/sourcemod/translations/shavit-zones.phrases.txt index a9cc95b0f..a5518f005 100644 --- a/addons/sourcemod/translations/shavit-zones.phrases.txt +++ b/addons/sourcemod/translations/shavit-zones.phrases.txt @@ -129,9 +129,14 @@ { "en" "No zones found." } + "ZoneMenuTrack" + { + "en" "Select a track:" + } "ZoneMenuTitle" { - "en" "Select a zone type:" + "#format" "{1:s}" + "en" "Select a zone type: ({1})" } "ZoneMenuYes" { @@ -199,10 +204,6 @@ "#format" "{1:s}" "en" "Zone track: {1}" } - "ZoneChangeTrack" - { - "en" "Change zone track" - } "ZoneEdit" { "en" "Edit a map zone" From 6a738938576d698740280b1023da3c882753bc29 Mon Sep 17 00:00:00 2001 From: shavit Date: Wed, 27 Mar 2019 11:36:22 +0200 Subject: [PATCH 34/39] Made teleport to last frame of replay playback seamless. --- addons/sourcemod/scripting/shavit-replay.sp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/shavit-replay.sp b/addons/sourcemod/scripting/shavit-replay.sp index 05ea7c32e..d95b26139 100644 --- a/addons/sourcemod/scripting/shavit-replay.sp +++ b/addons/sourcemod/scripting/shavit-replay.sp @@ -1678,7 +1678,7 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3 return Plugin_Changed; } - if(++gI_ReplayTick[style] >= gA_FrameCache[style][track].iFrameCount) + if(++gI_ReplayTick[style] >= gA_FrameCache[style][track].iFrameCount - 1) { gI_ReplayTick[style] = 0; gRS_ReplayStatus[style] = gA_CentralCache.iReplayStatus = Replay_End; From 08afbfa67a614f91512abc5c2d6c9425be5a8ebc Mon Sep 17 00:00:00 2001 From: shavit Date: Wed, 27 Mar 2019 12:59:25 +0200 Subject: [PATCH 35/39] Fixed replay HUD speed with speed multipliers. --- addons/sourcemod/scripting/shavit-hud.sp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/shavit-hud.sp b/addons/sourcemod/scripting/shavit-hud.sp index bb26db657..b7adc4e10 100644 --- a/addons/sourcemod/scripting/shavit-hud.sp +++ b/addons/sourcemod/scripting/shavit-hud.sp @@ -1320,6 +1320,7 @@ void UpdateMainHUD(int client) float fSpeed[3]; GetEntPropVector(target, Prop_Data, "m_vecVelocity", fSpeed); + float fSpeedHUD = ((gI_HUDSettings[client] & HUD_2DVEL) == 0)? GetVectorLength(fSpeed):(SquareRoot(Pow(fSpeed[0], 2.0) + Pow(fSpeed[1], 2.0))); bool bReplay = (gB_Replay && IsFakeClient(target)); ZoneHUD iZoneHUD = ZoneHUD_None; int iReplayStyle = 0; @@ -1349,12 +1350,17 @@ void UpdateMainHUD(int client) { fReplayTime = Shavit_GetReplayTime(iReplayStyle, iReplayTrack); fReplayLength = Shavit_GetReplayLength(iReplayStyle, iReplayTrack); + + if(gA_StyleSettings[iReplayStyle].fSpeedMultiplier != 1.0) + { + fSpeedHUD /= gA_StyleSettings[iReplayStyle].fSpeedMultiplier; + } } } huddata_t huddata; huddata.iTarget = target; - huddata.iSpeed = RoundToNearest(((gI_HUDSettings[client] & HUD_2DVEL) == 0)? GetVectorLength(fSpeed):(SquareRoot(Pow(fSpeed[0], 2.0) + Pow(fSpeed[1], 2.0)))); + huddata.iSpeed = RoundToNearest(fSpeedHUD); huddata.iZoneHUD = iZoneHUD; huddata.iStyle = (bReplay)? iReplayStyle:Shavit_GetBhopStyle(target); huddata.iTrack = (bReplay)? iReplayTrack:Shavit_GetClientTrack(target); From 4388409e0a2aa344b20b02d86b18c8296455a7da Mon Sep 17 00:00:00 2001 From: shavit Date: Wed, 27 Mar 2019 14:21:17 +0200 Subject: [PATCH 36/39] Fixed HSW strafe counter breaking. --- addons/sourcemod/scripting/shavit-core.sp | 52 +++++++++++------------ 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index f48742f8a..c7f13f355 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -2370,6 +2370,32 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3 } #endif + int iPButtons = buttons; + + if(gA_StyleSettings[gA_Timers[client].iStyle].bStrafeCountW && !gA_StyleSettings[gA_Timers[client].iStyle].bBlockW && + (gA_Timers[client].iLastButtons & IN_FORWARD) == 0 && (buttons & IN_FORWARD) > 0) + { + gA_Timers[client].iStrafes++; + } + + if(gA_StyleSettings[gA_Timers[client].iStyle].bStrafeCountA && !gA_StyleSettings[gA_Timers[client].iStyle].bBlockA && (gA_Timers[client].iLastButtons & IN_MOVELEFT) == 0 && + (buttons & IN_MOVELEFT) > 0 && (gA_StyleSettings[gA_Timers[client].iStyle].iForceHSW > 0 || ((buttons & IN_FORWARD) == 0 && (buttons & IN_BACK) == 0))) + { + gA_Timers[client].iStrafes++; + } + + if(gA_StyleSettings[gA_Timers[client].iStyle].bStrafeCountS && !gA_StyleSettings[gA_Timers[client].iStyle].bBlockS && + (gA_Timers[client].iLastButtons & IN_BACK) == 0 && (buttons & IN_BACK) > 0) + { + gA_Timers[client].iStrafes++; + } + + if(gA_StyleSettings[gA_Timers[client].iStyle].bStrafeCountD && !gA_StyleSettings[gA_Timers[client].iStyle].bBlockD && (gA_Timers[client].iLastButtons & IN_MOVERIGHT) == 0 && + (buttons & IN_MOVERIGHT) > 0 && (gA_StyleSettings[gA_Timers[client].iStyle].iForceHSW > 0 || ((buttons & IN_FORWARD) == 0 && (buttons & IN_BACK) == 0))) + { + gA_Timers[client].iStrafes++; + } + MoveType mtMoveType = GetEntityMoveType(client); // key blocking @@ -2486,30 +2512,6 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3 } } - if(gA_StyleSettings[gA_Timers[client].iStyle].bStrafeCountW && !gA_StyleSettings[gA_Timers[client].iStyle].bBlockW && - (gA_Timers[client].iLastButtons & IN_FORWARD) == 0 && (buttons & IN_FORWARD) > 0) - { - gA_Timers[client].iStrafes++; - } - - if(gA_StyleSettings[gA_Timers[client].iStyle].bStrafeCountA && !gA_StyleSettings[gA_Timers[client].iStyle].bBlockA && (gA_Timers[client].iLastButtons & IN_MOVELEFT) == 0 && - (buttons & IN_MOVELEFT) > 0 && (gA_StyleSettings[gA_Timers[client].iStyle].iForceHSW > 0 || ((buttons & IN_FORWARD) == 0 && (buttons & IN_BACK) == 0))) - { - gA_Timers[client].iStrafes++; - } - - if(gA_StyleSettings[gA_Timers[client].iStyle].bStrafeCountS && !gA_StyleSettings[gA_Timers[client].iStyle].bBlockS && - (gA_Timers[client].iLastButtons & IN_BACK) == 0 && (buttons & IN_BACK) > 0) - { - gA_Timers[client].iStrafes++; - } - - if(gA_StyleSettings[gA_Timers[client].iStyle].bStrafeCountD && !gA_StyleSettings[gA_Timers[client].iStyle].bBlockD && (gA_Timers[client].iLastButtons & IN_MOVERIGHT) == 0 && - (buttons & IN_MOVERIGHT) > 0 && (gA_StyleSettings[gA_Timers[client].iStyle].iForceHSW > 0 || ((buttons & IN_FORWARD) == 0 && (buttons & IN_BACK) == 0))) - { - gA_Timers[client].iStrafes++; - } - bool bInWater = (GetEntProp(client, Prop_Send, "m_nWaterLevel") >= 2); // enable duck-jumping/bhop in tf2 @@ -2522,8 +2524,6 @@ public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3 SetEntPropVector(client, Prop_Data, "m_vecAbsVelocity", fSpeed); } - int iPButtons = buttons; - if(gA_StyleSettings[gA_Timers[client].iStyle].bAutobhop && gA_Timers[client].bAuto && (buttons & IN_JUMP) > 0 && mtMoveType == MOVETYPE_WALK && !bInWater) { int iOldButtons = GetEntProp(client, Prop_Data, "m_nOldButtons"); From 54b2371b7092626b1905388448cd84d4ef9a44f1 Mon Sep 17 00:00:00 2001 From: shavit Date: Wed, 27 Mar 2019 14:50:43 +0200 Subject: [PATCH 37/39] Modernized custom spawn points setup and added multi-track support (#756). --- addons/sourcemod/scripting/shavit-zones.sp | 156 +++++++++++++++--- .../translations/shavit-zones.phrases.txt | 16 +- 2 files changed, 147 insertions(+), 25 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-zones.sp b/addons/sourcemod/scripting/shavit-zones.sp index 8ee3fb981..bd9c37942 100644 --- a/addons/sourcemod/scripting/shavit-zones.sp +++ b/addons/sourcemod/scripting/shavit-zones.sp @@ -810,7 +810,7 @@ void UnloadZones(int zone) { if(zone == Zone_CustomSpawn) { - ClearCustomSpawn(); + ClearCustomSpawn(-1); } else @@ -824,7 +824,7 @@ void UnloadZones(int zone) } } - ClearCustomSpawn(); + ClearCustomSpawn(-1); if(zone == 0) { @@ -980,26 +980,69 @@ public Action Command_AddSpawn(int client, int args) return Plugin_Handled; } - if(!IsPlayerAlive(client)) + return DisplayCustomSpawnMenu(client); +} + +Action DisplayCustomSpawnMenu(int client) +{ + Menu menu = new Menu(MenuHandler_AddCustomSpawn); + menu.SetTitle("%T\n ", "ZoneCustomSpawnMenuTitle", client); + + for(int i = 0; i < TRACKS_SIZE; i++) { - Shavit_PrintToChat(client, "%T", "ZoneDead", client); + char sInfo[8]; + IntToString(i, sInfo, 8); - return Plugin_Handled; + char sTrack[32]; + GetTrackName(client, i, sTrack, 32); + + menu.AddItem(sInfo, sTrack); } - if(!EmptyVector(gF_CustomSpawn[Track_Main])) + menu.ExitButton = true; + menu.Display(client, 60); + + return Plugin_Handled; +} + +public int MenuHandler_AddCustomSpawn(Menu menu, MenuAction action, int param1, int param2) +{ + if(action == MenuAction_Select) { - Shavit_PrintToChat(client, "%T", "ZoneCustomSpawnExists", client); + if(!IsPlayerAlive(param1)) + { + Shavit_PrintToChat(param1, "%T", "ZoneDead", param1); - return Plugin_Handled; - } + return 0; + } - gI_ZoneType[client] = Zone_CustomSpawn; + char sInfo[8]; + menu.GetItem(param2, sInfo, 8); + int iTrack = StringToInt(sInfo); + + if(!EmptyVector(gF_CustomSpawn[iTrack])) + { + char sTrack[32]; + GetTrackName(param1, iTrack, sTrack, 32); - GetClientAbsOrigin(client, gV_Point1[client]); - InsertZone(client); + Shavit_PrintToChat(param1, "%T", "ZoneCustomSpawnExists", param1, gS_ChatStrings.sVariable, sTrack, gS_ChatStrings.sText); - return Plugin_Handled; + return 0; + } + + gI_ZoneType[param1] = Zone_CustomSpawn; + gI_ZoneTrack[param1] = iTrack; + GetClientAbsOrigin(param1, gV_Point1[param1]); + + InsertZone(param1); + } + + else if(action == MenuAction_End) + { + delete menu; + } + + return 0; } public Action Command_DelSpawn(int client, int args) @@ -1009,16 +1052,68 @@ public Action Command_DelSpawn(int client, int args) return Plugin_Handled; } - Shavit_LogMessage("%L - deleted custom spawn from map `%s`.", client, gS_Map); + return DisplayCustomSpawnDeleteMenu(client); +} - char sQuery[256]; - FormatEx(sQuery, 256, "DELETE FROM %smapzones WHERE type = '%d' AND map = '%s';", gS_MySQLPrefix, Zone_CustomSpawn, gS_Map); +Action DisplayCustomSpawnDeleteMenu(int client) +{ + Menu menu = new Menu(MenuHandler_DeleteCustomSpawn); + menu.SetTitle("%T\n ", "ZoneCustomSpawnMenuDeleteTitle", client); - gH_SQL.Query(SQL_DeleteCustom_Spawn_Callback, sQuery, GetClientSerial(client)); + for(int i = 0; i < TRACKS_SIZE; i++) + { + char sInfo[8]; + IntToString(i, sInfo, 8); + + char sTrack[32]; + GetTrackName(client, i, sTrack, 32); + + menu.AddItem(sInfo, sTrack, (EmptyVector(gF_CustomSpawn[i]))? ITEMDRAW_DISABLED:ITEMDRAW_DEFAULT); + } + + menu.ExitButton = true; + menu.Display(client, 60); return Plugin_Handled; } +public int MenuHandler_DeleteCustomSpawn(Menu menu, MenuAction action, int param1, int param2) +{ + if(action == MenuAction_Select) + { + char sInfo[8]; + menu.GetItem(param2, sInfo, 8); + int iTrack = StringToInt(sInfo); + + if(EmptyVector(gF_CustomSpawn[iTrack])) + { + char sTrack[32]; + GetTrackName(param1, iTrack, sTrack, 32); + + Shavit_PrintToChat(param1, "%T", "ZoneCustomSpawnMissing", param1, gS_ChatStrings.sVariable, sTrack, gS_ChatStrings.sText); + + return 0; + } + + gI_ZoneTrack[param1] = iTrack; + Shavit_LogMessage("%L - deleted custom spawn from map `%s`.", param1, gS_Map); + + char sQuery[256]; + FormatEx(sQuery, 256, + "DELETE FROM %smapzones WHERE type = '%d' AND map = '%s' AND track = %d;", + gS_MySQLPrefix, Zone_CustomSpawn, gS_Map, iTrack); + + gH_SQL.Query(SQL_DeleteCustom_Spawn_Callback, sQuery, GetClientSerial(param1)); + } + + else if(action == MenuAction_End) + { + delete menu; + } + + return 0; +} + public void SQL_DeleteCustom_Spawn_Callback(Database db, DBResultSet results, const char[] error, any data) { if(results == null) @@ -1035,14 +1130,23 @@ public void SQL_DeleteCustom_Spawn_Callback(Database db, DBResultSet results, co return; } - ClearCustomSpawn(); - + ClearCustomSpawn(gI_ZoneTrack[client]); Shavit_PrintToChat(client, "%T", "ZoneCustomSpawnDelete", client); } -void ClearCustomSpawn() +void ClearCustomSpawn(int track) { - gF_CustomSpawn[Track_Main] = NULL_VECTOR; + if(track != -1) + { + gF_CustomSpawn[track] = NULL_VECTOR; + + return; + } + + for(int i = 0; i < TRACKS_SIZE; i++) + { + gF_CustomSpawn[i] = NULL_VECTOR; + } } void ClearPrebuiltZones() @@ -1994,14 +2098,17 @@ void InsertZone(int client) { Shavit_LogMessage("%L - added custom spawn {%.2f, %.2f, %.2f} to map `%s`.", client, gV_Point1[client][0], gV_Point1[client][1], gV_Point1[client][2], gS_Map); - FormatEx(sQuery, 512, "INSERT INTO %smapzones (map, type, destination_x, destination_y, destination_z) VALUES ('%s', %d, '%.03f', '%.03f', '%.03f');", gS_MySQLPrefix, gS_Map, Zone_CustomSpawn, gV_Point1[client][0], gV_Point1[client][1], gV_Point1[client][2]); + FormatEx(sQuery, 512, + "INSERT INTO %smapzones (map, type, destination_x, destination_y, destination_z, track) VALUES ('%s', %d, '%.03f', '%.03f', '%.03f', %d);", + gS_MySQLPrefix, gS_Map, Zone_CustomSpawn, gV_Point1[client][0], gV_Point1[client][1], gV_Point1[client][2], gI_ZoneTrack[client]); } else if(insert) // insert { Shavit_LogMessage("%L - added %s to map `%s`.", client, gS_ZoneNames[type], gS_Map); - FormatEx(sQuery, 512, "INSERT INTO %smapzones (map, type, corner1_x, corner1_y, corner1_z, corner2_x, corner2_y, corner2_z, destination_x, destination_y, destination_z, track) VALUES ('%s', %d, '%.03f', '%.03f', '%.03f', '%.03f', '%.03f', '%.03f', '%.03f', '%.03f', '%.03f', %d);", + FormatEx(sQuery, 512, + "INSERT INTO %smapzones (map, type, corner1_x, corner1_y, corner1_z, corner2_x, corner2_y, corner2_z, destination_x, destination_y, destination_z, track) VALUES ('%s', %d, '%.03f', '%.03f', '%.03f', '%.03f', '%.03f', '%.03f', '%.03f', '%.03f', '%.03f', %d);", gS_MySQLPrefix, gS_Map, type, gV_Point1[client][0], gV_Point1[client][1], gV_Point1[client][2], gV_Point2[client][0], gV_Point2[client][1], gV_Point2[client][2], gV_Teleport[client][0], gV_Teleport[client][1], gV_Teleport[client][2], gI_ZoneTrack[client]); } @@ -2020,7 +2127,8 @@ void InsertZone(int client) } } - FormatEx(sQuery, 512, "UPDATE %smapzones SET corner1_x = '%.03f', corner1_y = '%.03f', corner1_z = '%.03f', corner2_x = '%.03f', corner2_y = '%.03f', corner2_z = '%.03f', destination_x = '%.03f', destination_y = '%.03f', destination_z = '%.03f', track = %d WHERE %s = %d;", + FormatEx(sQuery, 512, + "UPDATE %smapzones SET corner1_x = '%.03f', corner1_y = '%.03f', corner1_z = '%.03f', corner2_x = '%.03f', corner2_y = '%.03f', corner2_z = '%.03f', destination_x = '%.03f', destination_y = '%.03f', destination_z = '%.03f', track = %d WHERE %s = %d;", gS_MySQLPrefix, gV_Point1[client][0], gV_Point1[client][1], gV_Point1[client][2], gV_Point2[client][0], gV_Point2[client][1], gV_Point2[client][2], gV_Teleport[client][0], gV_Teleport[client][1], gV_Teleport[client][2], gI_ZoneTrack[client], (gB_MySQL)? "id":"rowid", gI_ZoneDatabaseID[client]); } diff --git a/addons/sourcemod/translations/shavit-zones.phrases.txt b/addons/sourcemod/translations/shavit-zones.phrases.txt index a5518f005..3c43ce515 100644 --- a/addons/sourcemod/translations/shavit-zones.phrases.txt +++ b/addons/sourcemod/translations/shavit-zones.phrases.txt @@ -31,9 +31,23 @@ "#format" "{1:s},{2:s}" "en" "You {1}cannot{2} setup mapzones when you're dead." } + "ZoneCustomSpawnMenuTitle" + { + "en" "Add custom spawn for track:" + } + "ZoneCustomSpawnMenuDeleteTitle" + { + "en" "Delete custom spawn for track:" + } "ZoneCustomSpawnExists" { - "en" "Custom Spawn already exists. Please delete it before placing a new one." + "#format" "{1:s},{2:s},{3:s}" + "en" "Custom Spawn for track {1}{2}{3} already exists. Please delete it before placing a new one." + } + "ZoneCustomSpawnMissing" + { + "#format" "{1:s},{2:s},{3:s}" + "en" "Custom Spawn for track {1}{2}{3} is missing." } "ZoneCustomSpawnDelete" { From 39572abfd9a68203c68816f71ce0370c01ebc893 Mon Sep 17 00:00:00 2001 From: shavit Date: Wed, 27 Mar 2019 19:50:03 +0200 Subject: [PATCH 38/39] Added persisting timer data (#757). --- addons/sourcemod/scripting/shavit-core.sp | 2 +- addons/sourcemod/scripting/shavit-misc.sp | 209 +++++++++++++++++++- addons/sourcemod/scripting/shavit-replay.sp | 10 +- 3 files changed, 215 insertions(+), 6 deletions(-) diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index c7f13f355..be2d55b42 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -1712,7 +1712,7 @@ void ResumeTimer(int client) public void OnClientDisconnect(int client) { - StopTimer(client); + RequestFrame(StopTimer, client); } public void OnClientCookiesCached(int client) diff --git a/addons/sourcemod/scripting/shavit-misc.sp b/addons/sourcemod/scripting/shavit-misc.sp index 06c176fa7..f1c11f0d2 100644 --- a/addons/sourcemod/scripting/shavit-misc.sp +++ b/addons/sourcemod/scripting/shavit-misc.sp @@ -73,6 +73,21 @@ enum struct player_cpcache_t int iCurrentCheckpoint; } +enum struct persistent_data_t +{ + char sAuthID[32]; + float fDisconnectTime; + float fPosition[3]; + float fAngles[3]; + MoveType iMoveType; + float fGravity; + float fSpeed; + timer_snapshot_t aSnapshot; + int iTargetname; + int iClassname; + ArrayList aFrames; +} + // game specific EngineVersion gEV_Type = Engine_Unknown; int gI_Ammo = -1; @@ -109,6 +124,7 @@ timer_snapshot_t gA_SaveStates[MAXPLAYERS+1]; bool gB_SaveStates[MAXPLAYERS+1]; char gS_SaveStateTargetname[MAXPLAYERS+1][32]; ArrayList gA_SaveFrames[MAXPLAYERS+1]; +ArrayList gA_PersistentData = null; // cookies Handle gH_HideCookie = null; @@ -147,6 +163,7 @@ ConVar gCV_SpectatorList = null; ConVar gCV_MaxCP = null; ConVar gCV_MaxCP_Segmented = null; ConVar gCV_HideChatCommands = null; +ConVar gCV_PersistData = null; // forwards Handle gH_Forwards_OnClanTagChangePre = null; @@ -231,6 +248,7 @@ public void OnPluginStart() gSM_Checkpoints = new StringMap(); gA_Targetnames = new ArrayList(ByteCountToCells(64)); gA_Classnames = new ArrayList(ByteCountToCells(64)); + gA_PersistentData = new ArrayList(sizeof(persistent_data_t)); gI_Ammo = FindSendPropInfo("CCSPlayer", "m_iAmmo"); @@ -305,6 +323,7 @@ public void OnPluginStart() gCV_MaxCP = CreateConVar("shavit_misc_maxcp", "1000", "Maximum amount of checkpoints.\nNote: Very high values will result in high memory usage!", 0, true, 1.0, true, 10000.0); gCV_MaxCP_Segmented = CreateConVar("shavit_misc_maxcp_seg", "10", "Maximum amount of segmented checkpoints. Make this less or equal to shavit_misc_maxcp.\nNote: Very high values will result in HUGE memory usage!", 0, true, 1.0, true, 50.0); gCV_HideChatCommands = CreateConVar("shavit_misc_hidechatcmds", "1", "Hide commands from chat?\n0 - Disabled\n1 - Enabled", 0, true, 0.0, true, 1.0); + gCV_PersistData = CreateConVar("shavit_misc_persistdata", "300", "How long to persist timer data for disconnected users in seconds?\n-1 - Until map change\n0 - Disabled"); AutoExecConfig(); @@ -316,6 +335,8 @@ public void OnPluginStart() } // crons + CreateTimer(10.0, Timer_Cron, 0, TIMER_REPEAT); + if(gEV_Type != Engine_TF2) { CreateTimer(1.0, Timer_Scoreboard, 0, TIMER_REPEAT); @@ -461,9 +482,20 @@ public void OnMapStart() ResetCheckpoints(i); } + int iLength = gA_PersistentData.Length; + + for(int i = iLength - 1; i >= 0; i--) + { + persistent_data_t aData; + gA_PersistentData.GetArray(i, aData); + + delete aData.aFrames; + } + gSM_Checkpoints.Clear(); gA_Targetnames.Clear(); gA_Classnames.Clear(); + gA_PersistentData.Clear(); GetCurrentMap(gS_CurrentMap, 192); GetMapDisplayName(gS_CurrentMap, gS_CurrentMap, 192); @@ -724,6 +756,25 @@ public MRESReturn CCSPlayer__GetPlayerMaxSpeed(int pThis, Handle hReturn) return MRES_Override; } +public Action Timer_Cron(Handle Timer) +{ + int iLength = gA_PersistentData.Length; + float fTime = GetEngineTime(); + + for(int i = iLength - 1; i >= 0; i--) + { + persistent_data_t aData; + gA_PersistentData.GetArray(i, aData); + + if(fTime - aData.fDisconnectTime >= gCV_PersistData.FloatValue) + { + DeletePersistentData(i, aData); + } + } + + return Plugin_Continue; +} + public Action Timer_Scoreboard(Handle Timer) { for(int i = 1; i <= MaxClients; i++) @@ -1013,7 +1064,6 @@ public void OnClientPutInServer(int client) ResetCheckpoints(client); gB_SaveStates[client] = false; - delete gA_SaveFrames[client]; } @@ -1032,7 +1082,159 @@ public void OnClientDisconnect(int client) } } + if(IsFakeClient(client)) + { + return; + } + ResetCheckpoints(client); + + gB_SaveStates[client] = false; + delete gA_SaveFrames[client]; + + PersistData(client); +} + +void PersistData(int client) +{ + persistent_data_t aData; + + if(!IsPlayerAlive(client) || + !GetClientAuthId(client, AuthId_Steam3, aData.sAuthID, 32) || + Shavit_GetTimerStatus(client) == Timer_Stopped || + gCV_PersistData.IntValue == 0) + { + return; + } + + if(gB_Replay) + { + aData.aFrames = Shavit_GetReplayData(client); + } + + aData.fDisconnectTime = GetEngineTime(); + aData.iMoveType = GetEntityMoveType(client); + aData.fGravity = GetEntityGravity(client); + aData.fSpeed = GetEntPropFloat(client, Prop_Send, "m_flLaggedMovementValue"); + + float fPosition[3]; + GetClientAbsOrigin(client, fPosition); + CopyArray(fPosition, aData.fPosition, 3); + + float fAngles[3]; + GetClientEyeAngles(client, fAngles); + CopyArray(fAngles, aData.fAngles, 3); + + timer_snapshot_t aSnapshot; + Shavit_SaveSnapshot(client, aSnapshot); + CopyArray(aSnapshot, aData.aSnapshot, sizeof(timer_snapshot_t)); + + char sTargetname[64]; + GetEntPropString(client, Prop_Data, "m_iName", sTargetname, 64); + + aData.iTargetname = gA_Targetnames.FindString(sTargetname); + + if(aData.iTargetname == -1) + { + aData.iTargetname = gA_Targetnames.PushString(sTargetname); + } + + char sClassname[64]; + GetEntityClassname(client, sClassname, 64); + + aData.iClassname = gA_Classnames.FindString(sClassname); + + if(aData.iClassname == -1) + { + aData.iClassname = gA_Classnames.PushString(sClassname); + } + + gA_PersistentData.PushArray(aData); +} + +void DeletePersistentData(int index, persistent_data_t data) +{ + delete data.aFrames; + gA_PersistentData.Erase(index); +} + +public Action Timer_LoadPersistentData(Handle Timer, any data) +{ + char sAuthID[32]; + int client = GetClientFromSerial(data); + + if(client == 0 || + !GetClientAuthId(client, AuthId_Steam3, sAuthID, 32) || + GetClientTeam(client) < 2 || + !IsPlayerAlive(client)) + { + return Plugin_Stop; + } + + persistent_data_t aData; + int iIndex = -1; + int iLength = gA_PersistentData.Length; + + for(int i = 0; i < iLength; i++) + { + gA_PersistentData.GetArray(i, aData); + + if(StrEqual(sAuthID, aData.sAuthID)) + { + iIndex = i; + + break; + } + } + + if(iIndex == -1) + { + return Plugin_Stop; + } + + Shavit_StopTimer(client); + + float fPosition[3]; + CopyArray(aData.fPosition, fPosition, 3); + + float fAngles[3]; + CopyArray(aData.fAngles, fAngles, 3); + + SetEntityMoveType(client, aData.iMoveType); + SetEntityGravity(client, aData.fGravity); + SetEntPropFloat(client, Prop_Send, "m_flLaggedMovementValue", aData.fSpeed); + + timer_snapshot_t aSnapshot; + CopyArray(aData.aSnapshot, aSnapshot, sizeof(timer_snapshot_t)); + Shavit_LoadSnapshot(client, aSnapshot); + + if(aData.iTargetname != -1) + { + char sTargetname[64]; + gA_Targetnames.GetString(aData.iTargetname, sTargetname, 64); + + SetEntPropString(client, Prop_Data, "m_iName", sTargetname); + } + + if(aData.iClassname != -1) + { + char sClassname[64]; + gA_Classnames.GetString(aData.iClassname, sClassname, 64); + + SetEntPropString(client, Prop_Data, "m_iClassname", sClassname); + } + + if(gB_Replay && aData.aFrames != null) + { + Shavit_SetReplayData(client, aData.aFrames); + } + + TeleportEntity(client, fPosition, fAngles, view_as({ 0.0, 0.0, 0.0 })); + + delete aData.aFrames; + gA_PersistentData.Erase(iIndex); + + return Plugin_Stop; } void RemoveWeapon(any data) @@ -2557,6 +2759,11 @@ public void Player_Spawn(Event event, const char[] name, bool dontBroadcast) } } + else + { + CreateTimer(0.10, Timer_LoadPersistentData, GetClientSerial(client), TIMER_FLAG_NO_MAPCHANGE); + } + if(gCV_Scoreboard.BoolValue) { UpdateScoreboard(client); diff --git a/addons/sourcemod/scripting/shavit-replay.sp b/addons/sourcemod/scripting/shavit-replay.sp index d95b26139..17f78344b 100644 --- a/addons/sourcemod/scripting/shavit-replay.sp +++ b/addons/sourcemod/scripting/shavit-replay.sp @@ -1460,10 +1460,7 @@ public void OnClientDisconnect(int client) if(!IsFakeClient(client)) { - if(gA_PlayerFrames[client] != null) - { - delete gA_PlayerFrames[client]; - } + RequestFrame(DeleteFrames, client); return; } @@ -1486,6 +1483,11 @@ public void OnClientDisconnect(int client) } } +public void DeleteFrames(int client) +{ + delete gA_PlayerFrames[client]; +} + public Action Shavit_OnStart(int client) { ClearFrames(client); From 40d443180eb22e1bc21d6c630113ac192059236a Mon Sep 17 00:00:00 2001 From: shavit Date: Wed, 27 Mar 2019 22:02:30 +0200 Subject: [PATCH 39/39] Disabled timer from starting before cookies are loaded. --- addons/sourcemod/scripting/shavit-core.sp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/shavit-core.sp b/addons/sourcemod/scripting/shavit-core.sp index be2d55b42..2e42b7310 100644 --- a/addons/sourcemod/scripting/shavit-core.sp +++ b/addons/sourcemod/scripting/shavit-core.sp @@ -145,6 +145,7 @@ char gS_LogPath[PLATFORM_MAX_PATH]; char gS_DeleteMap[MAXPLAYERS+1][160]; char gS_WipePlayerID[MAXPLAYERS+1][32]; char gS_Verification[MAXPLAYERS+1][16]; +bool gB_CookiesRetrieved[MAXPLAYERS+1]; // flags int gI_StyleFlag[STYLE_LIMIT]; @@ -1622,7 +1623,7 @@ int GetTimerStatus(int client) void StartTimer(int client, int track) { - if(!IsValidClient(client, true) || GetClientTeam(client) < 2 || IsFakeClient(client)) + if(!IsValidClient(client, true) || GetClientTeam(client) < 2 || IsFakeClient(client) || !gB_CookiesRetrieved[client]) { return; } @@ -1748,6 +1749,8 @@ public void OnClientCookiesCached(int client) { CallOnStyleChanged(client, gA_Timers[client].iStyle, style, false); } + + gB_CookiesRetrieved[client] = true; } public void OnClientPutInServer(int client) @@ -1768,6 +1771,8 @@ public void OnClientPutInServer(int client) gA_Timers[client].iStyle = 0; strcopy(gS_DeleteMap[client], 160, ""); + gB_CookiesRetrieved[client] = false; + if(AreClientCookiesCached(client)) { OnClientCookiesCached(client);