From b3683fb9d7e5c08a52921fb8faa33df70d8e21e1 Mon Sep 17 00:00:00 2001 From: qawery-just-sad <53490397+qawery-just-sad@users.noreply.github.com> Date: Mon, 12 Apr 2021 21:49:02 +0200 Subject: [PATCH] Fixes rtv issues with rank/point requirement (#15) -added option for vips to bypass rank/points requirement -players outside rank/points requirement are not counted towards votes needed -added one player bypass -version++ --- README.md | 16 +- addons/sourcemod/scripting/mapchooser.sp | 200 ++++++++++++++++-- addons/sourcemod/scripting/nominations.sp | 2 +- addons/sourcemod/scripting/rockthevote.sp | 242 +++++++++++++++++++--- addons/sourcemod/scripting/voteextend.sp | 2 +- 5 files changed, 405 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 895dc32..c32c262 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This is a edit of the default SourceMod mapchooser and nomination plugin, it pro * Sourcemod 1.8+ * MySQL 5.7 / 8+ / MariaDB supported -* SurfTimer from [Olokos](https://github.com/surftimer/Surftimer-olokos) +* [SurfTimer](https://github.com/surftimer/Surftimer-Official)
I mean it works with any fork as long as the layout of ck_maptier and ck_zones are the same as in [Fluffys](https://github.com/fluffyst/Surftimer) archived repo :wink: **Compilation Requirements (Includes):** @@ -22,18 +22,6 @@ This is a edit of the default SourceMod mapchooser and nomination plugin, it pro * Get latest plugin files from **[Release Page](https://github.com/qawery-just-sad/surftimer-mapchooser/releases)** * Copy files over to `csgo/addons/sourcemod/plugins` -* Make sure that `csgo/addons/sourcemod/configs/databases.cfg` points to the surftimer database (You have to use the same database as the SurfTimer) -``` -"surftimer" - { - "driver" "mysql" - "host" "localhost" // The ip address to the database server - "database" "surftimerdb" // The database name that surftimer uses - "user" "dbuser" // The user name that has access to that database - "pass" "dbuserpassword" // The password for user specified above - "port" "3306" // The port to the database server - } -``` * Set `sm_server_tier` in `csgo/cfg/sourcemod/mapchooser.cfg` to the tier of maps you want appearing the nominate list. Example, for a tier 1-3 server, set it to `sm_server_tier 1.3`, a tier 1 only server would be `sm_server_tier 1.0` and if you want all tiers `sm_server_tier 0` -
This plugin is broken, trust me, it only works on my server :smile: +
This plugin is broken, trust me, it only works on my server 😝 diff --git a/addons/sourcemod/scripting/mapchooser.sp b/addons/sourcemod/scripting/mapchooser.sp index 63a437d..38d076e 100644 --- a/addons/sourcemod/scripting/mapchooser.sp +++ b/addons/sourcemod/scripting/mapchooser.sp @@ -46,7 +46,7 @@ public Plugin myinfo = name = "SurfTimer MapChooser", author = "AlliedModders LLC & SurfTimer Contributors", description = "Automated Map Voting", - version = "1.8", + version = "1.8.3", url = "https://github.com/qawery-just-sad/surftimer-mapchooser" }; @@ -75,6 +75,8 @@ ConVar g_Cvar_RunOffPercent; ConVar g_Cvar_ServerTier; ConVar g_Cvar_PointsRequirement; ConVar g_Cvar_RankRequirement; +ConVar g_Cvar_VIPOverwriteRequirements; +ConVar g_PlayerOne; // Chat prefix char g_szChatPrefix[256]; @@ -103,6 +105,10 @@ bool g_ChangeMapAtRoundEnd; bool g_ChangeMapInProgress; // int g_mapFileSerial = -1; +bool g_PointsREQ[MAXPLAYERS+1] = {false, ...}; +bool g_RankREQ[MAXPLAYERS+1] = {false, ...}; +int g_Voters; + MapChange g_ChangeTime; Handle g_NominationsResetForward = null; @@ -116,6 +122,8 @@ Handle g_hDb = null; char sql_SelectMapListSpecific[] = "SELECT ck_zones.mapname, tier, count(ck_zones.mapname), bonus FROM `ck_zones` INNER JOIN ck_maptier on ck_zones.mapname = ck_maptier.mapname LEFT JOIN ( SELECT mapname as map_2, MAX(ck_zones.zonegroup) as bonus FROM ck_zones GROUP BY mapname ) as a on ck_zones.mapname = a.map_2 WHERE (zonegroup = 0 AND zonetype = 1 or zonetype = 3) AND tier = %s GROUP BY mapname, tier, bonus ORDER BY mapname ASC"; char sql_SelectMapListRange[] = "SELECT ck_zones.mapname, tier, count(ck_zones.mapname), bonus FROM `ck_zones` INNER JOIN ck_maptier on ck_zones.mapname = ck_maptier.mapname LEFT JOIN ( SELECT mapname as map_2, MAX(ck_zones.zonegroup) as bonus FROM ck_zones GROUP BY mapname ) as a on ck_zones.mapname = a.map_2 WHERE (zonegroup = 0 AND zonetype = 1 or zonetype = 3) AND tier >= %s AND tier <= %s GROUP BY mapname, tier, bonus ORDER BY mapname ASC"; char sql_SelectMapList[] = "SELECT ck_zones.mapname, tier, count(ck_zones.mapname), bonus FROM `ck_zones` INNER JOIN ck_maptier on ck_zones.mapname = ck_maptier.mapname LEFT JOIN ( SELECT mapname as map_2, MAX(ck_zones.zonegroup) as bonus FROM ck_zones GROUP BY mapname ) as a on ck_zones.mapname = a.map_2 WHERE (zonegroup = 0 AND zonetype = 1 or zonetype = 3) GROUP BY mapname, tier, bonus ORDER BY mapname ASC"; +char sql_SelectRank[] = "SELECT COUNT(*) FROM ck_playerrank WHERE style = 0 AND points >= (SELECT points FROM ck_playerrank WHERE steamid = '%s' AND style = 0);"; +char sql_SelectPoints[] = "SELECT points FROM ck_playerrank WHERE steamid = '%s' AND style = 0"; /* Upper bound of how many team there could be */ #define MAXTEAMS 10 @@ -246,6 +254,7 @@ public void OnConfigsExecuted() // } // } + g_ChatPrefix = FindConVar("ck_chat_prefix"); GetConVarString(g_ChatPrefix, g_szChatPrefix, sizeof(g_szChatPrefix)); @@ -296,7 +305,25 @@ public void OnMapEnd() if (g_OldMapList.Length > g_Cvar_ExcludeMaps.IntValue) { g_OldMapList.Erase(0); - } + } + + for ( int i=1 ; i<=MAXPLAYERS ; i++ ) + { + g_RankREQ[i] = false; + g_PointsREQ[i] = false; + } + g_Voters = 0; +} + +public void OnClientPostAdminCheck(int client) +{ + if (IsFakeClient(client)) + { + return; + } + g_Voters++; + GetPlayerRank(client); + GetPlayerPoints(client); } public void OnClientDisconnect(int client) @@ -317,6 +344,14 @@ public void OnClientDisconnect(int client) g_NominateOwners.Erase(index); g_NominateList.Erase(index); + + if (IsFakeClient(client)) + { + return; + } + g_RankREQ[client] = false; + g_PointsREQ[client] = false; + g_Voters--; } public Action Command_SetNextmap(int client, int args) @@ -1360,32 +1395,167 @@ public void GetMapDisplayNameTier(char[] szMapName, char szBuffer[PLATFORM_MAX_P public bool DisplayVoteToPros(int time, int flags, Menu menu) { + g_PlayerOne = FindConVar("sm_rtv_oneplayer"); int total = 0; int[] players = new int[MaxClients]; - g_Cvar_PointsRequirement = FindConVar("sm_rtv_point_requirement"); - g_Cvar_RankRequirement = FindConVar("sm_rtv_rank_requirement"); - for (int i = 1; i <= MaxClients; i++) - { - if (!IsClientInGame(i) || IsFakeClient(i)) - continue; - if (g_Cvar_PointsRequirement != null && GetConVarInt(g_Cvar_PointsRequirement) > 0) + if (g_Voters == 1 && GetConVarBool(g_PlayerOne)) + { + for (int i = 1; i <= MaxClients; i++) { - if (surftimer_GetPlayerPoints(i) < GetConVarInt(g_Cvar_PointsRequirement)) + if (!IsClientInGame(i) || IsFakeClient(i)) { continue; } - } - if (g_Cvar_RankRequirement != null && GetConVarInt(g_Cvar_RankRequirement) > 0) + players[total++] = i; + } + } + else + { + for (int i = 1; i <= MaxClients; i++) { - if (surftimer_GetPlayerRank(i) > GetConVarInt(g_Cvar_RankRequirement) || surftimer_GetPlayerRank(i) == 0) + if (!IsClientInGame(i) || IsFakeClient(i)) + { + continue; + } + + if (GetConVarInt(g_Cvar_RankRequirement) > 0 && !g_RankREQ[i]) + { + continue; + } + + if (GetConVarInt(g_Cvar_PointsRequirement) > 0 && !g_PointsREQ[i]) { continue; } - } - players[total++] = i; + players[total++] = i; + } } menu.DisplayVote(players, total, time, flags); } + +stock bool VIPBypass(int client) +{ + g_Cvar_VIPOverwriteRequirements = FindConVar("sm_rtv_vipoverwrite"); + if (surftimer_IsClientVip(client) && GetConVarBool(g_Cvar_VIPOverwriteRequirements)) + { + return true; + } + else + { + return false; + } +} + +stock bool IsValidClient(int client) +{ + if (client >= 1 && client <= MaxClients && IsValidEntity(client) && IsClientConnected(client) && IsClientInGame(client)) + return true; + return false; +} + +void GetPlayerRank(int client) +{ + g_Cvar_RankRequirement = FindConVar("sm_rtv_rank_requirement"); + if (!(GetConVarInt(g_Cvar_RankRequirement) > 0)) + { + return; + } + + char szQuery[256], steamid[32]; + GetClientAuthId(client, AuthId_Steam2, steamid, MAX_NAME_LENGTH, true); + + FormatEx(szQuery, sizeof(szQuery), sql_SelectRank, steamid); + SQL_TQuery(g_hDb, GetPlayerRankCallBack, szQuery, client, DBPrio_Normal); +} + +void GetPlayerRankCallBack(Handle owner, Handle hndl, const char[] error, any client) +{ + if (hndl == null){ + LogError("[RTV] SQL Error (GetPlayerRankCallBack): %s", error); + return; + } + + if(!IsValidClient(client)) + { + return; + } + + if (SQL_HasResultSet(hndl) && SQL_FetchRow(hndl)) + { + int rank = SQL_FetchInt(hndl,0); + if(rank <= 0) + { + g_RankREQ[client] = false; + return; + } + + if(rank < GetConVarInt(g_Cvar_RankRequirement)) + { + g_RankREQ[client] = true; + } + else if (VIPBypass(client)) + { + g_RankREQ[client] = true; + } + else + { + g_RankREQ[client] = false; + } + + } +} + +void GetPlayerPoints(int client) +{ + g_Cvar_PointsRequirement = FindConVar("sm_rtv_point_requirement"); + if (!(GetConVarInt(g_Cvar_PointsRequirement) > 0)) + { + return; + } + + char szQuery[256], steamid[32]; + GetClientAuthId(client, AuthId_Steam2, steamid, MAX_NAME_LENGTH, true); + + FormatEx(szQuery, sizeof(szQuery), sql_SelectPoints, steamid); + SQL_TQuery(g_hDb, GetPlayerPointsCallBack, szQuery, client, DBPrio_Normal); +} + +void GetPlayerPointsCallBack(Handle owner, Handle hndl, const char[] error, any client) +{ + if (hndl == null){ + LogError("[RTV] SQL Error (GetPlayerPointsCallBack): %s", error); + return; + } + + if(!IsValidClient(client)) + { + return; + } + + if (SQL_HasResultSet(hndl) && SQL_FetchRow(hndl)) + { + int points = SQL_FetchInt(hndl,0); + if(points <= 0) + { + g_PointsREQ[client] = false; + return; + } + + if(points > GetConVarInt(g_Cvar_PointsRequirement)) + { + g_PointsREQ[client] = true; + } + else if (VIPBypass(client)) + { + g_PointsREQ[client] = true; + } + else + { + g_PointsREQ[client] = false; + } + + } +} \ No newline at end of file diff --git a/addons/sourcemod/scripting/nominations.sp b/addons/sourcemod/scripting/nominations.sp index 155c303..3f6eae0 100644 --- a/addons/sourcemod/scripting/nominations.sp +++ b/addons/sourcemod/scripting/nominations.sp @@ -43,7 +43,7 @@ public Plugin myinfo = name = "SurfTimer Nominations", author = "AlliedModders LLC & SurfTimer Contributors", description = "Provides Map Nominations", - version = "1.8", + version = "1.8.3", url = "https://github.com/qawery-just-sad/surftimer-mapchooser" }; diff --git a/addons/sourcemod/scripting/rockthevote.sp b/addons/sourcemod/scripting/rockthevote.sp index 9c31b58..ce0f949 100644 --- a/addons/sourcemod/scripting/rockthevote.sp +++ b/addons/sourcemod/scripting/rockthevote.sp @@ -45,7 +45,7 @@ public Plugin myinfo = name = "SurfTimer Rock The Vote", author = "AlliedModders LLC & SurfTimer Contributors", description = "Provides RTV Map Voting", - version = "1.8", + version = "1.8.3", url = "https://github.com/qawery-just-sad/surftimer-mapchooser" }; @@ -57,6 +57,8 @@ ConVar g_Cvar_ChangeTime; ConVar g_Cvar_RTVPostVoteAction; ConVar g_Cvar_PointsRequirement; ConVar g_Cvar_RankRequirement; +ConVar g_Cvar_VIPOverwriteRequirements; +ConVar g_PlayerOne; // Chat prefix char g_szChatPrefix[256]; @@ -68,12 +70,19 @@ int g_Votes = 0; // Total number of "say rtv" votes int g_VotesNeeded = 0; // Necessary votes before map vote begins. (voters * percent_needed) bool g_Voted[MAXPLAYERS+1] = {false, ...}; +bool g_PointsREQ[MAXPLAYERS+1] = {false, ...}; +bool g_RankREQ[MAXPLAYERS+1] = {false, ...}; + bool g_InChange = false; +Handle g_hDb = null; +char sql_SelectRank[] = "SELECT COUNT(*) FROM ck_playerrank WHERE style = 0 AND points >= (SELECT points FROM ck_playerrank WHERE steamid = '%s' AND style = 0);"; +char sql_SelectPoints[] = "SELECT points FROM ck_playerrank WHERE steamid = '%s' AND style = 0"; public void OnPluginStart() { LoadTranslations("st-rockthevote.phrases"); + db_setupDatabase(); AutoExecConfig_SetCreateDirectory(true); AutoExecConfig_SetCreateFile(true); @@ -87,7 +96,9 @@ public void OnPluginStart() g_Cvar_RTVPostVoteAction = AutoExecConfig_CreateConVar("sm_rtv_postvoteaction", "0", "What to do with RTV's after a mapvote has completed. 0 - Allow, success = instant change, 1 - Deny", _, true, 0.0, true, 1.0); g_Cvar_PointsRequirement = AutoExecConfig_CreateConVar("sm_rtv_point_requirement", "0", "Amount of points required to use the rtv command, 0 to disable"); g_Cvar_RankRequirement = AutoExecConfig_CreateConVar("sm_rtv_rank_requirement", "0", "Rank required to use the rtv command, 0 to disable"); - + g_Cvar_VIPOverwriteRequirements = AutoExecConfig_CreateConVar("sm_rtv_vipoverwrite", "0", "1 - VIP's bypass Rank and/or Points requirement, 0 - VIP's need to meet the Rank and/or Points requirement", _, true, 0.0, true, 1.0); + g_PlayerOne = AutoExecConfig_CreateConVar("sm_rtv_oneplayer", "1", "If there is only one player in the server allow him to rtv 1-allow 0-no", _, true, 0.0, true, 1.0); + RegConsoleCmd("sm_rtv", Command_RTV); AutoExecConfig_ExecuteFile(); @@ -105,6 +116,24 @@ public void OnPluginStart() } } +public void db_setupDatabase() +{ + char szError[255]; + g_hDb = SQL_Connect("surftimer", false, szError, 255); + + if (g_hDb == null) + SetFailState("[RTV] Unable to connect to database (%s)", szError); + + char szIdent[8]; + SQL_ReadDriver(g_hDb, szIdent, 8); + + if (!StrEqual(szIdent, "mysql", false)) + { + SetFailState("[RTV] Invalid database type"); + return; + } +} + public void OnMapEnd() { g_RTVAllowed = false; @@ -112,6 +141,11 @@ public void OnMapEnd() g_Votes = 0; g_VotesNeeded = 0; g_InChange = false; + for ( int i=1 ; i<=MAXPLAYERS ; i++ ) + { + g_RankREQ[i] = false; + g_PointsREQ[i] = false; + } } public void OnConfigsExecuted() @@ -124,27 +158,57 @@ public void OnConfigsExecuted() public void OnClientPostAdminCheck(int client) { - if (!IsFakeClient(client)) + if (IsFakeClient(client)) + { + return; + } + + GetPlayerRank(client); + GetPlayerPoints(client); + + g_Voters++; + CalcVotesNeeded(); +} + +public void CalcVotesNeeded() +{ + if ( GetConVarInt(g_Cvar_RankRequirement) > 0 || GetConVarInt(g_Cvar_PointsRequirement) > 0 ) + { + int RealVoters = 0; + for ( int i=1 ; i<= MAXPLAYERS ; i++ ) + { + if (g_RankREQ[i] == true || g_PointsREQ[i] == true) + { + RealVoters++; + } + } + g_VotesNeeded = RoundToCeil(float(RealVoters) * g_Cvar_Needed.FloatValue); + } + else { - g_Voters++; g_VotesNeeded = RoundToCeil(float(g_Voters) * g_Cvar_Needed.FloatValue); } } + public void OnClientDisconnect(int client) { if (g_Voted[client]) { - g_Votes--; g_Voted[client] = false; - } + } - if (!IsFakeClient(client)) + if (IsFakeClient(client)) { - g_Voters--; - g_VotesNeeded = RoundToCeil(float(g_Voters) * g_Cvar_Needed.FloatValue); + return; } + g_RankREQ[client] = false; + g_PointsREQ[client] = false; + + g_Voters--; + CalcVotesNeeded(); + if (g_Votes && g_Voters && g_Votes >= g_VotesNeeded && @@ -190,6 +254,11 @@ public Action Command_RTV(int client, int args) void AttemptRTV(int client) { + if (PlayerOne()) + { + return; + } + if (!g_RTVAllowed || (g_Cvar_RTVPostVoteAction.IntValue == 1 && HasEndOfMapVoteFinished())) { CReplyToCommand(client, "%t", "RTV Not Allowed", g_szChatPrefix); @@ -214,32 +283,25 @@ void AttemptRTV(int client) return; } - if (GetConVarInt(g_Cvar_PointsRequirement) > 0) + if (GetConVarInt(g_Cvar_PointsRequirement) > 0 && !g_PointsREQ[client]) { - if (surftimer_GetPlayerPoints(client) < GetConVarInt(g_Cvar_PointsRequirement)) - { - CPrintToChat(client, "%t", "Point Requirement", g_szChatPrefix); - return; - } + CPrintToChat(client, "%t", "Point Requirement", g_szChatPrefix); + return; } - - if (GetConVarInt(g_Cvar_RankRequirement) > 0) + if (GetConVarInt(g_Cvar_RankRequirement) > 0 && !g_RankREQ[client]) { - if (surftimer_GetPlayerRank(client) > GetConVarInt(g_Cvar_RankRequirement) || surftimer_GetPlayerRank(client) == 0) - { - CPrintToChat(client, "%t", "Rank Requirement", g_szChatPrefix, GetConVarInt(g_Cvar_RankRequirement)); - return; - } + CPrintToChat(client, "%t", "Rank Requirement", g_szChatPrefix, GetConVarInt(g_Cvar_RankRequirement)); + return; } - + char name[MAX_NAME_LENGTH]; GetClientName(client, name, sizeof(name)); - + g_Votes++; g_Voted[client] = true; - + CPrintToChatAll("%t", "RTV Requested", g_szChatPrefix, name, g_Votes, g_VotesNeeded); - + if (g_Votes >= g_VotesNeeded) { StartRTV(); @@ -319,4 +381,132 @@ stock bool IsValidClient(int client) if (client >= 1 && client <= MaxClients && IsValidEntity(client) && IsClientConnected(client) && IsClientInGame(client)) return true; return false; +} + +stock bool VIPBypass(int client) +{ + if (surftimer_IsClientVip(client) && GetConVarBool(g_Cvar_VIPOverwriteRequirements)) + { + return true; + } + else + { + return false; + } +} + +stock bool PlayerOne() +{ + if ( g_Voters == 1 && GetConVarBool(g_PlayerOne) ) + { + StartRTV(); + return true; + } + else + { + return false; + } +} + + +void GetPlayerRank(int client) +{ + if (!(GetConVarInt(g_Cvar_RankRequirement) > 0)) + { + return; + } + + char szQuery[256], steamid[32]; + GetClientAuthId(client, AuthId_Steam2, steamid, MAX_NAME_LENGTH, true); + + FormatEx(szQuery, sizeof(szQuery), sql_SelectRank, steamid); + SQL_TQuery(g_hDb, GetPlayerRankCallBack, szQuery, client, DBPrio_Normal); +} + +void GetPlayerRankCallBack(Handle owner, Handle hndl, const char[] error, any client) +{ + if (hndl == null){ + LogError("[RTV] SQL Error (GetPlayerRankCallBack): %s", error); + return; + } + + if(!IsValidClient(client)) + { + return; + } + + if (SQL_HasResultSet(hndl) && SQL_FetchRow(hndl)) + { + int rank = SQL_FetchInt(hndl,0); + if(rank <= 0) + { + g_RankREQ[client] = false; + return; + } + + if(rank < GetConVarInt(g_Cvar_RankRequirement)) + { + g_RankREQ[client] = true; + } + else if (VIPBypass(client)) + { + g_RankREQ[client] = true; + } + else + { + g_RankREQ[client] = false; + } + + } +} + +void GetPlayerPoints(int client) +{ + if (!(GetConVarInt(g_Cvar_PointsRequirement) > 0)) + { + return; + } + + char szQuery[256], steamid[32]; + GetClientAuthId(client, AuthId_Steam2, steamid, MAX_NAME_LENGTH, true); + + FormatEx(szQuery, sizeof(szQuery), sql_SelectPoints, steamid); + SQL_TQuery(g_hDb, GetPlayerPointsCallBack, szQuery, client, DBPrio_Normal); +} + +void GetPlayerPointsCallBack(Handle owner, Handle hndl, const char[] error, any client) +{ + if (hndl == null){ + LogError("[RTV] SQL Error (GetPlayerPointsCallBack): %s", error); + return; + } + + if(!IsValidClient(client)) + { + return; + } + + if (SQL_HasResultSet(hndl) && SQL_FetchRow(hndl)) + { + int points = SQL_FetchInt(hndl,0); + if(points <= 0) + { + g_PointsREQ[client] = false; + return; + } + + if(points > GetConVarInt(g_Cvar_PointsRequirement)) + { + g_PointsREQ[client] = true; + } + else if (VIPBypass(client)) + { + g_PointsREQ[client] = true; + } + else + { + g_PointsREQ[client] = false; + } + + } } \ No newline at end of file diff --git a/addons/sourcemod/scripting/voteextend.sp b/addons/sourcemod/scripting/voteextend.sp index 5be71f8..33d4ff5 100644 --- a/addons/sourcemod/scripting/voteextend.sp +++ b/addons/sourcemod/scripting/voteextend.sp @@ -34,7 +34,7 @@ public Plugin myinfo = name = "SurfTimer Vote Extend", author = "SurfTimer Contributors", description = "Allows players to vote extend the map", - version = "1.8", + version = "1.8.3", url = "https://github.com/qawery-just-sad/surftimer-mapchooser" };