AFK_manager  [На сервере]

Плагины и дополнения / Plugins and add-ons

Модераторы: Dame-danners, Longipongeoos

Аватар пользователя
Longipongeoos
Сообщений: 199
Зарегистрирован: 12 апр 2017, 16:50

AFK_manager  [На сервере]

Сообщение Longipongeoos » 01 ноя 2018, 17:17

Плагин перенаправляет в зрители игроков которые без действуют
Исходный код

Код: Выбрать все

#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/
Вложения
afk_manager.zip
(1.94 KiB) Загружено 200 раз

Вернуться в «SourceMod»

Кто сейчас на форуме

Количество пользователей, которые сейчас просматривают этот форум: нет зарегистрированных пользователей и 3 гостей