· 7 years ago · Jan 22, 2019, 11:58 PM
1#include <a_samp>
2// change MAX_PLAYERS to the amount of players (slots) you want
3// It is by default 1000 (as of 0.3.7 version)
4#undef MAX_PLAYERS
5#define MAX_PLAYERS 50
6//----------
7// INCLUDE
8#include <a_mysql>
9#include <zcmd>
10
11
12// Define
13
14#define d_input DIALOG_STYLE_INPUT
15
16// Configurazione MySQL
17#define MYSQL_HOST "127.0.0.1"
18#define MYSQL_USER "root"
19#define MYSQL_PASSWORD "Pass123!"
20#define MYSQL_DATABASE "dbrp"
21
22//-------------
23// info server
24#define emailserver "asd@gmail.com"
25
26
27// colori
28// system color
29#define COLOR_SYSTEM_ERROR 0xAA3333AA
30#define COLOR_SYSTEM_TITLE 0xFFFFFFAA
31#define COLOR_SYSTEM_TEXT 0xFFFFFFAA
32#define COLOR_SYSTEM_SUCCESS 0x33AA33AA
33#define COLOR_SYSTEM_INFO 0xAFAFAFAA
34
35
36// how many seconds until it kicks the player for taking too long to login
37#define SECONDS_TO_LOGIN 30
38#define NAME_CHECKER1 30
39
40// default spawn point: Las Venturas (The High Roller)
41#define DEFAULT_POS_X 1958.3783
42#define DEFAULT_POS_Y 1343.1572
43#define DEFAULT_POS_Z 15.3746
44#define DEFAULT_POS_A 270.1425
45
46// MySQL connection handle
47new MySQL: g_SQL;
48
49// player data
50enum E_PLAYERS
51{
52 ID,
53 Name[MAX_PLAYER_NAME],
54 Password[65], // the output of SHA256_PassHash function (which was added in 0.3.7 R1 version) is always 256 bytes in length, or the equivalent of 64 Pawn cells
55 Salt[17],
56 Kills,
57 Admin,
58 Age,
59 Sex,
60 Deaths,
61 Float: X_Pos,
62 Float: Y_Pos,
63 Float: Z_Pos,
64 Float: A_Pos,
65 Interior,
66
67 Cache: Cache_ID,
68 bool: IsLoggedIn,
69 LoginAttempts,
70 LoginTimer
71};
72new Player[MAX_PLAYERS][E_PLAYERS];
73
74new g_MysqlRaceCheck[MAX_PLAYERS];
75
76// dialog data
77enum
78{
79 DIALOG_UNUSED,
80 DIALOG_LOGIN,
81 DIALOG_REGISTER,
82 DIALOG_REGISTER_AGE,
83 DIALOG_REGISTER_SEX,
84 DIALOG_REGISTER_RECPASS
85};
86
87// protocollo controllo nome RP
88stock RPnamecheck(playerid)
89{
90 new pname[MAX_PLAYER_NAME],underline=0;
91 GetPlayerName(playerid, pname, sizeof(pname));
92 if(strfind(pname,"[",true) != (-1)) return 0;
93 else if(strfind(pname,"]",true) != (-1)) return 0;
94 else if(strfind(pname,"$",true) != (-1)) return 0;
95 else if(strfind(pname,"(",true) != (-1)) return 0;
96 else if(strfind(pname,")",true) != (-1)) return 0;
97 else if(strfind(pname,"=",true) != (-1)) return 0;
98 else if(strfind(pname,"@",true) != (-1)) return 0;
99 else if(strfind(pname,"1",true) != (-1)) return 0;
100 else if(strfind(pname,"2",true) != (-1)) return 0;
101 else if(strfind(pname,"3",true) != (-1)) return 0;
102 else if(strfind(pname,"4",true) != (-1)) return 0;
103 else if(strfind(pname,"5",true) != (-1)) return 0;
104 else if(strfind(pname,"6",true) != (-1)) return 0;
105 else if(strfind(pname,"7",true) != (-1)) return 0;
106 else if(strfind(pname,"8",true) != (-1)) return 0;
107 else if(strfind(pname,"9",true) != (-1)) return 0;
108 else if(strfind(pname,"fuck",true) != (-1)) return 0;
109 else if(strfind(pname,"FUCK",true) != (-1)) return 0;
110 else if(strfind(pname,"Boobies",true) != (-1)) return 0;
111 else if(strfind(pname,"Tupac_Shakur",true) != (-1)) return 0;
112 else if(strfind(pname,"Pussy",true) != (-1)) return 0;
113 else if(strfind(pname,"Rape",true) != (-1)) return 0;
114 else if(strfind(pname,"kill",true) != (-1)) return 0;
115 else if(strfind(pname,"shit",true) != (-1)) return 0;
116 else if(strfind(pname,"ass",true) != (-1)) return 0;
117 else if(strfind(pname,"Jack_Black",true) != (-1)) return 0;
118 else if(strfind(pname,"Max_Kenton",true) != (-1)) return 0;
119 else if(strfind(pname,"Will_Smith",true) != (-1)) return 0;
120 else if(strfind(pname,"Jaden_Smith",true) != (-1)) return 0;
121 else if(strfind(pname,"Megan_Fox",true) != (-1)) return 0;
122 else if(strfind(pname,"Charlie_Kenton",true) != (-1)) return 0;
123 else if(strfind(pname,"Hugh_Hefner",true) != (-1)) return 0;
124 else if(strfind(pname,"Paris_Hilton",true) != (-1)) return 0;
125 else if(strfind(pname,"Marshall_Mathers",true) != (-1)) return 0;
126 else if(strfind(pname,"Sheldon_Cooper",true) != (-1)) return 0;
127 else if(strfind(pname,"Jet_Lee",true) != (-1)) return 0;
128 else if(strfind(pname,"Jackie_Chan",true) != (-1)) return 0;
129 else if(strfind(pname,"Chuck_Norris",true) != (-1)) return 0;
130 else if(strfind(pname,"Peter_Parker",true) != (-1)) return 0;
131 else if(strfind(pname,"Spider_Man",true) != (-1)) return 0;
132 else if(strfind(pname,"Bat_Man",true) != (-1)) return 0;
133 else if(strfind(pname,"Emma_Stone",true) != (-1)) return 0;
134 else if(strfind(pname,"whore",true) != (-1)) return 0;
135 else if(strfind(pname,"Hugh_Jackman",true) != (-1)) return 0;
136 else if(strfind(pname,"Charles_Kenton",true) != (-1)) return 0;
137 else if(strfind(pname,"Harry_Potter",true) != (-1)) return 0;
138 else if(strfind(pname,"Chris_Hemsworth",true) != (-1)) return 0;
139 else if(strfind(pname,"Penis",true) != (-1)) return 0;
140 else if(strfind(pname,"_Dick",true) != (-1)) return 0;
141 else if(strfind(pname,"Vagina",true) != (-1)) return 0;
142 else if(strfind(pname,"Cock",true) != (-1)) return 0;
143 else if(strfind(pname,"Rectum",true) != (-1)) return 0;
144 else if(strfind(pname,"Sperm",true) != (-1)) return 0;
145 else if(strfind(pname,"Rektum",true) != (-1)) return 0;
146 else if(strfind(pname,"Pistol",true) != (-1)) return 0;
147 else if(strfind(pname,"AK47",true) != (-1)) return 0;
148 else if(strfind(pname,"Shotgun",true) != (-1)) return 0;
149 else if(strfind(pname,"Cum",true) != (-1)) return 0;
150 else if(strfind(pname,"Hitler",true) != (-1)) return 0;
151 else if(strfind(pname,"Jesus",true) != (-1)) return 0;
152 else if(strfind(pname,"God",true) != (-1)) return 0;
153 else if(strfind(pname,"Shotgun",true) != (-1)) return 0;
154 else if(strfind(pname,"Desert_Eagle",true) != (-1)) return 0;
155 else if(strfind(pname,"fucker",true) != (-1)) return 0;
156 else if(strfind(pname,"Retard",true) != (-1)) return 0;
157 else if(strfind(pname,"Tarded",true) != (-1)) return 0;
158 else if(strfind(pname,"fanny",true) != (-1)) return 0;
159 else if(strfind(pname,"Daniel_Hardy",true) != (-1)) return 0;
160 else if(strfind(pname,"abcdefghijklmnopqrstuvwxyz",true) != (-1)) return 0;
161 new maxname = strlen(pname);
162 for(new i=0; i<maxname; i++)
163 {
164 if(pname[i] == '_') underline ++;
165 }
166 if(underline != 1) return 0;
167 pname[0] = toupper(pname[0]);
168 for(new x=1; x<maxname; x++)
169 {
170 if(pname[x] == '_') pname[x+1] = toupper(pname[x+1]);
171 else if(pname[x] != '_' && pname[x-1] != '_') pname[x] = tolower(pname[x]);
172 }
173 SetPlayerName(playerid, "New_Name");
174 SetPlayerName(playerid, pname);
175 return 1;
176}
177
178
179
180
181
182
183main() {}
184
185
186public OnGameModeInit()
187{
188 new MySQLOpt: option_id = mysql_init_options();
189
190 mysql_set_option(option_id, AUTO_RECONNECT, true); // it automatically reconnects when loosing connection to mysql server
191
192 g_SQL = mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, option_id); // AUTO_RECONNECT is enabled for this connection handle only
193 if (g_SQL == MYSQL_INVALID_HANDLE || mysql_errno(g_SQL) != 0)
194 {
195 print("MySQL connection failed. Server is shutting down.");
196 SendRconCommand("exit"); // close the server if there is no connection
197 return 1;
198 }
199
200 print("MySQL connection is successful.");
201
202 // if the table has been created, the "SetupPlayerTable" function does not have any purpose so you may remove it completely
203 SetupPlayerTable();
204 return 1;
205}
206
207public OnGameModeExit()
208{
209 // save all player data before closing connection
210 for (new i = 0, j = GetPlayerPoolSize(); i <= j; i++) // GetPlayerPoolSize function was added in 0.3.7 version and gets the highest playerid currently in use on the server
211 {
212 if (IsPlayerConnected(i))
213 {
214 // reason is set to 1 for normal 'Quit'
215 OnPlayerDisconnect(i, 1);
216 }
217 }
218
219 mysql_close(g_SQL);
220 return 1;
221}
222
223// quando l'utente si connette al server
224public OnPlayerConnect(playerid)
225{
226 if(!RPnamecheck(playerid))
227 {
228 SetTimerEx("KickTimerNameRP", 3000, 0, "d", playerid);
229 SetPlayerPos(playerid, 982.1890, -1624.2583, 14.9526);
230 SetPlayerFacingAngle(playerid, 90);
231 new string[128], pname[MAX_PLAYER_NAME];
232 GetPlayerName(playerid, pname, MAX_PLAYER_NAME);
233 format(string, sizeof(string), "{FF0000}[INFO] Devi inserire un nome {}RP per entrare nel server");
234 SendClientMessage(playerid, COLOR_SYSTEM_ERROR, string);
235 }
236 else if(RPnamecheck(playerid))
237 {
238 g_MysqlRaceCheck[playerid]++;
239 // reset player data
240 static const empty_player[E_PLAYERS];
241 Player[playerid] = empty_player;
242
243 GetPlayerName(playerid, Player[playerid][Name], MAX_PLAYER_NAME);
244
245 // send a query to recieve all the stored player data from the table
246 new query[103];
247 mysql_format(g_SQL, query, sizeof query, "SELECT * FROM `players` WHERE `username` = '%e' LIMIT 1", Player[playerid][Name]);
248 mysql_tquery(g_SQL, query, "OnPlayerDataLoaded", "dd", playerid, g_MysqlRaceCheck[playerid]);
249 }
250 return 1;
251}
252
253public OnPlayerDisconnect(playerid, reason)
254{
255 g_MysqlRaceCheck[playerid]++;
256
257 UpdatePlayerData(playerid, reason);
258
259 // if the player was kicked (either wrong password or taking too long) during the login part, remove the data from the memory
260 if (cache_is_valid(Player[playerid][Cache_ID]))
261 {
262 cache_delete(Player[playerid][Cache_ID]);
263 Player[playerid][Cache_ID] = MYSQL_INVALID_CACHE;
264 }
265
266 // if the player was kicked before the time expires (30 seconds), kill the timer
267 if (Player[playerid][LoginTimer])
268 {
269 KillTimer(Player[playerid][LoginTimer]);
270 Player[playerid][LoginTimer] = 0;
271 }
272
273 // sets "IsLoggedIn" to false when the player disconnects, it prevents from saving the player data twice when "gmx" is used
274 Player[playerid][IsLoggedIn] = false;
275 return 1;
276}
277
278public OnPlayerSpawn(playerid)
279{
280 // spawn the player to their last saved position
281 SetPlayerInterior(playerid, Player[playerid][Interior]);
282 SetPlayerPos(playerid, Player[playerid][X_Pos], Player[playerid][Y_Pos], Player[playerid][Z_Pos]);
283 SetPlayerFacingAngle(playerid, Player[playerid][A_Pos]);
284
285 SetCameraBehindPlayer(playerid);
286 return 1;
287}
288
289public OnPlayerDeath(playerid, killerid, reason)
290{
291 UpdatePlayerDeaths(playerid);
292 UpdatePlayerKills(killerid);
293 return 1;
294}
295
296
297//-------------------------------------------
298// dialoghi
299public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
300{
301 switch (dialogid)
302 {
303 case DIALOG_UNUSED: return 1; // Useful for dialogs that contain only information and we do nothing depending on whether they responded or not
304
305 case DIALOG_LOGIN:
306 {
307 if (!response) return Kick(playerid);
308
309 new hashed_pass[65];
310 SHA256_PassHash(inputtext, Player[playerid][Salt], hashed_pass, 65);
311
312 if (strcmp(hashed_pass, Player[playerid][Password]) == 0)
313 {
314 //correct password, spawn the player
315 ShowPlayerDialog(playerid, DIALOG_UNUSED, DIALOG_STYLE_MSGBOX, "Login", "Login con successo.", "Okay", "");
316 // sets the specified cache as the active cache so we can retrieve the rest player data
317 cache_set_active(Player[playerid][Cache_ID]);
318 AssignPlayerData(playerid);
319 // remove the active cache from memory and unsets the active cache as well
320 cache_delete(Player[playerid][Cache_ID]);
321 Player[playerid][Cache_ID] = MYSQL_INVALID_CACHE;
322
323 KillTimer(Player[playerid][LoginTimer]);
324 Player[playerid][LoginTimer] = 0;
325 Player[playerid][IsLoggedIn] = true;
326
327 // spawn the player to their last saved position after login
328 SetSpawnInfo(playerid, NO_TEAM, 0, Player[playerid][X_Pos], Player[playerid][Y_Pos], Player[playerid][Z_Pos], Player[playerid][A_Pos], 0, 0, 0, 0, 0, 0);
329 SpawnPlayer(playerid);
330 }
331 else
332 {
333 Player[playerid][LoginAttempts]++;
334
335 if (Player[playerid][LoginAttempts] >= 3)
336 {
337 ShowPlayerDialog(playerid, DIALOG_UNUSED, DIALOG_STYLE_MSGBOX, "Login", "Hai superato i tentativi di accesso (3 tentativi).", "Okay", "");
338 DelayedKick(playerid);
339 }
340 else ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Login", "{FF0000}Password errata!\n{AFAFAF}Inserisci la password per entrare:", "Login", "Annulla");
341 }
342 }
343 case DIALOG_REGISTER:
344 { // registrazione - fase 1: password
345 if (!response) return Kick(playerid);
346
347 if (strlen(inputtext) <= 5) return ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Registrazione", "{FF0000}[ERRORE:]Hai inserito una password troppo corta, usa almeno 5 caratteri!\n{AFAFAF}Inserisci una password per registrarti:", "Continua", "Annulla");
348
349 // 16 random characters from 33 to 126 (in ASCII) for the salt
350 for (new i = 0; i < 16; i++) Player[playerid][Salt][i] = random(94) + 33;
351 SHA256_PassHash(inputtext, Player[playerid][Salt], Player[playerid][Password], 65);
352 new query[221];
353 mysql_format(g_SQL, query, sizeof query, "INSERT INTO `players` (`username`, `password`, `salt`) VALUES ('%e', '%s', '%e')", Player[playerid][Name], Player[playerid][Password], Player[playerid][Salt]);
354// mysql_tquery(g_SQL, query, "OnPlayerRegister", "d", playerid);
355 new string[128];
356 format(string, sizeof(string), "{AFAFAF}[INFO:] Ricorda la tua password è: {f4b642}'%s'", inputtext);
357 SendClientMessage(playerid, COLOR_SYSTEM_INFO, string);
358 format(string, sizeof(string), "{AFAFAF}[INFO:] Puoi cambiarla in game con il comando {ff0000}/cambia -> PASSWORD");
359 SendClientMessage(playerid, COLOR_SYSTEM_INFO, string);
360 ShowPlayerDialog(playerid, DIALOG_REGISTER_AGE, DIALOG_STYLE_INPUT, "Registrazione", "Inserisci l'età che vuoi avere nel server\nNon influenzerà il gioco", "Continua", "Annulla");
361 }
362/*
363 case DIALOG_REGISTER_AGE:
364 {
365 if (!response) return Kick(playerid);
366
367 if (!strlen(inputtext)) return ShowPlayerDialog(playerid, DIALOG_REGISTER_AGE, DIALOG_STYLE_INPUT, "Registrazione", "{FF0000}[ERRORE:]Devi inserire l'età per continuare!\n{AFAFAF}Non influenzerà il gioco:", "Continua", "Annulla");
368 if (!IsNumeric(inputtext)) return ShowPlayerDialog(playerid, DIALOG_REGISTER_AGE, DIALOG_STYLE_INPUT, "Registrazione", "{FF0000}[ERRORE:]Devi inserire un numero per l'età !\n{AFAFAF}Non influenzerà il gioco:", "Continua", "Annulla");
369// Player[playerid][Age] = strlen(inputtext);
370 new query[221];
371 mysql_format(g_SQL, query, sizeof query, "INSERT INTO `players` (`username`, `password`, `salt`, `age`) VALUES ('%e', '%s', '%e', '%s')", Player[playerid][Name], Player[playerid][Password], Player[playerid][Salt], inputtext);
372 ShowPlayerDialog(playerid, DIALOG_REGISTER_SEX, DIALOG_STYLE_LIST, "Seleziona il sesso", "{FF6666}Donna\n{0000cc}Uomo", "Continua", "");
373 }
374*/
375
376 case DIALOG_REGISTER_AGE:
377 {
378 if (!response) return Kick(playerid);
379
380 if (!strlen(inputtext))
381 {
382 ShowPlayerDialog(playerid, DIALOG_REGISTER_AGE, DIALOG_STYLE_INPUT, "Registrazione", "{FF0000}[ERRORE:]Devi inserire l'età per continuare!\n{AFAFAF}Non influenzerà il gioco:", "Continua", "Annulla");
383 return 1;
384 }
385 else if (strlen(inputtext))
386 {
387 if (!IsNumeric(inputtext))
388 {
389 ShowPlayerDialog(playerid, DIALOG_REGISTER_AGE, DIALOG_STYLE_INPUT, "Registrazione", "{FF0000}[ERRORE:]Devi inserire un numero per l'età !\n{AFAFAF}Non influenzerà il gioco:", "Continua", "Annulla");
390 return 1;
391 }
392 else if (IsNumeric(inputtext))
393 {
394 new query[221];
395 Player[playerid][Age] = strlen(inputtext);
396 mysql_format(g_SQL, query, sizeof query, "INSERT INTO `players` (`username`, `password`, `salt`, `age`) VALUES ('%e', '%s', '%e', 'd')", Player[playerid][Name], Player[playerid][Password], Player[playerid][Salt], Player[playerid][Age]);
397 new string[128];
398 format(string, sizeof(string), "{AFAFAF}[INFO:] Hai %d anni.", inputtext);
399 SendClientMessage(playerid, COLOR_SYSTEM_INFO, string);
400 ShowPlayerDialog(playerid, DIALOG_REGISTER_SEX, DIALOG_STYLE_LIST, "Seleziona il sesso", "{FF6666}Donna\n{0000cc}Uomo", "Continua", "");
401 }
402 }
403 }
404
405 case DIALOG_REGISTER_SEX:
406 {
407 switch(listitem)// Dialog: registrazione fase 3: sesso
408 {
409 case 0: // Registrazione sesso: selezionato: donna
410 {
411 Player[playerid][Sex] = 1; // 1 = donna
412 new query[221];
413 mysql_format(g_SQL, query, sizeof query, "INSERT INTO `players` (`username`, `password`, `salt`, `age`, `sex`) VALUES ('%e', '%s', '%e', '%d', '%d')", Player[playerid][Name], Player[playerid][Password], Player[playerid][Salt], Player[playerid][Age], Player[playerid][Sex]);
414// mysql_tquery(g_SQL, query, "OnPlayerRegister", "d", playerid);
415 new Messaggio[256];
416 format(Messaggio, sizeof (Messaggio), "[INFO]: %s sei {FF6666}una donna", Player[playerid][Name]);
417 SendClientMessage(playerid, COLOR_SYSTEM_INFO, Messaggio);
418 SendClientMessage(playerid, COLOR_SYSTEM_INFO, "Inserisci una chiave di sicurezza per recuperare la password");
419 ShowPlayerDialog(playerid, DIALOG_REGISTER_RECPASS, d_input, "Registrazione: recupero password", "{AFAFAF}Inserisci un codice per recuperare la password\n{FF0000}Inserisci una stringa sicura in caso di smarrimento password, o furto account", "Continua", "Annulla");
420 }
421 case 1: // Registrazione sesso: selezionato: uomo
422 {
423 Player[playerid][Sex] = 2; // 2 = uomo
424 new query[221];
425 mysql_format(g_SQL, query, sizeof query, "INSERT INTO `players` (`username`, `password`, `salt`, `age`, `sex`) VALUES ('%e', '%s', '%e', '%d', '%d')", Player[playerid][Name], Player[playerid][Password], Player[playerid][Salt], Player[playerid][Age], Player[playerid][Sex]);
426// mysql_tquery(g_SQL, query, "OnPlayerRegister", "d", playerid);
427 new Messaggio[256];
428 format(Messaggio, sizeof (Messaggio), "[INFO]: %s sei {0000cc}un uomo", Player[playerid][Name]);
429 SendClientMessage(playerid, COLOR_SYSTEM_INFO, Messaggio);
430 SendClientMessage(playerid, COLOR_SYSTEM_INFO, "Inserisci una chiave di sicurezza per recuperare la password");
431 ShowPlayerDialog(playerid, DIALOG_REGISTER_RECPASS, d_input, "Registrazione: recupero password", "{AFAFAF}Inserisci un codice per recuperare la password\n{FF0000}Inserisci una stringa sicura in caso di smarrimento password, o furto account", "Continua", "Annulla");
432 }
433 }
434 }
435 case DIALOG_REGISTER_RECPASS:
436 {
437 if (!response) return Kick(playerid);
438
439 if (!strlen(inputtext))
440 {
441 ShowPlayerDialog(playerid, DIALOG_REGISTER_RECPASS, d_input, "Registrazione", "{FF0000}[ERRORE:]Devi inserire un codice di recupero!\n{AFAFAF}Non influenzerà il gioco:", "Continua", "Annulla");
442 return 1;
443 }
444 else if (strlen(inputtext))
445 {
446 new query[221];
447 mysql_format(g_SQL, query, sizeof query, "INSERT INTO `players` (`username`, `password`, `salt`, `age`, `sex`, `recpass`) VALUES ('%e', '%s', '%e', '%s', '%d', '%s')", Player[playerid][Name], Player[playerid][Password], Player[playerid][Salt], Player[playerid][Age], Player[playerid][Sex], inputtext);
448 new string[128];
449 format(string, sizeof (string), "{AFAFAF}[INFO:] Ricorda il tuo codice di recupero è %s", inputtext);
450 SendClientMessage(playerid, COLOR_SYSTEM_INFO, string);
451 format(string, sizeof (string), "{AFAFAF}[INFO:] Se non ricordi la password invia il codice all'email %s per farla resettare", emailserver);
452 SendClientMessage(playerid, COLOR_SYSTEM_INFO, string);
453 mysql_tquery(g_SQL, query, "OnPlayerRegister", "d", playerid);
454 }
455 }
456 default: return 0; // dialog ID was not found, search in other scripts
457 }
458 return 1;
459}
460
461//-----------------------------------------------------
462
463// controllo se una string è numerica
464IsNumeric(const string[])
465{
466 for (new i = 0, j = strlen(string); i < j; i++)
467 {
468 if (string[i] > '9' || string[i] < '0') return 0;
469 }
470 return 1;
471}
472
473forward OnPlayerDataLoaded(playerid, race_check);
474public OnPlayerDataLoaded(playerid, race_check)
475{
476 /* race condition check:
477 player A connects -> SELECT query is fired -> this query takes very long
478 while the query is still processing, player A with playerid 2 disconnects
479 player B joins now with playerid 2 -> our laggy SELECT query is finally finished, but for the wrong player
480 what do we do against it?
481 we create a connection count for each playerid and increase it everytime the playerid connects or disconnects
482 we also pass the current value of the connection count to our OnPlayerDataLoaded callback
483 then we check if current connection count is the same as connection count we passed to the callback
484 if yes, everything is okay, if not, we just kick the player
485 */
486 if (race_check != g_MysqlRaceCheck[playerid]) return Kick(playerid);
487
488 new string[115];
489 if(cache_num_rows() > 0)
490 {
491 // we store the password and the salt so we can compare the password the player inputs
492 // and save the rest so we won't have to execute another query later
493 cache_get_value(0, "password", Player[playerid][Password], 65);
494 cache_get_value(0, "salt", Player[playerid][Salt], 17);
495
496 // saves the active cache in the memory and returns an cache-id to access it for later use
497 Player[playerid][Cache_ID] = cache_save();
498
499 format(string, sizeof string, "%s risulta registrato sul server.\nInserisci la password per entrare:", Player[playerid][Name]);
500 ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Login", string, "Login", "Annulla");
501
502 // from now on, the player has 30 seconds to login
503 Player[playerid][LoginTimer] = SetTimerEx("OnLoginTimeout", SECONDS_TO_LOGIN * 1000, false, "d", playerid);
504 }
505 else
506 {
507 format(string, sizeof string, "Benvenuto %s,\nInserisci una password per iniziare la registrazione:", Player[playerid][Name]);
508 ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Registrazione", string, "Continua", "Annulla");
509 }
510 return 1;
511}
512
513forward OnLoginTimeout(playerid);
514public OnLoginTimeout(playerid)
515{
516 // reset the variable that stores the timerid
517 Player[playerid][LoginTimer] = 0;
518
519 ShowPlayerDialog(playerid, DIALOG_UNUSED, DIALOG_STYLE_MSGBOX, "Login", "Sei stato kickato dal server per aver impiegato troppo tempo nel loggarti.", "Okay", "");
520 DelayedKick(playerid);
521 return 1;
522}
523
524// Timer kick nome no RP
525forward KickTimerNameRP(playerid);
526public KickTimerNameRP(playerid)
527{
528 Kick(playerid);
529}
530
531forward OnPlayerRegister(playerid);
532public OnPlayerRegister(playerid)
533{
534 // retrieves the ID generated for an AUTO_INCREMENT column by the sent query
535 Player[playerid][ID] = cache_insert_id();
536
537 ShowPlayerDialog(playerid, DIALOG_UNUSED, DIALOG_STYLE_MSGBOX, "Registration", "Account successfully registered, you have been automatically logged in.", "Okay", "");
538
539 Player[playerid][IsLoggedIn] = true;
540
541 Player[playerid][X_Pos] = DEFAULT_POS_X;
542 Player[playerid][Y_Pos] = DEFAULT_POS_Y;
543 Player[playerid][Z_Pos] = DEFAULT_POS_Z;
544 Player[playerid][A_Pos] = DEFAULT_POS_A;
545
546 SetSpawnInfo(playerid, NO_TEAM, 0, Player[playerid][X_Pos], Player[playerid][Y_Pos], Player[playerid][Z_Pos], Player[playerid][A_Pos], 0, 0, 0, 0, 0, 0);
547 SpawnPlayer(playerid);
548 return 1;
549}
550
551forward _KickPlayerDelayed(playerid);
552public _KickPlayerDelayed(playerid)
553{
554 Kick(playerid);
555 return 1;
556}
557
558
559//-----------------------------------------------------
560
561AssignPlayerData(playerid)
562{
563 cache_get_value_int(0, "id", Player[playerid][ID]);
564
565 cache_get_value_int(0, "kills", Player[playerid][Kills]);
566 cache_get_value_int(0, "deaths", Player[playerid][Deaths]);
567 cache_get_value_int(0, "admin", Player[playerid][Admin]);
568 cache_get_value_int(0, "sex", Player[playerid][Sex]);
569// cache_get_value_int(0, "age", Player[playerid][Age]);
570 cache_get_value(0, "age", Player[playerid][Age], 65);
571 cache_get_value_float(0, "x", Player[playerid][X_Pos]);
572 cache_get_value_float(0, "y", Player[playerid][Y_Pos]);
573 cache_get_value_float(0, "z", Player[playerid][Z_Pos]);
574 cache_get_value_float(0, "angle", Player[playerid][A_Pos]);
575 cache_get_value_int(0, "interior", Player[playerid][Interior]);
576 return 1;
577}
578
579DelayedKick(playerid, time = 500)
580{
581 SetTimerEx("_KickPlayerDelayed", time, false, "d", playerid);
582 return 1;
583}
584
585SetupPlayerTable()
586{
587 mysql_tquery(g_SQL, "CREATE TABLE IF NOT EXISTS `players` (`id` int(11) NOT NULL AUTO_INCREMENT,`username` varchar(24) NOT NULL,`password` char(64) NOT NULL,`salt` char(16) NOT NULL,`kills` mediumint(8) NOT NULL DEFAULT '0',`deaths` mediumint(8) NOT NULL DEFAULT '0',`x` float NOT NULL DEFAULT '0',`y` float NOT NULL DEFAULT '0',`z` float NOT NULL DEFAULT '0',`angle` float NOT NULL DEFAULT '0',`interior` tinyint(3) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `username` (`username`))");
588 return 1;
589}
590
591UpdatePlayerData(playerid, reason)
592{
593 if (Player[playerid][IsLoggedIn] == false) return 0;
594
595 // if the client crashed, it's not possible to get the player's position in OnPlayerDisconnect callback
596 // so we will use the last saved position (in case of a player who registered and crashed/kicked, the position will be the default spawn point)
597 if (reason == 1)
598 {
599 GetPlayerPos(playerid, Player[playerid][X_Pos], Player[playerid][Y_Pos], Player[playerid][Z_Pos]);
600 GetPlayerFacingAngle(playerid, Player[playerid][A_Pos]);
601 }
602
603 new query[145];
604 mysql_format(g_SQL, query, sizeof query, "UPDATE `players` SET `x` = %f, `y` = %f, `z` = %f, `angle` = %f, `interior` = %d WHERE `id` = %d LIMIT 1", Player[playerid][X_Pos], Player[playerid][Y_Pos], Player[playerid][Z_Pos], Player[playerid][A_Pos], GetPlayerInterior(playerid), Player[playerid][ID]);
605 mysql_tquery(g_SQL, query);
606 return 1;
607}
608
609UpdatePlayerDeaths(playerid)
610{
611 if (Player[playerid][IsLoggedIn] == false) return 0;
612
613 Player[playerid][Deaths]++;
614
615 new query[70];
616 mysql_format(g_SQL, query, sizeof query, "UPDATE `players` SET `deaths` = %d WHERE `id` = %d LIMIT 1", Player[playerid][Deaths], Player[playerid][ID]);
617 mysql_tquery(g_SQL, query);
618 return 1;
619}
620
621UpdatePlayerKills(killerid)
622{
623 // we must check before if the killer wasn't valid (connected) player to avoid run time error 4
624 if (killerid == INVALID_PLAYER_ID) return 0;
625 if (Player[killerid][IsLoggedIn] == false) return 0;
626
627 Player[killerid][Kills]++;
628
629 new query[70];
630 mysql_format(g_SQL, query, sizeof query, "UPDATE `players` SET `kills` = %d WHERE `id` = %d LIMIT 1", Player[killerid][Kills], Player[killerid][ID]);
631 mysql_tquery(g_SQL, query);
632 return 1;
633}
634//-----------------------------------------------------------------------
635// comandi - zcmd
636
637CMD:admin(playerid, params[])
638{
639 if(Player[playerid][Admin] == 0)
640 {
641 SendClientMessage(playerid, COLOR_SYSTEM_ERROR, "asd");
642 return 1;
643 }
644 else if(Player[playerid][Admin] >= 1)
645 {
646 SendClientMessage(playerid, COLOR_SYSTEM_SUCCESS, "123");
647 return 1;
648 }
649 return 1;
650}
651
652CMD:suicidio(playerid, params[])
653{
654 SetPlayerHealth(playerid, 0);
655 return 1;
656}
657
658public OnPlayerRequestClass(playerid,classid)
659{
660 SetPlayerPos(playerid, 982.1890, -1624.2583, 14.9526);
661 SetPlayerFacingAngle(playerid, 90);
662 return 1;
663}