06:31
ОбновитьСмайлыУправление мини-чатом
МИНИ-ЧАТ
Главная страница!

 



 
          





Рекомендуем:





Последние Файлы GTA 4 Последние Файлы GTA-MP Реклама
Скрипт GTA 4 элементы Watch... 07.09.2014
Ferrari 360 Spider [EPM con... 13.12.2013
Porsche Cayenne Turbo 2012 ... 13.12.2013
Shelby Terlingua Mustang v1... 13.12.2013
Hamann Lamborghini Gallardo... 27.10.2013
[GM] The Big PEN1:LS v2.00 ... 04.12.2017
Dgun (AvnanceRP,SampRP,Dimo... 19.03.2016
SAMP скрипт SX Events (MySQ... 03.03.2016
Карта ASL мэрия для SAMP се... 03.03.2016
AIM для SA-MP 0.3.7 22.02.2016
  • Страница 1 из 1
  • 1
Модератор форума: Dima-kun  
[Lesson] strtok или построение многоуровневых команд
LatronДата: Четверг, 28.07.2011, 16:16 | Сообщение # 1
Группа: I'm V.I.P.
Сообщений: 2115
Награды: 22
Город: Орел
Репутация: 1604
Замечания: 0%
Статус:
Итак, сегодня я расскажу вам как пользоватся кастомной функцией strtok, с ее помощью скриптеры делают команды вида /cmd argument1 argument2 , вам наверное всегда хотелось научится делать такие же команды, но нам важно не только сделать такую же, а научится делать.

Итак для начала добавим в мод саму функцию
Code

strtok(const string[], &index)
{
     new length = strlen(string);
     while ((index < length) && (string[index] <= ' '))
     {
         index++;
     }
   
     new offset = index;
     new result[20];
     while ((index < length) && (string[index] > ' ') && ((index - offset) < (sizeof(result) - 1)))
     {
         result[index - offset] = string[index];
         index++;
     }
     result[index - offset] = EOS;
     return result;
}


потом добавим в паблик OnPlayerCommandText переменные, нужные для работы нашей функции.
Code

new cmd[128],idx,tmp[128];
cmd = strtok(cmdtext, idx);

где cmd будет - возвращаемое функцией strtok текст введенный в команду(строковый тип), idx - сокращенный вариант написания слова index, будет использоватся в функции, tmp - ее мы будем использовать уже в команде, по аналогии с cmd. И строкой ниже мы в первый раз используем нашу функцию.

Для использования функции команда требует следующего построения:
Code

if(strcmp(cmd, "/mycmd", true) == 0) { }   


Итак, теперь разберем на примере как это все будет работать.
Code

if(strcmp(cmd, "/mycmd", true) == 0)
{
tmp = strtok(cmdtext, idx);
if(!strlen(tmp)) return SendClientMessage(playerid,0xFFFFFFAA,"Вы ввели пустое поле!");
new string[64];
format(string,64,"Вы ввели текст: %s",tmp);
SendClientMessage(playerid,0xFFFFFFAA,string);
return 1;
}

итак что же мы сделали? разберем построчно.

Code

tmp = strtok(cmdtext, idx);  


мы используем нашу функцию и геттим то, что ввел игрок в поле после команды. Так как strtok возвращает строковый тип далее в функции format мы использовали индикатор %s. Тоесть мы построили команду таким образом, чтобы нам высвечивался введенный нами после команды текст.
Code

if(!strlen(tmp)) return SendClientMessage(playerid,0xFFFFFFAA,"Вы ввели пустое поле!");

функция strlen(переменная) возвращает кол-во символов в переменной с текстом(в данном случае tmp) и если функция ничего не возвращает, то и введенный нами текст - пуст.
Code

new string[64];
format(string,64,"Вы ввели текст: %s",tmp);
SendClientMessage(playerid,0xFFFFFFAA,string);  


код добавленный мною для того чтобы вы наглядно увидели действие функции.

Итак теперь разберем команды где нам надо ввести числовое значение, например ID игрока.

Делаем все по старой схеме:

Code

if(strcmp(cmd, "/mycmd", true) == 0)
{
    tmp = strtok(cmdtext, idx);
    if(!strlen(tmp)) return SendClientMessage(playerid,0xFFFFFFAA,"Вы ввели пустое поле!");
    new numeric = strval(tmp);
    new string[64];
    format(string,64,"Вы ввели цифру: %d",numeric);
    SendClientMessage(playerid,0xFFFFFFAA,string);
    return 1;
}  


как вы уже заметили к команде добавилась одна строка:
Code

new numeric = strval(tmp);  


разберем ее.

Функция strval(переменная) конвертирует числовое значение из строкового. Тоесть если мы ввели /mycmd 5, то 5 изначально будет строкового типа, а для использования некоторых функций(kick, ban) нам нужно числовое значение, в этих случаях мы используем эту функцию.

Теперь разберемся с float значениями.
Code

if(strcmp(cmd, "/mycmd", true) == 0)
{
    tmp = strtok(cmdtext, idx);
    if(!strlen(tmp)) return SendClientMessage(playerid,0xFFFFFFAA,"Вы ввели пустое поле!");
    new float = floatstr(tmp);
    new string[64];
    format(string,64,"Вы ввели десятичную дробь: %f",float);
    SendClientMessage(playerid,0xFFFFFFAA,string);
    return 1;
}  

В команде мы поменяли две строки, одна из которых
Code

new float = floatstr(tmp);  


как вы уже поняли функция floatstr(переменная) конвертирует строковый тип в число с точкой(десятичная дробь). Практически тоже самое что и strval.

А теперь я предлагаю обьеденить полученные нами знания и написать /kick с причиной.
Code

if(strcmp(cmd, "/kick", true) == 0)
{
    tmp = strtok(cmdtext, idx);
    if(!strlen(tmp)) return SendClientMessage(playerid,0xFFFFFFAA,"Используйте /kick [ID] [причина]");
    new target = strval(tmp);

    tmp = strtok(cmdtext, idx);
    if(!strlen(tmp)) return SendClientMessage(playerid,0xFFFFFFAA,"Используйте /kick [ID] [причина]");

    if(IsPlayerConnected(target))
    {
       new string[256];
       Kick(target);
       format(string,256,"Кто-то кикнул игрока с ID %d. Причина: %s",target,tmp);
       SendClientMessageToAll(0xFFFFFFAA,string);
    }
    return 1;
}


как видите, чтобы сделать многоуровневую команду, надо просто расположить элементы друг за другом и все будет работать. В данной команде я добавил проверку на то подключен ли игрок серверу, так будет получше.

Надеюсь мой урок вам помог.

Внимание, если вам больше нравится zcmd, ненадо писать это в этой теме. Мне тоже она больше нравится. Я писал урок для тех, у кого вероятно есть мод в котором есть данные команды и они непонимают как они устроены. Также неплохо бы это знать для общего развития.

Урок написан by REALman



Моё портфолио

Мои работы:
[ Lesson ] Операторы в PAWN.
[ Lesson ] Переменная.
[ GM ] RegSys. ( Last update: 21.04.2012 )


ZiGGiДата: Четверг, 28.07.2011, 23:36 | Сообщение # 2
Мастер джэдай
Группа: Продвинутые
Сообщений: 2652
Награды: 34
Город: St. Petersburg
Репутация: 2102
Замечания: 20%
Статус:
sscanf это который плагином? Нет, уж лучше strtok'ом...


Бложе
[indent]Мой блог
Уроки по Pawn
[/indent]

Open-GTO
[indent]Блог разработчиков
GitHub: https://github.com/Open-GTO/Open-GTO
Сборки мода с сервером тут
[/indent]
toneysixДата: Пятница, 29.07.2011, 03:44 | Сообщение # 3
Джэдай
Группа: I'm V.I.P.
Сообщений: 1731
Награды: 77
Город: Салават
Репутация: 1825
Замечания: 0%
Статус:
Quote
а куда спешить, ведь с strtok команда все равно будет выполнятся секунды, а может и меньше смотря от построения кода, но ведь он будет выполнятся за очень короткое время, за которое даже не надо будет ждать.

Команды, зачастую, являются самой нагружаемой структурой в моде, единожды естественно не даст никаких визуальных результатов, но если относиться ко всему всерьез, то конструкция команды с использованием strcmp и strtok будет неуместным для средних и тяжелых модов, которые имеют перспективу в дальнейшем развитии. По скорости обычная гф-подобная конструкция, я так её называю, медленнее в 3-4 раза, чем конструкция со sscanof'ом и любого другого обработчика команд, например zcmd, от нашего русского программиста. sscanf проходит всего 2 цикла, когда strtok все 6, при двух аргументах, и они имеют достаточно не легкие я бы так сказал проверки. Плюс ко всему этому, в плагине работа идет намного быстрее, само выполнение функций, это тоже приносит свои плюсы, при запуске ваши библиотеки, будь это so или dll интегрируются в главный процесс сервера и работают совместно, поэтому это не приносит абсолютно никакой нагрузки на сервер. При большом количестве онлайн и достаточно сложном моде, в котором итак куча проверок это доп.снижение нагрузки, никак иначе оптимизация будет как раз кстати. Сам я для удобства изменил немного sscanf, были некоторые не удобности в его работе, теперь конфетка, и сокращается время написания всех этих команд в двое. То, что мы видим выше, никак иначе способ, который уже давным давно застарел и ходит по простору всего гф-подобного "чуда".
P.S: Секунды хД, если команда выполняется секунды, это уже мега жесть, это говорит о том, что есть огромная задержка, а поскольку павн идет в один поток, то эта задержка скажется на всем моде, это не надо забывать. Но про секунды ты конечно загнул, тут борются за каждую миллисекунду, а ты про секунды))
Однако:
Quote
Внимание, если вам больше нравится zcmd, ненадо писать это в этой теме. Мне тоже она больше нравится. Я писал урок для тех, у кого вероятно есть мод в котором есть данные команды и они непонимают как они устроены. Также неплохо бы это знать для общего развития.

Эту просьбу никто не взял во внимание xD



Русскоязычныи портал о MTA/GTA-IV-MP | http://multi-theft-auto.ru

Сообщение отредактировал toneysix - Пятница, 29.07.2011, 03:49
[-Smart-]Дата: Среда, 23.11.2011, 22:33 | Сообщение # 4
Группа: I'm V.I.P.
Сообщений: 249
Награды: 3
Город: Казань
Репутация: 229
Замечания: 20%
Статус:
Начал изучать.
Наткнулся на одну проблемку.
Но ее я уже решил..

Вот смотри ты пишешь

что команда
Code
if(strcmp(cmd, "/mycmd", true) == 0)  
{  
     tmp = strtok(cmdtext, idx);  
     if(!strlen(tmp)) return SendClientMessage(playerid,0xFFFFFFAA,"Вы ввели пустое поле!");  
     new numeric = strval(tmp);  
     new string[64];  
     format(string,64,"Вы ввели цифру: %d",numeric);  
     SendClientMessage(playerid,0xFFFFFFAA,string);  
     return 1;  
}  
будет писать тебе сообщение. Хотя это совершено не так так как она будет показывать только слово после 1 пробела и до 2 пробела.

DiSEДата: Четверг, 24.11.2011, 14:47 | Сообщение # 5
Группа: I'm V.I.P.
Сообщений: 1759
Награды: 23
Город: Уфа
Репутация: 337
Замечания: 80%
Статус:
Что не так-то? Всё правильно
MerixДата: Четверг, 24.11.2011, 15:05 | Сообщение # 6
Уважаемый человек
Группа: Продвинутые
Сообщений: 757
Награды: 20
Город: Тверь
Репутация: 1306
Замечания: 60%
Статус:
[-Smart-] правильно говорит, вот например
/mycmd Мы все умрем
из этого выведет только "Мы"



Совсем новое. Скоро ты обалдеешь.
EakwarpДата: Четверг, 24.11.2011, 15:10 | Сообщение # 7
Мастер джэдай
Группа: Продвинутые
Сообщений: 4874
Награды: 179
Город: Москва
Репутация: 2543
Замечания: 60%
Статус:
Лучше урок по переводу мода с этой доисторической схемы на zcmd или sscanff написали.


More than 4 years of development, more than 250,000 lines of source code, more than a hundred units and more than 3400 revisions. Valakas Roleplay - choose your role.


Valakas Roleplay on Twitter

Платные консультации, разработка, в ICQ. Дорого.
DiSEДата: Пятница, 25.11.2011, 15:47 | Сообщение # 8
Группа: I'm V.I.P.
Сообщений: 1759
Награды: 23
Город: Уфа
Репутация: 337
Замечания: 80%
Статус:
Eakwarp, так разве тут нет что ли?
  • Страница 1 из 1
  • 1
Поиск:





 


 


 
Хостинг от uCoz samp.at.ua