Jump to content

[SQLite] Crearea unui sistem de inregistrare/logare.


DarkyTheAngel

Recommended Posts

Salut.Am vazut ca Rimmon a inceput sa posteze cateva tutoriale despre SQLite, asa ca m-am gandit sa postez si eu un tutorial in care va arat cum sa faceti un sistem de inregistrare/logare pe SQLite.Prima data incepeti cu includerile.In cazul de fata, o sa folosesc doar fisierele a_samp.inc, zcmd.inc si YSI\y_ini.inc:

#include    "  a_samp  "

#include    "    zcmd  "

#include    " YSI\y_ini "

Acum ca am facut asta, o sa va intrebati de ce am adaugat si y_ini.L-am adaugat fiindca fisierul y_ini contine stock-ul strcpy iar ca sa nu il mai adaug in acest tutorial, am inclus y_ini.Ca sa fie mai usor de explicat si pentru a nu irosi ceva linii, o sa definesc dialog-urile si functile pe care le voi folosi in acest tutorial:

#define SPD                  ShowPlayerDialog

#define SCM                  SendClientMessage

#define DIALOG_REGISTER      ( 2012 )

#define DIALOG_LOGIN          ( 2013 )

#define isnull(%1)            ((!(%1[0])) || (((%1[0]) == '\1') && (!(%1[1]))))

Acum ca am facut si asta, trebuie sa facem si datele jucatorului (new-urile):

enum PlayerData

{

    Nume [ MAX_PLAYER_NAME ]  ,

    Bani                      ,

    Scor                      ,

    Ucideri                    ,

    Decese

} ;

new

        P_DATA      [ MAX_PLAYERS ] [ PlayerData ] ,

        bool: Logat [ MAX_PLAYERS ]                ,

        DB:Conturi

;

Daca a-ti facut toate astea, putem trece la urmatorul pas, acesta fiind pasul care tine de baza de date:

public OnFilterScriptInit ( )

