PDA

Просмотр полной версии : [Вопрос] Не обязательный параметр sscanf.



DelAccount
23.09.2016, 01:15
Всем привет, имеется такой вопрос. Как реализовать несколько не обязательных параметров (числовой, стринговый) в команде, используя sscanf? Всё перерыл, но никак не выходит. (ps 2 подобных темы на форуме уже читал, но это не то, что нужно).

К примеру, команда /mute. Обязательный параметр - ид игрока. Не обязательные - время мута, причина мута.
Делал по всякому, остановился на этом

if(sscanf(params, "uD(5) S(Не указано)[32]", params[0], params[1], params[2]))
return SendClientMessage(playerid, COLOR_WHITE,"Введите: /mute [playerid] {минуты} {причина}");
Такой код просто вырубает сервер. Если же сделать параметр D - обязательным, то есть udS(Не указано)[32], то не крашит, всё работает верно, но параметр d обязателен - а это не то, что нужно. У кого какие мысли?

Saibot
23.09.2016, 02:51
new targetid,
mute_time,
reason[32];

sscanf(params, "I(-1)is[32]", targetid, mute_time, reason)

if(targetid == -1)
return SendClientMessage(playerid, -1, !"Введите: /mute [playerid] {минуты} {причина}");

if(!mute_time)
{
//Если игрок не ввел кол-во минут
}
else
{
//Если игрок ввел кол-во минут
}

if(isnull(reason))
{
//Если игрок не ввел причину
}
else
{
//Если игрок ввел причину
}

DelAccount
23.09.2016, 04:26
благодарен. мой вариант не получится додумать?

http://forum.sa-mp.com/showthread.php?t=570927 тут есть что-то о подобном.


S(string)[length] Optional string
s[length] String

ziggi
23.09.2016, 09:20
Первый вариант: uD(5)S(Не указано)[32] должен работать, разве что ты пробел лишний туда вставил.

DelAccount
23.09.2016, 11:25
Я тоже так думал, но /mute id просто крашит сервер, а с указанием параметра минут /mute id 20 все в норме. Пробел вставил уже после "танцев с бубном", до этого пробовал без.

Daniel_Cortez
23.09.2016, 11:59
Я тоже так думал, но /mute id просто крашит сервер, а с указанием параметра минут /mute id 20 все в норме. Пробел вставил уже после "танцев с бубном", до этого пробовал без.
С чего вы решили, что краш происходит именно из-за sscanf2? Может быть, вы делали всё правильно, а причина краша была в чём-то другом?
Подключайте crashdetect и логи сюда, будем разбираться.

DelAccount
23.09.2016, 13:49
С чего вы решили, что краш происходит именно из-за sscanf2? Может быть, вы делали всё правильно, а причина краша была в чём-то другом?
Подключайте crashdetect и логи сюда, будем разбираться.

Именно по логам так и решил.


[12:43:57] [debug] Server crashed while executing Test.amx
[12:43:57] [debug] AMX backtrace:
[12:43:57] [debug] #0 native sscanf () from sscanf.DLL
[12:43:57] [debug] #1 00146af0 in public pc_cmd_mute (0, 5398472) from Test.amx
[12:43:57] [debug] Native backtrace:
[12:43:57] [debug] #0 00403334 in ?? () from samp-server.exe
[12:43:57] [debug] #1 004010b6 in ?? () from samp-server.exe
[12:43:57] [debug] #2 5eb7c6fa in ?? () from plugins\crashdetect.DLL
[12:43:57] [debug] #3 5eb82278 in ?? () from plugins\crashdetect.DLL
[12:43:57] [debug] #4 5eb7a0d7 in ?? () from plugins\crashdetect.DLL
[12:43:57] [debug] #5 5eb7c74a in ?? () from plugins\crashdetect.DLL
[12:43:57] [debug] #6 6d5a4509 in ?? () from plugins\streamer.DLL
[12:43:57] [debug] #7 538a4276 in ?? () from plugins\PawnCMD.DLL
[12:43:57] [debug] #8 538a3fce in ?? () from plugins\PawnCMD.DLL
[12:43:57] [debug] #9 00492a21 in ?? () from samp-server.exe
[12:43:57] [debug] #10 00452270 in ?? () from samp-server.exe
[12:43:57] [debug] #11 0049eef9 in ?? () from samp-server.exe
[12:43:57] [debug] #12 004aa31e in ?? () from samp-server.exe


CMD:mute(playerid, params[])
{

if(sscanf(params, "uD(5)S(Не указано)[32]", params[0], params[1], params[2]))
return SendClientMessage(playerid, -1, "Введите: /mute [playerid] {минуты} {причина}");

if(IsPlayerConnected(params[0]) == 0)
return SendClientMessage(playerid, COLOR_GREY, "Игрок не в сети / не авторизован");

if(PlayerInfo[params[0]][Mute] > 0)
{
PlayerInfo[params[0]][Mute] = 0;
SendMesAll(-1, COLOR_LIGHTRED, "Администратор %s снял бан чата у игрока %s", PlayerInfo[playerid][Name], PlayerInfo[params[0]][Name]);
return 1;
}

PlayerInfo[params[0]][Mute] = params[1] * 60;
SendMesAll(-1, COLOR_LIGHTRED, "Администратор %s выдал бан чата %s. Причина: %s", PlayerInfo[playerid][Name], PlayerInfo[params[0]][Name], params[2]);
SendMes(params[0], COLOR_LIGHTRED, "Вам дали бан чата на %d минут", params[1]);

return 1;
}

$continue$
23.09.2016, 13:56
Ключ -d3 выставить в pawn.cfg

DelAccount
23.09.2016, 14:26
Ключ -d3 выставить в pawn.cfg


[13:24:50] [debug] Server crashed while executing Test.amx
[13:24:50] [debug] AMX backtrace:
[13:24:50] [debug] #0 native sscanf () from sscanf.DLL
[13:24:50] [debug] #1 0019cd88 in public pc_cmd_mute (playerid=0, params[]=@00525e88 "") at C:\Users\Admin\Desktop\TestMode\gamemodes\Test.pwn:16099
[13:24:50] [debug] Native backtrace:
[13:24:50] [debug] #0 00403334 in ?? () from samp-server.exe
[13:24:50] [debug] #1 004010b6 in ?? () from samp-server.exe
[13:24:50] [debug] #2 5cb7c6fa in ?? () from plugins\crashdetect.DLL
[13:24:50] [debug] #3 5cb82278 in ?? () from plugins\crashdetect.DLL
[13:24:50] [debug] #4 5cb7a0d7 in ?? () from plugins\crashdetect.DLL
[13:24:50] [debug] #5 5cb7c74a in ?? () from plugins\crashdetect.DLL
[13:24:50] [debug] #6 691d4509 in ?? () from plugins\streamer.DLL
[13:24:50] [debug] #7 5c2a4276 in ?? () from plugins\PawnCMD.DLL
[13:24:50] [debug] #8 5c2a3fce in ?? () from plugins\PawnCMD.DLL
[13:24:50] [debug] #9 00492a21 in ?? () from samp-server.exe
[13:24:50] [debug] #10 00452270 in ?? () from samp-server.exe
[13:24:50] [debug] #11 0049eef9 in ?? () from samp-server.exe
[13:24:50] [debug] #12 004aa31e in ?? () from samp-server.exe

16099

if(sscanf(params, "uD(5)S(Не указано)[32]", params[0], params[1], params[2]))
return SendClientMessage(playerid, -1, !"Введите: /mute [playerid] {минуты} {причина}");

DeimoS
23.09.2016, 14:49
Эмм, так если ты вводишь только ID, у тебя под params выделяется 1-2 ячейки (ровно для хранения ID. Если ввёл "0" - выделится одна), а ты пытаешься обратиться к первой и второй.

Это прямо эталонный пример для этой (http://pro-pawn.ru/showthread.php?12988) темы, которую автору стоит почитать.
Твой случай описывается в следующих строках из той темы:

Кроме того, размер params может меняться в зависимости от параметров команды, гарантировано только существование params[0]. Если попытаться сохранить что-то в другой ячейке, можно словить ошибку из-за доступа к невалидному участку памяти.

Дело не в sscanf. Вот так будет норм

CMD:mute(playerid, params[])
{
new giveplayerid,
mute_time;
if(sscanf(params, "uD(5)S(Не указано)[32]", giveplayerid, mute_time, params))
return SendClientMessage(playerid, -1, "Введите: /mute [playerid] {минуты} {причина}");

if(giveplayerid == INVALID_PLAYER_ID)
return SendClientMessage(playerid, COLOR_GREY, "Игрок не в сети / не авторизован");

if(PlayerInfo[giveplayerid][Mute] > 0)
{
PlayerInfo[giveplayerid][Mute] = 0;
SendMesAll(-1, COLOR_LIGHTRED, "Администратор %s снял бан чата у игрока %s", PlayerInfo[playerid][Name], PlayerInfo[giveplayerid][Name]);
return 1;
}

PlayerInfo[giveplayerid][Mute] = mute_time * 60;
SendMesAll(-1, COLOR_LIGHTRED, "Администратор %s выдал бан чата %s. Причина: %s", PlayerInfo[playerid][Name], PlayerInfo[giveplayerid][Name], params);
SendMes(giveplayerid, COLOR_LIGHTRED, "Вам дали бан чата на %d минут", mute_time);

return 1;
}