04.05.2018, 05:54
(
Последний раз редактировалось Logic_; 04.05.2018 в 06:44.
)
Quote:
This question has been asked countless amounts of time. Using Dini is a mistake since it's very poorly slow and was made just to ease out to work with files, but later we got to see SQLite implementation and MySQL plugins in SA-MP.
Many people go forward to learn different saving systems rather than SQL because they think it's hard or useless, whereas SQL is a different language. It's not something that you'll just use in your SA-MP modifications, but also when you work with web development, and other projects. SQL provides database relations and so much features, that it's something that you should use as a saving system rather than other INI/ file based solutions that are not just slower, but also come up with bugs and other issues. For example, if you need help with a INI file, many people would just give their guesses but if you get stuck with SQL, you will not just find SA-MP forum to help you with that, but also different websites and communities. Also, there's no fast way to convert anything to a different saving system, take your time and do your changes slowly since you're new to it. Put your time in learning it and adapting your script to it and to be just dependent of it. SQLite is a built-in native implementation in SA-MP server and it doesn't require a SQL server to store the database, it saves it in scriptfiles folder. Whereas MySQL requires use of external plugins and is way faster than SQLite, for it's own reasons. MySQL allows you to show your data on your websites incase if you want to have a UCP or something similar. SQLite also provides this feature but your server and website should be on one machine. SQLite in my opinion is an overkill for SA-MP. So you should just stick to it if you don't want to go for MySQL. I've built lots of Call of Duty TDM scripts, some roleplay and I've sticked to SQLite for most of them since they are just enough and you won't need MySQL unless you want your project to be Hi-Fi. |
1. First part: Making database stuff
Modify your PATH definition to your database path.
PHP код:
#define PATH "/Accounts/%s.ini"
PHP код:
#define PATH "[database name].db
Once that's done, create a global variable at the top of the script, for example:
PHP код:
new DB: gSQL;
Now, moving towards OnGameModeInit, make a database connection here:
PHP код:
public OnGameModeInit() {
if((gSQL = db_open(PATH) == DB: 0) { // Opens a database connection with the path specified and assigns the connection ID to the variable "gSQL", then we compare the connection ID with ID 0, if both matches means that the database connection wasn't successful
// database failed creating! you might want to close your server or lock it
}
else {
// successful! now you can create a table! that table mentioned below comes here!!
}
}
Quote:
a table is a set of data elements (values) using a model of vertical columns (identifiable by name) and horizontal rows, the cell being the unit where a row and column intersect. A table has a specified number of columns, but can have any number of rows. |
PHP код:
db_query(gSQL, "CREATE TABLE IF NOT EXISTS `Users` (`userid` INTEGER PRIMARY KEY AUTOINCREMENT, `username` VARCHAR(24) COLLATE NOCASE, `password` VARCHAR(65), `admin` INTEGER DEFAULT 0)");
Now under OnGameModeExit, we'll close the database connection by using db_close. So your code will look like:
PHP код:
public OnGameModeExit() {
db_close(gSQL);
}
2. Register/ Login system
Now your OnPlayerConnect will be modified:
PHP код:
public OnPlayerConnect(playerid) {
new EMPTY_PINFO[pInfo];
PlayerInfo[playerid] = EMPTY_PINFO; // We cleaned the PlayerInfo array
new query[128], name[MAX_PLAYER_NAME], DBResult: result;
GetPlayerName(playerid, name, sizeof name); // fetched player name
format(query, sizeof query, "%s has joined the server", name);
SendClientMessageToAll(-1, query);
format(query, sizeof query, "SELECT COUNT(*) FROM `Users` WHERE `username` = '%q'", name); // we ran a query to select the number of accounts registered with player's name.
result = db_query(gSQL, query); // execute the query and save the result in the variable
if(db_num_rows(result)) { // this means that rows/ entries with that name are found
ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_INPUT,""COL_WHITE"Login",""COL_WHITE"Type your password below to login.","Login","Quit");
}
else { // not found any entries/ rows with that name.
ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_INPUT,""COL_WHITE"Registering...",""COL_WHITE"Type your password below to register a new account.","Register","Quit");
}
db_free_result(result); // free the result to avoid memory leaks.
return 1;
}
PHP код:
LoginPlayer(playerid) {
new query[128], name[MAX_PLAYER_NAME], DBResult: result;
GetPlayerName(playerid, name, sizeof name);
format(query, sizeof query, "SELECT * FROM `Users` WHERE `username` = '%q'", name); // Select everything from table called Users where username is equal to player-name
result = db_query(gSQL, query);
if (db_num_rows(result)) {
PlayerInfo[playerid][UserKey] = db_get_field_assoc_int(result, "userid");
PlayerInfo[playerid][UserAdmin] = db_get_field_assoc_int(result, "admin");
db_get_field_assoc(result, "password", PlayerInfo[playerid][UserPassword], 65);
// other stats... The fields must be present in the table too, otherwise they are not going to load!
}
db_free_result(result);
return 1;
}
PHP код:
RegisterPlayer(playerid, password[]) {
new query[128], name[MAX_PLAYER_NAME];
GetPlayerName(playerid, name, sizeof name);
format(query, sizeof query, "INSERT INTO `Users` (`username`, `password`) VALUES('%q', '%q')", name, password); // Insert into table Users with data for username and password
db_query(gSQL, query);
return 1;
}