Выполнение команды если игрок стоит на месте.

Тема в разделе "Программирование / Скриптинг", создана пользователем phll, 19 апр 2014.

  1. phll

    phll

    Сообщения:
    10
    Симпатии:
    0
    Если простой способ отловить afk? csgo.

    p.s. я плохо разбираюсь в этом:(.
     
    Последнее редактирование: 19 апр 2014
  2. FrozDark

    FrozDark Команда сайта HLMod Модератор

    Сообщения:
    1.761
    Симпатии:
    1.915
    попробуй
     

    Вложения:

    phll и Серый™ нравится это.
  3. phll

    phll

    Сообщения:
    10
    Симпатии:
    0
    Спасибо за ответ:) но не мог бы ты выложить исходник?
    как ты определяешь afk? и как сильно такая проверка может нагрузить серв?

    грубо говоря мне нужно условия определение afk(желательно не громозкое и легкое), при нахождение чтобы выполнилось это команда, и все:) KickClient(client, "AFK");.
     
  4. phll

    phll

    Сообщения:
    10
    Симпатии:
    0
    нашел вот это:
    Код:
    CheckForAFK(client)
    {
        new Float:f_Loc[3];
        new f_Team = GetClientTeam(client);
        new bool:f_SamePlace[3];
    
        if(f_Team > 1 || g_IsSynergy)
        {
            GetPlayerEye(client, f_Loc);
    
            for(new i = 0; i < 3; i++)
            {
                if(g_Position[client][i] == f_Loc[i])
                {
                    f_SamePlace[i] = true;
                }
                else
                {
                    f_SamePlace[i] = false;
                }
            }
        }
    
        if((f_SamePlace[0] == true
            && f_SamePlace[1] == true
            && f_SamePlace[2] == true)
            || (f_Team < 2 && g_IsSynergy == false))
        {
            g_TimeAFK[client]++;
        }
        else
        {
            g_TimeAFK[client] = 0;
        }
    }
    
    .......
    
    bool:GetPlayerEye(client, Float:pos[3])
    {
        new Float:vAngles[3], Float:vOrigin[3];
        GetClientEyePosition(client,vOrigin);
        GetClientEyeAngles(client, vAngles);
        
        new Handle:trace = TR_TraceRayFilterEx(vOrigin, vAngles, MASK_SHOT, RayType_Infinite, TraceEntityFilterPlayer);
        
        if(TR_DidHit(trace))
        {
             //This is the first function i ever saw that anything comes before the handle
            TR_GetEndPosition(pos, trace);
            CloseHandle(trace);
            return true;
        }
        CloseHandle(trace);
        return false;
    }
    немогу рзобраться, знаю что это то, но не могу использовать... может кто то сможет помощь? Нужная простая проверка afk, на респе в начале раунда. Если игрок не двигался 30 секунд, выполнить команду KickClient(client, "AFK")


    Вот плагин:
    Код:
    /**
     * vim: set ts=4 :
     * =============================================================================
     * AFK Manager
     * Handles AFK Players
     *
     * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
     * =============================================================================
     *
     * This program is free software; you can redistribute it and/or modify it under
     * the terms of the GNU General Public License, version 3.0, as published by the
     * Free Software Foundation.
     * 
     * This program is distributed in the hope that it will be useful, but WITHOUT
     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
     * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
     * details.
     *
     * You should have received a copy of the GNU General Public License along with
     * this program.  If not, see <http://www.gnu.org/licenses/>.
     *
     * As a special exception, AlliedModders LLC gives you permission to link the
     * code of this program (as well as its derivative works) to "Half-Life 2," the
     * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
     * by the Valve Corporation.  You must obey the GNU General Public License in
     * all respects for all other code used.  Additionally, AlliedModders LLC grants
     * this exception to all derivative works.  AlliedModders LLC defines further
     * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
     * or <http://www.sourcemod.net/license.php>.
     *
     */
    
    #pragma semicolon 1
    #include <sourcemod>
    #include <sdktools>
    
    #define VERSION "2.8"
    
    #define _DEBUG 0 // set to 1 to enable debug
    
    // global variables
    new Float:g_Position[MAXPLAYERS+1][3];
    new g_TimeAFK[MAXPLAYERS+1];
    new bool:g_IsSynergy = false;
    new bool:g_IsTF2Arena;
    new bool:g_IsLateLoad = false;
    new g_MaxPlayers = 0;
    
    // cvars
    new Handle:g_Cvar_Enabled = INVALID_HANDLE;
    new Handle:g_Cvar_MinPlayersMove = INVALID_HANDLE;
    new Handle:g_Cvar_MinPlayersKick = INVALID_HANDLE;
    new Handle:g_Cvar_AdminsImmune = INVALID_HANDLE;
    new Handle:g_Cvar_MoveSpec = INVALID_HANDLE;
    new Handle:g_Cvar_TimeToMove = INVALID_HANDLE;
    new Handle:g_Cvar_TimeToKick = INVALID_HANDLE;
    
    public Plugin:myinfo =
    {
        name = "AFK Manager",
        author = "Liam",
        description = "Handles AFK Players",
        version = VERSION,
        url = "http://www.wcugaming.org"
    };
    
    public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
    {
        g_IsLateLoad = late;
        return APLRes_Success;
    }
    
    public OnPluginStart( )
    {
        decl String:f_ModName[64];
    
        LoadTranslations("common.phrases");
        RegisterHooks( );
        RegisterCvars( );
        AutoExecConfig(true, "afk_manager");
        g_MaxPlayers = GetMaxClients();
    
        GetGameDescription(f_ModName, sizeof(f_ModName), true);
    
        if(!strcmp(f_ModName, "Synergy"))
        {
            g_IsSynergy = true;
        }
        
        if (g_IsLateLoad == true)
        {
            if (FindEntityByClassname(GetMaxClients() + 1, "tf_arena_logic") == INVALID_ENT_REFERENCE)
            {
                g_IsTF2Arena = false;
            }
            else
            {
                g_IsTF2Arena = true;
            }
        }
    }
    
    RegisterCvars( )
    {
        CreateConVar("sm_afk_version", VERSION, "Current version of the AFK Manager", FCVAR_REPLICATED|FCVAR_NOTIFY|FCVAR_DONTRECORD);
        g_Cvar_Enabled = CreateConVar("sm_afkenable", "1", "Is the AFK manager enabled or disabled? [0 = FALSE, 1 = TRUE]");
        g_Cvar_MinPlayersMove = CreateConVar("sm_minplayersmove", "4", "Minimum amount of connected clients needed to move AFK clients to spec.");
        g_Cvar_MinPlayersKick = CreateConVar("sm_minplayerskick", "6", "Minimum amount of connected clients needed to kick AFK clients.");
        g_Cvar_AdminsImmune = CreateConVar("sm_adminsimmune", "1", "Admins immune to being kicked? [0 = FALSE, 1 = TRUE]");
        g_Cvar_MoveSpec = CreateConVar("sm_movespec", "1", "Move AFK clients to spec before kicking them? [0 = FALSE, 1 = TRUE]");
        g_Cvar_TimeToMove = CreateConVar("sm_timetomove", "60.0", "Time in seconds before moving an AFK player.");
        g_Cvar_TimeToKick = CreateConVar("sm_timetokick", "120.0", "Time in seconds before kicking an AFK player.");
    }
    
    public OnMapStart( )
    {
        for(new i = 1; i <= g_MaxPlayers; i++)
        {
            g_TimeAFK[i] = 0;
        }
        CreateTimer(60.0, Timer_StartTimers, _, TIMER_FLAG_NO_MAPCHANGE);
    }
    
    public Action:Timer_StartTimers(Handle:Timer)
    {
        CreateTimer(7.0, Timer_UpdateView, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
        CreateTimer(10.0, Timer_CheckPlayers, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
    }
    
    RegisterHooks( )
    {
        HookEvent("player_spawn", Event_PlayerSpawn);
        HookEvent("player_team", Event_PlayerTeam);
        HookEventEx("arena_round_start", Event_ArenaRoundStart);
        HookEventEx("teamplay_round_start", Event_RoundStart);
        HookEventEx("round_start", Event_RoundStart);
    }
    
    public Action:Event_PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast)
    {
        new client = GetClientOfUserId(GetEventInt(event, "userid"));
        g_TimeAFK[client] = 0;
    }
    
    public Action:Event_RoundStart(Handle:event, const String:name[], bool:dontBroadcast)
    {
        g_IsTF2Arena = false;
    }
    
    public Action:Event_ArenaRoundStart(Handle:event, const String:name[], bool:dontBroadcast)
    {
        g_IsTF2Arena = true;
    }
    
    public Action:Event_PlayerTeam(Handle:event, const String:name[], bool:dontBroadcast)
    {
        new client = GetClientOfUserId(GetEventInt(event, "userid"));
        
        if(!g_IsSynergy)
        {        
            if(GetEventInt(event, "team") > 1)
            {
                g_TimeAFK[client] = 0;
            }
        }
        else
        {
            g_TimeAFK[client] = 0;
        }
    }
    
    public Action:Timer_UpdateView(Handle:Timer)
    {
        for(new i = 1; i <= g_MaxPlayers; i++)
        {
            if(IsRealPlayer(i) == false
                || IsPlayerAlive(i) == false)
            {
                continue;
            }
            GetPlayerEye(i, g_Position[i]);
        }
    }
    
    public Action:Timer_CheckPlayers(Handle:Timer)
    {
        if(GetConVarInt(g_Cvar_Enabled) == 0)
            return Plugin_Stop;
    
        if(GetConVarInt(g_Cvar_MinPlayersMove) >= GetClientCount( ))
        {
            return Plugin_Continue;
        }
    
        for(new i = 1; i < g_MaxPlayers; i++)
        {
            if(IsRealPlayer(i) == false)
            {
                continue;
            }
            CheckForAFK(i);
            HandleAFKClient(i);
        }
        return Plugin_Continue;
    }
    
    CheckForAFK(client)
    {
        new Float:f_Loc[3];
        new f_Team = GetClientTeam(client);
        new bool:f_SamePlace[3];
    
        if(f_Team > 1 || g_IsSynergy)
        {
            GetPlayerEye(client, f_Loc);
    
            for(new i = 0; i < 3; i++)
            {
                if(g_Position[client][i] == f_Loc[i])
                {
                    f_SamePlace[i] = true;
                }
                else
                {
                    f_SamePlace[i] = false;
                }
            }
        }
    
        if((f_SamePlace[0] == true
            && f_SamePlace[1] == true
            && f_SamePlace[2] == true)
            || (f_Team < 2 && g_IsSynergy == false))
        {
            g_TimeAFK[client]++;
        }
        else
        {
            g_TimeAFK[client] = 0;
        }
    }
    
    HandleAFKClient(client)
    {
        new f_SpecTime = RoundToZero(GetConVarFloat(g_Cvar_TimeToMove)) / 10;
        new f_KickTime = RoundToZero(GetConVarFloat(g_Cvar_TimeToKick)) / 10;
        new f_MoveSpec = GetConVarInt(g_Cvar_MoveSpec);
        new f_MinKick = GetConVarInt(g_Cvar_MinPlayersKick);
        decl String:f_Name[MAX_NAME_LENGTH];
        new f_Team = GetClientTeam(client);
    
        GetClientName(client, f_Name, sizeof(f_Name));
    
        if (g_IsSynergy == false
            && f_MoveSpec == 1
            && g_TimeAFK[client] < f_KickTime 
            && g_TimeAFK[client] >= f_SpecTime)
        {
            if(f_Team == 2 || f_Team == 3)
            {
                PrintToChatAll("%s was moved to spectate for being AFK.", f_Name);
                LogAction(0, -1, "\"%L\" was moved to spectate for being AFK too long.", client);
                ChangeClientTeam(client, 1);
                
                if (g_IsTF2Arena == true)
                {
                    SetEntProp(client, Prop_Send, "m_bArenaSpectator", true);
                }
            }
            return;
        }
        
        // added to do a last final check. Maybe they moved during the timer update and max count?
        CheckForAFK(client);
    
        if(g_TimeAFK[client] >= f_KickTime
            && !IsAdmin(client))
        {
    #if _DEBUG
            LogAction(0, -1, "Kicking Client: %d, Team: %d - CVar_MinKick: %d - ClientCount: %d", client, f_Team, f_MinKick, GetClientCount(false));
    #endif
            if(GetClientCount(false) >= f_MinKick) // this shouldn't matter but wtf ever
            {
                PrintToChatAll("%s was kicked for being AFK.", f_Name);
                LogAction(0, -1, "\"%L\" was kicked for being AFK too long.", client);
                KickClient(client, "You were AFK for too long.");
            }
        }
    }
    
    // This code was borrowed from Nican's spraytracer
    bool:GetPlayerEye(client, Float:pos[3])
    {
        new Float:vAngles[3], Float:vOrigin[3];
        GetClientEyePosition(client,vOrigin);
        GetClientEyeAngles(client, vAngles);
        
        new Handle:trace = TR_TraceRayFilterEx(vOrigin, vAngles, MASK_SHOT, RayType_Infinite, TraceEntityFilterPlayer);
        
        if(TR_DidHit(trace))
        {
             //This is the first function i ever saw that anything comes before the handle
            TR_GetEndPosition(pos, trace);
            CloseHandle(trace);
            return true;
        }
        CloseHandle(trace);
        return false;
    }
    
    public bool:TraceEntityFilterPlayer(entity, contentsMask)
    {
        return entity > GetMaxClients( );
    }
    
    bool:IsAdmin(client)
    {
    #if _DEBUG
        LogAction(0, -1, "Checking for admins.");
    #endif
    
        if(GetConVarInt(g_Cvar_AdminsImmune) == 0)
        {
    #if _DEBUG
            LogAction(0, -1, "Admins are not immune to being kicked.");
    #endif
            return false;
        }
    
        new AdminId:admin = GetUserAdmin(client);
    
    #if _DEBUG
        decl String:name[MAX_NAME_LENGTH];
    
        GetClientName(client, name, sizeof(name));
        LogAction(0, -1, "Checking for valid AdminID: Found: %d for client %s", _:admin, name);
    #endif
    
        if(admin == INVALID_ADMIN_ID)
        {
    #if _DEBUG
            LogAction(0, -1, "Client %s has an invalid Admin ID.", name);
    #endif
            return false;
        }
    #if _DEBUG
        LogAction(0, -1, "Client %s has a valid Admin ID and is immune.", name);
    #endif
        return true;
    }
    
    bool:IsRealPlayer(client)
    {
        if(!IsClientConnected(client)
            || !IsClientInGame(client)
            || IsFakeClient(client))
        {
            return false;
        }
        return true;
    }
    
    
     
  5. FrozDark

    FrozDark Команда сайта HLMod Модератор

    Сообщения:
    1.761
    Симпатии:
    1.915
    только он проверяет не только игрока стоящего на респе
     

    Вложения:

  6. HOSTVD

    HOSTVD

    Сообщения:
    11
    Симпатии:
    2
    Вот обрезанная версия плагина от wS (AFK Ping Control v1.3)
    PHP:
    #pragma semicolon 1
    #include <sourcemod>
    #include <sdktools_functions>

    new Handle:g_hTimer;
    new 
    Float:g_MyAngles[MAXPLAYERS 1][3];

    public 
    OnPluginStart()
    {
        
    wS_StartTimer();
    }

    wS_StartTimer(){g_hTimer CreateTimer(7.0g_AfkTimer_CallBack_TIMER_REPEAT TIMER_FLAG_NO_MAPCHANGE);} \\ если игрок бездействует 7 секундто кикает.

    public 
    OnMapStart()
    {
        
    g_hTimer INVALID_HANDLE;
    }

    public 
    Action:g_AfkTimer_CallBack(Handle:timer)
    {
        
    decl Float:angles[3];
        for (new 
    1<= MaxClientsi++)
        {
            if (
    IsClientInGame(i) && !IsFakeClient(i))
            {
                if (
    GetClientEyeAngles(iangles))
                {
                    if (
    angles[0] == g_MyAngles[i][0] && angles[1] == g_MyAngles[i][1] && angles[2] == g_MyAngles[i][2])
                    {
                        
    KickClient(i"AFK");
                    }
                    else
                        
    g_MyAngles[i] = angles;
                }
            }
        }
        return 
    Plugin_Continue;
    }

    public 
    OnClientPutInServer(client)
    {
        if (
    g_hTimer == INVALID_HANDLE && !IsFakeClient(client))
            
    wS_StartTimer();
    }
    вроде работает...
    Но было бы хорошо, если бы взглянул знающий человек и оптимизировал:).
     
  7. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.975
    Симпатии:
    2.981
    HOSTVD,
    PHP:
    #pragma semicolon 1
    #include <sourcemod>
    #include <sdktools_functions>

    new Handle:g_hTimer;
    new 
    Float:g_MyAngles[MAXPLAYERS 1][3];

    public 
    OnMapStart()
    {
        if(
    g_hTimer != INVALID_HANDLE)
        {
            
    KillTimer(g_hTimer);
            
    g_hTimer INVALID_HANDLE;
        }
        
    g_hTimer CreateTimer(7.0g_AfkTimer_CallBack_TIMER_REPEAT TIMER_FLAG_NO_MAPCHANGE);
    }

    public 
    Action:g_AfkTimer_CallBack(Handle:timer)
    {
        
    decl Float:angles[3];
        for (new 
    1<= MaxClientsi++)
        {
            if (
    IsClientInGame(i) && !IsFakeClient(i))
            {
                if (
    GetClientEyeAngles(iangles))
                {
                    if (
    angles[0] == g_MyAngles[i][0] && angles[1] == g_MyAngles[i][1] && angles[2] == g_MyAngles[i][2]) KickClient(i"AFK");
                    else 
    g_MyAngles[i] = angles;
                }
            }
        }
        return 
    Plugin_Continue;
    }
    Но еще не плохо было бы проверять наблюдатель ли он.
     
  8. HOSTVD

    HOSTVD

    Сообщения:
    11
    Симпатии:
    2
    Баг: если не двигать мышку а просто ходить туда сюда клавой, тебя всеравно кикнет. Из-за того что используется только GetClientEyeAngles.

    Добавлено через 2 минуты
    я в этом плох.... сможешь допилить на досуге?:)
     
    Последнее редактирование: 20 апр 2014
  9. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.975
    Симпатии:
    2.981
    Проверяй GetClientEyeAngles и GetClientAbsOrigin.

    Еще учитывай IsClientObserver, GetEntProp(client, Prop_Send, "m_iObserverMode") и GetEntPropEnt(client, Prop_Send, "m_hObserverTarget");

    У меня не бывает досуга..

    Чем это не устраивает?
    http://hlmod.ru/forum/plaginy-dlya-...chennyi-afk-manager-css-tf2-v-razrabotke.html
     
  10. KorDen

    KorDen Atra esterní ono thelduin! Ньюсмейкер

    Сообщения:
    2.194
    Симпатии:
    1.398
    R1KO, там нет проверки на AFK со спауна, я же как раз ее вырезал там
     
    R1KO нравится это.
  11. The End Is Near...

    The End Is Near... Russian Roulette

    Сообщения:
    893
    Симпатии:
    659
    R1KO
    Не нужно выделять переменную для таймера в данном случае
     
    R1KO нравится это.