Jump to content
  • 0

Problema clan members: Nu afiseaza membrii.


Question

Posted

salutare,

Am si eu o problema la dialog-ul members, nu afiseaza membrii.

Uitati codul mai jos: 

                case 1: {
                    new szDialog2[1024], Members, name[180], cwarn[180], cdays[180], szRank1[180];

                    format(query, sizeof(query), "SELECT * FROM `users` WHERE `users`.`Clan` = '%d' ORDER BY `users`.`ClanRank` DESC LIMIT 50", PlayerInfo[playerid][pClan]);
                    new Cache: result = mysql_query(SQL, query);
            
                    strcat(szDialog2, "#. Name\tRank\tClan Warns\tClan Days\n");
                    for(new i, j = cache_get_row_count (); i != j; ++i)
                    {
                        cache_get_field_content(i, "Username", name);
                        cache_get_field_content(i, "ClanRank", szRank1);
                        cache_get_field_content(i, "ClanWarns", cwarn);
                        cache_get_field_content(i, "ClanDays", cdays);
                        
                        format(Selected[playerid][Members], MAX_PLAYER_NAME, name);
                        format(szDialog, sizeof(szDialog), "%d. %s\t%d\t%s/3\t%s\n", Members+1, name, strval(szRank1), cwarn, cdays);
                        strcat(szDialog2, szDialog);
                        Members++;
                    }
                    cache_delete(result);
                    ShowPlayerDialog(playerid, DIALOG_CLAN_MEMBERS, DIALOG_STYLE_TABLIST_HEADERS, "Clan members", szDialog2, "Ok", "Back");
                }

5 answers to this question

Recommended Posts

  • 0
Posted

case 1:
{
    new szDialog2[4096], szDialog[256];
    new Members = 0;
    new name[24], cwarn[8], cdays[8], szRank1[8];

    format(query, sizeof(query),
        "SELECT Username, ClanRank, ClanWarns, ClanDays \
        FROM users WHERE Clan = %d \
        ORDER BY ClanRank DESC LIMIT 50",
        PlayerInfo[playerid][pClan]);

    new Cache:result = mysql_query(SQL, query);

    strcat(szDialog2, "#. Name\tRank\tClan Warns\tClan Days\n");

    new rows = cache_get_row_count();
    for(new i = 0; i < rows; i++)
    {
        cache_get_field_content(i, "Username", name);
        cache_get_field_content(i, "ClanRank", szRank1);
        cache_get_field_content(i, "ClanWarns", cwarn);
        cache_get_field_content(i, "ClanDays", cdays);

        strcpy(Selected[playerid][Members], name);

        format(szDialog, sizeof szDialog,
            "%d. %s\t%d\t%s/3\t%s\n",
            Members + 1,
            name,
            strval(szRank1),
            cwarn,
            cdays
        );

        strcat(szDialog2, szDialog);
        Members++;
    }

    cache_delete(result);

    ShowPlayerDialog(playerid,
        DIALOG_CLAN_MEMBERS,
        DIALOG_STYLE_TABLIST_HEADERS,
        "Clan members",
        szDialog2,
        "Ok",
        "Back"
    );
}
 

35012l1.png.aee1a3398b9bd9f8eec50574d2cd

  • 0
Posted (edited)

in primu rand, eu as  rescrie toata porcaria aia de cod, ti am rescris eu aici o varianta mult mai buna, daca am omis ceva, ai erori lasa un reply

 case 1: {
    new queryxx[256];
    mysql_format(SQL, queryxx, sizeof queryxx, "SELECT Username, ClanRank, ClanWarns, ClanDays FROM `users` WHERE `Clan` = '%d' ORDER BY ClanRank` DESC LIMIT 50", PlayerInfo[playerid][pClan]);
    return mysql_tquery(SQL, queryxx, "LoadClanMembers", "i", playerid);

}

