コード例 #1
0
ファイル: form_Main.cs プロジェクト: VEAF/perun
        private void con_Button_Reset_Flags_Click(object sender, EventArgs e)
        {
            // Reset error flags
            DialogResult dialogResult = MessageBox.Show("Are you sure to reset error flags?", "Question", MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Question);

            if (dialogResult == DialogResult.Yes)
            {
                // Reset errors counter
                Globals.ErrorsDatabase    = 0;                      // MySQL - Error counter
                Globals.ErrorsGame        = 0;                      // TCP connection - Error counter
                Globals.ErrorsHistoryGame = 0;                      // TCP connection - historic value of Error counter
                Globals.ErrorsSRS         = 0;                      // DCS SRS - error counter
                Globals.ErrorsLotATC      = 0;                      // LotATC - error counter

                // Force icons reload
                Globals.AppForceIconReload = true;

                // Add information
                PerunHelper.LogInfo(ref Globals.AppLogHistory, "Resetted error counter", 0, 1);
            }
            else if (dialogResult == DialogResult.No)
            {
                // Do nothing
            }
        }
コード例 #2
0
ファイル: form_Main.cs プロジェクト: VEAF/perun
        private void con_Button_Listen_OFF_Click(object sender, EventArgs e)
        {
            // Stop listening
            // Prepare GUI
            PerunHelper.LogInfo(ref Globals.AppLogHistory, "Closing connections", 0, 1);
            con_Button_Listen_OFF.Enabled = false;
            Tim_GUI_Tick(null, null);
            this.Refresh();
            Application.DoEvents();

            // Stop timmers
            tim_GUI.Enabled        = false;
            tim_3rdparties.Enabled = false;
            tim_MySQL.Enabled      = false;

            try
            {
                // Stop the server
                Globals.TCPServer.StopListen();
            }
            catch (Exception ex)
            {
                PerunHelper.LogError(ref Globals.AppLogHistory, $"ERROR TCP, error: {ex.Message}", 2, 1, "?");
                Console.WriteLine(ex.ToString());
            }

            while (Globals.TCPServer.thrTCPListener.IsAlive)
            {
                // Wait untill TCP server closed connection
                Thread.Sleep(200);                 //ms
            }
            form_Main_SetControlsToDisconnected(); // Enable controls

            // Load status images
            con_img_db.Image     = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected");
            con_img_dcs.Image    = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected");
            con_img_lotATC.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected");
            con_img_srs.Image    = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected");

            // Display information about closed connections
            PerunHelper.LogInfo(ref Globals.AppLogHistory, "Connections closed", 0, 1);
            Tim_GUI_Tick(null, null);

            // Set title bar
            this.Text         = Globals.AppTitle;
            trayIconMain.Text = this.Text;

            // Set globals
            Globals.AppInstanceID           = 0;
            Globals.AppUpdateGUI            = false;
            Globals.StatusDatabase          = false;
            Globals.StatusHistoryConnection = false;
            Globals.StatusSRS        = false;
            Globals.StatusLotATC     = false;
            Globals.StatusConnection = false;
        }
コード例 #3
0
        public bool ExtLotATCStatus;                                             // True if to use empty/default LotATC status

        // ################################ Main ################################
        private void form_Main_Load(object sender, EventArgs e)
        {
            // Form loaded
            Globals.AppLogHistory[0] = DateTime.Now.ToString("HH:mm:ss") + " > " + "Perun started"; // Add information to the log control
            form_Main_LoadSettings();                                                               // Load settings from registry

            // Display build version in title bar
            Globals.AppTitle = PerunHelper.GetAppVersion(this.Text + " - ");
            this.Text        = Globals.AppTitle;

            // Use command line parameters
            string[] args = Environment.GetCommandLineArgs();
            if (args.Length > 1)
            {
                // Get argument server port
                if (args[1] != null)
                {
                    con_txt_dcs_server_port.Text = args[1];
                }
            }
            if (args.Length > 2)
            {
                // Get argument instance id
                if (args[2] != null)
                {
                    con_txt_dcs_instance.Text = args[2];
                }
            }
            if (args.Length > 3)
            {
                // Get argument DCS SRS file path
                if (args[3] != null)
                {
                    con_txt_3rd_srs.Text      = args[3];
                    con_check_3rd_srs.Checked = true;
                }
            }
            if (args.Length > 4)
            {
                // Get argument lotATC file path
                if (args[4] != null)
                {
                    con_txt_3rd_lotatc.Text      = args[4];
                    con_check_3rd_lotatc.Checked = true;
                }
            }

            // Initialize controls
            con_img_db.Image     = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected");
            con_img_dcs.Image    = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected");
            con_img_lotATC.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected");
            con_img_srs.Image    = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected");
        }
コード例 #4
0
ファイル: form_Main.cs プロジェクト: VEAF/perun
        // ################################ User input ################################
        private void con_Button_Listen_ON_Click(object sender, EventArgs e)
        {
            // Start listening
            // Set globals
            Globals.AppInstanceID      = Int32.Parse(con_txt_dcs_instance.Text);
            Globals.AppForceIconReload = true;
            Globals.ErrorsDatabase     = 0;         // Reset error counter
            Globals.ErrorsGame         = 0;         // Reset error counter
            Globals.ErrorsSRS          = 0;         // Reset error counter
            Globals.ErrorsLotATC       = 0;         // Reset error counter
            Globals.StatusConnection   = false;     // Reset connection status

            // Prepare GUI
            form_Main_SetControlsToConnected();
            form_Main_SaveSettings();
            this.Text         = $"[#{con_txt_dcs_instance.Text}] {Globals.AppTitle}"; // Set title bar
            trayIconMain.Text = this.Text;                                            // Set notification icon text

            // Prepare MySQL connection string
            Globals.DatabaseConnection.DatabaseConnectionString = $"server={con_txt_mysql_server.Text};user={con_txt_mysql_username.Text};database={con_txt_mysql_database.Text};port={con_txt_mysql_port.Text};password={con_txt_mysql_password.Text}";

            // Start listening
            PerunHelper.LogInfo(ref Globals.AppLogHistory, "Opening connections", 0, 1);
            Globals.TCPServer.Create(Int32.Parse(con_txt_dcs_server_port.Text), ref Globals.AppLogHistory, ref Globals.DatabaseSendBuffer);
            Globals.TCPServer.thrTCPListener = new Thread(Globals.TCPServer.StartListen);
            Globals.TCPServer.thrTCPListener.Start();
            Globals.TCPServer.thrTCPListener.Name = "TCPThread";

            // Start timmers
            tim_MySQL.Enabled      = true;
            tim_GUI.Enabled        = true;
            tim_3rdparties.Enabled = true;

            // Send initial data
            Tim_MySQL_Tick(null, null);
            tim_3rdparties_Tick(null, null);
            TIM_Autostart.Enabled = false;
        }
コード例 #5
0
ファイル: PerunHelper.cs プロジェクト: szporwolik/perun
    public static int CheckVersions()
    {
        // Checks if all versions (mysql, winapp, lua) are the same  - ommit if run as debug build
#if !DEBUG
        // Checks the versions of APP, DCS Hook and MySQL database
        Match  match      = Regex.Match(Globals.VersionPerun, @"^\d+.\d+.\d+", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        string VersionApp = "v" + match.Groups[0].Value;

        int ReturnValue = 1;
        if (!String.IsNullOrEmpty(Globals.VersionDatabase))
        {
            // Check database
            if (VersionApp != Globals.VersionDatabase)
            {
                // Incorrect database version
                PerunHelper.LogError(ref Globals.AppLogHistory, $"ERROR Incorrect database revision : {Globals.VersionDatabase}", 1, 1, "?");
                Globals.ErrorsDatabase++;
                ReturnValue = 0;
            }
        }

        if (!String.IsNullOrEmpty(Globals.VersionDCSHook))
        {
            // Check database
            if (VersionApp != Globals.VersionDCSHook)
            {
                // Incorrect dcs script version
                PerunHelper.LogError(ref Globals.AppLogHistory, $"ERROR Incorrect DCS hook revision: {Globals.VersionDCSHook}", 2, 1, "?");
                Globals.ErrorsGame++;
                ReturnValue = 0;
            }
        }

        return(ReturnValue);
#else
        return(1);
#endif
    }
コード例 #6
0
ファイル: PerunHelper.cs プロジェクト: silvercn/perun
    public static int CheckVersions()
    {
#if !DEBUG
        // Checks the versions of APP, DCS Hook and MySQL database
        Match  match      = Regex.Match(Globals.VersionPerun, @"^\d+.\d+.\d+", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        string VersionApp = "v" + match.Groups[0].Value;

        int ReturnValue = 1;
        if (!String.IsNullOrEmpty(Globals.VersionDatabase))
        {
            // Check database
            if (VersionApp != Globals.VersionDatabase)
            {
                // Incorrect database version
                PerunHelper.AddLog(ref Globals.AppLogHistory, "ERROR Incorrect database revision : " + Globals.VersionDatabase, 1, 1, "?");
                Globals.ErrorsDatabase++;
                ReturnValue = 0;
            }
        }

        if (!String.IsNullOrEmpty(Globals.VersionDCSHook))
        {
            // Check database
            if (VersionApp != Globals.VersionDCSHook)
            {
                // Incorrect dcs script version
                PerunHelper.AddLog(ref Globals.AppLogHistory, "ERROR Incorrect DCS hook revision : " + Globals.VersionDCSHook, 2, 1, "?");
                Globals.ErrorsGame++;
                ReturnValue = 0;
            }
        }

        return(ReturnValue);
#else
        return(1);
#endif
    }
コード例 #7
0
ファイル: form_Main.cs プロジェクト: VEAF/perun
        private void tim_3rdparties_Tick(object sender, EventArgs e)
        {
            // Main timer to check MySQL connection and send JSON files to MySQL

            // Send ping to check for possible connection issues
            Globals.DatabaseConnection.SendToMySql("", true);

            if (PerunHelper.CheckVersions() == 0)
            {
                MessageBox.Show("Version mismatch detected - please check log files and update.\n\nPerun will now terminate.", "Perun ERROR!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                con_Button_Listen_OFF_Click(null, null);
            }

            // Take care of 3rd party stuff
            string ExtSRSJson    = "";
            string ExtLotATCJson = "";
            string ClientName    = "";

            bool ExtSRSUseDefault    = true;
            bool ExtLotATCUseDefault = true;

            // Handle SRS
            if (Globals.StatusConnection)
            {
                if (con_check_3rd_srs.Checked)
                {
                    try
                    {
                        ExtSRSJson = System.IO.File.ReadAllText(con_txt_3rd_srs.Text);
                        dynamic raw_dcssrs = JsonConvert.DeserializeObject(ExtSRSJson);

                        for (int i = 0; i < raw_dcssrs.Clients.Count; i++)
                        {
                            if (raw_dcssrs.Clients[i].RadioInfo != null)
                            {
                                int temp = raw_dcssrs.Clients[i].RadioInfo.radios.Count - 1;
                                for (int j = temp; j >= 0; j--)
                                {
                                    if (raw_dcssrs.Clients[i].RadioInfo.radios[j].name == "No Radio")
                                    {
                                        raw_dcssrs.Clients[i].RadioInfo.radios[j].Remove();
                                    }
                                }
                            }
                            if (raw_dcssrs.Clients[i].Name != null)
                            {
                                // Clean the user names from non alphanumeric characters
                                ClientName = raw_dcssrs.Clients[i].Name;
                                Regex rgx = new Regex("[^a-zA-Z0-9 -]");
                                ClientName = rgx.Replace(ClientName, "");

                                raw_dcssrs.Clients[i].Name = ClientName;
                            }
                        }

                        ExtSRSJson = JsonConvert.SerializeObject(raw_dcssrs);

                        ExtSRSJson = $"{{'type':'100','instance':'{Int32.Parse(con_txt_dcs_instance.Text)}','payload':{ExtSRSJson}}}";

                        ExtSRSUseDefault = false;
                        PerunHelper.LogInfo(ref Globals.AppLogHistory, "SRS data loaded", 3, 0, "100", true);
                        ExtSRSStatus = true;
                    }
                    catch (Exception exc_srs)
                    {
                        PerunHelper.LogError(ref Globals.AppLogHistory, $"ERROR SRS Data, error: {exc_srs.Message}", 3, 1, "100");
                        ExtSRSStatus = false;
                        Globals.ErrorsSRS++;
                    }
                }
                if (ExtSRSUseDefault)
                {
                    ExtSRSJson = $"{{'type':'100','instance':'{Int32.Parse(con_txt_dcs_instance.Text)}','payload':{{'ignore':'true'}}";
                }
                if (ExtSRSStatus)
                {
                    Globals.DatabaseConnection.SendToMySql(ExtSRSJson);
                }
            }

            // Handle LotATC
            if (Globals.StatusConnection)
            {
                if (con_check_3rd_lotatc.Checked)
                {
                    try
                    {
                        ExtLotATCJson = System.IO.File.ReadAllText(con_txt_3rd_lotatc.Text);

                        ExtLotATCJson       = $"{{'type':'101','instance':'{Int32.Parse(con_txt_dcs_instance.Text)}','payload':{ExtLotATCJson}}}";
                        ExtLotATCUseDefault = false;
                        PerunHelper.LogInfo(ref Globals.AppLogHistory, "LotATC data loaded", 3, 0, "101", true);
                        ExtLotATCStatus = true;
                    }
                    catch (Exception exc_lotatc)
                    {
                        PerunHelper.LogError(ref Globals.AppLogHistory, $"ERROR LotATC Data, error: {exc_lotatc.Message}", 3, 1, "101");
                        ExtLotATCStatus = false;
                        Globals.ErrorsLotATC++;
                    }
                }
                if (ExtLotATCUseDefault)
                {
                    ExtLotATCJson = $"{{'type':'101','instance':'{Int32.Parse(con_txt_dcs_instance.Text)}','payload':{{'ignore':'true'}}}}";   // No LotATC controller connected
                }
                if (ExtLotATCStatus)
                {
                    Globals.DatabaseConnection.SendToMySql(ExtLotATCJson);
                }
            }

            // Let's do not risk int overload
            Globals.ErrorsDatabase = (Globals.ErrorsDatabase > 999) ? 999 : Globals.ErrorsDatabase;
            Globals.ErrorsGame     = (Globals.ErrorsGame > 999) ? 999 : Globals.ErrorsGame;
            Globals.ErrorsSRS      = (Globals.ErrorsSRS > 999) ? 999 : Globals.ErrorsSRS;
            Globals.ErrorsLotATC   = (Globals.ErrorsLotATC > 999) ? 999 : Globals.ErrorsLotATC;
        }
コード例 #8
0
ファイル: form_Main.cs プロジェクト: VEAF/perun
        // ################################ Timers ################################
        private void Tim_GUI_Tick(object sender, EventArgs e)
        {
            // Main timer to sync GUI with background tasks and flush buffers

            // Refresh Log Window
            if (Globals.AppUpdateGUI)
            {
                con_List_Received.Items.Clear();
                foreach (string i in Globals.AppLogHistory)
                {
                    if (i != null)
                    {
                        con_List_Received.Items.Add(i);
                    }
                }
                Globals.AppUpdateGUI = false;
            }
            else
            {
                // Do nothing , control does not require update
            }

            // Enable see log button
            if (Globals.LastLogLocation != "")
            {
                con_Button_See_log.Enabled = true;
            }

            // Update mission status
            if (Globals.CurrentMission.Mission != "")
            {
                label17.Text = Globals.CurrentMission.Mission;
                label18.Text = Globals.CurrentMission.Theatre;
                label19.Text = Globals.CurrentMission.PlayerCount.ToString();

                label21.Text = PerunHelper.SecondsToString(Globals.CurrentMission.ModelTime);
                label16.Text = PerunHelper.SecondsToString(Globals.CurrentMission.RealTime);

                if (Globals.CurrentMission.Pause == "True")
                {
                    label21.Text = $"{label21.Text} (paused)";
                }
            }
            else
            {
                this.form_Main_SetBlankMissionInfo();
            }

            // Update status icons at main form - MySQL
            if ((Globals.DatabaseConnection.DatabaseStatus != Globals.StatusDatabase) || Globals.AppForceIconReload)
            {
                if (Globals.DatabaseConnection.DatabaseStatus)
                {
                    if (Globals.ErrorsDatabase == 0)
                    {
                        con_img_db.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_connected");
                    }
                    else
                    {
                        con_img_db.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_connected_error");
                    }
                }
                else
                {
                    con_img_db.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected_error");
                }
                Globals.StatusDatabase = Globals.DatabaseConnection.DatabaseStatus;
            }
            // Update status icons at main form - DCS
            if ((Globals.StatusConnection != Globals.StatusHistoryConnection) || Globals.AppForceIconReload || Globals.ErrorsGame != Globals.ErrorsHistoryGame)
            {
                if (Globals.StatusConnection)
                {
                    if (Globals.ErrorsGame == 0)
                    {
                        con_img_dcs.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_connected");
                    }
                    else
                    {
                        con_img_dcs.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_connected_error");
                    }
                }
                else
                {
                    con_img_dcs.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected_error");
                }
                Globals.StatusHistoryConnection = Globals.StatusConnection;
                Globals.ErrorsHistoryGame       = Globals.ErrorsGame;
            }

            // Frame times
            label31.Text = $"{Globals.LastFrameTime.ToString("0.")}u";
            label33.Text = $"{Globals.LastFrameDelay.ToString("0.")}u";

            // Check if we shall rate logs
            Globals.RotateLogs = con_check_minimize_to_tray.Checked;

            // Update status icons at main form - SRS
            if ((ExtSRSStatus != Globals.StatusSRS) || Globals.AppForceIconReload)
            {
                if (ExtSRSStatus && con_check_3rd_srs.Checked)
                {
                    if (Globals.ErrorsSRS == 0)
                    {
                        con_img_srs.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_connected");
                    }
                    else
                    {
                        con_img_srs.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_connected_error");
                    }
                }
                else
                {
                    con_img_srs.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected_error");
                }
                Globals.StatusSRS = ExtSRSStatus;
            }
            // Update status icons at main form - LotATC
            if ((ExtLotATCStatus != Globals.StatusLotATC) || Globals.AppForceIconReload)
            {
                if (ExtLotATCStatus && con_check_3rd_lotatc.Checked)
                {
                    if (Globals.ErrorsLotATC == 0)
                    {
                        con_img_lotATC.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_connected");
                    }
                    else
                    {
                        con_img_lotATC.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_connected_error");
                    }
                }
                else
                {
                    con_img_lotATC.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected_error");
                }
                Globals.StatusLotATC = ExtLotATCStatus;
            }
            Globals.AppForceIconReload = false;
        }
コード例 #9
0
ファイル: form_Main.cs プロジェクト: VEAF/perun
 private void con_Button_Add_Marker_Click(object sender, EventArgs e)
 {
     // Added user marker
     PerunHelper.LogError(ref Globals.AppLogHistory, "User Marker", 0, 1);
 }
コード例 #10
0
ファイル: form_Main.cs プロジェクト: VEAF/perun
        public bool ExtLotATCStatus;                                                // True if to use empty/default LotATC status

        // ################################ Main ################################
        private void form_Main_Load(object sender, EventArgs e)
        {
            // Load settings from registry
            form_Main_LoadSettings();

            // Form loaded
            PerunHelper.LogInfo(ref Globals.AppLogHistory, PerunHelper.GetAppVersion("Perun started - "));

            // Display build version in title bar
            Globals.AppTitle = PerunHelper.GetAppVersion(this.Text + " - ");
            this.Text        = Globals.AppTitle;

            // Use command line parameters
            string[] args = Environment.GetCommandLineArgs();
            if (args.Length > 1)
            {
                // Get argument server port
                if (args[1] != null)
                {
                    if (args[1] != "-1")
                    {
                        con_txt_dcs_server_port.Text = args[1];
                    }
                }
            }
            if (args.Length > 2)
            {
                // Get argument instance id
                if (args[2] != null)
                {
                    if (args[2] != "-1")
                    {
                        con_txt_dcs_instance.Text = args[2];
                    }
                }
            }

            if (args.Length > 3)
            {
                // Get argument DCS SRS file path
                if (args[3] != null)
                {
                    if (args[3] != "-1")
                    {
                        con_txt_3rd_srs.Text      = args[3];
                        con_check_3rd_srs.Checked = true;
                    }
                }
            }
            if (args.Length > 4)
            {
                // Get argument lotATC file path
                if (args[4] != null)
                {
                    if (args[4] != "-1")
                    {
                        con_txt_3rd_lotatc.Text      = args[4];
                        con_check_3rd_lotatc.Checked = true;
                    }
                }
            }

            if (args.Length > 5)
            {
                // Get argument lotATC file path
                if (args[5] != null)
                {
                    if (args[5] == "1")
                    {
                        if (args[5] != "-1")
                        {
                            TIM_Autostart.Enabled = true;
                            PerunHelper.LogInfo(ref Globals.AppLogHistory, "Autostart parameter provided", 0, 1);
                        }
                    }
                }
            }

            // Initialize controls
            con_img_db.Image     = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected");
            con_img_dcs.Image    = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected");
            con_img_lotATC.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected");
            con_img_srs.Image    = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected");

            this.form_Main_SetBlankMissionInfo();
        }
コード例 #11
0
    public void StartListen()
    {
        // Start listening
        NetworkStream nsReadStream         = null;
        TcpClient     tcpClient            = null;
        bool          bTCPConnectionOnline = false;
        string        strReceiveBuffer;

        // Main loop - do until diconnect button is clicked
        while (!bCloseConnection)
        {
            Console.WriteLine("TCP Listen start");
            TcpListener tcpServer = new TcpListener(IPAddress.Any, intListenPort);;     // Create listener object

            try
            {
                // Start listening to TCP
                string strReceivedData;

                // Start the main loop
                tcpServer.Start();

                // While user do not clicked Disconnect button
                while (!bCloseConnection)
                {
                    // Start listening
                    Console.WriteLine("TCP: Waiting for connection");
                    Globals.StatusConnection = false;

                    // Wait for pending connection
                    if (tcpServer.Pending())
                    {
                        Console.WriteLine("TCP: Connected");
                        bTCPConnectionOnline = true;
                        tcpClient            = tcpServer.AcceptTcpClient(); //if a connection exists, the server will accept it

                        nsReadStream             = tcpClient.GetStream();   //networkstream is used to send/receive messages
                        nsReadStream.ReadTimeout = 10000;
                        tcpClient.ReceiveTimeout = 10000;

                        while (tcpClient.Connected && !bCloseConnection && bTCPConnectionOnline)  //while the client is connected, we look for incoming messages
                        {
                            StringBuilder CompleteMessage = new StringBuilder();
                            Globals.StatusConnection = true;

                            if (nsReadStream.CanRead)
                            {
                                Console.WriteLine("TCP: Can read");
                                byte[] ReadBuffer = new byte[1024];
                                CompleteMessage = new StringBuilder();
                                int numberOfBytesRead = 0;

                                // Incoming message may be larger than the buffer size.
                                do
                                {
                                    Console.WriteLine("TCP: Read");
                                    numberOfBytesRead = nsReadStream.Read(ReadBuffer, 0, ReadBuffer.Length);
                                    CompleteMessage.AppendFormat("{0}", Encoding.UTF8.GetString(ReadBuffer, 0, numberOfBytesRead));
                                    if (numberOfBytesRead == 0)
                                    {
                                        break;
                                    }
                                }while (nsReadStream.DataAvailable && nsReadStream.CanRead && tcpClient.Connected);
                            }
                            strReceivedData = CompleteMessage.ToString();
                            Console.WriteLine("Sender: {0} Payload: {1}", null, strReceivedData);

                            string pattern = @"(\<SOT\>)+?.*?(\<EOT\>)+?";

                            foreach (Match match in Regex.Matches(strReceivedData, pattern))
                            {
                                strReceiveBuffer = match.Value;

                                Console.WriteLine("Found '{0}' at position {1} end {2}", match.Value, match.Index, match.Length);
                                Console.WriteLine("Prepared {0}", strReceiveBuffer.Substring(5, match.Length - 10));

                                strReceivedData = strReceiveBuffer.Substring(5, match.Length - 10);
                                try
                                {
                                    if (strReceivedData != "")
                                    {
                                        dynamic dynamicRawTCPFrame = JsonConvert.DeserializeObject(strReceivedData); // Deserialize received frame
                                        string  strRawTCPFrameType = dynamicRawTCPFrame.type;

                                        // Check if this is NOT keep alive
                                        if (Int32.Parse(strRawTCPFrameType) != 0)
                                        {
                                            // Add to mySQL send buffer (find first empty slot)
                                            PerunHelper.LogDebug(ref Globals.arrGUILogHistory, "Packet received", 2, 0, strRawTCPFrameType);
                                            bool AddedDataToBuffer = false;
                                            for (int i = 0; i < Globals.arrMySQLSendBuffer.Length - 1; i++)
                                            {
                                                if (Globals.arrMySQLSendBuffer[i] == null)
                                                {
                                                    Globals.arrMySQLSendBuffer[i] = strReceivedData;
                                                    AddedDataToBuffer             = true;
                                                    break;
                                                }
                                            }
                                            if (!AddedDataToBuffer)
                                            {
                                                PerunHelper.LogError(ref Globals.arrGUILogHistory, "ERROR TCP package was dropped", 1, 1, strRawTCPFrameType);
                                            }
                                        }
                                        else
                                        {
                                            // Keep alive
                                            PerunHelper.LogDebug(ref Globals.arrGUILogHistory, "Keep-alive received", 2, 0, "0");
                                        }

                                        if (dynamicRawTCPFrame.dcs_frame_time != null && dynamicRawTCPFrame.dcs_current_frame_delay != null)
                                        {
                                            PerunHelper.SetFrameRates((float)dynamicRawTCPFrame.dcs_frame_time, (float)dynamicRawTCPFrame.dcs_current_frame_delay);
                                        }
                                    }
                                    else
                                    {
                                        bTCPConnectionOnline = false;
                                    }
                                }
                                catch (Exception e)
                                {
                                    Globals.ErrorsGame++;
                                    Console.WriteLine(e.ToString());
                                    PerunHelper.LogError(ref Globals.arrGUILogHistory, $"ERROR TCP while message parsing , error: {e.Message}", 2, 1, "?");
                                    bTCPConnectionOnline = false;
                                }

                                // Send empty byte to check if connection is still alive
                                try
                                {
                                    tcpClient.Client.Send(new byte[] { 0 }, 1, 0);
                                }
                                catch (SocketException e)
                                {
                                    Console.WriteLine(e.ToString());
                                    PerunHelper.LogError(ref Globals.arrGUILogHistory, $"ERROR TCP cannot check connection, error: {e.Message}", 2, 1, "?");
                                }
                            }
                        }
                    }
                    System.Threading.Thread.Sleep(500);
                }
                tcpServer.Stop();
            }
            catch (Exception e)
            {
                Globals.ErrorsGame++;
                Console.WriteLine(e.ToString());
                PerunHelper.LogError(ref Globals.arrGUILogHistory, $"ERROR TCP - connection closed or port in use, error: {e.Message}", 1, 1, "?");

                // Reset last frame times on broken connection
                Globals.LastFrameTime  = 0f;
                Globals.LastFrameDelay = 0f;

                bTCPConnectionOnline = false;
            }

            // Clean up and prepare for next connection
            if (!(nsReadStream is null))
            {
                nsReadStream.Flush();
                nsReadStream.Close();
            }
            if (!(tcpClient is null))
            {
                tcpClient.Close();
            }
            if (!(tcpServer is null))
            {
                tcpServer.Stop();
            }
            Console.WriteLine("TCP listen stop");
        }
    }
コード例 #12
0
        private void tim_3rdparties_Tick(object sender, EventArgs e)
        {
            // Main timer to check MySQL connection and send JSON files to MySQL

            // Send ping to check for possible connection issues
            DatabaseConnection.SendToMySql("", true);

            if (PerunHelper.CheckVersions() == 0)
            {
                MessageBox.Show("Version mismatch detected - please check log files and update.\n\nPerun will now terminate.", "Perun ERROR!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                con_Button_Listen_OFF_Click(null, null);
            }

            // Take care of 3rd party stuff
            string ExtSRSJson    = "";
            string ExtLotATCJson = "";

            bool ExtSRSUseDefault    = true;
            bool ExtLotATCUseDefault = true;

            // Handle SRS
            if (Globals.StatusConnection)
            {
                if (con_check_3rd_srs.Checked)
                {
                    try
                    {
                        ExtSRSJson = System.IO.File.ReadAllText(con_txt_3rd_srs.Text);
                        dynamic raw_lotatc = JsonConvert.DeserializeObject(ExtSRSJson);

                        for (int i = 0; i < raw_lotatc.Clients.Count; i++)
                        {
                            if (raw_lotatc.Clients[i].RadioInfo != null)
                            {
                                int temp = raw_lotatc.Clients[i].RadioInfo.radios.Count - 1;
                                for (int j = temp; j >= 0; j--)
                                {
                                    raw_lotatc.Clients[i].RadioInfo.radios[j].enc.Parent.Remove();
                                    raw_lotatc.Clients[i].RadioInfo.radios[j].encKey.Parent.Remove();
                                    raw_lotatc.Clients[i].RadioInfo.radios[j].encMode.Parent.Remove();
                                    raw_lotatc.Clients[i].RadioInfo.radios[j].freqMax.Parent.Remove();
                                    raw_lotatc.Clients[i].RadioInfo.radios[j].freqMin.Parent.Remove();
                                    raw_lotatc.Clients[i].RadioInfo.radios[j].modulation.Parent.Remove();
                                    raw_lotatc.Clients[i].RadioInfo.radios[j].freqMode.Parent.Remove();
                                    raw_lotatc.Clients[i].RadioInfo.radios[j].volMode.Parent.Remove();
                                    raw_lotatc.Clients[i].RadioInfo.radios[j].expansion.Parent.Remove();
                                    raw_lotatc.Clients[i].RadioInfo.radios[j].channel.Parent.Remove();
                                    raw_lotatc.Clients[i].RadioInfo.radios[j].simul.Parent.Remove();

                                    if (raw_lotatc.Clients[i].RadioInfo.radios[j].name == "No Radio")
                                    {
                                        raw_lotatc.Clients[i].RadioInfo.radios[j].Remove();
                                    }
                                }
                                raw_lotatc.Clients[i].ClientChannelId.Parent.Remove();
                                raw_lotatc.Clients[i].RadioInfo.simultaneousTransmission.Parent.Remove();
                            }
                        }

                        ExtSRSJson = JsonConvert.SerializeObject(raw_lotatc);
                        ExtSRSJson = "{'type':'100','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':'" + ExtSRSJson + "'}";

                        ExtSRSUseDefault = false;
                        PerunHelper.AddLog(ref Globals.AppLogHistory, "SRS data loaded", 3, 0, "100", true);
                        ExtSRSStatus = true;
                    }
                    catch (Exception exc_srs)
                    {
                        PerunHelper.AddLog(ref Globals.AppLogHistory, "SRS data ERROR , error: " + exc_srs.Message, 3, 1, "100");
                        ExtSRSStatus = false;
                        Globals.ErrorsSRS++;
                    }
                }
                if (ExtSRSUseDefault)
                {
                    ExtSRSJson = "{'type':'100','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':{'ignore':'true'}}";
                }
                if (ExtSRSStatus)
                {
                    DatabaseConnection.SendToMySql(ExtSRSJson);
                }
            }

            // Handle LotATC
            if (Globals.StatusConnection)
            {
                if (con_check_3rd_lotatc.Checked)
                {
                    try
                    {
                        ExtLotATCJson = System.IO.File.ReadAllText(con_txt_3rd_lotatc.Text);
                        dynamic raw_srs = JsonConvert.DeserializeObject(ExtLotATCJson);

                        ExtLotATCJson       = "{'type':'101','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':'" + ExtLotATCJson + "'}";
                        ExtLotATCUseDefault = false;
                        PerunHelper.AddLog(ref Globals.AppLogHistory, "LotATC data loaded", 3, 0, "101", true);
                        ExtLotATCStatus = true;
                    }
                    catch (Exception exc_lotatc)
                    {
                        PerunHelper.AddLog(ref Globals.AppLogHistory, "LotATC data ERROR, error: " + exc_lotatc.Message, 3, 1, "101");
                        ExtLotATCStatus = false;
                        Globals.ErrorsLotATC++;
                    }
                }
                if (ExtLotATCUseDefault)
                {
                    ExtLotATCJson = "{'type':'101','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':{'ignore':'true'}}";   // No LotATC controller connected
                }
                if (ExtLotATCStatus)
                {
                    DatabaseConnection.SendToMySql(ExtLotATCJson);
                }
            }

            // Let's do not risk int overload
            Globals.ErrorsDatabase = (Globals.ErrorsDatabase > 999) ? 999 : Globals.ErrorsDatabase;
            Globals.ErrorsGame     = (Globals.ErrorsGame > 999) ? 999 : Globals.ErrorsGame;
            Globals.ErrorsSRS      = (Globals.ErrorsSRS > 999) ? 999 : Globals.ErrorsSRS;
            Globals.ErrorsLotATC   = (Globals.ErrorsLotATC > 999) ? 999 : Globals.ErrorsLotATC;
        }
コード例 #13
0
ファイル: DatabaseController.cs プロジェクト: silvercn/perun
    public int SendToMySql(string RawTCPFrame, bool CheckConnection = false)
    {
        // Main function to send data to mysql
        if (CheckConnection)
        {
            RawTCPFrame = "{\"type\": \"-1\"}";
        }
        dynamic TCPFrame          = JsonConvert.DeserializeObject(RawTCPFrame); // Deserialize raw data
        string  TCPFrameType      = TCPFrame.type;
        string  TCPFrameTimestamp = TCPFrame.timestamp;
        string  TCPFrameInstance  = TCPFrame.instance;
        string  TCPFramePayload;
        string  SQLQueryTxt;
        int     ReturnValue = 1;

        // Some frames may come without timestamp, use database currrent timestampe then
        if (TCPFrameTimestamp != null)
        {
            TCPFrameTimestamp = "'" + TCPFrameTimestamp + "'";
        }
        else
        {
            TCPFrameTimestamp = "CURRENT_TIMESTAMP()";
        }

        // Modify specific types
        if (TCPFrameType == "1")
        {
            TCPFrame.payload["v_win"] = "v" + Globals.VersionPerun; // Inject app version information

            // Pull DCS hook version
            Globals.VersionDCSHook = TCPFrame.payload.v_dcs_hook;
        }

        // Specific SQL per each frame type
        if (TCPFrameType == "50")
        {
            // Add entry to chat log
            SQLQueryTxt  = "INSERT INTO `pe_DataPlayers` (`pe_DataPlayers_ucid`) SELECT '" + TCPFrame.payload.ucid + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataPlayers` where `pe_DataPlayers_ucid` = '" + TCPFrame.payload.ucid + "' );";
            SQLQueryTxt += "UPDATE  `pe_DataPlayers` SET `pe_DataPlayers_updated` = " + TCPFrameTimestamp + ",`pe_DataPlayers_lastname`=@PAR_payload_player WHERE `pe_DataPlayers_ucid`='" + TCPFrame.payload.ucid + "' ;";
            SQLQueryTxt += "INSERT INTO `pe_DataMissionHashes` (`pe_DataMissionHashes_hash`,`pe_DataMissionHashes_instance`) SELECT '" + TCPFrame.payload.missionhash + "','" + TCPFrameInstance + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataMissionHashes` where `pe_DataMissionHashes_hash` ='" + TCPFrame.payload.missionhash + "' AND `pe_DataMissionHashes_instance`=" + TCPFrameInstance + ");";
            SQLQueryTxt += "UPDATE `pe_DataMissionHashes` SET `pe_DataMissionHashes_datetime` = " + TCPFrameTimestamp + " WHERE `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.missionhash + "' AND `pe_DataMissionHashes_instance`=" + TCPFrameInstance + " ;";
            SQLQueryTxt += "INSERT INTO `pe_LogChat` (`pe_LogChat_id`,`pe_LogChat_datetime`, `pe_LogChat_playerid`, `pe_LogChat_msg`, `pe_LogChat_all`,`pe_LogChat_missionhash_id`) VALUES (NULL,'" + TCPFrame.payload.datetime + "', (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + TCPFrame.payload.ucid + "'), @PAR_payload_msg, '" + TCPFrame.payload.all + "',(SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.missionhash + "'));";
        }
        else if (TCPFrameType == "51")
        {
            // Add entry to event log
            SQLQueryTxt  = "INSERT INTO `pe_DataMissionHashes` (`pe_DataMissionHashes_hash`,`pe_DataMissionHashes_instance`) SELECT '" + TCPFrame.payload.log_missionhash + "','" + TCPFrameInstance + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataMissionHashes` where `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.log_missionhash + "' AND `pe_DataMissionHashes_instance`=" + TCPFrameInstance + ");";
            SQLQueryTxt += "UPDATE `pe_DataMissionHashes` SET `pe_DataMissionHashes_datetime` = " + TCPFrameTimestamp + " WHERE `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.log_missionhash + "' AND `pe_DataMissionHashes_instance`=" + TCPFrameInstance + ";";
            SQLQueryTxt += "INSERT INTO `pe_LogEvent` (`pe_LogEvent_arg1`,`pe_LogEvent_arg2`,`pe_LogEvent_id`, `pe_LogEvent_datetime`, `pe_LogEvent_type`, `pe_LogEvent_content`,`pe_LogEvent_missionhash_id`) VALUES ('" + TCPFrame.payload.log_arg_1 + "','" + TCPFrame.payload.log_arg_2 + "', NULL, '" + TCPFrame.payload.log_datetime + "', '" + TCPFrame.payload.log_type + "', @PAR_log_content, (SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.log_missionhash + "'));";
        }
        else if (TCPFrameType == "52")
        {
            // Update user stats
            SQLQueryTxt  = "INSERT INTO `pe_DataMissionHashes` (`pe_DataMissionHashes_hash`,`pe_DataMissionHashes_instance`) SELECT '" + TCPFrame.payload.stat_missionhash + "','" + TCPFrameInstance + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataMissionHashes` where `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.stat_missionhash + "' AND `pe_DataMissionHashes_instance`=" + TCPFrameInstance + ");";
            SQLQueryTxt += "UPDATE `pe_DataMissionHashes` SET `pe_DataMissionHashes_datetime` = " + TCPFrameTimestamp + " WHERE `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.stat_missionhash + "' AND `pe_DataMissionHashes_instance`=" + TCPFrameInstance + " ;";
            SQLQueryTxt += "INSERT INTO `pe_DataPlayers` (`pe_DataPlayers_ucid`) SELECT '" + TCPFrame.payload.stat_ucid + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataPlayers` where `pe_DataPlayers_ucid` = '" + TCPFrame.payload.stat_ucid + "');";
            SQLQueryTxt += "UPDATE `pe_DataPlayers` SET `pe_DataPlayers_updated`=" + TCPFrameTimestamp + " WHERE `pe_DataPlayers_ucid`='" + TCPFrame.payload.stat_ucid + "';";
            SQLQueryTxt += "INSERT INTO `pe_DataTypes` (`pe_DataTypes_name`) SELECT '" + TCPFrame.payload.stat_data_type + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataTypes` where `pe_DataTypes_name` = '" + TCPFrame.payload.stat_data_type + "');";
            SQLQueryTxt += "INSERT INTO `pe_LogStats` (`pe_LogStats_playerid`,`pe_LogStats_missionhash_id`,`pe_LogStats_typeid`) SELECT (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + TCPFrame.payload.stat_ucid + "'), (SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.stat_missionhash + "'), (SELECT pe_DataTypes_id FROM `pe_DataTypes` where `pe_DataTypes_name` = '" + TCPFrame.payload.stat_data_type + "') FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_LogStats` WHERE `pe_LogStats_missionhash_id`=(SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.stat_missionhash + "') AND `pe_LogStats_playerid` =  (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + TCPFrame.payload.stat_ucid + "') AND `pe_LogStats_typeid`= (SELECT pe_DataTypes_id FROM `pe_DataTypes` where `pe_DataTypes_name` = '" + TCPFrame.payload.stat_data_type + "'));";
            SQLQueryTxt += "UPDATE `pe_LogStats` SET `ps_time`=" + TCPFrame.payload.stat_data_perun.ps_time + ",`pe_LogStats_seat`=" + TCPFrame.payload.stat_data_subslot + ",`pe_LogStats_masterslot`=" + TCPFrame.payload.stat_data_masterslot + ",`ps_kills_fortification`=" + TCPFrame.payload.stat_data_perun.ps_kills_fortification + ",`ps_kills_artillery`=" + TCPFrame.payload.stat_data_perun.ps_kills_artillery + ",`ps_other_landings`=" + TCPFrame.payload.stat_data_perun.ps_other_landings + ",`ps_other_takeoffs`=" + TCPFrame.payload.stat_data_perun.ps_other_takeoffs + ",`ps_pvp`=" + TCPFrame.payload.stat_data_perun.ps_pvp + ",`ps_deaths`=" + TCPFrame.payload.stat_data_perun.ps_deaths + ",`ps_ejections`=" + TCPFrame.payload.stat_data_perun.ps_ejections + ",`ps_crashes`=" + TCPFrame.payload.stat_data_perun.ps_crashes + ",`ps_teamkills`=" + TCPFrame.payload.stat_data_perun.ps_teamkills + ",`ps_kills_planes`=" + TCPFrame.payload.stat_data_perun.ps_kills_planes + ",`ps_kills_helicopters`=" + TCPFrame.payload.stat_data_perun.ps_kills_helicopters + ",`ps_kills_air_defense`=" + TCPFrame.payload.stat_data_perun.ps_kills_air_defense + ",`ps_kills_armor`=" + TCPFrame.payload.stat_data_perun.ps_kills_armor + ",`ps_kills_unarmed`=" + TCPFrame.payload.stat_data_perun.ps_kills_unarmed + ",`ps_kills_infantry`=" + TCPFrame.payload.stat_data_perun.ps_kills_infantry + ",`ps_kills_ships`=" + TCPFrame.payload.stat_data_perun.ps_kills_ships + ",`ps_kills_other`=" + TCPFrame.payload.stat_data_perun.ps_kills_other + ",`ps_airfield_takeoffs`=" + TCPFrame.payload.stat_data_perun.ps_airfield_takeoffs + ",`ps_airfield_landings`=" + TCPFrame.payload.stat_data_perun.ps_airfield_landings + ",`ps_ship_takeoffs`=" + TCPFrame.payload.stat_data_perun.ps_ship_takeoffs + ",`ps_ship_landings`=" + TCPFrame.payload.stat_data_perun.ps_ship_landings + ",`ps_farp_takeoffs`=" + TCPFrame.payload.stat_data_perun.ps_farp_takeoffs + ",`ps_farp_landings`=" + TCPFrame.payload.stat_data_perun.ps_farp_landings + ", `pe_LogStats_datetime`='" + TCPFrame.payload.stat_datetime + "',`pe_LogStats_playerid` =  (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + TCPFrame.payload.stat_ucid + "'),`pe_LogStats_missionhash_id`=(SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.stat_missionhash + "') WHERE `pe_LogStats_missionhash_id`=(SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.stat_missionhash + "') AND `pe_LogStats_playerid` =  (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + TCPFrame.payload.stat_ucid + "') AND `pe_LogStats_typeid`=(SELECT pe_DataTypes_id FROM `pe_DataTypes` where `pe_DataTypes_name` = '" + TCPFrame.payload.stat_data_type + "');";
        }
        else if (TCPFrameType == "53")
        {
            // User logged in to DCS server

            SQLQueryTxt  = "INSERT INTO `pe_DataPlayers` (`pe_DataPlayers_ucid`) SELECT '" + TCPFrame.payload.login_ucid + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataPlayers` where pe_DataPlayers_ucid='" + TCPFrame.payload.login_ucid + "');";
            SQLQueryTxt += "UPDATE `pe_DataPlayers` SET  pe_DataPlayers_lastip='" + TCPFrame.payload.login_ipaddr + "', pe_DataPlayers_lastname=@PAR_login_name,pe_DataPlayers_updated='" + TCPFrame.payload.login_datetime + "' WHERE `pe_DataPlayers_ucid`= '" + TCPFrame.payload.login_ucid + "';";
            SQLQueryTxt += "INSERT INTO `pe_LogLogins` (`pe_LogLogins_datetime`, `pe_LogLogins_playerid`, `pe_LogLogins_name`, `pe_LogLogins_ip`,`pe_LogLogins_instance`) VALUES ('" + TCPFrame.payload.login_datetime + "', (SELECT pe_DataPlayers_id from pe_DataPlayers WHERE pe_DataPlayers_ucid = '" + TCPFrame.payload.login_ucid + "'), @PAR_login_name, '" + TCPFrame.payload.login_ipaddr + "','" + TCPFrameInstance + "');";
        }
        else if (TCPFrameType == "-1")
        {
            // Keep alive message
            SQLQueryTxt = "SELECT `pe_Config_payload` FROM `pe_Config` WHERE `pe_Config_id` = 1;";
        }
        else
        {
            // General definition used for 1-10 type packets


            SQLQueryTxt  = "INSERT INTO `pe_DataRaw` (`pe_dataraw_type`,`pe_dataraw_instance`) SELECT '" + TCPFrameType + "','" + TCPFrameInstance + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataRaw` WHERE `pe_dataraw_type` = '" + TCPFrameType + "' AND `pe_dataraw_instance` = " + TCPFrameInstance + ");";
            SQLQueryTxt += "UPDATE `pe_DataRaw` SET `pe_dataraw_payload` = @PAR_TCPFramePayload, `pe_dataraw_updated`=" + TCPFrameTimestamp + " WHERE `pe_dataraw_type`=" + TCPFrameType + " AND `pe_dataraw_instance` = " + TCPFrameInstance + ";";
        }

        // Connect to mysql and execute sql
        try
        {
            DatabaseConnection = new MySqlConnection(DatabaseConnectionString);

            try
            {
                Console.WriteLine("Sending data to MySQL - Begin");
                DatabaseConnection.Open();
                DatabaseStatus = true;
                MySqlCommand DatabaseCommand = new MySqlCommand(SQLQueryTxt, DatabaseConnection);

                // Add parameters - prevent SQL injection
                if (TCPFrameType == "50")
                {
                    DatabaseCommand.Parameters.AddWithValue("@PAR_payload_player", TCPFrame.payload.player);
                    DatabaseCommand.Parameters.AddWithValue("@PAR_payload_msg", TCPFrame.payload.msg);
                }
                else if (TCPFrameType == "51")
                {
                    DatabaseCommand.Parameters.AddWithValue("@PAR_log_content", TCPFrame.payload.log_content);
                }
                else if (TCPFrameType == "53")
                {
                    DatabaseCommand.Parameters.AddWithValue("@PAR_login_name", TCPFrame.payload.login_name);
                }
                else
                {
                    TCPFramePayload = JsonConvert.SerializeObject(TCPFrame.payload); // Deserialize payload
                    DatabaseCommand.Parameters.AddWithValue("@PAR_TCPFramePayload", TCPFramePayload);
                }
                // End of add parameters

                MySqlDataReader DatabaseReader = DatabaseCommand.ExecuteReader();

                if (DatabaseReader.HasRows)
                {
                    while (DatabaseReader.Read())
                    {
                        if (TCPFrameType == "-1")
                        {
                            Globals.VersionDatabase = DatabaseReader.GetString(0);
                        }
                    }
                }
                else
                {
                    // Do nothing
                }

                DatabaseReader.Close();

                switch (Int32.Parse(TCPFrameType))
                {
                case 1:
                    PerunHelper.AddLog(ref Globals.AppLogHistory, "Connected players: " + TCPFrame.payload["c_players"], 1, 0, "1");
                    break;

                case 2:
                    PerunHelper.AddLog(ref Globals.AppLogHistory, "Mission: \"" + TCPFrame.payload["mission"]["name"] + "\"" + ", time:" + TCPFrame.payload["mission"]["modeltime"], 1, 0, "2");
                    break;

                case 3:
                    PerunHelper.AddLog(ref Globals.AppLogHistory, "Slots data updated", 1, 0, "3");
                    break;

                case 50:
                    PerunHelper.AddLog(ref Globals.AppLogHistory, "Player's \"" + TCPFrame.payload.player + "\" chat message saved", 1, 0, "50");
                    break;

                case 51:
                    PerunHelper.AddLog(ref Globals.AppLogHistory, "Game event: \"" + TCPFrame.payload.log_content + "\"", 1, 0, "51");
                    break;

                case 52:
                    PerunHelper.AddLog(ref Globals.AppLogHistory, "Player's \"" + TCPFrame.payload.stat_name + "\" stats saved", 1, 0, "52");
                    break;

                case 53:
                    PerunHelper.AddLog(ref Globals.AppLogHistory, "Player \"" + TCPFrame.payload.login_name + "\" logged in", 1, 0, "53");
                    break;

                case 100:
                    PerunHelper.AddLog(ref Globals.AppLogHistory, "SRS data send", 1, 0, "100");
                    break;

                case 101:
                    PerunHelper.AddLog(ref Globals.AppLogHistory, "LotATC data send", 1, 0, "101");
                    break;

                case -1:
                    break;

                default:
                    PerunHelper.AddLog(ref Globals.AppLogHistory, "Data send", 1, 0, TCPFrameType);
                    break;
                }
            }
            catch (ArgumentException a_ex)
            {
                // General exception found
                Console.WriteLine(a_ex.ToString());
                PerunHelper.AddLog(ref Globals.AppLogHistory, "ERROR MySQL - error: " + a_ex.Message, 1, 1, TCPFrameType);
                Globals.ErrorsGame++;
                DatabaseStatus = false;
                ReturnValue    = 0;
            }
            catch (MySqlException m_ex)
            {
                // MySQL exception found
                switch (m_ex.Number)
                {
                case 1042:     // Unable to connect to any of the specified MySQL hosts (Check Server,Port)
                    PerunHelper.AddLog(ref Globals.AppLogHistory, "ERROR MySQL - unable to connect, error: " + m_ex.Message, 1, 1, TCPFrameType);
                    DatabaseStatus = false;
                    ReturnValue    = 0;
                    break;

                case 0:     // Access denied (Check DB name,username,password)
                    PerunHelper.AddLog(ref Globals.AppLogHistory, "ERROR MySQL - access denied, error: " + m_ex.Message, 1, 1, TCPFrameType);
                    DatabaseStatus = false;
                    ReturnValue    = 0;
                    break;

                case 1064:     // Incorrect query
                    PerunHelper.AddLog(ref Globals.AppLogHistory, "ERROR MySQL - query: " + SQLQueryTxt, 1, 1, TCPFrameType);
                    PerunHelper.AddLog(ref Globals.AppLogHistory, "ERROR MySQL - error: " + m_ex.Message, 1, 1, TCPFrameType);
                    DatabaseStatus = true; // True as connection is not broken
                    ReturnValue    = 1;    // Return a value to remove this query from quae
                    break;

                default:
                    PerunHelper.AddLog(ref Globals.AppLogHistory, "ERROR MySQL - error id: " + m_ex.Number, 1, 1, TCPFrameType);
                    PerunHelper.AddLog(ref Globals.AppLogHistory, "ERROR MySQL - query: " + SQLQueryTxt, 1, 1, TCPFrameType);
                    PerunHelper.AddLog(ref Globals.AppLogHistory, "ERROR MySQL - error: " + m_ex.Message, 1, 1, TCPFrameType);
                    DatabaseStatus = false;
                    ReturnValue    = 0;
                    break;
                }
                Globals.ErrorsGame++;
            }
            DatabaseConnection.Close();
            Console.WriteLine("Sending data to MySQL - Done");
        }
        catch (ArgumentException x_ex)
        {
            PerunHelper.AddLog(ref Globals.AppLogHistory, "ERROR MySQL - unable to connect, error: " + x_ex.Message, 1, 1, TCPFrameType);
            ReturnValue = 0;
            Globals.ErrorsGame++;
        }

        return(ReturnValue);
    }
コード例 #14
0
    public bool DatabaseStatus;                             // MySQL connections status

    public int SendToMySql(string RawTCPFrame, bool CheckConnection = false)
    {
        // Main function to send data to mysql
        string SQLQueryTxt = "";                                        // MySQL Query string
        int    ReturnValue = 1;                                         // Default return value [1 for success]

        // Below is used to check if we still have database connection
        if (CheckConnection)
        {
            RawTCPFrame = "{\"type\": \"-1\"}";
        }

        // Parse frame
        dynamic TCPFrame          = JsonConvert.DeserializeObject(RawTCPFrame);                                         // Deserialize raw data
        string  TCPFrameType      = TCPFrame.type;                                                                      // Frame type
        string  TCPFrameTimestamp = (TCPFrame.timestamp != null) ? $"'{TCPFrame.timestamp}'" : "CURRENT_TIMESTAMP()";   // Frame timestamp (Some frames may come without timestamp, use database timestamp then)
        string  TCPFrameInstance  = TCPFrame.instance;                                                                  // Frame instance
        string  TCPFramePayload;                                                                                        // Frame payload (we will deserialise only for specific frame types)

        // Connect to mysql and execute sql
        try
        {
            DatabaseConnection = new MySqlConnection(DatabaseConnectionString);

            try
            {
                Console.WriteLine("Sending data to MySQL - Begin");
                DatabaseConnection.Open();
                DatabaseStatus = true;


                string       LogInfo         = "";
                int          LogDirection    = 1;
                MySqlCommand DatabaseCommand = null;

                // For frames 1 to 10 we will put those into data raw tables
                if (Int32.Parse(TCPFrameType) >= 1 && Int32.Parse(TCPFrameType) <= 10)
                {
                    SQLQueryTxt  = "INSERT INTO `pe_DataRaw` (`pe_dataraw_type`,`pe_dataraw_instance`) SELECT '" + TCPFrameType + "','" + TCPFrameInstance + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataRaw` WHERE `pe_dataraw_type` = '" + TCPFrameType + "' AND `pe_dataraw_instance` = " + TCPFrameInstance + ");";
                    SQLQueryTxt += "UPDATE `pe_DataRaw` SET `pe_dataraw_payload` = @PAR_TCPFramePayload, `pe_dataraw_updated`=" + TCPFrameTimestamp + " WHERE `pe_dataraw_type`=" + TCPFrameType + " AND `pe_dataraw_instance` = " + TCPFrameInstance + ";";
                }
                else
                {
                    SQLQueryTxt = "";
                }

                switch (Int32.Parse(TCPFrameType))
                {
                case -1:
                    // Keep alive message
                    LogInfo      = $"Reading MySQL config";
                    LogDirection = 3;

                    SQLQueryTxt = "SELECT `pe_Config_payload` FROM `pe_Config` WHERE `pe_Config_id` = 1;";

                    DatabaseCommand = new MySqlCommand(SQLQueryTxt, DatabaseConnection);
                    break;

                case 1:
                    // General status information (diagnostic information)
                    LogInfo = $"Status data updated";

                    TCPFrame.payload.server["v_win"] = "v" + Globals.VersionPerun;  // Inject app version information (for database)
                    Globals.VersionDCSHook           = TCPFrame.payload.v_dcs_hook; // Pull DCS hook version (for app)

                    SQLQueryTxt += "INSERT INTO `pe_OnlineStatus` (`pe_OnlineStatus_instance`) SELECT @PAR_TCPFrameInstance FROM DUAL WHERE NOT EXISTS(SELECT * FROM `pe_OnlineStatus` WHERE `pe_OnlineStatus_instance` = @PAR_TCPFrameInstance);";
                    SQLQueryTxt += "UPDATE `pe_OnlineStatus` SET `pe_OnlineStatus_perunversion_winapp` = '" + TCPFrame.payload.server.v_win + "', `pe_OnlineStatus_perunversion_dcshook` ='" + TCPFrame.payload.server.v_dcs_hook + "' WHERE `pe_OnlineStatus_instance` = @PAR_TCPFrameInstance ;";
                    SQLQueryTxt += "DELETE FROM pe_OnlinePlayers WHERE pe_OnlinePlayers_instance = @PAR_TCPFrameInstance;";

                    int player_count = 0;
                    foreach (var record_player in TCPFrame.payload.clients)
                    {
                        SQLQueryTxt += "INSERT INTO `pe_OnlinePlayers` (`pe_OnlinePlayers_id`, `pe_OnlinePlayers_instance`, `pe_OnlinePlayers_ping`, `pe_OnlinePlayers_side`, `pe_OnlinePlayers_slot`, `pe_OnlinePlayers_ucid`, `pe_OnlinePlayers_name`) VALUES (" + record_player.id + ", @PAR_TCPFrameInstance, '" + record_player.ping + "', '" + record_player.side + "', '" + record_player.slot + "', '" + record_player.ucid + $"',@PAR_UserName_{player_count});";
                        player_count++;
                        Globals.CurrentMission.PlayerCount = player_count;     // Save information for GUI - player count
                    }
                    SQLQueryTxt += "INSERT INTO `pe_OnlineStatus` (`pe_OnlineStatus_instance`) SELECT @PAR_TCPFrameInstance FROM DUAL WHERE NOT EXISTS(SELECT * FROM `pe_OnlineStatus` WHERE `pe_OnlineStatus_instance` = @PAR_TCPFrameInstance);";
                    SQLQueryTxt += "UPDATE `pe_OnlineStatus` SET `pe_OnlineStatus_mission_theatre` = @PAR_MissionTheathre, `pe_OnlineStatus_mission_name` = @PAR_MissionName , `pe_OnlineStatus_server_pause` = @PAR_MissionPause, `pe_OnlineStatus_mission_multiplayer` = '" + TCPFrame.payload.mission.multiplayer + "', `pe_OnlineStatus_server_realtime` = '" + TCPFrame.payload.mission.realtime + "', `pe_OnlineStatus_mission_modeltime` = '" + TCPFrame.payload.mission.modeltime + "', `pe_OnlineStatus_server_players` =  " + player_count + " WHERE `pe_OnlineStatus_instance` = @PAR_TCPFrameInstance;";

                    DatabaseCommand = new MySqlCommand(SQLQueryTxt, DatabaseConnection);
                    TCPFramePayload = JsonConvert.SerializeObject(TCPFrame.payload);     // Deserialize payload TUTAJ DODAC CATCH TBD
                    DatabaseCommand.Parameters.AddWithValue("@PAR_TCPFramePayload", TCPFramePayload);
                    DatabaseCommand.Parameters.AddWithValue("@PAR_TCPFrameInstance", TCPFrameInstance);
                    DatabaseCommand.Parameters.AddWithValue("@PAR_MissionName", TCPFrame.payload.mission.name);
                    DatabaseCommand.Parameters.AddWithValue("@PAR_MissionTheathre", TCPFrame.payload.mission.theatre);
                    DatabaseCommand.Parameters.AddWithValue("@PAR_MissionPause", TCPFrame.payload.mission.pause);

                    player_count = 0;
                    foreach (var record_player in TCPFrame.payload.clients)
                    {
                        DatabaseCommand.Parameters.AddWithValue($"@PAR_UserName_{player_count}", TCPFrame.payload.clients[player_count].name);
                        player_count++;
                    }

                    // Save for GUI
                    Globals.CurrentMission.Theatre = TCPFrame.payload.mission.theatre;      // Mission theatre
                    Globals.CurrentMission.Mission = TCPFrame.payload.mission.name;         // Mission name
                    Globals.CurrentMission.Pause   = TCPFrame.payload.mission.pause;        // Mission pause

                    Globals.CurrentMission.ModelTime = TCPFrame.payload.mission.modeltime;  // Mission time
                    Globals.CurrentMission.RealTime  = TCPFrame.payload.mission.realtime;   // Since start of server
                    break;

                case 2:
                    // Slots Data (basic mission etc)
                    LogInfo = $"Slots data updated";

                    DatabaseCommand = new MySqlCommand(SQLQueryTxt, DatabaseConnection);
                    TCPFramePayload = JsonConvert.SerializeObject(TCPFrame.payload);     // Deserialize payload
                    DatabaseCommand.Parameters.AddWithValue("@PAR_TCPFramePayload", TCPFramePayload);

                    break;

                case 50:
                    // Chat entry
                    LogInfo = $"Player \"{TCPFrame.payload.player}\" -> chat message saved";

                    SQLQueryTxt  = "INSERT INTO `pe_DataPlayers` (`pe_DataPlayers_ucid`) SELECT '" + TCPFrame.payload.ucid + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataPlayers` where `pe_DataPlayers_ucid` = '" + TCPFrame.payload.ucid + "' );";
                    SQLQueryTxt += "UPDATE  `pe_DataPlayers` SET `pe_DataPlayers_updated` = " + TCPFrameTimestamp + ",`pe_DataPlayers_lastname`=@PAR_payload_player WHERE `pe_DataPlayers_ucid`='" + TCPFrame.payload.ucid + "' ;";
                    SQLQueryTxt += "INSERT INTO `pe_DataMissionHashes` (`pe_DataMissionHashes_hash`,`pe_DataMissionHashes_instance`) SELECT '" + TCPFrame.payload.missionhash + "','" + TCPFrameInstance + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataMissionHashes` where `pe_DataMissionHashes_hash` ='" + TCPFrame.payload.missionhash + "' AND `pe_DataMissionHashes_instance`=" + TCPFrameInstance + ");";
                    SQLQueryTxt += "UPDATE `pe_DataMissionHashes` SET `pe_DataMissionHashes_datetime` = " + TCPFrameTimestamp + " WHERE `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.missionhash + "' AND `pe_DataMissionHashes_instance`=" + TCPFrameInstance + " ;";
                    SQLQueryTxt += "INSERT INTO `pe_LogChat` (`pe_LogChat_id`,`pe_LogChat_datetime`, `pe_LogChat_playerid`, `pe_LogChat_msg`, `pe_LogChat_all`,`pe_LogChat_missionhash_id`) VALUES (NULL,'" + TCPFrame.payload.datetime + "', (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + TCPFrame.payload.ucid + "'), @PAR_payload_msg, '" + TCPFrame.payload.all + "',(SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.missionhash + "'));";

                    DatabaseCommand = new MySqlCommand(SQLQueryTxt, DatabaseConnection);

                    DatabaseCommand.Parameters.AddWithValue("@PAR_payload_player", TCPFrame.payload.player);
                    DatabaseCommand.Parameters.AddWithValue("@PAR_payload_msg", TCPFrame.payload.msg);

                    break;

                case 51:
                    // Add entry to event log
                    LogInfo = $"Game event \"{TCPFrame.payload.log_content}\" -> saved";

                    SQLQueryTxt  = "INSERT INTO `pe_DataMissionHashes` (`pe_DataMissionHashes_hash`,`pe_DataMissionHashes_instance`) SELECT '" + TCPFrame.payload.log_missionhash + "','" + TCPFrameInstance + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataMissionHashes` where `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.log_missionhash + "' AND `pe_DataMissionHashes_instance`=" + TCPFrameInstance + ");";
                    SQLQueryTxt += "UPDATE `pe_DataMissionHashes` SET `pe_DataMissionHashes_datetime` = " + TCPFrameTimestamp + " WHERE `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.log_missionhash + "' AND `pe_DataMissionHashes_instance`=" + TCPFrameInstance + ";";
                    SQLQueryTxt += "INSERT INTO `pe_LogEvent` (`pe_LogEvent_arg1`,`pe_LogEvent_arg2`,`pe_LogEvent_id`, `pe_LogEvent_datetime`, `pe_LogEvent_type`, `pe_LogEvent_content`,`pe_LogEvent_missionhash_id`) VALUES ('" + TCPFrame.payload.log_arg_1 + "','" + TCPFrame.payload.log_arg_2 + "', NULL, '" + TCPFrame.payload.log_datetime + "', '" + TCPFrame.payload.log_type + "', @PAR_log_content, (SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.log_missionhash + "'));";

                    DatabaseCommand = new MySqlCommand(SQLQueryTxt, DatabaseConnection);

                    DatabaseCommand.Parameters.AddWithValue("@PAR_log_content", TCPFrame.payload.log_content);

                    break;

                case 52:
                    // Update user stats
                    LogInfo = $"Player \"{TCPFrame.payload.stat_name}\" -> stats updated";

                    SQLQueryTxt  = "INSERT INTO `pe_DataMissionHashes` (`pe_DataMissionHashes_hash`,`pe_DataMissionHashes_instance`) SELECT '" + TCPFrame.payload.stat_missionhash + "','" + TCPFrameInstance + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataMissionHashes` where `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.stat_missionhash + "' AND `pe_DataMissionHashes_instance`=" + TCPFrameInstance + ");";
                    SQLQueryTxt += "UPDATE `pe_DataMissionHashes` SET `pe_DataMissionHashes_datetime` = " + TCPFrameTimestamp + " WHERE `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.stat_missionhash + "' AND `pe_DataMissionHashes_instance`=" + TCPFrameInstance + " ;";
                    SQLQueryTxt += "INSERT INTO `pe_DataPlayers` (`pe_DataPlayers_ucid`) SELECT '" + TCPFrame.payload.stat_ucid + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataPlayers` where `pe_DataPlayers_ucid` = '" + TCPFrame.payload.stat_ucid + "');";
                    SQLQueryTxt += "UPDATE `pe_DataPlayers` SET `pe_DataPlayers_updated`=" + TCPFrameTimestamp + " WHERE `pe_DataPlayers_ucid`='" + TCPFrame.payload.stat_ucid + "';";
                    SQLQueryTxt += "INSERT INTO `pe_DataTypes` (`pe_DataTypes_name`) SELECT '" + TCPFrame.payload.stat_data_type + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataTypes` where `pe_DataTypes_name` = '" + TCPFrame.payload.stat_data_type + "');";
                    SQLQueryTxt += "INSERT INTO `pe_LogStats` (`pe_LogStats_playerid`,`pe_LogStats_missionhash_id`,`pe_LogStats_typeid`) SELECT (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + TCPFrame.payload.stat_ucid + "'), (SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.stat_missionhash + "'), (SELECT pe_DataTypes_id FROM `pe_DataTypes` where `pe_DataTypes_name` = '" + TCPFrame.payload.stat_data_type + "') FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_LogStats` WHERE `pe_LogStats_missionhash_id`=(SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.stat_missionhash + "') AND `pe_LogStats_playerid` =  (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + TCPFrame.payload.stat_ucid + "') AND `pe_LogStats_typeid`= (SELECT pe_DataTypes_id FROM `pe_DataTypes` where `pe_DataTypes_name` = '" + TCPFrame.payload.stat_data_type + "'));";
                    SQLQueryTxt += "UPDATE `pe_LogStats` SET `ps_time`=" + TCPFrame.payload.stat_data_perun.ps_time + ",`pe_LogStats_seat`=" + TCPFrame.payload.stat_data_subslot + ",`pe_LogStats_masterslot`=" + TCPFrame.payload.stat_data_masterslot + ",`ps_kills_fortification`=" + TCPFrame.payload.stat_data_perun.ps_kills_fortification + ",`ps_kills_artillery`=" + TCPFrame.payload.stat_data_perun.ps_kills_artillery + ",`ps_other_landings`=" + TCPFrame.payload.stat_data_perun.ps_other_landings + ",`ps_other_takeoffs`=" + TCPFrame.payload.stat_data_perun.ps_other_takeoffs + ",`ps_pvp`=" + TCPFrame.payload.stat_data_perun.ps_pvp + ",`ps_deaths`=" + TCPFrame.payload.stat_data_perun.ps_deaths + ",`ps_ejections`=" + TCPFrame.payload.stat_data_perun.ps_ejections + ",`ps_crashes`=" + TCPFrame.payload.stat_data_perun.ps_crashes + ",`ps_teamkills`=" + TCPFrame.payload.stat_data_perun.ps_teamkills + ",`ps_kills_planes`=" + TCPFrame.payload.stat_data_perun.ps_kills_planes + ",`ps_kills_helicopters`=" + TCPFrame.payload.stat_data_perun.ps_kills_helicopters + ",`ps_kills_air_defense`=" + TCPFrame.payload.stat_data_perun.ps_kills_air_defense + ",`ps_kills_armor`=" + TCPFrame.payload.stat_data_perun.ps_kills_armor + ",`ps_kills_unarmed`=" + TCPFrame.payload.stat_data_perun.ps_kills_unarmed + ",`ps_kills_infantry`=" + TCPFrame.payload.stat_data_perun.ps_kills_infantry + ",`ps_kills_ships`=" + TCPFrame.payload.stat_data_perun.ps_kills_ships + ",`ps_kills_other`=" + TCPFrame.payload.stat_data_perun.ps_kills_other + ",`ps_airfield_takeoffs`=" + TCPFrame.payload.stat_data_perun.ps_airfield_takeoffs + ",`ps_airfield_landings`=" + TCPFrame.payload.stat_data_perun.ps_airfield_landings + ",`ps_ship_takeoffs`=" + TCPFrame.payload.stat_data_perun.ps_ship_takeoffs + ",`ps_ship_landings`=" + TCPFrame.payload.stat_data_perun.ps_ship_landings + ",`ps_farp_takeoffs`=" + TCPFrame.payload.stat_data_perun.ps_farp_takeoffs + ",`ps_farp_landings`=" + TCPFrame.payload.stat_data_perun.ps_farp_landings + ", `pe_LogStats_datetime`='" + TCPFrame.payload.stat_datetime + "',`pe_LogStats_playerid` =  (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + TCPFrame.payload.stat_ucid + "'),`pe_LogStats_missionhash_id`=(SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.stat_missionhash + "') WHERE `pe_LogStats_missionhash_id`=(SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.stat_missionhash + "') AND `pe_LogStats_playerid` =  (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + TCPFrame.payload.stat_ucid + "') AND `pe_LogStats_typeid`=(SELECT pe_DataTypes_id FROM `pe_DataTypes` where `pe_DataTypes_name` = '" + TCPFrame.payload.stat_data_type + "');";

                    DatabaseCommand = new MySqlCommand(SQLQueryTxt, DatabaseConnection);

                    break;

                case 53:
                    // User logged in to DCS server
                    LogInfo = $"Player \"{TCPFrame.payload.login_name}\" -> logged in";

                    SQLQueryTxt  = "INSERT INTO `pe_DataPlayers` (`pe_DataPlayers_ucid`) SELECT '" + TCPFrame.payload.login_ucid + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataPlayers` where pe_DataPlayers_ucid='" + TCPFrame.payload.login_ucid + "');";
                    SQLQueryTxt += "UPDATE `pe_DataPlayers` SET  pe_DataPlayers_lastip='" + TCPFrame.payload.login_ipaddr + "', pe_DataPlayers_lastname=@PAR_login_name,pe_DataPlayers_updated='" + TCPFrame.payload.login_datetime + "' WHERE `pe_DataPlayers_ucid`= '" + TCPFrame.payload.login_ucid + "';";
                    SQLQueryTxt += "INSERT INTO `pe_LogLogins` (`pe_LogLogins_datetime`, `pe_LogLogins_playerid`, `pe_LogLogins_name`, `pe_LogLogins_ip`,`pe_LogLogins_instance`) VALUES ('" + TCPFrame.payload.login_datetime + "', (SELECT pe_DataPlayers_id from pe_DataPlayers WHERE pe_DataPlayers_ucid = '" + TCPFrame.payload.login_ucid + "'), @PAR_login_name, '" + TCPFrame.payload.login_ipaddr + "','" + TCPFrameInstance + "');";

                    DatabaseCommand = new MySqlCommand(SQLQueryTxt, DatabaseConnection);

                    DatabaseCommand.Parameters.AddWithValue("@PAR_login_name", TCPFrame.payload.login_name);

                    break;

                default:
                    // General definition used for other packets

                    // Switch to insert correct log information
                    switch (Int32.Parse(TCPFrameType))
                    {
                    case 3:
                        LogInfo = "Mission data updated";
                        break;

                    case 100:
                        LogInfo = "DCS SRS data updated";
                        break;

                    case 101:
                        LogInfo = "LotATC data updated";
                        break;

                    default:
                        LogInfo = "Unknown data updated";
                        break;
                    }

                    SQLQueryTxt  = "INSERT INTO `pe_DataRaw` (`pe_dataraw_type`,`pe_dataraw_instance`) SELECT '" + TCPFrameType + "','" + TCPFrameInstance + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataRaw` WHERE `pe_dataraw_type` = '" + TCPFrameType + "' AND `pe_dataraw_instance` = " + TCPFrameInstance + ");";
                    SQLQueryTxt += "UPDATE `pe_DataRaw` SET `pe_dataraw_payload` = @PAR_TCPFramePayload, `pe_dataraw_updated`=" + TCPFrameTimestamp + " WHERE `pe_dataraw_type`=" + TCPFrameType + " AND `pe_dataraw_instance` = " + TCPFrameInstance + ";";

                    DatabaseCommand = new MySqlCommand(SQLQueryTxt, DatabaseConnection);

                    TCPFramePayload = JsonConvert.SerializeObject(TCPFrame.payload);     // Deserialize payload
                    DatabaseCommand.Parameters.AddWithValue("@PAR_TCPFramePayload", TCPFramePayload);

                    break;
                }

                // End of add parameters
                MySqlDataReader DatabaseReader = DatabaseCommand.ExecuteReader();
                PerunHelper.LogDebug(ref Globals.AppLogHistory, LogInfo, LogDirection, 0, TCPFrameType);

                // Handle reading from database
                if (DatabaseReader.HasRows)
                {
                    while (DatabaseReader.Read())
                    {
                        PerunHelper.LogDebug(ref Globals.AppLogHistory, $"Received MySQL response, fields: {DatabaseReader.FieldCount}", 2, 0, TCPFrameType);
                        if (TCPFrameType == "-1")
                        {
                            Globals.VersionDatabase = DatabaseReader.GetString(0);
                        }
                    }
                }
                DatabaseReader.Close();
            }
            catch (ArgumentException a_ex)
            {
                // General exception found
                Console.WriteLine(a_ex.ToString());
                PerunHelper.LogError(ref Globals.AppLogHistory, $"ERROR MySQL - error: {a_ex.Message}", 1, 1, TCPFrameType);
                Globals.ErrorsGame++;
                DatabaseStatus = false;
                ReturnValue    = 0;
            }
            catch (MySqlException m_ex)
            {
                // MySQL exception found
                switch (m_ex.Number)
                {
                case 0:     // Access denied (Check DB name,username,password)
                    PerunHelper.LogError(ref Globals.AppLogHistory, $"ERROR MySQL - access denied, error: {m_ex.Message}", 1, 1, TCPFrameType);
                    DatabaseStatus = false;
                    ReturnValue    = 0;
                    break;

                case 1042:     // Unable to connect to any of the specified MySQL hosts (Check Server,Port)
                    PerunHelper.LogError(ref Globals.AppLogHistory, $"ERROR MySQL - unable to connect, error: {m_ex.Message}", 1, 1, TCPFrameType);
                    DatabaseStatus = false;
                    ReturnValue    = 0;
                    break;

                case 1064:     // Incorrect query
                    PerunHelper.LogError(ref Globals.AppLogHistory, $"ERROR MySQL - query: {SQLQueryTxt}", 1, 1, TCPFrameType);
                    PerunHelper.LogError(ref Globals.AppLogHistory, $"ERROR MySQL - error: {m_ex.Message}", 1, 1, TCPFrameType);
                    DatabaseStatus = true; // True as connection is not broken
                    ReturnValue    = 1;    // Return a value to remove this query from quae
                    break;

                default:        // Default error handler
                    PerunHelper.LogError(ref Globals.AppLogHistory, $"ERROR MySQL - error id: {m_ex.Number}", 1, 1, TCPFrameType);
                    PerunHelper.LogError(ref Globals.AppLogHistory, $"ERROR MySQL - query: {SQLQueryTxt}", 1, 1, TCPFrameType);
                    PerunHelper.LogError(ref Globals.AppLogHistory, $"ERROR MySQL - error: {m_ex.Message}", 1, 1, TCPFrameType);
                    DatabaseStatus = false;
                    ReturnValue    = 0;
                    break;
                }
                Globals.ErrorsGame++;
            }
            catch (Exception e)
            {
                // General exception found
                Console.WriteLine(e.ToString());
                PerunHelper.LogError(ref Globals.AppLogHistory, $"ERROR General - error: {e.Message}", 1, 1, TCPFrameType);
                Globals.ErrorsGame++;
                DatabaseStatus = false;
                ReturnValue    = 0;
            }
            DatabaseConnection.Close();
            Console.WriteLine("Sending data to MySQL - Done");
        }
        catch (ArgumentException x_ex)
        {
            // MySQL connection error
            PerunHelper.LogError(ref Globals.AppLogHistory, $"ERROR MySQL - unable to connect, error: {x_ex.Message}", 1, 1, TCPFrameType);
            ReturnValue = 0;
            Globals.ErrorsGame++;
        }

        return(ReturnValue);
    }