PDA

Просмотр полной версии : [Вопрос] CMD: id



BENGO
23.12.2017, 22:30
Всем привет! Делаю команду для поиска имен игроков, но вот какая штука, дает результат только в том случае, если вбивать сначала имени, а как сделать чтобы искало например с середины имени игрока, и с минимальным кол-во введенных символом от 4, я не знаю. Кто поможет, огромное спасибо, и извините, если вопрос глуповатый. Вид кода сейчас:


CMD:id(playerid, params[])
{
if(sscanf(params, "u", params[0]))
return SCM(playerid,-1,#Hint"Введите: /id [id игрока / NickName игрока]");
else if(!IsPlayerConnected(params[0]))
return SCM(playerid,-1,#Error"Неверный id игрока.");
else if(!gPlayerLogged[params[0]])
return SCM(playerid,-1,#Error"Игрок с данным id не авторизован.");

SCM(playerid,-1,"Результат поиска:");
SCM(playerid,COLOR_BLUE,"______________________________");
foreach(new i: Player)
{
if(!IsPlayerConnected(i)) continue;
static const
names[] = "%s [%d]";
new
str_names[sizeof(names)+(MAX_PLAYER_NAME-2)+(4-2)];
format(
str_names,
sizeof(str_names),
names,
Name(i),i);
SCM(playerid,-1,str_names);
}
SCM(playerid,COLOR_BLUE,"______________________________");
return true;
}

Pa4enka
23.12.2017, 22:47
Какой командный процессор используете? (я к тому, что Pawn.CMD позволяет облегчить поиск)

Geebrox
23.12.2017, 22:58
#if !defined MIN_PLAYER_NAME
#define MIN_PLAYER_NAME 4
#endif

CMD:id(playerid, params[])
{
extract params -> string:name_part[MIN_PLAYER_NAME]; else
{
return SendClientMessage(playerid, -1, !"Используйте: /id [часть имени игрока]");
}

static const message_template[] = "ID: %d | Имя: %s";
new
message[sizeof(message_template) - 2 + 3 - 2 + MAX_PLAYER_NAME];
player_name[MAX_PLAYER_NAME],
bool:isfound = false;

SendClientMessage(playerid, -1, !"Результаты поиска:");

for(new i = 0; i < GetPlayerPoolSize(); i++)
{
if(!GetPlayerName(playerid, player_name, MAX_PLAYER_NAME))
{
continue;
}

else if(strfind(player_name, name_part, true))
{
isfound = true;
format(message, sizeof(message), message_template, i, player_name);
SendClientMessage(playerid, -1, message);
}
}

if(!isfound)
{
SendClientMessage(playerid, -1, !"Поиск не дал результатов!");
}

return 1;
}

Не проверял на работоспособность.

BENGO
23.12.2017, 23:05
Какой командный процессор используете? (я к тому, что Pawn.CMD позволяет облегчить поиск)

DC_CMD

Kucklovod00
23.12.2017, 23:14
new
message[sizeof(message_template) - 2 + 3 - 2 + MAX_PLAYER_NAME];
player_name[MAX_PLAYER_NAME],
bool:isfound = false;
на

new
message[sizeof(message_template) - 2 + 3 - 2 + MAX_PLAYER_NAME],
player_name[MAX_PLAYER_NAME],
bool:isfound = false;

Geebrox
23.12.2017, 23:24
на

new
message[sizeof(message_template) - 2 + 3 - 2 + MAX_PLAYER_NAME],
player_name[MAX_PLAYER_NAME],
bool:isfound = false;

да точно, не обратил внимание, писал на быструю руку

DeimoS
23.12.2017, 23:44
Ну и ещё можно от массива player_name избавиться, записывая ник в массив для сообщения в чат. Всё равно при следующей итерации его содержимое перезаписывается только если ник найден
Это так, к слову :)

BENGO
24.12.2017, 00:35
#if !defined MIN_PLAYER_NAME
#define MIN_PLAYER_NAME 4
#endif

CMD:id(playerid, params[])
{
extract params -> string:name_part[MIN_PLAYER_NAME]; else
{
return SendClientMessage(playerid, -1, !"Используйте: /id [часть имени игрока]");
}

static const message_template[] = "ID: %d | Имя: %s";
new
message[sizeof(message_template) - 2 + 3 - 2 + MAX_PLAYER_NAME];
player_name[MAX_PLAYER_NAME],
bool:isfound = false;

SendClientMessage(playerid, -1, !"Результаты поиска:");

for(new i = 0; i < GetPlayerPoolSize(); i++)
{
if(!GetPlayerName(playerid, player_name, MAX_PLAYER_NAME))
{
continue;
}

else if(strfind(player_name, name_part, true))
{
isfound = true;
format(message, sizeof(message), message_template, i, player_name);
SendClientMessage(playerid, -1, message);
}
}

if(!isfound)
{
SendClientMessage(playerid, -1, !"Поиск не дал результатов!");
}

return 1;
}

Не проверял на работоспособность.

Спасибо конечно же, но возникла проблема здесь ругается:


extract params -> string:nick_name[MIN_PLAYER_NAME]; else
return SCM(playerid,-1,!#Hint"Введите: /id [NickName игрока]");

D:\çàãðóçêè\gamemodes\modes.pwn(710) : error 017: undefined symbol "EXTRN"
D:\çàãðóçêè\gamemodes\modes.pwn(710) : error 017: undefined symbol "nick_name"
D:\çàãðóçêè\gamemodes\modes.pwn(710) : warning 215: expression has no effect
D:\çàãðóçêè\gamemodes\modes.pwn(710) : error 001: expected token: ";", but found "]"
D:\çàãðóçêè\gamemodes\modes.pwn(710) : fatal error 107: too many error messages on one line

DeimoS
24.12.2017, 00:57
Там много ошибок в коде (playerid, например, в GetPlayerName)
Как-то так:

CMD:id(playerid, params[])
{
if(!(1 <= strlen(params) <= MAX_PLAYER_NAME-4))
{
return SendClientMessage(playerid, -1, "Используйте: /id [часть имени игрока]");
}

SendClientMessage(playerid, -1, "Результаты поиска:");

new message[12+11+MAX_PLAYER_NAME];
bool:isfound = false;
for(new i; i < MAX_PLAYERS; i++)
{
if(GetPlayerName(i, message, MAX_PLAYER_NAME))
{
if(strfind(message, params, true) != -1)
{
isfound = true;
format(message, sizeof(message), "ID: %d | Имя: %s", i, message);
SendClientMessage(playerid, -1, message);
}
}
}
if(isfound == false)
{
SendClientMessage(playerid, -1, "Поиск не дал результатов!");
}
return 1;
}

Kucklovod00
24.12.2017, 14:28
Там много ошибок в коде (playerid, например, в GetPlayerName)
Как-то так:

CMD:id(playerid, params[])
{
if(!(1 <= strlen(params) <= MAX_PLAYER_NAME-4))
{
return SendClientMessage(playerid, -1, "Используйте: /id [часть имени игрока]");
}

SendClientMessage(playerid, -1, "Результаты поиска:");

new message[12+3+MAX_PLAYER_NAME];
bool:isfound = false;
for(new i; i < MAX_PLAYERS; i++)
{
if(GetPlayerName(i, message, MAX_PLAYER_NAME))
{
if(strfind(message, params, true) != -1)
{
isfound = true;
format(message, sizeof(message), "ID: %d | Имя: %s", i, message);
SendClientMessage(playerid, -1, message);
}
}
}
if(isfound == false)
{
SendClientMessage(playerid, -1, "Поиск не дал результатов!");
}
return 1;
}
Почему 3 для i? Трудно поверить, но возможно на его сервер зайдет 1000 игроков.

StevenH
24.12.2017, 14:43
Почему 3 для i? Трудно поверить, но возможно на его сервер зайдет 1000 игроков.

И? Даже если будет 1000 ID (а такое иногда бывает, хотя ID должны быть от 0 до 999), то у такого игрока должно быть имя в 24 символа (тогда возможно 1 символ не покажется), но такого никогда не будет, т.к. MAX_PLAYER_NAME равен 24, а максимальная длина в имени - 20.

Поэтому даже если игрок будет с 1000 ID и именем в 20 символов, в любом случае будет все корректно показано.

Kucklovod00
24.12.2017, 15:39
И? Даже если будет 1000 ID (а такое иногда бывает, хотя ID должны быть от 0 до 999), то у такого игрока должно быть имя в 24 символа (тогда возможно 1 символ не покажется), но такого никогда не будет, т.к. MAX_PLAYER_NAME равен 24, а максимальная длина в имени - 20.

Поэтому даже если игрок будет с 1000 ID и именем в 20 символов, в любом случае будет все корректно показано.

А точно, спасибо. Прошу прощения.

ziggi
24.12.2017, 16:41
И? Даже если будет 1000 ID (а такое иногда бывает, хотя ID должны быть от 0 до 999), то у такого игрока должно быть имя в 24 символа (тогда возможно 1 символ не покажется), но такого никогда не будет, т.к. MAX_PLAYER_NAME равен 24, а максимальная длина в имени - 20.

Поэтому даже если игрок будет с 1000 ID и именем в 20 символов, в любом случае будет все корректно показано.

Максимальная длина имени - 24 символа, можно задать с помощью SetPlayerName, а 20 символов - это ограничение клиента.
А про 1000 ID - это вряд ли.

Daniel_Cortez
24.12.2017, 17:50
Другое дело, что есть возможность увеличения макс. кол-ва слотов в будущих версиях, ибо есть проекты с 2 и более серверами на 1000 игроков - и тогда уже понадобится 4 ячейки под ID игрока. Но кому какое дело? Нужно жить настоящим.

UPD:
http://ihost.pro-pawn.ru/image.php?di=6DKU
DeimoS, это такая шутка, да?

StevenH
24.12.2017, 20:01
Максимальная длина имени - 24 символа, можно задать с помощью SetPlayerName, а 20 символов - это ограничение клиента.
А про 1000 ID - это вряд ли.

Такое бывает, но редко (я про 1000 ID). Помнится играл на открытии Diamond RP (да и не только при открытии, такое бывает когда фулл сервер), то в ТАБе показывало Online: 1001, а ID`s у игроков в ТАБе был от 0 до 1000 (соответственно 1001 игрок), но больше никогда не видел. Что касается в клиенте, там я никогда 1001 игрока не видел.

Geebrox
25.12.2017, 02:25
http://ihost.pro-pawn.ru/image.php?di=6DKU
DeimoS, это такая шутка, да?

я думаю это связано с тем, что он перевел message_template прямо в процесс форматирование (что не советую делать)

DeimoS
25.12.2017, 10:53
UPD:
http://ihost.pro-pawn.ru/image.php?di=6DKU
DeimoS, это такая шутка, да?

Ни в коем случае. Решением той темы, что вы тут подняли, является создание макроса, который бы хранил нужное значение (собственно, я так и делал в своём моде). Но предлагать автору делать такой макрос лишь для данного случая - довольно странная идея, которая приведёт ко всем известному RLS, где можно найти с десяток функций для получения ника игрока. Угадывать наперёд: сколько же там будет максимальный онлайн в следующих версиях - тоже ничего хорошего, ибо получится тот же самый вариант с магическими числами. Поэтому логично просто взять значение с расчётом на максимальное значение Integer в Pawn, дабы избавить автора от всех проблем (ну разве что 11 можно на 10 изменить, ибо онлайн не будет отрицательным, но тогда и от MAX_PLAYER_NAME следовало отнимать 4).

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



я думаю это связано с тем, что он перевел message_template прямо в процесс форматирование (что не советую делать)

А я не советовал бы ради строки в 10 символов добавлять какой-то не нужный автоподсчёт этого размера в 10 символов, который всё равно потребует составления формулы. Да ещё и строки, содержимое которой будет редактироваться лишь раз при написании кода и, в крайнем случае, ещё пару раз позже. Раздувая код, ты лишь усложняешь его поддержку в будущем, не избавив себя ровно ни от чего, а лишь убив читаемость.

Geebrox
25.12.2017, 11:02
А я не советовал бы ради строки в 10 символов добавлять какой-то не нужный автоподсчёт этого размера в 10 символов, который всё равно потребует составления формулы. Да ещё и строки, содержимое которой будет редактироваться лишь раз при написании кода и, в крайнем случае, ещё пару раз позже. Раздувая код, ты лишь усложняешь его поддержку в будущем, не избавив себя ровно ни от чего, а лишь убив читаемость.

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

DeimoS
25.12.2017, 11:36
Ты не знаешь, что он хочет выводить в сообщение, может он еще добавит строку с размером на 20 символов.

Это не отменяет того факта, что в будущем он не станет изменять эту строку постоянно.


Я наоборот не усложняю читабельность, как это выглядит у тебя.

Как раз таки в твоём случае он и усложняется, ибо:
1) Убивается синтаксис format (не так наглядно видно где находится сама форматируемая строка, а где уже остальные параметры. С этим так же будет связано то, что опишу в конце)
2) Лишняя строка. Точнее, на каждый такой подсчёт будет лишняя строка. В итоге, часть твоего кода будет занимать именно эти строки, которые для тебя никакой смысловой нагрузки не несут, а только разбавляют код.



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

Серьёзно? Удобнее? А теперь представим, что у нас есть форматирование в цикле с кучей кода, типа:

static const message_template[] = "ID: %d | Имя: %s ID: %d | Имя: %s ID: %d | Имя: %s ID: %d | Имя: %s ID: %d | Имя: %s";
new
message[формула];
player_name[MAX_PLAYER_NAME],
bool:isfound = false;

SendClientMessage(playerid, -1, !"Результаты поиска:");

for(new i = 0; i < GetPlayerPoolSize(); i++)
{
if(!GetPlayerName(playerid, player_name, MAX_PLAYER_NAME))
{
else if(!GetPlayerName(playerid, player_name, MAX_PLAYER_NAME))
{
else if(!GetPlayerName(playerid, player_name, MAX_PLAYER_NAME))
{
else if(!GetPlayerName(playerid, player_name, MAX_PLAYER_NAME))
{
else if(!GetPlayerName(playerid, player_name, MAX_PLAYER_NAME))
{
else if(!GetPlayerName(playerid, player_name, MAX_PLAYER_NAME))
{
continue;
}
continue;
}
continue;
}
continue;
}
continue;
}
continue;
}
else if(!GetPlayerName(playerid, player_name, MAX_PLAYER_NAME))
{
else if(!GetPlayerName(playerid, player_name, MAX_PLAYER_NAME))
{
else if(!GetPlayerName(playerid, player_name, MAX_PLAYER_NAME))
{
else if(!GetPlayerName(playerid, player_name, MAX_PLAYER_NAME))
{
else if(!GetPlayerName(playerid, player_name, MAX_PLAYER_NAME))
{
continue;
}
continue;
}
continue;
}
continue;
}
continue;
}
else if(strfind(player_name, name_part, true))
{
isfound = true;
format(message, sizeof(message), message_template, i, player_name, i, player_name, i, player_name, i, player_name, i, player_name);
SendClientMessage(playerid, -1, message);
}
}

(пример, конечно, утрированный, но на практике таких ситуаций, когда между объявлением массива со строкой и самим форматированием куча строк, можно найти много)

Если я решу изменить порядок переменных в массиве, мне придётся изрядно так попотеть, чтоб сначала найти глазами static const, подсчитать порядковый номер нужного заполнителя, потом найти format (который никак синтаксически выделяться не будет, ибо нет строки в нём) и лишь потом начать искать нужную переменную, рискуя промахнуться, ибо все параметры в format сливаются.
Не говоря уже о том, что с самой формулой часто гораздо больше мороки, нежели составление её вручную (можем даже провести тест, кто быстрее будет составлять формулы: ты, с твоим автоподсчётом или я, с функцией подсчёта символов выделенного текста в Sublime Text)


Никто не спорит, что вилкой есть спагетти удобнее, нежели ложкой. Но это не значит, что и суп будет удобно есть вилкой. Используй автоподсчёт там, где он действительно будет к месту (например, диалог с последними обновлениями, где в нескольких местах выводятся данные из переменных). В остальных же случаях ты и собственное время убиваешь на составление формулы (под составлением я и static const подразумеваю), и усложняешь код.

Geebrox
25.12.2017, 11:53
Это не отменяет того факта, что в будущем он не станет изменять эту строку постоянно.

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

Да ещё и строки, содержимое которой будет редактироваться лишь раз при написании кода и, в крайнем случае, ещё пару раз позже.



Серьёзно? Удобнее? А теперь представим, что у нас есть форматирование в цикле с кучей кода, типа:

(пример, конечно, утрированный, но на практике таких ситуаций, когда между объявлением массива со строкой и самим форматированием куча строк, можно найти много)

Да серьезно, удобнее. Так как мне всего лишь нужно выйти из тела цикла и перед моими глазами будет содержимое формата строки.
А в твоем случае, если будет такой код, ты будешь искать этот сранный format по всем блокам кода



Если я решу изменить порядок переменных в массиве, мне придётся изрядно так попотеть, чтоб сначала найти глазами static const, подсчитать порядковый номер нужного заполнителя, потом найти format (который никак синтаксически выделяться не будет, ибо нет строки в нём) и лишь потом начать искать нужную переменную, рискуя промахнуться, ибо все параметры в format сливаются.[/SIZE]

Я думаю это удобнее, чем искать саму функцию среди куча кодов, менять строку, менять переменные, потом найти где был объявлен массив для хранение строки, подсчитать новый размер строки и изменить его. У тебя уходит больше времени поверь. Мне лишь необъодимо найти нужную переменную.



Никто не спорит, что вилкой есть спагетти удобнее, нежели ложкой. Но это не значит, что и суп будет удобно есть вилкой.

Совершенно верно, только тебе необходимо определить кто тут пытается есть суп вилкой м?

BENGO
25.12.2017, 21:40
Там много ошибок в коде (playerid, например, в GetPlayerName)
Как-то так:

CMD:id(playerid, params[])
{
if(!(1 <= strlen(params) <= MAX_PLAYER_NAME-4))
{
return SendClientMessage(playerid, -1, "Используйте: /id [часть имени игрока]");
}

SendClientMessage(playerid, -1, "Результаты поиска:");

new message[12+11+MAX_PLAYER_NAME];
bool:isfound = false;
for(new i; i < MAX_PLAYERS; i++)
{
if(GetPlayerName(i, message, MAX_PLAYER_NAME))
{
if(strfind(message, params, true) != -1)
{
isfound = true;
format(message, sizeof(message), "ID: %d | Имя: %s", i, message);
SendClientMessage(playerid, -1, message);
}
}
}
if(isfound == false)
{
SendClientMessage(playerid, -1, "Поиск не дал результатов!");
}
return 1;
}

В этом твоем варианте не возможен поиск по id игрока, а только по части имени, я не много доделал:


CMD:id(playerid, params[])
{
if(isnull(params))
return SCM(playerid,-1,#Hint"Введите: /id [name / id игрока]");
new targetid = strval(params),
message[13+3+MAX_PLAYER_NAME],
bool:isfound = false;
if(IsNumeric(params) && IsPlayerConnected(strval(params))) {
SCM(playerid,COLOR_BLUE,"Результаты поиска:");
format(message,sizeof(message),"ID: %d | Name: %s",targetid,Name(targetid));
return SCM(playerid,-1,message);
}
else if(!IsPlayerConnected(strval(params)))
return SCM(playerid,-1,#Error"Поиск не дал результатов.");
if((3 <= strlen(params) <= MAX_PLAYER_NAME-4)) {
foreach(new i: Player)
{
if(!IsPlayerConnected(i)) continue;
if(GetPlayerName(i,message,MAX_PLAYER_NAME)) {
if(strfind(message,params,true) != -1) {
isfound = true;
SCM(playerid,COLOR_BLUE,"Результаты поиска:");
format(message,sizeof(message),"ID: %d | Name: %s",i,message);
SCM(playerid,-1,message);
}
}
}
if(isfound == false) SCM(playerid,-1,#Error"Поиск не дал результатов.");
}
else if(!(3 <= strlen(params) <= MAX_PLAYER_NAME-4))
return SCM(playerid,-1,#Error"Минимальное кол-во символом - 3.");
return true;
}

P.S Видок правда не очень, но работает=)

Daniel_Cortez
25.12.2017, 22:07
Угадывать наперёд: сколько же там будет максимальный онлайн в следующих версиях - тоже ничего хорошего, ибо получится тот же самый вариант с магическими числами.
А чего там угадывать? Если больше 1000 ещё можно себе представить (есть несколько проектов, которые держат по несколько серверов с онлайном 1000), то больше 10 000 - едва ли. Есть, конечно, несколько успешных русскоязычных проектов, но они всё ж не настолько успешные, чтобы кому-то из них понадобился сервер на 10k игроков.



но тогда и от MAX_PLAYER_NAME следовало отнимать 4
Точно такой же принцип: в будущих версиях лимит символов для ника в клиенте может увеличиться. От куя не было подтверждения подобных планов, но и опровержения (т.е. утверждения о том, что он не собирается ничего делать с этой константой по той или иной объективной причине) тоже нет.
Не столько предусмотрительность, сколько просто здравый смысл, ИМХО.

DeimoS
26.12.2017, 00:40
Вот именно! Для этого и нужно такой медот, чтобы удобно было поддерживать изменение строки. А ты говорил:

Ну так и в чём удобство? Формулу любом случае придётся переписывать. И ради этого единственного случая изменения текста в моде добавится дополнительная строка (и каждый такой случай будет всё больше и больше необязательного кода привносить, который делает код удобнее, только при словах: "А ВОТ ВДРУГ ТЫ РЕШИШЬ ИЗМЕНИТЬ ТЕКСТ", - хотя даже и тут, опять же, стоит помнить, что формулу в любом случае придётся менять, что чаще гораздо дольше, чем ручной подсчёт)


Да серьезно, удобнее. Так как мне всего лишь нужно выйти из тела цикла и перед моими глазами будет содержимое формата строки.
А в твоем случае, если будет такой код, ты будешь искать этот сранный format по всем блокам кода

Не "всего лишь выйти из тела цикла", а сначала найти нужные переменные среди format, потом выйти из тела цикла, найти обявление static const, изменить содержимое, найти объявление массива, переписать строку и только тогда всё будет готово. И не факт, что ты не перепутаешь порядок переменных с заполнителями, ибо они находятся в разных местах.

Когда в моём случае просто меняешь текст, сразу же правя переменные, сверяя их порядок, а после составляешь ту же самую формулу, только подсчёт строки перенося не на плечи компилятора, а на плечи редактора, просто выделяя весь текст.


Я думаю это удобнее, чем искать саму функцию среди куча кодов, менять строку, менять переменные, потом найти где был объявлен массив для хранение строки, подсчитать новый размер строки и изменить его. У тебя уходит больше времени поверь. Мне лишь необъодимо найти нужную переменную.

Эмм, что? Тебе нужно всё то же самое сделать, только ещё придётся дополнительно "прыгать" глазами между static const и format, сверяя порядок переменных. А так: что формулу, что переменные в format, что сам текст - всё это нужно искать и менять точно так же.



Совершенно верно, только тебе необходимо определить кто тут пытается есть суп вилкой м?

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








А чего там угадывать? Если больше 1000 ещё можно себе представить (есть несколько проектов, которые держат по несколько серверов с онлайном 1000), то больше 10 000 - едва ли. Есть, конечно, несколько успешных русскоязычных проектов, но они всё ж не настолько успешные, чтобы кому-то из них понадобился сервер на 10k игроков.

Точно такой же принцип: в будущих версиях лимит символов для ника в клиенте может увеличиться. От куя не было подтверждения подобных планов, но и опровержения (т.е. утверждения о том, что он не собирается ничего делать с этой константой по той или иной объективной причине) тоже нет.
Не столько предусмотрительность, сколько просто здравый смысл, ИМХО.

Ну это ты сегодня считаешь так, а завтра Куй делает поддержку сингловых пешеходов, которые будут жрать определённое количество слотов, и расширяет лимит до 100к слотов, из которых 99к будут занимать эти боты.
Утрирую, конечно, но такое рассуждение ничуть не лучше моего варианта с "+3". Адекватным выходом будет именно макрос, либо размер, равен лимиту Integer, дабы уж наверняка перестраховаться (как, например, с экранированием символов ника в запросе на поиск аккаунта при входе на сервер. Казалось бы, в сампе есть своё ограничение на символы и символы, при помощи которых можно сделать SQL-инъекцию, невалидны. Но кто даёт гарантии, что завтра не найдут дыру в клиенте, которая позволит обходить это ограничение? Или Куй не напортачит?). Всё остальное, хоть и маловероятно, но рискует быть невалидным однажды.

- - - Добавлено - - -


В этом твоем варианте не возможен поиск по id игрока, а только по части имени, я не много доделал:


CMD:id(playerid, params[])
{
if(isnull(params))
return SCM(playerid,-1,#Hint"Введите: /id [name / id игрока]");
new targetid = strval(params),
message[13+3+MAX_PLAYER_NAME],
bool:isfound = false;
if(IsNumeric(params) && IsPlayerConnected(strval(params))) {
SCM(playerid,COLOR_BLUE,"Результаты поиска:");
format(message,sizeof(message),"ID: %d | Name: %s",targetid,Name(targetid));
return SCM(playerid,-1,message);
}
else if(!IsPlayerConnected(strval(params)))
return SCM(playerid,-1,#Error"Поиск не дал результатов.");
if((3 <= strlen(params) <= MAX_PLAYER_NAME-4)) {
foreach(new i: Player)
{
if(!IsPlayerConnected(i)) continue;
if(GetPlayerName(i,message,MAX_PLAYER_NAME)) {
if(strfind(message,params,true) != -1) {
isfound = true;
SCM(playerid,COLOR_BLUE,"Результаты поиска:");
format(message,sizeof(message),"ID: %d | Name: %s",i,message);
SCM(playerid,-1,message);
}
}
}
if(isfound == false) SCM(playerid,-1,#Error"Поиск не дал результатов.");
}
else if(!(3 <= strlen(params) <= MAX_PLAYER_NAME-4))
return SCM(playerid,-1,#Error"Минимальное кол-во символом - 3.");
return true;
}

P.S Видок правда не очень, но работает=)

Зачем в foreach проверка на онлайн? Да ещё и когда в GetPlayerName она и так встроена (функция вернёт 0, если игрок не подключён).
Да и флудить будет сообщением "Результаты поиска" в случае поиска по части ника

Как-то так (не проверял):

CMD:id(playerid, params[])
{
if(isnull(params))
return SCM(playerid,-1,#Hint"Введите: /id [name / id игрока]");

if(IsNumeric(params))
{
new targetid = strval(params);
if(!IsPlayerConnected(targetid))
{
SCM(playerid,-1,#Error"Поиск не дал результатов.");
return 1;
}

new message[13+3+MAX_PLAYER_NAME];
SCM(playerid,COLOR_BLUE,"Результаты поиска:");
format(message,sizeof(message),"ID: %d | Name: %s", targetid, Name(targetid));
SCM(playerid,-1,message);
return 1;
}
else
{
if(!(3 <= strlen(params) <= MAX_PLAYER_NAME-4))
{
SCM(playerid,-1,#Error"Минимальное кол-во символом - 3.");
return 1;
}
new message[13+3+MAX_PLAYER_NAME],
bool:isfound = false;

SCM(playerid, COLOR_BLUE, "Результаты поиска:");
foreach(new i: Player)
{
if(GetPlayerName(i, message, MAX_PLAYER_NAME))
{
if(strfind(message, params, true) != -1)
{
isfound = true;
format(message,sizeof(message),"ID: %d | Name: %s",i,message);
SCM(playerid, -1, message);
}
}
}
if(isfound == false)
{
SCM(playerid,-1,#Error"Поиск не дал результатов.");
}
}
return true;
}

BENGO
26.12.2017, 01:24
Да и флудить будет сообщением "Результаты поиска" в случае поиска по части ника
[/PHP]
Тут не очень понял, когда проверял флуда не было.

DeimoS
26.12.2017, 01:32
Тут не очень понял, когда проверял флуда не было.

Ну у тебя на каждого найденного игрока по новой выводило бы сообщение "Результаты поиска". То бишь, нашло 3-х игроков и было бы так:

Результаты поиска:
ID: %d | Name: %s
Результаты поиска:
ID: %d | Name: %s
Результаты поиска:
ID: %d | Name: %s
Сообщение за тело цикла нужно было убрать. Ну там, как видишь, не только его можно было убрать, но и от кучи лишних вызовов функций избавиться, да и не только

BENGO
26.12.2017, 01:39
Ну у тебя на каждого найденного игрока по новой выводило бы сообщение "Результаты поиска". То бишь, нашло 3-х игроков и было бы так:

Результаты поиска:
ID: %d | Name: %s
Результаты поиска:
ID: %d | Name: %s
Результаты поиска:
ID: %d | Name: %s
Сообщение за тело цикла нужно было убрать. Ну там, как видишь, не только его можно было убрать, но и от кучи лишних вызовов функций избавиться, да и не только

Понятно спасибо, но тогда же сообщение будет появляться, даже если никого не найдет верно? То бишь будет вывод:


SCM(playerid,COLOR_BLUE,"Результаты поиска:");
if(isfound == false)
{
SCM(playerid,-1,#Error"Поиск не дал результатов.");
}

Или я не прав?

DeimoS
26.12.2017, 11:48
Понятно спасибо, но тогда же сообщение будет появляться, даже если никого не найдет верно? То бишь будет вывод:


SCM(playerid,COLOR_BLUE,"Результаты поиска:");
if(isfound == false)
{
SCM(playerid,-1,#Error"Поиск не дал результатов.");
}

Или я не прав?

Прав. Можно сделать так:

CMD:id(playerid, params[])
{
if(isnull(params))
return SCM(playerid,-1,#Hint"Введите: /id [name / id игрока]");

if(IsNumeric(params))
{
new targetid = strval(params);
if(!IsPlayerConnected(targetid))
{
SCM(playerid,-1,#Error"Поиск не дал результатов.");
return 1;
}

new message[13+3+MAX_PLAYER_NAME];
SCM(playerid,COLOR_BLUE,"Результаты поиска:");
format(message,sizeof(message),"ID: %d | Name: %s", targetid, Name(targetid));
SCM(playerid,-1,message);
return 1;
}
else
{
if(!(3 <= strlen(params) <= MAX_PLAYER_NAME-4))
{
SCM(playerid,-1,#Error"Минимальное кол-во символом - 3.");
return 1;
}
new message[13+3+MAX_PLAYER_NAME],
bool:isfound = false;

foreach(new i: Player)
{
if(GetPlayerName(i, message, MAX_PLAYER_NAME))
{
if(strfind(message, params, true) != -1)
{
if(isfound == false)
{
isfound = true;
SCM(playerid, COLOR_BLUE, "Результаты поиска:");
}
format(message,sizeof(message),"ID: %d | Name: %s",i,message);
SCM(playerid, -1, message);
}
}
}
if(isfound == false)
{
SCM(playerid,-1,#Error"Поиск не дал результатов.");
}
}
return true;
}
добавив в цикл дополнительное условие и сделав вывод только в случае нахождения игроков

Daniel_Cortez
26.12.2017, 21:00
Ну это ты сегодня считаешь так, а завтра Куй делает поддержку сингловых пешеходов, которые будут жрать определённое количество слотов, и расширяет лимит до 100к слотов, из которых 99к будут занимать эти боты.
Утрирую, конечно, но такое рассуждение ничуть не лучше моего варианта с "+3".

С такими утрированными примерами твоя "предусмотрительность" только ещё больше походит на паранойю, без обид.




Адекватным выходом будет именно макрос, либо размер, равен лимиту Integer, дабы уж наверняка перестраховаться

Не упрёка ради, а корректности для: то, что ты пытаешься описать, называется ячейкой. Даже английский вариант "cell" звучал бы куда приемлимее - мы же с тобой оба прекрасно знаем, что в Pawn нет типа "Integer".




как, например, с экранированием символов ника в запросе на поиск аккаунта при входе на сервер

Экранирование тривиально в стольких видах приложений и на стольких разных ЯП, что нет смысла перечислять. Сравнение его со специфичными для SA-MP проблемами выглядит, мягко говоря, странно.




Казалось бы, в сампе есть своё ограничение на символы и символы, при помощи которых можно сделать SQL-инъекцию, невалидны. Но кто даёт гарантии, что завтра не найдут дыру в клиенте, которая позволит обходить это ограничение? Или Куй не напортачит?)

В случае с MySQL поднимется шум (ибо эта СУБД много где используется) и быстро выйдут хотфиксы для всех поддерживаемых версий.
Если же речь о SQLite, то с такой критической уязвимостью выход обновы SA-MP с закрытием дыры и парой новых моделек тоже должен произойти сравнительно быстро.




Всё остальное, хоть и маловероятно, но рискует быть невалидным однажды.

Богатый простор для паранойи, да.

DeimoS
28.12.2017, 17:18
В случае с MySQL поднимется шум (ибо эта СУБД много где используется) и быстро выйдут хотфиксы для всех поддерживаемых версий.
Если же речь о SQLite, то с такой критической уязвимостью выход обновы SA-MP с закрытием дыры и парой новых моделек тоже должен произойти сравнительно быстро.

Речь о самом SA-MP (в сервер встроена проверка на символы в ники, которую если убрать, можно много дел наделать как с БД, так и с самим сервером при "умелых" настройках хоста)


Богатый простор для паранойи, да.

Никто не спорит, что это сродни паранойи. Как и твои утверждения насчёт того, что 3-х символов не хватит однажды. Только свою паранойю ты почему-то оправдываешь, а мою считаешь чем-то нелогичным, ибо, в твоём понимании, такого не произойдёт никогда, а значит и вариант с магическими числами (ну чтоб поставить не 3, а 4) вполне уместен.
Как я уже выше писал, самым правильным вариантом будет создание соответствующей константы/макроса, которая уже будет хранить актуальное значение. А так же я объяснял почему в данной теме советовать эту самую константу не совсем уместно, из-за чего и будет логичнее всего просто пожертвовать чуть больше памяти, но наверняка оградить себя от проблем в будущем.