#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 - 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; };