Guest User

Untitled

a guest
Feb 1st, 2014
575
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.87 KB | None | 0 0
  1. /*
  2. * Nazwa: Register & Login
  3. * Autor: l0nger (aka AXV) <[email protected] | [email protected]>
  4. * Wersja: 1.1.132011
  5. *
  6. * Wymagane technologie baz danych: MySQL
  7. * Wymagane wtyczki: sscanf 2.8.1
  8. * (C) <2013>, <[email protected] | pawno.pl>
  9. **/
  10.  
  11. #pragma dynamic 4096
  12. #pragma compress 1
  13.  
  14. // naglowek SAMP
  15. #include a_samp
  16.  
  17. #define ALREADY_REDEFINED_MAXPLAYERS
  18.  
  19. #if defined ALREADY_REDEFINED_MAXPLAYERS
  20. #undef MAX_PLAYERS
  21. #define MAX_PLAYERS (5) // Prosze tutaj wpisac liczbe slotow serwera
  22. #endif
  23.  
  24. // naglowki technologiczne
  25. #include sscanf // Y_Less > 2.8.1
  26. #include mysql // StrickenKid > 2.1.1
  27.  
  28. // makrorozwieniecia
  29. #define outputChatMsg(%1,%2,%3) SendClientMessage(%1, %2, %3)
  30. #define hidePlayerDialog(%1) ShowPlayerDialog(%1, -1, NULL, {NULL}, {NULL}, {NULL}, {NULL})
  31. #define ResetVariablesInEnum(%0,%1) for(new __rvine; %1:__rvine != %1; __rvine++) %0[%1:__rvine]=0
  32.  
  33. // Dane do polaczenia z MySQL
  34. #define SQL_HOSTNAME "localhost" // host
  35. #define SQL_USERNAME "username" // uzytkownik
  36. #define SQL_PASSWORD "password" // haslo
  37. #define SQL_DATABASE "database" // baza danych
  38.  
  39. // Prefiks tabel
  40. #define PREFIX_DB "px_"
  41.  
  42. // Zmienne stale, wyliczeniowe i nie tylko...
  43. const MAX_LOGIN_ATTEMPTS = (5); // maksymalnie 5 prob logowan
  44. const NULL = (0); // miejsce zerowe!
  45.  
  46. enum {
  47. dialog_info = 0,
  48. dialog_login,
  49. dialog_register
  50. };
  51.  
  52. enum E_PLAYER_DATA {
  53. /* bool */
  54. bool:loggedIn,
  55.  
  56. /* chars */
  57. nickname[24],
  58. ipv4[16],
  59.  
  60. /* int */
  61. timeOnline,
  62. score,
  63. money,
  64. kills,
  65. deaths,
  66. suicides,
  67. loginAttempts // max. 5 prob
  68. };
  69.  
  70. new
  71. PlayerData[MAX_PLAYERS][E_PLAYER_DATA],
  72. MySQL:hMySQL;
  73.  
  74. // Funkcje publiczne
  75. public OnFilterScriptInit() {
  76. hMySQL = mysql_init(LOG_ONLY_ERRORS);
  77. new mysqlHandle = mysql_connect(SQL_HOSTNAME, SQL_USERNAME, SQL_PASSWORD, SQL_DATABASE, hMySQL, true);
  78.  
  79. if(mysqlHandle) {
  80. CreateDatabase();
  81. print(" [REG&LOG]: Polaczono z baza danych!");
  82. } else print(" [REG&LOG]: Nie mozna nawiazac polaczenia z baza danych! Sprawdz dane konfiguracyjne."), SendRconCommand("exit");
  83.  
  84. print(" Skrypt Register & Login - zaladowany poprawnie!");
  85. return 1;
  86. }
  87.  
  88. public OnFilterScriptExit() {
  89. mysql_close(hMySQL);
  90. return 1;
  91. }
  92.  
  93. public OnPlayerConnect(playerid) {
  94. ResetVariablesInEnum(PlayerData[playerid], E_PLAYER_DATA);
  95.  
  96. PlayerData[playerid][timeOnline]=gettime();
  97. GetPlayerName(playerid, PlayerData[playerid][nickname], 24);
  98. GetPlayerIp(playerid, PlayerData[playerid][ipv4], 16);
  99.  
  100. new
  101. s_buf[120+MAX_PLAYER_NAME];
  102.  
  103. if(PlayerExistsInDatabase(playerid)) {
  104. format(s_buf, sizeof(s_buf), "Witaj, %s!\nTwoje konto jest zarejestrowane.\nProszę wpisać hasło w poniższe okno, a następnie kliknąć przycisk 'ZALOGUJ'", PlayerData[playerid][nickname]);
  105. ShowPlayerDialog(playerid, dialog_login, DIALOG_STYLE_PASSWORD, "Panel > Logowanie", s_buf, "Zaloguj", "Opusc");
  106. } else {
  107. format(s_buf, sizeof(s_buf), "Witaj, %s!\nTwoje konto nie jest zarejestrowane.\nProszę wpisać hasło w poniższe okno, a następnie kliknąć przycisk 'REJESTRUJ'", PlayerData[playerid][nickname]);
  108. ShowPlayerDialog(playerid, dialog_register, DIALOG_STYLE_PASSWORD, "Panel > Rejestracja", s_buf, "Rejestruj", "");
  109. }
  110. return 1;
  111. }
  112.  
  113. public OnPlayerDisconnect(playerid, reason) {
  114. SavePlayerData(playerid, .leaving=1);
  115. }
  116.  
  117. public OnPlayerDeath(playerid, killerid, reason) {
  118. if(killerid != INVALID_PLAYER_ID) {
  119. PlayerData[killerid][kills]++;
  120. PlayerData[playerid][deaths]++;
  121. } else {
  122. PlayerData[playerid][deaths]++;
  123. PlayerData[playerid][suicides]++;
  124. }
  125. }
  126.  
  127. public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]) {
  128. static
  129. s_buf[120+MAX_PLAYER_NAME];
  130.  
  131. switch(dialogid) {
  132. case dialog_info: return 1;
  133. case dialog_login: {
  134. if(!response) {
  135. outputChatMsg(playerid, -1, "Anulowales logowanie.");
  136. hidePlayerDialog(playerid);
  137. kickPlayer(playerid);
  138. return 0;
  139. }
  140.  
  141. if(!OnPlayerLogin(playerid, inputtext)) {
  142. format(s_buf, sizeof(s_buf), "Witaj, %s!\nTwoje konto jest zarejestrowane.\nProszę wpisać hasło w poniższe okno, a następnie kliknąć przycisk 'ZALOGUJ'", PlayerData[playerid][nickname]);
  143. ShowPlayerDialog(playerid, dialog_login, DIALOG_STYLE_PASSWORD, "Panel > Logowanie", s_buf, "Zaloguj", "Opusc");
  144. }
  145. }
  146. case dialog_register: {
  147. if(!response) return 1;
  148.  
  149. if(!OnPlayerRegister(playerid, inputtext)) {
  150. format(s_buf, sizeof(s_buf), "Witaj, %s!\nTwoje konto nie jest zarejestrowane.\nProszę wpisać hasło w poniższe okno, a następnie kliknąć przycisk 'REJESTRUJ'", PlayerData[playerid][nickname]);
  151. ShowPlayerDialog(playerid, dialog_register, DIALOG_STYLE_PASSWORD, "Panel > Rejestracja", s_buf, "Rejestruj", "");
  152. }
  153. }
  154. }
  155. return 1;
  156. }
  157.  
  158. /**
  159. * @name: OnPlayerLogin
  160. * @desc: Funkcja sprawdza, czy haslo jest poprawne - jezeli tak - nastepuje wczytanie danych i wywolanie spawnu gracza
  161. * @params: playerid=id gracza, password=wpisywane haslo w GUI
  162. * @returns: brak
  163. **/
  164. stock OnPlayerLogin(playerid, password[]) {
  165. if(!password[0] || password[0] && !password[1]) {
  166. PlayerData[playerid][loginAttempts]++;
  167. return false;
  168. }
  169.  
  170. // -- SPRAWDZANIE POPRAWNOSCI HASLA --
  171. for(new i, j = strlen(password); i<j; i++) {
  172. switch(password[i]) {
  173. case 'a' .. 'z', 'A' .. 'Z', '0' .. '9', ';', '!', '@', '#', '$', '^', '&', '*', '(', ')': continue;
  174. default: return false;
  175. }
  176. }
  177.  
  178. new
  179. esc_password[32], // 25+7 na znaki escapowane
  180. esc_nickname[24+5], // to co wyzej
  181. s_buf[160];
  182.  
  183. mysql_real_escape_string(PlayerData[playerid][nickname], esc_nickname);
  184. mysql_real_escape_string(password, esc_password);
  185. format(s_buf, sizeof(s_buf), "SELECT (password = SHA1(CONCAT(salt, SHA1(CONCAT(salt, '%s'))))) AS valid FROM "PREFIX_DB"players WHERE nickname = '%s' LIMIT 1;", esc_password, esc_nickname);
  186. printf(s_buf);
  187. mysql_query(s_buf);
  188. mysql_store_result();
  189. new valid=mysql_fetch_int();
  190. mysql_free_result();
  191.  
  192. if(!valid) {
  193. format(s_buf, sizeof(s_buf), "proba zalogowania sie na konto %s", PlayerData[playerid][nickname]);
  194. RegisterLogWithIP(PlayerData[playerid][ipv4], s_buf);
  195.  
  196. if(++PlayerData[playerid][loginAttempts]>=MAX_LOGIN_ATTEMPTS-1) {
  197. format(s_buf, sizeof(s_buf), "proba zalogowania sie na konto %s - wyrzucony", PlayerData[playerid][nickname]);
  198. RegisterLogWithIP(PlayerData[playerid][ipv4], s_buf);
  199. hidePlayerDialog(playerid);
  200. kickPlayer(playerid);
  201. outputChatMsg(playerid, -1, "Wykorzystales limit prob zalogowan na konto. {ff0000}Zostales wyrzucony.");
  202. return false;
  203. }
  204. outputChatMsg(playerid, -1, "Podane haslo jest nieprawidlowe.");
  205. return false;
  206. } else {
  207. format(s_buf, sizeof(s_buf), "zalogowano sie na konto %s", PlayerData[playerid][nickname]);
  208. RegisterLogWithIP(PlayerData[playerid][ipv4], s_buf);
  209. PlayerData[playerid][loggedIn]=true;
  210. }
  211.  
  212. format(s_buf, sizeof(s_buf), "UPDATE "PREFIX_DB"players SET is_online=1, ts_activelast=NOW(), address_ip='%s', logons=logons+1 WHERE nickname='%s';", PlayerData[playerid][ipv4], PlayerData[playerid][nickname]);
  213. mysql_query(s_buf);
  214.  
  215. FetchPlayerData(playerid);
  216. format(s_buf, sizeof(s_buf), "%s! Jest to Twoja %d wizyta na tym serwerze.", PlayerData[playerid][nickname], GetPlayerIntegerData(playerid, "logons"));
  217. outputChatMsg(playerid, -1, s_buf);
  218.  
  219. SpawnPlayer(playerid);
  220. return true;
  221. }
  222.  
  223. /**
  224. * @name: OnPlayerRegister
  225. * @desc: Funkcja, ma za zadanie zarejestrowac gracza do bazy danych. Funkcja takze ma za zadanie sprawdzac znaki w hasle, czy nie sa nieprawidlowe
  226. * @params: playerid=id gracza, password=wpisywane haslo w GUI
  227. * @returns: false=jezeli haslo bedzie puste, lub nieprawidlowe, true=jezeli proces rejestracji przebiegnie prawidlowo
  228. **/
  229. stock OnPlayerRegister(playerid, const password[]) {
  230. if(!password[0] || password[0] && !password[1]) return false;
  231.  
  232. // -- SPRAWDZANIE POPRAWNOSCI HASLA --
  233. for(new i, j = strlen(password); i<j; i++) {
  234. switch(password[i]) {
  235. case 'a' .. 'z', 'A' .. 'Z', '0' .. '9', ';', '!', '@', '#', '$', '^', '&', '*', '(', ')': continue;
  236. case ':', '<', '>', '/', '[', ']': continue;
  237. default: return false;
  238. }
  239. }
  240.  
  241. new
  242. s_salt[5],
  243. esc_password[32], // 25+7 na znaki escapowane
  244. esc_nickname[24+5], // to co wyzej
  245. s_buf[250];
  246.  
  247. // -- GENEROWANIE SOLI --
  248. new i_salt;
  249. while(i_salt<sizeof(s_salt)-1) {
  250. s_salt[i_salt]=random(2)?(random(26)+(random(2)?'a':'A')):(random(10)+'0');
  251. i_salt++;
  252. }
  253. print(s_salt);
  254.  
  255. mysql_real_escape_string(password, esc_password);
  256. mysql_real_escape_string(PlayerData[playerid][nickname], esc_nickname);
  257. format(s_buf, sizeof(s_buf), "INSERT INTO "PREFIX_DB"players (nickname, salt, password, address_ip, ts_register, ts_activelast) VALUES ('%s', '%s', SHA1(CONCAT('%s', SHA1(CONCAT('%s', '%s')))), '%s', NOW(), NOW());", esc_nickname, s_salt, s_salt, s_salt, esc_password, PlayerData[playerid][ipv4]);
  258. if(mysql_query(s_buf) || !mysql_affected_rows()) {
  259. format(s_buf, sizeof(s_buf), "proba rejestracji konta: %s - nieudana, blad z polaczeniem mysql", PlayerData[playerid][nickname]);
  260. RegisterLogWithIP(PlayerData[playerid][ipv4], s_buf);
  261. outputChatMsg(playerid, -1, "Wystapil blad podczas wysylania formularza danych. Sprobuj ponownie!");
  262. hidePlayerDialog(playerid);
  263. kickPlayer(playerid);
  264. return false;
  265. }
  266.  
  267. format(s_buf, sizeof(s_buf), "zarejestrowano konto: %s", PlayerData[playerid][nickname]);
  268. RegisterLogWithIP(PlayerData[playerid][ipv4], s_buf);
  269.  
  270. format(s_buf, sizeof(s_buf), "Zarejestrowales konto: %s! Twoje haslo: %s - zapamietaj je do przyszlego logowania!", PlayerData[playerid][nickname], password);
  271. outputChatMsg(playerid, -1, s_buf);
  272.  
  273. PlayerData[playerid][loggedIn]=true;
  274. SpawnPlayer(playerid);
  275. return true;
  276. }
  277.  
  278. /**
  279. * @name: RegisterLogWithIP
  280. * @desc: Zapisywanie danych do logu rejestracji i logowan, lacznie z adresem ip
  281. * @params: ivp4=IP gracza, desc=opis przebiegu logu
  282. * @returns: brak
  283. **/
  284. stock RegisterLogWithIP(const address_ip[], const desc[]) {
  285. new
  286. s_buf[160];
  287.  
  288. format(s_buf, sizeof(s_buf), "INSERT INTO "PREFIX_DB"logins_logs (ts, address_ip, opis) VALUES (NOW(), '%s', '%s');", address_ip, desc);
  289. mysql_query(s_buf);
  290. printf(" [REG&LOG]: Zarejestrowano zdarzenie id: %d -> %s, %s", mysql_insert_id(), desc, address_ip);
  291. }
  292.  
  293. /**
  294. * @name: PlayerExistsInDatabase
  295. * @desc: Funkcja sprawdza, czy w bazie danych konto o podanym nicku istnieje
  296. * @params: playerid=id gracza
  297. * @returns: false=jezeli konto nie istnieje, true=jezeli konto istnieje
  298. **/
  299. stock PlayerExistsInDatabase(playerid) {
  300. new
  301. s_buf[100];
  302.  
  303. format(s_buf, sizeof(s_buf), "SELECT 1 FROM "PREFIX_DB"players WHERE nickname='%s' LIMIT 1;", PlayerData[playerid][nickname]);
  304. mysql_query(s_buf);
  305. mysql_store_result();
  306. new exid=mysql_num_rows() && mysql_fetch_int()>=1;
  307. mysql_free_result();
  308.  
  309. return exid;
  310. }
  311.  
  312. /**
  313. * @name: SavePlayerData
  314. * @desc: Funkcja zapisuje podstawowe dane gracza
  315. * @params: playerid=id gracza, leaving=czy juz wychodzi (potrzebne do zmiany is_online)
  316. * @returns: brak
  317. **/
  318. stock SavePlayerData(playerid, leaving=0) {
  319. new
  320. s_buf[128];
  321.  
  322. format(s_buf, sizeof(s_buf), "UPDATE "PREFIX_DB"players SET time_online=%d, score=%d, money=%d, deaths=%d, suicides=%d, kills=%d, is_online=%d WHERE nickname='%s';",
  323. gettime()-PlayerData[playerid][timeOnline],
  324. PlayerData[playerid][score],
  325. PlayerData[playerid][money],
  326. PlayerData[playerid][deaths],
  327. PlayerData[playerid][suicides],
  328. PlayerData[playerid][kills],
  329. (leaving==0)?1:0,
  330. PlayerData[playerid][nickname]
  331. );
  332. mysql_query(s_buf);
  333. }
  334.  
  335. /**
  336. * @name: FetchPlayerData
  337. * @desc: Funkcja pobiera wszystkie potrzebne dane, do wyswietlenia
  338. * @params: playerid=id gracza
  339. * @returns: brak
  340. **/
  341. stock FetchPlayerData(playerid) {
  342. new
  343. s_buf[127],
  344. tmpTime;
  345.  
  346. format(s_buf, 127, "SELECT money, score, kills, time_online, deaths, suicides FROM "PREFIX_DB"players WHERE nickname='%s' LIMIT 1;", PlayerData[playerid][nickname]);
  347. mysql_query(s_buf);
  348. mysql_store_result();
  349. if(mysql_fetch_row(s_buf, "|")) {
  350. sscanf(s_buf, "p<|>dddddd",
  351. PlayerData[playerid][money],
  352. PlayerData[playerid][score],
  353. PlayerData[playerid][kills],
  354. tmpTime,
  355. PlayerData[playerid][deaths],
  356. PlayerData[playerid][suicides]
  357. );
  358. }
  359. mysql_free_result();
  360.  
  361. PlayerData[playerid][timeOnline]+=tmpTime;
  362. SetPlayerScore(playerid, PlayerData[playerid][score]);
  363. GivePlayerMoney(playerid, PlayerData[playerid][money]);
  364. }
  365.  
  366.  
  367. /**
  368. * @name: GetPlayerIntegerData
  369. * @desc: Funkcja pobiera dane w postaci liczbowej z podanej kolumny (arg. column)
  370. * @params: playerid=id gracza, column=kolumna ISTNIEJACA w tabeli players
  371. * @returns: zwroci otrzymana wartosc
  372. **/
  373. stock GetPlayerIntegerData(playerid, const column[]) {
  374. new
  375. s_buf[127];
  376.  
  377. format(s_buf, 127, "SELECT %s FROM "PREFIX_DB"players WHERE nickname='%s' LIMIT 1;", column, PlayerData[playerid][nickname]);
  378. mysql_query(s_buf);
  379. mysql_store_result();
  380. mysql_fetch_row(s_buf);
  381. mysql_free_result();
  382. return strval(s_buf);
  383. }
  384.  
  385.  
  386. /**
  387. * @name: CreateDatabase
  388. * @desc: Funkcja, ma za zadanie stworzyc tabele
  389. * @params: option=opcja tworzenia (0=tworzy, jezeli ich nie ma, 1=usuwa tabele)
  390. * @returns: brak
  391. **/
  392. stock CreateDatabase(option=0) {
  393. if(option==1) {
  394. mysql_query("DROP TABLE "PREFIX_DB"players, "PREFIX_DB"logins_logs;");
  395. }
  396.  
  397. new
  398. s_buf[1024] = "CREATE TABLE IF NOT EXISTS "PREFIX_DB"players(";
  399.  
  400. strcat(s_buf, "id INT NOT NULL AUTO_INCREMENT,");
  401. strcat(s_buf, "nickname VARCHAR(24) NOT NULL,");
  402. strcat(s_buf, "password VARCHAR(48) NOT NULL,");
  403. strcat(s_buf, "salt VARCHAR(5) NOT NULL,");
  404. strcat(s_buf, "address_ip VARCHAR(16) NOT NULL DEFAULT '0.0.0.0',");
  405. strcat(s_buf, "ts_register TIMESTAMP NOT NULL,");
  406. strcat(s_buf, "ts_activelast TIMESTAMP NOT NULL,");
  407. strcat(s_buf, "logons SMALLINT NOT NULL DEFAULT '1',");
  408. strcat(s_buf, "time_online INT NOT NULL DEFAULT '0',");
  409. strcat(s_buf, "score INT NOT NULL DEFAULT '1',");
  410. strcat(s_buf, "money INT NOT NULL DEFAULT '1',");
  411. strcat(s_buf, "deaths INT NOT NULL DEFAULT '0',");
  412. strcat(s_buf, "suicides INT NOT NULL DEFAULT '0',");
  413. strcat(s_buf, "kills INT NOT NULL DEFAULT '0',");
  414. strcat(s_buf, "is_online TINYINT(1) NOT NULL DEFAULT '0',");
  415. strcat(s_buf, "PRIMARY KEY (`id`), UNIQUE KEY `nickname` (`nickname`), KEY `score` (`score`));");
  416. mysql_query(s_buf);
  417.  
  418. s_buf="CREATE TABLE IF NOT EXISTS "PREFIX_DB"logins_logs(";
  419. strcat(s_buf, "id INT NOT NULL AUTO_INCREMENT,");
  420. strcat(s_buf, "ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,");
  421. strcat(s_buf, "address_ip VARCHAR(16) NOT NULL DEFAULT '0.0.0.0',");
  422. strcat(s_buf, "opis VARCHAR(100) NOT NULL DEFAULT 'brak zarejestrowanego opisu',");
  423. strcat(s_buf, "PRIMARY KEY (`id`));");
  424. mysql_query(s_buf);
  425. }
  426.  
  427. // Implementacja kickfix
  428. stock kickPlayer(playerid) {
  429. SetTimerEx("func_kickPlayer", 100, 0, "i", playerid);
  430. }
  431.  
  432. forward func_kickPlayer(playerid);
  433. public func_kickPlayer(playerid) {
  434. if(IsPlayerConnected(playerid)) {
  435. Kick(playerid);
  436. return 1;
  437. }
  438. return 0;
  439. }
Advertisement
Add Comment
Please, Sign In to add comment