-
Notifications
You must be signed in to change notification settings - Fork 120
WIP: Headless broadcast #1105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
PabstMirror
wants to merge
4
commits into
master
Choose a base branch
from
headlessBroadcast
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
WIP: Headless broadcast #1105
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| idi\acre\addons\sys_headless |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| 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)); | ||
| }; | ||
| }; | ||
|
|
||
| class Extended_PostInit_EventHandlers { | ||
| class ADDON { | ||
| init = QUOTE(call COMPILE_FILE(XEH_postInit)); | ||
| }; | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| PREP(addRadio); | ||
| PREP(handleGetHeadlessID); | ||
| PREP(start); | ||
| PREP(stop); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| #include "script_component.hpp" | ||
|
|
||
| ["handleGetHeadlessID", { call FUNC(handleGetHeadlessID) }] call EFUNC(sys_rpc,addProcedure); | ||
| [QEGVAR(sys_radio,returnRadioId), { call FUNC(handleReturnRadioId) }] call CBA_fnc_addEventHandler; | ||
|
|
||
| if (hasInterface) then { | ||
| [ | ||
| {!isNull findDisplay 46}, | ||
| { | ||
| (findDisplay 46) displayAddEventHandler ["Unload", { | ||
| // Cleanup all headless ID's at mission end (or they will keep playing next mission, lol) | ||
| { | ||
| TRACE_1("RPC STOP: mission end",_x); | ||
| ["ext_remoteStopSpeaking", format ["%1,", _x]] call EFUNC(sys_rpc,callRemoteProcedure); | ||
| } forEach (missionNamespace getVariable [QGVAR(idsToCleanup), []]) | ||
| }]; | ||
| } | ||
| ] call CBA_fnc_waitUntilAndExecute; | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| #include "script_component.hpp" | ||
|
|
||
| ADDON = false; | ||
|
|
||
| PREP_RECOMPILE_START; | ||
| #include "XEH_PREP.hpp" | ||
| PREP_RECOMPILE_END; | ||
|
|
||
| ADDON = true; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| #include "script_component.hpp" | ||
|
|
||
| #include "XEH_PREP.hpp" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| #include "script_component.hpp" | ||
|
|
||
| class CfgPatches { | ||
| class ADDON { | ||
| name = COMPONENT_NAME; | ||
| units[] = {}; | ||
| weapons[] = {}; | ||
| requiredVersion = REQUIRED_VERSION; | ||
| requiredAddons[] = {"acre_sys_core"}; | ||
| author = ECSTRING(main,Author); | ||
| url = ECSTRING(main,URL); | ||
| VERSION_CONFIG; | ||
| }; | ||
| }; | ||
|
|
||
| #include "CfgEventHandlers.hpp" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| #include "script_component.hpp" | ||
| /* | ||
| * Author: ACRE2Team | ||
| * Adds a unique radio to a AI unit | ||
| * | ||
| * Arguments: | ||
| * 0: Unit <OBJECT> | ||
| * 1: Radio Base class <STRING> | ||
| * 2: Preset (optional) <STRING> | ||
| * | ||
| * Return Value: | ||
| * Added <BOOL> | ||
| * | ||
| * Example: | ||
| * [q2, "acre_prc343"] call acre_sys_headless_fnc_addRadio | ||
| * | ||
| * Public: No | ||
| */ | ||
| [{ | ||
| params ["_unit", "_radioBaseClass", ["_preset", "", [""]]]; | ||
| TRACE_3("addRadio",_unit,_radioBaseClass,_preset); | ||
|
|
||
| if (!isServer) exitWith { ERROR_1("only use on server - %1",_this); false }; | ||
| if (!alive _unit) exitWith { ERROR_1("bad unit - %1",_this); false }; | ||
| if (!([_radioBaseClass] call EFUNC(api,isBaseRadio))) exitWith { ERROR_1("bad radio - %1",_this); false }; | ||
| if (!([_unit, _radioBaseClass] call CBA_fnc_canAddItem)) exitWith { ERROR_1("cannot add radio - %1",_this); false }; | ||
|
|
||
| GVAR(newUniqueRadio) = ""; // Because this is all running on the server, this gvar will be set by the EH in-line | ||
|
|
||
| private _tempEH = [QEGVAR(sys_radio,returnRadioId), { | ||
| params ["_unit", "_class"]; | ||
| TRACE_2("returnRadioId tempEH",_unit,_class); | ||
| GVAR(newUniqueRadio) = _class; | ||
| }] call CBA_fnc_addEventHandler; | ||
|
|
||
| ["acre_getRadioId", [_unit, _radioBaseClass, QEGVAR(sys_radio,returnRadioId)]] call CBA_fnc_serverEvent; | ||
|
|
||
| TRACE_2("after getRadioID",_tempEH,GVAR(newUniqueRadio)); | ||
| [QEGVAR(sys_radio,returnRadioId), _tempEH] call CBA_fnc_removeEventHandler; | ||
|
|
||
| if (GVAR(newUniqueRadio) == "") exitWith { | ||
| ERROR_1("failed to get radio ID - %1",_this); | ||
| false | ||
| }; | ||
|
|
||
| _unit addItem GVAR(newUniqueRadio); | ||
|
|
||
| // initialize the new radio | ||
| if (_preset == "") then { | ||
| _preset = [_radioBaseClass] call EFUNC(sys_data,getRadioPresetName); | ||
| TRACE_2("got default preset",_radioBaseClass,_preset); | ||
| }; | ||
| [GVAR(newUniqueRadio), _preset] call EFUNC(sys_radio,initDefaultRadio); | ||
|
|
||
| ["acre_acknowledgeId", [GVAR(newUniqueRadio), _unit]] call CBA_fnc_serverEvent; | ||
|
|
||
| true | ||
| }, _this] call CBA_fnc_directCall; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| #include "script_component.hpp" | ||
| /* | ||
| * Author: ACRE2Team | ||
| * Get the alive player units matching the current channel. If global chat, all units are targeted. | ||
| * | ||
| * Arguments: | ||
| * None | ||
| * | ||
| * Return Value: | ||
| * Handled <BOOL> | ||
| * | ||
| * Example: | ||
| * ["1:2", "Botty", 499] call acre_sys_headless_fnc_handleGetHeadlessID | ||
| * | ||
| * Public: No | ||
| */ | ||
|
|
||
| params [["_netId","",[""]],["_targetName","",[""]],["_targetID","0",[""]]]; | ||
| TRACE_3("handleGetHeadlessID",_netId,_targetName,_targetID); | ||
|
|
||
| private _unit = objectFromNetId _netId; | ||
| if (isNull _unit) exitWith { | ||
| WARNING_1("null unit %1",_this); | ||
| }; | ||
| _targetID = parseNumber _targetID; | ||
| if (_targetID == 0) then { | ||
| WARNING_2("Cannot find TSID - Headless Unit [%1] DisplayName [%2]",_unit,_tsDisplayName); | ||
| }; | ||
|
|
||
| _unit setVariable [QGVAR(virtualID), _targetID]; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| #include "script_component.hpp" | ||
| /* | ||
| * Author: ACRE2Team | ||
| * Starts a unit speaking from a headless TS client | ||
| * Must be called on all clients | ||
| * | ||
| * Arguments: | ||
| * 0: Unit <OBJECT> | ||
| * 1: TS Display Name (name of a TS source inside the ACRE channel) <STRING> | ||
| * 2: Language Index <NUMBER> | ||
| * 3: Speaking Type (0 direct, 1 radio,...) <NUMBER> | ||
| * 4: Radio ID <STRING> | ||
| * | ||
| * Return Value: | ||
| * Started <BOOL> | ||
| * | ||
| * Example: | ||
| * [q2, "Botty", 0, 0, ""] call acre_sys_headless_fnc_start | ||
| * [q2, "Botty", 0, 1, "ACRE_PRC343_ID_2"] call acre_sys_headless_fnc_start | ||
| * | ||
| * Public: No | ||
| */ | ||
|
|
||
| if (!hasInterface) exitWith {}; | ||
|
|
||
| params ["_unit", "_tsDisplayName", "_languageId", "_speakingType", "_radioId"]; | ||
| TRACE_4("start",_unit,_tsName,_languageId,_speakingType,_radioId); | ||
|
|
||
| if (!alive _unit) exitWith { ERROR_1("bad unit",_this); false }; | ||
| if (!isNil {_unit getVariable [QGVAR(keepRunning), nil]}) exitWith { ERROR_1("unit is already active",_this); false }; | ||
|
|
||
| if (isNil QGVAR(idsToCleanup)) then { GVAR(idsToCleanup) = []; }; | ||
|
|
||
| private _netId = netId _unit; | ||
|
|
||
| // start getting tsId, won't have result until next frame+ | ||
| private _lastKnownId = 0; | ||
| _unit setVariable [QGVAR(virtualID), _lastKnownId]; | ||
| ["getHeadlessID", [_netId, _tsDisplayName]] call EFUNC(sys_rpc,callRemoteProcedure); | ||
|
|
||
| _unit setVariable [QGVAR(keepRunning), true]; | ||
|
|
||
| [{ | ||
| params ["_args", "_pfid"]; | ||
| _args params ["_unit", "_tsDisplayName", "_lastKnownId", "_languageId", "_netId", "_speakingType", "_radioID"]; | ||
| private _currentId = _unit getVariable [QGVAR(virtualID), 0]; | ||
| private _isSpeaking = [_unit] call EFUNC(api,isSpeaking); | ||
| private _keepRunning = (_unit getVariable [QGVAR(keepRunning), false]) && {alive _unit}; | ||
| TRACE_5("tick",_unit,_lastKnownId,_currentId,_isSpeaking,_keepRunning); | ||
|
|
||
| if ((_lastKnownId == 0) && {_currentId != 0}) then { | ||
| // When we first get a new valid ID, Ensure bot is not currently in plugin's speakingList (just in case it was never cleared) | ||
| TRACE_1("RPC STOP: reset on new ID",_currentId); | ||
| [ | ||
| "ext_remoteStopSpeaking", | ||
| format ["%1,", _currentId] | ||
| ] call EFUNC(sys_rpc,callRemoteProcedure); | ||
| }; | ||
| if (_isSpeaking) then { | ||
| // Handle client TS closed / pipe error - Need to manually do sqf-stopspeaking to remove from speakers list | ||
| if (!EGVAR(sys_io,serverStarted)) then { | ||
| TRACE_2("manual sqf stopspeaking: plugin problems",_currentId,_keepRunning); | ||
| _currentId = 0; | ||
| [str _lastKnownId, _netId] call EFUNC(sys_core,remoteStopSpeaking); | ||
| }; | ||
| // Normal shutdown or we lost tsID (bot disconnect) | ||
| if ((!_keepRunning) || {_currentId == 0}) then { | ||
| TRACE_2("RPC STOP: shutdown or bad ID",_keepRunning,_currentId); | ||
| [ | ||
| "ext_remoteStopSpeaking", | ||
| format ["%1,", _lastKnownId] | ||
| ] call EFUNC(sys_rpc,callRemoteProcedure); | ||
| }; | ||
| } else { | ||
| if (_keepRunning && {_currentId != 0}) then { | ||
| TRACE_1("RPC START: normal",_currentId); | ||
| [ | ||
| "ext_remoteStartSpeaking", | ||
| format ["%1,%2,%3,%4,%5,%6,", _currentId, _languageId, _netId, _speakingType, _radioId, 1] | ||
| ] call EFUNC(sys_rpc,callRemoteProcedure); | ||
| }; | ||
| }; | ||
| _args set [2, _currentId]; | ||
| if (_currentId !=0) then { GVAR(idsToCleanup) pushBackUnique _currentId; }; | ||
|
|
||
| if (_keepRunning) then { | ||
| // Keep checking ID, this handles a bot disconnecting and reconnecting under a different ID | ||
| ["getHeadlessID", [_netId, _tsDisplayName]] call EFUNC(sys_rpc,callRemoteProcedure); | ||
| } else { | ||
| TRACE_1("pfeh stop",_this); | ||
| [_pfid] call CBA_fnc_removePerFrameHandler; | ||
| _unit setVariable [QGVAR(keepRunning), nil]; | ||
| }; | ||
| }, 0.5, [_unit, _tsDisplayName, _lastKnownId, _languageId, _netID, _speakingType, _radioId]] call CBA_fnc_addPerFrameHandler; | ||
|
|
||
| true | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,25 @@ | ||||||
| #include "script_component.hpp" | ||||||
| /* | ||||||
| * Author: ACRE2Team | ||||||
| * Stops a unit speaking from a headless TS client | ||||||
| * | ||||||
| * Arguments: | ||||||
| * 0: Unit <OBJECT> | ||||||
| * | ||||||
| * Return Value: | ||||||
| * None | ||||||
| * | ||||||
| * Example: | ||||||
| * [q2] call acre_sys_headless_fnc_stop | ||||||
| * | ||||||
| * Public: No | ||||||
| */ | ||||||
| if (!hasInterface) exitWith {}; | ||||||
|
|
||||||
| params ["_unit"]; | ||||||
| TRACE_1("stop"_unit); | ||||||
|
|
||||||
| if (isNil {_unit getVariable [QGVAR(keepRunning), nil]}) exitWith { ERROR_1("unit is not active",_this); }; | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Likewise this could be simplified:
Suggested change
|
||||||
|
|
||||||
| // Won't have immediete effects, will shutdown at next PFEH interval | ||||||
| _unit setVariable [QGVAR(keepRunning), false]; | ||||||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| #define COMPONENT sys_headless | ||
| #define COMPONENT_BEAUTIFIED Headless | ||
| #include "\idi\acre\addons\main\script_mod.hpp" | ||
|
|
||
| // #define DEBUG_MODE_FULL | ||
| // #define DISABLE_COMPILE_CACHE | ||
| // #define ENABLE_PERFORMANCE_COUNTERS | ||
|
|
||
| #include "\idi\acre\addons\main\script_macros.hpp" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| #pragma once | ||
| #include "Engine.h" | ||
| #include "IRpcFunction.h" | ||
| #include "IServer.h" | ||
| #include "Log.h" | ||
| #include "TextMessage.h" | ||
|
|
||
| RPC_FUNCTION(getHeadlessID) { | ||
| const std::string netId{reinterpret_cast<const char *const>(vMessage->getParameter(0))}; | ||
| const std::string targetName{reinterpret_cast<const char *const>(vMessage->getParameter(1))}; | ||
|
|
||
| // try to get ID from the displayName by searching the clientList (0 indicates not found) | ||
| const acre::id_t targetID = CEngine::getInstance()->getClient()->getClientIDByName(targetName); | ||
|
|
||
| vServer->sendMessage(CTextMessage::formatNewMessage("handleGetHeadlessID", "%s,%s,%d,", netId.c_str(), targetName.c_str(), targetID)); | ||
| return acre::Result::ok; | ||
| } | ||
|
|
||
| public: | ||
| inline void setName(const char *const value) final { | ||
| m_Name = value; | ||
| } | ||
| inline const char *getName() const final { | ||
| return m_Name; | ||
| } | ||
|
|
||
| protected: | ||
| const char *m_Name; | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As of 'Arma 3' 2.18, the nil check could be simplified: