diff --git a/addons/recorder/XEH_prep.sqf b/addons/recorder/XEH_prep.sqf index a967ea6..b9d7e5c 100644 --- a/addons/recorder/XEH_prep.sqf +++ b/addons/recorder/XEH_prep.sqf @@ -19,6 +19,7 @@ PREP(addUnitEventHandlers); PREP(eh_connected); PREP(eh_disconnected); PREP(eh_onUserAdminStateChanged); +PREP(eh_onUserSelectedPlayer); PREP(adminUIcontrol); PREP(eh_firedMan); diff --git a/addons/recorder/fnc_addEventMission.sqf b/addons/recorder/fnc_addEventMission.sqf index 6f85cfd..66934c6 100644 --- a/addons/recorder/fnc_addEventMission.sqf +++ b/addons/recorder/fnc_addEventMission.sqf @@ -53,6 +53,15 @@ if (isNil QEGVAR(EH,OnUserAdminStateChanged)) then { OCAPEXTLOG(["Initialized OnUserAdminStateChanged EH"]); }; +if (isNil QEGVAR(EH,OnUserSelectedPlayer)) then { + // Event Handler: OCAP_EH_OnUserSelectedPlayer + // Handle for the "OnUserSelectedPlayer" mission event handler. Fired when a player object is selected for user. Calls . + EGVAR(EH,OnUserSelectedPlayer) = addMissionEventHandler ["OnUserSelectedPlayer", { + _this call FUNC(eh_onUserSelectedPlayer); + }]; + OCAPEXTLOG(["Initialized OnUserSelectedPlayer EH"]); +}; + if (isNil QEGVAR(EH,EntityKilled)) then { // Event Handler: OCAP_EH_EntityKilled // Handle for the "EntityKilled" mission event handler. Fired when an entity is killed. Calls . diff --git a/addons/recorder/fnc_adminUIcontrol.sqf b/addons/recorder/fnc_adminUIcontrol.sqf index 2fb5774..6f3885f 100644 --- a/addons/recorder/fnc_adminUIcontrol.sqf +++ b/addons/recorder/fnc_adminUIcontrol.sqf @@ -6,8 +6,8 @@ Description: Runs checks to determine if a player should have the administrative diary entry added or removed upon joining the mission or logging in/out as admin. - - at mission start to determine if a player is in - to add/remove when a player logs in or out as admin on the server + - at mission start to determine if a player is in Parameters: _PID - PlayerID indicating unique network client on the server [String] diff --git a/addons/recorder/fnc_eh_connected.sqf b/addons/recorder/fnc_eh_connected.sqf index a0e8210..9cab6d3 100644 --- a/addons/recorder/fnc_eh_connected.sqf +++ b/addons/recorder/fnc_eh_connected.sqf @@ -7,8 +7,6 @@ This function uses the event handler to log "connected" events to the timeline. - It also calls to apply the admin UI if the player is in . - Parameters: See the wiki for details. @@ -40,6 +38,3 @@ if (_owner isEqualTo 2) exitWith {}; ["playerUid", _uid] ]] call CBA_fnc_encodeJSON ]] call EFUNC(extension,sendData); - -// trigger admin control check for all connecting players -[_idstr, "connect"] call FUNC(adminUIcontrol); diff --git a/addons/recorder/fnc_eh_onUserSelectedPlayer.sqf b/addons/recorder/fnc_eh_onUserSelectedPlayer.sqf new file mode 100644 index 0000000..533299d --- /dev/null +++ b/addons/recorder/fnc_eh_onUserSelectedPlayer.sqf @@ -0,0 +1,50 @@ +/* ---------------------------------------------------------------------------- + FILE: fnc_eh_onUserSelectedPlayer.sqf + + FUNCTION: OCAP_recorder_fnc_eh_onUserSelectedPlayer + + Description: + Uses to detect when someone joins the server. + + Calls to apply the admin UI if the player is in . + + Parameters: + _networkId - The network ID of the player who has logged in or out of the server [String] + _playerObject - player object to be controlled by the user [Object] + + Returns: + Nothing + + Examples: + > call FUNC(eh_onUserSelectedPlayer); + + Public: + No + + Author: + IndigoFox +---------------------------------------------------------------------------- */ +#include "script_component.hpp" + +params ["_networkId", "_playerObject"]; + +// For non-JIP players, OnUserSelectedPlayer fires between preInit and postInit. Since we're initializing in postInit, this function will be too late to handle non-JIP players. Admins in this case are handled by . +if (!isNull _playerObject) exitWith { + _playerObject addEventHandler ["Local", { + params ["_playerObject"]; + _playerObject removeEventHandler [_thisEvent, _thisEventHandler]; + + private _networkId = getPlayerID _playerObject; + [_networkId, "connect"] call FUNC(adminUIcontrol); + }]; +}; + +// In rare cases, _playerObject may be objNull despite Arma 3 v2.18 allowing the event to be postponed. +// Make a last ditch attempt to wait for the player object to be set (similar to ). +[{ + !isNull (getUserInfo _this param [10, objNull, [objNull]]) +}, { + [_this, "connect"] call FUNC(adminUIcontrol); +}, _networkId, 30, { + diag_log text format ["[OCAP] (recorder) WARNING: connecting player object is null for PID: %1", _this]; +}] call CBA_fnc_waitUntilAndExecute; diff --git a/addons/recorder/fnc_init.sqf b/addons/recorder/fnc_init.sqf index 78f6686..30e12bd 100644 --- a/addons/recorder/fnc_init.sqf +++ b/addons/recorder/fnc_init.sqf @@ -132,11 +132,10 @@ call FUNC(eh_fired_server); call FUNC(telemetryLoop); [] spawn FUNC(getStaticObjects); -// Check already-connected players for admin controls (fixes race condition -// where players connected before OCAP initialized don't get diary entries) +// Check non-JIP players for admin controls, as postInit is too late for to fire. // Wait for getUserInfo to be populated before calling, as it may not be ready during postInit { - private _pid = str owner _x; + private _pid = getPlayerID _x; [{ private _info = getUserInfo _this; !isNil "_info" && {_info isEqualType [] && {count _info >= 11}}