Advertisement
Hinex_The_Crabe

ReservedSlots.sp

Sep 10th, 2016
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pawn 8.00 KB | None | 0 0
  1. /**
  2.  * vim: set ts=4 :
  3.  * =============================================================================
  4.  * SourceMod Reserved Slots Plugin
  5.  * Provides basic reserved slots.
  6.  *
  7.  * SourceMod (C)2004-2008 AlliedModders LLC.  All rights reserved.
  8.  * =============================================================================
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify it under
  11.  * the terms of the GNU General Public License, version 3.0, as published by the
  12.  * Free Software Foundation.
  13.  *
  14.  * This program is distributed in the hope that it will be useful, but WITHOUT
  15.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  16.  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
  17.  * details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License along with
  20.  * this program.  If not, see <http://www.gnu.org/licenses/>.
  21.  *
  22.  * As a special exception, AlliedModders LLC gives you permission to link the
  23.  * code of this program (as well as its derivative works) to "Half-Life 2," the
  24.  * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
  25.  * by the Valve Corporation.  You must obey the GNU General Public License in
  26.  * all respects for all other code used.  Additionally, AlliedModders LLC grants
  27.  * this exception to all derivative works.  AlliedModders LLC defines further
  28.  * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
  29.  * or <http://www.sourcemod.net/license.php>.
  30.  *
  31.  * Version: $Id$
  32.  */
  33.  
  34. #pragma semicolon 1
  35.  
  36. #include <sourcemod>
  37.  
  38. #pragma newdecls required
  39.  
  40. public Plugin myinfo =
  41. {
  42.     name = "Reserved Slots",
  43.     author = "AlliedModders LLC",
  44.     description = "Provides basic reserved slots",
  45.     version = SOURCEMOD_VERSION,
  46.     url = "http://www.sourcemod.net/"
  47. };
  48.  
  49. int g_adminCount = 0;
  50. bool g_isAdmin[MAXPLAYERS+1];
  51.  
  52. /* Handles to convars used by plugin */
  53. ConVar sm_reserved_slots;
  54. ConVar sm_hide_slots;
  55. ConVar sv_visiblemaxplayers;
  56. ConVar sm_reserve_type;
  57. ConVar sm_reserve_maxadmins;
  58. ConVar sm_reserve_kicktype;
  59.  
  60. enum KickType
  61. {
  62.     Kick_HighestPing,
  63.     Kick_HighestTime,
  64.     Kick_Random,   
  65. };
  66.  
  67. public void OnPluginStart()
  68. {
  69.     LoadTranslations("reservedslots.phrases");
  70.    
  71.     sm_reserved_slots = CreateConVar("sm_reserved_slots", "0", "Number of reserved player slots", 0, true, 0.0);
  72.     sm_hide_slots = CreateConVar("sm_hide_slots", "0", "If set to 1, reserved slots will hidden (subtracted from the max slot count)", 0, true, 0.0, true, 1.0);
  73.     sv_visiblemaxplayers = FindConVar("sv_visiblemaxplayers");
  74.     sm_reserve_type = CreateConVar("sm_reserve_type", "0", "Method of reserving slots", 0, true, 0.0, true, 2.0);
  75.     sm_reserve_maxadmins = CreateConVar("sm_reserve_maxadmins", "1", "Maximum amount of admins to let in the server with reserve type 2", 0, true, 0.0);
  76.     sm_reserve_kicktype = CreateConVar("sm_reserve_kicktype", "0", "How to select a client to kick (if appropriate)", 0, true, 0.0, true, 2.0);
  77.    
  78.     sm_reserved_slots.AddChangeHook(SlotCountChanged);
  79.     sm_hide_slots.AddChangeHook(SlotHideChanged);
  80. }
  81.  
  82. public void OnPluginEnd()
  83. {
  84.     /*  If the plugin has been unloaded, reset visiblemaxplayers. In the case of the server shutting down this effect will not be visible */
  85.     ResetVisibleMax();
  86. }
  87.  
  88. public void OnMapStart()
  89. {
  90.     CheckHiddenSlots();
  91. }
  92.  
  93. public void OnConfigsExecuted()
  94. {
  95.     CheckHiddenSlots();
  96. }
  97.  
  98. public Action OnTimedKick(Handle timer, any client)
  99. {  
  100.     if (!client || !IsClientInGame(client))
  101.     {
  102.         return Plugin_Handled;
  103.     }
  104.    
  105.     KickClient(client, "%T", "Slot reserved", client);
  106.    
  107.     CheckHiddenSlots();
  108.    
  109.     return Plugin_Handled;
  110. }
  111.  
  112. public void OnClientPostAdminCheck(int client)
  113. {
  114.     int reserved = sm_reserved_slots.IntValue;
  115.  
  116.     if (reserved > 0)
  117.     {
  118.         int clients = GetClientCount(false);
  119.         int limit = GetMaxHumanPlayers() - reserved;
  120.         int flags = GetUserFlagBits(client);
  121.        
  122.         int type = sm_reserve_type.IntValue;
  123.        
  124.         if (type == 0)
  125.         {
  126.             if (clients <= limit || IsFakeClient(client) || flags & ADMFLAG_ROOT || flags & ADMFLAG_RESERVATION)
  127.             {
  128.                 if (sm_hide_slots.BoolValue)
  129.                 {
  130.                     SetVisibleMaxSlots(clients, limit);
  131.                 }
  132.                
  133.                 return;
  134.             }
  135.            
  136.             /* Kick player because there are no public slots left */
  137.             CreateTimer(0.1, OnTimedKick, client);
  138.         }
  139.         else if (type == 1)
  140.         {  
  141.             if (clients > limit)
  142.             {
  143.                 if (flags & ADMFLAG_ROOT || flags & ADMFLAG_RESERVATION)
  144.                 {
  145.                     int target = SelectKickClient();
  146.                        
  147.                     if (target)
  148.                     {
  149.                         /* Kick public player to free the reserved slot again */
  150.                         CreateTimer(0.1, OnTimedKick, target);
  151.                     }
  152.                 }
  153.                 else
  154.                 {              
  155.                     /* Kick player because there are no public slots left */
  156.                     CreateTimer(0.1, OnTimedKick, client);
  157.                 }
  158.             }
  159.         }
  160.         else if (type == 2)
  161.         {
  162.             if (flags & ADMFLAG_ROOT || flags & ADMFLAG_RESERVATION)
  163.             {
  164.                 g_adminCount++;
  165.                 g_isAdmin[client] = true;
  166.             }
  167.            
  168.             if (clients > limit && g_adminCount < sm_reserve_maxadmins.IntValue)
  169.             {
  170.                 /* Server is full, reserved slots aren't and client doesn't have reserved slots access */
  171.                
  172.                 if (g_isAdmin[client])
  173.                 {
  174.                     int target = SelectKickClient();
  175.                        
  176.                     if (target)
  177.                     {
  178.                         /* Kick public player to free the reserved slot again */
  179.                         CreateTimer(0.1, OnTimedKick, target);
  180.                     }
  181.                 }
  182.                 else
  183.                 {              
  184.                     /* Kick player because there are no public slots left */
  185.                     CreateTimer(0.1, OnTimedKick, client);
  186.                 }      
  187.             }
  188.         }
  189.     }
  190. }
  191.  
  192. public void OnClientDisconnect_Post(int client)
  193. {
  194.     CheckHiddenSlots();
  195.    
  196.     if (g_isAdmin[client])
  197.     {
  198.         g_adminCount--;
  199.         g_isAdmin[client] = false
  200.     }
  201. }
  202.  
  203. public void SlotCountChanged(ConVar convar, const char[] oldValue, const char[] newValue)
  204. {
  205.     /* Reserved slots or hidden slots have been disabled - reset sv_visiblemaxplayers */
  206.     int slotcount = convar.IntValue;
  207.     if (slotcount == 0)
  208.     {
  209.         ResetVisibleMax();
  210.     }
  211.     else if (sm_hide_slots.BoolValue)
  212.     {
  213.         SetVisibleMaxSlots(GetClientCount(false), GetMaxHumanPlayers() - slotcount);
  214.     }
  215. }
  216.  
  217. public void SlotHideChanged(ConVar convar, const char[] oldValue, const char[] newValue)
  218. {
  219.     /* Reserved slots or hidden slots have been disabled - reset sv_visiblemaxplayers */
  220.     if (!convar.BoolValue)
  221.     {
  222.         ResetVisibleMax();
  223.     }
  224.     else
  225.     {
  226.         SetVisibleMaxSlots(GetClientCount(false), GetMaxHumanPlayers() - sm_reserved_slots.IntValue);
  227.     }
  228. }
  229.  
  230. void CheckHiddenSlots()
  231. {
  232.     if (sm_hide_slots.BoolValue)
  233.     {      
  234.         SetVisibleMaxSlots(GetClientCount(false), GetMaxHumanPlayers() - sm_reserved_slots.IntValue);
  235.     }
  236. }
  237.  
  238. void SetVisibleMaxSlots(int clients, int limit)
  239. {
  240.     int num = clients;
  241.    
  242.     if (clients == GetMaxHumanPlayers())
  243.     {
  244.         num = GetMaxHumanPlayers();
  245.     } else if (clients < limit) {
  246.         num = limit;
  247.     }
  248.    
  249.     sv_visiblemaxplayers.IntValue = num;
  250. }
  251.  
  252. void ResetVisibleMax()
  253. {
  254.     sv_visiblemaxplayers.IntValue = -1;
  255. }
  256.  
  257. int SelectKickClient()
  258. {
  259.     KickType type = view_as<KickType>(sm_reserve_kicktype.IntValue);
  260.    
  261.     float highestValue;
  262.     int highestValueId;
  263.    
  264.     float highestSpecValue;
  265.     int highestSpecValueId;
  266.    
  267.     bool specFound;
  268.    
  269.     float value;
  270.    
  271.     for (int i=1; i<=MaxClients; i++)
  272.     {  
  273.         if (!IsClientConnected(i))
  274.         {
  275.             continue;
  276.         }
  277.    
  278.         int flags = GetUserFlagBits(i);
  279.        
  280.         if (IsFakeClient(i) || flags & ADMFLAG_ROOT || flags & ADMFLAG_RESERVATION || CheckCommandAccess(i, "sm_reskick_immunity", ADMFLAG_RESERVATION, true))
  281.         {
  282.             continue;
  283.         }
  284.        
  285.         value = 0.0;
  286.            
  287.         if (IsClientInGame(i))
  288.         {
  289.             if (type == Kick_HighestPing)
  290.             {
  291.                 value = GetClientAvgLatency(i, NetFlow_Outgoing);
  292.             }
  293.             else if (type == Kick_HighestTime)
  294.             {
  295.                 value = GetClientTime(i);
  296.             }
  297.             else
  298.             {
  299.                 value = GetRandomFloat(0.0, 100.0);
  300.             }
  301.  
  302.             if (IsClientObserver(i))
  303.             {          
  304.                 specFound = true;
  305.                
  306.                 if (value > highestSpecValue)
  307.                 {
  308.                     highestSpecValue = value;
  309.                     highestSpecValueId = i;
  310.                 }
  311.             }
  312.         }
  313.        
  314.         if (value >= highestValue)
  315.         {
  316.             highestValue = value;
  317.             highestValueId = i;
  318.         }
  319.     }
  320.    
  321.     if (specFound)
  322.     {
  323.         return highestSpecValueId;
  324.     }
  325.    
  326.     return highestValueId;
  327. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement