PDA

Просмотр полной версии : [Вопрос] Ввод ника вместо ID в командах [sscanf].



Wise
10.11.2014, 19:53
Здравствуйте уважаемые пользователи pro-pawn. Я использую sscanf вместе со стандартным командным процессором (ZCMD не катит). Мне в некоторых командах надо делать так, чтобы администратор мог не только ввести ID игрока, но и написать его ник. Суть проблемы заключается вот в чём: допустим на сервере сидит один игрок с ником Alex_Brut. Если администратор вводит кмд /gethere [id_игрока], то всё работает замечательно. Если администратор вводит /gethere [nickname] то тоже всё замечательно, игрока перемещает к администратору (в данном случае просто выполняется команда). Но если ввести /gethere [Alex] или /gethere [Alex_Brutsss] или же /gethere [Al] то администратора все равно перемещает к игроку Alex_Brut. То есть получается, что проверка не срабатывает на подключение игрока (IsPlayerConnected), а если ввести например не /gethere Alex, а /gethere Mike (или другие никнеймы), то проверка срабатывает. Я советовался с Владиславом (Deimos) и он мне сказал почитать документацию к sscanf, но я так и не нашёл подобной проблемы. Вот собственно сама команда:

else if(!strcmp(cmd, "/gethere"))
{
if(PlayerInfo[playerid][pAdmin] < 2) return SendClientMessage(playerid, COLOR_ERROR, "Недостаточно прав для использования команды.");
if(sscanf(params, "u", params[0])) return SendClientMessage(playerid, COLOR_ERROR, "Команда /gethere [playerid/PartOfName]");
if(!IsPlayerConnected(params[0])) return SendClientMessage(playerid, COLOR_ERROR, "Этот игрок в данный момент не в сети.");
new Float:X, Float:Y, Float:Z;
GetPlayerPos(playerid, X, Y, Z);
SetPlayerInterior(params[0], GetPlayerInterior(playerid));
SetPlayerVirtualWorld(params[0], GetPlayerVirtualWorld(playerid));
if(GetPlayerState(params[0]) == 2) SetVehiclePos(GetPlayerVehicleID(params[0]), X, Y+4, Z);
else SetPlayerPos(params[0], X, Y+2, Z);
return 1;
}
Помогите пожалуйста разобраться с данной проблемой.

#ball
11.11.2014, 04:23
Попробуйте почитать вот это (https://github.com/Y-Less/sscanf/wiki/Users),возможно поможет.

Wise
11.11.2014, 07:54
Я это и читал.

FanHamMer
11.11.2014, 12:31
Я вообще не понял сути. Но типы так лоя информации, напишу.

Типы переменных для получения
i, d - Целочисленные 1 3 6
c - Буквы д ж а *
l - Логические занки true false
b - Бинарные 01001, 0b1100
h, x - Hex 1A, 0x23
o - Octal 045 12
n - Number 42, 0b010, 0xAC, 045
f - Дробные 0.7, -99.5
g - IEEE Float 0.7, -99.5, INFINITY, -INFINITY, NAN, NAN_E
u - Имя игрока или его ид Y_Less, 0
q - Bot name/id ShopBot, 27
r - Player name/id Y_Less, 42

Wise
11.11.2014, 16:04
Я вообще не понял сути. Но типы так лоя информации, напишу.

Типы переменных для получения
i, d - Целочисленные 1 3 6
c - Буквы д ж а *
l - Логические занки true false
b - Бинарные 01001, 0b1100
h, x - Hex 1A, 0x23
o - Octal 045 12
n - Number 42, 0b010, 0xAC, 045
f - Дробные 0.7, -99.5
g - IEEE Float 0.7, -99.5, INFINITY, -INFINITY, NAN, NAN_E
u - Имя игрока или его ид Y_Less, 0
q - Bot name/id ShopBot, 27
r - Player name/id Y_Less, 42

Я вроде всё внятно объяснил. Но попробую объяснить кратко: Представим, что у меня ник такой - Nick_Name. Если введу /gethere Nick_Name то всё работает нормально. Если я введу только имя (Nick) то тоже переместит игрока Nick_Name. Получается проверка здесь на подключение игрока не работает. А если например, вместо имени Nick, написать другое имя начинающееся с другой буквы, то здесь проверка начинает работать.

Wise
11.11.2014, 18:29
Попробовал вместо U использовать R все равно такой же баг.

DeimoS
11.11.2014, 19:09
Можно сделать следующее


SSCANF:return_user(text[])
{
new p_nick[MAX_PLAYER_NAME];
for(new t = strlen(text)-1; t != -1; t--)
{
switch(text[t])
{
case '0'..'9': continue;
default:
{
for(new i; i < MAX_PLAYERS; i++)//foreach(new i: Player)
{
if(!IsPlayerConnected(i)) continue;
GetPlayerName(i, p_nick, MAX_PLAYER_NAME);
if(!strcmp(p_nick, text, true)) return i;
}
return INVALID_PLAYER_ID;
}
}
}
return strval(text);
}

И теперь использовать так:

else if(!strcmp(cmd, "/gethere"))
{
if(PlayerInfo[playerid][pAdmin] < 2) return SendClientMessage(playerid, COLOR_ERROR, "Недостаточно прав для использования команды.");
if(sscanf(params, "k<return_user>", params[0])) return SendClientMessage(playerid, COLOR_ERROR, "Команда /gethere [playerid/PartOfName]");
if(!IsPlayerConnected(params[0])) return SendClientMessage(playerid, COLOR_ERROR, "Этот игрок в данный момент не в сети.");
new Float:X, Float:Y, Float:Z;
GetPlayerPos(playerid, X, Y, Z);
SetPlayerInterior(params[0], GetPlayerInterior(playerid));
SetPlayerVirtualWorld(params[0], GetPlayerVirtualWorld(playerid));
if(GetPlayerState(params[0]) == 2) SetVehiclePos(GetPlayerVehicleID(params[0]), X, Y+4, Z);
else SetPlayerPos(params[0], X, Y+2, Z);
return 1;
}

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


Попробовал вместо U использовать R все равно такой же баг.

"u" ищет среди всех игроков и ботов.
"r" ищет только среди игроков, пропуская ботов
"q" ищет только среди ботов.
В общем, это активирует разные проверки в цикле, который проверяет игроков

Wise
11.11.2014, 21:01
Спасибо огромное Владислав!!! Вы лучший! :good2: