Jump to content
code34

iniDBI2 - Save and Load data to the server or your local computer without databases!

Recommended Posts

This is how i create multiple databases

 

_DataBase = missionName + "." + worldName ;
_DataBase_Vehicles = missionName + "_Vehicles." + worldName ;
_DataBase_Wrecks = missionName + "_Wrecks." + worldName ;
_DataBase_AI = missionName + "_AI." + worldName ;
 
 
DataBase = ["new", _DataBase] call OO_INIDBI;
DataBase_Vehicles = ["new", _DataBase_Vehicles] call OO_INIDBI;
DataBase_Wrecks = ["new", _DataBase_Wrecks] call OO_INIDBI;

DataBase_AI = ["new", _DataBase_AI] call OO_INIDBI; 

 

 

but this must be run on the server

so if you used

   

initPlayerServer.sqf

 
//Executed only on server when a player joins mission (includes both mission start and JIP). See initialization order for details about when the script is exactly executed.
//[player:Object, didJIP:Boolean]
 
 
 
 

 

 

and add to it

 

 
//=======================
//SETUP PRIMARY
//=======================

 

params ["_player"];  // a new and better way of saying _player = _this select 0; makes it private also

_playerUID = getPlayerUID _player;  // (you can not use player on a server run script _player is fine as long as you have it defined)
_playerstring = _player;
_savestring = format["%1 (%2)",_playerstring,_playerUID];
_savestring = ["new", _savestring] call OO_INIDBI;   //(just means database name and ini will be the same but different for everyone that plays) 

 

//=======================
//SETUP SAVED/SAVING ARRAYS
//=======================
_nonvitaltimer = 60;

//=======================
//LOG FUNCTIONS
//=======================

 

while {true} do
{

_vehiclename = name vehicle _player; //these must be in the loop as their values need to be updated

_whereis = position _player;

sleep 3;
["write",["Positions","TestKey","_whereis"]] call _savestring;
 

        if (isNull objectParent _player) then   //== not in vehicle,  new way of finding out if in vehicle or not , not sure what was up with the extra {}
        {
        sleep 2;
        } else{
        ["write", ["VehicleEntries", "TestKey", "_vehiclename"]] call _savestring; 
        sleep _nonvitaltimer;
        };

 

};

Share this post


Link to post
Share on other sites
{
	_id = getplayeruid _x;
	["write", ["players", "id", _id]] call _inidbi;
	_id = ["read", ["players", "id"]] call _inidbi;
	_id remoteExec ["systemchat"]; 
	
} foreach playableunits;

This works for me, it saves the players id and reads it to systemchat. But what if I want to have an array containing different player variables?

Does not, I accidently used same _id variable so it looked like it was working.

{
	_id = getplayeruid _x;
	_name = name _x;
	["write", ["playerstats", "id", [_id,_name]]] call _inidbi;
	_id = ["read", ["playerstats", "id"]] call _inidbi;
	_id remoteExec ["systemchat"]; 
	
} foreach playableunits;

This does not work, nothing gets to systemchat. Works on MP, but only with one variable. How do I save an array per key?

 

Also am I doing this right? If I want to save player stats like so

section = playerstats

unique_id = key

array of player variables = value

 

 

2. Where do I find the database on my HD to manually edit it?

 

3. Can we get an example of how it is supposed to work?

Share this post


Link to post
Share on other sites

hi

 

 


{
    _id = getplayeruid _x;
    _name = name _x;
    ["write", ["playerstats", "id", [_id,_name]]] call _inidbi;
    _id = ["read", ["playerstats", "id"]] call _inidbi;
    _id remoteExec ["systemchat"];
    
} foreach playableunits;

 

 

you should try something simpliest

 

 


{
    _id = getplayeruid _x;
    _name = name _x;

    ["write", ["playerstats", _id, [_name,_score,_stuff,_otherthinglikeyouwant]]] call _inidbi;
    _stats = ["read", ["playerstats", _id]] call _inidbi;
    _stats remoteExec ["systemchat"];
} foreach playableunits;

 

 

you can find your datas in your inidbi2 addons directory :)

Share this post


Link to post
Share on other sites

Thanks for the example. Another question. If I only define _id and _name for a player, but later add other entries like deaths, will that work? or do I have to establish the array of all possible variables I want to write when creating the section?

 

2. How to check if an entry exists?

 

