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