_[G]M[K]_Sh1ft_

[TUT] MySQL Register/Login rendszer

7 hozzászólás ebben a témában

Sziasztok!

Ma készültem nektek egy kis bemutatóval, hogy hogyan lehet készíteni egy bejelentkező/regisztrációs rendszert, ami MySQL-en alapul. Ez menteni fogja a játékos pénzét, pontját, halálait, öléseit. Valamint a felhasználóknak lesz egy lejárati dátumuk is, mely után a rendszer törölni fogja őket. Nos hogy ezt megvalósítsuk erre 2 (vagy több) mód is létezik. Ezt időközben el fogom mondani.

Előkészületek:

Szükségünk lesz egy MySQL és egy sscanf pluginra.

<a href="http://forum.sa-mp.com/showthread.php?t=122983">MySQL Plugin</a>

Direkt link windows felhasználóknak <a href="http://files.g-stylezzz.com/mysql/rel/R6/windows/plugin-R6-win32_vs9.rar">KATT</a>

Direkt link linux felhasználóknak <a href="http://files.g-stylezzz.com/mysql/rel/R6/debian5/mysql.so">KATT</a>

<a href="https://dl.dropboxusercontent.com/u/102595204/sscanf-2.8.2.zip">sscanf Plugin</a>

Valamint ugye szükséged lesz egy MySQL adatbázisra amit phpmyadmin segítségével webes felületen elérhetsz.

Rendben most elvileg meg van mindenünk és hozzá is kezdhetünk!

Első lépés: - Táblázat létrehozása az adatbázisunkban

image.png

image.png

<a href="http://s23.postimg.org/btn76vly3/image.png">Kép teljes méretben</a>

Vagy választasz egy adatbázist > SQL menüpont > Kódot beilleszted > Indít

CREATE TABLE IF NOT EXISTS `users` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `Username` varchar(32) NOT NULL,
  `Password` varchar(32) NOT NULL,
  `Score` int(11) NOT NULL DEFAULT '0',
  `Money` int(16) NOT NULL DEFAULT '150000',
  `Kills` int(16) NOT NULL DEFAULT '0',
  `Deaths` int(16) NOT NULL DEFAULT '0',
  `ExpirationDate` date NOT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

Most lett egy táblázatunk:

image.png

<a href="http://s14.postimg.org/7z5rt9sup/image.png">Kép teljes méretben</a>

Második lépés: - A "scriptelés"

!Ne felejtsük hozzáadni a script elejéhez: #include <a_mysql> és #include <sscanf2>

Mielőtt hozzá kezdünk definiáljunk pár dolgot csak a rend kedvéért! :D

#define mysql_host "SzerverIPje"
#define mysql_user "MySQL_Felhasználóneved"
#define mysql_database "Adatbázisod_neve"
#define mysql_password "MySQL_Jelszód"

Most az OnGameModeInit() vagy az OnFilterScriptInit() alá írjuk be a következő sorokat:

mysql_debug(1);//Erre nincs szükséged, de ha hiba merül fel akkor a szervered mappájában Debug.txt fájl alatt utána tudsz nézni
mysql_connect(mysql_host,mysql_user,mysql_database ,mysql_password);

Most elvileg sikeresen „csatlakoztunk” az adatbázisunkhoz.

Tökéletes! Most csekkoljuk le, hogy ha egy felhasználó fellép, az szerepel-e az adatbázisunkban. Majd az eredmények megfelelően, hozzon elő egy dialógust mely megkéri, hogy regisztráljon vagy jelentkezzen be, ha regisztrálva van.

public OnPlayerConnect(playerid)
{
   new Query[80],string[164];
   format(Query,sizeof(Query),"SELECT `Username` FROM `users` WHERE `Username` = '%s' LIMIT 1;",pName(playerid));
   mysql_query(Query);//Elküldjük a "kérésünket" a szerver felé
   mysql_store_result();//Majd eltároljuk az eredményt
   if(mysql_num_rows() != 0)//Ezzel a feltétellel megkérdeztük, hogy van-e már adat a felhasználónkról.
   {//És ha van ez történik:
      format(string,sizeof(string),"Ezzel a felhasználónévvel már regisztráltak.\nKérlek add meg a jelszavad!");
      ShowPlayerDialog(playerid,0,DIALOG_STYLE_INPUT,"Bejelentkezés", string,"Login","");
   }
   else
   {//Ha nincs akkor ez
      format(string,sizeof(string),"Még nem regisztráltak ezzel a felhasználónévvel.\nKérlek adj meg egy jelszót!");
      ShowPlayerDialog(playerid,1,DIALOG_STYLE_INPUT,"Regisztráció", string,"Register","");
   }
   mysql_free_result();
   return 1;
}

