Проблемы с delay-таймером, ClientSay, Unknown Command

Тема в разделе "Запросы", создана пользователем console1988, 15 фев 2016.

  1. console1988

    console1988

    Сообщения:
    84
    Симпатии:
    5
    Ребят помогите пожалуйста
    Решили с другом заморочиться, мы в этом деле новички:
    Суть плагина:
    При активации клиентом консольной команды на нём же должна выполниться клиентская команда, но при этом команду можно использовать раз x секунд.
    Теперь в чём проблемы:
    1) при вводе команды sm_vip_tp20 выдается ошибка и команда не выполняется
    ] sm_vip_tp20
    FCVAR_SERVER_CAN_EXECUTE prevented server running command: say
    2) таймер работает, он выдаёт что Подождите использование через х секунд, но:
    в консоли идёт флуд
    ] sm_vip_tp20
    Unknown command: sm_vip_tp20
    3) как сделать команду например sm_vip_hp20, но, чтобы и у команды sm_vip_tp20 и у sm_vip_hp20
    был один общий таймер?
    т.е. в течении 20 секунд можно заюзать только 1 команду из 2 двух
    4)создать команду sm_vip_god20, но она уже будет по 2 таймеру работать?
    т.е. sm_vip_tp20 и sm_vip_hp20 - общий таймер?
    sm_vip_god20 отдельный таймер?




     
  2. console1988

    console1988

    Сообщения:
    84
    Симпатии:
    5
    сделал как мне надо, но вопрос? упростить можно?
    И возможно ли то, что я сделал что-то не так, стал сервер вылетать пару раз в день, error log пусто..
    --- Добавлено позже ---
    Дополнительно обнаруженный баг:
    Иногда пишет 22200000 секунд до востановления
    Причем это число может быть любым. Но не тем которое я выставил в исходнике
     

    Вложения:

    • cons_tp_hp.sp
      Размер файла:
      28,6 КБ
      Просмотров:
      2
  3. Reiko1231

    Reiko1231 AlexTheRegent

    Сообщения:
    237
    Симпатии:
    569
    Упростить можно очень сильно. Ниже прикладываю код с комментариями. Допишите пропущенные команды.
    В основе такого кода лежит теория об указателях и передаче по ссылке. Дело в том, что у сурсмода нет указателей, но за счёт того, что таймеры хранятся в массиве, можно передать настоящий таймер в функцию и произвести изменения над ним. Таким образом можно сократить количество проверок в коде в два раза. Это достигается добавлением в прототип к функции знака &, который говорит о том, что будет передана не копия переменной, а сама переменная.
    Немного изменил вывод задержки до след. использования до 1 цифры после запятой.
    Так же важным замечанием является код форварда OnClientPutInServer() - если не сбросить переменные таймера, то клиент, зашедший на слот вышеднего игрока унаследует его таймер и будет вынужден ждать (допустим, игрок отыграл 23 минуты и, использовав таймер на 1 минуту, вышел. Тогда зашедшему на его слот придётся ждать 24 минуты, прежде чем он сможет использовать эту команду).

    PHP:
    // переменные со значением времени, когда можно будет в следующий раз ввести команду
    new Float:playersTimers    [MAXPLAYERS+1];
    new 
    Float:playersTimers2[MAXPLAYERS+1];
    new 
    Float:playersTimers3[MAXPLAYERS+1];

    public 
    OnPluginStart()
    {
        
    // регистрируем все команды на один обработчик
        
    RegConsoleCmd("sm_vip_tp60",     Command_Handler);
        
    RegConsoleCmd("sm_vip_hp60",     Command_Handler);
        
    RegConsoleCmd("sm_vip_ju55",     Command_Handler);
        
    RegConsoleCmd("sm_vip_fl50",     Command_Handler);
        
    RegConsoleCmd("sm_vip_god30",     Command_Handler);
        
    RegConsoleCmd("sm_vip_wg20",     Command_Handler);
    }

    // при входе клиента сбрасываем все таймеры на ноль
    public OnClientPutInServer(client)
    {
        
    playersTimers[client]     = 0.0;
        
    playersTimers2[client]     = 0.0;
        
    playersTimers3[client]     = 0.0;
    }

    // игрок ввёл команду
    public Action:Command_Handler(clientargc)
    {
        
    // получаем команду
        
    decl String:command[32];
        
    // 0 аргумент - сама введённая команда
        
    GetCmdArg(0commandsizeof(command));
        
    // отрезаем начало команды, т.е. "sm_vip_"
        
    strcopy(commandsizeof(command), command[7]);

        
    // делаем предположение, что команда имеет вид "префикс команды""задержка до след. использования"
        // ищем, откуда начинается цифра
        
    decl String:sayCommand[8], String:strDelay[4];
        new 
    index;
        while ( !
    IsCharNumeric(command[index]) ) {
            
    index++;
        }

        
    // отделяем префикс команды
        
    strcopy(sayCommandindex+1command);
        
    // отделяем задержку до след. использования
        
    strcopy(strDelaysizeof(strDelay), command[index]);

        
    // получаем разность между текущим временем и временем, когда можно использовать команду
        
    new Float:difference;
        
    // если команда начинается с "tp" или "hp", используем первый таймер
        
    if ( !strcmp(sayCommand"tp") || !strcmp(sayCommand"hp") ) {
            
    difference CheckDelay(playersTimers[client], GetClientTime(client), StringToFloat(strDelay));
        }
        
    // если команда начинается с "ju" или "fl", используем второй таймер
        
    else if ( !strcmp(sayCommand"ju") || !strcmp(sayCommand"fl") ) {
            
    difference CheckDelay(playersTimers2[client], GetClientTime(client), StringToFloat(strDelay));
        }
        
    // если команда начинается с "god" или "wg", используем третий таймер
        
    else if ( !strcmp(sayCommand"god") || !strcmp(sayCommand"wg") ) {
            
    difference CheckDelay(playersTimers3[client], GetClientTime(client), StringToFloat(strDelay));
        }
        
    // иначе для такой команды нет таймера, выдадим ошибку
        
    else {
          
    LogError("invalid command prefix %s"sayCommand);
          return 
    Plugin_Handled;
        }

        
    // если разность != -1, то он не может использовать команду
        
    if ( difference != -1.0 ) {
            
    LogMessage("TP ERROR! Left: %f"difference);
            
    PrintHintText(client"Подождите еще %.1f"difference);
        }
        
    // иначе может
        
    else {
            
    FakeClientCommand(client"say !%s_checker228"sayCommand);
        }

        return 
    Plugin_Handled;
    }

    // функция проверки и установки след. времени использования
    Float:CheckDelay(&Float:timerFloat:currentTimeFloat:delay)
    {
        
    // находим разность
        
    new Float:difference timer currentTime;
        if ( 
    difference 0.0 ) { // если больше нуля, то возвращаем её
            
    return difference;
        }

        
    // увеличиваем таймер, если разность <= 0.0
        
    timer currentTime delay;
        
    // возвращаем -1.0, чтобы знать, что таймер точно истёк
        
    return -1.0;
    }
     
    console1988 нравится это.