forge/arma/server/addons/bank/functions/fnc_initStore.sqf
Jacob Schmidt 45a4f7460a Integrate task contracts and CAD UI pipeline
- add the imported server task addon to the current framework with task ownership, task catalog, mission-manager attack generation, org-owned reward routing, participant notifications, and reputation syncing
- restructure org persistence so core org data, assets, fleet, and members are handled through the current Redis/extension model with matching Rust repository and service updates
- wire the client CAD addon into the framework, actor device action, shared web UI bridge pattern, and task listing/acceptance flow
- add a source-driven CAD web UI layout with ui.config.mjs and extend the shared web UI builder to support custom HTML template pages for multi-surface UIs
2026-03-28 02:20:34 -05:00

351 lines
15 KiB
Plaintext

#include "..\script_component.hpp"
/*
* File: fnc_initStore.sqf
* Author: IDSolutions
* Date: 2025-12-17
* Last Update: 2026-03-16
* Public: No
*
* Description:
* Initializes the bank store for managing player bank accounts.
* Handles account lifecycle (init/fetch/create/migrate), transaction
* mutations, checkout charges, and session hydration.
*
* Parameter(s):
* None
*
* Returns:
* Bank store object [HASHMAP OBJECT]
*
* Example(s):
* call forge_server_bank_fnc_initStore
*/
#pragma hemtt ignore_variables ["_self"]
GVAR(BankBaseStore) = compileFinal createHashMapFromArray [
["#base", EGVAR(common,BaseStore)],
["#type", "BankBaseStore"],
["#create", compileFinal {
GVAR(IndexRegistry) = createHashMap;
GVAR(Registry) = createHashMap;
GVAR(SessionRegistry) = createHashMap;
["INFO", "Bank Store Initialized!"] call EFUNC(common,log);
}],
["buildChargeResult", compileFinal {
params [["_message", "Unable to process bank payment.", [""]]];
createHashMapFromArray [
["success", false],
["message", _message],
["patch", createHashMap]
]
}],
["buildHydratePayload", compileFinal {
params [["_uid", "", [""]], ["_mode", "", [""]], ["_resetAuthorization", false, [false]]];
if (_uid isEqualTo "") exitWith { createHashMap };
private _account = GVAR(Registry) getOrDefault [_uid, createHashMap];
if (_account isEqualTo createHashMap) then { _account = _self call ["init", [_uid]]; };
if (_account isEqualTo createHashMap) exitWith { createHashMap };
private _session = GVAR(BankSessionManager) call ["syncSessionMode", [_uid, _mode, _resetAuthorization]];
private _orgState = _self call ["resolveOrgState", [_uid]];
private _player = [_uid] call EFUNC(common,getPlayer);
private _playerName = if (isNull _player) then {
_account getOrDefault ["name", "Unknown"]
} else {
name _player
};
createHashMapFromArray [
["session", createHashMapFromArray [
["atmAuthorized", _session getOrDefault ["atmAuthorized", false]],
["mode", _session getOrDefault ["mode", "bank"]],
["orgFunds", _orgState getOrDefault ["funds", 0]],
["orgName", _orgState getOrDefault ["name", ""]],
["playerName", _playerName],
["transferTargets", _self call ["buildTransferTargets", [_uid]]],
["uid", _uid]
]],
["account", GVAR(BankMessenger) call ["buildClientAccountPatch", [_account]]]
]
}],
["buildTransferTargets", compileFinal {
params [["_sourceUid", "", [""]]];
private _targets = [];
{
if (isNull _x) then { continue; };
private _targetUid = getPlayerUID _x;
private _targetName = name _x;
if (_targetUid isEqualTo "" || { _targetUid isEqualTo _sourceUid } || { _targetName isEqualTo "" }) then { continue; };
_targets pushBack (createHashMapFromArray [
["name", _targetName],
["uid", _targetUid]
]);
} forEach allPlayers;
private _targetPairs = _targets apply { [toLowerANSI (_x getOrDefault ["name", ""]), _x] };
_targetPairs sort true;
_targetPairs apply { _x param [1, createHashMap] }
}],
["chargeCheckout", compileFinal {
params [["_uid", "", [""]], ["_source", "cash", [""]], ["_amount", 0, [0]], ["_commit", false, [false]]];
private _result = _self call ["buildChargeResult", []];
private _field = switch (toLowerANSI _source) do {
case "cash": { "cash" };
case "bank": { "bank" };
default { "" };
};
if (_field isEqualTo "") exitWith {
_result set ["message", "Selected bank payment source is unsupported."];
_result
};
private _account = GVAR(Registry) getOrDefault [_uid, createHashMap];
if (_account isEqualTo createHashMap) exitWith {
_result set ["message", "Bank account data is unavailable for checkout."];
_result
};
private _balance = _account getOrDefault [_field, 0];
if (_balance < _amount) exitWith {
private _message = [
"Bank balance cannot cover this checkout.",
"Cash on hand cannot cover this checkout."
] select (_field isEqualTo "cash");
_result set ["message", _message];
_result
};
private _patch = createHashMapFromArray [[_field, (_balance - _amount)]];
if (_commit) then {
_patch = _self call ["mset", [GVAR(Registry), "bank:update", _uid, _patch, false]];
};
_result set ["success", true];
_result set ["message", ""];
_result set ["patch", _patch];
_result
}],
["deposit", compileFinal {
params [["_uid", "", [""]], ["_amount", 0, [0]], ["_context", createHashMap, [createHashMap]]];
["INFO", format ["Deposit %1, for %2", _amount, _uid]] call EFUNC(common,log);
private _bank = _context getOrDefault ["bank", 0];
private _cash = _context getOrDefault ["cash", 0];
private _patch = createHashMapFromArray [
["bank", (_bank + _amount)],
["cash", (_cash - _amount)]
];
private _finalPatch = _self call ["mset", [GVAR(Registry), "bank:update", _uid, _patch, false]];
GVAR(BankMessenger) call ["sendAccountSync", [_uid, _finalPatch]];
GVAR(BankMessenger) call ["sendClientNotification", [_uid, "info", "Bank", format ["Deposited $%1", [_amount] call EFUNC(common,formatNumber)]]];
true
}],
["hydrateSession", compileFinal {
params [["_uid", "", [""]], ["_mode", "", [""]], ["_resetAuthorization", false, [false]]];
private _payload = _self call ["buildHydratePayload", [_uid, _mode, _resetAuthorization]];
if (_payload isEqualTo createHashMap) exitWith { false };
private _player = [_uid] call EFUNC(common,getPlayer);
if (isNull _player) exitWith { false };
[CRPC(bank,responseHydrateBank), [_payload], _player] call CFUNC(targetEvent);
true
}],
["init", compileFinal {
params [["_uid", "", [""]]];
if (_uid isEqualTo "") exitWith { createHashMap };
private _player = [_uid] call EFUNC(common,getPlayer);
private _playerName = if (isNull _player) then { "Unknown" } else { name _player };
private _cached = GVAR(Registry) getOrDefault [_uid, createHashMap];
if (_cached isNotEqualTo createHashMap) exitWith {
GVAR(BankMessenger) call ["sendAccountSync", [_uid, _cached, CRPC(bank,responseInitBank)]];
_cached
};
["bank:exists", [_uid]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"];
if !(_isSuccess) exitWith {
["ERROR", format ["Failed to check if bank account %1 exists! Using fallback account.", _uid]] call EFUNC(common,log);
private _fallbackAccount = GVAR(BankModel) call ["fromPlayer", [_player]];
_fallbackAccount set ["uid", _uid];
if ((_fallbackAccount getOrDefault ["name", ""]) isEqualTo "") then {
_fallbackAccount set ["name", _playerName];
};
private _regEntry = createHashMapFromArray [["uid", _uid], ["name", _playerName]];
GVAR(IndexRegistry) set [_uid, _regEntry];
GVAR(Registry) set [_uid, _fallbackAccount];
GVAR(BankMessenger) call ["sendAccountSync", [_uid, _fallbackAccount, CRPC(bank,responseInitBank)]];
_fallbackAccount
};
private _finalAccount = createHashMap;
if (_result isEqualTo "true") then {
_finalAccount = _self call ["fetch", ["bank:get", _uid]];
["INFO", format ["Found bank account for %1", _uid]] call EFUNC(common,log);
} else {
_finalAccount = GVAR(BankModel) call ["fromPlayer", [_player]];
_finalAccount set ["uid", _uid];
if ((_finalAccount getOrDefault ["name", ""]) isEqualTo "") then {
_finalAccount set ["name", _playerName];
};
private _json = _self call ["toJSON", [_finalAccount]];
["bank:create", [_uid, _json]] call EFUNC(extension,extCall) params ["_createResult", "_createSuccess"];
if (!_createSuccess) exitWith {
["ERROR", format ["Failed to create bank account %1! Using fallback account.", _uid]] call EFUNC(common,log);
private _regEntry = createHashMapFromArray [["uid", _uid], ["name", _playerName]];
GVAR(IndexRegistry) set [_uid, _regEntry];
GVAR(Registry) set [_uid, _finalAccount];
GVAR(BankMessenger) call ["sendAccountSync", [_uid, _finalAccount, CRPC(bank,responseInitBank)]];
_finalAccount
};
["INFO", format ["Created new bank account for %1", _uid]] call EFUNC(common,log);
};
_finalAccount = GVAR(BankModel) call ["migrate", [_finalAccount]];
if ((_finalAccount getOrDefault ["uid", ""]) isEqualTo "") then {
_finalAccount set ["uid", _uid];
};
if ((_finalAccount getOrDefault ["name", ""]) isEqualTo "") then {
_finalAccount set ["name", _playerName];
};
GVAR(IndexRegistry) set [_uid, createHashMapFromArray [["uid", _uid], ["name", _playerName]]];
GVAR(Registry) set [_uid, _finalAccount];
GVAR(BankMessenger) call ["sendAccountSync", [_uid, _finalAccount, CRPC(bank,responseInitBank)]];
_finalAccount
}],
["payment", compileFinal {
params [["_uid", "", [""]], ["_amount", 0, [0]], ["_context", createHashMap, [createHashMap]]];
["INFO", format ["Payment %1, for %2", _amount, _uid]] call EFUNC(common,log);
private _bank = _context getOrDefault ["bank", 0];
private _patch = createHashMapFromArray [["bank", (_bank + _amount)]];
private _finalPatch = _self call ["mset", [GVAR(Registry), "bank:update", _uid, _patch, false]];
GVAR(BankMessenger) call ["sendAccountSync", [_uid, _finalPatch]];
GVAR(BankMessenger) call ["sendClientNotification", [_uid, "info", "Bank", format ["Paid $%1", [_amount] call EFUNC(common,formatNumber)]]];
true
}],
["resolveOrgState", compileFinal {
params [["_uid", "", [""]]];
private _defaultState = createHashMapFromArray [
["funds", 0],
["name", ""]
];
if (_uid isEqualTo "") exitWith { _defaultState };
private _actor = EGVAR(actor,Registry) getOrDefault [_uid, createHashMap];
private _orgID = _actor getOrDefault ["organization", "default"];
if (_orgID isEqualTo "") then { _orgID = "default"; };
private _org = EGVAR(org,OrgStore) call ["loadById", [_orgID]];
if (_org isEqualTo createHashMap) then {
_org = EGVAR(org,OrgStore) call ["loadById", ["default"]];
};
if (_org isEqualTo createHashMap) exitWith { _defaultState };
createHashMapFromArray [
["funds", _org getOrDefault ["funds", 0]],
["name", _org getOrDefault ["name", ""]]
]
}],
["transfer", compileFinal {
params [["_uid", "", [""]], ["_target", "", [""]], ["_amount", 0, [0]], ["_context", createHashMap, [createHashMap]]];
private _account = _context getOrDefault ["account", createHashMap];
private _targetAccount = _context getOrDefault ["targetAccount", createHashMap];
private _sourceField = _context getOrDefault ["sourceField", "bank"];
private _selected = _context getOrDefault ["sourceBalance", 0];
private _targetBank = _context getOrDefault ["targetBank", 0];
private _sourcePatch = createHashMapFromArray [[_sourceField, (_selected - _amount)]];
private _targetPatch = createHashMapFromArray [["bank", (_targetBank + _amount)]];
private _finalSourcePatch = _self call ["mset", [GVAR(Registry), "bank:update", _uid, _sourcePatch, false]];
private _finalTargetPatch = _self call ["mset", [GVAR(Registry), "bank:update", _target, _targetPatch, false]];
GVAR(BankMessenger) call ["sendAccountSync", [_uid, _finalSourcePatch]];
GVAR(BankMessenger) call ["sendAccountSync", [_target, _finalTargetPatch]];
private _targetPlayer = [_target] call EFUNC(common,getPlayer);
private _targetName = if (isNull _targetPlayer) then {
_targetAccount getOrDefault ["name", "Recipient"]
} else {
name _targetPlayer
};
private _player = [_uid] call EFUNC(common,getPlayer);
private _playerName = if (isNull _player) then {
_account getOrDefault ["name", "Unknown"]
} else {
name _player
};
GVAR(BankMessenger) call ["sendClientNotification", [_uid, "info", "Bank", format ["Transferred $%1 to %2", [_amount] call EFUNC(common,formatNumber), _targetName]]];
GVAR(BankMessenger) call ["sendClientNotification", [_target, "info", "Bank", format ["Received $%1 from %2", [_amount] call EFUNC(common,formatNumber), _playerName]]];
true
}],
["withdraw", compileFinal {
params [["_uid", "", [""]], ["_amount", 0, [0]], ["_context", createHashMap, [createHashMap]]];
["INFO", format ["Withdraw %1, for %2", _amount, _uid]] call EFUNC(common,log);
private _bank = _context getOrDefault ["bank", 0];
private _cash = _context getOrDefault ["cash", 0];
private _patch = createHashMapFromArray [
["bank", (_bank - _amount)],
["cash", (_cash + _amount)]
];
private _finalPatch = _self call ["mset", [GVAR(Registry), "bank:update", _uid, _patch, false]];
GVAR(BankMessenger) call ["sendAccountSync", [_uid, _finalPatch]];
GVAR(BankMessenger) call ["sendClientNotification", [_uid, "info", "Bank", format ["Withdrew $%1", [_amount] call EFUNC(common,formatNumber)]]];
true
}],
["depositEarnings", compileFinal {
params [["_uid", "", [""]], ["_amount", 0, [0]], ["_context", createHashMap, [createHashMap]]];
["INFO", format ["Deposit Earnings %1, for %2", _amount, _uid]] call EFUNC(common,log);
private _bank = _context getOrDefault ["bank", 0];
private _earnings = _context getOrDefault ["earnings", 0];
private _patch = createHashMapFromArray [
["bank", (_bank + _amount)],
["earnings", (_earnings - _amount)]
];
private _finalPatch = _self call ["mset", [GVAR(Registry), "bank:update", _uid, _patch, false]];
GVAR(BankMessenger) call ["sendAccountSync", [_uid, _finalPatch]];
GVAR(BankMessenger) call ["sendClientNotification", [_uid, "info", "Bank", format ["Deposited $%1 from earnings", [_amount] call EFUNC(common,formatNumber)]]];
true
}]
];
GVAR(BankStore) = createHashMapObject [GVAR(BankBaseStore)];
GVAR(BankStore)