From 61a9741dc088cd3078ee96a4a54be4c837bc49bd Mon Sep 17 00:00:00 2001 From: Jacob Schmidt Date: Sat, 10 Jan 2026 15:42:33 -0600 Subject: [PATCH 01/37] Refactor Store system to use BaseStore and update Actor/Org initialization --- arma/client/.gitignore | 1 + .../actor/functions/fnc_initActorClass.sqf | 25 +-- .../bank/functions/fnc_handleUIEvents.sqf | 2 +- .../org/functions/fnc_handleUIEvents.sqf | 72 ++++++ arma/client/addons/org/ui/_site/index.html | 2 +- arma/client/addons/org/ui/_site/script.js | 209 ++++++++++++++---- arma/server/.gitignore | 1 + arma/server/addons/actor/XEH_preInit.sqf | 28 ++- arma/server/addons/actor/XEH_preStart.sqf | 1 - .../actor/functions/fnc_initActorStore.sqf | 174 +++++++++++---- arma/server/addons/bank/XEH_preInit.sqf | 32 ++- arma/server/addons/bank/XEH_preStart.sqf | 1 - .../bank/functions/fnc_initBankStore.sqf | 68 +++--- arma/server/addons/common/XEH_PREP.hpp | 2 +- arma/server/addons/common/XEH_preStart.sqf | 1 - .../addons/common/functions/fnc_baseStore.sqf | 103 +++++++++ .../common/functions/fnc_initBaseStore.sqf | 154 ------------- arma/server/addons/economy/XEH_postInit.sqf | 15 -- arma/server/addons/economy/XEH_preInit.sqf | 15 ++ arma/server/addons/economy/XEH_preStart.sqf | 1 - arma/server/addons/garage/XEH_preInit.sqf | 41 +++- arma/server/addons/garage/XEH_preStart.sqf | 1 - .../garage/functions/fnc_initGarageStore.sqf | 67 +----- .../garage/functions/fnc_initVGStore.sqf | 29 ++- arma/server/addons/locker/XEH_preInit.sqf | 36 ++- arma/server/addons/locker/XEH_preStart.sqf | 1 - .../locker/functions/fnc_initLockerStore.sqf | 67 +----- .../locker/functions/fnc_initVAStore.sqf | 27 ++- .../addons/main/functions/fnc_initStores.sqf | 2 +- .../addons/org/functions/fnc_initOrgStore.sqf | 15 +- examples/ext_data.sqf | 7 +- 31 files changed, 688 insertions(+), 512 deletions(-) create mode 100644 arma/server/addons/common/functions/fnc_baseStore.sqf delete mode 100644 arma/server/addons/common/functions/fnc_initBaseStore.sqf diff --git a/arma/client/.gitignore b/arma/client/.gitignore index b786b16..41f642f 100644 --- a/arma/client/.gitignore +++ b/arma/client/.gitignore @@ -3,6 +3,7 @@ hemtt.exe .hemtt/missions/~* .hemttout/ releases/ +.hemttprivatekey # Textures Exports/ diff --git a/arma/client/addons/actor/functions/fnc_initActorClass.sqf b/arma/client/addons/actor/functions/fnc_initActorClass.sqf index 1e008cc..260ecbd 100644 --- a/arma/client/addons/actor/functions/fnc_initActorClass.sqf +++ b/arma/client/addons/actor/functions/fnc_initActorClass.sqf @@ -24,28 +24,10 @@ GVAR(ActorClass) = createHashMapObject [[ _self set ["actor", createHashMap]; _self set ["isLoaded", false]; _self set ["lastSave", time]; - - private _actor = createHashMap; - _actor set ["uid", (getPlayerUID player)]; - _actor set ["name", (name player)]; - _actor set ["loadout", [[],[],[],["U_BG_Guerrilla_6_1",[]],[],[],"H_Cap_blk_ION","",[],["ItemMap","ItemGPS","ItemRadio","ItemCompass","ItemWatch",""]]]; - _actor set ["position", (getPosASL player)]; - _actor set ["direction", (getDir player)]; - _actor set ["stance", (stance player)]; - _actor set ["rank", (rank player)]; - _actor set ["state", (lifeState player)]; - _actor set ["phone_number", ""]; - _actor set ["email", ""]; - _actor set ["organization", ""]; - _actor set ["holster", true]; - - _self set ["actor", _actor]; }], ["init", { private _uid = _self get "uid"; - private _actor = _self get "actor"; - - [SRPC(actor,requestInitActor), [_uid, _actor]] call CFUNC(serverEvent); + [SRPC(actor,requestInitActor), [_uid]] call CFUNC(serverEvent); systemChat format ["Actor loaded for %1", (name player)]; diag_log "[FORGE:Client:Actor] Actor Class Initialized!"; @@ -114,22 +96,18 @@ GVAR(ActorClass) = createHashMapObject [[ }], ["applyDirection", { private _direction = _self call ["get", ["direction", 0]]; - if (GVAR(enableLoc)) then { player setDir _direction; }; }], ["applyStance", { private _stance = _self call ["get", ["stance", "STAND"]]; - if (GVAR(enableLoc)) then { player playAction _stance; }; }], ["applyRank", { private _rank = _self call ["get", ["rank", "PRIVATE"]]; - player setUnitRank _rank; }], ["applyLoadout", { private _loadout = _self call ["get", ["loadout", []]]; - if (GVAR(enableGear) && count _loadout > 0) then { player setUnitLoadout _loadout; }; }], ["getNearbyActions", { @@ -160,5 +138,4 @@ GVAR(ActorClass) = createHashMapObject [[ }] ]]; -SETVAR(player,FORGE_ActorClass,GVAR(ActorClass)); GVAR(ActorClass) diff --git a/arma/client/addons/bank/functions/fnc_handleUIEvents.sqf b/arma/client/addons/bank/functions/fnc_handleUIEvents.sqf index 0d0ec69..46973d4 100644 --- a/arma/client/addons/bank/functions/fnc_handleUIEvents.sqf +++ b/arma/client/addons/bank/functions/fnc_handleUIEvents.sqf @@ -37,7 +37,7 @@ switch (_event) do { // ======================================================================== case "bank::sync": { private _org = 0; // TODO: Get org balance - private _players = SREG(bank,NameRegistry); + private _players = SREG(bank,IndexRegistry); private _accountData = createHashMapFromArray [ ["uid", _uid], ["cash", _cash], diff --git a/arma/client/addons/org/functions/fnc_handleUIEvents.sqf b/arma/client/addons/org/functions/fnc_handleUIEvents.sqf index ce70c0f..89ac8f8 100644 --- a/arma/client/addons/org/functions/fnc_handleUIEvents.sqf +++ b/arma/client/addons/org/functions/fnc_handleUIEvents.sqf @@ -27,6 +27,78 @@ diag_log format ["[FORGE:Client:Org] Handling UI event: %1 with data: %2", _even switch (_event) do { case "org::close": { _display closeDisplay 1; }; + case "org::ready": { + private _orgData = GVAR(OrgClass) get "org"; + private _name = _orgData getOrDefault ["name", "Unknown"]; + private _id = _orgData getOrDefault ["id", ""]; + private _funds = _orgData getOrDefault ["funds", 0]; + private _reputation = _orgData getOrDefault ["reputation", 0]; + private _membersRaw = _orgData getOrDefault ["members", []]; + private _membersList = []; + + // Handle members + private _fnc_processMember = { + params ["_mData"]; + + private _mName = _mData getOrDefault ["name", "Unknown"]; + createHashMapFromArray [ + ["name", _mName], + ["rank", "Member"], + ["online", true] + ] + }; + + { + _membersList pushBack ([_y] call _fnc_processMember); + } forEach _membersRaw; + + private _totalMembers = count _membersList; + + // Handle assets + private _assetsRaw = _orgData getOrDefault ["assets", createHashMap]; + private _assetsList = []; + + private _fnc_processAsset = { + params ["_aData"]; + + private _aName = _aData getOrDefault ["name", "Unknown Asset"]; + private _aLocation = _aData getOrDefault ["location", "Unknown Location"]; + private _aIcon = _aData getOrDefault ["icon", "📦"]; + + createHashMapFromArray [ + ["name", _aName], + ["location", _aLocation], + ["icon", _aIcon] + ] + }; + + { + _assetsList pushBack ([_y] call _fnc_processAsset); + } forEach _assetsRaw; + + // Construct HashMap payload + private _payload = createHashMapFromArray [ + ["org", createHashMapFromArray [ + ["name", _name], + ["tag", _id], + ["status", "Active"] + ]], + ["stats", createHashMapFromArray [ + ["totalMembers", _totalMembers], + ["onlineMembers", _totalMembers], + ["balance", _funds], + ["reputation", _reputation] + ]], + ["membersOnline", _membersList], + ["assets", _assetsList], + ["activities", []], + ["missions", []] + ]; + + private _json = toJSON _payload; + + _control ctrlWebBrowserAction ["ExecJS", format ["updateOrgDashboard(%1)", _json]]; + }; default { hint format ["Unhandled UI event: %1", _event]; }; }; diff --git a/arma/client/addons/org/ui/_site/index.html b/arma/client/addons/org/ui/_site/index.html index b68277e..cdb8685 100644 --- a/arma/client/addons/org/ui/_site/index.html +++ b/arma/client/addons/org/ui/_site/index.html @@ -72,7 +72,7 @@
Reputation - Level 5 + 200
diff --git a/arma/client/addons/org/ui/_site/script.js b/arma/client/addons/org/ui/_site/script.js index 43e1821..d6561e9 100644 --- a/arma/client/addons/org/ui/_site/script.js +++ b/arma/client/addons/org/ui/_site/script.js @@ -76,11 +76,160 @@ function updateDashboard(data) { if (statValues[0]) statValues[0].textContent = data.stats.totalMembers; if (statValues[1]) statValues[1].textContent = data.stats.onlineMembers; if (statValues[2]) statValues[2].textContent = `$${data.stats.balance.toLocaleString()}`; - if (statValues[3]) statValues[3].textContent = `Level ${data.stats.reputation}`; + if (statValues[3]) statValues[3].textContent = `${data.stats.reputation}`; } + + // Update Members List + if (data.membersOnline) { + const memberList = document.querySelector('.member-list'); + if (memberList) { + memberList.innerHTML = ''; + data.membersOnline.forEach(member => { + const item = document.createElement('div'); + item.className = 'member-item'; + item.innerHTML = ` +
+
+ ${member.name} + ${member.rank} +
+ `; + memberList.appendChild(item); + }); + + // Update member count badge + const memberBadge = document.querySelector('.dashboard-card:nth-child(2) .card-badge'); + if (memberBadge) memberBadge.textContent = data.membersOnline.length; + } + } + + // Update Assets List + if (data.assets) { + const assetList = document.querySelector('.asset-list'); + if (assetList) { + assetList.innerHTML = ''; + data.assets.forEach(asset => { + const item = document.createElement('div'); + item.className = 'asset-item'; + item.innerHTML = ` + ${asset.icon || '📦'} +
+ ${asset.name} + ${asset.location} +
+ `; + assetList.appendChild(item); + }); + } + } + + // Update Activities List + if (data.activities) { + const activityList = document.querySelector('.activity-list'); + if (activityList) { + activityList.innerHTML = ''; + data.activities.forEach(activity => { + const item = document.createElement('div'); + item.className = 'activity-item'; + item.innerHTML = ` +
${activity.time}
+
${activity.text}
+ `; + activityList.appendChild(item); + }); + } + } + + // Update Missions List + if (data.missions) { + const missionList = document.querySelector('.mission-list'); + if (missionList) { + missionList.innerHTML = ''; + data.missions.forEach(mission => { + const item = document.createElement('div'); + item.className = 'mission-item'; + item.innerHTML = ` +
+ ${mission.name} + ${mission.priority.charAt(0).toUpperCase() + mission.priority.slice(1)} Priority +
+
${mission.description}
+
+
+
+
+ ${mission.progress}% +
+ `; + missionList.appendChild(item); + }); + + // Update mission count badge + const missionBadge = document.querySelector('.dashboard-card:last-child .card-badge'); + if (missionBadge) missionBadge.textContent = data.missions.length; + } + } + + // Re-attach event handlers for new elements if needed + // Note: The original setupEventHandlers attached to querySelectorAll which only finds elements existing at that time. + // We should re-run or use delegation. For simplicity, we can re-attach listeners to the new items. + attachDynamicHandlers(data); } -// Event handlers +function attachDynamicHandlers(data) { + // Member item clicks + const memberItems = document.querySelectorAll('.member-item'); + memberItems.forEach((item, index) => { + item.addEventListener('click', () => { + const memberData = data.membersOnline ? data.membersOnline[index] : null; + if (memberData) { + console.log('Member clicked:', memberData); + if (typeof A3API !== 'undefined') { + A3API.SendAlert(JSON.stringify({ + event: 'org::member::view', + data: { member: memberData } + })); + } + } + }); + }); + + // Asset item clicks + const assetItems = document.querySelectorAll('.asset-item'); + assetItems.forEach((item, index) => { + item.addEventListener('click', () => { + const assetData = data.assets ? data.assets[index] : null; + if (assetData) { + console.log('Asset clicked:', assetData); + if (typeof A3API !== 'undefined') { + A3API.SendAlert(JSON.stringify({ + event: 'org::asset::view', + data: { asset: assetData } + })); + } + } + }); + }); + + // Mission item clicks + const missionItems = document.querySelectorAll('.mission-item'); + missionItems.forEach((item, index) => { + item.addEventListener('click', () => { + const missionData = data.missions ? data.missions[index] : null; + if (missionData) { + console.log('Mission clicked:', missionData); + if (typeof A3API !== 'undefined') { + A3API.SendAlert(JSON.stringify({ + event: 'org::mission::view', + data: { mission: missionData } + })); + } + } + }); + }); +} + +// Static Event Handlers (Close, Settings, etc.) function setupEventHandlers() { // Close button const closeBtn = document.querySelector('.close-btn'); @@ -111,60 +260,26 @@ function setupEventHandlers() { } }); } - - // Member item clicks - const memberItems = document.querySelectorAll('.member-item'); - memberItems.forEach((item, index) => { - item.addEventListener('click', () => { - console.log('Member clicked:', mockData.membersOnline[index]); - if (typeof A3API !== 'undefined') { - A3API.SendAlert(JSON.stringify({ - event: 'org::member::view', - data: { member: mockData.membersOnline[index] } - })); - } - }); - }); - - // Asset item clicks - const assetItems = document.querySelectorAll('.asset-item'); - assetItems.forEach((item, index) => { - item.addEventListener('click', () => { - console.log('Asset clicked:', mockData.assets[index]); - if (typeof A3API !== 'undefined') { - A3API.SendAlert(JSON.stringify({ - event: 'org::asset::view', - data: { asset: mockData.assets[index] } - })); - } - }); - }); - - // Mission item clicks - const missionItems = document.querySelectorAll('.mission-item'); - missionItems.forEach((item, index) => { - item.addEventListener('click', () => { - console.log('Mission clicked:', mockData.missions[index]); - if (typeof A3API !== 'undefined') { - A3API.SendAlert(JSON.stringify({ - event: 'org::mission::view', - data: { mission: mockData.missions[index] } - })); - } - }); - }); } // Initialize dashboard function initDashboard() { console.log('Organization Dashboard initializing...'); - // Update with mock data - updateDashboard(mockData); - // Setup event handlers setupEventHandlers(); + // Request live data from Arma + if (typeof A3API !== 'undefined') { + A3API.SendAlert(JSON.stringify({ + event: 'org::ready', + data: {} + })); + } else { + // Use mock data for browser testing/development + updateDashboard(mockData); + } + console.log('Organization Dashboard initialized'); } diff --git a/arma/server/.gitignore b/arma/server/.gitignore index b786b16..41f642f 100644 --- a/arma/server/.gitignore +++ b/arma/server/.gitignore @@ -3,6 +3,7 @@ hemtt.exe .hemtt/missions/~* .hemttout/ releases/ +.hemttprivatekey # Textures Exports/ diff --git a/arma/server/addons/actor/XEH_preInit.sqf b/arma/server/addons/actor/XEH_preInit.sqf index d776427..5f0605e 100644 --- a/arma/server/addons/actor/XEH_preInit.sqf +++ b/arma/server/addons/actor/XEH_preInit.sqf @@ -7,12 +7,10 @@ PREP_RECOMPILE_END; // private _category = [QUOTE(MOD_NAME), LLSTRING(displayName)]; [QGVAR(requestInitActor), { - params [["_uid", "", [""]], ["_actor", createHashMap, [createHashMap]]]; + params [["_uid", "", [""]]]; if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Actor] Empty/Invalid UID!" }; - if (_actor isEqualTo createHashMap) exitWith { diag_log "[FORGE:Server:Actor] Empty/Invalid Actor data!" }; - - GVAR(ActorStore) call ["init", [_uid, _actor]]; + GVAR(ActorStore) call ["init", [_uid]]; }] call CFUNC(addEventHandler); [QGVAR(requestGetActor), { @@ -23,7 +21,10 @@ PREP_RECOMPILE_END; private _session = GVAR(PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:Actor] Empty/Invalid Session!" }; - GVAR(ActorStore) call ["get", [_uid, _sync]]; + private _finalData = GVAR(ActorStore) call ["get", [GVAR(ActorRegistry), "actor:get", _uid, _sync]]; + private _player = [_uid] call EFUNC(common,getPlayer); + + [CRPC(actor,responseSyncActor), [_finalData], _player] call CFUNC(targetEvent); }] call CFUNC(addEventHandler); [QGVAR(requestSetActor), { @@ -34,7 +35,10 @@ PREP_RECOMPILE_END; private _session = GVAR(PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:Actor] Empty/Invalid Session!" }; - GVAR(ActorStore) call ["set", [_uid, _key, _value, _sync]]; + private _hashMap = GVAR(ActorStore) call ["set", [GVAR(ActorRegistry), "actor:update", _uid, _key, _value, _sync]]; + private _player = [_uid] call EFUNC(common,getPlayer); + + [CRPC(actor,responseSyncActor), [_hashMap], _player] call CFUNC(targetEvent); }] call CFUNC(addEventHandler); [QGVAR(requestMSetActor), { @@ -46,7 +50,10 @@ PREP_RECOMPILE_END; private _session = GVAR(PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:Actor] Empty/Invalid Session!" }; - GVAR(ActorStore) call ["mset", [_uid, _fieldValuePairs, _sync]]; + private _hashMap = GVAR(ActorStore) call ["mset", [GVAR(ActorRegistry), "actor:update", _uid, _fieldValuePairs, _sync]]; + private _player = [_uid] call EFUNC(common,getPlayer); + + [CRPC(actor,responseSyncActor), [_hashMap], _player] call CFUNC(targetEvent); }] call CFUNC(addEventHandler); [QGVAR(requestSaveActor), { @@ -57,7 +64,10 @@ PREP_RECOMPILE_END; private _session = GVAR(PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:Actor] Empty/Invalid Session!" }; - GVAR(ActorStore) call ["save", [_uid, _sync]]; + private _finalData = GVAR(ActorStore) call ["save", [GVAR(ActorRegistry), "actor:update", _uid, _sync]]; + private _player = [_uid] call EFUNC(common,getPlayer); + + [CRPC(actor,responseSyncActor), [_finalData], _player] call CFUNC(targetEvent); }] call CFUNC(addEventHandler); [QGVAR(requestRemoveActor), { @@ -65,5 +75,5 @@ PREP_RECOMPILE_END; if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Actor] Empty/Invalid UID!" }; - GVAR(ActorStore) call ["remove", [_uid]]; + GVAR(ActorStore) call ["remove", [GVAR(ActorRegistry), _uid]]; }] call CFUNC(addEventHandler); diff --git a/arma/server/addons/actor/XEH_preStart.sqf b/arma/server/addons/actor/XEH_preStart.sqf index 0228885..a51262a 100644 --- a/arma/server/addons/actor/XEH_preStart.sqf +++ b/arma/server/addons/actor/XEH_preStart.sqf @@ -1,3 +1,2 @@ #include "script_component.hpp" - #include "XEH_PREP.hpp" diff --git a/arma/server/addons/actor/functions/fnc_initActorStore.sqf b/arma/server/addons/actor/functions/fnc_initActorStore.sqf index 32ac128..72dfb7a 100644 --- a/arma/server/addons/actor/functions/fnc_initActorStore.sqf +++ b/arma/server/addons/actor/functions/fnc_initActorStore.sqf @@ -17,69 +17,147 @@ */ #pragma hemtt ignore_variables ["_self"] -GVAR(ActorStore) = createHashMapObject [[ - ["#base", EGVAR(common,BaseStore)], - ["#type", "IActorStore"], - ["#create", { - GVAR(ActorRegistry) = createHashMap; - GVAR(PlayerSessions) = createHashMap; +GVAR(ActorModel) = compileFinal createHashMapObject [[ + ["#type", "ActorModel"], + ["defaults", { + private _actor = createHashMap; - _self set ["_registry", GVAR(ActorRegistry)]; - _self set ["_extCallPrefix", "actor"]; - _self set ["_readMethod", "get"]; - _self set ["_storeName", "Actor"]; - _self set ["_syncEventName", CRPC(actor,responseSyncActor)]; + _actor set ["uid", ""]; + _actor set ["name", ""]; + _actor set ["loadout", [[],[],[],["U_BG_Guerrilla_6_1",[]],[],[],"H_Cap_blk_ION","",[],["ItemMap","ItemGPS","ItemRadio","ItemCompass","ItemWatch",""]]]; + _actor set ["position", [0,0,0]]; + _actor set ["direction", 0]; + _actor set ["stance", "STAND"]; + _actor set ["rank", "PRIVATE"]; + _actor set ["state", "HEALTHY"]; + _actor set ["phone_number", ""]; + _actor set ["email", ""]; + _actor set ["organization", ""]; + _actor set ["holster", true]; - ["INFO", "Actor Store Initialized!", nil, nil] call EFUNC(common,log); + _actor }], - ["generateSessionToken", { - params [["_uid", "", [""]]]; + ["fromPlayer", { + params [["_player", objNull, [objNull]]]; - private _token = format ["%1_%2_%3", _uid, floor(random 999999), time]; - private _sessionToken = _token call EFUNC(common,generateHash); + if (_player isEqualTo objNull) exitWith { _self call ["defaults", []] }; - private _regEntry = createHashMapFromArray [["sessionToken", _sessionToken]]; - GVAR(PlayerSessions) set [_uid, _regEntry]; + private _actor = _self call ["defaults", []]; - _sessionToken + _actor set ["uid", getPlayerUID _player]; + _actor set ["name", name _player]; + _actor set ["position", getPosASL _player]; + _actor set ["direction", getDir _player]; + _actor set ["stance", stance _player]; + _actor set ["rank", rank _player]; + _actor set ["state", lifeState _player]; + + _actor }], - ["init", { - params [["_uid", "", [""]], ["_defaultActor", createHashMap, [createHashMap]]]; + ["migrate", { + params [["_actor", createHashMap, [createHashMap]]]; - _self call ["generateSessionToken", [_uid]]; - private _finalActor = createHashMap; + private _defaults = _self call ["defaults", []]; - ["actor:exists", [_uid]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"]; - private _exists = _result == "true"; + { + if !(_x in _actor) then { _actor set [_x, _y]; }; + } forEach _defaults; - if !(_exists) then { - _finalActor = _defaultActor; - _finalActor set ["uid", _uid]; + _actor + }], + ["validate", { + params [["_actor", createHashMap, [createHashMap]]]; - private _json = _self call ["toJSON", [_finalActor]]; - ["actor:create", [_uid, _json]] call EFUNC(extension,extCall); + private _uid = _actor getOrDefault ["uid", ""]; + private _name = _actor getOrDefault ["name", ""]; + private _position = _actor getOrDefault ["position", []]; + private _direction = _actor getOrDefault ["direction", 0]; + private _stance = _actor getOrDefault ["stance", ""]; + private _rank = _actor getOrDefault ["rank", ""]; + private _state = _actor getOrDefault ["state", ""]; + private _phone_number = _actor getOrDefault ["phone_number", ""]; + private _email = _actor getOrDefault ["email", ""]; + private _organization = _actor getOrDefault ["organization", ""]; - private _phone_number = _finalActor getOrDefault ["phone_number", ""]; - private _email = _finalActor getOrDefault ["email", ""]; - - ["INFO", format ["New player %1 registered with phone number: %2, email: %3", _uid, _phone_number, _email], nil, nil] call EFUNC(common,log); - } else { - private _existingActor = _self call ["fetch", [_uid]]; - _finalActor = _existingActor; - - { - if !(_x in _finalActor) then { _finalActor set [_x, _y]; }; - } forEach _defaultActor; + [_uid, _name, _position, _direction, _stance, _rank, _state, _phone_number, _email, _organization] try { + if (_uid isEqualTo "" || !(_uid isEqualType "")) then { throw "Invalid UID!"; }; + if (_name isEqualTo "" || !(_name isEqualType "")) then { throw "Invalid Name!"; }; + if (_position isEqualTo [] || !(_position isEqualType [])) then { throw "Invalid Position!"; }; + if (_direction < 0 || !(_direction isEqualType 0)) then { throw "Invalid Direction!"; }; + if (_stance isEqualTo "" || !(_stance isEqualType "")) then { throw "Invalid Stance!"; }; + if (_rank isEqualTo "" || !(_rank isEqualType "")) then { throw "Invalid Rank!"; }; + if (_state isEqualTo "" || !(_state isEqualType "")) then { throw "Invalid State!"; }; + if (_phone_number isEqualTo "" || !(_phone_number isEqualType "")) then { throw "Invalid Phone Number!"; }; + if (_email isEqualTo "" || !(_email isEqualType "")) then { throw "Invalid Email!"; }; + if (_organization isEqualTo "" || !(_organization isEqualType "")) then { throw "Invalid Organization!"; }; + } catch { + ["ERROR", format ["Failed to validate actor %1!", _exception]] call EFUNC(common,log); + false }; - GVAR(ActorRegistry) set [_uid, _finalActor]; - - private _player = [_uid] call EFUNC(common,getPlayer); - [CRPC(actor,responseInitActor), [_finalActor], _player] call CFUNC(targetEvent); - - _finalActor + true + }] +]]; + +GVAR(ActorRepository) = compileFinal createHashMapFromArray [ + ["#base", EGVAR(common,BaseStore)], + ["#type", "ActorRepository"], + ["#create", { + GVAR(ActorRegistry) = createHashMap; + ["INFO", "Actor Repository Initialized!"] call EFUNC(common,log); + }], + ["get", { + params [["_uid", "", [""]]]; + + private _cached = GVAR(ActorRegistry) getOrDefault [_uid, nil]; + if !(isNil { _cached }) exitWith { _cached }; + + private _player = [_uid] call EFUNC(common,getPlayer); + + ["actor:exists", [_uid]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"]; + if !(_isSuccess) exitWith { + ["ERROR", format ["Failed to check if actor %1 exists!", _uid]] call EFUNC(common,log); + createHashMap + }; + + private _finalActor = createHashMap; + + if (_result == "true") then { + _finalActor = _self call ["fetch", ["actor:get", _uid]]; + } else { + _finalActor = GVAR(ActorModel) call ["fromPlayer", [_player]]; + _finalActor set ["uid", _uid]; + + private _json = _self call ["toJSON", [_finalActor]]; + ["actor:create", [_uid, _json]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"]; + if !(_isSuccess) exitWith { + ["ERROR", format ["Failed to create actor %1!", _uid]] call EFUNC(common,log); + createHashMap + }; + }; + + _finalActor = GVAR(ActorModel) call ["migrate", [_finalActor]]; + GVAR(ActorRegistry) set [_uid, _finalActor]; + _finalActor + + }] +]; + +GVAR(ActorStore) = createHashMapObject [[ + ["#base", GVAR(ActorRepository)], + ["#type", "IActorStore"], + ["#create", { + ["INFO", "Actor Store Initialized!"] call EFUNC(common,log); + }], + ["init", { + params [["_uid", "", [""]]]; + + private _actor = _self call ["get", [_uid]]; + private _player = [_uid] call EFUNC(common,getPlayer); + + [CRPC(actor,responseInitActor), [_actor], _player] call CFUNC(targetEvent); + _actor }] ]]; -SETMVAR(FORGE_ActorStore,GVAR(ActorStore)); GVAR(ActorStore) diff --git a/arma/server/addons/bank/XEH_preInit.sqf b/arma/server/addons/bank/XEH_preInit.sqf index f94f7ed..ec7bb33 100644 --- a/arma/server/addons/bank/XEH_preInit.sqf +++ b/arma/server/addons/bank/XEH_preInit.sqf @@ -23,7 +23,7 @@ PREP_RECOMPILE_END; private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid Session!" }; - GVAR(BankStore) call ["get", [_uid, _sync]]; + GVAR(BankStore) call ["get", [GVAR(BankRegistry), "bank:get", _uid, _sync]]; }] call CFUNC(addEventHandler); [QGVAR(requestSetBank), { @@ -34,7 +34,10 @@ PREP_RECOMPILE_END; private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid Session!" }; - GVAR(BankStore) call ["set", [_uid, _key, _value, _sync]]; + private _hashMap = GVAR(BankStore) call ["set", [GVAR(BankRegistry), "bank:update", _uid, _key, _value, _sync]]; + private _player = [_uid] call EFUNC(common,getPlayer); + + [CRPC(bank,responseSyncBank), [_hashMap], _player] call CFUNC(targetEvent); }] call CFUNC(addEventHandler); [QGVAR(requestMSetBank), { @@ -46,7 +49,10 @@ PREP_RECOMPILE_END; private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid Session!" }; - GVAR(BankStore) call ["mset", [_uid, _fieldValuePairs, _sync]]; + private _hashMap = GVAR(BankStore) call ["mset", [GVAR(BankRegistry), "bank:update", _uid, _fieldValuePairs, _sync]]; + private _player = [_uid] call EFUNC(common,getPlayer); + + [CRPC(bank,responseSyncBank), [_hashMap], _player] call CFUNC(targetEvent); }] call CFUNC(addEventHandler); [QGVAR(requestSaveBank), { @@ -57,7 +63,10 @@ PREP_RECOMPILE_END; private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid Session!" }; - GVAR(BankStore) call ["save", [_uid, _sync]]; + private _finalData = GVAR(BankStore) call ["save", [GVAR(BankRegistry), "bank:update", _uid, _sync]]; + private _player = [_uid] call EFUNC(common,getPlayer); + + [CRPC(bank,responseSyncBank), [_finalData], _player] call CFUNC(targetEvent); }] call CFUNC(addEventHandler); [QGVAR(requestRemoveBank), { @@ -65,7 +74,7 @@ PREP_RECOMPILE_END; if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid UID!" }; - GVAR(BankStore) call ["remove", [_uid]]; + GVAR(BankStore) call ["remove", [GVAR(BankRegistry), _uid]]; }] call CFUNC(addEventHandler); [QGVAR(requestDeposit), { @@ -79,6 +88,17 @@ PREP_RECOMPILE_END; GVAR(BankStore) call ["deposit", [_uid, _amount]]; }] call CFUNC(addEventHandler); +[QGVAR(requestPayment), { + params [["_uid", "", [""]], ["_amount", 0, [0]]]; + + if (_uid isEqualTo "" || _amount isEqualTo 0) exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid UID or Amount!" }; + + private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil]; + if (isNil "_session") exitWith { diag_log "[FORGE:Server:Bank] Empty/Invalid Session!" }; + + GVAR(BankStore) call ["payment", [_uid, _amount]]; +}] call CFUNC(addEventHandler); + [QGVAR(requestTransfer), { params [["_uid", "", [""]], ["_target", "", [""]], ["_from", "", [""]], ["_amount", 0, [0]]]; @@ -86,9 +106,9 @@ PREP_RECOMPILE_END; diag_log "[FORGE:Server:Bank] Empty/Invalid UID, Target, From Account, or Amount!" }; - // Prevent self-transfers (security check) if (_uid isEqualTo _target) exitWith { diag_log format ["[FORGE:Server:Bank] SECURITY: Player %1 attempted self-transfer!", _uid]; + private _player = [_uid] call EFUNC(common,getPlayer); [CRPC(notifications,recieveNotification), ["error", "Bank", "Cannot transfer to yourself!"], _player] call CFUNC(targetEvent); }; diff --git a/arma/server/addons/bank/XEH_preStart.sqf b/arma/server/addons/bank/XEH_preStart.sqf index 0228885..a51262a 100644 --- a/arma/server/addons/bank/XEH_preStart.sqf +++ b/arma/server/addons/bank/XEH_preStart.sqf @@ -1,3 +1,2 @@ #include "script_component.hpp" - #include "XEH_PREP.hpp" diff --git a/arma/server/addons/bank/functions/fnc_initBankStore.sqf b/arma/server/addons/bank/functions/fnc_initBankStore.sqf index af9d3ea..7d5c1bf 100644 --- a/arma/server/addons/bank/functions/fnc_initBankStore.sqf +++ b/arma/server/addons/bank/functions/fnc_initBankStore.sqf @@ -17,21 +17,9 @@ */ #pragma hemtt ignore_variables ["_self"] -GVAR(BankStore) = createHashMapObject [[ +private _typeBank = compileFinal createHashMapFromArray [ ["#base", EGVAR(common,BaseStore)], - ["#type", "IBankStore"], - ["#create", { - GVAR(BankRegistry) = createHashMap; - GVAR(NameRegistry) = createHashMap; - - _self set ["_registry", GVAR(BankRegistry)]; - _self set ["_extCallPrefix", "bank"]; - _self set ["_readMethod", "get"]; - _self set ["_storeName", "Bank"]; - _self set ["_syncEventName", CRPC(bank,responseSyncBank)]; - - ["INFO", "Bank Store Initialized!", nil, nil] call EFUNC(common,log); - }], + ["#type", "IBaseBank"], ["init", { params [["_uid", "", [""]], ["_defaultAccount", createHashMap, [createHashMap]]]; @@ -49,7 +37,7 @@ GVAR(BankStore) = createHashMapObject [[ ["INFO", format ["Created new bank account for %1", _uid], nil, nil] call EFUNC(common,log); } else { - private _existingAccount = _self call ["fetch", [_uid]]; + private _existingAccount = _self call ["fetch", ["bank:get", _uid]]; _finalAccount = _existingAccount; { @@ -63,10 +51,9 @@ GVAR(BankStore) = createHashMapObject [[ private _player = [_uid] call EFUNC(common,getPlayer); private _regEntry = createHashMapFromArray [["uid", _uid], ["name", (name _player)]]; - GVAR(NameRegistry) set [_uid, _regEntry]; - [CRPC(bank,responseInitBank), [_finalAccount], _player] call CFUNC(targetEvent); - _finalAccount + GVAR(IndexRegistry) set [_uid, _regEntry]; + [CRPC(bank,responseInitBank), [_finalAccount], _player] call CFUNC(targetEvent); }], ["deposit", { params [["_uid", "", [""]], ["_amount", 0, [0]]]; @@ -80,15 +67,32 @@ GVAR(BankStore) = createHashMapObject [[ private _cash = _account getOrDefault ["cash", 0]; if (_cash < _amount) exitWith { ["WARNING", "Insufficient Funds!", nil, nil] call EFUNC(common,log); }; - private _finalAccount = createHashMapFromArray [ - ["bank", (_bank + _amount)], - ["cash", (_cash - _amount)] - ]; + 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], nil, nil] call EFUNC(common,log); + + private _account = GVAR(BankRegistry) getOrDefault [_uid, nil]; + if (isNil "_account") exitWith { ["ERROR", "Empty/Invalid Account!", nil, nil] 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]]]; @@ -115,6 +119,8 @@ GVAR(BankStore) = createHashMapObject [[ 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); }], @@ -130,15 +136,25 @@ GVAR(BankStore) = createHashMapObject [[ private _cash = _account getOrDefault ["cash", 0]; if (_bank < _amount) exitWith { ["WARNING", "Insufficient Funds!", nil, nil] call EFUNC(common,log); }; - private _finalAccount = createHashMapFromArray [ - ["bank", (_bank - _amount)], - ["cash", (_cash + _amount)] - ]; + 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", _typeBank], + ["#type", "IBankStore"], + ["#create", { + GVAR(BankRegistry) = createHashMap; + GVAR(IndexRegistry) = createHashMap; + + ["INFO", "Bank Store Initialized!", nil, nil] call EFUNC(common,log); + }] ]]; SETMVAR(FORGE_BankStore,GVAR(BankStore)); diff --git a/arma/server/addons/common/XEH_PREP.hpp b/arma/server/addons/common/XEH_PREP.hpp index b74d96d..a5a2c37 100644 --- a/arma/server/addons/common/XEH_PREP.hpp +++ b/arma/server/addons/common/XEH_PREP.hpp @@ -1,7 +1,7 @@ +PREP(baseStore); PREP(formatNumber); PREP(getPlayer); PREP(generateHash); PREP(generateSecureData); -PREP(initBaseStore); PREP(log); PREP(timeToSeconds); diff --git a/arma/server/addons/common/XEH_preStart.sqf b/arma/server/addons/common/XEH_preStart.sqf index 0228885..a51262a 100644 --- a/arma/server/addons/common/XEH_preStart.sqf +++ b/arma/server/addons/common/XEH_preStart.sqf @@ -1,3 +1,2 @@ #include "script_component.hpp" - #include "XEH_PREP.hpp" diff --git a/arma/server/addons/common/functions/fnc_baseStore.sqf b/arma/server/addons/common/functions/fnc_baseStore.sqf new file mode 100644 index 0000000..e40485d --- /dev/null +++ b/arma/server/addons/common/functions/fnc_baseStore.sqf @@ -0,0 +1,103 @@ +#include "..\script_component.hpp" + +/* + * File: fnc_baseStore.sqf + * Author: IDSolutions + * Date: 2026-01-08 + * Last Update: 2026-01-10 + * Public: No + * + * Description: + * No description added yet. + * + * Parameter(s): + * N/A + * + * Returns: + * Something [BOOL] + * + * Example(s): + * [parameter] call forge_x_component_fnc_myFunction + */ + +#pragma hemtt ignore_variables ["_self"] +GVAR(BaseStore) = compileFinal createHashMapFromArray [ + ["#type", "IBaseStore"], + ["fetch", { + params [["_function", "", [""]], ["_uid", "", [""]]]; + + private _data = createHashMap; + + [_function, [_uid]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"]; + ["INFO", format ["Data: %1", _result], nil, nil] call EFUNC(common,log); + + if (count _result > 0) then { _data = _self call ["toHashMap", [_result]] }; + + _data + }], + ["set", { + params [["_registry", createHashMap, [createHashMap]], ["_function", "", [""]], ["_uid", "", [""]], ["_field", "", [""]], ["_value", nil, [0, "", [], false, createHashMap, objNull, grpNull]], ["_sync", false, [false]]]; + + private _existingData = _registry get _uid; + private _finalData = +_existingData; + private _hashMap = createHashMap; + + _finalData set [_field, _value]; + _hashMap set [_field, _value]; + _registry set [_uid, _finalData]; + + if (_sync) then { + private _json = _self call ["toJSON", [_hashMap]]; + [_function, [_uid, _json]] call EFUNC(extension,extCall); + }; + + _hashMap + }], + ["mset", { + params [["_registry", createHashMap, [createHashMap]], ["_function", "", [""]], ["_uid", "", [""]], ["_fieldValuePairs", createHashMap, [createHashMap]], ["_sync", false, [false]]]; + + private _existingData = _registry get _uid; + private _finalData = +_existingData; + private _hashMap = createHashMap; + + { _finalData set [_x, _y]; } forEach _fieldValuePairs; + { _hashMap set [_x, _y]; } forEach _fieldValuePairs; + + _registry set [_uid, _finalData]; + + if (_sync) then { + private _json = _self call ["toJSON", [_hashMap]]; + [_function, [_uid, _json]] call EFUNC(extension,extCall); + }; + + _hashMap + }], + ["save", { + params [["_registry", createHashMap, [createHashMap]], ["_function", "", [""]], ["_uid", "", [""]]]; + + private _existingData = _registry get _uid; + private _finalData = +_existingData; + private _json = _self call ["toJSON", [_finalData]]; + + [_function, [_uid, _json]] call EFUNC(extension,extCall); + + _finalData + }], + ["remove", { + params [["_registry", createHashMap, [createHashMap]], ["_uid", "", [""]]]; + + _registry deleteAt _uid; + }], + ["toHashMap", { + params [["_data", "", [""]]]; + + fromJSON _data + }], + ["toJSON", { + params [["_data", createHashMap, [createHashMap]]]; + + toJSON _data + }] +]; + +GVAR(BaseStore) diff --git a/arma/server/addons/common/functions/fnc_initBaseStore.sqf b/arma/server/addons/common/functions/fnc_initBaseStore.sqf deleted file mode 100644 index a8abf0e..0000000 --- a/arma/server/addons/common/functions/fnc_initBaseStore.sqf +++ /dev/null @@ -1,154 +0,0 @@ -#include "..\script_component.hpp" - -/* - * Author: IDSolutions - * Initializes the base store. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Examples: - * [] call forge_server_common_fnc_initBaseStore - * - * Public: Yes - */ - -#pragma hemtt ignore_variables ["_self"] -GVAR(BaseStore) = createHashMapObject [[ - ["#type", "IBaseStore"], - ["fetch", { - params [["_uid", "", [""]]]; - - private _extCallPrefix = _self get "_extCallPrefix"; - private _readMethod = _self getOrDefault ["_readMethod", "get"]; - private _funcName = format ["%1:%2", _extCallPrefix, _readMethod]; - private _store = createHashMap; - - [_funcName, [_uid]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"]; - ["INFO", format ["Data: %1", _result], nil, nil] call EFUNC(common,log); - - if (count _result > 0) then { _store = _self call ["toHashMap", [_result]]; }; - - _store - }], - ["get", { - params [["_uid", "", [""]], ["_sync", false, [false]]]; - - private _finalData = createHashMap; - private _registry = _self get "_registry"; - - if (_sync) then { - private _existingData = _self call ["fetch", [_uid]]; - - _finalData = _existingData; - _registry set [_uid, _finalData]; - } else { - _finalData = _registry get _uid; - }; - - _finalData - }], - ["set", { - params [["_uid", "", [""]], ["_field", "", [""]], ["_value", nil], ["_sync", false, [false]]]; - - private _registry = _self get "_registry"; - private _existingData = _registry get _uid; - private _finalData = +_existingData; - private _hashMap = createHashMap; - - _finalData set [_field, _value]; - _hashMap set [_field, _value]; - _registry set [_uid, _finalData]; - - if (_sync) then { - private _extCallPrefix = _self get "_extCallPrefix"; - private _funcName = format ["%1:update", _extCallPrefix]; - private _json = _self call ["toJSON", [_hashMap]]; - - [_funcName, [_uid, _json]] call EFUNC(extension,extCall); - }; - - private _syncEventName = _self getOrDefault ["_syncEventName", ""]; - if (_syncEventName isNotEqualTo "") then { - private _player = [_uid] call EFUNC(common,getPlayer); - [_syncEventName, [_hashMap], _player] call CFUNC(targetEvent); - }; - - _hashMap - }], - ["mset", { - params [["_uid", "", [""]], ["_fieldValuePairs", createHashMap, [createHashMap]], ["_sync", false, [false]]]; - - private _registry = _self get "_registry"; - private _existingData = _registry get _uid; - private _finalData = +_existingData; - private _hashMap = createHashMap; - - { _finalData set [_x, _y]; } forEach _fieldValuePairs; - { _hashMap set [_x, _y]; } forEach _fieldValuePairs; - - _registry set [_uid, _finalData]; - - if (_sync) then { - private _extCallPrefix = _self get "_extCallPrefix"; - private _funcName = format ["%1:update", _extCallPrefix]; - private _json = _self call ["toJSON", [_hashMap]]; - - [_funcName, [_uid, _json]] call EFUNC(extension,extCall); - }; - - private _syncEventName = _self getOrDefault ["_syncEventName", ""]; - if (_syncEventName isNotEqualTo "") then { - private _player = [_uid] call EFUNC(common,getPlayer); - [_syncEventName, [_hashMap], _player] call CFUNC(targetEvent); - }; - - _hashMap - }], - ["save", { - params [["_uid", "", [""]], ["_sync", false, [false]]]; - - private _registry = _self get "_registry"; - private _existingData = _registry get _uid; - private _finalData = +_existingData; - private _extCallPrefix = _self get "_extCallPrefix"; - private _funcName = format ["%1:update", _extCallPrefix]; - private _json = _self call ["toJSON", [_finalData]]; - - [_funcName, [_uid, _json]] call EFUNC(extension,extCall); - - if (_sync) then { - private _syncEventName = _self getOrDefault ["_syncEventName", ""]; - if (_syncEventName isNotEqualTo "") then { - private _player = [_uid] call EFUNC(common,getPlayer); - [_syncEventName, [_finalData], _player] call CFUNC(targetEvent); - }; - }; - - _finalData - }], - ["remove", { - params [["_uid", "", [""]]]; - - private _registry = _self get "_registry"; - _registry deleteAt _uid; - }], - ["toHashMap", { - params [["_data", "", [""]]]; - - private _hashMap = fromJSON _data; - _hashMap - }], - ["toJSON", { - params [["_data", createHashMap, [createHashMap]]]; - - private _json = toJSON _data; - _json - }] -]]; - -SETMVAR(FORGE_BaseStore,GVAR(BaseStore)); -GVAR(BaseStore) diff --git a/arma/server/addons/economy/XEH_postInit.sqf b/arma/server/addons/economy/XEH_postInit.sqf index f10b958..b912379 100644 --- a/arma/server/addons/economy/XEH_postInit.sqf +++ b/arma/server/addons/economy/XEH_postInit.sqf @@ -1,18 +1,3 @@ #include "script_component.hpp" GVAR(MEconomyStore) call ["init", []]; - -[QGVAR(onKilled), { - params ["_unit"]; - GVAR(MEconomyStore) call ["onKilled", [_unit]]; -}] call CFUNC(addEventHandler); - -[QGVAR(onRespawn), { - params ["_unit", "_corpse", "_uid"]; - GVAR(MEconomyStore) call ["onRespawn", [_unit, _corpse, _uid]]; -}] call CFUNC(addEventHandler); - -[QGVAR(onHealed), { - params ["_unit"]; - GVAR(MEconomyStore) call ["onHealed", [_unit]]; -}] call CFUNC(addEventHandler); diff --git a/arma/server/addons/economy/XEH_preInit.sqf b/arma/server/addons/economy/XEH_preInit.sqf index e66ae75..d07df45 100644 --- a/arma/server/addons/economy/XEH_preInit.sqf +++ b/arma/server/addons/economy/XEH_preInit.sqf @@ -27,3 +27,18 @@ if (isNil QGVAR(FEconomyStore)) then { [] call FUNC(initFEconomyStore); }; params ["_source", "_target"]; GVAR(FEconomyStore) call ["stop", [_source, _target]]; }] call CFUNC(addEventHandler); + +[QGVAR(onKilled), { + params ["_unit"]; + GVAR(MEconomyStore) call ["onKilled", [_unit]]; +}] call CFUNC(addEventHandler); + +[QGVAR(onRespawn), { + params ["_unit", "_corpse", "_uid"]; + GVAR(MEconomyStore) call ["onRespawn", [_unit, _corpse, _uid]]; +}] call CFUNC(addEventHandler); + +[QGVAR(onHealed), { + params ["_unit"]; + GVAR(MEconomyStore) call ["onHealed", [_unit]]; +}] call CFUNC(addEventHandler); diff --git a/arma/server/addons/economy/XEH_preStart.sqf b/arma/server/addons/economy/XEH_preStart.sqf index 0228885..a51262a 100644 --- a/arma/server/addons/economy/XEH_preStart.sqf +++ b/arma/server/addons/economy/XEH_preStart.sqf @@ -1,3 +1,2 @@ #include "script_component.hpp" - #include "XEH_PREP.hpp" diff --git a/arma/server/addons/garage/XEH_preInit.sqf b/arma/server/addons/garage/XEH_preInit.sqf index 0ab16a4..30f27c4 100644 --- a/arma/server/addons/garage/XEH_preInit.sqf +++ b/arma/server/addons/garage/XEH_preInit.sqf @@ -21,7 +21,7 @@ PREP_RECOMPILE_END; private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:Garage] Empty/Invalid Session!" }; - GVAR(GarageStore) call ["get", [_uid, _sync]]; + GVAR(GarageStore) call ["get", [GVAR(GarageRegistry), "garage:get", _uid, _sync]]; }] call CFUNC(addEventHandler); [QGVAR(requestSetGarage), { @@ -32,7 +32,10 @@ PREP_RECOMPILE_END; private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:Garage] Empty/Invalid Session!" }; - GVAR(GarageStore) call ["set", [_uid, _key, _value, _sync]]; + private _hashMap = GVAR(GarageStore) call ["set", [GVAR(GarageRegistry), "garage:update", _uid, _key, _value, _sync]]; + private _player = [_uid] call EFUNC(common,getPlayer); + + [CRPC(garage,responseSyncGarage), [_hashMap], _player] call CFUNC(targetEvent); }] call CFUNC(addEventHandler); [QGVAR(requestMSetGarage), { @@ -44,7 +47,10 @@ PREP_RECOMPILE_END; private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:Garage] Empty/Invalid Session!" }; - GVAR(GarageStore) call ["mset", [_uid, _fieldValuePairs, _sync]]; + private _hashMap = GVAR(GarageStore) call ["mset", [GVAR(GarageRegistry), "garage:update", _uid, _fieldValuePairs, _sync]]; + private _player = [_uid] call EFUNC(common,getPlayer); + + [CRPC(garage,responseSyncGarage), [_hashMap], _player] call CFUNC(targetEvent); }] call CFUNC(addEventHandler); [QGVAR(requestSaveGarage), { @@ -55,7 +61,10 @@ PREP_RECOMPILE_END; private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:Garage] Empty/Invalid Session!" }; - GVAR(GarageStore) call ["save", [_uid, _sync]]; + private _finalData = GVAR(GarageStore) call ["save", [GVAR(GarageRegistry), "garage:update", _uid, _sync]]; + private _player = [_uid] call EFUNC(common,getPlayer); + + [CRPC(garage,responseSyncGarage), [_finalData], _player] call CFUNC(targetEvent); }] call CFUNC(addEventHandler); [QGVAR(requestRemoveGarage), { @@ -63,7 +72,7 @@ PREP_RECOMPILE_END; if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:Garage] Empty/Invalid UID!" }; - GVAR(GarageStore) call ["remove", [_uid]]; + GVAR(GarageStore) call ["remove", [GVAR(GarageRegistry), _uid]]; }] call CFUNC(addEventHandler); [QGVAR(requestInitVG), { @@ -83,7 +92,10 @@ PREP_RECOMPILE_END; private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:VGarage] Empty/Invalid Session!" }; - GVAR(VGarageStore) call ["get", [_uid, _sync]]; + private _hashMap = GVAR(VGarageStore) call ["get", [GVAR(VGarageRegistry), "owned:garage:fetch", _uid, _sync]]; + private _player = [_uid] call EFUNC(common,getPlayer); + + [CRPC(garage,responseSyncVG), [_hashMap], _player] call CFUNC(targetEvent); }] call CFUNC(addEventHandler); [QGVAR(requestSetVG), { @@ -94,7 +106,10 @@ PREP_RECOMPILE_END; private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:VGarage] Empty/Invalid Session!" }; - GVAR(VGarageStore) call ["set", [_uid, _key, _value, _sync]]; + private _hashMap = GVAR(VGarageStore) call ["set", [GVAR(VGarageRegistry), "", _uid, _key, _value, _sync]]; + private _player = [_uid] call EFUNC(common,getPlayer); + + [CRPC(garage,responseSyncVG), [_hashMap], _player] call CFUNC(targetEvent); }] call CFUNC(addEventHandler); [QGVAR(requestMSetVG), { @@ -106,7 +121,10 @@ PREP_RECOMPILE_END; private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:VGarage] Empty/Invalid Session!" }; - GVAR(VGarageStore) call ["mset", [_uid, _fieldValuePairs, _sync]]; + private _hashMap = GVAR(VGarageStore) call ["mset", [GVAR(VGarageRegistry), "", _uid, _fieldValuePairs, _sync]]; + private _player = [_uid] call EFUNC(common,getPlayer); + + [CRPC(garage,responseSyncVG), [_hashMap], _player] call CFUNC(targetEvent); }] call CFUNC(addEventHandler); [QGVAR(requestSaveVG), { @@ -117,7 +135,10 @@ PREP_RECOMPILE_END; private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:VGarage] Empty/Invalid Session!" }; - GVAR(VGarageStore) call ["save", [_uid, _sync]]; + private _finalData = GVAR(VGarageStore) call ["save", [GVAR(VGarageRegistry), "", _uid, _sync]]; + private _player = [_uid] call EFUNC(common,getPlayer); + + [CRPC(garage,responseSyncVG), [_finalData], _player] call CFUNC(targetEvent); }] call CFUNC(addEventHandler); [QGVAR(requestRemoveVG), { @@ -125,5 +146,5 @@ PREP_RECOMPILE_END; if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:VGarage] Empty/Invalid UID!" }; - GVAR(VGarageStore) call ["remove", [_uid]]; + GVAR(VGarageStore) call ["remove", [GVAR(VGarageRegistry), _uid]]; }] call CFUNC(addEventHandler); diff --git a/arma/server/addons/garage/XEH_preStart.sqf b/arma/server/addons/garage/XEH_preStart.sqf index 0228885..a51262a 100644 --- a/arma/server/addons/garage/XEH_preStart.sqf +++ b/arma/server/addons/garage/XEH_preStart.sqf @@ -1,3 +1,2 @@ #include "script_component.hpp" - #include "XEH_PREP.hpp" diff --git a/arma/server/addons/garage/functions/fnc_initGarageStore.sqf b/arma/server/addons/garage/functions/fnc_initGarageStore.sqf index 222463f..a80f4b1 100644 --- a/arma/server/addons/garage/functions/fnc_initGarageStore.sqf +++ b/arma/server/addons/garage/functions/fnc_initGarageStore.sqf @@ -4,7 +4,7 @@ * File: fnc_initGarageStore.sqf * Author: IDSolutions * Date: 2025-12-17 - * Last Update: 2026-01-03 + * Last Update: 2026-01-10 * Public: No * * Description: @@ -22,20 +22,9 @@ */ #pragma hemtt ignore_variables ["_self"] -GVAR(GarageStore) = createHashMapObject [[ +private _typeGarage = compileFinal createHashMapFromArray [ ["#base", EGVAR(common,BaseStore)], - ["#type", "IGarageStore"], - ["#create", { - GVAR(GarageRegistry) = createHashMap; - - _self set ["_registry", GVAR(GarageRegistry)]; - _self set ["_extCallPrefix", "garage"]; - _self set ["_readMethod", "get"]; - _self set ["_storeName", "Garage"]; - _self set ["_syncEventName", CRPC(garage,responseSyncGarage)]; - - ["INFO", "Garage Store Initialized!", nil, nil] call EFUNC(common,log); - }], + ["#type", "IGarageBase"], ["init", { params [["_uid", "", [""]], ["_defaultGarage", createHashMap, [createHashMap]]]; @@ -50,7 +39,7 @@ GVAR(GarageStore) = createHashMapObject [[ ["garage:create", [_uid]] call EFUNC(extension,extCall); ["INFO", format ["Created new garage for %1", _uid], nil, nil] call EFUNC(common,log); } else { - _finalGarage = _self call ["fetch", [_uid]]; + _finalGarage = _self call ["fetch", ["garage:get", _uid]]; ["INFO", format ["Found garage for %1", _uid], nil, nil] call EFUNC(common,log); }; @@ -60,48 +49,16 @@ GVAR(GarageStore) = createHashMapObject [[ [CRPC(garage,responseInitGarage), [_finalGarage], _player] call CFUNC(targetEvent); _finalGarage - }], - ["set", { - params [["_uid", "", [""]], ["_field", "", [""]], ["_value", nil], ["_sync", false, [false]]]; + }] +]; - private _existingData = GVAR(GarageRegistry) get _uid; - private _finalData = +_existingData; - private _hashMap = createHashMap; +GVAR(GarageStore) = createHashMapObject [[ + ["#base", _typeGarage], + ["#type", "IGarageStore"], + ["#create", { + GVAR(GarageRegistry) = createHashMap; - _finalData set [_field, _value]; - _hashMap set [_field, _value]; - GVAR(GarageRegistry) set [_uid, _finalData]; - - if (_sync) then { - private _json = _self call ["toJSON", [_finalData]]; - ["garage:update", [_uid, _json]] call EFUNC(extension,extCall); - }; - - private _player = [_uid] call EFUNC(common,getPlayer); - [CRPC(garage,responseSyncGarage), [_hashMap], _player] call CFUNC(targetEvent); - - _hashMap - }], - ["mset", { - params [["_uid", "", [""]], ["_fieldValuePairs", createHashMap, [createHashMap]], ["_sync", false, [false]]]; - - private _existingData = GVAR(GarageRegistry) get _uid; - private _finalData = +_existingData; - private _hashMap = createHashMap; - - { _finalData set [_x, _y]; } forEach _fieldValuePairs; - { _hashMap set [_x, _y]; } forEach _fieldValuePairs; - GVAR(GarageRegistry) set [_uid, _finalData]; - - if (_sync) then { - private _json = _self call ["toJSON", [_finalData]]; - ["garage:update", [_uid, _json]] call EFUNC(extension,extCall); - }; - - private _player = [_uid] call EFUNC(common,getPlayer); - [CRPC(garage,responseSyncGarage), [_hashMap], _player] call CFUNC(targetEvent); - - _hashMap + ["INFO", "Garage Store Initialized!", nil, nil] call EFUNC(common,log); }] ]]; diff --git a/arma/server/addons/garage/functions/fnc_initVGStore.sqf b/arma/server/addons/garage/functions/fnc_initVGStore.sqf index 5fb13d4..1deb9dd 100644 --- a/arma/server/addons/garage/functions/fnc_initVGStore.sqf +++ b/arma/server/addons/garage/functions/fnc_initVGStore.sqf @@ -4,7 +4,7 @@ * File: fnc_initVGStore.sqf * Author: IDSolutions * Date: 2025-12-17 - * Last Update: 2026-01-03 + * Last Update: 2026-01-10 * Public: No * * Description: @@ -22,20 +22,9 @@ */ #pragma hemtt ignore_variables ["_self"] -GVAR(VGarageStore) = createHashMapObject [[ +private _typeVGarage = compileFinal createHashMapFromArray [ ["#base", EGVAR(common,BaseStore)], - ["#type", "IVGarageStore"], - ["#create", { - GVAR(VGarageRegistry) = createHashMap; - - _self set ["_registry", GVAR(VGarageRegistry)]; - _self set ["_extCallPrefix", "owned:garage"]; - _self set ["_readMethod", "fetch"]; - _self set ["_storeName", "VGarage"]; - _self set ["_syncEventName", CRPC(garage,responseSyncVG)]; - - ["INFO", "VGarage Store Initialized!", nil, nil] call EFUNC(common,log); - }], + ["#type", "IVGarageBase"], ["init", { params [["_uid", "", [""]], ["_defaultVGarage", createHashMap, [createHashMap]]]; @@ -50,7 +39,7 @@ GVAR(VGarageStore) = createHashMapObject [[ ["owned:garage:create", [_uid]] call EFUNC(extension,extCall); ["INFO", format ["Created new VGarage for %1", _uid], nil, nil] call EFUNC(common,log); } else { - private _existingVGarage = _self call ["fetch", [_uid]]; + private _existingVGarage = _self call ["fetch", ["owned:garage:fetch", _uid]]; _finalVGarage = _existingVGarage; { @@ -65,6 +54,16 @@ GVAR(VGarageStore) = createHashMapObject [[ _finalVGarage }] +]; + +GVAR(VGarageStore) = createHashMapObject [[ + ["#base", _typeVGarage], + ["#type", "IVGarageStore"], + ["#create", { + GVAR(VGarageRegistry) = createHashMap; + + ["INFO", "VGarage Store Initialized!", nil, nil] call EFUNC(common,log); + }] ]]; SETMVAR(FORGE_VGarageStore,GVAR(VGarageStore)); diff --git a/arma/server/addons/locker/XEH_preInit.sqf b/arma/server/addons/locker/XEH_preInit.sqf index b4dc94a..3a1d38c 100644 --- a/arma/server/addons/locker/XEH_preInit.sqf +++ b/arma/server/addons/locker/XEH_preInit.sqf @@ -21,7 +21,7 @@ PREP_RECOMPILE_END; private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:Locker] Empty/Invalid Session!" }; - GVAR(LockerStore) call ["get", [_uid, _sync]]; + GVAR(LockerStore) call ["get", [GVAR(LockerRegistry), "locker:get", _uid, _sync]]; }] call CFUNC(addEventHandler); [QGVAR(requestSetLocker), { @@ -32,7 +32,10 @@ PREP_RECOMPILE_END; private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:Locker] Empty/Invalid Session!" }; - GVAR(LockerStore) call ["set", [_uid, _key, _value, _sync]]; + private _hashMap = GVAR(LockerStore) call ["set", [GVAR(LockerRegistry), "locker:update", _uid, _key, _value, _sync]]; + private _player = [_uid] call EFUNC(common,getPlayer); + + [CRPC(locker,responseSyncLocker), [_hashMap], _player] call CFUNC(targetEvent); }] call CFUNC(addEventHandler); [QGVAR(requestMSetLocker), { @@ -44,7 +47,10 @@ PREP_RECOMPILE_END; private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:Locker] Empty/Invalid Session!" }; - GVAR(LockerStore) call ["mset", [_uid, _fieldValuePairs, _sync]]; + private _hashMap = GVAR(LockerStore) call ["mset", [GVAR(LockerRegistry), "locker:update", _uid, _fieldValuePairs, _sync]]; + private _player = [_uid] call EFUNC(common,getPlayer); + + [CRPC(locker,responseSyncLocker), [_hashMap], _player] call CFUNC(targetEvent); }] call CFUNC(addEventHandler); [QGVAR(requestSaveLocker), { @@ -55,7 +61,10 @@ PREP_RECOMPILE_END; private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:Locker] Empty/Invalid Session!" }; - GVAR(LockerStore) call ["save", [_uid, _sync]]; + private _finalData = GVAR(LockerStore) call ["save", [GVAR(LockerRegistry), "locker:update", _uid, _sync]]; + private _player = [_uid] call EFUNC(common,getPlayer); + + [CRPC(locker,responseSyncLocker), [_finalData], _player] call CFUNC(targetEvent); }] call CFUNC(addEventHandler); [QGVAR(requestRemoveLocker), { @@ -83,7 +92,7 @@ PREP_RECOMPILE_END; private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:VArsenal] Empty/Invalid Session!" }; - GVAR(VArsenalStore) call ["get", [_uid, _sync]]; + GVAR(VArsenalStore) call ["get", [GVAR(VArsenalRegistry), "owned:locker:fetch", _uid, _sync]]; }] call CFUNC(addEventHandler); [QGVAR(requestSetVA), { @@ -94,7 +103,10 @@ PREP_RECOMPILE_END; private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:VArsenal] Empty/Invalid Session!" }; - GVAR(VArsenalStore) call ["set", [_uid, _key, _value, _sync]]; + private _hashMap = GVAR(VArsenalStore) call ["set", [GVAR(VArsenalRegistry), "owned:locker:update", _uid, _key, _value, _sync]]; + private _player = [_uid] call EFUNC(common,getPlayer); + + [CRPC(locker,responseSyncVArsenal), [_hashMap], _player] call CFUNC(targetEvent); }] call CFUNC(addEventHandler); [QGVAR(requestMSetVA), { @@ -106,7 +118,10 @@ PREP_RECOMPILE_END; private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:VArsenal] Empty/Invalid Session!" }; - GVAR(VArsenalStore) call ["mset", [_uid, _fieldValuePairs, _sync]]; + private _hashMap = GVAR(VArsenalStore) call ["mset", [GVAR(VArsenalRegistry), "owned:locker:update", _uid, _fieldValuePairs, _sync]]; + private _player = [_uid] call EFUNC(common,getPlayer); + + [CRPC(locker,responseSyncVArsenal), [_hashMap], _player] call CFUNC(targetEvent); }] call CFUNC(addEventHandler); [QGVAR(requestSaveVA), { @@ -117,7 +132,10 @@ PREP_RECOMPILE_END; private _session = EGVAR(actor,PlayerSessions) getOrDefault [_uid, nil]; if (isNil "_session") exitWith { diag_log "[FORGE:Server:VArsenal] Empty/Invalid Session!" }; - GVAR(VArsenalStore) call ["save", [_uid, _sync]]; + private _finalData = GVAR(VArsenalStore) call ["save", [GVAR(VArsenalRegistry), "owned:locker:update", _uid, _sync]]; + private _player = [_uid] call EFUNC(common,getPlayer); + + [CRPC(locker,responseSyncVArsenal), [_finalData], _player] call CFUNC(targetEvent); }] call CFUNC(addEventHandler); [QGVAR(requestRemoveVA), { @@ -125,5 +143,5 @@ PREP_RECOMPILE_END; if (_uid isEqualTo "") exitWith { diag_log "[FORGE:Server:VArsenal] Empty/Invalid UID!" }; - GVAR(VArsenalStore) call ["remove", [_uid]]; + GVAR(VArsenalStore) call ["remove", [GVAR(VArsenalRegistry), _uid]]; }] call CFUNC(addEventHandler); diff --git a/arma/server/addons/locker/XEH_preStart.sqf b/arma/server/addons/locker/XEH_preStart.sqf index 0228885..a51262a 100644 --- a/arma/server/addons/locker/XEH_preStart.sqf +++ b/arma/server/addons/locker/XEH_preStart.sqf @@ -1,3 +1,2 @@ #include "script_component.hpp" - #include "XEH_PREP.hpp" diff --git a/arma/server/addons/locker/functions/fnc_initLockerStore.sqf b/arma/server/addons/locker/functions/fnc_initLockerStore.sqf index 66f29d3..da54435 100644 --- a/arma/server/addons/locker/functions/fnc_initLockerStore.sqf +++ b/arma/server/addons/locker/functions/fnc_initLockerStore.sqf @@ -4,7 +4,7 @@ * File: fnc_initLockerStore.sqf * Author: IDSolutions * Date: 2025-12-17 - * Last Update: 2026-01-03 + * Last Update: 2026-01-10 * Public: No * * Description: @@ -22,20 +22,9 @@ */ #pragma hemtt ignore_variables ["_self"] -GVAR(LockerStore) = createHashMapObject [[ +private _typeLocker = compileFinal createHashMapFromArray [ ["#base", EGVAR(common,BaseStore)], - ["#type", "ILockerStore"], - ["#create", { - GVAR(LockerRegistry) = createHashMap; - - _self set ["_registry", GVAR(LockerRegistry)]; - _self set ["_extCallPrefix", "locker"]; - _self set ["_readMethod", "get"]; - _self set ["_storeName", "Locker"]; - _self set ["_syncEventName", CRPC(locker,responseSyncLocker)]; - - ["INFO", "Locker Store Initialized!", nil, nil] call EFUNC(common,log); - }], + ["#type", "ILockerBase"], ["init", { params [["_uid", "", [""]], ["_defaultLocker", createHashMap, [createHashMap]]]; @@ -57,53 +46,19 @@ GVAR(LockerStore) = createHashMapObject [[ GVAR(LockerRegistry) set [_uid, _finalLocker]; private _player = [_uid] call EFUNC(common,getPlayer); - [CRPC(locker,responseInitLocker), [_finalLocker], _player] call CFUNC(targetEvent); _finalLocker - }], - ["set", { - params [["_uid", "", [""]], ["_field", "", [""]], ["_value", nil], ["_sync", false, [false]]]; + }] +]; - private _existingData = GVAR(LockerRegistry) get _uid; - private _finalData = +_existingData; - private _hashMap = createHashMap; +GVAR(LockerStore) = createHashMapObject [[ + ["#base", _typeLocker], + ["#type", "ILockerStore"], + ["#create", { + GVAR(LockerRegistry) = createHashMap; - _finalData set [_field, _value]; - _hashMap set [_field, _value]; - GVAR(LockerRegistry) set [_uid, _finalData]; - - if (_sync) then { - private _json = _self call ["toJSON", [_finalData]]; - ["locker:update", [_uid, _json]] call EFUNC(extension,extCall); - }; - - private _player = [_uid] call EFUNC(common,getPlayer); - [CRPC(locker,responseSyncLocker), [_hashMap], _player] call CFUNC(targetEvent); - - _hashMap - }], - ["mset", { - params [["_uid", "", [""]], ["_fieldValuePairs", createHashMap, [createHashMap]], ["_sync", false, [false]]]; - - private _existingData = GVAR(LockerRegistry) get _uid; - private _finalData = +_existingData; - private _hashMap = createHashMap; - - { _finalData set [_x, _y]; } forEach _fieldValuePairs; - { _hashMap set [_x, _y]; } forEach _fieldValuePairs; - - GVAR(LockerRegistry) set [_uid, _finalData]; - - if (_sync) then { - private _json = _self call ["toJSON", [_finalData]]; - ["locker:update", [_uid, _json]] call EFUNC(extension,extCall); - }; - - private _player = [_uid] call EFUNC(common,getPlayer); - [CRPC(locker,responseSyncLocker), [_hashMap], _player] call CFUNC(targetEvent); - - _hashMap + ["INFO", "Locker Store Initialized!", nil, nil] call EFUNC(common,log); }] ]]; diff --git a/arma/server/addons/locker/functions/fnc_initVAStore.sqf b/arma/server/addons/locker/functions/fnc_initVAStore.sqf index fd85e6b..5f3dbf0 100644 --- a/arma/server/addons/locker/functions/fnc_initVAStore.sqf +++ b/arma/server/addons/locker/functions/fnc_initVAStore.sqf @@ -4,7 +4,7 @@ * File: fnc_initVAStore.sqf * Author: IDSolutions * Date: 2025-12-17 - * Last Update: 2026-01-03 + * Last Update: 2026-01-10 * Public: No * * Description: @@ -22,20 +22,9 @@ */ #pragma hemtt ignore_variables ["_self"] -GVAR(VArsenalStore) = createHashMapObject [[ +private _typeVArsenal = compileFinal createHashMapFromArray [ ["#base", EGVAR(common,BaseStore)], - ["#type", "IVArsenalStore"], - ["#create", { - GVAR(VArsenalRegistry) = createHashMap; - - _self set ["_registry", GVAR(VArsenalRegistry)]; - _self set ["_extCallPrefix", "owned:locker"]; - _self set ["_readMethod", "fetch"]; - _self set ["_storeName", "VArsenal"]; - _self set ["_syncEventName", CRPC(locker,responseSyncVA)]; - - ["INFO", "VArsenal Store Initialized!", nil, nil] call EFUNC(common,log); - }], + ["#type", "IVArsenalBase"], ["init", { params [["_uid", "", [""]], ["_defaultVArsenal", createHashMap, [createHashMap]]]; @@ -65,6 +54,16 @@ GVAR(VArsenalStore) = createHashMapObject [[ _finalVArsenal }] +]; + +GVAR(VArsenalStore) = createHashMapObject [[ + ["#base", _typeVArsenal], + ["#type", "IVArsenalStore"], + ["#create", { + GVAR(VArsenalRegistry) = createHashMap; + + ["INFO", "VArsenal Store Initialized!", nil, nil] call EFUNC(common,log); + }] ]]; SETMVAR(FORGE_VArsenalStore,GVAR(VArsenalStore)); diff --git a/arma/server/addons/main/functions/fnc_initStores.sqf b/arma/server/addons/main/functions/fnc_initStores.sqf index 52cdb8d..6047574 100644 --- a/arma/server/addons/main/functions/fnc_initStores.sqf +++ b/arma/server/addons/main/functions/fnc_initStores.sqf @@ -17,7 +17,7 @@ */ // Base -if (isNil QEGVAR(common,BaseStore)) then { [] call EFUNC(common,initBaseStore); }; +if (isNil QEGVAR(common,BaseStore)) then { [] call EFUNC(common,baseStore); }; // Actor if (isNil QEGVAR(actor,ActorStore)) then { [] call EFUNC(actor,initActorStore); }; diff --git a/arma/server/addons/org/functions/fnc_initOrgStore.sqf b/arma/server/addons/org/functions/fnc_initOrgStore.sqf index 6c178b4..7c2a671 100644 --- a/arma/server/addons/org/functions/fnc_initOrgStore.sqf +++ b/arma/server/addons/org/functions/fnc_initOrgStore.sqf @@ -41,10 +41,6 @@ GVAR(OrgStore) = createHashMapObject [[ private _actor = EGVAR(actor,ActorRegistry) get _uid; private _orgID = _actor get "organization"; - private _assets = createHashMap; - private _organization = createHashMap; - private _members = createHashMap; - ["org:exists", [_orgID]] call EFUNC(extension,extCall) params ["_result", "_isSuccess"]; private _exists = _result == "true"; @@ -58,13 +54,13 @@ GVAR(OrgStore) = createHashMapObject [[ private _regEntry = createHashMapFromArray [["orgID", _orgID]]; GVAR(IndexRegistry) set [_uid, _regEntry]; - _organization = _self call ["fetch", [_uid]]; - _members = _self call ["fetchMembers", [_uid]]; - // _assets = _self call ["fetchAssets", [_uid]]; + private _organization = _self call ["fetch", [_uid]]; + private _members = _self call ["fetchMembers", [_uid]]; + // private _assets = _self call ["fetchAssets", [_uid]]; private _finalOrg = GVAR(OrgRegistry) getOrDefault [_orgID, _organization]; _finalOrg set ["members", _members]; - _finalOrg set ["assets", _assets]; + // _finalOrg set ["assets", _assets]; GVAR(OrgRegistry) set [_orgID, _finalOrg, true]; @@ -77,13 +73,12 @@ GVAR(OrgStore) = createHashMapObject [[ private _assets = createHashMap; private _members = createHashMap; - private _organization = createHashMap; private _member = createHashMapFromArray [["uid", _uid], ["name", _name]]; private _regEntry = createHashMapFromArray [["orgID", "default"]]; GVAR(IndexRegistry) set [_uid, _regEntry]; - _organization = _self call ["fetch", ["default"]]; + private _organization = _self call ["fetch", ["default"]]; _members set [_uid, _member]; private _finalOrg = GVAR(OrgRegistry) getOrDefault ["default", _organization]; diff --git a/examples/ext_data.sqf b/examples/ext_data.sqf index 1318277..3fad43d 100644 --- a/examples/ext_data.sqf +++ b/examples/ext_data.sqf @@ -19,11 +19,10 @@ // Locker Registry [["_SP_PLAYER_",[["30Rnd_65x39_caseless_mag",[["amount",4],["classname","30Rnd_65x39_caseless_mag"],["category","magazine"]]],["arifle_MX_F",[["amount",1],["classname","arifle_MX_F"],["category","weapon"]]],["NVGoggles",[["amount",1],["classname","NVGoggles"],["category","hmd"]]]]]]; -// Organization Index Registry -[["_SP_PLAYER_",[["orgID","0160566824"]]]]; - -// Organization Registry +// Org Registry [["0160566824",[["assets",[]],["name","Black Rifle Company"],["id","0160566824"],["funds",0],["reputation",0],["owner","_SP_PLAYER_"],["members",[["_SP_PLAYER_",[["name","Jacob Schmidt"],["uid","_SP_PLAYER_"]]]]]]]]; +// Org Index Registry +[["_SP_PLAYER_",[["orgID","0160566824"]]]]; // Player Session Registry [["_SP_PLAYER_",[["sessionToken","855837"]]]]; From 9c09976ef29a178686ab9e0125eb7da4df5a5f28 Mon Sep 17 00:00:00 2001 From: Jacob Schmidt Date: Wed, 28 Jan 2026 20:07:24 -0600 Subject: [PATCH 02/37] feat: Initialize core client and server systems for actor, bank, garage, locker, and notifications, including UI components and data models. --- .../actor/functions/fnc_handleUIEvents.sqf | 14 +- .../actor/functions/fnc_initActorClass.sqf | 17 +- .../addons/actor/functions/fnc_openUI.sqf | 10 +- .../bank/functions/fnc_handleUIEvents.sqf | 14 +- .../bank/functions/fnc_initBankClass.sqf | 27 +-- .../addons/bank/functions/fnc_openUI.sqf | 14 +- arma/client/addons/bank/ui/_site/atm.html | 59 ------ .../garage/functions/fnc_handleUIEvents.sqf | 14 +- .../garage/functions/fnc_initGarageClass.sqf | 22 ++- .../garage/functions/fnc_initVGClass.sqf | 35 ++-- .../addons/garage/functions/fnc_openUI.sqf | 10 +- .../addons/garage/functions/fnc_openVG.sqf | 21 +- arma/client/addons/locker/XEH_postInit.sqf | 7 + arma/client/addons/locker/XEH_preStart.sqf | 1 - .../locker/functions/fnc_handleUIEvents.sqf | 14 +- .../locker/functions/fnc_initLockerClass.sqf | 31 ++- .../locker/functions/fnc_initVAClass.sqf | 31 +-- .../addons/locker/functions/fnc_openUI.sqf | 12 +- .../functions/fnc_handleUIEvents.sqf | 16 +- .../functions/fnc_initNotificationClass.sqf | 18 +- .../notifications/functions/fnc_openUI.sqf | 12 +- .../addons/org/functions/fnc_initOrgClass.sqf | 1 - arma/server/addons/actor/XEH_preInit.sqf | 13 -- .../actor/functions/fnc_initActorStore.sqf | 20 +- arma/server/addons/bank/XEH_preInit.sqf | 35 +--- .../bank/functions/fnc_initBankStore.sqf | 181 +++++++++++++----- .../addons/common/functions/fnc_baseStore.sqf | 18 +- .../addons/common/functions/fnc_log.sqf | 26 +-- arma/server/addons/garage/XEH_preInit.sqf | 43 +---- .../garage/functions/fnc_initGarage.sqf | 18 +- .../garage/functions/fnc_initGarageStore.sqf | 76 +++++--- .../garage/functions/fnc_initVGStore.sqf | 98 ++++++---- arma/server/addons/locker/XEH_preInit.sqf | 31 +-- .../locker/functions/fnc_initLocker.sqf | 66 ++++++- .../locker/functions/fnc_initLockerStore.sqf | 78 ++++---- .../locker/functions/fnc_initVAStore.sqf | 96 ++++++---- arma/server/addons/org/XEH_preInit.sqf | 16 -- lib/models/src/actor.rs | 5 +- lib/models/src/v_garage.rs | 8 +- lib/models/src/v_locker.rs | 35 +++- 40 files changed, 694 insertions(+), 569 deletions(-) diff --git a/arma/client/addons/actor/functions/fnc_handleUIEvents.sqf b/arma/client/addons/actor/functions/fnc_handleUIEvents.sqf index 415a5f2..6806bd3 100644 --- a/arma/client/addons/actor/functions/fnc_handleUIEvents.sqf +++ b/arma/client/addons/actor/functions/fnc_handleUIEvents.sqf @@ -1,19 +1,25 @@ #include "..\script_component.hpp" /* + * File: fnc_handleUIEvents.sqf * Author: IDSolutions + * Date: 2026-01-28 + * Last Update: 2026-01-28 + * Public: No + * + * Description: * Handles the UI events. * * Arguments: - * None + * 0: [CONTROL] - The control that triggered the event + * 1: [BOOL] - Whether the event is from a confirm dialog + * 2: [STRING] - The message containing the event data * * Return Value: - * None + * UI events handled [BOOL] * * Example: * [] call forge_client_actor_fnc_handleUIEvents; - * - * Public: No */ params ["_control", "_isConfirmDialog", "_message"]; diff --git a/arma/client/addons/actor/functions/fnc_initActorClass.sqf b/arma/client/addons/actor/functions/fnc_initActorClass.sqf index 260ecbd..bda2d1a 100644 --- a/arma/client/addons/actor/functions/fnc_initActorClass.sqf +++ b/arma/client/addons/actor/functions/fnc_initActorClass.sqf @@ -1,19 +1,24 @@ #include "..\script_component.hpp" /* + * File: fnc_initActorClass.sqf * Author: IDSolutions - * Initializes the actor class. + * Date: 2026-01-28 + * Last Update: 2026-01-28 + * Public: Yes + * + * Description: + * Initializes the actor class for managing player data. + * Provides methods for saving, loading, and applying actor data. * * Arguments: * None * * Return Value: - * None + * Actor class object [HASHMAP OBJECT] * - * Examples: + * Example: * [] call forge_client_actor_fnc_initActorClass - * - * Public: Yes */ #pragma hemtt ignore_variables ["_self"] @@ -131,7 +136,7 @@ GVAR(ActorClass) = createHashMapObject [[ if (_isGarage) then { _nearbyActions pushBack ["garage", _garageType]; }; if (_isGarage && GVAR(enableVG)) then { _nearbyActions pushBack ["vg", true]; }; if (_deviceType isNotEqualTo "") then { _nearbyActions pushBack ["device", _deviceType]; }; - if (_isPlayer) then { _nearbyActions pushBack ["player", name _x]; }; + if (_isPlayer && { _x isNotEqualTo player }) then { _nearbyActions pushBack ["player", name _x]; }; } forEach (player nearObjects 5); _control ctrlWebBrowserAction ["ExecJS", format ["updateAvailableActions(%1)", (toJSON _nearbyActions)]]; diff --git a/arma/client/addons/actor/functions/fnc_openUI.sqf b/arma/client/addons/actor/functions/fnc_openUI.sqf index 3517f5c..ce70ed1 100644 --- a/arma/client/addons/actor/functions/fnc_openUI.sqf +++ b/arma/client/addons/actor/functions/fnc_openUI.sqf @@ -1,19 +1,23 @@ #include "..\script_component.hpp" /* + * File: fnc_openUI.sqf * Author: IDSolutions + * Date: 2026-01-28 + * Last Update: 2026-01-28 + * Public: No + * + * Description: * Opens the player interaction interface. * * Arguments: * None * * Return Value: - * None + * UI opened [BOOL] * * Example: * [] call forge_client_actor_fnc_openUI; - * - * Public: No */ private _display = (findDisplay 46) createDisplay "RscActorMenu"; diff --git a/arma/client/addons/bank/functions/fnc_handleUIEvents.sqf b/arma/client/addons/bank/functions/fnc_handleUIEvents.sqf index 46973d4..6cb40ab 100644 --- a/arma/client/addons/bank/functions/fnc_handleUIEvents.sqf +++ b/arma/client/addons/bank/functions/fnc_handleUIEvents.sqf @@ -1,19 +1,25 @@ #include "..\script_component.hpp" /* + * File: fnc_handleUIEvents.sqf * Author: IDSolutions + * Date: 2025-12-16 + * Last Update: 2026-01-28 + * Public: No + * + * Description: * Handles the UI events. * * Arguments: - * None + * 0: [CONTROL] - The control that triggered the event + * 1: [BOOL] - Whether the event is from a confirm dialog + * 2: [STRING] - The message containing the event data * * Return Value: - * None + * UI events handled [BOOL] * * Example: * [] call forge_client_bank_fnc_handleUIEvents; - * - * Public: No */ params ["_control", "_isConfirmDialog", "_message"]; diff --git a/arma/client/addons/bank/functions/fnc_initBankClass.sqf b/arma/client/addons/bank/functions/fnc_initBankClass.sqf index 6776935..432d4fa 100644 --- a/arma/client/addons/bank/functions/fnc_initBankClass.sqf +++ b/arma/client/addons/bank/functions/fnc_initBankClass.sqf @@ -1,19 +1,23 @@ #include "..\script_component.hpp" /* + * File: fnc_initBankClass.sqf * Author: IDSolutions + * Date: 2025-12-16 + * Last Update: 2026-01-28 + * Public: No + * + * Description: * Initializes the bank class. * * Arguments: * None * * Return Value: - * None + * Bank class object [HASHMAP OBJECT] * - * Examples: + * Example: * [] call forge_client_bank_fnc_initBankClass - * - * Public: Yes */ #pragma hemtt ignore_variables ["_self"] @@ -24,23 +28,11 @@ GVAR(BankClass) = createHashMapObject [[ _self set ["account", createHashMap]; _self set ["isLoaded", false]; _self set ["lastSave", time]; - - private _account = createHashMap; - _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", []]; - - _self set ["account", _account]; }], ["init", { private _uid = _self get "uid"; - private _account = _self get "account"; - [SRPC(bank,requestInitBank), [_uid, _account]] call CFUNC(serverEvent); + [SRPC(bank,requestInitBank), [_uid]] call CFUNC(serverEvent); systemChat format ["Bank loaded for %1", (name player)]; diag_log "[FORGE:Client:Bank] Bank Class Initialized!"; @@ -80,5 +72,4 @@ GVAR(BankClass) = createHashMapObject [[ }] ]]; -SETVAR(player,FORGE_BankClass,GVAR(BankClass)); GVAR(BankClass) diff --git a/arma/client/addons/bank/functions/fnc_openUI.sqf b/arma/client/addons/bank/functions/fnc_openUI.sqf index 6a65db4..65086a8 100644 --- a/arma/client/addons/bank/functions/fnc_openUI.sqf +++ b/arma/client/addons/bank/functions/fnc_openUI.sqf @@ -1,19 +1,23 @@ #include "..\script_component.hpp" /* + * File: fnc_openUI.sqf * Author: IDSolutions + * Date: 2026-01-28 + * Last Update: 2026-01-28 + * Public: No + * + * Description: * Opens the player bank interaction interface. * * Arguments: - * None + * 0: [BOOL] - Whether to open the ATM interface * * Return Value: - * None + * UI opened [BOOL] * * Example: - * [] call forge_client_bank_fnc_openUI; - * - * Public: No + * [true] call forge_client_bank_fnc_openUI; */ params [["_isATM", false, [false]]]; diff --git a/arma/client/addons/bank/ui/_site/atm.html b/arma/client/addons/bank/ui/_site/atm.html index 42b5df9..79d56d4 100644 --- a/arma/client/addons/bank/ui/_site/atm.html +++ b/arma/client/addons/bank/ui/_site/atm.html @@ -94,12 +94,6 @@ - - - - - - @@ -135,59 +129,6 @@ - - - - - -