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

  • Автор темы console1988
  • Дата начала
C

console1988

Ребят помогите пожалуйста
Решили с другом заморочиться, мы в этом деле новички:
Суть плагина:
При активации клиентом консольной команды на нём же должна выполниться клиентская команда, но при этом команду можно использовать раз 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 отдельный таймер?




[HIDE]
#pragma semicolon 1

#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
#include <cstrike>
#define VERSION "1.00"
new playersTimers[32];
public Plugin:myinfo =
{
name = "ConsoLe plugin helper",
author = "Freemy",
description = "Teleports / delay",
version = VERSION,
url = "http://"
};
public OnPluginStart()
{
RegConsoleCmd("sm_vip_tp20", CommandTp);
}
public Action:CommandTp(client, args)
{
new delayValue = 20;

new tsNow = GetTime();
new lastTime = playersTimers[client];
if (tsNow-lastTime < delayValue)
{
new delayLeft;
delayLeft = (delayValue - (tsNow-lastTime));

LogMessage("TP ERROR! Left: %d", delayLeft);
PrintHintText(client, "Подождите еще %d", delayLeft);
}
else
{
LogMessage("I confirm TP player (%d)", client);

playersTimers[client] = tsNow;
ClientCommand(client, "say !tp");
}
}
[/HIDE]
 
C

console1988

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

Вложения

  • cons_tp_hp.sp
    28.6 КБ · Просмотры: 3

Reiko1231

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

Упростить можно очень сильно. Ниже прикладываю код с комментариями. Допишите пропущенные команды.
В основе такого кода лежит теория об указателях и передаче по ссылке. Дело в том, что у сурсмода нет указателей, но за счёт того, что таймеры хранятся в массиве, можно передать настоящий таймер в функцию и произвести изменения над ним. Таким образом можно сократить количество проверок в коде в два раза. Это достигается добавлением в прототип к функции знака &, который говорит о том, что будет передана не копия переменной, а сама переменная.
Немного изменил вывод задержки до след. использования до 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(client, argc)
{
    // получаем команду
    decl String:command[32];
    // 0 аргумент - сама введённая команда
    GetCmdArg(0, command, sizeof(command));
    // отрезаем начало команды, т.е. "sm_vip_"
    strcopy(command, sizeof(command), command[7]);

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

    // отделяем префикс команды
    strcopy(sayCommand, index+1, command);
    // отделяем задержку до след. использования
    strcopy(strDelay, sizeof(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:timer, Float:currentTime, Float:delay)
{
    // находим разность
    new Float:difference = timer - currentTime;
    if ( difference > 0.0 ) { // если больше нуля, то возвращаем её
        return difference;
    }

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