added new ReservedSlot plugin
This commit is contained in:
parent
0e1c5fbda3
commit
c66709f27c
232
ReservedSlot/scripting/ReservedSlot.sp
Normal file
232
ReservedSlot/scripting/ReservedSlot.sp
Normal file
@ -0,0 +1,232 @@
|
||||
#include <sourcemod>
|
||||
#include <cstrike>
|
||||
#include <connect>
|
||||
|
||||
#undef REQUIRE_PLUGIN
|
||||
#include <AfkManager>
|
||||
#include <GFLClanru>
|
||||
#include <entWatch>
|
||||
#define REQUIRE_PLUGIN
|
||||
|
||||
#pragma semicolon 1
|
||||
#pragma newdecls required
|
||||
|
||||
bool g_Plugin_AfkManager;
|
||||
bool g_Plugin_GFLClanru;
|
||||
bool g_Plugin_entWatch;
|
||||
|
||||
int g_Client_Reservation[MAXPLAYERS + 1] = {0, ...};
|
||||
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "Reserved Slot",
|
||||
author = "BotoX",
|
||||
description = "Kicks someone to make space for a connecting donator.",
|
||||
version = "0.1",
|
||||
url = ""
|
||||
};
|
||||
|
||||
public void OnPluginStart()
|
||||
{
|
||||
/* Late load */
|
||||
for(int client = 1; client <= MaxClients; client++)
|
||||
{
|
||||
if(IsClientInGame(client) && !IsFakeClient(client) && IsClientAuthorized(client))
|
||||
OnClientPostAdminCheck(client);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnAllPluginsLoaded()
|
||||
{
|
||||
g_Plugin_AfkManager = LibraryExists("AfkManager");
|
||||
g_Plugin_GFLClanru = LibraryExists("GFLClanru");
|
||||
g_Plugin_entWatch = LibraryExists("entWatch");
|
||||
|
||||
LogMessage("ReservedSlots capabilities:\nAfkManager: %s\nGFLClanru: %s\nentWatch: %s",
|
||||
(g_Plugin_AfkManager ? "loaded" : "not loaded"),
|
||||
(g_Plugin_GFLClanru ? "loaded" : "not loaded"),
|
||||
(g_Plugin_entWatch ? "loaded" : "not loaded"));
|
||||
}
|
||||
|
||||
public void OnClientPostAdminCheck(int client)
|
||||
{
|
||||
AdminId admin = GetUserAdmin(client);
|
||||
if(admin == INVALID_ADMIN_ID)
|
||||
return;
|
||||
|
||||
if(GetAdminFlag(admin, Admin_Reservation))
|
||||
{
|
||||
g_Client_Reservation[client] = GetAdminImmunityLevel(admin);
|
||||
if(!g_Client_Reservation[client])
|
||||
g_Client_Reservation[client] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnClientDisconnect(int client)
|
||||
{
|
||||
g_Client_Reservation[client] = 0;
|
||||
}
|
||||
|
||||
public EConnect OnClientPreConnectEx(const char[] sName, char sPassword[255], const char[] sIP, const char[] sSteam32ID, char sRejectReason[255])
|
||||
{
|
||||
// Server not full, nothing to do...
|
||||
if(GetClientCount(false) < MaxClients)
|
||||
return k_OnClientPreConnectEx_Accept;
|
||||
|
||||
// Try to get precached admin id.
|
||||
AdminId admin = FindAdminByIdentity(AUTHMETHOD_STEAM, sSteam32ID);
|
||||
int Immunity = 0;
|
||||
|
||||
// Valid and has reserved slot?
|
||||
if(admin != INVALID_ADMIN_ID && GetAdminFlag(admin, Admin_Reservation))
|
||||
{
|
||||
Immunity = GetAdminImmunityLevel(admin);
|
||||
|
||||
if(!KickValidClient(sName, sSteam32ID, admin, Immunity))
|
||||
{
|
||||
Format(sRejectReason, sizeof(sRejectReason), "No reserved slot available, sorry.");
|
||||
return k_OnClientPreConnectEx_Reject;
|
||||
}
|
||||
else
|
||||
return k_OnClientPreConnectEx_Accept;
|
||||
}
|
||||
|
||||
if(g_Plugin_GFLClanru)
|
||||
{
|
||||
DataPack pack = new DataPack();
|
||||
pack.WriteCell(admin);
|
||||
pack.WriteCell(Immunity);
|
||||
pack.WriteString(sName);
|
||||
|
||||
AsyncHasSteamIDReservedSlot(sSteam32ID, AsyncHasSteamIDReservedSlotCallback, pack);
|
||||
return k_OnClientPreConnectEx_Async;
|
||||
}
|
||||
|
||||
// Let the engine handle the rest.
|
||||
return k_OnClientPreConnectEx_Accept;
|
||||
}
|
||||
|
||||
public void AsyncHasSteamIDReservedSlotCallback(const char[] sSteam32ID, int Result, any Data)
|
||||
{
|
||||
// Slot free'd up while waiting or doesn't have a reserved slot?
|
||||
if(GetClientCount(false) < MaxClients || Result <= 0)
|
||||
{
|
||||
ClientPreConnectEx(sSteam32ID, k_OnClientPreConnectEx_Accept, "");
|
||||
return;
|
||||
}
|
||||
|
||||
DataPack pack = view_as<DataPack>(Data);
|
||||
pack.Reset();
|
||||
|
||||
AdminId admin = view_as<AdminId>(pack.ReadCell());
|
||||
int Immunity = pack.ReadCell();
|
||||
char sName[MAX_NAME_LENGTH];
|
||||
pack.ReadString(sName, sizeof(sName));
|
||||
|
||||
delete pack;
|
||||
|
||||
if(Result > Immunity)
|
||||
Immunity = Result;
|
||||
|
||||
if(!KickValidClient(sName, sSteam32ID, admin, Immunity))
|
||||
ClientPreConnectEx(sSteam32ID, k_OnClientPreConnectEx_Reject, "No reserved slot available, sorry.");
|
||||
else
|
||||
ClientPreConnectEx(sSteam32ID, k_OnClientPreConnectEx_Accept, "");
|
||||
}
|
||||
|
||||
stock bool KickValidClient(const char[] sName, const char[] sSteam32ID, AdminId admin, int Immunity)
|
||||
{
|
||||
int HighestValue[4] = {0, ...};
|
||||
int HighestValueClient[4] = {0, ...};
|
||||
|
||||
for(int client = 1; client <= MaxClients; client++)
|
||||
{
|
||||
if(!IsClientInGame(client) || IsFakeClient(client))
|
||||
continue;
|
||||
|
||||
int Donator = g_Client_Reservation[client];
|
||||
int ConnectionTime = RoundToNearest(GetClientTime(client));
|
||||
|
||||
int IdleTime;
|
||||
if(g_Plugin_AfkManager)
|
||||
IdleTime = GetClientIdleTime(client);
|
||||
else // Fall back to highest connection time.
|
||||
IdleTime = ConnectionTime;
|
||||
|
||||
bool HasItem = false;
|
||||
if(g_Plugin_entWatch)
|
||||
HasItem = entWatch_HasSpecialItem(client);
|
||||
|
||||
/* Spectators
|
||||
* Sort by idle time and also kick donators if IdleTime > 30
|
||||
*/
|
||||
if(GetClientTeam(client) == CS_TEAM_SPECTATOR)
|
||||
{
|
||||
if(!Donator || IdleTime > 30)
|
||||
{
|
||||
if(IdleTime > HighestValue[0])
|
||||
{
|
||||
HighestValue[0] = IdleTime;
|
||||
HighestValueClient[0] = client;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Spectators */
|
||||
|
||||
/* Dead non-donator with IdleTime > 30
|
||||
* Sort by idle time and don't kick donators.
|
||||
*/
|
||||
if(!Donator && GetClientTeam(client) != CS_TEAM_SPECTATOR && !IsPlayerAlive(client))
|
||||
{
|
||||
if(IdleTime > 30 && IdleTime > HighestValue[1])
|
||||
{
|
||||
HighestValue[1] = IdleTime;
|
||||
HighestValueClient[1] = client;
|
||||
}
|
||||
}
|
||||
/* Dead non-donator with IdleTime > 30 */
|
||||
|
||||
/* Alive non-donator with IdleTime > 30
|
||||
* Sort by idle time and don't kick donators and item owners.
|
||||
*/
|
||||
if(!Donator && IsPlayerAlive(client) && !HasItem)
|
||||
{
|
||||
if(IdleTime > 30 && IdleTime > HighestValue[2])
|
||||
{
|
||||
HighestValue[2] = IdleTime;
|
||||
HighestValueClient[2] = client;
|
||||
}
|
||||
}
|
||||
/* Alive non-donator with IdleTime > 30 */
|
||||
|
||||
/* Non-donator with highest connection time
|
||||
* Sort by connection time and don't kick donators and item owners.
|
||||
*/
|
||||
if(!Donator && !HasItem)
|
||||
{
|
||||
if(ConnectionTime > HighestValue[3])
|
||||
{
|
||||
HighestValue[3] = ConnectionTime;
|
||||
HighestValueClient[3] = client;
|
||||
}
|
||||
}
|
||||
/* Non-donator with highest connection time */
|
||||
}
|
||||
|
||||
// Check if any condition was met in the correct order and perform kick
|
||||
for(int i = 0; i < sizeof(HighestValue); i++)
|
||||
{
|
||||
if(HighestValue[i])
|
||||
{
|
||||
ExecuteKickValidClient(HighestValueClient[i], sName, sSteam32ID, admin, Immunity);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
stock void ExecuteKickValidClient(int client, const char[] sName, const char[] sSteam32ID, AdminId admin, int Immunity)
|
||||
{
|
||||
KickClientEx(client, "Kicked for reserved slot (%s joined).", sName);
|
||||
}
|
1
ReservedSlot/scripting/include/AfkManager.inc
Symbolic link
1
ReservedSlot/scripting/include/AfkManager.inc
Symbolic link
@ -0,0 +1 @@
|
||||
../../../AfkManager/scripting/include/AfkManager.inc
|
Loading…
Reference in New Issue
Block a user