SA-MP Forums Archive
[Include] [INC] SII 2.0.6 - Fast cache based INI Reader/Writer - Printable Version

+- SA-MP Forums Archive (https://sampforum.blast.hk)
+-- Forum: SA-MP Scripting and Plugins (https://sampforum.blast.hk/forumdisplay.php?fid=8)
+--- Forum: Filterscripts (https://sampforum.blast.hk/forumdisplay.php?fid=17)
+---- Forum: Includes (https://sampforum.blast.hk/forumdisplay.php?fid=83)
+---- Thread: [Include] [INC] SII 2.0.6 - Fast cache based INI Reader/Writer (/showthread.php?tid=58458)

Pages: 1 2


[INC] SII 2.0.6 - Fast cache based INI Reader/Writer - [DRuG]Slick - 18.12.2008

Slick's INI Include 2.0.6


I have decided to release an include of mine for reading/writing INI files. I wrote it some time ago after want of a faster solution than DINI. Rather than change to DJSON I still wanted to use INI files because they are simple and clean, and so this script was born.

Slick's INI Include works using a complete cache system that does all its manipulation in memory. When a file is opened, its transferred to memory where data can be read/written, deleted, etc and then wrote all back to the file when finished. Rather than opening/parsing/closing a file each time you want to access a entry. This means it is very fast.


Features
Benchmark
I performed some benchmarks using SII, DINI and the raw file functions. There were two tests performed over a number of times with the average results shown here. The first test involved creating a file, writing a key with a value and then removing the file. The second test did the same thing but with a mass number of entries being written which is where other solutions like DINI really begin to show their dull colours.

As you can see, SII is almost as fast as using the raw file functions on their own, around a 5 millisecond difference to be exact.


Tutorial
Basic player accounts with SII and DCMD
pawn Code:
#include <a_samp>
#include <SII> // Include SII.inc

#define dcmd(%1,%2,%3) if (!strcmp((%3)[1], #%1, true, (%2)) && ((((%3)[(%2) + 1] == '\0') && (dcmd_%1(playerid, ""))) || (((%3)[(%2) + 1] == ' ') && (dcmd_%1(playerid, (%3)[(%2) + 2]))))) return 1

new player_name[MAX_PLAYERS][MAX_PLAYER_NAME];
new bool: player_loggedin[MAX_PLAYERS];

main()
{

}

public OnGameModeInit()
{
    AddPlayerClass(0, 1958.3783, 1343.1572, 15.3746, 269.1425, 0, 0, 0, 0, 0, 0);
    return 1;
}

public OnPlayerConnect(playerid)
{
    GetPlayerName(playerid, player_name[playerid], MAX_PLAYER_NAME);
    return 1;
}

public OnPlayerDisconnect(playerid)
{
    player_loggedin[playerid] = false;
    return 1;
}

public OnPlayerCommandText(playerid, cmdtext[])
{
    dcmd(register, 8, cmdtext);
    dcmd(login, 5, cmdtext);
    return 0;
}

dcmd_register(playerid, params[])
{
    if (player_loggedin[playerid]) // Player is already registered and logged in
    {
        SendClientMessage(playerid, 0x0040FFAA, "You are already registered and logged in.");
        return 1;
    }
    else if (!params[0]) // No password was specified
    {
        SendClientMessage(playerid, 0x0040FFAA, "Usage: /register [password]");
        return 1;
    }
    else if (INI_Open("Users.ini")) // Try open "Users.ini"
    {
        new password[128];
        if (INI_ReadString(password, player_name[playerid], MAX_PLAYER_NAME)) // Is player already registered?
        {
            SendClientMessage(playerid, 0x0040FFAA, "You are already registred, please /login.");
        }
        else // Register player
        {
            INI_WriteString(player_name[playerid], params);
            SendClientMessage(playerid, 0x0040FFAA, "Registration successful.");
        }
        INI_Save(); // Save all the data we have written to "Users.ini"
        INI_Close(); // Remember to close open files when finished
        return 1;
    }
    SendClientMessage(playerid, 0x0040FFAA, "Registration failed."); // There was an error opening "Users.ini"
    return 1;
}

dcmd_login(playerid, params[])
{
    if (player_loggedin[playerid]) // Player is already logged in
    {
        SendClientMessage(playerid, 0x0040FFAA, "You are already logged in.");
        return 1;
    }
    else if (!params[0]) // No password was specified
    {
        SendClientMessage(playerid, 0x0040FFAA, "Usage: /login [password]");
        return 1;
    }
    else if (INI_Open("Users.ini")) // Try open "Users.ini"
    {
        new password[128];
        if (INI_ReadString(password, player_name[playerid], MAX_PLAYER_NAME)) // Read players data (if it exists)
        {
            if (!strcmp(password, params, false)) // Login player
            {
                player_loggedin[playerid] = true;
                SendClientMessage(playerid, 0x0040FFAA, "Login successful.");
            }
            else // Incorrect password
            {
                SendClientMessage(playerid, 0x0040FFAA, "Incorrect Password.");
            }
        }
        else // No data was found for the player
        {
            SendClientMessage(playerid, 0x0040FFAA, "Please /register first.");
        }
        INI_Close(); // Remember to close open files when finished, no need to save this time
        return 1;
    }
    SendClientMessage(playerid, 0x0040FFAA, "Login failed."); // There was an error opening "Users.ini"
    return 1;
}

// Other functions include INI_Exists("filename"), INI_WriteInt("key", value), INI_WriteFloat("key", Float: value),
// value = INI_ReadInt("key"), Float: value = INI_ReadFloat("key"), INI_RemoveEntry("key") and INI_Remove("filename").

Download (updated link)


Please post feedback and any bugs if you find them..
Enjoy


Re: Slick's INI Implementation 2.0.6 - Very fast cache based INI Reader/Writer - Jason_Gregory - 18.12.2008

Wow looks nice dude gonna Test it soon.Are u sure about the Backward Compatbilty =?


Re: SII 2.0.6 - Fast cache based INI Reader/Writer - [DRuG]Slick - 18.12.2008

Yep compatibly with DINI and most other INI files is supported


Re: SII 2.0.6 - Fast cache based INI Reader/Writer - [DRuG]Slick - 18.12.2008

Sorry I should have explained it better.

When INI_Open is called, the file is parsed to memory. Now lets say you use INI_WriteString to add some data (a line), it will write to memory, not the file. Only when you call INI_Save will everything be written back to the original file. Then lastly, you would call INI_Close which frees up memory ready for opening again (doesn't touch the file). So the only time the physical file is accessed is during INI_Open and INI_Save.

Hope that helped

EDIT: I redone the first post with a tutorial demonstrating a basic accounts system


Re: [INC] SII 2.0.6 - Fast cache based INI Reader/Writer - Antironix - 19.12.2008

Quote:
Originally Posted by [DRuG
Slick ]
Sorry I should have explained it better.

When INI_Open is called, the file is parsed to memory. Now lets say you use INI_WriteString to add some data (a line), it will write to memory, not the file. Only when you call INI_Save will everything be written back to the original file. Then lastly, you would call INI_Close which frees up memory ready for opening again (doesn't touch the file). So the only time the physical file is accessed is during INI_Open and INI_Save.

Hope that helped

EDIT: I redone the first post with a tutorial demonstrating a basic accounts system
I guess you can also open every file on startup and write during the game to the memory, also reading from it. And when the game ends, it writes everything.

With game I mean calling OnGameModeInit and OnGameModeExit.


Re: [INC] SII 2.0.6 - Fast cache based INI Reader/Writer - Mazza101 - 23.12.2008

Problem with mine atm.

Pawn:
Code:
	ownCar1owner = INI_ReadString("ownCar1owner");
		x = INI_ReadFloat("ownCar1x");
		y = INI_ReadFloat("ownCar1y");
		z = INI_ReadFloat("ownCar1z");
		f = INI_ReadFloat("ownCar1f");
		ownCar1 = AddStaticVehicle(560, x, y, z, f, 6, 0);

		ownCar2owner = INI_ReadString("ownCar2owner");
		x = INI_ReadFloat("ownCar2x");
		y = INI_ReadFloat("ownCar2y");
		z = INI_ReadFloat("ownCar2z");
		f = INI_ReadFloat("ownCar2f");
		ownCar2 = AddStaticVehicle(561, x, y, z, f, 6, 0);
Ini:
Code:
ownCar1owner=None
ownCar1x=1098
ownCar1y=-1774
ownCar1z=13.4
ownCar1f=268

ownCar2owner=None
ownCar2x=1098
ownCar2y=-1768
ownCar2z=13.4
ownCar2f=268
That is spawning the vehicle, but the first one faces the wrong direction and the second one is in completely the wrong place. Any ideas? (I've checked these co-ordinates and they're right).


Re: [INC] SII 2.0.6 - Fast cache based INI Reader/Writer - KillFrenzy - 24.12.2008

Code:
ownCar1owner=None
ownCar1x=1098
ownCar1y=-1774
ownCar1z=13.4
ownCar1f=268

ownCar2owner=None
ownCar2x=1098
ownCar2y=-1768
ownCar2z=13.4
ownCar2f=268
As far as I know, floats must not be alone, like, they must have a .0 on the end of it - otherwise are read as 0 - same for converting any other string to a float. So you should try changing that to this:
Code:
ownCar1owner=None
ownCar1x=1098.0
ownCar1y=-1774.0
ownCar1z=13.4
ownCar1f=268.0

ownCar2owner=None
ownCar2x=1098.0
ownCar2y=-1768.0
ownCar2z=13.4
ownCar2f=268.0

Also.. this part is wrong...
Code:
ownCar1owner = INI_ReadString("ownCar1owner");
Code:
ownCar2owner = INI_ReadString("ownCar2owner");
> stock INI_ReadString(dest[], const key[], maxlength = sizeof(dest))
You're using it wrong. Rather, It'd be:
Code:
INI_ReadString(ownCar1owner, "ownCar1owner");
Code:
INI_ReadString(ownCar2owner, "ownCar2owner");
Specify the size of the destination string if needed.


Oh yeah, if you're using it to store vehicles in that fashion, I'd suggest you increase the amount of lines, and store the XYZR like this, split using your own code by commas:
Code:
ownCar1pos=1098.0,-1774.0,13.4268.0,268.0
That results in a smaller file, and possibly even faster read/write speeds.


I've used SII for my entire gamemode - as far as I know, everything works perfectly.


Re: [INC] SII 2.0.6 - Fast cache based INI Reader/Writer - Mazza101 - 24.12.2008

That still doesn't seem to work :S

EDIT: Those new string commands bring up an Argument mismatch error.
EDIT2: They cars spawn fine as long as I don't have the string stuff in there?

Works:
Code:
		new float:x, float:y, float:z, float:f;
		
		//INI_ReadString(ownCar1owner, "ownCar1owner");
		x = INI_ReadFloat("ownCar1x");
		y = INI_ReadFloat("ownCar1y");
		z = INI_ReadFloat("ownCar1z");
		f = INI_ReadFloat("ownCar1f");
		ownCar1 = AddStaticVehicle(560, x, y, z, f, 6, 0);
		
		//INI_ReadString(ownCar2owner, "ownCar2owner");
		x = INI_ReadFloat("ownCar2x");
		y = INI_ReadFloat("ownCar2y");
		z = INI_ReadFloat("ownCar2z");
		f = INI_ReadFloat("ownCar2f");
		ownCar2 = AddStaticVehicle(561, x, y, z, f, 6, 0);



Re: [INC] SII 2.0.6 - Fast cache based INI Reader/Writer - KillFrenzy - 24.12.2008

> EDIT: Those new string commands bring up an Argument mismatch error.
I was assuming the variables 'ownCar1owner' and 'ownCar2owner' were strings, since a string is what you're reading. Right now, you have declared them as a normal integer - therefore an argument type mismatch.


Re: [INC] SII 2.0.6 - Fast cache based INI Reader/Writer - Mazza101 - 24.12.2008

Got it all working, thanks


Re: [INC] SII 2.0.6 - Fast cache based INI Reader/Writer - [DRuG]Slick - 24.12.2008

Quote:
Originally Posted by Wadabak
I guess you can also open every file on startup and write during the game to the memory, also reading from it. And when the game ends, it writes everything.

With game I mean calling OnGameModeInit and OnGameModeExit.
Not quite, you can only have one file open at a time, which is why you don't need file ID's. That's why I recommend you lay out your code similar to:
pawn Код:
if (INI_Open("filename"))
{
    // Functions here
    INI_Close();
}
To ensure any reading/writing functions don't get called if the file could not be opened. While this won't cause any direct problems, in a rare situation you might find you start manipulating data from another file that has been opened.

Glad to see you got it working Mazza101


Re: [INC] SII 2.0.6 - Fast cache based INI Reader/Writer - MX_Master - 01.05.2009

i like it, but can you add a "sections" support? If you do this it will be the best INI include ever i seen


Re: [INC] SII 2.0.6 - Fast cache based INI Reader/Writer - Goldkiller - 01.05.2009

Works fine and is really easy to use.I'm going to use it for my Admin script .
I added some extra functions because I thought they might be usefull,at least if you change from DINI to SII .

>> pastebin<<


Re: [INC] SII 2.0.6 - Fast cache based INI Reader/Writer - [DRuG]Slick - 03.05.2009

Whoa awesome to see people using it after all this time I did actually start writing an updated version some time ago, seeing you guys are interested is the boost I needed to finish it, stay tuned!


Re: [INC] SII 2.0.6 - Fast cache based INI Reader/Writer - MX_Master - 04.05.2009

Quote:
Originally Posted by [DRuG
Slick ]
Whoa awesome to see people using it after all this time I did actually start writing an updated version some time ago, seeing you guys are interested is the boost I needed to finish it, stay tuned!
great, i hope we'll see something special )


Re: [INC] SII 2.0.6 - Fast cache based INI Reader/Writer - Weirdosport - 04.05.2009

How does this compare in terms of speed with DJSon, I know that they write the information in different ways, but as it's not me that reads the INI's and rather the computer, I don't really care >.> As long as the computer's happy, I am too.


Re: [INC] SII 2.0.6 - Fast cache based INI Reader/Writer - MX_Master - 19.05.2009

any updates?


Re: [INC] SII 2.0.6 - Fast cache based INI Reader/Writer - BlackFoX - 21.05.2009

Really nice Include


Re: [INC] SII 2.0.6 - Fast cache based INI Reader/Writer - Trooper[Y] - 23.07.2009

Vry nice Script, use it everytime

But now i got following error:
Quote:

error 035: argument type mismatch (argument 1)

in
Код:
public untemp(string:playername)
{
	if(INI_Open("temp.ini"))
	{
	  INI_RemoveEntry(playername); //<<<<<<<<<<<<<<<<<<<<<<<<
	  INI_Save();
	  INI_Close();
	}
	return 1;
}
(Marked the error-line)

Hope on fast fix,
Trooper


Re: [INC] SII 2.0.6 - Fast cache based INI Reader/Writer - yezizhu - 23.07.2009

I'd sugges you use this code


Код:
public untemp(playername[])
{
	if(INI_Open("temp.ini"))
	{
	  INI_RemoveEntry(playername); //<<<<<<<<<<<<<<<<<<<<<<<<
	  INI_Save();
	  INI_Close();
	}
	return 1;
}
PS:It seems he didn't plan to release new update this year : o