Vice City: Multiplayer

Server Development => Community Plugins => Topic started by: Ankris on Aug 30, 2016, 04:08 PM

Title: SimpleIni
Post by: Ankris on Aug 30, 2016, 04:08 PM
Functions:

Download:
- https://github.com/Ankris/vcmp_simpleini/releases
- Source: https://github.com/Ankris/vcmp_simpleini

For Windows versions requires:
Visual C++ Redistributable Packages for Visual Studio 2013 (https://www.microsoft.com/en-us/download/details.aspx?id=40784)
Title: Re: SimpleIni
Post by: KAKAN on Aug 30, 2016, 06:02 PM
Good one!
The best thing: It loads the whole INI file into memory :D
And also, you can put the downloads in the "releases" section of your github page :D
Title: Re: SimpleIni
Post by: Ankris on Aug 30, 2016, 06:18 PM
Quote from: KAKAN on Aug 30, 2016, 06:02 PM.

Done, never noticed about that.
Title: Re: SimpleIni
Post by: Kewun on Aug 30, 2016, 06:42 PM
when trying using any function, server crash.
Title: Re: SimpleIni
Post by: . on Aug 30, 2016, 09:07 PM
I would highly suggest that you implement some error checking as well as checking the received arguments before releasing something. I know that the official plugins thought you to not check for errors and correct input data, but it's not a good practice.

Take this code from the very first function (INI_Open) :
const SQChar *file;
sq->getstring(v, 2, &file);

What if the the argument does not exist?
What if the argument is not a string?
What if it fails to retrieve the string?

You never check for those possibilities. And you're begging for a crash if you get the wrong data. And don't blame it on the scripter if he passes the wrong data because there's always a possibility for anything. It's your job to report what he did wrong.

First of all you check to see if you have that parameter and report which parameter is missing (I used dummy names in this example):
const SQInteger top = sq->gettop(vm);
// Is the first argument there?
if (top <= 1)
{
return sq->throwerror(vm, "Tou forgot to specify the first parameter");
}
// Is the second argument there?
else if (top <= 2)
{
return sq->throwerror(vm, "Tou forgot to specify the second parameter");
}
// Is the third argument there?
else if (top <= 3)
{
return sq->throwerror(vm, "Tou forgot to specify the third parameter");
}

Secondly, you check if you have the correct type and report what type you're expecting and possibly, even what type you received (I'm using dummy types in this example):
// Is the first parameter a user pointer?
if (sq->gettype(vm, 2) != OT_USERPOINTER)
{
return sq->throwerror(vm, "The first parameter is not a user pointer");
}
// Is the second parameter a string? We're expecting a string!
else if (sq->gettype(vm, 3) != OT_STRING)
{
return sq->throwerror(vm, "The first parameter is not a string");
}
// Is the third parameter an integer or float?
else if (sq->gettype(vm, 4) != OT_INTEGER && sq->gettype(vm, 3) != OT_FLOAT)
{
return sq->throwerror(vm, "The first parameter is not a numeric value");
}

Thirdly, some Squirrel functions also return a result which tells you whether or not they failed to do what you asked. So you check that too and return that result (if necessary) so that the VM can raise the proper error message:
// Dummy variable to store the result code where necessary
SQRESULT r = SQ_OK;

SQUserPointer ptr = NULL;
// Store the returned result code
r = sq->getuserpointer(vm, 2, &ptr);
// Check for failures
if (SQ_FAILED(r))
{
return r; // Return that result code to raise that error message
}

const SQChar *str;
// Store the returned result code
r = sq->getstring(vm, 3, &str);
// Check for failures
if (SQ_FAILED(r))
{
return r; // Return that result code to raise that error message
}

SQInteger value;
// Store the returned result code
r = sq->getinteger(vm, 4, &value);
// Check for failures
if (SQ_FAILED(r))
{
return r; // Return that result code to raise that error message
}

Then, You validate the obtained data. You can't start using null pointers incorrect values and not expect a crash:
// Is the specified pointer valid?
if (ptr == NULL)
{
return sq->throwerror(vm, "The specified string is invalid");
}
// Is the specified string valid?
else if (!str || *str == '\0')
{
return sq->throwerror(vm, "The specified string is empty or invalid");
}

And you constantly perform these checks and report back to the scripter so that he knows what he did wrong. A subtle crash or an ignored failure doesn't help anyone.

Another suggestion. Don't name global variables with just one letter, such as 'v' (which you did for the virtual machine). You clearly took this behavior from the official plugins. That's just wrong man. Wrong on so many levels that I simply don't know where to even begin if I were to describe it.

Don't learn anything from the official plugins. Everything there is just bad. Take that as an advice or as a warning. Your choice.
Title: Re: SimpleIni
Post by: Ankris on Aug 30, 2016, 09:28 PM
Quote from: . on Aug 30, 2016, 09:07 PM.