!_retrieved_id does only work if the read-attempt does not find anything because its a boolean false. But if I check and find something then !_retrieved_id is not a boolean anymore and breaks script

//return_value = function;
_inidbi = ["new", "stat_0001"] call OO_INIDBI;

	_id = getplayeruid _playerobject;
	_name = name _playerobject;
	
	//attempt to get player UID from database
	_retrieved_id = ["read", ["playerstats", _id]] call _inidbi;

	
	
	//check if id exists in database
if (!_retrieved_id) then
{
	_missions = 0;
	systemchat format ["_retrieved_id does not exist. Creating entry UID: %1", _id];
	_return = ["write", ["playerstats", _id, [_name,_missions]]] call _inidbi;
	systemchat format ["Write successful? %1", _return];
}
else
{
	systemchat "_retrieved_id exists";

};

//get UID again
_retrieved_id = ["read", ["playerstats", _id]] call _inidbi;

if (_retrieved_id) then
{
	_retrieved_missions = _retrieved_id select 1;
	systemchat format ["_retrieved_missions: %1", _retrieved_missions];
	_retrieved_missions = _retrieved_missions +1;
	_return = ["write", ["playerstats", _id, [_name,_missions]]] call _inidbi;
	systemchat format ["Write successful? %1", _return];
};

Share this post


Link to post
Share on other sites

try to use something like that :

 


_retrieved_id = ["read", ["playerstats", _id, false]] call _inidbi;

 

 

it will return false, if nothing is found :)

Share this post


Link to post
Share on other sites

try to use something like that :

 

 

 

 

it will return false, if nothing is found :)

Not sure where to use that. The problem I have is that I need a check whether a section exists. The code with !_retrieved_id works the first time a new player connects(when no entry exists). But the script breaks because it expects a bool, which it is not if it finds something.

 

So, not really sure where to put your example for it to work.

 

 

Here is the script with attempting your fix. It is a initplayerserver.sqf

_playerobject = _this select 0;
_isjip = _this select 1;

systemchat format ["_playerobject: %1 | _isjip: %2", _playerobject, _isjip];



//return_value = function;
_inidbi = ["new", "stat_0001"] call OO_INIDBI;

	_id = getplayeruid _playerobject;
	_name = name _playerobject;
	
	//attempt to get player UID from database
	//_retrieved_id = ["read", ["playerstats", _id]] call _inidbi;
	_retrieved_id = ["read", ["playerstats", _id, false]] call _inidbi;
	
	
	//check if id exists in database
if (!_retrieved_id) then
{
	_missions = 0;
	systemchat format ["_retrieved_id does not exist. Creating entry UID: %1", _id];
	_return = ["write", ["playerstats", _id, [_name,_missions]]] call _inidbi;
	systemchat format ["Write successful? %1", _return];
}
else
{
	systemchat "_retrieved_id exists";

};

//get UID again
//_retrieved_id = ["read", ["playerstats", _id]] call _inidbi;
_retrieved_id = ["read", ["playerstats", _id, false]] call _inidbi;
if (_retrieved_id) then
{
	_retrieved_missions = _retrieved_id select 1;
	systemchat format ["_retrieved_missions: %1", _retrieved_missions];
	_retrieved_missions = _retrieved_missions +1;
	_return = ["write", ["playerstats", _id, [_name,_missions]]] call _inidbi;
	systemchat format ["Write successful? %1", _return];
};

	

Share this post


Link to post
Share on other sites

So I have to check whether the return variable is a boolean or an array without breaking the script.

Share this post


Link to post
Share on other sites

Wait, I see you added the possibility to use custom return values. I will just give a non existing entry the default return of -1. That should fix it I hope.

 

 

EDIT, yes return value array then it works.

 

To repeat my other question. When I write a section (player id) do I have to write the whole array or can I just manipulate one entry of the array? and if so, can I add new elements to the array?

 

Example. I track player kills. So the array has 2 entries, name and kills. If I want to add in a deaths element, does that work? or do I have to consider that early in the creation

_return = ["write", ["playerstats", _id, [_name,_missions]]] call _inidbi;

1.Can I adress only _missions and leave out _name?

Share this post


Link to post
Share on other sites

hi

 

it works like an entrie file.

 

if you save an entrie, it will replace totaly the oldier one by the new one :)

Share this post


Link to post
Share on other sites

How can I check if a variable is <null>? Because when I updated my script to write more variables on an existing entry my array looked like this:

_SP_PLAYER_="["cat",0,<null>,<null>]"

Because that entry already existed in my database, and the array was small and had only 2 entries instead of 4. Which caused a division by zero error. I would like to add in a check for <null> to prevent that.

Share this post


Link to post
Share on other sites

Hi Nicholas,

 

I wanted to say thanks for releasing this - it's really easy to set up and use, so for someone like me who is not too familiar with databases, it's really helpful.  :)

 

Salut!

Share this post


Link to post
Share on other sites

How can I check if a variable is <null>? Because when I updated my script to write more variables on an existing entry my array looked like this:

_SP_PLAYER_="["cat",0,<null>,<null>]"

Because that entry already existed in my database, and the array was small and had only 2 entries instead of 4. Which caused a division by zero error. I would like to add in a check for <null> to prevent that.

 

Hi

 

you should check that before save your entrie with inidbi :)

Share this post


Link to post
Share on other sites

Hi Nicholas,

 

I wanted to say thanks for releasing this - it's really easy to set up and use, so for someone like me who is not too familiar with databases, it's really helpful.   :)

 

Salut!

 

thanks you for your feedback, it is always appreciated :)

Share this post


Link to post
Share on other sites

Do I see it correctly that you can write multiple types of data, but read always returns stored data as a string?

 

I had time to check it now. It does return values in their original state.

Share this post


Link to post
Share on other sites
code34, Please post the source code or the ready base, which is the month trying to write base on the basis of your creation nothing happens. :huh:
 
Required entry - reading:
 
- The player's position.
- health and tiredness.
- Uniform player.
- The player's backpack.
- Vest of the player.
- Headdress of the player.
- Player points.
- Binoculars, rangefinder player or laser pointer.
- The weapon of the player.
- Mounted on the weapon bipod, optics, flashlight or laser pointer, shops and so on.
- Night vision device player.
- Fit on the belt,map, watch, compass, GPS and so on.
- Items in your backpack, uniform and vest.

- The latest position of all vehicles on the map.

For earlier thanks I'm tired of trying, it was possible to spread such a default database included with the addon, not everyone understands the logic and operation of this creation. Especially without knowledge of English and limited manual without any specific examples for each simple case. :( :( :(

 
 
 

Share this post


Link to post
Share on other sites

 

code34, Please post the source code or the ready base, which is the month trying to write base on the basis of your creation nothing happens. :huh:

 
Required entry - reading:
 
- The player's position.

- health and tiredness.

- Uniform player.

- The player's backpack.

- Vest of the player.

- Headdress of the player.

- Player points.

- Binoculars, rangefinder player or laser pointer.

- The weapon of the player.

- Mounted on the weapon bipod, optics, flashlight or laser pointer, shops and so on.

- Night vision device player.

- Fit on the belt,map, watch, compass, GPS and so on.

- Items in your backpack, uniform and vest.

- The latest position of all vehicles on the map.

For earlier thanks I'm tired of trying, it was possible to spread such a default database included with the addon, not everyone understands the logic and operation of this creation. Especially without knowledge of English and limited manual without any specific examples for each simple case. :( :( :(

 

 
 

 

 

 

Why don't you post up your code you have tried?  It might be a simple error.

 

You're asking for an entire database system as an example (complete player stats, vehicles and shops).

Share this post


Link to post
Share on other sites

Why don't you post up your code you have tried?  It might be a simple error.

 

You're asking for an entire database system as an example (complete player stats, vehicles and shops).

If at least that worked in this version I would have published or publish nothing, there has been a mistake, and not asked, and generally stupid to give some base curve syntax, and to tell the rest of the guys write themselves .

Share this post


Link to post
Share on other sites

Okay well if you don't want to post up your efforts for others to help with, then try looking at Zonekillers "lost" mission.  There's a whole system in his mission which is similar to what you need so maybe you can figure something out from there.

Share this post


Link to post
Share on other sites

Okay well if you don't want to post up your efforts for others to help with, then try looking at Zonekillers "lost" mission.  There's a whole system in his mission which is similar to what you need so maybe you can figure something out from there.

 
Nothing to help - not to give silly advice, I already looked there, generally features a leg break.

Share this post


Link to post
Share on other sites

das attorney,

 

There is a system from Zooloo75 why are there beings at all written, without drums, on normal SQF and source code is simple and clear, it's just a nuance that client-side.
Why the fuck not here to do the same?
Why are there all through the ass?

 

