From 3c8d8c99f8e1ea84cb27d915b10c9a8c2ea58379 Mon Sep 17 00:00:00 2001 From: neon <> Date: Fri, 10 Aug 2018 12:43:49 +0200 Subject: [PATCH 1/3] mapchooser_extended: mapchooser_extended: add reserved/random nomination slots (by Botox) --- .../configs/mapchooser_extended.cfg | 490 +++++++++++++++++- .../scripting/include/mapchooser_extended.inc | 20 +- .../scripting/include/nativevotes.inc | 140 ++--- .../scripting/mapchooser_extended.sp | 241 ++++++--- 4 files changed, 728 insertions(+), 163 deletions(-) diff --git a/mapchooser_extended/configs/mapchooser_extended.cfg b/mapchooser_extended/configs/mapchooser_extended.cfg index f783cfaf..7b2d02f6 100644 --- a/mapchooser_extended/configs/mapchooser_extended.cfg +++ b/mapchooser_extended/configs/mapchooser_extended.cfg @@ -1,22 +1,484 @@ "mapchooser_extended" { - "example_map" - { - "MinTime" "1800" - "MaxTime" "2300" - - "MinPlayers" "25" - "MaxPlayers" "50" - "Cooldown" "20" - } - "_groups" { - "example_group" + "1" // final fantasy + { + "_max" "2" + "ze_ffvii_cosmo_canyon_v1beta1" {} + "ze_ffvii_cosmo_canyon_v1_1" {} + "ze_ffvii_cosmo_canyon_v2_1" {} + "ze_ffvii_cosmo_canyon_v4fix" {} + "ze_ffvii_cosmo_canyon_v5test2" {} + "ze_ffvii_cosmo_canyon_v5fix" {} + "ze_FFVII_Mako_Reactor_b2" {} + "ze_FFVII_Mako_Reactor_v1_4_1" {} + "ze_FFVII_Mako_Reactor_v3_1" {} + "ze_FFVII_Mako_Reactor_v5_3" {} + "ZE_FFVII_Mako_Reactor_V6_B08" {} + "ze_FFXII_Feywood_b3_1" {} + "ze_FFXII_Paramina_Rift_v1_4" {} + "ze_ffxii_ridorana_cataract_b6" {} + "ze_ffxii_ridorana_cataract_t4" {} + "ze_ffxii_westersand_v2_11a" {} + "ze_ffxii_westersand_v2d" {} + "ze_FFXII_Westersand_v5_2" {} + "ze_FFXII_Westersand_v7" {} + "ze_FFXII_Westersand_v7_2" {} + "ze_FFXII_Westersand_v8zeta1" {} + "ze_ffxiv_wanderers_palace_css" {} + "ze_FFXIV_Wanderers_Palace_v5s" {} + "ze_ffxiv_wanderers_palace_v4_5s" {} + "ze_FFXIV_Wanderers_Palace_v5_2f" {} + "ze_FFVII_Temple_Ancient_v3_3" {} + } + "2" // rooftop + { + "_max" "2" + "ze_gargantua_v2_0" {} + "ze_rooftop_runaway1_v4" {} + "ze_rooftop_runaway_xmas_v1" {} + "ze_rooftop_runaway2_v5" {} + "ze_rooftop_reborn_v3_2" {} + } + "3" // random { "_max" "1" - "example_map1" {} - "example_map2" {} + "ze_random_v9" {} + "ze_random_v10_fix" {} + "ze_random_escape_b7_3" {} + } + "4" // shroom + { + "_max" "2" + "ze_shroomforest2_v1" {} + "ze_shroomforest_v4_5" {} + "ze_shroomforest3_b6_2" {} + } + "5" // pirates + { + "_max" "1" + "ze_pirates_port_royal_v5_4s2" {} + "ze_pirates_port_royal_v3_6" {} + } + "6" // jurassic + { + "_max" "2" + "ze_jurassic_park_story_v1" {} + "ze_jurassicpark_c1v4" {} + "ze_jurassicpark_v2_10_ob" {} } } -} \ No newline at end of file + "ze_deadcore_s6" + { + "MinPlayers" "40" + } + "ze_abandoned_project_v1_2" + { + "MinPlayers" "20" + } + "ze_amkoescape_v1337" + { + "MinPlayers" "20" + } + "ze_Ancient_wrath_v1_fix2" + { + "MinPlayers" "20" + } + "ze_antartika_b2" + { + "MinPlayers" "40" + } + "ze_ashen_keep_v0_3" + { + "MinPlayers" "40" + } + "ze_avalanche_reboot_beta3" + { + "MinPlayers" "40" + } + "ze_bathroom_v2_5s" + { + "MinPlayers" "20" + } + "ze_bioshock_v6_3" + { + "MinPlayers" "40" + } + "ze_boredom_v543656" + { + "MinPlayers" "40" + } + "ze_castlevania_v1_3" + { + "MinPlayers" "40" + } + "ze_chicken_ranch_v2_1s" + { + "MinPlayers" "20" + } + "ze_christmas_infection_v2_3" + { + "MinPlayers" "40" + } + "ze_chroma_v0_4" + { + "MinPlayers" "40" + } + "ze_dark_souls_ptd_v0_4" + { + "MinPlayers" "40" + } + "ze_destruction_of_exorath_re3" + { + "MinPlayers" "20" + } + "ze_doom3_v1" + { + "MinPlayers" "40" + } + "ze_fapescape_rote_v1_3f" + { + "MinPlayers" "40" + } + "ze_fapescape_v1_2" + { + "MinPlayers" "20" + } + "ze_ffvii_cosmo_canyon_v5fix" + { + "MinPlayers" "40" + "Cooldown" "45" + } + "ze_FFVII_Temple_Ancient_v3_3" + { + "MinPlayers" "40" + } + "ze_FFXII_Feywood_b3_1" + { + "MinPlayers" "40" + "Cooldown" "45" + } + "ze_FFVII_Mako_Reactor_v5_3" + { + "MinTime" "2200" + "MaxTime" "1600" + "Cooldown" "45" + "MinPlayers" "20" + } + "ZE_FFVII_Mako_Reactor_V6_B08" + { + "Cooldown" "45" + "MinPlayers" "40" + } + "ze_FFXII_Paramina_Rift_v1_4" + { + "MinPlayers" "40" + "Cooldown" "45" + } + "ze_ffxii_ridorana_cataract_t4" + { + "MinPlayers" "40" + } + "ze_ffxii_westersand_v2d" + { + "MinPlayers" "40" + } + "ze_ffxii_westersand_v5_2" + { + "MinPlayers" "40" + "Cooldown" "45" + } + "ze_ffxii_westersand_v7_2" + { + "MinPlayers" "40" + "Cooldown" "45" + } + "ze_FFXII_Westersand_v8zeta1" + { + "MinPlayers" "40" + "Cooldown" "45" + } + "ze_ffxiv_wanderers_palace_v4_5s" + { + "MinPlayers" "40" + } + "ze_FFXIV_Wanderers_Palace_v5_2f" + { + "MinPlayers" "40" + "Cooldown" "45" + } + "ze_frostdrake_tower_v1s" + { + "MinPlayers" "40" + } + "ze_frozentemple_b8_2" + { + "MinPlayers" "20" + } + "ze_gris_fyk" + { + "MinPlayers" "40" + } + "ze_halloween_house_b4s" + { + "MinPlayers" "40" + } + "ze_hellz_rescuebase_v5_b1" + { + "MinPlayers" "20" + } + "ze_hsc_a4_5" + { + "MinPlayers" "40" + } + "ze_industrial_dejavu_v3_3_1" + { + "MinPlayers" "40" + } + "ze_Infected_Sewers_v6_5" + { + "MinPlayers" "40" + } + "ze_interception_b4" + { + "MinPlayers" "20" + } + "ze_johnny_nukem_b8_1" + { + "MinPlayers" "40" + } + "ze_journey_v1_2" + { + "MinPlayers" "40" + } + "ze_last_man_standing_v4_2" + { + "MinPlayers" "40" + } + "ze_legoland_crackheads_v2" + { + "MinPlayers" "20" + } + "ze_l0v0l_v1_4" + { + "MinPlayers" "20" + } + "ze_lila_panic_escape_v3_1" + { + "MinPlayers" "20" + } + "ze_lolxd_final_s" + { + "MinPlayers" "20" + } + "ze_LOTR_Isengard_v2_3" + { + "MinPlayers" "20" + } + "ze_lotr_minas_tirith_v2_2fix" + { + "MinTime" "1800" + "MaxTime" "2200" + "MinPlayers" "40" + "Cooldown" "45" + } + "ze_lotr_minas_tirith_v3_3" + { + "MinTime" "1800" + "MaxTime" "2200" + "MinPlayers" "40" + "Cooldown" "45" + } + "ze_megaman_a6" + { + "MinPlayers" "40" + } + "ze_minecraft_adventure_v1_2c" + { + "MinPlayers" "20" + } + "ze_mountain_escape_v5_zy" + { + "MinPlayers" "20" + "Cooldown" "45" + } + "ze_otakuroom_v5_6fs" + { + "MinPlayers" "20" + } + "ze_paper_escaper_v7_1" + { + "MinPlayers" "20" + } + "ze_Paranoid_Rezurrection_v11_9" + { + "MinPlayers" "20" + "Cooldown" "45" + } + "ze_parkers_pit_b8" + { + "MinPlayers" "20" + } + "ze_Parking_v3_1" + { + "MinPlayers" "20" + } + "ze_Pidaras_v1_4fix3" + { + "MinPlayers" "20" + } + "ze_Pirates_Port_Royal_v3_6" + { + "MinPlayers" "20" + } + "ze_pirates_port_royal_v5_4s2" + { + "MinPlayers" "20" + "Cooldown" "45" + } + "ze_pizzatime_v4s" + { + "MinPlayers" "40" + } + "ze_pkmn_adventure_v8_6s_fix2" + { + "MinPlayers" "40" + } + "ze_PoncherMonkey_Shooter_v3_5" + { + "MinPlayers" "40" + } + "ze_portal_story_v3_2" + { + "MinPlayers" "20" + } + "ze_predator_ultimate_v3" + { + "MinPlayers" "20" + } + "ze_project_alcaria_v1_5s" + { + "MinPlayers" "20" + } + "ze_prototype_v2" + { + "MinPlayers" "20" + } + "ze_ravenholm_v035fix" + { + "MinPlayers" "20" + } + "ze_rizomata_s1_3" + { + "MinPlayers" "40" + } + "ze_rtcw_ominous_rumors_v1" + { + "MinPlayers" "20" + } + "ze_sandstorm_f1" + { + "MinPlayers" "20" + } + "ze_Serpentis_Temple_v1_1" + { + "MinPlayers" "40" + "Cooldown" "45" + } + "ze_shroomforest_v4_5" + { + "MinPlayers" "20" + "Cooldown" "45" + } + "ze_shroomforest2_v1" + { + "MinPlayers" "20" + "Cooldown" "45" + } + "ze_shroomforest3_b6_2" + { + "MinPlayers" "40" + "Cooldown" "45" + } + "ze_siberia_1990_v1_2c" + { + "MinPlayers" "20" + } + "ze_slender_escape_b4" + { + "MinPlayers" "20" + } + "ze_stalker_ultimate_v2_3" + { + "MinPlayers" "20" + } + "ze_stalker_ultimate_v3" + { + "MinPlayers" "20" + } + "ze_stalker_monolit_a5" + { + "MinPlayers" "50" + } + "ze_starwars_v2fix" + { + "MinPlayers" "20" + } + "ze_strange_escape_b3" + { + "MinPlayers" "20" + } + "ze_sunkentemple_v3_1s" + { + "MinPlayers" "20" + } + "ze_sunlight_v2_0" + { + "MinPlayers" "20" + } + "ze_super_mario_64_v2_b5" + { + "MinPlayers" "40" + } + "ze_survivors_b5" + { + "MinPlayers" "40" + } + "ze_taboo_carnation_v2" + { + "MinPlayers" "40" + } + "ze_temple_raider_b4" + { + "MinPlayers" "40" + } + "ze_Temple_v2_1" + { + "MinPlayers" "40" + } + "ze_tesv_skyrim_v4fix" + { + "MinPlayers" "40" + "Cooldown" "45" + } + "ze_toaster_v1_2" + { + "MinPlayers" "20" + } + "ze_tyranny_v5_2" + { + "MinPlayers" "40" + } + "ze_undertale_g_v1_2s2" + { + "MinPlayers" "20" + } + "ze_ut2004_convoy_v2_2_1" + { + "MinPlayers" "40" + } + "ze_v0u0v_a4" + { + "MinPlayers" "40" + } \ No newline at end of file diff --git a/mapchooser_extended/scripting/include/mapchooser_extended.inc b/mapchooser_extended/scripting/include/mapchooser_extended.inc index 551d3e57..d1c3804e 100644 --- a/mapchooser_extended/scripting/include/mapchooser_extended.inc +++ b/mapchooser_extended/scripting/include/mapchooser_extended.inc @@ -12,7 +12,7 @@ * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License, version 3.0, as published by the * Free Software Foundation. - * + * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more @@ -52,7 +52,7 @@ enum CanNominateResult /** * Called whenever warning timer starts - * + * */ forward void OnMapVoteWarningStart(); @@ -68,7 +68,7 @@ forward void OnMapVoteWarningTick(int time); /** * Called whenever vote starts - * + * * @deprecated Will be removed in MapChooser 1.8. Use OnMapVoteStarted instead. */ forward void OnMapVoteStart(); @@ -81,7 +81,7 @@ forward void OnMapVoteEnd(const char[] map); /** * Is a map on the current game's official list? * This should be treated as informative only. - * + * * @param map Name of map to check * @return true if it's on the list of official maps for this game */ @@ -89,7 +89,7 @@ native bool IsMapOfficial(const char[] map); /** * Is nominate allowed? - * + * * @return A CanNominateResult corresponding to whether a vote is allowed or not */ native CanNominateResult CanNominate(); @@ -97,7 +97,7 @@ native CanNominateResult CanNominate(); /** * Add map to nomination exclude list. * Known as cooldown. - * + * * @param map Name of map * @param cooldown Cooldown, interpretation depends on mode. * @param mode 0: Normal, use cooldown value from config/default. @@ -122,15 +122,15 @@ native int GetMapTimeRestriction(const char[] map); // >0 = More than MaxPlayers native int GetMapPlayerRestriction(const char[] map); -// <0 = No group -// >=0 = Group _max -native int GetMapGroup(const char[] map, char[] group, int size); +// <=0 = No group +// >0 = Groups found +native int GetMapGroups(const char[] map, int[] groups, int size); // <0 = No restriction // >=0 = Group _max -> Group full native int GetMapGroupRestriction(const char[] map, int client = 0); -public SharedPlugin __pl_mapchooser_extended = +public SharedPlugin __pl_mapchooser_extended = { name = "mapchooser", file = "mapchooser_extended.smx", diff --git a/mapchooser_extended/scripting/include/nativevotes.inc b/mapchooser_extended/scripting/include/nativevotes.inc index c02c5bdf..ff88dae7 100644 --- a/mapchooser_extended/scripting/include/nativevotes.inc +++ b/mapchooser_extended/scripting/include/nativevotes.inc @@ -8,7 +8,7 @@ * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License, version 3.0, as published by the * Free Software Foundation. - * + * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more @@ -28,7 +28,7 @@ * * Version: $Id$ */ - + #include #include @@ -66,7 +66,7 @@ MenuAction_Display A menu is about to be displayed (param1=client). If you choo MenuAction_Select An item was selected (param1=client, param2=item). For subplugin support. MenuAction_End A vote has fully ended and the vote object is ready to be cleaned up param1 is MenuEnd reason, either MenuEnd_VotingCancelled or MenuEnd_VotingDone -MenuAction_VoteEnd A vote sequence has succeeded (param1=chosen item) +MenuAction_VoteEnd A vote sequence has succeeded (param1=chosen item) This is not called if NativeVotes_SetResultCallback has been used on the vote. You should call NativeVotes_DisplayPass or NativeVotes_DisplayPassEx after this MenuAction_VoteStart A vote sequence has started (nothing passed). Use this instead of MenuAction_Start @@ -181,17 +181,17 @@ enum NativeVotesCallFailType /* * Is a specific vote type supported by this game? - * + * * @param voteType Vote type */ native bool:NativeVotes_IsVoteTypeSupported(NativeVotesType:voteType); /** * Creates a new, empty vote. - * + * * @param handler Function which will receive vote actions. * @param voteType Vote type, cannot be changed after set - * @param actions Optionally set which actions to receive. Start, + * @param actions Optionally set which actions to receive. Start, * Cancel, and End will always be received regardless * of whether they are set or not. They are also * the only default actions. @@ -202,9 +202,9 @@ native Handle:NativeVotes_Create(MenuHandler:handler, NativeVotesType:voteType, /** * Frees all handles related to a vote. - * + * * THIS MUST BE CALLED TO AVOID HANDLE LEAKS - * + * * @param vote Vote handle * @noreturn */ @@ -261,13 +261,13 @@ native NativeVotes_RemoveAllItems(Handle:vote); * @return True on success, false if position is invalid. * @error Invalid Handlem */ -native bool:NativeVotes_GetItem(Handle:vote, - position, - String:infoBuf[], +native bool:NativeVotes_GetItem(Handle:vote, + position, + String:infoBuf[], infoBufLen, String:dispBuf[]="", dispBufLen=0); - + /** * Returns the number of items in a vote. * @@ -325,9 +325,9 @@ native NativeVotes_GetTitle(Handle:vote, String:buffer[], maxlength); /** * Sets the target userid for vote * This should be used instead of SetArgument for votes that target players - * + * * Also sets target SteamID - * + * * @param vote Vote Handle. * @param userid Client index of target player * @param setDetails If true, also sets vote details to client's name @@ -367,7 +367,7 @@ native bool:NativeVotes_IsVoteInProgress(); /** * Returns a style's maximum items - * + * * @return Maximum items */ native NativeVotes_GetMaxItems(); @@ -376,7 +376,7 @@ native NativeVotes_GetMaxItems(); * Sets a vote's option flags. * * If a certain bit is not supported, it will be stripped before being set. - * + * * NOTE: This is currently unused, but reserved for future use. * * @param menu Builtin Vote Handle. @@ -407,11 +407,11 @@ native NativeVotes_Cancel(); /** * Callback for when a vote has ended and results are available. - * + * * Due to SourceMod Forward limitations in plugins, multi-dimension arrays can't be passed * to forwards. This means we have to split the client_info and item_info arrays into * their components. - * + * * @param vote The vote being voted on. * @param num_votes Number of votes tallied in total. * @param num_clients Number of clients who could vote. @@ -422,24 +422,24 @@ native NativeVotes_Cancel(); * @param item_votes Array of vote vote counts. Parallel with item_indexes. * @noreturn */ -functag public NativeVotes_VoteHandler(Handle:vote, - num_votes, - num_clients, - const client_indexes[], - const client_votes[], - num_items, - const item_indexes[], - const item_votes[]); +typedef NativeVotes_VoteHandler = function int (Handle vote, + int num_votes, + int num_clients, + const int[] client_indexes, + const int[] client_votes, + int num_items, + const int[] item_indexes, + const int[] item_votes); /** * Function to convert client/vote arrays into their two-dimensional versions, * which can then be passed to a standard vote handler. - * + * * client_info and item_info are the resulting arrays. - * + * * Note: When declaring client_info and item_info, you'll probably want to declare them like this: * new client_info[num_clients][2]; * new item_info[num_items][2]; - * + * * @param num_clients Number of clients who could vote. * @param client_indexes Array of client indexes. Parallel with client_votes. * @param client_votes Array of client votes. Parallel with client_indexes. @@ -457,7 +457,7 @@ stock NativeVotes_FixResults(num_clients, num_items, const item_indexes[], const item_votes[], - client_info[][], + client_info[][], item_info[][]) { for (new i = 0; i < num_clients; ++i) @@ -465,7 +465,7 @@ stock NativeVotes_FixResults(num_clients, client_info[i][VOTEINFO_CLIENT_INDEX] = client_indexes[i]; client_info[i][VOTEINFO_CLIENT_ITEM] = client_votes[i]; } - + for (new i = 0; i < num_items; ++i) { item_info[i][VOTEINFO_ITEM_INDEX] = item_indexes[i]; @@ -494,8 +494,8 @@ native NativeVotes_SetResultCallback(Handle:vote, NativeVotes_VoteHandler:callba native NativeVotes_CheckVoteDelay(); /** - * Returns whether a client is in the pool of clients allowed - * to participate in the current vote. This is determined by + * Returns whether a client is in the pool of clients allowed + * to participate in the current vote. This is determined by * the client list passed to NativeVotes_Display(). * * @param client Client index. @@ -509,16 +509,16 @@ native bool:NativeVotes_IsClientInVotePool(client); * * @param client Client index. * @param revotes True to allow revotes, false otherwise. - * @return True on success, false if the client is in the vote pool + * @return True on success, false if the client is in the vote pool * but cannot vote again. - * @error No vote in progress, client is not in the voting pool, + * @error No vote in progress, client is not in the voting pool, * or client index is invalid. */ native bool:NativeVotes_RedrawClientVote(client, bool:revotes=true); /** * Retrieve the vote type - * + * * @param vote NativeVotes Handle. * @return The built in vote type * @error Invalid Handle @@ -527,9 +527,9 @@ native NativeVotesType:NativeVotes_GetType(Handle:vote); /** * Set the team this vote is for, or NATIVEVOTES_ALL_TEAMS for all teams. - * + * * Defaults to NATIVEVOTES_ALL_TEAMS if not explicitly set. - * + * * @param vote NativeVotes Handle. * @param team Team number this vote is for * @noreturn @@ -539,7 +539,7 @@ native NativeVotes_SetTeam(Handle:vote, team); /** * Retrieve the team this vote is for - * + * * @param vote NativeVotes Handle. * @return Team index or NATIVEVOTES_ALL_TEAMS for all teams. * @error Invalid Handle @@ -549,9 +549,9 @@ native NativeVotes_GetTeam(Handle:vote); /** * Set the client index of the player who initiated the vote. * Use NATIVEVOTES_SERVER_INDEX if initiated by the server itself. - * + * * Defaults to NATIVEVOTES_SERVER_INDEX if not explicitly set. - * + * * @param vote NativeVotes Handle. * @param client Client who initiated the vote or NATIVEVOTES_SERVER_INDEX * @noreturn @@ -560,9 +560,9 @@ native NativeVotes_GetTeam(Handle:vote); native NativeVotes_SetInitiator(Handle:vote, client); /** - * Retrieve the client index of the player who initiated the vote or NATIVEVOTES_SERVER_INDEX if + * Retrieve the client index of the player who initiated the vote or NATIVEVOTES_SERVER_INDEX if * initiated by the server itself. - * + * * @param Vote handle * @return Client index or NATIVEVOTES_SERVER_INDEX * @error Invalid Handle @@ -570,8 +570,8 @@ native NativeVotes_SetInitiator(Handle:vote, client); native NativeVotes_GetInitiator(Handle:vote); /** - * Broadcasts a vote to a list of clients. The most selected item will be - * returned through MenuAction_VoteEnd. On a tie, a random item will be returned + * Broadcasts a vote to a list of clients. The most selected item will be + * returned through MenuAction_VoteEnd. On a tie, a random item will be returned * from a list of the tied items. * * Note that MenuAction_VoteStart, MenuAction_VoteCancel, MenuAction_VoteEnd, and MenuAction_End are all @@ -599,7 +599,7 @@ stock bool:NativeVotes_DisplayToAll(Handle:vote, time) { new total = 0; decl players[MaxClients]; - + for (new i=1; i<=MaxClients; i++) { if (!IsClientInGame(i) || IsFakeClient(i)) @@ -608,7 +608,7 @@ stock bool:NativeVotes_DisplayToAll(Handle:vote, time) } players[total++] = i; } - + return NativeVotes_Display(vote, players, total, time); } @@ -628,7 +628,7 @@ stock bool:NativeVotes_DisplayToTeam(Handle:vote, team, time) new total; decl players[MaxClients]; - + for (new i=1; i<=MaxClients; i++) { if (!IsClientInGame(i) || IsFakeClient(i) || (GetClientTeam(i) != team)) @@ -637,7 +637,7 @@ stock bool:NativeVotes_DisplayToTeam(Handle:vote, team, time) } players[total++] = i; } - + return NativeVotes_Display(vote, players, total, time); } @@ -654,7 +654,7 @@ stock bool:NativeVotes_DisplayToAllNonSpectators(Handle:vote, time) { new total; decl players[MaxClients]; - + for (new i=1; i<=MaxClients; i++) { if (!IsClientInGame(i) || IsFakeClient(i) || (GetClientTeam(i) < 2)) @@ -663,7 +663,7 @@ stock bool:NativeVotes_DisplayToAllNonSpectators(Handle:vote, time) } players[total++] = i; } - + return NativeVotes_Display(vote, players, total, time); } @@ -673,7 +673,7 @@ stock bool:NativeVotes_DisplayToAllNonSpectators(Handle:vote, time) * You MUST call one of the NativeVotesDisplayPass* or NativeVotes_DisplayFail functions * to hide the vote screen for users who didn't vote, and to clear out their selection * for the next vote. - * + * * @param vote Vote handle * @param details Normally the item that won the vote or format string. Also used for custom vote winners * @param ... Variable number of format parameters. @@ -687,7 +687,7 @@ native NativeVotes_DisplayPass(Handle:vote, const String:details[]=""); * You MUST call one of the NativeVotesDisplayPass* or NativeVotes_DisplayFail functions * to hide the vote screen for users who didn't vote, and to clear out their selection * for the next vote. - * + * * @param vote Vote handle * @param client client to display to * @param format A format string. @@ -702,7 +702,7 @@ native NativeVotes_DisplayPassCustomToOne(Handle:vote, client, const String:form * You MUST call one of the NativeVotesDisplayPass* or NativeVotes_DisplayFail functions * to hide the vote screen for users who didn't vote, and to clear out their selection * for the next vote. - * + * * @param vote Vote handle * @param format A format string. * @param any Variable number of format parameters @@ -711,7 +711,7 @@ native NativeVotes_DisplayPassCustomToOne(Handle:vote, client, const String:form stock NativeVotes_DisplayPassCustom(Handle:vote, const String:format[], any:...) { decl String:buffer[192]; - + for (new i = 1; i <= MaxClients; ++i) { if (IsClientInGame(i)) @@ -731,7 +731,7 @@ stock NativeVotes_DisplayPassCustom(Handle:vote, const String:format[], any:...) * You MUST call one of NativeVotes_DisplayPass, NativeVotes_DisplayPassEx, * or NativeVotes_DisplayFail to hide the vote screen for users who didn't vote * and to clear out their selection for the next vote. - * + * * #param vote Vote handle * @param passType The pass screen to display * @param details Normally the item that won the vote. Also used for custom vote winners @@ -745,17 +745,17 @@ native NativeVotes_DisplayPassEx(Handle:vote, NativeVotesPassType:passType, cons * You MUST call one of NativeVotes_DisplayPass, NativeVotes_DisplayPassEx, * or NativeVotes_DisplayFail to hide the vote screen for users who didn't vote, * and to clear out their selection for the next vote. - * + * * @param reason Vote failure reason from NativeVotesFailType enum * @noreturn */ native NativeVotes_DisplayFail(Handle:vote, NativeVotesFailType:reason=NativeVotesFail_Generic); /** - * Quick stock to determine whether voting is allowed. This doesn't let you - * fine-tune a reason for not voting, so it's not recommended for lazily + * Quick stock to determine whether voting is allowed. This doesn't let you + * fine-tune a reason for not voting, so it's not recommended for lazily * telling clients that voting isn't allowed. - * + * * @return True if voting is allowed, false if voting is in progress * or the cooldown is active. */ @@ -765,15 +765,15 @@ stock bool:NativeVotes_IsNewVoteAllowed() { return false; } - + return true; } /** * Used when callvote is called with no arguments. - * + * * This is used to configure the VoteSetup usermessage on TF2 and CS:GO - * + * * @param client Client, in case the votes are restricted by client * @param voteTypes Populate this array with the vote types this server supports * Custom and multiple choice votes are not supported from @@ -787,9 +787,9 @@ stock bool:NativeVotes_IsNewVoteAllowed() /** * Forward for "callvote" handling - * + * * You should respond to this by starting a vote or by calling NativeVotes_DisplayCallVoteFail - * + * * @param client Client * @param voteType Type of vote being called. This will NEVER be a multiple-choice or custom vote. * @param voteArgument Vote argument or blank if the vote type has no argument. @@ -803,7 +803,7 @@ stock bool:NativeVotes_IsNewVoteAllowed() /** * Register a plugin as a vote manager. * This is used to abstract away the details of the callvote command. - * + * * @param callHandler Handler for callvote commands. * @param setupHandler Handler to override the which vote types your server supports. Only useful on TF2 and CS:GO. * @noreturn @@ -814,7 +814,7 @@ stock bool:NativeVotes_IsNewVoteAllowed() * Send a call vote fail screen to a user * Used to respond to a callvote with invalid arguments or for other reasons * (such as trying to target an admin for a kick/ban vote) - * + * * @param client The client to display the fail screen to * @param reason A vote call fail reason * @param time For NativeVotesCallFail_Recent, the number of seconds until the vote @@ -825,7 +825,7 @@ native NativeVotes_DisplayCallVoteFail(client, NativeVotesCallFailType:reason, t /** * Redraws the vote title from inside a MenuAction_Display callback * Not supported on L4D - * + * * @param text Vote title to draw * @error If called from outside MenuAction_Display * @return Plugin_Changed if the change is allowed, Plugin_Continue if it isn't. @@ -835,7 +835,7 @@ native Action:NativeVotes_RedrawVoteTitle(const String:text[]); /** * Redraws the vote text from inside a MenuAction_DisplayItem callback. * Only supported on multiple-choice votes - * + * * @param text Vote text to draw. * @error If called from outside MenuAction_DisplayItem * @return Plugin_Changed if the change is allowed, Plugin_Continue if it isn't. @@ -859,7 +859,7 @@ stock NativeVotes_GetInfo(param2, &winningVotes, &totalVotes) /** * Do not edit below this line! */ -public SharedPlugin:__pl_nativevotes = +public SharedPlugin:__pl_nativevotes = { name = "nativevotes", file = "nativevotes.smx", diff --git a/mapchooser_extended/scripting/mapchooser_extended.sp b/mapchooser_extended/scripting/mapchooser_extended.sp index 0232f79f..7d711f93 100644 --- a/mapchooser_extended/scripting/mapchooser_extended.sp +++ b/mapchooser_extended/scripting/mapchooser_extended.sp @@ -111,6 +111,7 @@ ConVar g_Cvar_ExtendRoundStep; ConVar g_Cvar_ExtendFragStep; ConVar g_Cvar_ExcludeMaps; ConVar g_Cvar_IncludeMaps; +ConVar g_Cvar_IncludeMapsReserved; ConVar g_Cvar_NoVoteMode; ConVar g_Cvar_Extend; ConVar g_Cvar_DontChange; @@ -141,6 +142,7 @@ bool g_HasIntermissionStarted = false; int g_mapFileSerial = -1; int g_NominateCount = 0; +int g_NominateReservedCount = 0; MapChange g_ChangeTime; Handle g_NominationsResetForward = INVALID_HANDLE; @@ -238,7 +240,8 @@ public void OnPluginStart() g_Cvar_ExtendRoundStep = CreateConVar("mce_extend_roundstep", "5", "Specifies how many more rounds each extension makes", _, true, 1.0); g_Cvar_ExtendFragStep = CreateConVar("mce_extend_fragstep", "10", "Specifies how many more frags are allowed when map is extended.", _, true, 5.0); g_Cvar_ExcludeMaps = CreateConVar("mce_exclude", "5", "Specifies how many past maps to exclude from the vote.", _, true, 0.0); - g_Cvar_IncludeMaps = CreateConVar("mce_include", "5", "Specifies how many maps to include in the vote.", _, true, 2.0, true, 6.0); + g_Cvar_IncludeMaps = CreateConVar("mce_include", "5", "Specifies how many maps to include in the vote.", _, true, 2.0, true, 7.0); + g_Cvar_IncludeMapsReserved = CreateConVar("mce_include_reserved", "2", "Specifies how many private/random maps to include in the vote.", _, true, 0.0, true, 5.0); g_Cvar_NoVoteMode = CreateConVar("mce_novote", "1", "Specifies whether or not MapChooser should pick a map if no votes are received.", _, true, 0.0, true, 1.0); g_Cvar_Extend = CreateConVar("mce_extend", "0", "Number of extensions allowed each map.", _, true, 0.0); g_Cvar_DontChange = CreateConVar("mce_dontchange", "1", "Specifies if a 'Don't Change' option should be added to early votes", _, true, 0.0); @@ -249,7 +252,7 @@ public void OnPluginStart() g_Cvar_RunOff = CreateConVar("mce_runoff", "1", "Hold run off votes if winning choice has less than a certain percentage of votes", _, true, 0.0, true, 1.0); g_Cvar_RunOffPercent = CreateConVar("mce_runoffpercent", "50", "If winning choice has less than this percent of votes, hold a runoff", _, true, 0.0, true, 100.0); - g_Cvar_BlockSlots = CreateConVar("mce_blockslots", "1", "Block slots to prevent accidental votes. Only applies when Voice Command style menus are in use.", _, true, 0.0, true, 1.0); + g_Cvar_BlockSlots = CreateConVar("mce_blockslots", "0", "Block slots to prevent accidental votes. Only applies when Voice Command style menus are in use.", _, true, 0.0, true, 1.0); //g_Cvar_BlockSlotsCount = CreateConVar("mce_blockslots_count", "2", "Number of slots to block.", _, true, 1.0, true, 3.0); g_Cvar_MaxRunOffs = CreateConVar("mce_maxrunoffs", "1", "Number of run off votes allowed each map.", _, true, 0.0); g_Cvar_StartTimePercent = CreateConVar("mce_start_percent", "35.0", "Specifies when to start the vote based on percents.", _, true, 0.0, true, 100.0); @@ -405,7 +408,7 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max CreateNative("GetMapMaxPlayers", Native_GetMapMaxPlayers); CreateNative("GetMapTimeRestriction", Native_GetMapTimeRestriction); CreateNative("GetMapPlayerRestriction", Native_GetMapPlayerRestriction); - CreateNative("GetMapGroup", Native_GetMapGroup); + CreateNative("GetMapGroups", Native_GetMapGroups); CreateNative("GetMapGroupRestriction", Native_GetMapGroupRestriction); return APLRes_Success; @@ -497,6 +500,7 @@ public void OnConfigsExecuted() g_MapVoteCompleted = false; g_NominateCount = 0; + g_NominateReservedCount = 0; ClearArray(g_NominateList); ClearArray(g_NominateOwners); @@ -1072,7 +1076,7 @@ void InitiateVote(MapChange when, Handle inputlist=INVALID_HANDLE) int nominateCount = GetArraySize(g_NominateList); - int voteSize = GetVoteSize(); + int voteSize = GetVoteSize(2); // The if and else if could be combined, but it looks extremely messy // This is a hack to lower the vote menu size by 1 when Don't Change or Extend Map should appear @@ -1181,6 +1185,7 @@ void InitiateVote(MapChange when, Handle inputlist=INVALID_HANDLE) /* Wipe out our nominations list - Nominations have already been informed of this */ g_NominateCount = 0; + g_NominateReservedCount = 0; ClearArray(g_NominateOwners); ClearArray(g_NominateList); @@ -1228,7 +1233,7 @@ void InitiateVote(MapChange when, Handle inputlist=INVALID_HANDLE) { //SetMenuExitButton(g_VoteMenu, false); - if(GetVoteSize() <= GetMaxPageItems(GetMenuStyle(g_VoteMenu))) + if(GetVoteSize(2) <= GetMaxPageItems(GetMenuStyle(g_VoteMenu))) { //This is necessary to get items 9 and 0 as usable voting items SetMenuPagination(g_VoteMenu, MENU_NO_PAGINATION); @@ -1651,12 +1656,31 @@ void CreateNextVote() delete OldMapListSnapshot; } - int voteSize = GetVoteSize(); + int voteSize = GetVoteSize(2); int limit = (voteSize < GetArraySize(tempMaps) ? voteSize : GetArraySize(tempMaps)); - StringMap groups = new StringMap(); - char group[255]; + // group -> number of maps nominated from group + StringMap groupmap = new StringMap(); + char groupstr[8]; + // populate groupmap with maps from nomination list + static char map_[PLATFORM_MAX_PATH]; + int groups_[32]; + for(int i = 0; i < GetArraySize(g_NominateList); i++) + { + GetArrayString(g_NominateList, i, map_, PLATFORM_MAX_PATH); + int groupsfound = InternalGetMapGroups(map_, groups_, sizeof(groups_)); + for(int group = 0; group < groupsfound; group++) + { + IntToString(group, groupstr, sizeof(groupstr)); + int groupcur = 0; + groupmap.GetValue(groupstr, groupcur); + groupcur++; + groupmap.SetValue(groupstr, groupcur, true); + } + } + + // find random maps which honor all restrictions for(int i = 0; i < limit; i++) { int b; @@ -1668,23 +1692,39 @@ void CreateNextVote() if(InternalGetMapPlayerRestriction(map) == 0) break; - int groupmax = InternalGetMapGroup(map, group, sizeof(group)); - if(groupmax >= 0) - { - int groupcur = 0; - groups.GetValue(group, groupcur); + bool okay = true; - if(groupcur >= groupmax) - break; - groupcur++; - groups.SetValue(group, groupcur, true); + int groups[32]; + int groupsfound = InternalGetMapGroups(map, groups, sizeof(groups)); + for(int group = 0; group < groupsfound; group++) + { + IntToString(group, groupstr, sizeof(groupstr)); + + int groupmax = InternalGetGroupMax(groups[group]); + if(groupmax >= 0) + { + int groupcur = 0; + groupmap.GetValue(groupstr, groupcur); + + if(groupcur >= groupmax) + { + okay = false; + break; + } + + groupcur++; + groupmap.SetValue(groupstr, groupcur, true); + } } + + if(okay) + break; } PushArrayString(g_NextMapList, map); RemoveFromArray(tempMaps, b); } - delete groups; + delete groupmap; CloseHandle(tempMaps); } @@ -1733,20 +1773,27 @@ NominateResult InternalNominateMap(char[] map, bool force, int owner) PushArrayString(g_NominateList, map); PushArrayCell(g_NominateOwners, owner); - g_NominateCount++; + if(owner == 0 && g_NominateReservedCount < GetVoteSize(1)) + g_NominateReservedCount++; + else + g_NominateCount++; - while(GetArraySize(g_NominateList) > GetVoteSize()) + while(GetArraySize(g_NominateList) > GetVoteSize(2)) { char oldmap[PLATFORM_MAX_PATH]; GetArrayString(g_NominateList, 0, oldmap, PLATFORM_MAX_PATH); Call_StartForward(g_NominationsResetForward); Call_PushString(oldmap); - Call_PushCell(GetArrayCell(g_NominateOwners, 0)); + int owner_ = GetArrayCell(g_NominateOwners, 0); + Call_PushCell(owner_); Call_Finish(); RemoveFromArray(g_NominateList, 0); RemoveFromArray(g_NominateOwners, 0); - g_NominateCount--; + if(owner_ == 0) + g_NominateReservedCount--; + else + g_NominateCount--; } return Nominate_Added; @@ -2165,7 +2212,7 @@ public int Native_GetMapPlayerRestriction(Handle plugin, int numParams) return InternalGetMapPlayerRestriction(map); } -public int Native_GetMapGroup(Handle plugin, int numParams) +public int Native_GetMapGroups(Handle plugin, int numParams) { int len; GetNativeStringLength(1, len); @@ -2177,11 +2224,11 @@ public int Native_GetMapGroup(Handle plugin, int numParams) char[] map = new char[len+1]; GetNativeString(1, map, len+1); - char[] group = new char[size]; - int groupmax = InternalGetMapGroup(map, group, size); - if(groupmax >= 0) - SetNativeString(2, group, size); - return groupmax; + int[] groups = new int[size]; + int found = InternalGetMapGroups(map, groups, size); + if(found >= 0) + SetNativeArray(2, groups, size); + return found; } public int Native_GetMapGroupRestriction(Handle plugin, int numParams) @@ -2196,45 +2243,51 @@ public int Native_GetMapGroupRestriction(Handle plugin, int numParams) char[] map = new char[len+1]; GetNativeString(1, map, len+1); - static char group[255]; - int groupmax = InternalGetMapGroup(map, group, sizeof(group)); - int groupcur = 0; - if(groupmax >= 0) - { - static char map_[PLATFORM_MAX_PATH]; - static char group_[255]; - for(int i = 0; i < GetArraySize(g_NominateList); i++) - { - GetArrayString(g_NominateList, i, map_, PLATFORM_MAX_PATH); - int tmp = InternalGetMapGroup(map_, group_, sizeof(group_)); - if(tmp == groupmax && StrEqual(group, group_)) - groupcur++; - } + int groups[32]; + int groupsfound = InternalGetMapGroups(map, groups, sizeof(groups)); - if(groupcur >= groupmax) + for(int group = 0; group < groupsfound; group ++) + { + int groupcur = 0; + int groupmax = InternalGetGroupMax(groups[group]); + + if(groupmax >= 0) { - // Check if client has nominated a map in the same group and can change their nomination - if(client > 0 && client < MaxClients) + static char map_[PLATFORM_MAX_PATH]; + int groups_[32]; + for(int i = 0; i < GetArraySize(g_NominateList); i++) { - int index = FindValueInArray(g_NominateOwners, client); - if(index != -1) - { - static char oldmap[PLATFORM_MAX_PATH]; - GetArrayString(g_NominateList, index, oldmap, PLATFORM_MAX_PATH); - char oldgroup[255]; - int tmp = InternalGetMapGroup(oldmap, oldgroup, sizeof(oldgroup)); - if(tmp == groupmax && StrEqual(group, group_)) - return -321; - } + GetArrayString(g_NominateList, i, map_, PLATFORM_MAX_PATH); + int tmp = InternalGetMapGroups(map_, groups_, sizeof(groups_)); + if(FindIntInArray(groups_, tmp, groups[group]) != -1) + groupcur++; } - return groupmax; - } + if(groupcur >= groupmax) + { + // Check if client has nominated a map in the same group and can change their nomination + bool okay = false; + if(client > 0 && client < MaxClients) + { + int index = FindValueInArray(g_NominateOwners, client); + if(index != -1) + { + static char oldmap[PLATFORM_MAX_PATH]; + GetArrayString(g_NominateList, index, oldmap, PLATFORM_MAX_PATH); + static int oldgroups[32]; + int tmp = InternalGetMapGroups(oldmap, oldgroups, sizeof(oldgroups)); + if(FindIntInArray(groups_, tmp, groups[group]) != -1) + okay = true; + } + } - return -123; + if(!okay) + return groupmax; + } + } } - return groupmax; + return -1; } @@ -2276,19 +2329,32 @@ stock void AddExtendToMenu(Handle menu, MapChange when) } } -stock int GetVoteSize() +// 0 = IncludeMaps, 1 = Reserved, 2 = IncludeMaps+Reserved +stock int GetVoteSize(int what=0) { - int voteSize = GetConVarInt(g_Cvar_IncludeMaps); + int voteSize = 0; + int includeMaps = GetConVarInt(g_Cvar_IncludeMaps); + int includeMapsReserved = GetConVarInt(g_Cvar_IncludeMapsReserved); + + if(what == 0 || what == 2) + voteSize += includeMaps; + if(what == 1 || what == 2) + voteSize += includeMapsReserved; // New in 1.9.5 to let us bump up the included maps count if(g_NativeVotes) { int max = NativeVotes_GetMaxItems(); - if(max < voteSize) + if(voteSize > max) voteSize = max; + if(includeMaps > max) + includeMaps = max; } + if(what == 1) + return voteSize - includeMaps; + return voteSize; } @@ -2327,7 +2393,7 @@ void CheckMapRestrictions(bool time = false, bool players = false) CPrintToChat(client, "[MCE] %t", "Nomination Removed Time Error", map); } } - + if (players) { int PlayerRestriction = InternalGetMapPlayerRestriction(map); @@ -2408,8 +2474,9 @@ stock int InternalGetMapMaxPlayers(const char[] map) return MaxPlayers; } -stock int InternalGetMapGroup(const char[] map, char[] group, int size) +stock int InternalGetMapGroups(const char[] map, int[] groups, int size) { + int found = 0; if(g_Config && g_Config.JumpToKey("_groups")) { if(!g_Config.GotoFirstSubKey(false)) @@ -2420,19 +2487,44 @@ stock int InternalGetMapGroup(const char[] map, char[] group, int size) do { - int ret = g_Config.GetNum("_max", 1); - g_Config.GetSectionName(group, size); + char groupstr[8]; + g_Config.GetSectionName(groupstr, sizeof(groupstr)); + int group = StringToInt(groupstr); if(g_Config.JumpToKey(map, false)) { - g_Config.Rewind(); - return ret; + groups[found++] = group; + if(found >= size) + { + g_Config.Rewind(); + return found; + } + g_Config.GoBack(); } } while(g_Config.GotoNextKey()); g_Config.Rewind(); } - return -999; + return found; +} + +stock int InternalGetGroupMax(int group) +{ + char groupstr[8]; + IntToString(group, groupstr, sizeof(groupstr)); + if(g_Config && g_Config.JumpToKey("_groups")) + { + if(g_Config.JumpToKey(groupstr, false)) + { + int max = g_Config.GetNum("_max", -1); + g_Config.Rewind(); + return max; + } + + g_Config.Rewind(); + } + + return -1; } // 0 = Okay @@ -2484,3 +2576,14 @@ stock int InternalGetMapPlayerRestriction(const char[] map) return 0; } + +stock int FindIntInArray(int[] array, int size, int value) +{ + for(int i = 0; i < size; i++) + { + if(array[i] == value) + return i; + } + + return -1; +} From b3d8fd1a9dd2ad89c94b79e6b2d61bdfab7dd527 Mon Sep 17 00:00:00 2001 From: neon <> Date: Fri, 10 Aug 2018 15:45:40 +0200 Subject: [PATCH 2/3] AntiBhopCheat: fix runtime error --- AntiBhopCheat/scripting/AntiBhopCheat.sp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AntiBhopCheat/scripting/AntiBhopCheat.sp b/AntiBhopCheat/scripting/AntiBhopCheat.sp index d026b46e..e96ad32c 100644 --- a/AntiBhopCheat/scripting/AntiBhopCheat.sp +++ b/AntiBhopCheat/scripting/AntiBhopCheat.sp @@ -264,7 +264,7 @@ void DoStats(CPlayer Player, CStreak CurStreak, CJump hJump) int iPrevJump = hJump.iPrevJump; int iNextJump = hJump.iNextJump; - if(iPrevJump != -1) + if(iPrevJump > 0) { int iPerf = iPrevJump - 1; if(iPerf > 2) From ad5978aa3c774d111c6671445473368266b12203 Mon Sep 17 00:00:00 2001 From: neon <> Date: Fri, 10 Aug 2018 16:18:42 +0200 Subject: [PATCH 3/3] AntiBhopCheat: blub --- AntiBhopCheat/scripting/AntiBhopCheat.sp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AntiBhopCheat/scripting/AntiBhopCheat.sp b/AntiBhopCheat/scripting/AntiBhopCheat.sp index e96ad32c..73c595bc 100644 --- a/AntiBhopCheat/scripting/AntiBhopCheat.sp +++ b/AntiBhopCheat/scripting/AntiBhopCheat.sp @@ -28,7 +28,7 @@ char g_sStats[4096]; public Plugin myinfo = { name = "AntiBhopCheat", - autho = "BotoX", + author = "BotoX", description = "Detect all kinds of bhop cheats", version = "0.0", url = "" @@ -80,7 +80,7 @@ public Action OnPlayerRunCmd(int client, int &buttons) return Plugin_Continue; } -public void OnPlayerRunCmdPost(int client, int buttons, int impulse, float vel[3], float angles[3], int weapon, int subtype, int cmdnum, int tickcount) +public void OnPlayerRunCmdPost(int client, int buttons, int impulse, const float vel[3], const float angles[3], int weapon, int subtype, int cmdnum, int tickcount, int seed, const int mouse[2]) { if(!IsPlayerAlive(client)) return;