I'm just lazy.

Also there is no like 150 functions to be hard to remember all parameters. Plus I already made some plugins since time ago so these kind of tutorials are useless4me.
Title: Re: SimpleIni
Post by: Thijn on Aug 31, 2016, 12:23 PM
Quote from: Ankris on Aug 30, 2016, 09:28 PMPlus I already made some plugins since time ago so these kind of tutorials are useless4me.
If this is your way of making plugins, you better just stop making them...
Title: Re: SimpleIni
Post by: Ankris on Sep 03, 2016, 01:39 AM
Quote from: Thijn on Aug 31, 2016, 12:23 PM
Quote from: Ankris on Aug 30, 2016, 09:28 PMPlus I already made some plugins since time ago so these kind of tutorials are useless4me.
If this is your way of making plugins, you better just stop making them...

If I remember all the functions and parameters of my own plugins, why should I?



New plugin update: https://github.com/Ankris/vcmp_simpleini/releases/tag/R2
Title: Re: SimpleIni
Post by: Mötley on Sep 03, 2016, 01:49 AM
Quote from: Thijn on Aug 31, 2016, 12:23 PMIf this is your way of making plugins, you better just stop making them...
Quote from: AdTec_224 on Jul 14, 2016, 10:56 PMIt's exactly this kind of thing that stops us as developers having the motivation to continue working on a free mod.
And it's exactly this thing that prevents interesting releases,
We should motivate others not put them down, Ankris was flat out honest with @.. post.
Just a little more motivation and it would of possibly happened.

I like the release and I really would love to see more interesting work :)
Title: Re: SimpleIni
Post by: KAKAN on Sep 03, 2016, 10:47 AM
Quote from: Ankris on Sep 03, 2016, 01:39 AM
Quote from: Thijn on Aug 31, 2016, 12:23 PM
Quote from: Ankris on Aug 30, 2016, 09:28 PMPlus I already made some plugins since time ago so these kind of tutorials are useless4me.
If this is your way of making plugins, you better just stop making them...

If I remember all the functions and parameters of my own plugins, why should I?
Yes, you can remember as you own that plugin( and other good devs too ). But think about newbies too, they will probably screw things up and atlast, PM/post a topic telling "I was using INI plugin and the server crashed".
Quote from: Mötley on Sep 03, 2016, 01:49 AMAnd it's exactly this thing that prevents interesting releases,
We should motivate others not put them down, Ankris was flat out honest with @.. post.
Just a little more motivation and it would of possibly happened.
true.
Title: Re: SimpleIni
Post by: Shadow on Sep 03, 2016, 02:21 PM
Quote from: Mötley on Sep 03, 2016, 01:49 AM...

Quote from: KAKAN on Sep 03, 2016, 10:47 AM
Quote from: Ankris on Sep 03, 2016, 01:39 AM
Quote from: Thijn on Aug 31, 2016, 12:23 PM
Quote from: Ankris on Aug 30, 2016, 09:28 PM...

All SLC did was provide constructive criticism. A bad release is not benefical for neither you, me, or the creator. Ankris has a lot to learn from SLC's advices and by understanding those advices, he can improve himself and his work. There's no reason to be offended at all, I'd be happy if someone pointed out my mistakes so I could fix them and create more efficient code. I really don't understand why you people get angry when people try to help you. SLC didn't call you a noob or anything, he replied with great professionalism, helping you understand why such practices are bad/discouraged.
Title: Re: SimpleIni
Post by: Ankris on Sep 04, 2016, 10:11 PM
Quote from: Shadow on Sep 03, 2016, 02:21 PM
Quote from: Mötley on Sep 03, 2016, 01:49 AM...

Quote from: KAKAN on Sep 03, 2016, 10:47 AM
Quote from: Ankris on Sep 03, 2016, 01:39 AM
Quote from: Thijn on Aug 31, 2016, 12:23 PM
Quote from: Ankris on Aug 30, 2016, 09:28 PM...
...

I hate mostly when someone tells me how to do the things because it's like 'THIS IS THE ONLY F***ING WAY, AND EVERYTHING ELSE IS WRONG'. There should be a word in english meaning this.
Title: Re: SimpleIni
Post by: Shadow on Sep 04, 2016, 10:13 PM
Quote from: Ankris on Sep 04, 2016, 10:11 PMI hate mostly when someone tells me how to do the things because it's like 'THIS IS THE ONLY F***ING WAY, AND EVERYTHING ELSE IS WRONG'. There should be a word in english meaning this.

He didn't say it's the only way. All he did say was that your ways were more dangerous due to the amount of errors that may occur without the end-user knowing about them. If your practice is bad and someone points out it is bad, you might have to change it.
Title: Re: SimpleIni
Post by: Ankris on Sep 04, 2016, 10:36 PM
Quote from: Shadow on Sep 04, 2016, 10:13 PM
Quote from: Ankris on Sep 04, 2016, 10:11 PM.
.

