
All checks were successful
Build / Build (push) Successful in 26s
This commit refactors how organization funds and reputation are handled, updates task completion logic to use the new organization functions, and modifies player saving to include organization data. Additionally, it introduces string serialization/deserialization and fixes a player save loop. * **Organization Funds and Reputation:** Replaces direct server calls for handling funds and reputation with calls to the new organization functions (`EFUNC(org,addFunds)` and `EFUNC(org,addReputation)`). This centralizes fund and reputation management within the organization store. * **Task Completion Logic:** Updates task completion functions (`fnc_destroy.sqf`, `fnc_attack.sqf`, `fnc_hostage.sqf`, `fnc_hvt.sqf`, `fnc_defuse.sqf`) to use the new organization functions for adding funds and reputation upon task success or failure. Also adds notifications to inform the player of reputation and fund changes. * **Player Saving:** Modifies the player saving function (`fnc_playerDBSave.sqf`) to include the player's organization ID in the saved data. * **String Serialization/Deserialization:** Adds `serializeString` and `deserializeString` PREP macros to `XEH_PREP.hpp` and uses them in `fnc_handleOrgLoad.sqf` and `fnc_create.sqf` to handle special characters in organization and member names. * **Player Save Loop Fix:** Removes unnecessary brackets from the `call FUNC(playerDBSave)` in `fnc_playerSaveLoop.sqf`. * **Organization Purchase Verification:** Adds organization ownership verification to `fnc_handlePurchase.sqf` to ensure only the owner can make purchases using organization funds. * **Player Initialization:** Updates `fnc_initPlayer.sqf` to retrieve and set the player's organization upon initialization.
245 lines
9.1 KiB
Plaintext
245 lines
9.1 KiB
Plaintext
#include "..\script_component.hpp"
|
|
|
|
/*
|
|
* Author: J. Schmidt
|
|
* Processes and transforms raw organization data from a database into a structured hashMap.
|
|
* Handles data normalization, type conversion, and ensures all required organization fields are present.
|
|
* This function is called as a callback when organization data is loaded from the database.
|
|
*
|
|
* Arguments:
|
|
* 0: Raw Data <ARRAY> - DragonflyDB HGETALL result containing raw organization data
|
|
*
|
|
* Return Value:
|
|
* None
|
|
*
|
|
* Example:
|
|
* _orgData call forge_client_org_fnc_handleOrgLoad
|
|
*
|
|
* Public: No
|
|
*/
|
|
|
|
// Log the received data for debugging purposes
|
|
diag_log text format ["[FORGE Organization] Organization data received: '%1'", _this];
|
|
|
|
// Store the raw data and get player information
|
|
private _data = _this;
|
|
private _playerNetId = netId player;
|
|
private _store = call FUNC(verifyOrgStore);
|
|
|
|
// Validate the received data
|
|
if (isNil "_data" || {!(_data isEqualType [])} || {count _data < 2} || {_data isEqualTo [""]}) exitWith {
|
|
diag_log text "[FORGE Organization] Empty or invalid organization data received";
|
|
|
|
// Mark the store as loaded but with no organization
|
|
if !(isNil "_store") then {
|
|
_store set ["currentOrganization", nil];
|
|
_store set ["isLoaded", true];
|
|
};
|
|
|
|
["No organization data found", "info", 5, "right"] call forge_client_misc_fnc_notify;
|
|
};
|
|
|
|
// Create organization data hashMap to store the processed data
|
|
private _orgData = createHashMap;
|
|
|
|
// Process the data array - convert from flat key-value pairs to structured hashMap
|
|
for "_i" from 0 to (count _data - 1) step 2 do {
|
|
private _key = _data select _i;
|
|
private _value = _data select (_i + 1);
|
|
|
|
// Unwrap single-item arrays
|
|
if (_value isEqualType []) then {
|
|
switch (_key) do {
|
|
case "assets": {
|
|
// Convert to hashMap by assetType
|
|
private _flattenedAssets = [];
|
|
|
|
// Handle multi-level nesting and ensure it's flattened first
|
|
if (count _value > 0 && {_value select 0 isEqualType []}) then {
|
|
{
|
|
if (_x isEqualType []) then {
|
|
_flattenedAssets append _x;
|
|
} else {
|
|
_flattenedAssets pushBack _x;
|
|
};
|
|
} forEach _value;
|
|
} else {
|
|
_flattenedAssets = _value;
|
|
};
|
|
|
|
// Create hashMap from flattened assets
|
|
private _assetsMap = createHashMap;
|
|
{
|
|
if (_x isEqualType [] && count _x >= 2) then {
|
|
private _type = _x select 0;
|
|
private _class = _x select 1;
|
|
|
|
// Create a hashMap for this asset
|
|
private _assetMap = createHashMap;
|
|
|
|
// Try to get ID or generate one
|
|
private _assetId = "";
|
|
private _idIndex = _x findIf {_x == "id"};
|
|
if (_idIndex != -1 && _idIndex + 1 < count _x) then {
|
|
_assetId = _x select (_idIndex + 1);
|
|
} else {
|
|
_assetId = format ["%1_%2", _class, diag_tickTime];
|
|
};
|
|
|
|
// Add ID and class to asset map
|
|
_assetMap set ["id", _assetId];
|
|
_assetMap set ["className", _class];
|
|
|
|
// Add any extra properties (key-value pairs)
|
|
for "_j" from 2 to (count _x - 1) step 2 do {
|
|
if (_j + 1 < count _x) then {
|
|
private _propName = _x select _j;
|
|
private _propValue = _x select (_j + 1);
|
|
if (_propName != "className") then {
|
|
_assetMap set [_propName, _propValue];
|
|
};
|
|
};
|
|
};
|
|
|
|
// Add this asset to its type array
|
|
private _typeArray = _assetsMap getOrDefault [_type, []];
|
|
_typeArray pushBack _assetMap;
|
|
_assetsMap set [_type, _typeArray];
|
|
};
|
|
} forEach _flattenedAssets;
|
|
|
|
_value = _assetsMap;
|
|
};
|
|
|
|
case "members": {
|
|
// Convert to hashMap by playerUID
|
|
private _flattenedMembers = [];
|
|
|
|
// Handle multi-level nesting and ensure it's flattened first
|
|
if (count _value > 0 && {_value select 0 isEqualType []}) then {
|
|
{
|
|
if (_x isEqualType []) then {
|
|
_flattenedMembers append _x;
|
|
} else {
|
|
_flattenedMembers pushBack _x;
|
|
};
|
|
} forEach _value;
|
|
} else {
|
|
_flattenedMembers = _value;
|
|
};
|
|
|
|
// Create member hashMap
|
|
private _membersMap = createHashMap;
|
|
{
|
|
if (_x isEqualType [] && count _x >= 3) then {
|
|
private _uid = _x select 0;
|
|
private _name = _x select 1;
|
|
private _role = _x select 2;
|
|
private _joinDate = if (count _x > 3) then { _x select 3 } else { "" };
|
|
|
|
// Replace underscores with spaces in name
|
|
if (_name isEqualType "") then {
|
|
_name = [_name] call EFUNC(misc,deserializeString);
|
|
};
|
|
|
|
// Create member hashMap
|
|
private _memberMap = createHashMap;
|
|
_memberMap set ["uid", _uid];
|
|
_memberMap set ["name", _name];
|
|
_memberMap set ["role", _role];
|
|
_memberMap set ["joinDate", _joinDate];
|
|
|
|
// Add extra properties if any (for future expansion)
|
|
for "_j" from 4 to (count _x - 1) step 2 do {
|
|
if (_j + 1 < count _x) then {
|
|
private _propName = _x select _j;
|
|
private _propValue = _x select (_j + 1);
|
|
_memberMap set [_propName, _propValue];
|
|
};
|
|
};
|
|
|
|
_membersMap set [_uid, _memberMap];
|
|
};
|
|
} forEach _flattenedMembers;
|
|
|
|
_value = _membersMap;
|
|
};
|
|
|
|
case "logs": {
|
|
// Flatten arrays but don't process contents
|
|
private _flattenedArray = [];
|
|
|
|
// Handle multi-level nesting
|
|
if (count _value > 0 && {_value select 0 isEqualType []}) then {
|
|
{
|
|
if (_x isEqualType []) then {
|
|
_flattenedArray append _x;
|
|
} else {
|
|
_flattenedArray pushBack _x;
|
|
};
|
|
} forEach _value;
|
|
|
|
_value = _flattenedArray;
|
|
};
|
|
};
|
|
|
|
default {
|
|
if (count _value == 1) then {
|
|
_value = _value select 0;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
// Process string values - deserialize names and owner
|
|
if (_value isEqualType "" && _key in ["name", "owner"]) then {
|
|
_value = [_value] call EFUNC(misc,deserializeString);
|
|
};
|
|
|
|
// Convert numeric values from strings to numbers
|
|
if (_key in ["funds", "reputation"] && _value isEqualType "") then {
|
|
_value = parseNumber _value;
|
|
};
|
|
|
|
// Store processed value in hashMap
|
|
_orgData set [_key, _value];
|
|
};
|
|
|
|
// Ensure we have all required fields in the hashMap
|
|
private _requiredFields = ["id", "name", "owner", "funds", "reputation", "assets", "members", "logs", "created", "lastModified"];
|
|
{
|
|
if (isNil {_orgData get _x}) then {
|
|
switch (_x) do {
|
|
case "funds";
|
|
case "reputation": {
|
|
_orgData set [_x, 0];
|
|
};
|
|
case "assets";
|
|
case "members": {
|
|
_orgData set [_x, createHashMap];
|
|
};
|
|
case "logs": {
|
|
_orgData set [_x, []];
|
|
};
|
|
case "created";
|
|
case "lastModified": {
|
|
_orgData set [_x, ""];
|
|
};
|
|
default {
|
|
_orgData set [_x, ""];
|
|
};
|
|
};
|
|
};
|
|
} forEach _requiredFields;
|
|
|
|
// Update the organization store with the complete hashMap
|
|
_store set ["currentOrganization", _orgData];
|
|
_store set ["isLoaded", true];
|
|
|
|
private _orgName = _orgData get "name";
|
|
|
|
// Log successful load and notify the user
|
|
if (!isNil "_orgName") then {
|
|
diag_log text format ["[FORGE Organization] Organization successfully loaded: %1", _orgName];
|
|
[format ["Organization '%1' loaded", _orgName], "success", 5, "right"] call forge_client_misc_fnc_notify;
|
|
}; |