From 67eda5d79b9a2ba31e539c22eed2864ec75f2c2b Mon Sep 17 00:00:00 2001 From: szporowolik Date: Mon, 21 Oct 2019 01:53:49 +0200 Subject: [PATCH 01/23] v0.8.3 - hotfix for disconnections issues , further network code improvment --- .../Perun_v1/01_Classes/TCPController.cs | 73 +++++++++++++------ 02_Windows_App/Perun_v1/Perun_v1.csproj | 2 +- .../Perun_v1/Properties/AssemblyInfo.cs | 4 +- 3 files changed, 52 insertions(+), 27 deletions(-) diff --git a/02_Windows_App/Perun_v1/01_Classes/TCPController.cs b/02_Windows_App/Perun_v1/01_Classes/TCPController.cs index fd5f725..4e8ce88 100644 --- a/02_Windows_App/Perun_v1/01_Classes/TCPController.cs +++ b/02_Windows_App/Perun_v1/01_Classes/TCPController.cs @@ -4,6 +4,7 @@ using System; using System.Net; using System.Net.Sockets; using System.Text; +using System.Text.RegularExpressions; using System.Threading; public class TCPController @@ -42,6 +43,7 @@ public class TCPController NetworkStream nsReadStream = null; TcpClient tcpClient = null; bool bTCPConnectionOnline = false; + string strReceiveBuffer; // Main loop - do until diconnect button is clicked while (!bCloseConnection) @@ -71,9 +73,9 @@ public class TCPController 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 = 6000; - tcpClient.ReceiveTimeout = 6000; - + nsReadStream.ReadTimeout = 10000; + tcpClient.ReceiveTimeout = 10000; + while (tcpClient.Connected && !bCloseConnection && bTCPConnectionOnline) //while the client is connected, we look for incoming messages { @@ -103,39 +105,62 @@ public class TCPController strReceivedData = CompleteMessage.ToString(); Console.WriteLine("Sender: {0} Payload: {1}", null, strReceivedData); - try + string pattern = @"(\)+?.*?(\)+?"; + + foreach (Match match in Regex.Matches(strReceivedData, pattern)) { - if (strReceivedData != "") + 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 { - dynamic dynamicRawTCPFrame = JsonConvert.DeserializeObject(strReceivedData); // Deserialize received frame - string strRawTCPFrameType = dynamicRawTCPFrame.type; - - PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "#" + Globals.intInstanceId + "> TCP packet received, type: " + strRawTCPFrameType); - - // Add to mySQL send buffer (find first empty slot) - if (Int32.Parse(strRawTCPFrameType) != 0) + if (strReceivedData != "") { - for (int i = 0; i < arrMySQLSendBuffer.Length - 1; i++) + dynamic dynamicRawTCPFrame = JsonConvert.DeserializeObject(strReceivedData); // Deserialize received frame + string strRawTCPFrameType = dynamicRawTCPFrame.type; + + PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "#" + Globals.intInstanceId + "> TCP packet received, type: " + strRawTCPFrameType); + + // Add to mySQL send buffer (find first empty slot) + if (Int32.Parse(strRawTCPFrameType) != 0) { - if (arrMySQLSendBuffer[i] == null) + for (int i = 0; i < arrMySQLSendBuffer.Length - 1; i++) { - arrMySQLSendBuffer[i] = strReceivedData; - break; + if (arrMySQLSendBuffer[i] == null) + { + arrMySQLSendBuffer[i] = strReceivedData; + break; + } } } } + else + { + bTCPConnectionOnline = false; + } } - else + catch (Exception e) { + Globals.intGameErros++; + Console.WriteLine(e.ToString()); + PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "#" + Globals.intInstanceId + " > TCP ERROR incorrect JSON > " + e.Message); bTCPConnectionOnline = false; } - } - catch (Exception e) - { - Globals.intGameErros++; - Console.WriteLine(e.ToString()); - PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "#" + Globals.intInstanceId + " > TCP ERROR incorrect JSON > " + e.Message); - 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.GUILogHistoryAdd(ref arrGUILogHistory, "#" + Globals.intInstanceId + " > TCP ERROR cannot send > " + e.Message); + } + } } } diff --git a/02_Windows_App/Perun_v1/Perun_v1.csproj b/02_Windows_App/Perun_v1/Perun_v1.csproj index 346de2f..61e91ee 100644 --- a/02_Windows_App/Perun_v1/Perun_v1.csproj +++ b/02_Windows_App/Perun_v1/Perun_v1.csproj @@ -34,7 +34,7 @@ true Perun.htm 0 - 0.8.2.%2a + 0.8.3.%2a false true true diff --git a/02_Windows_App/Perun_v1/Properties/AssemblyInfo.cs b/02_Windows_App/Perun_v1/Properties/AssemblyInfo.cs index bfcf35b..c0d428c 100644 --- a/02_Windows_App/Perun_v1/Properties/AssemblyInfo.cs +++ b/02_Windows_App/Perun_v1/Properties/AssemblyInfo.cs @@ -33,7 +33,7 @@ using System.Runtime.InteropServices; // Możesz określić wszystkie wartości lub użyć domyślnych numerów kompilacji i poprawki // przy użyciu symbolu „*”, tak jak pokazano poniżej: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.8.2.0")] -[assembly: AssemblyFileVersion("0.8.2.0")] +[assembly: AssemblyVersion("0.8.3.0")] +[assembly: AssemblyFileVersion("0.8.3.0")] [assembly: NeutralResourcesLanguage("en")] From cabd8d28bb84dceecc5940f8e00419f2244812db Mon Sep 17 00:00:00 2001 From: szporowolik Date: Mon, 21 Oct 2019 01:54:43 +0200 Subject: [PATCH 02/23] Update to v.0.8.3 of lua file --- 01_DCS/Hooks/Perun.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/01_DCS/Hooks/Perun.lua b/01_DCS/Hooks/Perun.lua index 3d77713..0ab2ced 100644 --- a/01_DCS/Hooks/Perun.lua +++ b/01_DCS/Hooks/Perun.lua @@ -20,7 +20,7 @@ Perun.MOTD_L2 = "Wymagamy obecnosci DCS SRS oraz TeamSpeak - szczegoly na forum" -- Variable init -Perun.Version = "v0.8.2" +Perun.Version = "v0.8.3" Perun.StatusData = {} Perun.SlotsData = {} Perun.MissionData = {} @@ -192,7 +192,7 @@ Perun.ConnectToPerun = function () Perun.AddLog("TCP connection error : " .. err) else Perun.AddLog("Connected to TCP server") - Perun.TCP:setoption("keepalive") + -- Perun.TCP:setoption("keepalive") Perun.lastReconnect = _now end end @@ -207,7 +207,7 @@ Perun.SendToPerun = function(data_id, data_package) TempData["instance"]=Perun.Instance temp=net.lua2json(TempData) - temp=stripChars(temp) + temp="" .. stripChars(temp) .. "" -- TCP Part - sending Perun.AddLog("Sending packet: " .. data_id) @@ -527,7 +527,7 @@ Perun.onSimulationFrame = function() end -- Send keepalive - if _now > Perun.lastSentKeepAlive + 5 then + if _now > Perun.lastSentKeepAlive + 3 then Perun.lastSentKeepAlive = _now Perun.SendToPerun(0,nil) end From 9123619ad1b2e7b6055ad4984913c4362a451e11 Mon Sep 17 00:00:00 2001 From: szporowolik Date: Mon, 21 Oct 2019 14:12:12 +0200 Subject: [PATCH 03/23] Updated file naming and remobed unused images --- .../Perun_v1/02_Forms/form_Main.Designer.cs | 4 ---- 02_Windows_App/Perun_v1/02_Forms/form_Main.cs | 6 ++++++ 02_Windows_App/Perun_v1/02_Forms/form_Main.resx | 3 +++ 02_Windows_App/Perun_v1/Perun_v1.csproj | 9 +-------- .../Perun_v1/Properties/Resources.resx | 2 +- 02_Windows_App/Perun_v1/Resources/ico_db.png | Bin 8447 -> 0 bytes 02_Windows_App/Perun_v1/Resources/ico_error.png | Bin 7220 -> 0 bytes 02_Windows_App/Perun_v1/Resources/ico_game.png | Bin 8330 -> 0 bytes .../Perun_v1/Resources/ico_lotatc.png | Bin 20030 -> 0 bytes 02_Windows_App/Perun_v1/Resources/ico_srs.png | Bin 9394 -> 0 bytes 02_Windows_App/Perun_v1/Resources/img_db.png | Bin 233 -> 0 bytes ...onnectedx.png => status-connected-error.png} | Bin .../Resources/status-disconnected-game.png | Bin 1383 -> 0 bytes 13 files changed, 11 insertions(+), 13 deletions(-) delete mode 100644 02_Windows_App/Perun_v1/Resources/ico_db.png delete mode 100644 02_Windows_App/Perun_v1/Resources/ico_error.png delete mode 100644 02_Windows_App/Perun_v1/Resources/ico_game.png delete mode 100644 02_Windows_App/Perun_v1/Resources/ico_lotatc.png delete mode 100644 02_Windows_App/Perun_v1/Resources/ico_srs.png delete mode 100644 02_Windows_App/Perun_v1/Resources/img_db.png rename 02_Windows_App/Perun_v1/Resources/{status-connectedx.png => status-connected-error.png} (100%) delete mode 100644 02_Windows_App/Perun_v1/Resources/status-disconnected-game.png diff --git a/02_Windows_App/Perun_v1/02_Forms/form_Main.Designer.cs b/02_Windows_App/Perun_v1/02_Forms/form_Main.Designer.cs index 5c3d5ad..b7cfce9 100644 --- a/02_Windows_App/Perun_v1/02_Forms/form_Main.Designer.cs +++ b/02_Windows_App/Perun_v1/02_Forms/form_Main.Designer.cs @@ -427,7 +427,6 @@ // // con_img_lotATC // - this.con_img_lotATC.Image = global::Perun_v1.Properties.Resources.status_disconnected; this.con_img_lotATC.Location = new System.Drawing.Point(292, 335); this.con_img_lotATC.Name = "con_img_lotATC"; this.con_img_lotATC.Size = new System.Drawing.Size(29, 28); @@ -437,7 +436,6 @@ // // con_img_srs // - this.con_img_srs.Image = global::Perun_v1.Properties.Resources.status_disconnected; this.con_img_srs.Location = new System.Drawing.Point(207, 335); this.con_img_srs.Name = "con_img_srs"; this.con_img_srs.Size = new System.Drawing.Size(29, 28); @@ -447,7 +445,6 @@ // // con_img_dcs // - this.con_img_dcs.Image = global::Perun_v1.Properties.Resources.status_disconnected; this.con_img_dcs.Location = new System.Drawing.Point(122, 335); this.con_img_dcs.Name = "con_img_dcs"; this.con_img_dcs.Size = new System.Drawing.Size(29, 28); @@ -458,7 +455,6 @@ // con_img_db // this.con_img_db.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.con_img_db.Image = global::Perun_v1.Properties.Resources.status_disconnected; this.con_img_db.Location = new System.Drawing.Point(37, 335); this.con_img_db.Name = "con_img_db"; this.con_img_db.Size = new System.Drawing.Size(29, 28); diff --git a/02_Windows_App/Perun_v1/02_Forms/form_Main.cs b/02_Windows_App/Perun_v1/02_Forms/form_Main.cs index 74d6634..243b2c3 100644 --- a/02_Windows_App/Perun_v1/02_Forms/form_Main.cs +++ b/02_Windows_App/Perun_v1/02_Forms/form_Main.cs @@ -68,6 +68,12 @@ namespace Perun_v1 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"); } public form_Main() diff --git a/02_Windows_App/Perun_v1/02_Forms/form_Main.resx b/02_Windows_App/Perun_v1/02_Forms/form_Main.resx index b2f7f0f..d3bd974 100644 --- a/02_Windows_App/Perun_v1/02_Forms/form_Main.resx +++ b/02_Windows_App/Perun_v1/02_Forms/form_Main.resx @@ -419,6 +419,9 @@ 687, 19 + + 26 + AAABAAEAQD8AAAEAIAAgQQAAFgAAACgAAABAAAAAfgAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA diff --git a/02_Windows_App/Perun_v1/Perun_v1.csproj b/02_Windows_App/Perun_v1/Perun_v1.csproj index 61e91ee..319ede4 100644 --- a/02_Windows_App/Perun_v1/Perun_v1.csproj +++ b/02_Windows_App/Perun_v1/Perun_v1.csproj @@ -182,17 +182,10 @@ - - + - - - - - - diff --git a/02_Windows_App/Perun_v1/Properties/Resources.resx b/02_Windows_App/Perun_v1/Properties/Resources.resx index 143a6d2..49c3998 100644 --- a/02_Windows_App/Perun_v1/Properties/Resources.resx +++ b/02_Windows_App/Perun_v1/Properties/Resources.resx @@ -122,7 +122,7 @@ ..\Resources\status-connected.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\status-connectedx.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\status-connected-error.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\status-disconnected.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a diff --git a/02_Windows_App/Perun_v1/Resources/ico_db.png b/02_Windows_App/Perun_v1/Resources/ico_db.png deleted file mode 100644 index fb784649ca7c8d25cc7ed96cd20ff1e383b67737..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8447 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 diff --git a/02_Windows_App/Perun_v1/Resources/ico_error.png b/02_Windows_App/Perun_v1/Resources/ico_error.png deleted file mode 100644 index cd9246a086959ae148ab6f41fd09b0f9fabd45b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7220 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 diff --git a/02_Windows_App/Perun_v1/Resources/ico_game.png b/02_Windows_App/Perun_v1/Resources/ico_game.png deleted file mode 100644 index d906fde6d0a2251540bf765ab78a6a9959439c2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8330 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

pjC* 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

kQqi2(5-jg9e=5H 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 diff --git a/02_Windows_App/Perun_v1/Resources/img_db.png b/02_Windows_App/Perun_v1/Resources/img_db.png deleted file mode 100644 index 3e9d6ed41b4901ee2e3811ef6e85df0978acf1d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 233 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1SD@H!x2AA6$+S6}hN-9%vmdKI;Vst04O9%8~^|S diff --git a/02_Windows_App/Perun_v1/Resources/status-connectedx.png b/02_Windows_App/Perun_v1/Resources/status-connected-error.png similarity index 100% rename from 02_Windows_App/Perun_v1/Resources/status-connectedx.png rename to 02_Windows_App/Perun_v1/Resources/status-connected-error.png diff --git a/02_Windows_App/Perun_v1/Resources/status-disconnected-game.png b/02_Windows_App/Perun_v1/Resources/status-disconnected-game.png deleted file mode 100644 index c7f9b172f798c1217557d0c619f40f80892082f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1383 zcmV-t1(^DYP)m4~mZk!58tPr3kUsB(2GAtY&xS z`fz8+%)_5)tn1Hlf zDe;j-lmR>ni~;8Xi-2Xc-LQS?03(J-t{0GWvW0>S5*e8hLRp;G#J zl>0@|PNKt%5fcW&&olYB9Yv6{Pb~sppaRDOKsRus-EzSFs6=#30S$fk0dJtZAvI-yZ>jdu>}(&Jn|5Ce`ZY$04&(H30=3h}QmN2+Kp;;O9|j;Rq%~PQp4;!f=%1l2z|<-_ zhnO?9c)V+~kk%w2E|wj>>=|3J&?&?0TFA{E!&lDW>#Ui^l07F-^w)cEX|$_HNNXHD zB>=-fOq4#k>1JmTj-CMSYOr%BGS+lIX;^Qex7yhujmn$g1$s(T=T0$xSJ2JB$8zhW z(6TXmB^g{A?dov@J*ct!3@VgY&6K&!c9J<^Hd}_=<^Wv_+^*SxGgEiFFG?XdX|}Us zP{>Vgpd@N^8Q@=!QP_}x9RMWsIuK@3Mo>=8-Q8oi-hyS7bt>MBQpq_C;T8dXIYVn^GaKQDm-=mY$zya~JnY(&9EDeRpEUID&~I+9YM^MF+AY_(a6 zg%Ag`L-X%B7o5^<&hwC}y^Y)7H=+)1TYx)I=O$1yZ~;{nngG7G-;E{RM{qw-y`o1G z_MfxBKfu+Pg9y~(XtvA9v>cLBzKp2zZ?@#B5aO8CynLj6pg8ZpEl{=S0_qpvhpOtY piF{?OUJ&cl9XW&Gmndbd{{XoQ+~H)&CB^^%002ovPDHLkV1ga!e(nGO From 464261f09f894c71108ade0142d30453267ac3b4 Mon Sep 17 00:00:00 2001 From: szporowolik Date: Mon, 21 Oct 2019 14:37:35 +0200 Subject: [PATCH 04/23] Fixed folder structure --- .../Perun_v1/02_Forms/form_Main.Designer.cs | 66 +++++++++++++----- 02_Windows_App/Perun_v1/02_Forms/form_Main.cs | 29 ++++++++ .../Perun_v1/03_Resources/perun_logo.png | Bin 0 -> 2219 bytes .../status-connected-error.png | Bin .../status-connected.png | Bin .../status-disconnected-error.png | Bin .../status-disconnected.png | Bin 02_Windows_App/Perun_v1/Perun_v1.csproj | 12 ++-- .../Perun_v1/Properties/Resources.resx | 8 +-- 9 files changed, 87 insertions(+), 28 deletions(-) create mode 100644 02_Windows_App/Perun_v1/03_Resources/perun_logo.png rename 02_Windows_App/Perun_v1/{Resources => 03_Resources}/status-connected-error.png (100%) rename 02_Windows_App/Perun_v1/{Resources => 03_Resources}/status-connected.png (100%) rename 02_Windows_App/Perun_v1/{Resources => 03_Resources}/status-disconnected-error.png (100%) rename 02_Windows_App/Perun_v1/{Resources => 03_Resources}/status-disconnected.png (100%) diff --git a/02_Windows_App/Perun_v1/02_Forms/form_Main.Designer.cs b/02_Windows_App/Perun_v1/02_Forms/form_Main.Designer.cs index b7cfce9..10a224e 100644 --- a/02_Windows_App/Perun_v1/02_Forms/form_Main.Designer.cs +++ b/02_Windows_App/Perun_v1/02_Forms/form_Main.Designer.cs @@ -72,6 +72,8 @@ this.con_img_srs = new System.Windows.Forms.PictureBox(); this.con_img_dcs = new System.Windows.Forms.PictureBox(); this.con_img_db = new System.Windows.Forms.PictureBox(); + this.con_Button_Reset_Flags = new System.Windows.Forms.Button(); + this.con_img_logo = new System.Windows.Forms.PictureBox(); this.con_GroupBox_1.SuspendLayout(); this.con_GroupBox_2.SuspendLayout(); this.con_GroupBox_3.SuspendLayout(); @@ -80,6 +82,7 @@ ((System.ComponentModel.ISupportInitialize)(this.con_img_srs)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.con_img_dcs)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.con_img_db)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.con_img_logo)).BeginInit(); this.SuspendLayout(); // // con_List_Received @@ -96,7 +99,7 @@ // // con_Button_Listen_ON // - this.con_Button_Listen_ON.Location = new System.Drawing.Point(12, 553); + this.con_Button_Listen_ON.Location = new System.Drawing.Point(12, 602); this.con_Button_Listen_ON.Name = "con_Button_Listen_ON"; this.con_Button_Listen_ON.Size = new System.Drawing.Size(86, 39); this.con_Button_Listen_ON.TabIndex = 2; @@ -107,7 +110,7 @@ // con_Button_Listen_OFF // this.con_Button_Listen_OFF.Enabled = false; - this.con_Button_Listen_OFF.Location = new System.Drawing.Point(104, 553); + this.con_Button_Listen_OFF.Location = new System.Drawing.Point(104, 602); this.con_Button_Listen_OFF.Name = "con_Button_Listen_OFF"; this.con_Button_Listen_OFF.Size = new System.Drawing.Size(86, 39); this.con_Button_Listen_OFF.TabIndex = 3; @@ -118,7 +121,7 @@ // con_GroupBox_1 // this.con_GroupBox_1.Controls.Add(this.con_List_Received); - this.con_GroupBox_1.Location = new System.Drawing.Point(12, 385); + this.con_GroupBox_1.Location = new System.Drawing.Point(12, 434); this.con_GroupBox_1.Name = "con_GroupBox_1"; this.con_GroupBox_1.Size = new System.Drawing.Size(324, 162); this.con_GroupBox_1.TabIndex = 4; @@ -142,7 +145,7 @@ this.con_GroupBox_2.Controls.Add(this.con_txt_mysql_database); this.con_GroupBox_2.Controls.Add(this.con_txt_mysql_server); this.con_GroupBox_2.Controls.Add(this.con_txt_mysql_password); - this.con_GroupBox_2.Location = new System.Drawing.Point(12, 27); + this.con_GroupBox_2.Location = new System.Drawing.Point(14, 54); this.con_GroupBox_2.Name = "con_GroupBox_2"; this.con_GroupBox_2.Size = new System.Drawing.Size(324, 154); this.con_GroupBox_2.TabIndex = 5; @@ -236,7 +239,7 @@ this.con_GroupBox_3.Controls.Add(this.con_txt_3rd_srs); this.con_GroupBox_3.Controls.Add(this.con_check_3rd_lotatc); this.con_GroupBox_3.Controls.Add(this.con_check_3rd_srs); - this.con_GroupBox_3.Location = new System.Drawing.Point(12, 261); + this.con_GroupBox_3.Location = new System.Drawing.Point(14, 288); this.con_GroupBox_3.Name = "con_GroupBox_3"; this.con_GroupBox_3.Size = new System.Drawing.Size(324, 68); this.con_GroupBox_3.TabIndex = 6; @@ -281,7 +284,7 @@ // // con_Button_Quit // - this.con_Button_Quit.Location = new System.Drawing.Point(251, 553); + this.con_Button_Quit.Location = new System.Drawing.Point(251, 602); this.con_Button_Quit.Name = "con_Button_Quit"; this.con_Button_Quit.Size = new System.Drawing.Size(86, 39); this.con_Button_Quit.TabIndex = 7; @@ -292,7 +295,7 @@ // con_lab_github // this.con_lab_github.AutoSize = true; - this.con_lab_github.Location = new System.Drawing.Point(141, 9); + this.con_lab_github.Location = new System.Drawing.Point(155, 38); this.con_lab_github.Name = "con_lab_github"; this.con_lab_github.Size = new System.Drawing.Size(181, 13); this.con_lab_github.TabIndex = 8; @@ -303,7 +306,7 @@ // label5 // this.label5.AutoSize = true; - this.label5.Location = new System.Drawing.Point(15, 9); + this.label5.Location = new System.Drawing.Point(12, 38); this.label5.Name = "label5"; this.label5.Size = new System.Drawing.Size(120, 13); this.label5.TabIndex = 9; @@ -342,7 +345,7 @@ this.groupBox1.Controls.Add(this.con_txt_dcs_instance); this.groupBox1.Controls.Add(this.label7); this.groupBox1.Controls.Add(this.con_txt_dcs_server_port); - this.groupBox1.Location = new System.Drawing.Point(12, 187); + this.groupBox1.Location = new System.Drawing.Point(14, 214); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(324, 68); this.groupBox1.TabIndex = 7; @@ -386,7 +389,7 @@ this.label9.AutoSize = true; this.label9.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.label9.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label9.Location = new System.Drawing.Point(21, 369); + this.label9.Location = new System.Drawing.Point(21, 396); this.label9.Name = "label9"; this.label9.Size = new System.Drawing.Size(61, 13); this.label9.TabIndex = 1; @@ -397,7 +400,7 @@ this.label10.AutoSize = true; this.label10.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.label10.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label10.Location = new System.Drawing.Point(117, 369); + this.label10.Location = new System.Drawing.Point(117, 396); this.label10.Name = "label10"; this.label10.Size = new System.Drawing.Size(39, 13); this.label10.TabIndex = 14; @@ -408,7 +411,7 @@ this.label11.AutoSize = true; this.label11.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.label11.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label11.Location = new System.Drawing.Point(205, 369); + this.label11.Location = new System.Drawing.Point(205, 396); this.label11.Name = "label11"; this.label11.Size = new System.Drawing.Size(32, 13); this.label11.TabIndex = 15; @@ -419,7 +422,7 @@ this.label12.AutoSize = true; this.label12.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.label12.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label12.Location = new System.Drawing.Point(282, 369); + this.label12.Location = new System.Drawing.Point(282, 396); this.label12.Name = "label12"; this.label12.Size = new System.Drawing.Size(49, 13); this.label12.TabIndex = 16; @@ -427,7 +430,7 @@ // // con_img_lotATC // - this.con_img_lotATC.Location = new System.Drawing.Point(292, 335); + this.con_img_lotATC.Location = new System.Drawing.Point(292, 362); this.con_img_lotATC.Name = "con_img_lotATC"; this.con_img_lotATC.Size = new System.Drawing.Size(29, 28); this.con_img_lotATC.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; @@ -436,7 +439,7 @@ // // con_img_srs // - this.con_img_srs.Location = new System.Drawing.Point(207, 335); + this.con_img_srs.Location = new System.Drawing.Point(207, 362); this.con_img_srs.Name = "con_img_srs"; this.con_img_srs.Size = new System.Drawing.Size(29, 28); this.con_img_srs.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; @@ -445,7 +448,7 @@ // // con_img_dcs // - this.con_img_dcs.Location = new System.Drawing.Point(122, 335); + this.con_img_dcs.Location = new System.Drawing.Point(122, 362); this.con_img_dcs.Name = "con_img_dcs"; this.con_img_dcs.Size = new System.Drawing.Size(29, 28); this.con_img_dcs.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; @@ -455,18 +458,42 @@ // con_img_db // this.con_img_db.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.con_img_db.Location = new System.Drawing.Point(37, 335); + this.con_img_db.Location = new System.Drawing.Point(37, 362); this.con_img_db.Name = "con_img_db"; this.con_img_db.Size = new System.Drawing.Size(29, 28); this.con_img_db.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; this.con_img_db.TabIndex = 10; this.con_img_db.TabStop = false; // + // con_Button_Reset_Flags + // + this.con_Button_Reset_Flags.Enabled = false; + this.con_Button_Reset_Flags.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.con_Button_Reset_Flags.Location = new System.Drawing.Point(224, 414); + this.con_Button_Reset_Flags.Name = "con_Button_Reset_Flags"; + this.con_Button_Reset_Flags.Size = new System.Drawing.Size(114, 20); + this.con_Button_Reset_Flags.TabIndex = 17; + this.con_Button_Reset_Flags.Text = "Reset error flags"; + this.con_Button_Reset_Flags.UseVisualStyleBackColor = true; + this.con_Button_Reset_Flags.Click += new System.EventHandler(this.con_Button_Reset_Flags_Click); + // + // con_img_logo + // + this.con_img_logo.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; + this.con_img_logo.Location = new System.Drawing.Point(12, 7); + this.con_img_logo.Name = "con_img_logo"; + this.con_img_logo.Size = new System.Drawing.Size(29, 28); + this.con_img_logo.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; + this.con_img_logo.TabIndex = 18; + this.con_img_logo.TabStop = false; + // // form_Main // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(349, 604); + this.ClientSize = new System.Drawing.Size(349, 653); + this.Controls.Add(this.con_img_logo); + this.Controls.Add(this.con_Button_Reset_Flags); this.Controls.Add(this.label12); this.Controls.Add(this.label11); this.Controls.Add(this.label10); @@ -503,6 +530,7 @@ ((System.ComponentModel.ISupportInitialize)(this.con_img_srs)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.con_img_dcs)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.con_img_db)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.con_img_logo)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -552,6 +580,8 @@ private System.Windows.Forms.Label label10; private System.Windows.Forms.Label label11; private System.Windows.Forms.Label label12; + private System.Windows.Forms.Button con_Button_Reset_Flags; + private System.Windows.Forms.PictureBox con_img_logo; } } diff --git a/02_Windows_App/Perun_v1/02_Forms/form_Main.cs b/02_Windows_App/Perun_v1/02_Forms/form_Main.cs index 243b2c3..975aacc 100644 --- a/02_Windows_App/Perun_v1/02_Forms/form_Main.cs +++ b/02_Windows_App/Perun_v1/02_Forms/form_Main.cs @@ -125,6 +125,7 @@ namespace Perun_v1 con_Button_Listen_ON.Enabled = false; con_Button_Listen_OFF.Enabled = true; con_Button_Quit.Enabled = false; + con_Button_Reset_Flags.Enabled = true; con_txt_mysql_database.Enabled = false; con_txt_mysql_username.Enabled = false; con_txt_mysql_password.Enabled = false; @@ -144,6 +145,7 @@ namespace Perun_v1 con_Button_Listen_ON.Enabled = true; con_Button_Listen_OFF.Enabled = false; con_Button_Quit.Enabled = true; + con_Button_Reset_Flags.Enabled = false; con_txt_mysql_database.Enabled = true; con_txt_mysql_username.Enabled = true; con_txt_mysql_password.Enabled = true; @@ -155,6 +157,7 @@ namespace Perun_v1 con_check_3rd_srs.Enabled = true; con_txt_dcs_server_port.Enabled = true; con_txt_dcs_instance.Enabled = true; + } // ################################ User input ################################ @@ -588,5 +591,31 @@ namespace Perun_v1 { } + + private void con_Button_Reset_Flags_Click(object sender, EventArgs e) + { + 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.intMysqlErros = 0; // MySQL - Error counter + Globals.intGameErros = 0; // TCP connection - Error counter + Globals.intGameErrosHistory = 0; // TCP connection - historic value of Error counter + Globals.intSRSErros = 0; // DCS SRS - error counter + Globals.intLotATCErros = 0; // LotATC - error counter + + // Force icons reload + Globals.bStatusIconsForce = true; + + // Add information + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + Globals.intInstanceId + " > " + "Reseted error counter"); + } + else if (dialogResult == DialogResult.No) + { + // Do nothing + } + + + } } } diff --git a/02_Windows_App/Perun_v1/03_Resources/perun_logo.png b/02_Windows_App/Perun_v1/03_Resources/perun_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..babf277d52b205bfa7c57208b0ee5313f20c3f48 GIT binary patch literal 2219 zcmV;c2vqlpP)O<*5(|28G7Rqsb3y2#*qyZ2#E1cV@FQn`}7!&Dq`WeDD1| z=FXkp-1}RLMvL8?l}x0XP0Y7%H`YpG;{za<9|JIp+sywz1|R{Nn3HN%ZSVwxCOQE~ zqGK~y)wZ@i>wyLY*^*Lj>f@&_zQzN=3e)$j)vSKwF$1^&fU4jHL#4Z#HyX6b#da|0 z1$F(70+6&OYmKWT8VxRWI?N-73zTA$9i}b^7^vZ)lsB}U4br>;_KQxcRLa(}$; zEjg%7J*AoZq%v&0-15>XPmp}wL&=eOkgQjh4_xqt`j=?a0DM%CTN$ zDgd|Wsm=h%NdD;RQp+hy36Mrcgq^YKHvp2saS}qItLOdv_yz!yz<&Az@Qxaxxm}E? z=kD#VeKa-HcQ->q3PaHJ{#kgrncO3cv`q>nlVAfxz$<{k<$^#)*f zBwCDgHFsMb)$y=2MrLaO@=2i}Px-TaD?#RZ; z6VCMeimPwi=m7p{&;>pGigU6=FM=l~XSOkeXv z+lji5%ap~sG62*OHb=RCPraipuZ>7=&J?WR3H}4XdR}*o8p%!w4x$x%?aN_ClKFyr zBHTh-y00mvP)nEE%Kn0i+YBXvSc*2S7488uQ(9l>!cMk*0KHAcI-0 z=70s#mBKhTDCfvf{{@i6WT-I!2kHC)--^phHN90~09YCK{^$YoLVB6mA<+5BINd`c zd1Y8Kgxzr}0^FdR`W)=`B-ebl7)hpxPK~hhOd{RcND%a=E~>Z z0RjX_(BBs5PxQBgw!D(Vc5P*q^rNq_k)Z9l&nzE1pI9`_c6neAU} zT;7?JBsap&a7z+6O0T#TC#p9Aq$?LxC4emArMRsWsF4=P0B3#DK>0^i|8@XK0Yz#K zfHdc{t2WROsiKEE6M7fC&6Dh54`;bf8hv@Z&N8H~^iu}`WH<%frl6DE@DQYI4YNRz@J{l&h<; z)&o6wmo$%t>vT~U0OWaAYi^X<1t2{+rgwvpa+OhPzqcRXJfI5sE?zaB723U78v(hJ z44_W1!9$~l$Nb#KOhoFW+2=S?!p}8Y>RObhGfSfddfn@mRq6wOFA=xEzMJ-(bQa~( zgwG?k6YvAI9YA_&E9I%AhYjz)QW9MSS8m-{{xQ%ISeXPcSgn0bcT1b{Sl+D;kjh|5%v>H6s( z%cD_aIU!VpQ9))z2JO1~oqEkYg{Csqg}R>l)4$T zL{GAI5%uCod0AQms8W_0&ID_hnoN1iWDwURJV}4vVm~i2)@5?A{yj&oM$2g78-QZ5 zMyoid(NI_W)68WbI~ZV_y?E>zQ98vs#Bk-SA0NijpoUCU2q2@`sky%DkiSBVL{tH* zb^AUExwq;!=O>t(8B={@DD$~8l5&(kqRv!b%1h%?5+~Ok&3DTWR-1Xxp z)J_2T8plZj;1!icd{W+2R+{a#&hL^U=M7gPKN2$+q`5rp+Lr$-T%MO)!)=bUWG~+~ zsuiL%x6E+cBx)i`GkL?b>k^f;k}|^$iE|9(cUp0dKJO$qHM8ZC=Z&jCUei6Ui{4qw zB+bOX`;v6IDM2X~T^E%d+SKV7{}(iok905n4iQTZNl=248Fv66%Oxm}MctCoF?EKS zeuFggumok3zecR5pe5_o_|SE5jIRT5sp)+!b^B2I&todh+0K0XrqL?Vg^j}6%+wkH zS ResXFileCodeGenerator - Resources.Designer.cs Designer + Resources.Designer.cs - - True - Resources.resx - True - @@ -159,6 +154,11 @@ SettingsSingleFileGenerator Settings.Designer.cs + + True + True + Resources.resx + True Settings.settings diff --git a/02_Windows_App/Perun_v1/Properties/Resources.resx b/02_Windows_App/Perun_v1/Properties/Resources.resx index 49c3998..b40f041 100644 --- a/02_Windows_App/Perun_v1/Properties/Resources.resx +++ b/02_Windows_App/Perun_v1/Properties/Resources.resx @@ -119,15 +119,15 @@ - ..\Resources\status-connected.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\03_Resources\status-connected.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\status-connected-error.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\03_Resources\status-connected-error.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\status-disconnected.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\03_Resources\status-disconnected.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\status-disconnected-error.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\03_Resources\status-disconnected-error.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a \ No newline at end of file From 9d06065d7011f124450ad7bd65a12c7755de9614 Mon Sep 17 00:00:00 2001 From: szporowolik Date: Mon, 21 Oct 2019 14:47:25 +0200 Subject: [PATCH 05/23] GUI updated, added graphical header and logo --- .../Perun_v1/02_Forms/form_Main.Designer.cs | 89 ++++++++++++------ .../Perun_v1/03_Resources/perun_logo.png | Bin 2219 -> 6129 bytes 02_Windows_App/Perun_v1/Perun_v1.csproj | 2 + .../Perun_v1/Properties/Resources.Designer.cs | 10 ++ .../Perun_v1/Properties/Resources.resx | 3 + .../Perun_v1/Resources/perun_logo.png | Bin 0 -> 233 bytes 6 files changed, 74 insertions(+), 30 deletions(-) create mode 100644 02_Windows_App/Perun_v1/Resources/perun_logo.png diff --git a/02_Windows_App/Perun_v1/02_Forms/form_Main.Designer.cs b/02_Windows_App/Perun_v1/02_Forms/form_Main.Designer.cs index 10a224e..45b18f8 100644 --- a/02_Windows_App/Perun_v1/02_Forms/form_Main.Designer.cs +++ b/02_Windows_App/Perun_v1/02_Forms/form_Main.Designer.cs @@ -68,21 +68,23 @@ this.label10 = new System.Windows.Forms.Label(); this.label11 = new System.Windows.Forms.Label(); this.label12 = new System.Windows.Forms.Label(); + this.con_Button_Reset_Flags = new System.Windows.Forms.Button(); + this.label13 = new System.Windows.Forms.Label(); + this.label14 = new System.Windows.Forms.Label(); + this.con_img_logo = new System.Windows.Forms.PictureBox(); this.con_img_lotATC = new System.Windows.Forms.PictureBox(); this.con_img_srs = new System.Windows.Forms.PictureBox(); this.con_img_dcs = new System.Windows.Forms.PictureBox(); this.con_img_db = new System.Windows.Forms.PictureBox(); - this.con_Button_Reset_Flags = new System.Windows.Forms.Button(); - this.con_img_logo = new System.Windows.Forms.PictureBox(); this.con_GroupBox_1.SuspendLayout(); this.con_GroupBox_2.SuspendLayout(); this.con_GroupBox_3.SuspendLayout(); this.groupBox1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.con_img_logo)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.con_img_lotATC)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.con_img_srs)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.con_img_dcs)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.con_img_db)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.con_img_logo)).BeginInit(); this.SuspendLayout(); // // con_List_Received @@ -295,9 +297,10 @@ // con_lab_github // this.con_lab_github.AutoSize = true; - this.con_lab_github.Location = new System.Drawing.Point(155, 38); + this.con_lab_github.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.con_lab_github.Location = new System.Drawing.Point(183, 39); this.con_lab_github.Name = "con_lab_github"; - this.con_lab_github.Size = new System.Drawing.Size(181, 13); + this.con_lab_github.Size = new System.Drawing.Size(155, 12); this.con_lab_github.TabIndex = 8; this.con_lab_github.TabStop = true; this.con_lab_github.Text = "https://github.com/szporwolik/perun"; @@ -306,9 +309,10 @@ // label5 // this.label5.AutoSize = true; - this.label5.Location = new System.Drawing.Point(12, 38); + this.label5.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label5.Location = new System.Drawing.Point(183, 27); this.label5.Name = "label5"; - this.label5.Size = new System.Drawing.Size(120, 13); + this.label5.Size = new System.Drawing.Size(102, 12); this.label5.TabIndex = 9; this.label5.Text = "Manual and bugtracker:"; // @@ -428,6 +432,49 @@ this.label12.TabIndex = 16; this.label12.Text = "LotATC"; // + // con_Button_Reset_Flags + // + this.con_Button_Reset_Flags.Enabled = false; + this.con_Button_Reset_Flags.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.con_Button_Reset_Flags.Location = new System.Drawing.Point(224, 414); + this.con_Button_Reset_Flags.Name = "con_Button_Reset_Flags"; + this.con_Button_Reset_Flags.Size = new System.Drawing.Size(114, 20); + this.con_Button_Reset_Flags.TabIndex = 17; + this.con_Button_Reset_Flags.Text = "Reset error flags"; + this.con_Button_Reset_Flags.UseVisualStyleBackColor = true; + this.con_Button_Reset_Flags.Click += new System.EventHandler(this.con_Button_Reset_Flags_Click); + // + // label13 + // + this.label13.AutoSize = true; + this.label13.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label13.Location = new System.Drawing.Point(63, 7); + this.label13.Name = "label13"; + this.label13.Size = new System.Drawing.Size(74, 25); + this.label13.TabIndex = 19; + this.label13.Text = "Perun"; + // + // label14 + // + this.label14.AutoSize = true; + this.label14.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label14.Location = new System.Drawing.Point(65, 32); + this.label14.Name = "label14"; + this.label14.Size = new System.Drawing.Size(88, 13); + this.label14.TabIndex = 20; + this.label14.Text = "for DCS World"; + // + // con_img_logo + // + this.con_img_logo.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; + this.con_img_logo.Image = global::Perun_v1.Properties.Resources.perun_logo; + this.con_img_logo.Location = new System.Drawing.Point(12, 7); + this.con_img_logo.Name = "con_img_logo"; + this.con_img_logo.Size = new System.Drawing.Size(45, 41); + this.con_img_logo.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; + this.con_img_logo.TabIndex = 18; + this.con_img_logo.TabStop = false; + // // con_img_lotATC // this.con_img_lotATC.Location = new System.Drawing.Point(292, 362); @@ -465,33 +512,13 @@ this.con_img_db.TabIndex = 10; this.con_img_db.TabStop = false; // - // con_Button_Reset_Flags - // - this.con_Button_Reset_Flags.Enabled = false; - this.con_Button_Reset_Flags.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.con_Button_Reset_Flags.Location = new System.Drawing.Point(224, 414); - this.con_Button_Reset_Flags.Name = "con_Button_Reset_Flags"; - this.con_Button_Reset_Flags.Size = new System.Drawing.Size(114, 20); - this.con_Button_Reset_Flags.TabIndex = 17; - this.con_Button_Reset_Flags.Text = "Reset error flags"; - this.con_Button_Reset_Flags.UseVisualStyleBackColor = true; - this.con_Button_Reset_Flags.Click += new System.EventHandler(this.con_Button_Reset_Flags_Click); - // - // con_img_logo - // - this.con_img_logo.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - this.con_img_logo.Location = new System.Drawing.Point(12, 7); - this.con_img_logo.Name = "con_img_logo"; - this.con_img_logo.Size = new System.Drawing.Size(29, 28); - this.con_img_logo.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; - this.con_img_logo.TabIndex = 18; - this.con_img_logo.TabStop = false; - // // form_Main // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(349, 653); + this.Controls.Add(this.label14); + this.Controls.Add(this.label13); this.Controls.Add(this.con_img_logo); this.Controls.Add(this.con_Button_Reset_Flags); this.Controls.Add(this.label12); @@ -526,11 +553,11 @@ this.con_GroupBox_3.PerformLayout(); this.groupBox1.ResumeLayout(false); this.groupBox1.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.con_img_logo)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.con_img_lotATC)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.con_img_srs)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.con_img_dcs)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.con_img_db)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.con_img_logo)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -582,6 +609,8 @@ private System.Windows.Forms.Label label12; private System.Windows.Forms.Button con_Button_Reset_Flags; private System.Windows.Forms.PictureBox con_img_logo; + private System.Windows.Forms.Label label13; + private System.Windows.Forms.Label label14; } } diff --git a/02_Windows_App/Perun_v1/03_Resources/perun_logo.png b/02_Windows_App/Perun_v1/03_Resources/perun_logo.png index babf277d52b205bfa7c57208b0ee5313f20c3f48..020b2bf396e11a6e0864186c2f63d7f11655842b 100644 GIT binary patch literal 6129 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 + + diff --git a/02_Windows_App/Perun_v1/Properties/Resources.Designer.cs b/02_Windows_App/Perun_v1/Properties/Resources.Designer.cs index d9c9b98..f3d5c91 100644 --- a/02_Windows_App/Perun_v1/Properties/Resources.Designer.cs +++ b/02_Windows_App/Perun_v1/Properties/Resources.Designer.cs @@ -60,6 +60,16 @@ namespace Perun_v1.Properties { } } + ///

+ /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap perun_logo { + get { + object obj = ResourceManager.GetObject("perun_logo", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/02_Windows_App/Perun_v1/Properties/Resources.resx b/02_Windows_App/Perun_v1/Properties/Resources.resx index b40f041..6d2bfc3 100644 --- a/02_Windows_App/Perun_v1/Properties/Resources.resx +++ b/02_Windows_App/Perun_v1/Properties/Resources.resx @@ -118,6 +118,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\03_Resources\perun_logo.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\03_Resources\status-connected.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a diff --git a/02_Windows_App/Perun_v1/Resources/perun_logo.png b/02_Windows_App/Perun_v1/Resources/perun_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..3e9d6ed41b4901ee2e3811ef6e85df0978acf1d2 GIT binary patch literal 233 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1SD@H!x2AA6$+S6}hN-9%vmdKI;Vst04O9%8~^|S literal 0 HcmV?d00001 From fb96745ede4eb51e06cb4b37f5c194a7516674be Mon Sep 17 00:00:00 2001 From: szporowolik Date: Mon, 21 Oct 2019 14:51:19 +0200 Subject: [PATCH 06/23] Added user marker button --- .../Perun_v1/02_Forms/form_Main.Designer.cs | 15 +++++++++++++++ 02_Windows_App/Perun_v1/02_Forms/form_Main.cs | 11 ++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/02_Windows_App/Perun_v1/02_Forms/form_Main.Designer.cs b/02_Windows_App/Perun_v1/02_Forms/form_Main.Designer.cs index 45b18f8..70436fe 100644 --- a/02_Windows_App/Perun_v1/02_Forms/form_Main.Designer.cs +++ b/02_Windows_App/Perun_v1/02_Forms/form_Main.Designer.cs @@ -76,6 +76,7 @@ this.con_img_srs = new System.Windows.Forms.PictureBox(); this.con_img_dcs = new System.Windows.Forms.PictureBox(); this.con_img_db = new System.Windows.Forms.PictureBox(); + this.con_Button_Add_Marker = new System.Windows.Forms.Button(); this.con_GroupBox_1.SuspendLayout(); this.con_GroupBox_2.SuspendLayout(); this.con_GroupBox_3.SuspendLayout(); @@ -512,11 +513,24 @@ this.con_img_db.TabIndex = 10; this.con_img_db.TabStop = false; // + // con_Button_Add_Marker + // + this.con_Button_Add_Marker.Enabled = false; + this.con_Button_Add_Marker.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.con_Button_Add_Marker.Location = new System.Drawing.Point(12, 414); + this.con_Button_Add_Marker.Name = "con_Button_Add_Marker"; + this.con_Button_Add_Marker.Size = new System.Drawing.Size(114, 20); + this.con_Button_Add_Marker.TabIndex = 21; + this.con_Button_Add_Marker.Text = "Add log marker"; + this.con_Button_Add_Marker.UseVisualStyleBackColor = true; + this.con_Button_Add_Marker.Click += new System.EventHandler(this.con_Button_Add_Marker_Click); + // // form_Main // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(349, 653); + this.Controls.Add(this.con_Button_Add_Marker); this.Controls.Add(this.label14); this.Controls.Add(this.label13); this.Controls.Add(this.con_img_logo); @@ -611,6 +625,7 @@ private System.Windows.Forms.PictureBox con_img_logo; private System.Windows.Forms.Label label13; private System.Windows.Forms.Label label14; + private System.Windows.Forms.Button con_Button_Add_Marker; } } diff --git a/02_Windows_App/Perun_v1/02_Forms/form_Main.cs b/02_Windows_App/Perun_v1/02_Forms/form_Main.cs index 975aacc..633fabd 100644 --- a/02_Windows_App/Perun_v1/02_Forms/form_Main.cs +++ b/02_Windows_App/Perun_v1/02_Forms/form_Main.cs @@ -126,6 +126,7 @@ namespace Perun_v1 con_Button_Listen_OFF.Enabled = true; con_Button_Quit.Enabled = false; con_Button_Reset_Flags.Enabled = true; + con_Button_Add_Marker.Enabled = true; con_txt_mysql_database.Enabled = false; con_txt_mysql_username.Enabled = false; con_txt_mysql_password.Enabled = false; @@ -146,6 +147,7 @@ namespace Perun_v1 con_Button_Listen_OFF.Enabled = false; con_Button_Quit.Enabled = true; con_Button_Reset_Flags.Enabled = false; + con_Button_Add_Marker.Enabled = false; con_txt_mysql_database.Enabled = true; con_txt_mysql_username.Enabled = true; con_txt_mysql_password.Enabled = true; @@ -594,6 +596,7 @@ namespace Perun_v1 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) { @@ -608,7 +611,7 @@ namespace Perun_v1 Globals.bStatusIconsForce = true; // Add information - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + Globals.intInstanceId + " > " + "Reseted error counter"); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + Globals.intInstanceId + " > " + "Resetted error counter"); } else if (dialogResult == DialogResult.No) { @@ -617,5 +620,11 @@ namespace Perun_v1 } + + private void con_Button_Add_Marker_Click(object sender, EventArgs e) + { + // Added user marker + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + Globals.intInstanceId + " > " + "User marker"); + } } } From 488d4dfcace0d2f40baee6130530b956b05980bd Mon Sep 17 00:00:00 2001 From: VladMordock Date: Mon, 21 Oct 2019 15:05:59 +0200 Subject: [PATCH 07/23] Update Readme - image update and added FAQ --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fb7e79b..e3ee048 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Provided windows app puts received TCP packets to MySQL database; additionaly Pe However, this software is intended to be used by experienced users - the output is MySQL data and/or JSON file; you will need to process/display it yourself. -![Perun in action](https://i.imgur.com/vHw8Xu5.png) +![Perun in action](https://i.imgur.com/MieyBej.png) ![Data flow](https://i.imgur.com/JbNu77l.png) ## Prerequisites @@ -57,6 +57,15 @@ Example for windows shortcut: ``` C:\Perun_v1\Perun.exe 48621 1 "G:\DCS SRS\clients-list.json" "C:\Users\DCS\Saved Games\DCS\Mods\tech\LotAtc\stats.json" ``` +## Troubleshooting - FAQ +- [I keep getting 1305 MySQL error](#i-keep-getting-1305-mysql-error) +- [Carrier landing are not tracked correctly](#carrier-landing-are-not-tracked-correctly) + +### I keep getting 1305 MySQL error +That probably means that your database does not support JSON functions, you shall upgrade your MySQL server to at lease 5.7 version. + +### Carrier landing are not tracked correctly +DCS API does not track carrier landing natively, so there is a trick to achive that. You shall set your carrier to a propoer group name to have landings tracked. # API documentation (for expert users) ## MySQL database structure From c66daec294da4ac4de5ee9bafc136705c3a88b60 Mon Sep 17 00:00:00 2001 From: VladMordock Date: Mon, 21 Oct 2019 15:24:04 +0200 Subject: [PATCH 08/23] Update readme Added gildia.org logo and perun log --- README.md | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index e3ee048..b9f47d9 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ ![alt text](https://img.shields.io/github/release-pre/szporwolik/perun.svg "Latest release") ![alt text](https://img.shields.io/github/release-date-pre/szporwolik/perun.svg "Latest release date") +![Perun logo](https://i.imgur.com/JkeHYjJ.png) # Perun for DCS World - Included lua script extracts data from DCS World multiplayer server and sends information to TCP port and JSON file for further processing. Provided windows app puts received TCP packets to MySQL database; additionaly Perun windows application can be used to merge LotATC and DCS SRS data in one database making Perun for DCS World wannabe ultimate integration tool for the server admins. @@ -15,7 +15,6 @@ However, this software is intended to be used by experienced users - the output ![Data flow](https://i.imgur.com/JbNu77l.png) ## Prerequisites - Core: * For JSON Export: * DCS World stable or DCS World beta @@ -28,7 +27,6 @@ Core: * for [LotATC](https://www.lotatc.com/) you will need location of stats.json file and proper LotATC configuration with JSON data export enabled - see [LotATC documentation](https://www.lotatc.com/documentation/server_configuration.html) ## Installing - * Download latest [release](https://github.com/szporwolik/perun/releases) * Copy contents of [01_DCS](https://github.com/szporwolik/perun/tree/master/01_DCS) to your \Scripts folder (located inside DCS folder in your Saved Games) * **optionaly** create MySQL database using SQL script located in [03_MySQL](https://github.com/szporwolik/perun/tree/master/03_MySQL); note that you need just a one database per DCS server machine - multiple instances pushing data to the one database are supported @@ -104,32 +102,24 @@ DCS API does not track carrier landing natively, so there is a trick to achive t # Project information ## Built With - * [VisualStudio 2017 Community](https://visualstudio.microsoft.com/vs/community/) * [Notepad++](https://notepad-plus-plus.org/) -## used 3rd party resources - -* [Tango Icon Library](http://tango.freedesktop.org/Tango_Icon_Library) - ## Contributing - Please contact me if you'd like to contribute. ## Versioning - We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/szporwolik/perun/tags). ## Authors - * **Szymon Porwolik** - *Initial work* - [szporwolik](https://github.com/szporwolik) See also the list of [contributors](https://github.com/szporwolik/perun/contributors) who participated in this project. ## License - This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details ## Acknowledgments +![Gildia.org Logo](https://images.weserv.nl/?url=https://i.imgur.com/nFHxQMy.png&w=140&il) -* Thanks to [Gildia DCS](https://forum.gildia.org) Polish community of DCS World pilots. +Thanks to [Gildia DCS](https://forum.gildia.org) Polish community of DCS World pilots. From 1a73404c4c59b81da97f55f82f349bc60b5cd021 Mon Sep 17 00:00:00 2001 From: szporowolik Date: Mon, 21 Oct 2019 15:34:46 +0200 Subject: [PATCH 09/23] Fixed logging to gui (removed date), file log will keep the log date --- 02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs b/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs index 62119a2..4760e3f 100644 --- a/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs +++ b/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs @@ -13,10 +13,10 @@ internal class PerunHelper } // Add new entry - arrLogHistory[arrLogHistory.Length - 1] = DateTime.Now.ToString("yyyy-dd-MM HH:mm:ss") + " > " + strEntryToAdd; // Add entry at the last position + arrLogHistory[arrLogHistory.Length - 1] = DateTime.Now.ToString("HH:mm:ss") + " > " + strEntryToAdd; // Add entry at the last position // Add the entry to log file - LogController.WriteLog(arrLogHistory[arrLogHistory.Length - 1]); + LogController.WriteLog(DateTime.Now.ToString("yyyy-dd-MM ") + arrLogHistory[arrLogHistory.Length - 1]); // Update control at my window Globals.bGUILogHistoryUpdate = true; From 49495ba9c48d2c7a6c15a386217d755b066d9a2c Mon Sep 17 00:00:00 2001 From: szporowolik Date: Mon, 21 Oct 2019 16:41:10 +0200 Subject: [PATCH 10/23] Log file and GUI improvment --- .../Perun_v1/01_Classes/DatabaseController.cs | 18 ++++++------ .../Perun_v1/01_Classes/PerunHelper.cs | 29 +++++++++++++++++-- .../Perun_v1/01_Classes/TCPController.cs | 8 ++--- 02_Windows_App/Perun_v1/02_Forms/form_Main.cs | 18 ++++++------ 4 files changed, 48 insertions(+), 25 deletions(-) diff --git a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs index 496699f..3cee1c7 100644 --- a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs +++ b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs @@ -103,31 +103,31 @@ public class DatabaseController Console.WriteLine(rdrMySQL[0] + " -- " + rdrMySQL[1]); } rdrMySQL.Close(); - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + strUDPFrameInstance + " > MySQL updated, package type: " + strUDPFrameType); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "MySQL updated, package type: " + strUDPFrameType,1); } catch (ArgumentException a_ex) { // General exception found Console.WriteLine(a_ex.ToString()); - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + strUDPFrameInstance + " > ERROR MySQL - package type: " + strUDPFrameType); - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + strUDPFrameInstance + " > ERROR MySQL >" + a_ex.Message); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - package type: " + strUDPFrameType,1,1); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - error: " + a_ex.Message,1,1); bStatus = false; } catch (MySqlException m_ex) { // MySQL exception found - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + strUDPFrameInstance + " > ERROR MySQL - package type: " + strUDPFrameType); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - package type: " + strUDPFrameType,1,1); switch (m_ex.Number) { case 1042: // Unable to connect to any of the specified MySQL hosts (Check Server,Port) - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + strUDPFrameInstance + " > ERROR MySQL - unable to connect >" + m_ex.Message); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - unable to connect, error: " + m_ex.Message,1,1); break; case 0: // Access denied (Check DB name,username,password) - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + strUDPFrameInstance + " > ERROR MySQL - access denied > " + m_ex.Message); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - access denied, error: " + m_ex.Message,1,1); break; default: - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + strUDPFrameInstance + " > ERROR MySQL > " + m_ex.Number); - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + strUDPFrameInstance + " > ERROR MySQL > " + m_ex.Message); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - error id: " + m_ex.Number,1,1); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - error: " + m_ex.Message,1,1); break; } bStatus = false; @@ -137,7 +137,7 @@ public class DatabaseController } catch (ArgumentException x_ex) { - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + strUDPFrameInstance + " > ERROR MySQL - unable to connect > " + x_ex.Message); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - unable to connect, error: " + x_ex.Message,1,1); } diff --git a/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs b/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs index 4760e3f..d34b93a 100644 --- a/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs +++ b/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs @@ -4,8 +4,31 @@ using System.Reflection; internal class PerunHelper { - public static void GUILogHistoryAdd(ref string[] arrLogHistory, string strEntryToAdd) + public static void GUILogHistoryAdd(ref string[] arrLogHistory, string strEntryToAdd, int intDirection = 0, int intMarker = 0) { + // Declare values + string strDirection; + string strMarker; + // Set direction marker + switch (intDirection) + { + case 1: + strDirection = ">"; + break; + case 2: + strDirection = "<"; + break; + case 3: + strDirection = "^"; + break; + default: + strDirection = " "; + break; + } + + // Set marker for user flags (markers) + strMarker = (intMarker>0) ? "X" : " "; + // Rotate log history for (int i = 0; i < arrLogHistory.Length - 1; i++) { @@ -13,10 +36,10 @@ internal class PerunHelper } // Add new entry - arrLogHistory[arrLogHistory.Length - 1] = DateTime.Now.ToString("HH:mm:ss") + " > " + strEntryToAdd; // Add entry at the last position + arrLogHistory[arrLogHistory.Length - 1] = DateTime.Now.ToString("HH:mm:ss") + " " + strDirection + " " + strEntryToAdd; // Add entry at the last position // Add the entry to log file - LogController.WriteLog(DateTime.Now.ToString("yyyy-dd-MM ") + arrLogHistory[arrLogHistory.Length - 1]); + LogController.WriteLog(DateTime.Now.ToString("yyyy-dd-MM ") + " " + DateTime.Now.ToString("HH:mm:ss") + " | Instance: "+ Globals.intInstanceId + " | " + strMarker + " | " + strDirection + " | " + strEntryToAdd); // Update control at my window Globals.bGUILogHistoryUpdate = true; diff --git a/02_Windows_App/Perun_v1/01_Classes/TCPController.cs b/02_Windows_App/Perun_v1/01_Classes/TCPController.cs index 4e8ce88..f781268 100644 --- a/02_Windows_App/Perun_v1/01_Classes/TCPController.cs +++ b/02_Windows_App/Perun_v1/01_Classes/TCPController.cs @@ -122,7 +122,7 @@ public class TCPController dynamic dynamicRawTCPFrame = JsonConvert.DeserializeObject(strReceivedData); // Deserialize received frame string strRawTCPFrameType = dynamicRawTCPFrame.type; - PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "#" + Globals.intInstanceId + "> TCP packet received, type: " + strRawTCPFrameType); + PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "TCP packet received, type: " + strRawTCPFrameType,2); // Add to mySQL send buffer (find first empty slot) if (Int32.Parse(strRawTCPFrameType) != 0) @@ -146,7 +146,7 @@ public class TCPController { Globals.intGameErros++; Console.WriteLine(e.ToString()); - PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "#" + Globals.intInstanceId + " > TCP ERROR incorrect JSON > " + e.Message); + PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "ERROR while message parsing , error: " + e.Message,2,1); bTCPConnectionOnline = false; } @@ -158,7 +158,7 @@ public class TCPController catch (SocketException e) { Console.WriteLine(e.ToString()); - PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "#" + Globals.intInstanceId + " > TCP ERROR cannot send > " + e.Message); + PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "TCP ERROR cannot check connection, error: " + e.Message,2,1); } } @@ -172,7 +172,7 @@ public class TCPController { Globals.intGameErros++; Console.WriteLine(e.ToString()); - PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "#" + Globals.intInstanceId + " > TCP error - connection closed or port in use > " + e.Message); + PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "TCP error - connection closed or port in use, error: " + e.Message,1,1); bTCPConnectionOnline = false; } diff --git a/02_Windows_App/Perun_v1/02_Forms/form_Main.cs b/02_Windows_App/Perun_v1/02_Forms/form_Main.cs index 633fabd..61c8a66 100644 --- a/02_Windows_App/Perun_v1/02_Forms/form_Main.cs +++ b/02_Windows_App/Perun_v1/02_Forms/form_Main.cs @@ -187,7 +187,7 @@ namespace Perun_v1 dcConnection.strMySQLConnectionString = "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.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + Globals.intInstanceId + " > " + "Opening connections"); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Opening connections",0,1); tcpServer.Create(Int32.Parse(con_txt_dcs_server_port.Text), ref Globals.arrGUILogHistory, ref arrMySQLSendBuffer); tcpServer.thrTCPListener = new Thread(tcpServer.StartListen); tcpServer.thrTCPListener.Start(); @@ -207,7 +207,7 @@ namespace Perun_v1 { // Stop listening // Prepare GUI - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + Globals.intInstanceId + " > " + "Closing connections"); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Closing connections",0,1); con_Button_Listen_OFF.Enabled = false; Tim_GUI_Tick(null, null); this.Refresh(); @@ -240,7 +240,7 @@ namespace Perun_v1 con_img_srs.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected"); // Display information about closed connections - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + Globals.intInstanceId + " > " + "Connections closed"); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Connections closed",0,1); Tim_GUI_Tick(null, null); // Set title bar @@ -534,12 +534,12 @@ namespace Perun_v1 strSRSJson = "{'type':'100','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':{'ignore':'false'}}"; // No SRS clients connected } boolSRSdefault = false; - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + Int32.Parse(con_txt_dcs_instance.Text) + " > SRS data loaded"); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "SRS data loaded",3); bSRSStatus = true; } catch (Exception exc_srs) { - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + Int32.Parse(con_txt_dcs_instance.Text) + " > SRS data ERROR > " + exc_srs.Message); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "SRS data ERROR , error: " + exc_srs.Message,3,1); bSRSStatus = false; Globals.intSRSErros++; } @@ -562,12 +562,12 @@ namespace Perun_v1 strLotATCJson = "{'type':'101','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':'" + strLotATCJson + "'}"; boolLotATCdefault = false; - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + Int32.Parse(con_txt_dcs_instance.Text) + " > LotATC data loaded"); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "LotATC data loaded",3); bLotATCStatus = true; } catch (Exception exc_lotatc) { - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + Int32.Parse(con_txt_dcs_instance.Text) + " > LotATC data ERROR > " + exc_lotatc.Message); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "LotATC data ERROR, error: " + exc_lotatc.Message,3,1); bLotATCStatus = false; Globals.intLotATCErros++; } @@ -611,7 +611,7 @@ namespace Perun_v1 Globals.bStatusIconsForce = true; // Add information - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + Globals.intInstanceId + " > " + "Resetted error counter"); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Resetted error counter",0,1); } else if (dialogResult == DialogResult.No) { @@ -624,7 +624,7 @@ namespace Perun_v1 private void con_Button_Add_Marker_Click(object sender, EventArgs e) { // Added user marker - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + Globals.intInstanceId + " > " + "User marker"); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "User Marker",0,1); } } } From 2084d8811755bffcf01d7b8be74e09bc1614c70b Mon Sep 17 00:00:00 2001 From: szporowolik Date: Mon, 21 Oct 2019 16:47:26 +0200 Subject: [PATCH 11/23] Keep alive information added to logs --- 02_Windows_App/Perun_v1/01_Classes/TCPController.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/02_Windows_App/Perun_v1/01_Classes/TCPController.cs b/02_Windows_App/Perun_v1/01_Classes/TCPController.cs index f781268..759b3da 100644 --- a/02_Windows_App/Perun_v1/01_Classes/TCPController.cs +++ b/02_Windows_App/Perun_v1/01_Classes/TCPController.cs @@ -122,11 +122,11 @@ public class TCPController dynamic dynamicRawTCPFrame = JsonConvert.DeserializeObject(strReceivedData); // Deserialize received frame string strRawTCPFrameType = dynamicRawTCPFrame.type; - PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "TCP packet received, type: " + strRawTCPFrameType,2); - - // Add to mySQL send buffer (find first empty slot) + // Check if this is NOT keep alive if (Int32.Parse(strRawTCPFrameType) != 0) { + // Add to mySQL send buffer (find first empty slot) + PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "TCP packet received, type: " + strRawTCPFrameType, 2); for (int i = 0; i < arrMySQLSendBuffer.Length - 1; i++) { if (arrMySQLSendBuffer[i] == null) @@ -135,6 +135,10 @@ public class TCPController break; } } + } else + { + // Keep alive + PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "Keep-alive received", 2); } } else From 5889bc6ddf0c63035b88ca3f45cc879d15b4cfc6 Mon Sep 17 00:00:00 2001 From: szporowolik Date: Mon, 21 Oct 2019 16:55:44 +0200 Subject: [PATCH 12/23] SRS and LotATC sending will now look better in log files --- .../Perun_v1/01_Classes/DatabaseController.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs index 3cee1c7..a979024 100644 --- a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs +++ b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs @@ -103,7 +103,19 @@ public class DatabaseController Console.WriteLine(rdrMySQL[0] + " -- " + rdrMySQL[1]); } rdrMySQL.Close(); - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "MySQL updated, package type: " + strUDPFrameType,1); + switch (Int32.Parse(strUDPFrameType)) + { + case 100: + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "SRS data send to MySQL", 1); + break; + case 101: + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "LotATC data send to MySQL", 1); + break; + default: + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "MySQL updated, package type: " + strUDPFrameType, 1); + break; + } + } catch (ArgumentException a_ex) { From 5908f8f3322dd6ea05cc78826d15c0932769afef Mon Sep 17 00:00:00 2001 From: szporowolik Date: Mon, 21 Oct 2019 17:50:04 +0200 Subject: [PATCH 13/23] Logging improvment - GUI and log file shall be much easier to read and contain more information --- .../Perun_v1/01_Classes/DatabaseController.cs | 109 ++++++++++-------- .../Perun_v1/01_Classes/PerunHelper.cs | 23 ++-- .../Perun_v1/01_Classes/TCPController.cs | 10 +- 02_Windows_App/Perun_v1/02_Forms/form_Main.cs | 8 +- 4 files changed, 81 insertions(+), 69 deletions(-) diff --git a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs index a979024..729c753 100644 --- a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs +++ b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs @@ -9,80 +9,80 @@ public class DatabaseController public MySqlConnection connMySQL; public bool bStatus; - public void SendToMySql(string strRawUDPFrame) + public void SendToMySql(string strRawTCPFrame) { // Main function to send data to mysql - dynamic strUDPFrame = JsonConvert.DeserializeObject(strRawUDPFrame); // Deserialize raw data - string strUDPFrameType = strUDPFrame.type; - string strUDPFrameTimestamp = strUDPFrame.timestamp; - string strUDPFrameInstance = strUDPFrame.instance; - string strUDPFramePayload; - string strUDPFramePayload_Perun; + dynamic strTCPFrame = JsonConvert.DeserializeObject(strRawTCPFrame); // Deserialize raw data + string strTCPFrameType = strTCPFrame.type; + string strTCPFrameTimestamp = strTCPFrame.timestamp; + string strTCPFrameInstance = strTCPFrame.instance; + string strTCPFramePayload; + string strTCPFramePayload_Perun; string strSQLQueryTxt; // Some frames may come without timestamp, use database currrent timestampe then - if (strUDPFrameTimestamp != null) + if (strTCPFrameTimestamp != null) { - strUDPFrameTimestamp = "'" + strUDPFrameTimestamp + "'"; + strTCPFrameTimestamp = "'" + strTCPFrameTimestamp + "'"; } else { - strUDPFrameTimestamp = "CURRENT_TIMESTAMP()"; + strTCPFrameTimestamp = "CURRENT_TIMESTAMP()"; } // Modify specific types - if (strUDPFrameType == "1") + if (strTCPFrameType == "1") { - strUDPFrame.payload["v_win"] = "v" + Globals.strPerunVersion; // Inject app version information + strTCPFrame.payload["v_win"] = "v" + Globals.strPerunVersion; // Inject app version information } // Specific SQL per each frame type - if (strUDPFrameType == "50") + if (strTCPFrameType == "50") { // Add entry to chat log - strSQLQueryTxt = "INSERT INTO `pe_DataPlayers` (`pe_DataPlayers_ucid`) SELECT '" + strUDPFrame.payload.ucid + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataPlayers` where `pe_DataPlayers_ucid` = '" + strUDPFrame.payload.ucid + "' );"; - strSQLQueryTxt += "UPDATE `pe_DataPlayers` SET `pe_DataPlayers_updated` = " + strUDPFrameTimestamp + ",`pe_DataPlayers_lastname`='" + strUDPFrame.payload.player + "' WHERE `pe_DataPlayers_ucid`='" + strUDPFrame.payload.ucid + "' ;"; - strSQLQueryTxt += "INSERT INTO `pe_DataMissionHashes` (`pe_DataMissionHashes_hash`,`pe_DataMissionHashes_instance`) SELECT '" + strUDPFrame.payload.missionhash + "','" + strUDPFrameInstance + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataMissionHashes` where `pe_DataMissionHashes_hash` ='" + strUDPFrame.payload.missionhash + "' AND `pe_DataMissionHashes_instance`=" + strUDPFrameInstance + ");"; - strSQLQueryTxt += "UPDATE `pe_DataMissionHashes` SET `pe_DataMissionHashes_datetime` = " + strUDPFrameTimestamp + " WHERE `pe_DataMissionHashes_hash` = '" + strUDPFrame.payload.missionhash + "' AND `pe_DataMissionHashes_instance`=" + strUDPFrameInstance + " ;"; - strSQLQueryTxt += "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,'" + strUDPFrame.payload.datetime + "', (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + strUDPFrame.payload.ucid + "'), '" + strUDPFrame.payload.msg + "', '" + strUDPFrame.payload.all + "',(SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + strUDPFrame.payload.missionhash + "'));"; + strSQLQueryTxt = "INSERT INTO `pe_DataPlayers` (`pe_DataPlayers_ucid`) SELECT '" + strTCPFrame.payload.ucid + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataPlayers` where `pe_DataPlayers_ucid` = '" + strTCPFrame.payload.ucid + "' );"; + strSQLQueryTxt += "UPDATE `pe_DataPlayers` SET `pe_DataPlayers_updated` = " + strTCPFrameTimestamp + ",`pe_DataPlayers_lastname`='" + strTCPFrame.payload.player + "' WHERE `pe_DataPlayers_ucid`='" + strTCPFrame.payload.ucid + "' ;"; + strSQLQueryTxt += "INSERT INTO `pe_DataMissionHashes` (`pe_DataMissionHashes_hash`,`pe_DataMissionHashes_instance`) SELECT '" + strTCPFrame.payload.missionhash + "','" + strTCPFrameInstance + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataMissionHashes` where `pe_DataMissionHashes_hash` ='" + strTCPFrame.payload.missionhash + "' AND `pe_DataMissionHashes_instance`=" + strTCPFrameInstance + ");"; + strSQLQueryTxt += "UPDATE `pe_DataMissionHashes` SET `pe_DataMissionHashes_datetime` = " + strTCPFrameTimestamp + " WHERE `pe_DataMissionHashes_hash` = '" + strTCPFrame.payload.missionhash + "' AND `pe_DataMissionHashes_instance`=" + strTCPFrameInstance + " ;"; + strSQLQueryTxt += "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,'" + strTCPFrame.payload.datetime + "', (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + strTCPFrame.payload.ucid + "'), '" + strTCPFrame.payload.msg + "', '" + strTCPFrame.payload.all + "',(SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + strTCPFrame.payload.missionhash + "'));"; } - else if (strUDPFrameType == "51") + else if (strTCPFrameType == "51") { // Add entry to event log - strSQLQueryTxt = "INSERT INTO `pe_DataMissionHashes` (`pe_DataMissionHashes_hash`,`pe_DataMissionHashes_instance`) SELECT '" + strUDPFrame.payload.log_missionhash + "','" + strUDPFrameInstance + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataMissionHashes` where `pe_DataMissionHashes_hash` = '" + strUDPFrame.payload.log_missionhash + "' AND `pe_DataMissionHashes_instance`=" + strUDPFrameInstance + ");"; - strSQLQueryTxt += "UPDATE `pe_DataMissionHashes` SET `pe_DataMissionHashes_datetime` = " + strUDPFrameTimestamp + " WHERE `pe_DataMissionHashes_hash` = '" + strUDPFrame.payload.log_missionhash + "' AND `pe_DataMissionHashes_instance`=" + strUDPFrameInstance + ";"; - strSQLQueryTxt += "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 ('" + strUDPFrame.payload.log_arg_1 + "','" + strUDPFrame.payload.log_arg_2 + "', NULL, '" + strUDPFrame.payload.log_datetime + "', '" + strUDPFrame.payload.log_type + "', '" + strUDPFrame.payload.log_content + "', (SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + strUDPFrame.payload.log_missionhash + "'));"; + strSQLQueryTxt = "INSERT INTO `pe_DataMissionHashes` (`pe_DataMissionHashes_hash`,`pe_DataMissionHashes_instance`) SELECT '" + strTCPFrame.payload.log_missionhash + "','" + strTCPFrameInstance + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataMissionHashes` where `pe_DataMissionHashes_hash` = '" + strTCPFrame.payload.log_missionhash + "' AND `pe_DataMissionHashes_instance`=" + strTCPFrameInstance + ");"; + strSQLQueryTxt += "UPDATE `pe_DataMissionHashes` SET `pe_DataMissionHashes_datetime` = " + strTCPFrameTimestamp + " WHERE `pe_DataMissionHashes_hash` = '" + strTCPFrame.payload.log_missionhash + "' AND `pe_DataMissionHashes_instance`=" + strTCPFrameInstance + ";"; + strSQLQueryTxt += "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 ('" + strTCPFrame.payload.log_arg_1 + "','" + strTCPFrame.payload.log_arg_2 + "', NULL, '" + strTCPFrame.payload.log_datetime + "', '" + strTCPFrame.payload.log_type + "', '" + strTCPFrame.payload.log_content + "', (SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + strTCPFrame.payload.log_missionhash + "'));"; } - else if (strUDPFrameType == "52") + else if (strTCPFrameType == "52") { // Update user stats - strUDPFramePayload = JsonConvert.SerializeObject(strUDPFrame.payload.stat_data_dcs); // Deserialize payload - strUDPFramePayload_Perun = JsonConvert.SerializeObject(strUDPFrame.payload.stat_data_perun); // Deserialize payload + strTCPFramePayload = JsonConvert.SerializeObject(strTCPFrame.payload.stat_data_dcs); // Deserialize payload + strTCPFramePayload_Perun = JsonConvert.SerializeObject(strTCPFrame.payload.stat_data_perun); // Deserialize payload - strSQLQueryTxt = "INSERT INTO `pe_DataMissionHashes` (`pe_DataMissionHashes_hash`,`pe_DataMissionHashes_instance`) SELECT '" + strUDPFrame.payload.stat_missionhash + "','" + strUDPFrameInstance + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataMissionHashes` where `pe_DataMissionHashes_hash` = '" + strUDPFrame.payload.stat_missionhash + "' AND `pe_DataMissionHashes_instance`=" + strUDPFrameInstance + ");"; - strSQLQueryTxt += "UPDATE `pe_DataMissionHashes` SET `pe_DataMissionHashes_datetime` = " + strUDPFrameTimestamp + " WHERE `pe_DataMissionHashes_hash` = '" + strUDPFrame.payload.stat_missionhash + "' AND `pe_DataMissionHashes_instance`=" + strUDPFrameInstance + " ;"; - strSQLQueryTxt += "INSERT INTO `pe_DataPlayers` (`pe_DataPlayers_ucid`) SELECT '" + strUDPFrame.payload.stat_ucid + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataPlayers` where `pe_DataPlayers_ucid` = '" + strUDPFrame.payload.stat_ucid + "');"; - strSQLQueryTxt += "UPDATE `pe_DataPlayers` SET `pe_DataPlayers_updated`=" + strUDPFrameTimestamp + " WHERE `pe_DataPlayers_ucid`='" + strUDPFrame.payload.stat_ucid + "';"; - strSQLQueryTxt += "INSERT INTO `pe_DataTypes` (`pe_DataTypes_name`) SELECT '" + strUDPFrame.payload.stat_data_type + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataTypes` where `pe_DataTypes_name` = '" + strUDPFrame.payload.stat_data_type + "');"; - strSQLQueryTxt += "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` = '" + strUDPFrame.payload.stat_ucid + "'), (SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + strUDPFrame.payload.stat_missionhash + "'), (SELECT pe_DataTypes_id FROM `pe_DataTypes` where `pe_DataTypes_name` = '" + strUDPFrame.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` = '" + strUDPFrame.payload.stat_missionhash + "') AND `pe_LogStats_playerid` = (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + strUDPFrame.payload.stat_ucid + "') AND `pe_LogStats_typeid`= (SELECT pe_DataTypes_id FROM `pe_DataTypes` where `pe_DataTypes_name` = '" + strUDPFrame.payload.stat_data_type + "'));"; - strSQLQueryTxt += "UPDATE `pe_LogStats` SET `ps_kills_fortification`=" + strUDPFrame.payload.stat_data_perun.ps_kills_fortification + ",`ps_other_landings`=" + strUDPFrame.payload.stat_data_perun.ps_other_landings + ",`ps_other_takeoffs`=" + strUDPFrame.payload.stat_data_perun.ps_other_takeoffs + ",`ps_pvp`=" + strUDPFrame.payload.stat_data_perun.ps_pvp + ",`ps_deaths`=" + strUDPFrame.payload.stat_data_perun.ps_deaths + ",`ps_ejections`=" + strUDPFrame.payload.stat_data_perun.ps_ejections + ",`ps_crashes`=" + strUDPFrame.payload.stat_data_perun.ps_crashes + ",`ps_teamkills`=" + strUDPFrame.payload.stat_data_perun.ps_teamkills + ",`ps_kills_planes`=" + strUDPFrame.payload.stat_data_perun.ps_kills_planes + ",`ps_kills_helicopters`=" + strUDPFrame.payload.stat_data_perun.ps_kills_helicopters + ",`ps_kills_air_defense`=" + strUDPFrame.payload.stat_data_perun.ps_kills_air_defense + ",`ps_kills_armor`=" + strUDPFrame.payload.stat_data_perun.ps_kills_armor + ",`ps_kills_unarmed`=" + strUDPFrame.payload.stat_data_perun.ps_kills_unarmed + ",`ps_kills_infantry`=" + strUDPFrame.payload.stat_data_perun.ps_kills_infantry + ",`ps_kills_ships`=" + strUDPFrame.payload.stat_data_perun.ps_kills_ships + ",`ps_kills_other`=" + strUDPFrame.payload.stat_data_perun.ps_kills_other + ",`ps_airfield_takeoffs`=" + strUDPFrame.payload.stat_data_perun.ps_airfield_takeoffs + ",`ps_airfield_landings`=" + strUDPFrame.payload.stat_data_perun.ps_airfield_landings + ",`ps_ship_takeoffs`=" + strUDPFrame.payload.stat_data_perun.ps_ship_takeoffs + ",`ps_ship_landings`=" + strUDPFrame.payload.stat_data_perun.ps_ship_landings + ",`ps_farp_takeoffs`=" + strUDPFrame.payload.stat_data_perun.ps_farp_takeoffs + ",`ps_farp_landings`=" + strUDPFrame.payload.stat_data_perun.ps_farp_landings + ", `pe_LogStats_datetime`='" + strUDPFrame.payload.stat_datetime + "',`pe_LogStats_playerid` = (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + strUDPFrame.payload.stat_ucid + "'),`pe_LogStats_missionhash_id`=(SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + strUDPFrame.payload.stat_missionhash + "') WHERE `pe_LogStats_missionhash_id`=(SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + strUDPFrame.payload.stat_missionhash + "') AND `pe_LogStats_playerid` = (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + strUDPFrame.payload.stat_ucid + "') AND `pe_LogStats_typeid`=(SELECT pe_DataTypes_id FROM `pe_DataTypes` where `pe_DataTypes_name` = '" + strUDPFrame.payload.stat_data_type + "');"; + strSQLQueryTxt = "INSERT INTO `pe_DataMissionHashes` (`pe_DataMissionHashes_hash`,`pe_DataMissionHashes_instance`) SELECT '" + strTCPFrame.payload.stat_missionhash + "','" + strTCPFrameInstance + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataMissionHashes` where `pe_DataMissionHashes_hash` = '" + strTCPFrame.payload.stat_missionhash + "' AND `pe_DataMissionHashes_instance`=" + strTCPFrameInstance + ");"; + strSQLQueryTxt += "UPDATE `pe_DataMissionHashes` SET `pe_DataMissionHashes_datetime` = " + strTCPFrameTimestamp + " WHERE `pe_DataMissionHashes_hash` = '" + strTCPFrame.payload.stat_missionhash + "' AND `pe_DataMissionHashes_instance`=" + strTCPFrameInstance + " ;"; + strSQLQueryTxt += "INSERT INTO `pe_DataPlayers` (`pe_DataPlayers_ucid`) SELECT '" + strTCPFrame.payload.stat_ucid + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataPlayers` where `pe_DataPlayers_ucid` = '" + strTCPFrame.payload.stat_ucid + "');"; + strSQLQueryTxt += "UPDATE `pe_DataPlayers` SET `pe_DataPlayers_updated`=" + strTCPFrameTimestamp + " WHERE `pe_DataPlayers_ucid`='" + strTCPFrame.payload.stat_ucid + "';"; + strSQLQueryTxt += "INSERT INTO `pe_DataTypes` (`pe_DataTypes_name`) SELECT '" + strTCPFrame.payload.stat_data_type + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataTypes` where `pe_DataTypes_name` = '" + strTCPFrame.payload.stat_data_type + "');"; + strSQLQueryTxt += "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` = '" + strTCPFrame.payload.stat_ucid + "'), (SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + strTCPFrame.payload.stat_missionhash + "'), (SELECT pe_DataTypes_id FROM `pe_DataTypes` where `pe_DataTypes_name` = '" + strTCPFrame.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` = '" + strTCPFrame.payload.stat_missionhash + "') AND `pe_LogStats_playerid` = (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + strTCPFrame.payload.stat_ucid + "') AND `pe_LogStats_typeid`= (SELECT pe_DataTypes_id FROM `pe_DataTypes` where `pe_DataTypes_name` = '" + strTCPFrame.payload.stat_data_type + "'));"; + strSQLQueryTxt += "UPDATE `pe_LogStats` SET `ps_kills_fortification`=" + strTCPFrame.payload.stat_data_perun.ps_kills_fortification + ",`ps_other_landings`=" + strTCPFrame.payload.stat_data_perun.ps_other_landings + ",`ps_other_takeoffs`=" + strTCPFrame.payload.stat_data_perun.ps_other_takeoffs + ",`ps_pvp`=" + strTCPFrame.payload.stat_data_perun.ps_pvp + ",`ps_deaths`=" + strTCPFrame.payload.stat_data_perun.ps_deaths + ",`ps_ejections`=" + strTCPFrame.payload.stat_data_perun.ps_ejections + ",`ps_crashes`=" + strTCPFrame.payload.stat_data_perun.ps_crashes + ",`ps_teamkills`=" + strTCPFrame.payload.stat_data_perun.ps_teamkills + ",`ps_kills_planes`=" + strTCPFrame.payload.stat_data_perun.ps_kills_planes + ",`ps_kills_helicopters`=" + strTCPFrame.payload.stat_data_perun.ps_kills_helicopters + ",`ps_kills_air_defense`=" + strTCPFrame.payload.stat_data_perun.ps_kills_air_defense + ",`ps_kills_armor`=" + strTCPFrame.payload.stat_data_perun.ps_kills_armor + ",`ps_kills_unarmed`=" + strTCPFrame.payload.stat_data_perun.ps_kills_unarmed + ",`ps_kills_infantry`=" + strTCPFrame.payload.stat_data_perun.ps_kills_infantry + ",`ps_kills_ships`=" + strTCPFrame.payload.stat_data_perun.ps_kills_ships + ",`ps_kills_other`=" + strTCPFrame.payload.stat_data_perun.ps_kills_other + ",`ps_airfield_takeoffs`=" + strTCPFrame.payload.stat_data_perun.ps_airfield_takeoffs + ",`ps_airfield_landings`=" + strTCPFrame.payload.stat_data_perun.ps_airfield_landings + ",`ps_ship_takeoffs`=" + strTCPFrame.payload.stat_data_perun.ps_ship_takeoffs + ",`ps_ship_landings`=" + strTCPFrame.payload.stat_data_perun.ps_ship_landings + ",`ps_farp_takeoffs`=" + strTCPFrame.payload.stat_data_perun.ps_farp_takeoffs + ",`ps_farp_landings`=" + strTCPFrame.payload.stat_data_perun.ps_farp_landings + ", `pe_LogStats_datetime`='" + strTCPFrame.payload.stat_datetime + "',`pe_LogStats_playerid` = (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + strTCPFrame.payload.stat_ucid + "'),`pe_LogStats_missionhash_id`=(SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + strTCPFrame.payload.stat_missionhash + "') WHERE `pe_LogStats_missionhash_id`=(SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + strTCPFrame.payload.stat_missionhash + "') AND `pe_LogStats_playerid` = (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + strTCPFrame.payload.stat_ucid + "') AND `pe_LogStats_typeid`=(SELECT pe_DataTypes_id FROM `pe_DataTypes` where `pe_DataTypes_name` = '" + strTCPFrame.payload.stat_data_type + "');"; } - else if (strUDPFrameType == "53") + else if (strTCPFrameType == "53") { // User logged in to DCS server - strSQLQueryTxt = "INSERT INTO `pe_DataPlayers` (`pe_DataPlayers_ucid`) SELECT '" + strUDPFrame.payload.login_ucid + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataPlayers` where pe_DataPlayers_ucid='" + strUDPFrame.payload.login_ucid + "');"; - strSQLQueryTxt += "UPDATE `pe_DataPlayers` SET pe_DataPlayers_lastip='" + strUDPFrame.payload.login_ipaddr + "', pe_DataPlayers_lastname='" + strUDPFrame.payload.login_name + "',pe_DataPlayers_updated='" + strUDPFrame.payload.login_datetime + "' WHERE `pe_DataPlayers_ucid`= '" + strUDPFrame.payload.login_ucid + "';"; - strSQLQueryTxt += "INSERT INTO `pe_LogLogins` (`pe_LogLogins_datetime`, `pe_LogLogins_playerid`, `pe_LogLogins_name`, `pe_LogLogins_ip`,`pe_LogLogins_instance`) VALUES ('" + strUDPFrame.payload.login_datetime + "', (SELECT pe_DataPlayers_id from pe_DataPlayers WHERE pe_DataPlayers_ucid = '" + strUDPFrame.payload.login_ucid + "'), '" + strUDPFrame.payload.login_name + "', '" + strUDPFrame.payload.login_ipaddr + "','" + strUDPFrameInstance + "');"; + strSQLQueryTxt = "INSERT INTO `pe_DataPlayers` (`pe_DataPlayers_ucid`) SELECT '" + strTCPFrame.payload.login_ucid + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataPlayers` where pe_DataPlayers_ucid='" + strTCPFrame.payload.login_ucid + "');"; + strSQLQueryTxt += "UPDATE `pe_DataPlayers` SET pe_DataPlayers_lastip='" + strTCPFrame.payload.login_ipaddr + "', pe_DataPlayers_lastname='" + strTCPFrame.payload.login_name + "',pe_DataPlayers_updated='" + strTCPFrame.payload.login_datetime + "' WHERE `pe_DataPlayers_ucid`= '" + strTCPFrame.payload.login_ucid + "';"; + strSQLQueryTxt += "INSERT INTO `pe_LogLogins` (`pe_LogLogins_datetime`, `pe_LogLogins_playerid`, `pe_LogLogins_name`, `pe_LogLogins_ip`,`pe_LogLogins_instance`) VALUES ('" + strTCPFrame.payload.login_datetime + "', (SELECT pe_DataPlayers_id from pe_DataPlayers WHERE pe_DataPlayers_ucid = '" + strTCPFrame.payload.login_ucid + "'), '" + strTCPFrame.payload.login_name + "', '" + strTCPFrame.payload.login_ipaddr + "','" + strTCPFrameInstance + "');"; } else { // General definition used for 1-10 type packets - strUDPFramePayload = JsonConvert.SerializeObject(strUDPFrame.payload); // Deserialize payload + strTCPFramePayload = JsonConvert.SerializeObject(strTCPFrame.payload); // Deserialize payload - strSQLQueryTxt = "INSERT INTO `pe_DataRaw` (`pe_dataraw_type`,`pe_dataraw_instance`) SELECT '" + strUDPFrameType + "','" + strUDPFrameInstance + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataRaw` WHERE `pe_dataraw_type` = '" + strUDPFrameType + "' AND `pe_dataraw_instance` = " + strUDPFrameInstance + ");"; - strSQLQueryTxt += "UPDATE `pe_DataRaw` SET `pe_dataraw_payload` = JSON_QUOTE('" + strUDPFramePayload + "'), `pe_dataraw_updated`=" + strUDPFrameTimestamp + " WHERE `pe_dataraw_type`=" + strUDPFrameType + " AND `pe_dataraw_instance` = " + strUDPFrameInstance + ";"; + strSQLQueryTxt = "INSERT INTO `pe_DataRaw` (`pe_dataraw_type`,`pe_dataraw_instance`) SELECT '" + strTCPFrameType + "','" + strTCPFrameInstance + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataRaw` WHERE `pe_dataraw_type` = '" + strTCPFrameType + "' AND `pe_dataraw_instance` = " + strTCPFrameInstance + ");"; + strSQLQueryTxt += "UPDATE `pe_DataRaw` SET `pe_dataraw_payload` = JSON_QUOTE('" + strTCPFramePayload + "'), `pe_dataraw_updated`=" + strTCPFrameTimestamp + " WHERE `pe_dataraw_type`=" + strTCPFrameType + " AND `pe_dataraw_instance` = " + strTCPFrameInstance + ";"; } // Connect to mysql and execute sql @@ -103,16 +103,25 @@ public class DatabaseController Console.WriteLine(rdrMySQL[0] + " -- " + rdrMySQL[1]); } rdrMySQL.Close(); - switch (Int32.Parse(strUDPFrameType)) + switch (Int32.Parse(strTCPFrameType)) { + case 1: + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Connected players: " + strTCPFrame.payload["c_players"], 1,0,"1"); + break; + case 2: + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Mission: \"" + strTCPFrame.payload["mission"]["name"]+"\""+ ", time:" + strTCPFrame.payload["mission"]["modeltime"], 1, 0, "2"); + break; + case 3: + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Slots data updated", 1, 0, "3"); + break; case 100: - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "SRS data send to MySQL", 1); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "SRS data send", 1,0,"100"); break; case 101: - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "LotATC data send to MySQL", 1); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "LotATC data send", 1,0,"101"); break; default: - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "MySQL updated, package type: " + strUDPFrameType, 1); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Data send", 1,0, strTCPFrameType); break; } @@ -121,25 +130,23 @@ public class DatabaseController { // General exception found Console.WriteLine(a_ex.ToString()); - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - package type: " + strUDPFrameType,1,1); - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - error: " + a_ex.Message,1,1); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - error: " + a_ex.Message,1,1, strTCPFrameType); bStatus = false; } catch (MySqlException m_ex) { // MySQL exception found - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - package type: " + strUDPFrameType,1,1); switch (m_ex.Number) { case 1042: // Unable to connect to any of the specified MySQL hosts (Check Server,Port) - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - unable to connect, error: " + m_ex.Message,1,1); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - unable to connect, error: " + m_ex.Message,1,1, strTCPFrameType); break; case 0: // Access denied (Check DB name,username,password) - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - access denied, error: " + m_ex.Message,1,1); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - access denied, error: " + m_ex.Message,1,1, strTCPFrameType); break; default: - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - error id: " + m_ex.Number,1,1); - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - error: " + m_ex.Message,1,1); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - error id: " + m_ex.Number,1,1, strTCPFrameType); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - error: " + m_ex.Message,1,1, strTCPFrameType); break; } bStatus = false; @@ -149,7 +156,7 @@ public class DatabaseController } catch (ArgumentException x_ex) { - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - unable to connect, error: " + x_ex.Message,1,1); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - unable to connect, error: " + x_ex.Message,1,1, strTCPFrameType); } diff --git a/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs b/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs index d34b93a..a83e4a8 100644 --- a/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs +++ b/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs @@ -4,7 +4,7 @@ using System.Reflection; internal class PerunHelper { - public static void GUILogHistoryAdd(ref string[] arrLogHistory, string strEntryToAdd, int intDirection = 0, int intMarker = 0) + public static void GUILogHistoryAdd(ref string[] arrLogHistory, string strEntryToAdd, int intDirection = 0, int intMarker = 0, string strType = " ", bool bSkipGui = false) { // Declare values string strDirection; @@ -29,17 +29,22 @@ internal class PerunHelper // Set marker for user flags (markers) strMarker = (intMarker>0) ? "X" : " "; - // Rotate log history - for (int i = 0; i < arrLogHistory.Length - 1; i++) + // Set frame type + strType=strType.PadLeft(3, ' '); + + if (!bSkipGui) { - arrLogHistory[i] = arrLogHistory[i + 1]; // Shift one down + // Rotate log history + for (int i = 0; i < arrLogHistory.Length - 1; i++) + { + arrLogHistory[i] = arrLogHistory[i + 1]; // Shift one down + } + + // Add new entry + arrLogHistory[arrLogHistory.Length - 1] = DateTime.Now.ToString("HH:mm:ss") + " " + strDirection + " " + strEntryToAdd; // Add entry at the last position } - - // Add new entry - arrLogHistory[arrLogHistory.Length - 1] = DateTime.Now.ToString("HH:mm:ss") + " " + strDirection + " " + strEntryToAdd; // Add entry at the last position - // Add the entry to log file - LogController.WriteLog(DateTime.Now.ToString("yyyy-dd-MM ") + " " + DateTime.Now.ToString("HH:mm:ss") + " | Instance: "+ Globals.intInstanceId + " | " + strMarker + " | " + strDirection + " | " + strEntryToAdd); + LogController.WriteLog(DateTime.Now.ToString("yyyy-dd-MM ") + " " + DateTime.Now.ToString("HH:mm:ss") + " | Instance: "+ Globals.intInstanceId + " | " + strMarker + " | "+ strDirection + " | "+ strType + " | " + strEntryToAdd); // Update control at my window Globals.bGUILogHistoryUpdate = true; diff --git a/02_Windows_App/Perun_v1/01_Classes/TCPController.cs b/02_Windows_App/Perun_v1/01_Classes/TCPController.cs index 759b3da..30dc13d 100644 --- a/02_Windows_App/Perun_v1/01_Classes/TCPController.cs +++ b/02_Windows_App/Perun_v1/01_Classes/TCPController.cs @@ -126,7 +126,7 @@ public class TCPController if (Int32.Parse(strRawTCPFrameType) != 0) { // Add to mySQL send buffer (find first empty slot) - PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "TCP packet received, type: " + strRawTCPFrameType, 2); + PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "Packet received" , 2,0, strRawTCPFrameType,true); for (int i = 0; i < arrMySQLSendBuffer.Length - 1; i++) { if (arrMySQLSendBuffer[i] == null) @@ -138,7 +138,7 @@ public class TCPController } else { // Keep alive - PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "Keep-alive received", 2); + PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "Keep-alive received", 2,0,"0",true); } } else @@ -150,7 +150,7 @@ public class TCPController { Globals.intGameErros++; Console.WriteLine(e.ToString()); - PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "ERROR while message parsing , error: " + e.Message,2,1); + PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "ERROR while message parsing , error: " + e.Message,2,1,"?"); bTCPConnectionOnline = false; } @@ -162,7 +162,7 @@ public class TCPController catch (SocketException e) { Console.WriteLine(e.ToString()); - PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "TCP ERROR cannot check connection, error: " + e.Message,2,1); + PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "TCP ERROR cannot check connection, error: " + e.Message,2,1,"?"); } } @@ -176,7 +176,7 @@ public class TCPController { Globals.intGameErros++; Console.WriteLine(e.ToString()); - PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "TCP error - connection closed or port in use, error: " + e.Message,1,1); + PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "TCP error - connection closed or port in use, error: " + e.Message,1,1,"?"); bTCPConnectionOnline = false; } diff --git a/02_Windows_App/Perun_v1/02_Forms/form_Main.cs b/02_Windows_App/Perun_v1/02_Forms/form_Main.cs index 61c8a66..5ad1998 100644 --- a/02_Windows_App/Perun_v1/02_Forms/form_Main.cs +++ b/02_Windows_App/Perun_v1/02_Forms/form_Main.cs @@ -534,12 +534,12 @@ namespace Perun_v1 strSRSJson = "{'type':'100','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':{'ignore':'false'}}"; // No SRS clients connected } boolSRSdefault = false; - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "SRS data loaded",3); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "SRS data loaded",3,0,"100",true); bSRSStatus = true; } catch (Exception exc_srs) { - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "SRS data ERROR , error: " + exc_srs.Message,3,1); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "SRS data ERROR , error: " + exc_srs.Message,3,1,"100"); bSRSStatus = false; Globals.intSRSErros++; } @@ -562,12 +562,12 @@ namespace Perun_v1 strLotATCJson = "{'type':'101','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':'" + strLotATCJson + "'}"; boolLotATCdefault = false; - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "LotATC data loaded",3); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "LotATC data loaded",3,0,"101",true); bLotATCStatus = true; } catch (Exception exc_lotatc) { - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "LotATC data ERROR, error: " + exc_lotatc.Message,3,1); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "LotATC data ERROR, error: " + exc_lotatc.Message,3,1,"101"); bLotATCStatus = false; Globals.intLotATCErros++; } From efc215f58a91ad5eccd17b68b235598ecd523a41 Mon Sep 17 00:00:00 2001 From: szporowolik Date: Mon, 21 Oct 2019 18:09:23 +0200 Subject: [PATCH 14/23] Further logging improvment --- .../Perun_v1/01_Classes/DatabaseController.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs index 729c753..4de222d 100644 --- a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs +++ b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs @@ -114,6 +114,18 @@ public class DatabaseController case 3: PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Slots data updated", 1, 0, "3"); break; + case 50: + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Player "+ strTCPFrame.payload.player + " chat message saved", 1, 0, "50"); + break; + case 51: + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Game event: "+ strTCPFrame.payload.log_content, 1, 0, "51"); + break; + case 52: + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Player "+ strTCPFrame.payload.stat_name + " stats saved", 1, 0, "52"); + break; + case 53: + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Player "+ strTCPFrame.payload.login_name + " logged in", 1, 0, "53"); + break; case 100: PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "SRS data send", 1,0,"100"); break; From 1f110321b465c25af48586ff7be2c567c8e52fbd Mon Sep 17 00:00:00 2001 From: szporowolik Date: Mon, 21 Oct 2019 20:21:01 +0200 Subject: [PATCH 15/23] Not send srs/lotatc data if there is no game connection. --- 02_Windows_App/Perun_v1/02_Forms/form_Main.cs | 138 +++++++++--------- 1 file changed, 72 insertions(+), 66 deletions(-) diff --git a/02_Windows_App/Perun_v1/02_Forms/form_Main.cs b/02_Windows_App/Perun_v1/02_Forms/form_Main.cs index 5ad1998..af0b841 100644 --- a/02_Windows_App/Perun_v1/02_Forms/form_Main.cs +++ b/02_Windows_App/Perun_v1/02_Forms/form_Main.cs @@ -486,99 +486,105 @@ namespace Perun_v1 bool boolLotATCdefault = true; // Handle SRS - if (con_check_3rd_srs.Checked) + if (Globals.bClientConnected) { - try + if (con_check_3rd_srs.Checked) { - strSRSJson = System.IO.File.ReadAllText(con_txt_3rd_srs.Text); - dynamic raw_lotatc = JsonConvert.DeserializeObject(strSRSJson); - - for (int i = 0; i < raw_lotatc.Count; i++) + try { + strSRSJson = System.IO.File.ReadAllText(con_txt_3rd_srs.Text); + dynamic raw_lotatc = JsonConvert.DeserializeObject(strSRSJson); - if (raw_lotatc[i].RadioInfo != null) + for (int i = 0; i < raw_lotatc.Count; i++) { - int temp = raw_lotatc[i].RadioInfo.radios.Count - 1; - for (int j = temp; j >= 0; j--) + if (raw_lotatc[i].RadioInfo != null) { - raw_lotatc[i].RadioInfo.radios[j].enc.Parent.Remove(); - raw_lotatc[i].RadioInfo.radios[j].encKey.Parent.Remove(); - raw_lotatc[i].RadioInfo.radios[j].encMode.Parent.Remove(); - raw_lotatc[i].RadioInfo.radios[j].freqMax.Parent.Remove(); - raw_lotatc[i].RadioInfo.radios[j].freqMin.Parent.Remove(); - raw_lotatc[i].RadioInfo.radios[j].modulation.Parent.Remove(); - raw_lotatc[i].RadioInfo.radios[j].freqMode.Parent.Remove(); - raw_lotatc[i].RadioInfo.radios[j].volMode.Parent.Remove(); - raw_lotatc[i].RadioInfo.radios[j].expansion.Parent.Remove(); - raw_lotatc[i].RadioInfo.radios[j].channel.Parent.Remove(); - raw_lotatc[i].RadioInfo.radios[j].simul.Parent.Remove(); - if (raw_lotatc[i].RadioInfo.radios[j].name == "No Radio") + int temp = raw_lotatc[i].RadioInfo.radios.Count - 1; + for (int j = temp; j >= 0; j--) { - raw_lotatc[i].RadioInfo.radios[j].Remove(); + raw_lotatc[i].RadioInfo.radios[j].enc.Parent.Remove(); + raw_lotatc[i].RadioInfo.radios[j].encKey.Parent.Remove(); + raw_lotatc[i].RadioInfo.radios[j].encMode.Parent.Remove(); + raw_lotatc[i].RadioInfo.radios[j].freqMax.Parent.Remove(); + raw_lotatc[i].RadioInfo.radios[j].freqMin.Parent.Remove(); + raw_lotatc[i].RadioInfo.radios[j].modulation.Parent.Remove(); + raw_lotatc[i].RadioInfo.radios[j].freqMode.Parent.Remove(); + raw_lotatc[i].RadioInfo.radios[j].volMode.Parent.Remove(); + raw_lotatc[i].RadioInfo.radios[j].expansion.Parent.Remove(); + raw_lotatc[i].RadioInfo.radios[j].channel.Parent.Remove(); + raw_lotatc[i].RadioInfo.radios[j].simul.Parent.Remove(); + + if (raw_lotatc[i].RadioInfo.radios[j].name == "No Radio") + { + raw_lotatc[i].RadioInfo.radios[j].Remove(); + } } + raw_lotatc[i].ClientChannelId.Parent.Remove(); + raw_lotatc[i].RadioInfo.simultaneousTransmission.Parent.Remove(); } - raw_lotatc[i].ClientChannelId.Parent.Remove(); - raw_lotatc[i].RadioInfo.simultaneousTransmission.Parent.Remove(); } + + if (raw_lotatc.Count > 0) + { + strSRSJson = JsonConvert.SerializeObject(raw_lotatc); + strSRSJson = "{'type':'100','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':'" + strSRSJson + "'}"; + } + else + { + strSRSJson = "{'type':'100','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':{'ignore':'false'}}"; // No SRS clients connected + } + boolSRSdefault = false; + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "SRS data loaded", 3, 0, "100", true); + bSRSStatus = true; + } + catch (Exception exc_srs) + { + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "SRS data ERROR , error: " + exc_srs.Message, 3, 1, "100"); + bSRSStatus = false; + Globals.intSRSErros++; } - if (raw_lotatc.Count > 0) - { - strSRSJson = JsonConvert.SerializeObject(raw_lotatc); - strSRSJson = "{'type':'100','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':'" + strSRSJson + "'}"; - } - else - { - strSRSJson = "{'type':'100','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':{'ignore':'false'}}"; // No SRS clients connected - } - boolSRSdefault = false; - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "SRS data loaded",3,0,"100",true); - bSRSStatus = true; + } - catch (Exception exc_srs) + if (boolSRSdefault) { - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "SRS data ERROR , error: " + exc_srs.Message,3,1,"100"); - bSRSStatus = false; - Globals.intSRSErros++; + strSRSJson = "{'type':'100','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':{'ignore':'true'}}"; } - - + dcConnection.SendToMySql(strSRSJson); } - if (boolSRSdefault) - { - strSRSJson = "{'type':'100','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':{'ignore':'true'}}"; - } - dcConnection.SendToMySql(strSRSJson); // Handle LotATC - if (con_check_3rd_lotatc.Checked) + if (Globals.bClientConnected) { - try + if (con_check_3rd_lotatc.Checked) { - strLotATCJson = System.IO.File.ReadAllText(con_txt_3rd_lotatc.Text); - dynamic raw_srs = JsonConvert.DeserializeObject(strLotATCJson); + try + { + strLotATCJson = System.IO.File.ReadAllText(con_txt_3rd_lotatc.Text); + dynamic raw_srs = JsonConvert.DeserializeObject(strLotATCJson); + + strLotATCJson = "{'type':'101','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':'" + strLotATCJson + "'}"; + boolLotATCdefault = false; + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "LotATC data loaded", 3, 0, "101", true); + bLotATCStatus = true; + } + catch (Exception exc_lotatc) + { + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "LotATC data ERROR, error: " + exc_lotatc.Message, 3, 1, "101"); + bLotATCStatus = false; + Globals.intLotATCErros++; + } + - strLotATCJson = "{'type':'101','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':'" + strLotATCJson + "'}"; - boolLotATCdefault = false; - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "LotATC data loaded",3,0,"101",true); - bLotATCStatus = true; } - catch (Exception exc_lotatc) + if (boolLotATCdefault) { - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "LotATC data ERROR, error: " + exc_lotatc.Message,3,1,"101"); - bLotATCStatus = false; - Globals.intLotATCErros++; + strLotATCJson = "{'type':'101','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':{'ignore':'true'}}"; // No LotATC controller connected } - - + dcConnection.SendToMySql(strLotATCJson); } - if (boolLotATCdefault) - { - strLotATCJson = "{'type':'101','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':{'ignore':'true'}}"; // No LotATC controller connected - } - dcConnection.SendToMySql(strLotATCJson); // Let's do not risk int overload Globals.intMysqlErros = (Globals.intMysqlErros > 999) ? 999 : Globals.intMysqlErros; From 83ce2bd4903369e29c5efe603c73c3dad55f9ada Mon Sep 17 00:00:00 2001 From: szporowolik Date: Mon, 21 Oct 2019 20:22:18 +0200 Subject: [PATCH 16/23] Improved log files - events --- 02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs index 4de222d..919d68d 100644 --- a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs +++ b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs @@ -115,16 +115,16 @@ public class DatabaseController PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Slots data updated", 1, 0, "3"); break; case 50: - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Player "+ strTCPFrame.payload.player + " chat message saved", 1, 0, "50"); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Player's \""+ strTCPFrame.payload.player + "\" chat message saved", 1, 0, "50"); break; case 51: - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Game event: "+ strTCPFrame.payload.log_content, 1, 0, "51"); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Game event: \""+ strTCPFrame.payload.log_content +"\"", 1, 0, "51"); break; case 52: - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Player "+ strTCPFrame.payload.stat_name + " stats saved", 1, 0, "52"); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Player's \""+ strTCPFrame.payload.stat_name + "\" stats saved", 1, 0, "52"); break; case 53: - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Player "+ strTCPFrame.payload.login_name + " logged in", 1, 0, "53"); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Player \""+ strTCPFrame.payload.login_name + "\" logged in", 1, 0, "53"); break; case 100: PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "SRS data send", 1,0,"100"); From b8087f63334f5572abe466eed313eada6281d385 Mon Sep 17 00:00:00 2001 From: szporowolik Date: Tue, 22 Oct 2019 01:15:48 +0200 Subject: [PATCH 17/23] First approach for multicrew stats --- 01_DCS/Hooks/Perun.lua | 160 +++++++++++++++++++++++++++++------------ 1 file changed, 116 insertions(+), 44 deletions(-) diff --git a/01_DCS/Hooks/Perun.lua b/01_DCS/Hooks/Perun.lua index 0ab2ced..3be720b 100644 --- a/01_DCS/Hooks/Perun.lua +++ b/01_DCS/Hooks/Perun.lua @@ -189,9 +189,9 @@ Perun.ConnectToPerun = function () _, err = Perun.TCP:connect(Perun.TCPPerunHost, Perun.TCPTargetPort) if err then - Perun.AddLog("TCP connection error : " .. err) + Perun.AddLog("ERROR - TCP connection error : " .. err) else - Perun.AddLog("Connected to TCP server") + Perun.AddLog("Sucess - connected to TCP server") -- Perun.TCP:setoption("keepalive") Perun.lastReconnect = _now end @@ -210,7 +210,6 @@ Perun.SendToPerun = function(data_id, data_package) temp="" .. stripChars(temp) .. "" -- TCP Part - sending - Perun.AddLog("Sending packet: " .. data_id) intStatus = nil intTries =0 err=nil @@ -226,7 +225,7 @@ Perun.SendToPerun = function(data_id, data_package) err = nil end if err then - Perun.AddLog("Packed dropped : " .. data_id) + Perun.AddLog("ERROR - packed dropped : " .. data_id) end end @@ -314,7 +313,7 @@ Perun.LogChat = function(playerID,msg,all) end Perun.LogEvent = function(log_type,log_content,log_arg_1,log_arg_2) - -- Logs chat messages + -- Logs events messages data={} data['log_type']= log_type @@ -465,6 +464,7 @@ Perun.LogStats = function(playerID) data['stat_data_perun']=_temp data['stat_data_type']=_temp['ps_type']; data['stat_ucid']=net.get_player_info(playerID, 'ucid') + data['stat_name']=net.get_player_info(playerID, 'name') data['stat_datetime']=os.date('%Y-%m-%d %H:%M:%S') data['stat_missionhash']=Perun.MissionHash @@ -483,6 +483,47 @@ Perun.LogLogin = function(playerID) Perun.SendToPerun(53,data) end +Perun.CheckMulticrew = function (owner_playerID,owner_unittype) + -- Check multicrew and return list of co-player + + _coplayers = {} + table.insert(_coplayers, owner_playerID) + if owner_unittype == "F-14B" or owner_unittype == "Yak-52" or owner_unittype == "L-39C" or owner_unittype == "SA342M" or owner_unittype =="SA342Minigun" or owner_unittype == "SA342Mistral" or owner_unittype == "SA342L" then -- TBD add additional multicrew model types + + _owner_slot=net.get_player_info(owner_playerID, 'slot') + _owner_side=net.get_player_info(owner_playerID, 'side') + + -- Check if we are co-player + _t_start, _t_end = string.find(_owner_slot, '_%d+') + _sub_slot = nil + if _t_start then + -- This is co-player + _master_slot = string.sub(_owner_slot, 0 , _t_start -1 ) + _sub_slot = string.sub(_owner_slot, _t_start + 1, _t_end ) + else + _master_slot = _owner_slot + + end + + if _master_slot ~= "" then + -- Search for all players to account for event + _all_players = net.get_player_list() + for PlayerIDIndex, playerID in ipairs(_all_players) do + local _playerDetails = net.get_player_info( playerID ) + + if _playerDetails.side == _owner_side and (_playerDetails.slot == _master_slot or _playerDetails.slot == _master_slot .. "_1" or _playerDetails.slot == _master_slot .. "_2") and playerID ~= owner_playerID then + -- Let's build coplayers list + table.insert(_coplayers, playerID) + else + -- No coplayers + end + end + end + end + return _coplayers +end + + --- ########### Event callbacks ########### Perun.onSimulationStart = function() @@ -554,10 +595,6 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) end Perun.LogEvent(eventName,Perun.SideID2Name( net.get_player_info(arg1, "side")) .. " player " .. net.get_player_info(arg1, "name").." killed friendy " .. net.get_player_info(arg3, "name") .. " using " .. arg2,nil,nil); - - if arg1 ~= arg3 then - -- Perun.LogStatsCount(arg1,"friendly_fire",DCS.getUnitType(net.get_player_info(arg1 , 'slot'))) - end elseif eventName == "mission_end" then --"mission_end", winner, msg @@ -576,31 +613,41 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) if net.get_player_info(arg1, "name") ~= nil then _temp2 = " player ".. net.get_player_info(arg1, "name") .." "; - if Perun.GetCategory(arg5) == "Planes" then - Perun.LogStatsCount(arg1,"kill_Planes",arg2) - elseif Perun.GetCategory(arg5) == "Helicopters" then - Perun.LogStatsCount(arg1,"kill_Helicopters",arg2) - elseif Perun.GetCategory(arg5) == "Ships" then - Perun.LogStatsCount(arg1,"kill_Ships",arg2) - elseif Perun.GetCategory(arg5) == "Air Defence" then - Perun.LogStatsCount(arg1,"kill_Air_Defence",arg2) - elseif Perun.GetCategory(arg5) == "Unarmed" then - Perun.LogStatsCount(arg1,"kill_Unarmed",arg2) - elseif Perun.GetCategory(arg5) == "Armor" then - Perun.LogStatsCount(arg1,"kill_Armor",arg2) - elseif Perun.GetCategory(arg5) == "Infantry" then - Perun.LogStatsCount(arg1,"kill_Infantry",arg2) - elseif Perun.GetCategory(arg5) == "Fortification" then - Perun.LogStatsCount(arg1,"kill_Fortification",arg2) - else - Perun.LogStatsCount(arg1,"kill_Other",arg2) - end - if net.get_player_info(arg4, "name") ~= nil and arg3 ~= arg6 then - Perun.LogStatsCount(arg1,"kill_PvP",arg2) + + _temp_event_type="" + if arg3 ~= arg6 then + if Perun.GetCategory(arg5) == "Planes" then + _temp_event_type="kill_Planes" + elseif Perun.GetCategory(arg5) == "Helicopters" then + _temp_event_type="kill_Helicopters" + elseif Perun.GetCategory(arg5) == "Ships" then + _temp_event_type="kill_Ships" + elseif Perun.GetCategory(arg5) == "Air Defence" then + _temp_event_type="kill_Air_Defence" + elseif Perun.GetCategory(arg5) == "Unarmed" then + _temp_event_type="kill_Unarmed" + elseif Perun.GetCategory(arg5) == "Armor" then + _temp_event_type="kill_Armor" + elseif Perun.GetCategory(arg5) == "Infantry" then + _temp_event_type="kill_Infantry" + elseif Perun.GetCategory(arg5) == "Fortification" then + _temp_event_type="kill_Fortification" + else + _temp_event_type="kill_Other" + end + if net.get_player_info(arg4, "name") ~= nil and arg3 ~= arg6 then + pilots_accounted = Perun.CheckMulticrew(arg1,arg2) + for _, pilotID in ipairs(pilots_accounted) do + Perun.LogStatsCount(pilotID,"kill_PvP",DCS.getUnitType(arg2)); + end + end + else + _temp_event_type="friendly_fire" end - if arg3 == arg6 then - Perun.LogStatsCount(arg1,"friendly_fire",arg2) + pilots_accounted = Perun.CheckMulticrew(arg1,arg2) + for _, pilotID in ipairs(pilots_accounted) do + Perun.LogStatsCount(pilotID,_temp_event_type,DCS.getUnitType(arg2)); end else @@ -642,12 +689,20 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) elseif eventName == "crash" then --"crash", playerID, unit_missionID Perun.LogEvent(eventName, Perun.SideID2Name( net.get_player_info(arg1, "side")) .. " player " .. net.get_player_info(arg1, "name") .. " crashed in " .. DCS.getUnitType(arg2),nil,nil); - Perun.LogStatsCount(arg1,"crash",DCS.getUnitType(arg2)) + + pilots_accounted = Perun.CheckMulticrew(arg1,DCS.getUnitType(arg2)) + for _, pilotID in ipairs(pilots_accounted) do + Perun.LogStatsCount(pilotID,"crash",DCS.getUnitType(arg2)); + end elseif eventName == "eject" then --"eject", playerID, unit_missionID Perun.LogEvent(eventName, Perun.SideID2Name( net.get_player_info(arg1, "side")) .. " player " .. net.get_player_info(arg1, "name") .. " ejected " .. DCS.getUnitType(arg2),nil,nil); - Perun.LogStatsCount(arg1,"eject",DCS.getUnitType(arg2)); - + + pilots_accounted = Perun.CheckMulticrew(arg1,DCS.getUnitType(arg2)) + for _, pilotID in ipairs(pilots_accounted) do + Perun.LogStatsCount(pilotID,"eject",DCS.getUnitType(arg2)); + end + elseif eventName == "takeoff" then --"takeoff", playerID, unit_missionID, airdromeName if arg3 ~= "" then @@ -658,14 +713,20 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) Perun.LogEvent(eventName, Perun.SideID2Name( net.get_player_info(arg1, "side")) .. " player " .. net.get_player_info(arg1, "name") .. " took off in ".. DCS.getUnitType(arg2) .. _temp,arg3,nil); + _type = "" if string.find(arg3, "FARP",1,true) then - Perun.LogStatsCount(arg1,"tookoff_FARP",DCS.getUnitType(arg2)) + _type="tookoff_FARP" elseif string.find(arg3, "CVN-74 John C. Stennis",1,true) or string.find(arg3, "LHA-1 Tarawa",1,true) then - Perun.LogStatsCount(arg1,"tookoff_SHIP",DCS.getUnitType(arg2)) + _type="tookoff_SHIP" elseif arg3 ~= "" then - Perun.LogStatsCount(arg1,"tookoff_AIRFIELD",DCS.getUnitType(arg2)) + _type="tookoff_AIRFIELD" else - Perun.LogStatsCount(arg1,"tookoff_OTHER",DCS.getUnitType(arg2)) + _type="tookoff_OTHER" + end + + pilots_accounted = Perun.CheckMulticrew(arg1,DCS.getUnitType(arg2)) + for _, pilotID in ipairs(pilots_accounted) do + Perun.LogStatsCount(pilotID,_type,DCS.getUnitType(arg2)) end elseif eventName == "landing" then @@ -678,20 +739,31 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) Perun.LogEvent(eventName, Perun.SideID2Name( net.get_player_info(arg1, "side")) .. " player " .. net.get_player_info(arg1, "name") .. " landed in " .. DCS.getUnitType(arg2).. _temp,arg3,nil); + _type = "" if string.find(arg3, "FARP",1,true) then - Perun.LogStatsCount(arg1,"landing_FARP",DCS.getUnitType(arg2)) + _type = "landing_FARP" elseif string.find(arg3, "CVN-74 John C. Stennis",1,true) or string.find(arg3, "LHA-1 Tarawa",1,true) then - Perun.LogStatsCount(arg1,"landing_SHIP",DCS.getUnitType(arg2)) + _type = "landing_SHIP" elseif arg3 ~= "" then - Perun.LogStatsCount(arg1,"landing_AIRFIELD",DCS.getUnitType(arg2)) + _type = "landing_AIRFIELD" else - Perun.LogStatsCount(arg1,"landing_OTHER",DCS.getUnitType(arg2)) + _type = "landing_OTHER" + end + + pilots_accounted = Perun.CheckMulticrew(arg1,DCS.getUnitType(arg2)) + for _, pilotID in ipairs(pilots_accounted) do + Perun.LogStatsCount(pilotID,_type,DCS.getUnitType(arg2)) end elseif eventName == "pilot_death" then --"pilot_death", playerID, unit_missionID Perun.LogEvent(eventName, Perun.SideID2Name( net.get_player_info(arg1, "side")) .. " player " .. net.get_player_info(arg1, "name") .. " in " .. DCS.getUnitType(arg2) .. " died",nil,nil); - Perun.LogStatsCount(arg1,"pilot_death",DCS.getUnitType(arg2)) + + pilots_accounted = Perun.CheckMulticrew(arg1,DCS.getUnitType(arg2)) + for _, pilotID in ipairs(pilots_accounted) do + Perun.LogStatsCount(pilotID,"pilot_death",DCS.getUnitType(arg2)) + end + else Perun.LogEvent(eventName,"Unknown event type",nil,nil); end From ab86b3bcec188b7505f0aa55935cf02836240489 Mon Sep 17 00:00:00 2001 From: szporowolik Date: Tue, 22 Oct 2019 14:48:21 +0200 Subject: [PATCH 18/23] Fixed mysql error couter --- 02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs index 919d68d..883ecdd 100644 --- a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs +++ b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs @@ -161,6 +161,7 @@ public class DatabaseController PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - error: " + m_ex.Message,1,1, strTCPFrameType); break; } + Globals.intGameErros++; bStatus = false; } connMySQL.Close(); From a78ad87312ccbf7b0f58b67728f8960aff7b60c7 Mon Sep 17 00:00:00 2001 From: szporowolik Date: Tue, 22 Oct 2019 15:12:07 +0200 Subject: [PATCH 19/23] Improved MySQL connection status; performane improvment --- .../Perun_v1/01_Classes/DatabaseController.cs | 19 ++++++++++++++----- .../Perun_v1/01_Classes/PerunHelper.cs | 6 +++--- 02_Windows_App/Perun_v1/02_Forms/form_Main.cs | 7 ++++++- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs index 883ecdd..5b2fd0e 100644 --- a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs +++ b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs @@ -9,9 +9,13 @@ public class DatabaseController public MySqlConnection connMySQL; public bool bStatus; - public void SendToMySql(string strRawTCPFrame) + public void SendToMySql(string strRawTCPFrame, bool bCheckConnection = false) { // Main function to send data to mysql + if (bCheckConnection) + { + strRawTCPFrame = "{\"type\": \"-1\"}"; + } dynamic strTCPFrame = JsonConvert.DeserializeObject(strRawTCPFrame); // Deserialize raw data string strTCPFrameType = strTCPFrame.type; string strTCPFrameTimestamp = strTCPFrame.timestamp; @@ -76,6 +80,11 @@ public class DatabaseController strSQLQueryTxt += "UPDATE `pe_DataPlayers` SET pe_DataPlayers_lastip='" + strTCPFrame.payload.login_ipaddr + "', pe_DataPlayers_lastname='" + strTCPFrame.payload.login_name + "',pe_DataPlayers_updated='" + strTCPFrame.payload.login_datetime + "' WHERE `pe_DataPlayers_ucid`= '" + strTCPFrame.payload.login_ucid + "';"; strSQLQueryTxt += "INSERT INTO `pe_LogLogins` (`pe_LogLogins_datetime`, `pe_LogLogins_playerid`, `pe_LogLogins_name`, `pe_LogLogins_ip`,`pe_LogLogins_instance`) VALUES ('" + strTCPFrame.payload.login_datetime + "', (SELECT pe_DataPlayers_id from pe_DataPlayers WHERE pe_DataPlayers_ucid = '" + strTCPFrame.payload.login_ucid + "'), '" + strTCPFrame.payload.login_name + "', '" + strTCPFrame.payload.login_ipaddr + "','" + strTCPFrameInstance + "');"; } + else if (strTCPFrameType == "-1") + { + // keep alibe + strSQLQueryTxt = "SELECT 1;"; + } else { // General definition used for 1-10 type packets @@ -98,10 +107,6 @@ public class DatabaseController MySqlCommand cmdMySQL = new MySqlCommand(strSQLQueryTxt, connMySQL); MySqlDataReader rdrMySQL = cmdMySQL.ExecuteReader(); - while (rdrMySQL.Read()) - { - Console.WriteLine(rdrMySQL[0] + " -- " + rdrMySQL[1]); - } rdrMySQL.Close(); switch (Int32.Parse(strTCPFrameType)) { @@ -132,6 +137,8 @@ public class DatabaseController case 101: PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "LotATC data send", 1,0,"101"); break; + case -1: + break; default: PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Data send", 1,0, strTCPFrameType); break; @@ -143,6 +150,7 @@ public class DatabaseController // General exception found Console.WriteLine(a_ex.ToString()); PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - error: " + a_ex.Message,1,1, strTCPFrameType); + Globals.intGameErros++; bStatus = false; } catch (MySqlException m_ex) @@ -158,6 +166,7 @@ public class DatabaseController break; default: PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - error id: " + m_ex.Number,1,1, strTCPFrameType); + PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - query: " + strSQLQueryTxt, 1, 1, strTCPFrameType); PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - error: " + m_ex.Message,1,1, strTCPFrameType); break; } diff --git a/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs b/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs index a83e4a8..e97b659 100644 --- a/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs +++ b/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs @@ -42,12 +42,12 @@ internal class PerunHelper // Add new entry arrLogHistory[arrLogHistory.Length - 1] = DateTime.Now.ToString("HH:mm:ss") + " " + strDirection + " " + strEntryToAdd; // Add entry at the last position + + // Update control at my window + Globals.bGUILogHistoryUpdate = true; } // Add the entry to log file LogController.WriteLog(DateTime.Now.ToString("yyyy-dd-MM ") + " " + DateTime.Now.ToString("HH:mm:ss") + " | Instance: "+ Globals.intInstanceId + " | " + strMarker + " | "+ strDirection + " | "+ strType + " | " + strEntryToAdd); - - // Update control at my window - Globals.bGUILogHistoryUpdate = true; } public static string GetAppVersion(string strBeginning) { diff --git a/02_Windows_App/Perun_v1/02_Forms/form_Main.cs b/02_Windows_App/Perun_v1/02_Forms/form_Main.cs index af0b841..32f9157 100644 --- a/02_Windows_App/Perun_v1/02_Forms/form_Main.cs +++ b/02_Windows_App/Perun_v1/02_Forms/form_Main.cs @@ -478,7 +478,12 @@ namespace Perun_v1 private void tim_3rdparties_Tick(object sender, EventArgs e) { - // Main timer to send JSON files to MySQL + // Main timer to check MySQL connection and send JSON files to MySQL + + // Send ping to check for possible connection issues + dcConnection.SendToMySql("", true); + + // Take care of 3rd party stuff string strSRSJson = ""; string strLotATCJson = ""; From 53aade262e74264823152f11fde24af4e4738a2f Mon Sep 17 00:00:00 2001 From: szporowolik Date: Tue, 22 Oct 2019 16:13:12 +0200 Subject: [PATCH 20/23] Code cleanup --- .../Perun_v1/01_Classes/DatabaseController.cs | 160 +++++++-------- 02_Windows_App/Perun_v1/01_Classes/Globals.cs | 2 +- .../Perun_v1/01_Classes/LogController.cs | 32 +-- .../Perun_v1/01_Classes/PerunHelper.cs | 31 ++- .../Perun_v1/01_Classes/TCPController.cs | 6 + .../Perun_v1/02_Forms/form_Main.Designer.cs | 1 - 02_Windows_App/Perun_v1/02_Forms/form_Main.cs | 183 +++++++++--------- 02_Windows_App/Perun_v1/Perun_v1.csproj | 3 + 8 files changed, 207 insertions(+), 211 deletions(-) diff --git a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs index 5b2fd0e..4733bd1 100644 --- a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs +++ b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs @@ -5,142 +5,142 @@ using System; public class DatabaseController { - public string strMySQLConnectionString; // MySQL connection string - public MySqlConnection connMySQL; - public bool bStatus; + public string DatabaseConnectionString; // MySQL connection string + public MySqlConnection DatabaseConnection; + public bool DatabaseStatus; - public void SendToMySql(string strRawTCPFrame, bool bCheckConnection = false) + public int SendToMySql(string RawTCPFrame, bool CheckConnection = false) { // Main function to send data to mysql - if (bCheckConnection) + if (CheckConnection) { - strRawTCPFrame = "{\"type\": \"-1\"}"; + RawTCPFrame = "{\"type\": \"-1\"}"; } - dynamic strTCPFrame = JsonConvert.DeserializeObject(strRawTCPFrame); // Deserialize raw data - string strTCPFrameType = strTCPFrame.type; - string strTCPFrameTimestamp = strTCPFrame.timestamp; - string strTCPFrameInstance = strTCPFrame.instance; - string strTCPFramePayload; - string strTCPFramePayload_Perun; - string strSQLQueryTxt; - + dynamic TCPFrame = JsonConvert.DeserializeObject(RawTCPFrame); // Deserialize raw data + string TCPFrameType = TCPFrame.type; + string TCPFrameTimestamp = TCPFrame.timestamp; + string TCPFrameInstance = TCPFrame.instance; + string TCPFramePayload; + string TCPFramePayload_Perun; + string SQLQueryTxt; + int ReturnValue = 1; // Some frames may come without timestamp, use database currrent timestampe then - if (strTCPFrameTimestamp != null) + if (TCPFrameTimestamp != null) { - strTCPFrameTimestamp = "'" + strTCPFrameTimestamp + "'"; + TCPFrameTimestamp = "'" + TCPFrameTimestamp + "'"; } else { - strTCPFrameTimestamp = "CURRENT_TIMESTAMP()"; + TCPFrameTimestamp = "CURRENT_TIMESTAMP()"; } // Modify specific types - if (strTCPFrameType == "1") + if (TCPFrameType == "1") { - strTCPFrame.payload["v_win"] = "v" + Globals.strPerunVersion; // Inject app version information + TCPFrame.payload["v_win"] = "v" + Globals.strPerunVersion; // Inject app version information } // Specific SQL per each frame type - if (strTCPFrameType == "50") + if (TCPFrameType == "50") { // Add entry to chat log - strSQLQueryTxt = "INSERT INTO `pe_DataPlayers` (`pe_DataPlayers_ucid`) SELECT '" + strTCPFrame.payload.ucid + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataPlayers` where `pe_DataPlayers_ucid` = '" + strTCPFrame.payload.ucid + "' );"; - strSQLQueryTxt += "UPDATE `pe_DataPlayers` SET `pe_DataPlayers_updated` = " + strTCPFrameTimestamp + ",`pe_DataPlayers_lastname`='" + strTCPFrame.payload.player + "' WHERE `pe_DataPlayers_ucid`='" + strTCPFrame.payload.ucid + "' ;"; - strSQLQueryTxt += "INSERT INTO `pe_DataMissionHashes` (`pe_DataMissionHashes_hash`,`pe_DataMissionHashes_instance`) SELECT '" + strTCPFrame.payload.missionhash + "','" + strTCPFrameInstance + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataMissionHashes` where `pe_DataMissionHashes_hash` ='" + strTCPFrame.payload.missionhash + "' AND `pe_DataMissionHashes_instance`=" + strTCPFrameInstance + ");"; - strSQLQueryTxt += "UPDATE `pe_DataMissionHashes` SET `pe_DataMissionHashes_datetime` = " + strTCPFrameTimestamp + " WHERE `pe_DataMissionHashes_hash` = '" + strTCPFrame.payload.missionhash + "' AND `pe_DataMissionHashes_instance`=" + strTCPFrameInstance + " ;"; - strSQLQueryTxt += "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,'" + strTCPFrame.payload.datetime + "', (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + strTCPFrame.payload.ucid + "'), '" + strTCPFrame.payload.msg + "', '" + strTCPFrame.payload.all + "',(SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + strTCPFrame.payload.missionhash + "'));"; + 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`='" + TCPFrame.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 + "'), '" + TCPFrame.payload.msg + "', '" + TCPFrame.payload.all + "',(SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.missionhash + "'));"; } - else if (strTCPFrameType == "51") + else if (TCPFrameType == "51") { // Add entry to event log - strSQLQueryTxt = "INSERT INTO `pe_DataMissionHashes` (`pe_DataMissionHashes_hash`,`pe_DataMissionHashes_instance`) SELECT '" + strTCPFrame.payload.log_missionhash + "','" + strTCPFrameInstance + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataMissionHashes` where `pe_DataMissionHashes_hash` = '" + strTCPFrame.payload.log_missionhash + "' AND `pe_DataMissionHashes_instance`=" + strTCPFrameInstance + ");"; - strSQLQueryTxt += "UPDATE `pe_DataMissionHashes` SET `pe_DataMissionHashes_datetime` = " + strTCPFrameTimestamp + " WHERE `pe_DataMissionHashes_hash` = '" + strTCPFrame.payload.log_missionhash + "' AND `pe_DataMissionHashes_instance`=" + strTCPFrameInstance + ";"; - strSQLQueryTxt += "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 ('" + strTCPFrame.payload.log_arg_1 + "','" + strTCPFrame.payload.log_arg_2 + "', NULL, '" + strTCPFrame.payload.log_datetime + "', '" + strTCPFrame.payload.log_type + "', '" + strTCPFrame.payload.log_content + "', (SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + strTCPFrame.payload.log_missionhash + "'));"; + 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 + "', '" + TCPFrame.payload.log_content + "', (SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.log_missionhash + "'));"; } - else if (strTCPFrameType == "52") + else if (TCPFrameType == "52") { // Update user stats - strTCPFramePayload = JsonConvert.SerializeObject(strTCPFrame.payload.stat_data_dcs); // Deserialize payload - strTCPFramePayload_Perun = JsonConvert.SerializeObject(strTCPFrame.payload.stat_data_perun); // Deserialize payload + TCPFramePayload = JsonConvert.SerializeObject(TCPFrame.payload.stat_data_dcs); // Deserialize payload + TCPFramePayload_Perun = JsonConvert.SerializeObject(TCPFrame.payload.stat_data_perun); // Deserialize payload - strSQLQueryTxt = "INSERT INTO `pe_DataMissionHashes` (`pe_DataMissionHashes_hash`,`pe_DataMissionHashes_instance`) SELECT '" + strTCPFrame.payload.stat_missionhash + "','" + strTCPFrameInstance + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataMissionHashes` where `pe_DataMissionHashes_hash` = '" + strTCPFrame.payload.stat_missionhash + "' AND `pe_DataMissionHashes_instance`=" + strTCPFrameInstance + ");"; - strSQLQueryTxt += "UPDATE `pe_DataMissionHashes` SET `pe_DataMissionHashes_datetime` = " + strTCPFrameTimestamp + " WHERE `pe_DataMissionHashes_hash` = '" + strTCPFrame.payload.stat_missionhash + "' AND `pe_DataMissionHashes_instance`=" + strTCPFrameInstance + " ;"; - strSQLQueryTxt += "INSERT INTO `pe_DataPlayers` (`pe_DataPlayers_ucid`) SELECT '" + strTCPFrame.payload.stat_ucid + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataPlayers` where `pe_DataPlayers_ucid` = '" + strTCPFrame.payload.stat_ucid + "');"; - strSQLQueryTxt += "UPDATE `pe_DataPlayers` SET `pe_DataPlayers_updated`=" + strTCPFrameTimestamp + " WHERE `pe_DataPlayers_ucid`='" + strTCPFrame.payload.stat_ucid + "';"; - strSQLQueryTxt += "INSERT INTO `pe_DataTypes` (`pe_DataTypes_name`) SELECT '" + strTCPFrame.payload.stat_data_type + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataTypes` where `pe_DataTypes_name` = '" + strTCPFrame.payload.stat_data_type + "');"; - strSQLQueryTxt += "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` = '" + strTCPFrame.payload.stat_ucid + "'), (SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + strTCPFrame.payload.stat_missionhash + "'), (SELECT pe_DataTypes_id FROM `pe_DataTypes` where `pe_DataTypes_name` = '" + strTCPFrame.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` = '" + strTCPFrame.payload.stat_missionhash + "') AND `pe_LogStats_playerid` = (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + strTCPFrame.payload.stat_ucid + "') AND `pe_LogStats_typeid`= (SELECT pe_DataTypes_id FROM `pe_DataTypes` where `pe_DataTypes_name` = '" + strTCPFrame.payload.stat_data_type + "'));"; - strSQLQueryTxt += "UPDATE `pe_LogStats` SET `ps_kills_fortification`=" + strTCPFrame.payload.stat_data_perun.ps_kills_fortification + ",`ps_other_landings`=" + strTCPFrame.payload.stat_data_perun.ps_other_landings + ",`ps_other_takeoffs`=" + strTCPFrame.payload.stat_data_perun.ps_other_takeoffs + ",`ps_pvp`=" + strTCPFrame.payload.stat_data_perun.ps_pvp + ",`ps_deaths`=" + strTCPFrame.payload.stat_data_perun.ps_deaths + ",`ps_ejections`=" + strTCPFrame.payload.stat_data_perun.ps_ejections + ",`ps_crashes`=" + strTCPFrame.payload.stat_data_perun.ps_crashes + ",`ps_teamkills`=" + strTCPFrame.payload.stat_data_perun.ps_teamkills + ",`ps_kills_planes`=" + strTCPFrame.payload.stat_data_perun.ps_kills_planes + ",`ps_kills_helicopters`=" + strTCPFrame.payload.stat_data_perun.ps_kills_helicopters + ",`ps_kills_air_defense`=" + strTCPFrame.payload.stat_data_perun.ps_kills_air_defense + ",`ps_kills_armor`=" + strTCPFrame.payload.stat_data_perun.ps_kills_armor + ",`ps_kills_unarmed`=" + strTCPFrame.payload.stat_data_perun.ps_kills_unarmed + ",`ps_kills_infantry`=" + strTCPFrame.payload.stat_data_perun.ps_kills_infantry + ",`ps_kills_ships`=" + strTCPFrame.payload.stat_data_perun.ps_kills_ships + ",`ps_kills_other`=" + strTCPFrame.payload.stat_data_perun.ps_kills_other + ",`ps_airfield_takeoffs`=" + strTCPFrame.payload.stat_data_perun.ps_airfield_takeoffs + ",`ps_airfield_landings`=" + strTCPFrame.payload.stat_data_perun.ps_airfield_landings + ",`ps_ship_takeoffs`=" + strTCPFrame.payload.stat_data_perun.ps_ship_takeoffs + ",`ps_ship_landings`=" + strTCPFrame.payload.stat_data_perun.ps_ship_landings + ",`ps_farp_takeoffs`=" + strTCPFrame.payload.stat_data_perun.ps_farp_takeoffs + ",`ps_farp_landings`=" + strTCPFrame.payload.stat_data_perun.ps_farp_landings + ", `pe_LogStats_datetime`='" + strTCPFrame.payload.stat_datetime + "',`pe_LogStats_playerid` = (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + strTCPFrame.payload.stat_ucid + "'),`pe_LogStats_missionhash_id`=(SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + strTCPFrame.payload.stat_missionhash + "') WHERE `pe_LogStats_missionhash_id`=(SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + strTCPFrame.payload.stat_missionhash + "') AND `pe_LogStats_playerid` = (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + strTCPFrame.payload.stat_ucid + "') AND `pe_LogStats_typeid`=(SELECT pe_DataTypes_id FROM `pe_DataTypes` where `pe_DataTypes_name` = '" + strTCPFrame.payload.stat_data_type + "');"; + 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_kills_fortification`=" + TCPFrame.payload.stat_data_perun.ps_kills_fortification + ",`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 (strTCPFrameType == "53") + else if (TCPFrameType == "53") { // User logged in to DCS server - strSQLQueryTxt = "INSERT INTO `pe_DataPlayers` (`pe_DataPlayers_ucid`) SELECT '" + strTCPFrame.payload.login_ucid + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataPlayers` where pe_DataPlayers_ucid='" + strTCPFrame.payload.login_ucid + "');"; - strSQLQueryTxt += "UPDATE `pe_DataPlayers` SET pe_DataPlayers_lastip='" + strTCPFrame.payload.login_ipaddr + "', pe_DataPlayers_lastname='" + strTCPFrame.payload.login_name + "',pe_DataPlayers_updated='" + strTCPFrame.payload.login_datetime + "' WHERE `pe_DataPlayers_ucid`= '" + strTCPFrame.payload.login_ucid + "';"; - strSQLQueryTxt += "INSERT INTO `pe_LogLogins` (`pe_LogLogins_datetime`, `pe_LogLogins_playerid`, `pe_LogLogins_name`, `pe_LogLogins_ip`,`pe_LogLogins_instance`) VALUES ('" + strTCPFrame.payload.login_datetime + "', (SELECT pe_DataPlayers_id from pe_DataPlayers WHERE pe_DataPlayers_ucid = '" + strTCPFrame.payload.login_ucid + "'), '" + strTCPFrame.payload.login_name + "', '" + strTCPFrame.payload.login_ipaddr + "','" + strTCPFrameInstance + "');"; + 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='" + TCPFrame.payload.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 + "'), '" + TCPFrame.payload.login_name + "', '" + TCPFrame.payload.login_ipaddr + "','" + TCPFrameInstance + "');"; } - else if (strTCPFrameType == "-1") + else if (TCPFrameType == "-1") { - // keep alibe - strSQLQueryTxt = "SELECT 1;"; + // Keep alive message + SQLQueryTxt = "SELECT 1;"; } else { // General definition used for 1-10 type packets - strTCPFramePayload = JsonConvert.SerializeObject(strTCPFrame.payload); // Deserialize payload + TCPFramePayload = JsonConvert.SerializeObject(TCPFrame.payload); // Deserialize payload - strSQLQueryTxt = "INSERT INTO `pe_DataRaw` (`pe_dataraw_type`,`pe_dataraw_instance`) SELECT '" + strTCPFrameType + "','" + strTCPFrameInstance + "' FROM DUAL WHERE NOT EXISTS (SELECT * FROM `pe_DataRaw` WHERE `pe_dataraw_type` = '" + strTCPFrameType + "' AND `pe_dataraw_instance` = " + strTCPFrameInstance + ");"; - strSQLQueryTxt += "UPDATE `pe_DataRaw` SET `pe_dataraw_payload` = JSON_QUOTE('" + strTCPFramePayload + "'), `pe_dataraw_updated`=" + strTCPFrameTimestamp + " WHERE `pe_dataraw_type`=" + strTCPFrameType + " AND `pe_dataraw_instance` = " + strTCPFrameInstance + ";"; + 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` = JSON_QUOTE('" + TCPFramePayload + "'), `pe_dataraw_updated`=" + TCPFrameTimestamp + " WHERE `pe_dataraw_type`=" + TCPFrameType + " AND `pe_dataraw_instance` = " + TCPFrameInstance + ";"; } // Connect to mysql and execute sql try { - connMySQL = new MySqlConnection(strMySQLConnectionString); + DatabaseConnection = new MySqlConnection(DatabaseConnectionString); try { Console.WriteLine("Sending data to MySQL - Begin"); - connMySQL.Open(); - bStatus = true; - MySqlCommand cmdMySQL = new MySqlCommand(strSQLQueryTxt, connMySQL); - MySqlDataReader rdrMySQL = cmdMySQL.ExecuteReader(); - - rdrMySQL.Close(); - switch (Int32.Parse(strTCPFrameType)) + DatabaseConnection.Open(); + DatabaseStatus = true; + MySqlCommand DatabaseCommand = new MySqlCommand(SQLQueryTxt, DatabaseConnection); + MySqlDataReader DatabaseReader = DatabaseCommand.ExecuteReader(); + DatabaseReader.Close(); + + switch (Int32.Parse(TCPFrameType)) { case 1: - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Connected players: " + strTCPFrame.payload["c_players"], 1,0,"1"); + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "Connected players: " + TCPFrame.payload["c_players"], 1,0,"1"); break; case 2: - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Mission: \"" + strTCPFrame.payload["mission"]["name"]+"\""+ ", time:" + strTCPFrame.payload["mission"]["modeltime"], 1, 0, "2"); + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "Mission: \"" + TCPFrame.payload["mission"]["name"]+"\""+ ", time:" + TCPFrame.payload["mission"]["modeltime"], 1, 0, "2"); break; case 3: - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Slots data updated", 1, 0, "3"); + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "Slots data updated", 1, 0, "3"); break; case 50: - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Player's \""+ strTCPFrame.payload.player + "\" chat message saved", 1, 0, "50"); + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "Player's \""+ TCPFrame.payload.player + "\" chat message saved", 1, 0, "50"); break; case 51: - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Game event: \""+ strTCPFrame.payload.log_content +"\"", 1, 0, "51"); + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "Game event: \""+ TCPFrame.payload.log_content +"\"", 1, 0, "51"); break; case 52: - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Player's \""+ strTCPFrame.payload.stat_name + "\" stats saved", 1, 0, "52"); + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "Player's \""+ TCPFrame.payload.stat_name + "\" stats saved", 1, 0, "52"); break; case 53: - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Player \""+ strTCPFrame.payload.login_name + "\" logged in", 1, 0, "53"); + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "Player \""+ TCPFrame.payload.login_name + "\" logged in", 1, 0, "53"); break; case 100: - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "SRS data send", 1,0,"100"); + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "SRS data send", 1,0,"100"); break; case 101: - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "LotATC data send", 1,0,"101"); + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "LotATC data send", 1,0,"101"); break; case -1: break; default: - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Data send", 1,0, strTCPFrameType); + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "Data send", 1,0, TCPFrameType); break; } @@ -149,9 +149,10 @@ public class DatabaseController { // General exception found Console.WriteLine(a_ex.ToString()); - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - error: " + a_ex.Message,1,1, strTCPFrameType); + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "ERROR MySQL - error: " + a_ex.Message,1,1, TCPFrameType); Globals.intGameErros++; - bStatus = false; + DatabaseStatus = false; + ReturnValue = 0; } catch (MySqlException m_ex) { @@ -159,28 +160,31 @@ public class DatabaseController switch (m_ex.Number) { case 1042: // Unable to connect to any of the specified MySQL hosts (Check Server,Port) - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - unable to connect, error: " + m_ex.Message,1,1, strTCPFrameType); + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "ERROR MySQL - unable to connect, error: " + m_ex.Message,1,1, TCPFrameType); break; case 0: // Access denied (Check DB name,username,password) - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - access denied, error: " + m_ex.Message,1,1, strTCPFrameType); + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "ERROR MySQL - access denied, error: " + m_ex.Message,1,1, TCPFrameType); break; default: - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - error id: " + m_ex.Number,1,1, strTCPFrameType); - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - query: " + strSQLQueryTxt, 1, 1, strTCPFrameType); - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - error: " + m_ex.Message,1,1, strTCPFrameType); + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "ERROR MySQL - error id: " + m_ex.Number,1,1, TCPFrameType); + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "ERROR MySQL - query: " + SQLQueryTxt, 1, 1, TCPFrameType); + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "ERROR MySQL - error: " + m_ex.Message,1,1, TCPFrameType); break; } Globals.intGameErros++; - bStatus = false; + DatabaseStatus = false; + ReturnValue = 0; } - connMySQL.Close(); + DatabaseConnection.Close(); Console.WriteLine("Sending data to MySQL - Done"); } catch (ArgumentException x_ex) { - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "ERROR MySQL - unable to connect, error: " + x_ex.Message,1,1, strTCPFrameType); + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "ERROR MySQL - unable to connect, error: " + x_ex.Message,1,1, TCPFrameType); + ReturnValue = 0; + Globals.intGameErros++; } - + return ReturnValue; } } diff --git a/02_Windows_App/Perun_v1/01_Classes/Globals.cs b/02_Windows_App/Perun_v1/01_Classes/Globals.cs index 9ec565d..1553d30 100644 --- a/02_Windows_App/Perun_v1/01_Classes/Globals.cs +++ b/02_Windows_App/Perun_v1/01_Classes/Globals.cs @@ -3,7 +3,7 @@ internal class Globals { public static string strPerunVersion = "DEBUG"; // Helper for pulling version definition - public static string[] arrGUILogHistory = new string[10]; // Log history for GUI + public static string[] AppLogHistory = new string[10]; // Log history for GUI public static bool bGUILogHistoryUpdate = true; // Flag if log control requires update public static string strPerunTitleText = ""; // Helper to update title public static int intInstanceId = 0; // Kepp the instance ID diff --git a/02_Windows_App/Perun_v1/01_Classes/LogController.cs b/02_Windows_App/Perun_v1/01_Classes/LogController.cs index 709bf46..98b2a5a 100644 --- a/02_Windows_App/Perun_v1/01_Classes/LogController.cs +++ b/02_Windows_App/Perun_v1/01_Classes/LogController.cs @@ -6,36 +6,36 @@ class LogController // TBD - done via https://stackoverflow.com/questions/20185015/how-to-write-log-file-in-c public static void WriteLog(string strLog) { - StreamWriter log; - FileStream fileStream = null; - DirectoryInfo logDirInfo = null; - FileInfo logFileInfo; + StreamWriter LogStreamWriter; + FileStream LogFileStream = null; + DirectoryInfo LogDirectoryInfo = null; + FileInfo LogFileInfo; - string logFilePath = Path.Combine(Environment.ExpandEnvironmentVariables("%userprofile%"), "Documents") + "\\Perun\\"; - logFilePath = logFilePath + "Perun_Log_" + System.DateTime.Today.ToString("yyyyddMM") + "." + "txt"; - logFileInfo = new FileInfo(logFilePath); - logDirInfo = new DirectoryInfo(logFileInfo.DirectoryName); - if (!logDirInfo.Exists) logDirInfo.Create(); - if (!logFileInfo.Exists) + string LogFilePath = Path.Combine(Environment.ExpandEnvironmentVariables("%userprofile%"), "Documents") + "\\Perun\\"; + LogFilePath = LogFilePath + "Perun_Log_" + System.DateTime.Today.ToString("yyyyddMM") + "." + "txt"; + LogFileInfo = new FileInfo(LogFilePath); + LogDirectoryInfo = new DirectoryInfo(LogFileInfo.DirectoryName); + if (!LogDirectoryInfo.Exists) LogDirectoryInfo.Create(); + if (!LogFileInfo.Exists) { - fileStream = logFileInfo.Create(); + LogFileStream = LogFileInfo.Create(); } else { try { - fileStream = new FileStream(logFilePath, FileMode.Append); + LogFileStream = new FileStream(LogFilePath, FileMode.Append); } catch { - // Do nothing + // Do nothing } } try { - log = new StreamWriter(fileStream); - log.WriteLine(strLog); - log.Close(); + LogStreamWriter = new StreamWriter(LogFileStream); + LogStreamWriter.WriteLine(strLog); + LogStreamWriter.Close(); } catch { diff --git a/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs b/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs index e97b659..6f3a56b 100644 --- a/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs +++ b/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs @@ -7,27 +7,27 @@ internal class PerunHelper public static void GUILogHistoryAdd(ref string[] arrLogHistory, string strEntryToAdd, int intDirection = 0, int intMarker = 0, string strType = " ", bool bSkipGui = false) { // Declare values - string strDirection; - string strMarker; + string LogDirection; + string LogMarker; // Set direction marker switch (intDirection) { case 1: - strDirection = ">"; + LogDirection = ">"; break; case 2: - strDirection = "<"; + LogDirection = "<"; break; case 3: - strDirection = "^"; + LogDirection = "^"; break; default: - strDirection = " "; + LogDirection = " "; break; } // Set marker for user flags (markers) - strMarker = (intMarker>0) ? "X" : " "; + LogMarker = (intMarker>0) ? "X" : " "; // Set frame type strType=strType.PadLeft(3, ' '); @@ -41,28 +41,19 @@ internal class PerunHelper } // Add new entry - arrLogHistory[arrLogHistory.Length - 1] = DateTime.Now.ToString("HH:mm:ss") + " " + strDirection + " " + strEntryToAdd; // Add entry at the last position + arrLogHistory[arrLogHistory.Length - 1] = DateTime.Now.ToString("HH:mm:ss") + " " + LogDirection + " " + strEntryToAdd; // Add entry at the last position // Update control at my window Globals.bGUILogHistoryUpdate = true; } // Add the entry to log file - LogController.WriteLog(DateTime.Now.ToString("yyyy-dd-MM ") + " " + DateTime.Now.ToString("HH:mm:ss") + " | Instance: "+ Globals.intInstanceId + " | " + strMarker + " | "+ strDirection + " | "+ strType + " | " + strEntryToAdd); + LogController.WriteLog(DateTime.Now.ToString("yyyy-dd-MM ") + " " + DateTime.Now.ToString("HH:mm:ss") + " | Instance: "+ Globals.intInstanceId + " | " + LogMarker + " | "+ LogDirection + " | "+ strType + " | " + strEntryToAdd); } + public static string GetAppVersion(string strBeginning) { // Gets build version - if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed) - { - // For network deployed - System.Deployment.Application.ApplicationDeployment cd = System.Deployment.Application.ApplicationDeployment.CurrentDeployment; - Globals.strPerunVersion = cd.CurrentVersion.ToString(); - } - else - { - // For other cases - Globals.strPerunVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); - } + Globals.strPerunVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); return strBeginning + "v" + Globals.strPerunVersion; } } \ No newline at end of file diff --git a/02_Windows_App/Perun_v1/01_Classes/TCPController.cs b/02_Windows_App/Perun_v1/01_Classes/TCPController.cs index 30dc13d..6b348e6 100644 --- a/02_Windows_App/Perun_v1/01_Classes/TCPController.cs +++ b/02_Windows_App/Perun_v1/01_Classes/TCPController.cs @@ -127,14 +127,20 @@ public class TCPController { // Add to mySQL send buffer (find first empty slot) PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "Packet received" , 2,0, strRawTCPFrameType,true); + bool AddedDataToBuffer = false; for (int i = 0; i < arrMySQLSendBuffer.Length - 1; i++) { if (arrMySQLSendBuffer[i] == null) { arrMySQLSendBuffer[i] = strReceivedData; + AddedDataToBuffer = true; break; } } + if (!AddedDataToBuffer) + { + PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "ERROR package was dropped", 1, 1, strRawTCPFrameType); + } } else { // Keep alive diff --git a/02_Windows_App/Perun_v1/02_Forms/form_Main.Designer.cs b/02_Windows_App/Perun_v1/02_Forms/form_Main.Designer.cs index 70436fe..b6aea20 100644 --- a/02_Windows_App/Perun_v1/02_Forms/form_Main.Designer.cs +++ b/02_Windows_App/Perun_v1/02_Forms/form_Main.Designer.cs @@ -98,7 +98,6 @@ this.con_List_Received.Name = "con_List_Received"; this.con_List_Received.Size = new System.Drawing.Size(307, 134); this.con_List_Received.TabIndex = 0; - this.con_List_Received.SelectedIndexChanged += new System.EventHandler(this.con_List_Received_SelectedIndexChanged); // // con_Button_Listen_ON // diff --git a/02_Windows_App/Perun_v1/02_Forms/form_Main.cs b/02_Windows_App/Perun_v1/02_Forms/form_Main.cs index 32f9157..c2fb6de 100644 --- a/02_Windows_App/Perun_v1/02_Forms/form_Main.cs +++ b/02_Windows_App/Perun_v1/02_Forms/form_Main.cs @@ -10,28 +10,26 @@ namespace Perun_v1 public partial class form_Main : Form { // Variable definitions - public string[] arrMySQLSendBuffer = new string[65534]; // MySQL send buffer - public bool bAllowAppClosure = false; // Helper to handle system tray + public string[] DatabaseSendBuffer = new string[50]; // MySQL send buffer + public bool AppCanClose = false; // Helper to handle system tray - true needed to quit the app - public DatabaseController dcConnection = new DatabaseController(); // MySQL controller - public TCPController tcpServer = new TCPController(); // TCP controller + public DatabaseController DatabaseConnection = new DatabaseController(); // Main MySQL controller + public TCPController TCPServer = new TCPController(); // Main TCP controller - public bool bSRSStatus; // Use empty/default SRS status - public bool bLotATCStatus; // Use empty/default LotATC status + public bool ExtSRSStatus; // True if to use empty/default SRS status + public bool ExtLotATCStatus; // True if to use empty/default LotATC status // ################################ Main ################################ private void form_Main_Load(object sender, EventArgs e) { - // Form loaded - fill controls with default values - Globals.arrGUILogHistory[0] = DateTime.Now.ToString("HH:mm:ss") + " > " + "Perun started"; + // 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.strPerunTitleText = PerunHelper.GetAppVersion(this.Text + " - "); this.Text = Globals.strPerunTitleText; - // Load settings from registry - form_Main_LoadSettings(); - // Use command line parameters string[] args = Environment.GetCommandLineArgs(); if (args.Length > 1) @@ -119,14 +117,14 @@ namespace Perun_v1 Properties.Settings.Default.Save(); } - private void form_Main_DisableControls() + private void form_Main_SetControlsToConnected() { // Disables controls - con_Button_Listen_ON.Enabled = false; + con_Button_Add_Marker.Enabled = true; con_Button_Listen_OFF.Enabled = true; + con_Button_Listen_ON.Enabled = false; con_Button_Quit.Enabled = false; con_Button_Reset_Flags.Enabled = true; - con_Button_Add_Marker.Enabled = true; con_txt_mysql_database.Enabled = false; con_txt_mysql_username.Enabled = false; con_txt_mysql_password.Enabled = false; @@ -140,13 +138,13 @@ namespace Perun_v1 con_txt_dcs_instance.Enabled = false; } - private void form_Main_EnableControls() + private void form_Main_SetControlsToDisconnected() { // Enables controls - con_Button_Listen_ON.Enabled = true; - con_Button_Listen_OFF.Enabled = false; - con_Button_Quit.Enabled = true; con_Button_Reset_Flags.Enabled = false; + con_Button_Listen_OFF.Enabled = false; + con_Button_Listen_ON.Enabled = true; + con_Button_Quit.Enabled = true; con_Button_Add_Marker.Enabled = false; con_txt_mysql_database.Enabled = true; con_txt_mysql_username.Enabled = true; @@ -169,29 +167,27 @@ namespace Perun_v1 // Set globals Globals.intInstanceId = Int32.Parse(con_txt_dcs_instance.Text); Globals.bStatusIconsForce = true; - Globals.intMysqlErros = 0; // Reset error counter Globals.intGameErros = 0; // Reset error counter Globals.intSRSErros = 0; // Reset error counter Globals.intLotATCErros = 0; // Reset error counter - Globals.bClientConnected = false; // Reset connection status // Prepare GUI - form_Main_DisableControls(); + form_Main_SetControlsToConnected(); form_Main_SaveSettings(); this.Text = "[#" + con_txt_dcs_instance.Text + "] " + Globals.strPerunTitleText; // Set title bar trayIconMain.Text = this.Text; // Set notification icon text // Prepare MySQL connection string - dcConnection.strMySQLConnectionString = "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; + 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.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Opening connections",0,1); - tcpServer.Create(Int32.Parse(con_txt_dcs_server_port.Text), ref Globals.arrGUILogHistory, ref arrMySQLSendBuffer); - tcpServer.thrTCPListener = new Thread(tcpServer.StartListen); - tcpServer.thrTCPListener.Start(); - tcpServer.thrTCPListener.Name = "TCPThread"; + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "Opening connections",0,1); + TCPServer.Create(Int32.Parse(con_txt_dcs_server_port.Text), ref Globals.AppLogHistory, ref DatabaseSendBuffer); + TCPServer.thrTCPListener = new Thread(TCPServer.StartListen); + TCPServer.thrTCPListener.Start(); + TCPServer.thrTCPListener.Name = "TCPThread"; // Start timmers tim_MySQL.Enabled = true; @@ -207,7 +203,7 @@ namespace Perun_v1 { // Stop listening // Prepare GUI - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Closing connections",0,1); + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "Closing connections",0,1); con_Button_Listen_OFF.Enabled = false; Tim_GUI_Tick(null, null); this.Refresh(); @@ -218,29 +214,32 @@ namespace Perun_v1 tim_3rdparties.Enabled = false; tim_MySQL.Enabled = false; - // Wait untill TCP server closed connection try { - tcpServer.StopListen(); + // Stop the server + TCPServer.StopListen(); } catch (Exception ex) { + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "TCP ERROR, error: " + ex.Message, 2, 1, "?"); Console.WriteLine(ex.ToString()); } - while (tcpServer.thrTCPListener.IsAlive) + while (TCPServer.thrTCPListener.IsAlive) { - Thread.Sleep(100); //ms + // Wait untill TCP server closed connection + Thread.Sleep(200); //ms } - form_Main_EnableControls(); // Enable controls + 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.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Connections closed",0,1); + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "Connections closed",0,1); Tim_GUI_Tick(null, null); // Set title bar @@ -249,8 +248,6 @@ namespace Perun_v1 // Set globals Globals.intInstanceId = 0; - - // Set helpers for updates Globals.bGUILogHistoryUpdate = false; Globals.bdcConnection = false; Globals.bTCPServer = false; @@ -299,13 +296,13 @@ namespace Perun_v1 // ################################ Form state ################################ private void con_Button_Quit_Click(object sender, EventArgs e) { - // Close app + // Try to close app DialogResult dialogResult = MessageBox.Show("Are you sure to exit Perun?", "Question", MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Question); if (dialogResult == DialogResult.Yes) { form_Main_SaveSettings(); - bAllowAppClosure = true; // Save settings on exit + AppCanClose = true; // Save settings on exit this.Close(); // Allow to exit application } else if (dialogResult == DialogResult.No) @@ -341,11 +338,10 @@ namespace Perun_v1 TopMost = top; } - private void form_Main_FormClosing(object sender, FormClosingEventArgs e) { // Minimize to try on clicking "X" - if (e.CloseReason == CloseReason.UserClosing && !bAllowAppClosure) + if (e.CloseReason == CloseReason.UserClosing && !AppCanClose) { e.Cancel = true; form_Main_SendToTray(); // Send app to system tray @@ -367,7 +363,7 @@ namespace Perun_v1 if (Globals.bGUILogHistoryUpdate) { con_List_Received.Items.Clear(); - foreach (string i in Globals.arrGUILogHistory) + foreach (string i in Globals.AppLogHistory) { if (i != null) { @@ -381,10 +377,10 @@ namespace Perun_v1 // Do nothing , control does not require update } - // Update status icons at main form - if ((dcConnection.bStatus != Globals.bdcConnection) || Globals.bStatusIconsForce) + // Update status icons at main form - MySQL + if ((DatabaseConnection.DatabaseStatus != Globals.bdcConnection) || Globals.bStatusIconsForce) { - if (dcConnection.bStatus) + if (DatabaseConnection.DatabaseStatus) { if (Globals.intMysqlErros == 0) { @@ -399,9 +395,9 @@ namespace Perun_v1 { con_img_db.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected_error"); } - Globals.bdcConnection = dcConnection.bStatus; + Globals.bdcConnection = DatabaseConnection.DatabaseStatus; } - + // Update status icons at main form - DCS if ((Globals.bClientConnected != Globals.bTCPServer) || Globals.bStatusIconsForce || Globals.intGameErros != Globals.intGameErrosHistory) { if (Globals.bClientConnected) @@ -422,9 +418,10 @@ namespace Perun_v1 Globals.bTCPServer = Globals.bClientConnected; Globals.intGameErrosHistory = Globals.intGameErros; } - if ((bSRSStatus != Globals.bSRSStatus) || Globals.bStatusIconsForce) + // Update status icons at main form - SRS + if ((ExtSRSStatus != Globals.bSRSStatus) || Globals.bStatusIconsForce) { - if (bSRSStatus && con_check_3rd_srs.Checked) + if (ExtSRSStatus && con_check_3rd_srs.Checked) { if (Globals.intSRSErros == 0) { @@ -439,11 +436,12 @@ namespace Perun_v1 { con_img_srs.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected_error"); } - Globals.bSRSStatus = bSRSStatus; + Globals.bSRSStatus = ExtSRSStatus; } - if ((bLotATCStatus != Globals.bLotATCStatus) || Globals.bStatusIconsForce) + // Update status icons at main form - LotATC + if ((ExtLotATCStatus != Globals.bLotATCStatus) || Globals.bStatusIconsForce) { - if (bLotATCStatus && con_check_3rd_lotatc.Checked) + if (ExtLotATCStatus && con_check_3rd_lotatc.Checked) { if (Globals.intLotATCErros == 0) { @@ -458,7 +456,7 @@ namespace Perun_v1 { con_img_lotATC.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected_error"); } - Globals.bLotATCStatus = bLotATCStatus; + Globals.bLotATCStatus = ExtLotATCStatus; } Globals.bStatusIconsForce = false; } @@ -466,12 +464,14 @@ namespace Perun_v1 private void Tim_MySQL_Tick(object sender, EventArgs e) { // Send buffer to MySQL - for (int i = 0; i < arrMySQLSendBuffer.Length - 1; i++) + for (int i = 0; i < DatabaseSendBuffer.Length - 1; i++) { - if (arrMySQLSendBuffer[i] != null) + if (DatabaseSendBuffer[i] != null) { - dcConnection.SendToMySql(arrMySQLSendBuffer[i]); - arrMySQLSendBuffer[i] = null; + if (DatabaseConnection.SendToMySql(DatabaseSendBuffer[i]) > 0) + { + DatabaseSendBuffer[i] = null; // If packet was send then delete it from send buffer + } } } } @@ -481,14 +481,14 @@ namespace Perun_v1 // Main timer to check MySQL connection and send JSON files to MySQL // Send ping to check for possible connection issues - dcConnection.SendToMySql("", true); + DatabaseConnection.SendToMySql("", true); // Take care of 3rd party stuff - string strSRSJson = ""; - string strLotATCJson = ""; + string ExtSRSJson = ""; + string ExtLotATCJson = ""; - bool boolSRSdefault = true; - bool boolLotATCdefault = true; + bool ExtSRSUseDefault = true; + bool ExtLotATCUseDefault = true; // Handle SRS if (Globals.bClientConnected) @@ -497,8 +497,8 @@ namespace Perun_v1 { try { - strSRSJson = System.IO.File.ReadAllText(con_txt_3rd_srs.Text); - dynamic raw_lotatc = JsonConvert.DeserializeObject(strSRSJson); + ExtSRSJson = System.IO.File.ReadAllText(con_txt_3rd_srs.Text); + dynamic raw_lotatc = JsonConvert.DeserializeObject(ExtSRSJson); for (int i = 0; i < raw_lotatc.Count; i++) { @@ -533,31 +533,31 @@ namespace Perun_v1 if (raw_lotatc.Count > 0) { - strSRSJson = JsonConvert.SerializeObject(raw_lotatc); - strSRSJson = "{'type':'100','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':'" + strSRSJson + "'}"; + ExtSRSJson = JsonConvert.SerializeObject(raw_lotatc); + ExtSRSJson = "{'type':'100','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':'" + ExtSRSJson + "'}"; } else { - strSRSJson = "{'type':'100','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':{'ignore':'false'}}"; // No SRS clients connected + ExtSRSJson = "{'type':'100','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':{'ignore':'false'}}"; // No SRS clients connected } - boolSRSdefault = false; - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "SRS data loaded", 3, 0, "100", true); - bSRSStatus = true; + ExtSRSUseDefault = false; + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "SRS data loaded", 3, 0, "100", true); + ExtSRSStatus = true; } catch (Exception exc_srs) { - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "SRS data ERROR , error: " + exc_srs.Message, 3, 1, "100"); - bSRSStatus = false; + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "SRS data ERROR , error: " + exc_srs.Message, 3, 1, "100"); + ExtSRSStatus = false; Globals.intSRSErros++; } } - if (boolSRSdefault) + if (ExtSRSUseDefault) { - strSRSJson = "{'type':'100','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':{'ignore':'true'}}"; + ExtSRSJson = "{'type':'100','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':{'ignore':'true'}}"; } - dcConnection.SendToMySql(strSRSJson); + DatabaseConnection.SendToMySql(ExtSRSJson); } // Handle LotATC @@ -567,28 +567,28 @@ namespace Perun_v1 { try { - strLotATCJson = System.IO.File.ReadAllText(con_txt_3rd_lotatc.Text); - dynamic raw_srs = JsonConvert.DeserializeObject(strLotATCJson); + ExtLotATCJson = System.IO.File.ReadAllText(con_txt_3rd_lotatc.Text); + dynamic raw_srs = JsonConvert.DeserializeObject(ExtLotATCJson); - strLotATCJson = "{'type':'101','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':'" + strLotATCJson + "'}"; - boolLotATCdefault = false; - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "LotATC data loaded", 3, 0, "101", true); - bLotATCStatus = true; + ExtLotATCJson = "{'type':'101','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':'" + ExtLotATCJson + "'}"; + ExtLotATCUseDefault = false; + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "LotATC data loaded", 3, 0, "101", true); + ExtLotATCStatus = true; } catch (Exception exc_lotatc) { - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "LotATC data ERROR, error: " + exc_lotatc.Message, 3, 1, "101"); - bLotATCStatus = false; + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "LotATC data ERROR, error: " + exc_lotatc.Message, 3, 1, "101"); + ExtLotATCStatus = false; Globals.intLotATCErros++; } } - if (boolLotATCdefault) + if (ExtLotATCUseDefault) { - strLotATCJson = "{'type':'101','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':{'ignore':'true'}}"; // No LotATC controller connected + ExtLotATCJson = "{'type':'101','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':{'ignore':'true'}}"; // No LotATC controller connected } - dcConnection.SendToMySql(strLotATCJson); + DatabaseConnection.SendToMySql(ExtLotATCJson); } // Let's do not risk int overload @@ -599,12 +599,6 @@ namespace Perun_v1 } - - private void con_List_Received_SelectedIndexChanged(object sender, EventArgs e) - { - - } - private void con_Button_Reset_Flags_Click(object sender, EventArgs e) { // Reset error flags @@ -622,20 +616,19 @@ namespace Perun_v1 Globals.bStatusIconsForce = true; // Add information - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "Resetted error counter",0,1); + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "Resetted error counter",0,1); } else if (dialogResult == DialogResult.No) { // Do nothing } - - } + } private void con_Button_Add_Marker_Click(object sender, EventArgs e) { // Added user marker - PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "User Marker",0,1); + PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "User Marker",0,1); } } } diff --git a/02_Windows_App/Perun_v1/Perun_v1.csproj b/02_Windows_App/Perun_v1/Perun_v1.csproj index 1922f65..2cedcb0 100644 --- a/02_Windows_App/Perun_v1/Perun_v1.csproj +++ b/02_Windows_App/Perun_v1/Perun_v1.csproj @@ -131,14 +131,17 @@ Form + PreserveNewest form_Main.cs + PreserveNewest form_Main.cs + PreserveNewest ResXFileCodeGenerator From a0c9a249f6752e42376f3c06dec257942bb6ce56 Mon Sep 17 00:00:00 2001 From: szporowolik Date: Tue, 22 Oct 2019 16:30:47 +0200 Subject: [PATCH 21/23] Code clean up --- .../Perun_v1/01_Classes/DatabaseController.cs | 8 +- 02_Windows_App/Perun_v1/01_Classes/Globals.cs | 36 ++++--- .../Perun_v1/01_Classes/PerunHelper.cs | 8 +- .../Perun_v1/01_Classes/TCPController.cs | 8 +- 02_Windows_App/Perun_v1/02_Forms/form_Main.cs | 98 +++++++++---------- 5 files changed, 81 insertions(+), 77 deletions(-) diff --git a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs index 4733bd1..c49e76f 100644 --- a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs +++ b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs @@ -38,7 +38,7 @@ public class DatabaseController // Modify specific types if (TCPFrameType == "1") { - TCPFrame.payload["v_win"] = "v" + Globals.strPerunVersion; // Inject app version information + TCPFrame.payload["v_win"] = "v" + Globals.VersionPerun; // Inject app version information } // Specific SQL per each frame type @@ -150,7 +150,7 @@ public class DatabaseController // General exception found Console.WriteLine(a_ex.ToString()); PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "ERROR MySQL - error: " + a_ex.Message,1,1, TCPFrameType); - Globals.intGameErros++; + Globals.ErrorsGame++; DatabaseStatus = false; ReturnValue = 0; } @@ -171,7 +171,7 @@ public class DatabaseController PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "ERROR MySQL - error: " + m_ex.Message,1,1, TCPFrameType); break; } - Globals.intGameErros++; + Globals.ErrorsGame++; DatabaseStatus = false; ReturnValue = 0; } @@ -182,7 +182,7 @@ public class DatabaseController { PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "ERROR MySQL - unable to connect, error: " + x_ex.Message,1,1, TCPFrameType); ReturnValue = 0; - Globals.intGameErros++; + Globals.ErrorsGame++; } return ReturnValue; diff --git a/02_Windows_App/Perun_v1/01_Classes/Globals.cs b/02_Windows_App/Perun_v1/01_Classes/Globals.cs index 1553d30..1dcab73 100644 --- a/02_Windows_App/Perun_v1/01_Classes/Globals.cs +++ b/02_Windows_App/Perun_v1/01_Classes/Globals.cs @@ -2,21 +2,25 @@ internal class Globals { - public static string strPerunVersion = "DEBUG"; // Helper for pulling version definition - public static string[] AppLogHistory = new string[10]; // Log history for GUI - public static bool bGUILogHistoryUpdate = true; // Flag if log control requires update - public static string strPerunTitleText = ""; // Helper to update title - public static int intInstanceId = 0; // Kepp the instance ID - public static bool bStatusIconsForce = true; // Force main window icons reload - public static bool bdcConnection = false; // Historic db connection status - public static bool bTCPServer = false; // Historic tcp connection status - public static bool bSRSStatus = false; // Historic srs connection status - public static bool bLotATCStatus = false; // Historic lotatc connection status - public static bool bClientConnected = false; // Flag if is TCP connectionstill alive - public static int intMysqlErros = 0; // MySQL - Error counter - public static int intGameErros = 0; // TCP connection - Error counter - public static int intGameErrosHistory = 0; // TCP connection - historic value of Error counter - public static int intSRSErros = 0; // DCS SRS - error counter - public static int intLotATCErros = 0; // LotATC - error counter + public static string[] AppLogHistory = new string[10]; // Log history for GUI + public static bool AppUpdateGUI = true; // Flag if log control requires update + public static string AppTitle = ""; // Helper to update title + public static int AppInstanceID = 0; // Kepp the instance ID + public static bool AppForceIconReload = true; // Force main window icons reload + + public static bool StatusDatabase = false; // Historic db connection status + public static bool StatusSRS = false; // Historic srs connection status + public static bool StatusLotATC = false; // Historic lotatc connection status + public static bool StatusHistoryConnection = false; // Historic tcp connection status + public static bool StatusConnection = false; // Flag if is TCP connectionstill alive + public static int ErrorsDatabase = 0; // MySQL - Error counter + public static int ErrorsGame = 0; // TCP connection - Error counter + public static int ErrorsHistoryGame = 0; // TCP connection - historic value of Error counter + public static int ErrorsSRS = 0; // DCS SRS - error counter + public static int ErrorsLotATC = 0; // LotATC - error counter + + public static string VersionDCSHook = ""; // Version - DCS hook + public static string VersionDatabase = ""; // Version - Database + public static string VersionPerun = "DEBUG"; // Version - Perun } diff --git a/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs b/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs index 6f3a56b..462d0d1 100644 --- a/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs +++ b/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs @@ -44,16 +44,16 @@ internal class PerunHelper arrLogHistory[arrLogHistory.Length - 1] = DateTime.Now.ToString("HH:mm:ss") + " " + LogDirection + " " + strEntryToAdd; // Add entry at the last position // Update control at my window - Globals.bGUILogHistoryUpdate = true; + Globals.AppUpdateGUI = true; } // Add the entry to log file - LogController.WriteLog(DateTime.Now.ToString("yyyy-dd-MM ") + " " + DateTime.Now.ToString("HH:mm:ss") + " | Instance: "+ Globals.intInstanceId + " | " + LogMarker + " | "+ LogDirection + " | "+ strType + " | " + strEntryToAdd); + LogController.WriteLog(DateTime.Now.ToString("yyyy-dd-MM ") + " " + DateTime.Now.ToString("HH:mm:ss") + " | Instance: "+ Globals.AppInstanceID + " | " + LogMarker + " | "+ LogDirection + " | "+ strType + " | " + strEntryToAdd); } public static string GetAppVersion(string strBeginning) { // Gets build version - Globals.strPerunVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); - return strBeginning + "v" + Globals.strPerunVersion; + Globals.VersionPerun = Assembly.GetExecutingAssembly().GetName().Version.ToString(); + return strBeginning + "v" + Globals.VersionPerun; } } \ No newline at end of file diff --git a/02_Windows_App/Perun_v1/01_Classes/TCPController.cs b/02_Windows_App/Perun_v1/01_Classes/TCPController.cs index 6b348e6..3450b81 100644 --- a/02_Windows_App/Perun_v1/01_Classes/TCPController.cs +++ b/02_Windows_App/Perun_v1/01_Classes/TCPController.cs @@ -64,7 +64,7 @@ public class TCPController { // Start listening Console.WriteLine("TCP: Waiting for connection"); - Globals.bClientConnected = false; + Globals.StatusConnection = false; // Wait for pending connection if (tcpServer.Pending()) @@ -80,7 +80,7 @@ public class TCPController while (tcpClient.Connected && !bCloseConnection && bTCPConnectionOnline) //while the client is connected, we look for incoming messages { StringBuilder CompleteMessage = new StringBuilder(); - Globals.bClientConnected = true; + Globals.StatusConnection = true; if (nsReadStream.CanRead) { @@ -154,7 +154,7 @@ public class TCPController } catch (Exception e) { - Globals.intGameErros++; + Globals.ErrorsGame++; Console.WriteLine(e.ToString()); PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "ERROR while message parsing , error: " + e.Message,2,1,"?"); bTCPConnectionOnline = false; @@ -180,7 +180,7 @@ public class TCPController } catch (Exception e) { - Globals.intGameErros++; + Globals.ErrorsGame++; Console.WriteLine(e.ToString()); PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "TCP error - connection closed or port in use, error: " + e.Message,1,1,"?"); bTCPConnectionOnline = false; diff --git a/02_Windows_App/Perun_v1/02_Forms/form_Main.cs b/02_Windows_App/Perun_v1/02_Forms/form_Main.cs index c2fb6de..96ea7a7 100644 --- a/02_Windows_App/Perun_v1/02_Forms/form_Main.cs +++ b/02_Windows_App/Perun_v1/02_Forms/form_Main.cs @@ -27,8 +27,8 @@ namespace Perun_v1 form_Main_LoadSettings(); // Load settings from registry // Display build version in title bar - Globals.strPerunTitleText = PerunHelper.GetAppVersion(this.Text + " - "); - this.Text = Globals.strPerunTitleText; + Globals.AppTitle = PerunHelper.GetAppVersion(this.Text + " - "); + this.Text = Globals.AppTitle; // Use command line parameters string[] args = Environment.GetCommandLineArgs(); @@ -165,18 +165,18 @@ namespace Perun_v1 { // Start listening // Set globals - Globals.intInstanceId = Int32.Parse(con_txt_dcs_instance.Text); - Globals.bStatusIconsForce = true; - Globals.intMysqlErros = 0; // Reset error counter - Globals.intGameErros = 0; // Reset error counter - Globals.intSRSErros = 0; // Reset error counter - Globals.intLotATCErros = 0; // Reset error counter - Globals.bClientConnected = false; // Reset connection status + 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.strPerunTitleText; // Set title bar + this.Text = "[#" + con_txt_dcs_instance.Text + "] " + Globals.AppTitle; // Set title bar trayIconMain.Text = this.Text; // Set notification icon text // Prepare MySQL connection string @@ -243,17 +243,17 @@ namespace Perun_v1 Tim_GUI_Tick(null, null); // Set title bar - this.Text = Globals.strPerunTitleText; + this.Text = Globals.AppTitle; trayIconMain.Text = this.Text; // Set globals - Globals.intInstanceId = 0; - Globals.bGUILogHistoryUpdate = false; - Globals.bdcConnection = false; - Globals.bTCPServer = false; - Globals.bSRSStatus = false; - Globals.bLotATCStatus = false; - Globals.bClientConnected = false; + Globals.AppInstanceID = 0; + Globals.AppUpdateGUI = false; + Globals.StatusDatabase = false; + Globals.StatusHistoryConnection = false; + Globals.StatusSRS = false; + Globals.StatusLotATC = false; + Globals.StatusConnection = false; } private void con_lab_github_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) @@ -360,7 +360,7 @@ namespace Perun_v1 // Main timer to sync GUI with background tasks and flush buffers // Refresh Log Window - if (Globals.bGUILogHistoryUpdate) + if (Globals.AppUpdateGUI) { con_List_Received.Items.Clear(); foreach (string i in Globals.AppLogHistory) @@ -370,7 +370,7 @@ namespace Perun_v1 con_List_Received.Items.Add(i); } } - Globals.bGUILogHistoryUpdate = false; + Globals.AppUpdateGUI = false; } else { @@ -378,11 +378,11 @@ namespace Perun_v1 } // Update status icons at main form - MySQL - if ((DatabaseConnection.DatabaseStatus != Globals.bdcConnection) || Globals.bStatusIconsForce) + if ((DatabaseConnection.DatabaseStatus != Globals.StatusDatabase) || Globals.AppForceIconReload) { if (DatabaseConnection.DatabaseStatus) { - if (Globals.intMysqlErros == 0) + if (Globals.ErrorsDatabase == 0) { con_img_db.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_connected"); } @@ -395,14 +395,14 @@ namespace Perun_v1 { con_img_db.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected_error"); } - Globals.bdcConnection = DatabaseConnection.DatabaseStatus; + Globals.StatusDatabase = DatabaseConnection.DatabaseStatus; } // Update status icons at main form - DCS - if ((Globals.bClientConnected != Globals.bTCPServer) || Globals.bStatusIconsForce || Globals.intGameErros != Globals.intGameErrosHistory) + if ((Globals.StatusConnection != Globals.StatusHistoryConnection) || Globals.AppForceIconReload || Globals.ErrorsGame != Globals.ErrorsHistoryGame) { - if (Globals.bClientConnected) + if (Globals.StatusConnection) { - if (Globals.intGameErros == 0) + if (Globals.ErrorsGame == 0) { con_img_dcs.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_connected"); } @@ -415,15 +415,15 @@ namespace Perun_v1 { con_img_dcs.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected_error"); } - Globals.bTCPServer = Globals.bClientConnected; - Globals.intGameErrosHistory = Globals.intGameErros; + Globals.StatusHistoryConnection = Globals.StatusConnection; + Globals.ErrorsHistoryGame = Globals.ErrorsGame; } // Update status icons at main form - SRS - if ((ExtSRSStatus != Globals.bSRSStatus) || Globals.bStatusIconsForce) + if ((ExtSRSStatus != Globals.StatusSRS) || Globals.AppForceIconReload) { if (ExtSRSStatus && con_check_3rd_srs.Checked) { - if (Globals.intSRSErros == 0) + if (Globals.ErrorsSRS == 0) { con_img_srs.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_connected"); } @@ -436,14 +436,14 @@ namespace Perun_v1 { con_img_srs.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected_error"); } - Globals.bSRSStatus = ExtSRSStatus; + Globals.StatusSRS = ExtSRSStatus; } // Update status icons at main form - LotATC - if ((ExtLotATCStatus != Globals.bLotATCStatus) || Globals.bStatusIconsForce) + if ((ExtLotATCStatus != Globals.StatusLotATC) || Globals.AppForceIconReload) { if (ExtLotATCStatus && con_check_3rd_lotatc.Checked) { - if (Globals.intLotATCErros == 0) + if (Globals.ErrorsLotATC == 0) { con_img_lotATC.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_connected"); } @@ -456,9 +456,9 @@ namespace Perun_v1 { con_img_lotATC.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected_error"); } - Globals.bLotATCStatus = ExtLotATCStatus; + Globals.StatusLotATC = ExtLotATCStatus; } - Globals.bStatusIconsForce = false; + Globals.AppForceIconReload = false; } private void Tim_MySQL_Tick(object sender, EventArgs e) @@ -491,7 +491,7 @@ namespace Perun_v1 bool ExtLotATCUseDefault = true; // Handle SRS - if (Globals.bClientConnected) + if (Globals.StatusConnection) { if (con_check_3rd_srs.Checked) { @@ -548,7 +548,7 @@ namespace Perun_v1 { PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "SRS data ERROR , error: " + exc_srs.Message, 3, 1, "100"); ExtSRSStatus = false; - Globals.intSRSErros++; + Globals.ErrorsSRS++; } @@ -561,7 +561,7 @@ namespace Perun_v1 } // Handle LotATC - if (Globals.bClientConnected) + if (Globals.StatusConnection) { if (con_check_3rd_lotatc.Checked) { @@ -579,7 +579,7 @@ namespace Perun_v1 { PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "LotATC data ERROR, error: " + exc_lotatc.Message, 3, 1, "101"); ExtLotATCStatus = false; - Globals.intLotATCErros++; + Globals.ErrorsLotATC++; } @@ -592,10 +592,10 @@ namespace Perun_v1 } // Let's do not risk int overload - Globals.intMysqlErros = (Globals.intMysqlErros > 999) ? 999 : Globals.intMysqlErros; - Globals.intGameErros = (Globals.intGameErros > 999) ? 999 : Globals.intGameErros; - Globals.intSRSErros = (Globals.intSRSErros > 999) ? 999 : Globals.intSRSErros; - Globals.intLotATCErros = (Globals.intLotATCErros > 999) ? 999 : Globals.intLotATCErros; + 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; } @@ -606,14 +606,14 @@ namespace Perun_v1 if (dialogResult == DialogResult.Yes) { // Reset errors counter - Globals.intMysqlErros = 0; // MySQL - Error counter - Globals.intGameErros = 0; // TCP connection - Error counter - Globals.intGameErrosHistory = 0; // TCP connection - historic value of Error counter - Globals.intSRSErros = 0; // DCS SRS - error counter - Globals.intLotATCErros = 0; // LotATC - error 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.bStatusIconsForce = true; + Globals.AppForceIconReload = true; // Add information PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "Resetted error counter",0,1); From 9770c26b9308c19aca4a12583b5aed55e6c035e0 Mon Sep 17 00:00:00 2001 From: szporowolik Date: Tue, 22 Oct 2019 17:36:36 +0200 Subject: [PATCH 22/23] Added version checking of database, dcs hook and windows app - in case of mismatch , app is terminating --- .../Perun_v1/01_Classes/DatabaseController.cs | 55 +++++++++++++------ .../Perun_v1/01_Classes/PerunHelper.cs | 37 ++++++++++++- .../Perun_v1/01_Classes/TCPController.cs | 12 ++-- 02_Windows_App/Perun_v1/02_Forms/form_Main.cs | 26 +++++---- 4 files changed, 95 insertions(+), 35 deletions(-) diff --git a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs index c49e76f..e4e441c 100644 --- a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs +++ b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs @@ -39,6 +39,9 @@ public class DatabaseController 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 @@ -83,7 +86,7 @@ public class DatabaseController else if (TCPFrameType == "-1") { // Keep alive message - SQLQueryTxt = "SELECT 1;"; + SQLQueryTxt = "SELECT `pe_Config_payload` FROM `pe_Config` WHERE `pe_Config_id` = 1;"; } else { @@ -106,41 +109,57 @@ public class DatabaseController DatabaseStatus = true; MySqlCommand DatabaseCommand = new MySqlCommand(SQLQueryTxt, DatabaseConnection); 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.GUILogHistoryAdd(ref Globals.AppLogHistory, "Connected players: " + TCPFrame.payload["c_players"], 1,0,"1"); + PerunHelper.AddLog(ref Globals.AppLogHistory, "Connected players: " + TCPFrame.payload["c_players"], 1,0,"1"); break; case 2: - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "Mission: \"" + TCPFrame.payload["mission"]["name"]+"\""+ ", time:" + TCPFrame.payload["mission"]["modeltime"], 1, 0, "2"); + PerunHelper.AddLog(ref Globals.AppLogHistory, "Mission: \"" + TCPFrame.payload["mission"]["name"]+"\""+ ", time:" + TCPFrame.payload["mission"]["modeltime"], 1, 0, "2"); break; case 3: - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "Slots data updated", 1, 0, "3"); + PerunHelper.AddLog(ref Globals.AppLogHistory, "Slots data updated", 1, 0, "3"); break; case 50: - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "Player's \""+ TCPFrame.payload.player + "\" chat message saved", 1, 0, "50"); + PerunHelper.AddLog(ref Globals.AppLogHistory, "Player's \""+ TCPFrame.payload.player + "\" chat message saved", 1, 0, "50"); break; case 51: - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "Game event: \""+ TCPFrame.payload.log_content +"\"", 1, 0, "51"); + PerunHelper.AddLog(ref Globals.AppLogHistory, "Game event: \""+ TCPFrame.payload.log_content +"\"", 1, 0, "51"); break; case 52: - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "Player's \""+ TCPFrame.payload.stat_name + "\" stats saved", 1, 0, "52"); + PerunHelper.AddLog(ref Globals.AppLogHistory, "Player's \""+ TCPFrame.payload.stat_name + "\" stats saved", 1, 0, "52"); break; case 53: - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "Player \""+ TCPFrame.payload.login_name + "\" logged in", 1, 0, "53"); + PerunHelper.AddLog(ref Globals.AppLogHistory, "Player \""+ TCPFrame.payload.login_name + "\" logged in", 1, 0, "53"); break; case 100: - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "SRS data send", 1,0,"100"); + PerunHelper.AddLog(ref Globals.AppLogHistory, "SRS data send", 1,0,"100"); break; case 101: - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "LotATC data send", 1,0,"101"); + PerunHelper.AddLog(ref Globals.AppLogHistory, "LotATC data send", 1,0,"101"); break; case -1: break; default: - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "Data send", 1,0, TCPFrameType); + PerunHelper.AddLog(ref Globals.AppLogHistory, "Data send", 1,0, TCPFrameType); break; } @@ -149,7 +168,7 @@ public class DatabaseController { // General exception found Console.WriteLine(a_ex.ToString()); - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "ERROR MySQL - error: " + a_ex.Message,1,1, TCPFrameType); + PerunHelper.AddLog(ref Globals.AppLogHistory, "ERROR MySQL - error: " + a_ex.Message,1,1, TCPFrameType); Globals.ErrorsGame++; DatabaseStatus = false; ReturnValue = 0; @@ -160,15 +179,15 @@ public class DatabaseController switch (m_ex.Number) { case 1042: // Unable to connect to any of the specified MySQL hosts (Check Server,Port) - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "ERROR MySQL - unable to connect, error: " + m_ex.Message,1,1, TCPFrameType); + PerunHelper.AddLog(ref Globals.AppLogHistory, "ERROR MySQL - unable to connect, error: " + m_ex.Message,1,1, TCPFrameType); break; case 0: // Access denied (Check DB name,username,password) - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "ERROR MySQL - access denied, error: " + m_ex.Message,1,1, TCPFrameType); + PerunHelper.AddLog(ref Globals.AppLogHistory, "ERROR MySQL - access denied, error: " + m_ex.Message,1,1, TCPFrameType); break; default: - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "ERROR MySQL - error id: " + m_ex.Number,1,1, TCPFrameType); - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "ERROR MySQL - query: " + SQLQueryTxt, 1, 1, TCPFrameType); - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "ERROR MySQL - error: " + m_ex.Message,1,1, TCPFrameType); + 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); break; } Globals.ErrorsGame++; @@ -180,7 +199,7 @@ public class DatabaseController } catch (ArgumentException x_ex) { - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "ERROR MySQL - unable to connect, error: " + x_ex.Message,1,1, TCPFrameType); + PerunHelper.AddLog(ref Globals.AppLogHistory, "ERROR MySQL - unable to connect, error: " + x_ex.Message,1,1, TCPFrameType); ReturnValue = 0; Globals.ErrorsGame++; } diff --git a/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs b/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs index 462d0d1..0617c05 100644 --- a/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs +++ b/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs @@ -1,10 +1,11 @@ // This class gathers all helper functions using System; using System.Reflection; +using System.Text.RegularExpressions; internal class PerunHelper { - public static void GUILogHistoryAdd(ref string[] arrLogHistory, string strEntryToAdd, int intDirection = 0, int intMarker = 0, string strType = " ", bool bSkipGui = false) + public static void AddLog(ref string[] arrLogHistory, string strEntryToAdd, int intDirection = 0, int intMarker = 0, string strType = " ", bool bSkipGui = false) { // Declare values string LogDirection; @@ -56,4 +57,38 @@ internal class PerunHelper Globals.VersionPerun = Assembly.GetExecutingAssembly().GetName().Version.ToString(); return strBeginning + "v" + Globals.VersionPerun; } + + public static int CheckVersions() + { + // 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; + } } \ No newline at end of file diff --git a/02_Windows_App/Perun_v1/01_Classes/TCPController.cs b/02_Windows_App/Perun_v1/01_Classes/TCPController.cs index 3450b81..a92dfb6 100644 --- a/02_Windows_App/Perun_v1/01_Classes/TCPController.cs +++ b/02_Windows_App/Perun_v1/01_Classes/TCPController.cs @@ -126,7 +126,7 @@ public class TCPController if (Int32.Parse(strRawTCPFrameType) != 0) { // Add to mySQL send buffer (find first empty slot) - PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "Packet received" , 2,0, strRawTCPFrameType,true); + PerunHelper.AddLog(ref arrGUILogHistory, "Packet received" , 2,0, strRawTCPFrameType,true); bool AddedDataToBuffer = false; for (int i = 0; i < arrMySQLSendBuffer.Length - 1; i++) { @@ -139,12 +139,12 @@ public class TCPController } if (!AddedDataToBuffer) { - PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "ERROR package was dropped", 1, 1, strRawTCPFrameType); + PerunHelper.AddLog(ref arrGUILogHistory, "ERROR package was dropped", 1, 1, strRawTCPFrameType); } } else { // Keep alive - PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "Keep-alive received", 2,0,"0",true); + PerunHelper.AddLog(ref arrGUILogHistory, "Keep-alive received", 2,0,"0",true); } } else @@ -156,7 +156,7 @@ public class TCPController { Globals.ErrorsGame++; Console.WriteLine(e.ToString()); - PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "ERROR while message parsing , error: " + e.Message,2,1,"?"); + PerunHelper.AddLog(ref arrGUILogHistory, "ERROR while message parsing , error: " + e.Message,2,1,"?"); bTCPConnectionOnline = false; } @@ -168,7 +168,7 @@ public class TCPController catch (SocketException e) { Console.WriteLine(e.ToString()); - PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "TCP ERROR cannot check connection, error: " + e.Message,2,1,"?"); + PerunHelper.AddLog(ref arrGUILogHistory, "TCP ERROR cannot check connection, error: " + e.Message,2,1,"?"); } } @@ -182,7 +182,7 @@ public class TCPController { Globals.ErrorsGame++; Console.WriteLine(e.ToString()); - PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "TCP error - connection closed or port in use, error: " + e.Message,1,1,"?"); + PerunHelper.AddLog(ref arrGUILogHistory, "TCP error - connection closed or port in use, error: " + e.Message,1,1,"?"); bTCPConnectionOnline = false; } diff --git a/02_Windows_App/Perun_v1/02_Forms/form_Main.cs b/02_Windows_App/Perun_v1/02_Forms/form_Main.cs index 96ea7a7..1b1baca 100644 --- a/02_Windows_App/Perun_v1/02_Forms/form_Main.cs +++ b/02_Windows_App/Perun_v1/02_Forms/form_Main.cs @@ -183,7 +183,7 @@ namespace Perun_v1 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.GUILogHistoryAdd(ref Globals.AppLogHistory, "Opening connections",0,1); + PerunHelper.AddLog(ref Globals.AppLogHistory, "Opening connections",0,1); TCPServer.Create(Int32.Parse(con_txt_dcs_server_port.Text), ref Globals.AppLogHistory, ref DatabaseSendBuffer); TCPServer.thrTCPListener = new Thread(TCPServer.StartListen); TCPServer.thrTCPListener.Start(); @@ -203,7 +203,7 @@ namespace Perun_v1 { // Stop listening // Prepare GUI - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "Closing connections",0,1); + PerunHelper.AddLog(ref Globals.AppLogHistory, "Closing connections",0,1); con_Button_Listen_OFF.Enabled = false; Tim_GUI_Tick(null, null); this.Refresh(); @@ -221,7 +221,7 @@ namespace Perun_v1 } catch (Exception ex) { - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "TCP ERROR, error: " + ex.Message, 2, 1, "?"); + PerunHelper.AddLog(ref Globals.AppLogHistory, "TCP ERROR, error: " + ex.Message, 2, 1, "?"); Console.WriteLine(ex.ToString()); } @@ -239,7 +239,7 @@ namespace Perun_v1 con_img_srs.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected"); // Display information about closed connections - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "Connections closed",0,1); + PerunHelper.AddLog(ref Globals.AppLogHistory, "Connections closed",0,1); Tim_GUI_Tick(null, null); // Set title bar @@ -483,6 +483,12 @@ namespace Perun_v1 // 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 = ""; @@ -541,12 +547,12 @@ namespace Perun_v1 ExtSRSJson = "{'type':'100','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':{'ignore':'false'}}"; // No SRS clients connected } ExtSRSUseDefault = false; - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "SRS data loaded", 3, 0, "100", true); + PerunHelper.AddLog(ref Globals.AppLogHistory, "SRS data loaded", 3, 0, "100", true); ExtSRSStatus = true; } catch (Exception exc_srs) { - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "SRS data ERROR , error: " + exc_srs.Message, 3, 1, "100"); + PerunHelper.AddLog(ref Globals.AppLogHistory, "SRS data ERROR , error: " + exc_srs.Message, 3, 1, "100"); ExtSRSStatus = false; Globals.ErrorsSRS++; } @@ -572,12 +578,12 @@ namespace Perun_v1 ExtLotATCJson = "{'type':'101','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':'" + ExtLotATCJson + "'}"; ExtLotATCUseDefault = false; - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "LotATC data loaded", 3, 0, "101", true); + PerunHelper.AddLog(ref Globals.AppLogHistory, "LotATC data loaded", 3, 0, "101", true); ExtLotATCStatus = true; } catch (Exception exc_lotatc) { - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "LotATC data ERROR, error: " + exc_lotatc.Message, 3, 1, "101"); + PerunHelper.AddLog(ref Globals.AppLogHistory, "LotATC data ERROR, error: " + exc_lotatc.Message, 3, 1, "101"); ExtLotATCStatus = false; Globals.ErrorsLotATC++; } @@ -616,7 +622,7 @@ namespace Perun_v1 Globals.AppForceIconReload = true; // Add information - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "Resetted error counter",0,1); + PerunHelper.AddLog(ref Globals.AppLogHistory, "Resetted error counter",0,1); } else if (dialogResult == DialogResult.No) { @@ -628,7 +634,7 @@ namespace Perun_v1 private void con_Button_Add_Marker_Click(object sender, EventArgs e) { // Added user marker - PerunHelper.GUILogHistoryAdd(ref Globals.AppLogHistory, "User Marker",0,1); + PerunHelper.AddLog(ref Globals.AppLogHistory, "User Marker",0,1); } } } From e1cfdba2cc3aacea9afc76208a5cbc07b5b91a0b Mon Sep 17 00:00:00 2001 From: szporowolik Date: Tue, 22 Oct 2019 17:40:20 +0200 Subject: [PATCH 23/23] Database upgrade to v0.8.3 --- 03_MySQL/m1081_perun.sql | 53 ++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/03_MySQL/m1081_perun.sql b/03_MySQL/m1081_perun.sql index f7f1603..e0b09d5 100644 --- a/03_MySQL/m1081_perun.sql +++ b/03_MySQL/m1081_perun.sql @@ -8,6 +8,45 @@ SET time_zone = "+00:00"; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8mb4 */; +CREATE DATABASE IF NOT EXISTS `m1081_perun` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; +USE `m1081_perun`; + +DELIMITER $$ +DROP PROCEDURE IF EXISTS `sp_CleanDatabase`$$ +CREATE DEFINER=`m1081`@`%.devil` PROCEDURE `sp_CleanDatabase` () MODIFIES SQL DATA +BEGIN + DELETE FROM pe_DataMissionHashes; + DELETE FROM pe_DataPlayers; + DELETE FROM pe_DataRaw; + DELETE FROM pe_LogChat; + DELETE FROM pe_LogEvent; + DELETE FROM pe_LogLogins; + DELETE FROM pe_LogStats; + + ALTER TABLE pe_DataMissionHashes AUTO_INCREMENT = 1; + ALTER TABLE pe_DataPlayers AUTO_INCREMENT = 1; + ALTER TABLE pe_DataRaw AUTO_INCREMENT = 1; + ALTER TABLE pe_LogChat AUTO_INCREMENT = 1; + ALTER TABLE pe_LogEvent AUTO_INCREMENT = 1; + ALTER TABLE pe_LogLogins AUTO_INCREMENT = 1; + ALTER TABLE pe_LogStats AUTO_INCREMENT = 1; + +END$$ + +DROP PROCEDURE IF EXISTS `sp_SyncForumGame`$$ +$$ + +DELIMITER ; + +DROP TABLE IF EXISTS `pe_Config`; +CREATE TABLE IF NOT EXISTS `pe_Config` ( + `pe_Config_id` int(11) NOT NULL, + `pe_Config_payload` varchar(255) DEFAULT NULL, + PRIMARY KEY (`pe_Config_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +INSERT INTO `pe_Config` (`pe_Config_id`, `pe_Config_payload`) VALUES +(1, 'v0.8.3'); DROP TABLE IF EXISTS `pe_DataMissionHashes`; CREATE TABLE IF NOT EXISTS `pe_DataMissionHashes` ( @@ -18,7 +57,7 @@ CREATE TABLE IF NOT EXISTS `pe_DataMissionHashes` ( PRIMARY KEY (`pe_DataMissionHashes_id`), UNIQUE KEY `UNIQUE_hash` (`pe_DataMissionHashes_hash`), KEY `pe_DataMissionHashes_instance` (`pe_DataMissionHashes_instance`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=818 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_DataPlayers`; CREATE TABLE IF NOT EXISTS `pe_DataPlayers` ( @@ -29,7 +68,7 @@ CREATE TABLE IF NOT EXISTS `pe_DataPlayers` ( `pe_DataPlayers_updated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`pe_DataPlayers_id`), UNIQUE KEY `UNIQUE_UCID` (`pe_DataPlayers_ucid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=219 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_DataRaw`; CREATE TABLE IF NOT EXISTS `pe_DataRaw` ( @@ -47,7 +86,7 @@ CREATE TABLE IF NOT EXISTS `pe_DataTypes` ( `pe_DataTypes_update` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`pe_DataTypes_id`), UNIQUE KEY `UNIQUE_TYPE_NAME` (`pe_DataTypes_name`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=57 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_LogChat`; CREATE TABLE IF NOT EXISTS `pe_LogChat` ( @@ -61,7 +100,7 @@ CREATE TABLE IF NOT EXISTS `pe_LogChat` ( KEY `pe_LogChat_missionhash_id` (`pe_LogChat_missionhash_id`), KEY `pe_LogChat_playerid` (`pe_LogChat_playerid`), KEY `pe_LogChat_datetime` (`pe_LogChat_datetime`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=19739 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_LogEvent`; CREATE TABLE IF NOT EXISTS `pe_LogEvent` ( @@ -75,7 +114,7 @@ CREATE TABLE IF NOT EXISTS `pe_LogEvent` ( PRIMARY KEY (`pe_LogEvent_id`), KEY `pe_LogEvent_missionhash_id` (`pe_LogEvent_missionhash_id`), KEY `pe_LogEvent_datetime` (`pe_LogEvent_datetime`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=93657 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_LogLogins`; CREATE TABLE IF NOT EXISTS `pe_LogLogins` ( @@ -88,7 +127,7 @@ CREATE TABLE IF NOT EXISTS `pe_LogLogins` ( PRIMARY KEY (`pe_LogLogins_id`), KEY `pe_LogLogins_playerid` (`pe_LogLogins_playerid`), KEY `pe_LogLogins_datetime` (`pe_LogLogins_datetime`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=10742 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_LogStats`; CREATE TABLE IF NOT EXISTS `pe_LogStats` ( @@ -132,7 +171,7 @@ CREATE TABLE IF NOT EXISTS `pe_LogStats` ( KEY `pe_LogStats_missionhash_id` (`pe_LogStats_missionhash_id`), KEY `pe_LogStats_playerid` (`pe_LogStats_playerid`), KEY `pe_LogStats_typeid` (`pe_LogStats_typeid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=9595 DEFAULT CHARSET=utf8; DROP TRIGGER IF EXISTS `pe_LogStats_UPDATE`; DELIMITER $$ CREATE TRIGGER `pe_LogStats_UPDATE` BEFORE UPDATE ON `pe_LogStats` FOR EACH ROW BEGIN