forward LoadClanMembers(const playerid);
public LoadClanMembers(const playerid) {
    new const rows = cache_num_rows();

    if(!rows)
        return 1;

    new lines[256], 
        gDialog[1024], 
        name[MAX_PLAYER_NAME], 
        rank, days, warns, Members;

    lines = "#. Name\tRank\tClan Warns\tClan Days\n";

    strcat(gDialog, lines);

    for(new i = 0; i < rows; i++) {
        rank = cache_get_field_content_int(i, "ClanRank");
        days = cache_get_field_content_int(i, "ClanDays");
        warns = cache_get_field_content_int(i, "ClanWarns");

        cache_get_field_content(i, "Username", name, SQL, MAX_PLAYER_NAME);

        format(Selected[playerid][Members], MAX_PLAYER_NAME, name);

        format(lines, sizeof(lines), "%d. %s\t%d\t%s/3\t%s\n", Members+1, name, rank, warns, days);

        strcat(gDialog, lines);

        Members++;
    }
    return ShowPlayerDialog(playerid, DIALOG_CLAN_MEMBERS, DIALOG_STYLE_TABLIST_HEADERS, "Clan members", gDialog, "Ok", "Back");
}                

eu nu vad sens si logica ala acest " Members " si  

format(Selected[playerid][Members], MAX_PLAYER_NAME, name);

eu ti am pastrat logica codului, dar nu ii vand sensu ce vrei sa faci aici

Edited by AlexxAdv
  • 0
Posted
4 hours ago, AlexxAdv said:

in primu rand, eu as  rescrie toata porcaria aia de cod, ti am rescris eu aici o varianta mult mai buna, daca am omis ceva, ai erori lasa un reply

 case 1: {
    new queryxx[256];
    mysql_format(SQL, queryxx, sizeof queryxx, "SELECT Username, ClanRank, ClanWarns, ClanDays FROM `users` WHERE `Clan` = '%d' ORDER BY ClanRank` DESC LIMIT 50", PlayerInfo[playerid][pClan]);
    return mysql_tquery(SQL, queryxx, "LoadClanMembers", "i", playerid);

}

forward LoadClanMembers(const playerid);
public LoadClanMembers(const playerid) {
    new const rows = cache_num_rows();

    if(!rows)
        return 1;

    new lines[256], 
        gDialog[1024], 
        name[MAX_PLAYER_NAME], 
        rank, days, warns, Members;

    lines = "#. Name\tRank\tClan Warns\tClan Days\n";

    strcat(gDialog, lines);

    for(new i = 0; i < rows; i++) {
        rank = cache_get_field_content_int(i, "ClanRank");
        days = cache_get_field_content_int(i, "ClanDays");
        warns = cache_get_field_content_int(i, "ClanWarns");

        cache_get_field_content(i, "Username", name, SQL, MAX_PLAYER_NAME);

        format(Selected[playerid][Members], MAX_PLAYER_NAME, name);

        format(lines, sizeof(lines), "%d. %s\t%d\t%s/3\t%s\n", Members+1, name, rank, warns, days);

        strcat(gDialog, lines);

        Members++;
    }
    return ShowPlayerDialog(playerid, DIALOG_CLAN_MEMBERS, DIALOG_STYLE_TABLIST_HEADERS, "Clan members", gDialog, "Ok", "Back");
}                

eu nu vad sens si logica ala acest " Members " si  

format(Selected[playerid][Members], MAX_PLAYER_NAME, name);

eu ti am pastrat logica codului, dar nu ii vand sensu ce vrei sa faci aici

Actualizeaza clanrank, clan warns dupa username probabil

asgood.ro

 

 

 

  • 0
Posted

The reason your members aren't showing up is likely due to how MySQL caches and String Concatenation behave in PAWN when buffers are mismanaged.

