Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <a_samp>
- // change MAX_PLAYERS to the amount of players (slots) you want
- // It is by default 1000 (as of 0.3.7 version)
- #undef MAX_PLAYERS
- #define MAX_PLAYERS 50
- #include <a_mysql>
- #include <zcmd>
- // MySQL configuration
- #define MYSQL_HOST "127.0.0.1"
- #define MYSQL_USER "root"
- #define MYSQL_PASSWORD "Pass123!"
- #define MYSQL_DATABASE "dbrp"
- // colori
- // system color
- #define COLOR_SYSTEM_ERROR 0xAA3333AA
- #define COLOR_SYSTEM_TITLE 0xFFFFFFAA
- #define COLOR_SYSTEM_TEXT 0xFFFFFFAA
- #define COLOR_SYSTEM_SUCCESS 0x33AA33AA
- #define COLOR_SYSTEM_INFO 0xAFAFAFAA
- // how many seconds until it kicks the player for taking too long to login
- #define SECONDS_TO_LOGIN 30
- // default spawn point: Las Venturas (The High Roller)
- #define DEFAULT_POS_X 1958.3783
- #define DEFAULT_POS_Y 1343.1572
- #define DEFAULT_POS_Z 15.3746
- #define DEFAULT_POS_A 270.1425
- // MySQL connection handle
- new MySQL: g_SQL;
- // player data
- enum E_PLAYERS
- {
- ID,
- Name[MAX_PLAYER_NAME],
- 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
- Salt[17],
- Kills,
- Admin,
- Age,
- Sex,
- Deaths,
- Float: X_Pos,
- Float: Y_Pos,
- Float: Z_Pos,
- Float: A_Pos,
- Interior,
- Cache: Cache_ID,
- bool: IsLoggedIn,
- LoginAttempts,
- LoginTimer
- };
- new Player[MAX_PLAYERS][E_PLAYERS];
- new g_MysqlRaceCheck[MAX_PLAYERS];
- // dialog data
- enum
- {
- DIALOG_UNUSED,
- DIALOG_LOGIN,
- DIALOG_REGISTER,
- DIALOG_REGISTER_AGE,
- DIALOG_REGISTER_SEX
- };
- main() {}
- public OnGameModeInit()
- {
- new MySQLOpt: option_id = mysql_init_options();
- mysql_set_option(option_id, AUTO_RECONNECT, true); // it automatically reconnects when loosing connection to mysql server
- g_SQL = mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, option_id); // AUTO_RECONNECT is enabled for this connection handle only
- if (g_SQL == MYSQL_INVALID_HANDLE || mysql_errno(g_SQL) != 0)
- {
- print("MySQL connection failed. Server is shutting down.");
- SendRconCommand("exit"); // close the server if there is no connection
- return 1;
- }
- print("MySQL connection is successful.");
- // if the table has been created, the "SetupPlayerTable" function does not have any purpose so you may remove it completely
- SetupPlayerTable();
- return 1;
- }
- public OnGameModeExit()
- {
- // save all player data before closing connection
- 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
- {
- if (IsPlayerConnected(i))
- {
- // reason is set to 1 for normal 'Quit'
- OnPlayerDisconnect(i, 1);
- }
- }
- mysql_close(g_SQL);
- return 1;
- }
- public OnPlayerConnect(playerid)
- {
- g_MysqlRaceCheck[playerid]++;
- // reset player data
- static const empty_player[E_PLAYERS];
- Player[playerid] = empty_player;
- GetPlayerName(playerid, Player[playerid][Name], MAX_PLAYER_NAME);
- // send a query to recieve all the stored player data from the table
- new query[103];
- mysql_format(g_SQL, query, sizeof query, "SELECT * FROM `players` WHERE `username` = '%e' LIMIT 1", Player[playerid][Name]);
- mysql_tquery(g_SQL, query, "OnPlayerDataLoaded", "dd", playerid, g_MysqlRaceCheck[playerid]);
- return 1;
- }
- public OnPlayerDisconnect(playerid, reason)
- {
- g_MysqlRaceCheck[playerid]++;
- UpdatePlayerData(playerid, reason);
- // if the player was kicked (either wrong password or taking too long) during the login part, remove the data from the memory
- if (cache_is_valid(Player[playerid][Cache_ID]))
- {
- cache_delete(Player[playerid][Cache_ID]);
- Player[playerid][Cache_ID] = MYSQL_INVALID_CACHE;
- }
- // if the player was kicked before the time expires (30 seconds), kill the timer
- if (Player[playerid][LoginTimer])
- {
- KillTimer(Player[playerid][LoginTimer]);
- Player[playerid][LoginTimer] = 0;
- }
- // sets "IsLoggedIn" to false when the player disconnects, it prevents from saving the player data twice when "gmx" is used
- Player[playerid][IsLoggedIn] = false;
- return 1;
- }
- public OnPlayerSpawn(playerid)
- {
- // spawn the player to their last saved position
- SetPlayerInterior(playerid, Player[playerid][Interior]);
- SetPlayerPos(playerid, Player[playerid][X_Pos], Player[playerid][Y_Pos], Player[playerid][Z_Pos]);
- SetPlayerFacingAngle(playerid, Player[playerid][A_Pos]);
- SetCameraBehindPlayer(playerid);
- return 1;
- }
- public OnPlayerDeath(playerid, killerid, reason)
- {
- UpdatePlayerDeaths(playerid);
- UpdatePlayerKills(killerid);
- return 1;
- }
- public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
- {
- switch (dialogid)
- {
- case DIALOG_UNUSED: return 1; // Useful for dialogs that contain only information and we do nothing depending on whether they responded or not
- case DIALOG_LOGIN:
- {
- if (!response) return Kick(playerid);
- new hashed_pass[65];
- SHA256_PassHash(inputtext, Player[playerid][Salt], hashed_pass, 65);
- if (strcmp(hashed_pass, Player[playerid][Password]) == 0)
- {
- //correct password, spawn the player
- ShowPlayerDialog(playerid, DIALOG_UNUSED, DIALOG_STYLE_MSGBOX, "Login", "Login con successo.", "Okay", "");
- // sets the specified cache as the active cache so we can retrieve the rest player data
- cache_set_active(Player[playerid][Cache_ID]);
- AssignPlayerData(playerid);
- // remove the active cache from memory and unsets the active cache as well
- cache_delete(Player[playerid][Cache_ID]);
- Player[playerid][Cache_ID] = MYSQL_INVALID_CACHE;
- KillTimer(Player[playerid][LoginTimer]);
- Player[playerid][LoginTimer] = 0;
- Player[playerid][IsLoggedIn] = true;
- // spawn the player to their last saved position after login
- 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);
- SpawnPlayer(playerid);
- }
- else
- {
- Player[playerid][LoginAttempts]++;
- if (Player[playerid][LoginAttempts] >= 3)
- {
- ShowPlayerDialog(playerid, DIALOG_UNUSED, DIALOG_STYLE_MSGBOX, "Login", "Hai superato i tentativi di accesso (3 tentativi).", "Okay", "");
- DelayedKick(playerid);
- }
- else ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Login", "{FF0000}Password errata!\n{AFAFAF}Inserisci la password per entrare:", "Login", "Annulla");
- }
- }
- case DIALOG_REGISTER:
- {
- if (!response) return Kick(playerid);
- 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");
- // 16 random characters from 33 to 126 (in ASCII) for the salt
- for (new i = 0; i < 16; i++) Player[playerid][Salt][i] = random(94) + 33;
- SHA256_PassHash(inputtext, Player[playerid][Salt], Player[playerid][Password], 65);
- new query[221];
- 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]);
- // mysql_tquery(g_SQL, query, "OnPlayerRegister", "d", playerid);
- ShowPlayerDialog(playerid, DIALOG_REGISTER_AGE, DIALOG_STYLE_INPUT, "Registrazione", "Inserisci l'età che vuoi avere nel server\nNon influenzerà il gioco", "Continua", "Annulla");
- }
- case DIALOG_REGISTER_AGE:
- {
- if (!response) return Kick(playerid);
- 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");
- 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");
- Player[playerid][Age] = strlen(inputtext);
- new query[221];
- 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]);
- ShowPlayerDialog(playerid, DIALOG_REGISTER_SEX, DIALOG_STYLE_LIST, "Seleziona il sesso", "{FF6666}Donna\n{0000cc}Uomo", "Continua", "");
- }
- case DIALOG_REGISTER_SEX:
- {
- switch(listitem)// Dialog: registrazione fase 3: sesso
- {
- case 0: // Registrazione sesso: selezionato: donna
- {
- Player[playerid][Sex] = 1; // 1 = donna
- new query[221];
- 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]);
- mysql_tquery(g_SQL, query, "OnPlayerRegister", "d", playerid);
- new Messaggio[256];
- format(Messaggio, sizeof (Messaggio), "[INFO]: %s sei {FF6666}una donna", Player[playerid][Name]);
- SendClientMessage(playerid, COLOR_SYSTEM_INFO, Messaggio);
- }
- case 1: // Registrazione sesso: selezionato: uomo
- {
- Player[playerid][Sex] = 2; // 2 = uomo
- new query[221];
- 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]);
- mysql_tquery(g_SQL, query, "OnPlayerRegister", "d", playerid);
- new Messaggio[256];
- format(Messaggio, sizeof (Messaggio), "[INFO]: %s sei {0000cc}un uomo", Player[playerid][Name]);
- SendClientMessage(playerid, COLOR_SYSTEM_INFO, Messaggio);
- }
- }
- }
- default: return 0; // dialog ID was not found, search in other scripts
- }
- return 1;
- }
- //-----------------------------------------------------
- // controllo se una string è numerica
- IsNumeric(const string[])
- {
- for (new i = 0, j = strlen(string); i < j; i++)
- {
- if (string[i] > '9' || string[i] < '0') return 0;
- }
- return 1;
- }
- forward OnPlayerDataLoaded(playerid, race_check);
- public OnPlayerDataLoaded(playerid, race_check)
- {
- /* race condition check:
- player A connects -> SELECT query is fired -> this query takes very long
- while the query is still processing, player A with playerid 2 disconnects
- player B joins now with playerid 2 -> our laggy SELECT query is finally finished, but for the wrong player
- what do we do against it?
- we create a connection count for each playerid and increase it everytime the playerid connects or disconnects
- we also pass the current value of the connection count to our OnPlayerDataLoaded callback
- then we check if current connection count is the same as connection count we passed to the callback
- if yes, everything is okay, if not, we just kick the player
- */
- if (race_check != g_MysqlRaceCheck[playerid]) return Kick(playerid);
- new string[115];
- if(cache_num_rows() > 0)
- {
- // we store the password and the salt so we can compare the password the player inputs
- // and save the rest so we won't have to execute another query later
- cache_get_value(0, "password", Player[playerid][Password], 65);
- cache_get_value(0, "salt", Player[playerid][Salt], 17);
- // saves the active cache in the memory and returns an cache-id to access it for later use
- Player[playerid][Cache_ID] = cache_save();
- format(string, sizeof string, "%s risulta registrato sul server.\nInserisci la password per entrare:", Player[playerid][Name]);
- ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Login", string, "Login", "Annulla");
- // from now on, the player has 30 seconds to login
- Player[playerid][LoginTimer] = SetTimerEx("OnLoginTimeout", SECONDS_TO_LOGIN * 1000, false, "d", playerid);
- }
- else
- {
- format(string, sizeof string, "Benvenuto %s,\nInserisci una password per iniziare la registrazione:", Player[playerid][Name]);
- ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Registrazione", string, "Continua", "Annulla");
- }
- return 1;
- }
- forward OnLoginTimeout(playerid);
- public OnLoginTimeout(playerid)
- {
- // reset the variable that stores the timerid
- Player[playerid][LoginTimer] = 0;
- ShowPlayerDialog(playerid, DIALOG_UNUSED, DIALOG_STYLE_MSGBOX, "Login", "Sei stato kickato dal server per aver impiegato troppo tempo nel loggarti.", "Okay", "");
- DelayedKick(playerid);
- return 1;
- }
- forward OnPlayerRegister(playerid);
- public OnPlayerRegister(playerid)
- {
- // retrieves the ID generated for an AUTO_INCREMENT column by the sent query
- Player[playerid][ID] = cache_insert_id();
- ShowPlayerDialog(playerid, DIALOG_UNUSED, DIALOG_STYLE_MSGBOX, "Registration", "Account successfully registered, you have been automatically logged in.", "Okay", "");
- Player[playerid][IsLoggedIn] = true;
- Player[playerid][X_Pos] = DEFAULT_POS_X;
- Player[playerid][Y_Pos] = DEFAULT_POS_Y;
- Player[playerid][Z_Pos] = DEFAULT_POS_Z;
- Player[playerid][A_Pos] = DEFAULT_POS_A;
- 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);
- SpawnPlayer(playerid);
- return 1;
- }
- forward _KickPlayerDelayed(playerid);
- public _KickPlayerDelayed(playerid)
- {
- Kick(playerid);
- return 1;
- }
- //-----------------------------------------------------
- AssignPlayerData(playerid)
- {
- cache_get_value_int(0, "id", Player[playerid][ID]);
- cache_get_value_int(0, "kills", Player[playerid][Kills]);
- cache_get_value_int(0, "deaths", Player[playerid][Deaths]);
- cache_get_value_int(0, "admin", Player[playerid][Admin]);
- cache_get_value_int(0, "sex", Player[playerid][Sex]);
- cache_get_value_int(0, "age", Player[playerid][Age]);
- cache_get_value_float(0, "x", Player[playerid][X_Pos]);
- cache_get_value_float(0, "y", Player[playerid][Y_Pos]);
- cache_get_value_float(0, "z", Player[playerid][Z_Pos]);
- cache_get_value_float(0, "angle", Player[playerid][A_Pos]);
- cache_get_value_int(0, "interior", Player[playerid][Interior]);
- return 1;
- }
- DelayedKick(playerid, time = 500)
- {
- SetTimerEx("_KickPlayerDelayed", time, false, "d", playerid);
- return 1;
- }
- SetupPlayerTable()
- {
- 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`))");
- return 1;
- }
- UpdatePlayerData(playerid, reason)
- {
- if (Player[playerid][IsLoggedIn] == false) return 0;
- // if the client crashed, it's not possible to get the player's position in OnPlayerDisconnect callback
- // 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)
- if (reason == 1)
- {
- GetPlayerPos(playerid, Player[playerid][X_Pos], Player[playerid][Y_Pos], Player[playerid][Z_Pos]);
- GetPlayerFacingAngle(playerid, Player[playerid][A_Pos]);
- }
- new query[145];
- 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]);
- mysql_tquery(g_SQL, query);
- return 1;
- }
- UpdatePlayerDeaths(playerid)
- {
- if (Player[playerid][IsLoggedIn] == false) return 0;
- Player[playerid][Deaths]++;
- new query[70];
- mysql_format(g_SQL, query, sizeof query, "UPDATE `players` SET `deaths` = %d WHERE `id` = %d LIMIT 1", Player[playerid][Deaths], Player[playerid][ID]);
- mysql_tquery(g_SQL, query);
- return 1;
- }
- UpdatePlayerKills(killerid)
- {
- // we must check before if the killer wasn't valid (connected) player to avoid run time error 4
- if (killerid == INVALID_PLAYER_ID) return 0;
- if (Player[killerid][IsLoggedIn] == false) return 0;
- Player[killerid][Kills]++;
- new query[70];
- mysql_format(g_SQL, query, sizeof query, "UPDATE `players` SET `kills` = %d WHERE `id` = %d LIMIT 1", Player[killerid][Kills], Player[killerid][ID]);
- mysql_tquery(g_SQL, query);
- return 1;
- }
- //-----------------------------------------------------------------------
- // comandi - zcmd
- CMD:admin(playerid, params[])
- {
- if(Player[playerid][Admin] == 0)
- {
- SendClientMessage(playerid, COLOR_SYSTEM_ERROR, "asd");
- return 1;
- }
- else if(Player[playerid][Admin] >= 1)
- {
- SendClientMessage(playerid, COLOR_SYSTEM_SUCCESS, "123");
- return 1;
- }
- return 1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement