#include "..\script_component.hpp" /* * File: fnc_initBankStore.sqf * Author: IDSolutions * Date: 2025-12-17 * Last Update: 2026-01-30 * Public: Yes * * Description: * Initializes the bank store for managing player bank accounts. * Provides methods for syncing, saving, and applying bank accounts to the player. * * Arguments: * None * * Return Value: * Bank store object [HASHMAP OBJECT] * * Example: * call forge_server_bank_fnc_initBankStore */ #pragma hemtt ignore_variables ["_self"] GVAR(BankModel) = compileFinal createHashMapObject [[ ["#type", "BankModel"], ["defaults", { private _account = createHashMap; _account set ["uid", ""]; _account set ["name", ""]; _account set ["bank", 0]; _account set ["cash", 0]; _account set ["earnings", 0]; _account set ["pin", 1234]; _account set ["transactions", []]; _account }], ["fromPlayer", { params [["_player", objNull, [objNull]]]; if (_player isEqualTo objNull) exitWith { _self call ["defaults", []] }; private _account = _self call ["defaults", []]; _account set ["uid", getPlayerUID _player]; _account set ["name", name _player]; _account set ["bank", 0]; _account set ["cash", 0]; _account set ["earnings", 0]; _account set ["pin", 1234]; _account set ["transactions", []]; _account }], ["migrate", { params [["_account", createHashMap, [createHashMap]]]; private _defaults = _self call ["defaults", []]; { if !(_x in _account) then { _account set [_x, _y]; }; } forEach _defaults; _account }], ["validate", { params [["_account", createHashMap, [createHashMap]]]; private _uid = _account getOrDefault ["uid", ""]; private _name = _account getOrDefault ["name", ""]; private _bank = _account getOrDefault ["bank", 0]; private _cash = _account getOrDefault ["cash", 0]; private _earnings = _account getOrDefault ["earnings", 0]; private _pin = _account getOrDefault ["pin", 1234]; [_uid, _name, _bank, _cash, _earnings, _pin] try { if (_uid isEqualTo "" || !(_uid isEqualType "")) then { throw "Invalid UID!"; }; if (_name isEqualTo "" || !(_name isEqualType "")) then { throw "Invalid Name!"; }; if (_bank < 0 || !(_bank isEqualType 0)) then { throw "Invalid Bank!"; }; if (_cash < 0 || !(_cash isEqualType 0)) then { throw "Invalid Cash!"; }; if (_earnings < 0 || !(_earnings isEqualType 0)) then { throw "Invalid Earnings!"; }; if (_pin < 1000 || _pin > 9999 || !(_pin isEqualType 0)) then { throw "Invalid Pin!"; }; } catch { ["ERROR", format ["Failed to validate account %1!", _exception]] call EFUNC(common,log); false }; true }] ]]; GVAR(BankRepository) = compileFinal createHashMapFromArray [ ["#base", EGVAR(common,BaseStore)], ["#type", "BankRepository"], ["#create", { GVAR(BankRegistry) = createHashMap; GVAR(IndexRegistry) = createHashMap; ["INFO", "Bank Repository Initialized!"] call EFUNC(common,log); }], ["get", { params [["_uid", "", [""]]]; private _cached = GVAR(BankRegistry) getOrDefault [_uid, nil]; if !(isNil { _cached }) exitWith { _cached }; private _player = [_uid] call EFUNC(common,getPlayer); ["bank:exists", [_uid]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"]; if !(_isSuccess) exitWith { ["ERROR", format ["Failed to check if bank account %1 exists!", _uid]] call EFUNC(common,log); createHashMap }; private _finalAccount = createHashMap; if (_result == "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]; private _json = _self call ["toJSON", [_finalAccount]]; ["bank:create", [_uid, _json]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"]; if !(_isSuccess) exitWith { ["ERROR", format ["Failed to create bank account %1!", _uid]] call EFUNC(common,log); createHashMap }; ["INFO", format ["Created new bank account for %1", _uid]] call EFUNC(common,log); }; private _regEntry = createHashMapFromArray [["uid", _uid], ["name", (name _player)]]; GVAR(IndexRegistry) set [_uid, _regEntry]; // _finalAccount = GVAR(BankModel) call ["migrate", [_finalAccount]]; GVAR(BankRegistry) set [_uid, _finalAccount]; _finalAccount }], ["deposit", { params [["_uid", "", [""]], ["_amount", 0, [0]]]; ["INFO", format ["Deposit %1, for %2", _amount, _uid]] call EFUNC(common,log); private _account = GVAR(BankRegistry) getOrDefault [_uid, nil]; if (isNil "_account") exitWith { ["ERROR", "Empty/Invalid Account!"] call EFUNC(common,log); }; private _bank = _account getOrDefault ["bank", 0]; private _cash = _account getOrDefault ["cash", 0]; if (_cash < _amount) exitWith { ["WARNING", "Insufficient Funds!"] call EFUNC(common,log); }; private _finalAccount = createHashMapFromArray [["bank", (_bank + _amount)], ["cash", (_cash - _amount)]]; _self call ["mset", [_uid, _finalAccount]]; private _player = [_uid] call EFUNC(common,getPlayer); [CRPC(bank,responseSyncBank), [_finalAccount], _player] call CFUNC(targetEvent); [CRPC(notifications,recieveNotification), ["info", "Bank", format ["Deposited $%1", _amount]], _player] call CFUNC(targetEvent); }], ["payment", { params [["_uid", "", [""]], ["_amount", 0, [0]]]; ["INFO", format ["Payment %1, for %2", _amount, _uid]] call EFUNC(common,log); private _account = GVAR(BankRegistry) getOrDefault [_uid, nil]; if (isNil "_account") exitWith { ["ERROR", "Empty/Invalid Account!"] call EFUNC(common,log); }; private _bank = _account getOrDefault ["bank", 0]; private _finalAccount = createHashMapFromArray [["bank", (_bank + _amount)]]; _self call ["mset", [_uid, _finalAccount]]; private _player = [_uid] call EFUNC(common,getPlayer); [CRPC(bank,responseSyncBank), [_finalAccount], _player] call CFUNC(targetEvent); [CRPC(notifications,recieveNotification), ["info", "Bank", format ["Paid $%1", _amount]], _player] call CFUNC(targetEvent); }], ["transfer", { params [["_uid", "", [""]], ["_target", "", [""]], ["_from", "", [""]], ["_amount", 0, [0]]]; if (_uid isEqualTo _target) exitWith { ["WARNING", format ["Self-transfer attempt blocked for %1", _uid]] call EFUNC(common,log); }; private _account = GVAR(BankRegistry) getOrDefault [_uid, nil]; if (isNil "_account") exitWith { ["ERROR", "Empty/Invalid Account!"] call EFUNC(common,log); }; private _targetAccount = GVAR(BankRegistry) getOrDefault [_target, nil]; if (isNil "_targetAccount") exitWith { ["ERROR", "Empty/Invalid Target Account!"] call EFUNC(common,log); }; private _bank = _account getOrDefault [_from, 0]; if (_bank < _amount) exitWith { ["WARNING", "Insufficient Funds!"] call EFUNC(common,log); }; private _targetBank = _targetAccount getOrDefault ["bank", 0]; private _finalAccount = createHashMapFromArray [[_from, (_bank - _amount)]]; private _finalTargetBank = createHashMapFromArray [["bank", (_targetBank + _amount)]]; _self call ["mset", [_uid, _finalAccount]]; _self call ["mset", [_target, _finalTargetBank]]; private _player = [_uid] call EFUNC(common,getPlayer); private _targetPlayer = [_target] call EFUNC(common,getPlayer); [CRPC(bank,responseSyncBank), [_finalAccount], _player] call CFUNC(targetEvent); [CRPC(bank,responseSyncBank), [_finalTargetBank], _targetPlayer] call CFUNC(targetEvent); [CRPC(notifications,recieveNotification), ["info", "Bank", format ["Transferred $%1 to %2", _amount, (name _targetPlayer)]], _player] call CFUNC(targetEvent); [CRPC(notifications,recieveNotification), ["info", "Bank", format ["Received $%1 from %2", _amount, (name _player)]], _targetPlayer] call CFUNC(targetEvent); }], ["withdraw", { params [["_uid", "", [""]], ["_amount", 0, [0]]]; ["INFO", format ["Withdraw %1, for %2", _amount, _uid]] call EFUNC(common,log); private _account = GVAR(BankRegistry) getOrDefault [_uid, nil]; if (isNil "_account") exitWith { ["ERROR", "Empty/Invalid Account!"] call EFUNC(common,log); }; private _bank = _account getOrDefault ["bank", 0]; private _cash = _account getOrDefault ["cash", 0]; if (_bank < _amount) exitWith { ["WARNING", "Insufficient Funds!"] call EFUNC(common,log); }; private _finalAccount = createHashMapFromArray [["bank", (_bank - _amount)], ["cash", (_cash + _amount)]]; _self call ["mset", [_uid, _finalAccount]]; private _player = [_uid] call EFUNC(common,getPlayer); [CRPC(bank,responseSyncBank), [_finalAccount], _player] call CFUNC(targetEvent); [CRPC(notifications,recieveNotification), ["info", "Bank", format ["Withdrew $%1", _amount]], _player] call CFUNC(targetEvent); }] ]; GVAR(BankStore) = createHashMapObject [[ ["#base", GVAR(BankRepository)], ["#type", "IBankStore"], ["#create", { ["INFO", "Bank Store Initialized!"] call EFUNC(common,log); }], ["init", { params [["_uid", "", [""]]]; private _account = _self call ["get", [_uid]]; private _player = [_uid] call EFUNC(common,getPlayer); [CRPC(bank,responseInitBank), [_account], _player] call CFUNC(targetEvent); }] ]]; GVAR(BankStore)