Jump to content

[Issue] Banking_data not saving for new players? (FIXED)


Recommended Posts

WORKING FIX:

 

To fix this you have to create a trigger in your DB that adds an entry to the banking_data field every time a new player_data entry is created.

 

Here's the code for the trigger:

CREATE TRIGGER `bankingIssueFix` AFTER INSERT ON `player_data`
 FOR EACH ROW INSERT INTO banking_data
( PlayerUID, PlayerName, BankSaldo,  LastUpdated)
VALUES
(NEW.PlayerUID, NEW.PlayerName, 0, NOW())

To apply this just paste it into a query field and execute it. Like so:

bankingIssueFix.png

 

 

Big thanks to waTTe and raymix for figuring this out.

 

 

If it still doesn't work for you, you can try these as well:

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

The original issue:

 

I'm not sure if this happens to only me or others as well, but here's my issue. Whenever a new player (first log in) deposits money in bank it doesn't save in the database. You can see in-game you have your money in bank but if you re-log the money is gone. When I search through the database I find that the game doesn't create banking_data rows for new players. They only create one after a player has logged in at least once, and after there has been at least 1 server restart. 

 

I tried fixing this. At first I figured there must be something wrong with the server_playerSetup.sqf because that's where the initial banking_data should be created. I read up on the Soul's DLL and he wrote that CHILD:102 checks if player exists in banking_data and adds if not. There is a code in server_playerSetup.sqf that does this:

_doLoop = 0;
while {_doLoop < 5} do {
	_key = format["CHILD:102:%1:",_characterID];
	_primary = _key call server_hiveReadWrite;
	if (count _primary > 0) then {
		if ((_primary select 0) != "ERROR") then {
			_doLoop = 9;
		};
	};
	_doLoop = _doLoop + 1;
};

At this point I thought this wasn't executed correctly or at the wrong time so I tried a different approach. I made a little code that checks the same thing right before a player tries to deposit money. I tried doing this with public variables:

"PVDZE_account_Doublecheck" addPublicVariableEventHandler {
	_playerObj = ((_this select 1) select 0);
	_playerID = getPlayerUID _playerObj;
	_bankMoney = _playerObj getVariable ["bankMoney",0];
	
	_characterID =_playerObj getVariable ["CharacterID","0"];
	_key = format["CHILD:102:%1:",_characterID];
	_key call server_hiveReadWrite;
};

And right before the deposit code I added:

PVDZE_account_Doublecheck = [player];
publicVariableServer "PVDZE_account_Doublecheck";

Now I know the code works because server_log is show successful 102 calls. But banking_data is still empty. I tried doing a 102 call with playerUID instead of characterID and instantly got an error. This was just to see if maybe I was using the wrong ID. 

 

I'm all out of ideas now, there is an alternative fix to this with 999 calls but afaik the available DLLs don't support 999 + banking_data calls (except the multichar one, which doesn't work if you don't have multichar support). Any help is appreciated.

 

Link to comment
Share on other sites

in your mysql db try and set the banksaldo field to allow null values and add a default value of 0

that could resolve this problem.

 

Yup this did indeed fix it. 

What's the correct way of using child 101 tho? I still want to use the double checker code just in case.

 

 

 

Edit// Nevermind I figured it out. If anyone else is interested in this, here's a quick tutorial:

 

Open \dayz_server\bankzones\bankinit.sqf (from your server's PBO)

 

At the end add:

"PVDZE_account_Doublecheck" addPublicVariableEventHandler {
	_playerObj = ((_this select 1) select 0);
	_playerID = getPlayerUID _playerObj;
	_playerName = name _playerObj;
	
	_doLoop = 0;
	while {_doLoop < 3} do {
		_key = format["CHILD:101:%1:%2:%3:",_playerID,dayZ_instance,_playerName];
		_primary = _key call server_hiveReadWrite;
		if (count _primary > 0) then {
			if ((_primary select 0) != "ERROR") then {
				_doLoop = 9;
			};
		};
		_doLoop = _doLoop + 1;
	};
};

Open \gold\init.sqf (from your mission PBO)

 

Find:

if (_amount < 1 or _amount > _wealth) exitWith {
	cutText ["You can not deposit more than you have.", "PLAIN DOWN"];
};

Place the following code below it:

PVDZE_account_Doublecheck = [player];
publicVariableServer "PVDZE_account_Doublecheck";

This simply checks if the player actually has any entries in banking_data. If not, then creates it.

 

Edit2// Just in case also add this public variable (PVDZE_account_Doublecheck) to BattlEyes publicvariables.txt. Not sure if it's really needed but better safe than sorry.

Edited by Rocu
Link to comment
Share on other sites

can u explain it more?

 

Depending on the software you use to manage your database, edit your banking_data table structure so that it accepts NULL values and set it's default value to 0. If you don't know how to do these things, then just execute the following SQL code:

ALTER TABLE  `banking_data` CHANGE  `BankSaldo`  `BankSaldo` BIGINT( 24 ) NULL DEFAULT  '0'

BE AWARE! If you're messing around with your DB, always make backups before changing anything.

Link to comment
Share on other sites

Depending on the software you use to manage your database, edit your banking_data table structure so that it accepts NULL values and set it's default value to 0. If you don't know how to do these things, then just execute the following SQL code:

ALTER TABLE  `banking_data` CHANGE  `BankSaldo`  `BankSaldo` BIGINT( 24 ) NULL DEFAULT  '0'

BE AWARE! If you're messing around with your DB, always make backups before changing anything.

 

 

Disregard this comment

Link to comment
Share on other sites

Sadly this did not work ;( for my issue

 

Are you sure you had the exact same issue as me? My error was only occurring for completely new players. If you have an issue where bank accounts randomly don't save sometimes then this ain't a fix for that.

Link to comment
Share on other sites

Yup this did indeed fix it. 

What's the correct way of using child 101 tho? I still want to use the double checker code just in case.

 

 

 

Edit// Nevermind I figured it out. If anyone else is interested in this, here's a quick tutorial:

 

Open \dayz_server\bankzones\bankinit.sqf (from your server's PBO)

 

At the end add:

"PVDZE_account_Doublecheck" addPublicVariableEventHandler {
	_playerObj = ((_this select 1) select 0);
	_playerID = getPlayerUID _playerObj;
	_playerName = name _playerObj;
	
	_doLoop = 0;
	while {_doLoop < 3} do {
		_key = format["CHILD:101:%1:%2:%3:",_playerID,dayZ_instance,_playerName];
		_primary = _key call server_hiveReadWrite;
		if (count _primary > 0) then {
			if ((_primary select 0) != "ERROR") then {
				_doLoop = 9;
			};
		};
		_doLoop = _doLoop + 1;
	};
};

Open \gold\init.sqf (from your mission PBO)

 

Find:

if (_amount < 1 or _amount > _wealth) exitWith {
	cutText ["You can not deposit more than you have.", "PLAIN DOWN"];
};

Place the following code below it:

PVDZE_account_Doublecheck = [player];
publicVariableServer "PVDZE_account_Doublecheck";

This simply checks if the player actually has any entries in banking_data. If not, then creates it.

 

 

When you mean add below the stuff in it or replace the other save in the file ?

Link to comment
Share on other sites

When you mean add below the stuff in it or replace the other save in the file ?

 

 

Add below, as in, add that block of code under the other block of code. Like this:

if (_amount < 1 or _amount > _wealth) exitWith {
	cutText ["You can not deposit more than you have.", "PLAIN DOWN"];
};

PVDZE_account_Doublecheck = [player];
publicVariableServer "PVDZE_account_Doublecheck";
Link to comment
Share on other sites

 

Add below, as in, add that block of code under the other block of code. Like this:

if (_amount < 1 or _amount > _wealth) exitWith {
	cutText ["You can not deposit more than you have.", "PLAIN DOWN"];
};

PVDZE_account_Doublecheck = [player];
publicVariableServer "PVDZE_account_Doublecheck";

 

I meant this part 

"PVDZE_account_Doublecheck" addPublicVariableEventHandler {
	_playerObj = ((_this select 1) select 0);
	_playerID = getPlayerUID _playerObj;
	_playerName = name _playerObj;
	
	_doLoop = 0;
	while {_doLoop < 3} do {
		_key = format["CHILD:101:%1:%2:%3:",_playerID,dayZ_instance,_playerName];
		_primary = _key call server_hiveReadWrite;
		if (count _primary > 0) then {
			if ((_primary select 0) != "ERROR") then {
				_doLoop = 9;
			};
		};
		_doLoop = _doLoop + 1;
	};
};
Link to comment
Share on other sites

 

I meant this part 

 

 

Add it at the bottom of the file. Don't replace anything.

 

 

 

Well it just doesn't save at all

 

Then this isn't the fix you're seeking for. You probably messed something up whilst installing. Do it again from the beginning.

Link to comment
Share on other sites

I have done both of these but I still have players randomly loosing all their bank gold.  Is there a way to either periodically save in the background or like in older versions of Epoch where you could mouse wheel and "Force Save" your bank/character info?  I am using Soul's hive.

Link to comment
Share on other sites

This problem and fix is specifically directed to new spawns. This issue will start occurring when you have an active server with a bunch of people in it.

The other common problem, which you're seeking the solution to, is a whole different story. Which really isn't a problem at all, just a failure during installation. At this point there has been so much discussion about it around the forums that I suggest looking around/using search for the solution.

Link to comment
Share on other sites

Well unless I missed my mark, which is entirely possible, I have successfully applied all the fixes at the top of this thread.  If there are more fixes I need to apply, would it be possible for someone to point me in the right direction and maybe consolidate them in to one post?

Link to comment
Share on other sites

since this fix didnt always work for me i simply created a database trigger which inserts id and name into the banking data field when a new player_Data entry is created

 

to apply this you should truncate your player_data table (no inventory will be lost, its just a table with names and playerUIDs)

 

after that exec that query:

CREATE TRIGGER banking
AFTER UPDATE ON player_Data
FOR EACH ROW
INSERT INTO banking_Data
( PlayerUID, PlayerName, BankSaldo,  LastUpdated)
VALUES
(NEW.PlayerUID, NEW.PlayerName, 0, NOW());

done, hf

Link to comment
Share on other sites

since this fix didnt always work for me i simply created a database trigger which inserts id and name into the banking data field when a new player_Data entry is created

 

to apply this you should truncate your player_data table (no inventory will be lost, its just a table with names and playerUIDs)

 

after that exec that query:

done, hf

 

Yup seems like this would do the trick as well. Will change the first post for possible fixes. Thanks for that.

Link to comment
Share on other sites

since this fix didnt always work for me i simply created a database trigger which inserts id and name into the banking data field when a new player_Data entry is created

 

to apply this you should truncate your player_data table (no inventory will be lost, its just a table with names and playerUIDs)

 

after that exec that query:

CREATE TRIGGER banking
AFTER UPDATE ON player_Data
FOR EACH ROW
INSERT INTO banking_Data
( PlayerUID, PlayerName, BankSaldo,  LastUpdated)
VALUES
(NEW.PlayerUID, NEW.PlayerName, 0, NOW());

done, hf

 

Please explain how to truncate the table.  I am using Heidi SQL, not sure if I have option to remove the other two columns. 

Link to comment
Share on other sites

Simply execute that query:

TRUNCATE TABLE player_data

You could also empty it by hand if you like ^^

I think we have this issue and I guess we need the resolution so here thanks for posting it.

 

CREATE TRIGGER banking

AFTER UPDATE ON player_Data

FOR EACH ROW

INSERT INTO banking_Data

( PlayerUID, PlayerName, BankSaldo, LastUpdated)

VALUES

(NEW.PlayerUID, NEW.PlayerName, 0, NOW());

I understand the above code it will auto-insert bank account to the table every time it's actioned - cool!

 

 

 

 

however this TRUNCATE command alarms my bambi side.

 

 

TRUNCATE TABLE (Transact-SQL)

Removes all rows from a table without logging the individual row deletions. TRUNCATE TABLE is similar to the DELETE statement with no WHERE clause; however, TRUNCATE TABLE is faster and uses fewer system and transaction log resources.

 

 

 

 

 

Why are we truncating it? :)

Link to comment
Share on other sites

we do truncate it because this trigger only works on insert in player_data not and not on update, (it would be possible to create a trigger for update too!)

 

so if you would have a player where banking_Data did not get created and he is already in the player_Data table, my trigger would not help fix it ....

 

it doesnt really hurt to truncate the player_Data table because nothing gets lost. No character gets wiped or anything

 

its only a table with playername and playerUID which simply gets created new if its missing ...

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
×
×
  • Create New...