1.1 --- a/plugins/reservedslots.sp Fri Jul 11 06:51:21 2008 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,310 +0,0 @@
1.4 -/**
1.5 - * vim: set ts=4 :
1.6 - * =============================================================================
1.7 - * SourceMod Reserved Slots Plugin
1.8 - * Provides basic reserved slots.
1.9 - *
1.10 - * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
1.11 - * =============================================================================
1.12 - *
1.13 - * This program is free software; you can redistribute it and/or modify it under
1.14 - * the terms of the GNU General Public License, version 3.0, as published by the
1.15 - * Free Software Foundation.
1.16 - *
1.17 - * This program is distributed in the hope that it will be useful, but WITHOUT
1.18 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.19 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.20 - * details.
1.21 - *
1.22 - * You should have received a copy of the GNU General Public License along with
1.23 - * this program. If not, see <http://www.gnu.org/licenses/>.
1.24 - *
1.25 - * As a special exception, AlliedModders LLC gives you permission to link the
1.26 - * code of this program (as well as its derivative works) to "Half-Life 2," the
1.27 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
1.28 - * by the Valve Corporation. You must obey the GNU General Public License in
1.29 - * all respects for all other code used. Additionally, AlliedModders LLC grants
1.30 - * this exception to all derivative works. AlliedModders LLC defines further
1.31 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
1.32 - * or <http://www.sourcemod.net/license.php>.
1.33 - *
1.34 - * Version: $Id$
1.35 - */
1.36 -
1.37 -#pragma semicolon 1
1.38 -
1.39 -#include <sourcemod>
1.40 -
1.41 -public Plugin:myinfo =
1.42 -{
1.43 - name = "Reserved Slots",
1.44 - author = "AlliedModders LLC",
1.45 - description = "Provides basic reserved slots",
1.46 - version = SOURCEMOD_VERSION,
1.47 - url = "http://www.sourcemod.net/"
1.48 -};
1.49 -
1.50 -/* Maximum number of clients that can connect to server */
1.51 -new g_MaxClients;
1.52 -new g_adminCount = 0;
1.53 -new bool:g_isAdmin[MAXPLAYERS+1];
1.54 -
1.55 -/* Handles to convars used by plugin */
1.56 -new Handle:sm_reserved_slots;
1.57 -new Handle:sm_hide_slots;
1.58 -new Handle:sv_visiblemaxplayers;
1.59 -new Handle:sm_reserve_type;
1.60 -new Handle:sm_reserve_maxadmins;
1.61 -new Handle:sm_reserve_kicktype;
1.62 -
1.63 -enum KickType
1.64 -{
1.65 - Kick_HighestPing,
1.66 - Kick_HighestTime,
1.67 - Kick_Random,
1.68 -};
1.69 -
1.70 -public OnPluginStart()
1.71 -{
1.72 - LoadTranslations("reservedslots.phrases");
1.73 -
1.74 - sm_reserved_slots = CreateConVar("sm_reserved_slots", "0", "Number of reserved player slots", 0, true, 0.0);
1.75 - 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);
1.76 - sv_visiblemaxplayers = FindConVar("sv_visiblemaxplayers");
1.77 - sm_reserve_type = CreateConVar("sm_reserve_type", "0", "Method of reserving slots", 0, true, 0.0, true, 2.0);
1.78 - 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);
1.79 - sm_reserve_kicktype = CreateConVar("sm_reserve_kicktype", "0", "How to select a client to kick (if appropriate)", 0, true, 0.0, true, 2.0);
1.80 -
1.81 - HookConVarChange(sm_reserved_slots, SlotsChanged);
1.82 - HookConVarChange(sm_hide_slots, SlotsChanged);
1.83 -}
1.84 -
1.85 -public OnPluginEnd()
1.86 -{
1.87 - /* If the plugin has been unloaded, reset visiblemaxplayers. In the case of the server shutting down this effect will not be visible */
1.88 - SetConVarInt(sv_visiblemaxplayers, g_MaxClients);
1.89 -}
1.90 -
1.91 -public OnMapStart()
1.92 -{
1.93 - g_MaxClients = GetMaxClients();
1.94 -
1.95 - if (GetConVarBool(sm_hide_slots))
1.96 - {
1.97 - SetVisibleMaxSlots(GetClientCount(false), g_MaxClients - GetConVarInt(sm_reserved_slots));
1.98 - }
1.99 -}
1.100 -
1.101 -public OnConfigsExecuted()
1.102 -{
1.103 - if (GetConVarBool(sm_hide_slots))
1.104 - {
1.105 - SetVisibleMaxSlots(GetClientCount(false), g_MaxClients - GetConVarInt(sm_reserved_slots));
1.106 - }
1.107 -}
1.108 -
1.109 -public Action:OnTimedKick(Handle:timer, any:client)
1.110 -{
1.111 - if (!client || !IsClientInGame(client))
1.112 - {
1.113 - return Plugin_Handled;
1.114 - }
1.115 -
1.116 - KickClient(client, "%T", "Slot reserved", client);
1.117 -
1.118 - if (GetConVarBool(sm_hide_slots))
1.119 - {
1.120 - SetVisibleMaxSlots(GetClientCount(false), g_MaxClients - GetConVarInt(sm_reserved_slots));
1.121 - }
1.122 -
1.123 - return Plugin_Handled;
1.124 -}
1.125 -
1.126 -public OnClientPostAdminCheck(client)
1.127 -{
1.128 - new reserved = GetConVarInt(sm_reserved_slots);
1.129 -
1.130 - if (reserved > 0)
1.131 - {
1.132 - new clients = GetClientCount(false);
1.133 - new limit = g_MaxClients - reserved;
1.134 - new flags = GetUserFlagBits(client);
1.135 -
1.136 - new type = GetConVarInt(sm_reserve_type);
1.137 -
1.138 - if (type == 0)
1.139 - {
1.140 - if (clients <= limit || IsFakeClient(client) || flags & ADMFLAG_ROOT || flags & ADMFLAG_RESERVATION)
1.141 - {
1.142 - if (GetConVarBool(sm_hide_slots))
1.143 - {
1.144 - SetVisibleMaxSlots(clients, limit);
1.145 - }
1.146 -
1.147 - return;
1.148 - }
1.149 -
1.150 - /* Kick player because there are no public slots left */
1.151 - CreateTimer(0.1, OnTimedKick, client);
1.152 - }
1.153 - else if (type == 1)
1.154 - {
1.155 - if (clients > limit)
1.156 - {
1.157 - if (flags & ADMFLAG_ROOT || flags & ADMFLAG_RESERVATION)
1.158 - {
1.159 - new target = SelectKickClient();
1.160 -
1.161 - if (target)
1.162 - {
1.163 - /* Kick public player to free the reserved slot again */
1.164 - CreateTimer(0.1, OnTimedKick, target);
1.165 - }
1.166 - }
1.167 - else
1.168 - {
1.169 - /* Kick player because there are no public slots left */
1.170 - CreateTimer(0.1, OnTimedKick, client);
1.171 - }
1.172 - }
1.173 - }
1.174 - else if (type == 2)
1.175 - {
1.176 - if (flags & ADMFLAG_ROOT || flags & ADMFLAG_RESERVATION)
1.177 - {
1.178 - g_adminCount++;
1.179 - g_isAdmin[client] = true;
1.180 - }
1.181 -
1.182 - if (clients > limit && g_adminCount < GetConVarInt(sm_reserve_maxadmins))
1.183 - {
1.184 - /* Server is full, reserved slots aren't and client doesn't have reserved slots access */
1.185 -
1.186 - if (g_isAdmin[client])
1.187 - {
1.188 - new target = SelectKickClient();
1.189 -
1.190 - if (target)
1.191 - {
1.192 - /* Kick public player to free the reserved slot again */
1.193 - CreateTimer(0.1, OnTimedKick, target);
1.194 - }
1.195 - }
1.196 - else
1.197 - {
1.198 - /* Kick player because there are no public slots left */
1.199 - CreateTimer(0.1, OnTimedKick, client);
1.200 - }
1.201 - }
1.202 - }
1.203 - }
1.204 -}
1.205 -
1.206 -public OnClientDisconnect_Post(client)
1.207 -{
1.208 - if (GetConVarBool(sm_hide_slots))
1.209 - {
1.210 - SetVisibleMaxSlots(GetClientCount(false), g_MaxClients - GetConVarInt(sm_reserved_slots));
1.211 - }
1.212 -
1.213 - if (g_isAdmin[client])
1.214 - {
1.215 - g_adminCount--;
1.216 - g_isAdmin[client] = false;
1.217 - }
1.218 -}
1.219 -
1.220 -public SlotsChanged(Handle:convar, const String:oldValue[], const String:newValue[])
1.221 -{
1.222 - /* Reserved slots or hidden slots have been disabled - reset sv_visiblemaxplayers */
1.223 - if (StringToInt(newValue) == 0)
1.224 - {
1.225 - SetConVarInt(sv_visiblemaxplayers, g_MaxClients);
1.226 - }
1.227 -}
1.228 -
1.229 -SetVisibleMaxSlots(clients, limit)
1.230 -{
1.231 - new num = clients;
1.232 -
1.233 - if (clients == g_MaxClients)
1.234 - {
1.235 - num = g_MaxClients;
1.236 - } else if (clients < limit) {
1.237 - num = limit;
1.238 - }
1.239 -
1.240 - SetConVarInt(sv_visiblemaxplayers, num);
1.241 -}
1.242 -
1.243 -SelectKickClient()
1.244 -{
1.245 - new KickType:type = KickType:GetConVarInt(sm_reserve_kicktype);
1.246 -
1.247 - new Float:highestValue;
1.248 - new highestValueId;
1.249 -
1.250 - new Float:highestSpecValue;
1.251 - new highestSpecValueId;
1.252 -
1.253 - new bool:specFound;
1.254 -
1.255 - new Float:value;
1.256 -
1.257 - for (new i=1; i<=g_MaxClients; i++)
1.258 - {
1.259 - if (!IsClientConnected(i))
1.260 - {
1.261 - continue;
1.262 - }
1.263 -
1.264 - new flags = GetUserFlagBits(i);
1.265 -
1.266 - if (IsFakeClient(i) || flags & ADMFLAG_ROOT || flags & ADMFLAG_RESERVATION || CheckCommandAccess(i, "sm_reskick_immunity", ADMFLAG_RESERVATION, false))
1.267 - {
1.268 - continue;
1.269 - }
1.270 -
1.271 - value = 0.0;
1.272 -
1.273 - if (IsClientInGame(i))
1.274 - {
1.275 - if (type == Kick_HighestPing)
1.276 - {
1.277 - value = GetClientAvgLatency(i, NetFlow_Outgoing);
1.278 - }
1.279 - else if (type == Kick_HighestTime)
1.280 - {
1.281 - value = GetClientTime(i);
1.282 - }
1.283 - else
1.284 - {
1.285 - value = GetRandomFloat(0.0, 100.0);
1.286 - }
1.287 -
1.288 - if (IsClientObserver(i))
1.289 - {
1.290 - specFound = true;
1.291 -
1.292 - if (value > highestSpecValue)
1.293 - {
1.294 - highestSpecValue = value;
1.295 - highestSpecValueId = i;
1.296 - }
1.297 - }
1.298 - }
1.299 -
1.300 - if (value >= highestValue)
1.301 - {
1.302 - highestValue = value;
1.303 - highestValueId = i;
1.304 - }
1.305 - }
1.306 -
1.307 - if (specFound)
1.308 - {
1.309 - return highestSpecValueId;
1.310 - }
1.311 -
1.312 - return highestValueId;
1.313 -}
1.314 \ No newline at end of file