diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index 5c37862c7b..4a7b12a8c5 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -19,6 +19,10 @@ if (_currentVersion != _previousVersion) then { 0 spawn COMPILE_FILE(scripts\Version\checkVersionNumber); +//add network event handlers +"ACEg" addPublicVariableEventHandler { _this call FUNC(_handletNetEvent); }; +"ACEc" addPublicVariableEventHandler { _this call FUNC(_handletNetEvent); }; + // everything that only player controlled machines need, goes below this if (!hasInterface) exitWith {}; @@ -67,3 +71,5 @@ enableCamShake true; [_this select 1] call FUNC(setName) }; }] call FUNC(addCustomEventhandler); + + diff --git a/addons/common/XEH_preInit.sqf b/addons/common/XEH_preInit.sqf index 52ccdff4d4..57713d2611 100644 --- a/addons/common/XEH_preInit.sqf +++ b/addons/common/XEH_preInit.sqf @@ -137,6 +137,16 @@ PREP(showUser); PREP(addCuratorUnloadEventhandler); PREP(fixCrateContent); +//ACE events global variables +GVAR(netEvents) = [[],[]]; + +PREP(globalEvent); +PREP(_handleNetEvent); +PREP(addNetEventHandler); +PREP(targetEvent); +PREP(serverEvent); + + // Loop to update the ACE_player variable ACE_player = player; if (hasInterface) then { diff --git a/addons/common/functions/fnc__handleNetEvent.sqf b/addons/common/functions/fnc__handleNetEvent.sqf new file mode 100644 index 0000000000..37a8ce8e6e --- /dev/null +++ b/addons/common/functions/fnc__handleNetEvent.sqf @@ -0,0 +1,59 @@ +//fnc__handleNetEvent.sqf +// internal handler for net events +#include "script_component.hpp" + +private ["_eventType", "_event", "_eventName", "_eventArgs", "_eventNames", "_eventIndex", "_eventTargets", "_sentEvents", "_owner", "_serverFlagged"]; + +_eventType = _this select 0; +_event = _this select 1; + + +if(_eventType == "ACEg") then { + _eventName = _event select 0; + _eventArgs = _event select 1; + + _eventNames = GVAR(netEvents) select 0; + _eventIndex = _eventNames find _eventName; + if(_eventIndex != -1) then { + _events = (GVAR(netEvents) select 1) select _eventIndex; + { + if(!isNil "_x") then { + _eventArgs call CALLSTACK_NAMED(_x, format[ARR_3("Net Event %1 ID: %2",_eventName,_forEachIndex)]); + }; + } forEach _events; + }; +}; + +if(_eventType == "ACEc") then { + if(isServer) then { + _eventName = _event select 0; + _eventTargets = _event select 1; + _eventArgs = _event select 2; + + _sentEvents = []; + if(!IS_ARRAY(_eventTargets)) then { + _eventTargets = [_eventTargets]; + }; + _serverFlagged = false; + { + _owner = _x; + if(IS_OBJECT(_x)) then { + _owner = owner _x; + }; + if(!(_owner in _sentEvents)) then { + PUSH(_sentEvents, _owner); + ACEg = [_eventName, _eventArgs]; + if(isDedicated || {_x != ACE_player}) then { + if(isDedicated && {local _x} && {!_serverFlagged}) then { + _serverFlagged = true; + ["ACEg", ACEg] call FUNC(_handleNetEvent); + } else { + _owner publicVariableClient "ACEg"; + }; + } else { + ["ACEg", ACEg] call FUNC(_handleNetEvent); + }; + }; + } forEach _eventTargets; + }; +}; \ No newline at end of file diff --git a/addons/common/functions/fnc_addNetEventHandler.sqf b/addons/common/functions/fnc_addNetEventHandler.sqf new file mode 100644 index 0000000000..1a6160e93c --- /dev/null +++ b/addons/common/functions/fnc_addNetEventHandler.sqf @@ -0,0 +1,32 @@ +/* + * Author: Nou + * + * Add a network event handler. + * + * Argument: + * 0: Event name (string) + * 1: Event code (code) + * + * Return value: + * Event handler ID number (for use with fnc_removeNetEventHandler) + */ +#include "script_component.hpp" +private ["_eventName", "_eventCode", "_eventNames", "_eventFunctions", "_eventNameCount", "_eventIndex", "_eventFunctionCount"]; +_eventName = _this select 0; +_eventCode = _this select 1; + +_eventNames = GVAR(netEvents) select 0; +_eventFunctions = []; +_eventIndex = _eventNames find _eventName; +if(_eventIndex != -1) then { + _eventFunctions = (GVAR(netEvents) select 1) select _eventIndex; +} else { + _eventNameCount = count _eventNames; + _eventNames set[_eventNameCount, _eventName]; + (GVAR(netEvents) select 1) set[_eventNameCount, _eventFunctions]; +}; + +_eventFunctionCount = count _eventFunctions; +_eventFunctions set[_eventFunctionCount, _eventCode]; + +_eventFunctionCount; \ No newline at end of file diff --git a/addons/common/functions/fnc_globalEvent.sqf b/addons/common/functions/fnc_globalEvent.sqf new file mode 100644 index 0000000000..dcf40261cf --- /dev/null +++ b/addons/common/functions/fnc_globalEvent.sqf @@ -0,0 +1,22 @@ +/* + * Author: Nou + * + * Execute a global event on all clients, including self. + * + * Argument: + * 0: Event name (string) + * 1: Event args (any) + * + * Return value: + * Nothing + */ +#include "script_component.hpp" +private ["_eventName", "_eventArgs"]; + +_eventName = _this select 0; +_eventArgs = _this select 1; + + +ACEg = [_eventName, _eventArgs]; +publicVariable "ACEg"; +["ACEg", ACEg] call FUNC(_handleNetEvent); \ No newline at end of file diff --git a/addons/common/functions/fnc_serverEvent.sqf b/addons/common/functions/fnc_serverEvent.sqf new file mode 100644 index 0000000000..5e7ba3f92b --- /dev/null +++ b/addons/common/functions/fnc_serverEvent.sqf @@ -0,0 +1,25 @@ +/* + * Author: Nou + * + * Execute a event only on the server. + * + * Argument: + * 0: Event name (string) + * 1: Event args (any) + * + * Return value: + * Nothing + */ +#include "script_component.hpp" +private ["_eventName", "_eventArgs"]; + +_eventName = _this select 0; +_eventArgs = _this select 1; + + +ACEg = [_eventName, _eventArgs]; +if(!isServer) then { + publicVariableServer "ACEg"; +} else { + ["ACEg", ACEg] call FUNC(_handleNetEvent); +}; diff --git a/addons/common/functions/fnc_targetEvent.sqf b/addons/common/functions/fnc_targetEvent.sqf new file mode 100644 index 0000000000..4984c3d720 --- /dev/null +++ b/addons/common/functions/fnc_targetEvent.sqf @@ -0,0 +1,29 @@ +/* + * Author: Nou + * + * Execute a event only on specific clients. + * + * Argument: + * 0: Event name (string) + * 1: Event targets (object or array of objects) + * 2: Event args (any) + * + * Note: If local executor is in list of targets, event will execute with + * network delay, and not immediatly. + * + * Return value: + * Nothing + */ +#include "script_component.hpp" +private ["_eventName", "_eventArgs", "_eventTargets"]; + +_eventName = _this select 0; +_eventTargets = _this select 1; +_eventArgs = _this select 2; + +ACEc = [_eventName, _eventTargets, _eventArgs]; +if(!isServer) then { + publicVariableServer "ACEc"; +} else { + ["ACEc", ACEc] call FUNC(_handleNetEvent); +}; \ No newline at end of file