Анти АФК

Тема в разделе "Общего назначения", создана пользователем Flame, 18 ноя 2016.

  1. Flame

    Flame -Заслуженый кодер форума-

    На днях глядел я серверный вариант мутатора кикающего игроков, если они находятся в состоянии "away from keyboard" - проще говоря AFK. А буквально только что пришло мне в голову, что клиентский вариант данного мутатора будет на порядок изящнее и короче.

    Ниже я приведу этот мутатор, а позже может выложу ещё и серверный вариант для сравнения. В комментариях к коду можно прочесть все нюансы мутатора.

    Настройки:
    bTryToMoveToSpectator - будем ли мы пытаться отправить игрока в зрители или сразу выкидываем из игры
    bAdminIsImmune - действует ли мутатор на админов
    bIgnoreTrader - действует ли мутатор во время трейдера
    AFKTime - через сколько секунд начинаем карательные действия против игрока
    InformTime - за сколько секунд до карательных действий выводим обратный отчёт игроку и звуки обратного отсчёта

    Код:
    Код:
    class AntiAFKMut extends Mutator config(AntiAFKMut);
    
    #exec OBJ LOAD FILE=Inf_Weapons_Foley.uax
    
    var config bool bTryToMoveToSpectator, bAdminIsImmune, bIgnoreTrader;
    var config int AFKTime, InformTime;
    
    var Vector oldLocation;
    var Rotator oldRotation;
    var int Counter;
    var bool bAlreadyTried;
    
    //Настройки лежат на сервере, а используются на клиенте
    replication
    {
        reliable if(bNetDirty && Role == Role_Authority)
            AFKTime,InformTime,bTryToMoveToSpectator,bAdminIsImmune,bIgnoreTrader;
    }
    
    //Таймер будет работать только на клиенте
    simulated function PostBeginPlay()
    {
        if(Role<Role_Authority)
            SetTimer(1.0,true);
    }
    
    simulated function Timer()
    {
        local PlayerController PC;
        PC=Level.GetLocalPlayerController();
    
        //Если контроллер none, то незачем идти дальше
        if(PC==none)
            return;
    
        //Если сейчас трейдер и переменная bIgnoreTrader=false, то счётчик AFK обнуляем и дальше не идём
        if    (
                !bIgnoreTrader
                &&    KFGameReplicationInfo(PC.GameReplicationInfo)!=none
                &&    !KFGameReplicationInfo(PC.GameReplicationInfo).bWaveInProgress
            )
        {
            if(Counter>0)
                Counter=0;
            return;
        }
    
        //Нету тела (мёртв или зритель или этот контроллер - не игрок) - нет смысла идти дальше
        if(PC.Pawn==none)
            return;
    
        //Если в настройках задан иммунитет админов, то их не трогаем и выходим из таймера
        if(PC.PlayerReplicationInfo.bAdmin && bAdminIsImmune)
            return;
    
        //Если в прошлый раз (секунду назад) было то же самое положение и поворот тела - увеличиваем счётчик на 1, иначе сбрасываем на 0
        if(oldLocation==PC.Pawn.Location && oldRotation==PC.Pawn.Rotation)
            Counter++;
        else
            Counter=0;
    
        //Информирование игрока о том, что скоро им займутся
        if(AFKTime-Counter<InformTime && Counter>0)
        {
            PC.ClientMessage("ÿAntiAFK Timer:"@Max(AFKTime-Counter,0));
            PC.PlayOwnedSound(Sound'Inf_Weapons_Foley.dryfire_rifle');
        }
    
        //Если прошло AFKTime секунд и игрок не пошевелился - начинаем над ним расправу
        if(Counter>=AFKTime)
        {
            //Вначале пытаемся запихнуть его в зрители (если в настройках bTryToMoveToSpectator==true)
            if(bTryToMoveToSpectator && !bAlreadyTried)
            {
                PC.BecomeSpectator();
                bAlreadyTried=true;
            }
            //Ну если не получилось сделать зрителем, то игрок как бы сам набирает команду disconnect :)
            else
                ConsoleCommand("disconnect");
        }
    
        //Обновляем "старые" значения положения и поворота
        oldLocation=PC.Pawn.Location;
        oldRotation=PC.Pawn.Rotation;
    }
    
    defaultproperties
    {
        bAddToServerPackages=true
        bAlwaysRelevant=true
        RemoteRole=ROLE_SimulatedProxy
        GroupName="KF-AntiAFK"
        FriendlyName="AntiAFKMut"
        Description="AntiAFKMut"
    }
    

    Ссылка 1 или Ссылка 2
    AntiAFKMut.AntiAFKMut

    Upd. Кстати, вот серверный вариант мутатора. Там правда вроде с косяками версия - поизучаю попозже и поправлю при необходимости
     
    Последнее редактирование: 18 ноя 2016
    LLIePLLIeHb, RaideN-, HATAXA и ещё 1-му нравится это.