#include <a_samp> #include <YSI\y_ini> main( ) { } //======= DEFINITIONS ========= //Registration System #define PATH "/Accounts/%s.ini" #define DIALOG_REGISTER 1 #define DIALOG_LOGIN 2 #define DIALOG_SUCCESS_1 3 #define DIALOG_SUCCESS_2 4 #define COL_WHITE "{FFFFFF}" #define COL_RED "{F81414}" #define COL_GREEN "{00FF22}" #define COL_LIGHTBLUE "{00CED1}" //--------------------------- //====== END OF DEFINITIONS ========= //========= ENUMS ============= //Registration System enum pInfo { pPass, pCash, pAdmin, pKills, pDeaths } new PlayerInfo[MAX_PLAYERS][pInfo]; //-------------------------------------- //======== END OF ENUMS ========= //======== FUNCTIONS ======================== //Registration System forward LoadUser_data(playerid,name[],value[]); public LoadUser_data(playerid,name[],value[]) { INI_Int("Password",PlayerInfo[playerid][pPass]); INI_Int("Cash",PlayerInfo[playerid][pCash]); INI_Int("Admin",PlayerInfo[playerid][pAdmin]); INI_Int("Kills",PlayerInfo[playerid][pKills]); INI_Int("Deaths",PlayerInfo[playerid][pDeaths]); return 1; } //--------------------------------- //========== END OF FUNCTIONS =============== //========== STOCKS ============== //REGISTRATION SYSTEM stock UserPath(playerid) { new string[128],playername[MAX_PLAYER_NAME]; GetPlayerName(playerid,playername,sizeof(playername)); format(string,sizeof(string),PATH,playername); return string; } /*Credits to Dracoblue*/ stock udb_hash(buf[]) { new length=strlen(buf); new s1 = 1; new s2 = 0; new n; for (n=0; n<length; n++) { s1 = (s1 + buf[n]) % 65521; s2 = (s2 + s1) % 65521; } return (s2 << 16) + s1; } //-------------------------------------- //============= END OF STOCKS ================= public OnGameModeInit() { // Don't use these lines if it's a filterscript SetGameModeText("Life of Fort Carson"); AddPlayerClass(76,-177.3635,1110.9661,19.7422,132.1115,0,0,0,0,0,0); // FORTCARSONSPAWN return 1; } public OnGameModeExit() { return 1; } public OnPlayerRequestClass(playerid, classid) { SetPlayerPos(playerid, -199.6335, 1104.6046, 19.5938); SetPlayerCameraPos(playerid, -193.4531, 1101.3687, 19.5938); SetPlayerCameraLookAt(playerid, -196.6335, 1103.3114, 19.5938); return 1; } public OnPlayerConnect(playerid) { if(fexist(UserPath(playerid))) { new pname[MAX_PLAYER_NAME], string[22 + MAX_PLAYER_NAME]; GetPlayerName(playerid, pname, sizeof(pname)); format(string, sizeof(string), "%s has joined the server", pname); SendClientMessageToAll(0xAAAAAAAA, string); INI_ParseFile(UserPath(playerid), "LoadUser_%s", .bExtra = true, .extra = playerid); ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_INPUT,""COL_WHITE"Login",""COL_WHITE"Type your password below to login.","Login","Quit"); } else { ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_INPUT,""COL_WHITE"Registering...",""COL_WHITE"Type your password below to register a new account.","Register","Quit"); } return 1; } public OnPlayerDisconnect(playerid, reason) { new INI:File = INI_Open(UserPath(playerid)); INI_SetTag(File,"data"); INI_WriteInt(File,"Cash",GetPlayerMoney(playerid)); INI_WriteInt(File,"Admin",PlayerInfo[playerid][pAdmin]); INI_WriteInt(File,"Kills",PlayerInfo[playerid][pKills]); INI_WriteInt(File,"Deaths",PlayerInfo[playerid][pDeaths]); INI_Close(File); new pname[MAX_PLAYER_NAME], string[39 + MAX_PLAYER_NAME]; GetPlayerName(playerid, pname, sizeof(pname)); switch(reason) { case 0: format(string, sizeof(string), "%s has left the server. (Lost Connection)", pname); case 1: format(string, sizeof(string), "%s has left the server. (Leaving)", pname); case 2: format(string, sizeof(string), "%s has left the server. (Kicked)", pname); } SendClientMessageToAll(0xAAAAAAAA, string); return 1; } public OnPlayerSpawn(playerid) { return 1; } public OnPlayerDeath(playerid, killerid, reason) { PlayerInfo[killerid][pKills]++; PlayerInfo[playerid][pDeaths]++; return 1; } public OnVehicleSpawn(vehicleid) { return 1; } public OnVehicleDeath(vehicleid, killerid) { return 1; } public OnPlayerText(playerid, text[]) { return 1; } public OnPlayerCommandText(playerid, cmdtext[]) { if (strcmp("/savemyshit", cmdtext, true, 10) == 0) { new INI:File = INI_Open(UserPath(playerid)); INI_SetTag(File,"data"); INI_WriteInt(File,"Cash",GetPlayerMoney(playerid)); INI_WriteInt(File,"Admin",PlayerInfo[playerid][pAdmin]); INI_WriteInt(File,"Kills",PlayerInfo[playerid][pKills]); INI_WriteInt(File,"Deaths",PlayerInfo[playerid][pDeaths]); INI_Close(File); SendClientMessage(playerid, 0x00FF00FF, "SAVEMYSHIT WORKS!"); return 1; } return 0; } public OnPlayerEnterVehicle(playerid, vehicleid, ispassenger) { return 1; } public OnPlayerExitVehicle(playerid, vehicleid) { return 1; } public OnPlayerStateChange(playerid, newstate, oldstate) { return 1; } public OnPlayerEnterCheckpoint(playerid) { return 1; } public OnPlayerLeaveCheckpoint(playerid) { return 1; } public OnPlayerEnterRaceCheckpoint(playerid) { return 1; } public OnPlayerLeaveRaceCheckpoint(playerid) { return 1; } public OnRconCommand(cmd[]) { return 1; } public OnPlayerRequestSpawn(playerid) { return 1; } public OnObjectMoved(objectid) { return 1; } public OnPlayerObjectMoved(playerid, objectid) { return 1; } public OnPlayerPickUpPickup(playerid, pickupid) { return 1; } public OnVehicleMod(playerid, vehicleid, componentid) { return 1; } public OnVehiclePaintjob(playerid, vehicleid, paintjobid) { return 1; } public OnVehicleRespray(playerid, vehicleid, color1, color2) { return 1; } public OnPlayerSelectedMenuRow(playerid, row) { return 1; } public OnPlayerExitedMenu(playerid) { return 1; } public OnPlayerInteriorChange(playerid, newinteriorid, oldinteriorid) { return 1; } public OnPlayerKeyStateChange(playerid, newkeys, oldkeys) { return 1; } public OnRconLoginAttempt(ip[], password[], success) { return 1; } public OnPlayerUpdate(playerid) { return 1; } public OnPlayerStreamIn(playerid, forplayerid) { return 1; } public OnPlayerStreamOut(playerid, forplayerid) { return 1; } public OnVehicleStreamIn(vehicleid, forplayerid) { return 1; } public OnVehicleStreamOut(vehicleid, forplayerid) { return 1; } public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]) { switch( dialogid ) { case DIALOG_REGISTER: { if (!response) return Kick(playerid); if(response) { if(!strlen(inputtext)) return ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_INPUT, ""COL_WHITE"Registering...",""COL_RED"You have entered an invalid password.\n"COL_WHITE"Type your password below to register a new account.","Register","Quit"); new INI:File = INI_Open(UserPath(playerid)); INI_SetTag(File,"data"); INI_WriteInt(File,"Password",udb_hash(inputtext)); INI_WriteInt(File,"Cash",0); INI_WriteInt(File,"Admin",0); INI_WriteInt(File,"Kills",0); INI_WriteInt(File,"Deaths",0); INI_Close(File); SetSpawnInfo(playerid, 0, 0, -177.36, 1110.96, 19.74, 132.11, 0, 0, 0, 0, 0, 0); //SpawnPlayer(playerid); ShowPlayerDialog(playerid, DIALOG_SUCCESS_1, DIALOG_STYLE_MSGBOX,""COL_WHITE"Welcome to Fort Carson",""COL_GREEN"Thank you for registering your database","Ok",""); } } case DIALOG_LOGIN: { if ( !response ) return Kick ( playerid ); if( response ) { if(udb_hash(inputtext) == PlayerInfo[playerid][pPass]) { INI_ParseFile(UserPath(playerid), "LoadUser_%s", .bExtra = true, .extra = playerid); GivePlayerMoney(playerid, PlayerInfo[playerid][pCash]); ShowPlayerDialog(playerid, DIALOG_SUCCESS_2, DIALOG_STYLE_MSGBOX,""COL_WHITE"Success!",""COL_GREEN"You have successfully logged in!","Ok",""); } else { ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_INPUT,""COL_WHITE"Login",""COL_RED"You have entered an incorrect password.\n"COL_WHITE"Type your password below to login.","Login","Quit"); } return 1; } } } return 1; } public OnPlayerClickPlayer(playerid, clickedplayerid, source) { return 1; }
public OnPlayerCommandText(playerid, cmdtext[]) { if (strcmp("/savemyshit", cmdtext, true, 10) == 0) { new INI:File = INI_Open(UserPath(playerid)); INI_SetTag(File,"data"); INI_WriteInt(File,"Cash",GetPlayerMoney(playerid)); INI_WriteInt(File,"Admin",PlayerInfo[playerid][pAdmin]); INI_WriteInt(File,"Kills",PlayerInfo[playerid][pKills]); INI_WriteInt(File,"Deaths",PlayerInfo[playerid][pDeaths]); INI_Close(File); SendClientMessage(playerid, 0x00FF00FF, "SAVEMYSHIT WORKS!"); return 1; } return 0; }
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. |
#define PATH "/Accounts/%s.ini"
#define PATH "[database name].db
new DB: gSQL;
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!!
}
}
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. |
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)");
public OnGameModeExit() {
db_close(gSQL);
}
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;
}
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;
}
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;
}
public OnPlayerConnect(playerid) { if(fexist(UserPath(playerid))) { new pname[MAX_PLAYER_NAME], string[22 + MAX_PLAYER_NAME]; GetPlayerName(playerid, pname, sizeof(pname)); format(string, sizeof(string), "%s has joined the server", pname); SendClientMessageToAll(0xAAAAAAAA, string); INI_ParseFile(UserPath(playerid), "LoadUser_data", .bExtra = true, .extra = playerid); ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_INPUT,""COL_WHITE"Login",""COL_WHITE"Type your password below to login.","Login","Quit"); } else { ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_INPUT,""COL_WHITE"Registering...",""COL_WHITE"Type your password below to register a new account.","Register","Quit"); } return 1; }
//Edited LoadUser_%s to LoadUser_data