AFK_manager [На сервере]
Добавлено: 01 ноя 2018, 17:17
Плагин перенаправляет в зрители игроков которые без действуют
Исходный код
Настройки:
Установка:
Выполните настройку в исходнике
Скомпилируйте плагин
Скопируйте скомпилированный файл .smx в директорию: sourcemod/plugins/

Код: Выбрать все
#include <sourcemod>
#include <sdktools>
const IMMUNITY_FLAG = ADMFLAG_ROOT; // Иммунитет к функциям плагина
const Float:AFK_CHECK_INTERVAL = 10.0; // Частота проверок
const Float:AFK_THRESHOLD = 30.0; // Погрешность в расчетах Origin в CS:GO [менять не стоит :)]
const Float:AFK_TIME_MOVE = 40.0; // Через сколько секунд бездействия игрока перевести в спектры
const AFK_PLAYERS_KICK = 30; // Сколько должно быть игроков на сервере, чтобы игрока кикнуло из спектров
const Float:AFK_TIME_KICK = 120.0; // Через сколько секунд игрока выкинуть с сервера с учетом AFK_PLAYERS_KICK
float g_fAfkTime[MAXPLAYERS + 1];
float g_fEyePos[MAXPLAYERS + 1][3];
float g_fOriginPos[MAXPLAYERS + 1][3];
int g_iObserverMode[MAXPLAYERS + 1];
int g_iObserverTarget[MAXPLAYERS + 1];
const SpecMode_Free_Look = 6;
const CS_TEAM_SPECTATOR = 1;
public Plugin myinfo =
{
name = "AFK Manager",
author = "neugomon",
description = "AFK Manager",
version = "1.2.1",
url = ""
}
public void OnPluginStart()
{
HookEvent("player_spawn", Event_PlayerSpawn);
HookEvent("player_team", Event_PlayerTeam);
HookEvent("player_death", Event_PlayerDeath);
}
public void OnConfigsExecuted()
{
CreateTimer(.interval = AFK_CHECK_INTERVAL, .func = CheckPlayerAfk, .flags = TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
}
public void Event_PlayerSpawn(Handle event, const char[] name, bool dontBroadcast)
{
int client = GetClientOfUserId(GetEventInt(event, "userid"));
if(IsClientInGame(client) && IsPlayerAlive(client))
ResetPlayerData(client);
}
public void Event_PlayerTeam(Handle event, const char[] name, bool dontBroadcast)
{
int client = GetClientOfUserId(GetEventInt(event, "userid"));
if(IsClientInGame(client))
{
ResetPlayerData(client);
if(GetEventInt(event, "team") == CS_TEAM_SPECTATOR)
{
GetClientEyeAngles(client, g_fEyePos[client]);
g_iObserverMode[client] = GetEntProp(client, Prop_Send, "m_iObserverMode");
g_iObserverTarget[client]= GetEntPropEnt(client, Prop_Send, "m_hObserverTarget");
}
}
}
public void Event_PlayerDeath(Handle event, const char[] name, bool dontBroadcast)
{
int client = GetClientOfUserId(GetEventInt(event, "userid"));
ResetPlayerData(client);
}
public Action CheckPlayerAfk(Handle timer, any data)
{
// PrintToChatAll("-> afk check");
float fEyePos[3];
float fOriginPos[3];
bool bSpecKick = (GetClientCount(true) >= AFK_PLAYERS_KICK && AFK_TIME_KICK > 0.0);
for(int client = 1, team; client <= MaxClients; client++)
{
if(!IsClientInGame(client))
continue;
team = GetClientTeam(client);
if(IsClientObserver(client))
{
if(team > CS_TEAM_SPECTATOR && !IsPlayerAlive(client))
continue;
else if(team == CS_TEAM_SPECTATOR || CheckObserver(client))
g_fAfkTime[client] += AFK_CHECK_INTERVAL;
else
{
g_fAfkTime[client] = 0.0;
continue;
}
}
else
{
fEyePos = g_fEyePos[client];
fOriginPos = g_fOriginPos[client];
GetClientEyeAngles(client, g_fEyePos[client]);
GetClientAbsOrigin(client, g_fOriginPos[client]);
if((g_fEyePos[client][0] == fEyePos[0]) &&
(g_fEyePos[client][1] == fEyePos[1]) &&
(g_fEyePos[client][2] == fEyePos[2]) &&
(FloatAbs(g_fOriginPos[client][0] - fOriginPos[0]) < AFK_THRESHOLD) &&
(FloatAbs(g_fOriginPos[client][1] - fOriginPos[1]) < AFK_THRESHOLD) &&
(FloatAbs(g_fOriginPos[client][2] - fOriginPos[2]) < AFK_THRESHOLD) &&
~GetEntityFlags(client) & FL_FROZEN)
{
g_fAfkTime[client] += AFK_CHECK_INTERVAL;
}
else
{
g_fAfkTime[client] = 0.0;
continue;
}
}
if(team > CS_TEAM_SPECTATOR)
{
if((AFK_TIME_MOVE - g_fAfkTime[client]) <= 0.0)
ChangeClientTeam(client, CS_TEAM_SPECTATOR);
else
{
PrintToChat(
client,
"\x01[\x04AFK\x01] \x08Вы находитесь AFK \x03%.0f \x08сек из \x01допустимых \x03%.0f \x08сек",
g_fAfkTime[client],
AFK_TIME_MOVE
);
}
}
else if(bSpecKick && (AFK_TIME_KICK - g_fAfkTime[client]) <= 0.0 && ~GetUserFlagBits(client) & IMMUNITY_FLAG)
KickClient(client, "Вы слишком долго находились AFK");
}
return Plugin_Continue;
}
void ResetPlayerData(int client)
{
g_fAfkTime[client] = 0.0;
g_fEyePos[client][0] = g_fEyePos[client][1] = g_fEyePos[client][2] = 0.0;
g_iObserverMode[client] = g_iObserverTarget[client] = 0;
}
bool CheckObserver(int client)
{
int iLastObserverMode = g_iObserverMode[client];
g_iObserverMode[client]= GetEntProp(client, Prop_Send, "m_iObserverMode");
if(iLastObserverMode && g_iObserverMode[client] != iLastObserverMode)
return false;
float fEyePos[3];
fEyePos = g_fEyePos[client];
if(g_iObserverMode[client] == SpecMode_Free_Look)
GetClientEyeAngles(client, g_fEyePos[client]);
else
{
int iLastObserverTarget = g_iObserverTarget[client];
g_iObserverTarget[client]= GetEntPropEnt(client, Prop_Send, "m_hObserverTarget");
if(!iLastObserverMode && !iLastObserverTarget)
return true;
if(iLastObserverTarget > 0 && g_iObserverTarget[client] != iLastObserverTarget)
{
return (
iLastObserverTarget > MaxClients ||
!IsClientInGame(iLastObserverTarget)
) ? false : (!IsPlayerAlive(iLastObserverTarget));
}
}
return (
(g_fEyePos[client][0] == fEyePos[0]) &&
(g_fEyePos[client][1] == fEyePos[1]) &&
(g_fEyePos[client][2] == fEyePos[2])
) ? true : false;
}
Настройки:
Код: Выбрать все
const IMMUNITY_FLAG = ADMFLAG_ROOT; // Иммунитет к функциям плагина
const Float:AFK_CHECK_INTERVAL = 10.0; // Частота проверок
const Float:AFK_THRESHOLD = 30.0; // Погрешность в расчетах Origin в CS:GO [менять не стоит :)]
const Float:AFK_TIME_MOVE = 40.0; // Через сколько секунд бездействия игрока перевести в спектры
const AFK_PLAYERS_KICK = 30; // Сколько должно быть игроков на сервере, чтобы игрока кикнуло из спектров
const Float:AFK_TIME_KICK = 120.0; // Через сколько секунд игрока выкинуть с сервера с учетом AFK_PLAYERS_KICK
Установка:
Выполните настройку в исходнике
Скомпилируйте плагин
Скопируйте скомпилированный файл .smx в директорию: sourcemod/plugins/