Rei_Ayanami

[EasyDB] Login and register tutorial

Jul 28th, 2023
39
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <a_samp>
  2.  
  3. #define CONNECTION_TYPE_MYSQL // tells "easydb" that we are using mysql
  4. #define ENABLE_CONSOLE_MESSAGES // tells "easydb" that we would need console messages/debugs while run time to keep checks and detect if any errors/warnings
  5.  
  6. #include <easydb>
  7. #include <izcmd>
  8. #include <sscanf2>
  9. #include <easydialog>
  10.  
  11. #define MIN_PASSWORD_LENGTH (5)
  12. #define MAX_PASSWORD_LENGTH (45)
  13.  
  14. #define MAX_LOGIN_ATTEMPTS (3)
  15.  
  16. #define PASSWORD_SALT "334t!t>D<QW**@!)#$>C_)_AAgddh"
  17.  
  18. enum E_ACCOUNT
  19. {
  20. E_ACCOUNT_SQLID,
  21. E_ACCOUNT_PASSWORD[64],
  22. E_ACCOUNT_KILLS,
  23. E_ACCOUNT_DEATHS,
  24. E_ACCOUNT_MONEY,
  25. E_ACCOUNT_SCORE
  26. };
  27. new p_Account[MAX_PLAYERS][E_ACCOUNT];
  28.  
  29. new p_LoginAttempts[MAX_PLAYERS];
  30.  
  31. public OnGameModeInit()
  32. {
  33. DB::Init("sa-mp", "localhost", "root", "");
  34.  
  35. // Creating/Verifying table where we'll save user data
  36. DB::VerifyTable("Users", "ID", false,
  37. "Name", STRING,
  38. "Password", STRING,
  39. "IP", STRING,
  40. "Kills", INTEGER,
  41. "Deaths", INTEGER,
  42. "Money", INTEGER,
  43. "Score", INTEGER);
  44.  
  45. return 1;
  46. }
  47.  
  48. public OnPlayerConnect(playerid)
  49. {
  50. p_LoginAttempts[playerid] = 0; // reset login attempts to 0
  51.  
  52. new name[MAX_PLAYER_NAME];
  53. GetPlayerName(playerid, name, MAX_PLAYER_NAME);
  54.  
  55. DB::Fetch("Users", 0, _, _, _, "`Name` = '%q'", name);
  56. if (fetch_rows_count() > 0) // if the user is existing member (LOGIN)
  57. {
  58. p_Account[playerid][E_ACCOUNT_SQLID] = fetch_row_id();
  59. fetch_string("Password", p_Account[playerid][E_ACCOUNT_PASSWORD], 64);
  60. p_Account[playerid][E_ACCOUNT_KILLS] = fetch_int("Kills");
  61. p_Account[playerid][E_ACCOUNT_DEATHS] = fetch_int("Deaths");
  62. p_Account[playerid][E_ACCOUNT_MONEY] = fetch_int("Money");
  63. p_Account[playerid][E_ACCOUNT_SCORE] = fetch_int("Score");
  64.  
  65. Dialog_Show(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Login account...", "{FFFFFF}Good to see you back to SA-MP 0.3.7 Server! Please complete the login formality to access your account (password required).", "Login", "Quit");
  66. }
  67. else // user is new (REGISTER)
  68. {
  69. p_Account[playerid][E_ACCOUNT_SQLID] = -1;
  70. p_Account[playerid][E_ACCOUNT_PASSWORD][0] = EOS;
  71. p_Account[playerid][E_ACCOUNT_KILLS] = 0;
  72. p_Account[playerid][E_ACCOUNT_DEATHS] = 0;
  73. p_Account[playerid][E_ACCOUNT_MONEY] = 0;
  74. p_Account[playerid][E_ACCOUNT_SCORE] = 0;
  75.  
  76. Dialog_Show(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Register account...", "{FFFFFF}Welcome to SA-MP 0.3.7 Server! Please complete this small registeration formality to sign-up with us (password required).", "Register", "Quit");
  77. }
  78.  
  79. fetcher_close();
  80. return 1;
  81. }
  82.  
  83. Dialog:DIALOG_LOGIN(playerid, response, listitem, inputtext[])
  84. {
  85. // if player clicks "Quit" (will be kicked)
  86. if (!response)
  87. return Kick(playerid);
  88.  
  89. // we'll hash player password here which will be further used for comparing
  90. new password[64];
  91. SHA256_PassHash(inputtext, PASSWORD_SALT, password, sizeof (password));
  92.  
  93. // as we have stored player data when he/she connected, so we'll check the password is matching
  94. if (strcmp(p_Account[playerid][E_ACCOUNT_PASSWORD], password)) // if password is incorrect
  95. {
  96. p_LoginAttempts[playerid]++;
  97.  
  98. new str[150];
  99. format(str, sizeof (str), "Incorrect password, you are left with %i/%i attempts.", p_LoginAttempts[playerid], MAX_LOGIN_ATTEMPTS);
  100. SendClientMessage(playerid, 0xFFFFFFFF, str);
  101.  
  102. if (p_LoginAttempts[playerid] >= MAX_LOGIN_ATTEMPTS)
  103. return Kick(playerid);
  104.  
  105. return Dialog_Show(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Login account...", "{FFFFFF}Good to see you back to SA-MP 0.3.7 Server! Please complete the login formality to access your account (password required).", "Login", "Quit");
  106. }
  107.  
  108. // player has successfully logged-in
  109. new name[MAX_PLAYER_NAME];
  110. GetPlayerName(playerid, name, MAX_PLAYER_NAME);
  111.  
  112. new str[150];
  113. format(str, sizeof (str), "Welcome back %s [id: %i]", name, playerid);
  114. SendClientMessage(playerid, 0xFFFFFFFF, str);
  115.  
  116. ResetPlayerMoney(playerid);
  117. GivePlayerMoney(playerid, p_Account[playerid][E_ACCOUNT_MONEY]);
  118. SetPlayerScore(playerid, p_Account[playerid][E_ACCOUNT_SCORE]);
  119.  
  120. // update player information
  121. new ip[18];
  122. GetPlayerIp(playerid, ip, sizeof (ip));
  123.  
  124. DB::Update("Users", p_Account[playerid][E_ACCOUNT_SQLID], 1,
  125. "IP", STRING, ip);
  126.  
  127. return 1;
  128. }
  129.  
  130. Dialog:DIALOG_REGISTER(playerid, response, listitem, inputtext[])
  131. {
  132. // if player clicks "Quit" (will be kicked)
  133. if (!response)
  134. return Kick(playerid);
  135.  
  136. // check if password is not empty
  137. if (!inputtext[0] || inputtext[0] == ' ')
  138. {
  139. SendClientMessage(playerid, 0xFFFFFFFF, "Invalid password length, cannot be empty.");
  140.  
  141. return Dialog_Show(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Register account...", "{FFFFFF}Welcome to SA-MP 0.3.7 Server! Please complete this small registeration formality to sign-up with us (password required).", "Register", "Quit");
  142. }
  143.  
  144. // check for password lengths
  145. new len = strlen(inputtext);
  146. if (len > MAX_PASSWORD_LENGTH || len < MIN_PASSWORD_LENGTH)
  147. {
  148. new str[150];
  149. format(str, sizeof (str), "Invalid password length, must be between %i - %i chars.", MIN_PASSWORD_LENGTH, MAX_PASSWORD_LENGTH);
  150. SendClientMessage(playerid, 0xFFFFFFFF, str);
  151.  
  152. return Dialog_Show(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Register account...", "{FFFFFF}Welcome to SA-MP 0.3.7 Server! Please complete this small registeration formality to sign-up with us (password required).", "Register", "Quit");
  153. }
  154.  
  155. // hashing the password
  156. SHA256_PassHash(inputtext, PASSWORD_SALT, p_Account[playerid][E_ACCOUNT_PASSWORD], 64);
  157.  
  158. // player has successfully registered
  159. new name[MAX_PLAYER_NAME];
  160. GetPlayerName(playerid, name, MAX_PLAYER_NAME);
  161.  
  162. new str[150];
  163. format(str, sizeof (str), "Welcome %s [id: %i]", name, playerid);
  164. SendClientMessage(playerid, 0xFFFFFFFF, str);
  165.  
  166. // create player's row into "Users" table
  167. new ip[18];
  168. GetPlayerIp(playerid, ip, sizeof (ip));
  169.  
  170. DB::CreateRow("Users",
  171. "Name", STRING, name,
  172. "Password", STRING, p_Account[playerid][E_ACCOUNT_PASSWORD],
  173. "IP", STRING, ip);
  174.  
  175. DB::Fetch("Users", 0, _, _, _, "`Name` = '%q'", name);
  176. p_Account[playerid][E_ACCOUNT_SQLID] = fetch_row_id();
  177. fetcher_close();
  178.  
  179. return 1;
  180. }
  181.  
  182. public OnPlayerDeath(playerid, killerid, reason)
  183. {
  184. p_Account[playerid][E_ACCOUNT_DEATHS]++; // increase player's deaths count
  185.  
  186. if (killerid != INVALID_PLAYER_ID)
  187. p_Account[killerid][E_ACCOUNT_KILLS]++; // increase killer's kills count if the id is of a connected player
  188.  
  189. return 1;
  190. }
  191.  
  192. public OnPlayerDisconnect(playerid, reason)
  193. {
  194. DB::Update("Users", p_Account[playerid][E_ACCOUNT_SQLID], 1,
  195. "Kills", INTEGER, p_Account[playerid][E_ACCOUNT_KILLS],
  196. "Deaths", INTEGER, p_Account[playerid][E_ACCOUNT_DEATHS],
  197. "Score", INTEGER, GetPlayerScore(playerid),
  198. "Money", INTEGER, GetPlayerMoney(playerid));
  199. return 1;
  200. }
  201.  
  202. public OnGameModeExit()
  203. {
  204. DB::Exit();
  205. return 1;
  206. }
  207.  
  208. CMD:changepass(playerid, params[])
  209. {
  210. new password[64];
  211. if (sscanf(params, "s[64]", password))
  212. return SendClientMessage(playerid, 0xFFFFFFFF, "Usage: /changepass [new password]");
  213.  
  214. // check password's length
  215. new len = strlen(password);
  216. if (len > MAX_PASSWORD_LENGTH || len < MIN_PASSWORD_LENGTH)
  217. {
  218. new str[150];
  219. format(str, sizeof (str), "Invalid password length, must be between %i - %i chars.", MIN_PASSWORD_LENGTH, MAX_PASSWORD_LENGTH);
  220. return SendClientMessage(playerid, 0xFFFFFFFF, str);
  221. }
  222.  
  223. // hashing the password
  224. SHA256_PassHash(password, PASSWORD_SALT, p_Account[playerid][E_ACCOUNT_PASSWORD], 64);
  225.  
  226. // update player's password
  227. DB::Update("Users", p_Account[playerid][E_ACCOUNT_SQLID], 1,
  228. "Password", STRING, p_Account[playerid][E_ACCOUNT_PASSWORD]);
  229.  
  230. return SendClientMessage(playerid, 0xFFFFFFFF, "Password successfully updated.");
  231. }
Add Comment
Please, Sign In to add comment