Getting supporters add-on to work with new loadaccount persistence file?

  • Offline Magic
  • First Blood
  • ***
  • Posts: 92
I am trying to get the supporters addon i had runningf pre-1.62 running with the new set up and i cannot seem to get it to work. I use LouDs database option to allocate a supporter level to a player via the database, then use Caels gearcheck.sqf to apply the different levels of gear accordingly.

All the files and calls are in place as per the old server, but i am thinking that the new layout of the persistence/server/players/extdb/loadaccount.sqf file might be the problem?

Here is the pre 1.62 version:

Code: [Select]
// ******************************************************************************************
// * This project is licensed under the GNU Affero GPL v3. Copyright © 2014 A3Wasteland.com *
// ******************************************************************************************
// @file Name: loadAccount.sqf
// @file Author: Torndeco, AgentRev

if (!isServer) exitWith {};

private ["_UID", "_bank", "_moneySaving", "_result", "_data", "_dataTemp", "_ghostingTimer", "_secs", "_supporters", "_supportersEnabled"];
_UID = _this;

_bank = 0;
_supporters = 0;
_PlayerSupporterLevel = 0;
_moneySaving = ["A3W_moneySaving"] call isConfigOn;
_supportersEnabled = ["A3W_supportersEnabled"] call isConfigOn;

if (_supportersEnabled) then
{
_result = ["getPlayerSupporterLevel:" + _UID, 2] call extDB_Database_async;

if (count _result > 0) then
{
_supporters = _result select 0;
};
};

if (_moneySaving) then
{
_result = ["getPlayerBankMoney:" + _UID, 2] call extDB_Database_async;

if (count _result > 0) then
{
_bank = _result select 0;
};
};

_result = ([format ["checkPlayerSave:%1:%2", _UID, call A3W_extDB_MapID], 2] call extDB_Database_async) select 0;

if (!_result) then
{
_data =
[
["PlayerSaveValid", false],
["BankMoney", _bank],
["SupporterLevel", _supporters]
];
}
else
{
// The order of these values is EXTREMELY IMPORTANT!
_data =
[
"Damage",
"HitPoints",

"LoadedMagazines",

"PrimaryWeapon",
"SecondaryWeapon",
"HandgunWeapon",

"PrimaryWeaponItems",
"SecondaryWeaponItems",
"HandgunItems",

"AssignedItems",

"CurrentWeapon",
"Stance",

"Uniform",
"Vest",
"Backpack",
"Goggles",
"Headgear",

"UniformWeapons",
"UniformItems",
"UniformMagazines",

"VestWeapons",
"VestItems",
"VestMagazines",

"BackpackWeapons",
"BackpackItems",
"BackpackMagazines",

"WastelandItems",

"UniformTexture",
"BackpackTexture",

"Hunger",
"Thirst",

"Position",
"Direction"
];

if (_moneySaving) then
{
_data pushBack "Money";
};

_result = [format ["getPlayerSave:%1:%2:%3", _UID, call A3W_extDB_MapID, _data joinString ","], 2] call extDB_Database_async;

{
_data set [_forEachIndex, [_data select _forEachIndex, _x]];
} forEach _result;

_dataTemp = _data;
_data = [["PlayerSaveValid", true]];

_ghostingTimer = ["A3W_extDB_GhostingTimer", 5*60] call getPublicVar;

if (_ghostingTimer > 0) then
{
_result = [format ["getTimeSinceServerSwitch:%1:%2:%3", _UID, call A3W_extDB_MapID, call A3W_extDB_ServerID], 2] call extDB_Database_async;

if (count _result > 0) then
{
_secs = _result select 0;

if (_secs < _ghostingTimer) then
{
_data pushBack ["GhostingTimer", _ghostingTimer - _secs];
};
};
};

_data append _dataTemp;
_data pushBack ["BankMoney", _bank];
_data pushBack ["SupporterLevel", _supporters];
};

_data

And here is how i have edited the new version:

