SA-MP Forums Archive
Find player by part of his nickname - Printable Version

+- SA-MP Forums Archive (https://sampforum.blast.hk)
+-- Forum: SA-MP Scripting and Plugins (https://sampforum.blast.hk/forumdisplay.php?fid=8)
+--- Forum: Scripting Help (https://sampforum.blast.hk/forumdisplay.php?fid=12)
+--- Thread: Find player by part of his nickname (/showthread.php?tid=607825)



Find player by part of his nickname - AtomD - 24.05.2016

Hello.

The objective is to write a command for this stuff in the title using sscanf.
Command: /id [name/part]
I found some tutorial in sscanf topic and I really didn't understood how this method works (and whether works).

Could anybody explain me how to make it and how it works?

Thanks.


Re: Find player by part of his nickname - ilijap - 24.05.2016

Why explain? Its specifier . It work like this: If you enter /id John and If there is only one with strating name John it will select him if there are more with starting name John then it will select nothing :P. http://prntscr.com/b7tx8h


Re: Find player by part of his nickname - SsHady - 24.05.2016

Код:
command(id, playerid, params[])
{
    new name[24];
    if(sscanf(params, "s[24]", name)) return SendClientMessage(playerid, GREY, "Usage: /id [player name or part of name]");
    format(string, sizeof(string), "%s\n%s - ID %d", string, RemoveUnderScore(GetPlayerID(name, 1)), GetPlayerID(name, 1));
	SendClientMessage(playerid, WHITE, string);
    return 1;
}
Код:
	stock GetPlayerID(const playername[], partofname=0) //By Jan "DracoBlue" Schќtze (edited by Gabriel "Larcius" Cordes) || Or ******, I don't remember.
{
	new i;
	new playername1[MAX_STRING];
	for (i=0;i<MAX_PLAYERS;i++)
	{
		if (IsPlayerConnected(i))
		{
			GetPlayerName(i,playername1,sizeof(playername1));
			if (strcmp(playername1,playername,true)==0)
			{
				return i;
			}
		}
	}
	new correctsigns_userid=-1;
	new tmpuname[MAX_STRING];
	new hasmultiple=-1;
	if(partofname)
	{
		for (i=0;i<MAX_PLAYERS;i++)
		{
			if (IsPlayerConnected(i))
			{
				GetPlayerName(i,tmpuname,sizeof(tmpuname));
				if (strfind(tmpuname,partofname,true)==0)
				{
					hasmultiple++;
					correctsigns_userid=i;
				}
				if (hasmultiple>0)
				{
					return -2;
				}
			}
		}
	}
	return correctsigns_userid;
}



Re: Find player by part of his nickname - Konstantinos - 24.05.2016

Read this:
Quote:
Originally Posted by ******
Users can now optionally return an ARRAY of users instead of just one. This array is just a list of matched IDs, followed by "INVALID_PLAYER_ID". Given the following players:

Код:
0) ******
1) [CLAN]******
2) Jake
3) Alex
4) Hass
This code:

pawn Код:
new ids[3], i;
if (sscanf("Le", "?<MATCH_NAME_PARTIAL=1>u[3]", ids)) printf("Error in input");
for (i = 0; ids[i] != INVALID_PLAYER_ID; ++i)
{
    if (ids[i] == cellmin)
    {
        printf("Too many matches");
        break;
    }
    printf("id = %d", ids[i]);
}
if (i == 0) printf("No matching players found.");
Will output:

Код:
id = 0
id = 1
Too many matches
Searching "Les" instead will give:

Код:
id = 0
id = 1
And searching without "MATCH_NAME_PARTIAL" will give:

Код:
No matching players found.
Basically, if an array of size "N" is passed, this code will return the first N-1 results. If there are less than "N" players whose name matches the given name then that many players will be returned and the next slot will be "INVALID_PLAYER_ID" to indicate the end of the list. On the other hand if there are MORE than "N - 1" players whose name matches the given pattern, then the last slot will be "cellmin" to indicate this fact.

