- 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
351 lines
15 KiB
Plaintext
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)
|