Portal SAMP
[Ajuda] Erros ao utilizar MySQL - Versão de Impressão

+- Portal SAMP (https://portalsamp.com)
+-- Fórum: SA-MP (https://portalsamp.com/forumdisplay.php?fid=5)
+--- Fórum: Área de suporte (https://portalsamp.com/forumdisplay.php?fid=6)
+--- Tópico: [Ajuda] Erros ao utilizar MySQL (/showthread.php?tid=4663)

Páginas: 1 2


RE: Erros ao utilizar MySQL - pushline - 01/04/2024

(01/04/2024 14:28)White_Blue Escreveu:
(01/04/2024 13:34)pushline Escreveu: Complementando o que o samuel falou, eu faria assim: (e não recomendo fazer stock pra funções já que stocks ocupam mais memória e só servem pra includes)

Código PHP:
new Query[255];
mysql_format(Querysizeof(Query), "SELECT * FROM tabela_players WHERE username = '%e' LIMIT 1"nome_player);
mysql_tquery(MYSQL_DEFAULT_HANDLEQuery"LoadAccount""i"playerid); // esse "i" podes acrescentar mais argumentos, tais como string ("s"), float ("f") e etc (array n passa se eu n me engano).

forward LoadAccount(playerid); // se fosse colocar no tquery "iii", teria que ter 3 parametros no forward + public.
public LoadAccount(playerid)

  if(!cache_num_rows())
  {
    return SendClientMessage(playerid, -1"Player inexistente.");
  }

  cache_get_value_int(0"ID"PlayerInfo[playerid][pID]);
  cache_get_value_name(0"Senha"PlayerInfo[playerid][pSenha]);
  cache_get_value_int(0"Level"PlayerInfo[playerid][pLevel]);
  cache_get_value_int(0"EXP"PlayerInfo[playerid][pExp]);
  cache_get_value_int(0"Dinheiro"PlayerInfo[playerid][pGrana]);
  cache_get_value_int(0"Saldo"PlayerInfo[playerid][pSaldo]);
  cache_get_value_int(0"Admin"PlayerInfo[playerid][pAdmin]);
  cache_get_value_float(0"PosX"PlayerInfo[playerid][pPosX]);
  cache_get_value_float(0"PosY"PlayerInfo[playerid][pPosY]);
  cache_get_value_float(0"PosZ"PlayerInfo[playerid][pPosZ]);
  cache_get_value_int(0"Sede"PlayerInfo[playerid][pSede]);
  cache_get_value_int(0"Fome"PlayerInfo[playerid][pFome]);
  cache_get_value_int(0"Sono"PlayerInfo[playerid][pSono]);
  cache_get_value_int(0"Sexo"PlayerInfo[playerid][pSkin]);
  cache_get_value_float(0"Vida"PlayerInfo[playerid][pVida]);
  cache_get_value_float(0"Colete"PlayerInfo[playerid][pColete]);
  return 1;


stock = funções (que tecnicamente é apenas uma palavra-chave para dizer para o compilador ignroar a função caso a mesma não for utilizada);
public = callbacks/eventos;

Se usa stock para funções e publics apenas devem ser usadas para eventos. Não é questão de memória.

Funções não precisam ser declaradas como stock. Geralmente só includes, caso a pessoa não chegue a usar todas
E stock realmente não consume memória! Acabei errando ao ler este artigo denovo: https://sampforum.blast.hk/showthread.php?tid=570635

(01/04/2024 13:46)Ryzen_ Escreveu:
(01/04/2024 13:34)pushline Escreveu: Complementando o que o samuel falou, eu faria assim: (e não recomendo fazer stock pra funções já que stocks ocupam mais memória e só servem pra includes)

Código PHP:
new Query[255];
mysql_format(Querysizeof(Query), "SELECT * FROM tabela_players WHERE username = '%e' LIMIT 1"nome_player);
mysql_tquery(MYSQL_DEFAULT_HANDLEQuery"LoadAccount""i"playerid); // esse "i" podes acrescentar mais argumentos, tais como string ("s"), float ("f") e etc (array n passa se eu n me engano).

forward LoadAccount(playerid); // se fosse colocar no tquery "iii", teria que ter 3 parametros no forward + public.
public LoadAccount(playerid)

  if(!cache_num_rows())
  {
    return SendClientMessage(playerid, -1"Player inexistente.");
  }

  cache_get_value_int(0"ID"PlayerInfo[playerid][pID]);
  cache_get_value_name(0"Senha"PlayerInfo[playerid][pSenha]);
  cache_get_value_int(0"Level"PlayerInfo[playerid][pLevel]);
  cache_get_value_int(0"EXP"PlayerInfo[playerid][pExp]);
  cache_get_value_int(0"Dinheiro"PlayerInfo[playerid][pGrana]);
  cache_get_value_int(0"Saldo"PlayerInfo[playerid][pSaldo]);
  cache_get_value_int(0"Admin"PlayerInfo[playerid][pAdmin]);
  cache_get_value_float(0"PosX"PlayerInfo[playerid][pPosX]);
  cache_get_value_float(0"PosY"PlayerInfo[playerid][pPosY]);
  cache_get_value_float(0"PosZ"PlayerInfo[playerid][pPosZ]);
  cache_get_value_int(0"Sede"PlayerInfo[playerid][pSede]);
  cache_get_value_int(0"Fome"PlayerInfo[playerid][pFome]);
  cache_get_value_int(0"Sono"PlayerInfo[playerid][pSono]);
  cache_get_value_int(0"Sexo"PlayerInfo[playerid][pSkin]);
  cache_get_value_float(0"Vida"PlayerInfo[playerid][pVida]);
  cache_get_value_float(0"Colete"PlayerInfo[playerid][pColete]);
  return 1;

Stock ocupa mais memória? Não sabia. Pelo que me foi dito, era recomendado utilizar publics apenas em callbacks, e fora delas, utilizar apenas a stock. Quem criou o sistema de LoadAccount foi um outro membro da equipe, pois partiu dele a decisão de ir do DOF2 para o MySQL (Apenas nas contas, os demais sistemas ficaram em DOF, tais como o sistema de clans). Obrigado pelas respostas Samuel e Pushline, me ajudou a dar uma clareada. O que o outro membro da equipe fez, se encontra atualmente dessa forma (Na função CreateAccount(), creio que também tenha algo de errado, podem verificar por favor? Também notei que ele usou mysql_query() nela):

Função LoadAccount() presente no arquivo "login.inc":
Código PHP:
stock LoadAccount(playerid) {
    //format(File, sizeof(File), PASTA_CONTAS, GetPlayerNameEx(playerid));

    SetCameraBehindPlayer(playerid);
    CancelSelectTextDraw(playerid);
    StopAudioStreamForPlayer(playerid);
    DeletePVar(playerid"hash");
    print("LoadAccount chamada");


    // HUD
    ShowPlayerGlobalHUDStats(playerid);
    ShowPlayerHUDStats(playerid);
    PlayerTextDrawShow(playeridrelogio[playerid]);
    ShowTextData(playerid);

    // Stats system
    SetPlayerProgressBarValue(playeridStatsBar[playerid][0], float(PlayerInfo[playerid][pFome]));
    SetPlayerProgressBarValue(playeridStatsBar[playerid][1], float(PlayerInfo[playerid][pSede]));
    SetPlayerProgressBarValue(playeridStatsBar[playerid][2], float(PlayerInfo[playerid][pSono]));


    // Timers
    TimerHunger[playerid] = SetTimerEx("HungerTimer"1200000true"i"playerid);
    TimerSono[playerid] = SetTimerEx("SonoTimer"2400000true"i"playerid);
    TimerSede[playerid] = SetTimerEx("SedeTimer"900000true"i"playerid);
    ClockTimer[playerid] = SetTimerEx("Clock"1000true"i"playerid);
    TimerSegundos[playerid] = SetTimerEx("AtualizarSegundos"1000true"i"playerid);
    SetTimerEx("SetPlayerCashInTime"1300false"ii"playeridGetPlayerCash(playerid));
    KillTimer(TimerExpirarLogin[playerid]);

    TogglePlayerSpectating(playeridfalse);
    SetSpawnInfo(playeridNO_TEAMPlayerInfo[playerid][pSkin], PlayerInfo[playerid][pPosX], PlayerInfo[playerid][pPosY], PlayerInfo[playerid][pPosZ], 0.3040WEAPON_FIST0WEAPON_FIST0WEAPON_FIST0);
    SpawnPlayer(playerid);
    SetPlayerScore(playeridPlayerInfo[playerid][pLevel]);
    SetPlayerJobColor(playeridGetPlayerJob(playerid));
    SetPlayerClanColor(playeridGetPlayerClan(playerid));

    SetPVarInt(playerid"exp"gettime());

    format(STRXsizeof(STRX), "%d"GetPlayerWanted(playerid));
    PlayerTextDrawSetString(playeridPlayerHUD[playerid][0], STRX);

    SetPVarInt(playerid"AFKUpdate"gettime());
    DeletePVar(playerid"unhashedpassword");
    PlayerInfo[playerid][pLogado] = true;
    SetPlayerSkin(playeridPlayerInfo[playerid][pSkin]);

    cache_get_value_int(0"ID"PlayerInfo[playerid][pID]);
    cache_get_value_name(0"Senha"PlayerInfo[playerid][pSenha]);
    cache_get_value_int(0"Level"PlayerInfo[playerid][pLevel]);
    cache_get_value_int(0"EXP"PlayerInfo[playerid][pExp]);
    cache_get_value_int(0"Dinheiro"PlayerInfo[playerid][pGrana]);
    cache_get_value_int(0"Saldo"PlayerInfo[playerid][pSaldo]);
    cache_get_value_int(0"Admin"PlayerInfo[playerid][pAdmin]);
    cache_get_value_float(0"PosX"PlayerInfo[playerid][pPosX]);
    cache_get_value_float(0"PosY"PlayerInfo[playerid][pPosY]);
    cache_get_value_float(0"PosZ"PlayerInfo[playerid][pPosZ]);
    cache_get_value_int(0"Sede"PlayerInfo[playerid][pSede]);
    cache_get_value_int(0"Fome"PlayerInfo[playerid][pFome]);
    cache_get_value_int(0"Sono"PlayerInfo[playerid][pSono]);
    cache_get_value_int(0"Sexo"PlayerInfo[playerid][pSkin]);
    cache_get_value_float(0"Vida"PlayerInfo[playerid][pVida]);
    cache_get_value_float(0"Colete"PlayerInfo[playerid][pColete]);
    
    
if(PlayerInfo[playerid][pInterior] > 0) {
        SetTimerEx("SetInterior"200false"i"playerid);
    }

    SetPlayerHealth(playeridPlayerInfo[playerid][pVida]);
    SetPlayerArmour(playeridPlayerInfo[playerid][pColete]);
    TogglePlayerControllable(playeridfalse);
    
    SetTimerEx
("DestogglePlayerControllable"300false"i"playerid);
    return 1;


Funções presentes no arquivo da GM:
Código PHP:
forward CreateAccount(playerid);
public 
CreateAccount(playerid) {
    new query[500], email[128];
    GetPVarString(playerid"unconfirmedemail"email);

    PlayerInfo[playerid][pID] = cache_insert_id();
    PlayerInfo[playerid][pLevel] = 0;
    PlayerInfo[playerid][pExp] = 0;
    PlayerInfo[playerid][pGrana] = 5000;
    PlayerInfo[playerid][pSaldo] = 0;
    PlayerInfo[playerid][pAdmin] = 0;
    PlayerInfo[playerid][pPosX] = 1154.4115;
    PlayerInfo[playerid][pPosY] = -1747.7765;
    PlayerInfo[playerid][pPosZ] = 13.5703;
    PlayerInfo[playerid][pFome] = 100;
    PlayerInfo[playerid][pSede] = 100;
    PlayerInfo[playerid][pSono] = 100;
    PlayerInfo[playerid][pVida] = 100.0;
    PlayerInfo[playerid][pColete] = 0.0;

    mysql_format(connquerysizeof(query), "SELECT * FROM jogadores WHERE ID='%i'"PlayerInfo[playerid][pID]);
    mysql_query(connquery);
    LoadAccount(playerid);
    
    
//DOF2_SetString(file, "Email", email);
    DeletePVar(playerid"unconfirmedemail");
    DeletePVar(playerid"hash");
    

    
print("CreateAccount Chamada");
    SetPlayerJob(playeridPROF_DESEMPREGADO);
    CancelSelectTextDraw(playerid);
    ShowPlayerDialog(playeridDIALOG_GENDERDIALOG_STYLE_MSGBOX"Gênero - Escolha seu Gênero""{FFFFFF}Escolha seu Gênero""Masculino""Feminino");
    return 1;
}

forward OnPassCheck(playerid);
public 
OnPassCheck(playerid) {
    if(bcrypt_is_equal()) {
        PlayerInfo[playerid][pLogado] = true;
        LoadAccount(playerid);
        SendClientMessage(playeridMarrom"| INFO | %s de volta, %s | Último login: %s"PlayerInfo[playerid][pSexo] ? "Bem-vindo" "Bem-vinda"GetPlayerNameEx(playerid), DOF2_GetString(File"UltimoLogin"));
    } else {
        PlayerInfo[playerid][pTentativas]++;
        SendClientMessage(playeridVermelho"| ERRO | Senha inválida");
    }
    return 1;


Função OnPlayerConnect (Creio que o problema em não carregar os dados no momento em que é feito o login, possa estar contido nisso. Já que não vejo chamada alguma do LoadAccount ao player se conectar): 

Código PHP:
public OnPlayerConnect(playerid) {
    PlayerInfo[playerid][pLogado] = false;

    LoadBan(playerid);

    if(!strcmp(GetPlayerNameEx(playerid), "Ninguem")) return Kick(playerid);
    else if(IsTextIP(GetPlayerNameEx(playerid))) return Kick(playerid);

    LoadPlayerTextDraws(playerid);
    LoadPlayerProgressBars(playerid);
    PreloadAnimLibs(playerid);

    LoadSocialMediaMap(playerid);

    new Random random(MAX_SONGS), song[128];
    format(songsizeof(song), "%s"musicas[Random]);

    PlayAudioStreamForPlayer(playeridsong);
    return 1;


Att.: Em "mysql_format(Query, sizeof(Query), "SELECT * FROM tabela_players WHERE username = '%e' LIMIT 1", nome_player);", o que seria o "nome_player"? A variável responsável por armazenar o nick do jogador, tal como "PlayerInfo[playerid][pName]"?

Att-2: Creio ter entendido já. Provavelmente é uma forma de pegar o nick do player através do ID, que no meu caso seria "GetPlayerNameEx(playerid)", correto?

Esse código é meio estranho. o CreateAccount procura o player pra voltar dados do sql (sendo que a função é pra criar) e depois dá load? O loadaccount não vai funcionar o cache_... lá dentro por que tem que "enviar" esse cache com tquery.

Na att 1 e 2 - o "nome_player" é só um exemplo pro nome do player, você pode usar o que quiser lá dentro pra referenciar o nome do player, tal como o pName ou o NameEx. 

Recomendo fazer a query de procura de player (LoadAccount) no OnPlayerConnect, e dentro dela, se não tiver algum player (!cache_num_rows()), chamar a createAccount com um "insert into ..." usando mysql_tquery.


RE: Erros ao utilizar MySQL - Ryzen_ - 01/04/2024

(01/04/2024 15:21)pushline Escreveu:
(01/04/2024 14:28)White_Blue Escreveu:
(01/04/2024 13:34)pushline Escreveu: Complementando o que o samuel falou, eu faria assim: (e não recomendo fazer stock pra funções já que stocks ocupam mais memória e só servem pra includes)

Código PHP:
new Query[255];
mysql_format(Querysizeof(Query), "SELECT * FROM tabela_players WHERE username = '%e' LIMIT 1"nome_player);
mysql_tquery(MYSQL_DEFAULT_HANDLEQuery"LoadAccount""i"playerid); // esse "i" podes acrescentar mais argumentos, tais como string ("s"), float ("f") e etc (array n passa se eu n me engano).

forward LoadAccount(playerid); // se fosse colocar no tquery "iii", teria que ter 3 parametros no forward + public.
public LoadAccount(playerid)

  if(!cache_num_rows())
  {
    return SendClientMessage(playerid, -1"Player inexistente.");
  }

  cache_get_value_int(0"ID"PlayerInfo[playerid][pID]);
  cache_get_value_name(0"Senha"PlayerInfo[playerid][pSenha]);
  cache_get_value_int(0"Level"PlayerInfo[playerid][pLevel]);
  cache_get_value_int(0"EXP"PlayerInfo[playerid][pExp]);
  cache_get_value_int(0"Dinheiro"PlayerInfo[playerid][pGrana]);
  cache_get_value_int(0"Saldo"PlayerInfo[playerid][pSaldo]);
  cache_get_value_int(0"Admin"PlayerInfo[playerid][pAdmin]);
  cache_get_value_float(0"PosX"PlayerInfo[playerid][pPosX]);
  cache_get_value_float(0"PosY"PlayerInfo[playerid][pPosY]);
  cache_get_value_float(0"PosZ"PlayerInfo[playerid][pPosZ]);
  cache_get_value_int(0"Sede"PlayerInfo[playerid][pSede]);
  cache_get_value_int(0"Fome"PlayerInfo[playerid][pFome]);
  cache_get_value_int(0"Sono"PlayerInfo[playerid][pSono]);
  cache_get_value_int(0"Sexo"PlayerInfo[playerid][pSkin]);
  cache_get_value_float(0"Vida"PlayerInfo[playerid][pVida]);
  cache_get_value_float(0"Colete"PlayerInfo[playerid][pColete]);
  return 1;


stock = funções (que tecnicamente é apenas uma palavra-chave para dizer para o compilador ignroar a função caso a mesma não for utilizada);
public = callbacks/eventos;

Se usa stock para funções e publics apenas devem ser usadas para eventos. Não é questão de memória.

Funções não precisam ser declaradas como stock. Geralmente só includes, caso a pessoa não chegue a usar todas
E stock realmente não consume memória! Acabei errando ao ler este artigo denovo: https://sampforum.blast.hk/showthread.php?tid=570635

(01/04/2024 13:46)Ryzen_ Escreveu:
(01/04/2024 13:34)pushline Escreveu: Complementando o que o samuel falou, eu faria assim: (e não recomendo fazer stock pra funções já que stocks ocupam mais memória e só servem pra includes)

Código PHP:
new Query[255];
mysql_format(Querysizeof(Query), "SELECT * FROM tabela_players WHERE username = '%e' LIMIT 1"nome_player);
mysql_tquery(MYSQL_DEFAULT_HANDLEQuery"LoadAccount""i"playerid); // esse "i" podes acrescentar mais argumentos, tais como string ("s"), float ("f") e etc (array n passa se eu n me engano).

forward LoadAccount(playerid); // se fosse colocar no tquery "iii", teria que ter 3 parametros no forward + public.
public LoadAccount(playerid)

  if(!cache_num_rows())
  {
    return SendClientMessage(playerid, -1"Player inexistente.");
  }

  cache_get_value_int(0"ID"PlayerInfo[playerid][pID]);
  cache_get_value_name(0"Senha"PlayerInfo[playerid][pSenha]);
  cache_get_value_int(0"Level"PlayerInfo[playerid][pLevel]);
  cache_get_value_int(0"EXP"PlayerInfo[playerid][pExp]);
  cache_get_value_int(0"Dinheiro"PlayerInfo[playerid][pGrana]);
  cache_get_value_int(0"Saldo"PlayerInfo[playerid][pSaldo]);
  cache_get_value_int(0"Admin"PlayerInfo[playerid][pAdmin]);
  cache_get_value_float(0"PosX"PlayerInfo[playerid][pPosX]);
  cache_get_value_float(0"PosY"PlayerInfo[playerid][pPosY]);
  cache_get_value_float(0"PosZ"PlayerInfo[playerid][pPosZ]);
  cache_get_value_int(0"Sede"PlayerInfo[playerid][pSede]);
  cache_get_value_int(0"Fome"PlayerInfo[playerid][pFome]);
  cache_get_value_int(0"Sono"PlayerInfo[playerid][pSono]);
  cache_get_value_int(0"Sexo"PlayerInfo[playerid][pSkin]);
  cache_get_value_float(0"Vida"PlayerInfo[playerid][pVida]);
  cache_get_value_float(0"Colete"PlayerInfo[playerid][pColete]);
  return 1;

Stock ocupa mais memória? Não sabia. Pelo que me foi dito, era recomendado utilizar publics apenas em callbacks, e fora delas, utilizar apenas a stock. Quem criou o sistema de LoadAccount foi um outro membro da equipe, pois partiu dele a decisão de ir do DOF2 para o MySQL (Apenas nas contas, os demais sistemas ficaram em DOF, tais como o sistema de clans). Obrigado pelas respostas Samuel e Pushline, me ajudou a dar uma clareada. O que o outro membro da equipe fez, se encontra atualmente dessa forma (Na função CreateAccount(), creio que também tenha algo de errado, podem verificar por favor? Também notei que ele usou mysql_query() nela):

Função LoadAccount() presente no arquivo "login.inc":
Código PHP:
stock LoadAccount(playerid) {
    //format(File, sizeof(File), PASTA_CONTAS, GetPlayerNameEx(playerid));

    SetCameraBehindPlayer(playerid);
    CancelSelectTextDraw(playerid);
    StopAudioStreamForPlayer(playerid);
    DeletePVar(playerid"hash");
    print("LoadAccount chamada");


    // HUD
    ShowPlayerGlobalHUDStats(playerid);
    ShowPlayerHUDStats(playerid);
    PlayerTextDrawShow(playeridrelogio[playerid]);
    ShowTextData(playerid);

    // Stats system
    SetPlayerProgressBarValue(playeridStatsBar[playerid][0], float(PlayerInfo[playerid][pFome]));
    SetPlayerProgressBarValue(playeridStatsBar[playerid][1], float(PlayerInfo[playerid][pSede]));
    SetPlayerProgressBarValue(playeridStatsBar[playerid][2], float(PlayerInfo[playerid][pSono]));


    // Timers
    TimerHunger[playerid] = SetTimerEx("HungerTimer"1200000true"i"playerid);
    TimerSono[playerid] = SetTimerEx("SonoTimer"2400000true"i"playerid);
    TimerSede[playerid] = SetTimerEx("SedeTimer"900000true"i"playerid);
    ClockTimer[playerid] = SetTimerEx("Clock"1000true"i"playerid);
    TimerSegundos[playerid] = SetTimerEx("AtualizarSegundos"1000true"i"playerid);
    SetTimerEx("SetPlayerCashInTime"1300false"ii"playeridGetPlayerCash(playerid));
    KillTimer(TimerExpirarLogin[playerid]);

    TogglePlayerSpectating(playeridfalse);
    SetSpawnInfo(playeridNO_TEAMPlayerInfo[playerid][pSkin], PlayerInfo[playerid][pPosX], PlayerInfo[playerid][pPosY], PlayerInfo[playerid][pPosZ], 0.3040WEAPON_FIST0WEAPON_FIST0WEAPON_FIST0);
    SpawnPlayer(playerid);
    SetPlayerScore(playeridPlayerInfo[playerid][pLevel]);
    SetPlayerJobColor(playeridGetPlayerJob(playerid));
    SetPlayerClanColor(playeridGetPlayerClan(playerid));

    SetPVarInt(playerid"exp"gettime());

    format(STRXsizeof(STRX), "%d"GetPlayerWanted(playerid));
    PlayerTextDrawSetString(playeridPlayerHUD[playerid][0], STRX);

    SetPVarInt(playerid"AFKUpdate"gettime());
    DeletePVar(playerid"unhashedpassword");
    PlayerInfo[playerid][pLogado] = true;
    SetPlayerSkin(playeridPlayerInfo[playerid][pSkin]);

    cache_get_value_int(0"ID"PlayerInfo[playerid][pID]);
    cache_get_value_name(0"Senha"PlayerInfo[playerid][pSenha]);
    cache_get_value_int(0"Level"PlayerInfo[playerid][pLevel]);
    cache_get_value_int(0"EXP"PlayerInfo[playerid][pExp]);
    cache_get_value_int(0"Dinheiro"PlayerInfo[playerid][pGrana]);
    cache_get_value_int(0"Saldo"PlayerInfo[playerid][pSaldo]);
    cache_get_value_int(0"Admin"PlayerInfo[playerid][pAdmin]);
    cache_get_value_float(0"PosX"PlayerInfo[playerid][pPosX]);
    cache_get_value_float(0"PosY"PlayerInfo[playerid][pPosY]);
    cache_get_value_float(0"PosZ"PlayerInfo[playerid][pPosZ]);
    cache_get_value_int(0"Sede"PlayerInfo[playerid][pSede]);
    cache_get_value_int(0"Fome"PlayerInfo[playerid][pFome]);
    cache_get_value_int(0"Sono"PlayerInfo[playerid][pSono]);
    cache_get_value_int(0"Sexo"PlayerInfo[playerid][pSkin]);
    cache_get_value_float(0"Vida"PlayerInfo[playerid][pVida]);
    cache_get_value_float(0"Colete"PlayerInfo[playerid][pColete]);
    
    
if(PlayerInfo[playerid][pInterior] > 0) {
        SetTimerEx("SetInterior"200false"i"playerid);
    }

    SetPlayerHealth(playeridPlayerInfo[playerid][pVida]);
    SetPlayerArmour(playeridPlayerInfo[playerid][pColete]);
    TogglePlayerControllable(playeridfalse);
    
    SetTimerEx
("DestogglePlayerControllable"300false"i"playerid);
    return 1;


Funções presentes no arquivo da GM:
Código PHP:
forward CreateAccount(playerid);
public 
CreateAccount(playerid) {
    new query[500], email[128];
    GetPVarString(playerid"unconfirmedemail"email);

    PlayerInfo[playerid][pID] = cache_insert_id();
    PlayerInfo[playerid][pLevel] = 0;
    PlayerInfo[playerid][pExp] = 0;
    PlayerInfo[playerid][pGrana] = 5000;
    PlayerInfo[playerid][pSaldo] = 0;
    PlayerInfo[playerid][pAdmin] = 0;
    PlayerInfo[playerid][pPosX] = 1154.4115;
    PlayerInfo[playerid][pPosY] = -1747.7765;
    PlayerInfo[playerid][pPosZ] = 13.5703;
    PlayerInfo[playerid][pFome] = 100;
    PlayerInfo[playerid][pSede] = 100;
    PlayerInfo[playerid][pSono] = 100;
    PlayerInfo[playerid][pVida] = 100.0;
    PlayerInfo[playerid][pColete] = 0.0;

    mysql_format(connquerysizeof(query), "SELECT * FROM jogadores WHERE ID='%i'"PlayerInfo[playerid][pID]);
    mysql_query(connquery);
    LoadAccount(playerid);
    
    
//DOF2_SetString(file, "Email", email);
    DeletePVar(playerid"unconfirmedemail");
    DeletePVar(playerid"hash");
    

    
print("CreateAccount Chamada");
    SetPlayerJob(playeridPROF_DESEMPREGADO);
    CancelSelectTextDraw(playerid);
    ShowPlayerDialog(playeridDIALOG_GENDERDIALOG_STYLE_MSGBOX"Gênero - Escolha seu Gênero""{FFFFFF}Escolha seu Gênero""Masculino""Feminino");
    return 1;
}

forward OnPassCheck(playerid);
public 
OnPassCheck(playerid) {
    if(bcrypt_is_equal()) {
        PlayerInfo[playerid][pLogado] = true;
        LoadAccount(playerid);
        SendClientMessage(playeridMarrom"| INFO | %s de volta, %s | Último login: %s"PlayerInfo[playerid][pSexo] ? "Bem-vindo" "Bem-vinda"GetPlayerNameEx(playerid), DOF2_GetString(File"UltimoLogin"));
    } else {
        PlayerInfo[playerid][pTentativas]++;
        SendClientMessage(playeridVermelho"| ERRO | Senha inválida");
    }
    return 1;


Função OnPlayerConnect (Creio que o problema em não carregar os dados no momento em que é feito o login, possa estar contido nisso. Já que não vejo chamada alguma do LoadAccount ao player se conectar): 

Código PHP:
public OnPlayerConnect(playerid) {
    PlayerInfo[playerid][pLogado] = false;

    LoadBan(playerid);

    if(!strcmp(GetPlayerNameEx(playerid), "Ninguem")) return Kick(playerid);
    else if(IsTextIP(GetPlayerNameEx(playerid))) return Kick(playerid);

    LoadPlayerTextDraws(playerid);
    LoadPlayerProgressBars(playerid);
    PreloadAnimLibs(playerid);

    LoadSocialMediaMap(playerid);

    new Random random(MAX_SONGS), song[128];
    format(songsizeof(song), "%s"musicas[Random]);

    PlayAudioStreamForPlayer(playeridsong);
    return 1;


Att.: Em "mysql_format(Query, sizeof(Query), "SELECT * FROM tabela_players WHERE username = '%e' LIMIT 1", nome_player);", o que seria o "nome_player"? A variável responsável por armazenar o nick do jogador, tal como "PlayerInfo[playerid][pName]"?

Att-2: Creio ter entendido já. Provavelmente é uma forma de pegar o nick do player através do ID, que no meu caso seria "GetPlayerNameEx(playerid)", correto?



Esse código é meio estranho. o CreateAccount procura o player pra voltar dados do sql (sendo que a função é pra criar) e depois dá load? O loadaccount não vai funcionar o cache_... lá dentro por que tem que "enviar" esse cache com tquery.

Na att 1 e 2 - o "nome_player" é só um exemplo pro nome do player, você pode usar o que quiser lá dentro pra referenciar o nome do player, tal como o pName ou o NameEx. 

Recomendo fazer a query de procura de player (LoadAccount) no OnPlayerConnect, e dentro dela, se não tiver algum player (!cache_num_rows()), chamar a createAccount com um "insert into ..." usando mysql_tquery.

Pessoal, deixa stock pra lá ;-;, dêem uma olhada no meu antepenúltimo post aqui no tópico, pq ainda fiquei com dúvida ;-;


RE: Erros ao utilizar MySQL - pushline - 01/04/2024

Eu respondi rei Big Grin, só dar uma subida, se tiver duas respostas seguidas da mesma pessoa ela junta em uma só xD


RE: Erros ao utilizar MySQL - Ryzen_ - 01/04/2024

(01/04/2024 15:32)pushline Escreveu: Eu respondi rei Big Grin, só dar uma subida, se tiver duas respostas seguidas da mesma pessoa ela junta em uma só xD

Aaah. Não havia atualizado para mim ainda. Muito obrigado.

(01/04/2024 15:21)pushline Escreveu:
(01/04/2024 14:28)White_Blue Escreveu:
(01/04/2024 13:34)pushline Escreveu: Complementando o que o samuel falou, eu faria assim: (e não recomendo fazer stock pra funções já que stocks ocupam mais memória e só servem pra includes)

Código PHP:
new Query[255];
mysql_format(Querysizeof(Query), "SELECT * FROM tabela_players WHERE username = '%e' LIMIT 1"nome_player);
mysql_tquery(MYSQL_DEFAULT_HANDLEQuery"LoadAccount""i"playerid); // esse "i" podes acrescentar mais argumentos, tais como string ("s"), float ("f") e etc (array n passa se eu n me engano).

forward LoadAccount(playerid); // se fosse colocar no tquery "iii", teria que ter 3 parametros no forward + public.
public LoadAccount(playerid)

  if(!cache_num_rows())
  {
    return SendClientMessage(playerid, -1"Player inexistente.");
  }

  cache_get_value_int(0"ID"PlayerInfo[playerid][pID]);
  cache_get_value_name(0"Senha"PlayerInfo[playerid][pSenha]);
  cache_get_value_int(0"Level"PlayerInfo[playerid][pLevel]);
  cache_get_value_int(0"EXP"PlayerInfo[playerid][pExp]);
  cache_get_value_int(0"Dinheiro"PlayerInfo[playerid][pGrana]);
  cache_get_value_int(0"Saldo"PlayerInfo[playerid][pSaldo]);
  cache_get_value_int(0"Admin"PlayerInfo[playerid][pAdmin]);
  cache_get_value_float(0"PosX"PlayerInfo[playerid][pPosX]);
  cache_get_value_float(0"PosY"PlayerInfo[playerid][pPosY]);
  cache_get_value_float(0"PosZ"PlayerInfo[playerid][pPosZ]);
  cache_get_value_int(0"Sede"PlayerInfo[playerid][pSede]);
  cache_get_value_int(0"Fome"PlayerInfo[playerid][pFome]);
  cache_get_value_int(0"Sono"PlayerInfo[playerid][pSono]);
  cache_get_value_int(0"Sexo"PlayerInfo[playerid][pSkin]);
  cache_get_value_float(0"Vida"PlayerInfo[playerid][pVida]);
  cache_get_value_float(0"Colete"PlayerInfo[playerid][pColete]);
  return 1;


stock = funções (que tecnicamente é apenas uma palavra-chave para dizer para o compilador ignroar a função caso a mesma não for utilizada);
public = callbacks/eventos;

Se usa stock para funções e publics apenas devem ser usadas para eventos. Não é questão de memória.

Funções não precisam ser declaradas como stock. Geralmente só includes, caso a pessoa não chegue a usar todas
E stock realmente não consume memória! Acabei errando ao ler este artigo denovo: https://sampforum.blast.hk/showthread.php?tid=570635

(01/04/2024 13:46)Ryzen_ Escreveu:
(01/04/2024 13:34)pushline Escreveu: Complementando o que o samuel falou, eu faria assim: (e não recomendo fazer stock pra funções já que stocks ocupam mais memória e só servem pra includes)

Código PHP:
new Query[255];
mysql_format(Querysizeof(Query), "SELECT * FROM tabela_players WHERE username = '%e' LIMIT 1"nome_player);
mysql_tquery(MYSQL_DEFAULT_HANDLEQuery"LoadAccount""i"playerid); // esse "i" podes acrescentar mais argumentos, tais como string ("s"), float ("f") e etc (array n passa se eu n me engano).

forward LoadAccount(playerid); // se fosse colocar no tquery "iii", teria que ter 3 parametros no forward + public.
public LoadAccount(playerid)

  if(!cache_num_rows())
  {
    return SendClientMessage(playerid, -1"Player inexistente.");
  }

  cache_get_value_int(0"ID"PlayerInfo[playerid][pID]);
  cache_get_value_name(0"Senha"PlayerInfo[playerid][pSenha]);
  cache_get_value_int(0"Level"PlayerInfo[playerid][pLevel]);
  cache_get_value_int(0"EXP"PlayerInfo[playerid][pExp]);
  cache_get_value_int(0"Dinheiro"PlayerInfo[playerid][pGrana]);
  cache_get_value_int(0"Saldo"PlayerInfo[playerid][pSaldo]);
  cache_get_value_int(0"Admin"PlayerInfo[playerid][pAdmin]);
  cache_get_value_float(0"PosX"PlayerInfo[playerid][pPosX]);
  cache_get_value_float(0"PosY"PlayerInfo[playerid][pPosY]);
  cache_get_value_float(0"PosZ"PlayerInfo[playerid][pPosZ]);
  cache_get_value_int(0"Sede"PlayerInfo[playerid][pSede]);
  cache_get_value_int(0"Fome"PlayerInfo[playerid][pFome]);
  cache_get_value_int(0"Sono"PlayerInfo[playerid][pSono]);
  cache_get_value_int(0"Sexo"PlayerInfo[playerid][pSkin]);
  cache_get_value_float(0"Vida"PlayerInfo[playerid][pVida]);
  cache_get_value_float(0"Colete"PlayerInfo[playerid][pColete]);
  return 1;

Stock ocupa mais memória? Não sabia. Pelo que me foi dito, era recomendado utilizar publics apenas em callbacks, e fora delas, utilizar apenas a stock. Quem criou o sistema de LoadAccount foi um outro membro da equipe, pois partiu dele a decisão de ir do DOF2 para o MySQL (Apenas nas contas, os demais sistemas ficaram em DOF, tais como o sistema de clans). Obrigado pelas respostas Samuel e Pushline, me ajudou a dar uma clareada. O que o outro membro da equipe fez, se encontra atualmente dessa forma (Na função CreateAccount(), creio que também tenha algo de errado, podem verificar por favor? Também notei que ele usou mysql_query() nela):

Função LoadAccount() presente no arquivo "login.inc":
Código PHP:
stock LoadAccount(playerid) {
    //format(File, sizeof(File), PASTA_CONTAS, GetPlayerNameEx(playerid));

    SetCameraBehindPlayer(playerid);
    CancelSelectTextDraw(playerid);
    StopAudioStreamForPlayer(playerid);
    DeletePVar(playerid"hash");
    print("LoadAccount chamada");


    // HUD
    ShowPlayerGlobalHUDStats(playerid);
    ShowPlayerHUDStats(playerid);
    PlayerTextDrawShow(playeridrelogio[playerid]);
    ShowTextData(playerid);

    // Stats system
    SetPlayerProgressBarValue(playeridStatsBar[playerid][0], float(PlayerInfo[playerid][pFome]));
    SetPlayerProgressBarValue(playeridStatsBar[playerid][1], float(PlayerInfo[playerid][pSede]));
    SetPlayerProgressBarValue(playeridStatsBar[playerid][2], float(PlayerInfo[playerid][pSono]));


    // Timers
    TimerHunger[playerid] = SetTimerEx("HungerTimer"1200000true"i"playerid);
    TimerSono[playerid] = SetTimerEx("SonoTimer"2400000true"i"playerid);
    TimerSede[playerid] = SetTimerEx("SedeTimer"900000true"i"playerid);
    ClockTimer[playerid] = SetTimerEx("Clock"1000true"i"playerid);
    TimerSegundos[playerid] = SetTimerEx("AtualizarSegundos"1000true"i"playerid);
    SetTimerEx("SetPlayerCashInTime"1300false"ii"playeridGetPlayerCash(playerid));
    KillTimer(TimerExpirarLogin[playerid]);

    TogglePlayerSpectating(playeridfalse);
    SetSpawnInfo(playeridNO_TEAMPlayerInfo[playerid][pSkin], PlayerInfo[playerid][pPosX], PlayerInfo[playerid][pPosY], PlayerInfo[playerid][pPosZ], 0.3040WEAPON_FIST0WEAPON_FIST0WEAPON_FIST0);
    SpawnPlayer(playerid);
    SetPlayerScore(playeridPlayerInfo[playerid][pLevel]);
    SetPlayerJobColor(playeridGetPlayerJob(playerid));
    SetPlayerClanColor(playeridGetPlayerClan(playerid));

    SetPVarInt(playerid"exp"gettime());

    format(STRXsizeof(STRX), "%d"GetPlayerWanted(playerid));
    PlayerTextDrawSetString(playeridPlayerHUD[playerid][0], STRX);

    SetPVarInt(playerid"AFKUpdate"gettime());
    DeletePVar(playerid"unhashedpassword");
    PlayerInfo[playerid][pLogado] = true;
    SetPlayerSkin(playeridPlayerInfo[playerid][pSkin]);

    cache_get_value_int(0"ID"PlayerInfo[playerid][pID]);
    cache_get_value_name(0"Senha"PlayerInfo[playerid][pSenha]);
    cache_get_value_int(0"Level"PlayerInfo[playerid][pLevel]);
    cache_get_value_int(0"EXP"PlayerInfo[playerid][pExp]);
    cache_get_value_int(0"Dinheiro"PlayerInfo[playerid][pGrana]);
    cache_get_value_int(0"Saldo"PlayerInfo[playerid][pSaldo]);
    cache_get_value_int(0"Admin"PlayerInfo[playerid][pAdmin]);
    cache_get_value_float(0"PosX"PlayerInfo[playerid][pPosX]);
    cache_get_value_float(0"PosY"PlayerInfo[playerid][pPosY]);
    cache_get_value_float(0"PosZ"PlayerInfo[playerid][pPosZ]);
    cache_get_value_int(0"Sede"PlayerInfo[playerid][pSede]);
    cache_get_value_int(0"Fome"PlayerInfo[playerid][pFome]);
    cache_get_value_int(0"Sono"PlayerInfo[playerid][pSono]);
    cache_get_value_int(0"Sexo"PlayerInfo[playerid][pSkin]);
    cache_get_value_float(0"Vida"PlayerInfo[playerid][pVida]);
    cache_get_value_float(0"Colete"PlayerInfo[playerid][pColete]);
    
    
if(PlayerInfo[playerid][pInterior] > 0) {
        SetTimerEx("SetInterior"200false"i"playerid);
    }

    SetPlayerHealth(playeridPlayerInfo[playerid][pVida]);
    SetPlayerArmour(playeridPlayerInfo[playerid][pColete]);
    TogglePlayerControllable(playeridfalse);
    
    SetTimerEx
("DestogglePlayerControllable"300false"i"playerid);
    return 1;


Funções presentes no arquivo da GM:
Código PHP:
forward CreateAccount(playerid);
public 
CreateAccount(playerid) {
    new query[500], email[128];
    GetPVarString(playerid"unconfirmedemail"email);

    PlayerInfo[playerid][pID] = cache_insert_id();
    PlayerInfo[playerid][pLevel] = 0;
    PlayerInfo[playerid][pExp] = 0;
    PlayerInfo[playerid][pGrana] = 5000;
    PlayerInfo[playerid][pSaldo] = 0;
    PlayerInfo[playerid][pAdmin] = 0;
    PlayerInfo[playerid][pPosX] = 1154.4115;
    PlayerInfo[playerid][pPosY] = -1747.7765;
    PlayerInfo[playerid][pPosZ] = 13.5703;
    PlayerInfo[playerid][pFome] = 100;
    PlayerInfo[playerid][pSede] = 100;
    PlayerInfo[playerid][pSono] = 100;
    PlayerInfo[playerid][pVida] = 100.0;
    PlayerInfo[playerid][pColete] = 0.0;

    mysql_format(connquerysizeof(query), "SELECT * FROM jogadores WHERE ID='%i'"PlayerInfo[playerid][pID]);
    mysql_query(connquery);
    LoadAccount(playerid);
    
    
//DOF2_SetString(file, "Email", email);
    DeletePVar(playerid"unconfirmedemail");
    DeletePVar(playerid"hash");
    

    
print("CreateAccount Chamada");
    SetPlayerJob(playeridPROF_DESEMPREGADO);
    CancelSelectTextDraw(playerid);
    ShowPlayerDialog(playeridDIALOG_GENDERDIALOG_STYLE_MSGBOX"Gênero - Escolha seu Gênero""{FFFFFF}Escolha seu Gênero""Masculino""Feminino");
    return 1;
}

forward OnPassCheck(playerid);
public 
OnPassCheck(playerid) {
    if(bcrypt_is_equal()) {
        PlayerInfo[playerid][pLogado] = true;
        LoadAccount(playerid);
        SendClientMessage(playeridMarrom"| INFO | %s de volta, %s | Último login: %s"PlayerInfo[playerid][pSexo] ? "Bem-vindo" "Bem-vinda"GetPlayerNameEx(playerid), DOF2_GetString(File"UltimoLogin"));
    } else {
        PlayerInfo[playerid][pTentativas]++;
        SendClientMessage(playeridVermelho"| ERRO | Senha inválida");
    }
    return 1;


Função OnPlayerConnect (Creio que o problema em não carregar os dados no momento em que é feito o login, possa estar contido nisso. Já que não vejo chamada alguma do LoadAccount ao player se conectar): 

Código PHP:
public OnPlayerConnect(playerid) {
    PlayerInfo[playerid][pLogado] = false;

    LoadBan(playerid);

    if(!strcmp(GetPlayerNameEx(playerid), "Ninguem")) return Kick(playerid);
    else if(IsTextIP(GetPlayerNameEx(playerid))) return Kick(playerid);

    LoadPlayerTextDraws(playerid);
    LoadPlayerProgressBars(playerid);
    PreloadAnimLibs(playerid);

    LoadSocialMediaMap(playerid);

    new Random random(MAX_SONGS), song[128];
    format(songsizeof(song), "%s"musicas[Random]);

    PlayAudioStreamForPlayer(playeridsong);
    return 1;


Att.: Em "mysql_format(Query, sizeof(Query), "SELECT * FROM tabela_players WHERE username = '%e' LIMIT 1", nome_player);", o que seria o "nome_player"? A variável responsável por armazenar o nick do jogador, tal como "PlayerInfo[playerid][pName]"?

Att-2: Creio ter entendido já. Provavelmente é uma forma de pegar o nick do player através do ID, que no meu caso seria "GetPlayerNameEx(playerid)", correto?

Esse código é meio estranho. o CreateAccount procura o player pra voltar dados do sql (sendo que a função é pra criar) e depois dá load? O loadaccount não vai funcionar o cache_... lá dentro por que tem que "enviar" esse cache com tquery.

Na att 1 e 2 - o "nome_player" é só um exemplo pro nome do player, você pode usar o que quiser lá dentro pra referenciar o nome do player, tal como o pName ou o NameEx. 

Recomendo fazer a query de procura de player (LoadAccount) no OnPlayerConnect, e dentro dela, se não tiver algum player (!cache_num_rows()), chamar a createAccount com um "insert into ..." usando mysql_tquery.

Pelo que eu vi no código (Essa parte não foi feita por mim, do salvamento e carregamento. Antes era em DOF, mas o outro tá tentando alterar para MySQL), a CreateAccount() está dentro da OnPassHash(), que é chamada dentro da dialog de login após o player confirmar o sua senha. Creio que isso esteja correto, já que realmente os dados são inseridos na tabela normalmente. Os únicos erros que notei, é que ele não salva os dados do player após ele deslogar, assim como também não faz o Load corretamente. Irei passar novamente as funções responsáveis pelo salvamento e carregamento das contas, caso seja necessário (Todas estão em um arquivo chamado login.inc):

SaveAccount()
Código PHP:
stock SaveAccount(playerid) {
    new 
query[500];

    new 
Float:HealthFloat:Armour;
    
GetPlayerHealth(playeridHealth);
    
GetPlayerArmour(playeridArmour);

    
GetPlayerPos(playeridPlayerInfo[playerid][pPosX], PlayerInfo[playerid][pPosY], PlayerInfo[playerid][pPosZ]);

    
mysql_format(connquerysizeof(query), "UPDATE `jogadores` SET \
    `Level`='%i',\
    `EXP`='%i',\
    `Dinheiro`='%i',\
    `Saldo`='%i',\
    `Admin`='%i',\
    `Skin`='%i',\
    `PosX`='%f',\
    `PosY`='%f',\
    `PosZ`='%f',\
    `Sede`='%i',\
    `Fome`='%i',\
    `Sono`='%i',\
    `Vida`='%f',\
    `Colete`='%f',\
    `Dinamites`='%i',\
    `Contrato`='%i',\
    `ValorContrato`='%i',\
    `Organizacao`='%i',\
    `Cargo`='%i' WHERE `ID`='%i'"
,
    
PlayerInfo[playerid][pLevel],
    
PlayerInfo[playerid][pExp],
    
PlayerInfo[playerid][pGrana],
    
PlayerInfo[playerid][pSaldo],
    
PlayerInfo[playerid][pAdmin],
    
GetPlayerSkin(playerid),
    
PlayerInfo[playerid][pPosX],
    
PlayerInfo[playerid][pPosY],
    
PlayerInfo[playerid][pPosZ],
    
PlayerInfo[playerid][pSede],
    
PlayerInfo[playerid][pFome],
    
PlayerInfo[playerid][pSono],
    
Health,
    
Armour,
    
PlayerInfo[playerid][pEmprego],
    
PlayerInfo[playerid][pEmpregoCategoria],
    
PlayerInfo[playerid][pWantedLevel],
    
PlayerInfo[playerid][pTempoPreso],
    
PlayerInfo[playerid][pPreso],
    
PlayerInfo[playerid][pMutado],
    
PlayerInfo[playerid][pTempoMutado],
    
PlayerInfo[playerid][pDinamites],
    
PlayerInfo[playerid][CNHA],
    
PlayerInfo[playerid][CNHB],
    
PlayerInfo[playerid][CNHC],
    
PlayerInfo[playerid][pContrato],
    
PlayerInfo[playerid][pValorContrato],
    
PlayerInfo[playerid][pOrganizacao],
    
PlayerInfo[playerid][pCargo],
    
PlayerInfo[playerid][pID]);
    
mysql_query(connquery);

    
printf("[MYSQL] Dados do Jogador %s ID %d salvo com sucesso"GetPlayerNameEx(playerid), PlayerInfo[playerid][pID]);

    return 
1;


LoadAccount()
Código PHP:
stock LoadAccount(playerid) {
    
//format(File, sizeof(File), PASTA_CONTAS, GetPlayerNameEx(playerid));

    
SetCameraBehindPlayer(playerid);
    
CancelSelectTextDraw(playerid);
    
StopAudioStreamForPlayer(playerid);
    
DeletePVar(playerid"hash");
    print(
"LoadAccount chamada");


    
// HUD
    
ShowPlayerGlobalHUDStats(playerid);
    
ShowPlayerHUDStats(playerid);
    
PlayerTextDrawShow(playeridrelogio[playerid]);
    
ShowTextData(playerid);

    
// Stats system
    
SetPlayerProgressBarValue(playeridStatsBar[playerid][0], float(PlayerInfo[playerid][pFome]));
    
SetPlayerProgressBarValue(playeridStatsBar[playerid][1], float(PlayerInfo[playerid][pSede]));
    
SetPlayerProgressBarValue(playeridStatsBar[playerid][2], float(PlayerInfo[playerid][pSono]));


    
// Timers
    
TimerHunger[playerid] = SetTimerEx("HungerTimer"1200000true"i"playerid);
    
TimerSono[playerid] = SetTimerEx("SonoTimer"2400000true"i"playerid);
    
TimerSede[playerid] = SetTimerEx("SedeTimer"900000true"i"playerid);
    
ClockTimer[playerid] = SetTimerEx("Clock"1000true"i"playerid);
    
TimerSegundos[playerid] = SetTimerEx("AtualizarSegundos"1000true"i"playerid);
    
SetTimerEx("SetPlayerCashInTime"1300false"ii"playeridGetPlayerCash(playerid));
    
KillTimer(TimerExpirarLogin[playerid]);

    
TogglePlayerSpectating(playeridfalse);
    
SetSpawnInfo(playeridNO_TEAMPlayerInfo[playerid][pSkin], PlayerInfo[playerid][pPosX], PlayerInfo[playerid][pPosY], PlayerInfo[playerid][pPosZ], 0.3040WEAPON_FIST0WEAPON_FIST0WEAPON_FIST0);
    
SpawnPlayer(playerid);
    
SetPlayerScore(playeridPlayerInfo[playerid][pLevel]);
    
SetPlayerJobColor(playeridGetPlayerJob(playerid));
    
SetPlayerClanColor(playeridGetPlayerClan(playerid));

    
SetPVarInt(playerid"exp"gettime());

    
format(STRXsizeof(STRX), "%d"GetPlayerWanted(playerid));
    
PlayerTextDrawSetString(playeridPlayerHUD[playerid][0], STRX);

    
SetPVarInt(playerid"AFKUpdate"gettime());
    
DeletePVar(playerid"unhashedpassword");
    
PlayerInfo[playerid][pLogado] = true;
    
SetPlayerSkin(playeridPlayerInfo[playerid][pSkin]);

    
cache_get_value_int(0"ID"PlayerInfo[playerid][pID]);
    
cache_get_value_name(0"Senha"PlayerInfo[playerid][pSenha]);
    
cache_get_value_int(0"Level"PlayerInfo[playerid][pLevel]);
    
cache_get_value_int(0"EXP"PlayerInfo[playerid][pExp]);
    
cache_get_value_int(0"Dinheiro"PlayerInfo[playerid][pGrana]);
    
cache_get_value_int(0"Saldo"PlayerInfo[playerid][pSaldo]);
    
cache_get_value_int(0"Admin"PlayerInfo[playerid][pAdmin]);
    
cache_get_value_float(0"PosX"PlayerInfo[playerid][pPosX]);
    
cache_get_value_float(0"PosY"PlayerInfo[playerid][pPosY]);
    
cache_get_value_float(0"PosZ"PlayerInfo[playerid][pPosZ]);
    
cache_get_value_int(0"Sede"PlayerInfo[playerid][pSede]);
    
cache_get_value_int(0"Fome"PlayerInfo[playerid][pFome]);
    
cache_get_value_int(0"Sono"PlayerInfo[playerid][pSono]);
    
// cache_get_value_int(0, "Sexo", PlayerInfo[playerid][pSkin]);
    
cache_get_value_float(0"Vida"PlayerInfo[playerid][pVida]);
    
cache_get_value_float(0"Colete"PlayerInfo[playerid][pColete]);
    
    if(
PlayerInfo[playerid][pInterior] > 0) {
        
SetTimerEx("SetInterior"200false"i"playerid);
    }

    
SetPlayerHealth(playeridPlayerInfo[playerid][pVida]);
    
SetPlayerArmour(playeridPlayerInfo[playerid][pColete]);
    
TogglePlayerControllable(playeridfalse);
    
    
SetTimerEx("DestogglePlayerControllable"300false"i"playerid);
    return 
1;




RE: Erros ao utilizar MySQL - pushline - 01/04/2024

No saveaccount recomendo tirar as aspas ao redor dos especificadores (%i, %f) deixar só pra string (%e), mude para tquery também para não ter a possibilidade do servidor crashar caso a query demorar mais que 5 segundos (tem esse bug no samp/plugin q o sv crasha qnd uma query demora mais q 5s).

"assim como também não faz o Load corretamente." como assim?

A forma que eu faria esse login é assim:
procuro se tal player com X nome existe, se não existe, chama dialog registro -> salva conta -> spawna ou etc.
caso existir -> chama dialog login -> verifica se hash do bcrypt eh igual etc -> se logar -> load account -> chama spawn após load.