Code: [Select]
// ******************************************************************************************
// * This project is licensed under the GNU Affero GPL v3. Copyright © 2014 A3Wasteland.com *
// ******************************************************************************************
// @file Name: loadAccount.sqf
// @file Author: Torndeco, AgentRev

if (!isServer) exitWith {};

params ["_UID", "_player"];
private ["_result", "_data", "_location", "_dataTemp", "_ghostingTimer", "_secs", "_columns", "_pvar", "_pvarG", "_supporters", "_supportersEnabled"];

_supporters = 0;
_PlayerSupporterLevel = 0;
_supportersEnabled = ["A3W_supportersEnabled"] call isConfigOn;

if (_supportersEnabled) then
{
_result = ["getPlayerSupporterLevel:" + _UID, 2] call extDB_Database_async;

if (count _result > 0) then
{
_supporters = _result select 0;
};
};

private _moneySaving = ["A3W_moneySaving"] call isConfigOn;
private _crossMap = ["A3W_extDB_playerSaveCrossMap"] call isConfigOn;
private _environment = ["A3W_extDB_Environment", "normal"] call getPublicVar;
private _mapID = call A3W_extDB_MapID;

private _query = [["checkPlayerSave", _UID, _mapID], ["checkPlayerSaveXMap", _UID, _environment]] select _crossMap;
_result = ([_query, 2] call extDB_Database_async) param [0,false];

if (!_result) then
{
_data =
[
["PlayerSaveValid", false],
["SupporterLevel", _supporters]
];

// prevent constraint fail on first save
private _sqlValues = [[["Name", name _player]], [0,1], false] call extDB_pairsToSQL;
[["insertOrUpdatePlayerInfo", _UID, _sqlValues select 0, _sqlValues select 1]] call extDB_Database_async;
}
else
{
// The order of these values is EXTREMELY IMPORTANT!
_data =
[
"Damage",
"HitPoints",

"LoadedMagazines",

"PrimaryWeapon",
"SecondaryWeapon",
"HandgunWeapon",

"PrimaryWeaponItems",
"SecondaryWeaponItems",
"HandgunItems",

"AssignedItems",

"CurrentWeapon",

"Uniform",
"Vest",
"Backpack",
"Goggles",
"Headgear",

"UniformWeapons",
"UniformItems",
"UniformMagazines",

"VestWeapons",
"VestItems",
"VestMagazines",

"BackpackWeapons",
"BackpackItems",
"BackpackMagazines",

"WastelandItems",

"Hunger",
"Thirst"
];

_location = ["Stance", "Position", "Direction"];

if (!_crossMap) then
{
_data append _location;
};

if (_moneySaving) then
{
_data pushBack "Money";
};

_query = [["getPlayerSave", _UID, _mapID], ["getPlayerSaveXMap", _UID, _environment]] select _crossMap;
_query pushBack (_data joinString ",");
_result = [_query, 2] call extDB_Database_async;

{ _data set [_forEachIndex, [_data select _forEachIndex, _x]] } forEach _result;

if (_crossMap) then
{
_result = [["getPlayerSave", _UID, _mapID, _location joinString ","], 2] call extDB_Database_async;

if (count _result == count _location) then
{
{ _location set [_forEachIndex, [_location select _forEachIndex, _x]] } forEach _result;

_data append _location;
};
};

_dataTemp = _data;
_data = [["PlayerSaveValid", true]];

_ghostingTimer = ["A3W_extDB_GhostingTimer", 5*60] call getPublicVar;

if (_ghostingTimer > 0) then
{
_query = [["getTimeSinceServerSwitch", _UID, _mapID], ["getTimeSinceServerSwitchXMap", _UID, _environment]] select _crossMap;
_query pushBack call A3W_extDB_ServerID;
_result = [_query, 2] call extDB_Database_async;

if (count _result > 0) then
{
_secs = _result select 0; // [_result select 1] = LastServerID, if _crossMap then [_result select 2] = WorldName

if (_secs < _ghostingTimer) then
{
_data pushBack ["GhostingTimer", _ghostingTimer - _secs];
};
};
};

_data append _dataTemp;
_data pushBack ["SupporterLevel", _supporters];
//_data pushBack ["BankMoney", _bank];
};

