- Add a dispatcher web view and layout switching - Route group role updates and dispatcher hydration through the UI bridge - Refresh top bar and hide map/side panel outside operations mode
305 lines
12 KiB
Plaintext
305 lines
12 KiB
Plaintext
#include "..\script_component.hpp"
|
|
|
|
/*
|
|
* File: fnc_initGroupRepository.sqf
|
|
* Author: IDSolutions
|
|
* Date: 2026-03-30
|
|
* Public: No
|
|
*
|
|
* Description:
|
|
* Initializes the CAD group repository for live group state, roles,
|
|
* and dispatcher/leader-managed group profiles.
|
|
*
|
|
* Arguments:
|
|
* None
|
|
*
|
|
* Return Value:
|
|
* CAD group repository object [HASHMAP OBJECT]
|
|
*
|
|
* Example:
|
|
* call forge_server_cad_fnc_initGroupRepository
|
|
*/
|
|
|
|
#pragma hemtt ignore_variables ["_self"]
|
|
GVAR(GroupRepositoryBaseClass) = compileFinal createHashMapFromArray [
|
|
["#type", "CadGroupRepositoryBaseClass"],
|
|
["#create", compileFinal {
|
|
_self set ["groupRegistry", createHashMap];
|
|
_self set ["groupProfileRegistry", createHashMap];
|
|
_self set ["validStatuses", [
|
|
"available",
|
|
"en_route",
|
|
"on_task",
|
|
"holding",
|
|
"danger",
|
|
"refit",
|
|
"offline"
|
|
]];
|
|
_self set ["validRoles", [
|
|
"infantry",
|
|
"recon",
|
|
"armor",
|
|
"air",
|
|
"logistics",
|
|
"support"
|
|
]];
|
|
}],
|
|
["resolveGroupId", compileFinal {
|
|
params [["_group", grpNull, [grpNull]]];
|
|
|
|
if (isNull _group) exitWith { "" };
|
|
|
|
private _leader = leader _group;
|
|
private _leaderUid = if (isNull _leader) then { "" } else { getPlayerUID _leader };
|
|
if (_leaderUid isNotEqualTo "") exitWith { format ["group:%1", _leaderUid] };
|
|
|
|
private _groupLabel = groupId _group;
|
|
if (_groupLabel isNotEqualTo "") exitWith { format ["group:%1", _groupLabel] };
|
|
|
|
str _group
|
|
}],
|
|
["getCurrentTaskIdForGroup", compileFinal {
|
|
params [["_groupID", "", [""]]];
|
|
|
|
if (_groupID isEqualTo "") exitWith { "" };
|
|
|
|
private _assignmentRepository = _self getOrDefault ["assignmentRepository", createHashMap];
|
|
private _assignmentRegistry = _assignmentRepository getOrDefault ["assignmentRegistry", createHashMap];
|
|
private _taskID = "";
|
|
|
|
{
|
|
if ((_y getOrDefault ["groupId", ""]) isNotEqualTo _groupID) then { continue; };
|
|
if !((_y getOrDefault ["state", ""]) in ["assigned", "acknowledged"]) then { continue; };
|
|
if ((EGVAR(task,TaskStore) call ["getTaskStatus", [_x]]) isNotEqualTo "active") then { continue; };
|
|
|
|
_taskID = _x;
|
|
} forEach _assignmentRegistry;
|
|
|
|
_taskID
|
|
}],
|
|
["syncGroups", compileFinal {
|
|
private _previousRegistry = _self getOrDefault ["groupRegistry", createHashMap];
|
|
private _profileRegistry = _self getOrDefault ["groupProfileRegistry", createHashMap];
|
|
private _nextRegistry = createHashMap;
|
|
|
|
{
|
|
private _group = _x;
|
|
if (side _group isNotEqualTo west) then { continue; };
|
|
|
|
private _members = allPlayers select { group _x isEqualTo _group };
|
|
if (_members isEqualTo []) then { continue; };
|
|
|
|
private _leader = leader _group;
|
|
if (isNull _leader || { !isPlayer _leader }) then {
|
|
_leader = _members # 0;
|
|
};
|
|
|
|
private _groupID = _self call ["resolveGroupId", [_group]];
|
|
if (_groupID isEqualTo "") then { continue; };
|
|
|
|
private _leaderUid = getPlayerUID _leader;
|
|
private _actor = EGVAR(actor,Registry) getOrDefault [_leaderUid, createHashMap];
|
|
if (_actor isEqualTo createHashMap && { _leaderUid isNotEqualTo "" }) then {
|
|
_actor = EGVAR(actor,ActorStore) call ["init", [_leaderUid]];
|
|
};
|
|
|
|
private _orgID = _actor getOrDefault ["organization", "default"];
|
|
if (_orgID isEqualTo "") then { _orgID = "default"; };
|
|
|
|
private _existingRecord = +(_previousRegistry getOrDefault [_groupID, createHashMap]);
|
|
private _profile = +(_profileRegistry getOrDefault [_groupID, createHashMap]);
|
|
private _memberUids = [];
|
|
private _memberRoster = [];
|
|
|
|
{
|
|
private _memberUid = getPlayerUID _x;
|
|
private _memberState = toLowerANSI (lifeState _x);
|
|
|
|
if (_memberUid isNotEqualTo "") then {
|
|
_memberUids pushBack _memberUid;
|
|
};
|
|
|
|
_memberRoster pushBack (createHashMapFromArray [
|
|
["uid", _memberUid],
|
|
["name", name _x],
|
|
["lifeState", _memberState],
|
|
["isLeader", _x isEqualTo _leader]
|
|
]);
|
|
} forEach _members;
|
|
|
|
private _record = createHashMapFromArray [
|
|
["groupId", _groupID],
|
|
["callsign", [groupId _group, _groupID] select ((groupId _group) isEqualTo "")],
|
|
["leaderUid", _leaderUid],
|
|
["leaderName", name _leader],
|
|
["memberUids", _memberUids],
|
|
["members", _memberRoster],
|
|
["orgId", _orgID],
|
|
["role", [_existingRecord getOrDefault ["role", "infantry"], _profile getOrDefault ["role", _existingRecord getOrDefault ["role", "infantry"]]] select (_profile isNotEqualTo createHashMap)],
|
|
["status", [_existingRecord getOrDefault ["status", "available"], _profile getOrDefault ["status", _existingRecord getOrDefault ["status", "available"]]] select (_profile isNotEqualTo createHashMap)],
|
|
["position", getPosATL _leader],
|
|
["currentTaskId", _self call ["getCurrentTaskIdForGroup", [_groupID]]],
|
|
["lastUpdate", serverTime]
|
|
];
|
|
|
|
_nextRegistry set [_groupID, _record];
|
|
_profileRegistry set [_groupID, createHashMapFromArray [
|
|
["role", _record getOrDefault ["role", "infantry"]],
|
|
["status", _record getOrDefault ["status", "available"]]
|
|
]];
|
|
} forEach allGroups;
|
|
|
|
_self set ["groupProfileRegistry", _profileRegistry];
|
|
_self set ["groupRegistry", _nextRegistry];
|
|
_nextRegistry
|
|
}],
|
|
["getGroupRecord", compileFinal {
|
|
params [["_groupID", "", [""]]];
|
|
|
|
if (_groupID isEqualTo "") exitWith { createHashMap };
|
|
|
|
private _groupRegistry = _self call ["syncGroups", []];
|
|
+(_groupRegistry getOrDefault [_groupID, createHashMap])
|
|
}],
|
|
["getPlayerGroupId", compileFinal {
|
|
params [["_uid", "", [""]]];
|
|
|
|
if (_uid isEqualTo "") exitWith { "" };
|
|
|
|
private _player = [_uid] call EFUNC(common,getPlayer);
|
|
if (_player isEqualTo objNull) exitWith { "" };
|
|
|
|
_self call ["resolveGroupId", [group _player]]
|
|
}],
|
|
["isGroupLeader", compileFinal {
|
|
params [["_uid", "", [""]], ["_groupID", "", [""]]];
|
|
|
|
if (_uid isEqualTo "" || { _groupID isEqualTo "" }) exitWith { false };
|
|
|
|
private _groupRecord = _self call ["getGroupRecord", [_groupID]];
|
|
(_groupRecord getOrDefault ["leaderUid", ""]) isEqualTo _uid
|
|
}],
|
|
["buildGroups", compileFinal {
|
|
private _groupRegistry = _self call ["syncGroups", []];
|
|
private _groups = [];
|
|
|
|
{
|
|
_groups pushBack +_y;
|
|
} forEach _groupRegistry;
|
|
|
|
_groups
|
|
}],
|
|
["updateGroupStatus", compileFinal {
|
|
params [["_requesterUid", "", [""]], ["_groupID", "", [""]], ["_status", "", [""]]];
|
|
|
|
private _result = createHashMapFromArray [
|
|
["success", false],
|
|
["message", "Unable to update group status."],
|
|
["group", createHashMap]
|
|
];
|
|
|
|
private _finalStatus = toLowerANSI _status;
|
|
if !(_finalStatus in (_self getOrDefault ["validStatuses", []])) exitWith {
|
|
_result set ["message", "Invalid group status."];
|
|
_result
|
|
};
|
|
|
|
private _permissionService = _self getOrDefault ["permissionService", createHashMap];
|
|
private _isAuthorized = (_self call ["isGroupLeader", [_requesterUid, _groupID]]) || { _permissionService call ["canDispatch", [_requesterUid]] };
|
|
if !_isAuthorized exitWith {
|
|
_result set ["message", "You are not authorized to update that group."];
|
|
_result
|
|
};
|
|
|
|
private _groupRegistry = _self call ["syncGroups", []];
|
|
private _groupRecord = +(_groupRegistry getOrDefault [_groupID, createHashMap]);
|
|
if (_groupRecord isEqualTo createHashMap) exitWith {
|
|
_result set ["message", "Group could not be resolved."];
|
|
_result
|
|
};
|
|
|
|
_groupRecord set ["status", _finalStatus];
|
|
_groupRecord set ["lastUpdate", serverTime];
|
|
_groupRegistry set [_groupID, _groupRecord];
|
|
_self set ["groupRegistry", _groupRegistry];
|
|
|
|
private _profileRegistry = _self getOrDefault ["groupProfileRegistry", createHashMap];
|
|
private _profile = +(_profileRegistry getOrDefault [_groupID, createHashMap]);
|
|
_profile set ["role", _groupRecord getOrDefault ["role", "infantry"]];
|
|
_profile set ["status", _finalStatus];
|
|
_profileRegistry set [_groupID, _profile];
|
|
_self set ["groupProfileRegistry", _profileRegistry];
|
|
|
|
private _activityRepository = _self getOrDefault ["activityRepository", createHashMap];
|
|
_activityRepository call ["appendActivity", [
|
|
"group_status",
|
|
format ["%1 updated %2 to %3.", _requesterUid, _groupRecord getOrDefault ["callsign", _groupID], _finalStatus],
|
|
"",
|
|
_groupID,
|
|
_requesterUid
|
|
]];
|
|
|
|
_result set ["success", true];
|
|
_result set ["message", "Group status updated."];
|
|
_result set ["group", _groupRecord];
|
|
_result
|
|
}],
|
|
["updateGroupRole", compileFinal {
|
|
params [["_requesterUid", "", [""]], ["_groupID", "", [""]], ["_role", "", [""]]];
|
|
|
|
private _result = createHashMapFromArray [
|
|
["success", false],
|
|
["message", "Unable to update group role."],
|
|
["group", createHashMap]
|
|
];
|
|
|
|
private _finalRole = toLowerANSI _role;
|
|
if !(_finalRole in (_self getOrDefault ["validRoles", []])) exitWith {
|
|
_result set ["message", "Invalid group role."];
|
|
_result
|
|
};
|
|
|
|
private _permissionService = _self getOrDefault ["permissionService", createHashMap];
|
|
private _isAuthorized = (_self call ["isGroupLeader", [_requesterUid, _groupID]]) || { _permissionService call ["canDispatch", [_requesterUid]] };
|
|
if !_isAuthorized exitWith {
|
|
_result set ["message", "You are not authorized to update that group role."];
|
|
_result
|
|
};
|
|
|
|
private _groupRegistry = _self call ["syncGroups", []];
|
|
private _groupRecord = +(_groupRegistry getOrDefault [_groupID, createHashMap]);
|
|
if (_groupRecord isEqualTo createHashMap) exitWith {
|
|
_result set ["message", "Group could not be resolved."];
|
|
_result
|
|
};
|
|
|
|
_groupRecord set ["role", _finalRole];
|
|
_groupRecord set ["lastUpdate", serverTime];
|
|
_groupRegistry set [_groupID, _groupRecord];
|
|
_self set ["groupRegistry", _groupRegistry];
|
|
|
|
private _profileRegistry = _self getOrDefault ["groupProfileRegistry", createHashMap];
|
|
private _profile = +(_profileRegistry getOrDefault [_groupID, createHashMap]);
|
|
_profile set ["role", _finalRole];
|
|
_profile set ["status", _groupRecord getOrDefault ["status", "available"]];
|
|
_profileRegistry set [_groupID, _profile];
|
|
_self set ["groupProfileRegistry", _profileRegistry];
|
|
|
|
private _activityRepository = _self getOrDefault ["activityRepository", createHashMap];
|
|
_activityRepository call ["appendActivity", [
|
|
"group_role",
|
|
format ["%1 updated %2 role to %3.", _requesterUid, _groupRecord getOrDefault ["callsign", _groupID], _finalRole],
|
|
"",
|
|
_groupID,
|
|
_requesterUid
|
|
]];
|
|
|
|
_result set ["success", true];
|
|
_result set ["message", "Group role updated."];
|
|
_result set ["group", _groupRecord];
|
|
_result
|
|
}]
|
|
];
|
|
|
|
createHashMapObject [GVAR(GroupRepositoryBaseClass)]
|