From eec98d03eb06e392c4780e43b52124d3aafcb22c Mon Sep 17 00:00:00 2001 From: Jacob Schmidt Date: Sat, 3 May 2025 19:33:45 -0500 Subject: [PATCH] feat: Implement admin event handling and improve player data saving This commit introduces admin event handling to manage various administrative actions and enhances the player data saving process. The following changes were made: - Implemented event handling for admin actions such as advancing funds, handling paydays, transferring funds, sending messages, and updating paygrades. These events are triggered via the `QGVAR(handleEvents)` event handler. - Added `initAdminStore` and `verifyAdminStore` functions to manage the admin store. - Refactored the `fnc_handleDisconnect.sqf` script to use the `GETVAR` macro for retrieving player data, ensuring consistency and readability. - Replaced hardcoded default values with `QUOTE()` wrapped values in `fnc_handleDisconnect.sqf` for better maintainability and configuration. --- .vscode/tasks.json | 24 ---- addons/admin/XEH_PREP.hpp | 4 +- addons/admin/XEH_preInit_server.sqf | 55 +++++++- addons/admin/functions/fnc_initAdminStore.sqf | 119 ++++++++++++++++++ .../admin/functions/fnc_verifyAdminStore.sqf | 32 +++++ .../save/functions/fnc_handleDisconnect.sqf | 22 +--- 6 files changed, 211 insertions(+), 45 deletions(-) delete mode 100644 .vscode/tasks.json create mode 100644 addons/admin/functions/fnc_initAdminStore.sqf create mode 100644 addons/admin/functions/fnc_verifyAdminStore.sqf diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index f42e096..0000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Start Arma 3 Server", - "type": "process", - "command": "wscript.exe", - "args": [ - "D:\\SteamLibrary\\steamapps\\common\\Arma 3\\start_serverhub_hidden.vbs" - ], - "presentation": { - "reveal": "silent", - "panel": "shared", - "showReuseMessage": false, - "clear": true - }, - "problemMatcher": [], - "group": { - "kind": "build", - "isDefault": true - } - } - ] -} \ No newline at end of file diff --git a/addons/admin/XEH_PREP.hpp b/addons/admin/XEH_PREP.hpp index 4a0760f..c7d92c8 100644 --- a/addons/admin/XEH_PREP.hpp +++ b/addons/admin/XEH_PREP.hpp @@ -1 +1,3 @@ -PREP(initAdmin); \ No newline at end of file +PREP(initAdmin); +PREP(initAdminStore); +PREP(verifyAdminStore); \ No newline at end of file diff --git a/addons/admin/XEH_preInit_server.sqf b/addons/admin/XEH_preInit_server.sqf index 89674b7..58cdb5b 100644 --- a/addons/admin/XEH_preInit_server.sqf +++ b/addons/admin/XEH_preInit_server.sqf @@ -1,3 +1,56 @@ #include "script_component.hpp" -call FUNC(initAdmin); \ No newline at end of file +call FUNC(initAdmin); +call FUNC(initAdminStore); + +[QGVAR(handleEvents), { + params ["_event", "_params"]; + + diag_log format ["[FORGE: Admin] Received event: %1 with params: %2", _event, _params]; + + switch (_event) do { + case "advanceAll": { + private _adminStore = call FUNC(verifyAdminStore); + _params params ["_amount"]; + + if (isNil "_amount") exitWith { diag_log "Amount cannot be empty!"; }; + + _adminStore call ["handleTransfer", ["advanceAll", _amount]]; + }; + case "handlePayday": { + private _adminStore = call FUNC(verifyAdminStore); + + _adminStore call ["handleTransfer", ["payday"]]; + }; + case "handleTransfer": { + private _adminStore = call FUNC(verifyAdminStore); + _params params ["_condition", "_amount", "_uid"]; + + if (isNil "_condition") exitWith { diag_log "Condition cannot be empty!"; }; + + _adminStore call ["handleTransfer", [_condition, _amount, _uid]]; + }; + case "sendMessage": { + private _adminStore = call FUNC(verifyAdminStore); + _params params ["_uid", "_message"]; + + if (isNil "_message") exitWith { diag_log "Message cannot be empty!"; }; + if (_uid isEqualTo "") then { + _adminStore call ["broadcastMessage", [_message]]; + } else { + _adminStore call ["sendMessage", [_uid, _message]]; + }; + }; + case "updatePaygrade": { + private _adminStore = call FUNC(verifyAdminStore); + _params params ["_uid", "_paygrade"]; + + if (_uid isEqualTo "" && _paygrade isEqualTo "") exitWith { diag_log "UID or Paygrade cannot be empty!"; }; + + _adminStore call ["updatePaygrade", [_uid, _paygrade]]; + }; + default { + diag_log format ["Unknown event: %1 with params: %2", _event, _params]; + }; + }; +}] call CFUNC(addEventHandler); \ No newline at end of file diff --git a/addons/admin/functions/fnc_initAdminStore.sqf b/addons/admin/functions/fnc_initAdminStore.sqf new file mode 100644 index 0000000..c08ca26 --- /dev/null +++ b/addons/admin/functions/fnc_initAdminStore.sqf @@ -0,0 +1,119 @@ +#include "..\script_component.hpp" + +/* + * Function: forge_server_admin_fnc_initAdminStore + * Author: IDSolutions + * + * Description: + * Initializes a server-side admin store interface for managing admin operations + * Provides CRUD operations for admin data, including database persistence through ArmaDragonflyClient + * + * Creates a hashMap object with methods for: + * - Sending messages to players + * - Managing player data + * - Performing administrative tasks + * + * Returns: + * + * Example: + * private _adminStore = call forge_server_admin_fnc_initAdminStore; + * _adminStore call ["sendMessage", [getPlayerUID player, "Hello, this is a test message"]]; + */ + +private _adminStore = createHashMapObject [[ + ["#type", "IAdminStore"], + ["broadcastMessage", { + params ["_message"]; + + [format ["Incoming Message from Field Commander:
%1", _message], "warning", 5] remoteExec ["forge_client_misc_fnc_notify", 0]; + }], + ["sendMessage", { + params ["_uid", "_message"]; + private _target = objNull; + + { + if (getPlayerUID _x == _uid) exitWith { _target = _x; }; + } forEach allPlayers; + + if (!isNull _target) then { + [format ["Incoming Message from Field Commander:
%1", _message], "warning", 5] remoteExec ["forge_client_misc_fnc_notify", _target]; + }; + }], + ["updatePaygrade", { + params ["_uid", "_paygrade"]; + private _target = objNull; + + { + if (getPlayerUID _x == _uid) exitWith { _target = _x; }; + } forEach allPlayers; + + if (!isNull _target) then { SETPVAR(_target,FORGE_PayGrade,_paygrade); }; + }], + ["handleTransfer", { + params ["_condition", "_amount", "_uid"]; + + switch (_condition) do { + case ("advance"): { + private _target = objNull; + + { + if (getPlayerUID _x == _uid) exitWith { _target = _x; }; + } forEach allPlayers; + + if (isNull _target) exitWith {}; + + private _bank = GETVAR(_target,FORGE_Bank,0); + private _newBalance = _bank + _amount; + + SETPVAR(_target,FORGE_Bank,_newBalance); + }; + case ("advanceAll"): { + { + private _player = _x; + private _bank = GETVAR(_player,FORGE_Bank,0); + private _newBalance = _bank + _amount; + + SETPVAR(_player,FORGE_Bank,_newBalance); + } forEach allPlayers; + }; + case ("deduct"): { + private _target = objNull; + + { + if (getPlayerUID _x == _uid) exitWith { _target = _x; }; + } forEach allPlayers; + + if (isNull _target) exitWith {}; + + private _bank = GETVAR(_target,FORGE_Bank,0); + private _newBalance = _bank - _amount; + + if (_newBalance < 0) then { _newBalance = 0; }; + + SETPVAR(_target,FORGE_Bank,_newBalance); + }; + case ("payday"): { + private _payGrades = (missionConfigFile >> "CfgPaygrades" >> "payGrades") call BIS_fnc_getCfgData; + + { + private _player = _x; + private _payGrade = GETVAR(_player,FORGE_PayGrade,nil); + + { + _x params ["_payGradeIndex", "_payGradeBonus"]; + + if (_payGradeIndex == _payGrade) then { + private _bank = GETVAR(_player,FORGE_Bank,0); + private _newBalance = _bank + _payGradeBonus; + + SETPVAR(_player,FORGE_Bank,_newBalance); + }; + } forEach _payGrades; + } forEach allPlayers; + }; + }; + }] +]]; + +SETMVAR(FORGE_ADMIN_STORE_REG,_adminStore); +GETMVAR(FORGE_ADMIN_STORE_REG,_adminStore); \ No newline at end of file diff --git a/addons/admin/functions/fnc_verifyAdminStore.sqf b/addons/admin/functions/fnc_verifyAdminStore.sqf new file mode 100644 index 0000000..abeb71a --- /dev/null +++ b/addons/admin/functions/fnc_verifyAdminStore.sqf @@ -0,0 +1,32 @@ +#include "..\script_component.hpp" + +/* + * Function: forge_server_admin_fnc_verifyAdminStore + * Author: IDSolutions + * + * [Description] + * Ensures the admin store is initialized and returns the store object. + * Acts as a singleton accessor for the admin store interface. + * If the store doesn't exist yet, it initializes it first. + * + * Arguments: + * None + * + * Return Value: + * Admin Store - The admin store interface object + * + * Example: + * private _adminStore = call forge_server_admin_fnc_verifyAdminStore + * + * Public: No + */ + +private _store = GETMVAR(FORGE_ADMIN_STORE_REG,nil); + +if (isNil "_store") then { + _store = call FUNC(initAdminStore); + + diag_log text "[FORGE Admin] Admin store initialized"; +}; + +_store \ No newline at end of file diff --git a/addons/save/functions/fnc_handleDisconnect.sqf b/addons/save/functions/fnc_handleDisconnect.sqf index a9ae70c..55a3bdd 100644 --- a/addons/save/functions/fnc_handleDisconnect.sqf +++ b/addons/save/functions/fnc_handleDisconnect.sqf @@ -27,38 +27,22 @@ addMissionEventHandler ["HandleDisconnect", { private _data = [ _uid, - // "armory_unlocks", [_unit getVariable ["Armory_Unlocks", _default_armory_unlocks]], - // "garage_unlocks", [_unit getVariable ["Garage_Unlocks", _default_garage_unlocks]], "armory_unlocks", [GETVAR(_unit,Armory_Unlocks,_default_armory_unlocks)], "garage_unlocks", [GETVAR(_unit,Garage_Unlocks,_default_garage_unlocks)], - // "locker", [_unit getVariable ["FORGE_Locker", []]], - // "garage", [_unit getVariable ["FORGE_Garage", []]], "locker", [GETVAR(_unit,FORGE_Locker,[])], "garage", [GETVAR(_unit,FORGE_Garage,[])], - // "cash", [_unit getVariable ["FORGE_Cash", 0]], - // "bank", [_unit getVariable ["FORGE_Bank", 0]], "cash", [GETVAR(_unit,FORGE_Cash,0)], "bank", [GETVAR(_unit,FORGE_Bank,0)], - // "number", [_unit getVariable ["FORGE_Phone_Number", "unknown"]], - // "email", [_unit getVariable ["FORGE_Email", "unknown@spearnet.mil"]], - "number", [GETVAR(_unit,FORGE_Phone_Number,"unknown")], - "email", [GETVAR(_unit,FORGE_Email,"unknown@spearnet.mil")], - // "paygrade", [_unit getVariable ["Paygrade", "E1"]], - "paygrade", [GETVAR(_unit,Paygrade,"E1")], + "number", [GETVAR(_unit,FORGE_Phone_Number,QUOTE(unknown))], + "email", [GETVAR(_unit,FORGE_Email,QUOTE(unknown@spearnet.mil))], + "paygrade", [GETVAR(_unit,FORGE_PayGrade,QUOTE(E1))], "reputation", [rating _unit], "loadout", [getUnitLoadout _unit], - // "holster", [_unit getVariable ["FORGE_Holster_Weapon", true]], "holster", [GETVAR(_unit,FORGE_Holster_Weapon,true)], "position", [getPosASLVisual _unit], "direction", [getDirVisual _unit] ]; - // if (vehicle _unit == _unit) then { - // _data pushBack "currentWeapon"; - // _data pushBack [currentMuzzle _unit]; - // _data pushBack "stance"; - // _data pushBack [stance _unit]; - // }; if (isNull objectParent _unit) then { _data pushBack "currentWeapon"; _data pushBack [currentMuzzle _unit];