private _bank = 0;
private _bounty = 0;
private _bountyKills = [];

if (_moneySaving) then
{
_result = ["getPlayerBankMoney:" + _UID, 2] call extDB_Database_async;

_bank = _result param [0,0];
};

if (["A3W_atmBounties"] call isConfigOn) then
{
_result = ["getPlayerBounty:" + _UID, 2] call extDB_Database_async;

_bounty = _result param [0,0];
_bountyKills = _result param [1,[]];
};

_data append
[
["BankMoney", _bank],
["Bounty", _bounty],
["BountyKills", _bountyKills]
];

if (["A3W_privateParking"] call isConfigOn) then
{
_columns = (call fn_getVehicleVars) apply {_x select 0};
_result = [["getParkedVehicles", _UID, _environment, _columns joinString ","], 2, true] call extDB_Database_async;

_columns deleteAt 0; // remove ID col
private _vehicles = [];
private ["_vehID", "_vehVars"];

{
_vehID = _x deleteAt 0;
_vehVars = _x;

{ _vehVars set [_forEachIndex, [_columns select _forEachIndex, _x]] } forEach _vehVars;

_vehicles pushBack [_vehID, _vehVars];
} forEach _result;

_player setVariable ["parked_vehicles", _vehicles];
_data pushBack ["ParkedVehicles", _vehicles];
};

if (["A3W_privateStorage"] call isConfigOn) then
{
_columns = ["Weapons", "Magazines", "Items", "Backpacks"];
_result = [["getPlayerStorageXMap", _UID, _environment, _columns joinString ","], 2] call extDB_Database_async;

private _storage = [];

{ _storage pushBack [_columns select _forEachIndex, _x] } forEach _result;

_data pushBack ["PrivateStorage", _storage];
};

// before returning player data, restore global player stats if applicable
if (["A3W_playerStatsGlobal"] call isConfigOn) then
{
_columns = ["playerKills", "aiKills", "teamKills", "deathCount", "reviveCount", "captureCount"];
_result = [["getPlayerStats", _UID, _columns joinString ","], 2] call extDB_Database_async;

{
_pvar = format ["A3W_playerScore_%1_%2", _columns select _forEachIndex, _UID];
_pvarG = _pvar + "_global";
missionNamespace setVariable [_pvarG, _x - (missionNamespace getVariable [_pvar, 0])];
publicVariable _pvarG;
} forEach _result;
};

_data

Would anyone be able to spot anything obvious?

I have added the supporterlevel column to the database and added it to the a3wasteland.ini here:

Code: [Select]
[Default]
Version = 12

Number of Inputs = 0

Sanitize Input Value Check = false
Sanitize Output Value Check = false

Prepared Statement Cache = true

Return InsertID = false

Strip = true
Strip Chars Action = STRIP
Strip Chars = /\|;{}<>'`
Strip Custom Chars = /\|;{}<>'`


; --------------------------------------------------------------------------------
; DB INFO
; --------------------------------------------------------------------------------

[getDBVersion]
SQL1_1 = SELECT IFNULL ((SELECT Value FROM DBInfo WHERE Name = 'Version'), '2.0');

Prepared Statement Cache = false

; --------------------------------------------------------------------------------
; SERVER INSTANCE & MAP
; --------------------------------------------------------------------------------

[checkServerInstance]
SQL1_1 = SELECT IF ((SELECT 1 FROM ServerInstance WHERE ID = ?), 'true', 'false');

Prepared Statement Cache = false
Number of Inputs = 1
SQL1_INPUTS = 1

[insertServerInstance]
SQL1_1 = INSERT INTO ServerInstance SET ID = ?;

Prepared Statement Cache = false
Number of Inputs = 1
SQL1_INPUTS = 1