🔍 The "Ghost" Logic Bugs

  1. The szDialog Confusion: In your original code, you used szDialog inside the loop but declared szDialog2 outside. If szDialog wasn't properly initialized or was too small, strcat(szDialog2, szDialog) would append empty or garbage data.

  2. The Members Variable: You declared new Members; but never initialized it to 0. In some compiler versions, uninitialized locals can contain random "garbage" values from the stack. If Members started at a huge number, Selected[playerid][Members] would cause a memory out-of-bounds error, potentially crashing the script before it reached the dialog.

  3. Buffer Overflow: With 50 members, your szDialog2[1024] was likely hitting its limit. When a string in PAWN exceeds its size during a format or strcat, it can null-terminate prematurely or cause the script to bail out.

🛠️ The Fixed Logic

Here is the corrected logic. I have also moved the variables to be more memory-efficient and added an explicit initialization for the counter.

Code snippet
case 1: 
{
    // Use a static buffer to prevent stack exhaustion
    static szBigDialog[3000]; 
    new query[128], rows;

    format(query, sizeof(query), "SELECT `Username`, `ClanRank`, `ClanWarns`, `ClanDays` FROM `users` WHERE `Clan` = '%d' ORDER BY `ClanRank` DESC LIMIT 50", PlayerInfo[playerid][pClan]);
    
    new Cache:result = mysql_query(SQL, query);
    cache_get_row_count(rows);

    // Reset the buffer and the member counter
    szBigDialog[0] = EOS; 
    strcat(szBigDialog, "#. Name\tRank\tClan Warns\tClan Days\n");

    if(rows == 0) {
        strcat(szBigDialog, " \tNo members found\t \t ");
    } else {
        new tempName[MAX_PLAYER_NAME], tempRank, tempWarns, tempDays;
        new rowEntry[128];

        for(new i = 0; i < rows; i++)
        {
            // Extracting data correctly
            cache_get_value_name(i, "Username", tempName, sizeof(tempName));
            cache_get_value_name_int(i, "ClanRank", tempRank);
            cache_get_value_name_int(i, "ClanWarns", tempWarns);
            cache_get_value_name_int(i, "ClanDays", tempDays);

            // Store name for the OnDialogResponse selection
            format(Selected[playerid][i], MAX_PLAYER_NAME, tempName);

            // Build the row
            format(rowEntry, sizeof(rowEntry), "%d. %s\t%d\t%d/3\t%d\n", i + 1, tempName, tempRank, tempWarns, tempDays);
            
            // Append to the big string
            strcat(szBigDialog, rowEntry);
        }
    }

    cache_delete(result);
    ShowPlayerDialog(playerid, DIALOG_CLAN_MEMBERS, DIALOG_STYLE_TABLIST_HEADERS, "Clan members", szBigDialog, "Select", "Back");
}

💡 Why this version works:

  • Initialization: szBigDialog[0] = EOS ensures you aren't appending to old data left in memory.

  • Safety: Using rows directly from cache_get_row_count ensures the loop only runs exactly as many times as there are results.

  • Proper Indices: Using i as the index for Selected[playerid][i] ensures that the row number in the dialog matches the ID in your array perfectly.

  • Column Names: Ensure your SQL column names (Username, ClanRank, etc.) match your database exactly. MySQL is case-sensitive on some Linux distributions.

⚠️ A Note on Selected[playerid]

Make sure your Selected array is large enough to hold the names! It should be defined globally like this: new Selected[MAX_PLAYERS][50][MAX_PLAYER_NAME];

If it’s defined as [MAX_PLAYERS][MAX_PLAYER_NAME], you are trying to store 50 names into a single string slot, which will overwrite the previous name every time.

Would you like me to check how you've defined the Selected variable to make sure it can handle 50 members?

  • 0
Posted (edited)
3 hours ago, segmentationfault said:

The reason your members aren't showing up is likely due to how MySQL caches and String Concatenation behave in PAWN when buffers are mismanaged.

