1
0
Fork 0
mirror of https://github.com/hawkeye-stan/msfs-popout-panel-manager.git synced 2024-11-22 05:40:11 +00:00
msfs-popout-panel-manager/SimconnectAgent/SimConnector.cs

631 lines
25 KiB
C#
Raw Permalink Normal View History

2022-07-23 19:23:32 +00:00
using Microsoft.FlightSimulator.SimConnect;
using MSFSPopoutPanelManager.Shared;
using System;
using System.Collections.Generic;
using System.Diagnostics;
2023-07-12 22:41:31 +00:00
using System.Reflection;
2022-08-13 06:14:49 +00:00
using System.Threading.Tasks;
2022-07-23 19:23:32 +00:00
using System.Timers;
2023-07-30 21:30:47 +00:00
using static MSFSPopoutPanelManager.SimConnectAgent.SimDataDefinitions;
2022-07-23 19:23:32 +00:00
namespace MSFSPopoutPanelManager.SimConnectAgent
{
public class SimConnector
{
private const int MSFS_CONNECTION_RETRY_TIMEOUT = 2000;
2023-07-12 22:41:31 +00:00
private const uint WM_USER_SIMCONNECT = 0x0402;
2022-07-23 19:23:32 +00:00
private SimConnect _simConnect;
private Timer _connectionTimer;
2022-08-13 06:14:49 +00:00
private bool _isDisabledReconnect;
2022-07-23 19:23:32 +00:00
2024-02-28 02:44:21 +00:00
private readonly List<SimConnectDataDefinition> _simConnectRequiredDataDefinitions = SimDataDefinitions.GetRequiredDefinitions();
2024-03-14 22:50:32 +00:00
private readonly List<SimConnectDataDefinition> _simConnectDynamicLodDataDefinitions = SimDataDefinitions.GetDynamicLodDefinitions();
2023-07-12 22:41:31 +00:00
private List<SimConnectDataDefinition> _simConnectHudBarDataDefinitions;
2024-02-28 02:44:21 +00:00
private readonly FieldInfo[] _simConnectStructFields = typeof(SimConnectStruct).GetFields(BindingFlags.Public | BindingFlags.Instance);
2023-07-12 22:41:31 +00:00
2022-07-23 19:23:32 +00:00
public event EventHandler<string> OnException;
2023-07-12 22:41:31 +00:00
public event EventHandler<List<SimDataItem>> OnReceivedRequiredData;
public event EventHandler<List<SimDataItem>> OnReceivedHudBarData;
2024-03-14 22:50:32 +00:00
public event EventHandler<List<SimDataItem>> OnReceivedDynamicLodData;
2022-07-23 19:23:32 +00:00
public event EventHandler OnConnected;
public event EventHandler OnDisconnected;
2023-07-12 22:41:31 +00:00
public event EventHandler<SimConnectEvent> OnReceiveSystemEvent;
2024-03-14 22:50:32 +00:00
public event EventHandler<int> OnReceivedEventFrameData;
2023-07-12 22:41:31 +00:00
public event EventHandler<string> OnActiveAircraftChanged;
2022-07-23 19:23:32 +00:00
public bool Connected { get; set; }
public void Start()
{
2024-02-28 02:44:21 +00:00
_connectionTimer = new()
{
Interval = MSFS_CONNECTION_RETRY_TIMEOUT,
Enabled = true
};
_connectionTimer.Elapsed += (_, _) =>
2022-07-23 19:23:32 +00:00
{
try
{
2023-07-12 22:41:31 +00:00
Debug.WriteLine("Connecting to MSFS...");
2022-07-23 19:23:32 +00:00
InitializeSimConnect();
}
catch
{
// handle SimConnect instantiation error when MSFS is not connected
}
};
}
public void Restart()
{
_connectionTimer.Enabled = true;
}
2023-07-12 22:41:31 +00:00
public void SetSimConnectHudBarDataDefinition(SimDataDefinitionType definitionType)
{
_simConnectHudBarDataDefinitions = SimDataDefinitions.GetHudBarDefinitions(definitionType);
AddHudBarDataDefinitions();
}
2024-03-14 22:50:32 +00:00
public void SetSimConnectDynamicLodDataDefinition()
{
AddDynamicLodDataDefinitions();
}
2022-07-23 19:23:32 +00:00
private void HandleOnRecvOpen(SimConnect sender, SIMCONNECT_RECV_OPEN data)
{
ReceiveMessage();
}
public void StopAndReconnect()
{
2024-02-28 02:44:21 +00:00
if (_isDisabledReconnect)
return;
Stop();
InitializeSimConnect();
2022-07-23 19:23:32 +00:00
}
public void Stop()
{
2024-02-28 02:44:21 +00:00
_simConnect = null;
2022-07-23 19:23:32 +00:00
Connected = false;
}
2023-07-12 22:41:31 +00:00
public void RequestRequiredData()
2022-07-23 19:23:32 +00:00
{
if (_simConnect == null || !Connected)
return;
2023-07-12 22:41:31 +00:00
try
{
2024-02-28 02:44:21 +00:00
_simConnect.RequestDataOnSimObjectType(DataRequest.REQUIRED_REQUEST, DataDefinition.REQUIRED_DEFINITION, 0, SIMCONNECT_SIMOBJECT_TYPE.USER);
2023-07-12 22:41:31 +00:00
}
catch
2022-07-23 19:23:32 +00:00
{
2023-07-12 22:41:31 +00:00
if (!_isDisabledReconnect)
_isDisabledReconnect = true;
OnException?.Invoke(this, null);
}
}
public void RequestHudBarData()
{
if (_simConnect == null || !Connected)
return;
try
{
if (_simConnectHudBarDataDefinitions != null)
2024-02-28 02:44:21 +00:00
_simConnect.RequestDataOnSimObjectType(DataRequest.HUDBAR_REQUEST, DataDefinition.HUDBAR_DEFINITION, 0, SIMCONNECT_SIMOBJECT_TYPE.USER);
2023-07-12 22:41:31 +00:00
}
catch
{
if (!_isDisabledReconnect)
_isDisabledReconnect = true;
OnException?.Invoke(this, null);
2022-07-23 19:23:32 +00:00
}
}
2024-03-14 22:50:32 +00:00
public void RequestDynamicLodData()
{
if (_simConnect == null || !Connected)
return;
try
{
if (_simConnectDynamicLodDataDefinitions != null)
_simConnect.RequestDataOnSimObjectType(DataRequest.DYNAMICLOD_REQUEST, DataDefinition.DYNAMICLOD_DEFINITION, 0, SIMCONNECT_SIMOBJECT_TYPE.USER);
}
catch
{
if (!_isDisabledReconnect)
_isDisabledReconnect = true;
OnException?.Invoke(this, null);
}
}
2022-07-23 19:23:32 +00:00
public void ReceiveMessage()
{
if (_simConnect == null)
return;
try
{
2022-08-13 06:14:49 +00:00
if (!_isDisabledReconnect)
_simConnect.ReceiveMessage();
2022-07-23 19:23:32 +00:00
}
catch (Exception ex)
{
if (ex.Message != "0xC00000B0")
{
FileLogger.WriteLog($"SimConnector: SimConnect receive message exception - {ex.Message}", StatusMessageType.Error);
2022-08-13 06:14:49 +00:00
}
2022-07-23 19:23:32 +00:00
2022-08-13 06:14:49 +00:00
if (!_isDisabledReconnect)
{
// Prevent multiple reconnects from running
_isDisabledReconnect = true;
2023-07-12 22:41:31 +00:00
OnException?.Invoke(this, null);
2022-07-23 19:23:32 +00:00
}
}
}
2024-02-28 02:44:21 +00:00
public void TransmitActionEvent(ActionEvent eventId, uint data)
2022-07-23 19:23:32 +00:00
{
if (_simConnect != null)
{
try
{
2024-02-28 02:44:21 +00:00
_simConnect.TransmitClientEvent(0U, eventId, data, NotificationGroup.GROUP0, SIMCONNECT_EVENT_FLAG.GROUPID_IS_PRIORITY);
2023-07-12 22:41:31 +00:00
System.Threading.Thread.Sleep(200);
2022-07-23 19:23:32 +00:00
}
catch (Exception ex)
{
2024-02-28 02:44:21 +00:00
var eventName = eventId.ToString()[4..]; // trim out KEY_ prefix
2022-07-23 19:23:32 +00:00
FileLogger.WriteLog($"SimConnector: SimConnect transmit event exception - EventName: {eventName} - {ex.Message}", StatusMessageType.Error);
}
}
}
2024-02-28 02:44:21 +00:00
public void SetDataObject(WritableVariableName propName, object dValue)
2022-07-23 19:23:32 +00:00
{
2023-07-12 22:41:31 +00:00
try
2022-07-23 19:23:32 +00:00
{
2024-02-28 02:44:21 +00:00
if (_simConnect == null)
return;
var dataStruct = new WritableDataStruct
{
Prop0 = (double)dValue
};
2023-07-12 22:41:31 +00:00
2023-07-30 21:30:47 +00:00
switch (propName)
{
2024-02-28 02:44:21 +00:00
case WritableVariableName.TrackIREnable:
_simConnect.SetDataOnSimObject(DataDefinition.WRITABLE_TRACK_IR_DEFINITION, SimConnect.SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_DATA_SET_FLAG.DEFAULT, dataStruct);
break;
case WritableVariableName.CockpitCameraZoom:
_simConnect.SetDataOnSimObject(DataDefinition.WRITABLE_COCKPIT_CAMERA_ZOOM_DEFINITION, SimConnect.SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_DATA_SET_FLAG.DEFAULT, dataStruct);
2023-07-30 21:30:47 +00:00
break;
2024-02-29 00:54:25 +00:00
case WritableVariableName.CameraState:
_simConnect.SetDataOnSimObject(DataDefinition.WRITABLE_COCKPIT_CAMERA_STATE_DEFINITION, SimConnect.SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_DATA_SET_FLAG.DEFAULT, dataStruct);
break;
2024-02-28 02:44:21 +00:00
case WritableVariableName.CameraRequestAction:
_simConnect.SetDataOnSimObject(DataDefinition.WRITABLE_CAMERA_REQUEST_ACTION_DEFINITION, SimConnect.SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_DATA_SET_FLAG.DEFAULT, dataStruct);
2023-07-30 21:30:47 +00:00
break;
2024-02-28 02:44:21 +00:00
case WritableVariableName.CameraViewTypeAndIndex0:
_simConnect.SetDataOnSimObject(DataDefinition.WRITABLE_CAMERA_VIEW_TYPE_INDEX_0_DEFINITION, SimConnect.SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_DATA_SET_FLAG.DEFAULT, dataStruct);
break;
case WritableVariableName.CameraViewTypeAndIndex1:
_simConnect.SetDataOnSimObject(DataDefinition.WRITABLE_CAMERA_VIEW_TYPE_INDEX_1_DEFINITION, SimConnect.SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_DATA_SET_FLAG.DEFAULT, dataStruct);
2023-08-16 03:41:14 +00:00
break;
2023-07-30 21:30:47 +00:00
}
2023-07-12 22:41:31 +00:00
}
catch (Exception ex)
{
FileLogger.WriteLog($"SimConnector: Unable to set SimConnect variable - {ex.Message}", StatusMessageType.Error);
2022-07-23 19:23:32 +00:00
}
}
2024-03-14 22:50:32 +00:00
public void StartReceiveFrameData()
{
if (_simConnect == null)
return;
_simConnect.OnRecvEventFrame -= HandleOnRecvEventFrame;
_simConnect.OnRecvEventFrame += HandleOnRecvEventFrame;
_simConnect.UnsubscribeFromSystemEvent(SimConnectEvent.FRAME);
_simConnect.SubscribeToSystemEvent(SimConnectEvent.FRAME, "Frame");
}
public void StopReceiveFrameData()
{
_simConnect.OnRecvEventFrame -= HandleOnRecvEventFrame;
_simConnect.UnsubscribeFromSystemEvent(SimConnectEvent.FRAME);
}
2022-07-23 19:23:32 +00:00
private void InitializeSimConnect()
{
2023-07-12 22:41:31 +00:00
Debug.WriteLine("Trying to start simConnect");
2022-07-23 19:23:32 +00:00
_simConnect = new SimConnect("MSFS Pop Out Panel Manager", Process.GetCurrentProcess().MainWindowHandle, WM_USER_SIMCONNECT, null, 0);
2023-07-12 22:41:31 +00:00
Debug.WriteLine("SimConnect started");
2022-07-23 19:23:32 +00:00
_connectionTimer.Enabled = false;
2024-02-28 02:44:21 +00:00
// Listen to connect and quit messages
2022-07-23 19:23:32 +00:00
_simConnect.OnRecvOpen += HandleOnRecvOpen;
_simConnect.OnRecvQuit += HandleOnRecvQuit;
_simConnect.OnRecvException += HandleOnRecvException;
_simConnect.OnRecvEvent += HandleOnReceiveSystemEvent;
2024-02-28 02:44:21 +00:00
_simConnect.OnRecvSimobjectDataBytype += HandleOnRecvSimObjectDataByType;
2022-08-01 23:21:42 +00:00
_simConnect.OnRecvEventFilename += HandleOnRecvEventFilename;
2022-08-02 15:51:28 +00:00
_simConnect.OnRecvSystemState += HandleOnRecvSystemState;
2022-07-23 19:23:32 +00:00
// Register simConnect system events
2024-02-28 02:44:21 +00:00
_simConnect.UnsubscribeFromSystemEvent(SimConnectEvent.SIM_START);
_simConnect.SubscribeToSystemEvent(SimConnectEvent.SIM_START, "SimStart");
_simConnect.UnsubscribeFromSystemEvent(SimConnectEvent.SIM_STOP);
_simConnect.SubscribeToSystemEvent(SimConnectEvent.SIM_STOP, "SimStop");
2023-07-12 22:41:31 +00:00
_simConnect.UnsubscribeFromSystemEvent(SimConnectEvent.VIEW);
_simConnect.SubscribeToSystemEvent(SimConnectEvent.VIEW, "View");
2024-02-28 02:44:21 +00:00
_simConnect.UnsubscribeFromSystemEvent(SimConnectEvent.AIRCRAFT_LOADED);
_simConnect.SubscribeToSystemEvent(SimConnectEvent.AIRCRAFT_LOADED, "AircraftLoaded");
2024-03-14 22:50:32 +00:00
2023-07-12 22:41:31 +00:00
AddRequiredDataDefinitions();
SetupActionEvents();
2022-07-23 19:23:32 +00:00
2024-02-28 02:44:21 +00:00
_simConnect.RequestSystemState(SystemStateRequestId.AIRCRAFT_PATH, "AircraftLoaded");
2022-08-02 15:51:28 +00:00
2022-08-13 06:14:49 +00:00
_isDisabledReconnect = false;
Task.Run(() =>
{
for (var i = 0; i < 5; i++)
{
System.Threading.Thread.Sleep(1000);
ReceiveMessage();
}
});
2024-02-28 02:44:21 +00:00
OnConnected?.Invoke(this, EventArgs.Empty);
2022-08-13 06:14:49 +00:00
Connected = true;
2022-07-23 19:23:32 +00:00
}
2024-03-14 22:50:32 +00:00
private void HandleOnRecvEventFrame(SimConnect sender, SIMCONNECT_RECV_EVENT_FRAME data)
{
if (data == null)
return;
OnReceivedEventFrameData?.Invoke(this, Convert.ToInt32(data.fFrameRate));
}
2022-08-02 15:51:28 +00:00
private void HandleOnRecvSystemState(SimConnect sender, SIMCONNECT_RECV_SYSTEM_STATE data)
{
switch ((SystemStateRequestId)Enum.Parse(typeof(SystemStateRequestId), data.dwRequestID.ToString()))
{
2024-02-28 02:44:21 +00:00
case SystemStateRequestId.AIRCRAFT_PATH:
2022-08-02 15:51:28 +00:00
SetActiveAircraftTitle(data.szString);
break;
}
}
2022-08-01 23:21:42 +00:00
private void HandleOnRecvEventFilename(SimConnect sender, SIMCONNECT_RECV_EVENT_FILENAME data)
{
switch (data.uEventID)
{
2024-02-28 02:44:21 +00:00
case (uint)SimConnectEvent.AIRCRAFT_LOADED:
2022-08-02 15:51:28 +00:00
SetActiveAircraftTitle(data.szFileName);
2022-08-01 23:21:42 +00:00
break;
}
}
2023-07-12 22:41:31 +00:00
private void SetupActionEvents()
2022-07-23 19:23:32 +00:00
{
2023-07-12 22:41:31 +00:00
foreach (ActionEvent item in Enum.GetValues(typeof(ActionEvent)))
{
_simConnect.MapClientEventToSimEvent(item, item.ToString());
}
}
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
private void AddRequiredDataDefinitions()
{
if (_simConnect == null || _simConnectRequiredDataDefinitions == null)
return;
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
foreach (var definition in _simConnectRequiredDataDefinitions)
2022-07-23 19:23:32 +00:00
{
2024-02-28 02:44:21 +00:00
if (definition.DefinitionId != DataDefinition.REQUIRED_DEFINITION ||
definition.DataDefinitionType != DataDefinitionType.SimConnect) continue;
2022-08-01 23:21:42 +00:00
2024-02-28 02:44:21 +00:00
SIMCONNECT_DATATYPE simConnectDataType;
switch (definition.DataType)
{
case DataType.String:
simConnectDataType = SIMCONNECT_DATATYPE.STRING256;
break;
case DataType.Float64:
simConnectDataType = SIMCONNECT_DATATYPE.FLOAT64;
break;
default:
simConnectDataType = SIMCONNECT_DATATYPE.FLOAT64;
break;
2023-07-12 22:41:31 +00:00
}
2022-08-01 23:21:42 +00:00
2024-02-28 02:44:21 +00:00
_simConnect.AddToDataDefinition(definition.DefinitionId, definition.VariableName, definition.SimConnectUnit, simConnectDataType, 0.0f, SimConnect.SIMCONNECT_UNUSED);
}
2022-08-01 23:21:42 +00:00
2024-02-28 02:44:21 +00:00
_simConnect.AddToDataDefinition(DataDefinition.WRITABLE_TRACK_IR_DEFINITION, "TRACK IR ENABLE", "bool", SIMCONNECT_DATATYPE.FLOAT64, 0.0f, SimConnect.SIMCONNECT_UNUSED);
2024-02-29 00:54:25 +00:00
_simConnect.AddToDataDefinition(DataDefinition.WRITABLE_COCKPIT_CAMERA_STATE_DEFINITION, "CAMERA STATE", "enum", SIMCONNECT_DATATYPE.FLOAT64, 0.0f, SimConnect.SIMCONNECT_UNUSED);
2024-02-28 02:44:21 +00:00
_simConnect.AddToDataDefinition(DataDefinition.WRITABLE_COCKPIT_CAMERA_ZOOM_DEFINITION, "COCKPIT CAMERA ZOOM", "percentage", SIMCONNECT_DATATYPE.FLOAT64, 0.0f, SimConnect.SIMCONNECT_UNUSED);
_simConnect.AddToDataDefinition(DataDefinition.WRITABLE_CAMERA_REQUEST_ACTION_DEFINITION, "CAMERA REQUEST ACTION", "enum", SIMCONNECT_DATATYPE.FLOAT64, 0.0f, SimConnect.SIMCONNECT_UNUSED);
_simConnect.AddToDataDefinition(DataDefinition.WRITABLE_CAMERA_VIEW_TYPE_INDEX_0_DEFINITION, "CAMERA VIEW TYPE AND INDEX:0", "number", SIMCONNECT_DATATYPE.FLOAT64, 0.0f, SimConnect.SIMCONNECT_UNUSED);
_simConnect.AddToDataDefinition(DataDefinition.WRITABLE_CAMERA_VIEW_TYPE_INDEX_1_DEFINITION, "CAMERA VIEW TYPE AND INDEX:1", "number", SIMCONNECT_DATATYPE.FLOAT64, 0.0f, SimConnect.SIMCONNECT_UNUSED);
_simConnect.RegisterDataDefineStruct<SimConnectStruct>(DataDefinition.REQUIRED_DEFINITION);
_simConnect.RegisterDataDefineStruct<SimConnectStruct>(DataDefinition.WRITABLE_TRACK_IR_DEFINITION);
2024-02-29 00:54:25 +00:00
_simConnect.RegisterDataDefineStruct<SimConnectStruct>(DataDefinition.WRITABLE_COCKPIT_CAMERA_STATE_DEFINITION);
2024-02-28 02:44:21 +00:00
_simConnect.RegisterDataDefineStruct<SimConnectStruct>(DataDefinition.WRITABLE_COCKPIT_CAMERA_ZOOM_DEFINITION);
_simConnect.RegisterDataDefineStruct<SimConnectStruct>(DataDefinition.WRITABLE_CAMERA_VIEW_TYPE_INDEX_0_DEFINITION);
_simConnect.RegisterDataDefineStruct<SimConnectStruct>(DataDefinition.WRITABLE_CAMERA_VIEW_TYPE_INDEX_1_DEFINITION);
2023-07-12 22:41:31 +00:00
}
2022-08-01 23:21:42 +00:00
2023-07-12 22:41:31 +00:00
private void AddHudBarDataDefinitions()
{
if (_simConnect == null)
return;
2022-07-23 19:23:32 +00:00
2024-02-28 02:44:21 +00:00
_simConnect.ClearDataDefinition(DataDefinition.HUDBAR_DEFINITION);
2023-07-12 22:41:31 +00:00
if (_simConnectHudBarDataDefinitions == null)
return;
foreach (var definition in _simConnectHudBarDataDefinitions)
2022-07-23 19:23:32 +00:00
{
2024-02-28 02:44:21 +00:00
if (definition.DefinitionId != DataDefinition.HUDBAR_DEFINITION ||
definition.DataDefinitionType != DataDefinitionType.SimConnect) continue;
2023-07-12 22:41:31 +00:00
2024-02-28 02:44:21 +00:00
SIMCONNECT_DATATYPE simConnectDataType;
switch (definition.DataType)
{
case DataType.String:
simConnectDataType = SIMCONNECT_DATATYPE.STRING256;
break;
case DataType.Float64:
simConnectDataType = SIMCONNECT_DATATYPE.FLOAT64;
break;
default:
simConnectDataType = SIMCONNECT_DATATYPE.FLOAT64;
break;
2023-07-12 22:41:31 +00:00
}
2024-02-28 02:44:21 +00:00
_simConnect.AddToDataDefinition(definition.DefinitionId, definition.VariableName, definition.SimConnectUnit, simConnectDataType, 0.0f, SimConnect.SIMCONNECT_UNUSED);
2022-07-23 19:23:32 +00:00
}
2023-07-12 22:41:31 +00:00
2024-02-28 02:44:21 +00:00
_simConnect.RegisterDataDefineStruct<SimConnectStruct>(DataDefinition.HUDBAR_DEFINITION);
2022-07-23 19:23:32 +00:00
}
2024-03-14 22:50:32 +00:00
private void AddDynamicLodDataDefinitions()
{
if (_simConnect == null)
return;
_simConnect.ClearDataDefinition(DataDefinition.DYNAMICLOD_DEFINITION);
if (_simConnectDynamicLodDataDefinitions == null)
return;
foreach (var definition in _simConnectDynamicLodDataDefinitions)
{
if (definition.DefinitionId != DataDefinition.DYNAMICLOD_DEFINITION ||
definition.DataDefinitionType != DataDefinitionType.SimConnect) continue;
SIMCONNECT_DATATYPE simConnectDataType;
switch (definition.DataType)
{
case DataType.String:
simConnectDataType = SIMCONNECT_DATATYPE.STRING256;
break;
case DataType.Float64:
simConnectDataType = SIMCONNECT_DATATYPE.FLOAT64;
break;
default:
simConnectDataType = SIMCONNECT_DATATYPE.FLOAT64;
break;
}
_simConnect.AddToDataDefinition(definition.DefinitionId, definition.VariableName, definition.SimConnectUnit, simConnectDataType, 0.0f, SimConnect.SIMCONNECT_UNUSED);
}
_simConnect.RegisterDataDefineStruct<SimConnectStruct>(DataDefinition.DYNAMICLOD_DEFINITION);
}
2022-07-23 19:23:32 +00:00
private void HandleOnRecvQuit(SimConnect sender, SIMCONNECT_RECV data)
{
Stop();
2024-02-28 02:44:21 +00:00
OnDisconnected?.Invoke(this, EventArgs.Empty);
2022-07-23 19:23:32 +00:00
}
private void HandleOnRecvException(SimConnect sender, SIMCONNECT_RECV_EXCEPTION data)
{
2024-02-28 02:44:21 +00:00
var e = (SIMCONNECT_EXCEPTION)data.dwException;
2022-07-23 19:23:32 +00:00
switch (e)
{
case SIMCONNECT_EXCEPTION.DATA_ERROR:
case SIMCONNECT_EXCEPTION.NAME_UNRECOGNIZED:
case SIMCONNECT_EXCEPTION.ALREADY_CREATED:
case SIMCONNECT_EXCEPTION.UNRECOGNIZED_ID:
case SIMCONNECT_EXCEPTION.EVENT_ID_DUPLICATE:
break;
default:
2024-02-28 02:44:21 +00:00
OnException?.Invoke(this, $"SimConnector: SimConnect on receive exception - {e}");
2022-07-23 19:23:32 +00:00
break;
}
}
2023-07-12 22:41:31 +00:00
private void HandleOnReceiveSystemEvent(SimConnect sender, SIMCONNECT_RECV_EVENT data)
{
var systemEvent = ((SimConnectEvent)data.uEventID);
OnReceiveSystemEvent?.Invoke(this, systemEvent);
}
2024-02-28 02:44:21 +00:00
private void HandleOnRecvSimObjectDataByType(SimConnect sender, SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE data)
2022-07-23 19:23:32 +00:00
{
2023-07-12 22:41:31 +00:00
if (_simConnect == null || !Connected)
return;
2024-02-28 02:44:21 +00:00
switch (data.dwRequestID)
{
case (int)DataRequest.REQUIRED_REQUEST:
ParseRequiredReceivedSimData(data);
break;
case (int)DataRequest.HUDBAR_REQUEST:
ParseHudBarReceivedSimData(data);
break;
2024-03-14 22:50:32 +00:00
case (int)DataRequest.DYNAMICLOD_REQUEST:
ParseDynamicLodReceivedSimData(data);
break;
2024-02-28 02:44:21 +00:00
}
2023-07-12 22:41:31 +00:00
}
private void ParseRequiredReceivedSimData(SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE data)
{
if (_simConnectRequiredDataDefinitions == null)
2022-07-23 19:23:32 +00:00
return;
try
{
2023-07-12 22:41:31 +00:00
var simData = new List<SimDataItem>();
var simDataStruct = (SimConnectStruct)data.dwData[0];
2024-02-28 02:44:21 +00:00
var i = 0;
2023-07-12 22:41:31 +00:00
foreach (var definition in _simConnectRequiredDataDefinitions)
2022-07-23 19:23:32 +00:00
{
2024-02-28 02:44:21 +00:00
if (definition.DataDefinitionType != DataDefinitionType.SimConnect)
continue;
var dataValue = _simConnectStructFields[i].GetValue(simDataStruct);
var simDataItem = new SimDataItem
2022-07-23 19:23:32 +00:00
{
2024-02-28 02:44:21 +00:00
PropertyName = definition.PropName,
Value = dataValue == null ? 0 : (double)dataValue
};
simData.Add(simDataItem);
i++;
2022-07-23 19:23:32 +00:00
}
2023-07-12 22:41:31 +00:00
OnReceivedRequiredData?.Invoke(this, simData);
2022-07-23 19:23:32 +00:00
}
catch (Exception ex)
{
2023-07-12 22:41:31 +00:00
FileLogger.WriteException($"SimConnector: SimConnect received required data exception - {ex.Message}", ex);
2022-07-23 19:23:32 +00:00
}
}
2023-07-12 22:41:31 +00:00
private void ParseHudBarReceivedSimData(SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE data)
2022-07-23 19:23:32 +00:00
{
2023-07-12 22:41:31 +00:00
try
{
if (_simConnectHudBarDataDefinitions == null)
return;
var simData = new List<SimDataItem>();
var simDataStruct = (SimConnectStruct)data.dwData[0];
2024-02-28 02:44:21 +00:00
var i = 0;
2023-07-12 22:41:31 +00:00
lock (_simConnectHudBarDataDefinitions)
{
foreach (var definition in _simConnectHudBarDataDefinitions)
{
2024-02-28 02:44:21 +00:00
if (definition.DataDefinitionType != DataDefinitionType.SimConnect)
continue;
var dataValue = _simConnectStructFields[i].GetValue(simDataStruct);
var simDataItem = new SimDataItem
2023-07-12 22:41:31 +00:00
{
2024-02-28 02:44:21 +00:00
PropertyName = definition.PropName,
Value = dataValue == null ? 0 : (double)dataValue
};
simData.Add(simDataItem);
i++;
2023-07-12 22:41:31 +00:00
}
}
OnReceivedHudBarData?.Invoke(this, simData);
}
catch (Exception ex)
{
FileLogger.WriteException($"SimConnector: SimConnect received hud bar data exception - {ex.Message}", ex);
StopAndReconnect();
}
2022-07-23 19:23:32 +00:00
}
2022-08-02 15:51:28 +00:00
2024-03-14 22:50:32 +00:00
private void ParseDynamicLodReceivedSimData(SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE data)
{
try
{
if (_simConnectDynamicLodDataDefinitions == null)
return;
var simData = new List<SimDataItem>();
var simDataStruct = (SimConnectStruct)data.dwData[0];
var i = 0;
lock (_simConnectDynamicLodDataDefinitions)
{
foreach (var definition in _simConnectDynamicLodDataDefinitions)
{
if (definition.DataDefinitionType != DataDefinitionType.SimConnect)
continue;
var dataValue = _simConnectStructFields[i].GetValue(simDataStruct);
var simDataItem = new SimDataItem
{
PropertyName = definition.PropName,
Value = dataValue == null ? 0 : (double)dataValue
};
simData.Add(simDataItem);
i++;
}
}
OnReceivedDynamicLodData?.Invoke(this, simData);
}
catch (Exception ex)
{
FileLogger.WriteException($"SimConnector: SimConnect received dynamic lod data exception - {ex.Message}", ex);
StopAndReconnect();
}
}
2022-08-02 15:51:28 +00:00
private void SetActiveAircraftTitle(string aircraftFilePath)
{
var filePathToken = aircraftFilePath.Split(@"\");
2022-08-13 06:14:49 +00:00
if (filePathToken.Length > 1)
{
2024-02-28 02:44:21 +00:00
var aircraftName = filePathToken[^2];
2022-08-13 06:14:49 +00:00
aircraftName = aircraftName.Replace("_", " ").ToUpper();
2023-07-12 22:41:31 +00:00
OnActiveAircraftChanged?.Invoke(this, aircraftName);
2022-08-13 06:14:49 +00:00
}
2022-08-02 15:51:28 +00:00
}
2022-07-23 19:23:32 +00:00
}
}