staff command is wrongfully coded, shows only 1 admin instead of more...
#1

hello once again,

recently i've decided to make my own staff command to see how it would go, and it didn't, obviously. even if it doesn't show any errors and successfully compiles, as the title says, it shows 1 player instead of 2+ and when i set myself to 0 level, it still shows me on the dialog...

here's the wrongfully coded command:

Code:
CMD:staff(playerid, params[])
{
	#pragma unused params
	if(PlayerInfo[playerid][LoggedIn] == true)
	{
	    new string[192];
	    new admrank[32];
	    new count;
	    new pname[MAX_PLAYER_NAME];
        for(new i; i<MAX_PLAYERS; i++)
        {
            if(IsPlayerConnected(i))
			{
				if(IsPlayerAdmin(i))
				{
       				 admrank = "{FF0000}RCON Admin";
				}
				else
				{
    				switch(PlayerInfo[i][AdminLevel])
					{
				        case 1: admrank = "{FFFF00}Moderator";
				        case 2: admrank = "{008000}Administrator";
				        case 3: admrank = "{3366FF}Manager";
				    }
				    GetPlayerName(i, pname, sizeof(pname));
				    format(string, sizeof(string), "{FFFFFF}%s (ID: %d) | Level: %d | Rank: %s", pname, i, PlayerInfo[i][AdminLevel], admrank);
				    ++count;
				}
			}
		}
		if(!count)
		format(string, sizeof(string), "{FF0000}There are currently no staff online.");
		ShowPlayerDialog(playerid, DIALOGID0+2, DIALOG_STYLE_MSGBOX, "{FFFFFF}Server staff currently online:", string, "Okay", "");
		return 1;
	} else return SendClientMessage(playerid, COLOR_RED, "ERROR: Account must be registered in order to use commands.");
}
cheers
Reply
#2

