Proof of concept command-line version
This commit is contained in:
parent
cc93415ffc
commit
a3cb0eb7ca
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
DesignTimeBuild
|
||||
bin
|
||||
obj
|
||||
packages
|
||||
|
||||
*.suo
|
||||
*.user
|
71
FSFlightLogger.sln
Normal file
71
FSFlightLogger.sln
Normal file
@ -0,0 +1,71 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30413.136
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FSFlightLogger", "FSFlightLogger\FSFlightLogger.csproj", "{5871FA9B-88A7-4F98-8755-2FC48D4DBF44}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimConnectUnitTests", "SimConnectUnitTests\SimConnectUnitTests.csproj", "{2CD97D07-EF26-4CDA-A090-DF3D698E7F60}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FSFlightLoggerCmd", "FSFlightLoggerCmd\FSFlightLoggerCmd.csproj", "{767C7EAA-9230-4DEE-89FA-9699288C831B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlightLoggerLib", "FlightLoggerLib\FlightLoggerLib.csproj", "{D85BCC97-F653-4286-98D9-073A33A55857}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimConnect", "SimConnect\SimConnect.csproj", "{F160BB6A-7620-41E5-A99C-948C208875E4}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{5871FA9B-88A7-4F98-8755-2FC48D4DBF44}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{5871FA9B-88A7-4F98-8755-2FC48D4DBF44}.Debug|x64.Build.0 = Debug|x64
|
||||
{5871FA9B-88A7-4F98-8755-2FC48D4DBF44}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{5871FA9B-88A7-4F98-8755-2FC48D4DBF44}.Debug|x86.Build.0 = Debug|x86
|
||||
{5871FA9B-88A7-4F98-8755-2FC48D4DBF44}.Release|x64.ActiveCfg = Release|x64
|
||||
{5871FA9B-88A7-4F98-8755-2FC48D4DBF44}.Release|x64.Build.0 = Release|x64
|
||||
{5871FA9B-88A7-4F98-8755-2FC48D4DBF44}.Release|x86.ActiveCfg = Release|x86
|
||||
{5871FA9B-88A7-4F98-8755-2FC48D4DBF44}.Release|x86.Build.0 = Release|x86
|
||||
{2CD97D07-EF26-4CDA-A090-DF3D698E7F60}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{2CD97D07-EF26-4CDA-A090-DF3D698E7F60}.Debug|x64.Build.0 = Debug|x64
|
||||
{2CD97D07-EF26-4CDA-A090-DF3D698E7F60}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{2CD97D07-EF26-4CDA-A090-DF3D698E7F60}.Debug|x86.Build.0 = Debug|x86
|
||||
{2CD97D07-EF26-4CDA-A090-DF3D698E7F60}.Release|x64.ActiveCfg = Release|x64
|
||||
{2CD97D07-EF26-4CDA-A090-DF3D698E7F60}.Release|x64.Build.0 = Release|x64
|
||||
{2CD97D07-EF26-4CDA-A090-DF3D698E7F60}.Release|x86.ActiveCfg = Release|x86
|
||||
{2CD97D07-EF26-4CDA-A090-DF3D698E7F60}.Release|x86.Build.0 = Release|x86
|
||||
{767C7EAA-9230-4DEE-89FA-9699288C831B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{767C7EAA-9230-4DEE-89FA-9699288C831B}.Debug|x64.Build.0 = Debug|x64
|
||||
{767C7EAA-9230-4DEE-89FA-9699288C831B}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{767C7EAA-9230-4DEE-89FA-9699288C831B}.Debug|x86.Build.0 = Debug|x86
|
||||
{767C7EAA-9230-4DEE-89FA-9699288C831B}.Release|x64.ActiveCfg = Release|x64
|
||||
{767C7EAA-9230-4DEE-89FA-9699288C831B}.Release|x64.Build.0 = Release|x64
|
||||
{767C7EAA-9230-4DEE-89FA-9699288C831B}.Release|x86.ActiveCfg = Release|x86
|
||||
{767C7EAA-9230-4DEE-89FA-9699288C831B}.Release|x86.Build.0 = Release|x86
|
||||
{D85BCC97-F653-4286-98D9-073A33A55857}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D85BCC97-F653-4286-98D9-073A33A55857}.Debug|x64.Build.0 = Debug|x64
|
||||
{D85BCC97-F653-4286-98D9-073A33A55857}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{D85BCC97-F653-4286-98D9-073A33A55857}.Debug|x86.Build.0 = Debug|x86
|
||||
{D85BCC97-F653-4286-98D9-073A33A55857}.Release|x64.ActiveCfg = Release|x64
|
||||
{D85BCC97-F653-4286-98D9-073A33A55857}.Release|x64.Build.0 = Release|x64
|
||||
{D85BCC97-F653-4286-98D9-073A33A55857}.Release|x86.ActiveCfg = Release|x86
|
||||
{D85BCC97-F653-4286-98D9-073A33A55857}.Release|x86.Build.0 = Release|x86
|
||||
{F160BB6A-7620-41E5-A99C-948C208875E4}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F160BB6A-7620-41E5-A99C-948C208875E4}.Debug|x64.Build.0 = Debug|x64
|
||||
{F160BB6A-7620-41E5-A99C-948C208875E4}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{F160BB6A-7620-41E5-A99C-948C208875E4}.Debug|x86.Build.0 = Debug|x86
|
||||
{F160BB6A-7620-41E5-A99C-948C208875E4}.Release|x64.ActiveCfg = Release|x64
|
||||
{F160BB6A-7620-41E5-A99C-948C208875E4}.Release|x64.Build.0 = Release|x64
|
||||
{F160BB6A-7620-41E5-A99C-948C208875E4}.Release|x86.ActiveCfg = Release|x86
|
||||
{F160BB6A-7620-41E5-A99C-948C208875E4}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {427083A8-FC16-46A5-9DD7-FB805B89A26A}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
9
FSFlightLogger.sln.DotSettings
Normal file
9
FSFlightLogger.sln.DotSettings
Normal file
@ -0,0 +1,9 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LINES/@EntryValue">False</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DLL/@EntryIndexedValue">DLL</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=KML/@EntryIndexedValue">KML</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=XYZ/@EntryIndexedValue">XYZ</s:String>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
6
FSFlightLogger/App.config
Normal file
6
FSFlightLogger/App.config
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
|
||||
</startup>
|
||||
</configuration>
|
124
FSFlightLogger/FSFlightLogger.csproj
Normal file
124
FSFlightLogger/FSFlightLogger.csproj
Normal file
@ -0,0 +1,124 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{5871FA9B-88A7-4F98-8755-2FC48D4DBF44}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>FSFlightLogger</RootNamespace>
|
||||
<AssemblyName>FSFlightLogger</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.1.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SimpleInjector, Version=5.0.0.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SimpleInjector.5.0.3\lib\net461\SimpleInjector.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="MainForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="MainForm.Designer.cs">
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="MainForm.resx">
|
||||
<DependentUpon>MainForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="SimConnect\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SimConnect\SimConnect.csproj">
|
||||
<Project>{f160bb6a-7620-41e5-a99c-948c208875e4}</Project>
|
||||
<Name>SimConnect</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
313
FSFlightLogger/MainForm.Designer.cs
generated
Normal file
313
FSFlightLogger/MainForm.Designer.cs
generated
Normal file
@ -0,0 +1,313 @@
|
||||
namespace FSFlightLogger
|
||||
{
|
||||
partial class MainForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
|
||||
this.OutputGroupbox = new System.Windows.Forms.GroupBox();
|
||||
this.StatusImageList = new System.Windows.Forms.ImageList(this.components);
|
||||
this.FlightSimulatorStatusIcon = new System.Windows.Forms.PictureBox();
|
||||
this.FlightSimulatorLabel = new System.Windows.Forms.Label();
|
||||
this.FlightSimulatorStatusLabel = new System.Windows.Forms.Label();
|
||||
this.RecordButton = new System.Windows.Forms.Button();
|
||||
this.RecordingStatusIcon = new System.Windows.Forms.PictureBox();
|
||||
this.OutputCSVCheckbox = new System.Windows.Forms.CheckBox();
|
||||
this.OutputKMLCheckbox = new System.Windows.Forms.CheckBox();
|
||||
this.OutputCSVPathTextbox = new System.Windows.Forms.TextBox();
|
||||
this.OutputCSVPathLabel = new System.Windows.Forms.Label();
|
||||
this.OutputCSVPathBrowseButton = new System.Windows.Forms.Button();
|
||||
this.OutputKMLPathBrowseButton = new System.Windows.Forms.Button();
|
||||
this.OutputKMLPathLabel = new System.Windows.Forms.Label();
|
||||
this.OutputKMLPathTextbox = new System.Windows.Forms.TextBox();
|
||||
this.TriggersGroupbox = new System.Windows.Forms.GroupBox();
|
||||
this.TriggerWaitForMovementCheckbox = new System.Windows.Forms.CheckBox();
|
||||
this.TriggerNewLogStationaryCheckbox = new System.Windows.Forms.CheckBox();
|
||||
this.TriggerNewLogStationaryTimeEdit = new System.Windows.Forms.NumericUpDown();
|
||||
this.TriggerNewLogStationaryUnitsLabel = new System.Windows.Forms.Label();
|
||||
this.OutputGroupbox.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.FlightSimulatorStatusIcon)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.RecordingStatusIcon)).BeginInit();
|
||||
this.TriggersGroupbox.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.TriggerNewLogStationaryTimeEdit)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// OutputGroupbox
|
||||
//
|
||||
this.OutputGroupbox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.OutputGroupbox.Controls.Add(this.OutputKMLPathBrowseButton);
|
||||
this.OutputGroupbox.Controls.Add(this.OutputKMLPathLabel);
|
||||
this.OutputGroupbox.Controls.Add(this.OutputKMLPathTextbox);
|
||||
this.OutputGroupbox.Controls.Add(this.OutputCSVPathBrowseButton);
|
||||
this.OutputGroupbox.Controls.Add(this.OutputCSVPathLabel);
|
||||
this.OutputGroupbox.Controls.Add(this.OutputCSVPathTextbox);
|
||||
this.OutputGroupbox.Controls.Add(this.OutputKMLCheckbox);
|
||||
this.OutputGroupbox.Controls.Add(this.OutputCSVCheckbox);
|
||||
this.OutputGroupbox.Location = new System.Drawing.Point(12, 59);
|
||||
this.OutputGroupbox.Name = "OutputGroupbox";
|
||||
this.OutputGroupbox.Size = new System.Drawing.Size(482, 136);
|
||||
this.OutputGroupbox.TabIndex = 0;
|
||||
this.OutputGroupbox.TabStop = false;
|
||||
this.OutputGroupbox.Text = " Output ";
|
||||
//
|
||||
// StatusImageList
|
||||
//
|
||||
this.StatusImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("StatusImageList.ImageStream")));
|
||||
this.StatusImageList.TransparentColor = System.Drawing.Color.Transparent;
|
||||
this.StatusImageList.Images.SetKeyName(0, "Idle");
|
||||
this.StatusImageList.Images.SetKeyName(1, "Recording");
|
||||
this.StatusImageList.Images.SetKeyName(2, "FSDisconnected");
|
||||
this.StatusImageList.Images.SetKeyName(3, "FSConnected");
|
||||
//
|
||||
// FlightSimulatorStatusIcon
|
||||
//
|
||||
this.FlightSimulatorStatusIcon.Location = new System.Drawing.Point(12, 12);
|
||||
this.FlightSimulatorStatusIcon.Name = "FlightSimulatorStatusIcon";
|
||||
this.FlightSimulatorStatusIcon.Size = new System.Drawing.Size(32, 32);
|
||||
this.FlightSimulatorStatusIcon.TabIndex = 1;
|
||||
this.FlightSimulatorStatusIcon.TabStop = false;
|
||||
//
|
||||
// FlightSimulatorLabel
|
||||
//
|
||||
this.FlightSimulatorLabel.AutoSize = true;
|
||||
this.FlightSimulatorLabel.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.FlightSimulatorLabel.Location = new System.Drawing.Point(50, 9);
|
||||
this.FlightSimulatorLabel.Name = "FlightSimulatorLabel";
|
||||
this.FlightSimulatorLabel.Size = new System.Drawing.Size(133, 21);
|
||||
this.FlightSimulatorLabel.TabIndex = 2;
|
||||
this.FlightSimulatorLabel.Text = "Flight Simulator";
|
||||
//
|
||||
// FlightSimulatorStatusLabel
|
||||
//
|
||||
this.FlightSimulatorStatusLabel.AutoSize = true;
|
||||
this.FlightSimulatorStatusLabel.Location = new System.Drawing.Point(51, 31);
|
||||
this.FlightSimulatorStatusLabel.Name = "FlightSimulatorStatusLabel";
|
||||
this.FlightSimulatorStatusLabel.Size = new System.Drawing.Size(70, 13);
|
||||
this.FlightSimulatorStatusLabel.TabIndex = 3;
|
||||
this.FlightSimulatorStatusLabel.Text = "Connecting...";
|
||||
//
|
||||
// RecordButton
|
||||
//
|
||||
this.RecordButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.RecordButton.Enabled = false;
|
||||
this.RecordButton.Location = new System.Drawing.Point(348, 17);
|
||||
this.RecordButton.Name = "RecordButton";
|
||||
this.RecordButton.Size = new System.Drawing.Size(108, 23);
|
||||
this.RecordButton.TabIndex = 4;
|
||||
this.RecordButton.Text = "&Start recording";
|
||||
this.RecordButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// RecordingStatusIcon
|
||||
//
|
||||
this.RecordingStatusIcon.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.RecordingStatusIcon.Location = new System.Drawing.Point(462, 12);
|
||||
this.RecordingStatusIcon.Name = "RecordingStatusIcon";
|
||||
this.RecordingStatusIcon.Size = new System.Drawing.Size(32, 32);
|
||||
this.RecordingStatusIcon.TabIndex = 5;
|
||||
this.RecordingStatusIcon.TabStop = false;
|
||||
//
|
||||
// OutputCSVCheckbox
|
||||
//
|
||||
this.OutputCSVCheckbox.AutoSize = true;
|
||||
this.OutputCSVCheckbox.Location = new System.Drawing.Point(10, 23);
|
||||
this.OutputCSVCheckbox.Name = "OutputCSVCheckbox";
|
||||
this.OutputCSVCheckbox.Size = new System.Drawing.Size(141, 17);
|
||||
this.OutputCSVCheckbox.TabIndex = 0;
|
||||
this.OutputCSVCheckbox.Text = "Comma-separated (CSV)";
|
||||
this.OutputCSVCheckbox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// OutputKMLCheckbox
|
||||
//
|
||||
this.OutputKMLCheckbox.AutoSize = true;
|
||||
this.OutputKMLCheckbox.Location = new System.Drawing.Point(10, 79);
|
||||
this.OutputKMLCheckbox.Name = "OutputKMLCheckbox";
|
||||
this.OutputKMLCheckbox.Size = new System.Drawing.Size(119, 17);
|
||||
this.OutputKMLCheckbox.TabIndex = 1;
|
||||
this.OutputKMLCheckbox.Text = "Google Earth (KML)";
|
||||
this.OutputKMLCheckbox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// OutputCSVPathTextbox
|
||||
//
|
||||
this.OutputCSVPathTextbox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.OutputCSVPathTextbox.Enabled = false;
|
||||
this.OutputCSVPathTextbox.Location = new System.Drawing.Point(71, 46);
|
||||
this.OutputCSVPathTextbox.Name = "OutputCSVPathTextbox";
|
||||
this.OutputCSVPathTextbox.Size = new System.Drawing.Size(373, 20);
|
||||
this.OutputCSVPathTextbox.TabIndex = 2;
|
||||
//
|
||||
// OutputCSVPathLabel
|
||||
//
|
||||
this.OutputCSVPathLabel.AutoSize = true;
|
||||
this.OutputCSVPathLabel.Location = new System.Drawing.Point(26, 49);
|
||||
this.OutputCSVPathLabel.Name = "OutputCSVPathLabel";
|
||||
this.OutputCSVPathLabel.Size = new System.Drawing.Size(32, 13);
|
||||
this.OutputCSVPathLabel.TabIndex = 3;
|
||||
this.OutputCSVPathLabel.Text = "Path:";
|
||||
//
|
||||
// OutputCSVPathBrowseButton
|
||||
//
|
||||
this.OutputCSVPathBrowseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.OutputCSVPathBrowseButton.Enabled = false;
|
||||
this.OutputCSVPathBrowseButton.Location = new System.Drawing.Point(448, 46);
|
||||
this.OutputCSVPathBrowseButton.Name = "OutputCSVPathBrowseButton";
|
||||
this.OutputCSVPathBrowseButton.Size = new System.Drawing.Size(28, 20);
|
||||
this.OutputCSVPathBrowseButton.TabIndex = 4;
|
||||
this.OutputCSVPathBrowseButton.Text = "...";
|
||||
this.OutputCSVPathBrowseButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// OutputKMLPathBrowseButton
|
||||
//
|
||||
this.OutputKMLPathBrowseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.OutputKMLPathBrowseButton.Enabled = false;
|
||||
this.OutputKMLPathBrowseButton.Location = new System.Drawing.Point(448, 102);
|
||||
this.OutputKMLPathBrowseButton.Name = "OutputKMLPathBrowseButton";
|
||||
this.OutputKMLPathBrowseButton.Size = new System.Drawing.Size(28, 20);
|
||||
this.OutputKMLPathBrowseButton.TabIndex = 7;
|
||||
this.OutputKMLPathBrowseButton.Text = "...";
|
||||
this.OutputKMLPathBrowseButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// OutputKMLPathLabel
|
||||
//
|
||||
this.OutputKMLPathLabel.AutoSize = true;
|
||||
this.OutputKMLPathLabel.Location = new System.Drawing.Point(26, 105);
|
||||
this.OutputKMLPathLabel.Name = "OutputKMLPathLabel";
|
||||
this.OutputKMLPathLabel.Size = new System.Drawing.Size(32, 13);
|
||||
this.OutputKMLPathLabel.TabIndex = 6;
|
||||
this.OutputKMLPathLabel.Text = "Path:";
|
||||
//
|
||||
// OutputKMLPathTextbox
|
||||
//
|
||||
this.OutputKMLPathTextbox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.OutputKMLPathTextbox.Enabled = false;
|
||||
this.OutputKMLPathTextbox.Location = new System.Drawing.Point(71, 102);
|
||||
this.OutputKMLPathTextbox.Name = "OutputKMLPathTextbox";
|
||||
this.OutputKMLPathTextbox.Size = new System.Drawing.Size(373, 20);
|
||||
this.OutputKMLPathTextbox.TabIndex = 5;
|
||||
//
|
||||
// TriggersGroupbox
|
||||
//
|
||||
this.TriggersGroupbox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.TriggersGroupbox.Controls.Add(this.TriggerNewLogStationaryUnitsLabel);
|
||||
this.TriggersGroupbox.Controls.Add(this.TriggerNewLogStationaryTimeEdit);
|
||||
this.TriggersGroupbox.Controls.Add(this.TriggerNewLogStationaryCheckbox);
|
||||
this.TriggersGroupbox.Controls.Add(this.TriggerWaitForMovementCheckbox);
|
||||
this.TriggersGroupbox.Location = new System.Drawing.Point(12, 201);
|
||||
this.TriggersGroupbox.Name = "TriggersGroupbox";
|
||||
this.TriggersGroupbox.Size = new System.Drawing.Size(482, 99);
|
||||
this.TriggersGroupbox.TabIndex = 6;
|
||||
this.TriggersGroupbox.TabStop = false;
|
||||
this.TriggersGroupbox.Text = " Triggers ";
|
||||
//
|
||||
// TriggerWaitForMovementCheckbox
|
||||
//
|
||||
this.TriggerWaitForMovementCheckbox.AutoSize = true;
|
||||
this.TriggerWaitForMovementCheckbox.Checked = true;
|
||||
this.TriggerWaitForMovementCheckbox.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.TriggerWaitForMovementCheckbox.Location = new System.Drawing.Point(10, 23);
|
||||
this.TriggerWaitForMovementCheckbox.Name = "TriggerWaitForMovementCheckbox";
|
||||
this.TriggerWaitForMovementCheckbox.Size = new System.Drawing.Size(454, 17);
|
||||
this.TriggerWaitForMovementCheckbox.TabIndex = 0;
|
||||
this.TriggerWaitForMovementCheckbox.Text = " Wait for movement before logging the starting point (recommended, ignores initia" +
|
||||
"l teleports)";
|
||||
this.TriggerWaitForMovementCheckbox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// TriggerNewLogStationaryCheckbox
|
||||
//
|
||||
this.TriggerNewLogStationaryCheckbox.AutoSize = true;
|
||||
this.TriggerNewLogStationaryCheckbox.Location = new System.Drawing.Point(10, 46);
|
||||
this.TriggerNewLogStationaryCheckbox.Name = "TriggerNewLogStationaryCheckbox";
|
||||
this.TriggerNewLogStationaryCheckbox.Size = new System.Drawing.Size(353, 17);
|
||||
this.TriggerNewLogStationaryCheckbox.TabIndex = 1;
|
||||
this.TriggerNewLogStationaryCheckbox.Text = " Start a new log when stationary for at least (excluding when paused):";
|
||||
this.TriggerNewLogStationaryCheckbox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// TriggerNewLogStationaryTimeEdit
|
||||
//
|
||||
this.TriggerNewLogStationaryTimeEdit.Enabled = false;
|
||||
this.TriggerNewLogStationaryTimeEdit.Location = new System.Drawing.Point(33, 69);
|
||||
this.TriggerNewLogStationaryTimeEdit.Name = "TriggerNewLogStationaryTimeEdit";
|
||||
this.TriggerNewLogStationaryTimeEdit.Size = new System.Drawing.Size(78, 20);
|
||||
this.TriggerNewLogStationaryTimeEdit.TabIndex = 2;
|
||||
this.TriggerNewLogStationaryTimeEdit.Value = new decimal(new int[] {
|
||||
30,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// TriggerNewLogStationaryUnitsLabel
|
||||
//
|
||||
this.TriggerNewLogStationaryUnitsLabel.AutoSize = true;
|
||||
this.TriggerNewLogStationaryUnitsLabel.Location = new System.Drawing.Point(117, 71);
|
||||
this.TriggerNewLogStationaryUnitsLabel.Name = "TriggerNewLogStationaryUnitsLabel";
|
||||
this.TriggerNewLogStationaryUnitsLabel.Size = new System.Drawing.Size(47, 13);
|
||||
this.TriggerNewLogStationaryUnitsLabel.TabIndex = 3;
|
||||
this.TriggerNewLogStationaryUnitsLabel.Text = "seconds";
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(506, 309);
|
||||
this.Controls.Add(this.TriggersGroupbox);
|
||||
this.Controls.Add(this.RecordingStatusIcon);
|
||||
this.Controls.Add(this.RecordButton);
|
||||
this.Controls.Add(this.FlightSimulatorStatusLabel);
|
||||
this.Controls.Add(this.FlightSimulatorLabel);
|
||||
this.Controls.Add(this.FlightSimulatorStatusIcon);
|
||||
this.Controls.Add(this.OutputGroupbox);
|
||||
this.Name = "MainForm";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "FS Flight Logger";
|
||||
this.OutputGroupbox.ResumeLayout(false);
|
||||
this.OutputGroupbox.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.FlightSimulatorStatusIcon)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.RecordingStatusIcon)).EndInit();
|
||||
this.TriggersGroupbox.ResumeLayout(false);
|
||||
this.TriggersGroupbox.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.TriggerNewLogStationaryTimeEdit)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.GroupBox OutputGroupbox;
|
||||
private System.Windows.Forms.Button OutputKMLPathBrowseButton;
|
||||
private System.Windows.Forms.Label OutputKMLPathLabel;
|
||||
private System.Windows.Forms.TextBox OutputKMLPathTextbox;
|
||||
private System.Windows.Forms.Button OutputCSVPathBrowseButton;
|
||||
private System.Windows.Forms.Label OutputCSVPathLabel;
|
||||
private System.Windows.Forms.TextBox OutputCSVPathTextbox;
|
||||
private System.Windows.Forms.CheckBox OutputKMLCheckbox;
|
||||
private System.Windows.Forms.CheckBox OutputCSVCheckbox;
|
||||
private System.Windows.Forms.ImageList StatusImageList;
|
||||
private System.Windows.Forms.PictureBox FlightSimulatorStatusIcon;
|
||||
private System.Windows.Forms.Label FlightSimulatorLabel;
|
||||
private System.Windows.Forms.Label FlightSimulatorStatusLabel;
|
||||
private System.Windows.Forms.Button RecordButton;
|
||||
private System.Windows.Forms.PictureBox RecordingStatusIcon;
|
||||
private System.Windows.Forms.GroupBox TriggersGroupbox;
|
||||
private System.Windows.Forms.Label TriggerNewLogStationaryUnitsLabel;
|
||||
private System.Windows.Forms.NumericUpDown TriggerNewLogStationaryTimeEdit;
|
||||
private System.Windows.Forms.CheckBox TriggerNewLogStationaryCheckbox;
|
||||
private System.Windows.Forms.CheckBox TriggerWaitForMovementCheckbox;
|
||||
}
|
||||
}
|
||||
|
49
FSFlightLogger/MainForm.cs
Normal file
49
FSFlightLogger/MainForm.cs
Normal file
@ -0,0 +1,49 @@
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Forms.VisualStyles;
|
||||
using SimConnect;
|
||||
|
||||
namespace FSFlightLogger
|
||||
{
|
||||
public partial class MainForm : Form
|
||||
{
|
||||
private readonly ISimConnectClientFactory simConnectClientFactory;
|
||||
|
||||
|
||||
public MainForm(ISimConnectClientFactory simConnectClientFactory)
|
||||
{
|
||||
this.simConnectClientFactory = simConnectClientFactory;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
SetFlightSimulatorConnected(false);
|
||||
SetRecording(false);
|
||||
//var simConnectClient = simConnectClientFactory.TryConnect("FS Flight Logger");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
components?.Dispose();
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
|
||||
private void SetFlightSimulatorConnected(bool connected)
|
||||
{
|
||||
FlightSimulatorStatusIcon.Image = StatusImageList.Images[connected ? "FSConnected" : "FSDisconnected"];
|
||||
}
|
||||
|
||||
private void SetRecording(bool recording)
|
||||
{
|
||||
RecordingStatusIcon.Image = StatusImageList.Images[recording ? "Recording" : "Idle"];
|
||||
}
|
||||
}
|
||||
}
|
474
FSFlightLogger/MainForm.resx
Normal file
474
FSFlightLogger/MainForm.resx
Normal file
@ -0,0 +1,474 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="StatusImageList.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<data name="StatusImageList.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>
|
||||
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
|
||||
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
|
||||
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACO
|
||||
UAAAAk1TRnQBSQFMAgEBBAEAAQgBAAEIAQABIAEAASABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAGA
|
||||
AwABQAMAAQEBAAEgBgABgP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A
|
||||
/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A
|
||||
/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8AfgADPAFJA3QBlwOGAcIDiwHZA4sB3AOLAdwDjAHaA4YBwwN0
|
||||
AZgDPQFLAwEBAlQAAjwBOwFJAXMBcgFzAZcBfAF7AYgBwgF1AXQBlQHZAXIBcAGYAdwBcgFwAZgB3AF3
|
||||
AXYBlQHaAXwBewGIAcMCcgFzAZgCPQE8AUsDAQECMAADAQECAwQEBQEHAwUBBwMFAQcDBQEHAwUBBwMF
|
||||
AQcDBQEHAwUBBwMFAQcDBQEHAwUBBwMFAQcDBQEHAwUBBwMFAQcDBQEHAwUBBwMFAQcDBQEHAwUBBwMF
|
||||
AQcDBQEHAwUBBwMFAQcDAwEEAwABARAAAwIBAwMHAQkDCgENAwoBDgMKAQ4DCgEOAwoBDgMKAQ4DCgEO
|
||||
AwoBDgMKAQ4DCgEOAwoBDgMKAQ4DCgEOAwoBDgMKAQ4DCgEOAwoBDgMKAQ4DCgEOAwoBDgMKAQ4DCgEO
|
||||
AwoBDgMKAQ0DBgEIAwEBAigAAw0BEANzAZYDhgHfA4cB/wOEAf8DhAH/A4sB/wOQAf8DkAH/A4sB/wOE
|
||||
Af8DgwH/A4YB/wOGAeQDdQGbAw8BE0AAAw0BEAJyAXABlgFoAWcBlQHfAUYBRQG0Af8COQG6Af8BMAEx
|
||||
AcMB/wExATMB0QH/ATUBNwHYAf8BNQE3AdgB/wExATMB0QH/AjABwgH/AjgBuQH/AUUBRAGzAf8BZwFm
|
||||
AZYB5AJ0AXEBmwMPARMnAAEBAwYBCAMQARUDGAEiAx4BKwMeASwDHgEsAx4BLAMeASwDHgEsAx4BLAMe
|
||||
ASwDHgEsAx4BLAMeASwDHgEsAx4BLAMeASwDHgEsAx4BLAMeASwDHgEsAx4BLAMeASwDHgEsAx4BKwMX
|
||||
ASADDgETAwQBBg8AAQEDCwEPAxwBKQErAikBRAEyAi8BVgEyAi8BVwEyAi8BVwEyATABLwFXATMBMAEv
|
||||
AVcBMwEwAS8BVwEzATABLwFXATMCLwFXATMCLwFXATMCLwFXATMCLwFXATMCLwFXATMCLwFXATMCLwFX
|
||||
ATMCLwFXATMBMAEvAVcBMwEwAS8BVwEzATABLwFXATMBMAEvAVcBMgIvAVcBMgIvAVcBMgEwAS8BVgEp
|
||||
AScBKAFAARsCGgEmAwkBDCQAA14BdgOJAekDeQH/A4YB/wOdAf8DqgH/A7UB/wO6Af8DvQH/A70B/wO5
|
||||
Af8DtAH/A6oB/wOdAf8DhgH/A3cB/wOJAe8DYQF8OAACXwFcAXYCZwGcAekBLgEtAbAB/wEnASgBzwH/
|
||||
AUIBRQHnAf8BVgFcAfAB/wFlAXAB9wH/AW4BfgH6Af8BdAGGAfsB/wFzAYYB+wH/AW0BfAH6Af8BZAFu
|
||||
AfcB/wFVAVwB8AH/AUIBRQHnAf8BJwEoAc8B/wIsAa4B/wJlAZwB7wJiAV4BfCAAAwEBAgMQARUDNgFf
|
||||
A0EBfwNCAYADQgGAA0IBgANCAYADQgGAA0MBgANDAYADQwGAA0MBgANDAYADQwGAA0MBgANDAYADQwGA
|
||||
A0MBgANDAYADQwGAA0IBgANCAYADQgGAA0IBgANCAYADQQF+AzMBVwMLAQ8DAAEBCAADAgEDAR0CHAEp
|
||||
AU0BMQErAb4BWwEbAQoB/QFeARsBCAH/AV4BGwEIAf8BXwEcAQgB/wFhARwBCAH/AWEBGwEIAf8BYwEb
|
||||
AQkB/wFjARsBCQH/AWMBGwEJAf8BYwEbAQkB/wFjARsBCQH/AWMBGwEJAf8BYwEbAQkB/wFjARsBCQH/
|
||||
AWMBGwEJAf8BYwEbAQkB/wFjARsBCQH/AWMBGwEJAf8BYQEcAQgB/wFhARsBCAH/AV8BGwEIAf8BXgEb
|
||||
AQgB/wFeARsBCAH/AVsBHAELAfsBSwE0ATABrQMVAR0DAQECGAADBAEGA3gBpgN1Af8DgAH/A6IB/wOv
|
||||
Af8DtwH/A78B/wPGAf8DygH/A8wB/wPMAf8DygH/A8UB/wO9Af8DtgH/A68B/wOiAf8DgAH/A3IB/wN9
|
||||
AbEDDAEPKAADBAEGAnIBeAGmAjEBpAH/Ah4BywH/AUkBTAHqAf8BYgFoAe8B/wFrAXcB9gH/AXYBiQH8
|
||||
Af8BgwGbAv8BjQGpAv8BkQGtAv8BkAGsAv8BjAGnAv8BgQGYAv8BdAGGAfsB/wFqAXUB9QH/AWEBZwHv
|
||||
Af8BSQFMAesB/wIfAcwB/wEuAS0BoQH/AnYBfQGxAwwBDxsAAQEDNwFdA0cBgANFAYADRQGAA0YBgANG
|
||||
AYADRwGAA0cBgANHAYADRwGAA0cBgANHAYADRwGAA0cBgANHAYADRwGAA0cBgANHAYADRwGAA0cBgANH
|
||||
AYADRwGAA0YBgANGAYADRQGAA0UBgANHAYADMQFOAwABAQgAAwEBAgFaATcBLgG6AYMBKwENAf8BdgEl
|
||||
AQsB/wF3ASYBDAH/AXsBKAEMAf8BfgEoAQwB/wGCASkBDQH/AYQBKgENAf8BhgEqAQ0B/wGGASsBDQH/
|
||||
AYYBKwENAf8BhgErAQ0B/wGGASsBDQH/AYYBKwENAf8BhgErAQ0B/wGGASsBDQH/AYYBKwENAf8BhgEr
|
||||
AQ0B/wGGASsBDQH/AYUBKgENAf8BhAEqAQ0B/wGBASkBDQH/AX0BKQEMAf8BewEnAQwB/wF3ASUBDAH/
|
||||
AXYBJgELAf8BgwEsAQ0B/wFRAToBNQGbAwABARQAAxUBGgOIAdcDbgH/A5MB/wOpAf8DsgH/A7kB/wO+
|
||||
Af8DwwH/A8gB/wPLAf8DygH/A8oB/wPKAf8DxwH/A8EB/wO8Af8DuAH/A7EB/wOoAf8DlAH/A20B/wOE
|
||||
Ad4DFwEcIAADFQEaAnQBjwHXARcBFgGwAf8BNgE3Ad0B/wFaAV4B6QH/AWUBbQHxAf8BbgF7AfcB/wF3
|
||||
AYoB+AH/AYMBmQH6Af8BjQGnAfsB/wGRAa0B/AH/AZABqgH8Af8BkAGrAfwB/wGRAa0B+wH/AYsBpQH6
|
||||
Af8BgAGWAfgB/wF1AYcB9wH/AW0BeQH2Af8BZAFrAfAB/wFZAV0B6AH/ATcBOAHeAf8BFgEVAa8B/wJv
|
||||
AYwB3gMXARwUAAMOARMDSAF/A0wBgANMAYADTQGAA04BgANPAYADUAGAA1ABgANQAYADUAGAA1ABgANQ
|
||||
AYADUAGAA1ABgANQAYADUAGAA1ABgANQAYADUAGAA1ABgANQAYADTwGAA08BgANOAYADTQGAA0wBgANM
|
||||
AYADRwF9AwQBBggAAR0CGwEmAY8BNAEQAf4BpQE9AREB/wGqAT8BEgH/AbABQQETAf8BtgFDARQB/wG7
|
||||
AUUBFAH/AcABSAEVAf8BwwFIARUB/wHEAUkBFQH/AcUBSgEVAf8BxQFKARUB/wHFAUoBFQH/AcUBSgEV
|
||||
Af8BxQFKARUB/wHFAUoBFQH/AcUBSgEVAf8BxQFKARUB/wHFAUoBFQH/AcUBSgEVAf8BxAFJARUB/wHC
|
||||
AUgBFQH/Ab8BSAEVAf8BuwFFARQB/wG1AUMBFAH/Aa8BQAETAf8BqgE/ARIB/wGkATwBEQH/AYgBMgET
|
||||
AfkDCQEMFAADhwHWA2wB/wOZAf8DpwH/A68B/wOzAf8DtwH/A7wB/wPCAf8DwwH/A8QB/wPFAf8DxQH/
|
||||
A8QB/wPDAf8DwAH/A7sB/wO2Af8DsgH/A64B/wOmAf8DmQH/A2wB/wOFAeMDBwEJHAACcgGPAdYCDgGy
|
||||
Af8BQgFDAd0B/wFZAV0B5gH/AWIBagHvAf8BaQF2Ae8B/wFxAYMB8AH/AXoBjwHyAf8BhAGbAfUB/wGH
|
||||
AaAB9QH/AYkBowH2Af8BigGlAfYB/wGKAaUB9gH/AYkBowH1Af8BhwGfAfUB/wGCAZgB8wH/AXgBjQHx
|
||||
Af8BbwGBAfAB/wFoAXQB7wH/AWEBaAHuAf8BWAFcAeUB/wFCAUMB3QH/Ag4BsgH/Am0BjgHjAwcBCRAA
|
||||
AxgBIANLAYADUAGAA1EBgANTAYADVAGAA1UBgANWAYADYgGAA2ABgANXAYADVwGAA1cBgANXAYADVwGA
|
||||
A1cBgANXAYADVwGAA1cBgANXAYADZQGAA1cBgANVAYADVQGAA1QBgANSAYADUQGAA1ABgANKAYADDgET
|
||||
CAABLwEqASgBPwGiAT0BEQH/AcMBTAEVAf8BzQFQARYB/wHVAVUBGQH/AdoBWgEeAf8B3AFeASMB/wHd
|
||||
AWEBKAH/AeoBogGAAf8B5wGVAW4B/wHfAWcBLgH/Ad8BZwEuAf8B3wFnAS4B/wHfAWcBLgH/Ad8BZwEu
|
||||
Af8B3wFnAS4B/wHfAWcBLgH/Ad8BZwEuAf8B3wFnAS4B/wHfAWcBLgH/Ae0BswGXAf8B3wFqATMB/wHd
|
||||
AWEBJwH/AdsBXgEiAf8B2QFZAR4B/wHUAVQBGAH/AcwBTwEWAf8BwAFLARUB/wGaATcBEAH/AR0BHAEb
|
||||
ASYQAANzAZ0DaQH/A5QB/wOjAf8DqgH/A6wB/wOxAf8DtQH/A7kB/wO8Af8DvgH/A78B/wO/Af8DvwH/
|
||||
A78B/wO9Af8DuwH/A7kB/wO1Af8DsAH/A6wB/wOqAf8DowH/A5YB/wNoAf8DfAGyGAACbQF0AZ0CDwGq
|
||||
Af8BPgFAAdgB/wFVAVkB4gH/AVwBZAHpAf8BYgFuAegB/wFpAXoB6gH/AXIBhgHsAf8BeQGQAe0B/wF+
|
||||
AZcB7gH/AYIBnAHvAf8BgwGeAfAB/wGEAZ8B8AH/AYQBngHwAf8BgwGeAfAB/wGBAZsB7wH/AX0BlgHu
|
||||
Af8BeAGOAe0B/wFxAYQB6wH/AWgBeAHpAf8BYQFsAegB/wFcAWIB6AH/AVQBWAHiAf8CQAHZAf8CDwGp
|
||||
Af8CdAF9AbIQAAMYASADTAGAA1EBgANTAYADVQGAA1YBgANXAYADWAGAA3EBgANoAYADWQGAA1kBgANZ
|
||||
AYADWQGAA1kBgANZAYADWQGAA1kBgANZAYADWwGAA3QBgANoAYADWAGAA1cBgANWAYADVQGAA1MBgANR
|
||||
AYADSgGAAw8BFAgAATABKgEoAT8BqAE/ARIB/wHOAVEBFgH/AdkBVwEaAf8B3AFfASQB/wHeAWYBLQH/
|
||||
Ad8BawEyAf8B4QFvATgB/wH6AesB5AH/AfEBwQGpAf8B4gFzAT8B/wHiAXMBPwH/AeIBcwE/Af8B4gFz
|
||||
AT8B/wHiAXMBPwH/AeIBcwE/Af8B4gFzAT8B/wHiAXMBPwH/AeIBcwE/Af8B5AF9AU0B/wH9AfwB+wH/
|
||||
AfEBwAGpAf8B4QFuATcB/wHfAWoBMQH/Ad0BZQErAf8B3AFeASMB/wHYAVYBGQH/Ac0BUQEWAf8BnAE5
|
||||
ARAB/wEeARwBGwEnDAADRgFWA2wB/wOIAf8DnwH/A6UB/wOmAf8DqgH/A68B/wOzAf8DtgH/A7gB/wO6
|
||||
Af8DugH/A7sB/wO7Af8DugH/A7kB/wO4Af8DtgH/A7IB/wOuAf8DqQH/A6UB/wOkAf8DngH/A4oB/wNn
|
||||
Af8DTgFiEAACRgFFAVYCJAGdAf8BLgEvAc0B/wFQAVMB3AH/AVcBXAHjAf8BWwFlAeIB/wFhAW8B5AH/
|
||||
AWkBegHmAf8BcAGEAegB/wF1AYwB6gH/AXkBkgHsAf8BewGVAe0B/wF8AZcB7QH/AX0BmAHtAf8BfQGY
|
||||
Ae0B/wF8AZYB7QH/AXoBlQHtAf8BeAGRAewB/wF0AYoB6gH/AW8BgwHoAf8BZwF4AeYB/wFgAW4B4wH/
|
||||
AVkBYwHiAf8BVgFbAeMB/wFPAVIB2wH/ATABMQHQAf8BIAEfAZgB/wJOAUwBYgwAAxgBIANNAYADUgGA
|
||||
A1QBgANWAYADVwGAA1gBgANeAYADdAGAA2kBgANaAYADWgGAA1oBgANaAYADWgGAA1oBgANaAYADWgGA
|
||||
A1oBgANmAYADdQGAA3QBgANaAYADWAGAA1cBgANWAYADVAGAA1IBgANLAYADDwEUCAABMAEqASgBPwGr
|
||||
AUEBEgH/AdUBUwEXAf8B2wFbASAB/wHdAWUBKwH/Ad8BawEyAf8B4QFwAToB/wHnAYwBYAH/A/4B/wHz
|
||||
AcQBrgH/AeQBeQFHAf8B5AF5AUcB/wHkAXkBRwH/AeQBeQFHAf8B5AF5AUcB/wHkAXkBRwH/AeQBeQFH
|
||||
Af8B5AF5AUcB/wHkAXkBRwH/Ae8BtAGYBf8B/QH7AfoB/wHjAXYBQgH/AeEBbwE5Af8B3wFqATEB/wHd
|
||||
AWQBKQH/AdsBWwEeAf8B0wFSARcB/wGeATkBEQH/AR8BHAEbAScLAAEBA4YB6QNsAf8DmQH/A6AB/wOg
|
||||
Af8DpAH/A6kB/wOtAf8DsQH/A7QB/wO2Af8DuAH/A7kB/wO5Af8DuQH/A7gB/wO3Af8DtgH/A7QB/wOw
|
||||
Af8DrAH/A6gB/wOjAf8DoAH/A58B/wOYAf8DcAH/A4MB8QMBAQILAAEBAmEBnAHpAg0BtAH/AUsBTAHV
|
||||
Af8BUQFVAd4B/wFUAVsB3AH/AVoBZAHeAf8BYQFuAeIB/wFnAXcB5QH/AW0BgAHoAf8BcQGGAeoB/wF0
|
||||
AYsB7AH/AXYBjQHtAf8BeAGQAe0B/wF5AZEB7gH/AXgBkQHuAf8BdwGPAe0B/wF2AY0B7AH/AXMBigHr
|
||||
Af8BcAGFAeoB/wFsAX0B5wH/AWYBdgHkAf8BYAFsAeEB/wFZAWMB3QH/AVQBWwHbAf8BUAFUAd0B/wFK
|
||||
AUsB1AH/AhEBuAH/AloBmAHxAwEBAggAAxgBIANNAYADUwGAA1UBgANXAYADWAGAA1kBgANoAYADdQGA
|
||||
A2kBgANbAYADWwGAA1sBgANbAYADWwGAA1sBgANbAYADWwGAA1sBgANvAYADdQGAA28BgANaAYADWQGA
|
||||
A1gBgANWAYADVQGAA1MBgANLAYADDwEUCAABMAEqASgBPwGvAUIBEwH/AdgBVgEZAf8B3AFgASUB/wHf
|
||||
AWgBLwH/AeEBbwE4Af8B4wFzAUAB/wHxAb4BpgX/AfMByAGyAf8B5gF9AUwB/wHmAX4BTAH/AeYBfgFM
|
||||
Af8B5gF+AUwB/wHmAX4BTAH/AeYBfgFMAf8B5gF+AUwB/wHmAX4BTAH/AeYBfgFMAf8B+AHjAdkF/wH4
|
||||
AeIB2AH/AeQBdwFGAf8B4gFzAT8B/wHhAW4BNwH/Ad4BaAEuAf8B3AFeASMB/wHXAVUBGAH/AaIBOwER
|
||||
Af8BHwEcARsBJwgAA1oBcwNoAf8DiwH/A5kB/wOcAf8DngH/A6MB/wOnAf8DqwH/A64B/wOwAf8DsgH/
|
||||
A7MB/wO1Af8DtQH/A7UB/wO1Af8DswH/A7IB/wOwAf8DrQH/A6oB/wOmAf8DogH/A50B/wObAf8DmAH/
|
||||
A4wB/wNkAf8DZQGGCAABWQFYAVoBcwIYAZ8B/wE3ATgBywH/AUoBTQHWAf8BTwFUAdcB/wFTAVsB2AH/
|
||||
AVoBYwHbAf8BXwFrAd8B/wFlAXQB4gH/AWkBegHkAf8BbQGBAeYB/wFwAYQB5wH/AXEBhwHoAf8BcwGK
|
||||
AekB/wF0AYsB6QH/AXQBiwHpAf8BcwGKAekB/wFxAYYB5wH/AW8BhAHnAf8BbAGAAeYB/wFpAXkB4wH/
|
||||
AWQBcgHhAf8BXgFqAd4B/wFZAWIB2gH/AVMBWgHXAf8BTgFTAdYB/wFJAUwB1QH/ATgBOQHMAf8CFQGb
|
||||
Af8CYgFkAYYIAAMYASADTgGAA1MBgANWAYADVwGAA10BgANmAYADcgGAA3UBgANqAYADXAGAA1wBgANc
|
||||
AYADXAGAA1wBgANcAYADXAGAA1wBgANfAYADdAGAA3UBgANqAYADWwGAA1oBgANZAYADVwGAA1UBgANT
|
||||
AYADTAGAAw8BFAgAATABKgEoAT8BsgFEARMB/wHZAVgBGwH/Ad0BYwEoAf8B3wFrATIB/wHmAYoBXQH/
|
||||
Ae8BtgGcAf8B+wHxAewF/wH0AcoBtQH/AecBggFPAf8B5wGCAU8B/wHnAYIBTwH/AecBggFPAf8B5wGC
|
||||
AU8B/wHnAYIBTwH/AecBggFPAf8B5wGCAU8B/wHqAZQBagH/A/4F/wH0AcsBtwH/AeUBewFJAf8B4wF2
|
||||
AUQB/wHiAXEBPAH/Ad8BagExAf8B3AFiAScB/wHZAVcBGgH/AaUBPQERAf8BHwEcARsBJwgAA4AB3ANp
|
||||
Af8DkQH/A5YB/wOYAf8DmwH/A58B/wOjAf8DpwH/A6kB/wOrAf8DrQH/A64B/wOvAf8DrwH/A68B/wOv
|
||||
Af8DrgH/A60B/wOrAf8DqQH/A6YB/wOjAf8DnwH/A5oB/wOYAf8DlgH/A5EB/wNrAf8DgQHxCAACXAGU
|
||||
AdwCDQGtAf8BQwFFAcwB/wFIAUwB0gH/AUwBUQHRAf8BUQFZAdQB/wFXAWEB1wH/AVwBZwHaAf8BYgFv
|
||||
AdwB/wFlAXUB3gH/AWgBeQHgAf8BagF9AeEB/wFtAYAB4gH/AW4BgwHjAf8BbgGDAeMB/wFuAYMB4wH/
|
||||
AW4BgwHiAf8BbAGAAeIB/wFqAXwB4QH/AWgBeQHgAf8BZQF0Ad4B/wFhAW0B3AH/AVsBZwHaAf8BVgFf
|
||||
AdcB/wFQAVcB0wH/AUwBUQHRAf8BSAFMAdIB/wFDAUQBywH/ARABDwGvAf8CVgGYAfEIAAMYASADTgGA
|
||||
A1QBgANiAYADbgGAA3QBgAN1AYADdQGAA3UBgANxAYADXwGAA1wBgANcAYADXAGAA1wBgANcAYADXAGA
|
||||
A1wBgANpAYADdQGAA3UBgANlAYADWwGAA1oBgANZAYADVwGAA1YBgANUAYADTAGAAw8BFAgAATABKgEo
|
||||
AT8BtQFFARMB/wHaAVoBHQH/AekBoAF9Af8B9wHhAdYB/wH+Av0N/wH6Ae0B5wH/AeoBkgFmAf8B6AGF
|
||||
AVMB/wHoAYUBUwH/AegBhQFTAf8B6AGFAVMB/wHoAYUBUwH/AegBhQFTAf8B6AGFAVMB/wHzAcUBrwn/
|
||||
Ae8BsQGTAf8B5gF9AUsB/wHkAXcBRgH/AeIBcgE+Af8B4AFsATMB/wHdAWMBKQH/AdoBWQEcAf8BpwE9
|
||||
ARIB/wEfARwBGwEnBAADEgEWA3cB/wN5Af8DjwH/A5IB/wOVAf8DmAH/A5sB/wOfAf8DogH/A6UB/wOn
|
||||
Af8DqAH/A6kB/wOqAf8DqgH/A6oB/wOqAf8DqQH/A6gB/wOmAf8DpAH/A6IB/wOfAf8DmwH/A5gB/wOU
|
||||
Af8DkgH/A48B/wN8Af8DcQH/AygBMQMSARYBNQE0AaUB/wEkASUBugH/AUEBQwHKAf8BRQFJAcwB/wFJ
|
||||
AU8BzgH/AU4BVQHQAf8BUgFcAdMB/wFYAWIB1gH/AVwBaAHYAf8BYAFuAdoB/wFjAXIB2wH/AWQBdQHc
|
||||
Af8BZgF4Ad0B/wFnAXkB3gH/AWcBegHeAf8BZwF5Ad4B/wFnAXkB3gH/AWYBeAHdAf8BZAF0AdwB/wFi
|
||||
AXIB2wH/AV8BbQHZAf8BWwFnAdgB/wFXAWIB1gH/AVEBWwHTAf8BTQFUAdAB/wFJAU4BzQH/AUUBSQHM
|
||||
Af8BQQFDAckB/wInAbwB/wIuAZ4B/wMoATEEAAMYASADTgGAA1QBgANmAYADagGAA2sBgANsAYADbQGA
|
||||
A3QBgAN1AYADcQGAA2ABgANdAYADXQGAA10BgANdAYADXQGAA10BgANxAYADdQGAA3QBgANgAYADWwGA
|
||||
A1oBgANZAYADVwGAA1YBgANUAYADTAGAAw8BFAgAATABKgEoAT8BtwFEARMB/wHbAVoBHgH/Ae4BtQGa
|
||||
Af8B8wHLAbgB/wH0AdABvwH/AfYB1QHGAf8B9gHZAcsB/wH+AfwB+wX/AfsB7QHnAf8B6wGZAW8B/wHo
|
||||
AYcBVQH/AegBhwFVAf8B6AGHAVUB/wHoAYcBVQH/AegBhwFVAf8B6AGHAVUB/wH7Ae4B6AX/A/4B/wHq
|
||||
AZUBawH/AeYBfQFMAf8B5AF5AUcB/wHiAXMBPwH/AeABbQE0Af8B3QFkASsB/wHaAVoBHQH/AakBPQES
|
||||
Af8BHwEcARsBJwQAA0kBXANmAf8DgwH/A40B/wOOAf8DkQH/A5UB/wOYAf8DmwH/A54B/wOgAf8DogH/
|
||||
A6MB/wOkAf8DpQH/A6UB/wOlAf8DpAH/A6QB/wOjAf8DoQH/A6AB/wOdAf8DmgH/A5gB/wOUAf8DkQH/
|
||||
A44B/wONAf8DhAH/A2EB/wNnAYgCRwFKAVwCGQGbAf8BMgEzAb8B/wFAAUIBxwH/AUIBRwHHAf8BRgFM
|
||||
AcoB/wFLAVEBzQH/AU8BVwHPAf8BUwFeAdEB/wFYAWMB0wH/AVsBaAHVAf8BXQFsAdYB/wFfAW4B1wH/
|
||||
AWEBcAHYAf8BYgFyAdgB/wFiAXMB2QH/AWIBcwHZAf8BYQFxAdgB/wFgAXAB2AH/AV4BbgHXAf8BXAFq
|
||||
AdYB/wFaAWcB1QH/AVcBYgHTAf8BUgFdAdEB/wFOAVYBzwH/AUkBUQHNAf8BRQFKAckB/wFBAUUBxwH/
|
||||
AT8BQQHHAf8BMwE0Ab8B/wIUAZYB/wJjAWcBiAQAAxgBIANOAYADVAGAA1YBgANYAYADWQGAA1sBgANb
|
||||
AYADZAGAA3QBgAN1AYADcgGAA2EBgANdAYADXQGAA10BgANdAYADYwGAA3UBgAN1AYADcwGAA1wBgANb
|
||||
AYADWgGAA1kBgANXAYADVgGAA1QBgANMAYADDwEUCAABMAEqASgBPwG4AUQBEwH/AdsBWgEfAf8B3gFm
|
||||
ASwB/wHgAW0BNgH/AeMBcwFAAf8B5QF6AUgB/wHmAX4BTAH/Ae4BrAGMAf8C/gH9Bf8B/AHyAe4B/wHr
|
||||
AZ0BdQH/AegBhwFVAf8B6AGHAVUB/wHoAYcBVQH/AegBhwFVAf8B7QGmAYIJ/wH9AfgB9gH/AecBggFQ
|
||||
Af8B5gF+AUwB/wHkAXkBRwH/AeIBcwE/Af8B4AFtATQB/wHdAWUBKwH/AdoBWgEdAf8BqgE+ARIB/wEf
|
||||
ARwBGwEnBAADcwGiA1wB/wOFAf8DigH/A4sB/wOOAf8DkQH/A5QB/wOXAf8DmQH/A5sB/wOdAf8DngH/
|
||||
A58B/wOgAf8DoAH/A6AB/wOgAf8DnwH/A54B/wOdAf8DmwH/A5gB/wOWAf8DkwH/A5AB/wONAf8DigH/
|
||||
A4kB/wOFAf8DXgH/A3sBvgJmAXgBogEHAQYBmAH/ATcBOAG9Af8BPQE/AcMB/wE/AUMBwgH/AUMBSAHF
|
||||
Af8BRwFOAcgB/wFLAVQBygH/AU8BWgHMAf8BUwFeAc0B/wFWAWIBzwH/AVgBZgHQAf8BWgFpAdEB/wFb
|
||||
AWoB0QH/AVwBbAHSAf8BXQFtAdMB/wFdAWwB0wH/AVwBbAHSAf8BWwFqAdEB/wFZAWgB0QH/AVgBZQHQ
|
||||
Af8BVQFhAc8B/wFSAV4BzQH/AU8BWQHLAf8BSgFTAckB/wFGAU0BxwH/AUIBRwHEAf8BPQFBAcIB/wE8
|
||||
AT8BwgH/AjcBvQH/AQkBCAGbAf8CagGCAb4EAAMYASADTgGAA1QBgANWAYADWAGAA1kBgANbAYADWwGA
|
||||
A1wBgANlAYADdAGAA3UBgANzAYADYgGAA10BgANdAYADXQGAA2sBgAN1AYADdQGAA24BgANcAYADWwGA
|
||||
A1oBgANZAYADVwGAA1YBgANUAYADTQGAAw8BFAgAATABKgEoAT8BuQFFARMB/wHbAVoBHwH/Ad4BZgEs
|
||||
Af8B4AFtATYB/wHjAXMBQAH/AeUBegFIAf8B5gF+AUwB/wHnAYIBUAH/Ae8BsQGTAf8D/gX/AfwB9gH0
|
||||
Af8B7AGkAYAB/wHoAYcBVQH/AegBhwFVAf8B6AGHAVUB/wH1AdEBvwn/AfgB4AHUAf8B5wGCAU8B/wHm
|
||||
AX4BTAH/AeQBeQFHAf8B4gFzAT8B/wHgAW0BNAH/Ad0BZQErAf8B2gFaAR0B/wGrAT8BEgH/AR8BHAEb
|
||||
AScEAAN9AckDXwH/A4IB/wOGAf8DhwH/A4oB/wONAf8DjwH/A5EB/wOUAf8DlgH/A5cB/wOYAf8DmgH/
|
||||
A5oB/wOaAf8DmgH/A5oB/wOaAf8DmAH/A5cB/wOWAf8DkwH/A5EB/wOPAf8DjQH/A4kB/wOGAf8DhQH/
|
||||
A4IB/wNiAf8DfAHUAmIBiwHJAQgBBwGeAf8CNgG5Af8BOQE8Ab4B/wE7AT4BvgH/AT8BRAHBAf8BQgFJ
|
||||
AcMB/wFFAU4BxQH/AUkBUwHHAf8BTQFYAckB/wFQAVwBygH/AVIBXwHLAf8BUwFhAcwB/wFVAWMBzQH/
|
||||
AVYBZQHNAf8BVgFlAc0B/wFWAWUBzQH/AVYBZQHNAf8BVQFjAc0B/wFTAWABywH/AVIBXgHLAf8BTwFb
|
||||
AcoB/wFMAVgByAH/AUkBUgHGAf8BRQFNAcUB/wFCAUgBwwH/AT4BRAHAAf8BOwE+Ab0B/wE5ATsBvQH/
|
||||
AjUBuQH/AgsBoQH/Al0BiwHUBAADGAEgA08BgANUAYADVgGAA1gBgANZAYADWwGAA1sBgANcAYADXAGA
|
||||
A2gBgAN0AYADdQGAA3MBgANkAYADXQGAA2UBgAN0AYADdQGAA3UBgANoAYADXAGAA1sBgANaAYADWQGA
|
||||
A1cBgANWAYADVAGAA00BgAMPARQIAAEwASoBKAE/AboBRQETAf8B2wFbAR8B/wHeAWYBLAH/AeABbQE2
|
||||
Af8B4wFzAUAB/wHlAXoBSAH/AeYBfgFMAf8B5wGCAVAB/wHoAYYBVAH/AfIBwAGoAf8D/gX/Af0B+gH4
|
||||
Af8B7gGqAYgB/wHoAYcBVQH/Ae8BsAGRAf8B/gH9AfwJ/wHzAcIBqgH/AecBggFPAf8B5gF+AUwB/wHk
|
||||
AXkBRwH/AeIBcwE/Af8B4AFtATQB/wHdAWUBKwH/AdoBWgEdAf8BrAE/ARIB/wEfARwBGwEnBAADdgHH
|
||||
A2IB/wN+Af8DggH/A4MB/wOFAf8DiAH/A4sB/wONAf8DjgH/A5EB/wOSAf8DkwH/A5QB/wOUAf8DlAH/
|
||||
A5QB/wOUAf8DkwH/A5MB/wOSAf8DkAH/A44B/wOMAf8DigH/A4cB/wOFAf8DgwH/A4IB/wN9Af8DYwH/
|
||||
A3oB3QJZAYYBxwILAZ8B/wIzAbUB/wE2ATgBuAH/ATcBOgG5Af8BOgE/AbsB/wE+AUMBvgH/AUEBSAHA
|
||||
Af8BRAFMAcEB/wFGAVABwwH/AUkBVQHFAf8BSwFXAcUB/wFNAVkBxgH/AU8BXAHHAf8BTwFdAcYB/wFP
|
||||
AV0BxwH/AU8BXQHHAf8BTwFdAcYB/wFOAVwBxgH/AU0BWQHGAf8BSwFXAcUB/wFJAVQBxAH/AUcBUAHC
|
||||
Af8BQwFMAcEB/wFAAUcBvwH/AT0BQwG9Af8BOgE+AbsB/wE3ATsBuQH/ATYBNwG4Af8CMgG0Af8CDQGh
|
||||
Af8CVgGOAd0EAAMYASADTwGAA1QBgANWAYADWAGAA1kBgANbAYADXAGAA10BgANeAYADXwGAA2wBgAN0
|
||||
AYADdQGAA3QBgANrAYADdAGAA3UBgAN1AYADdQGAA2YBgANdAYADXAGAA1sBgANZAYADVwGAA1YBgANU
|
||||
AYADTQGAAw8BFAgAATABKgEoAT8BugFFARMB/wHbAVsBHwH/Ad4BZgEsAf8B4AFtATYB/wHjAXMBQQH/
|
||||
AeUBfQFNAf8B5gGFAVYB/wHnAYoBXQH/AegBjwFiAf8B6AGSAWcB/wH1AdYBxwH/A/4F/wH+AfwB+wH/
|
||||
AfMBzgG8Af8B/gL8Df8B7wG0AZcB/wHnAYkBXAH/AeYBhQFVAf8B5AF8AUsB/wHiAXMBPwH/AeABbQE0
|
||||
Af8B3QFlASsB/wHaAVoBHQH/AawBPwESAf8BHwEcARsBJwQAA3UByANeAf8DegH/A30B/wN+Af8DgQH/
|
||||
A4MB/wOEAf8DhgH/A4gB/wOKAf8DiwH/A40B/wONAf8DjQH/A40B/wONAf8DjQH/A40B/wOMAf8DiwH/
|
||||
A4kB/wOHAf8DhQH/A4QB/wODAf8DgQH/A30B/wN9Af8DegH/A2AB/wN4AdwCWAGGAcgBCQEIAZsB/wEv
|
||||
ATABsAH/ATIBNAGzAf8BNAE3AbQB/wE2ATsBtgH/ATkBPgG4Af8BOwFBAbkB/wE9AUUBuwH/AT8BSAG8
|
||||
Af8BQgFMAb0B/wFDAU4BvgH/AUYBUgHAAf8BRwFUAcAB/wFHAVQBwAH/AUcBVAHAAf8BRwFUAcAB/wFH
|
||||
AVQBwAH/AUcBUwHAAf8BRQFRAb8B/wFDAU4BvgH/AUEBSwG9Af8BPwFHAbsB/wE8AUUBugH/AToBQQG5
|
||||
Af8BOAE+AbcB/wE2AToBtQH/ATMBNgGzAf8BMgEzAbMB/wIvAbAB/wELAQoBnQH/AlQBjAHcBAADGAEg
|
||||
A08BgANUAYADWAGAA1wBgANeAYADXwGAA18BgANgAYADYAGAA2ABgANhAYADbgGAA3UBgAN1AYADdQGA
|
||||
A3UBgAN1AYADdQGAA3QBgANiAYADYAGAA18BgANfAYADXgGAA1sBgANYAYADVAGAA00BgAMPARQIAAEw
|
||||
ASoBKAE/AboBRQETAf8B2wFcASAB/wHfAXEBOwH/AeIBggFTAf8B5AGNAWIB/wHmAZIBaQH/AecBlAFt
|
||||
Af8B6AGWAW8B/wHoAZkBcQH/AegBmQFyAf8B6QGbAXUB/wH3Ad4B0xn/A/4B/wHqAaQBgwH/AegBlQFv
|
||||
Af8B5wGUAWwB/wHmAZEBaAH/AeQBjQFhAf8B4gGBAVEB/wHfAXABOgH/AdoBWwEeAf8BrAE/ARIB/wEf
|
||||
ARwBGwEnBAADdQHCA1cB/wN2Af8DeQH/A3oB/wN6Af8DfAH/A4EB/wOEAf8DhgH/A4gB/wOJAf8DiwH/
|
||||
A4wB/wOMAf8DjAH/A4wB/wOMAf8DjAH/A4sB/wOJAf8DiAH/A4YB/wOEAf8DgQH/A3sB/wN6Af8DeQH/
|
||||
A3gB/wN2Af8DWgH/A3YB0gJaAYMBwgIBAZIB/wIsAasB/wEvATABrwH/ATABMwGvAf8BMAE0Aa8B/wEy
|
||||
ATgBsQH/ATgBPgG0Af8BPAFDAbYB/wE/AUcBuAH/AUIBSwG6Af8BRAFNAboB/wFGAVABvAH/AUcBUgG9
|
||||
Af8BRwFTAb0B/wFIAVMBvAH/AUgBUwG9Af8BRwFSAb0B/wFHAVIBvQH/AUYBUAG8Af8BQwFMAboB/wFC
|
||||
AUoBuQH/AT8BRwG4Af8BPAFCAbYB/wE4AT4BtAH/ATIBNwGwAf8BMAEzAa8B/wEvATIBrgH/AS4BMAGu
|
||||
Af8CKwGrAf8CBAGVAf8CVgGGAdIEAAMYASADTwGAA1cBgANdAYADXgGAA18BgANfAYADYAGAA2EBgANh
|
||||
AYADYQGAA2EBgANhAYADcQGAA3UBgAN1AYADdQGAA3UBgAN1AYADcgGAA2EBgANgAYADYAGAA18BgANf
|
||||
AYADXgGAA1wBgANXAYADTQGAAw8BFAgAATABKgEoAT8BugFFARMB/wHcAWkBMwH/AeIBhwFcAf8B4wGO
|
||||
AWMB/wHlAZIBaQH/AeYBlQFtAf8B5wGYAXIB/wHoAZoBdQH/AegBnAF2Af8B6AGcAXcB/wHoAZwBdwH/
|
||||
AegBnwF7Af8B+gHtAecV/wH8AfQB8QH/AegBmwF3Af8B6AGZAXQB/wHnAZcBcQH/AeYBlQFsAf8B5QGS
|
||||
AWkB/wHjAY0BYgH/AeEBhwFbAf8B3AFpATIB/wGsAT8BEgH/AR8BHAEbAScEAANpAZoDUQH/A3IB/wN2
|
||||
Af8DdAH/A3gB/wOCAf8DhwH/A4kB/wOKAf8DiwH/A4wB/wONAf8DjgH/A44B/wOOAf8DjgH/A40B/wON
|
||||
Af8DjAH/A4wB/wOKAf8DiQH/A4gB/wOGAf8DgQH/A3cB/wNzAf8DdQH/A3EB/wNSAf8DdAG8AlwBbwGa
|
||||
AgABhwH/AigBpgH/ASwBLQGqAf8BKAErAakB/wEuATIBrAH/AT0BQQGyAf8BQwFHAbUB/wFFAUoBtwH/
|
||||
AUcBTQG4Af8BSQFPAbkB/wFKAVIBugH/AUsBUwG7Af8BTAFUAbwB/wFMAVQBvAH/AU0BVQG8Af8BTQFV
|
||||
AbwB/wFMAVQBuwH/AUwBUwG7Af8BSwFSAboB/wFKAVEBugH/AUgBTwG4Af8BRgFNAbcB/wFEAUkBtgH/
|
||||
AUIBRgG1Af8BPAFAAbEB/wEuATEBqwH/ASgBKgGoAf8CLAGpAf8BKAEnAaUB/wIAAYoB/wJgAXwBvAQA
|
||||
AxgBIANPAYADWAGAA14BgANfAYADXwGAA2ABgANhAYADYQGAA2IBgANiAYADYgGAA2kBgAN0AYADdQGA
|
||||
A3UBgAN1AYADdQGAA3UBgANvAYADYgGAA2EBgANhAYADYAGAA18BgANeAYADXQGAA1gBgANNAYADDwEU
|
||||
CAABMAEqASgBPwG6AUUBEwH/Ad0BbQE7Af8B4gGLAWMB/wHkAZEBaQH/AeUBlQFuAf8B5gGaAXQB/wHn
|
||||
AZwBeAH/AegBngF7Af8B6QGgAXwB/wHpAaABfQH/AekBoAF9Af8B8AHFAbAB/wP+Ff8B+AHkAdoB/wHp
|
||||
AaABfAH/AegBngF6Af8B5wGcAXcB/wHmAZoBcwH/AeUBlQFuAf8B5AGRAWgB/wHiAYsBYgH/Ad0BbQE5
|
||||
Af8BrAE/ARIB/wEfARwBGwEnBAADSAFfA1EB/wNrAf8DbwH/A3MB/wOFAf8DiAH/A4gB/wOJAf8DigH/
|
||||
A4sB/wOMAf8DjQH/A44B/wOOAf8DjgH/A44B/wOOAf8DjgH/A40B/wOMAf8DiwH/A4kB/wOIAf8DiAH/
|
||||
A4gB/wOEAf8DcwH/A28B/wNsAf8DTQH/A2MBhwJGAUkBXwIDAYMB/wEhASABoAH/AiUBowH/ASoBLAGm
|
||||
Af8BQwFFAbEB/wFIAUsBtAH/AUcBSwG0Af8BSQFNAbUB/wFKAU8BtgH/AUsBUQG3Af8BTQFTAbcB/wFO
|
||||
AVQBuAH/AU8BVQG5Af8BTwFWAbkB/wFQAVYBuQH/AVABVgG5Af8BTwFWAbkB/wFPAVUBuAH/AU4BUwG3
|
||||
Af8BTQFSAbcB/wFLAVEBtgH/AUkBTwG1Af8BSAFNAbQB/wFHAUoBtAH/AUgBSwG0Af8BQgFEAbAB/wEq
|
||||
ASwBpQH/AiUBowH/AiEBoAH/AgABfQH/Al0BZAGHBAADGAEgA04BgANZAYADXwGAA18BgANgAYADYQGA
|
||||
A2EBgANiAYADYgGAA2cBgANtAYADdAGAA3UBgAN1AYADdQGAA3UBgAN1AYADdQGAA28BgANiAYADYgGA
|
||||
A2EBgANhAYADYAGAA18BgANeAYADWAGAA00BgAMPARQIAAEwASoBKAE/AbkBRQETAf8B3gFyAUAB/wHj
|
||||
AZIBagH/AeQBlQFwAf8B5QGYAXYB/wHnAZwBegH/AecBnwF9Af8B6AGhAYAB/wHpAaIBgQH/Ae0BuQGh
|
||||
Af8B9QHbAc8B/wP+Gf8B+AHjAdoB/wHpAaQBgwH/AegBoAF+Af8B5wGfAXwB/wHmAZwBeQH/AeUBmAF1
|
||||
Af8B5AGVAW8B/wHjAZEBaQH/Ad0BcQE/Af8BqwE/ARIB/wEfARwBGwEnBAADDwETA2EB/wNdAf8DaQH/
|
||||
A3oB/wOMAf8DhwH/A4kB/wOLAf8DiwH/A4wB/wONAf8DjgH/A44B/wOOAf8DjwH/A48B/wOPAf8DjgH/
|
||||
A44B/wONAf8DjQH/A4sB/wOKAf8DiQH/A4cB/wOLAf8DegH/A2gB/wNfAf8DWAH/AyoBNAMPARMCHQGL
|
||||
Af8CDgGTAf8CHQGcAf8CNwGnAf8BUAFRAbMB/wFJAUsBsQH/AUsBTgGyAf8BTQFQAbQB/wFOAVIBtAH/
|
||||
AU8BVAG1Af8BUAFVAbUB/wFRAVYBtgH/AVIBVwG2Af8BUgFYAbcB/wFTAVgBtwH/AVMBWAG3Af8BUwFX
|
||||
AbcB/wFSAVgBtwH/AVEBVgG2Af8BUAFVAbUB/wFQAVQBtQH/AU4BUgG0Af8BTQFQAbIB/wFLAU4BsgH/
|
||||
AUkBSwGxAf8BUAFSAbIB/wI3AacB/wEcAR0BnAH/AhABlQH/AhQBggH/AyoBNAQAAxgBIANOAYADWQGA
|
||||
A18BgANgAYADYQGAA2IBgANkAYADagGAA3IBgAN0AYADdQGAA3UBgAN1AYADdQGAA3UBgAN1AYADdQGA
|
||||
A3UBgAN1AYADcAGAA2QBgANiAYADYQGAA2EBgANgAYADXwGAA1kBgANNAYADDwEUCAABMAEqASgBPwG5
|
||||
AUUBEwH/Ad4BdgFFAf8B4wGWAXEB/wHlAZoBdgH/AeYBngF7Af8B5wGhAYAB/wHpAaoBjQH/AfEBzQG8
|
||||
Af8B+gHwAewB/wP+Jf8B+AHmAd4B/wHpAakBjQH/AecBogGCAf8B5gGhAX4B/wHmAZ4BewH/AeQBmgF1
|
||||
Af8B4wGWAXAB/wHdAXUBRAH/AasBPgESAf8BHwEcARsBJwgAA2oB3QNPAf8DYwH/A3wB/wOPAf8DigH/
|
||||
A4wB/wOMAf8DjgH/A44B/wOPAf8DkAH/A5AB/wOQAf8DkAH/A5AB/wOQAf8DkAH/A5AB/wOPAf8DjgH/
|
||||
A44B/wOMAf8DiwH/A4oB/wOPAf8DfAH/A2IB/wNQAf8DaQHvCAACQAGCAd0CAAGDAf8CGAGVAf8BPQE8
|
||||
AacB/wJYAbMB/wFQAVEBsAH/AVEBUgGyAf8BUwFUAbIB/wFVAVYBswH/AVUBWAG0Af8BVgFZAbQB/wFX
|
||||
AVsBtQH/AVcBWwG1Af8BVwFbAbUB/wFYAVsBtQH/AVgBWwG1Af8BVwFbAbUB/wFXAVsBtQH/AVcBWwG1
|
||||
Af8BVgFZAbQB/wFVAVcBtAH/AVUBVgGzAf8BUwFUAbIB/wFRAVIBsQH/AVABUQGwAf8CWAGzAf8CPAGn
|
||||
Af8CFwGUAf8CAAGEAf8COQGEAe8IAAMYASADTgGAA1oBgANgAYADYgGAA2cBgANuAYADdAGAA3UBgAN1
|
||||
AYADdQGAA3UBgAN1AYADdQGAA3QBgAN0AYADcgGAA3MBgAN1AYADdQGAA3UBgANxAYADZAGAA2IBgANi
|
||||
AYADYQGAA2ABgANaAYADTQGAAw8BFAgAATABKgEoAT8BuAFGARMB/wHeAXoBSgH/AeQBmgF3Af8B5gGf
|
||||
AYAB/wHsAb0BpgH/AfYB4AHVAf8B/gL8Gf8D/gH/Af4B/QH8Af8B+gHyAe4B/wH8AfcB9A3/AfkB7gHp
|
||||
Af8B6QGuAZIB/wHnAaMBhQH/AeYBogGBAf8B5QGdAXwB/wHkAZkBdgH/Ad4BegFKAf8BqwE+ARIB/wEf
|
||||
ARwBGwEnCAADUgFwA0cB/wNZAf8DeQH/A5UB/wOMAf8DjgH/A48B/wOQAf8DkAH/A5IB/wOSAf8DkgH/
|
||||
A5IB/wOTAf8DkwH/A5IB/wOSAf8DkgH/A5EB/wOQAf8DjwH/A48B/wOOAf8DjAH/A5QB/wN5Af8DWgH/
|
||||
A0YB/wNiAYoIAAJNAVQBcAIAAXEB/wIKAY0B/wI6AaQB/wJhAbYB/wJWAa8B/wJXAbEB/wFYAVkBsgH/
|
||||
AVkBWgGzAf8BWgFbAbMB/wFcAV0BtAH/AVwBXgG0Af8BXAFeAbUB/wFcAV8BtAH/AV0BXwG1Af8BXQFf
|
||||
AbUB/wFcAV8BtAH/AVwBXgG0Af8BXAFfAbQB/wFbAV0BtAH/AVoBWwGzAf8BWQFaAbIB/wJYAbIB/wJX
|
||||
AbEB/wFXAVYBrwH/AmEBtQH/AjoBpAH/AgsBjgH/AgABbgH/AlsBZAGKCAADGAEgA04BgANbAYADaAGA
|
||||
A3IBgAN0AYADdQGAA3UBgAN1AYADdQGAA3QBgANzAYADbwGAA2wBgANoAYADZQGAA2QBgANmAYADcgGA
|
||||
A3UBgAN1AYADdQGAA3EBgANjAYADYgGAA2IBgANhAYADWwGAA0wBgAMPARQIAAEwASoBKAE/AbYBRAET
|
||||
Af8B3wF9AVAB/wHtAcIBrwH/AfsB9AHxAf8D/hH/Af4C/QH/AfwB9wH1Af8B9gHhAdkB/wHzAdMBxwH/
|
||||
Ae0BvgGrAf8B6gGvAZcB/wHoAakBjwH/AesBtQGfAf8B+wH0AfEN/wH5AewB5gH/AegBqgGNAf8B5gGl
|
||||
AYYB/wHlAaEBgwH/AeQBngF9Af8B3gF7AU8B/wGpAT0BEgH/AR8BHAEbAScMAANlAegDSAH/A3EB/wOb
|
||||
Af8DkAH/A5EB/wORAf8DkgH/A5MB/wOUAf8DlAH/A5QB/wOUAf8DlQH/A5UB/wOUAf8DlAH/A5QB/wOU
|
||||
Af8DkwH/A5IB/wORAf8DkQH/A5AB/wObAf8DcQH/A0kB/wNfAfMDBAEGDAACNQF/AegCAAFyAf8CMAGc
|
||||
Af8CawG5Af8CXQGwAf8CXQGxAf8CXwGxAf8CXwGyAf8BYAFhAbMB/wFhAWIBtAH/AWEBYgG0Af8BYQFj
|
||||
AbQB/wFiAWMBtAH/AWIBZAG1Af8BYgFkAbUB/wFiAWQBtAH/AWEBYgG0Af8BYQFiAbQB/wFhAWIBtAH/
|
||||
AWABYQGzAf8CXwGyAf8CXwGxAf8BXgFdAbEB/wJdAbAB/wJrAbgB/wIwAZwB/wIAAXQB/wIsAX0B8wME
|
||||
AQYIAAMYASADTgGAA1sBgANkAYADcQGAA3QBgAN0AYADcAGAA20BgANqAYADZgGAA2QBgANkAYADZAGA
|
||||
A2QBgANkAYADZAGAA2QBgANmAYADcgGAA3UBgAN1AYADdQGAA28BgANjAYADYwGAA2IBgANbAYADTAGA
|
||||
Aw8BFAgAATABKgEoAT8BswFEARMB/wHeAYIBVgH/AecBrAGRAf8B+QHtAegB/wP+Af8B/QH6AfkB/wH4
|
||||
AeoB5AH/AfQB2QHNAf8B7wHKAbgB/wHqAbYBngH/AekBsAGUAf8B6AGuAZIB/wHoAa4BkgH/AegBrgGS
|
||||
Af8B6AGuAZIB/wHoAa4BkgH/AegBrgGSAf8B6wG4AaAB/wH6AfIB7g3/AfYB4QHYAf8B5gGnAYsB/wHm
|
||||
AaUBiAH/AeUBowGEAf8B3gGBAVUB/wGmAT0BEQH/AR8CHAEnDAADQgFVA0IB/wNVAf8DjgH/A54B/wOT
|
||||
Af8DlQH/A5YB/wOWAf8DlwH/A5cB/wOXAf8DmAH/A5gB/wOYAf8DlwH/A5cB/wOXAf8DlgH/A5YB/wOV
|
||||
Af8DlQH/A5MB/wOdAf8DjwH/A1YB/wM/Af8DUAFoEAACQAFDAVUCAAFmAf8CDAGCAf8CWwGuAf8CcQG6
|
||||
Af8CYgGyAf8CZQGzAf8CZgGzAf8BZgFnAbMB/wJnAbQB/wJnAbQB/wFnAWgBtAH/AWgBaQG1Af8BaAFp
|
||||
AbUB/wFoAWkBtQH/AWcBaQG1Af8BZwFoAbQB/wJnAbQB/wFmAWcBswH/AWYBZwGzAf8CZgGyAf8CZQGy
|
||||
Af8CYgGxAf8CcQG5Af8CXAGvAf8CDAGEAf8CAAFgAf8CTQFQAWgMAAMYASADTQGAA1wBgANjAYADZAGA
|
||||
A2YBgANkAYADZAGAA2QBgANkAYADZAGAA2QBgANkAYADZAGAA2QBgANkAYADZAGAA2QBgANkAYADZgGA
|
||||
A3EBgAN1AYADdQGAA3UBgANtAYADYwGAA2MBgANcAYADSwGAAw8BFAgAATABKgEoAT8BsAFDARMB/wHd
|
||||
AYQBXAH/AeUBpAGKAf8B5wGsAZQB/wHpAbkBogH/AecBsAGVAf8B5wGvAZIB/wHoAa8BkwH/AegBsQGV
|
||||
Af8B6AGwAZUB/wHoAbABlQH/AegBsAGVAf8B6AGwAZUB/wHoAbABlQH/AegBsAGVAf8B6AGwAZUB/wHo
|
||||
AbABlQH/AegBsAGVAf8B6gG3AZ8B/wH6AfAB6w3/AfMB2QHNAf8B5gGmAYwB/wHlAaQBiQH/Ad0BhAFb
|
||||
Af8BowE9AREB/wEfAhwBJxAAA2cBoQNAAf8DYgH/A6gB/wOhAf8DmQH/A5oB/wOaAf8DmwH/A5sB/wOb
|
||||
Af8DmwH/A5sB/wObAf8DmwH/A5sB/wOaAf8DmgH/A5oB/wOaAf8DmQH/A6AB/wOoAf8DZAH/Az4B/wNt
|
||||
AbYYAAJYAW4BoQIAAWEB/wIgAYwB/wKCAcAB/wJ3AboB/wJrAbQB/wJuAbUB/wJuAbUB/wJuAbYB/wFv
|
||||
AW4BtgH/Am8BtgH/Am8BtgH/Am8BtgH/Am8BtgH/Am8BtgH/Am8BtgH/AW8BbgG1Af8CbgG1Af8CbgG1
|
||||
Af8CbgG1Af8CawG0Af8CdgG5Af8CggHAAf8CIQGOAf8CAAFcAf8CWQF2AbYQAAMYASADTQGAA10BgANj
|
||||
AYADZAGAA2QBgANkAYADZAGAA2UBgANlAYADZQGAA2UBgANlAYADZQGAA2UBgANlAYADZQGAA2UBgANl
|
||||
AYADZQGAA2YBgANxAYADdQGAA3UBgAN0AYADZQGAA2MBgANdAYADSwGAAw8BFAgAATABKgEoAT8BrgFD
|
||||
ARMB/wHdAYoBZAH/AeUBqAGOAf8B5gGqAZAB/wHmAa0BkgH/AecBrgGUAf8B5wGuAZYB/wHoAa8BlwH/
|
||||
AegBrwGYAf8B6AGvAZgB/wHoAa8BmAH/AegBrwGYAf8B6AGvAZgB/wHoAa8BmAH/AegBrwGYAf8B6AGv
|
||||
AZgB/wHoAa8BmAH/AegBrwGYAf8B6AGvAZgB/wHpAbUBoAH/AfgB7AHnCf8D/gH/AecBrwGYAf8B5QGo
|
||||
AY0B/wHcAYoBYwH/AaIBPQERAf8BHwIcAScTAAEBA10B1QNDAf8DbAH/A7IB/wOuAf8DnwH/A6EB/wOh
|
||||
Af8DoQH/A6EB/wOhAf8DoQH/A6EB/wOhAf8DoQH/A6EB/wOhAf8DoQH/A58B/wOrAf8DswH/A28B/wM9
|
||||
Af8DXwHjAwYBCBsAAQECNwFwAdUCAAFnAf8CLwGRAf8CkQHHAf8CiwHDAf8CdQG3Af8CeAG5Af8CeQG5
|
||||
Af8CeQG6Af8CeQG5Af8CeQG5Af8CeQG5Af8CeQG5Af8CeQG5Af8CeQG5Af8CeQG5Af8CeQG5Af8CeAG5
|
||||
Af8CdQG3Af8CiAHBAf8CkgHIAf8CMwGVAf8CAAFbAf8CNwFzAeMDBgEIEAADGAEgA00BgANcAYADZAGA
|
||||
A2QBgANkAYADZQGAA2UBgANlAYADZQGAA2UBgANlAYADZQGAA2UBgANlAYADZQGAA2UBgANlAYADZQGA
|
||||
A2UBgANlAYADZgGAA3ABgAN0AYADcgGAA2UBgANkAYADXAGAA0sBgAMPARQIAAEwASoBKAE/AawBQgES
|
||||
Af8B2wGJAWEB/wHlAakBkgH/AeYBrAGUAf8B5gGvAZYB/wHmAbABmAH/AecBsQGZAf8B5wGwAZoB/wHn
|
||||
AbIBmgH/AecBswGbAf8B5wGzAZsB/wHnAbMBmwH/AecBswGbAf8B5wGzAZsB/wHnAbMBmwH/AecBswGb
|
||||
Af8B5wGzAZsB/wHnAbMBmwH/AecBswGbAf8B5wGyAZoB/wHoAbQBngH/AfgB6gHjAf8D/gH/AfoB8gHv
|
||||
Af8B5gGvAZgB/wHlAakBkQH/AdoBigFhAf8BoQE8AREB/wEfARwBGwEnFAADDgESA1AB0QM/Af8DZAH/
|
||||
A6kB/wPCAf8DsQH/A6cB/wOoAf8DqQH/A6kB/wOpAf8DqQH/A6kB/wOpAf8DqAH/A6cB/wOvAf8DwQH/
|
||||
A64B/wNnAf8DOQH/A10B3AMWARsgAAMOARICKAFhAdECAAFfAf8CJwGJAf8ChQG/Af8CqAHSAf8CkQHE
|
||||
Af8CgwG8Af8ChQG9Af8ChQG+Af8ChgG+Af8ChgG+Af8ChgG+Af8ChgG+Af8ChgG+Af8ChQG9Af8CgwG8
|
||||
Af8CjgHCAf8CpwHRAf8CiwHDAf8CLAGLAf8CAAFSAf8COQFuAdwDFgEbFAADEQEXA0sBgANXAYADZAGA
|
||||
A2UBgANlAYADZQGAA2UBgANlAYADZQGAA2UBgANlAYADZQGAA2UBgANlAYADZQGAA2UBgANlAYADZQGA
|
||||
A2UBgANlAYADZQGAA2UBgANnAYADZgGAA2UBgANkAYADVwGAA0kBfgMGAQgIAAEjASABHwEtAZ4BOwER
|
||||
Af8B0QFuAT4B/wHmAasBlwH/AeYBsAGZAf8B5gGzAZoB/wHnAbQBmwH/AecBtQGcAf8B5wG2AZwB/wHn
|
||||
AbYBnAH/AecBuQGdAf8B5wG5AZ0B/wHnAbkBnQH/AecBuQGdAf8B5wG5AZ0B/wHnAbkBnQH/AecBuQGd
|
||||
Af8B5wG5AZ0B/wHnAbkBnQH/AecBuQGdAf8B5wG1AZwB/wHnAbYBnAH/AecBtwGeAf8B6QG/AagB/wHn
|
||||
AbcBnwH/AeYBsAGZAf8B5gGrAZcB/wHRAW8BPgH/AZIBNgERAfwBDQIMARAYAAMEAQUDZQGlAzkB/wNF
|
||||
Af8DhAH/A7MB/wPKAf8DxAH/A70B/wO1Af8DswH/A7MB/wO0Af8DuwH/A8QB/wPKAf8DugH/A4wB/wNF
|
||||
Af8DNQH/A2kBsQMKAQ0oAAMEAQUCVQFtAaUCAAFTAf8CAAFsAf8CVAGgAf8ClQHFAf8CtAHXAf8CrQHT
|
||||
Af8CogHNAf8CmAHHAf8ClAHFAf8ClAHFAf8ClwHGAf8CoAHLAf8CrAHSAf8CtQHXAf8CngHKAf8CXgGm
|
||||
Af8CAAFtAf8CAAFJAf8CVwFxAbEDCgENHAADPQFkA08BgANXAYADXgGAA2ABgANgAYADYAGAA2EBgANh
|
||||
AYADYQGAA2EBgANhAYADYQGAA2EBgANhAYADYQGAA2EBgANhAYADYQGAA2EBgANhAYADYAGAA2ABgANg
|
||||
AYADXgGAA1cBgANPAYADNwFVEAABcgE+ASwBxwG/AU0BFQH/AdIBcAFBAf8B3AGRAXAB/wHfAZwBeQH/
|
||||
AeABmwF6Af8B4gGdAXoB/wHjAZ8BewH/AeMBnwF8Af8B4wGgAXwB/wHjAZ8BfAH/AeMBnwF8Af8B4wGf
|
||||
AXwB/wHjAZ8BfAH/AeMBnwF8Af8B4wGfAXwB/wHjAZ8BfAH/AeMBnwF8Af8B4wGgAXwB/wHjAZ8BewH/
|
||||
AeMBnwF7Af8B4gGcAXoB/wHgAZsBegH/Ad4BnAF5Af8B3AGRAXAB/wHSAXABQQH/AbsBSgEUAf8BZwFD
|
||||
ATYBqSQAA00BdANPAeYDOAH/A0oB/wN9Af8DlwH/A6wB/wO/Af8DxgH/A8cB/wPBAf8DsQH/A5oB/wOD
|
||||
Af8DSgH/AzQB/wNJAewDWAF7OAACRgFQAXQCHgFnAeYCAAFQAf8CBAFyAf8CSwGaAf8CbwGuAf8CjAG+
|
||||
Af8CpgHNAf8CsAHTAf8CsQHUAf8CqQHPAf8CkgHCAf8CcgGwAf8CUgGeAf8CBAFyAf8CAAFIAf8CGAFg
|
||||
AewCUwFaAXskAAMMAQ8DPQFkA0sBgANNAYADTQGAA00BgANOAYADTgGAA04BgANOAYADTgGAA04BgANO
|
||||
AYADTgGAA04BgANOAYADTgGAA04BgANOAYADTgGAA04BgANOAYADTQGAA00BgANNAYADSgF/AzkBWwMG
|
||||
AQgQAAEXARYBFQEdAXIBPgEsAccBngE7AREB/wGsAUIBEgH/Aa0BQwETAf8BsAFDARMB/wGzAUQBEwH/
|
||||
AbYBRAETAf8BuAFFARMB/wG5AUUBEwH/AbkBRQETAf8BuQFFARMB/wG5AUUBEwH/AbkBRQETAf8BuQFF
|
||||
ARMB/wG5AUUBEwH/AbkBRQETAf8BuQFFARMB/wG5AUUBEwH/AbgBRQETAf8BtgFEARMB/wGzAUQBEwH/
|
||||
AbABQwETAf8BrQFDARMB/wGsAUIBEgH/AZoBOgERAf4BbAFBATIBtQENAgwBECgAAwoBDQNbAZADSQHe
|
||||
AzwB/wM5Af8DQAH/A04B/wNiAf8DZAH/A1AB/wNAAf8DOgH/AzoB/wNPAeADYQGWAw4BEkAAAwoBDQJQ
|
||||
AWABkAIcAV8B3gIAAVkB/wIAAVMB/wIAAWIB/wIJAXUB/wIlAYYB/wIoAYgB/wIMAXYB/wIAAWEB/wIA
|
||||
AVQB/wIAAVQB/wIjAWMB4AJXAWUBlgMOARIwAAMSARcDGAEgAxgBIAMYASADGAEgAxgBIAMYASADGAEg
|
||||
AxgBIAMYASADGAEgAxgBIAMYASADGAEgAxgBIAMYASADGAEgAxgBIAMYASADGAEgAxgBIAMYASADGAEg
|
||||
Aw4BEyAAASMBIAEfAS0BMAErASgBPwEwASsBKQE/ATABKwEpAT8BMQErASkBPwExASsBKQE/ATEBKwEp
|
||||
AT8BMQErASkBPwExASsBKQE/ATEBKwEpAT8BMQErASkBPwExASsBKQE/ATEBKwEpAT8BMQErASkBPwEx
|
||||
ASsBKQE/ATEBKwEpAT8BMQErASkBPwExASsBKQE/ATEBKwEpAT8BMQErASkBPwEwASsBKQE/ATABKwEp
|
||||
AT8BMAErASgBPwEeARwBGwEmPAADMAFAA1UBigNYAb4DTAHsA0EB8gNAAfIDTQHuA1wBwANVAY0DNQFE
|
||||
WAACLgEwAUACSgFaAYoCPAFlAb4CGgFkAewCCgFZAfICCgFZAfICGgFkAe4CQQFpAcACSgFZAY0CMwE1
|
||||
AUT/AC0AAUIBTQE+BwABPgMAASgDAAGAAwABQAMAAQEBAAEBBgABBBYAA///AP8AAwAB/wHgAQMC/wHg
|
||||
AQMB/wHAAgABAwHAAgABAwH/AgAC/wIAAf8BgAIAAQMBgAIAAQMB/gIAAX8B/gIAAX8BgAIAAQEBgAIA
|
||||
AQEB+AIAAR8B+AIAAR8BgAIAAQEBgAIAAQEB8AIAAQ8B8AIAAQ8BgAIAAQEBgAIAAQEB8AIAAQcB8AIA
|
||||
AQcBgAIAAQEBgAIAAQEB4AIAAQcB4AIAAQcBgAIAAQEBgAIAAQEBwAIAAQMBwAIAAQMBgAIAAQEBgAIA
|
||||
AQEBgAIAAQEBgAIAAQEBgAIAAQEBgAIAAQEBgAIAAQEBgAIAAQEBgAIAAQEBgAIAAQEBgAIAAQEBgAIA
|
||||
AQEBgAIAAQEBgAIAAQEIAAGAAgABAQGAAgABAQgAAYACAAEBAYACAAEBCAABgAIAAQEBgAIAAQEIAAGA
|
||||
AgABAQGAAgABAQgAAYACAAEBAYACAAEBCAABgAIAAQEBgAIAAQEIAAGAAgABAQGAAgABAQgAAYACAAEB
|
||||
AYACAAEBCAABgAIAAQEBgAIAAQEIAAGAAgABAQGAAgABAQGAAgABAQGAAgABAQGAAgABAQGAAgABAQGA
|
||||
AgABAQGAAgABAQGAAgABAQGAAgABAQHAAgABAQHAAgABAQGAAgABAQGAAgABAQHAAgABAwHAAgABAwGA
|
||||
AgABAQGAAgABAQHgAgABBwHgAgABBwGAAgABAQGAAgABAQHgAgABBwHgAgABBwGAAgABAQGAAgABAQHw
|
||||
AgABDwHwAgABDwGAAgABAQGAAgABAQH4AgABHwH4AgABHwHAAgABAwHAAgABAwH+AgABfwH+AgABfwHA
|
||||
AgABAwHAAgABAwH/AgAC/wIAAf8B8AIAAQ8B8AIAAQ8B/wHgAQcC/wHgAQcJ/ws=
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
39
FSFlightLogger/Program.cs
Normal file
39
FSFlightLogger/Program.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using SimConnect;
|
||||
using SimConnect.Concrete;
|
||||
using SimpleInjector;
|
||||
using SimpleInjector.Diagnostics;
|
||||
|
||||
namespace FSFlightLogger
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
public static void Main()
|
||||
{
|
||||
var container = CreateContainer();
|
||||
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(container.GetInstance<MainForm>());
|
||||
}
|
||||
|
||||
|
||||
public static Container CreateContainer()
|
||||
{
|
||||
var container = new Container();
|
||||
|
||||
// Since the MainForm is registered as well, do not call Verify on the container as it would create an instance
|
||||
container.Options.EnableAutoVerification = false;
|
||||
|
||||
container.Register<MainForm>();
|
||||
container.Register<ISimConnectClientFactory, SimConnectClientFactory>();
|
||||
|
||||
return container;
|
||||
}
|
||||
}
|
||||
}
|
36
FSFlightLogger/Properties/AssemblyInfo.cs
Normal file
36
FSFlightLogger/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("FSFlightLogger")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("FSFlightLogger")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2020")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("5871fa9b-88a7-4f98-8755-2fc48d4dbf44")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
71
FSFlightLogger/Properties/Resources.Designer.cs
generated
Normal file
71
FSFlightLogger/Properties/Resources.Designer.cs
generated
Normal file
@ -0,0 +1,71 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace FSFlightLogger.Properties
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources
|
||||
{
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((resourceMan == null))
|
||||
{
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("FSFlightLogger.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture
|
||||
{
|
||||
get
|
||||
{
|
||||
return resourceCulture;
|
||||
}
|
||||
set
|
||||
{
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
117
FSFlightLogger/Properties/Resources.resx
Normal file
117
FSFlightLogger/Properties/Resources.resx
Normal file
@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
30
FSFlightLogger/Properties/Settings.Designer.cs
generated
Normal file
30
FSFlightLogger/Properties/Settings.Designer.cs
generated
Normal file
@ -0,0 +1,30 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace FSFlightLogger.Properties
|
||||
{
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
|
||||
{
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default
|
||||
{
|
||||
get
|
||||
{
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
7
FSFlightLogger/Properties/Settings.settings
Normal file
7
FSFlightLogger/Properties/Settings.settings
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
BIN
FSFlightLogger/Resources/Images/FSXConnected.png
Normal file
BIN
FSFlightLogger/Resources/Images/FSXConnected.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
BIN
FSFlightLogger/Resources/Images/FSXDisconnected.png
Normal file
BIN
FSFlightLogger/Resources/Images/FSXDisconnected.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
FSFlightLogger/Resources/Images/Idle.png
Normal file
BIN
FSFlightLogger/Resources/Images/Idle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
BIN
FSFlightLogger/Resources/Images/P3DConnected.png
Normal file
BIN
FSFlightLogger/Resources/Images/P3DConnected.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
FSFlightLogger/Resources/Images/P3DDisconnected.png
Normal file
BIN
FSFlightLogger/Resources/Images/P3DDisconnected.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
BIN
FSFlightLogger/Resources/Images/Recording.png
Normal file
BIN
FSFlightLogger/Resources/Images/Recording.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
7
FSFlightLogger/packages.config
Normal file
7
FSFlightLogger/packages.config
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Bcl.AsyncInterfaces" version="1.0.0" targetFramework="net472" />
|
||||
<package id="SimpleInjector" version="5.0.3" targetFramework="net472" />
|
||||
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.2" targetFramework="net472" />
|
||||
<package id="System.Threading.Tasks.Extensions" version="4.5.2" targetFramework="net472" />
|
||||
</packages>
|
6
FSFlightLoggerCmd/App.config
Normal file
6
FSFlightLoggerCmd/App.config
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
|
||||
</startup>
|
||||
</configuration>
|
86
FSFlightLoggerCmd/FSFlightLoggerCmd.csproj
Normal file
86
FSFlightLoggerCmd/FSFlightLoggerCmd.csproj
Normal file
@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProjectGuid>{767C7EAA-9230-4DEE-89FA-9699288C831B}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>FSFlightLoggerCmd</RootNamespace>
|
||||
<AssemblyName>FSFlightLoggerCmd</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="CommandLine, Version=2.8.0.0, Culture=neutral, PublicKeyToken=5a870481e358d379, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\CommandLineParser.2.8.0\lib\net461\CommandLine.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FlightLoggerLib\FlightLoggerLib.csproj">
|
||||
<Project>{D85BCC97-F653-4286-98D9-073A33A55857}</Project>
|
||||
<Name>FlightLoggerLib</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SimConnect\SimConnect.csproj">
|
||||
<Project>{f160bb6a-7620-41e5-a99c-948c208875e4}</Project>
|
||||
<Name>SimConnect</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
216
FSFlightLoggerCmd/Program.cs
Normal file
216
FSFlightLoggerCmd/Program.cs
Normal file
@ -0,0 +1,216 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using CommandLine;
|
||||
using FlightLoggerLib;
|
||||
using FlightLoggerLib.Concrete;
|
||||
using SimConnect;
|
||||
using SimConnect.Attribute;
|
||||
using SimConnect.Concrete;
|
||||
using SimConnect.Lib;
|
||||
|
||||
namespace FSFlightLoggerCmd
|
||||
{
|
||||
// TODO verb for converting CSV to KML
|
||||
|
||||
|
||||
public class PositionData
|
||||
{
|
||||
[SimConnectVariable("PLANE LATITUDE", "degrees")]
|
||||
public float Latitude;
|
||||
|
||||
[SimConnectVariable("PLANE LONGITUDE", "degrees")]
|
||||
public float Longitude;
|
||||
|
||||
[SimConnectVariable("PLANE ALTITUDE", "feet")]
|
||||
public float Altitude;
|
||||
|
||||
[SimConnectVariable("AIRSPEED INDICATED", "knots")]
|
||||
public float Airspeed;
|
||||
}
|
||||
|
||||
|
||||
public class Program
|
||||
{
|
||||
private enum OutputFormat
|
||||
{
|
||||
None,
|
||||
CSV,
|
||||
KML
|
||||
};
|
||||
|
||||
|
||||
// ReSharper disable once ClassNeverInstantiated.Local - used by CommandLineParser
|
||||
// ReSharper disable UnusedAutoPropertyAccessor.Local - used by CommandLineParser
|
||||
private class Options
|
||||
{
|
||||
[Option('o', "outputPath", Required = false, HelpText = "Specifies the output path for the log files. Defaults to a 'Flight logs' folder on the desktop.")]
|
||||
public string OutputPath { get; set; }
|
||||
|
||||
[Option('i', "interval", Required = false, Default = 1, HelpText = "The minimum time, in seconds, between log entries.")]
|
||||
public int IntervalTime { get; set; }
|
||||
|
||||
[Option('d', "distance", Required = false, Default = 1, HelpText = "The minimum distance, in meters, between log entries.")]
|
||||
public int IntervalDistance { get; set; }
|
||||
|
||||
[Option('v', "verbose", Required = false, HelpText = "Enable verbose logging.")]
|
||||
public bool Verbose { get; set; }
|
||||
|
||||
[Option('f', "format", Required = false, Default = OutputFormat.CSV, HelpText = "The output format to use. Possible values: CSV, KML.")]
|
||||
public OutputFormat OutputFormat { get; set; }
|
||||
|
||||
[Option('s', "format2", Required = false, Default = OutputFormat.None, HelpText = "The secondary output format to use. Possible values: None, CSV, KML.")]
|
||||
public OutputFormat OutputFormat2 { get; set; }
|
||||
}
|
||||
// ReSharper restore UnusedAutoPropertyAccessor.Local
|
||||
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var parser = new Parser(settings =>
|
||||
{
|
||||
settings.CaseInsensitiveEnumValues = true;
|
||||
});
|
||||
|
||||
parser.ParseArguments<Options>(args)
|
||||
.WithParsed(Run);
|
||||
}
|
||||
|
||||
private static void Run(Options o)
|
||||
{
|
||||
var intervalTime = TimeSpan.FromSeconds(o.IntervalTime);
|
||||
void VerboseLog(string message)
|
||||
{
|
||||
if (o.Verbose)
|
||||
Console.WriteLine(message);
|
||||
}
|
||||
|
||||
|
||||
var factory = new SimConnectClientFactory();
|
||||
var client = TryConnect(factory).Result;
|
||||
|
||||
var outputPath = o.OutputPath;
|
||||
if (string.IsNullOrEmpty(outputPath))
|
||||
outputPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "Flight logs");
|
||||
|
||||
|
||||
Directory.CreateDirectory(outputPath);
|
||||
var loggers = new List<IFlightLogger>();
|
||||
AddLogger(loggers, o.OutputFormat, outputPath);
|
||||
|
||||
if (o.OutputFormat2 != o.OutputFormat)
|
||||
AddLogger(loggers, o.OutputFormat2, outputPath);
|
||||
|
||||
|
||||
var lastTime = DateTime.MinValue;
|
||||
var lastData = new PositionData
|
||||
{
|
||||
Latitude = 0,
|
||||
Longitude = 0,
|
||||
Altitude = 0,
|
||||
Airspeed = 0
|
||||
};
|
||||
|
||||
|
||||
client.AddDefinition<PositionData>(data =>
|
||||
{
|
||||
// TODO take vertical position into account when going straight up or down (not a common use case, but still)
|
||||
var distanceMeters = LatLon.DistanceBetweenInMeters(lastData.Latitude, lastData.Longitude, data.Latitude, data.Longitude);
|
||||
if (distanceMeters < o.IntervalDistance)
|
||||
{
|
||||
if (data.Airspeed < 0.1)
|
||||
data.Airspeed = 0;
|
||||
|
||||
// Make an exception if we were last moving and have now stopped, so the 0 velocity record is logged as well
|
||||
if (data.Airspeed > 0 || lastData.Airspeed == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
var now = DateTime.Now;
|
||||
var time = now - lastTime;
|
||||
if (time < intervalTime)
|
||||
return;
|
||||
|
||||
VerboseLog("Logging position, elapsed time: " + time.TotalSeconds + ", distance: " + distanceMeters);
|
||||
|
||||
lastTime = now;
|
||||
lastData = data;
|
||||
|
||||
// ReSharper disable once AccessToDisposedClosure - covered by disposing the client first
|
||||
loggers.ForEach(logger =>
|
||||
logger.LogPosition(now, new FlightPosition
|
||||
{
|
||||
Latitude = data.Latitude,
|
||||
Longitude = data.Longitude,
|
||||
Altitude = data.Altitude,
|
||||
Airspeed = data.Airspeed
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
var stopEvent = new ManualResetEventSlim(false);
|
||||
Console.CancelKeyPress += (sender, args) =>
|
||||
{
|
||||
stopEvent.Set();
|
||||
args.Cancel = true;
|
||||
};
|
||||
|
||||
Console.WriteLine("Flight log active, press Ctrl-C to stop");
|
||||
Console.WriteLine("Output path: " + outputPath);
|
||||
stopEvent.Wait(Timeout.Infinite);
|
||||
|
||||
Console.WriteLine("Closing...");
|
||||
client.Dispose();
|
||||
loggers.ForEach(logger => logger.Dispose());
|
||||
|
||||
if (!Debugger.IsAttached)
|
||||
return;
|
||||
|
||||
Console.WriteLine("Press any Enter key to continue");
|
||||
Console.ReadLine();
|
||||
}
|
||||
|
||||
|
||||
private static void AddLogger(ICollection<IFlightLogger> loggers, OutputFormat outputFormat, string outputPath)
|
||||
{
|
||||
switch (outputFormat)
|
||||
{
|
||||
case OutputFormat.CSV:
|
||||
loggers.Add(new CSVFlightLogger(outputPath));
|
||||
break;
|
||||
|
||||
case OutputFormat.KML:
|
||||
loggers.Add(new KMLFlightLogger(outputPath, TimeSpan.FromSeconds(5)));
|
||||
break;
|
||||
|
||||
case OutputFormat.None:
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static async Task<ISimConnectClient> TryConnect(ISimConnectClientFactory factory)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
Console.WriteLine("Attempting to connect to SimConnect...");
|
||||
|
||||
var client = await factory.TryConnect("FS Flight Logger");
|
||||
if (client != null)
|
||||
{
|
||||
Console.WriteLine("Success!");
|
||||
return client;
|
||||
}
|
||||
|
||||
Console.WriteLine("Failed to connect, retrying in 5 seconds");
|
||||
await Task.Delay(TimeSpan.FromSeconds(5));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
36
FSFlightLoggerCmd/Properties/AssemblyInfo.cs
Normal file
36
FSFlightLoggerCmd/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("FSFlightLoggerCmd")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("FSFlightLoggerCmd")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2020")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("767c7eaa-9230-4dee-89fa-9699288c831b")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
4
FSFlightLoggerCmd/packages.config
Normal file
4
FSFlightLoggerCmd/packages.config
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="CommandLineParser" version="2.8.0" targetFramework="net472" />
|
||||
</packages>
|
71
FlightLoggerLib/Concrete/CSVFlightLogger.cs
Normal file
71
FlightLoggerLib/Concrete/CSVFlightLogger.cs
Normal file
@ -0,0 +1,71 @@
|
||||
using CsvHelper;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using CsvHelper.Configuration;
|
||||
using CsvHelper.Configuration.Attributes;
|
||||
|
||||
namespace FlightLoggerLib.Concrete
|
||||
{
|
||||
public class CSVFlightLogger : IFlightLogger
|
||||
{
|
||||
private readonly CsvWriter output;
|
||||
|
||||
|
||||
public CSVFlightLogger(string path)
|
||||
{
|
||||
var filename = Path.Combine(path, DateTime.Now.ToString("yyyy-MM-dd HH.mm.ss") + ".csv");
|
||||
var header = !File.Exists(filename);
|
||||
|
||||
output = new CsvWriter(new StreamWriter(filename, true), new CsvConfiguration(CultureInfo.CurrentCulture)
|
||||
{
|
||||
SanitizeForInjection = false,
|
||||
HasHeaderRecord = header
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
output?.Dispose();
|
||||
}
|
||||
|
||||
|
||||
public async Task LogPosition(DateTime eventTime, FlightPosition position)
|
||||
{
|
||||
var record = new OutputRecord
|
||||
{
|
||||
Time = eventTime,
|
||||
Latitude = position.Latitude,
|
||||
Longitude = position.Longitude,
|
||||
Altitude = position.Altitude,
|
||||
Airspeed = position.Airspeed
|
||||
};
|
||||
|
||||
await output.WriteRecordsAsync(Enumerable.Repeat(record, 1));
|
||||
await output.FlushAsync();
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected class OutputRecord
|
||||
{
|
||||
[Index(0)]
|
||||
public DateTime Time { get; set; }
|
||||
|
||||
[Index(1)]
|
||||
public float Latitude { get; set; }
|
||||
|
||||
[Index(2)]
|
||||
public float Longitude { get; set; }
|
||||
|
||||
[Index(3)]
|
||||
public float Altitude { get; set; }
|
||||
|
||||
[Index(4)]
|
||||
public float Airspeed { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
208
FlightLoggerLib/Concrete/KMLFlightLogger.cs
Normal file
208
FlightLoggerLib/Concrete/KMLFlightLogger.cs
Normal file
@ -0,0 +1,208 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
using SharpKml.Base;
|
||||
using SharpKml.Dom;
|
||||
|
||||
namespace FlightLoggerLib.Concrete
|
||||
{
|
||||
public class KMLFlightLogger : IFlightLogger
|
||||
{
|
||||
private readonly string filename;
|
||||
private readonly System.TimeSpan flushInterval;
|
||||
private readonly Document output;
|
||||
private readonly Folder rootFolder;
|
||||
private readonly LineString positionPath;
|
||||
|
||||
private DateTime lastFlush = DateTime.MinValue;
|
||||
private Vector lastPosition;
|
||||
private float lastSpeed;
|
||||
private DateTime lastPointDate = DateTime.MinValue;
|
||||
|
||||
|
||||
public KMLFlightLogger(string path, System.TimeSpan flushInterval)
|
||||
{
|
||||
var dateString = DateTime.Now.ToString("yyyy-MM-dd HH.mm.ss");
|
||||
filename = Path.Combine(path, dateString + ".kml");
|
||||
this.flushInterval = flushInterval;
|
||||
|
||||
|
||||
// Create folder
|
||||
rootFolder = new Folder
|
||||
{
|
||||
Name = dateString,
|
||||
Open = true
|
||||
};
|
||||
|
||||
|
||||
// Create flight path line and placemark
|
||||
positionPath = new LineString
|
||||
{
|
||||
Tessellate = false,
|
||||
AltitudeMode = AltitudeMode.Absolute,
|
||||
Coordinates = new CoordinateCollection()
|
||||
};
|
||||
|
||||
var positionPlacemark = new Placemark
|
||||
{
|
||||
Name = "Flight path",
|
||||
StyleUrl = new Uri("#flightpath", UriKind.Relative),
|
||||
Geometry = positionPath
|
||||
};
|
||||
|
||||
rootFolder.AddFeature(positionPlacemark);
|
||||
|
||||
output = new Document();
|
||||
|
||||
AddFlightPathStyleMap();
|
||||
|
||||
var paddleHotspot = new Hotspot { X = 31, XUnits = Unit.Pixel, Y = 1, YUnits = Unit.Pixel };
|
||||
AddIconStyleMap("start", 1.1, "http://maps.google.com/mapfiles/kml/paddle/grn-circle.png", "http://maps.google.com/mapfiles/kml/paddle/grn-circle-lv.png", paddleHotspot);
|
||||
AddIconStyleMap("end", 1.1, "http://maps.google.com/mapfiles/kml/paddle/red-square.png", "http://maps.google.com/mapfiles/kml/paddle/red-square-lv.png", paddleHotspot);
|
||||
AddIconStyleMap("fullstop", 1.1, "http://maps.google.com/mapfiles/kml/shapes/placemark_circle.png", null, paddleHotspot);
|
||||
|
||||
output.AddFeature(rootFolder);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (lastPosition != null)
|
||||
AddPoint(lastPosition, "End", "end");
|
||||
|
||||
Flush().Wait();
|
||||
}
|
||||
|
||||
|
||||
protected async Task AutoFlush()
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
var diff = now - lastFlush;
|
||||
|
||||
if (diff < flushInterval)
|
||||
return;
|
||||
|
||||
await Flush();
|
||||
lastFlush = now;
|
||||
}
|
||||
|
||||
protected async Task Flush()
|
||||
{
|
||||
var serializer = new Serializer();
|
||||
serializer.Serialize(output);
|
||||
|
||||
using (var writer = new StreamWriter(filename))
|
||||
{
|
||||
await writer.WriteAsync(serializer.Xml);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void AddFlightPathStyleMap()
|
||||
{
|
||||
var styleMap = new StyleMapCollection { Id = "flightpath" };
|
||||
styleMap.Add(new Pair { State = StyleState.Normal, StyleUrl = new Uri("flightpath-normal", UriKind.Relative) });
|
||||
styleMap.Add(new Pair { State = StyleState.Highlight, StyleUrl = new Uri("flightpath-normal", UriKind.Relative) });
|
||||
|
||||
var styleNormal = new Style
|
||||
{
|
||||
Id = "flightpath-normal",
|
||||
Line = new LineStyle
|
||||
{
|
||||
Color = new Color32(255, 10, 10, 138),
|
||||
Width = 5
|
||||
}
|
||||
};
|
||||
|
||||
output.AddStyle(styleMap);
|
||||
output.AddStyle(styleNormal);
|
||||
}
|
||||
|
||||
|
||||
protected void AddIconStyleMap(string id, double scale, string iconUrl, string listUrl, Hotspot iconHotspot = null)
|
||||
{
|
||||
var styleMap = new StyleMapCollection { Id = id };
|
||||
styleMap.Add(new Pair { State = StyleState.Normal, StyleUrl = new Uri(id + "-normal", UriKind.Relative) });
|
||||
styleMap.Add(new Pair { State = StyleState.Highlight, StyleUrl = new Uri(id + "-normal", UriKind.Relative) });
|
||||
|
||||
var styleNormal = new Style
|
||||
{
|
||||
Id = id + "-normal",
|
||||
Icon = new IconStyle
|
||||
{
|
||||
Scale = scale,
|
||||
Icon = new IconStyle.IconLink(new Uri(iconUrl, UriKind.Absolute)),
|
||||
Hotspot = iconHotspot
|
||||
},
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(listUrl))
|
||||
{
|
||||
styleNormal.List = new ListStyle();
|
||||
styleNormal.List.AddItemIcon(new ItemIcon
|
||||
{
|
||||
Href = new Uri(listUrl, UriKind.Absolute)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
output.AddStyle(styleMap);
|
||||
output.AddStyle(styleNormal);
|
||||
}
|
||||
|
||||
|
||||
protected string GetPointDate()
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
|
||||
// If the date hasn't changed since the last point label, just return the time
|
||||
if (now.Date == lastPointDate)
|
||||
return now.ToString("T");
|
||||
|
||||
lastPointDate = now.Date;
|
||||
return now.ToString("F");
|
||||
}
|
||||
|
||||
|
||||
protected void AddPoint(Vector coordinate, string label, string styleMapId, bool includeTimestamp = true)
|
||||
{
|
||||
var point = new Point { Coordinate = coordinate, AltitudeMode = AltitudeMode.Absolute };
|
||||
|
||||
var placemark = new Placemark
|
||||
{
|
||||
Name = includeTimestamp ? $"{label} ({GetPointDate()})" : label,
|
||||
StyleUrl = new Uri("#" + styleMapId, UriKind.Relative),
|
||||
Geometry = point,
|
||||
Visibility = true
|
||||
};
|
||||
|
||||
rootFolder.AddFeature(placemark);
|
||||
}
|
||||
|
||||
|
||||
private const float MetersPerFoot = 0.3048f;
|
||||
|
||||
|
||||
public async Task LogPosition(DateTime eventTime, FlightPosition position)
|
||||
{
|
||||
var altitudeMeters = position.Altitude * MetersPerFoot;
|
||||
var coordinate = new Vector(position.Latitude, position.Longitude, altitudeMeters);
|
||||
|
||||
if (lastPosition == null)
|
||||
AddPoint(coordinate, "Start", "start");
|
||||
|
||||
if (lastSpeed > 0 && position.Airspeed == 0)
|
||||
AddPoint(coordinate, "Full stop", "fullstop");
|
||||
|
||||
lastPosition = coordinate;
|
||||
lastSpeed = position.Airspeed;
|
||||
|
||||
positionPath.Coordinates.Add(coordinate);
|
||||
|
||||
await AutoFlush();
|
||||
}
|
||||
|
||||
|
||||
// TODO log events, engine stop etc.
|
||||
}
|
||||
}
|
95
FlightLoggerLib/FlightLoggerLib.csproj
Normal file
95
FlightLoggerLib/FlightLoggerLib.csproj
Normal file
@ -0,0 +1,95 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{D85BCC97-F653-4286-98D9-073A33A55857}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>FlightLoggerLib</RootNamespace>
|
||||
<AssemblyName>FlightLoggerLib</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="CsvHelper, Version=15.0.0.0, Culture=neutral, PublicKeyToken=8c4959082be5c823, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\CsvHelper.15.0.5\lib\net47\CsvHelper.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Ionic.Zip.Reduced, Version=1.9.1.8, Culture=neutral, PublicKeyToken=edbe51ad942a3f5c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\DotNetZip.Reduced.1.9.1.8\lib\net20\Ionic.Zip.Reduced.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.1\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SharpKml.Core, Version=5.1.3.0, Culture=neutral, PublicKeyToken=9bb853c026a5c0ac, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SharpKml.Core.5.1.3\lib\net45\SharpKml.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.IO.Compression" />
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.6.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Concrete\KMLFlightLogger.cs" />
|
||||
<Compile Include="Concrete\CSVFlightLogger.cs" />
|
||||
<Compile Include="IFlightLogger.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
21
FlightLoggerLib/IFlightLogger.cs
Normal file
21
FlightLoggerLib/IFlightLogger.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FlightLoggerLib
|
||||
{
|
||||
public class FlightPosition
|
||||
{
|
||||
public float Latitude { get; set; }
|
||||
public float Longitude { get; set; }
|
||||
public float Altitude { get; set; }
|
||||
public float Airspeed { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
public interface IFlightLogger : IDisposable
|
||||
{
|
||||
Task LogPosition(DateTime eventTime, FlightPosition position);
|
||||
//void LogEvent
|
||||
}
|
||||
}
|
36
FlightLoggerLib/Properties/AssemblyInfo.cs
Normal file
36
FlightLoggerLib/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("FlightLoggerLib")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("FlightLoggerLib")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2020")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("d85bcc97-f653-4286-98d9-073a33a55857")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
15
FlightLoggerLib/app.config
Normal file
15
FlightLoggerLib/app.config
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.0.1" newVersion="4.2.0.1" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.6.0" newVersion="4.0.6.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
11
FlightLoggerLib/packages.config
Normal file
11
FlightLoggerLib/packages.config
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="CsvHelper" version="15.0.5" targetFramework="net472" />
|
||||
<package id="DotNetZip.Reduced" version="1.9.1.8" targetFramework="net472" />
|
||||
<package id="Microsoft.Bcl.AsyncInterfaces" version="1.1.1" targetFramework="net472" />
|
||||
<package id="Microsoft.CSharp" version="4.7.0" targetFramework="net472" />
|
||||
<package id="SharpKml.Core" version="5.1.3" targetFramework="net472" />
|
||||
<package id="System.Runtime.CompilerServices.Unsafe" version="4.7.1" targetFramework="net472" />
|
||||
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net472" />
|
||||
<package id="System.Xml.XDocument" version="4.3.0" targetFramework="net472" />
|
||||
</packages>
|
11
README.md
Normal file
11
README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# FSFlightLogger
|
||||
|
||||
Log flight paths and other information to CSV or Google Earth KML files.
|
||||
|
||||
Works with SimConnect compatible simulators, including Microsoft Flight Simulator X and 2020 (not 2004 and earlier) and Lockheed Martin's Prepar3D.
|
||||
|
||||
32-bits builds uses the SimConnect clients up to Flight Simulator X, which will work with Flight Simulator 2020. 64-bits builds can only work with the Flight Simulator 2020 SimConnect client and is not compatible with earlier Flight Simualtors.
|
||||
|
||||
|
||||
This project is in it's infancy. A working command-line version is implemented as a proof of concept, a proper UI with more features is in development.
|
||||
It also includes a (far from incomplete) C# wrapper for the native SimConnect DLL instead of using the default managed wrapper, as it allowed for easier switching between versions.
|
60
SimConnect/Attribute/SimConnectVariableAttribute.cs
Normal file
60
SimConnect/Attribute/SimConnectVariableAttribute.cs
Normal file
@ -0,0 +1,60 @@
|
||||
namespace SimConnect.Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates the property should be registered as a SimConnect variable in the definition to receive updates.
|
||||
/// </summary>
|
||||
public class SimConnectVariableAttribute : System.Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the SimConnect variable
|
||||
/// </summary>
|
||||
public string VariableName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The SimConnect data type. If null, the SimConnect data type will be determined from the .NET type.
|
||||
/// </summary>
|
||||
public SimConnectDataType? DataType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The requested units for the value. See the SimConnect documentation for available units
|
||||
/// </summary>
|
||||
public string UnitsName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// For integer and floating point types, determines how much the value must change before an update is sent
|
||||
/// </summary>
|
||||
public float Epsilon { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Indicates the property should be registered as a SimConnect variable in the definition to receive updates.
|
||||
/// </summary>
|
||||
/// <param name="variableName">The name of the SimConnect variable</param>
|
||||
/// <param name="dataType">The SimConnect data type. If null, the SimConnect data type will be determined from the .NET type.</param>
|
||||
/// <param name="unitsName">The requested units for the value. See the SimConnect documentation for available units</param>
|
||||
/// <param name="epsilon">For integer and floating point types, determines how much the value must change before an update is sent</param>
|
||||
public SimConnectVariableAttribute(string variableName, SimConnectDataType dataType, string unitsName = "", float epsilon = 0)
|
||||
{
|
||||
VariableName = variableName;
|
||||
DataType = dataType;
|
||||
UnitsName = unitsName;
|
||||
Epsilon = epsilon;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Indicates the property should be registered as a SimConnect variable in the definition to receive updates.
|
||||
/// </summary>
|
||||
/// <param name="variableName">The name of the SimConnect variable</param>
|
||||
/// <param name="unitsName">The requested units for the value. See the SimConnect documentation for available units</param>
|
||||
/// <param name="epsilon">For integer and floating point types, determines how much the value must change before an update is sent</param>
|
||||
public SimConnectVariableAttribute(string variableName, string unitsName = "", float epsilon = 0)
|
||||
{
|
||||
VariableName = variableName;
|
||||
DataType = null;
|
||||
UnitsName = unitsName;
|
||||
Epsilon = epsilon;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
272
SimConnect/Concrete/DefaultSimConnectClient.cs
Normal file
272
SimConnect/Concrete/DefaultSimConnectClient.cs
Normal file
@ -0,0 +1,272 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
namespace SimConnect.Concrete
|
||||
{
|
||||
/// <summary>
|
||||
/// Default implementation of ISimConnectClient. Compatible with Flight Simulator 2020, X Stream Edition, X and Prepar3D.
|
||||
/// Requires the following DLL files to be present: FSX2020-SimConnect.dll, FSX-SE-SimConnect.dll, FSX-SE-SimConnect.dll, FSX-SimConnect.dll.
|
||||
/// These are renamed versions of the SimConnect.dll from the various flight simulator installations.
|
||||
/// </summary>
|
||||
public class DefaultSimConnectClient : ISimConnectClient, IDisposable
|
||||
{
|
||||
private readonly ISimConnectLibrary simConnectLibrary;
|
||||
private SimConnectWorker worker;
|
||||
|
||||
private uint nextDefinitionID = 1;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of DefaultSimConnectClient.
|
||||
/// </summary>
|
||||
/// <param name="simConnectLibrary">The low-level SimConnect library interface to use</param>
|
||||
public DefaultSimConnectClient(ISimConnectLibrary simConnectLibrary)
|
||||
{
|
||||
this.simConnectLibrary = simConnectLibrary;
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
worker?.Close().Wait();
|
||||
simConnectLibrary?.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to open a connection to the SimConnect server
|
||||
/// </summary>
|
||||
/// <param name="appName">The application name passed to the SimConnect server.</param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> TryOpen(string appName)
|
||||
{
|
||||
if (worker != null)
|
||||
await worker.Close();
|
||||
|
||||
worker = new SimConnectWorker(simConnectLibrary, appName);
|
||||
return await worker.Open();
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public void AttachObserver(ISimConnectClientObserver observer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public IDisposable AddDefinition<T>(SimConnectDataHandlerAction<T> onData) where T : class
|
||||
{
|
||||
if (worker == null)
|
||||
throw new InvalidOperationException("TryOpen must be called first");
|
||||
|
||||
var definition = new SimConnectDefinition(typeof(T));
|
||||
void HandleData(Stream stream)
|
||||
{
|
||||
var data = definition.ParseData(stream);
|
||||
onData((T)data);
|
||||
}
|
||||
|
||||
var definitionRegistration = new SimConnectDefinitionRegistration<T>(nextDefinitionID, definition, HandleData, worker);
|
||||
nextDefinitionID++;
|
||||
|
||||
return definitionRegistration;
|
||||
}
|
||||
|
||||
|
||||
private class SimConnectDefinitionRegistration<T> : IDisposable where T : class
|
||||
{
|
||||
private readonly uint definitionID;
|
||||
private readonly SimConnectWorker worker;
|
||||
|
||||
|
||||
public SimConnectDefinitionRegistration(uint definitionID, SimConnectDefinition definition, Action<Stream> onData, SimConnectWorker worker)
|
||||
{
|
||||
this.definitionID = definitionID;
|
||||
this.worker = worker;
|
||||
|
||||
worker.RegisterDefinition(definitionID, definition, onData);
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
worker.UnregisterDefinition(definitionID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class SimConnectWorker
|
||||
{
|
||||
private readonly ISimConnectLibrary simConnectLibrary;
|
||||
private readonly string appName;
|
||||
|
||||
private Task workerTask;
|
||||
|
||||
private readonly AutoResetEvent workerPulse = new AutoResetEvent(false);
|
||||
private readonly object workerLock = new object();
|
||||
private volatile bool closed;
|
||||
private readonly Queue<Action<IntPtr>> workQueue = new Queue<Action<IntPtr>>();
|
||||
|
||||
private readonly TaskCompletionSource<bool> openResult = new TaskCompletionSource<bool>();
|
||||
private readonly ConcurrentDictionary<uint, Action<Stream>> definitionDataHandler = new ConcurrentDictionary<uint, Action<Stream>>();
|
||||
|
||||
|
||||
public SimConnectWorker(ISimConnectLibrary simConnectLibrary, string appName)
|
||||
{
|
||||
this.simConnectLibrary = simConnectLibrary;
|
||||
this.appName = appName;
|
||||
}
|
||||
|
||||
|
||||
public async Task<bool> Open()
|
||||
{
|
||||
if (workerTask == null)
|
||||
workerTask = Task.Run(RunInBackground);
|
||||
|
||||
return await openResult.Task;
|
||||
}
|
||||
|
||||
|
||||
public async Task Close()
|
||||
{
|
||||
closed = true;
|
||||
|
||||
workerPulse.Set();
|
||||
await workerTask;
|
||||
}
|
||||
|
||||
|
||||
public void RegisterDefinition(uint definitionID, SimConnectDefinition definition, Action<Stream> onData)
|
||||
{
|
||||
Enqueue(hSimConnect =>
|
||||
{
|
||||
foreach (var variable in definition.Variables)
|
||||
{
|
||||
simConnectLibrary.SimConnect_AddToDataDefinition(hSimConnect, definitionID, variable.VariableName, variable.UnitsName,
|
||||
variable.DataType, variable.Epsilon);
|
||||
}
|
||||
|
||||
definitionDataHandler.AddOrUpdate(definitionID, onData, (key, value) => onData);
|
||||
simConnectLibrary.SimConnect_RequestDataOnSimObject(hSimConnect, definitionID, definitionID, 0, SimConnectPeriod.SimFrame, 1);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void UnregisterDefinition(uint definitionID)
|
||||
{
|
||||
Enqueue(hSimConnect =>
|
||||
{
|
||||
definitionDataHandler.TryRemove(definitionID, out var unused);
|
||||
simConnectLibrary.SimConnect_ClearDataDefinition(hSimConnect, definitionID);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void Enqueue(Action<IntPtr> work)
|
||||
{
|
||||
lock(workerLock)
|
||||
{
|
||||
workQueue.Enqueue(work);
|
||||
}
|
||||
|
||||
workerPulse.Set();
|
||||
}
|
||||
|
||||
|
||||
private void RunInBackground()
|
||||
{
|
||||
var dataEvent = new EventWaitHandle(false, EventResetMode.AutoReset);
|
||||
|
||||
var errorCode = simConnectLibrary.SimConnect_Open(out var simConnectHandle, appName, IntPtr.Zero, 0, dataEvent.SafeWaitHandle.DangerousGetHandle(), 0);
|
||||
openResult.TrySetResult(errorCode == 0);
|
||||
|
||||
if (errorCode != 0)
|
||||
return;
|
||||
|
||||
|
||||
while(!closed)
|
||||
{
|
||||
switch (WaitHandle.WaitAny(new WaitHandle[] { workerPulse, dataEvent }))
|
||||
{
|
||||
case 0:
|
||||
HandleWorkQueue(simConnectHandle);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
HandleData(ref simConnectHandle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (simConnectHandle != IntPtr.Zero)
|
||||
simConnectLibrary.SimConnect_Close(simConnectHandle);
|
||||
}
|
||||
|
||||
|
||||
private void HandleWorkQueue(IntPtr simConnectHandle)
|
||||
{
|
||||
while (!closed)
|
||||
{
|
||||
Action<IntPtr> work;
|
||||
|
||||
lock(workerLock)
|
||||
{
|
||||
work = workQueue.Count > 0 ? workQueue.Dequeue() : null;
|
||||
}
|
||||
|
||||
if (work == null)
|
||||
break;
|
||||
|
||||
work(simConnectHandle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void HandleData(ref IntPtr simConnectHandle)
|
||||
{
|
||||
while (!closed && simConnectLibrary.SimConnect_GetNextDispatch(simConnectHandle, out var dataPtr, out var dataSize) == 0)
|
||||
{
|
||||
var recv = Marshal.PtrToStructure<SimConnectRecv>(dataPtr);
|
||||
|
||||
// ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault
|
||||
switch ((SimConnectRecvID) recv.dwID)
|
||||
{
|
||||
case SimConnectRecvID.Exception:
|
||||
var recvException = Marshal.PtrToStructure<SimConnectRecvException>(dataPtr);
|
||||
if (recvException.dwException == 0)
|
||||
break;
|
||||
|
||||
break;
|
||||
|
||||
case SimConnectRecvID.SimobjectData:
|
||||
case SimConnectRecvID.SimobjectDataByType:
|
||||
var recvSimobjectData = Marshal.PtrToStructure<SimConnectRecvSimobjectData>(dataPtr);
|
||||
if (!definitionDataHandler.TryGetValue((uint)recvSimobjectData.dwDefineID, out var dataHandler))
|
||||
break;
|
||||
|
||||
unsafe
|
||||
{
|
||||
var streamOffset = Marshal.OffsetOf<SimConnectRecvSimobjectData>("dwData").ToInt32();
|
||||
var stream = new UnmanagedMemoryStream((byte*)IntPtr.Add(dataPtr, streamOffset).ToPointer(), (long)dataSize - streamOffset);
|
||||
dataHandler(stream);
|
||||
}
|
||||
break;
|
||||
|
||||
case SimConnectRecvID.Quit:
|
||||
simConnectHandle = IntPtr.Zero;
|
||||
closed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
34
SimConnect/Concrete/SimConnectClientFactory.cs
Normal file
34
SimConnect/Concrete/SimConnectClientFactory.cs
Normal file
@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using SimConnect.Unmanaged;
|
||||
|
||||
namespace SimConnect.Concrete
|
||||
{
|
||||
/// <summary>
|
||||
/// Default implementation of ISimConnectClientFactory
|
||||
/// </summary>
|
||||
public class SimConnectClientFactory : ISimConnectClientFactory
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public async Task<ISimConnectClient> TryConnect(string appName)
|
||||
{
|
||||
// FS 2020 SimConnect.dll is 64-bits, the others are 32-bits
|
||||
if (Environment.Is64BitProcess)
|
||||
return await TryDefaultClient(appName, "FS2020-SimConnect.dll");
|
||||
|
||||
// This order prevents a version mismatch, but perhaps an option to explicitly set the version might be nice as well
|
||||
return await TryDefaultClient(appName, "FSX-SimConnect.dll")
|
||||
?? await TryDefaultClient(appName, "FSXSP2-SimConnect.dll")
|
||||
?? await TryDefaultClient(appName, "FSX-SE-SimConnect.dll");
|
||||
}
|
||||
|
||||
|
||||
private static async Task<ISimConnectClient> TryDefaultClient(string appName, string libraryFilename)
|
||||
{
|
||||
var library = new SimConnectDLLLibrary(libraryFilename);
|
||||
var client = new DefaultSimConnectClient(library);
|
||||
|
||||
return await client.TryOpen(appName) ? client : null;
|
||||
}
|
||||
}
|
||||
}
|
197
SimConnect/Concrete/SimConnectDefinition.cs
Normal file
197
SimConnect/Concrete/SimConnectDefinition.cs
Normal file
@ -0,0 +1,197 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using SimConnect.Attribute;
|
||||
|
||||
namespace SimConnect.Concrete
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a SimConnect variable.
|
||||
/// </summary>
|
||||
public struct SimConnectVariable
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the SimConnect variable
|
||||
/// </summary>
|
||||
public string VariableName;
|
||||
|
||||
/// <summary>
|
||||
/// The SimConnect data type. If null, the SimConnect data type will be determined from the .NET type.
|
||||
/// </summary>
|
||||
public SimConnectDataType DataType;
|
||||
|
||||
/// <summary>
|
||||
/// The requested units for the value. See the SimConnect documentation for available units
|
||||
/// </summary>
|
||||
public string UnitsName;
|
||||
|
||||
/// <summary>
|
||||
/// For integer and floating point types, determines how much the value must change before an update is sent
|
||||
/// </summary>
|
||||
public float Epsilon;
|
||||
};
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a SimConnect definition from properties annotated with the SimConnectVariable attribute.
|
||||
/// </summary>
|
||||
public class SimConnectDefinition
|
||||
{
|
||||
private readonly Type type;
|
||||
|
||||
private delegate void SetterProc(object instance, BinaryReader data);
|
||||
|
||||
private struct SimConnectVariableProperty
|
||||
{
|
||||
public SimConnectVariable Variable;
|
||||
public SetterProc Setter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides access to the parsed variables.
|
||||
/// </summary>
|
||||
public IEnumerable<SimConnectVariable> Variables => variables.Select(v => v.Variable);
|
||||
|
||||
private readonly List<SimConnectVariableProperty> variables;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of a SimConnectDefinition based on the provided class.
|
||||
/// </summary>
|
||||
/// <param name="type">The class type used for the definition</param>
|
||||
public SimConnectDefinition(Type type)
|
||||
{
|
||||
if (!type.IsClass)
|
||||
throw new InvalidOperationException($"{type.FullName} is not a class type");
|
||||
|
||||
this.type = type;
|
||||
variables = ParseVariables(type);
|
||||
|
||||
if (variables.Count == 0)
|
||||
throw new InvalidOperationException($"At least one property of {type.FullName} should be annotated with the SimConnectVariable attribute");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Parses the SimConnect data stream to an object according to this definition.
|
||||
/// </summary>
|
||||
/// <param name="data">The SimConnect data stream</param>
|
||||
/// <returns>An instance of the type for this definition</returns>
|
||||
public object ParseData(Stream data)
|
||||
{
|
||||
var reader = new BinaryReader(data);
|
||||
var instance = Activator.CreateInstance(type);
|
||||
|
||||
foreach (var variable in variables)
|
||||
variable.Setter(instance, reader);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
private static List<SimConnectVariableProperty> ParseVariables(IReflect type)
|
||||
{
|
||||
var result = new List<SimConnectVariableProperty>();
|
||||
|
||||
foreach (var member in type.GetMembers(BindingFlags.Public | BindingFlags.Instance)
|
||||
.Where(m => m.MemberType == MemberTypes.Field || m.MemberType == MemberTypes.Property))
|
||||
{
|
||||
var variableAttribute = member.GetCustomAttribute<SimConnectVariableAttribute>();
|
||||
if (variableAttribute == null)
|
||||
continue;
|
||||
|
||||
|
||||
var dataType = variableAttribute.DataType;
|
||||
var setter = GetSetter(member, ref dataType);
|
||||
|
||||
if (!dataType.HasValue)
|
||||
throw new InvalidOperationException($"DataType could not be determined for member {member.Name}");
|
||||
|
||||
result.Add(new SimConnectVariableProperty
|
||||
{
|
||||
Variable = new SimConnectVariable
|
||||
{
|
||||
VariableName = variableAttribute.VariableName,
|
||||
DataType = dataType.Value,
|
||||
UnitsName = variableAttribute.UnitsName,
|
||||
Epsilon = variableAttribute.Epsilon
|
||||
},
|
||||
Setter = setter
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private readonly struct SimConnectTypeMapping
|
||||
{
|
||||
public readonly Type Type;
|
||||
public readonly SimConnectDataType SimConnectDataType;
|
||||
public readonly bool IsDefaultForTypeForType;
|
||||
public readonly Func<BinaryReader, object> Converter;
|
||||
|
||||
public SimConnectTypeMapping(Type type, SimConnectDataType simConnectDataType, bool isDefaultForType, Func<BinaryReader, object> converter)
|
||||
{
|
||||
Type = type;
|
||||
SimConnectDataType = simConnectDataType;
|
||||
IsDefaultForTypeForType = isDefaultForType;
|
||||
Converter = converter;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static readonly List<SimConnectTypeMapping> SimConnectTypeMappings = new List<SimConnectTypeMapping>
|
||||
{
|
||||
{ new SimConnectTypeMapping(typeof(double), SimConnectDataType.Float64, true, reader => reader.ReadDouble()) },
|
||||
{ new SimConnectTypeMapping(typeof(float), SimConnectDataType.Float32, true, reader => reader.ReadSingle()) },
|
||||
{ new SimConnectTypeMapping(typeof(int), SimConnectDataType.Int32, true, reader => reader.ReadInt32()) },
|
||||
{ new SimConnectTypeMapping(typeof(uint), SimConnectDataType.Int32, true, reader => reader.ReadUInt32()) },
|
||||
{ new SimConnectTypeMapping(typeof(long), SimConnectDataType.Int64, true, reader => reader.ReadInt64()) },
|
||||
{ new SimConnectTypeMapping(typeof(ulong), SimConnectDataType.Int64, true, reader => reader.ReadUInt64()) }
|
||||
};
|
||||
|
||||
|
||||
private static SetterProc GetSetter(MemberInfo member, ref SimConnectDataType? dataType)
|
||||
{
|
||||
Type valueType;
|
||||
Action<object, object> valueSetter;
|
||||
|
||||
if (member.MemberType == MemberTypes.Field)
|
||||
{
|
||||
var fieldInfo = (FieldInfo)member;
|
||||
valueType = fieldInfo.FieldType;
|
||||
valueSetter = (instance, data) => fieldInfo.SetValue(instance, data);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
var propertyInfo = (PropertyInfo)member;
|
||||
valueType = propertyInfo.PropertyType;
|
||||
valueSetter = (instance, data) => propertyInfo.SetValue(instance, data);
|
||||
}
|
||||
|
||||
|
||||
foreach (var mapping in SimConnectTypeMappings.Where(mapping => mapping.Type == valueType))
|
||||
{
|
||||
if (dataType.HasValue && mapping.SimConnectDataType != dataType)
|
||||
continue;
|
||||
|
||||
if (!dataType.HasValue && !mapping.IsDefaultForTypeForType)
|
||||
continue;
|
||||
|
||||
if (!dataType.HasValue)
|
||||
dataType = mapping.SimConnectDataType;
|
||||
|
||||
return (instance, reader) =>
|
||||
{
|
||||
valueSetter(instance, mapping.Converter(reader));
|
||||
};
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"No mapping exists for type {valueType.FullName} with SimConnect DataType {dataType} for member {member.Name}");
|
||||
}
|
||||
}
|
||||
}
|
BIN
SimConnect/FS2020-SimConnect.dll
Normal file
BIN
SimConnect/FS2020-SimConnect.dll
Normal file
Binary file not shown.
BIN
SimConnect/FSX-SE-SimConnect.dll
Normal file
BIN
SimConnect/FSX-SE-SimConnect.dll
Normal file
Binary file not shown.
BIN
SimConnect/FSX-SimConnect.dll
Normal file
BIN
SimConnect/FSX-SimConnect.dll
Normal file
Binary file not shown.
BIN
SimConnect/FSXSP2-SimConnect.dll
Normal file
BIN
SimConnect/FSXSP2-SimConnect.dll
Normal file
Binary file not shown.
46
SimConnect/ISimConnectClient.cs
Normal file
46
SimConnect/ISimConnectClient.cs
Normal file
@ -0,0 +1,46 @@
|
||||
using System;
|
||||
|
||||
namespace SimConnect
|
||||
{
|
||||
/// <summary>
|
||||
/// Called when new data arrives from the SimConnect server.
|
||||
/// </summary>
|
||||
/// <param name="data">An instance of the data class as passed to AddDefinition containing the variable values</param>
|
||||
/// <typeparam name="T">The data class as passed to AddDefinition</typeparam>
|
||||
public delegate void SimConnectDataHandlerAction<in T>(T data) where T : class;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets notified of changes to the SimConnect state.
|
||||
/// </summary>
|
||||
public interface ISimConnectClientObserver
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets called when the SimConnect connection is lost. The client will not receive further notifications,
|
||||
/// a new connection should be attempted if desired.
|
||||
/// </summary>
|
||||
void OnQuit();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Provides access to the SimConnect library.
|
||||
/// </summary>
|
||||
public interface ISimConnectClient : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Attaches the specified observer to receive status notifications.
|
||||
/// </summary>
|
||||
/// <param name="observer">The observer to receive status notifications</param>
|
||||
void AttachObserver(ISimConnectClientObserver observer);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Registers a definition to receive updates from the SimConnect server.
|
||||
/// </summary>
|
||||
/// <param name="onData">A callback method which is called whenever a data update is received</param>
|
||||
/// <typeparam name="T">A class defining the variables to monitor annotated using the SimConnectVariable attribute</typeparam>
|
||||
/// <returns>An IDisposable which can be disposed to unregister the definition. Dispose is not required to be called when the client is disconnected, but will not throw an exception.</returns>
|
||||
IDisposable AddDefinition<T>(SimConnectDataHandlerAction<T> onData) where T : class;
|
||||
}
|
||||
}
|
17
SimConnect/ISimConnectClientFactory.cs
Normal file
17
SimConnect/ISimConnectClientFactory.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SimConnect
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a factory for creating a SimConnect client instance.
|
||||
/// </summary>
|
||||
public interface ISimConnectClientFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Tries to connect to any of the compatible running SimConnect servers.
|
||||
/// </summary>
|
||||
/// <param name="appName">The application name passed to the SimConnect server.</param>
|
||||
/// <returns>A client interface if succesful or nil if no connection could be made.</returns>
|
||||
Task<ISimConnectClient> TryConnect(string appName);
|
||||
}
|
||||
}
|
186
SimConnect/ISimConnectLibrary.cs
Normal file
186
SimConnect/ISimConnectLibrary.cs
Normal file
@ -0,0 +1,186 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
namespace SimConnect
|
||||
{
|
||||
/// <summary>
|
||||
/// Corresponds to SIMCONNECT_DATAType.
|
||||
/// </summary>
|
||||
public enum SimConnectDataType
|
||||
{
|
||||
/// <summary>
|
||||
/// invalid data Type
|
||||
/// </summary>
|
||||
Invalid = 0,
|
||||
|
||||
/// <summary>
|
||||
/// 32-bit integer number
|
||||
/// </summary>
|
||||
Int32,
|
||||
|
||||
/// <summary>
|
||||
/// 64-bit integer number
|
||||
/// </summary>
|
||||
Int64,
|
||||
|
||||
/// <summary>
|
||||
/// 32-bit floating-point number (Single)
|
||||
/// </summary>
|
||||
Float32,
|
||||
|
||||
/// <summary>
|
||||
/// 64-bit floating-point number (Double)
|
||||
/// </summary>
|
||||
Float64,
|
||||
|
||||
/// <summary>
|
||||
/// 8-byte String
|
||||
/// </summary>
|
||||
String8,
|
||||
|
||||
/// <summary>
|
||||
/// 32-byte String
|
||||
/// </summary>
|
||||
String32,
|
||||
|
||||
/// <summary>
|
||||
/// 64-byte String
|
||||
/// </summary>
|
||||
String64,
|
||||
|
||||
/// <summary>
|
||||
/// 128-byte String
|
||||
/// </summary>
|
||||
String128,
|
||||
|
||||
/// <summary>
|
||||
/// 256-byte String
|
||||
/// </summary>
|
||||
String256,
|
||||
|
||||
/// <summary>
|
||||
/// 260-byte String
|
||||
/// </summary>
|
||||
String260,
|
||||
|
||||
/// <summary>
|
||||
/// variable-length String
|
||||
/// </summary>
|
||||
StringV,
|
||||
|
||||
/// <summary>
|
||||
/// see SIMCONNECT_DATA_INITPOSITION
|
||||
/// </summary>
|
||||
InitPosition,
|
||||
|
||||
/// <summary>
|
||||
/// see SIMCONNECT_DATA_MARKERSTATE
|
||||
/// </summary>
|
||||
MarkerState,
|
||||
|
||||
/// <summary>
|
||||
/// see SIMCONNECT_DATA_WAYPOINT
|
||||
/// </summary>
|
||||
Waypoint,
|
||||
|
||||
/// <summary>
|
||||
/// see SIMCONNECT_DATA_LATLONALT
|
||||
/// </summary>
|
||||
LatLonAlt,
|
||||
|
||||
/// <summary>
|
||||
/// see SIMCONNECT_DATA_XYZ
|
||||
/// </summary>
|
||||
XYZ
|
||||
}
|
||||
|
||||
|
||||
// see SimConnect documentation
|
||||
#pragma warning disable 1591
|
||||
public enum SimConnectPeriod
|
||||
{
|
||||
Never = 0,
|
||||
Once,
|
||||
VisualFrame,
|
||||
SimFrame,
|
||||
Second
|
||||
};
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct SimConnectRecv
|
||||
{
|
||||
public uint dwSize;
|
||||
public uint dwVersion;
|
||||
public uint dwID;
|
||||
}
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct SimConnectRecvException
|
||||
{
|
||||
public SimConnectRecv Recv;
|
||||
|
||||
public uint dwException;
|
||||
public uint dwSendID;
|
||||
public uint dwIndex;
|
||||
}
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct SimConnectRecvSimobjectData
|
||||
{
|
||||
public SimConnectRecv Recv;
|
||||
|
||||
public uint dwRequestID;
|
||||
public uint dwObjectID;
|
||||
public uint dwDefineID;
|
||||
public uint dwFlags; // SIMCONNECT_DATA_REQUEST_FLAG
|
||||
public uint dwentrynumber;
|
||||
// if multiple objects returned, this is number <entrynumber> out of <outof>.
|
||||
public uint dwoutof; // note: starts with 1, not 0.
|
||||
public uint dwDefineCount; // data count (number of datums, *not* byte count)
|
||||
public uint dwData; // data begins here, dwDefineCount data items
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Provides a low-level interface to a compatible SimConnect.dll.
|
||||
/// </summary>
|
||||
public interface ISimConnectLibrary : IDisposable
|
||||
{
|
||||
uint SimConnect_Open(out IntPtr phSimConnect, string szName, IntPtr hwnd, uint userEventWin32, IntPtr hEventHandle, uint configIndex);
|
||||
uint SimConnect_Close(IntPtr hSimConnect);
|
||||
|
||||
uint SimConnect_AddToDataDefinition(IntPtr hSimConnect, uint defineID, string datumName, string unitsName, SimConnectDataType datumType = SimConnectDataType.Float64, float epsilon = 0, uint datumID = uint.MaxValue);
|
||||
uint SimConnect_ClearDataDefinition(IntPtr hSimConnect, uint defineID);
|
||||
|
||||
uint SimConnect_RequestDataOnSimObject(IntPtr hSimConnect, uint requestID, uint defineID, uint objectID, SimConnectPeriod period, uint flags, uint origin = 0, uint interval = 0, uint limit = 0);
|
||||
uint SimConnect_GetNextDispatch(IntPtr hSimConnect, out IntPtr ppData, out uint pcbData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public enum SimConnectRecvID
|
||||
{
|
||||
Null = 0,
|
||||
Exception,
|
||||
Open,
|
||||
Quit,
|
||||
Event,
|
||||
EventObjectAddRemove,
|
||||
EventFilename,
|
||||
EventFrame,
|
||||
SimobjectData,
|
||||
SimobjectDataByType,
|
||||
WeatherObservation,
|
||||
CloudState,
|
||||
AssignedObjectID,
|
||||
ReservedKey,
|
||||
CustomAction,
|
||||
SystemState,
|
||||
ClientData
|
||||
};
|
||||
#pragma warning restore 1591
|
||||
}
|
40
SimConnect/Lib/LatLon.cs
Normal file
40
SimConnect/Lib/LatLon.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
|
||||
namespace SimConnect.Lib
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides helpers methods for latitude / longitude calculations.
|
||||
/// </summary>
|
||||
public static class LatLon
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the approximate radius of the earth in kilometers.
|
||||
/// </summary>
|
||||
public const double EarthRadiusKm = 6378.137;
|
||||
|
||||
|
||||
// Source: https://stackoverflow.com/questions/639695/how-to-convert-latitude-or-longitude-to-meters
|
||||
/// <summary>
|
||||
/// Calculates the distance between two coordinates.
|
||||
/// </summary>
|
||||
/// <param name="lat1">Latitude of point 1 in degrees</param>
|
||||
/// <param name="lon1">Longitude of point 1 in degrees</param>
|
||||
/// <param name="lat2">Latitude of point 2 in degrees</param>
|
||||
/// <param name="lon2">Longitude of point 2 in degrees</param>
|
||||
/// <returns></returns>
|
||||
public static double DistanceBetweenInMeters(float lat1, float lon1, float lat2, float lon2)
|
||||
{
|
||||
var distanceLat = lat2 * Math.PI / 180 - lat1 * Math.PI / 180;
|
||||
var distanceLon = lon2 * Math.PI / 180 - lon1 * Math.PI / 180;
|
||||
|
||||
var a = Math.Sin(distanceLat / 2) * Math.Sin(distanceLat / 2) +
|
||||
Math.Cos(lat1 * Math.PI / 180) * Math.Cos(lat2 * Math.PI / 180) *
|
||||
Math.Sin(distanceLon / 2) * Math.Sin(distanceLon / 2);
|
||||
|
||||
var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
|
||||
var distanceKm = EarthRadiusKm * c;
|
||||
|
||||
return distanceKm * 1000;
|
||||
}
|
||||
}
|
||||
}
|
117
SimConnect/Lib/UnmanagedLibrary.cs
Normal file
117
SimConnect/Lib/UnmanagedLibrary.cs
Normal file
@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Permissions;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
// Source: https://docs.microsoft.com/en-us/archive/blogs/jmstall/type-safe-managed-wrappers-for-kernel32getprocaddress
|
||||
namespace SimConnect.Lib
|
||||
{
|
||||
/// <summary>
|
||||
/// Utility class to wrap an unmanaged DLL and be responsible for freeing it.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is a managed wrapper over the native LoadLibrary, GetProcAddress, and FreeLibrary calls.
|
||||
/// </remarks>
|
||||
public sealed class UnmanagedLibrary : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// See http://msdn.microsoft.com/msdnmag/issues/05/10/Reliability/ for more about safe handles.
|
||||
/// </summary>
|
||||
[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
|
||||
public sealed class SafeLibraryHandle : SafeHandleZeroOrMinusOneIsInvalid
|
||||
{
|
||||
private SafeLibraryHandle() : base(true) { }
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
return NativeMethods.FreeLibrary(handle);
|
||||
}
|
||||
}
|
||||
|
||||
private static class NativeMethods
|
||||
{
|
||||
private const string SKernel = "kernel32";
|
||||
|
||||
[DllImport(SKernel, CharSet = CharSet.Auto, BestFitMapping = false, SetLastError = true)]
|
||||
public static extern SafeLibraryHandle LoadLibrary(string fileName);
|
||||
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
[DllImport(SKernel, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool FreeLibrary(IntPtr hModule);
|
||||
|
||||
[DllImport(SKernel)]
|
||||
public static extern IntPtr GetProcAddress(SafeLibraryHandle hModule, String procname);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to load a dll and be responible for freeing it.
|
||||
/// </summary>
|
||||
/// <param name="fileName">full path name of dll to load</param>
|
||||
/// <exception cref="System.IO.FileNotFoundException">if fileName can't be found</exception>
|
||||
/// <remarks>Throws exceptions on failure. Most common failure would be file-not-found, or
|
||||
/// that the file is not a loadable image.</remarks>
|
||||
public UnmanagedLibrary(string fileName)
|
||||
{
|
||||
libraryHandle = NativeMethods.LoadLibrary(fileName);
|
||||
if (!libraryHandle.IsInvalid)
|
||||
return;
|
||||
|
||||
var hr = Marshal.GetHRForLastWin32Error();
|
||||
Marshal.ThrowExceptionForHR(hr);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dynamically lookup a function in the dll via kernel32!GetProcAddress.
|
||||
/// </summary>
|
||||
/// <param name="functionName">raw name of the function in the export table.</param>
|
||||
/// <returns>null if function is not found. Else a delegate to the unmanaged function.
|
||||
/// </returns>
|
||||
/// <remarks>GetProcAddress results are valid as long as the dll is not yet unloaded. This
|
||||
/// is very very dangerous to use since you need to ensure that the dll is not unloaded
|
||||
/// until after you're done with any objects implemented by the dll. For example, if you
|
||||
/// get a delegate that then gets an IUnknown implemented by this dll,
|
||||
/// you can not dispose this library until that IUnknown is collected. Else, you may free
|
||||
/// the library and then the CLR may call release on that IUnknown and it will crash.</remarks>
|
||||
public TDelegate GetUnmanagedFunction<TDelegate>(string functionName) where TDelegate : class
|
||||
{
|
||||
var p = NativeMethods.GetProcAddress(libraryHandle, functionName);
|
||||
|
||||
// Failure is a common case, especially for adaptive code.
|
||||
if (p == IntPtr.Zero)
|
||||
return null;
|
||||
|
||||
var function = Marshal.GetDelegateForFunctionPointer(p, typeof(TDelegate));
|
||||
|
||||
// Ideally, we'd just make the constraint on TDelegate be
|
||||
// System.Delegate, but compiler error CS0702 (constrained can't be System.Delegate)
|
||||
// prevents that. So we make the constraint system.object and do the cast from object-->TDelegate.
|
||||
object o = function;
|
||||
|
||||
return (TDelegate)o;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call FreeLibrary on the unmanaged dll. All function pointers
|
||||
/// handed out from this class become invalid after this.
|
||||
/// </summary>
|
||||
/// <remarks>This is very dangerous because it suddenly invalidate
|
||||
/// everything retrieved from this dll. This includes any functions
|
||||
/// handed out via GetProcAddress, and potentially any objects returned
|
||||
/// from those functions (which may have an implemention in the
|
||||
/// dll).
|
||||
/// </remarks>
|
||||
public void Dispose()
|
||||
{
|
||||
if (!libraryHandle.IsClosed)
|
||||
{
|
||||
libraryHandle.Close();
|
||||
}
|
||||
}
|
||||
|
||||
// Unmanaged resource. CLR will ensure SafeHandles get freed, without requiring a finalizer on this class.
|
||||
private readonly SafeLibraryHandle libraryHandle;
|
||||
}
|
||||
}
|
36
SimConnect/Properties/AssemblyInfo.cs
Normal file
36
SimConnect/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("SimConnect")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("SimConnect")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2020")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("f160bb6a-7620-41e5-a99c-948c208875e4")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
98
SimConnect/SimConnect.csproj
Normal file
98
SimConnect/SimConnect.csproj
Normal file
@ -0,0 +1,98 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{F160BB6A-7620-41E5-A99C-948C208875E4}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>SimConnect</RootNamespace>
|
||||
<AssemblyName>SimConnect</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Attribute\SimConnectVariableAttribute.cs" />
|
||||
<Compile Include="Concrete\DefaultSimConnectClient.cs" />
|
||||
<Compile Include="Concrete\SimConnectClientFactory.cs" />
|
||||
<Compile Include="Concrete\SimConnectDefinition.cs" />
|
||||
<Compile Include="ISimConnectClient.cs" />
|
||||
<Compile Include="ISimConnectClientFactory.cs" />
|
||||
<Compile Include="ISimConnectLibrary.cs" />
|
||||
<Compile Include="Lib\LatLon.cs" />
|
||||
<Compile Include="Lib\UnmanagedLibrary.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Unmanaged\SimConnectDLLLibrary.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(Platform)' == 'x64'">
|
||||
<Content Include="FS2020-SimConnect.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(Platform)' == 'x86'">
|
||||
<Content Include="FSX-SE-SimConnect.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="FSX-SimConnect.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="FSXSP2-SimConnect.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
77
SimConnect/Unmanaged/SimConnectDLLLibrary.cs
Normal file
77
SimConnect/Unmanaged/SimConnectDLLLibrary.cs
Normal file
@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using SimConnect.Lib;
|
||||
|
||||
#pragma warning disable 1591
|
||||
namespace SimConnect.Unmanaged
|
||||
{
|
||||
public class SimConnectDLLLibrary : ISimConnectLibrary, IDisposable
|
||||
{
|
||||
private delegate uint SimConnectOpenProc(out IntPtr phSimConnect, string szName, IntPtr hwnd, uint userEventWin32, IntPtr hEventHandle, uint configIndex);
|
||||
private delegate uint SimConnectCloseProc(IntPtr hSimConnect);
|
||||
private delegate uint SimConnectAddToDataDefinitionProc(IntPtr hSimConnect, uint defineID, string datumName, string unitsName, SimConnectDataType datumType = SimConnectDataType.Float64, float epsilon = 0, uint datumID = uint.MaxValue);
|
||||
private delegate uint SimConnectClearDataDefinitionProc(IntPtr hSimConnect, uint defineID);
|
||||
private delegate uint SimConnectRequestDataOnSimObjectProc(IntPtr hSimConnect, uint requestID, uint defineID, uint objectID, SimConnectPeriod period, uint flags, uint origin = 0, uint interval = 0, uint limit = 0);
|
||||
private delegate uint SimConnectGetNextDispatchProc(IntPtr hSimConnect, out IntPtr ppData, out uint pcbData);
|
||||
|
||||
private readonly UnmanagedLibrary library;
|
||||
|
||||
private readonly SimConnectOpenProc simConnectOpen;
|
||||
private readonly SimConnectCloseProc simConnectClose;
|
||||
private readonly SimConnectAddToDataDefinitionProc simConnectAddToDataDefinition;
|
||||
private readonly SimConnectClearDataDefinitionProc simConnectClearDataDefinition;
|
||||
private readonly SimConnectRequestDataOnSimObjectProc simConnectRequestDataOnSimObject;
|
||||
private readonly SimConnectGetNextDispatchProc simConnectGetNextDispatch;
|
||||
|
||||
|
||||
|
||||
public SimConnectDLLLibrary(string libraryFilename)
|
||||
{
|
||||
library = new UnmanagedLibrary(libraryFilename);
|
||||
simConnectOpen = library.GetUnmanagedFunction<SimConnectOpenProc>("SimConnect_Open");
|
||||
simConnectClose = library.GetUnmanagedFunction<SimConnectCloseProc>("SimConnect_Close");
|
||||
simConnectAddToDataDefinition = library.GetUnmanagedFunction<SimConnectAddToDataDefinitionProc>("SimConnect_AddToDataDefinition");
|
||||
simConnectClearDataDefinition = library.GetUnmanagedFunction<SimConnectClearDataDefinitionProc>("SimConnect_ClearDataDefinition");
|
||||
simConnectRequestDataOnSimObject = library.GetUnmanagedFunction<SimConnectRequestDataOnSimObjectProc>("SimConnect_RequestDataOnSimObject");
|
||||
simConnectGetNextDispatch = library.GetUnmanagedFunction<SimConnectGetNextDispatchProc>("SimConnect_GetNextDispatch");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
library?.Dispose();
|
||||
}
|
||||
|
||||
|
||||
public uint SimConnect_Open(out IntPtr phSimConnect, string szName, IntPtr hwnd, uint userEventWin32, IntPtr hEventHandle, uint configIndex)
|
||||
{
|
||||
return simConnectOpen(out phSimConnect, szName, hwnd, userEventWin32, hEventHandle, configIndex);
|
||||
}
|
||||
|
||||
public uint SimConnect_Close(IntPtr hSimConnect)
|
||||
{
|
||||
return simConnectClose(hSimConnect);
|
||||
}
|
||||
|
||||
|
||||
public uint SimConnect_AddToDataDefinition(IntPtr hSimConnect, uint defineID, string datumName, string unitsName, SimConnectDataType datumType = SimConnectDataType.Float64, float epsilon = 0, uint datumID = uint.MaxValue)
|
||||
{
|
||||
return simConnectAddToDataDefinition(hSimConnect, defineID, datumName, unitsName, datumType, epsilon, datumID);
|
||||
}
|
||||
|
||||
public uint SimConnect_ClearDataDefinition(IntPtr hSimConnect, uint defineID)
|
||||
{
|
||||
return simConnectClearDataDefinition(hSimConnect, defineID);
|
||||
}
|
||||
|
||||
|
||||
public uint SimConnect_RequestDataOnSimObject(IntPtr hSimConnect, uint requestID, uint defineID, uint objectID, SimConnectPeriod period, uint flags, uint origin = 0, uint interval = 0, uint limit = 0)
|
||||
{
|
||||
return simConnectRequestDataOnSimObject(hSimConnect, requestID, defineID, objectID, period, flags, origin, interval, limit);
|
||||
}
|
||||
|
||||
public uint SimConnect_GetNextDispatch(IntPtr hSimConnect, out IntPtr ppData, out uint pcbData)
|
||||
{
|
||||
return simConnectGetNextDispatch(hSimConnect, out ppData, out pcbData);
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore 1591
|
36
SimConnectUnitTests/Properties/AssemblyInfo.cs
Normal file
36
SimConnectUnitTests/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("SimConnectUnitTests")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("SimConnectUnitTests")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2020")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("2cd97d07-ef26-4cda-a090-df3d698e7f60")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
58
SimConnectUnitTests/SimConnectDefinitionTest.cs
Normal file
58
SimConnectUnitTests/SimConnectDefinitionTest.cs
Normal file
@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using FluentAssertions;
|
||||
using SimConnect.Attribute;
|
||||
using SimConnect.Concrete;
|
||||
using Xunit;
|
||||
|
||||
namespace SimConnectUnitTests
|
||||
{
|
||||
public class SimConnectDefinitionTest
|
||||
{
|
||||
[Fact]
|
||||
public void EmptyObject()
|
||||
{
|
||||
Action test = () =>
|
||||
{
|
||||
var unused = new SimConnectDefinition(typeof(object));
|
||||
};
|
||||
|
||||
test.Should().Throw<InvalidOperationException>("the object is empty");
|
||||
}
|
||||
|
||||
|
||||
// ReSharper disable UnusedMember.Global
|
||||
// ReSharper disable UnusedMember.Local
|
||||
#pragma warning disable 649
|
||||
private class NativeVariablesTest
|
||||
{
|
||||
[SimConnectVariable("INT")]
|
||||
public int IntField;
|
||||
|
||||
[SimConnectVariable("UINT")]
|
||||
public uint UIntField;
|
||||
|
||||
[SimConnectVariable("LONG")]
|
||||
public long LongField;
|
||||
|
||||
[SimConnectVariable("ULONG")]
|
||||
public ulong ULongField;
|
||||
|
||||
[SimConnectVariable("SINGLE")]
|
||||
public float SingleProperty { get; set; }
|
||||
|
||||
[SimConnectVariable("DOUBLE")]
|
||||
public double DoubleProperty { get; set; }
|
||||
}
|
||||
#pragma warning restore 649
|
||||
// ReSharper restore UnusedMember.Local
|
||||
// ReSharper restore UnusedMember.Global
|
||||
|
||||
|
||||
[Fact]
|
||||
public void NativeVariables()
|
||||
{
|
||||
var definition = new SimConnectDefinition(typeof(NativeVariablesTest));
|
||||
definition.Variables.Should().HaveCount(6);
|
||||
}
|
||||
}
|
||||
}
|
112
SimConnectUnitTests/SimConnectUnitTests.csproj
Normal file
112
SimConnectUnitTests/SimConnectUnitTests.csproj
Normal file
@ -0,0 +1,112 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\packages\xunit.core.2.4.1\build\xunit.core.props" Condition="Exists('..\packages\xunit.core.2.4.1\build\xunit.core.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{2CD97D07-EF26-4CDA-A090-DF3D698E7F60}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>SimConnectUnitTests</RootNamespace>
|
||||
<AssemblyName>SimConnectUnitTests</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug %2832 bits%29\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Release %2832 bits%29\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug %2832 bits%29\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Release %2832 bits%29\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="FluentAssertions, Version=5.10.3.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\FluentAssertions.5.10.3\lib\net47\FluentAssertions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\xunit.abstractions.2.0.3\lib\net35\xunit.abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="xunit.assert, Version=2.4.1.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\xunit.assert.2.4.1\lib\netstandard1.1\xunit.assert.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="xunit.core, Version=2.4.1.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\xunit.extensibility.core.2.4.1\lib\net452\xunit.core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="xunit.execution.desktop, Version=2.4.1.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\xunit.extensibility.execution.2.4.1\lib\net452\xunit.execution.desktop.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="SimConnectDefinitionTest.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Analyzer Include="..\packages\xunit.analyzers.0.10.0\analyzers\dotnet\cs\xunit.analyzers.dll" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SimConnect\SimConnect.csproj">
|
||||
<Project>{f160bb6a-7620-41e5-a99c-948c208875e4}</Project>
|
||||
<Name>SimConnect</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\xunit.core.2.4.1\build\xunit.core.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.core.2.4.1\build\xunit.core.props'))" />
|
||||
<Error Condition="!Exists('..\packages\xunit.core.2.4.1\build\xunit.core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.core.2.4.1\build\xunit.core.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\packages\xunit.core.2.4.1\build\xunit.core.targets" Condition="Exists('..\packages\xunit.core.2.4.1\build\xunit.core.targets')" />
|
||||
</Project>
|
11
SimConnectUnitTests/packages.config
Normal file
11
SimConnectUnitTests/packages.config
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="FluentAssertions" version="5.10.3" targetFramework="net472" />
|
||||
<package id="xunit" version="2.4.1" targetFramework="net472" />
|
||||
<package id="xunit.abstractions" version="2.0.3" targetFramework="net472" />
|
||||
<package id="xunit.analyzers" version="0.10.0" targetFramework="net472" />
|
||||
<package id="xunit.assert" version="2.4.1" targetFramework="net472" />
|
||||
<package id="xunit.core" version="2.4.1" targetFramework="net472" />
|
||||
<package id="xunit.extensibility.core" version="2.4.1" targetFramework="net472" />
|
||||
<package id="xunit.extensibility.execution" version="2.4.1" targetFramework="net472" />
|
||||
</packages>
|
Loading…
Reference in New Issue
Block a user