Skip to content

Commit

Permalink
Removed "ClickOnce" installation, added pop-up dialogs to guide LiveC…
Browse files Browse the repository at this point in the history
…am usage (#2)

* Removed ClickOnce
* Added user warnings about & hints for correcting improper LiveCam configuration
  • Loading branch information
noodnik2 authored Mar 6, 2021
1 parent d802c5f commit 3d91792
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 29 deletions.
7 changes: 5 additions & 2 deletions FS2020PlanePath/FS2020PlanePath.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,20 @@
<ManifestKeyFile>FS2020PlanePath_TemporaryKey.pfx</ManifestKeyFile>
</PropertyGroup>
<PropertyGroup>
<GenerateManifests>true</GenerateManifests>
<GenerateManifests>false</GenerateManifests>
</PropertyGroup>
<PropertyGroup>
<SignManifests>true</SignManifests>
<SignManifests>false</SignManifests>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>icon.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<PropertyGroup>
<TargetZone>LocalIntranet</TargetZone>
</PropertyGroup>
<ItemGroup>
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\packages\EntityFramework.6.3.0\lib\net45\EntityFramework.dll</HintPath>
Expand Down
8 changes: 4 additions & 4 deletions FS2020PlanePath/FS2020_SQLLiteDB.cs
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ public int WriteFlight(string aircraft)
return Convert.ToInt32(FlightID);
}

