Jump to content
Sign in to follow this  
firefly2442

Arma2MySQL

Recommended Posts

Yeah, that's looking pretty good I think. You'll just have to test it to make sure. I would test all this with Arma2NET Explorer, then once you have it working, try it in Arma. Look at the example mission on Github (there's one for Arma2 and one for Arma3). CBA event handlers are setup on the server side and then are called from the clients. So then you could have it load all this stuff in when they connect in. The missions are fairly well commented, if there's a part that is unclear let me know and I can add more comments. init.sqf gets loaded in first, just open that file and start tracing out what is getting loaded in.

Share this post


Link to post
Share on other sites

I can't get it working. It does not load with the server, no log file is created. I had first compressed arma and now I installed it with steam, still nothing. How to troubleshoot this? I'm running Win Server 2012 64bit.

- My ArmA is installed: C:\Program Files (x86)\Steam\SteamApps\common\Arma 2 Operation Arrowhead

- I extracted compiled version here: \Arma 2 Operation Arrowhead\@Arma2NET

- arma2netmysql things are here: C:\Users\Administrator\AppData\Local\Arma2NETMySQL, having 2 folders (logs, sqlite) and a Databases.txt file.

- Databases.txt only non-comment line is this: mysql,dbase,mysql.kask.fi,3306,user,pass

- I didn't find anything interesting in servers RPT file

Share this post


Link to post
Share on other sites

Hi Kaski,

A way to test this without starting your server, open \Arma 2 Operation Arrowhead\@Arma2NET and run Arma2Net Explorer.exe. Click list Addins make sure your pluggins show then click Load Addins.

If all Addins load etc in the bottom command box copy and paste this

Arma2NETMySQLCommand ['weapons', 'SELECT * FROM users LIMIT 3']

Then check back to your C:\Users\Administrator\AppData\Local\Arma2NETMySQl\logs directory..... There you should find a log buddy, and info inside to let you know if it has access to your database and if there was any problems.

Hope this helps

Regards,

Geordie

Edit: Please note that in this command "Arma2NETMySQLCommand ['weapons', 'SELECT * FROM users LIMIT 3']" Change "weapons" to your database name.

Incase you are trying to connect to a remote MYSQL server make sure you allow access from your Windows server, My advice install everything locally

Edited by GeordieBen

Share this post


Link to post
Share on other sites

Did you watch the tutorial video? I think it's quite helpful if you haven't seen it. Are you getting any Arma2NET log files? Check there first to make sure the plugin is loading.

I can't get it working. It does not load with the server, no log file is created. I had first compressed arma and now I installed it with steam, still nothing. How to troubleshoot this? I'm running Win Server 2012 64bit.

- My ArmA is installed: C:\Program Files (x86)\Steam\SteamApps\common\Arma 2 Operation Arrowhead

- I extracted compiled version here: \Arma 2 Operation Arrowhead\@Arma2NET

- arma2netmysql things are here: C:\Users\Administrator\AppData\Local\Arma2NETMySQL, having 2 folders (logs, sqlite) and a Databases.txt file.

- Databases.txt only non-comment line is this: mysql,dbase,mysql.kask.fi,3306,user,pass

- I didn't find anything interesting in servers RPT file

Share this post


Link to post
Share on other sites

I've started working on an asynchronous update that will hopefully improve performance on the server side and prevent blocking on the server while it waits for the response. The plugin is in a development branch in Git and the example Arma3 mission is being worked on. All logic for this asynchronous call will need to be on the SQF side.

Share this post


Link to post
Share on other sites

Hey Guys,

Ok so im a little stuck here guys. I have added the CBA_CO into the root directory and i get the following message ingame " YOU ARE MISSING THE FOLLOWING MOD CBA_MAIN" isnt CBA server side?

Anyway to the point, i want to use CBA to help trace my query's for the MySql plugin because my data isnt being stored into my MySQL database. Because im not the best scripter, infact im not a scripter at all if im honest (but learning) i am using (ZAG)Ed! "Copy To Clipboard" persistent database script and trying to mod it in a way that instead of saving to txt documents it stores into my local database.

So heres what i have got

In my init.sqf

//init 3rd Party Scripts
[] execVM "addons\cleanup.sqf";
[] execVM "addons\R3F_ARTY_AND_LOG\init.sqf";
[] execVM "addons\proving_Ground\init.sqf";
[] execVM "dbcore\init.sqf"; <<<< my database init
[0.1, 0.5, 0.5] execVM "addons\scripts\DynamicWeatherEffects.sqf";

in my dbcore\init.sqf

//Loading scripts

if(isServer) then {
execVM "persistentdb\loadplayers.sqf";
execVM "persistentdb\loadobjects.sqf";
execVM "persistentdb\saveobjects.sqf";
execVM "persistentdb\saveplayerserver.sqf";
};
if(!isDedicated) then {
execVM "dbcore\saveplayers.sqf";
//execVM "dbcore\loadrequest.sqf";
};

and finally in my dbcore\saveplayers.sqf

//Player save
//Author: {ZAG}Ed!

persistentstatsloaded = false;
waitUntil {persistentstatsloaded};
persistentdbsaveplayertimerrunning = false;
while {true} do {
waitUntil{alive player};
waitUntil{!respawnDialogActive};
persistentdbsaveplayertimer = false;
_team = side player;
_puid = getPlayerUID player;
[] spawn {if(persistentdbsaveplayertimerrunning) exitWith {}; persistentdbsaveplayertimerrunning = true; sleep 15; persistentdbsaveplayertimer = true; persistentdbsaveplayertimerrunning = false;};
//minor exploit prevention
_weapons = count(weapons player);
waitUntil {persistentdbsaveplayertimer or !alive player or (count(weapons player) != _weapons) or mutexScriptInProgress};
if(mutexScriptInProgress) then {sleep 0.5};

if (isServer) then
{

private ["puid", "pname", "getDir", "getPos", "weapons", "magazine", "health", "thirstlevel", "hungerlevel", "cmoney", "canfood", "water", "medkits", "fuel", "repairkits", "fuelFull", "fuelEmpty", "bombs", "spawnBeacon", "camonet"];

_puid = _this select 0;
_pname = _this select 1;
_getDir = _this select 2;
_getPos = _this select 3;
_query = format ["INSERT INTO table_users (uid, name, dir, pos,) VALUES ('%0', '%1', '%2', '%3')", _puid,_pname,_getDir,_getPos];
TRACE_1("Query: ",_query);
"Arma2Net.Unmanaged" callExtension format ["Arma2NETMySQLCommand ['wasteland', '%0']", _query];

call CBA_fnc_addEventHandler;

_weapons = _this select 4;
_magazine= _this select 5;
_health = _this select 6;
_thirthlevel = _this select 7;
_query = format ["INSERT INTO table_users (weapons, magazine, health, thirstlevel) VALUES ('%4', '%5', '%6', '%7')", _weapons,_magazine,_health,_thirstlevel];
"Arma2Net.Unmanaged" callExtension format ["Arma2NETMySQLCommand ['wasteland', '%1']", _query];


_hungerlevel = _this select 8;
_cmoney = _this select 9;
_canfood = _this select 10;
_water = _this select 11;
_query = format ["INSERT INTO table_users (hungerlevel, cmoney, canfood, water) VALUES ('%8', '%9', '%10', '%11')", _hungerlevel,_cmoney,_canfood,_water];
"Arma2Net.Unmanaged" callExtension format ["Arma2NETMySQLCommand ['wasteland', '%1']", _query];


_medkits = _this select 12
_fuel = _this select 13;
_repairkits = _this select 14;
_fuelFull = _this select 15;
_query = format ["INSERT INTO table_users (medkits, fuel, repairkits, fuelFull) VALUES ('%12', '%13', '%14', '%15')", _medkits,_fuel,_repairkits,_fuelFull ];
"Arma2Net.Unmanaged" callExtension format ["Arma2NETMySQLCommand ['wasteland', '%1']", _query];

_fuelEmpty = _this select 16;
_bombs = _this select 17;
_spawnBeacon = _this select 18;
_camonet = _this select 19;
_query = format ["INSERT INTO table_users (fuelEmpty, bombs, spawnBeacon, camonet) VALUES ('%16', '%17', '%18', '%19')", _fuelEmpty,_bombs,_spawnBeacon,_camonet];
"Arma2Net.Unmanaged" callExtension format ["Arma2NETMySQLCommand ['wasteland', '%1']", _query];

};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////// ORIGINAL CODE BELOW ///////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//_itemarray = [player getVariable "cmoney",
//player getVariable "canfood",
//player getVariable "medkits",
//player getVariable "water",
//player getVariable "fuel",
//player getVariable "repairkits",
//player getVariable "fuelFull",
//player getVariable "fuelEmpty",
//player getVariable "bombs",
//player getVariable "spawnBeacon",
//player getVariable "camonet",
//hungerLevel,
//thirstLevel]
/;


//_locationarray = [getPos player, getDir player];

//_weaponsarray = [weapons player, magazines player];


//_damage = getDammage player;

//if(!alive player) then {
//_itemarray = [0,0,0,0,0,0,0,0,0,0,0,0,0];
//_weaponsarray = [[],[]];
//_damage = 1
//};

//playersavearray = [_itemarray, _locationarray, _weaponsarray, _damage];
//call compile (format["%2%1playersave = playersavearray;
//publicVariableServer ""%2%1playersave"";", getPlayerUID player, _team]);
//};

Is there anything that looks like it shouldnt be there? also do i have to make a script to tell arma to communicate with the database or is this done automatically with the plugin?

Really hope someone can point me in the right direction, this is bugging the hell out of me

Thanks

Regards,

Geordie

Edited by GeordieBen

Share this post


Link to post
Share on other sites

@Geordie: If you're running Arma 2, you'll probably want the following mods for CBA: @CBA_A2;@CBA_OA;@CBA;

You can see in the script, "Arma2Net.Unmanaged" callExtension format ["Arma2NETMySQLCommand ... this is where the plugin is being called. It looks generally OK to me, what do the logs say?

Share this post


Link to post
Share on other sites
@Geordie: If you're running Arma 2, you'll probably want the following mods for CBA: @CBA_A2;@CBA_OA;@CBA;

You can see in the script, "Arma2Net.Unmanaged" callExtension format ["Arma2NETMySQLCommand ... this is where the plugin is being called. It looks generally OK to me, what do the logs say?

Hey Buddy,

Yea i though everything looked ok to, i just dont understand why nothing is showing in my database. I'm getting no logs at all, sorry infact the only logs i get are when i run the Arma2Netexplorer.exe i can insert data into the database via the explorer with commands such as

Arma2NETMySQLCommand ["wasteland", "INSERT INTO users (uid, name, ammo, money, food, water, health, weapons, location) VALUES ( '8998', 'jogn', '21', '2', '2', '2', '2', '2', '2' )"]

But starting the server and trying to get something to save just doesnt happen. I run this on a windows 2008 r2 dedicated server, where would my logs save?? I have logs saving in AppData but only ones i mentioned before that are logged while executing commands in the explorer. Im not getting any server_console.log or RPT logs saving anywhere.

Regards,

Geordie

Share this post


Link to post
Share on other sites

Are you starting the game with the @Arma2NET mod? Check the readme file, it details where you can find the Arma2NET and Arma2NETMySQL log files.

Share this post


Link to post
Share on other sites

Yes i have the following command line...

-mod=expansion\beta;expansion\beta\expansion;@CBA_CO;@CBA_OA;@CBA_A2;@CBA;@Arma2NET -arma2netdev

in my Arma2NETMySQL file there is logs, but only ones logged via the Arma2NET explorer, as for C:\Users\Yourname\AppData\Local\Arma2NET\ i dont have this file at all

Share this post


Link to post
Share on other sites

This: -arma2netdev is not needed anymore. You can safely remove it. I'm a little confused, did you install Arma2NETMySQL to your root Arma2 folder or Appdata? This is where the log files will be for the plugin. I would check Arma2NET first though to see if the plugin is getting loaded when you start Arma2. It sounds like you have things very close if Arma2NET Explorer is working.

Share this post


Link to post
Share on other sites

I followed your video tut, the Arma2mysql is in the appdata with the logs folder, and database.txt, everything else is in the servers root directory in the @arma2net.

How would I test if the plugin loads when Arma starts mate? What do I type into a2net explorer? Bet my problem is something simple lol, I have done everything over 2/3 times over and still no further forward haha

Regards

Geordie

Edited by GeordieBen

Share this post


Link to post
Share on other sites

If you can run Arma2NET Explorer, everything should be good. You can also check the Arma2NET log files when you start Arma but... it sounds like you've got everything in the right place. I'm assuming you've setup the database with an .sql file that sets up the structure already. I didn't write the wasteland script, but you could try just the insertion part to see if it's working. Just manually write something to the database via the Arma2NETMySQLCommand. Or, you could try the example missions I have for Arma2 and Arma3. If you're still stuck, let me know and I can take a closer look.

Share this post


Link to post
Share on other sites

I didnt actually use a .sql file i just made the database with phpmyadmin and created the full database with the sql query window. I spent 3/4 month learning sql before attempting this persistent database, seems like its all been a waste of time lmfao. I dont have to have a database document stored in the /Appdata/Arma2NETMySQL do i? I noticed you have in the example mission a mysql and a sqlite folders, sqlite i can understand because thats simply saves the data there and im assuming the mysql is just purely there for someone to import to there database.

Anyway, heres a log showing that running a command in the explorer works...

Info: 17:35:53 - Logging started in directory: C:\Users\GeordieBen\AppData\Local\Arma2NETMySQL/logs/
Info: 17:35:53 - Arma2NETMySQL Plugin Started.
Info: 17:35:53 - Version number: 0.1.0.0
Info: 17:35:53 - Loading databases...
Warning: 17:35:53 - Unable to find the Databases.txt file here: C:\xxgames\BENM1\1445\@Arma2NET\Databases.txt
Info: 17:35:53 - Databases.txt file loading in from: C:\Users\GeordieBen\AppData\Local\Arma2NETMySQL/Databases.txt
Info: 17:35:53 - Type: mysql Database: wasteland IPAddress: 127.0.0.1 Port: 3306 Username: wasteland Password: NotShownForSecurityReasons
Error: 17:35:54 - The number and/or format of the arguments passed in doesn't match.
Info: 17:40:24 - Received - Database: wasteland SQL Query: SELECT * FROM users LIMIT 3
Info: 17:51:54 - Received - Database: wasteland SQL Query: SELECT * FROM users LIMIT 3

There must be some error in my sqf coding, im not great at sqf code if im honest.... Just picking up bits and bobs as i go.

I'm wondering if this code is correct?

_puid = _this select 0;
_pname = _this select 1;
_getDir = _this select 2;
_getPos = _this select 3;
_query = format ["INSERT INTO users (uid, name, dir, pos,) VALUES ('%0', '%1', '%2', '%3')", _puid,_pname,_getDir,_getPos];
TRACE_1("Query: ",_query);
"Arma2Net.Unmanaged" callExtension format ["Arma2NETMySQLCommand ['wasteland', '%0']", _query];

Should it be like this

_puid = _this select 0;
_pname = _this select 1;
_getDir = _this select 2;
_getPos = _this select 3;
_query = format ["INSERT INTO users (uid, name, dir, pos,) VALUES ('_puid', '_pname', '_getDir', '_getPos')"];
TRACE_1("Query: ",_query);
"Arma2Net.Unmanaged" callExtension format ["Arma2NETMySQLCommand ['wasteland', '%0']", _query];

Edited by GeordieBen

Share this post


Link to post
Share on other sites

Ahh ok, now we're getting somewhere. Yes, it looks like the parameters being passed in via the SQF are wrong. Try changing format to start with %1 perhaps? See here: https://community.bistudio.com/wiki/format

_query = format ["INSERT INTO users (uid, name, dir, pos,) VALUES ('%1', '%2', '%3', '%4')", _puid,_pname,_getDir,_getPos];
TRACE_1("Query: ",_query);
"Arma2Net.Unmanaged" callExtension format ["Arma2NETMySQLCommand ['wasteland', '%1']", _query];

Share this post


Link to post
Share on other sites

Right I've managed to get it to save as I want now, It returns it, well not really as I want it it seems.¨

The code below is after I've done

_get = call compile _get;

_get = _get select 0;

_get = _get select 0;

DROPPED OUTER LAYERS: ["0101(UID)","Name","41000","item1`1`item2`2`item3`4","[]"]

Everything is in a string, how can I turn them all into well actual numbers and items also the item list goes into this function afterwards

split_array = {
_get = (_this select 0) select 3;
diag_log "___ARRAY DIAG__";
diag_log format ["%1", _get];
if ([(_get select 0), "`"] call CBA_fnc_find > 0) then {
_items = [(_get select 2), "`"] call CBA_fnc_split;
} else {
_items set [0, (_get select 2)];
};
diag_log format ["%1", _items];
};

This function is just to turn everything back to an array? As taken from the example mission.

Share this post


Link to post
Share on other sites

It's been awhile since I've looked at this stuff and frankly I'm not so good with SQF but I believe you are correct. Looking here:

https://github.com/firefly2442/Arma2NetMySQLPlugin-Arma3-ExampleMission/blob/master/as_loadouts/selectLoadout.sqf

As far as I can tell, each of the items returned from the database is setup in an array, with sub items delimited using "`". You can see around line 65 it starts parsing them and turning them (I believe) back into SQF formatted arrays.

Share this post


Link to post
Share on other sites

Actually I got everything sorted, loads, saves all that jazz however now it's more code optimization needed.

I'm gonna upload what I have so far, if anyone could take a look at it and point anything out that'd be great, I was planning on releasing it for life servers to use.

This is for ours basiclly what it saves so far is

-Bank

-Inventory

-Licenses

-Streetrep

-One car of your choice

However as I mentioned before it feels very unoptimized mostly the fact that it calls A LOT of functions before comming down to the barebone saving, I'd like to cut down a lot on the functions if possible but I'm out of ideas. (This is without CBA running on client btw only server)

My main questions now are

How would this preform with 50 people loading in at the same time (during server startup)?

How badly is the server's performance hit by several people saving at the same time?

http://infecto.se/status/statsave.rar

Share this post


Link to post
Share on other sites

Wow that's cool. You might want to create a separate thread for it. That way it gets more attention by people who might be interested? I'm working a little on all this "performance" stuff related to callExtension. Hopefully will have something soon. Let me know how it goes with 50 people though. I'll be interested to hear.

Share this post


Link to post
Share on other sites

change string returned number to actual number

_magNumber = parseNumber (_pAmmoCount select 0);

ive managed to get this working fully on arma 3 - awesome system. just completed an addition to it - a pilot licence system and driving system.-Once you get i t going it works well. Calls the info on join and save everything on leaving.

got the following working

-weapons (complete down to round numbers) etc

-position

-stance

-health

I made the system on Arma2 and managed to use the MPframe work to do the calling and saving - eve made a system of saving without using CBA to remove "" etc

PM if you need any help (exchange ideas)

Share this post


Link to post
Share on other sites

I see the mentioning of arrays and well I would feel bad not sharing how I got around it as I too ran into the issue of passing arrays to the database that contained " in them. So here are two functions that I wrote to make them safe to be passed to Arma2NETMysql.

Pass your array to this.

DB_fnc_mresArray =
{
private["_array"];
if(typeName (_this select 0) != (typeName [])) exitWith {"[]"};
_array = _this select 0;
_array = str(str(_array));
_array = toArray(_array);

for "_i" from 0 to (count _array)-1 do
{
	_sel = _array select _i;
	if((_i != 0 && _i != ((count _array)-1))) then
	{
		if(_sel == 34) then
		{
			_array set[_i,96];
		};
	};
};

_array = toString(_array);
_array;
};

Example: [["One","Two","Three"]] call DB_fnc_mresArray;

Returns: "[`One`,`Two`,`Three`]"

And now the part that converts it back to an array once received from the database.

DB_fnc_mresToArray =
{
private["_array"];
if(typeName (_this select 0) != (typeName "")) exitWith {[]};
_array = _this select 0;
_array = toArray(_array);

for "_i" from 0 to (count _array)-1 do
{
	_sel = _array select _i;
	if(_sel == 96) then
	{
		_array set[_i,39];
	};
};

_array = toString(_array);
_array = call compile format["%1", _array];
_array;
};

Example: ["[`One`,`Two`,`Three`]"] call DB_fnc_mresToArray;

And it will return the array: ["One","Two","Three"]

Not the most elegant way to do things but this is SQF and well.... Making SQF insert things to a database and to be friendly are blah but I do hope this helps some people..

Share this post


Link to post
Share on other sites
I see the mentioning of arrays and well I would feel bad not sharing how I got around it as I too ran into the issue of passing arrays to the database that contained " in them. So here are two functions that I wrote to make them safe to be passed to Arma2NETMysql.

Pass your array to this.

DB_fnc_mresArray =
{
private["_array"];
if(typeName (_this select 0) != (typeName [])) exitWith {"[]"};
_array = _this select 0;
_array = str(str(_array));
_array = toArray(_array);

for "_i" from 0 to (count _array)-1 do
{
	_sel = _array select _i;
	if((_i != 0 && _i != ((count _array)-1))) then
	{
		if(_sel == 34) then
		{
			_array set[_i,96];
		};
	};
};

_array = toString(_array);
_array;
};

Example: [["One","Two","Three"]] call DB_fnc_mresArray;

Returns: "[`One`,`Two`,`Three`]"

And now the part that converts it back to an array once received from the database.

DB_fnc_mresToArray =
{
private["_array"];
if(typeName (_this select 0) != (typeName "")) exitWith {[]};
_array = _this select 0;
_array = toArray(_array);

for "_i" from 0 to (count _array)-1 do
{
	_sel = _array select _i;
	if(_sel == 96) then
	{
		_array set[_i,39];
	};
};

_array = toString(_array);
_array = call compile format["%1", _array];
_array;
};

Example: ["[`One`,`Two`,`Three`]"] call DB_fnc_mresToArray;

And it will return the array: ["One","Two","Three"]

Not the most elegant way to do things but this is SQF and well.... Making SQF insert things to a database and to be friendly are blah but I do hope this helps some people..

Thanks for sharing! I will definetly be testing this out tommorow!

Share this post


Link to post
Share on other sites

quick question - ive tried using on playerconnected - to provide the database with the server name and id - cant get it to work - any tips chaps?

Share this post


Link to post
Share on other sites

Made some progress on the asynchronous call. I believe it's working, but it still needs testing. The code is up on Github (see appropriate development branches, plugin and Arma3 mission). Hopefully this will alleviate the performance issues folks were having when running with massive numbers of players. Please test if you're experienced with these things. When it's deemed stable, I will merge into the master branch.

Share this post


Link to post
Share on other sites
Made some progress on the asynchronous call. I believe it's working, but it still needs testing. The code is up on Github (see appropriate development branches, plugin and Arma3 mission). Hopefully this will alleviate the performance issues folks were having when running with massive numbers of players. Please test if you're experienced with these things. When it's deemed stable, I will merge into the master branch.

I've never compiled a plugin like this before, what would be the easiest way of doing so?

Edit: Nvm got it sorted!

In other news, gonna be testing your new update with 30+ players tonight, will get back to you how it works out!

Edited by Infection

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
Sign in to follow this  

×