Доступ к готовым решениям

Переход в группу "Пользователь"

300.00 ₽
Одноразовый платёж
Быстрый переход в группу "Пользователи", без надобности написания постов и ожидания.

Покупка дает возможность:
Быть полноправным участником форума
Нормальное копирование кода
Создавать темы
Скачивать файлы
Доступ к архиву Pawno-Info

Урок Для новичков №1: DC_CMD | sscanf2

Статус
В этой теме нельзя размещать новые ответы.

Long-

Мастер
Команды DC_CMD + Sscanf2​

Команды в SA:MP существуют для того, чтобы можно было взаимодействовать с сервером.
Покупать оружее и т.п


Пример обработки команд стандартным способом:​

PHP:
public OnPlayerCommandText(playerid, cmdtext[])
{
    if(strcmp(cmdtext, "/command") == 0)
    {
        SendClientMessage(playerid, -1, "Вызвана.");
        return 1;
    }
    if(strcmp(cmdtext, "/command1") == 0)
    {
        SendClientMessage(playerid, -1, "Вызвана.");
        return 1;
    }
    return 0;
}
Данный код при вводе команд /command и /command1 выводит соответствующие сообщения. При этом, если нужно будет сделать обработку параметров команд (например, получить число 4 из строки "/cmd1 4"), такой код придётся усложнить, в 2-3 раза.
Но есть другой способ обработки команд: командный процессор DC_CMD


Пример создания команд для DC_CMD: ​

PHP:
CMD:command (playerid, params[])
{
    SendClientMessage(playerid, 0xFFFFFFFF, "Вызвана.");
    return 1;
}

CMD:command 1(playerid, params[])
{
    SendClientMessage(playerid, 0xFFFFFFFF, "Вызвана.");
    return 1;
}

Преимущества DC_CMD: ​


  • Более простой синтаксис команд.
  • Команды можно расположить в любом участке скрипта (не только в OnPlayerCommandText).
  • Не требуется вручную отделять параметры команд (уже отделённые параметры передаются в команду в строке params).
  • Проще в освоении.
  • Работает в разы быстрее других обработчиков, создавая меньшую нагрузку на сервер.

Теперь перейдём к обработке параметров.
Допустим, у нас есть команда "/ban", которая банит на сервере игрока с указанным ID (пример: "/ban 65").

PHP:
CMD:ban(playerid, params[])
{
    // ...
}
Однако, кроме самой команды, потребуется ещё и обработать ID указанного игрока, а именно - извлечь этот ID из строки params (именно в ней обработчик DC_CMD передаёт параметры).
Стандартным способом это делается с помощью функции strval, которая преобразует содержимое строки в число:

new target = strval(params);

Но в данном способе есть много минусов

  • Если игрок ничего не ввёл, строка params будет пустой и функция strval вернёт 0, из-за чего можно нечаянно забанить игрока ID 0 (а если под ID 0 находитесь вы - забаните сами себя).
  • Для обработки более чем 1 параметра, извлечения ID игроков и т.п. приходится вставлять в скрипт и много раз использовать пользовательские функции strtok, IsNumeric, ReturnUser и т.д.

Чтобы избежать этих ошибок, придётся сделать дополнительные проверки на пустоту и подсчёт количества параметров (сосчитать все пробелы в строке и прибавить 1). Такая задача может оказаться слишком трудной для начинающих скриптеров.
Однако, есть иное решение: плагин sscanf2.
Использование:
PHP:
sscanf(<исх. строка>, <форматная строка>, <переменные>);
<исходная строка> - строка, из которой считываются нужные значения
<форматная строка> - строка, в которой указывается, какого типа данные должны быть считаны из исходной строки (пример: "ds[40]")

  • d, i - целое число
  • f - вещественное число (Float)
  • u - игрок (ID или часть имени)
  • s[размер] - строка с указанной макс. длиной

<переменные> - переменные, в которые будут записаны значения, полученные из исходной строки


Для получения ID игрока в команде /ban плагин sscanf2 можно использовать следующим образом ​
PHP:
CMD:ban(playerid, params[])
{
    new target;
    sscanf(params, "u", target);
}
В результате в переменной target будет получен ID игрока, которого нужно забанить.

Но что делать, если ID всё же не был введён игроком?
Здесь всё тоже предусмотрено: функция sscanf возвращает 1 в случае ошибки и 0 в случае успеха. Таким образом, проверку на неправильный ввод можно записать в виде ветвления if
PHP:
CMD:ban(playerid, params[])
{
    new target;
    if(sscanf(params, "u", target))
    {
        SendClientMessage(playerid, 0xFFFFFFFF,
                          "Использование: /ban [ID игрока/часть имени]");
        return 1;
    }
    // ...
}
Если функция sscanf не сможет правильно считать параметры, она вернёт 1 (при этом в условиях всем ненулевым числам соответствует значение true), условие выполнится, игроку будет выведена подсказка о правильном использовании и команда прервёт свою работу.



