Refactor store module: rename StoreStore to StorefrontStore, update initialization and checkout logic, and enhance documentation #7
@ -46,7 +46,7 @@ if (isNil QEGVAR(org,OrgPayloadBuilder)) then { call EFUNC(org,initPayloadBuilde
|
|||||||
if (isNil QEGVAR(org,OrgStore)) then { call EFUNC(org,initOrgStore); };
|
if (isNil QEGVAR(org,OrgStore)) then { call EFUNC(org,initOrgStore); };
|
||||||
|
|
||||||
// Store
|
// Store
|
||||||
if (isNil QEGVAR(store,StoreStore)) then { call EFUNC(store,initStoreStore); };
|
if (isNil QEGVAR(store,StorefrontStore)) then { call EFUNC(store,initStorefrontStore); };
|
||||||
|
|
||||||
// Validation Harness
|
// Validation Harness
|
||||||
if (isNil QGVAR(ValidationHarness)) then { call FUNC(initValidationHarness); };
|
if (isNil QGVAR(ValidationHarness)) then { call FUNC(initValidationHarness); };
|
||||||
|
|||||||
@ -100,7 +100,7 @@ GVAR(ValidationHarness) = createHashMapObject [[
|
|||||||
_self call ["logResult", [_self call ["buildResult", [_actionLower, false, "Store checkout validation payload was invalid.", createHashMap]]]]
|
_self call ["logResult", [_self call ["buildResult", [_actionLower, false, "Store checkout validation payload was invalid.", createHashMap]]]]
|
||||||
};
|
};
|
||||||
|
|
||||||
private _result = EGVAR(store,StoreStore) call ["checkout", [_uid, _player, toJSON _payloadMap]];
|
private _result = EGVAR(store,StorefrontStore) call ["checkout", [_uid, _player, toJSON _payloadMap]];
|
||||||
private _success = _result getOrDefault ["success", false];
|
private _success = _result getOrDefault ["success", false];
|
||||||
private _message = _result getOrDefault ["message", "Store checkout validation completed."];
|
private _message = _result getOrDefault ["message", "Store checkout validation completed."];
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,18 @@
|
|||||||
# forge_server_store
|
# forge_server_store
|
||||||
|
|
||||||
Description for this addon
|
Server-side SQF module for storefront entities, catalog hydration, and checkout
|
||||||
|
coordination.
|
||||||
|
|
||||||
|
## Stores and Services
|
||||||
|
|
||||||
|
- `StorefrontStore` builds storefront hydrate payloads, validates checkout
|
||||||
|
requests, calls the Rust `store:checkout` backend, syncs UI patches, and saves
|
||||||
|
hot state for related modules.
|
||||||
|
- `StoreCatalogService` scans live Arma config categories, builds catalog
|
||||||
|
responses, resolves checkout entries, and calculates authoritative prices.
|
||||||
|
|
||||||
|
## Editor Entities
|
||||||
|
|
||||||
|
`fnc_initStore` marks editor-placed store objects with `isStore = true`. It
|
||||||
|
matches non-null mission namespace objects whose variable names contain
|
||||||
|
`store`, mirroring the garage entity initialization pattern.
|
||||||
|
|||||||
@ -1,2 +1,3 @@
|
|||||||
PREP(initCatalogService);
|
PREP(initCatalogService);
|
||||||
PREP(initStoreStore);
|
PREP(initStore);
|
||||||
|
PREP(initStorefrontStore);
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
// call FUNC(initStore);
|
call FUNC(initStore);
|
||||||
|
|||||||
@ -38,7 +38,7 @@ PREP_RECOMPILE_END;
|
|||||||
private _player = [_uid] call EFUNC(common,getPlayer);
|
private _player = [_uid] call EFUNC(common,getPlayer);
|
||||||
if (_player isEqualTo objNull) exitWith {};
|
if (_player isEqualTo objNull) exitWith {};
|
||||||
|
|
||||||
private _payload = GVAR(StoreStore) call ["buildHydratePayload", [_uid]];
|
private _payload = GVAR(StorefrontStore) call ["buildHydratePayload", [_uid]];
|
||||||
if (_payload isEqualTo createHashMap) exitWith {};
|
if (_payload isEqualTo createHashMap) exitWith {};
|
||||||
|
|
||||||
[CRPC(store,responseHydrateStore), [_payload, _bridgeEvent], _player] call CFUNC(targetEvent);
|
[CRPC(store,responseHydrateStore), [_payload, _bridgeEvent], _player] call CFUNC(targetEvent);
|
||||||
@ -54,6 +54,6 @@ PREP_RECOMPILE_END;
|
|||||||
private _player = [_uid] call EFUNC(common,getPlayer);
|
private _player = [_uid] call EFUNC(common,getPlayer);
|
||||||
if (_player isEqualTo objNull) exitWith {};
|
if (_player isEqualTo objNull) exitWith {};
|
||||||
|
|
||||||
private _result = GVAR(StoreStore) call ["checkout", [_uid, _player, _payloadJson]];
|
private _result = GVAR(StorefrontStore) call ["checkout", [_uid, _player, _payloadJson]];
|
||||||
[CRPC(store,responseCheckout), [_result], _player] call CFUNC(targetEvent);
|
[CRPC(store,responseCheckout), [_result], _player] call CFUNC(targetEvent);
|
||||||
}] call CFUNC(addEventHandler);
|
}] call CFUNC(addEventHandler);
|
||||||
|
|||||||
32
arma/server/addons/store/functions/fnc_initStore.sqf
Normal file
32
arma/server/addons/store/functions/fnc_initStore.sqf
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* File: fnc_initStore.sqf
|
||||||
|
* Author: IDSolutions
|
||||||
|
* Date: 2026-04-17
|
||||||
|
* Public: No
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initializes all editor-placed store entities.
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* call forge_server_store_fnc_initStore
|
||||||
|
*/
|
||||||
|
|
||||||
|
private _stores = (allVariables missionNamespace) select {
|
||||||
|
private _var = missionNamespace getVariable _x;
|
||||||
|
("store" in _x) && { _var isEqualType objNull } && { !isNull _var }
|
||||||
|
};
|
||||||
|
|
||||||
|
if (_stores isEqualTo []) exitWith { ["INFO", "No editor-placed stores found."] call EFUNC(common,log) };
|
||||||
|
|
||||||
|
{
|
||||||
|
private _store = missionNamespace getVariable _x;
|
||||||
|
SETPVAR(_store,isStore,true);
|
||||||
|
} forEach _stores;
|
||||||
@ -1,23 +1,23 @@
|
|||||||
#include "..\script_component.hpp"
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* File: fnc_initStoreStore.sqf
|
* File: fnc_initStorefrontStore.sqf
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
* Date: 2026-03-12
|
* Date: 2026-03-12
|
||||||
* Last Update: 2026-04-04
|
* Last Update: 2026-04-04
|
||||||
* Public: No
|
* Public: No
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Initializes the server-side store checkout flow.
|
* Initializes the server-side storefront state and checkout flow.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (isNil QGVAR(StoreCatalogService)) then { call FUNC(initCatalogService); };
|
if (isNil QGVAR(StoreCatalogService)) then { call FUNC(initCatalogService); };
|
||||||
|
|
||||||
#pragma hemtt ignore_variables ["_self"]
|
#pragma hemtt ignore_variables ["_self"]
|
||||||
GVAR(StoreBaseStore) = compileFinal createHashMapFromArray [
|
GVAR(StorefrontBaseStore) = compileFinal createHashMapFromArray [
|
||||||
["#type", "StoreBaseStore"],
|
["#type", "StorefrontBaseStore"],
|
||||||
["#create", compileFinal {
|
["#create", compileFinal {
|
||||||
["INFO", "Store checkout service initialized!"] call EFUNC(common,log);
|
["INFO", "Storefront store initialized!"] call EFUNC(common,log);
|
||||||
}],
|
}],
|
||||||
["buildHydratePayload", compileFinal {
|
["buildHydratePayload", compileFinal {
|
||||||
params [["_uid", "", [""]]];
|
params [["_uid", "", [""]]];
|
||||||
@ -405,5 +405,5 @@ GVAR(StoreBaseStore) = compileFinal createHashMapFromArray [
|
|||||||
}]
|
}]
|
||||||
];
|
];
|
||||||
|
|
||||||
GVAR(StoreStore) = createHashMapObject [GVAR(StoreBaseStore)];
|
GVAR(StorefrontStore) = createHashMapObject [GVAR(StorefrontBaseStore)];
|
||||||
GVAR(StoreStore)
|
GVAR(StorefrontStore)
|
||||||
@ -28,7 +28,7 @@ docs/ Framework-level documentation
|
|||||||
| Locker | Player item storage keyed by classname with category and amount. | `arma/client/addons/locker` | `arma/server/addons/locker` | `lib/models/src/locker.rs`, `lib/services/src/locker.rs` | `locker:*`, `locker:hot:*` |
|
| Locker | Player item storage keyed by classname with category and amount. | `arma/client/addons/locker` | `arma/server/addons/locker` | `lib/models/src/locker.rs`, `lib/services/src/locker.rs` | `locker:*`, `locker:hot:*` |
|
||||||
| Organization | Player organizations, membership, treasury, credit lines, shared assets, and fleet data. | `arma/client/addons/org` | `arma/server/addons/org` | `lib/models/src/org.rs`, `lib/services/src/org.rs` | `org:*`, `org:hot:*` |
|
| Organization | Player organizations, membership, treasury, credit lines, shared assets, and fleet data. | `arma/client/addons/org` | `arma/server/addons/org` | `lib/models/src/org.rs`, `lib/services/src/org.rs` | `org:*`, `org:hot:*` |
|
||||||
| Phone | Contacts, messages, and email state. | `arma/client/addons/phone` | `arma/server/addons/phone` | `lib/models/src/phone.rs`, `lib/services/src/phone.rs` | `phone:*` |
|
| Phone | Contacts, messages, and email state. | `arma/client/addons/phone` | `arma/server/addons/phone` | `lib/models/src/phone.rs`, `lib/services/src/phone.rs` | `phone:*` |
|
||||||
| Store | Store catalog checkout workflows and checkout charging integration. | `arma/client/addons/store` | `arma/server/addons/store` | `lib/models/src/store.rs`, `lib/services/src/store.rs` | `store:checkout` |
|
| Store | Storefront entity setup, catalog hydration, checkout workflows, and checkout charging integration. | `arma/client/addons/store` | `arma/server/addons/store` | `lib/models/src/store.rs`, `lib/services/src/store.rs` | `store:checkout` |
|
||||||
| Task | Mission/task catalog, ownership, status, reward context, and task counters. | none | `arma/server/addons/task` | `lib/models/src/task.rs`, `lib/services/src/task.rs` | `task:*` |
|
| Task | Mission/task catalog, ownership, status, reward context, and task counters. | none | `arma/server/addons/task` | `lib/models/src/task.rs`, `lib/services/src/task.rs` | `task:*` |
|
||||||
| Owned Garage | Organization or owner-scoped vehicle unlock storage. | via garage/org UI | server extension only | `lib/models/src/v_garage.rs`, `lib/services/src/v_garage.rs` | `owned:garage:*` |
|
| Owned Garage | Organization or owner-scoped vehicle unlock storage. | via garage/org UI | server extension only | `lib/models/src/v_garage.rs`, `lib/services/src/v_garage.rs` | `owned:garage:*` |
|
||||||
| Owned Locker | Organization or owner-scoped arsenal unlock storage. | via locker/org UI | server extension only | `lib/models/src/v_locker.rs`, `lib/services/src/v_locker.rs` | `owned:locker:*` |
|
| Owned Locker | Organization or owner-scoped arsenal unlock storage. | via locker/org UI | server extension only | `lib/models/src/v_locker.rs`, `lib/services/src/v_locker.rs` | `owned:locker:*` |
|
||||||
|
|||||||
@ -4,6 +4,22 @@ The store module processes checkout requests. It charges a payment source and
|
|||||||
grants purchased items to the player locker, virtual arsenal locker, and
|
grants purchased items to the player locker, virtual arsenal locker, and
|
||||||
virtual garage unlocks.
|
virtual garage unlocks.
|
||||||
|
|
||||||
|
## Server SQF Module
|
||||||
|
|
||||||
|
The server addon uses two long-lived module objects:
|
||||||
|
|
||||||
|
- `StorefrontStore` is the storefront workflow facade. It builds hydrate
|
||||||
|
payloads, validates checkout requests, calls the Rust `store:checkout`
|
||||||
|
command, syncs UI patches, and asks related module stores to save hot state.
|
||||||
|
- `StoreCatalogService` scans configured item and vehicle categories, builds
|
||||||
|
catalog responses, resolves checkout entries, and calculates authoritative
|
||||||
|
prices.
|
||||||
|
|
||||||
|
Editor-placed store entities are initialized by `fnc_initStore` during store
|
||||||
|
post-init. The initializer matches non-null mission namespace objects whose
|
||||||
|
variable names contain `store` and sets `isStore = true`, following the same
|
||||||
|
pattern used by garage entities.
|
||||||
|
|
||||||
## Checkout Model
|
## Checkout Model
|
||||||
|
|
||||||
`store:checkout` accepts one JSON context.
|
`store:checkout` accepts one JSON context.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user