I didn't also say he said it's the only way. There was a bit of meaning of it in that reply.
Title: Re: SimpleIni
Post by: Mötley on Oct 09, 2016, 06:43 PM
INI_SetInteger(ini pointer, string section, string key, integer value)

Lol,,,,...

Could someone tell me what Ini pointer is. I always return errors. No clue as of why,Probably something really dumb on my part
Title: Re: SimpleIni
Post by: Kewun on Oct 09, 2016, 06:46 PM
its some sh!t like   IniFile <- INI_Open("test.ini")

then

INI_SetInteger(IniFile, other, some, params)
Title: Re: SimpleIni
Post by: Mötley on Oct 09, 2016, 06:51 PM
wut.. I thought it was called simple Ini.. lol?!?
Title: Re: SimpleIni
Post by: Kewun on Oct 09, 2016, 06:52 PM
yeah thats the sh!tty thing in it
Title: Re: SimpleIni
Post by: Mötley on Oct 09, 2016, 07:14 PM
But I will say It's different. Seems like fun. Intended to fully use this plug-in and release a example.

If Ankris doesn't beat me to it or some other

I do not know about some as I feel it's really not needed but, Like INI_Exists, INI_SaveFile, But I will use it anyway I guess
Title: Re: SimpleIni
Post by: KAKAN on Oct 10, 2016, 05:35 AM
A OO style would be better. Then, we would use it something like:-
local INIFile = INI("filename");
print(INIFile.ReadRaw())
INIFile.Get(...);
That'd be better I guess :)
Quote from: Mötley on Oct 09, 2016, 06:51 PMwut.. I thought it was called simple Ini.. lol?!?
he saves the shits to your RAM, that means, everything is stored in that INI pointer, so, that's a good way to do it.
Title: Re: SimpleIni
Post by: Mötley on Oct 10, 2016, 11:41 PM
I find it best to use a global variable and assign an initial value

# I have  not assigned  a true system yet

This is a junk script for figuring out how it works
Accounts_Ini <- INI_Open("Accounts.ini");
IPs__Ini <- INI_Open("IP_List.ini");
Subnets__Ini <- INI_Open("Subnet_List.ini");
UniqueID__Ini <- INI_Open("UniqueID_List.ini");

function SaveIniFiles() {
INI_SaveFile( Accounts_Ini, "Accounts.ini");
INI_SaveFile( IPs__Ini, "IP_List.ini");
INI_SaveFile( Subnets__Ini, "Subnet_List.ini");
INI_SaveFile( UniqueID__Ini, "UniqueID_List.ini");
}

function onPlayerJoin( player )
{
local ip = player.IP.tostring();
local sliceip = split( ip, "." );
local ip1 = sliceip[ 0 ], ip2 = sliceip[ 1 ];
local subnet = format( ip1 + "." + ip2 );

Pstats[ player.ID ] = PlayerStats();
INI_SetInteger( Accounts_Ini, player.Name, "Joins", Pstats[ player.ID ].Joins);
INI_SetString( IPs__Ini, "IP", player.Name, player.IP);

INI_SetString( Subnets__Ini, "Subnet", player.Name, subnet);

INI_SetString( UniqueID__Ini, "UID", player.Name, player.UniqueID2);

SaveIniFiles();

}

Title: Re: SimpleIni
Post by: jWeb on Oct 11, 2016, 12:02 AM
I know we're going off topic here and the posts will most likely get removed, but I had to highlight this portion of code:
Quote from: Mötley on Oct 10, 2016, 11:41 PM local ip = player.IP.tostring();
local sliceip = split( ip, "." );
local ip1 = sliceip[ 0 ], ip2 = sliceip[ 1 ];
local subnet = format( ip1 + "." + ip2 );

player.IP is already a string. What's the point of format()?  What's the point of creating `ip1` and `ip2` variables? Actually, I don't even wanna know.
Title: Re: SimpleIni
Post by: Mötley on Oct 11, 2016, 12:07 AM
Those are subnet ips. They will come in handy later on in the server
Title: Re: SimpleIni
Post by: Thijn on Oct 11, 2016, 06:07 AM
Quote from: Mötley on Oct 11, 2016, 12:07 AMThose are subnet ips. They will come in handy later on in the server
What he means is, you can rewrite that piece of code to
local sliceip = split( player.IP, "." );
local subnet = sliceip[0] + "." + sliceip[1];
Title: Re: SimpleIni
Post by: Mötley on Oct 11, 2016, 11:44 AM
LOL!!!!
http://forum.liberty-unleashed.co.uk/index.php/topic,1037.0.html

Thank you both of you. When I read Thijn Code my mind said WTF!!
xD ;D
Thank you ;)