Remek ezzel is megvolnánk. Most készítsük el az űrlap(dialógus) feldolgozását:

public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
    if(dialogid == 0)
   {
      new Query[256],EscapedStr[32];
      mysql_real_escape_string(inputtext, EscapedStr);//Ennek segítségével megakadályozzuk azt hogy kárt tehessenek az adatbázisunkban.
      //A speciális karaktereket ki Eszképeli (kiveszi) pl: az aposztróf elé rak egy '\' jelet lásd: \'. Hogy miért hasznos? Nos, ha ez nem lenne
      //akkor aki ért hozzá, nagy károkat tudna csinálni. (Azt hogy hogyan lehet nem áll módomban elmondani)
      format(Query,sizeof(Query),"SELECT * FROM `users` WHERE `Username` = '%s' AND `Password` = '%s'",pName(playerid),EscapedStr);
      mysql_query(Query);
      mysql_store_result();
      if(mysql_num_rows() != 0)//művelet eredménye
      {
         SendClientMessage(playerid,-1,"Sikeresen bejelentkeztél!!");
         LoadStats(playerid);
      }
      else
      {
         //SendClientMessage(playerid,-1,"Rossz jelszó!");
         Kick(playerid);
      }
      mysql_free_result();
   }
   if(dialogid == 1)
   {
      if(strlen(inputtext) == 0)
      {
         ShowPlayerDialog(playerid,1,DIALOG_STYLE_INPUT,"Regisztráció","Kérlek adj meg egy jelszót!","Register!","");
      }
      else
      {
          //Lejárati dátum megadása
          new Year, Month, Day;
          getdate(Year, Month, Day);
          new CD[32];
          if(Month == 12) {
              format(CD,sizeof(CD),"%d-01-%02d", Year+1, Day);
          }
          else {
             format(CD,sizeof(CD),"%d-%02d-%02d", Year, Month+1, Day);
          }
          //Lejárati dátum értéke most: Regisztrálás dátuma +1 hónap

          
          new Query[256];
         new EscapedText[60];
         mysql_real_escape_string(inputtext, EscapedText);
         format(Query,sizeof(Query),"INSERT INTO `users` (Username,Password,ExpirationDate) VALUES ('%s','%s','%s')",pName(playerid),EscapedText,CD);
         mysql_query(Query);//Most feltöltjük az adatokat az adatbázis users táblázatába. (ami nincs megadva, akkor annak az értéke egyenlő lesz azzal
         //amit megadtunk, mint automatikus érték)
         SendClientMessage(playerid,-1,"Sikeresen regisztráltál!");
         LoadStats(playerid);//Adatok bekérése
      }
   }
   return 0;
}

Még mielőtt folytatnánk, hozzunk létre változókat a felhasználó számára.

Írjuk a mód elejére:

enum PlayerData
{
   ID,Username[32],Password[32],Score,Money,Kills,Deaths,ExpirationDate[16]
}
new PlayerInfo[MAX_PLAYERS][PlayerData];

Következő lépésben „értelmet” adunk a pName és a LoadStats parancsunknak/függvényünknek.

stock LoadStats(playerid)
{
   new Query[256];
   format(Query, sizeof(Query), "SELECT * FROM `users` WHERE `Username` = '%s' ", pName(playerid));
   mysql_query(Query);
   
   mysql_store_result();
   mysql_fetch_row_format(Query, "|");
   sscanf(Query, "e<p<|>is[32]s[32]iiiis[16]>", PlayerInfo[playerid]);//Érték adás az adatbázistól kapott adatok alapján, abban a sorrenben
   //ahogy az enumoknál adtuk meg.
   mysql_free_result();
   //Értékek felhasználása
   GivePlayerMoney(playerid,PlayerInfo[playerid][Money]);
   SetPlayerScore(playerid,PlayerInfo[playerid][score]);
   return 1;
}
stock pName(playerid)
{
   new name[MAX_PLAYER_NAME];
   GetPlayerName(playerid, name, sizeof(name));
   return name;
}

Ez most szép és jó, de hát ha változás történt a felhasználónkkal azt nem menti a kilépésekor :'(

-Most akkor mit is szeretnénk csinálni?

-Szeretnénk menteni a pontját, pénzét, öléseit, halálait, no meg, meg kéne valahogy hosszabbítani a "lejárati dátum"-ot

A kód:

public OnPlayerDisconnect(playerid,reason)
{
    new Year, Month, Day;
   getdate(Year, Month, Day);
    new CD[32];
    if(Month == 12) {
        format(CD,sizeof(CD),"%d-01-%02d", Year+1, Day);
    }
    else {
       format(CD,sizeof(CD),"%d-%02d-%02d", Year, Month+1, Day);
    }
   new Query[256];
    format(Query, sizeof(Query), "UPDATE users SET Score = %d, Money = %d, Kills = %d, Deaths = %d, ExpirationDate = '%s' WHERE Username='%s'",
   GetPlayerScore(playerid),GetPlayerMoney(playerid),PlayerInfo[playerid][Kills],PlayerInfo[playerid][Deaths],CD,pName(playerid));
    mysql_query(Query);
   return 1;
}

Harmadik lépés: - Feladat ütemezés/Esemény hozzáadása

Rendben most van egy scriptünk, ami adatokat kér és közöl az adatbázissal. Ha jól látom most minden tökéletes, kivéve a „lejárati dátumot”. Mivel hiába van, az ott nekünk, még nem csinál semmit :(

Ezért most kattintsunk az adatbázisunk nevére > SQL menüpont és illesszük be a következő kódot:

SET GLOBAL event_scheduler = ON;
CREATE EVENT myevent
    ON SCHEDULE
      EVERY 6 HOUR
    COMMENT 'Inaktiv felhasznalok torlese'
    DO
      DELETE FROM `adatbazisneve`.`users` WHERE `users`.`ExpirationDate` < CURDATE();

Eredmény:

image.png

<a href="http://s17.postimg.org/z5lbf5qen/image.png">Kép teljes méretben</a>

- Ez most mire volt jó?

- Létrehoztunk egy eseményt mely ismétlődni fog minden hatodik órában. (Persze ezt át írhatod)

- Mi is tulajdonképpen ez az esemény?

- Ugye ez szépen lefut nekünk minden hatodik órában, majd szépen törli az olyan felhasználók adatait melyeknek a "lejárati dátuma" kisebb mint a mai.

Példa:

Mai dátum: 2015-09-19

Géza lejárati dátuma: 2015-09-18 Törlődni fog? IGEN

Gizi lejárati dátuma: 2015-09-19 Törlődni fog? NEM

Hát igen itt van a bibi, ha nincs jogosultságod ilyenre.

Hogy mit tehetsz ez ügyben? A szolgáltató vagy a rendszer gazda felé fordulsz, hogy szeretnél létrehozni egy ilyen eseményt/időzítőt a rendszerben, ami lefut bizonyos időközönként.

Ha ez nem lehetséges, ugye úgy kezdtem, hogy erre több mód is van. Nos a másik mód az lenne , hogy a scriptben egy időzítő segítségével vagy egy függvény segítségével lefutatjuk ezt a sort:

DELETE FROM ` adatbazisneve `.`users` WHERE `users`.`ExpirationDate` < CURDATE();

>>>

new Query[256];
format(Query, sizeof(Query), " DELETE FROM ` adatbazisneve `.`users` WHERE `users`.`ExpirationDate` < CURDATE();”);
mysql_query(Query);

Remélem nem felejtettem ki semmit, használjátok egészséggel!  :thumbsup:

Valamint a kérdéseiteket vagy ha bármiféle problémátok lenne bátran jelezzétek kommentben!

Vélemény?

Ez az első tutorialom, remélem nem szúrtam el nagyon és érthető voltam. Nem azt mondom hogy nézzétek el a hibáim(de remélem nincs :D), mert akkor miért is raktam ezt ki?

További jó fórumozást és szép napot!

_[G]M[K]_Sh1ft_

1 személy kedveli ezt

Megosztás


Megosztás link alapján
Megosztás egy közösségi oldalon

Nem a bites cuccrol van szó, hanem arról h ez még két vagy három évvel ezelőtti pluginokkal működik. Az ujjal egyáltalán nem

Megosztás


Megosztás link alapján
Megosztás egy közösségi oldalon

Nem a bites cuccrol van szó, hanem arról h ez még két vagy három évvel ezelőtti pluginokkal működik. Az ujjal egyáltalán nem

Ezt egy kicsit bővebben kitudnád nekem fejteni mire gondolsz?

(milyen új pluginok?)

Megosztás


Megosztás link alapján
Megosztás egy közösségi oldalon
M[K]_Sh1ft_" post="566808" timestamp="1452893939"]

Nem a bites cuccrol van szó, hanem arról h ez még két vagy három évvel ezelőtti pluginokkal működik. Az ujjal egyáltalán nem

Ezt egy kicsit bővebben kitudnád nekem fejteni mire gondolsz?

(milyen új pluginok?)

https://github.com/pBlueG/SA-MP-MySQL/releases

Megosztás


Megosztás link alapján
Megosztás egy közösségi oldalon
Vendég
A téma le van zárva, így nem szólhatsz hozzá!