 |
|
 |
|
|
|
Последние Файлы GTA 4 |
Последние Файлы GTA-MP |
Реклама |
|
|
|
|
|
[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, так разве тут нет что ли?
|
| |
|
|
|
 |
|
 | |
| |
|