public void OnKeyDown(object o, KeyEventArgs k)
        {
            System.IO.File.AppendAllText(logFilePath, "VisionExport OnKeyDown called.\n");

            if (k.KeyCode == Keys.Z)
            {
                if (notificationsEnabled)
                {
                    UI.Notify("Notifications Disabled");
                    notificationsEnabled = false;
                }
                else
                {
                    UI.Notify("Notifications Enabled");
                    notificationsEnabled = true;
                }
            }
            if (k.KeyCode == Keys.PageUp)
            {
                postgresTask?.Wait();
                postgresTask = StartSession();
                runTask?.Wait();
                runTask = StartRun();
                if (notificationsEnabled)
                {
                    UI.Notify("GTA Vision Enabled");
                }
            }
            if (k.KeyCode == Keys.PageDown)
            {
                StopRun();
                StopSession();
                if (notificationsEnabled)
                {
                    UI.Notify("GTA Vision Disabled");
                }
            }
            if (k.KeyCode == Keys.H) // temp modification
            {
                EnterVehicle();
                if (notificationsEnabled)
                {
                    UI.Notify("Trying to enter vehicle");
                }
                ToggleNavigation();
            }
            if (k.KeyCode == Keys.Y) // temp modification
            {
                ReloadGame();
            }
            if (k.KeyCode == Keys.U) // temp modification
            {
                var settings = ScriptSettings.Load("GTAVisionExport.xml");
                var loc      = AppDomain.CurrentDomain.BaseDirectory;

                //UI.Notify(ConfigurationManager.AppSettings["database_connection"]);
                var str = settings.GetValue("", "ConnectionString");
                if (notificationsEnabled)
                {
                    UI.Notify(loc);
                }
            }
            if (k.KeyCode == Keys.G) // temp modification
            {
                /*
                 * IsGamePaused = true;
                 * Game.Pause(true);
                 * Script.Wait(500);
                 * TraverseWeather();
                 * Script.Wait(500);
                 * IsGamePaused = false;
                 * Game.Pause(false);
                 */
                var data = GTAData.DumpData(Game.GameTime + ".tiff", new List <Weather>(wantedWeather));

                string path = @"C:\Users\NGV-02\Documents\Data\trymatrix.txt";
                // This text is added only once to the file.
                if (!File.Exists(path))
                {
                    // Create a file to write to.
                    using (StreamWriter file = File.CreateText(path))
                    {
                        file.WriteLine("cam direction file");
                        file.WriteLine("direction:");
                        file.WriteLine(GameplayCamera.Direction.X.ToString() + ' ' + GameplayCamera.Direction.Y.ToString() + ' ' + GameplayCamera.Direction.Z.ToString());
                        file.WriteLine("Dot Product:");
                        file.WriteLine(Vector3.Dot(GameplayCamera.Direction, GameplayCamera.Rotation));
                        file.WriteLine("position:");
                        file.WriteLine(GameplayCamera.Position.X.ToString() + ' ' + GameplayCamera.Position.Y.ToString() + ' ' + GameplayCamera.Position.Z.ToString());
                        file.WriteLine("rotation:");
                        file.WriteLine(GameplayCamera.Rotation.X.ToString() + ' ' + GameplayCamera.Rotation.Y.ToString() + ' ' + GameplayCamera.Rotation.Z.ToString());
                        file.WriteLine("relative heading:");
                        file.WriteLine(GameplayCamera.RelativeHeading.ToString());
                        file.WriteLine("relative pitch:");
                        file.WriteLine(GameplayCamera.RelativePitch.ToString());
                        file.WriteLine("fov:");
                        file.WriteLine(GameplayCamera.FieldOfView.ToString());
                    }
                }
            }

            if (k.KeyCode == Keys.T) // temp modification
            {
                World.Weather = Weather.Raining;
                /* set it between 0 = stop, 1 = heavy rain. set it too high will lead to sloppy ground */
                Function.Call(GTA.Native.Hash._SET_RAIN_FX_INTENSITY, 0.5f);
                var test = Function.Call <float>(GTA.Native.Hash.GET_RAIN_LEVEL);
                if (notificationsEnabled)
                {
                    UI.Notify("" + test);
                }
                World.CurrentDayTime = new TimeSpan(12, 0, 0);
                //Script.Wait(5000);
            }

            if (k.KeyCode == Keys.N)
            {
                /*
                 * //var color = VisionNative.GetColorBuffer();
                 *
                 * List<byte[]> colors = new List<byte[]>();
                 * Game.Pause(true);
                 * Script.Wait(1);
                 * var depth = VisionNative.GetDepthBuffer();
                 * var stencil = VisionNative.GetStencilBuffer();
                 * foreach (var wea in wantedWeather) {
                 *  World.TransitionToWeather(wea, 0.0f);
                 *  Script.Wait(1);
                 *  colors.Add(VisionNative.GetColorBuffer());
                 * }
                 * Game.Pause(false);
                 * if (depth != null)
                 * {
                 *  var res = Game.ScreenResolution;
                 *  var t = Tiff.Open(Path.Combine(dataPath, "test.tiff"), "w");
                 *  ImageUtils.WriteToTiff(t, res.Width, res.Height, colors, depth, stencil);
                 *  t.Close();
                 *  UI.Notify(GameplayCamera.FieldOfView.ToString());
                 * }
                 * else
                 * {
                 *  UI.Notify("No Depth Data quite yet");
                 * }
                 * //UI.Notify((connection != null && connection.Connected).ToString());
                 */
                //var color = VisionNative.GetColorBuffer();
                for (int i = 0; i < 100; i++)
                {
                    List <byte[]> colors = new List <byte[]>();
                    Game.Pause(true);
                    var depth   = VisionNative.GetDepthBuffer();
                    var stencil = VisionNative.GetStencilBuffer();
                    foreach (var wea in wantedWeather)
                    {
                        World.TransitionToWeather(wea, 0.0f);
                        Script.Wait(1);
                        colors.Add(VisionNative.GetColorBuffer());
                    }

                    Game.Pause(false);
                    var res = Game.ScreenResolution;
                    var t   = Tiff.Open(Path.Combine(dataPath, "info" + i.ToString() + ".tiff"), "w");
                    ImageUtils.WriteToTiff(t, res.Width, res.Height, colors, depth, stencil);
                    t.Close();
                    if (notificationsEnabled)
                    {
                        UI.Notify(GameplayCamera.FieldOfView.ToString());
                    }
                    //UI.Notify((connection != null && connection.Connected).ToString());


                    var data = GTAData.DumpData(Game.GameTime + ".dat", new List <Weather>(wantedWeather));

                    string path = @"C:\Users\NGV-02\Documents\Data\info.txt";
                    // This text is added only once to the file.
                    if (!File.Exists(path))
                    {
                        // Create a file to write to.
                        using (StreamWriter file = File.CreateText(path))
                        {
                            file.WriteLine("cam direction & Ped pos file");
                        }
                    }

                    using (StreamWriter file = File.AppendText(path))
                    {
                        file.WriteLine("==============info" + i.ToString() + ".tiff 's metadata=======================");
                        file.WriteLine("cam pos");
                        file.WriteLine(GameplayCamera.Position.X.ToString());
                        file.WriteLine(GameplayCamera.Position.Y.ToString());
                        file.WriteLine(GameplayCamera.Position.Z.ToString());
                        file.WriteLine("cam direction");
                        file.WriteLine(GameplayCamera.Direction.X.ToString());
                        file.WriteLine(GameplayCamera.Direction.Y.ToString());
                        file.WriteLine(GameplayCamera.Direction.Z.ToString());
                        file.WriteLine("character");
                        file.WriteLine(data.Pos.X.ToString());
                        file.WriteLine(data.Pos.Y.ToString());
                        file.WriteLine(data.Pos.Z.ToString());
                        foreach (var detection in data.Detections)
                        {
                            file.WriteLine(detection.Type.ToString());
                            file.WriteLine(detection.Pos.X.ToString());
                            file.WriteLine(detection.Pos.Y.ToString());
                            file.WriteLine(detection.Pos.Z.ToString());
                        }
                    }

                    Script.Wait(200);
                }
            }
            if (k.KeyCode == Keys.I)
            {
                var info = new GTAVisionUtils.InstanceData();
                if (notificationsEnabled)
                {
                    UI.Notify(info.type);
                }
                if (notificationsEnabled)
                {
                    UI.Notify(info.publichostname);
                }
            }
        }
        public void OnTick(object o, EventArgs e)
        {
            if (server.Poll(10, SelectMode.SelectRead) && connection == null)
            {
                connection = server.Accept();
                if (notificationsEnabled)
                {
                    UI.Notify("CONNECTED");
                }
                connection.Blocking = false;
            }
            handlePipeInput();
            if (!enabled)
            {
                return;
            }

            //Array values = Enum.GetValues(typeof(Weather));


            switch (checkStatus())
            {
            case GameStatus.NeedReload:
                //TODO: need to get a new session and run?
                StopRun();
                runTask?.Wait();
                runTask = StartRun();
                //StopSession();
                //Autostart();
                if (notificationsEnabled)
                {
                    UI.Notify("need reload game");
                }
                Script.Wait(100);
                ReloadGame();
                break;

            case GameStatus.NeedStart:
                //TODO do the autostart manually or automatically?
                //Autostart();
                // use reloading temporarily
                StopRun();

                ReloadGame();
                Script.Wait(100);
                runTask?.Wait();
                runTask = StartRun();
                //Autostart();
                break;

            case GameStatus.NoActionNeeded:
                break;
            }
            if (!runTask.IsCompleted)
            {
                return;
            }
            if (!postgresTask.IsCompleted)
            {
                return;
            }

            List <byte[]> colors = new List <byte[]>();

            Game.Pause(true);
            Script.Wait(500);
            GTAData dat = GTAData.DumpData(Game.GameTime + ".tiff", new List <Weather>());

            if (dat == null)
            {
                return;
            }
            var thisframe = VisionNative.GetCurrentTime();
            var depth     = VisionNative.GetDepthBuffer();
            var stencil   = VisionNative.GetStencilBuffer();

            colors.Add(VisionNative.GetColorBuffer());

            /*
             * foreach (var wea in wantedWeather) {
             *  World.TransitionToWeather(wea, 0.0f);
             *  Script.Wait(1);
             *  colors.Add(VisionNative.GetColorBuffer());
             * }*/
            Game.Pause(false);

            /*
             * if (World.Weather != Weather.Snowing)
             * {
             *  World.TransitionToWeather(Weather.Snowing, 1);
             *
             * }*/
            var colorframe    = VisionNative.GetLastColorTime();
            var depthframe    = VisionNative.GetLastConstantTime();
            var constantframe = VisionNative.GetLastConstantTime();

            //UI.Notify("DIFF: " + (colorframe - depthframe) + " FRAMETIME: " + (1 / Game.FPS) * 1000);
            if (notificationsEnabled)
            {
                UI.Notify(colors[0].Length.ToString());
            }
            if (depth == null || stencil == null)
            {
                if (notificationsEnabled)
                {
                    UI.Notify("No DEPTH");
                }
                return;
            }

            /*
             * this code checks to see if there's drift
             * it's kinda pointless because we end up "straddling" a present call,
             * so the capture time difference can be ~1/4th of a frame but still the
             * depth/stencil and color buffers are one frame offset from each other
             * if (Math.Abs(thisframe - colorframe) < 60 && Math.Abs(colorframe - depthframe) < 60 &&
             *  Math.Abs(colorframe - constantframe) < 60)
             * {
             *
             *
             *
             *
             *
             *  PostgresExport.SaveSnapshot(dat, run.guid);
             * }
             */
            ImageUtils.WaitForProcessing();
            ImageUtils.StartUploadTask(archive, Game.GameTime.ToString(), Game.ScreenResolution.Width,
                                       Game.ScreenResolution.Height, colors, depth, stencil);

            PostgresExport.SaveSnapshot(dat, run.guid);
            S3Stream.Flush();
            if ((Int64)S3Stream.Length > (Int64)2048 * (Int64)1024 * (Int64)1024)
            {
                ImageUtils.WaitForProcessing();
                StopRun();
                runTask?.Wait();
                runTask = StartRun();
            }
        }