diff --git a/01_DCS/Hooks/Perun.lua b/01_DCS/Hooks/Perun.lua
index f1f2c2e..3d77713 100644
--- a/01_DCS/Hooks/Perun.lua
+++ b/01_DCS/Hooks/Perun.lua
@@ -9,18 +9,18 @@ package.cpath = package.cpath..";"..lfs.currentdir().."/LuaSocket/?.dll"
Perun.RefreshStatus = 15 -- (int) base refresh rate in seconds to send status update (values lower than 60 may affect performance!)
Perun.RefreshMission = 60 -- (int) refresh rate in seconds to send mission information (values lower than 60 may affect performance!)
-Perun.TCPTargetPort = 48621 -- (int) TCP port to send data to
+Perun.TCPTargetPort = 48622 -- (int) TCP port to send data to
Perun.TCPPerunHost = "localhost" -- (string) IP adress of the Perun instance or "localhost"
-Perun.Instance = 1 -- (int) Id number of instance (if multiple DCS instances are to run at the same PC)
+Perun.Instance = 2 -- (int) Id number of instance (if multiple DCS instances are to run at the same PC)
Perun.JsonStatusLocation = "Scripts\\Json\\" -- (string) folder relative do user's SaveGames DCS folder -> status file updated each RefreshMission
-Perun.MOTD_L1 = "Welcome to our server!" -- (string) Message send to players connecting the server - Line 1
-Perun.MOTD_L2 = "Please use SRS radio." -- (string) Message send to players connecting the server - Line 2
+Perun.MOTD_L1 = "Witamy na serwerze Gildia.org !" -- (string) Message send to players connecting the server - Line 1
+Perun.MOTD_L2 = "Wymagamy obecnosci DCS SRS oraz TeamSpeak - szczegoly na forum" -- (string) Message send to players connecting the server - Line 2
-- ###################### END OF SETTINGS - DO NOT MODIFY OUTSIDE THIS SECTION ######################
-- Variable init
-Perun.Version = "v0.8.0"
+Perun.Version = "v0.8.2"
Perun.StatusData = {}
Perun.SlotsData = {}
Perun.MissionData = {}
@@ -30,15 +30,16 @@ Perun.StatDataLastType = {}
Perun.MissionHash=""
Perun.lastSentStatus =0
Perun.lastSentMission =0
+Perun.lastSentKeepAlive =0
+Perun.lastReconnect = 0
Perun.JsonStatusLocation = lfs.writedir() .. Perun.JsonStatusLocation
Perun.socket = require("socket")
Perun.IsServer = true --DCS.isServer( ) -- TBD looks like DCS API error, always returning True
-Perun.TCPSourcePort = Perun.TCPTargetPort + 10 + Perun.Instance - 1
-- ########### Helper function definitions ###########
function stripChars(str)
-- remove accents characters from string
- -- via https://stackoverflow.com/questions/50459102/replace-accented-characters-in-string-to-standard-with-lua TBD: rewrite
+ -- via https://stackoverflow.com/questions/50459102/replace-accented-characters-in-string-to-standard-with-lua
tableAccents = {}
tableAccents["à"] = "a"
tableAccents["á"] = "a"
@@ -152,6 +153,11 @@ Perun.SideID2Name = function(id)
return sides[id]
end
+Perun.UpdateStatusPart = function(part_id, data_package)
+ -- Helper for status update container
+ Perun.StatusData[part_id] = data_package
+end
+
-- ########### Main code ###########
Perun.AddLog = function(text)
@@ -159,29 +165,6 @@ Perun.AddLog = function(text)
net.log("Perun : ".. text)
end
-Perun.ConnectToPerun = function ()
- Perun.AddLog("Connecting to TCP server")
- Perun.TCP = assert(Perun.socket.tcp())
- Perun.TCP:settimeout(2000)
- _, err = Perun.TCP:connect(Perun.TCPPerunHost, Perun.TCPTargetPort)
- if err then
- Perun.AddLog("TCP connection error : " .. err)
- else
- Perun.AddLog("Connected to TCP server")
- end
-end
-
-Perun.SendPacket = function (data_id,temp)
- _, err = Perun.TCP:send(temp)
-
- if err then
- Perun.AddLog("Packed drop " .. data_id .. ", error: " .. err)
- Perun.ConnectToPerun()
- else
- Perun.AddLog("Packet send " .. data_id)
- end
-end
-
Perun.UpdateJsonStatus = function()
-- Updates status json file
TempData={}
@@ -195,10 +178,28 @@ Perun.UpdateJsonStatus = function()
perun_export = io.open(Perun.JsonStatusLocation .. "perun_status_data.json", "w")
perun_export:write(_temp .. "\n")
perun_export:close()
+ Perun.AddLog("Updated JSON")
end
-Perun.Send = function(data_id, data_package)
- -- Sends data package
+Perun.ConnectToPerun = function ()
+ -- Connects to Perun server
+ Perun.AddLog("Connecting to TCP server")
+ Perun.TCP = assert(Perun.socket.tcp())
+ Perun.TCP:settimeout(5000)
+
+ _, err = Perun.TCP:connect(Perun.TCPPerunHost, Perun.TCPTargetPort)
+ if err then
+ Perun.AddLog("TCP connection error : " .. err)
+ else
+ Perun.AddLog("Connected to TCP server")
+ Perun.TCP:setoption("keepalive")
+ Perun.lastReconnect = _now
+ end
+end
+
+Perun.SendToPerun = function(data_id, data_package)
+ -- Prepares and sends data package
+ -- Prepare data
TempData={}
TempData["type"]=data_id
TempData["payload"]=data_package
@@ -208,12 +209,25 @@ Perun.Send = function(data_id, data_package)
temp=net.lua2json(TempData)
temp=stripChars(temp)
- Perun.SendPacket(data_id,temp)
-end
-
-Perun.UpdateStatusPart = function(part_id, data_package)
- -- Helper for status update container
- Perun.StatusData[part_id] = data_package
+ -- TCP Part - sending
+ Perun.AddLog("Sending packet: " .. data_id)
+ intStatus = nil
+ intTries =0
+ err=nil
+ while intStatus == nil and intTries < 3 do
+ intStatus, err = Perun.TCP:send(temp)
+ if err then
+ Perun.AddLog("Packed not send : " .. data_id .. " , error: " .. err .. ", tries: " .. intTries)
+ Perun.ConnectToPerun()
+ else
+ Perun.AddLog("Packet send : " .. data_id .. " , tries:" .. intTries)
+ end
+ intTries=intTries+1
+ err = nil
+ end
+ if err then
+ Perun.AddLog("Packed dropped : " .. data_id)
+ end
end
Perun.UpdateStatus = function()
@@ -223,14 +237,14 @@ Perun.UpdateStatus = function()
-- Update version data
Perun.ServerData['v_dcs_hook']=Perun.Version
- -- Update server data
+ -- Update clients data data
_table=net.get_player_list()
_count = 0
for _ in pairs(_table) do _count = _count + 1 end
Perun.ServerData['c_players']=_count
-- Send
- Perun.Send(1,Perun.ServerData)
+ Perun.SendToPerun(1,Perun.ServerData)
-- Status data - update all subsections
-- 1 - Mission
@@ -253,7 +267,7 @@ Perun.UpdateStatus = function()
Perun.UpdateStatusPart("players",_temp2)
-- Send
- Perun.Send(2,Perun.StatusData)
+ Perun.SendToPerun(2,Perun.StatusData)
-- Update slots data
Perun.SlotsData['coalitions']=DCS.getAvailableCoalitions()
@@ -275,18 +289,18 @@ Perun.UpdateStatus = function()
end
-- Send
- Perun.Send(3,Perun.SlotsData)
+ Perun.SendToPerun(3,Perun.SlotsData)
end
Perun.UpdateMission = function()
-- Main function for mission information updates
Perun.MissionData=DCS.getCurrentMission()
- -- Perun.Send(4,Perun.MissionData)
+ -- Perun.SendToPerun(4,Perun.MissionData) -- TBD can cause data transmission troubles
end
Perun.LogChat = function(playerID,msg,all)
- -- Log chat messages
+ -- Logs chat messages
data={}
data['player']= net.get_player_info(playerID, "name")
@@ -296,11 +310,11 @@ Perun.LogChat = function(playerID,msg,all)
data['datetime']=os.date('%Y-%m-%d %H:%M:%S')
data['missionhash']=Perun.MissionHash
- Perun.Send(50,data)
+ Perun.SendToPerun(50,data)
end
Perun.LogEvent = function(log_type,log_content,log_arg_1,log_arg_2)
- -- Log chat messages
+ -- Logs chat messages
data={}
data['log_type']= log_type
@@ -310,7 +324,7 @@ Perun.LogEvent = function(log_type,log_content,log_arg_1,log_arg_2)
data['log_datetime']=os.date('%Y-%m-%d %H:%M:%S')
data['log_missionhash']=Perun.MissionHash
- Perun.Send(51,data)
+ Perun.SendToPerun(51,data)
end
Perun.LogStatsCount = function(argPlayerID,argAction,argType)
@@ -358,6 +372,7 @@ Perun.LogStatsCount = function(argPlayerID,argAction,argType)
Perun.StatData[_ucid]['ps_ejections']=Perun.StatData[_ucid]['ps_ejections']+1
elseif argAction == "pilot_death" then
if DCS.getModelTime() > 300 then
+ -- we do not track deaths during first 5 minutes due to spawning issues TBD
Perun.StatData[_ucid]['ps_deaths']=Perun.StatData[_ucid]['ps_deaths']+1
end
elseif argAction == "friendly_fire" then
@@ -453,7 +468,7 @@ Perun.LogStats = function(playerID)
data['stat_datetime']=os.date('%Y-%m-%d %H:%M:%S')
data['stat_missionhash']=Perun.MissionHash
- Perun.Send(52,data)
+ Perun.SendToPerun(52,data)
end
Perun.LogLogin = function(playerID)
@@ -465,7 +480,7 @@ Perun.LogLogin = function(playerID)
data['login_name']=net.get_player_info(playerID, 'name')
data['login_datetime']=os.date('%Y-%m-%d %H:%M:%S')
- Perun.Send(53,data)
+ Perun.SendToPerun(53,data)
end
--- ########### Event callbacks ###########
@@ -510,6 +525,12 @@ Perun.onSimulationFrame = function()
Perun.UpdateStatus()
end
+
+ -- Send keepalive
+ if _now > Perun.lastSentKeepAlive + 5 then
+ Perun.lastSentKeepAlive = _now
+ Perun.SendToPerun(0,nil)
+ end
end
Perun.onPlayerStart = function (id)
diff --git a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs
index 3900a07..496699f 100644
--- a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs
+++ b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs
@@ -19,7 +19,7 @@ public class DatabaseController
string strUDPFramePayload;
string strUDPFramePayload_Perun;
string strSQLQueryTxt;
-
+
// Some frames may come without timestamp, use database currrent timestampe then
if (strUDPFrameTimestamp != null)
@@ -32,18 +32,18 @@ public class DatabaseController
}
// Modify specific types
- if (strUDPFrameType == "1")
+ if (strUDPFrameType == "1")
{
strUDPFrame.payload["v_win"] = "v" + Globals.strPerunVersion; // Inject app version information
}
- // Specific SQL
+ // Specific SQL per each frame type
if (strUDPFrameType == "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 += "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 + "'));";
}
@@ -52,7 +52,7 @@ public class DatabaseController
// 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_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 + "'));";
}
else if (strUDPFrameType == "52")
{
@@ -74,15 +74,15 @@ public class DatabaseController
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_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 + "');";
}
else
{
// General definition used for 1-10 type packets
strUDPFramePayload = JsonConvert.SerializeObject(strUDPFrame.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 '" + 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 + ";";
}
// Connect to mysql and execute sql
@@ -103,29 +103,31 @@ public class DatabaseController
Console.WriteLine(rdrMySQL[0] + " -- " + rdrMySQL[1]);
}
rdrMySQL.Close();
- PerunHelper.LogHistoryAdd(ref Globals.arrLogHistory, "#" + strUDPFrameInstance + " > MySQL updated, package type: " + strUDPFrameType);
+ PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + strUDPFrameInstance + " > MySQL updated, package type: " + strUDPFrameType);
}
catch (ArgumentException a_ex)
{
// General exception found
Console.WriteLine(a_ex.ToString());
- PerunHelper.LogHistoryAdd(ref Globals.arrLogHistory, "ERROR MySQL - package type: " + strUDPFrameType);
+ PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + strUDPFrameInstance + " > ERROR MySQL - package type: " + strUDPFrameType);
+ PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + strUDPFrameInstance + " > ERROR MySQL >" + a_ex.Message);
bStatus = false;
}
catch (MySqlException m_ex)
{
// MySQL exception found
- PerunHelper.LogHistoryAdd(ref Globals.arrLogHistory, "ERROR MySQL - package type: " + strUDPFrameType);
+ PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + strUDPFrameInstance + " > ERROR MySQL - package type: " + strUDPFrameType);
switch (m_ex.Number)
{
case 1042: // Unable to connect to any of the specified MySQL hosts (Check Server,Port)
- PerunHelper.LogHistoryAdd(ref Globals.arrLogHistory, "ERROR MySQL - unable to connect");
+ PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + strUDPFrameInstance + " > ERROR MySQL - unable to connect >" + m_ex.Message);
break;
case 0: // Access denied (Check DB name,username,password)
- PerunHelper.LogHistoryAdd(ref Globals.arrLogHistory, "ERROR MySQL - access denied");
+ PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + strUDPFrameInstance + " > ERROR MySQL - access denied > " + m_ex.Message);
break;
default:
- PerunHelper.LogHistoryAdd(ref Globals.arrLogHistory, "ERROR MySQL - " + m_ex.Number);
+ PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + strUDPFrameInstance + " > ERROR MySQL > " + m_ex.Number);
+ PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + strUDPFrameInstance + " > ERROR MySQL > " + m_ex.Message);
break;
}
bStatus = false;
@@ -133,11 +135,11 @@ public class DatabaseController
connMySQL.Close();
Console.WriteLine("Sending data to MySQL - Done");
}
- catch (ArgumentException)
+ catch (ArgumentException x_ex)
{
- PerunHelper.LogHistoryAdd(ref Globals.arrLogHistory, "ERROR MySQL - wrong connection parameters");
+ PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + strUDPFrameInstance + " > ERROR MySQL - unable to connect > " + x_ex.Message);
}
-
+
}
}
diff --git a/02_Windows_App/Perun_v1/01_Classes/Globals.cs b/02_Windows_App/Perun_v1/01_Classes/Globals.cs
index 27b4bac..9ec565d 100644
--- a/02_Windows_App/Perun_v1/01_Classes/Globals.cs
+++ b/02_Windows_App/Perun_v1/01_Classes/Globals.cs
@@ -1,17 +1,22 @@
// This class gathers all global variable
-using MySql.Data.MySqlClient;
internal class Globals
{
- public static string strPerunVersion = "DEBUG"; // Helper for pulling version definition
- public static string[] arrLogHistory = new string[10]; // Log history for GUI
- public static bool bLogHistoryUpdate = true; // Mark if log control require update
- public static string strPerunTitleText = "";
-
- public static bool bStatusIconsForce = true; // Force icons reload
- public static bool bdcConnection = false; // Historic db connection status
- public static bool btcpcServer = 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 string strPerunVersion = "DEBUG"; // Helper for pulling version definition
+ public static string[] arrGUILogHistory = 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
}
diff --git a/02_Windows_App/Perun_v1/01_Classes/LogController.cs b/02_Windows_App/Perun_v1/01_Classes/LogController.cs
new file mode 100644
index 0000000..709bf46
--- /dev/null
+++ b/02_Windows_App/Perun_v1/01_Classes/LogController.cs
@@ -0,0 +1,45 @@
+using System;
+using System.IO;
+
+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;
+
+ 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)
+ {
+ fileStream = logFileInfo.Create();
+ }
+ else
+ {
+ try
+ {
+ fileStream = new FileStream(logFilePath, FileMode.Append);
+ }
+ catch
+ {
+ // Do nothing
+ }
+ }
+ try
+ {
+ log = new StreamWriter(fileStream);
+ log.WriteLine(strLog);
+ log.Close();
+ }
+ catch
+ {
+ // Do nothing
+ }
+ }
+}
diff --git a/02_Windows_App/Perun_v1/01_Classes/NativeMethods.cs b/02_Windows_App/Perun_v1/01_Classes/NativeMethods.cs
deleted file mode 100644
index 6815b57..0000000
--- a/02_Windows_App/Perun_v1/01_Classes/NativeMethods.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-// This class just wraps some Win32 stuff that we're going to use for blocking of multiple instances
-using System;
-using System.Runtime.InteropServices;
-
-internal class NativeMethods
-{
- public const int HWND_BROADCAST = 0xffff;
- public static readonly int WM_SHOWME = RegisterWindowMessage("WM_SHOWME");
- [DllImport("user32")]
- public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);
- [DllImport("user32")]
- public static extern int RegisterWindowMessage(string message);
-}
\ No newline at end of file
diff --git a/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs b/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs
index faafdd3..62119a2 100644
--- a/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs
+++ b/02_Windows_App/Perun_v1/01_Classes/PerunHelper.cs
@@ -4,29 +4,37 @@ using System.Reflection;
internal class PerunHelper
{
- public static void LogHistoryAdd(ref string[] arrLogHistory, string strEntryToAdd)
+ public static void GUILogHistoryAdd(ref string[] arrLogHistory, string strEntryToAdd)
{
- // Add entry to log history and rotate
+ // Rotate log history
for (int i = 0; i < arrLogHistory.Length - 1; i++)
{
arrLogHistory[i] = arrLogHistory[i + 1]; // Shift one down
}
- arrLogHistory[arrLogHistory.Length - 1] = DateTime.Now.ToString("HH:mm:ss") + " > " + strEntryToAdd; // Add entry at the last position
- Globals.bLogHistoryUpdate = true;
+ // Add new entry
+ arrLogHistory[arrLogHistory.Length - 1] = DateTime.Now.ToString("yyyy-dd-MM HH:mm:ss") + " > " + strEntryToAdd; // Add entry at the last position
+
+ // Add the entry to log file
+ LogController.WriteLog(arrLogHistory[arrLogHistory.Length - 1]);
+
+ // Update control at my window
+ Globals.bGUILogHistoryUpdate = true;
}
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();
}
- return strBeginning+"v" + Globals.strPerunVersion;
+ return strBeginning + "v" + Globals.strPerunVersion;
}
}
\ No newline at end of file
diff --git a/02_Windows_App/Perun_v1/01_Classes/Program.cs b/02_Windows_App/Perun_v1/01_Classes/Program.cs
index 59686ac..1b59dab 100644
--- a/02_Windows_App/Perun_v1/01_Classes/Program.cs
+++ b/02_Windows_App/Perun_v1/01_Classes/Program.cs
@@ -1,5 +1,4 @@
using System;
-using System.Threading;
using System.Windows.Forms;
namespace Perun_v1
@@ -10,13 +9,11 @@ namespace Perun_v1
/// Main entry point to app
///
- // Mutex to block multiple instances
- //static Mutex mutex = new Mutex(true, "{5a710507-92e9-4664-9b91-918b8b82f107}");
-
[STAThread]
static void Main()
{
+ // Main entry point to the app
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ApplicationExit += new EventHandler(Application_ApplicationExit);
diff --git a/02_Windows_App/Perun_v1/01_Classes/TCPController.cs b/02_Windows_App/Perun_v1/01_Classes/TCPController.cs
index 7c682a8..fd5f725 100644
--- a/02_Windows_App/Perun_v1/01_Classes/TCPController.cs
+++ b/02_Windows_App/Perun_v1/01_Classes/TCPController.cs
@@ -5,49 +5,49 @@ using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
-using System.Windows.Forms;
public class TCPController
{
// Main class for TCP listener
- public int intListenPort; // Port to connect to
- public bool bDone; // Helper to exit main loop without killing thread
- public string[] arrLogHistory; // Log history for GUI
- public string[] arrSendBuffer; // Mysql send buffer
- public Thread thrTCPListener; // Seperate thread for TCP
- public bool bStatus; // TCP connecion status
+ public int intListenPort; // Port to connect to
+ public bool bCloseConnection; // Helper to exit main loop without killing thread
+ public string[] arrGUILogHistory; // Log history for GUI
+ public string[] arrMySQLSendBuffer; // MySQL send buffer
+ public Thread thrTCPListener; // Seperate thread for TCP
public void Create(int par_intListenPort, ref string[] par_arrLogHistory, ref string[] par_arrSendBuffer)
{
- // Create class
+ // Create class and map creation arguments to class
intListenPort = par_intListenPort;
- arrLogHistory = par_arrLogHistory;
- arrSendBuffer = par_arrSendBuffer;
- bDone = false;
- bStatus = false;
+ arrGUILogHistory = par_arrLogHistory;
+ arrMySQLSendBuffer = par_arrSendBuffer;
+ bCloseConnection = false;
}
public void StopListen()
{
- // Finish listening
- bDone = true;
- bStatus = false;
+ // Stop listening
+ bCloseConnection = true;
- for (int i = 0; i < arrSendBuffer.Length - 1; i++)
+ // Clear send buffer
+ for (int i = 0; i < arrMySQLSendBuffer.Length - 1; i++)
{
- arrSendBuffer[i] = null;
+ arrMySQLSendBuffer[i] = null;
}
}
public void StartListen()
{
- NetworkStream ns=null;
- TcpClient tcpClient=null;
+ // Start listening
+ NetworkStream nsReadStream = null;
+ TcpClient tcpClient = null;
+ bool bTCPConnectionOnline = false;
- while (!bDone)
+ // Main loop - do until diconnect button is clicked
+ while (!bCloseConnection)
{
Console.WriteLine("TCP Listen start");
- TcpListener tcpServer = new TcpListener(IPAddress.Any, intListenPort); ; // Listener object
+ TcpListener tcpServer = new TcpListener(IPAddress.Any, intListenPort); ; // Create listener object
try
{
@@ -56,80 +56,106 @@ public class TCPController
// Start the main loop
tcpServer.Start();
- bStatus = true;
- while (!bDone)
+
+ // While user do not clicked Disconnect button
+ while (!bCloseConnection)
{
// Start listening
+ Console.WriteLine("TCP: Waiting for connection");
+ Globals.bClientConnected = false;
- Console.WriteLine("TCP: Waiting for packet");
- tcpClient = tcpServer.AcceptTcpClient(); //if a connection exists, the server will accept it
- ns = tcpClient.GetStream(); //networkstream is used to send/receive messages
- //ns.ReadTimeout = 100;
-
- while (tcpClient.Connected && !bDone) //while the client is connected, we look for incoming messages
+ // Wait for pending connection
+ if (tcpServer.Pending())
{
- StringBuilder CompleteMessage = new StringBuilder();
+ Console.WriteLine("TCP: Connected");
+ bTCPConnectionOnline = true;
+ tcpClient = tcpServer.AcceptTcpClient(); //if a connection exists, the server will accept it
+ nsReadStream = tcpClient.GetStream(); //networkstream is used to send/receive messages
+ nsReadStream.ReadTimeout = 6000;
+ tcpClient.ReceiveTimeout = 6000;
- if (ns.CanRead)
+
+ while (tcpClient.Connected && !bCloseConnection && bTCPConnectionOnline) //while the client is connected, we look for incoming messages
{
- byte[] ReadBuffer = new byte[1024];
- CompleteMessage = new StringBuilder();
- int numberOfBytesRead = 0;
+ StringBuilder CompleteMessage = new StringBuilder();
+ Globals.bClientConnected = true;
- // Incoming message may be larger than the buffer size.
- do
+ if (nsReadStream.CanRead)
{
- numberOfBytesRead = ns.Read(ReadBuffer, 0, ReadBuffer.Length);
- CompleteMessage.AppendFormat("{0}", Encoding.ASCII.GetString(ReadBuffer, 0, numberOfBytesRead));
- }
- while (ns.DataAvailable && !bDone);
- }
- strReceivedData = CompleteMessage.ToString();
- Console.WriteLine("Sender: {0} Payload: {1}", null, strReceivedData);
+ Console.WriteLine("TCP: Can read");
+ byte[] ReadBuffer = new byte[1024];
+ CompleteMessage = new StringBuilder();
+ int numberOfBytesRead = 0;
- try
- {
- dynamic dynamicRawTCPFrame = JsonConvert.DeserializeObject(strReceivedData); // Deserialize received frame
- string strRawTCPFrameType = dynamicRawTCPFrame.type;
-
- PerunHelper.LogHistoryAdd(ref arrLogHistory, "TCP packet received, type: " + strRawTCPFrameType);
-
- // Add to mySQL send buffer (find first empty slot)
- for (int i = 0; i < arrSendBuffer.Length - 1; i++)
- {
- if (arrSendBuffer[i] == null)
+ // Incoming message may be larger than the buffer size.
+ do
{
- arrSendBuffer[i] = strReceivedData;
- break;
+ Console.WriteLine("TCP: Read");
+ numberOfBytesRead = nsReadStream.Read(ReadBuffer, 0, ReadBuffer.Length);
+ CompleteMessage.AppendFormat("{0}", Encoding.ASCII.GetString(ReadBuffer, 0, numberOfBytesRead));
+ if (numberOfBytesRead == 0)
+ {
+ break;
+ }
+ }
+ while (nsReadStream.DataAvailable && nsReadStream.CanRead && tcpClient.Connected);
+ }
+ strReceivedData = CompleteMessage.ToString();
+ Console.WriteLine("Sender: {0} Payload: {1}", null, strReceivedData);
+
+ try
+ {
+ if (strReceivedData != "")
+ {
+ 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)
+ {
+ for (int i = 0; i < arrMySQLSendBuffer.Length - 1; i++)
+ {
+ if (arrMySQLSendBuffer[i] == null)
+ {
+ arrMySQLSendBuffer[i] = strReceivedData;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ bTCPConnectionOnline = false;
}
}
- }
- catch(Exception e)
- {
- Console.WriteLine(e.ToString());
- PerunHelper.LogHistoryAdd(ref arrLogHistory, "TCP ERROR incorrect JSON");
+ catch (Exception e)
+ {
+ Globals.intGameErros++;
+ Console.WriteLine(e.ToString());
+ PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "#" + Globals.intInstanceId + " > TCP ERROR incorrect JSON > " + e.Message);
+ bTCPConnectionOnline = false;
+ }
}
}
-
+ System.Threading.Thread.Sleep(500);
}
tcpServer.Stop();
- bStatus = false;
}
catch (Exception e)
{
- // General exception found
- if (e.HResult != -2147467259)
- {
- Console.WriteLine(e.ToString());
- PerunHelper.LogHistoryAdd(ref arrLogHistory, "TCP error - connection closed or port in use");
- }
-
+ Globals.intGameErros++;
+ Console.WriteLine(e.ToString());
+ PerunHelper.GUILogHistoryAdd(ref arrGUILogHistory, "#" + Globals.intInstanceId + " > TCP error - connection closed or port in use > " + e.Message);
+ bTCPConnectionOnline = false;
}
- if (!(ns is null))
+ // Clean up and prepare for next connection
+ if (!(nsReadStream is null))
{
- ns.Flush();
- ns.Close();
+ nsReadStream.Flush();
+ nsReadStream.Close();
}
if (!(tcpClient is null))
{
@@ -139,7 +165,6 @@ public class TCPController
{
tcpServer.Stop();
}
- bStatus = false;
Console.WriteLine("TCP listen stop");
}
}
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 fc3a6bf..5c3d5ad 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
@@ -34,7 +34,7 @@
this.con_Button_Listen_ON = new System.Windows.Forms.Button();
this.con_Button_Listen_OFF = new System.Windows.Forms.Button();
this.con_GroupBox_1 = new System.Windows.Forms.GroupBox();
- this.tim_1000ms = new System.Windows.Forms.Timer(this.components);
+ this.tim_GUI = new System.Windows.Forms.Timer(this.components);
this.con_GroupBox_2 = new System.Windows.Forms.GroupBox();
this.label6 = new System.Windows.Forms.Label();
this.con_txt_mysql_port = new System.Windows.Forms.TextBox();
@@ -57,22 +57,21 @@
this.trayIconMain = new System.Windows.Forms.NotifyIcon(this.components);
this.openFileDialog_SRS = new System.Windows.Forms.OpenFileDialog();
this.openFileDialog_LotATC = new System.Windows.Forms.OpenFileDialog();
- this.tim_10000ms = new System.Windows.Forms.Timer(this.components);
- this.tim_200ms = new System.Windows.Forms.Timer(this.components);
- this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components);
+ this.tim_3rdparties = new System.Windows.Forms.Timer(this.components);
+ this.tim_MySQL = new System.Windows.Forms.Timer(this.components);
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.label8 = new System.Windows.Forms.Label();
this.con_txt_dcs_instance = new System.Windows.Forms.MaskedTextBox();
this.label7 = new System.Windows.Forms.Label();
this.con_txt_dcs_server_port = new System.Windows.Forms.MaskedTextBox();
- 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.label9 = new System.Windows.Forms.Label();
this.label10 = new System.Windows.Forms.Label();
this.label11 = new System.Windows.Forms.Label();
this.label12 = new System.Windows.Forms.Label();
+ 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_GroupBox_1.SuspendLayout();
this.con_GroupBox_2.SuspendLayout();
this.con_GroupBox_3.SuspendLayout();
@@ -89,10 +88,11 @@
this.con_List_Received.FormattingEnabled = true;
this.con_List_Received.Items.AddRange(new object[] {
"Not connected"});
- this.con_List_Received.Location = new System.Drawing.Point(6, 19);
+ this.con_List_Received.Location = new System.Drawing.Point(11, 19);
this.con_List_Received.Name = "con_List_Received";
- this.con_List_Received.Size = new System.Drawing.Size(307, 147);
+ 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
//
@@ -118,17 +118,17 @@
// con_GroupBox_1
//
this.con_GroupBox_1.Controls.Add(this.con_List_Received);
- this.con_GroupBox_1.Location = new System.Drawing.Point(12, 369);
+ this.con_GroupBox_1.Location = new System.Drawing.Point(12, 385);
this.con_GroupBox_1.Name = "con_GroupBox_1";
- this.con_GroupBox_1.Size = new System.Drawing.Size(324, 176);
+ this.con_GroupBox_1.Size = new System.Drawing.Size(324, 162);
this.con_GroupBox_1.TabIndex = 4;
this.con_GroupBox_1.TabStop = false;
this.con_GroupBox_1.Text = "Data log";
//
- // tim_1000ms
+ // tim_GUI
//
- this.tim_1000ms.Interval = 1000;
- this.tim_1000ms.Tick += new System.EventHandler(this.timer1_Tick);
+ this.tim_GUI.Interval = 200;
+ this.tim_GUI.Tick += new System.EventHandler(this.Tim_GUI_Tick);
//
// con_GroupBox_2
//
@@ -327,19 +327,14 @@
//
this.openFileDialog_LotATC.FileName = "openFileDialog1";
//
- // tim_10000ms
+ // tim_3rdparties
//
- this.tim_10000ms.Interval = 30000;
- this.tim_10000ms.Tick += new System.EventHandler(this.tim_10000ms_Tick);
+ this.tim_3rdparties.Interval = 30000;
+ this.tim_3rdparties.Tick += new System.EventHandler(this.tim_3rdparties_Tick);
//
- // tim_200ms
+ // tim_MySQL
//
- this.tim_200ms.Tick += new System.EventHandler(this.tim_200ms_Tick);
- //
- // notifyIcon1
- //
- this.notifyIcon1.Text = "notifyIcon1";
- this.notifyIcon1.Visible = true;
+ this.tim_MySQL.Tick += new System.EventHandler(this.Tim_MySQL_Tick);
//
// groupBox1
//
@@ -386,8 +381,53 @@
this.con_txt_dcs_server_port.Size = new System.Drawing.Size(207, 20);
this.con_txt_dcs_server_port.TabIndex = 3;
//
+ // label9
+ //
+ 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.Name = "label9";
+ this.label9.Size = new System.Drawing.Size(61, 13);
+ this.label9.TabIndex = 1;
+ this.label9.Text = "Database";
+ //
+ // label10
+ //
+ 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.Name = "label10";
+ this.label10.Size = new System.Drawing.Size(39, 13);
+ this.label10.TabIndex = 14;
+ this.label10.Text = "Game";
+ //
+ // label11
+ //
+ 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.Name = "label11";
+ this.label11.Size = new System.Drawing.Size(32, 13);
+ this.label11.TabIndex = 15;
+ this.label11.Text = "SRS";
+ //
+ // label12
+ //
+ 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.Name = "label12";
+ this.label12.Size = new System.Drawing.Size(49, 13);
+ this.label12.TabIndex = 16;
+ this.label12.Text = "LotATC";
+ //
// 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);
@@ -397,7 +437,8 @@
//
// con_img_srs
//
- this.con_img_srs.Location = new System.Drawing.Point(208, 335);
+ 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);
this.con_img_srs.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
@@ -406,7 +447,8 @@
//
// con_img_dcs
//
- this.con_img_dcs.Location = new System.Drawing.Point(135, 335);
+ 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);
this.con_img_dcs.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
@@ -416,49 +458,14 @@
// con_img_db
//
this.con_img_db.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
- this.con_img_db.Location = new System.Drawing.Point(69, 335);
+ 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);
this.con_img_db.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.con_img_db.TabIndex = 10;
this.con_img_db.TabStop = false;
//
- // label9
- //
- this.label9.AutoSize = true;
- this.label9.Location = new System.Drawing.Point(15, 335);
- this.label9.Name = "label9";
- this.label9.Size = new System.Drawing.Size(56, 13);
- this.label9.TabIndex = 1;
- this.label9.Text = "Database:";
- //
- // label10
- //
- this.label10.AutoSize = true;
- this.label10.Location = new System.Drawing.Point(101, 335);
- this.label10.Name = "label10";
- this.label10.Size = new System.Drawing.Size(38, 13);
- this.label10.TabIndex = 14;
- this.label10.Text = "Game:";
- //
- // label11
- //
- this.label11.AutoSize = true;
- this.label11.Location = new System.Drawing.Point(170, 335);
- this.label11.Name = "label11";
- this.label11.Size = new System.Drawing.Size(32, 13);
- this.label11.TabIndex = 15;
- this.label11.Text = "SRS:";
- //
- // label12
- //
- this.label12.AutoSize = true;
- this.label12.Location = new System.Drawing.Point(243, 335);
- this.label12.Name = "label12";
- this.label12.Size = new System.Drawing.Size(46, 13);
- this.label12.TabIndex = 16;
- this.label12.Text = "LotATC:";
- //
// form_Main
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@@ -484,10 +491,9 @@
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
- this.MinimizeBox = false;
this.Name = "form_Main";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
- this.Text = "Perun for DCS World";
+ this.Text = "Perun for DCS";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.form_Main_FormClosing);
this.Load += new System.EventHandler(this.form_Main_Load);
this.con_GroupBox_1.ResumeLayout(false);
@@ -512,7 +518,7 @@
private System.Windows.Forms.Button con_Button_Listen_ON;
private System.Windows.Forms.Button con_Button_Listen_OFF;
private System.Windows.Forms.GroupBox con_GroupBox_1;
- private System.Windows.Forms.Timer tim_1000ms;
+ private System.Windows.Forms.Timer tim_GUI;
private System.Windows.Forms.GroupBox con_GroupBox_2;
private System.Windows.Forms.GroupBox con_GroupBox_3;
private System.Windows.Forms.TextBox con_txt_mysql_database;
@@ -533,11 +539,10 @@
private System.Windows.Forms.NotifyIcon trayIconMain;
private System.Windows.Forms.OpenFileDialog openFileDialog_SRS;
private System.Windows.Forms.OpenFileDialog openFileDialog_LotATC;
- private System.Windows.Forms.Timer tim_10000ms;
+ private System.Windows.Forms.Timer tim_3rdparties;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.TextBox con_txt_mysql_port;
- private System.Windows.Forms.Timer tim_200ms;
- private System.Windows.Forms.NotifyIcon notifyIcon1;
+ private System.Windows.Forms.Timer tim_MySQL;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.MaskedTextBox con_txt_dcs_server_port;
private System.Windows.Forms.Label label7;
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 cbcd6ea..74d6634 100644
--- a/02_Windows_App/Perun_v1/02_Forms/form_Main.cs
+++ b/02_Windows_App/Perun_v1/02_Forms/form_Main.cs
@@ -1,20 +1,20 @@
-using System;
+using Newtonsoft.Json;
+using System;
using System.Diagnostics;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
-using Newtonsoft.Json;
namespace Perun_v1
{
public partial class form_Main : Form
{
// Variable definitions
- public string[] arrSendBuffer = new string[65534]; // MySQL send buffer
- public bool bLetMeOut = false; // Helper to handle system tray
+ public string[] arrMySQLSendBuffer = new string[65534]; // MySQL send buffer
+ public bool bAllowAppClosure = false; // Helper to handle system tray
public DatabaseController dcConnection = new DatabaseController(); // MySQL controller
- public TCPController tcpcServer=new TCPController(); // TCP controller
+ public TCPController tcpServer = new TCPController(); // TCP controller
public bool bSRSStatus; // Use empty/default SRS status
public bool bLotATCStatus; // Use empty/default LotATC status
@@ -23,18 +23,20 @@ namespace Perun_v1
private void form_Main_Load(object sender, EventArgs e)
{
// Form loaded - fill controls with default values
- Globals.arrLogHistory[0] = DateTime.Now.ToString("HH:mm:ss") + " > " + "Perun started";
-
- Globals.strPerunTitleText = PerunHelper.GetAppVersion(this.Text + " - "); // Display build version in title bar
+ Globals.arrGUILogHistory[0] = DateTime.Now.ToString("HH:mm:ss") + " > " + "Perun started";
+
+ // Display build version in title bar
+ Globals.strPerunTitleText = PerunHelper.GetAppVersion(this.Text + " - ");
this.Text = Globals.strPerunTitleText;
- form_Main_LoadSettings(); // Load settings
+ // Load settings from registry
+ form_Main_LoadSettings();
// Use command line parameters
string[] args = Environment.GetCommandLineArgs();
if (args.Length > 1)
{
- // server port
+ // Get argument server port
if (args[1] != null)
{
con_txt_dcs_server_port.Text = args[1];
@@ -42,7 +44,7 @@ namespace Perun_v1
}
if (args.Length > 2)
{
- // instance id
+ // Get argument instance id
if (args[2] != null)
{
con_txt_dcs_instance.Text = args[2];
@@ -50,7 +52,7 @@ namespace Perun_v1
}
if (args.Length > 3)
{
- // srs
+ // Get argument DCS SRS file path
if (args[3] != null)
{
con_txt_3rd_srs.Text = args[3];
@@ -59,7 +61,7 @@ namespace Perun_v1
}
if (args.Length > 4)
{
- // lotatc
+ // Get argument lotATC file path
if (args[4] != null)
{
con_txt_3rd_lotatc.Text = args[4];
@@ -77,7 +79,7 @@ namespace Perun_v1
// ################################ Helpers ################################
private void form_Main_LoadSettings()
{
- // Loads settings
+ // Loads registry settings
con_txt_mysql_database.Text = Properties.Settings.Default.MYSQL_DB;
con_txt_mysql_username.Text = Properties.Settings.Default.MYSQL_User;
con_txt_mysql_password.Text = Properties.Settings.Default.MYSQL_Password;
@@ -89,12 +91,11 @@ namespace Perun_v1
con_check_3rd_srs.Checked = Properties.Settings.Default.OTHER_SRS_USE;
con_txt_dcs_server_port.Text = Properties.Settings.Default.DCS_Server_Port.ToString();
con_txt_dcs_instance.Text = Properties.Settings.Default.DCS_Instance.ToString();
-
}
private void form_Main_SaveSettings()
{
- // Saves settings
+ // Saves registry settings
Properties.Settings.Default.MYSQL_Server = con_txt_mysql_database.Text;
Properties.Settings.Default.MYSQL_DB = con_txt_mysql_database.Text;
Properties.Settings.Default.MYSQL_User = con_txt_mysql_username.Text;
@@ -140,7 +141,7 @@ namespace Perun_v1
con_txt_mysql_database.Enabled = true;
con_txt_mysql_username.Enabled = true;
con_txt_mysql_password.Enabled = true;
- con_txt_mysql_port.Enabled = true;
+ con_txt_mysql_port.Enabled = true;
con_txt_mysql_server.Enabled = true;
con_txt_3rd_lotatc.Enabled = true;
con_txt_3rd_srs.Enabled = true;
@@ -154,84 +155,98 @@ namespace Perun_v1
private void con_Button_Listen_ON_Click(object sender, EventArgs e)
{
// Start listening
- PerunHelper.LogHistoryAdd(ref Globals.arrLogHistory, "Opening connections");
- tcpcServer.Create(Int32.Parse(con_txt_dcs_server_port.Text), ref Globals.arrLogHistory, ref arrSendBuffer);
- tcpcServer.thrTCPListener = new Thread(tcpcServer.StartListen);
- tcpcServer.thrTCPListener.Start();
- tcpcServer.thrTCPListener.Name = "TCPThread";
-
- form_Main_DisableControls(); // Disable controlls
- form_Main_SaveSettings(); // Save settings
-
- // Prepare 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;
-
- // Force icons update
+ // 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_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;
+
+ // Start listening
+ PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + Globals.intInstanceId + " > " + "Opening connections");
+ 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";
+
// Start timmers
- tim_200ms.Enabled = true;
- tim_1000ms.Enabled = true;
- tim_10000ms.Enabled = true;
+ tim_MySQL.Enabled = true;
+ tim_GUI.Enabled = true;
+ tim_3rdparties.Enabled = true;
// Send initial data
- tim_10000ms_Tick(null, null);
-
- // Set title bar
- this.Text = "[#"+ con_txt_dcs_instance.Text + "] " + Globals.strPerunTitleText;
+ Tim_MySQL_Tick(null, null);
+ tim_3rdparties_Tick(null, null);
}
private void con_Button_Listen_OFF_Click(object sender, EventArgs e)
{
// Stop listening
-
- // Display information
- PerunHelper.LogHistoryAdd(ref Globals.arrLogHistory, "Closing connections");
+ // Prepare GUI
+ PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + Globals.intInstanceId + " > " + "Closing connections");
con_Button_Listen_OFF.Enabled = false;
- timer1_Tick(null, null);
+ Tim_GUI_Tick(null, null);
this.Refresh();
Application.DoEvents();
-
+ // Stop timmers
+ tim_GUI.Enabled = false;
+ tim_3rdparties.Enabled = false;
+ tim_MySQL.Enabled = false;
+
+ // Wait untill TCP server closed connection
try
{
- tcpcServer.StopListen();
+ tcpServer.StopListen();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
- while (tcpcServer.thrTCPListener.IsAlive)
+ while (tcpServer.thrTCPListener.IsAlive)
{
- Thread.Sleep(10); //ms
+ Thread.Sleep(100); //ms
}
form_Main_EnableControls(); // Enable controls
- con_img_db.Image = null;
- con_img_dcs.Image = null;
- con_img_lotATC.Image = null;
- con_img_srs.Image = null;
-
- // Stop timmers
- tim_1000ms.Enabled = false;
- tim_10000ms.Enabled = false;
- tim_200ms.Enabled = false;
+ 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.LogHistoryAdd(ref Globals.arrLogHistory, "Connections closed");
- timer1_Tick(null, null);
+ PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + Globals.intInstanceId + " > " + "Connections closed");
+ Tim_GUI_Tick(null, null);
// Set title bar
this.Text = Globals.strPerunTitleText;
+ trayIconMain.Text = this.Text;
+
+ // Set globals
+ Globals.intInstanceId = 0;
// Set helpers for updates
- Globals.bLogHistoryUpdate = false;
+ Globals.bGUILogHistoryUpdate = false;
Globals.bdcConnection = false;
- Globals.btcpcServer = false;
+ Globals.bTCPServer = false;
Globals.bSRSStatus = false;
Globals.bLotATCStatus = false;
- }
+ Globals.bClientConnected = false;
+ }
private void con_lab_github_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
@@ -279,7 +294,7 @@ namespace Perun_v1
{
form_Main_SaveSettings();
- bLetMeOut = true; // Save settings on exit
+ bAllowAppClosure = true; // Save settings on exit
this.Close(); // Allow to exit application
}
else if (dialogResult == DialogResult.No)
@@ -288,16 +303,6 @@ namespace Perun_v1
}
}
- protected override void WndProc(ref Message m)
- {
- // Try to run of 2nd instance
- if (m.Msg == NativeMethods.WM_SHOWME)
- {
- form_Main_BringFromTray();
- }
- base.WndProc(ref m);
- }
-
private void form_Main_SendToTray()
{
// Sends app to system tray
@@ -329,7 +334,7 @@ namespace Perun_v1
private void form_Main_FormClosing(object sender, FormClosingEventArgs e)
{
// Minimize to try on clicking "X"
- if (e.CloseReason == CloseReason.UserClosing && !bLetMeOut)
+ if (e.CloseReason == CloseReason.UserClosing && !bAllowAppClosure)
{
e.Cancel = true;
form_Main_SendToTray(); // Send app to system tray
@@ -343,89 +348,124 @@ namespace Perun_v1
}
// ################################ Timers ################################
- private void timer1_Tick(object sender, EventArgs e)
+ private void Tim_GUI_Tick(object sender, EventArgs e)
{
// Main timer to sync GUI with background tasks and flush buffers
+
// Refresh Log Window
- if (Globals.bLogHistoryUpdate)
+ if (Globals.bGUILogHistoryUpdate)
{
con_List_Received.Items.Clear();
- foreach (string i in Globals.arrLogHistory)
+ foreach (string i in Globals.arrGUILogHistory)
{
if (i != null)
{
con_List_Received.Items.Add(i);
}
}
- Globals.bLogHistoryUpdate = false;
- } else
+ Globals.bGUILogHistoryUpdate = false;
+ }
+ else
{
// Do nothing , control does not require update
}
- }
-
- private void tim_200ms_Tick(object sender, EventArgs e)
- {
- // Send buffer to MySQL
- for (int i = 0; i < arrSendBuffer.Length - 1; i++)
- {
- if (arrSendBuffer[i] != null)
- {
- dcConnection.SendToMySql(arrSendBuffer[i]);
- arrSendBuffer[i] = null;
- }
- }
// Update status icons at main form
- if ((dcConnection.bStatus != Globals.bdcConnection) || Globals.bStatusIconsForce) {
+ if ((dcConnection.bStatus != Globals.bdcConnection) || Globals.bStatusIconsForce)
+ {
if (dcConnection.bStatus)
{
- con_img_db.Image = (Image)Properties.Resources.ResourceManager.GetObject("ico_db");
- } else
+ if (Globals.intMysqlErros == 0)
+ {
+ con_img_db.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_connected");
+ }
+ else
+ {
+ con_img_db.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_connected_error");
+ }
+ }
+ else
{
- con_img_db.Image = (Image)Properties.Resources.ResourceManager.GetObject("ico_error");
+ con_img_db.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected_error");
}
Globals.bdcConnection = dcConnection.bStatus;
}
- if ((tcpcServer.bStatus != Globals.btcpcServer) || Globals.bStatusIconsForce) {
- if (tcpcServer.bStatus)
+ if ((Globals.bClientConnected != Globals.bTCPServer) || Globals.bStatusIconsForce || Globals.intGameErros != Globals.intGameErrosHistory)
+ {
+ if (Globals.bClientConnected)
{
- con_img_dcs.Image = (Image)Properties.Resources.ResourceManager.GetObject("ico_game");
+ if (Globals.intGameErros == 0)
+ {
+ con_img_dcs.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_connected");
+ }
+ else
+ {
+ con_img_dcs.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_connected_error");
+ }
}
else
{
- con_img_dcs.Image = (Image)Properties.Resources.ResourceManager.GetObject("ico_error");
+ con_img_dcs.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected_error");
}
- Globals.btcpcServer = tcpcServer.bStatus;
+ Globals.bTCPServer = Globals.bClientConnected;
+ Globals.intGameErrosHistory = Globals.intGameErros;
}
- if ((bSRSStatus != Globals.bSRSStatus) || Globals.bStatusIconsForce) {
- if (bSRSStatus)
+ if ((bSRSStatus != Globals.bSRSStatus) || Globals.bStatusIconsForce)
+ {
+ if (bSRSStatus && con_check_3rd_srs.Checked)
{
- con_img_srs.Image = (Image)Properties.Resources.ResourceManager.GetObject("ico_srs");
+ if (Globals.intSRSErros == 0)
+ {
+ con_img_srs.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_connected");
+ }
+ else
+ {
+ con_img_srs.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_connected_error");
+ }
}
else
- {;
- con_img_srs.Image = (Image)Properties.Resources.ResourceManager.GetObject("ico_error");
+ {
+ con_img_srs.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected_error");
}
Globals.bSRSStatus = bSRSStatus;
}
if ((bLotATCStatus != Globals.bLotATCStatus) || Globals.bStatusIconsForce)
{
- if (bLotATCStatus)
+ if (bLotATCStatus && con_check_3rd_lotatc.Checked)
{
- con_img_lotATC.Image = (Image)Properties.Resources.ResourceManager.GetObject("ico_lotatc");
+ if (Globals.intLotATCErros == 0)
+ {
+ con_img_lotATC.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_connected");
+ }
+ else
+ {
+ con_img_lotATC.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_connected_error");
+ }
}
else
{
- con_img_lotATC.Image = (Image)Properties.Resources.ResourceManager.GetObject("ico_error");
+ con_img_lotATC.Image = (Image)Properties.Resources.ResourceManager.GetObject("status_disconnected_error");
}
Globals.bLotATCStatus = bLotATCStatus;
}
Globals.bStatusIconsForce = false;
}
- private void tim_10000ms_Tick(object sender, EventArgs e)
+ private void Tim_MySQL_Tick(object sender, EventArgs e)
+ {
+ // Send buffer to MySQL
+ for (int i = 0; i < arrMySQLSendBuffer.Length - 1; i++)
+ {
+ if (arrMySQLSendBuffer[i] != null)
+ {
+ dcConnection.SendToMySql(arrMySQLSendBuffer[i]);
+ arrMySQLSendBuffer[i] = null;
+ }
+ }
+ }
+
+ private void tim_3rdparties_Tick(object sender, EventArgs e)
{
// Main timer to send JSON files to MySQL
string strSRSJson = "";
@@ -483,13 +523,14 @@ namespace Perun_v1
strSRSJson = "{'type':'100','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':{'ignore':'false'}}"; // No SRS clients connected
}
boolSRSdefault = false;
- PerunHelper.LogHistoryAdd(ref Globals.arrLogHistory, "#" + Int32.Parse(con_txt_dcs_instance.Text) + " > SRS data loaded");
+ PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + Int32.Parse(con_txt_dcs_instance.Text) + " > SRS data loaded");
bSRSStatus = true;
}
- catch
+ catch (Exception exc_srs)
{
- PerunHelper.LogHistoryAdd(ref Globals.arrLogHistory, "#" + Int32.Parse(con_txt_dcs_instance.Text) + " > SRS data ERROR");
+ PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + Int32.Parse(con_txt_dcs_instance.Text) + " > SRS data ERROR > " + exc_srs.Message);
bSRSStatus = false;
+ Globals.intSRSErros++;
}
@@ -510,13 +551,14 @@ namespace Perun_v1
strLotATCJson = "{'type':'101','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':'" + strLotATCJson + "'}";
boolLotATCdefault = false;
- PerunHelper.LogHistoryAdd(ref Globals.arrLogHistory, "#" + Int32.Parse(con_txt_dcs_instance.Text) + " > LotATC data loaded");
+ PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + Int32.Parse(con_txt_dcs_instance.Text) + " > LotATC data loaded");
bLotATCStatus = true;
}
- catch
+ catch (Exception exc_lotatc)
{
- PerunHelper.LogHistoryAdd(ref Globals.arrLogHistory, "#" + Int32.Parse(con_txt_dcs_instance.Text) + " > LotATC data ERROR");
+ PerunHelper.GUILogHistoryAdd(ref Globals.arrGUILogHistory, "#" + Int32.Parse(con_txt_dcs_instance.Text) + " > LotATC data ERROR > " + exc_lotatc.Message);
bLotATCStatus = false;
+ Globals.intLotATCErros++;
}
@@ -526,7 +568,19 @@ namespace Perun_v1
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;
+ Globals.intGameErros = (Globals.intGameErros > 999) ? 999 : Globals.intGameErros;
+ Globals.intSRSErros = (Globals.intSRSErros > 999) ? 999 : Globals.intSRSErros;
+ Globals.intLotATCErros = (Globals.intLotATCErros > 999) ? 999 : Globals.intLotATCErros;
+
}
+
+ private void con_List_Received_SelectedIndexChanged(object sender, EventArgs e)
+ {
+
+ }
}
}
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 3a3403e..b2f7f0f 100644
--- a/02_Windows_App/Perun_v1/02_Forms/form_Main.resx
+++ b/02_Windows_App/Perun_v1/02_Forms/form_Main.resx
@@ -117,7 +117,7 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
+
17, 17
@@ -413,15 +413,12 @@
397, 17
-
+
563, 19
-
+
687, 19
-
- 797, 19
-
AAABAAEAQD8AAAEAIAAgQQAAFgAAACgAAABAAAAAfgAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
diff --git a/02_Windows_App/Perun_v1/Perun_v1.csproj b/02_Windows_App/Perun_v1/Perun_v1.csproj
index c9a2b6d..346de2f 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.1.%2a
+ 0.8.2.%2a
false
true
true
@@ -124,11 +124,11 @@
+
-
Form
@@ -182,6 +182,11 @@
+
+
+
+
+
diff --git a/02_Windows_App/Perun_v1/Properties/AssemblyInfo.cs b/02_Windows_App/Perun_v1/Properties/AssemblyInfo.cs
index 39a3f2a..bfcf35b 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.1.0")]
-[assembly: AssemblyFileVersion("0.8.1.0")]
+[assembly: AssemblyVersion("0.8.2.0")]
+[assembly: AssemblyFileVersion("0.8.2.0")]
[assembly: NeutralResourcesLanguage("en")]
diff --git a/02_Windows_App/Perun_v1/Properties/Resources.Designer.cs b/02_Windows_App/Perun_v1/Properties/Resources.Designer.cs
index 5736650..d9c9b98 100644
--- a/02_Windows_App/Perun_v1/Properties/Resources.Designer.cs
+++ b/02_Windows_App/Perun_v1/Properties/Resources.Designer.cs
@@ -63,9 +63,9 @@ namespace Perun_v1.Properties {
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
- internal static System.Drawing.Bitmap ico_db {
+ internal static System.Drawing.Bitmap status_connected {
get {
- object obj = ResourceManager.GetObject("ico_db", resourceCulture);
+ object obj = ResourceManager.GetObject("status_connected", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
@@ -73,9 +73,9 @@ namespace Perun_v1.Properties {
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
- internal static System.Drawing.Bitmap ico_error {
+ internal static System.Drawing.Bitmap status_connected_error {
get {
- object obj = ResourceManager.GetObject("ico_error", resourceCulture);
+ object obj = ResourceManager.GetObject("status_connected_error", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
@@ -83,9 +83,9 @@ namespace Perun_v1.Properties {
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
- internal static System.Drawing.Bitmap ico_game {
+ internal static System.Drawing.Bitmap status_disconnected {
get {
- object obj = ResourceManager.GetObject("ico_game", resourceCulture);
+ object obj = ResourceManager.GetObject("status_disconnected", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
@@ -93,19 +93,9 @@ namespace Perun_v1.Properties {
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
- internal static System.Drawing.Bitmap ico_lotatc {
+ internal static System.Drawing.Bitmap status_disconnected_error {
get {
- object obj = ResourceManager.GetObject("ico_lotatc", resourceCulture);
- return ((System.Drawing.Bitmap)(obj));
- }
- }
-
- ///
- /// Looks up a localized resource of type System.Drawing.Bitmap.
- ///
- internal static System.Drawing.Bitmap ico_srs {
- get {
- object obj = ResourceManager.GetObject("ico_srs", resourceCulture);
+ object obj = ResourceManager.GetObject("status_disconnected_error", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
diff --git a/02_Windows_App/Perun_v1/Properties/Resources.resx b/02_Windows_App/Perun_v1/Properties/Resources.resx
index 3bef010..143a6d2 100644
--- a/02_Windows_App/Perun_v1/Properties/Resources.resx
+++ b/02_Windows_App/Perun_v1/Properties/Resources.resx
@@ -118,19 +118,16 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- ..\Resources\ico_db.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+ ..\Resources\status-connected.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
- ..\Resources\ico_error.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\ico_game.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
-
- ..\Resources\ico_lotatc.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-
-
- ..\Resources\ico_srs.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
\ No newline at end of file
diff --git a/02_Windows_App/Perun_v1/Resources/status-connected.png b/02_Windows_App/Perun_v1/Resources/status-connected.png
new file mode 100644
index 0000000..729fb81
Binary files /dev/null and b/02_Windows_App/Perun_v1/Resources/status-connected.png differ
diff --git a/02_Windows_App/Perun_v1/Resources/status-connectedx.png b/02_Windows_App/Perun_v1/Resources/status-connectedx.png
new file mode 100644
index 0000000..5e31a64
Binary files /dev/null and b/02_Windows_App/Perun_v1/Resources/status-connectedx.png differ
diff --git a/02_Windows_App/Perun_v1/Resources/status-disconnected-error.png b/02_Windows_App/Perun_v1/Resources/status-disconnected-error.png
new file mode 100644
index 0000000..893323b
Binary files /dev/null and b/02_Windows_App/Perun_v1/Resources/status-disconnected-error.png differ
diff --git a/02_Windows_App/Perun_v1/Resources/status-disconnected-game.png b/02_Windows_App/Perun_v1/Resources/status-disconnected-game.png
new file mode 100644
index 0000000..c7f9b17
Binary files /dev/null and b/02_Windows_App/Perun_v1/Resources/status-disconnected-game.png differ
diff --git a/02_Windows_App/Perun_v1/Resources/status-disconnected.png b/02_Windows_App/Perun_v1/Resources/status-disconnected.png
new file mode 100644
index 0000000..7fd0e57
Binary files /dev/null and b/02_Windows_App/Perun_v1/Resources/status-disconnected.png differ
diff --git a/README.md b/README.md
index 71dd2e3..fb7e79b 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@ Core:
* For JSON Export:
* DCS World stable or DCS World beta
* **(Optional)** For MySQL Export:
- * MySQL database with read/write access (tested with v5.7.21)
+ * MySQL database with read/write access running at min. 5.7 server (tested with v5.7.21; native JSON support is required)
* .NET Framework 4.8.0
3rd party applications support:
@@ -71,16 +71,24 @@ C:\Perun_v1\Perun.exe 48621 1 "G:\DCS SRS\clients-list.json" "C:\Users\DCS\Saved
## Data packets - send from lua to TCP port
* ```ID: 1```, contains version/diagnostic information
+ * perun version - for server administration usage
+ * player count - actual number of connected players
* ```ID: 2```, contains status data in the following sections
- * mission - minimal information about mission
+ * mission name - name of the mission file
+ * model time - simulation time
+ * real time - real time
+ * pause - information if server is paused
+ * multiplayer - information if this is multiplayer game (always true for dedicated server usage)
+ * theather - information about area of operation
+ * weather - basic weather information
* players - connected players
* ```ID: 3```, available slots list and coalitions
* coalitions - available coalitions
* slots - available slots
-* ```ID: 4```, stores mission data
+* ```ID: 4```, stores mission data ; idea is to have whole DCS.getCurrentMission() result - currenlty commented out due to performance issues
* ```ID: 50```, chat event
* ```ID: 51```, game event
-* ```ID: 52```, player stats
+* ```ID: 52```, player stats ; note that as DSC native stats are not reliable, seperate stats couting methods are used
* ```ID: 53```, player login to DCS server
* ```ID: 100```, DCS SRS's client-list.json
* ```ID: 101```, LotATC's stats.json