Теперь, когда ID игрока получен и все случаи неправильного ввода обработаны, можно доделать оставшуюся часть команды:​

PHP:
CMD:ban(playerid, params[])
{
    new target;
    if(sscanf(params, "u", target))
    {
        SendClientMessage(playerid, 0xFFFFFFFF,
                          "Использование: /ban [ID игрока/часть имени]");
        return 1;
    }
    Ban(target);
    return 1;
}

Сделаем тестовую команду выдачу уровня:​

PHP:
CMD:givelevel(playerid, params[])
{
    new target, level;
    if(sscanf(params, "ud", target, level))
                return SendClientMessage(playerid, 0xFFFFFFFF, "Используйте: /givelevel [ID игрока/часть имени] [уровень]");

    SetPlayerScore(target, GetPlayerScore(target) + level);
    return 1;
}
Это команда отвечает за выдачу уровня определенного игрока.
И как вы успели заметить, тут мы используем 2 параметра это

  • target - Сюда записываем id игрока.
  • level - Записываем LVL который хотим дать игроку.

Разберем
PHP:
SetPlayerScore(target, GetPlayerScore(target) + level);
по подробнее.

  • SetPlayerScore - Функция отвечающая за число находящийся в TAB листе.
  • targetid - переменная в которую мы записали ID игрока.
  • GetPlayerScore(target) - Функция отвечающая за получения текущего числа в TAB листе.
  • + level - Так как мы уже получили текущее число которое уже есть и приплюсовываем к этому числу которое уже есть, ту переменную в которую записали число(Уровень).

Давайте создадим еще одну тестовую команду, но уже будем записывать не число а текст вывода определенному игроку:​

PHP:
CMD:sms(playerid, params[])
{
     new target, text, sendername[MAX_PLAYER_NAME], str_[28-4+MAX_PLAYER_NAME+120];
     if(sscanf(params, "us[145]", target, text))
                 return SendClientMessage(playerid, 0xFFFFFFFF, "Используйте: /sms [ID игрока/часть имени] [Text]");

     GetPlayerName(playerid, sendername, sizeof(sendername));
     format(str_ , sizeof(str_), "Игрок %s отправил вам текст: %s", sendername, text);
     SendClientMessage(target, 0xFFFFFFFF, str_);
     return 1;
}
Тут вы уже видите серьезную команду с записью имя игрока, текста, форматирования, много переменных, и уже наверное напугались :D
Но на самом деле не чего тут страшного нет, и самые обычные функции.

Разберем первую строку
PHP:
new target, text, sendername[MAX_PLAYER_NAME], str_[28-4+MAX_PLAYER_NAME+120];
по подробнее.

  • target - записываем id игрока.
  • text - записываем текст.
  • sendername[MAX_PLAYER_NAME] - в нее будет записываться имя игрока.

  • MAX_PLAYER_NAME - это макрос который определяет размер ячеек директивой #define по дефолту в a_samp.inc она имеет значение 24.
  • А 24 это максимальное длина имени, можно написать за место MAX_PLAYER_NAME просто 24 разницы не будет.
  • str_[28-4+MAX_PLAYER_NAME+120] - сюда как раз и будет записываться отформатированный текст.


  • 28-4+MAX_PLAYER_NAME+120 - Это размер ячеек сколько можно будет поместить в эту переменную символов.
  • Я сделал точный подсчет всего символов 28 не считая %s два раза. Именно поэтому я отнимаю 4 ибо % - 1 s - 2. и еще раз % - 1 s - 2.
  • + MAX_PLAYER_NAME - Ну думаю понятно максимальное длина имени.
  • + 120 - это и есть текст который будет передаваться в функцию SendClientMessage по дефолту в чат максимальная длина 144 + нуль символ 145.

Теперь расскажу подробнее про эту
PHP:
if(sscanf(params, "us[145]", target, text))
  • u - ид игрока
  • s[145] - сам текст и 145 ячеек.Так как всего максимальная длина 144 в чате + нуль символ 1 получается 145.

Получения имени игрока:

PHP:
GetPlayerName(<id игрока>, <строковая переменная>, <размер>)
Теперь про форматирования, это будет отдельный урок, расскажу кратко.

PHP:
format(<строковая переменная>, <размер>, <форматная строка>, <список>)
PHP:
SendClientMessage(target, 0xFFFFFFFF, str_);
Ну и здесь мы уже выводим отформатированный текст игроку.


Всем спасибо это был урок для новичков #1.

Урок #2 - Временно не доступен
​
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху Снизу