From bec0adcdbf8e18e95209c13f7d124d2a0154c5e3 Mon Sep 17 00:00:00 2001 From: Jacob Schmidt Date: Fri, 28 Mar 2025 09:46:08 -0500 Subject: [PATCH] feat: Update build environment and add XEH PREP This commit includes the following changes: - Updates the build environment in the GitHub Actions workflow to use `ubuntu-latest` instead of `ubuntu-22.04`. - Adds `playerGroup2Server` to the XEH_PREP.hpp file. - Updates the picture path in CfgMods.hpp to include the file extension. --- .github/workflows/build.yml | 2 +- addons/db/$PBOPREFIX$ | 1 + addons/db/CfgEventHandlers.hpp | 19 ++++ addons/db/XEH_PREP.hpp | 13 +++ addons/db/XEH_postInit.sqf | 3 + addons/db/XEH_postInit_client.sqf | 1 + addons/db/XEH_preInit.sqf | 33 +++++++ addons/db/XEH_preInit_server.sqf | 1 + addons/db/XEH_preStart.sqf | 2 + addons/db/config.cpp | 16 +++ addons/db/functions/fnc_createStore.sqf | 26 +++++ addons/db/functions/fnc_getFromStore.sqf | 39 ++++++++ addons/db/functions/fnc_getStore.sqf | 25 +++++ addons/db/functions/fnc_initDB.sqf | 98 +++++++++++++++++++ addons/db/functions/fnc_loadFromMission.sqf | 32 ++++++ addons/db/functions/fnc_loadFromProfile.sqf | 32 ++++++ addons/db/functions/fnc_loadGameState.sqf | 64 ++++++++++++ addons/db/functions/fnc_processDBRequest.sqf | 43 ++++++++ addons/db/functions/fnc_saveGameState.sqf | 78 +++++++++++++++ addons/db/functions/fnc_saveToMission.sqf | 34 +++++++ addons/db/functions/fnc_saveToProfile.sqf | 34 +++++++ addons/db/functions/fnc_saveToStore.sqf | 44 +++++++++ addons/db/functions/fnc_saveToTemp.sqf | 39 ++++++++ addons/db/functions/fnc_verifyDB.sqf | 22 +++++ addons/db/script_component.hpp | 15 +++ addons/main/CfgMods.hpp | 2 +- addons/misc/XEH_PREP.hpp | 1 + .../misc/functions/fnc_playerGroup2Server.sqf | 10 ++ 28 files changed, 727 insertions(+), 2 deletions(-) create mode 100644 addons/db/$PBOPREFIX$ create mode 100644 addons/db/CfgEventHandlers.hpp create mode 100644 addons/db/XEH_PREP.hpp create mode 100644 addons/db/XEH_postInit.sqf create mode 100644 addons/db/XEH_postInit_client.sqf create mode 100644 addons/db/XEH_preInit.sqf create mode 100644 addons/db/XEH_preInit_server.sqf create mode 100644 addons/db/XEH_preStart.sqf create mode 100644 addons/db/config.cpp create mode 100644 addons/db/functions/fnc_createStore.sqf create mode 100644 addons/db/functions/fnc_getFromStore.sqf create mode 100644 addons/db/functions/fnc_getStore.sqf create mode 100644 addons/db/functions/fnc_initDB.sqf create mode 100644 addons/db/functions/fnc_loadFromMission.sqf create mode 100644 addons/db/functions/fnc_loadFromProfile.sqf create mode 100644 addons/db/functions/fnc_loadGameState.sqf create mode 100644 addons/db/functions/fnc_processDBRequest.sqf create mode 100644 addons/db/functions/fnc_saveGameState.sqf create mode 100644 addons/db/functions/fnc_saveToMission.sqf create mode 100644 addons/db/functions/fnc_saveToProfile.sqf create mode 100644 addons/db/functions/fnc_saveToStore.sqf create mode 100644 addons/db/functions/fnc_saveToTemp.sqf create mode 100644 addons/db/functions/fnc_verifyDB.sqf create mode 100644 addons/db/script_component.hpp create mode 100644 addons/misc/functions/fnc_playerGroup2Server.sqf diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6110770..9537f88 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,7 +16,7 @@ on: jobs: build: name: Build - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest steps: - name: Checkout Source Code uses: actions/checkout@v4 diff --git a/addons/db/$PBOPREFIX$ b/addons/db/$PBOPREFIX$ new file mode 100644 index 0000000..edfc9f9 --- /dev/null +++ b/addons/db/$PBOPREFIX$ @@ -0,0 +1 @@ +z\forge_server\addons\db \ No newline at end of file diff --git a/addons/db/CfgEventHandlers.hpp b/addons/db/CfgEventHandlers.hpp new file mode 100644 index 0000000..78b189a --- /dev/null +++ b/addons/db/CfgEventHandlers.hpp @@ -0,0 +1,19 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_preStart)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_preInit)); + serverInit = QUOTE(call COMPILE_FILE(XEH_preInit_server)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_postInit)); + clientInit = QUOTE(call COMPILE_FILE(XEH_postInit_client)); + }; +}; \ No newline at end of file diff --git a/addons/db/XEH_PREP.hpp b/addons/db/XEH_PREP.hpp new file mode 100644 index 0000000..f99e560 --- /dev/null +++ b/addons/db/XEH_PREP.hpp @@ -0,0 +1,13 @@ +PREP(createStore); +PREP(getFromStore); +PREP(getStore); +PREP(initDB); +PREP(loadFromMission); +PREP(loadFromProfile); +PREP(loadGameState); +PREP(saveGameState); +PREP(saveToMission); +PREP(saveToProfile); +PREP(saveToStore); +PREP(saveToTemp); +PREP(verifyDB); \ No newline at end of file diff --git a/addons/db/XEH_postInit.sqf b/addons/db/XEH_postInit.sqf new file mode 100644 index 0000000..f221374 --- /dev/null +++ b/addons/db/XEH_postInit.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +call FUNC(initDB); \ No newline at end of file diff --git a/addons/db/XEH_postInit_client.sqf b/addons/db/XEH_postInit_client.sqf new file mode 100644 index 0000000..84f2529 --- /dev/null +++ b/addons/db/XEH_postInit_client.sqf @@ -0,0 +1 @@ +#include "script_component.hpp" \ No newline at end of file diff --git a/addons/db/XEH_preInit.sqf b/addons/db/XEH_preInit.sqf new file mode 100644 index 0000000..33ccbc9 --- /dev/null +++ b/addons/db/XEH_preInit.sqf @@ -0,0 +1,33 @@ +#include "script_component.hpp" +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +GVAR(playerOwners) = createHashMap; +GVAR(tempStores) = createHashMap; + +// Process database requests +["forge_db_request", { + params ["_playerUID", "_requestType", "_data", "_requestID"]; + + TRACE_4("DB Request",_playerUID,_requestType,_data,_requestID); + + private _result = [_requestType, _data] call FUNC(processDBRequest); + ["forge_db_response", [_playerUID, _requestType, _result, _requestID]] call CBA_fnc_globalEvent; +}] call CBA_fnc_addEventHandler; + +// Register clients for direct messaging +["forge_db_registerClient", { + params ["_playerUID", "_ownerID"]; + GVAR(playerOwners) set [_playerUID, _ownerID]; +}] call CBA_fnc_addEventHandler; + +// Clean up on disconnect +addMissionEventHandler ["PlayerDisconnected", { + params ["_id", "_uid", "_name", "_jip", "_owner"]; + GVAR(playerOwners) deleteAt _uid; +}]; + +ADDON = true; \ No newline at end of file diff --git a/addons/db/XEH_preInit_server.sqf b/addons/db/XEH_preInit_server.sqf new file mode 100644 index 0000000..84f2529 --- /dev/null +++ b/addons/db/XEH_preInit_server.sqf @@ -0,0 +1 @@ +#include "script_component.hpp" \ No newline at end of file diff --git a/addons/db/XEH_preStart.sqf b/addons/db/XEH_preStart.sqf new file mode 100644 index 0000000..7dca066 --- /dev/null +++ b/addons/db/XEH_preStart.sqf @@ -0,0 +1,2 @@ +#include "script_component.hpp" +#include "XEH_PREP.hpp" \ No newline at end of file diff --git a/addons/db/config.cpp b/addons/db/config.cpp new file mode 100644 index 0000000..3725b3d --- /dev/null +++ b/addons/db/config.cpp @@ -0,0 +1,16 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"forge_server_main"}; + authors[] = {"J. Schmidt", "Creedcoder"}; + author = "J. Schmidt"; + VERSION_CONFIG; + }; +}; + +#include "CfgEventHandlers.hpp" \ No newline at end of file diff --git a/addons/db/functions/fnc_createStore.sqf b/addons/db/functions/fnc_createStore.sqf new file mode 100644 index 0000000..dcdc6c1 --- /dev/null +++ b/addons/db/functions/fnc_createStore.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" + +/* + * Function: forge_server_db_fnc_createStore + * Author: J. Schmidt + * + * Description: + * Creates a new collection in the database + * + * Arguments: + * 0: _name - Store name + * 1: _schema - Store schema + * + * Return Value: + * Store object or nil if failed + */ + +params [["_name", "", [""]], ["_schema", [], [[]]]]; + +if (_name isEqualTo "") exitWith { + ERROR_MSG("Store name cannot be empty"); + nil +}; + +private _database = call FUNC(verifyDB); +_database call ["createStore", [_name, _schema]] \ No newline at end of file diff --git a/addons/db/functions/fnc_getFromStore.sqf b/addons/db/functions/fnc_getFromStore.sqf new file mode 100644 index 0000000..ee86b6d --- /dev/null +++ b/addons/db/functions/fnc_getFromStore.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" + +/* + * Function: forge_server_db_fnc_getFromStore + * Author: J. Schmidt + * + * Description: + * Retrieves data from a store + * + * Arguments: + * 0: _name - Store name + * 1: _key - Key to retrieve (Optional, get entire store if empty) + * 2: _default - Default value if key not found + * 3: _namespace - Namespace to use (Optional, default: missionNamespace) + * + * Return Value: + * Retrieved data or default value + */ + +params [ + ["_name", "", [""]], + ["_key", "", [""]], + ["_default", nil], + ["_namespace", missionNamespace, [missionNamespace]] +]; + +if (_name isEqualTo "") exitWith { + ERROR_MSG_1("Invalid store name: %1",_name); + _default +}; + +private _stores = _namespace getVariable [QGVAR(stores), createHashMap]; +private _store = _stores getOrDefault [_name, createHashMap]; + +if (_key isEqualTo "") then { + _store +} else { + _store getOrDefault [_key, _default] +} \ No newline at end of file diff --git a/addons/db/functions/fnc_getStore.sqf b/addons/db/functions/fnc_getStore.sqf new file mode 100644 index 0000000..2ac3e28 --- /dev/null +++ b/addons/db/functions/fnc_getStore.sqf @@ -0,0 +1,25 @@ +#include "..\script_component.hpp" + +/* + * Function: forge_server_db_fnc_getStore + * Author: J. Schmidt + * + * Description: + * Retrieves a store from the database + * + * Arguments: + * 0: _name - Store name + * + * Return Value: + * Store object or nil if not found + */ + +params [["_name", "", [""]]]; + +if (_name isEqualTo "") exitWith { + ERROR_MSG("Store name cannot be empty"); + nil +}; + +private _database = GETMVAR(GVAR(store),nil); +_database call ["getStore", [_name]] \ No newline at end of file diff --git a/addons/db/functions/fnc_initDB.sqf b/addons/db/functions/fnc_initDB.sqf new file mode 100644 index 0000000..b67c7fe --- /dev/null +++ b/addons/db/functions/fnc_initDB.sqf @@ -0,0 +1,98 @@ +#include "..\script_component.hpp" + +/* + * Function: forge_server_db_fnc_initDB + * Author: J. Schmidt + * + * Description: + * Initializes the database system, creating the interface for other modules + * + * Arguments: + * None + * + * Return Value: + * Database interface object + */ + +private _storeInterface = createHashMapObject [[ + ["#type", "IStore"], + ["#create", { + private _storeRegistry = GETVAR(profileNamespace,FORGE_STORE_REG,createHashMap); + _self set ["stores", _storeRegistry]; + }], + ["createStore", { + params [["_name", "", [""]]]; + + if (_name == "") exitWith { ERROR_MSG("Store name cannot be empty"); nil }; + + private _stores = _self get "stores"; + private _store = _stores getOrDefault [_name, nil]; + + if !(isNil "_store") exitWith { _store }; + + private _store = createHashMap; + + _stores set [_name, _store]; + _store + }], + ["getStore", { + params [["_name", "", [""]]]; + + if (_name == "") exitWith { ERROR_MSG("Store name cannot be empty"); nil }; + + private _stores = _self get "stores"; + _stores getOrDefault [_name, nil] + }], + ["deleteStore", { + params [["_name", "", [""]]]; + + if (_name == "") exitWith { ERROR_MSG("Store name cannot be empty"); false }; + + private _stores = _self get "stores"; + private _store = _stores getOrDefault [_name, nil]; + + if (isNil "_store") exitWith { ERROR_MSG_1("Store %1 not found", _name); false }; + + _stores deleteAt _name; + true + }], + ["set", { + params [["_name", "", [""]], ["_key", "", [""]], ["_value", nil]]; + + if (_name == "" || _key == "") exitWith { ERROR_MSG("Store name and, or key cannot be empty"); false }; + + private _stores = _self get "stores"; + private _store = _stores getOrDefault [_name, nil]; + + if (isNil "_store") exitWith { ERROR_MSG_1("Store %1 not found", _name); false }; + + _store set [_key, _value]; + true + }], + ["get", { + params [["_name", "", [""]], ["_key", "", [""]], ["_default", nil]]; + + if (_name == "" || _key == "") exitWith { ERROR_MSG("Store name and, or key cannot be empty"); _default }; + + private _store = _self call ["getStore", [_name]]; + + if (isNil "_store") exitWith { ERROR_MSG_1("Store %1 not found", _name); _default }; + + _store getOrDefault [_key, _default] + }], + ["delete", { + params [["_name", "", [""]], ["_key", "", [""]]]; + + if (_name == "" || _key == "") exitWith { ERROR_MSG("Store name and, or key cannot be empty"); false }; + + private _store = _self call ["getStore", [_name]]; + + if (isNil "_store") exitWith { ERROR_MSG_1("Store %1 not found", _name); false }; + + _store deleteAt _key; + true + }] +]]; + +SETPVAR(missionNamespace,FORGE_STORE_REG,_storeInterface); +GETMVAR(FORGE_STORE_REG,nil) \ No newline at end of file diff --git a/addons/db/functions/fnc_loadFromMission.sqf b/addons/db/functions/fnc_loadFromMission.sqf new file mode 100644 index 0000000..7e034ea --- /dev/null +++ b/addons/db/functions/fnc_loadFromMission.sqf @@ -0,0 +1,32 @@ +#include "..\script_component.hpp" + +/* + * Function: forge_server_db_fnc_loadFromMission + * Author: J. Schmidt + * + * Description: + * Loads data from mission namespace using the database interface + * + * Arguments: + * 0: _name - Store name + * 1: _key - Key to retrieve + * 2: _default - Default value if not found + * + * Return Value: + * Retrieved data or default value + */ + +params [ + ["_name", "", [""]], + ["_key", "", [""]], + ["_default", nil] +]; + +private _database = call FUNC(verifyDB); +private _store = _database call ["getStore", [_name]]; + +if (isNil "_store") exitWith { + _default +}; + +[_name, _key, _default, missionNamespace] call FUNC(getFromStore) \ No newline at end of file diff --git a/addons/db/functions/fnc_loadFromProfile.sqf b/addons/db/functions/fnc_loadFromProfile.sqf new file mode 100644 index 0000000..cd66065 --- /dev/null +++ b/addons/db/functions/fnc_loadFromProfile.sqf @@ -0,0 +1,32 @@ +#include "..\script_component.hpp" + +/* + * Function: forge_server_db_fnc_loadFromProfile + * Author: J. Schmidt + * + * Description: + * Loads data from profile namespace + * + * Arguments: + * 0: _name - Store name + * 1: _key - Key to retrieve (Optional, get entire collection if empty) + * 2: _default - Default value if key not found + * + * Return Value: + * Retrieved data or default value + */ + +params [ + ["_name", "", [""]], + ["_key", "", [""]], + ["_default", nil] +]; + +private _database = call FUNC(verifyDB); +private _store = _database call ["getStore", [_name]]; + +if (isNil "_store") exitWith { + _default +}; + +[_name, _key, _default, profileNamespace] call FUNC(getFromStore); \ No newline at end of file diff --git a/addons/db/functions/fnc_loadGameState.sqf b/addons/db/functions/fnc_loadGameState.sqf new file mode 100644 index 0000000..43aca01 --- /dev/null +++ b/addons/db/functions/fnc_loadGameState.sqf @@ -0,0 +1,64 @@ +#include "..\script_component.hpp" + +/* + * Function: forge_server_db_fnc_loadGameState + * Author: J. Schmidt + * + * Description: + * Loads game state from mission namespace and sets appropriate variables + * + * Arguments: + * None + * + * Return Value: + * Success + */ + +private _companyState = ["companyStore", "CompanyState", nil] call FUNC(loadFromMission); +if (!isNil "_companyState") then { + companyFunds = _companyState getOrDefault ["funds", 0]; + companyRating = _companyState getOrDefault ["rating", 0]; + companyGenerals = _companyState getOrDefault ["operations", []]; + companyGarageUnlocks = _companyState getOrDefault ["garage_unlocks", []]; +}; + +private _playerUID = getPlayerUID player; +private _playerState = ["playerStore", _playerUID, nil] call FUNC(loadFromMission); +if (!isNil "_playerState") then { + private _armory_unlocks = _playerState getOrDefault ["armory_unlocks", [[],[],[],[]]]; + private _garage_unlocks = _playerState getOrDefault ["garage_unlocks", [[],[],[],[],[],[]]]; + private _locker = _playerState getOrDefault ["locker", []]; + private _garage = _playerState getOrDefault ["garage", []]; + private _cash = _playerState getOrDefault ["cash", 0]; + private _bank = _playerState getOrDefault ["bank", 0]; + private _number = _playerState getOrDefault ["number", "unknown"]; + private _email = _playerState getOrDefault ["email", "unknown@spearnet.mil"]; + private _paygrade = _playerState getOrDefault ["paygrade", "E1"]; + private _holster = _playerState getOrDefault ["holster", true]; + + EGVAR(arsenal,armory_unlocks) = _armory_unlocks; + EGVAR(arsenal,garage_unlocks) = _garage_unlocks; + SETPVAR(player,FORGE_Locker,_locker); + SETPVAR(player,FORGE_Garage,_garage); + SETPVAR(player,FORGE_Cash,_cash); + SETPVAR(player,FORGE_Bank,_bank); + SETPVAR(player,FORGE_Phone_Number,_number); + SETPVAR(player,FORGE_Email,_email); + SETPVAR(player,FORGE_Paygrade,_paygrade); + SETPVAR(player,FORGE_Holster_Weapon,_holster); + + if (isNull objectParent player) then { + player setUnitLoadout (_playerState getOrDefault ["loadout", []]); + if (_playerState getOrDefault ["currentWeapon", ""] != "") then { + player selectWeapon (_playerState get "currentWeapon"); + }; + player setPosASL (_playerState getOrDefault ["position", getPosASL player]); + player setDir (_playerState getOrDefault ["direction", 0]); + + if (_playerState getOrDefault ["stance", ""] != "") then { + [player, _playerState get "stance"] call ace_common_fnc_setStance; + }; + }; +}; + +true \ No newline at end of file diff --git a/addons/db/functions/fnc_processDBRequest.sqf b/addons/db/functions/fnc_processDBRequest.sqf new file mode 100644 index 0000000..185336c --- /dev/null +++ b/addons/db/functions/fnc_processDBRequest.sqf @@ -0,0 +1,43 @@ +#include "..\script_component.hpp" + +/* + * Function: forge_server_db_fnc_processDBRequest + * Author: J. Schmidt + * + * Description: + * Processes database requests from clients + * + * Arguments: + * 0: _type - Type of database operation + * 1: _data - Data for the operation + * + * Return Value: + * Operation result + */ + +params [["_type", "", [""]], ["_data", nil, []]]; + +switch (_type) do { + case "getStore": { + params ["_name"]; + [_name] call FUNC(getStore); + }; + case "saveTostore": { + _data params ["_name", "_data", "_key"]; + [_name, _data, _key] call FUNC(saveToStore); + }; + case "getFromstore": { + _data params ["_name", "_key"]; + [_name, _key] call FUNC(getFromStore); + }; + case "loadGameState": { + [] call FUNC(loadGameState); + }; + case "saveGameState": { + [_data] call FUNC(saveGameState); + }; + default { + WARNING_1("Unknown database request type: %1", _type); + nil + }; +}; \ No newline at end of file diff --git a/addons/db/functions/fnc_saveGameState.sqf b/addons/db/functions/fnc_saveGameState.sqf new file mode 100644 index 0000000..64bb5bb --- /dev/null +++ b/addons/db/functions/fnc_saveGameState.sqf @@ -0,0 +1,78 @@ +#include "..\script_component.hpp" + +/* + * Function: forge_server_db_fnc_saveGameState + * Author: J. Schmidt + * + * Description: + * Collects and saves the current game state to mission namespace + * + * Arguments: + * None + * + * Return Value: + * Success + */ + +if (isNil "companyFunds") then { companyFunds = 0 }; +if (isNil "companyRating") then { companyRating = 0 }; +if (isNil "companyGenerals") then { companyGenerals = [] }; +if (isNil "companyGarageUnlocks") then { companyGarageUnlocks = [] }; +if (isNil EGVAR(arsenal,armory_unlocks)) then { EGVAR(arsenal,armory_unlocks) = [[],[],[],[]] }; +if (isNil EGVAR(arsenal,garage_unlocks)) then { EGVAR(arsenal,garage_unlocks) = [[],[],[],[],[],[]] }; + +private _companyState = createHashMapFromArray [ + ["key", "CompanyState"], + ["funds", companyFunds], + ["rating", companyRating], + ["operations", companyGenerals], + ["garage_unlocks", companyGarageUnlocks] +]; + +["companyStore", _companyState, "CompanyState"] call FUNC(saveToMission); + +{ + if (alive _x) then { + private _playerState = createHashMapFromArray [ + ["key", getPlayerUID _x], + ["armory_unlocks", EGVAR(arsenal,armory_unlocks)], + ["garage_unlocks", EGVAR(arsenal,garage_unlocks)], + ["locker", GETVAR(_x,FORGE_Locker,[])], + ["garage", GETVAR(_x,FORGE_Garage,[])], + ["cash", GETVAR(_x,FORGE_Cash,0)], + ["bank", GETVAR(_x,FORGE_Bank,0)], + ["number", GETVAR(_x,FORGE_Phone_Number,"unknown")], + ["email", GETVAR(_x,FORGE_Email,"unknown@spearnet.mil")], + ["paygrade", GETVAR(_x,FORGE_Paygrade,"E1")], + ["reputation", rating _x], + ["loadout", getUnitLoadout _x], + ["holster", GETVAR(_x,FORGE_Holster_Weapon,true)], + ["position", getPosASLVisual _x], + ["direction", getDirVisual _x] + ]; + + if (isNull objectParent _x) then { + _playerState set ["currentWeapon", currentMuzzle _x]; + _playerState set ["stance", stance _x]; + }; + + ["playerStore", _playerState, getPlayerUID _x] call FUNC(saveToMission); + }; +} forEach playableUnits; + +private _vehicles = nearestObjects [player, ["LandVehicle"], 50]; +{ + if (alive _x) then { + private _vehicleState = createHashMapFromArray [ + ["key", netId _x], + ["class", typeOf _x], + ["position", getPosATL _x], + ["direction", getDir _x], + ["health", damage _x] + ]; + + ["vehicleStore", _vehicleState, netId _x] call FUNC(saveToMission); + }; +} forEach _vehicles; + +true \ No newline at end of file diff --git a/addons/db/functions/fnc_saveToMission.sqf b/addons/db/functions/fnc_saveToMission.sqf new file mode 100644 index 0000000..45b32b1 --- /dev/null +++ b/addons/db/functions/fnc_saveToMission.sqf @@ -0,0 +1,34 @@ +#include "..\script_component.hpp" + +/* + * Function: forge_server_db_fnc_saveToMission + * Author: J. Schmidt + * + * Description: + * Saves data to mission namespace through the database interface + * + * Arguments: + * 0: _name - Store name + * 1: _data - Data to save + * 2: _key - Key to save under + * + * Return Value: + * Success + */ + +params [ + ["_name", "", [""]], + ["_data", nil, [createHashMap, [], "", 0, true]], + ["_key", "", [""]] +]; + +private _database = call FUNC(verifyDB); +private _store = _database call ["getStore", [_name]]; + +if (isNil "_store") then { + _store = _database call ["createStore", [_name, []]]; +}; + +[_name, _data, _key, missionNamespace] call FUNC(saveToStore); + +true \ No newline at end of file diff --git a/addons/db/functions/fnc_saveToProfile.sqf b/addons/db/functions/fnc_saveToProfile.sqf new file mode 100644 index 0000000..48b52d6 --- /dev/null +++ b/addons/db/functions/fnc_saveToProfile.sqf @@ -0,0 +1,34 @@ +#include "..\script_component.hpp" + +/* + * Function: forge_server_db_fnc_saveToProfile + * Author: J. Schmidt + * + * Description: + * Saves data to profile namespace through the database interface + * + * Arguments: + * 0: _name - Store name + * 1: _data - Data to save + * 2: _key - Key to save under + * + * Return Value: + * Success + */ + +params [ + ["_name", "", [""]], + ["_data", nil, [createHashMap, [], "", 0, true]], + ["_key", "", [""]] +]; + +private _database = call FUNC(verifyDB); +private _store = _database call ["getStore", [_name]]; + +if (isNil "_store") then { + _store = _database call ["createStore", [_name, []]]; +}; + +[_name, _data, _key, profileNamespace] call FUNC(saveToStore); + +true \ No newline at end of file diff --git a/addons/db/functions/fnc_saveToStore.sqf b/addons/db/functions/fnc_saveToStore.sqf new file mode 100644 index 0000000..e854570 --- /dev/null +++ b/addons/db/functions/fnc_saveToStore.sqf @@ -0,0 +1,44 @@ +#include "..\script_component.hpp" + +/* + * Function: forge_server_db_fnc_saveToStore + * Author: J. Schmidt + * + * Description: + * Saves data to a store in the specified namespace + * + * Arguments: + * 0: _name - Store name + * 1: _data - Data to save + * 2: _key - Key to save under + * 3: _namespace - Namespace to use (Optional, default: missionNamespace) + * + * Return Value: + * Success + */ + +params [ + ["_name", "", [""]], + ["_data", nil, [createHashMap, [], "", 0, true]], + ["_key", "", [""]], + ["_namespace", missionNamespace, [missionNamespace]] +]; + +if (_name isEqualTo "" || _key isEqualTo "") exitWith { + ERROR_MSG_2("Invalid store name or key: %1, %2", _name, _key); + false +}; + +private _stores = _namespace getVariable [QGVAR(stores), createHashMap]; +private _store = _stores getOrDefault [_name, createHashMap]; + +_store set [_key, _data]; +_stores set [_name, _store]; +_namespace setVariable [QGVAR(stores), _stores]; + +switch (_namespace) do { + case (missionNamespace): { saveMissionProfileNamespace; }; + case (profileNamespace): { saveProfileNamespace; }; +}; + +true \ No newline at end of file diff --git a/addons/db/functions/fnc_saveToTemp.sqf b/addons/db/functions/fnc_saveToTemp.sqf new file mode 100644 index 0000000..1d9773e --- /dev/null +++ b/addons/db/functions/fnc_saveToTemp.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" + +/* + * Function: forge_server_db_fnc_saveToTemp + * Author: J. Schmidt + * + * Description: + * Saves data to temporary mission store (not persisted between sessions) + * + * Arguments: + * 0: _name - Store name + * 1: _data - Data to save + * 2: _key - Key to save under + * + * Return Value: + * Success + */ + +params [ + ["_name", "", [""]], + ["_data", nil, [createHashMap, [], "", 0, true]], + ["_key", "", [""]] +]; + +private _database = call FUNC(verifyDB); +private _store = _database call ["getStore", [_name]]; + +if (isNil "_store") then { + _store = _database call ["createStore", [_name, []]]; +}; + +private _tempStores = missionNamespace getVariable [QGVAR(tempStores), createHashMap]; +private _tempStore = _tempStores getOrDefault [_name, createHashMap]; + +_tempStore set [_key, _data]; +_tempStores set [_name, _tempStore]; +missionNamespace setVariable [QGVAR(tempStores), _tempStores]; + +true diff --git a/addons/db/functions/fnc_verifyDB.sqf b/addons/db/functions/fnc_verifyDB.sqf new file mode 100644 index 0000000..fa7687d --- /dev/null +++ b/addons/db/functions/fnc_verifyDB.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" + +/* + * Function: forge_server_db_fnc_verifyDB + * Author: J. Schmidt + * + * Description: + * Verifies the database is initialized and returns the database object + * + * Arguments: + * None + * + * Return Value: + * Database object + */ + +private _store = GETMVAR(GVAR(store),nil); +if (isNil "_store") then { + _store = [] call FUNC(initDB); +}; + +_store \ No newline at end of file diff --git a/addons/db/script_component.hpp b/addons/db/script_component.hpp new file mode 100644 index 0000000..b2c6a23 --- /dev/null +++ b/addons/db/script_component.hpp @@ -0,0 +1,15 @@ +#define COMPONENT db +#define COMPONENT_BEAUTIFIED DB +#include "..\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE + +#ifdef DEBUG_ENABLED_DB + #define DEBUG_MODE_FULL +#endif + #ifdef DEBUG_SETTINGS_DB + #define DEBUG_SETTINGS DEBUG_SETTINGS_DB +#endif + +#include "..\main\script_macros.hpp" \ No newline at end of file diff --git a/addons/main/CfgMods.hpp b/addons/main/CfgMods.hpp index 0591fad..81efe72 100644 --- a/addons/main/CfgMods.hpp +++ b/addons/main/CfgMods.hpp @@ -3,7 +3,7 @@ class CfgMods { dir = "@forge_server"; name = "FORGE Server"; author = "IDSolutions"; - picture = "A3\Ui_f\data\Logos\arma3_expansion_alpha_ca"; + picture = "A3\Ui_f\data\Logos\arma3_expansion_alpha_ca.paa"; hideName = "false"; hidePicture = "false"; action = "https://innovativedevsolutions.org"; diff --git a/addons/misc/XEH_PREP.hpp b/addons/misc/XEH_PREP.hpp index 7e5ae61..eb01d3a 100644 --- a/addons/misc/XEH_PREP.hpp +++ b/addons/misc/XEH_PREP.hpp @@ -1,5 +1,6 @@ PREP(cargoToPairs); PREP(playSound); +PREP(playerGroup2Server); PREP(redirectClient2Server); PREP(emailMessage); PREP(textMessage); \ No newline at end of file diff --git a/addons/misc/functions/fnc_playerGroup2Server.sqf b/addons/misc/functions/fnc_playerGroup2Server.sqf new file mode 100644 index 0000000..8a97614 --- /dev/null +++ b/addons/misc/functions/fnc_playerGroup2Server.sqf @@ -0,0 +1,10 @@ +#include "..\script_component.hpp" + +params [["_ip", "127.0.0.1", [""]], ["_port", "2312", [""]], ["_password", "abc", [""]]]; + +private _units = units group player select { isPlayer _x }; +private _machineIDs = _units apply { owner _x }; + +{ + [_ip, _port, _password] remoteExecCall ["forge_server_misc_fnc_redirectClient2Server", _x]; +} forEach _machineIDs; \ No newline at end of file