From ec1d6b3a5ea47ba62e69bfebc5a11d52e0c52c77 Mon Sep 17 00:00:00 2001 From: szporowolik Date: Wed, 23 Oct 2019 00:10:48 +0200 Subject: [PATCH 01/17] v9.0.0 config --- 02_Windows_App/Perun_v1/Perun_v1.csproj | 2 +- 02_Windows_App/Perun_v1/Properties/AssemblyInfo.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/02_Windows_App/Perun_v1/Perun_v1.csproj b/02_Windows_App/Perun_v1/Perun_v1.csproj index 2cedcb0..76a74fd 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.3.%2a + 0.9.0.%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 c0d428c..92ae68d 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.3.0")] -[assembly: AssemblyFileVersion("0.8.3.0")] +[assembly: AssemblyVersion("0.9.0.0")] +[assembly: AssemblyFileVersion("0.9.0.0")] [assembly: NeutralResourcesLanguage("en")] From 55fe32f0fd5a06e3e9df68685205884beef2b1ed Mon Sep 17 00:00:00 2001 From: szporowolik Date: Wed, 23 Oct 2019 01:34:41 +0200 Subject: [PATCH 02/17] Code clean up --- 02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs | 4 ---- 1 file changed, 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 e4e441c..785c246 100644 --- a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs +++ b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs @@ -21,7 +21,6 @@ public class DatabaseController string TCPFrameTimestamp = TCPFrame.timestamp; string TCPFrameInstance = TCPFrame.instance; string TCPFramePayload; - string TCPFramePayload_Perun; string SQLQueryTxt; int ReturnValue = 1; @@ -64,9 +63,6 @@ public class DatabaseController else if (TCPFrameType == "52") { // Update user stats - TCPFramePayload = JsonConvert.SerializeObject(TCPFrame.payload.stat_data_dcs); // Deserialize payload - TCPFramePayload_Perun = JsonConvert.SerializeObject(TCPFrame.payload.stat_data_perun); // Deserialize payload - 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 + "');"; From 5b0ee02e11c60f78a2baa032d254baec8d3a2048 Mon Sep 17 00:00:00 2001 From: szporowolik Date: Wed, 23 Oct 2019 20:19:25 +0200 Subject: [PATCH 03/17] v0.9.0 & code cleanup in lua file --- 01_DCS/Hooks/Perun.lua | 693 +++++++++++++++++++++-------------------- 1 file changed, 359 insertions(+), 334 deletions(-) diff --git a/01_DCS/Hooks/Perun.lua b/01_DCS/Hooks/Perun.lua index 3be720b..a1ba6a9 100644 --- a/01_DCS/Hooks/Perun.lua +++ b/01_DCS/Hooks/Perun.lua @@ -7,20 +7,22 @@ package.cpath = package.cpath..";"..lfs.currentdir().."/LuaSocket/?.dll" -- ###################### SETTINGS - DO NOT MODIFY OUTSIDE THIS SECTION ############################# -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 = 48622 -- (int) TCP port to send data to -Perun.TCPPerunHost = "localhost" -- (string) IP adress of the Perun instance or "localhost" -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 = "Witamy na serwerze Gildia.org !" -- (string) Message send to players connecting the server - Line 1 +Perun.RefreshStatus = 15 -- (int) [default: 60] Base refresh rate in seconds to send status update +Perun.RefreshMission = 60 -- (int) [default: 120] Refresh rate in seconds to send mission information +Perun.TCPTargetPort = 48622 -- (int) [default: 48621] TCP port to send data to +Perun.TCPPerunHost = "localhost" -- (string) [default: "localhost"] IP adress of the Perun instance or "localhost" +Perun.Instance = 2 -- (int) [default: 1] Id number of instance (if multiple DCS instances are to run at the same PC) +Perun.JsonStatusLocation = "Scripts\\Json\\" -- (string) [default: "Scripts\\Json\\"] Folder relative do user's SaveGames DCS folder -> status file updated each RefreshMission +Perun.MissionStartNoDeathWindow = 300 -- (int) [default: 300] Number of secounds after mission start when death of the pilot will not go to statistics, shall avoid death penalty during spawning DCS bugs +Perun.DebugMode = 2 -- (int) [0 (default),1,2] Value greater than 0 will display Perun information in DCS log file, values: 1 - minimal verbose, 2 - all log information will be logged +Perun.LogServerMessages = 1 -- (int) [0,1 (default)] Set to 1 if you want to log also the chat messages send by server +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.3" +Perun.Version = "v0.9.0" Perun.StatusData = {} Perun.SlotsData = {} Perun.MissionData = {} @@ -28,108 +30,113 @@ Perun.ServerData = {} Perun.StatData = {} Perun.StatDataLastType = {} Perun.MissionHash="" -Perun.lastSentStatus =0 -Perun.lastSentMission =0 -Perun.lastSentKeepAlive =0 +Perun.lastSentStatus = 0 +Perun.lastSentMission = 0 +Perun.lastSentKeepAlive = 0 Perun.lastReconnect = 0 +Perun.SendRetries = 3 +Perun.RefreshKeepAlive = 3 Perun.JsonStatusLocation = lfs.writedir() .. Perun.JsonStatusLocation Perun.socket = require("socket") Perun.IsServer = true --DCS.isServer( ) -- TBD looks like DCS API error, always returning True -- ########### Helper function definitions ########### function stripChars(str) - -- remove accents characters from string + -- Hellper functions removes accents characters from string -- via https://stackoverflow.com/questions/50459102/replace-accented-characters-in-string-to-standard-with-lua - tableAccents = {} - tableAccents["à"] = "a" - tableAccents["á"] = "a" - tableAccents["â"] = "a" - tableAccents["ã"] = "a" - tableAccents["ä"] = "a" - tableAccents["ç"] = "c" - tableAccents["è"] = "e" - tableAccents["é"] = "e" - tableAccents["ê"] = "e" - tableAccents["ë"] = "e" - tableAccents["ì"] = "i" - tableAccents["í"] = "i" - tableAccents["î"] = "i" - tableAccents["ï"] = "i" - tableAccents["ñ"] = "n" - tableAccents["ò"] = "o" - tableAccents["ó"] = "o" - tableAccents["ô"] = "o" - tableAccents["õ"] = "o" - tableAccents["ö"] = "o" - tableAccents["ù"] = "u" - tableAccents["ú"] = "u" - tableAccents["û"] = "u" - tableAccents["ü"] = "u" - tableAccents["ý"] = "y" - tableAccents["ÿ"] = "y" - tableAccents["À"] = "A" - tableAccents["Á"] = "A" - tableAccents["Â"] = "A" - tableAccents["Ã"] = "A" - tableAccents["Ä"] = "A" - tableAccents["Ç"] = "C" - tableAccents["È"] = "E" - tableAccents["É"] = "E" - tableAccents["Ê"] = "E" - tableAccents["Ë"] = "E" - tableAccents["Ì"] = "I" - tableAccents["Í"] = "I" - tableAccents["Î"] = "I" - tableAccents["Ï"] = "I" - tableAccents["Ñ"] = "N" - tableAccents["Ò"] = "O" - tableAccents["Ó"] = "O" - tableAccents["Ô"] = "O" - tableAccents["Õ"] = "O" - tableAccents["Ö"] = "O" - tableAccents["Ù"] = "U" - tableAccents["Ú"] = "U" - tableAccents["Û"] = "U" - tableAccents["Ü"] = "U" - tableAccents["Ý"] = "Y" + local _tableAccents = {} + _tableAccents["à"] = "a" + _tableAccents["á"] = "a" + _tableAccents["â"] = "a" + _tableAccents["ã"] = "a" + _tableAccents["ä"] = "a" + _tableAccents["ç"] = "c" + _tableAccents["è"] = "e" + _tableAccents["é"] = "e" + _tableAccents["ê"] = "e" + _tableAccents["ë"] = "e" + _tableAccents["ì"] = "i" + _tableAccents["í"] = "i" + _tableAccents["î"] = "i" + _tableAccents["ï"] = "i" + _tableAccents["ñ"] = "n" + _tableAccents["ò"] = "o" + _tableAccents["ó"] = "o" + _tableAccents["ô"] = "o" + _tableAccents["õ"] = "o" + _tableAccents["ö"] = "o" + _tableAccents["ù"] = "u" + _tableAccents["ú"] = "u" + _tableAccents["û"] = "u" + _tableAccents["ü"] = "u" + _tableAccents["ý"] = "y" + _tableAccents["ÿ"] = "y" + _tableAccents["À"] = "A" + _tableAccents["Á"] = "A" + _tableAccents["Â"] = "A" + _tableAccents["Ã"] = "A" + _tableAccents["Ä"] = "A" + _tableAccents["Ç"] = "C" + _tableAccents["È"] = "E" + _tableAccents["É"] = "E" + _tableAccents["Ê"] = "E" + _tableAccents["Ë"] = "E" + _tableAccents["Ì"] = "I" + _tableAccents["Í"] = "I" + _tableAccents["Î"] = "I" + _tableAccents["Ï"] = "I" + _tableAccents["Ñ"] = "N" + _tableAccents["Ò"] = "O" + _tableAccents["Ó"] = "O" + _tableAccents["Ô"] = "O" + _tableAccents["Õ"] = "O" + _tableAccents["Ö"] = "O" + _tableAccents["Ù"] = "U" + _tableAccents["Ú"] = "U" + _tableAccents["Û"] = "U" + _tableAccents["Ü"] = "U" + _tableAccents["Ý"] = "Y" -- Polish accents - tableAccents["ę"] = "e" - tableAccents["Ę"] = "Ę" - tableAccents["ó"] = "o" - tableAccents["Ó"] = "O" - tableAccents["ą"] = "a" - tableAccents["Ą"] = "A" - tableAccents["ś"] = "s" - tableAccents["Ś"] = "S" - tableAccents["ć"] = "c" - tableAccents["Ć"] = "C" - tableAccents["ż"] = "z" - tableAccents["Ż"] = "Z" - tableAccents["ź"] = "z" - tableAccents["Ź"] = "Z" - tableAccents["ł"] = "l" - tableAccents["Ł"] = "L" + _tableAccents["ę"] = "e" + _tableAccents["Ę"] = "Ę" + _tableAccents["ó"] = "o" + _tableAccents["Ó"] = "O" + _tableAccents["ą"] = "a" + _tableAccents["Ą"] = "A" + _tableAccents["ś"] = "s" + _tableAccents["Ś"] = "S" + _tableAccents["ć"] = "c" + _tableAccents["Ć"] = "C" + _tableAccents["ż"] = "z" + _tableAccents["Ż"] = "Z" + _tableAccents["ź"] = "z" + _tableAccents["Ź"] = "Z" + _tableAccents["ł"] = "l" + _tableAccents["Ł"] = "L" - -- TBD additonal characters + -- TBD additonal characters for other languages - normalizedString = '' - - for strChar in string.gmatch(str, "([%z\1-\127\194-\244][\128-\191]*)") do - if tableAccents[strChar] ~= nil then - normalizedString = normalizedString..tableAccents[strChar] + -- Check string and replace special chars via replacement table + local _normalizedString = '' + for _strChar in string.gmatch(str, "([%z\1-\127\194-\244][\128-\191]*)") do + if _tableAccents[_strChar] ~= nil then + -- Replace char + _normalizedString = _normalizedString.._tableAccents[_strChar] else - normalizedString = normalizedString..strChar + -- No need to replace + _normalizedString = _normalizedString.._strChar end end - return normalizedString + return _normalizedString end Perun.GetCategory = function(id) - -- Returns object category basing on ID - -- Helper function via https://pastebin.com/GUAXrd2U TBD: rewrite + -- Helper function returns object category basing on I via https://pastebin.com/GUAXrd2U TBD: rewrite local _killed_target_category = DCS.getUnitTypeAttribute(id, "category") - if _killed_target_category == nil then + + -- Below, simple hack to get the propper category when DCS API is not returning correct value + if _killed_target_category == nil then local _killed_target_cat_check_ship = DCS.getUnitTypeAttribute(id, "DeckLevel") local _killed_target_cat_check_plane = DCS.getUnitTypeAttribute(id, "WingSpan") if _killed_target_cat_check_ship ~= nil and _killed_target_cat_check_plane == nil then @@ -145,86 +152,89 @@ end Perun.SideID2Name = function(id) -- Helper function returns side name per side (coalition) id - local sides = { + local _sides = { [0] = 'SPECTATOR', [1] = 'RED', [2] = 'BLUE', + [3] = 'NEUTRAL', -- TBD check once this is released in DCS } - return sides[id] -end - -Perun.UpdateStatusPart = function(part_id, data_package) - -- Helper for status update container - Perun.StatusData[part_id] = data_package + return _sides[id] end -- ########### Main code ########### -Perun.AddLog = function(text) +Perun.AddLog = function(text,LogLevel) -- Adds logs to DCS.log file - net.log("Perun : ".. text) + LogLevel = LogLevel or 1 + if Perun.DebugMode == LogLevel then + net.log("Perun : ".. text) + end end Perun.UpdateJsonStatus = function() -- Updates status json file - TempData={} - TempData["1"]=Perun.ServerData - TempData["2"]=Perun.StatusData - TempData["3"]=Perun.SlotsData - -- TempData["4"]=Perun.MissionData -- TBD: hangs for some large missions + local _TempData={} + _TempData["1"]=Perun.ServerData + _TempData["2"]=Perun.StatusData + _TempData["3"]=Perun.SlotsData + -- _TempData["4"]=Perun.MissionData -- TBD: hangs for some large missions - _temp=net.lua2json(TempData) - - perun_export = io.open(Perun.JsonStatusLocation .. "perun_status_data.json", "w") - perun_export:write(_temp .. "\n") - perun_export:close() - Perun.AddLog("Updated JSON") + -- Export data to JSON file + local _perun_export = io.open(Perun.JsonStatusLocation .. "perun_status_data.json", "w") + _perun_export:write(net.lua2json(_TempData) .. "\n") + _perun_export:close() + Perun.AddLog("Updated JSON",2) end Perun.ConnectToPerun = function () -- Connects to Perun server - Perun.AddLog("Connecting to TCP server") + Perun.AddLog("Connecting to TCP server",2) Perun.TCP = assert(Perun.socket.tcp()) Perun.TCP:settimeout(5000) - _, err = Perun.TCP:connect(Perun.TCPPerunHost, Perun.TCPTargetPort) - if err then - Perun.AddLog("ERROR - TCP connection error : " .. err) + _, _err = Perun.TCP:connect(Perun.TCPPerunHost, Perun.TCPTargetPort) + if _err then + -- Could not connect + Perun.AddLog("ERROR - TCP connection error : " .. _err) else - Perun.AddLog("Sucess - connected to TCP server") - -- Perun.TCP:setoption("keepalive") + -- Connected + Perun.AddLog("Sucess - connected to TCP server",2) 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 - TempData["timestamp"]=os.date('%Y-%m-%d %H:%M:%S') - TempData["instance"]=Perun.Instance + local _TempData={} + _TempData["type"]=data_id + _TempData["payload"]=data_package + _TempData["timestamp"]=os.date('%Y-%m-%d %H:%M:%S') + _TempData["instance"]=Perun.Instance - temp=net.lua2json(TempData) - temp="" .. stripChars(temp) .. "" + -- Build TCP frame + local _TCPFrame="" .. stripChars(net.lua2json(_TempData)) .. "" -- TCP Part - sending - 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) + local _intStatus = nil + local _intTries =0 + local _err=nil + + -- Try to send a few times (defind in settings section) + while _intStatus == nil and _intTries < Perun.SendRetries do + _intStatus, _err = Perun.TCP:send(_TCPFrame) + if _err then + -- Failure, packet was not send + Perun.AddLog("Packed not send : " .. data_id .. " , error: " .. _err .. ", tries: " .. _intTries,2) Perun.ConnectToPerun() else - Perun.AddLog("Packet send : " .. data_id .. " , tries:" .. intTries) + -- Succes, packet was send + Perun.AddLog("Packet send : " .. data_id .. " , tries:" .. _intTries,2) end - intTries=intTries+1 - err = nil + _intTries=_intTries+1 + _err = nil end - if err then + if _err then + -- Add information to log file Perun.AddLog("ERROR - packed dropped : " .. data_id) end end @@ -236,266 +246,266 @@ Perun.UpdateStatus = function() -- Update version data Perun.ServerData['v_dcs_hook']=Perun.Version - -- Update clients data data - _table=net.get_player_list() + -- Update clients data - count connected players + _playerlist=net.get_player_list() _count = 0 - for _ in pairs(_table) do _count = _count + 1 end + for _ in pairs(_playerlist) do _count = _count + 1 end Perun.ServerData['c_players']=_count -- Send + Perun.AddLog("Sending server data",2) Perun.SendToPerun(1,Perun.ServerData) -- Status data - update all subsections - -- 1 - Mission - temp={} - temp['name']=DCS.getMissionName() - temp['modeltime']=DCS.getModelTime() - temp['realtime']=DCS.getRealTime() - temp['pause']=DCS.getPause() - temp['multiplayer']=DCS.isMultiplayer() - temp['theatre'] = Perun.MissionData['mission']['theatre'] - temp['weather'] = Perun.MissionData['mission']['weather'] - Perun.UpdateStatusPart("mission",temp) + -- 1 - Mission data + local _TempData={} + _TempData['name']=DCS.getMissionName() + _TempData['modeltime']=DCS.getModelTime() + _TempData['realtime']=DCS.getRealTime() + _TempData['pause']=DCS.getPause() + _TempData['multiplayer']=DCS.isMultiplayer() + _TempData['theatre'] = Perun.MissionData['mission']['theatre'] + _TempData['weather'] = Perun.MissionData['mission']['weather'] + Perun.StatusData["mission"] = _TempData - -- 2 - Players - _temp = net.get_player_list() - _temp2={} - for k, i in ipairs(_temp) do - _temp2[k]=net.get_player_info(i) + -- 2 - Players data + _PlayersTable={} + for _k, _i in ipairs(_playerlist) do + _PlayersTable[_k]=net.get_player_info(_i) end - Perun.UpdateStatusPart("players",_temp2) + Perun.StatusData["players"] = _PlayersTable -- Send + Perun.AddLog("Sending status data",2) Perun.SendToPerun(2,Perun.StatusData) -- Update slots data Perun.SlotsData['coalitions']=DCS.getAvailableCoalitions() Perun.SlotsData['slots']={} - for j, i in pairs(Perun.SlotsData['coalitions']) do - Perun.SlotsData['slots'][j]=DCS.getAvailableSlots(j) + -- Build up slot table + for _j, _i in pairs(Perun.SlotsData['coalitions']) do + Perun.SlotsData['slots'][_j]=DCS.getAvailableSlots(_j) - for sj, si in pairs(Perun.SlotsData['slots'][j]) do - Perun.SlotsData['slots'][j][sj]['countryName']= nil - Perun.SlotsData['slots'][j][sj]['onboard_num']= nil - Perun.SlotsData['slots'][j][sj]['groupSize']= nil - Perun.SlotsData['slots'][j][sj]['groupName']= nil - Perun.SlotsData['slots'][j][sj]['callsign']= nil - Perun.SlotsData['slots'][j][sj]['task']= nil - Perun.SlotsData['slots'][j][sj]['airdromeId']= nil - Perun.SlotsData['slots'][j][sj]['helipadName']= nil + for _sj, _si in pairs(Perun.SlotsData['slots'][_j]) do + Perun.SlotsData['slots'][_j][_sj]['countryName']= nil + Perun.SlotsData['slots'][_j][_sj]['onboard_num']= nil + Perun.SlotsData['slots'][_j][_sj]['groupSize']= nil + Perun.SlotsData['slots'][_j][_sj]['groupName']= nil + Perun.SlotsData['slots'][_j][_sj]['callsign']= nil + Perun.SlotsData['slots'][_j][_sj]['task']= nil + Perun.SlotsData['slots'][_j][_sj]['airdromeId']= nil + Perun.SlotsData['slots'][_j][_sj]['helipadName']= nil end - end + -- Send + Perun.AddLog("Sending slots data",2) Perun.SendToPerun(3,Perun.SlotsData) end - Perun.UpdateMission = function() -- Main function for mission information updates + Perun.AddLog("Updating mission data",2) Perun.MissionData=DCS.getCurrentMission() -- Perun.SendToPerun(4,Perun.MissionData) -- TBD can cause data transmission troubles + Perun.AddLog("Mission data updated",2) end Perun.LogChat = function(playerID,msg,all) -- Logs chat messages + local _TempData={} + _TempData['player']= net.get_player_info(playerID, "name") + _TempData['msg']=stripChars(msg) + _TempData['all']=all + _TempData['ucid']=net.get_player_info(playerID, 'ucid') + _TempData['datetime']=os.date('%Y-%m-%d %H:%M:%S') + _TempData['missionhash']=Perun.MissionHash - data={} - data['player']= net.get_player_info(playerID, "name") - data['msg']=stripChars(msg) - data['all']=all - data['ucid']=net.get_player_info(playerID, 'ucid') - data['datetime']=os.date('%Y-%m-%d %H:%M:%S') - data['missionhash']=Perun.MissionHash - - Perun.SendToPerun(50,data) + Perun.AddLog("Sending chat message",2) + Perun.SendToPerun(50,_TempData) end Perun.LogEvent = function(log_type,log_content,log_arg_1,log_arg_2) -- Logs events messages + local _TempData={} + _TempData['log_type']= log_type + _TempData['log_arg_1']= log_arg_1 + _TempData['log_arg_2']= log_arg_2 + _TempData['log_content']=log_content + _TempData['log_datetime']=os.date('%Y-%m-%d %H:%M:%S') + _TempData['log_missionhash']=Perun.MissionHash - data={} - data['log_type']= log_type - data['log_arg_1']= log_arg_1 - data['log_arg_2']= log_arg_2 - data['log_content']=log_content - data['log_datetime']=os.date('%Y-%m-%d %H:%M:%S') - data['log_missionhash']=Perun.MissionHash - - Perun.SendToPerun(51,data) + Perun.AddLog("Sending event data, event: "..log_type .. ", arg1:" .. log_arg_1 .. ", arg2:" .. log_arg_2 .. ", content: " .. log_content,2) + Perun.SendToPerun(51,_TempData) end Perun.LogStatsCount = function(argPlayerID,argAction,argType) -- Creates or updates Perun statistics array - _ucid=net.get_player_info(argPlayerID, 'ucid')..argType + local _player_hash=net.get_player_info(argPlayerID, 'ucid')..argType - if Perun.StatData[_ucid] == nil then + if Perun.StatData[_player_hash] == nil then -- Create empty element - _temp={} - _temp['ps_type'] = argType - _temp['ps_pvp'] = 0 - _temp['ps_deaths'] = 0 - _temp['ps_ejections'] = 0 - _temp['ps_crashes'] = 0 - _temp['ps_teamkills'] = 0 - _temp['ps_kills_planes'] = 0 - _temp['ps_kills_helicopters'] = 0 - _temp['ps_kills_air_defense'] = 0 - _temp['ps_kills_armor'] = 0 - _temp['ps_kills_unarmed'] = 0 - _temp['ps_kills_infantry'] = 0 - _temp['ps_kills_ships'] = 0 - _temp['ps_kills_fortification'] = 0 - _temp['ps_kills_other'] = 0 - _temp['ps_airfield_takeoffs'] = 0 - _temp['ps_airfield_landings'] = 0 - _temp['ps_ship_takeoffs'] = 0 - _temp['ps_ship_landings'] = 0 - _temp['ps_farp_takeoffs'] = 0 - _temp['ps_farp_landings'] = 0 - _temp['ps_other_takeoffs'] = 0 - _temp['ps_other_landings'] = 0 + local _TempData={} + _TempData['ps_type'] = argType + _TempData['ps_pvp'] = 0 + _TempData['ps_deaths'] = 0 + _TempData['ps_ejections'] = 0 + _TempData['ps_crashes'] = 0 + _TempData['ps_teamkills'] = 0 + _TempData['ps_kills_planes'] = 0 + _TempData['ps_kills_helicopters'] = 0 + _TempData['ps_kills_air_defense'] = 0 + _TempData['ps_kills_armor'] = 0 + _TempData['ps_kills_unarmed'] = 0 + _TempData['ps_kills_infantry'] = 0 + _TempData['ps_kills_ships'] = 0 + _TempData['ps_kills_fortification'] = 0 + _TempData['ps_kills_other'] = 0 + _TempData['ps_airfield_takeoffs'] = 0 + _TempData['ps_airfield_landings'] = 0 + _TempData['ps_ship_takeoffs'] = 0 + _TempData['ps_ship_landings'] = 0 + _TempData['ps_farp_takeoffs'] = 0 + _TempData['ps_farp_landings'] = 0 + _TempData['ps_other_takeoffs'] = 0 + _TempData['ps_other_landings'] = 0 - Perun.StatData[_ucid]=_temp + Perun.StatData[_player_hash]=_TempData end if argType ~= nil then - Perun.StatData[_ucid]['ps_type']=argType; - Perun.StatDataLastType[net.get_player_info(argPlayerID, 'ucid')]=_ucid + Perun.StatData[_player_hash]['ps_type']=argType; + Perun.StatDataLastType[net.get_player_info(argPlayerID, 'ucid')]=_player_hash else -- Do nothing end if argAction == "eject" then - Perun.StatData[_ucid]['ps_ejections']=Perun.StatData[_ucid]['ps_ejections']+1 + Perun.StatData[_player_hash]['ps_ejections']=Perun.StatData[_player_hash]['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 + if DCS.getModelTime() > Perun.MissionStartNoDeathWindow then + -- we do not track deaths during mission startup due to spawning issues + Perun.StatData[_player_hash]['ps_deaths']=Perun.StatData[_player_hash]['ps_deaths']+1 end elseif argAction == "friendly_fire" then - Perun.StatData[_ucid]['ps_teamkills']=Perun.StatData[_ucid]['ps_teamkills']+1 + Perun.StatData[_player_hash]['ps_teamkills']=Perun.StatData[_player_hash]['ps_teamkills']+1 elseif argAction == "crash" then - Perun.StatData[_ucid]['ps_crashes']=Perun.StatData[_ucid]['ps_crashes']+1 + Perun.StatData[_player_hash]['ps_crashes']=Perun.StatData[_player_hash]['ps_crashes']+1 elseif argAction == "landing_FARP" then - Perun.StatData[_ucid]['ps_farp_landings']=Perun.StatData[_ucid]['ps_farp_landings']+1 + Perun.StatData[_player_hash]['ps_farp_landings']=Perun.StatData[_player_hash]['ps_farp_landings']+1 elseif argAction == "landing_SHIP" then - Perun.StatData[_ucid]['ps_ship_landings']=Perun.StatData[_ucid]['ps_ship_landings']+1 + Perun.StatData[_player_hash]['ps_ship_landings']=Perun.StatData[_player_hash]['ps_ship_landings']+1 elseif argAction == "landing_AIRFIELD" then - Perun.StatData[_ucid]['ps_airfield_landings']=Perun.StatData[_ucid]['ps_airfield_landings']+1 + Perun.StatData[_player_hash]['ps_airfield_landings']=Perun.StatData[_player_hash]['ps_airfield_landings']+1 elseif argAction == "tookoff_FARP" then - Perun.StatData[_ucid]['ps_farp_takeoffs']=Perun.StatData[_ucid]['ps_farp_takeoffs']+1 + Perun.StatData[_player_hash]['ps_farp_takeoffs']=Perun.StatData[_player_hash]['ps_farp_takeoffs']+1 elseif argAction == "tookoff_SHIP" then - Perun.StatData[_ucid]['ps_ship_takeoffs']=Perun.StatData[_ucid]['ps_ship_takeoffs']+1 + Perun.StatData[_player_hash]['ps_ship_takeoffs']=Perun.StatData[_player_hash]['ps_ship_takeoffs']+1 elseif argAction == "tookoff_AIRFIELD" then - Perun.StatData[_ucid]['ps_airfield_takeoffs']=Perun.StatData[_ucid]['ps_airfield_takeoffs']+1 + Perun.StatData[_player_hash]['ps_airfield_takeoffs']=Perun.StatData[_player_hash]['ps_airfield_takeoffs']+1 elseif argAction == "kill_Planes" then - Perun.StatData[_ucid]['ps_kills_planes']=Perun.StatData[_ucid]['ps_kills_planes']+1 + Perun.StatData[_player_hash]['ps_kills_planes']=Perun.StatData[_player_hash]['ps_kills_planes']+1 elseif argAction == "kill_Helicopters" then - Perun.StatData[_ucid]['ps_kills_helicopters']=Perun.StatData[_ucid]['ps_kills_helicopters']+1 + Perun.StatData[_player_hash]['ps_kills_helicopters']=Perun.StatData[_player_hash]['ps_kills_helicopters']+1 elseif argAction == "kill_Ships" then - Perun.StatData[_ucid]['ps_kills_ships']=Perun.StatData[_ucid]['ps_kills_ships']+1 + Perun.StatData[_player_hash]['ps_kills_ships']=Perun.StatData[_player_hash]['ps_kills_ships']+1 elseif argAction == "kill_Air_Defence" then - Perun.StatData[_ucid]['ps_kills_air_defense']=Perun.StatData[_ucid]['ps_kills_air_defense']+1 + Perun.StatData[_player_hash]['ps_kills_air_defense']=Perun.StatData[_player_hash]['ps_kills_air_defense']+1 elseif argAction == "kill_Unarmed" then - Perun.StatData[_ucid]['ps_kills_unarmed']=Perun.StatData[_ucid]['ps_kills_unarmed']+1 + Perun.StatData[_player_hash]['ps_kills_unarmed']=Perun.StatData[_player_hash]['ps_kills_unarmed']+1 elseif argAction == "kill_Armor" then - Perun.StatData[_ucid]['ps_kills_armor']=Perun.StatData[_ucid]['ps_kills_armor']+1 + Perun.StatData[_player_hash]['ps_kills_armor']=Perun.StatData[_player_hash]['ps_kills_armor']+1 elseif argAction == "kill_Infantry" then - Perun.StatData[_ucid]['ps_kills_infantry']=Perun.StatData[_ucid]['ps_kills_infantry']+1 + Perun.StatData[_player_hash]['ps_kills_infantry']=Perun.StatData[_player_hash]['ps_kills_infantry']+1 elseif argAction == "kill_Fortification" then - Perun.StatData[_ucid]['ps_kills_fortification']=Perun.StatData[_ucid]['ps_kills_fortification']+1 + Perun.StatData[_player_hash]['ps_kills_fortification']=Perun.StatData[_player_hash]['ps_kills_fortification']+1 elseif argAction == "kill_Other" then - Perun.StatData[_ucid]['ps_kills_other']=Perun.StatData[_ucid]['ps_kills_other']+1 + Perun.StatData[_player_hash]['ps_kills_other']=Perun.StatData[_player_hash]['ps_kills_other']+1 elseif argAction == "kill_PvP" then - Perun.StatData[_ucid]['ps_pvp']=Perun.StatData[_ucid]['ps_pvp']+1 + Perun.StatData[_player_hash]['ps_pvp']=Perun.StatData[_player_hash]['ps_pvp']+1 elseif argAction == "landing_OTHER" then - Perun.StatData[_ucid]['ps_other_landings']=Perun.StatData[_ucid]['ps_other_landings']+1 + Perun.StatData[_player_hash]['ps_other_landings']=Perun.StatData[_player_hash]['ps_other_landings']+1 elseif argAction == "tookoff_OTHER" then - Perun.StatData[_ucid]['ps_other_takeoffs']=Perun.StatData[_ucid]['ps_other_takeoffs']+1 + Perun.StatData[_player_hash]['ps_other_takeoffs']=Perun.StatData[_player_hash]['ps_other_takeoffs']+1 end + Perun.AddLog("Stats data prepared",2) Perun.LogStats(argPlayerID); end Perun.LogStatsGet = function(playerID) - -- Gets Perun statistics array per player - - local next = next + -- Gets Perun statistics array per player TBD rewrite + local next = next -- Make next function local - this improves performance TBD + local _player_hash = nil + if next(Perun.StatDataLastType) == nil then - _ucid=net.get_player_info(playerID, 'ucid')..DCS.getUnitType(playerID) + -- Array is empty + _player_hash=net.get_player_info(playerID, 'ucid')..DCS.getUnitType(playerID) elseif Perun.StatDataLastType[net.get_player_info(playerID, 'ucid')]== nil then - _ucid=net.get_player_info(playerID, 'ucid')..DCS.getUnitType(playerID) + -- Last type entry is empty + _player_hash=net.get_player_info(playerID, 'ucid')..DCS.getUnitType(playerID) else - _ucid=Perun.StatDataLastType[net.get_player_info(playerID, 'ucid')] + -- Return last type entry + _player_hash=Perun.StatDataLastType[net.get_player_info(playerID, 'ucid')] end - local next = next + local next = next -- Make next function local - this improves performance TBD if next(Perun.StatData) == nil then - Perun.LogStatsCount(playerID,'init') - + -- Array is empty + Perun.LogStatsCount(playerID,'init') -- Init statistics end - if Perun.StatData[_ucid]== nil then - Perun.LogStatsCount(playerID,'init') + if Perun.StatData[_player_hash]== nil then + -- Stats for player are empty + Perun.LogStatsCount(playerID,'init') -- Init statistics end - return Perun.StatData[_ucid]; + + Perun.AddLog("Getting stats data",2) + return Perun.StatData[_player_hash]; end Perun.LogStats = function(playerID) -- Log player status - - -- TBD : DCS stats not working at the moment WIP - p_stats_dcs={} - p_stats_dcs['PS_CAR']=net.get_stat(playerID,2) - p_stats_dcs['PS_PLANE']=net.get_stat(playerID,3) - p_stats_dcs['PS_SHIP']=net.get_stat(playerID,4) - p_stats_dcs['PS_SCORE']=net.get_stat(playerID,5) - p_stats_dcs['PS_LAND']=net.get_stat(playerID,6) - p_stats_dcs['PS_PING']=net.get_stat(playerID,0) - p_stats_dcs['PS_CRASH']=net.get_stat(playerID,1) - p_stats_dcs['PS_EJECT']=net.get_stat(playerID,7) - - _temp=Perun.LogStatsGet(playerID) - data={} - data['stat_data_dcs']=p_stats_dcs - 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 + local _PlayerStatsTable=Perun.LogStatsGet(playerID) + local _TempData={} + _TempData['stat_data_perun']=_PlayerStatsTable + _TempData['stat_data_type']=_PlayerStatsTable['ps_type']; + _TempData['stat_ucid']=net.get_player_info(playerID, 'ucid') + _TempData['stat_name']=net.get_player_info(playerID, 'name') + _TempData['stat_datetime']=os.date('%Y-%m-%d %H:%M:%S') + _TempData['stat_missionhash']=Perun.MissionHash - Perun.SendToPerun(52,data) + Perun.AddLog("Sending stats data",2) + Perun.SendToPerun(52,_TempData) end Perun.LogLogin = function(playerID) -- Player logged in + local _TempData={} + _TempData['login_ucid']=net.get_player_info(playerID, 'ucid') + _TempData['login_ipaddr']=net.get_player_info(playerID, 'ipaddr') + _TempData['login_name']=net.get_player_info(playerID, 'name') + _TempData['login_datetime']=os.date('%Y-%m-%d %H:%M:%S') - data={} - data['login_ucid']=net.get_player_info(playerID, 'ucid') - data['login_ipaddr']=net.get_player_info(playerID, 'ipaddr') - data['login_name']=net.get_player_info(playerID, 'name') - data['login_datetime']=os.date('%Y-%m-%d %H:%M:%S') - - Perun.SendToPerun(53,data) + Perun.AddLog("Sending login event",2) + Perun.SendToPerun(53,_TempData) end Perun.CheckMulticrew = function (owner_playerID,owner_unittype) -- Check multicrew and return list of co-player - _coplayers = {} + local _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') + local _owner_slot=net.get_player_info(owner_playerID, 'slot') + local _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 + local _master_slot = nil + local _sub_slot = nil if _t_start then -- This is co-player _master_slot = string.sub(_owner_slot, 0 , _t_start -1 ) @@ -507,7 +517,7 @@ Perun.CheckMulticrew = function (owner_playerID,owner_unittype) if _master_slot ~= "" then -- Search for all players to account for event - _all_players = net.get_player_list() + local _all_players = net.get_player_list() for PlayerIDIndex, playerID in ipairs(_all_players) do local _playerDetails = net.get_player_info( playerID ) @@ -520,6 +530,8 @@ Perun.CheckMulticrew = function (owner_playerID,owner_unittype) end end end + + Perun.AddLog("Multicrew check completed",2) return _coplayers end @@ -527,24 +539,31 @@ end --- ########### Event callbacks ########### Perun.onSimulationStart = function() + -- Simulation was started Perun.MissionHash=DCS.getMissionName( ).."@".. Perun.Instance .. "@"..os.date('%Y%m%d_%H%M%S'); Perun.LogEvent("SimStart","Mission " .. Perun.MissionHash .. " started",nil,nil); Perun.StatData = {} Perun.StatDataLastType = {} + -- TBD send this to Perun end Perun.onSimulationStop = function() + -- Simulation was stopped Perun.LogEvent("SimStop","Mission " .. Perun.MissionHash .. " finished",nil,nil); Perun.MissionHash=""; Perun.StatData = {} Perun.StatDataLastType = {} + -- TBD send this to Perun end Perun.onPlayerDisconnect = function(id, err_code) + -- Player disconnected - TBD DCS Bug, this is not triggered at this point of time Perun.LogEvent("disconnect", "Player " .. net.get_player_info(id, "name") .. " disconnected; " .. err_code,net.get_player_info(id, "name"),err_code); + -- TBD send this to Perun end Perun.onSimulationFrame = function() + -- Repeat for each simulator frame local _now = DCS.getRealTime() -- First run @@ -568,18 +587,22 @@ Perun.onSimulationFrame = function() end -- Send keepalive - if _now > Perun.lastSentKeepAlive + 3 then + if _now > Perun.lastSentKeepAlive + Perun.SendRetries then Perun.lastSentKeepAlive = _now Perun.SendToPerun(0,nil) end end Perun.onPlayerStart = function (id) + -- Player entered cocpit net.send_chat_to(Perun.MOTD_L1, id); net.send_chat_to(Perun.MOTD_L2, id); + + Perun.AddLog("Player entered the game",2) end Perun.onPlayerTrySendChat = function (playerID, msg, all) + -- Somebody tries to send chat message if msg~=Perun.MOTD_L1 and msg~=Perun.MOTD_L2 then Perun.LogChat(playerID,msg,all) end @@ -588,6 +611,8 @@ Perun.onPlayerTrySendChat = function (playerID, msg, all) end Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) + -- Game event has occured + Perun.AddLog("Event handler for "..eventName .. " started",2) if eventName == "friendly_fire" then --"friendly_fire", playerID, weaponName, victimPlayerID if arg2 == "" then @@ -602,17 +627,17 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) elseif eventName == "kill" then --"kill", killerPlayerID, killerUnitType, killerSide, victimPlayerID, victimUnitType, victimSide, weaponName - _tempX="" + local _temp_victim="" if net.get_player_info(arg4, "name") ~= nil then - _tempX = " player ".. net.get_player_info(arg4, "name") .." "; + _temp_victim = " player ".. net.get_player_info(arg4, "name") .." "; Perun.LogStats(arg4); else - _tempX = " AI "; + _temp_victim = " AI "; end if net.get_player_info(arg1, "name") ~= nil then - _temp2 = " player ".. net.get_player_info(arg1, "name") .." "; + _temp_killer = " player ".. net.get_player_info(arg1, "name") .." "; _temp_event_type="" if arg3 ~= arg6 then @@ -651,30 +676,32 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) end else - _temp2 = " AI "; + _temp_killer = " AI "; end if arg7 == "" then arg7 = "Cannon" end - Perun.LogEvent(eventName,Perun.SideID2Name(arg3) .. _temp2 .. " in " .. arg2 .. " killed " .. Perun.SideID2Name(arg6) .. _tempX .. " in " .. arg5 .. " using " .. arg7 .. " [".. Perun.GetCategory(arg5).."]",arg7,Perun.GetCategory(arg5)); + Perun.LogEvent(eventName,Perun.SideID2Name(arg3) .. _temp_killer .. " in " .. arg2 .. " killed " .. Perun.SideID2Name(arg6) .. _temp_victim .. " in " .. arg5 .. " using " .. arg7 .. " [".. Perun.GetCategory(arg5).."]",arg7,Perun.GetCategory(arg5)); + elseif eventName == "self_kill" then --"self_kill", playerID + Perun.LogStats(arg1); Perun.LogEvent(eventName,net.get_player_info(arg1, "name") .. " killed himself",nil,nil); - Perun.LogStats(arg1); elseif eventName == "change_slot" then --"change_slot", playerID, slotID, prevSide if DCS.getUnitType(arg2) ~= nil and DCS.getUnitType(arg2) ~= "" then - _temp = DCS.getUnitType(arg2); + _temp_slot = DCS.getUnitType(arg2); else - _temp = "SPECTATOR"; + _temp_slot = "SPECTATOR"; end - Perun.LogEvent(eventName,Perun.SideID2Name( net.get_player_info(arg1, "side")) .. " player " .. net.get_player_info(arg1, "name") .. " changed slot to " .. _temp,nil,nil); - Perun.LogStatsCount(arg1,"init",_temp) + Perun.LogStatsCount(arg1,"init",_temp_slot) + Perun.LogEvent(eventName,Perun.SideID2Name( net.get_player_info(arg1, "side")) .. " player " .. net.get_player_info(arg1, "name") .. " changed slot to " .. _temp_slot,nil,nil); + elseif eventName == "connect" then --"connect", playerID, name @@ -683,52 +710,50 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) elseif eventName == "disconnect" then --"disconnect", playerID, name, playerSide, reason_code + Perun.LogStats(arg1); Perun.LogEvent(eventName, Perun.SideID2Name(arg3) .. " player " ..net.get_player_info(arg1, "name") .. " disconnected",nil,nil); - Perun.LogStats(arg1); 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); - pilots_accounted = Perun.CheckMulticrew(arg1,DCS.getUnitType(arg2)) for _, pilotID in ipairs(pilots_accounted) do Perun.LogStatsCount(pilotID,"crash",DCS.getUnitType(arg2)); end + 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); + 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); - pilots_accounted = Perun.CheckMulticrew(arg1,DCS.getUnitType(arg2)) for _, pilotID in ipairs(pilots_accounted) do Perun.LogStatsCount(pilotID,"eject",DCS.getUnitType(arg2)); end - + Perun.LogEvent(eventName, Perun.SideID2Name( net.get_player_info(arg1, "side")) .. " player " .. net.get_player_info(arg1, "name") .. " ejected " .. DCS.getUnitType(arg2),nil,nil); + elseif eventName == "takeoff" then --"takeoff", playerID, unit_missionID, airdromeName if arg3 ~= "" then - _temp = " from " .. arg3; + _temp_airfield = " from " .. arg3; else - _temp = ""; + _temp_airfield = ""; end - 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 = "" + _temp_type = "" if string.find(arg3, "FARP",1,true) then - _type="tookoff_FARP" - elseif string.find(arg3, "CVN-74 John C. Stennis",1,true) or string.find(arg3, "LHA-1 Tarawa",1,true) then - _type="tookoff_SHIP" + _temp_type="tookoff_FARP" + elseif string.find(arg3, "CVN-74 John C. Stennis",1,true) or string.find(arg3, "LHA-1 Tarawa",1,true) or string.find(arg3, "SHIP",1,true) then + _temp_type="tookoff_SHIP" elseif arg3 ~= "" then - _type="tookoff_AIRFIELD" + _temp_type="tookoff_AIRFIELD" else - _type="tookoff_OTHER" + _temp_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)) + Perun.LogStatsCount(pilotID,_temp_type,DCS.getUnitType(arg2)) end - + 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_airfield,arg3,nil); + elseif eventName == "landing" then --"landing", playerID, unit_missionID, airdromeName if arg3 ~= "" then @@ -737,42 +762,42 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) _temp =""; end - 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 = "" + _temp_type = "" if string.find(arg3, "FARP",1,true) then - _type = "landing_FARP" - elseif string.find(arg3, "CVN-74 John C. Stennis",1,true) or string.find(arg3, "LHA-1 Tarawa",1,true) then - _type = "landing_SHIP" + _temp_type = "landing_FARP" + elseif string.find(arg3, "CVN-74 John C. Stennis",1,true) or string.find(arg3, "LHA-1 Tarawa",1,true) or string.find(arg3, "SHIP",1,true) then + _temp_type = "landing_SHIP" elseif arg3 ~= "" then - _type = "landing_AIRFIELD" + _temp_type = "landing_AIRFIELD" else - _type = "landing_OTHER" + _temp_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)) + Perun.LogStatsCount(pilotID,_temp_type,DCS.getUnitType(arg2)) end - + 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); + 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); - pilots_accounted = Perun.CheckMulticrew(arg1,DCS.getUnitType(arg2)) for _, pilotID in ipairs(pilots_accounted) do Perun.LogStatsCount(pilotID,"pilot_death",DCS.getUnitType(arg2)) end - + 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); + else Perun.LogEvent(eventName,"Unknown event type",nil,nil); - end + end + Perun.AddLog("Event handler for "..eventName .. " finished",2) end -- ########### Finalize and set callbacks ########### if Perun.IsServer then - DCS.setUserCallbacks(Perun) - net.log("Perun by VladMordock was loaded: " .. Perun.Version ) - Perun.ConnectToPerun() + -- If this game instance is hosting multiplayer game, start Perun + DCS.setUserCallbacks(Perun) -- Set user callbacs, map DCS event handlers with functions defined above + net.log("Perun by VladMordock was loaded: " .. Perun.Version ) -- Display perun information in log + Perun.ConnectToPerun() -- Connect to Perun server end From 6d64f7f6e006cd6822a3396bf29187fc98f7faee Mon Sep 17 00:00:00 2001 From: szporowolik Date: Thu, 24 Oct 2019 00:30:31 +0200 Subject: [PATCH 04/17] Huge Lua improvments for multicrew support --- 01_DCS/Hooks/Perun.lua | 596 +++++++++++++++++++++++------------------ 1 file changed, 329 insertions(+), 267 deletions(-) diff --git a/01_DCS/Hooks/Perun.lua b/01_DCS/Hooks/Perun.lua index a1ba6a9..b50736e 100644 --- a/01_DCS/Hooks/Perun.lua +++ b/01_DCS/Hooks/Perun.lua @@ -40,7 +40,7 @@ Perun.JsonStatusLocation = lfs.writedir() .. Perun.JsonStatusLocation Perun.socket = require("socket") Perun.IsServer = true --DCS.isServer( ) -- TBD looks like DCS API error, always returning True --- ########### Helper function definitions ########### +-- ################################ Helper function definitions ################################ function stripChars(str) -- Hellper functions removes accents characters from string -- via https://stackoverflow.com/questions/50459102/replace-accented-characters-in-string-to-standard-with-lua @@ -161,8 +161,6 @@ Perun.SideID2Name = function(id) return _sides[id] end --- ########### Main code ########### - Perun.AddLog = function(text,LogLevel) -- Adds logs to DCS.log file LogLevel = LogLevel or 1 @@ -171,21 +169,103 @@ Perun.AddLog = function(text,LogLevel) end end -Perun.UpdateJsonStatus = function() - -- Updates status json file - local _TempData={} - _TempData["1"]=Perun.ServerData - _TempData["2"]=Perun.StatusData - _TempData["3"]=Perun.SlotsData - -- _TempData["4"]=Perun.MissionData -- TBD: hangs for some large missions - - -- Export data to JSON file - local _perun_export = io.open(Perun.JsonStatusLocation .. "perun_status_data.json", "w") - _perun_export:write(net.lua2json(_TempData) .. "\n") - _perun_export:close() - Perun.AddLog("Updated JSON",2) +Perun.GenerateMissionHash = function() + -- Generates unique simulation mission hash + return DCS.getMissionName( ).."@".. Perun.Instance .. "@" .. Perun.Version .. "@".. os.date('%Y%m%d_%H%M%S') end +Perun.GetMulticrewAllParameters = function (PlayerId) + -- Gets all multicrew parameters + local _result = "" + local _player_slot=net.get_player_info(PlayerId, 'slot') + local _master_type= "?" + local _master_slot = nil + local _sub_slot = nil + + if _player_slot and _player_slot ~= '' and not (string.find(_player_slot, 'red') or string.find(_player_slot, 'blue')) then + -- Player took model + _master_slot = _player_slot + _sub_slot =0 + + if (not tonumber(_player_slot)) then + -- If this is multiseat slot parse master slot and look for seat number + _t_start, _t_end = string.find(_player_slot, '_%d+') + + if _t_start then + -- This is co-player + _master_slot = string.sub(_player_slot, 0 , _t_start -1 ) + _sub_slot = string.sub(_player_slot, _t_start + 1, _t_end ) + end + end + _master_type = DCS.getUnitType(_master_slot) + + elseif string.find(_player_slot, 'red') or string.find(_player_slot, 'blue') then + -- Deal with the special slots addded by Combined Arms and Spectators + if string.find(_player_slot, 'artillery_commander') then + _master_type = "artillery_commander" + elseif string.find(_player_slot, 'instructor') then + _master_type = "instructor" + elseif string.find(_player_slot, 'forward_observer') then + _master_type = "forward_observer" + elseif string.find(_player_slot, 'observer') then + _master_type = "observer" + end + end + return _master_type,_master_slot,_sub_slot +end + +Perun.GetMulticrewParameter = function (PlayerId,Parameter) + -- Get specific multicrew Parameter + _master_type,_master_slot,_sub_slot = Perun.GetMulticrewAllParameters(PlayerId) + + if Parameter == "mastertype" then + return _master_type + elseif Parameter == "masterslot" then + return _master_slot + elseif Parameter == "subslot" then + return _sub_slot + elseif Parameter == "subtype" then + if _sub_slot == 0 then + return _master_type + else + return _master_type .. "_" .. _sub_slot + end + else + return nil + end +end + +Perun.GetMulticrewCrew = function (owner_playerID) + -- Get all multicrew crew + _master_type,_master_slot,_sub_slot = Perun.GetMulticrewAllParameters(owner_playerID) + + local _crew = {} + table.insert(_crew, owner_playerID) + if _master_type == "F-14B" or _master_type == "Yak-52" or _master_type == "L-39C" or _master_type == "SA342M" or _master_type =="SA342Minigun" or _master_type == "SA342Mistral" or _master_type == "SA342L" then -- TBD add additional multicrew model types + local _owner_side=net.get_player_info(owner_playerID, 'side') + + if _master_slot and _master_slot ~= "" then + -- Search for all players from crew + local _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" or _playerDetails.slot == _master_slot .. "_3" or _playerDetails.slot == _master_slot .. "_4") and _playerID ~= owner_playerID then + -- Add to crew list + table.insert(_crew, _playerID) + else + -- Do nothing + end + end + end + end + + Perun.AddLog("Multicrew check completed: " .. net.lua2json(_crew),2) + return _crew +end + +-- ################################ TCP Connection ################################ + Perun.ConnectToPerun = function () -- Connects to Perun server Perun.AddLog("Connecting to TCP server",2) @@ -239,6 +319,213 @@ Perun.SendToPerun = function(data_id, data_package) end end +-- ################################ Log functions ################################ + +Perun.LogChat = function(playerID,msg,all) + -- Logs chat messages + local _TempData={} + _TempData['player']= net.get_player_info(playerID, "name") + _TempData['msg']=stripChars(msg) + _TempData['all']=all + _TempData['ucid']=net.get_player_info(playerID, 'ucid') + _TempData['datetime']=os.date('%Y-%m-%d %H:%M:%S') + _TempData['missionhash']=Perun.MissionHash + + Perun.AddLog("Sending chat message",2) + Perun.SendToPerun(50,_TempData) +end + +Perun.LogEvent = function(log_type,log_content,log_arg_1,log_arg_2) + -- Logs events messages + local _TempData={} + _TempData['log_type']= log_type + _TempData['log_arg_1']= log_arg_1 + _TempData['log_arg_2']= log_arg_2 + _TempData['log_content']=log_content + _TempData['log_datetime']=os.date('%Y-%m-%d %H:%M:%S') + _TempData['log_missionhash']=Perun.MissionHash + + if log_arg_1 == nil then + log_arg_1 = "null" + end + if log_arg_2 == nil then + log_arg_2 = "null" + end + + Perun.AddLog("Sending event data, event: " .. log_type .. ", arg1:" .. log_arg_1 .. ", arg2:" .. log_arg_2 .. ", content: " .. log_content,2) + Perun.SendToPerun(51,_TempData) +end + +Perun.LogStats = function(playerID) + -- Log player status + local _PlayerStatsTable=Perun.LogStatsGet(playerID) + local _TempData={} + _TempData['stat_data_perun']=_PlayerStatsTable + _TempData['stat_data_type']=_PlayerStatsTable['ps_type']; + _TempData['stat_ucid']=net.get_player_info(playerID, 'ucid') + _TempData['stat_name']=net.get_player_info(playerID, 'name') + _TempData['stat_datetime']=os.date('%Y-%m-%d %H:%M:%S') + _TempData['stat_missionhash']=Perun.MissionHash + + Perun.AddLog("Sending stats data",2) + Perun.SendToPerun(52,_TempData) +end + +Perun.LogLogin = function(playerID) + -- Player logged in + local _TempData={} + _TempData['login_ucid']=net.get_player_info(playerID, 'ucid') + _TempData['login_ipaddr']=net.get_player_info(playerID, 'ipaddr') + _TempData['login_name']=net.get_player_info(playerID, 'name') + _TempData['login_datetime']=os.date('%Y-%m-%d %H:%M:%S') + + Perun.AddLog("Sending login event",2) + Perun.SendToPerun(53,_TempData) +end + +--- ################################ Calculate stats ################################ + +Perun.LogStatsCount = function(argPlayerID,argAction) + -- Creates or updates Perun statistics array + local _player_hash=net.get_player_info(argPlayerID, 'ucid')..Perun.GetMulticrewParameter(argPlayerID,"subtype") + + if Perun.StatData[_player_hash] == nil then + -- Create empty element + local _TempData={} + _TempData['ps_type'] = Perun.GetMulticrewParameter(argPlayerID,"subtype") + _TempData['ps_pvp'] = 0 + _TempData['ps_deaths'] = 0 + _TempData['ps_ejections'] = 0 + _TempData['ps_crashes'] = 0 + _TempData['ps_teamkills'] = 0 + _TempData['ps_kills_planes'] = 0 + _TempData['ps_kills_helicopters'] = 0 + _TempData['ps_kills_air_defense'] = 0 + _TempData['ps_kills_armor'] = 0 + _TempData['ps_kills_unarmed'] = 0 + _TempData['ps_kills_infantry'] = 0 + _TempData['ps_kills_ships'] = 0 + _TempData['ps_kills_fortification'] = 0 + _TempData['ps_kills_other'] = 0 + _TempData['ps_airfield_takeoffs'] = 0 + _TempData['ps_airfield_landings'] = 0 + _TempData['ps_ship_takeoffs'] = 0 + _TempData['ps_ship_landings'] = 0 + _TempData['ps_farp_takeoffs'] = 0 + _TempData['ps_farp_landings'] = 0 + _TempData['ps_other_takeoffs'] = 0 + _TempData['ps_other_landings'] = 0 + + Perun.StatData[_player_hash]=_TempData + end + + if argType ~= nil then + Perun.StatData[_player_hash]['ps_type']=Perun.GetMulticrewParameter(argPlayerID,"subtype"); + Perun.StatDataLastType[net.get_player_info(argPlayerID, 'ucid')]=_player_hash + else + -- Do nothing + end + + if argAction == "eject" then + Perun.StatData[_player_hash]['ps_ejections']=Perun.StatData[_player_hash]['ps_ejections']+1 + elseif argAction == "pilot_death" then + if DCS.getModelTime() > Perun.MissionStartNoDeathWindow then + -- we do not track deaths during mission startup due to spawning issues + Perun.StatData[_player_hash]['ps_deaths']=Perun.StatData[_player_hash]['ps_deaths']+1 + end + elseif argAction == "friendly_fire" then + Perun.StatData[_player_hash]['ps_teamkills']=Perun.StatData[_player_hash]['ps_teamkills']+1 + elseif argAction == "crash" then + Perun.StatData[_player_hash]['ps_crashes']=Perun.StatData[_player_hash]['ps_crashes']+1 + elseif argAction == "landing_FARP" then + Perun.StatData[_player_hash]['ps_farp_landings']=Perun.StatData[_player_hash]['ps_farp_landings']+1 + elseif argAction == "landing_SHIP" then + Perun.StatData[_player_hash]['ps_ship_landings']=Perun.StatData[_player_hash]['ps_ship_landings']+1 + elseif argAction == "landing_AIRFIELD" then + Perun.StatData[_player_hash]['ps_airfield_landings']=Perun.StatData[_player_hash]['ps_airfield_landings']+1 + elseif argAction == "tookoff_FARP" then + Perun.StatData[_player_hash]['ps_farp_takeoffs']=Perun.StatData[_player_hash]['ps_farp_takeoffs']+1 + elseif argAction == "tookoff_SHIP" then + Perun.StatData[_player_hash]['ps_ship_takeoffs']=Perun.StatData[_player_hash]['ps_ship_takeoffs']+1 + elseif argAction == "tookoff_AIRFIELD" then + Perun.StatData[_player_hash]['ps_airfield_takeoffs']=Perun.StatData[_player_hash]['ps_airfield_takeoffs']+1 + elseif argAction == "kill_Planes" then + Perun.StatData[_player_hash]['ps_kills_planes']=Perun.StatData[_player_hash]['ps_kills_planes']+1 + elseif argAction == "kill_Helicopters" then + Perun.StatData[_player_hash]['ps_kills_helicopters']=Perun.StatData[_player_hash]['ps_kills_helicopters']+1 + elseif argAction == "kill_Ships" then + Perun.StatData[_player_hash]['ps_kills_ships']=Perun.StatData[_player_hash]['ps_kills_ships']+1 + elseif argAction == "kill_Air_Defence" then + Perun.StatData[_player_hash]['ps_kills_air_defense']=Perun.StatData[_player_hash]['ps_kills_air_defense']+1 + elseif argAction == "kill_Unarmed" then + Perun.StatData[_player_hash]['ps_kills_unarmed']=Perun.StatData[_player_hash]['ps_kills_unarmed']+1 + elseif argAction == "kill_Armor" then + Perun.StatData[_player_hash]['ps_kills_armor']=Perun.StatData[_player_hash]['ps_kills_armor']+1 + elseif argAction == "kill_Infantry" then + Perun.StatData[_player_hash]['ps_kills_infantry']=Perun.StatData[_player_hash]['ps_kills_infantry']+1 + elseif argAction == "kill_Fortification" then + Perun.StatData[_player_hash]['ps_kills_fortification']=Perun.StatData[_player_hash]['ps_kills_fortification']+1 + elseif argAction == "kill_Other" then + Perun.StatData[_player_hash]['ps_kills_other']=Perun.StatData[_player_hash]['ps_kills_other']+1 + elseif argAction == "kill_PvP" then + Perun.StatData[_player_hash]['ps_pvp']=Perun.StatData[_player_hash]['ps_pvp']+1 + elseif argAction == "landing_OTHER" then + Perun.StatData[_player_hash]['ps_other_landings']=Perun.StatData[_player_hash]['ps_other_landings']+1 + elseif argAction == "tookoff_OTHER" then + Perun.StatData[_player_hash]['ps_other_takeoffs']=Perun.StatData[_player_hash]['ps_other_takeoffs']+1 + end + + Perun.AddLog("Stats data prepared",2) + Perun.LogStats(argPlayerID); +end + +-- ################################ Data preparation ################################ + +Perun.LogStatsGet = function(playerID) + -- Gets Perun statistics array per player TBD rewrite + local next = next -- Make next function local - this improves performance TBD + local _player_hash = nil + + if next(Perun.StatDataLastType) == nil then + -- Array is empty + _player_hash=net.get_player_info(playerID, 'ucid')..Perun.GetMulticrewParameter(playerID,"subtype") + elseif Perun.StatDataLastType[net.get_player_info(playerID, 'ucid')]== nil then + -- Last type entry is empty + _player_hash=net.get_player_info(playerID, 'ucid')..Perun.GetMulticrewParameter(playerID,"subtype") + else + -- Return last type entry + _player_hash=Perun.StatDataLastType[net.get_player_info(playerID, 'ucid')] + end + + local next = next -- Make next function local - this improves performance TBD + if next(Perun.StatData) == nil then + -- Array is empty + Perun.LogStatsCount(playerID,'init') -- Init statistics + end + if Perun.StatData[_player_hash]== nil then + -- Stats for player are empty + Perun.LogStatsCount(playerID,'init') -- Init statistics + end + + Perun.AddLog("Getting stats data",2) + return Perun.StatData[_player_hash]; +end + +Perun.UpdateJsonStatus = function() + -- Updates status json file + local _TempData={} + _TempData["1"]=Perun.ServerData + _TempData["2"]=Perun.StatusData + _TempData["3"]=Perun.SlotsData + -- _TempData["4"]=Perun.MissionData -- TBD: hangs for some large missions + + -- Export data to JSON file + local _perun_export = io.open(Perun.JsonStatusLocation .. "perun_status_data.json", "w") + _perun_export:write(net.lua2json(_TempData) .. "\n") + _perun_export:close() + Perun.AddLog("Updated JSON",2) +end + Perun.UpdateStatus = function() -- Main function for status updates @@ -312,235 +599,11 @@ Perun.UpdateMission = function() Perun.AddLog("Mission data updated",2) end -Perun.LogChat = function(playerID,msg,all) - -- Logs chat messages - local _TempData={} - _TempData['player']= net.get_player_info(playerID, "name") - _TempData['msg']=stripChars(msg) - _TempData['all']=all - _TempData['ucid']=net.get_player_info(playerID, 'ucid') - _TempData['datetime']=os.date('%Y-%m-%d %H:%M:%S') - _TempData['missionhash']=Perun.MissionHash - - Perun.AddLog("Sending chat message",2) - Perun.SendToPerun(50,_TempData) -end - -Perun.LogEvent = function(log_type,log_content,log_arg_1,log_arg_2) - -- Logs events messages - local _TempData={} - _TempData['log_type']= log_type - _TempData['log_arg_1']= log_arg_1 - _TempData['log_arg_2']= log_arg_2 - _TempData['log_content']=log_content - _TempData['log_datetime']=os.date('%Y-%m-%d %H:%M:%S') - _TempData['log_missionhash']=Perun.MissionHash - - Perun.AddLog("Sending event data, event: "..log_type .. ", arg1:" .. log_arg_1 .. ", arg2:" .. log_arg_2 .. ", content: " .. log_content,2) - Perun.SendToPerun(51,_TempData) -end - -Perun.LogStatsCount = function(argPlayerID,argAction,argType) - -- Creates or updates Perun statistics array - local _player_hash=net.get_player_info(argPlayerID, 'ucid')..argType - - if Perun.StatData[_player_hash] == nil then - -- Create empty element - local _TempData={} - _TempData['ps_type'] = argType - _TempData['ps_pvp'] = 0 - _TempData['ps_deaths'] = 0 - _TempData['ps_ejections'] = 0 - _TempData['ps_crashes'] = 0 - _TempData['ps_teamkills'] = 0 - _TempData['ps_kills_planes'] = 0 - _TempData['ps_kills_helicopters'] = 0 - _TempData['ps_kills_air_defense'] = 0 - _TempData['ps_kills_armor'] = 0 - _TempData['ps_kills_unarmed'] = 0 - _TempData['ps_kills_infantry'] = 0 - _TempData['ps_kills_ships'] = 0 - _TempData['ps_kills_fortification'] = 0 - _TempData['ps_kills_other'] = 0 - _TempData['ps_airfield_takeoffs'] = 0 - _TempData['ps_airfield_landings'] = 0 - _TempData['ps_ship_takeoffs'] = 0 - _TempData['ps_ship_landings'] = 0 - _TempData['ps_farp_takeoffs'] = 0 - _TempData['ps_farp_landings'] = 0 - _TempData['ps_other_takeoffs'] = 0 - _TempData['ps_other_landings'] = 0 - - Perun.StatData[_player_hash]=_TempData - end - - if argType ~= nil then - Perun.StatData[_player_hash]['ps_type']=argType; - Perun.StatDataLastType[net.get_player_info(argPlayerID, 'ucid')]=_player_hash - else - -- Do nothing - end - - if argAction == "eject" then - Perun.StatData[_player_hash]['ps_ejections']=Perun.StatData[_player_hash]['ps_ejections']+1 - elseif argAction == "pilot_death" then - if DCS.getModelTime() > Perun.MissionStartNoDeathWindow then - -- we do not track deaths during mission startup due to spawning issues - Perun.StatData[_player_hash]['ps_deaths']=Perun.StatData[_player_hash]['ps_deaths']+1 - end - elseif argAction == "friendly_fire" then - Perun.StatData[_player_hash]['ps_teamkills']=Perun.StatData[_player_hash]['ps_teamkills']+1 - elseif argAction == "crash" then - Perun.StatData[_player_hash]['ps_crashes']=Perun.StatData[_player_hash]['ps_crashes']+1 - elseif argAction == "landing_FARP" then - Perun.StatData[_player_hash]['ps_farp_landings']=Perun.StatData[_player_hash]['ps_farp_landings']+1 - elseif argAction == "landing_SHIP" then - Perun.StatData[_player_hash]['ps_ship_landings']=Perun.StatData[_player_hash]['ps_ship_landings']+1 - elseif argAction == "landing_AIRFIELD" then - Perun.StatData[_player_hash]['ps_airfield_landings']=Perun.StatData[_player_hash]['ps_airfield_landings']+1 - elseif argAction == "tookoff_FARP" then - Perun.StatData[_player_hash]['ps_farp_takeoffs']=Perun.StatData[_player_hash]['ps_farp_takeoffs']+1 - elseif argAction == "tookoff_SHIP" then - Perun.StatData[_player_hash]['ps_ship_takeoffs']=Perun.StatData[_player_hash]['ps_ship_takeoffs']+1 - elseif argAction == "tookoff_AIRFIELD" then - Perun.StatData[_player_hash]['ps_airfield_takeoffs']=Perun.StatData[_player_hash]['ps_airfield_takeoffs']+1 - elseif argAction == "kill_Planes" then - Perun.StatData[_player_hash]['ps_kills_planes']=Perun.StatData[_player_hash]['ps_kills_planes']+1 - elseif argAction == "kill_Helicopters" then - Perun.StatData[_player_hash]['ps_kills_helicopters']=Perun.StatData[_player_hash]['ps_kills_helicopters']+1 - elseif argAction == "kill_Ships" then - Perun.StatData[_player_hash]['ps_kills_ships']=Perun.StatData[_player_hash]['ps_kills_ships']+1 - elseif argAction == "kill_Air_Defence" then - Perun.StatData[_player_hash]['ps_kills_air_defense']=Perun.StatData[_player_hash]['ps_kills_air_defense']+1 - elseif argAction == "kill_Unarmed" then - Perun.StatData[_player_hash]['ps_kills_unarmed']=Perun.StatData[_player_hash]['ps_kills_unarmed']+1 - elseif argAction == "kill_Armor" then - Perun.StatData[_player_hash]['ps_kills_armor']=Perun.StatData[_player_hash]['ps_kills_armor']+1 - elseif argAction == "kill_Infantry" then - Perun.StatData[_player_hash]['ps_kills_infantry']=Perun.StatData[_player_hash]['ps_kills_infantry']+1 - elseif argAction == "kill_Fortification" then - Perun.StatData[_player_hash]['ps_kills_fortification']=Perun.StatData[_player_hash]['ps_kills_fortification']+1 - elseif argAction == "kill_Other" then - Perun.StatData[_player_hash]['ps_kills_other']=Perun.StatData[_player_hash]['ps_kills_other']+1 - elseif argAction == "kill_PvP" then - Perun.StatData[_player_hash]['ps_pvp']=Perun.StatData[_player_hash]['ps_pvp']+1 - elseif argAction == "landing_OTHER" then - Perun.StatData[_player_hash]['ps_other_landings']=Perun.StatData[_player_hash]['ps_other_landings']+1 - elseif argAction == "tookoff_OTHER" then - Perun.StatData[_player_hash]['ps_other_takeoffs']=Perun.StatData[_player_hash]['ps_other_takeoffs']+1 - end - - Perun.AddLog("Stats data prepared",2) - Perun.LogStats(argPlayerID); -end - -Perun.LogStatsGet = function(playerID) - -- Gets Perun statistics array per player TBD rewrite - local next = next -- Make next function local - this improves performance TBD - local _player_hash = nil - - if next(Perun.StatDataLastType) == nil then - -- Array is empty - _player_hash=net.get_player_info(playerID, 'ucid')..DCS.getUnitType(playerID) - elseif Perun.StatDataLastType[net.get_player_info(playerID, 'ucid')]== nil then - -- Last type entry is empty - _player_hash=net.get_player_info(playerID, 'ucid')..DCS.getUnitType(playerID) - else - -- Return last type entry - _player_hash=Perun.StatDataLastType[net.get_player_info(playerID, 'ucid')] - end - - local next = next -- Make next function local - this improves performance TBD - if next(Perun.StatData) == nil then - -- Array is empty - Perun.LogStatsCount(playerID,'init') -- Init statistics - end - if Perun.StatData[_player_hash]== nil then - -- Stats for player are empty - Perun.LogStatsCount(playerID,'init') -- Init statistics - end - - Perun.AddLog("Getting stats data",2) - return Perun.StatData[_player_hash]; -end - - - -Perun.LogStats = function(playerID) - -- Log player status - local _PlayerStatsTable=Perun.LogStatsGet(playerID) - local _TempData={} - _TempData['stat_data_perun']=_PlayerStatsTable - _TempData['stat_data_type']=_PlayerStatsTable['ps_type']; - _TempData['stat_ucid']=net.get_player_info(playerID, 'ucid') - _TempData['stat_name']=net.get_player_info(playerID, 'name') - _TempData['stat_datetime']=os.date('%Y-%m-%d %H:%M:%S') - _TempData['stat_missionhash']=Perun.MissionHash - - Perun.AddLog("Sending stats data",2) - Perun.SendToPerun(52,_TempData) -end - -Perun.LogLogin = function(playerID) - -- Player logged in - local _TempData={} - _TempData['login_ucid']=net.get_player_info(playerID, 'ucid') - _TempData['login_ipaddr']=net.get_player_info(playerID, 'ipaddr') - _TempData['login_name']=net.get_player_info(playerID, 'name') - _TempData['login_datetime']=os.date('%Y-%m-%d %H:%M:%S') - - Perun.AddLog("Sending login event",2) - Perun.SendToPerun(53,_TempData) -end - -Perun.CheckMulticrew = function (owner_playerID,owner_unittype) - -- Check multicrew and return list of co-player - - local _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 - local _owner_slot=net.get_player_info(owner_playerID, 'slot') - local _owner_side=net.get_player_info(owner_playerID, 'side') - - -- Check if we are co-player - _t_start, _t_end = string.find(_owner_slot, '_%d+') - local _master_slot = nil - local _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 - local _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 - - Perun.AddLog("Multicrew check completed",2) - return _coplayers -end - - ---- ########### Event callbacks ########### +--- ################################ Event callbacks ################################ Perun.onSimulationStart = function() -- Simulation was started - Perun.MissionHash=DCS.getMissionName( ).."@".. Perun.Instance .. "@"..os.date('%Y%m%d_%H%M%S'); + Perun.MissionHash=Perun.GenerateMissionHash() Perun.LogEvent("SimStart","Mission " .. Perun.MissionHash .. " started",nil,nil); Perun.StatData = {} Perun.StatDataLastType = {} @@ -550,7 +613,7 @@ end Perun.onSimulationStop = function() -- Simulation was stopped Perun.LogEvent("SimStop","Mission " .. Perun.MissionHash .. " finished",nil,nil); - Perun.MissionHash=""; + Perun.MissionHash=Perun.GenerateMissionHash(); Perun.StatData = {} Perun.StatDataLastType = {} -- TBD send this to Perun @@ -597,8 +660,6 @@ Perun.onPlayerStart = function (id) -- Player entered cocpit net.send_chat_to(Perun.MOTD_L1, id); net.send_chat_to(Perun.MOTD_L2, id); - - Perun.AddLog("Player entered the game",2) end Perun.onPlayerTrySendChat = function (playerID, msg, all) @@ -612,7 +673,7 @@ end Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) -- Game event has occured - Perun.AddLog("Event handler for "..eventName .. " started",2) + Perun.AddLog("Event handler for ".. eventName .. " started",2) if eventName == "friendly_fire" then --"friendly_fire", playerID, weaponName, victimPlayerID if arg2 == "" then @@ -629,7 +690,7 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) --"kill", killerPlayerID, killerUnitType, killerSide, victimPlayerID, victimUnitType, victimSide, weaponName local _temp_victim="" if net.get_player_info(arg4, "name") ~= nil then - _temp_victim = " player ".. net.get_player_info(arg4, "name") .." "; + _temp_victim = " player ".. net.get_player_info(arg4, "name") .. " "; Perun.LogStats(arg4); else @@ -661,18 +722,18 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) _temp_event_type="kill_Other" end if net.get_player_info(arg4, "name") ~= nil and arg3 ~= arg6 then - pilots_accounted = Perun.CheckMulticrew(arg1,arg2) + pilots_accounted = Perun.GetMulticrewCrew(arg1) for _, pilotID in ipairs(pilots_accounted) do - Perun.LogStatsCount(pilotID,"kill_PvP",DCS.getUnitType(arg2)); + Perun.LogStatsCount(pilotID,"kill_PvP"); end end else _temp_event_type="friendly_fire" end - pilots_accounted = Perun.CheckMulticrew(arg1,arg2) + pilots_accounted = Perun.GetMulticrewCrew(arg1) for _, pilotID in ipairs(pilots_accounted) do - Perun.LogStatsCount(pilotID,_temp_event_type,DCS.getUnitType(arg2)); + Perun.LogStatsCount(pilotID,_temp_event_type); end else @@ -699,7 +760,7 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) _temp_slot = "SPECTATOR"; end - Perun.LogStatsCount(arg1,"init",_temp_slot) + Perun.LogStatsCount(arg1,"init") Perun.LogEvent(eventName,Perun.SideID2Name( net.get_player_info(arg1, "side")) .. " player " .. net.get_player_info(arg1, "name") .. " changed slot to " .. _temp_slot,nil,nil); @@ -715,17 +776,17 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) elseif eventName == "crash" then --"crash", playerID, unit_missionID - pilots_accounted = Perun.CheckMulticrew(arg1,DCS.getUnitType(arg2)) + pilots_accounted = Perun.GetMulticrewCrew(arg1) for _, pilotID in ipairs(pilots_accounted) do - Perun.LogStatsCount(pilotID,"crash",DCS.getUnitType(arg2)); + Perun.LogStatsCount(pilotID,"crash"); end 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); elseif eventName == "eject" then --"eject", playerID, unit_missionID - pilots_accounted = Perun.CheckMulticrew(arg1,DCS.getUnitType(arg2)) + pilots_accounted = Perun.GetMulticrewCrew(arg1) for _, pilotID in ipairs(pilots_accounted) do - Perun.LogStatsCount(pilotID,"eject",DCS.getUnitType(arg2)); + Perun.LogStatsCount(pilotID,"eject"); end Perun.LogEvent(eventName, Perun.SideID2Name( net.get_player_info(arg1, "side")) .. " player " .. net.get_player_info(arg1, "name") .. " ejected " .. DCS.getUnitType(arg2),nil,nil); @@ -748,9 +809,9 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) _temp_type="tookoff_OTHER" end - pilots_accounted = Perun.CheckMulticrew(arg1,DCS.getUnitType(arg2)) + pilots_accounted = Perun.GetMulticrewCrew(arg1) for _, pilotID in ipairs(pilots_accounted) do - Perun.LogStatsCount(pilotID,_temp_type,DCS.getUnitType(arg2)) + Perun.LogStatsCount(pilotID,_temp_type) end 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_airfield,arg3,nil); @@ -773,17 +834,17 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) _temp_type = "landing_OTHER" end - pilots_accounted = Perun.CheckMulticrew(arg1,DCS.getUnitType(arg2)) + pilots_accounted = Perun.GetMulticrewCrew(arg1) for _, pilotID in ipairs(pilots_accounted) do - Perun.LogStatsCount(pilotID,_temp_type,DCS.getUnitType(arg2)) + Perun.LogStatsCount(pilotID,_temp_type) end - 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); + Perun.LogEvent(eventName, Perun.SideID2Name( net.get_player_info(arg1, "side")) .. " player " .. net.get_player_info(arg1, "name") .. " landed in " .. DCS.getUnitType(arg2).. _temp_airfield,arg3,nil); elseif eventName == "pilot_death" then --"pilot_death", playerID, unit_missionID - pilots_accounted = Perun.CheckMulticrew(arg1,DCS.getUnitType(arg2)) + pilots_accounted = Perun.GetMulticrewCrew(arg1) for _, pilotID in ipairs(pilots_accounted) do - Perun.LogStatsCount(pilotID,"pilot_death",DCS.getUnitType(arg2)) + Perun.LogStatsCount(pilotID,"pilot_death") end 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); @@ -791,13 +852,14 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) Perun.LogEvent(eventName,"Unknown event type",nil,nil); end - Perun.AddLog("Event handler for "..eventName .. " finished",2) + Perun.AddLog("Event handler for " .. eventName .. " finished",2) end -- ########### Finalize and set callbacks ########### if Perun.IsServer then -- If this game instance is hosting multiplayer game, start Perun - DCS.setUserCallbacks(Perun) -- Set user callbacs, map DCS event handlers with functions defined above - net.log("Perun by VladMordock was loaded: " .. Perun.Version ) -- Display perun information in log - Perun.ConnectToPerun() -- Connect to Perun server + Perun.MissionHash=Perun.GenerateMissionHash() -- Generate initial missionhash + DCS.setUserCallbacks(Perun) -- Set user callbacs, map DCS event handlers with functions defined above + net.log("Perun by VladMordock was loaded: " .. Perun.Version ) -- Display perun information in log + Perun.ConnectToPerun() -- Connect to Perun server end From fcdf6ed0be5ab6e276e6ed4bef76ee4bfcd582ff Mon Sep 17 00:00:00 2001 From: szporowolik Date: Thu, 24 Oct 2019 01:49:30 +0200 Subject: [PATCH 05/17] Multicrew support in the decent form was added --- 01_DCS/Hooks/Perun.lua | 55 +++++++++---------- .../Perun_v1/01_Classes/DatabaseController.cs | 2 +- 2 files changed, 26 insertions(+), 31 deletions(-) diff --git a/01_DCS/Hooks/Perun.lua b/01_DCS/Hooks/Perun.lua index b50736e..a7659ae 100644 --- a/01_DCS/Hooks/Perun.lua +++ b/01_DCS/Hooks/Perun.lua @@ -210,6 +210,8 @@ Perun.GetMulticrewAllParameters = function (PlayerId) elseif string.find(_player_slot, 'observer') then _master_type = "observer" end + _master_slot = -1 + _sub_slot = 0 end return _master_type,_master_slot,_sub_slot end @@ -361,7 +363,8 @@ Perun.LogStats = function(playerID) local _PlayerStatsTable=Perun.LogStatsGet(playerID) local _TempData={} _TempData['stat_data_perun']=_PlayerStatsTable - _TempData['stat_data_type']=_PlayerStatsTable['ps_type']; + _TempData['stat_data_type']= _PlayerStatsTable['ps_type']; + _TempData['stat_data_masterslot'] = _PlayerStatsTable['ps_masterslot']; _TempData['stat_ucid']=net.get_player_info(playerID, 'ucid') _TempData['stat_name']=net.get_player_info(playerID, 'name') _TempData['stat_datetime']=os.date('%Y-%m-%d %H:%M:%S') @@ -393,6 +396,7 @@ Perun.LogStatsCount = function(argPlayerID,argAction) -- Create empty element local _TempData={} _TempData['ps_type'] = Perun.GetMulticrewParameter(argPlayerID,"subtype") + _TempData['ps_masterslot'] = Perun.GetMulticrewParameter(argPlayerID,"masterslot") _TempData['ps_pvp'] = 0 _TempData['ps_deaths'] = 0 _TempData['ps_ejections'] = 0 @@ -419,13 +423,15 @@ Perun.LogStatsCount = function(argPlayerID,argAction) Perun.StatData[_player_hash]=_TempData end + -- TBD BELLOW SEEMS TO BE OBSOLETE, CHECK AND DELETE if argType ~= nil then Perun.StatData[_player_hash]['ps_type']=Perun.GetMulticrewParameter(argPlayerID,"subtype"); Perun.StatDataLastType[net.get_player_info(argPlayerID, 'ucid')]=_player_hash else -- Do nothing end - + -- TBD ABOVE SEEMS TO BE OBSOLETE, CHECK AND DELETE + if argAction == "eject" then Perun.StatData[_player_hash]['ps_ejections']=Perun.StatData[_player_hash]['ps_ejections']+1 elseif argAction == "pilot_death" then @@ -474,11 +480,21 @@ Perun.LogStatsCount = function(argPlayerID,argAction) elseif argAction == "tookoff_OTHER" then Perun.StatData[_player_hash]['ps_other_takeoffs']=Perun.StatData[_player_hash]['ps_other_takeoffs']+1 end + + -- Always update master slot + Perun.StatData[_player_hash]['ps_masterslot'] = Perun.GetMulticrewParameter(argPlayerID,"masterslot") Perun.AddLog("Stats data prepared",2) Perun.LogStats(argPlayerID); end +Perun.LogStatsCountCrew = function (MasterPilotID,ActionType) + -- Change stats for the whole crew + local _pilots_accounted = Perun.GetMulticrewCrew(MasterPilotID) + for _, pilotID in ipairs(_pilots_accounted) do + Perun.LogStatsCount(pilotID,ActionType) + end +end -- ################################ Data preparation ################################ Perun.LogStatsGet = function(playerID) @@ -722,19 +738,13 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) _temp_event_type="kill_Other" end if net.get_player_info(arg4, "name") ~= nil and arg3 ~= arg6 then - pilots_accounted = Perun.GetMulticrewCrew(arg1) - for _, pilotID in ipairs(pilots_accounted) do - Perun.LogStatsCount(pilotID,"kill_PvP"); - end + Perun.LogStatsCountCrew (arg1,"kill_PvP") end else _temp_event_type="friendly_fire" end - pilots_accounted = Perun.GetMulticrewCrew(arg1) - for _, pilotID in ipairs(pilots_accounted) do - Perun.LogStatsCount(pilotID,_temp_event_type); - end + Perun.LogStatsCountCrew (arg1,_temp_event_type) else _temp_killer = " AI "; @@ -776,18 +786,12 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) elseif eventName == "crash" then --"crash", playerID, unit_missionID - pilots_accounted = Perun.GetMulticrewCrew(arg1) - for _, pilotID in ipairs(pilots_accounted) do - Perun.LogStatsCount(pilotID,"crash"); - end + Perun.LogStatsCountCrew (arg1,"crash") 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); elseif eventName == "eject" then --"eject", playerID, unit_missionID - pilots_accounted = Perun.GetMulticrewCrew(arg1) - for _, pilotID in ipairs(pilots_accounted) do - Perun.LogStatsCount(pilotID,"eject"); - end + Perun.LogStatsCountCrew (arg1,"eject") Perun.LogEvent(eventName, Perun.SideID2Name( net.get_player_info(arg1, "side")) .. " player " .. net.get_player_info(arg1, "name") .. " ejected " .. DCS.getUnitType(arg2),nil,nil); elseif eventName == "takeoff" then @@ -809,10 +813,7 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) _temp_type="tookoff_OTHER" end - pilots_accounted = Perun.GetMulticrewCrew(arg1) - for _, pilotID in ipairs(pilots_accounted) do - Perun.LogStatsCount(pilotID,_temp_type) - end + Perun.LogStatsCountCrew (arg1,_temp_type) 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_airfield,arg3,nil); elseif eventName == "landing" then @@ -834,18 +835,12 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) _temp_type = "landing_OTHER" end - pilots_accounted = Perun.GetMulticrewCrew(arg1) - for _, pilotID in ipairs(pilots_accounted) do - Perun.LogStatsCount(pilotID,_temp_type) - end + Perun.LogStatsCountCrew (arg1,_temp_type) Perun.LogEvent(eventName, Perun.SideID2Name( net.get_player_info(arg1, "side")) .. " player " .. net.get_player_info(arg1, "name") .. " landed in " .. DCS.getUnitType(arg2).. _temp_airfield,arg3,nil); elseif eventName == "pilot_death" then --"pilot_death", playerID, unit_missionID - pilots_accounted = Perun.GetMulticrewCrew(arg1) - for _, pilotID in ipairs(pilots_accounted) do - Perun.LogStatsCount(pilotID,"pilot_death") - end + Perun.LogStatsCountCrew (arg1,"pilot_death") 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); else diff --git a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs index 785c246..c4efbb5 100644 --- a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs +++ b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs @@ -69,7 +69,7 @@ public class DatabaseController 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 + "');"; + SQLQueryTxt += "UPDATE `pe_LogStats` SET `pe_LogStats_masterslot`=" + TCPFrame.payload.stat_data_masterslot + ",`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 (TCPFrameType == "53") { From 4bd536f55673dbc3c02300a795a510da8b1d747f Mon Sep 17 00:00:00 2001 From: szporowolik Date: Fri, 25 Oct 2019 13:03:24 +0200 Subject: [PATCH 06/17] Occupied seat will be stored in the database, for easier displaying --- 01_DCS/Hooks/Perun.lua | 7 +++++-- .../Perun_v1/01_Classes/DatabaseController.cs | 17 ++++++++++++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/01_DCS/Hooks/Perun.lua b/01_DCS/Hooks/Perun.lua index a7659ae..8c47e3c 100644 --- a/01_DCS/Hooks/Perun.lua +++ b/01_DCS/Hooks/Perun.lua @@ -365,7 +365,8 @@ Perun.LogStats = function(playerID) _TempData['stat_data_perun']=_PlayerStatsTable _TempData['stat_data_type']= _PlayerStatsTable['ps_type']; _TempData['stat_data_masterslot'] = _PlayerStatsTable['ps_masterslot']; - _TempData['stat_ucid']=net.get_player_info(playerID, 'ucid') + _TempData['stat_data_subslot'] = _PlayerStatsTable['ps_subslot']; + _TempData['stat_ucid']=net.get_player_info(playerID, 'ucid') _TempData['stat_name']=net.get_player_info(playerID, 'name') _TempData['stat_datetime']=os.date('%Y-%m-%d %H:%M:%S') _TempData['stat_missionhash']=Perun.MissionHash @@ -397,6 +398,7 @@ Perun.LogStatsCount = function(argPlayerID,argAction) local _TempData={} _TempData['ps_type'] = Perun.GetMulticrewParameter(argPlayerID,"subtype") _TempData['ps_masterslot'] = Perun.GetMulticrewParameter(argPlayerID,"masterslot") + _TempData['ps_subslot'] = Perun.GetMulticrewParameter(argPlayerID,"subslot") _TempData['ps_pvp'] = 0 _TempData['ps_deaths'] = 0 _TempData['ps_ejections'] = 0 @@ -481,8 +483,9 @@ Perun.LogStatsCount = function(argPlayerID,argAction) Perun.StatData[_player_hash]['ps_other_takeoffs']=Perun.StatData[_player_hash]['ps_other_takeoffs']+1 end - -- Always update master slot + -- Always update slots Perun.StatData[_player_hash]['ps_masterslot'] = Perun.GetMulticrewParameter(argPlayerID,"masterslot") + Perun.StatData[_player_hash]['ps_subslot'] = Perun.GetMulticrewParameter(argPlayerID,"subslot") Perun.AddLog("Stats data prepared",2) Perun.LogStats(argPlayerID); diff --git a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs index c4efbb5..6887e80 100644 --- a/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs +++ b/02_Windows_App/Perun_v1/01_Classes/DatabaseController.cs @@ -69,7 +69,7 @@ public class DatabaseController 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 `pe_LogStats_masterslot`=" + TCPFrame.payload.stat_data_masterslot + ",`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 + "');"; + SQLQueryTxt += "UPDATE `pe_LogStats` SET `pe_LogStats_seat`=" + TCPFrame.payload.stat_data_subslot + ",`pe_LogStats_masterslot`=" + TCPFrame.payload.stat_data_masterslot + ",`ps_kills_fortification`=" + TCPFrame.payload.stat_data_perun.ps_kills_fortification + ",`ps_other_landings`=" + TCPFrame.payload.stat_data_perun.ps_other_landings + ",`ps_other_takeoffs`=" + TCPFrame.payload.stat_data_perun.ps_other_takeoffs + ",`ps_pvp`=" + TCPFrame.payload.stat_data_perun.ps_pvp + ",`ps_deaths`=" + TCPFrame.payload.stat_data_perun.ps_deaths + ",`ps_ejections`=" + TCPFrame.payload.stat_data_perun.ps_ejections + ",`ps_crashes`=" + TCPFrame.payload.stat_data_perun.ps_crashes + ",`ps_teamkills`=" + TCPFrame.payload.stat_data_perun.ps_teamkills + ",`ps_kills_planes`=" + TCPFrame.payload.stat_data_perun.ps_kills_planes + ",`ps_kills_helicopters`=" + TCPFrame.payload.stat_data_perun.ps_kills_helicopters + ",`ps_kills_air_defense`=" + TCPFrame.payload.stat_data_perun.ps_kills_air_defense + ",`ps_kills_armor`=" + TCPFrame.payload.stat_data_perun.ps_kills_armor + ",`ps_kills_unarmed`=" + TCPFrame.payload.stat_data_perun.ps_kills_unarmed + ",`ps_kills_infantry`=" + TCPFrame.payload.stat_data_perun.ps_kills_infantry + ",`ps_kills_ships`=" + TCPFrame.payload.stat_data_perun.ps_kills_ships + ",`ps_kills_other`=" + TCPFrame.payload.stat_data_perun.ps_kills_other + ",`ps_airfield_takeoffs`=" + TCPFrame.payload.stat_data_perun.ps_airfield_takeoffs + ",`ps_airfield_landings`=" + TCPFrame.payload.stat_data_perun.ps_airfield_landings + ",`ps_ship_takeoffs`=" + TCPFrame.payload.stat_data_perun.ps_ship_takeoffs + ",`ps_ship_landings`=" + TCPFrame.payload.stat_data_perun.ps_ship_landings + ",`ps_farp_takeoffs`=" + TCPFrame.payload.stat_data_perun.ps_farp_takeoffs + ",`ps_farp_landings`=" + TCPFrame.payload.stat_data_perun.ps_farp_landings + ", `pe_LogStats_datetime`='" + TCPFrame.payload.stat_datetime + "',`pe_LogStats_playerid` = (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + TCPFrame.payload.stat_ucid + "'),`pe_LogStats_missionhash_id`=(SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.stat_missionhash + "') WHERE `pe_LogStats_missionhash_id`=(SELECT `pe_DataMissionHashes_id` FROM `pe_DataMissionHashes` WHERE `pe_DataMissionHashes_hash` = '" + TCPFrame.payload.stat_missionhash + "') AND `pe_LogStats_playerid` = (SELECT `pe_DataPlayers_id` from `pe_DataPlayers` WHERE `pe_DataPlayers_ucid` = '" + TCPFrame.payload.stat_ucid + "') AND `pe_LogStats_typeid`=(SELECT pe_DataTypes_id FROM `pe_DataTypes` where `pe_DataTypes_name` = '" + TCPFrame.payload.stat_data_type + "');"; } else if (TCPFrameType == "53") { @@ -176,19 +176,30 @@ public class DatabaseController { case 1042: // Unable to connect to any of the specified MySQL hosts (Check Server,Port) PerunHelper.AddLog(ref Globals.AppLogHistory, "ERROR MySQL - unable to connect, error: " + m_ex.Message,1,1, TCPFrameType); + DatabaseStatus = false; + ReturnValue = 0; break; case 0: // Access denied (Check DB name,username,password) PerunHelper.AddLog(ref Globals.AppLogHistory, "ERROR MySQL - access denied, error: " + m_ex.Message,1,1, TCPFrameType); + DatabaseStatus = false; + ReturnValue = 0; + break; + case 1064: // Incorrect query + PerunHelper.AddLog(ref Globals.AppLogHistory, "ERROR MySQL - query: " + SQLQueryTxt, 1, 1, TCPFrameType); + PerunHelper.AddLog(ref Globals.AppLogHistory, "ERROR MySQL - error: " + m_ex.Message, 1, 1, TCPFrameType); + DatabaseStatus = true; // True as connection is not broken + ReturnValue = 1; // Return a value to remove this query from quae break; default: PerunHelper.AddLog(ref Globals.AppLogHistory, "ERROR MySQL - error id: " + m_ex.Number,1,1, TCPFrameType); PerunHelper.AddLog(ref Globals.AppLogHistory, "ERROR MySQL - query: " + SQLQueryTxt, 1, 1, TCPFrameType); PerunHelper.AddLog(ref Globals.AppLogHistory, "ERROR MySQL - error: " + m_ex.Message,1,1, TCPFrameType); + DatabaseStatus = false; + ReturnValue = 0; break; } Globals.ErrorsGame++; - DatabaseStatus = false; - ReturnValue = 0; + } DatabaseConnection.Close(); Console.WriteLine("Sending data to MySQL - Done"); From 75f1e0d316937ed7abb95a2925f7057f274b31c0 Mon Sep 17 00:00:00 2001 From: szporowolik Date: Sat, 26 Oct 2019 21:15:18 +0200 Subject: [PATCH 07/17] Database update to v0.9.0 --- 03_MySQL/m1081_perun.sql | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/03_MySQL/m1081_perun.sql b/03_MySQL/m1081_perun.sql index e0b09d5..b8e428f 100644 --- a/03_MySQL/m1081_perun.sql +++ b/03_MySQL/m1081_perun.sql @@ -46,7 +46,7 @@ CREATE TABLE IF NOT EXISTS `pe_Config` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `pe_Config` (`pe_Config_id`, `pe_Config_payload`) VALUES -(1, 'v0.8.3'); +(1, 'v0.9.0'); DROP TABLE IF EXISTS `pe_DataMissionHashes`; CREATE TABLE IF NOT EXISTS `pe_DataMissionHashes` ( @@ -57,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 AUTO_INCREMENT=818 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=7155 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_DataPlayers`; CREATE TABLE IF NOT EXISTS `pe_DataPlayers` ( @@ -68,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 AUTO_INCREMENT=219 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=222 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_DataRaw`; CREATE TABLE IF NOT EXISTS `pe_DataRaw` ( @@ -86,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 AUTO_INCREMENT=57 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_LogChat`; CREATE TABLE IF NOT EXISTS `pe_LogChat` ( @@ -100,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 AUTO_INCREMENT=19739 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=21177 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_LogEvent`; CREATE TABLE IF NOT EXISTS `pe_LogEvent` ( @@ -114,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 AUTO_INCREMENT=93657 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=95755 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_LogLogins`; CREATE TABLE IF NOT EXISTS `pe_LogLogins` ( @@ -127,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 AUTO_INCREMENT=10742 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=11064 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_LogStats`; CREATE TABLE IF NOT EXISTS `pe_LogStats` ( @@ -136,6 +136,8 @@ CREATE TABLE IF NOT EXISTS `pe_LogStats` ( `pe_LogStats_missionhash_id` bigint(20) DEFAULT NULL, `pe_LogStats_playerid` bigint(20) DEFAULT NULL, `pe_LogStats_typeid` int(11) DEFAULT NULL, + `pe_LogStats_masterslot` int(11) DEFAULT NULL, + `pe_LogStats_seat` int(10) UNSIGNED DEFAULT NULL, `ps_kills` int(11) UNSIGNED NOT NULL DEFAULT '0', `ps_pvp` int(11) UNSIGNED NOT NULL DEFAULT '0', `ps_deaths` int(11) UNSIGNED NOT NULL DEFAULT '0', @@ -170,8 +172,10 @@ CREATE TABLE IF NOT EXISTS `pe_LogStats` ( UNIQUE KEY `UNIQUE_STATS_PER_MISSION_AND_UCID_AND_TYPE` (`pe_LogStats_playerid`,`pe_LogStats_missionhash_id`,`pe_LogStats_typeid`) USING BTREE, 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 AUTO_INCREMENT=9595 DEFAULT CHARSET=utf8; + KEY `pe_LogStats_typeid` (`pe_LogStats_typeid`), + KEY `pe_LogStats_masterslot` (`pe_LogStats_masterslot`), + KEY `pe_LogStats_mstatus` (`pe_LogStats_mstatus`) +) ENGINE=InnoDB AUTO_INCREMENT=9900 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 From a341d06dc8cb3d5fea8eca3aff7bbc2df77f737a Mon Sep 17 00:00:00 2001 From: VladMordock Date: Sun, 27 Oct 2019 21:12:18 +0100 Subject: [PATCH 08/17] Changed screenshot --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b9f47d9..920abfe 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/MieyBej.png) +![Perun in action](https://i.imgur.com/JIlLENa.png) ![Data flow](https://i.imgur.com/JbNu77l.png) ## Prerequisites From 57f90954d317dff808e6a43bc84050c79f3cdff4 Mon Sep 17 00:00:00 2001 From: szporowolik Date: Mon, 28 Oct 2019 00:11:53 +0100 Subject: [PATCH 09/17] Fixes for multicrew support --- 01_DCS/Hooks/Perun.lua | 68 +++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/01_DCS/Hooks/Perun.lua b/01_DCS/Hooks/Perun.lua index 8c47e3c..75156ac 100644 --- a/01_DCS/Hooks/Perun.lua +++ b/01_DCS/Hooks/Perun.lua @@ -266,6 +266,16 @@ Perun.GetMulticrewCrew = function (owner_playerID) return _crew end +Perun.GetMulticrewCrewNames = function (owner_playerID) + -- Get all crew names and return as string (needed for logging purposes) + local _pilots_accounted = Perun.GetMulticrewCrew(owner_playerID) + local _result_text = "" + for _, pilotID in ipairs(_pilots_accounted) do + _result_text= _result_text .. net.get_player_info(pilotID, "name") .. ", " + end + return _result_text +end + -- ################################ TCP Connection ################################ Perun.ConnectToPerun = function () @@ -709,7 +719,7 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) --"kill", killerPlayerID, killerUnitType, killerSide, victimPlayerID, victimUnitType, victimSide, weaponName local _temp_victim="" if net.get_player_info(arg4, "name") ~= nil then - _temp_victim = " player ".. net.get_player_info(arg4, "name") .. " "; + _temp_victim = " player(s) ".. Perun.GetMulticrewCrewNames(arg1) .. " "; Perun.LogStats(arg4); else @@ -717,25 +727,27 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) end if net.get_player_info(arg1, "name") ~= nil then - _temp_killer = " player ".. net.get_player_info(arg1, "name") .." "; + _temp_killers = " player(s) ".. Perun.GetMulticrewCrewNames(arg1) .." "; _temp_event_type="" if arg3 ~= arg6 then - if Perun.GetCategory(arg5) == "Planes" then + _temp_category=Perun.GetCategory(arg5) + + if _temp_category == "Planes" then _temp_event_type="kill_Planes" - elseif Perun.GetCategory(arg5) == "Helicopters" then + elseif _temp_category == "Helicopters" then _temp_event_type="kill_Helicopters" - elseif Perun.GetCategory(arg5) == "Ships" then + elseif _temp_category == "Ships" then _temp_event_type="kill_Ships" - elseif Perun.GetCategory(arg5) == "Air Defence" then + elseif _temp_category == "Air Defence" then _temp_event_type="kill_Air_Defence" - elseif Perun.GetCategory(arg5) == "Unarmed" then + elseif _temp_category == "Unarmed" then _temp_event_type="kill_Unarmed" - elseif Perun.GetCategory(arg5) == "Armor" then + elseif _temp_category == "Armor" then _temp_event_type="kill_Armor" - elseif Perun.GetCategory(arg5) == "Infantry" then + elseif _temp_category == "Infantry" then _temp_event_type="kill_Infantry" - elseif Perun.GetCategory(arg5) == "Fortification" then + elseif _temp_category == "Fortification" then _temp_event_type="kill_Fortification" else _temp_event_type="kill_Other" @@ -750,14 +762,14 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) Perun.LogStatsCountCrew (arg1,_temp_event_type) else - _temp_killer = " AI "; + _temp_killers = " AI "; end if arg7 == "" then arg7 = "Cannon" end - Perun.LogEvent(eventName,Perun.SideID2Name(arg3) .. _temp_killer .. " in " .. arg2 .. " killed " .. Perun.SideID2Name(arg6) .. _temp_victim .. " in " .. arg5 .. " using " .. arg7 .. " [".. Perun.GetCategory(arg5).."]",arg7,Perun.GetCategory(arg5)); + Perun.LogEvent(eventName,Perun.SideID2Name(arg3) .. _temp_killers .. " in " .. arg2 .. " killed " .. Perun.SideID2Name(arg6) .. _temp_victim .. " in " .. arg5 .. " using " .. arg7 .. " [".. Perun.GetCategory(arg5).."]",arg7,Perun.GetCategory(arg5)); elseif eventName == "self_kill" then --"self_kill", playerID @@ -767,14 +779,14 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) elseif eventName == "change_slot" then --"change_slot", playerID, slotID, prevSide - if DCS.getUnitType(arg2) ~= nil and DCS.getUnitType(arg2) ~= "" then - _temp_slot = DCS.getUnitType(arg2); - else - _temp_slot = "SPECTATOR"; - end - - Perun.LogStatsCount(arg1,"init") - Perun.LogEvent(eventName,Perun.SideID2Name( net.get_player_info(arg1, "side")) .. " player " .. net.get_player_info(arg1, "name") .. " changed slot to " .. _temp_slot,nil,nil); + Perun.LogStatsCount(arg1,"init") + _master_type,_master_slot,_sub_slot = Perun.GetMulticrewAllParameters(arg1) + if _sub_slot == nil then + _sub_slot ="" + else + _sub_slot =" (" .. _sub_slot .. ") " + end + Perun.LogEvent(eventName,Perun.SideID2Name( net.get_player_info(arg1, "side")) .. " player " .. net.get_player_info(arg1, "name") .. " changed slot to " .. _master_type .. " " .. _sub_slot,nil,nil); elseif eventName == "connect" then @@ -790,12 +802,12 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) elseif eventName == "crash" then --"crash", playerID, unit_missionID Perun.LogStatsCountCrew (arg1,"crash") - 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.LogEvent(eventName, Perun.SideID2Name( net.get_player_info(arg1, "side")) .. " player(s) " .. Perun.GetMulticrewCrewNames(arg1) .. " crashed in " .. DCS.getUnitType(arg2),nil,nil); elseif eventName == "eject" then --"eject", playerID, unit_missionID - Perun.LogStatsCountCrew (arg1,"eject") - 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.LogStatsCountCrew (arg1,"eject") -- TBD crew or initiator only? + Perun.LogEvent(eventName, Perun.SideID2Name( net.get_player_info(arg1, "side")) .. " player(s) " .. Perun.GetMulticrewCrewNames(arg1) .. " ejected " .. DCS.getUnitType(arg2),nil,nil); elseif eventName == "takeoff" then --"takeoff", playerID, unit_missionID, airdromeName @@ -805,6 +817,7 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) _temp_airfield = ""; end + -- TBD below shall be moved to function and arrays of strings - see landings _temp_type = "" if string.find(arg3, "FARP",1,true) then _temp_type="tookoff_FARP" @@ -817,7 +830,7 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) end Perun.LogStatsCountCrew (arg1,_temp_type) - 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_airfield,arg3,nil); + Perun.LogEvent(eventName, Perun.SideID2Name( net.get_player_info(arg1, "side")) .. " player(s) " .. Perun.GetMulticrewCrewNames(arg1) .. " took off in ".. DCS.getUnitType(arg2) .. _temp_airfield,arg3,nil); elseif eventName == "landing" then --"landing", playerID, unit_missionID, airdromeName @@ -827,6 +840,7 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) _temp =""; end + -- TBD below shall be moved to function and arrays of strings - see takeoffs _temp_type = "" if string.find(arg3, "FARP",1,true) then _temp_type = "landing_FARP" @@ -839,12 +853,12 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) end Perun.LogStatsCountCrew (arg1,_temp_type) - Perun.LogEvent(eventName, Perun.SideID2Name( net.get_player_info(arg1, "side")) .. " player " .. net.get_player_info(arg1, "name") .. " landed in " .. DCS.getUnitType(arg2).. _temp_airfield,arg3,nil); + Perun.LogEvent(eventName, Perun.SideID2Name( net.get_player_info(arg1, "side")) .. " player(s) " .. Perun.GetMulticrewCrewNames(arg1) .. " landed in " .. DCS.getUnitType(arg2).. _temp_airfield,arg3,nil); elseif eventName == "pilot_death" then --"pilot_death", playerID, unit_missionID - Perun.LogStatsCountCrew (arg1,"pilot_death") - 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.LogStatsCountCrew (arg1,"pilot_death") -- TBD crew or initiator only? + Perun.LogEvent(eventName, Perun.SideID2Name( net.get_player_info(arg1, "side")) .. " player(s) " .. Perun.GetMulticrewCrewNames(arg1) .. " in " .. DCS.getUnitType(arg2) .. " died",nil,nil); else Perun.LogEvent(eventName,"Unknown event type",nil,nil); From 14c5a8896f03373cd673e2e7ec72e2264c1673f0 Mon Sep 17 00:00:00 2001 From: szporowolik Date: Mon, 28 Oct 2019 16:48:05 +0100 Subject: [PATCH 10/17] DCS will now inform that Perun connection is broken --- 01_DCS/Hooks/Perun.lua | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/01_DCS/Hooks/Perun.lua b/01_DCS/Hooks/Perun.lua index 75156ac..c3cb552 100644 --- a/01_DCS/Hooks/Perun.lua +++ b/01_DCS/Hooks/Perun.lua @@ -33,12 +33,14 @@ Perun.MissionHash="" Perun.lastSentStatus = 0 Perun.lastSentMission = 0 Perun.lastSentKeepAlive = 0 +Perun.lastConnectionError = 0 Perun.lastReconnect = 0 Perun.SendRetries = 3 Perun.RefreshKeepAlive = 3 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.ConnectionError = "[Perun] ERROR: Connection broken - contact server admin!" -- ################################ Helper function definitions ################################ function stripChars(str) @@ -164,8 +166,8 @@ end Perun.AddLog = function(text,LogLevel) -- Adds logs to DCS.log file LogLevel = LogLevel or 1 - if Perun.DebugMode == LogLevel then - net.log("Perun : ".. text) + if Perun.DebugMode >= LogLevel then + net.log("[Perun] ".. text) end end @@ -287,10 +289,10 @@ Perun.ConnectToPerun = function () _, _err = Perun.TCP:connect(Perun.TCPPerunHost, Perun.TCPTargetPort) if _err then -- Could not connect - Perun.AddLog("ERROR - TCP connection error : " .. _err) + Perun.AddLog("ERROR - TCP connection error : " .. _err , 1) else -- Connected - Perun.AddLog("Sucess - connected to TCP server",2) + Perun.AddLog("Success - connected to TCP server",2) Perun.lastReconnect = _now end end @@ -310,6 +312,7 @@ Perun.SendToPerun = function(data_id, data_package) local _intStatus = nil local _intTries =0 local _err=nil + local _dropped = true -- Try to send a few times (defind in settings section) while _intStatus == nil and _intTries < Perun.SendRetries do @@ -321,13 +324,24 @@ Perun.SendToPerun = function(data_id, data_package) else -- Succes, packet was send Perun.AddLog("Packet send : " .. data_id .. " , tries:" .. _intTries,2) + _dropped = false end _intTries=_intTries+1 - _err = nil end - if _err then - -- Add information to log file - Perun.AddLog("ERROR - packed dropped : " .. data_id) + + if _dropped == true then + -- Add information to log file and send chat message to all that Perun connection is broken + Perun.AddLog("ERROR - packed dropped : " .. data_id,1) + local _now = DCS.getRealTime() + if _now > Perun.lastConnectionError + 60 then + -- Informs all players that there is Peron error; below hack for DCS net.send_chat not working + local _all_players = net.get_player_list() + for PlayerIDIndex, _playerID in ipairs(_all_players) do + net.send_chat_to(Perun.ConnectionError , _playerID) + end + -- Reset last error send counter + Perun.lastConnectionError = _now + end end end @@ -693,7 +707,7 @@ end Perun.onPlayerTrySendChat = function (playerID, msg, all) -- Somebody tries to send chat message - if msg~=Perun.MOTD_L1 and msg~=Perun.MOTD_L2 then + if msg~=Perun.MOTD_L1 and msg~=Perun.MOTD_L2 and msg~=Perun.ConnectionError then Perun.LogChat(playerID,msg,all) end @@ -709,7 +723,7 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) arg2 = "Cannon" 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); + Perun.LogEvent(eventName,Perun.SideID2Name( net.get_player_info(arg1, "side")) .. " player(s) " .. Perun.GetMulticrewCrewNames(arg1) .." killed friendly " .. Perun.GetMulticrewCrewNames(arg3) .. " using " .. arg2,nil,nil); elseif eventName == "mission_end" then --"mission_end", winner, msg @@ -717,13 +731,13 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) elseif eventName == "kill" then --"kill", killerPlayerID, killerUnitType, killerSide, victimPlayerID, victimUnitType, victimSide, weaponName - local _temp_victim="" + local _temp_victims="" if net.get_player_info(arg4, "name") ~= nil then - _temp_victim = " player(s) ".. Perun.GetMulticrewCrewNames(arg1) .. " "; + _temp_victims = " player(s) ".. Perun.GetMulticrewCrewNames(arg4) .. " "; Perun.LogStats(arg4); else - _temp_victim = " AI "; + _temp_victims = " AI "; end if net.get_player_info(arg1, "name") ~= nil then @@ -769,7 +783,7 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) arg7 = "Cannon" end - Perun.LogEvent(eventName,Perun.SideID2Name(arg3) .. _temp_killers .. " in " .. arg2 .. " killed " .. Perun.SideID2Name(arg6) .. _temp_victim .. " in " .. arg5 .. " using " .. arg7 .. " [".. Perun.GetCategory(arg5).."]",arg7,Perun.GetCategory(arg5)); + Perun.LogEvent(eventName,Perun.SideID2Name(arg3) .. _temp_killers .. " in " .. arg2 .. " killed " .. Perun.SideID2Name(arg6) .. _temp_victims .. " in " .. arg5 .. " using " .. arg7 .. " [".. Perun.GetCategory(arg5).."]",arg7,Perun.GetCategory(arg5)); elseif eventName == "self_kill" then --"self_kill", playerID From 078ba09cc7bfc40fdccb8a187057dbcf95c4ac25 Mon Sep 17 00:00:00 2001 From: szporowolik Date: Mon, 28 Oct 2019 16:49:02 +0100 Subject: [PATCH 11/17] MySQL structure cleanup --- 03_MySQL/m1081_perun.sql | 79 ++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 52 deletions(-) diff --git a/03_MySQL/m1081_perun.sql b/03_MySQL/m1081_perun.sql index b8e428f..8ee2a1a 100644 --- a/03_MySQL/m1081_perun.sql +++ b/03_MySQL/m1081_perun.sql @@ -11,33 +11,6 @@ SET time_zone = "+00:00"; 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, @@ -57,7 +30,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 AUTO_INCREMENT=7155 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=7184 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_DataPlayers`; CREATE TABLE IF NOT EXISTS `pe_DataPlayers` ( @@ -68,7 +41,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 AUTO_INCREMENT=222 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=224 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_DataRaw`; CREATE TABLE IF NOT EXISTS `pe_DataRaw` ( @@ -76,7 +49,9 @@ CREATE TABLE IF NOT EXISTS `pe_DataRaw` ( `pe_dataraw_instance` smallint(5) UNSIGNED NOT NULL, `pe_dataraw_payload` text NOT NULL, `pe_dataraw_updated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - PRIMARY KEY (`pe_dataraw_type`,`pe_dataraw_instance`) + PRIMARY KEY (`pe_dataraw_type`,`pe_dataraw_instance`), + KEY `pe_dataraw_type_pe_dataraw_instance` (`pe_dataraw_type`,`pe_dataraw_instance`), + KEY `pe_dataraw_updated` (`pe_dataraw_updated`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_DataTypes`; @@ -99,8 +74,9 @@ CREATE TABLE IF NOT EXISTS `pe_LogChat` ( PRIMARY KEY (`pe_LogChat_id`), 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 AUTO_INCREMENT=21177 DEFAULT CHARSET=utf8; + KEY `pe_LogChat_datetime` (`pe_LogChat_datetime`), + KEY `pe_LogChat_all` (`pe_LogChat_all`) +) ENGINE=InnoDB AUTO_INCREMENT=21901 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_LogEvent`; CREATE TABLE IF NOT EXISTS `pe_LogEvent` ( @@ -111,10 +87,12 @@ CREATE TABLE IF NOT EXISTS `pe_LogEvent` ( `pe_LogEvent_content` text NOT NULL, `pe_LogEvent_arg1` varchar(150) DEFAULT NULL, `pe_LogEvent_arg2` varchar(150) DEFAULT NULL, + `pe_LogEvent_argPlayers` varchar(150) DEFAULT NULL, PRIMARY KEY (`pe_LogEvent_id`), KEY `pe_LogEvent_missionhash_id` (`pe_LogEvent_missionhash_id`), - KEY `pe_LogEvent_datetime` (`pe_LogEvent_datetime`) -) ENGINE=InnoDB AUTO_INCREMENT=95755 DEFAULT CHARSET=utf8; + KEY `pe_LogEvent_datetime` (`pe_LogEvent_datetime`), + KEY `pe_LogEvent_type_2` (`pe_LogEvent_type`) +) ENGINE=InnoDB AUTO_INCREMENT=98685 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_LogLogins`; CREATE TABLE IF NOT EXISTS `pe_LogLogins` ( @@ -126,8 +104,9 @@ CREATE TABLE IF NOT EXISTS `pe_LogLogins` ( `pe_LogLogins_ip` varchar(100) NOT NULL, PRIMARY KEY (`pe_LogLogins_id`), KEY `pe_LogLogins_playerid` (`pe_LogLogins_playerid`), - KEY `pe_LogLogins_datetime` (`pe_LogLogins_datetime`) -) ENGINE=InnoDB AUTO_INCREMENT=11064 DEFAULT CHARSET=utf8; + KEY `pe_LogLogins_datetime` (`pe_LogLogins_datetime`), + KEY `pe_LogLogins_instance` (`pe_LogLogins_instance`) +) ENGINE=InnoDB AUTO_INCREMENT=11195 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_LogStats`; CREATE TABLE IF NOT EXISTS `pe_LogStats` ( @@ -162,31 +141,18 @@ CREATE TABLE IF NOT EXISTS `pe_LogStats` ( `ps_other_landings` int(10) UNSIGNED NOT NULL DEFAULT '0', `ps_other_takeoffs` int(10) UNSIGNED NOT NULL DEFAULT '0', `pe_LogStats_mstatus` enum('?','RTB','MIA','KIA') DEFAULT NULL, - `ps_takeoffs` int(10) UNSIGNED DEFAULT '0', - `ps_landings` int(10) UNSIGNED DEFAULT '0', - `ps_kills_AA` int(10) UNSIGNED DEFAULT '0', - `ps_kills_AG` int(10) UNSIGNED DEFAULT '0', - `ps_kills_AS` int(10) UNSIGNED DEFAULT '0', - `ps_kills_AAA` int(10) UNSIGNED DEFAULT '0', PRIMARY KEY (`pe_LogStats_id`), UNIQUE KEY `UNIQUE_STATS_PER_MISSION_AND_UCID_AND_TYPE` (`pe_LogStats_playerid`,`pe_LogStats_missionhash_id`,`pe_LogStats_typeid`) USING BTREE, KEY `pe_LogStats_missionhash_id` (`pe_LogStats_missionhash_id`), KEY `pe_LogStats_playerid` (`pe_LogStats_playerid`), KEY `pe_LogStats_typeid` (`pe_LogStats_typeid`), KEY `pe_LogStats_masterslot` (`pe_LogStats_masterslot`), - KEY `pe_LogStats_mstatus` (`pe_LogStats_mstatus`) -) ENGINE=InnoDB AUTO_INCREMENT=9900 DEFAULT CHARSET=utf8; + KEY `pe_LogStats_mstatus` (`pe_LogStats_mstatus`), + KEY `pe_LogStats_seat` (`pe_LogStats_seat`) +) ENGINE=InnoDB AUTO_INCREMENT=10086 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 - - SET NEW.ps_takeoffs = NEW.ps_airfield_takeoffs + NEW.ps_farp_takeoffs + NEW.ps_other_takeoffs + NEW.ps_ship_takeoffs; - SET NEW.ps_landings = NEW.ps_airfield_landings + NEW.ps_farp_landings + NEW.ps_other_landings + NEW.ps_ship_landings; - SET NEW.ps_kills_AA = NEW.ps_kills_planes + NEW.ps_kills_helicopters; - SET NEW.ps_kills_AG = NEW.ps_kills_armor + NEW.ps_kills_unarmed + NEW.ps_kills_fortification; - SET NEW.ps_kills_AS = NEW.ps_kills_ships; - SET NEW.ps_kills_AAA = NEW.ps_kills_air_defense; - IF NEW.ps_ejections > 0 THEN SET NEW.pe_LogStats_mstatus = "MIA"; ELSEIF NEW.ps_deaths > 0 THEN @@ -207,7 +173,16 @@ $$ DELIMITER ; +ALTER TABLE `pe_DataMissionHashes` ADD FULLTEXT KEY `pe_DataMissionHashes_hash` (`pe_DataMissionHashes_hash`); + ALTER TABLE `pe_DataPlayers` ADD FULLTEXT KEY `pe_DataPlayers_ucid` (`pe_DataPlayers_ucid`); + +ALTER TABLE `pe_DataTypes` ADD FULLTEXT KEY `pe_DataTypes_name` (`pe_DataTypes_name`); + +ALTER TABLE `pe_LogChat` ADD FULLTEXT KEY `pe_LogChat_msg` (`pe_LogChat_msg`); + +ALTER TABLE `pe_LogEvent` ADD FULLTEXT KEY `pe_LogEvent_argPlayers` (`pe_LogEvent_argPlayers`); +ALTER TABLE `pe_LogEvent` ADD FULLTEXT KEY `pe_LogEvent_type` (`pe_LogEvent_type`); COMMIT; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; From 087dbe84af6b2c25fa631ae046ce9eea6e98825e Mon Sep 17 00:00:00 2001 From: VladMordock Date: Mon, 28 Oct 2019 17:04:41 +0100 Subject: [PATCH 12/17] Update README.md Update with information about data display --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 920abfe..fc7010b 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,12 @@ 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" ``` +## Displaying data +Data displaying and handling is not in the current scope of this project. Since the end of 2018 the Perun data displaying has been hardcoded at forum.gildia.org , website for the Polish DCS community; examples: +![Who is online](https://i.imgur.com/5lVwsJw.png) +![Mission statistics](https://i.imgur.com/uiRSa9e.png) +Due to resource limitations, "Perun for DCS World" will focus on pulling the data from DCS (and external modules) and pushing it to MySQL server, but ** if anyone would like to develop open sourced PHP applets for data/statistics displaying ** we're willing to cooperate and support such projects. Unfortunetly it's not possible to share the hardcoded code from forum.gildia.org. + ## 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) From c01d5da10f6b7a516cccdf337cac6e899b07f4b5 Mon Sep 17 00:00:00 2001 From: VladMordock Date: Mon, 28 Oct 2019 17:05:48 +0100 Subject: [PATCH 13/17] Update README.md Readme fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fc7010b..5192c8a 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ C:\Perun_v1\Perun.exe 48621 1 "G:\DCS SRS\clients-list.json" "C:\Users\DCS\Saved Data displaying and handling is not in the current scope of this project. Since the end of 2018 the Perun data displaying has been hardcoded at forum.gildia.org , website for the Polish DCS community; examples: ![Who is online](https://i.imgur.com/5lVwsJw.png) ![Mission statistics](https://i.imgur.com/uiRSa9e.png) -Due to resource limitations, "Perun for DCS World" will focus on pulling the data from DCS (and external modules) and pushing it to MySQL server, but ** if anyone would like to develop open sourced PHP applets for data/statistics displaying ** we're willing to cooperate and support such projects. Unfortunetly it's not possible to share the hardcoded code from forum.gildia.org. +Due to resource limitations, "Perun for DCS World" will focus on pulling the data from DCS (and external modules) and pushing it to MySQL server, but if anyone would like to develop open sourced PHP applets for data/statistics displaying we're willing to cooperate and support such projects. Unfortunetly it's not possible to share the hardcoded code from forum.gildia.org. ## Troubleshooting - FAQ - [I keep getting 1305 MySQL error](#i-keep-getting-1305-mysql-error) From a6e809a3b165a8dce35a0f7f9264ceb64e8c3d88 Mon Sep 17 00:00:00 2001 From: VladMordock Date: Tue, 29 Oct 2019 00:07:51 +0100 Subject: [PATCH 14/17] Update m1081_perun.sql Fixed landing bug --- 03_MySQL/m1081_perun.sql | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/03_MySQL/m1081_perun.sql b/03_MySQL/m1081_perun.sql index 8ee2a1a..99dde12 100644 --- a/03_MySQL/m1081_perun.sql +++ b/03_MySQL/m1081_perun.sql @@ -30,7 +30,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 AUTO_INCREMENT=7184 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=7194 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_DataPlayers`; CREATE TABLE IF NOT EXISTS `pe_DataPlayers` ( @@ -76,7 +76,7 @@ CREATE TABLE IF NOT EXISTS `pe_LogChat` ( KEY `pe_LogChat_playerid` (`pe_LogChat_playerid`), KEY `pe_LogChat_datetime` (`pe_LogChat_datetime`), KEY `pe_LogChat_all` (`pe_LogChat_all`) -) ENGINE=InnoDB AUTO_INCREMENT=21901 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=22235 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_LogEvent`; CREATE TABLE IF NOT EXISTS `pe_LogEvent` ( @@ -92,7 +92,7 @@ CREATE TABLE IF NOT EXISTS `pe_LogEvent` ( KEY `pe_LogEvent_missionhash_id` (`pe_LogEvent_missionhash_id`), KEY `pe_LogEvent_datetime` (`pe_LogEvent_datetime`), KEY `pe_LogEvent_type_2` (`pe_LogEvent_type`) -) ENGINE=InnoDB AUTO_INCREMENT=98685 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=98988 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_LogLogins`; CREATE TABLE IF NOT EXISTS `pe_LogLogins` ( @@ -106,7 +106,7 @@ CREATE TABLE IF NOT EXISTS `pe_LogLogins` ( KEY `pe_LogLogins_playerid` (`pe_LogLogins_playerid`), KEY `pe_LogLogins_datetime` (`pe_LogLogins_datetime`), KEY `pe_LogLogins_instance` (`pe_LogLogins_instance`) -) ENGINE=InnoDB AUTO_INCREMENT=11195 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=11239 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_LogStats`; CREATE TABLE IF NOT EXISTS `pe_LogStats` ( @@ -149,7 +149,7 @@ CREATE TABLE IF NOT EXISTS `pe_LogStats` ( KEY `pe_LogStats_masterslot` (`pe_LogStats_masterslot`), KEY `pe_LogStats_mstatus` (`pe_LogStats_mstatus`), KEY `pe_LogStats_seat` (`pe_LogStats_seat`) -) ENGINE=InnoDB AUTO_INCREMENT=10086 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=10124 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 @@ -157,13 +157,13 @@ CREATE TRIGGER `pe_LogStats_UPDATE` BEFORE UPDATE ON `pe_LogStats` FOR EACH ROW SET NEW.pe_LogStats_mstatus = "MIA"; ELSEIF NEW.ps_deaths > 0 THEN SET NEW.pe_LogStats_mstatus = "KIA"; - ELSEIF NEW.ps_landings >= NEW.ps_takeoffs THEN - IF NEW.ps_takeoffs > 0 or NEW.ps_landings > 0 THEN + ELSEIF (NEW.ps_airfield_landings + NEW.ps_farp_landings + NEW.ps_other_landings + NEW.ps_ship_landings) >= (NEW.ps_airfield_takeoffs + NEW.ps_farp_takeoffs + NEW.ps_other_takeoffs + NEW.ps_ship_takeoffs) THEN + IF (NEW.ps_airfield_takeoffs + NEW.ps_farp_takeoffs + NEW.ps_other_takeoffs + NEW.ps_ship_takeoffs) > 0 or (NEW.ps_airfield_landings + NEW.ps_farp_landings + NEW.ps_other_landings + NEW.ps_ship_landings) > 0 THEN SET NEW.pe_LogStats_mstatus = "RTB"; ELSE SET NEW.pe_LogStats_mstatus = "?"; END IF; - ELSEIF NEW.ps_takeoffs > NEW.ps_landings and NEW.ps_ejections=0 and NEW.ps_deaths=0 THEN + ELSEIF (NEW.ps_airfield_takeoffs + NEW.ps_farp_takeoffs + NEW.ps_other_takeoffs + NEW.ps_ship_takeoffs) > (NEW.ps_airfield_landings + NEW.ps_farp_landings + NEW.ps_other_landings + NEW.ps_ship_landings) and NEW.ps_ejections=0 and NEW.ps_deaths=0 THEN SET NEW.pe_LogStats_mstatus = "MIA"; ELSE SET NEW.pe_LogStats_mstatus = "?"; @@ -180,9 +180,6 @@ ALTER TABLE `pe_DataPlayers` ADD FULLTEXT KEY `pe_DataPlayers_ucid` (`pe_DataPla ALTER TABLE `pe_DataTypes` ADD FULLTEXT KEY `pe_DataTypes_name` (`pe_DataTypes_name`); ALTER TABLE `pe_LogChat` ADD FULLTEXT KEY `pe_LogChat_msg` (`pe_LogChat_msg`); - -ALTER TABLE `pe_LogEvent` ADD FULLTEXT KEY `pe_LogEvent_argPlayers` (`pe_LogEvent_argPlayers`); -ALTER TABLE `pe_LogEvent` ADD FULLTEXT KEY `pe_LogEvent_type` (`pe_LogEvent_type`); COMMIT; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; From ddd72adea37f93a75cd2a86dd113926b2b3c95c8 Mon Sep 17 00:00:00 2001 From: szporowolik Date: Thu, 31 Oct 2019 10:25:06 +0100 Subject: [PATCH 15/17] Fixed "landed at" bug --- 01_DCS/Hooks/Perun.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/01_DCS/Hooks/Perun.lua b/01_DCS/Hooks/Perun.lua index c3cb552..5fd483a 100644 --- a/01_DCS/Hooks/Perun.lua +++ b/01_DCS/Hooks/Perun.lua @@ -849,9 +849,9 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7) elseif eventName == "landing" then --"landing", playerID, unit_missionID, airdromeName if arg3 ~= "" then - _temp = " at " .. arg3; + _temp_airfield = " at " .. arg3; else - _temp =""; + _temp_airfield =""; end -- TBD below shall be moved to function and arrays of strings - see takeoffs From 6423f6534cdc31ab87567820cd09506db2c3787b Mon Sep 17 00:00:00 2001 From: szporowolik Date: Thu, 31 Oct 2019 10:28:00 +0100 Subject: [PATCH 16/17] DB structure upadated and frozen for v0.9.0 --- 03_MySQL/m1081_perun.sql | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/03_MySQL/m1081_perun.sql b/03_MySQL/m1081_perun.sql index 99dde12..590ba41 100644 --- a/03_MySQL/m1081_perun.sql +++ b/03_MySQL/m1081_perun.sql @@ -30,7 +30,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 AUTO_INCREMENT=7194 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=7215 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_DataPlayers`; CREATE TABLE IF NOT EXISTS `pe_DataPlayers` ( @@ -41,7 +41,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 AUTO_INCREMENT=224 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=226 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_DataRaw`; CREATE TABLE IF NOT EXISTS `pe_DataRaw` ( @@ -61,7 +61,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 AUTO_INCREMENT=59 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=60 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_LogChat`; CREATE TABLE IF NOT EXISTS `pe_LogChat` ( @@ -76,7 +76,7 @@ CREATE TABLE IF NOT EXISTS `pe_LogChat` ( KEY `pe_LogChat_playerid` (`pe_LogChat_playerid`), KEY `pe_LogChat_datetime` (`pe_LogChat_datetime`), KEY `pe_LogChat_all` (`pe_LogChat_all`) -) ENGINE=InnoDB AUTO_INCREMENT=22235 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=22686 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_LogEvent`; CREATE TABLE IF NOT EXISTS `pe_LogEvent` ( @@ -92,7 +92,7 @@ CREATE TABLE IF NOT EXISTS `pe_LogEvent` ( KEY `pe_LogEvent_missionhash_id` (`pe_LogEvent_missionhash_id`), KEY `pe_LogEvent_datetime` (`pe_LogEvent_datetime`), KEY `pe_LogEvent_type_2` (`pe_LogEvent_type`) -) ENGINE=InnoDB AUTO_INCREMENT=98988 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=99807 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_LogLogins`; CREATE TABLE IF NOT EXISTS `pe_LogLogins` ( @@ -106,7 +106,7 @@ CREATE TABLE IF NOT EXISTS `pe_LogLogins` ( KEY `pe_LogLogins_playerid` (`pe_LogLogins_playerid`), KEY `pe_LogLogins_datetime` (`pe_LogLogins_datetime`), KEY `pe_LogLogins_instance` (`pe_LogLogins_instance`) -) ENGINE=InnoDB AUTO_INCREMENT=11239 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=11344 DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `pe_LogStats`; CREATE TABLE IF NOT EXISTS `pe_LogStats` ( @@ -149,7 +149,7 @@ CREATE TABLE IF NOT EXISTS `pe_LogStats` ( KEY `pe_LogStats_masterslot` (`pe_LogStats_masterslot`), KEY `pe_LogStats_mstatus` (`pe_LogStats_mstatus`), KEY `pe_LogStats_seat` (`pe_LogStats_seat`) -) ENGINE=InnoDB AUTO_INCREMENT=10124 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=10220 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 From 0385aa8ee5007118812aea27226d0c5d022c6c96 Mon Sep 17 00:00:00 2001 From: VladMordock Date: Thu, 31 Oct 2019 23:19:30 +0100 Subject: [PATCH 17/17] Update README.md Information about contributing edited. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5192c8a..839769b 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,7 @@ DCS API does not track carrier landing natively, so there is a trick to achive t * [Notepad++](https://notepad-plus-plus.org/) ## Contributing -Please contact me if you'd like to contribute. +Please contact me if you'd like to contribute. Short rule is that all pull request shall come to "dev" branch, pull requests to "master" will be deleted. ## 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).