I put the version 1.4 it writes, but not reads and after remains your corpse, I killed dancing with a tambourine with her for a few weeks now with this pain. What prevents putting it init.sqf basic functionality reading save to those whom I have enumerated, the author of that inclination to masochism?

Share this post


Link to post
Share on other sites

 

 
Nothing to help - not to give silly advice, I already looked there, generally features a leg break.

 

 

OK - silly advice time over.

Share this post


Link to post
Share on other sites

OK - silly advice time over.

 

Bitch doesn't work !!!! :angry: 

Nearly the same variations at 1.4 with syntax writes but not reads.
 
v.1
while {true} do {
sleep 5;
systemChat "Сохранение...";
_x = player;        
_databasename = getPlayerUID _x;
_inidbi = ["new", _databasename] call OO_INIDBI;

//============    Load Stats
//PLAYER
playerPos = ["read", ["playerData", "location", "ARRAY"]] call _inidbi;
playerHealth = ["read", ["playerData", "health", "SCALAR"]] call _inidbi;
playerOxygen = ["read", ["playerData", "oxygen", "SCALAR"]] call _inidbi;
//INVENTORY
playerBackpack = ["read", ["playerData", "backpack", "STRING"]] call _inidbi;
playerBackpackGear = ["read", ["playerData", "backpackGear", "ARRAY"]] call _inidbi;
playerVest = ["read", ["playerData", "vest", "STRING"]] call _inidbi;
playerVestGear = ["read", ["playerData", "vestGear", "ARRAY"]] call _inidbi;
playerUniform = ["read", ["playerData", "uniform", "STRING"]] call _inidbi;
playerUniformGear = ["read", ["playerData", "uniformGear", "ARRAY"]]call _inidbi;
playerGadgets = ["read", ["playerData", "gadgets", "ARRAY"]] call _inidbi;
playerHeadgear = ["read", ["playerData", "headgear", "STRING"]] call _inidbi;
playerGoggles = ["read", ["playerData", "goggles", "STRING"]] call _inidbi;
playerWep = ["read", ["playerData", "weapons", "ARRAY"]] call _inidbi;
playerPrimWepAttach = ["read", ["playerData", "primWeaponAttachments", "ARRAY"]] call _inidbi;
playerSecWepAttach = ["read", ["playerData", "secWeaponAttachments", "ARRAY"]] call _inidbi;
playerMagazines = ["read", ["playerData", "magazines", "ARRAY"]] call _inidbi;

//============    Save Stats
//PLAYER
["write", ["playerData", "name", name _x]] call _inidbi;
["write", ["playerData", "location", position _x]] call _inidbi;
["write", ["playerData", "oxygen", getOxygenRemaining _x]] call _inidbi;
["write", ["playerData", "health", damage _x]] call _inidbi;
//INVENTORY
["write", ["playerData", "weapons", weapons _x]] call _inidbi;
["write", ["playerData", "primWeaponAttachments", primaryWeaponItems _x]] call _inidbi;
["write", ["playerData", "secWeaponAttachments", secondaryWeaponItems _x]] call _inidbi;
["write", ["playerData", "magazines", magazinesAmmoFull _x]] call _inidbi;
["write", ["playerData", "backpack", backpack _x]] call _inidbi;
["write", ["playerData", "backpackGear", backpackItems _x]] call _inidbi;
["write", ["playerData", "vest", vest _x]] call _inidbi;    
["write", ["playerData", "vestGear", vestItems _x]] call _inidbi;
["write", ["playerData", "uniform", uniform _x]] call _inidbi;
["write", ["playerData", "uniformGear", uniformItems _x]] call _inidbi;
["write", ["playerData", "gadgets", assignedItems _x]] call _inidbi;
["write", ["playerData", "headgear", headgear _x]] call _inidbi;
["write", ["playerData", "goggles", goggles _x]] call _inidbi;

};    
//=====================================================================================================================

2016/03/20, 18:51:36 "IniDBI: write failed data is empty"

2016/03/20, 18:51:36 "IniDBI: write failed data is empty"

2016/03/20, 18:51:36 "IniDBI: write failed data is empty"

2016/03/20, 18:51:36 "IniDBI: write failed data is empty"

2016/03/20, 18:51:36 "IniDBI: write failed data is empty"

2016/03/20, 18:51:36 "IniDBI: write failed data is empty"

 

v.2

while {true} do {
sleep 5;
systemChat "Сохранение...";

_inidbi = ["new", "PlayersData"] call OO_INIDBI;
_playerData = getPlayerUID player;

//============	Load Stats
//PLAYER
playerPos = ["read", [_playerData, "location", "ARRAY"]] call _inidbi;
playerHealth = ["read", [_playerData, "health", "SCALAR"]] call _inidbi;
playerOxygen = ["read", [_playerData, "oxygen", "SCALAR"]] call _inidbi;
//INVENTORY
playerBackpack = ["read", [_playerData, "backpack", "STRING"]] call _inidbi;
playerBackpackGear = ["read", [_playerData, "backpackGear", "ARRAY"]] call _inidbi;
playerVest = ["read", [_playerData, "vest", "STRING"]] call _inidbi;
playerVestGear = ["read", [_playerData, "vestGear", "ARRAY"]] call _inidbi;
playerUniform = ["read", [_playerData, "uniform", "STRING"]] call _inidbi;
playerUniformGear = ["read", [_playerData, "uniformGear", "ARRAY"]]call _inidbi;
playerGadgets = ["read", [_playerData, "gadgets", "ARRAY"]] call _inidbi;
playerHeadgear = ["read", [_playerData, "headgear", "STRING"]] call _inidbi;
playerGoggles = ["read", [_playerData, "goggles", "STRING"]] call _inidbi;
playerWep = ["read", [_playerData, "weapons", "ARRAY"]] call _inidbi;
playerPrimWepAttach = ["read", [_playerData, "primWeaponAttachments", "ARRAY"]] call _inidbi;
playerSecWepAttach = ["read", [_playerData, "secWeaponAttachments", "ARRAY"]] call _inidbi;
playerMagazines = ["read", [_playerData, "magazines", "ARRAY"]] call _inidbi;

//============	Save Stats
//PLAYER
["write", [_playerData, "name", name player]] call _inidbi;
["write", [_playerData, "location", position player]] call _inidbi;
["write", [_playerData, "oxygen", getOxygenRemaining player]] call _inidbi;
["write", [_playerData, "health", damage player]] call _inidbi;
//INVENTORY
["write", [_playerData, "weapons", weapons player]] call _inidbi;
["write", [_playerData, "primWeaponAttachments", primaryWeaponItems player]] call _inidbi;
["write", [_playerData, "secWeaponAttachments", secondaryWeaponItems player]] call _inidbi;
["write", [_playerData, "magazines", magazinesAmmoFull player]] call _inidbi;
["write", [_playerData, "backpack", backpack player]] call _inidbi;
["write", [_playerData, "backpackGear", backpackItems player]] call _inidbi;
["write", [_playerData, "vest", vest player]] call _inidbi;	
["write", [_playerData, "vestGear", vestItems player]] call _inidbi;
["write", [_playerData, "uniform", uniform player]] call _inidbi;
["write", [_playerData, "uniformGear", uniformItems player]] call _inidbi;
["write", [_playerData, "gadgets", assignedItems player]] call _inidbi;
["write", [_playerData, "headgear", headgear player]] call _inidbi;
["write", [_playerData, "goggles", goggles player]] call _inidbi;

};	
//=====================================================================================================================


2016/03/20, 19:02:39 "IniDBI: write failed data is empty"

2016/03/20, 19:02:39 "IniDBI: write failed data is empty"

2016/03/20, 19:02:39 "IniDBI: write failed data is empty"

2016/03/20, 19:02:39 "IniDBI: write failed data is empty"

2016/03/20, 19:02:39 "IniDBI: write failed data is empty"

2016/03/20, 19:02:39 "IniDBI: write failed data is empty"

Share this post


Link to post
Share on other sites

Hi code34,

 

thanks for the great work!

 

I want to know if its possible to create more than 1 database file and check the existance of every single database file?

 

Or we can only have one database file?

 

Function: exists
Usage : "exists" call _inidbi;
Output: true if the database exists

 

with this  exists function i can only check the existance of one database.

 

NVM

 

i can do it with one database.:D

Share this post


Link to post
Share on other sites

hi

 

In fact you have several solutions, you can :

create several objects oo_inidbi each one for a database

 

or

 

create only one object, and set the db name when you want to use another database :)

  • Like 1

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×