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
<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:
<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!
#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:
<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.
« Válasz #1 Dátum: 2015. október 29. - 14:21:08 »
+1
Még egy ide-oda pakolgatós \"leírás\".
Naplózva
« Válasz #2 Dátum: 2016. január 11. - 03:44:12 »
0
NEMROSSZBÚÚÚÚÚÚÚÚÚÚÚ... DE EZ ECSEPET ÖREG.
Naplózva
« Válasz #3 Dátum: 2016. január 11. - 05:53:54 »
0
A bites cuccot mi nemtudjuk felfogni.
Naplózva
« Válasz #4 Dátum: 2016. január 11. - 14:07:02 »
0
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
Naplózva
« Válasz #5 Dátum: 2016. január 15. - 22:38:59 »
0
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?)
Naplózva
« Válasz #6 Dátum: 2016. január 15. - 23:10:41 »
0
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
[/quote]
Ezt egy kicsit bővebben kitudnád nekem fejteni mire gondolsz?
(milyen új pluginok?)
[/quote]
https://github.com/pBlueG/SA-MP-MySQL/releases
Naplózva