1.1 --- a/plugins/reservedslots.sp Wed Dec 19 22:19:34 2007 +0000
1.2 +++ b/plugins/reservedslots.sp Wed Dec 26 01:16:38 2007 +0000
1.3 @@ -53,6 +53,10 @@
1.4 new Handle:sv_visiblemaxplayers;
1.5 new Handle:sm_reserve_type;
1.6
1.7 +/* Variables to keep track of admin count */
1.8 +new bool:g_hasReserved[MAXPLAYERS+1];
1.9 +new g_adminCount;
1.10 +
1.11 public OnPluginStart()
1.12 {
1.13 LoadTranslations("reservedslots.phrases");
1.14 @@ -64,6 +68,7 @@
1.15
1.16 HookConVarChange(sm_reserved_slots, SlotsChanged);
1.17 HookConVarChange(sm_hide_slots, SlotsChanged);
1.18 + HookConVarChange(sm_reserve_type, TypeChanged);
1.19 }
1.20
1.21 public OnPluginEnd()
1.22 @@ -119,6 +124,8 @@
1.23
1.24 new type = GetConVarInt(sm_reserve_type);
1.25
1.26 +
1.27 +
1.28 if (type == 0)
1.29 {
1.30 if (clients <= limit || IsFakeClient(client) || flags & ADMFLAG_ROOT || flags & ADMFLAG_RESERVATION)
1.31 @@ -134,7 +141,7 @@
1.32 /* Kick player because there are no public slots left */
1.33 CreateTimer(0.1, OnTimedKick, client);
1.34 }
1.35 - else
1.36 + else if (type == 1)
1.37 {
1.38 if (clients > limit)
1.39 {
1.40 @@ -155,6 +162,33 @@
1.41 }
1.42 }
1.43 }
1.44 + else if (type == 2)
1.45 + {
1.46 + /* Skip the increment if hasReserved is already marked as true.
1.47 + * This could only occur if TypeChanged was called after a user is marked as 'ingame' but before they reach this point
1.48 + * In this case they will already have been counted.
1.49 + */
1.50 + if ((!g_hasReserved[client]) && (flags & ADMFLAG_ROOT || flags & ADMFLAG_RESERVATION))
1.51 + {
1.52 + g_hasReserved[client] = true;
1.53 + g_adminCount++;
1.54 + }
1.55 +
1.56 + if (g_adminCount >= reserved)
1.57 + {
1.58 + /* reserved slots are occupied by admins already so current slot must be a 'public' slot. No action */
1.59 + return;
1.60 + }
1.61 +
1.62 + new slotsRemaining = g_MaxClients - clients;
1.63 + new reservedRemaining = reserved - g_adminCount;
1.64 +
1.65 + if ((slotsRemaining < reservedRemaining) && (!g_hasReserved[client]))
1.66 + {
1.67 + /* Kick player because there are no public slots left */
1.68 + CreateTimer(0.1, OnTimedKick, client);
1.69 + }
1.70 + }
1.71 }
1.72 }
1.73
1.74 @@ -164,6 +198,12 @@
1.75 {
1.76 SetVisibleMaxSlots(GetClientCount(false), g_MaxClients - GetConVarInt(sm_reserved_slots));
1.77 }
1.78 +
1.79 + if (g_hasReserved[client])
1.80 + {
1.81 + g_adminCount--;
1.82 + g_hasReserved[client] = false;
1.83 + }
1.84 }
1.85
1.86 public SlotsChanged(Handle:convar, const String:oldValue[], const String:newValue[])
1.87 @@ -175,6 +215,35 @@
1.88 }
1.89 }
1.90
1.91 +public TypeChanged(Handle:convar, const String:oldValue[], const String:newValue[])
1.92 +{
1.93 + if (StringToInt(newValue) == 2)
1.94 + {
1.95 + g_adminCount = 0;
1.96 + new flags;
1.97 +
1.98 + for (new i=1; i<=g_MaxClients; i++)
1.99 + {
1.100 + if (!IsClientInGame(i))
1.101 + {
1.102 + continue;
1.103 + }
1.104 +
1.105 + flags = GetUserFlagBits(i);
1.106 +
1.107 + if (flags & ADMFLAG_ROOT || flags & ADMFLAG_RESERVATION)
1.108 + {
1.109 + g_hasReserved[i] = true;
1.110 + g_adminCount++;
1.111 + }
1.112 + else
1.113 + {
1.114 + g_hasReserved[i] = false;
1.115 + }
1.116 + }
1.117 + }
1.118 +}
1.119 +
1.120 SetVisibleMaxSlots(clients, limit)
1.121 {
1.122 new num = clients;