{

new

string [  756  ]

;

Conturi = db_open ( "Conturi.db" ) ;

strcat ( string , "CREATE TABLE IF NOT EXISTS `Jucatori`"  ,    756 ) ;

strcat ( string , "(`ID` INTEGER PRIMARY KEY AUTOINCREMENT            ,\

        `Nume`                            TEXT            ,\

          `Parola`                          TEXT            ,\

                      `Bani`                        NUMERIC            ,\

                      `Scor`                        NUMERIC , " , 756 ) ;

strcat ( string ,  "`Ucideri`                      NUMERIC            ,\

                      `Decese`                      NUMERIC ) " , 756 ) ;

db_free_result ( db_query ( Conturi , string ) ) ;

return ( 1 ) ;

}

Daca vreti sa faceti sistemul de inregistrare in modul de joc, schimbati OnFilterScriptInit cu OnGameModeInit.La acest "callback", se va crea baza de date/se va deschide baza de date.Pentru a functiona corect, la final cand modul de joc/scriptul se inchide, trebuie sa inchideti si baza de date:

public OnFilterScriptExit ( )

{

db_close ( Conturi ) ;

return ( 1 ) ;

}

Aici povestea se repeta.Schimbati OnFilterScriptExit cu OnGameModeExit daca aveti "gamemode" si nu "filterscript".Acum ca am facut si baza de date, trebuie sa facem ca atunci cand un jucator se conecteaza, sa ii apara dialogul de inregistrare/logare.Cum facem asta? Simplu.La "callback"-ul OnPlayerConnect trebuie sa verificam daca jucatorul exista in baza de date sau nu:

public OnPlayerConnect ( playerid )

{

new

  Query [  256          ] ,

        pNume [ MAX_PLAYER_NAME ] ,

        DBResult:Result

;

Logat  [ playerid ] = false ;

GetPlayerName ( playerid , pNume , MAX_PLAYER_NAME ) ;

strcpy ( P_DATA [ playerid ] [ Nume ] , DB_Escape ( pNume ) , MAX_PLAYER_NAME ) ;

format ( Query , 256 , "SELECT * FROM `Jucatori` WHERE `Nume` = '%s'" , P_DATA [ playerid ] [ Nume ] ) ;

Result = db_query ( Conturi , Query ) ;

if ( db_num_rows ( Result ) > 0 )

SPD ( playerid , DIALOG_LOGIN , DIALOG_STYLE_PASSWORD , "Logheaza-te" , "Introdu parola in casuta de mai jos:" , "O.K" , "" ) ;

else

SPD ( playerid , DIALOG_REGISTER , DIALOG_STYLE_PASSWORD , "Inregistreaza-te" , "Introdu parola in casuta de mai jos:" , "O.K" , "" ) ;

db_free_result ( Result ) ;

return ( 1 ) ;

}

Acum ca am trecut si de acest pas cu succes, trebuie sa facem ca atunci cand jucatorul se deconecteaza, sa ii se salveze datele.Presupun ca va intrebati "CUM?!" deci am sa va arat cum se poate face asta.Prima data trebuie sa verificam daca jucatorul este logat (de asta se ocupa "bool: Logat"):

public OnPlayerDisconnect ( playerid , reason )

{

if ( Logat [ playerid ] )

{

new

Query [  256  ]

;

format ( Query , sizeof ( Query ) , "UPDATE `Jucatori` SET `Bani` = '%d' ,`Scor` = '%d' , `Ucideri` = '%d' , `Decese` = '%d' WHERE `Nume` = '%s'"

  , GetPlayerMoney ( playerid ) , GetPlayerScore ( playerid ) , P_DATA [ playerid ] [ Ucideri ] , P_DATA [ playerid ] [ Decese ] , P_DATA [ playerid ] [ Nume ] ) ;

db_free_result ( db_query ( Conturi , Query ) ) ;

}

return ( 1 ) ;

}

Acum se salveaza datele jucatorului.Trebuie sa mai facem si "Uciderile" si "Decesele" jucatorului.Pentru a realiza acest lucru, avem nevoie de public-ul (callback-ul) OnPlayerDeath:

public OnPlayerDeath ( playerid , killerid , reason )

{

P_DATA [ playerid ] [ Decese ] ++ ;

if ( killerid != INVALID_PLAYER_ID )

{

P_DATA [ killerid ] [ Ucideri ] ++ ;

}

return ( 1 ) ;

}

Dupa ce am facut si asta, cred ca trebuie sa facem si ultimul pas (pasul final), cel care consta il salvarea si generarea datelor jucatorului.Pentru a realiza asta, ne vom folosi de public-ul OnDialogResponse.Folosindune de acesta, vom mai verifica daca parola introdusa este corecta/gresita sau daca parola introdusa de jucator este "null" adica daca jucatorul nu a introdus nimic:

public OnDialogResponse ( playerid , dialogid , response , listitem , inputtext [ ] )

{

if ( dialogid == DIALOG_REGISTER )

{

if ( !response || isnull(inputtext ) ) return SPD ( playerid , DIALOG_REGISTER , DIALOG_STYLE_PASSWORD , "Inregistreaza-te" , "Introdu parola in casuta de mai jos:" , "O.K" , "" ) ;

new

Query [  256  ]

;

format ( Query , sizeof ( Query ) , "INSERT INTO `Jucatori` ( `Nume` , `Parola` , `Bani` , `Scor` , `Ucideri` , `Decese` ) VALUES ( '%s' , '%s' , '%d' , '%d' , '%d' , '%d' )"

, P_DATA [ playerid ] [ Nume ] , DB_Escape ( inputtext ) , 0 , 0 , 0 , 0 ) ;

db_free_result ( db_query ( Conturi , Query ) ) ;

SCM ( playerid , -1 , "Te-ai inregistrat cu succes." ) ;

Logat [ playerid ] = true ;

return ( 1 ) ;

}

if ( dialogid == DIALOG_LOGIN )

{

if ( !response || isnull ( inputtext ) ) return SPD ( playerid , DIALOG_LOGIN , DIALOG_STYLE_PASSWORD , "Logheaza-te" , "Introdu parola in casuta de mai jos:" , "O.K" , "" ) ;

new

Query  [  256  ] ,

        DBResult:Result

;

format ( Query , sizeof ( Query ) , "SELECT `Bani` , `Scor` , `Ucideri` , `Decese` FROM `Jucatori` WHERE `Nume` = '%s' AND `Parola` = '%s'"

  , P_DATA [ playerid ] [ Nume ] , DB_Escape ( inputtext ) ) ;

Result = db_query ( Conturi , Query ) ;

if ( db_num_rows ( Result ) )

{

new

Field [  30  ]

;

db_get_field_assoc ( Result , "Bani" , Field , 30 ) ;

P_DATA [ playerid ] [ Bani ] = strval ( Field ) ;

ResetPlayerMoney ( playerid ) ;

GivePlayerMoney ( playerid , strval ( Field ) ) ;

db_get_field_assoc ( Result , "Scor" , Field , 30 ) ;

P_DATA [ playerid ] [ Scor ] = strval ( Field ) ;

SetPlayerScore ( playerid , strval ( Field ) ) ;

db_get_field_assoc ( Result , "Ucideri" , Field , 30 ) ;

P_DATA [ playerid ] [ Ucideri ] = strval ( Field ) ;

db_get_field_assoc ( Result , "Decese" , Field , 30 ) ;

P_DATA [ playerid ] [ Decese ] = strval(Field);

Logat [ playerid ] = true ;

}

else

{

SPD ( playerid , DIALOG_LOGIN , DIALOG_STYLE_PASSWORD , "Logheaza-te" , "Parola gresita.Introdu parola in casuta de mai jos:" , "O.K" , "" ) ;

}

db_free_result ( Result ) ;

return ( 1 ) ;

}

return ( 0 ) ;

}

Cam asta a fost tot.Dar, ca sa nu primiti erori la compilare, adaugati stock-ul DB_Escape la final de script:

stock DB_Escape ( text [] )

{

new

ret[ MAX_INI_ENTRY_TEXT * 2 ] ,

ch                            ,

i                            ,

j

;

while ( ( ch = text [ i++ ] ) && j < sizeof ( ret ) )

{

if ( ch == '\'' )

{

if  ( j < sizeof ( ret ) - 2 )

{

ret [ j++ ] = '\'' ;

ret [ j++ ] = '\'' ;

}

}

else if ( j < sizeof ( ret ) )

{

ret [ j++ ] = ch ;

}

else

{

j++ ;

}

}

ret [ sizeof ( ret ) - 1 ] = '\0' ;

return ret ;

}

Daca a-ti urmat toti pasii corect (de la cap la coada) ar trebuii sa functioneze corect sistemul de inregistrare/logare.O zi buna!

Link to comment
Share on other sites

Anakin" post="138239" timestamp="1365257464"]

Mda ....

Altu care face pentru RESPECT !

Nu imi spune tu ca nu aveai de lucrat la CS Sau sa faci orice altceva !

Un tutorial destul de bun , printre cele mai bune .

Eu nu fac fiindca se folosesc toti de el si se lauda ca ii facut de ei sau din alte motive nu de lene :P

Ok dar un tutorial tot puteai sa faci, acolo chiar ca nu trebuie credite. Si e normal sa se foloseasca un incepator de tutoriale, deoarece asa se dezvolta in pawn

 

1859311972_BANNER-GIREADAcopy-min.thumb.png.48e5e420ae2185dce5b244965a1d2601.png

 

Link to comment
Share on other sites

Ok dar un tutorial tot puteai sa faci, acolo chiar ca nu trebuie credite. Si e normal sa se foloseasca un incepator de tutoriale, deoarece asa se dezvolta in pawn

Serios .

Nu stiu pe nimeni decat un amic care vrea sa invete serios pawn dar unii nu vor sa invete .

Degeaba faci un tut ca el tot nu intelege si daca are o problema tot nu se uita la acel tut el o vrea rezolvata pe a lui nu sa ia exemplu si sa rezolve ei ci tu xD

idiots.png
Link to comment
Share on other sites

  • 1 month later...
  • 3 weeks later...

De fapt, "DB_Escape" e o functie care filtreaza un string, pentru a feri scriptul de SQL injection, nu e pus acolo doar "ca sa nu dea erori la compilare". E cam acelasi lucru cu mysql_real_escape_string(params), doar ca stock-ul asta e mult mai slab.

In al doilea rand, tu salvezi datele jucatorului la OnPlayerDisconnect cu GetPlayerMoney(params) si GetPlayerScore(params) ceea ce nu-i indicat deloc pentru ca datele astea sunt luate din memoria calculatorului fiecarui jucator. Si e foarte usor sa gasesti o adresa de memorie si sa-i schimbi valoarea.

Cam aiurea indentarea, dar asta nu conteaza...fiecare cu gusturile lui in programare.

In rest, e destul de ok.

Link to comment
Share on other sites

  • 8 months later...
  • 3 weeks later...

Incearca si tu sa faci gandestete in pula mea cand m-am apucat eu de scripting nimeni nu vroia sa ma ajute si am inceput sa invat singur sa incerc unele chesti mai complicate care m-am gandit sa le postez sau sa fac niste tutoriale au fost pentru faptul ca eu am muncit o gramada ca sa le fac si nu am vrut ca si alti sa munceasca atata  dar nah asta a fost o prostie de asta acuma in samp toti stiu mysql etc etc pentru ca alti care stiau i-au invatat le-au dat scripturi mur in gura . Ori si cum acuma in samp toti ratati au servere deschise RPG ( GF Edit ) toti sunt scripteri mari scripteri ma scuzati ca se dau ei mari ca nush ce au plm , prostesc copii de 12 ani sa fure bani de la parinti sa le doneze lor ca sa le dea o masina bag pula . De curand am inceput sa invat functiile orm am inceput cu incetu m-am uitat pe wiki mi-am facut un system de L/R care credca am sa-l postez ma mai gandesc . Ce sa zic puneti mana si invatati , incercati si ganditiva cum ar trebui unele lucruri aranjate in asa fel ca sa va dea rezultatul dorit . MUNCA MUNCA SI IAR MUNCA !

Link to comment
Share on other sites

  • 1 month later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • 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.