🔍 The "Ghost" Logic Bugs

  1. The szDialog Confusion: In your original code, you used szDialog inside the loop but declared szDialog2 outside. If szDialog wasn't properly initialized or was too small, strcat(szDialog2, szDialog) would append empty or garbage data.

  2. The Members Variable: You declared new Members; but never initialized it to 0. In some compiler versions, uninitialized locals can contain random "garbage" values from the stack. If Members started at a huge number, Selected[playerid][Members] would cause a memory out-of-bounds error, potentially crashing the script before it reached the dialog.

  3. Buffer Overflow: With 50 members, your szDialog2[1024] was likely hitting its limit. When a string in PAWN exceeds its size during a format or strcat, it can null-terminate prematurely or cause the script to bail out.

🛠️ The Fixed Logic

Here is the corrected logic. I have also moved the variables to be more memory-efficient and added an explicit initialization for the counter.

Code snippet
 
case 1: 
{
    // Use a static buffer to prevent stack exhaustion
    static szBigDialog[3000]; 
    new query[128], rows;

    format(query, sizeof(query), "SELECT `Username`, `ClanRank`, `ClanWarns`, `ClanDays` FROM `users` WHERE `Clan` = '%d' ORDER BY `ClanRank` DESC LIMIT 50", PlayerInfo[playerid][pClan]);
    
    new Cache:result = mysql_query(SQL, query);
    cache_get_row_count(rows);

    // Reset the buffer and the member counter
    szBigDialog[0] = EOS; 
    strcat(szBigDialog, "#. Name\tRank\tClan Warns\tClan Days\n");

    if(rows == 0) {
        strcat(szBigDialog, " \tNo members found\t \t ");
    } else {
        new tempName[MAX_PLAYER_NAME], tempRank, tempWarns, tempDays;
        new rowEntry[128];

        for(new i = 0; i < rows; i++)
        {
            // Extracting data correctly
            cache_get_value_name(i, "Username", tempName, sizeof(tempName));
            cache_get_value_name_int(i, "ClanRank", tempRank);
            cache_get_value_name_int(i, "ClanWarns", tempWarns);
            cache_get_value_name_int(i, "ClanDays", tempDays);

            // Store name for the OnDialogResponse selection
            format(Selected[playerid][i], MAX_PLAYER_NAME, tempName);

            // Build the row
            format(rowEntry, sizeof(rowEntry), "%d. %s\t%d\t%d/3\t%d\n", i + 1, tempName, tempRank, tempWarns, tempDays);
            
            // Append to the big string
            strcat(szBigDialog, rowEntry);
        }
    }

    cache_delete(result);
    ShowPlayerDialog(playerid, DIALOG_CLAN_MEMBERS, DIALOG_STYLE_TABLIST_HEADERS, "Clan members", szBigDialog, "Select", "Back");
}

💡 Why this version works:

  • Initialization: szBigDialog[0] = EOS ensures you aren't appending to old data left in memory.

  • Safety: Using rows directly from cache_get_row_count ensures the loop only runs exactly as many times as there are results.

  • Proper Indices: Using i as the index for Selected[playerid][i] ensures that the row number in the dialog matches the ID in your array perfectly.

  • Column Names: Ensure your SQL column names (Username, ClanRank, etc.) match your database exactly. MySQL is case-sensitive on some Linux distributions.

⚠️ A Note on Selected[playerid]

Make sure your Selected array is large enough to hold the names! It should be defined globally like this: new Selected[MAX_PLAYERS][50][MAX_PLAYER_NAME];

If it’s defined as [MAX_PLAYERS][MAX_PLAYER_NAME], you are trying to store 50 names into a single string slot, which will overwrite the previous name every time.

Would you like me to check how you've defined the Selected variable to make sure it can handle 50 members?

mai bine o stergi bro...pe laanga faptu ca e mai proasta decat versiunea pusa de el sau ma rog, tot pe acolo ambelee, 2 prostii, mai e si gresita...

Edited by AlexxAdv

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. For more details you can also review our Terms of Use and Privacy Policy.