public int WriteFlightPoint(long pk, double latitude, double longitude, Int32 altitude)
public int WriteFlightPoint(long flightId, double latitude, double longitude, Int32 altitude)
{
SQLiteCommand sqlite_cmd;
string Insertsql;
Expand All @@ -838,7 +838,7 @@ public int WriteFlightPoint(long pk, double latitude, double longitude, Int32 al
transaction = sqlite_conn.BeginTransaction();
Insertsql = "Insert into FlightSamples (FlightID, latitude, longitude, altitude, sample_datetimestamp) VALUES (@FlightID, @latitude, @longitude, @altitude, @sample_datetimestamp)";
sqlite_cmd.CommandText = Insertsql;
sqlite_cmd.Parameters.AddWithValue("@FlightID", pk);
sqlite_cmd.Parameters.AddWithValue("@FlightID", flightId);
sqlite_cmd.Parameters.AddWithValue("@latitude", latitude);
sqlite_cmd.Parameters.AddWithValue("@longitude", longitude);
sqlite_cmd.Parameters.AddWithValue("@altitude", altitude);
Expand All @@ -859,7 +859,7 @@ public int WriteFlightPoint(long pk, double latitude, double longitude, Int32 al
return Convert.ToInt32(FlightSampleID);
}

public void WriteFlightPointDetails(long pk, Int32 altitude_above_ground, Int32 engine1rpm, Int32 engine2rpm, Int32 engine3rpm, Int32 engine4rpm, Int32 lightsmask, double ground_velocity,
public void WriteFlightPointDetails(long flightSampleId, Int32 altitude_above_ground, Int32 engine1rpm, Int32 engine2rpm, Int32 engine3rpm, Int32 engine4rpm, Int32 lightsmask, double ground_velocity,
double plane_pitch, double plane_bank, double plane_heading_true, double plane_heading_magnetic,
double plane_airspeed_indicated, double airspeed_true, double vertical_speed, double heading_indicator,
Int32 flaps_handle_position, Int32 spoilers_handle_position, Int32 gear_handle_position,
Expand All @@ -877,7 +877,7 @@ public void WriteFlightPointDetails(long pk, Int32 altitude_above_ground, Int32
Insertsql += "@vertical_speed, @heading_indicator, @flaps_handle_position, @spoilers_handle_position, @gear_handle_position, @ambient_wind_velocity, @ambient_wind_direction, @ambient_temperature, @stall_warning, ";
Insertsql += "@overspeed_warning, @is_gear_retractable, @spoiler_available, @sim_on_ground)";
sqlite_cmd.CommandText = Insertsql;
sqlite_cmd.Parameters.AddWithValue("@FlightSamplesID", pk);
sqlite_cmd.Parameters.AddWithValue("@FlightSamplesID", flightSampleId);
sqlite_cmd.Parameters.AddWithValue("@alitutdeaboveground", altitude_above_ground);
sqlite_cmd.Parameters.AddWithValue("@engine1rpm", engine1rpm);
sqlite_cmd.Parameters.AddWithValue("@engine2rpm", engine2rpm);
Expand Down
6 changes: 1 addition & 5 deletions FS2020PlanePath/GeneratedFlightDataConnector.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace FS2020PlanePath
{
Expand Down Expand Up @@ -87,7 +86,7 @@ public bool HandleWindowMessage(ref Message m)

private void TimerTickHandler(object sender, EventArgs e)
{
PostMessage(parentControl.Handle, WM_USER_SIMCONNECT, 0, 0);
UserDialogUtils.PostMessage(parentControl.Handle, WM_USER_SIMCONNECT, 0, 0);
}

private void pumpFlightDataUpdates()
Expand Down Expand Up @@ -154,9 +153,6 @@ private static FlightDataStructure FpdToFds(FlightPathData fpd)
};
}

[DllImport("user32.dll", SetLastError = true)]
static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

private const int WM_USER_SIMCONNECT = 0x0402;

private Timer timer;
Expand Down
2 changes: 2 additions & 0 deletions FS2020PlanePath/KmlLiveCam.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ public class KmlCameraParameterValues : ICloneable

// prevent Newtonsoft serialization of the corresponding method
public bool ShouldSerializegetMultitrackUpdates() => false;

// NOTE: this delegate is called by LiveCams in order to retrieve position updates
public GetMultitrackUpdatesDelegate getMultitrackUpdates { get; set; }

public KmlCameraParameterValues ShallowCopy()
Expand Down
80 changes: 77 additions & 3 deletions FS2020PlanePath/MainPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using SharpKml.Dom;
using SharpKml.Engine;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace FS2020PlanePath
{
Expand All @@ -21,8 +22,10 @@ public partial class MainPage : Form
//const string sourceRepo = "SAHorowitz/MSFS2020-PilotPathRecorder";
const string sourceRepo = "noodnik2/MSFS2020-PilotPathRecorder";
const string EXPORT_KMLFILE_CAPTION = "Export KML File";
const int WM_APP_LOGGING_INACTIVE = 0x8001;

bool bLoggingEnabled = false;
bool bLoggingEnabled;
bool inactiveLoggingWarningIssued;
FlightDataConnector flightDataConnector;
ScKmlAdapter scKmlAdapter;
LiveCamRegistry liveCamRegistry;
Expand Down Expand Up @@ -85,6 +88,22 @@ private KmlCameraParameterValues CreateKmlParameterValues()

private KmlCameraParameterValues[] getKmlCameraUpdatesFromDb(int flightId, long seqSince)
{

//
// Send a notification that can be used to warn the user of and advise them how to handle two cases:
// 1. liveCam is asking for flight 0 because logging was not active when it was launched; or,
// 2. liveCam was playing a flight, but that flight is no longer being logged
//
if (flightId == 0 || (seqSince != 0 && flightId != nCurrentFlightID))
{
Invoke(
new Action(
() => UserDialogUtils.PostMessage(Handle, WM_APP_LOGGING_INACTIVE, 0, 0)
)
);
return new KmlCameraParameterValues[0];
}

Console.WriteLine($"fetching camera updates for flight #{flightId} from timestamp({seqSince})");

List<FlightPathData> flightPaths = FlightPathDB.GetFlightPathSinceTimestamp(flightId, seqSince);
Expand Down Expand Up @@ -273,6 +292,24 @@ private void AttemptSimConnection(string operationalMode)

protected override void DefWndProc(ref Message m)
{

if (m.Msg == WM_APP_LOGGING_INACTIVE)
{
// warn user only once per connection
if (!inactiveLoggingWarningIssued)
{
inactiveLoggingWarningIssued = true;
UserDialogUtils.displayMessage(
"Flight Logging Not Active",
"A 'LiveCam' was unable to access the active flight's log." +
"\nRelaunch the LiveCam with flight logging enabled.",
MessageBoxIcon.Warning
);
}
return;
}


if (!flightDataConnector.HandleWindowMessage(ref m))
{
base.DefWndProc(ref m);
Expand Down Expand Up @@ -306,6 +343,8 @@ private void PauseFlightLoggingToggleBtn_Click(object sender, EventArgs e)

private void StopLoggingAction()
{
inactiveLoggingWarningIssued = false;

if (nCurrentFlightID == 0)
{
loggingStatusLB.Text = "";
Expand Down Expand Up @@ -1063,8 +1102,43 @@ out liveCamEntity
throw new Exception($"Could not load KmlLiveCam from '{liveCamFilename}'");
}

private bool ContinueInSpiteOfProblematicLinkContext()
{
List<String> problematicContextMessages = new List<String>();
if (!LiveCameraCB.Checked)
{
problematicContextMessages.Add("- Link will be inactive without an enabled 'LiveCam'.");
problematicContextMessages.Add(" hint: enable using the 'LiveCam' checkbox");
problematicContextMessages.Add("");
}
if (!flightDataConnector.IsSimConnected())
{
problematicContextMessages.Add("- You'll go to 'Null Island' without an active connection.");
problematicContextMessages.Add(" hint: activate one using the 'Connect' button");
problematicContextMessages.Add("");
}
if (problematicContextMessages.Count() == 0)
{
return true;
}

problematicContextMessages.Add("Do you wish to continue in spite of these warnings?");
return (
UserDialogUtils.obtainConfirmation(
"Link Activation Warning",
string.Join("\n", problematicContextMessages.ToArray()),
MessageBoxIcon.Warning
)
);
}

private void geLinkBT_Click(object sender, EventArgs e)
{
if (!ContinueInSpiteOfProblematicLinkContext())
{
return;
}

string alias, lensName;
string liveCamUrl = LiveCameraHostPortCB.Text;
try
Expand Down Expand Up @@ -1187,8 +1261,8 @@ private string malformedUriErrorMessage(string url, UriFormatException ufe)

private void RetrySimConnectionBtn_Click(object sender, EventArgs e)
{
Button button = (Button)sender;
if (button.Text == DISCONNECT_BUTTON_TEXT)
Button button = (Button) sender;
if (flightDataConnector.IsSimConnected())
{
flightDataConnector.CloseConnection();
UpdateConnectionDialogStatus();
Expand Down
1 change: 1 addition & 0 deletions FS2020PlanePath/ReplayFlightDataGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ internal ReplayFlightDataGenerator(
)
{
segmentDurationSecs = context.segmentDurationSecs;
// retrieve the (entire) flight path of the specified pre-recorded flight
flightPath = dbAccessor.GetFlightPathSinceTimestamp(context.flightNo, 0);
generatorName = $"Replay of {context.flightName}";
Console.WriteLine($"{generatorName}; size({flightPath.Count})");
Expand Down
4 changes: 4 additions & 0 deletions FS2020PlanePath/UserInterfaceUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.ComponentModel;
using System.Diagnostics;
using System.Media;
using System.Runtime.InteropServices;

namespace FS2020PlanePath
{
Expand Down Expand Up @@ -205,6 +206,9 @@ public static void showHelpPopupText(Control parent, string popupText)
Help.ShowPopup(parent, popupText, parent.Location);
}

[DllImport("user32.dll", SetLastError = true)]
public static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

}

}
20 changes: 7 additions & 13 deletions FS2020PlanePath/app.manifest
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<assemblyIdentity version="1.0.0.0" name="MyApplication.app" />
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
Expand All @@ -18,33 +18,29 @@
-->
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
<applicationRequestMinimum>
<defaultAssemblyRequest permissionSetReference="Custom" />
<PermissionSet ID="Custom" SameSite="site" />
</applicationRequestMinimum>
</security>
</trustInfo>

<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- A list of the Windows versions that this application has been tested on
and is designed to work with. Uncomment the appropriate elements
and Windows will automatically select the most compatible environment. -->

<!-- Windows Vista -->
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->

<!-- Windows 7 -->
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->

<!-- Windows 8 -->
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->

<!-- Windows 8.1 -->
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->

<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />

<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>

<!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher
DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need
to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should
Expand All @@ -56,7 +52,6 @@
</windowsSettings>
</application>
-->

<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
<!--
<dependency>
Expand All @@ -72,5 +67,4 @@
</dependentAssembly>
</dependency>
-->

</assembly>
</assembly>
3 changes: 3 additions & 0 deletions README-installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ file extension.

## "How do I install and run it?"

NOTE: the notes below are addendum to the [installation instructions](README.md#instructions-for-install)
on the main README document.

1. Download the `PilotPathRecorder*.zip` deliverable build asset from a
[release](https://github.com/noodnik2/MSFS2020-PilotPathRecorder/releases).
If you haven't any reason to prefer a specific release, please
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ v1.0.3 - Fixed all issues related to international use of the program


## Instructions for use
Note that the Flight Simluator should be up and running before launching Pilot Path Recorder. If not, then click Retry Sim Connection until you get the "SimConnect Connected" message. Next choose the write frequency of how often to write to the database when above the minimum altitude threshold. Adjust the minimum altitude threshold as well. For example if you want to write every 30 seconds when above ground by 5000 feet use the values 30 and 5000 respectfully.
Note that the Flight Simulator should be up and running before launching Pilot Path Recorder. If not, then click Retry Sim Connection until you get the "SimConnect Connected" message. Next choose the write frequency of how often to write to the database when above the minimum altitude threshold. Adjust the minimum altitude threshold as well. For example if you want to write every 30 seconds when above ground by 5000 feet use the values 30 and 5000 respectfully.

There are two ways to log a flight. Automatic and manual. For automatic ensure the "Automatic Logging is checked and set the appropriate ground speed. Once the plane is above that speed logging will begin. When it is below that speed logging will end and the flight will be recorded. For manual logging, click 'Start Logging' when you are ready to start the recording. You may pause at anytime using the pause function and continue logging when ready. 'Stop Logging' ends the recording for that flight.

Expand Down Expand Up @@ -94,7 +94,8 @@ Click on First Person View to review your flight from the first person perspecti
## Instructions for install
1. Install .NET 4.7.2 - download can be found at https://dotnet.microsoft.com/download/dotnet-framework/net472

2. Download Pilot Path Recorder zip file from the releases area of this project: https://github.com/SAHorowitz/MSFS2020-PilotPathRecorder/releases
2. Download Pilot Path Recorder zip file from the releases area of this project:
https://github.com/noodnik2/MSFS2020-PilotPathRecorder/releases

3. Unzip contents of Pilot Path Recorder to a directory

Expand Down

0 comments on commit 3d91792

Please sign in to comment.