[getServerMapID]
SQL1_1 = SELECT IFNULL ((SELECT ID FROM ServerMap WHERE WorldName = ? AND Environment = ?), 0);

Prepared Statement Cache = false
Number of Inputs = 2
SQL1_INPUTS = 1,2

[insertServerMap]
SQL1_1 = INSERT INTO ServerMap SET WorldName = ?, Environment = ?;

Prepared Statement Cache = false
Return InsertID = true
Number of Inputs = 2
SQL1_INPUTS = 1,2

; --------------------------------------------------------------------------------
; PLAYER SAVING
; --------------------------------------------------------------------------------

[checkPlayerSave]
SQL1_1 = SELECT IF ((SELECT 1 FROM PlayerSave WHERE PlayerUID = ? AND MapID = ?), 'true', 'false');

Number of Inputs = 2
SQL1_INPUTS = 1,2

[checkPlayerSaveXMap]
SQL1_1 = SELECT IF ((SELECT 1 FROM PlayerSave ps INNER JOIN (SELECT ID AS ServerMapID FROM ServerMap WHERE Environment = ?) sm
SQL1_2 =             WHERE PlayerUID = ? AND ps.MapID = sm.ServerMapID GROUP BY 1), 'true', 'false');

Number of Inputs = 2
SQL1_INPUTS = 2,1

[getPlayerSave]
SQL1_1 = SELECT $CUSTOM_1$ FROM PlayerSave WHERE PlayerUID = ? AND MapID = ?;

Number of Inputs = 2
Number of Custom Inputs = 1
SQL1_INPUTS = 1,2

[getPlayerSaveXMap]
SQL1_1 = SELECT $CUSTOM_1$ FROM PlayerSave ps INNER JOIN (SELECT ID AS ServerMapID FROM ServerMap WHERE Environment = ?) sm
SQL1_2 = WHERE PlayerUID = ? AND ps.MapID = sm.ServerMapID
SQL1_3 = ORDER BY LastModified DESC LIMIT 1;

Number of Inputs = 2
Number of Custom Inputs = 1
SQL1_INPUTS = 2,1

[getPlayerBankMoney]
SQL1_1 = SELECT BankMoney FROM PlayerInfo WHERE UID = ?;

Number of Inputs = 1
SQL1_INPUTS = 1

[getPlayerBounty]
SQL1_1 = SELECT Bounty, BountyKills FROM PlayerInfo WHERE UID = ?;

Number of Inputs = 1
SQL1_INPUTS = 1

[getTimeSinceServerSwitch]
SQL1_1 = SELECT TIMESTAMPDIFF(SECOND, LastModified, NOW()), LastServerID FROM PlayerSave
SQL1_2 = WHERE PlayerUID = ? AND MapID = ? AND LastServerID != ? AND LastServerID IS NOT NULL;

Number of Inputs = 3
SQL1_INPUTS = 1,2,3

[getTimeSinceServerSwitchXMap]
SQL1_1 = SELECT TIMESTAMPDIFF(SECOND, LastModified, NOW()), LastServerID, WorldName
SQL1_2 = FROM PlayerSave ps INNER JOIN (SELECT ID AS ServerMapID, WorldName FROM ServerMap WHERE Environment = ?) sm
SQL1_3 = WHERE PlayerUID = ? AND ps.MapID = sm.ServerMapID AND LastServerID != ? AND LastServerID IS NOT NULL
SQL1_4 = ORDER BY LastModified DESC LIMIT 1;

Number of Inputs = 3
SQL1_INPUTS = 2,1,3

[insertOrUpdatePlayerInfo]
SQL1_1 = INSERT INTO PlayerInfo SET UID = ?, BattlEyeGUID = REPLACE(?,'"',''), $CUSTOM_1$
SQL1_2 = ON DUPLICATE KEY UPDATE $CUSTOM_2$;

Number of Inputs = 1
Number of Custom Inputs = 2
SQL1_INPUTS = 1,1-STRING-BEGUID

Strip Custom Chars = /\|;{}<>`

[insertOrUpdatePlayerSave]
SQL1_1 = INSERT INTO PlayerSave SET PlayerUID = ?, MapID = ?, LastServerID = ?, CreationDate = NOW(), $CUSTOM_1$
SQL1_2 = ON DUPLICATE KEY UPDATE LastServerID = VALUES(LastServerID), $CUSTOM_2$;

Number of Inputs = 3
Number of Custom Inputs = 2
SQL1_INPUTS = 1,2,3

Strip Custom Chars = /|;{}<>`

[deletePlayerSave]
SQL1_1 = DELETE FROM PlayerSave WHERE PlayerUID = ? AND MapID = ?;

Number of Inputs = 2
SQL1_INPUTS = 1,2

[deletePlayerSaveXMap]
SQL1_1 = DELETE ps FROM PlayerSave ps INNER JOIN (SELECT ID AS ServerMapID FROM ServerMap WHERE Environment = ?) sm
SQL1_2 = WHERE PlayerUID = ? AND ps.MapID = sm.ServerMapID;

Number of Inputs = 2
SQL1_INPUTS = 2,1

[getPlayerStats]
SQL1_1 = SELECT $CUSTOM_1$ FROM PlayerStats WHERE PlayerUID = ?;

Number of Inputs = 1
Number of Custom Inputs = 1
SQL1_INPUTS = 1

[insertOrUpdatePlayerStats]
SQL1_1 = INSERT INTO PlayerStats SET PlayerUID = ?, $CUSTOM_1$ = $CUSTOM_2$
SQL1_2 = ON DUPLICATE KEY UPDATE $CUSTOM_1$ = $CUSTOM_1$ + $CUSTOM_2$;
SQL2_1 = INSERT INTO PlayerStatsMap SET PlayerUID = ?, ServerID = ?, MapID = ?, $CUSTOM_1$ = $CUSTOM_2$
SQL2_2 = ON DUPLICATE KEY UPDATE $CUSTOM_1$ = $CUSTOM_1$ + $CUSTOM_2$;

Number of Inputs = 3
Number of Custom Inputs = 2
SQL1_INPUTS = 1
SQL2_INPUTS = 1,2,3

[getPlayerSupporterLevel]
SQL1_1 = SELECT SupporterLevel FROM PlayerInfo WHERE UID = ?;

Number of Inputs = 1
SQL1_INPUTS = 1

Any help would be greatly appreciated.

Thanks
  • Offline Magic
  • First Blood
  • ***
  • Posts: 92
Or could it be my shoddy conversion of the persistance/server/players/setupPlayerDB.sqf file?

Pre 1.62:

Code: [Select]
"pvar_requestPlayerData" addPublicVariableEventHandler
{
(_this select 1) spawn
{
_UID = _this select 1;
_data = _UID call fn_loadAccount;

[[_this, _data],
{
_pVal = _this select 0;
_data = _this select 1;

_player = _pVal select 0;
_UID = _pVal select 1;
_pNetId = _pVal select 2;

_pvarName = "pvar_applyPlayerData_" + _UID;

missionNamespace setVariable [_pvarName, _data];
(owner _player) publicVariableClient _pvarName;

{
if (_x select 0 == "BankMoney") then
{
_player setVariable ["bmoney", _x select 1, true];
};
if (_x select 0 == "supporterLevel") then
{
_player setVariable ["supporter", _x select 1, true];
};
} forEach _data;

diag_log format ["pvar_requestPlayerData: %1", [owner _player, _player, objectFromNetId _pNetId]];
}] execFSM "call.fsm";
};
};

New version:

Code: [Select]
"pvar_requestPlayerData" addPublicVariableEventHandler
{
(_this select 1) spawn
{
params ["_player", "_UID"];
_data = [_UID, _player] call fn_loadAccount;

[[_this, _data],
{
params ["_pVal", "_data"];
_pVal params ["_player", "_UID", "_pNetId"];

_pvarName = "pvar_applyPlayerData_" + _UID;

missionNamespace setVariable [_pvarName, _data];
(owner _player) publicVariableClient _pvarName;

{
_x params ["_var", "_val"];
switch (_var) do
{
case "BankMoney":    { _player setVariable ["bmoney", _val, true] };
case "Bounty":       { _player setVariable ["bounty", _val, true] };
case "supporterLevel":    { _player setVariable ["supporter", _val, true] };
case "BountyKills":  { _player setVariable ["bountyKills", _val, true] };
};
} forEach _data;

diag_log format ["pvar_requestPlayerData: %1", [owner _player, _player, objectFromNetId _pNetId]];
}] execFSM "call.fsm";
};
};
  • Offline AgentRev
  • Developer
  • Veteran
  • ******
  • Posts: 2584
the switch statement is case-sensitive, "supporterLevel" is not gonna work if the database column is named "SupporterLevel"
  • Offline Magic
  • First Blood
  • ***
  • Posts: 92
Thanks very much for the reply.

I have changed the supporterLevel to SupporterLevel in the setupPlayerDB file, but it still will not work.  Is there any issues with where the call is placed in the setupPlayerDB file, or does it need a data_append reference too?

Or could there be an issue with where the reference is placed in the a3wasteland.ini file? or even what position the column is located in the database?

Im struggling here, its the last thing needing to be fixed for the apex changeover for me.
  • Offline Magic
  • First Blood
  • ***
  • Posts: 92
in the gearCheck.sqf, the call is made with this code:

Code: [Select]
_supportersEnabled = ["A3W_supportersEnabled"] call isConfigOn;
_supporterLevel = player getVariable ["supporter", 0];


sleep 1;
switch (_supporterLevel) do
{
    case 1:

im right in thinking that wouldn't need a capital S?
  • Offline AgentRev
  • Developer
  • Veteran
  • ******
  • Posts: 2584
I don't know, I cannot spot any problem in the code... have you tried looking at the extDB logs?

Also, make sure "A3W_supportersEnabled" is in the broadcast list from server\init.sqf
  • Offline Magic
  • First Blood
  • ***
  • Posts: 92
Aha! Fixed. Boom. For anyone else searching this issue, the problem was a poxy capital s in the persistance/server/players/default/loadAccount.sqf:

Code: [Select]
["supporter", "NUMBER", "PlayerInfo"] call _getValue;
Thanks for taking the trouble to help anyways dude, appreciate it, cheers.
  • Offline AgentRev
  • Developer
  • Veteran
  • ******
  • Posts: 2584
wait, so you're still using iniDB? why did you edit the extDB files?
  • Offline Magic
  • First Blood
  • ***
  • Posts: 92
no, am using extDB. I frankensteined the code from the original LouDnl system that gave players that virtual arsenal thing so that i could use the database to add and remove players on the fly but use the Cael gear addon for actually implementing the loadouts without having to keep uploading new PBOs when someone was added or removed. I have probably got loads of bit of code that are not needed or just plain ridiculous as i clearly haven't got a clue what i am doing, but i got it working so was fairly satisfied with that. If a more streamlined way of activating the cael gear system from a database field could be done i would be more than happy to implement it!
  • Offline AgentRev
  • Developer
  • Veteran
  • ******
  • Posts: 2584
none of that actually explains why you need the iniDB files to work...
  • Offline hobart
  • First Blood
  • ***
  • Posts: 82
Thank you for this thread it helped a lot I am finally updating and was using the Supporters by CreamPie as well and was thumping my head on the desk over this!
  • Offline Matt76
  • Mercenary
  • *****
  • Posts: 418
  • co founder of customcombatgaming.com
Be careful you're not allowed to offer load outs to donators chap
  • Offline hobart
  • First Blood
  • ***
  • Posts: 82
Oh I know, I use this for admins, on my forums I vehemently refuse donations anyway. I did however find a technicality that could possibly allow those whom wish to accept donations for the use of this to use them but again. I do not accept donations. BIS said "as long as everyone joining has the ability to use it". When in the cat skinning biz one must have many knives...