When combined with "U" and returning the default, the first slot is always exactly the default value (even if that's not a valid connected player) and the next slot is always "INVALID_PLAYER_ID".

Note also that user arrays can't be combined with normal arrays or enums, but normal single-return user specifiers still can be.



Re: Find player by part of his nickname - AtomD - 24.05.2016

Quote:
Originally Posted by ilijap
Посмотреть сообщение
Why explain? Its specifier . It work like this: If you enter /id John and If there is only one with strating name John it will select him if there are more with starting name John then it will select nothing :P. http://prntscr.com/b7tx8h
I didn't understood how to find a player with 'u' specifier.

Код:
new ids[3], i;
if (sscanf("Le", "?<MATCH_NAME_PARTIAL=1>u[3]", ids)) printf("Error in input");
for (i = 0; ids[i] != INVALID_PLAYER_ID; ++i)
{
    if (ids[i] == cellmin)
    {
        printf("Too many matches");
        break;
    }
    printf("id = %d", ids[i]);
}
if (i == 0) printf("No matching players found.");
The loop looks very strange for me.


Re: Find player by part of his nickname - AtomD - 24.05.2016

Quote:
Originally Posted by Konstantinos
Посмотреть сообщение
Read this:
So, the final command is:
Код:
CMD:id(playerid, params[])
{
	extract params -> new string:szName[MAX_PLAYER_NAME + 1]; else
	{
		SendClientMessage(playerid, C_DUMMY, "Используйте: /id [ник или часть ника]");
		return true;
	}

	new szMessage[64];
	new arrPlayers[8];
	new bTooMany;
	new index;


	if(sscanf(szName, "?<MATCH_NAME_PARTIAL=1>u[8]", arrPlayers))
	{
		SendClientMessage(playerid, C_ERROR, "Произошла неизвестная ошибка при поиске"); //Unknown error
		return true;
	}

	for(index = 0; arrPlayers[index] != INVALID_PLAYER_ID; ++index)
	{
		if(arrPlayers[index] == cellmin)
		{
			bTooMany = 1;
			break;
		}

		 format(szMessage, 64, "%i. %s - %i", index + 1, Players[index][m_szName], arrPlayers[index]);
		SendClientMessage(playerid, -1, szMessage);
	}

	if(index == 0)
	{
		SendClientMessage(playerid, C_DUMMY, "Совпадений не найдено");
		return true;
	}

	if(bTooMany == 1)
	{
		SendClientMessage(playerid, C_DUMMY, "Показано 7 первых найденых игроков");
		return true;
	}

	return true;
}
This should work?


Re: Find player by part of his nickname - ilijap - 24.05.2016

Quote:
Originally Posted by AtomD
Посмотреть сообщение
I didn't understood how to find a player with 'u' specifier.

Код:
new ids[3], i;
if (sscanf("Le", "?<MATCH_NAME_PARTIAL=1>u[3]", ids)) printf("Error in input");
for (i = 0; ids[i] != INVALID_PLAYER_ID; ++i)
{
    if (ids[i] == cellmin)
    {
        printf("Too many matches");
        break;
    }
    printf("id = %d", ids[i]);
}
if (i == 0) printf("No matching players found.");
The loop looks very strange for me.
Dont use like that

I prefer this:


PHP код:
new idsi;
if (
sscanf("Le""r"ids)) print("Error in input"); //what is Le?
//check if player is connected
if(!IsPlayerConnected(ids)) return print("Player is not connected'); 
printf("
id = %d", ids); 
If you want for all players with that starting name use strcmp


Re: Find player by part of his nickname - AtomD - 24.05.2016

Quote:
Originally Posted by AtomD
Посмотреть сообщение
So, the final command is:
Код:
CMD:id(playerid, params[])
{
	extract params -> new string:szName[MAX_PLAYER_NAME + 1]; else
	{
		SendClientMessage(playerid, C_DUMMY, "Используйте: /id [ник или часть ника]");
		return true;
	}

	new szMessage[64];
	new arrPlayers[8];
	new bTooMany;
	new index;


	if(sscanf(szName, "?<MATCH_NAME_PARTIAL=1>u[8]", arrPlayers))
	{
		SendClientMessage(playerid, C_ERROR, "Произошла неизвестная ошибка при поиске"); //Unknown error
		return true;
	}

	for(index = 0; arrPlayers[index] != INVALID_PLAYER_ID; ++index)
	{
		if(arrPlayers[index] == cellmin)
		{
			bTooMany = 1;
			break;
		}

		 format(szMessage, 64, "%i. %s - %i", index + 1, Players[index][m_szName], arrPlayers[index]);
		SendClientMessage(playerid, -1, szMessage);
	}

	if(index == 0)
	{
		SendClientMessage(playerid, C_DUMMY, "Совпадений не найдено");
		return true;
	}

	if(bTooMany == 1)
	{
		SendClientMessage(playerid, C_DUMMY, "Показано 7 первых найденых игроков");
		return true;
	}

	return true;
}
This should work?
Tested this. Perhaps works fine. Thanks all.


Re: Find player by part of his nickname - Konstantinos - 24.05.2016

In format, you have:
pawn Код:
Players[index][m_szName]
It should be:
pawn Код:
Players[arrPlayers[index]][m_szName]