13.01.2019, 13:12
Hi, some days ago I was thinking if is possible connect a database mysql to samp, like create a register, login and a load stats system for the users, is that possible? And if it is, how?
I have made a very detailed Tutorial in the German community concerning a Register/Login System based on MySQL:
https://breadfish.de/index.php?threa...ations-system/ I'm sure you'll get along with it, even without speaking German. If required, use the translation feature of Chrome for example. JustMe.77 used the Tutorial to release a Filterscript with nice Textdraws, as a "ready to use" version: https://sampforum.blast.hk/showthread.php?pid=3911490#pid3911490 You might also go along with this, if you do not want to go through the Tutorial completely. |
echo Executing Server Config... lanmode 0 rcon_password passwword maxplayers 50 port 7777 hostname SA-MP 0.3 Server gamemode0 rpgm 1 filterscripts beispiel plugins sscanf mysql announce 0 chatlogging 0 weburl www.sa-mp.com onfoot_rate 40 incar_rate 40 weapon_rate 40 stream_distance 300.0 stream_rate 1000 maxnpc 0 logtimeformat [%H:%M:%S] language English
---------- Loaded log file: "server_log.txt". ---------- SA-MP Dedicated Server ---------------------- v0.3.7-R2, ©2005-2015 SA-MP Team Server Plugins -------------- Loading plugin: sscanf =============================== sscanf plugin loaded. Version: 2.8.3 © 2018 Alex "Y_Less" Cole =============================== Loaded. Loading plugin: mysql Failed. Loaded 1 plugins. Ban list -------- Loaded: samp.ban Started server on port: 7777, with maxplayers: 50 lanmode is OFF. Filterscripts --------------- Loading filterscript 'beispiel.amx'... Loaded 1 filterscripts. ---------------------------------- Blank Gamemode by your name here ---------------------------------- Number of vehicle models: 0
#include <bcrypt> //https://sampforum.blast.hk/showthread.php?tid=453544
#include <easyDialog> //https://sampforum.blast.hk/showthread.php?tid=475838
#define BCRYPT_COST 12
#define easyDialogParams response, listitem, inputtext[]
enum playerStatsVars{
Name[24],
bool:LoggedIn
};
new pStats[MAX_PLAYERS][playerStatsVars];
//for delayed kick message
KickEx(playerid,msg[120]){
SendClientMessage(playerid,-1,msg);
return SetTimerEx("callKick",100,false,"d",playerid);
}
forward callKick(playerid);
public callKick(playerid){
return Kick(playerid);
}
//getting username
getUserName(playerid){
new s[24];
GetPlayerName(playerid,s,24);
return s;
}
//this must be added under onplayerconnect for example
Dialog_Show(playerid, RegisterPlayer, DIALOG_STYLE_PASSWORD, "account registration", "account with such name doesn't exsist.\nfor registration enter password.", "register", "close");
//makes dialog creation easier
Dialog:RegisterPlayer(playerid,easyDialogParams){
if(!response){
return KickEx(playerid,"you selected close option.");
}
if(!(6<=strlen(inputtext)<=30)){
SendClientMessage(playerid,-1,"password must be between 6 to 30!");
return 1;
}
//hashing password
bcrypt_hash(inputtext, BCRYPT_COST, "RegisterPlayer", "d", playerid);
return 1;
}
//thread from password bcrypt
forward RegisterPlayer(playerid);
public RegisterPlayer(playerid){
//copies player name into array, so you don't need to call GetPlayerName, native functions are slower then variables
strmid(pStats[playerid][Name],getUserName(playerid),0,24,24);
new s[400];
//no need to escape string, because user input isnt insert here
format(s,400,"insert into player_account(username,password) values('%s','%s')",pStats[playerid][Name],password);
mysql_tquery(serverCon,s,"threadRegisterPlayer","d",playerid);
return 1;
}
//thread from database
forward threadRegisterPlayer(playerid);
public threadRegisterPlayer(playerid){
SendClientMessage(playerid,-1,"account registered.");
pStats[playerid][LoggedIn]=true;
return 1;
}
Great to hear!
You can add new stats by adding them to: 1. The MySQL Database Table "users" with phpMyAdmin 2. Add the variables to pDataEnum 3. Reset them at OnPlayerConnect 4. Load them in OnUserLogin using cache_get_value_name for Strings or cache_get_value_name_int for Integers 5. Save them at SaveUserStats |
pEmail,
pEmail[64],
PlayerInfo[playerid][pEmail] = 0;
PlayerInfo[playerid][pEmail] = "";
cache_get_value_name(0, "email", PlayerInfo[playerid][pEmail]);
cache_get_value_name(0, "email", PlayerInfo[playerid][pEmail],64);
new playeremail = PlayerInfo[playerid][pEmail];
new playeremail[64]; format(playeremail, 64, PlayerInfo[playerid][pEmail]);
mysql_format(handle, query, sizeof(query), "UPDATE users SET email = '%d', level = '%d', admin = '%d', money = '%d', kills = '%d', deaths = '%d' WHERE id = '%d'", playeremail, livello, adminl, soldi, uccisioni, morti, idgiocatore);
mysql_format(handle, query, sizeof(query), "UPDATE users SET email = '%s', level = '%d', admin = '%d', money = '%d', kills = '%d', deaths = '%d' WHERE id = '%d'", playeremail, livello, adminl, soldi, uccisioni, morti, idgiocatore);
C:\Users\ouday\OneDrive\Desktop\Giochi\samp\samp rp\samp03DL_svr_R1_win32\gamemodes\gamemoderp.pwn(239) : error 047: array sizes do not match, or destination array is too small Pawn compiler 3.2.3664 Copyright © 1997-2006, ITB CompuPhase 1 Error.
Change the following:
Code:
pEmail, Code:
pEmail[64], Code:
PlayerInfo[playerid][pEmail] = 0; Code:
PlayerInfo[playerid][pEmail] = ""; Code:
cache_get_value_name(0, "email", PlayerInfo[playerid][pEmail]); Code:
cache_get_value_name(0, "email", PlayerInfo[playerid][pEmail],64); Code:
new playeremail = PlayerInfo[playerid][pEmail]; Code:
new playeremail[64]; format(playeremail, 64, PlayerInfo[playerid][pEmail]); Code:
mysql_format(handle, query, sizeof(query), "UPDATE users SET email = '%d', level = '%d', admin = '%d', money = '%d', kills = '%d', deaths = '%d' WHERE id = '%d'", playeremail, livello, adminl, soldi, uccisioni, morti, idgiocatore); Code:
mysql_format(handle, query, sizeof(query), "UPDATE users SET email = '%s', level = '%d', admin = '%d', money = '%d', kills = '%d', deaths = '%d' WHERE id = '%d'", playeremail, livello, adminl, soldi, uccisioni, morti, idgiocatore); And make sure that "email" is defined as VARCHAR with LENGTH 64 in MySQL Database. |
PlayerInfo[playerid][pEmail] = "";
format(PlayerInfo[playerid][pEmail], 64, "");
if(dialogid == DIALOG_REGISTER_EMAIL) { //Se il giocatore seleziona Annulla/Esci if(!response) return Kick(playerid); //In tal caso l'utente inserisci una password troppo breve o non inserisce niente ritorna sullo stesso dialogo if(strlen(inputtext) < 5) return ShowPlayerDialog(playerid, DIALOG_REGISTER_EMAIL, DIALOG_STYLE_PASSWORD, "Registrazione", "{FF0000}ERRORE:\n{000000}Devi inserire una mail valide\n{00FF00}INFO: Servirа per proteggere meglio il tuo account!", "Continua", "Annulla"); //We just save the E-Mail in the variable, it will be saved when the user leaves the server, or by calling SaveUserStats. format(PlayerInfo[playerid][pEmail], 64, inputtext); return 1; }
Concerning the error, my fault. Change
Code:
PlayerInfo[playerid][pEmail] = ""; Code:
format(PlayerInfo[playerid][pEmail], 64, ""); Code:
if(dialogid == DIALOG_REGISTER_EMAIL) { //Se il giocatore seleziona Annulla/Esci if(!response) return Kick(playerid); //In tal caso l'utente inserisci una password troppo breve o non inserisce niente ritorna sullo stesso dialogo if(strlen(inputtext) < 5) return ShowPlayerDialog(playerid, DIALOG_REGISTER_EMAIL, DIALOG_STYLE_PASSWORD, "Registrazione", "{FF0000}ERRORE:\n{000000}Devi inserire una mail valide\n{00FF00}INFO: Servirа per proteggere meglio il tuo account!", "Continua", "Annulla"); //We just save the E-Mail in the variable, it will be saved when the user leaves the server, or by calling SaveUserStats. format(PlayerInfo[playerid][pEmail], 64, inputtext); return 1; } |
SaveUserStats(playerid);