PHP Code:
CMD:staff(playeridparams[])
{
    
#pragma unused params
    
if(PlayerInfo[playerid][LoggedIn] == true)
    {
        new 
string[192];
        new 
string2[192]
        new 
admrank[32];
        new 
count;
        new 
pname[MAX_PLAYER_NAME];
        for(new 
ii<MAX_PLAYERSi++)
        {
            if(
IsPlayerConnected(i))
            {
                
GetPlayerName(ipnamesizeof(pname));
                if(
IsPlayerAdmin(i))
                {
                       
admrank "{FF0000}RCON Admin";
                       
format(string2sizeof(string2), "{FFFFFF}%s (ID: %d) | Level: %d | Rank: %s"pnameiPlayerInfo[i][AdminLevel], admrank);
                    
strcat(stringstring2);
                    ++
count;
                }
                else if(
PlayerInfo[i][AdminLevel] > 0)
                {
                    switch(
PlayerInfo[i][AdminLevel])
                    {
                        case 
1admrank "{FFFF00}Moderator";
                        case 
2admrank "{008000}Administrator";
                        case 
3admrank "{3366FF}Manager";
                    }
                    
format(string2sizeof(string2), "{FFFFFF}%s (ID: %d) | Level: %d | Rank: %s"pnameiPlayerInfo[i][AdminLevel], admrank);
                    
strcat(stringstring2);
                    ++
count;
                }
            }
        }
        if(!
count)
        
format(stringsizeof(string), "{FF0000}There are currently no staff online.");
        
ShowPlayerDialog(playeridDIALOGID0+2DIALOG_STYLE_MSGBOX"{FFFFFF}Server staff currently online:"string"Okay""");
        return 
1;
    } else return 
SendClientMessage(playeridCOLOR_RED"ERROR: Account must be registered in order to use commands.");

I have not tested
Reply
#3

pray to the almighty god
Reply
#4

This is your code:
pawn Code:
if (IsPlayerAdmin(i))
{
    admrank = "{FF0000}RCON Admin";
}
else
{
    switch (PlayerInfo[i][AdminLevel])
    {
        case 1:
            admrank = "{FFFF00}Moderator";
        case 2:
            admrank = "{008000}Administrator";
        case 3:
            admrank = "{3366FF}Manager";
    }
    GetPlayerName(i, pname, sizeof(pname));
    format(string, sizeof(string), "{FFFFFF}%s (ID: %d) | Level: %d | Rank: %s", pname, i, PlayerInfo[i][AdminLevel], admrank);
    ++count;
}
- If the player is RCON admin, nothing happens (not getting the name and adding them into the list).
- If the player is not RCON admin, it gets the name even if the level is 0 and it uses as rank the previous value (if any).
- `string` is overwritten every time. Using:
pawn Code:
format(string, sizeof (string), "%s ...", string, ...);
keeps the previous text. Alternative way is format+strcat.
- Not new lines.

The correct steps are shown below:
pawn Code:
if (IsPlayerAdmin(i))
{
    GetPlayerName(i, pname, sizeof(pname));
    format(string, sizeof(string), "%s{FFFFFF}%s (ID: %d) {FF0000}RCON Admin\n", string, pname, i);
    ++count;

    // If RCON:
        // - get name
        // - re-format text
        // - increase counter
}
else
{
    switch (PlayerInfo[i][AdminLevel])
    {
        // If the player is not admin, skip the current player and go to the next so..
        // the code below will not have any effect (will not be executed at all) to non admins
        case 0: continue; // <--'
        case 1: admrank = "{FFFF00}Moderator";
        case 2: admrank = "{008000}Administrator";
        case 3: admrank = "{3366FF}Manager";
    }
    GetPlayerName(i, pname, sizeof(pname));
    format(string, sizeof(string), "%s{FFFFFF}%s (ID: %d) | Level: %d | Rank: %s\n", string, pname, i, PlayerInfo[i][AdminLevel], admrank);
    ++count;

    // If admin:
        // - get name
        // - re-format text
        // - increase counter
    // If NOT admin:
        // - skip it - continue to the next player
}
Reply
#5

PHP Code:
CMD:staff(playeridparams[])
{
    
#pragma unused params
    
if(PlayerInfo[playerid][LoggedIn] == true)
    {
        new 
string[192];
        new 
admrank[32];
        new 
count;
        new 
pname[MAX_PLAYER_NAME];
        for(new 
ii<MAX_PLAYERSi++)
        {
            if(
IsPlayerConnected(i))
            {
                if(
IsPlayerAdmin(i))
                {
                        
admrank "{FF0000}RCON Admin";
                }
                else
                {
                    switch(
PlayerInfo[i][AdminLevel])
                    {
                        case 
1admrank "{FFFF00}Moderator";
                        case 
2admrank "{008000}Administrator";
                        case 
3admrank "{3366FF}Manager";
                        default: continue;
                    }
                    ++
count;
                }
                    
GetPlayerName(ipnamesizeof(pname));
                    
format(stringsizeof(string), "{FFFFFF}%s (ID: %d) | Level: %d | Rank: %s"pnameiPlayerInfo[i][AdminLevel], admrank);
SendClientMessage(playerid, -1string);            }
        }
        if(!
count)
        
format(stringsizeof(string), "{FF0000}There are currently no staff online.");
        
ShowPlayerDialog(playeridDIALOGID0+2DIALOG_STYLE_MSGBOX"{FFFFFF}Server staff currently online:"string"Okay""");
        return 
1;
    } else return 
SendClientMessage(playeridCOLOR_RED"ERROR: Account must be registered in order to use commands.");

Reply
#6

sorry, still shows the same, tried those 3 codes you sent me guys, but still, it shows 1 admin instead of 2, and even though the ranks are set to 3,2 and 1, still doesn't show anything...
Reply
#7

Quote:
Originally Posted by Calisthenics
View Post
This is your code:
pawn Code:
if (IsPlayerAdmin(i))
{
    admrank = "{FF0000}RCON Admin";
}
else
{
    switch (PlayerInfo[i][AdminLevel])
    {
        case 1:
            admrank = "{FFFF00}Moderator";
        case 2:
            admrank = "{008000}Administrator";
        case 3:
            admrank = "{3366FF}Manager";
    }
    GetPlayerName(i, pname, sizeof(pname));
    format(string, sizeof(string), "{FFFFFF}%s (ID: %d) | Level: %d | Rank: %s", pname, i, PlayerInfo[i][AdminLevel], admrank);
    ++count;
}
- If the player is RCON admin, nothing happens (not getting the name and adding them into the list).
- If the player is not RCON admin, it gets the name even if the level is 0 and it uses as rank the previous value (if any).
- `string` is overwritten every time. Using:
pawn Code:
format(string, sizeof (string), "%s ...", string, ...);
keeps the previous text. Alternative way is format+strcat.
- Not new lines.

The correct steps are shown below:
pawn Code:
if (IsPlayerAdmin(i))
{
    GetPlayerName(i, pname, sizeof(pname));
    format(string, sizeof(string), "%s{FFFFFF}%s (ID: %d) {FF0000}RCON Admin\n", string, pname, i);
    ++count;

    // If RCON:
        // - get name
        // - re-format text
        // - increase counter
}
else
{
    switch (PlayerInfo[i][AdminLevel])
    {
        // If the player is not admin, skip the current player and go to the next so..
        // the code below will not have any effect (will not be executed at all) to non admins
        case 0: continue; // <--'
        case 1: admrank = "{FFFF00}Moderator";
        case 2: admrank = "{008000}Administrator";
        case 3: admrank = "{3366FF}Manager";
    }
    GetPlayerName(i, pname, sizeof(pname));
    format(string, sizeof(string), "%s{FFFFFF}%s (ID: %d) | Level: %d | Rank: %s\n", string, pname, i, PlayerInfo[i][AdminLevel], admrank);
    ++count;

    // If admin:
        // - get name
        // - re-format text
        // - increase counter
    // If NOT admin:
        // - skip it - continue to the next player
}
i tried your corrected code once again, but this time, it won't even show the dialog

here's how i recoded it:

pawn Code:
CMD:staff(playerid, params[])
{
    #pragma unused params
    if(PlayerInfo[playerid][LoggedIn] == true)
    {
        new string[192];
        new admrank[32];
        new count;
        new pname[MAX_PLAYER_NAME];
        for(new i; i<MAX_PLAYERS; i++)
        {
            if(IsPlayerConnected(i))
            {
                if (IsPlayerAdmin(i))
                {
                    GetPlayerName(i, pname, sizeof(pname));
                    format(string, sizeof(string), "%s{FFFFFF}%s (ID: %d) {FF0000}RCON Admin\n", string, pname, i);
                    ++count;
                }
                else
                {
                    switch(PlayerInfo[i][AdminLevel])
                    {
                        case 0: continue;
                        case 1: admrank = "{FFFF00}Moderator";
                        case 2: admrank = "{008000}Administrator";
                        case 3: admrank = "{3366FF}Manager";
                    }
                    GetPlayerName(i, pname, sizeof(pname));
                    format(string, sizeof(string), "%s{FFFFFF}%s (ID: %d) | Level: %d | Rank: %s\n", string, pname, i, PlayerInfo[i][AdminLevel], admrank);
                    ++count;
                }
            }
        }
        if(count == 0) return format(string, sizeof(string), "{FF0000}There are currently no staff online.");
        ShowPlayerDialog(playerid, DIALOGID0+2, DIALOG_STYLE_MSGBOX, "{FFFFFF}Server staff currently online:", string, "Okay", "");
        return 1;
    } else return SendClientMessage(playerid, COLOR_RED, "ERROR: Account must be registered in order to use commands.");
}
EDIT: turns out that i recoded the code you sent me yesterday wrong i guess, and the problem that wasn't displaying the dialog was at the
pawn Code:
if(count == 0) return format(string, sizeof(string), "{FF0000}There are currently no staff online.");
i removed the return since there was already a "return 1;" at the end if i'm not wrong and yes, it shows more than 1 staff, thanks so much bud, hah it seems like i'm actually learning something

p.s: still want you to explain how you made it allow to have more than 1 staff on the dialog
Reply
#8

I wrote a simulation to test it and then I saw your edit. In case you are interested: https://pastebin.com/raw/fbgDDGTi
it prints correctly:
pawn Code:
{FFFFFF}Server staff currently online:
{FFFFFF}Christopher (ID: 2) | Level: 2 | Rank: {008000}Administrator
{FFFFFF}George (ID: 3) {FF0000}RCON Admin
{FFFFFF}John (ID: 5) | Level: 1 | Rank: {FFFF00}Moderator
{FFFFFF}Robert (ID: 9) | Level: 3 | Rank: {3366FF}Manager
I will give another example, I'll use format instead of a better method to copy string just for the purpose of re-formatting:
pawn Code:
format(string, sizeof (string), "Infernus\n");
format(string, sizeof (string), "Banshee\n");
print(string);
`string` will be overwritten and display only the last text we formatted which is "Banshee\n". Every time you use format, it resets the previous text and writes from the beginning. Two ways to keep the previous text and join the current:
pawn Code:
// First method:
format(string, sizeof (string), "Infernus\n");
format(string, sizeof (string), "%sBanshee\n", string);
print(string);
now `string` is "Infernus\n" and then we put in string the text we just formatted + the new one "Banshee\n". Now it displays "Infernus\nBanshee\n".

The second method I mentioned in your other thread is format+strcat. `strcat` joins the text without resetting.
pawn Code:
// Second method:
format(tmp, sizeof (tmp), "Infernus\n");
strcat(string, tmp); // string now is "Infernus\n"

format(tmp, sizeof (tmp), "Banshee\n");
strcat(string, tmp); // string now is "Infernus\nBanshee\n"

print(string);
The overwriting happens with `admrank` variable too. Every time a player is RCON or admin in general, it keeps resetting and sets the new rank. You can try to play around with static const from the example of your other thread and I have a suggestion too.

Players loop until MAX_PLAYERS should not be used, especially if you have not re-defined MAX_PLAYERS so it loops 1000 times by default.
- y_iterate (also known as foreach) is the first alternative and most recommended.
- `GetPlayerPoolSize` is the other one.
Reply
#9

Start using foreach, makes loop writing much easier and efficent.
You may use server administrator rank names other places also, so you can define it globally.
You can also store players name into array, so you don't have to use GetPlayerName every time you want to use it.
Define dialog ID's with name, so in the future you will understand also, what have you written together or start using easyDialog, so everything related with dialogs can be in one place.
Every command doesn't need check if player is logged in.
Example code of checking if player is logged in or not, it depends what command processor you are using.
PHP Code:
public OnPlayerCommandReceived(playeridcmd[], params[], flags){
    if(!
PlayerInfo[playerid][LoggedIn])return SendClientMessage(playerid, -1"You must be logged in!"), 0;
    return 
1;

PHP Code:
#include <YSI_Data\y_iterate>   //iterating through arrays
enum{
    
DIALOG_STAFF
};
static const 
aRankNames[][40]={
    
"",
    
"{FFFF00}Moderator",
    
"{008000}Administrator",
    
"{3366FF}Manager",
    
"{FF0000}RCON Admin"
};
getAdminRank(pid){
    if(
IsPlayerAdmin(pid)) return (sizeof(aRankNames) - 1);
    return 
PlayerInfo[pid][AdminLevel];
}
getNameWithID(pid){
    new 
s[32];
    
format(s32"%s[%d]"PlayerData[pid][Name], pid);
    return 
s;
}
CMD:staff(pid){
    new 
rank,
        
bs[500];
    foreach(new 
Player){
        if(!(
rank=getAdminRank(i)))continue;
        
format(bssizeof(bs), "%s%s | %s\n"bsgetNameWithID(i), aRankNames[rank]);
    }
    if(!
strlen(bs))
        return 
SendClientMessage(pid, -1"No staff online!");
    
ShowPlayerDialog(pidDIALOG_STAFFDIALOG_STYLE_MSGBOX"Server staff"bs"Okay""");
    return 
1;

Reply
#10

so the "%s' and "string" does the trick, okay, new achievement unlocked... thanks man once again
Reply


Forum Jump:


Users browsing this thread: