34 Commits

Author SHA1 Message Date
VladMordock
30502e6fcc Merge pull request #26 from szporwolik/dev
v0.9.2
2019-11-18 01:37:48 +01:00
VladMordock
7d16dc197c Merge branch 'master' into dev 2019-11-18 01:37:27 +01:00
szporowolik
7ad493f5f0 Shall be ready for final testing and v0.9.2 release 2019-11-11 02:46:45 +01:00
szporowolik
2821ee9cd6 Final fix for #25 ; all stats cache mechanism was improved. 2019-11-11 02:25:43 +01:00
szporowolik
946d60c5f5 Database upgrade to add feature #25 2019-11-11 00:22:17 +01:00
szporowolik
c831835dfa First approach for feature request #25 - shall work, testing is required 2019-11-11 00:20:38 +01:00
szporowolik
28b614662b Minor fixes 2019-11-08 00:04:42 +01:00
szporowolik
5fbd071b9b Commented pulling of all mission data, shall improve performance. 2019-11-07 23:53:39 +01:00
szporowolik
26bf326e0a Code clean up for takeoffs and landings 2019-11-07 23:39:20 +01:00
szporowolik
fc6b1d9629 Deleted JSON export 2019-11-07 23:22:55 +01:00
szporowolik
c1fc566f03 Removed json export 2019-11-07 23:22:31 +01:00
VladMordock
382def09da Update README.md
Removed references about JSON export.
2019-11-07 23:17:38 +01:00
szporowolik
fdcb82cafa Fixed issue #19 - disconnect event 2019-11-07 23:11:00 +01:00
szporowolik
fe2b9cd3f1 Changes trying to get player disconnect event hanlder to work 2019-11-07 01:18:23 +01:00
szporowolik
15707672d2 Fixed date format in Perun log file 2019-11-07 01:12:39 +01:00
VladMordock
63fbb0b3bb Update m1081_perun.sql
Another trouble with MySQL compatibility fixed
2019-11-07 00:58:14 +01:00
szporowolik
885bbf2989 Shall fix the lag issue when connection is not available. 2019-11-07 00:20:01 +01:00
VladMordock
9349309645 Update m1081_perun.sql
Fix for "ERROR MySQL - error id: 1364" on specific MySQL config
2019-11-06 23:46:45 +01:00
VladMordock
8c6e87120e Update README.md
Update about 1364 mysql error.
2019-11-06 23:32:31 +01:00
VladMordock
18bebf887b Update README.md 2019-11-06 23:19:42 +01:00
VladMordock
5b22ddd66e Update README.md 2019-11-06 23:18:20 +01:00
VladMordock
01d8b6ceba Update README.md 2019-11-06 23:12:37 +01:00
VladMordock
4d989167ba Update README.md
Updated to avoid confusion.
2019-11-06 16:59:39 +01:00
szporowolik
1c13b8896a Preparation for 0.9.2 2019-11-04 00:33:42 +01:00
VladMordock
a9e87b1049 Update README.md 2019-11-03 01:17:12 +01:00
VladMordock
c8b7abc41c Merge pull request #21 from szporwolik/dev
Dev
2019-11-02 23:18:00 +01:00
szporowolik
7270ff8bab v0.9.1 2019-11-02 23:13:40 +01:00
szporowolik
ed8ed6d62a Db update for v0.9.1 2019-11-02 23:10:41 +01:00
szporowolik
9b54a0be8d Fix for disconnects not beeing tracked 2019-11-02 18:25:06 +01:00
szporowolik
becbce25c0 v0.9.1 preparation 2019-11-02 18:23:04 +01:00
szporowolik
7c1b533d79 Version check will not run for DEBUG builds 2019-11-02 18:22:20 +01:00
szporowolik
6c10f5bace Update for DCS SRS 1.7.2 ( SRS's JSON file format was changed) 2019-11-02 18:18:40 +01:00
szporowolik
c2b5f6258b Update build information 2019-11-02 17:29:11 +01:00
VladMordock
61d2a1b16e Update README.md
Added information about stats for FARP and Carrier operations.
2019-10-31 23:32:12 +01:00
10 changed files with 214 additions and 166 deletions

View File

@@ -9,9 +9,9 @@ package.cpath = package.cpath..";"..lfs.currentdir().."/LuaSocket/?.dll"
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.TCPTargetPort = 48620 -- (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.Instance = 1 -- (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
@@ -22,24 +22,27 @@ Perun.MOTD_L2 = "Wymagamy obecnosci DCS SRS oraz TeamSpeak - szczegoly na forum"
-- ###################### END OF SETTINGS - DO NOT MODIFY OUTSIDE THIS SECTION ######################
-- Variable init
Perun.Version = "v0.9.0"
Perun.Version = "v0.9.2"
Perun.StatusData = {}
Perun.SlotsData = {}
Perun.MissionData = {}
Perun.ServerData = {}
Perun.StatData = {}
Perun.StatDataLastType = {}
Perun.PlayersTableCache = {}
Perun.MissionHash=""
Perun.ReconnectTimeout = 30
Perun.lastSentStatus = 0
Perun.lastSentMission = 0
Perun.lastSentKeepAlive = 0
Perun.lastConnectionError = 0
Perun.lastReconnect = 0
Perun.SendRetries = 3
Perun.lastTimer = 0
Perun.lastReconnect = (-1) * Perun.ReconnectTimeout
Perun.SendRetries = 2
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.IsServer = DCS.isServer( )
Perun.ConnectionError = "[Perun] ERROR: Connection broken - contact server admin!"
-- ################################ Helper function definitions ################################
@@ -134,7 +137,7 @@ function stripChars(str)
end
Perun.GetCategory = function(id)
-- Helper function returns object category basing on I via https://pastebin.com/GUAXrd2U TBD: rewrite
-- Helper function returns object category basing on https://pastebin.com/GUAXrd2U
local _killed_target_category = DCS.getUnitTypeAttribute(id, "category")
-- Below, simple hack to get the propper category when DCS API is not returning correct value
@@ -179,11 +182,15 @@ 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
local _player_slot = net.get_player_info(PlayerId, 'slot')
if not _player_slot then
_player_slot=Perun.PlayersTableCache["p"..PlayerId].slot
end
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
@@ -214,6 +221,9 @@ Perun.GetMulticrewAllParameters = function (PlayerId)
end
_master_slot = -1
_sub_slot = 0
else
_master_slot = -1
_sub_slot = -1
end
return _master_type,_master_slot,_sub_slot
end
@@ -278,6 +288,29 @@ Perun.GetMulticrewCrewNames = function (owner_playerID)
return _result_text
end
Perun.GetTakeOffLandingEvent = function (takeoff,location)
-- Get correct event type for statistics basing on objecy which served as runway/farp
local _operation = ""
if takeoff == true then
_operation="tookoff_"
else
_operation="landing_"
end
local _temp_type = ""
if string.find(location, "FARP",1,true) then
_temp_type = "FARP"
elseif string.find(location, "CVN-74 John C. Stennis",1,true) or string.find(location, "LHA-1 Tarawa",1,true) or string.find(location, "SHIP",1,true) then
_temp_type = "SHIP"
elseif location ~= "" then
_temp_type = "AIRFIELD"
else
_temp_type = "OTHER"
end
return _operation .. _temp_type
end
-- ################################ TCP Connection ################################
Perun.ConnectToPerun = function ()
@@ -293,8 +326,9 @@ Perun.ConnectToPerun = function ()
else
-- Connected
Perun.AddLog("Success - connected to TCP server",2)
Perun.lastReconnect = _now
end
local _now = DCS.getRealTime()
Perun.lastReconnect = _now
end
Perun.SendToPerun = function(data_id, data_package)
@@ -315,12 +349,15 @@ Perun.SendToPerun = function(data_id, data_package)
local _dropped = true
-- Try to send a few times (defind in settings section)
local _now = DCS.getRealTime()
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()
if _now > Perun.lastReconnect + Perun.ReconnectTimeout then
Perun.ConnectToPerun()
end
else
-- Succes, packet was send
Perun.AddLog("Packet send : " .. data_id .. " , tries:" .. _intTries,2)
@@ -332,8 +369,7 @@ Perun.SendToPerun = function(data_id, data_package)
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
if _now > Perun.lastConnectionError + Perun.ReconnectTimeout 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
@@ -390,8 +426,8 @@ Perun.LogStats = function(playerID)
_TempData['stat_data_type']= _PlayerStatsTable['ps_type'];
_TempData['stat_data_masterslot'] = _PlayerStatsTable['ps_masterslot'];
_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_ucid']=_PlayerStatsTable['ps_ucid'];
_TempData['stat_name']=_PlayerStatsTable['ps_name'];
_TempData['stat_datetime']=os.date('%Y-%m-%d %H:%M:%S')
_TempData['stat_missionhash']=Perun.MissionHash
@@ -399,6 +435,16 @@ Perun.LogStats = function(playerID)
Perun.SendToPerun(52,_TempData)
end
Perun.LogAllStats = function()
-- Log all players data
local _all_players = net.get_player_list()
for PlayerIDIndex, _playerID in ipairs(_all_players) do
if _playerID ~= 1 then
Perun.LogStats(_playerID)
end
end
end
Perun.LogLogin = function(playerID)
-- Player logged in
local _TempData={}
@@ -413,13 +459,18 @@ end
--- ################################ Calculate stats ################################
Perun.LogStatsCount = function(argPlayerID,argAction)
Perun.LogStatsCount = function(argPlayerID,argAction,argTimer)
-- Creates or updates Perun statistics array
local _player_hash=net.get_player_info(argPlayerID, 'ucid')..Perun.GetMulticrewParameter(argPlayerID,"subtype")
-- By default we will be sending stats
argTimer = argTimer or false
if Perun.StatData[_player_hash] == nil then
-- Create empty element
local _TempData={}
_TempData['ps_ucid'] = net.get_player_info(argPlayerID, 'ucid')
_TempData['ps_name'] = net.get_player_info(argPlayerID, 'name')
_TempData['ps_type'] = Perun.GetMulticrewParameter(argPlayerID,"subtype")
_TempData['ps_masterslot'] = Perun.GetMulticrewParameter(argPlayerID,"masterslot")
_TempData['ps_subslot'] = Perun.GetMulticrewParameter(argPlayerID,"subslot")
@@ -428,6 +479,7 @@ Perun.LogStatsCount = function(argPlayerID,argAction)
_TempData['ps_ejections'] = 0
_TempData['ps_crashes'] = 0
_TempData['ps_teamkills'] = 0
_TempData['ps_time'] = 0
_TempData['ps_kills_planes'] = 0
_TempData['ps_kills_helicopters'] = 0
_TempData['ps_kills_air_defense'] = 0
@@ -449,15 +501,12 @@ 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");
if Perun.GetMulticrewParameter(argPlayerID,"subtype") ~= nil then
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
@@ -505,6 +554,8 @@ Perun.LogStatsCount = function(argPlayerID,argAction)
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
elseif argAction == "timer" then
Perun.StatData[_player_hash]['ps_time']=Perun.StatData[_player_hash]['ps_time']+1
end
-- Always update slots
@@ -512,7 +563,11 @@ Perun.LogStatsCount = function(argPlayerID,argAction)
Perun.StatData[_player_hash]['ps_subslot'] = Perun.GetMulticrewParameter(argPlayerID,"subslot")
Perun.AddLog("Stats data prepared",2)
Perun.LogStats(argPlayerID);
-- If this is timer request do not send data to database
if argTimer ~= true then
Perun.LogStats(argPlayerID);
end
end
Perun.LogStatsCountCrew = function (MasterPilotID,ActionType)
@@ -525,22 +580,27 @@ 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
-- Gets Perun statistics array per player
local next = next -- Make next function local - this improves performance
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')]
local _ucid = net.get_player_info(playerID, 'ucid')
if not _ucid then
_ucid=Perun.PlayersTableCache["p"..playerID].ucid
end
local next = next -- Make next function local - this improves performance TBD
if next(Perun.StatDataLastType) == nil then
-- Array is empty
_player_hash=_ucid..Perun.GetMulticrewParameter(playerID,"subtype")
elseif Perun.StatDataLastType[net.get_player_info(playerID, 'ucid')]== nil then
-- Last type entry is empty
_player_hash=_ucid..Perun.GetMulticrewParameter(playerID,"subtype")
else
-- Return last type entry
_player_hash=Perun.StatDataLastType[_ucid]
end
local next = next -- Make next function local - this improves performance
if next(Perun.StatData) == nil then
-- Array is empty
Perun.LogStatsCount(playerID,'init') -- Init statistics
@@ -554,21 +614,6 @@ Perun.LogStatsGet = function(playerID)
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
@@ -650,7 +695,7 @@ Perun.onSimulationStart = function()
Perun.LogEvent("SimStart","Mission " .. Perun.MissionHash .. " started",nil,nil);
Perun.StatData = {}
Perun.StatDataLastType = {}
-- TBD send this to Perun
Perun.PlayersTableCache = {}
end
Perun.onSimulationStop = function()
@@ -659,13 +704,21 @@ Perun.onSimulationStop = function()
Perun.MissionHash=Perun.GenerateMissionHash();
Perun.StatData = {}
Perun.StatDataLastType = {}
-- TBD send this to Perun
Perun.LogAllStats()
Perun.PlayersTableCache = {}
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
-- Player disconnected
Perun.LogEvent("disconnect", "Player " .. id .. " disconnected.(?)",nil,nil);
return
end
Perun.onPlayerStop = function (id)
-- Player left the simulation (happens right before a disconnect, if player exited by desire)
Perun.LogEvent("quit", "Player " .. id .. " quit the server.",nil,nil);
return
end
Perun.onSimulationFrame = function()
@@ -682,7 +735,6 @@ Perun.onSimulationFrame = function()
Perun.lastSentMission = _now
Perun.UpdateMission()
Perun.UpdateJsonStatus()
end
-- Send status update
@@ -697,6 +749,19 @@ Perun.onSimulationFrame = function()
Perun.lastSentKeepAlive = _now
Perun.SendToPerun(0,nil)
end
-- Calucalate time on slot per each of players
if _now > Perun.lastTimer + 60 then
Perun.lastTimer = _now;
local _all_players = net.get_player_list()
for PlayerIDIndex, _playerID in ipairs(_all_players) do
if _playerID ~= 1 then
Perun.LogStatsCount(_playerID,"timer",true)
end
end
end
end
Perun.onPlayerStart = function (id)
@@ -792,26 +857,29 @@ Perun.onGameEvent = function (eventName,arg1,arg2,arg3,arg4,arg5,arg6,arg7)
elseif eventName == "change_slot" then
--"change_slot", playerID, slotID, prevSide
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);
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);
Perun.LogStats(arg1);
Perun.LogStatsCount(arg1,"init")
Perun.PlayersTableCache["p"..arg1]=net.get_player_info(arg1);
elseif eventName == "connect" then
--"connect", playerID, name
Perun.LogLogin(arg1);
Perun.LogEvent(eventName,"Player "..net.get_player_info(arg1, "name") .. " connected",nil,nil);
Perun.PlayersTableCache["p"..arg1]=net.get_player_info(arg1);
elseif eventName == "disconnect" then
--"disconnect", playerID, name, playerSide, reason_code
Perun.LogEvent(eventName,"Player " .. arg2 .. " disconnected (".. arg4 .. ")." ,arg4,nil);
Perun.LogStats(arg1);
Perun.LogEvent(eventName, Perun.SideID2Name(arg3) .. " player " ..net.get_player_info(arg1, "name") .. " disconnected",nil,nil);
elseif eventName == "crash" then
--"crash", playerID, unit_missionID
@@ -831,19 +899,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"
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
_temp_type="tookoff_AIRFIELD"
else
_temp_type="tookoff_OTHER"
end
Perun.LogStatsCountCrew (arg1,_temp_type)
Perun.LogStatsCountCrew (arg1,Perun.GetTakeOffLandingEvent(true,arg3))
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
@@ -854,19 +910,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 takeoffs
_temp_type = ""
if string.find(arg3, "FARP",1,true) then
_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
_temp_type = "landing_AIRFIELD"
else
_temp_type = "landing_OTHER"
end
Perun.LogStatsCountCrew (arg1,_temp_type)
Perun.LogStatsCountCrew (arg1,Perun.GetTakeOffLandingEvent(false,arg3))
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

View File

@@ -1 +0,0 @@
[]

View File

@@ -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_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 + "');";
SQLQueryTxt += "UPDATE `pe_LogStats` SET `ps_time`=" + TCPFrame.payload.stat_data_perun.ps_time + ",`pe_LogStats_seat`=" + TCPFrame.payload.stat_data_subslot + ",`pe_LogStats_masterslot`=" + TCPFrame.payload.stat_data_masterslot + ",`ps_kills_fortification`=" + TCPFrame.payload.stat_data_perun.ps_kills_fortification + ",`ps_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")
{

View File

@@ -48,7 +48,7 @@ internal class PerunHelper
Globals.AppUpdateGUI = true;
}
// Add the entry to log file
LogController.WriteLog(DateTime.Now.ToString("yyyy-dd-MM ") + " " + DateTime.Now.ToString("HH:mm:ss") + " | Instance: "+ Globals.AppInstanceID + " | " + LogMarker + " | "+ LogDirection + " | "+ strType + " | " + strEntryToAdd);
LogController.WriteLog(DateTime.Now.ToString("yyyy-MM-dd ") + " " + DateTime.Now.ToString("HH:mm:ss") + " | Instance: "+ Globals.AppInstanceID + " | " + LogMarker + " | "+ LogDirection + " | "+ strType + " | " + strEntryToAdd);
}
public static string GetAppVersion(string strBeginning)
@@ -60,6 +60,7 @@ internal class PerunHelper
public static int CheckVersions()
{
#if !DEBUG
// Checks the versions of APP, DCS Hook and MySQL database
Match match = Regex.Match(Globals.VersionPerun, @"^\d+.\d+.\d+", RegexOptions.Compiled | RegexOptions.IgnoreCase);
string VersionApp = "v" + match.Groups[0].Value;
@@ -90,5 +91,8 @@ internal class PerunHelper
}
return ReturnValue;
#else
return 1;
#endif
}
}

View File

@@ -157,11 +157,11 @@
// label6
//
this.label6.AutoSize = true;
this.label6.Location = new System.Drawing.Point(41, 48);
this.label6.Location = new System.Drawing.Point(19, 48);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(59, 13);
this.label6.Size = new System.Drawing.Size(81, 13);
this.label6.TabIndex = 9;
this.label6.Text = "Server port";
this.label6.Text = "MySQL DB port";
//
// con_txt_mysql_port
//
@@ -198,20 +198,20 @@
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(47, 74);
this.label2.Location = new System.Drawing.Point(18, 74);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(53, 13);
this.label2.Size = new System.Drawing.Size(82, 13);
this.label2.TabIndex = 4;
this.label2.Text = "Database";
this.label2.Text = "Database name";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(22, 22);
this.label1.Location = new System.Drawing.Point(3, 22);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(78, 13);
this.label1.Size = new System.Drawing.Size(100, 13);
this.label1.TabIndex = 3;
this.label1.Text = "Server address";
this.label1.Text = "MySQL DB address";
//
// con_txt_mysql_database
//
@@ -359,11 +359,11 @@
// label8
//
this.label8.AutoSize = true;
this.label8.Location = new System.Drawing.Point(41, 45);
this.label8.Location = new System.Drawing.Point(7, 45);
this.label8.Name = "label8";
this.label8.Size = new System.Drawing.Size(62, 13);
this.label8.Size = new System.Drawing.Size(93, 13);
this.label8.TabIndex = 12;
this.label8.Text = "Instance ID";
this.label8.Text = "Perun Instance ID";
//
// con_txt_dcs_instance
//
@@ -375,11 +375,11 @@
// label7
//
this.label7.AutoSize = true;
this.label7.Location = new System.Drawing.Point(41, 19);
this.label7.Location = new System.Drawing.Point(44, 19);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(59, 13);
this.label7.Size = new System.Drawing.Size(56, 13);
this.label7.TabIndex = 10;
this.label7.Text = "Server port";
this.label7.Text = "Perun port";
//
// con_txt_dcs_server_port
//

View File

@@ -506,46 +506,40 @@ namespace Perun_v1
ExtSRSJson = System.IO.File.ReadAllText(con_txt_3rd_srs.Text);
dynamic raw_lotatc = JsonConvert.DeserializeObject(ExtSRSJson);
for (int i = 0; i < raw_lotatc.Count; i++)
for (int i = 0; i < raw_lotatc.Clients.Count; i++)
{
if (raw_lotatc[i].RadioInfo != null)
if (raw_lotatc.Clients[i].RadioInfo != null)
{
int temp = raw_lotatc[i].RadioInfo.radios.Count - 1;
int temp = raw_lotatc.Clients[i].RadioInfo.radios.Count - 1;
for (int j = temp; j >= 0; j--)
{
raw_lotatc[i].RadioInfo.radios[j].enc.Parent.Remove();
raw_lotatc[i].RadioInfo.radios[j].encKey.Parent.Remove();
raw_lotatc[i].RadioInfo.radios[j].encMode.Parent.Remove();
raw_lotatc[i].RadioInfo.radios[j].freqMax.Parent.Remove();
raw_lotatc[i].RadioInfo.radios[j].freqMin.Parent.Remove();
raw_lotatc[i].RadioInfo.radios[j].modulation.Parent.Remove();
raw_lotatc[i].RadioInfo.radios[j].freqMode.Parent.Remove();
raw_lotatc[i].RadioInfo.radios[j].volMode.Parent.Remove();
raw_lotatc[i].RadioInfo.radios[j].expansion.Parent.Remove();
raw_lotatc[i].RadioInfo.radios[j].channel.Parent.Remove();
raw_lotatc[i].RadioInfo.radios[j].simul.Parent.Remove();
raw_lotatc.Clients[i].RadioInfo.radios[j].enc.Parent.Remove();
raw_lotatc.Clients[i].RadioInfo.radios[j].encKey.Parent.Remove();
raw_lotatc.Clients[i].RadioInfo.radios[j].encMode.Parent.Remove();
raw_lotatc.Clients[i].RadioInfo.radios[j].freqMax.Parent.Remove();
raw_lotatc.Clients[i].RadioInfo.radios[j].freqMin.Parent.Remove();
raw_lotatc.Clients[i].RadioInfo.radios[j].modulation.Parent.Remove();
raw_lotatc.Clients[i].RadioInfo.radios[j].freqMode.Parent.Remove();
raw_lotatc.Clients[i].RadioInfo.radios[j].volMode.Parent.Remove();
raw_lotatc.Clients[i].RadioInfo.radios[j].expansion.Parent.Remove();
raw_lotatc.Clients[i].RadioInfo.radios[j].channel.Parent.Remove();
raw_lotatc.Clients[i].RadioInfo.radios[j].simul.Parent.Remove();
if (raw_lotatc[i].RadioInfo.radios[j].name == "No Radio")
if (raw_lotatc.Clients[i].RadioInfo.radios[j].name == "No Radio")
{
raw_lotatc[i].RadioInfo.radios[j].Remove();
raw_lotatc.Clients[i].RadioInfo.radios[j].Remove();
}
}
raw_lotatc[i].ClientChannelId.Parent.Remove();
raw_lotatc[i].RadioInfo.simultaneousTransmission.Parent.Remove();
raw_lotatc.Clients[i].ClientChannelId.Parent.Remove();
raw_lotatc.Clients[i].RadioInfo.simultaneousTransmission.Parent.Remove();
}
}
if (raw_lotatc.Count > 0)
{
ExtSRSJson = JsonConvert.SerializeObject(raw_lotatc);
ExtSRSJson = "{'type':'100','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':'" + ExtSRSJson + "'}";
}
else
{
ExtSRSJson = "{'type':'100','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':{'ignore':'false'}}"; // No SRS clients connected
}
ExtSRSJson = JsonConvert.SerializeObject(raw_lotatc);
ExtSRSJson = "{'type':'100','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':'" + ExtSRSJson + "'}";
ExtSRSUseDefault = false;
PerunHelper.AddLog(ref Globals.AppLogHistory, "SRS data loaded", 3, 0, "100", true);
ExtSRSStatus = true;
@@ -563,7 +557,10 @@ namespace Perun_v1
{
ExtSRSJson = "{'type':'100','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':{'ignore':'true'}}";
}
DatabaseConnection.SendToMySql(ExtSRSJson);
if (ExtSRSStatus)
{
DatabaseConnection.SendToMySql(ExtSRSJson);
}
}
// Handle LotATC
@@ -594,7 +591,10 @@ namespace Perun_v1
{
ExtLotATCJson = "{'type':'101','instance':'" + Int32.Parse(con_txt_dcs_instance.Text) + "','payload':{'ignore':'true'}}"; // No LotATC controller connected
}
DatabaseConnection.SendToMySql(ExtLotATCJson);
if (ExtLotATCStatus)
{
DatabaseConnection.SendToMySql(ExtLotATCJson);
}
}
// Let's do not risk int overload

View File

@@ -12,29 +12,27 @@
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<IsWebBootstrapper>true</IsWebBootstrapper>
<IsWebBootstrapper>false</IsWebBootstrapper>
<TargetFrameworkProfile />
<PublishUrl>ftp://s18.mydevil.net/perun/</PublishUrl>
<PublishUrl>C:\Users\DCS\Desktop\Perun\</PublishUrl>
<Install>true</Install>
<InstallFrom>Web</InstallFrom>
<UpdateEnabled>true</UpdateEnabled>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<InstallUrl>http://share.porwolik.com/ftp/perun/</InstallUrl>
<SupportUrl>https://github.com/szporwolik/perun</SupportUrl>
<ErrorReportUrl>https://github.com/szporwolik/perun</ErrorReportUrl>
<TargetCulture>en</TargetCulture>
<ProductName>Perun for DCS World</ProductName>
<PublisherName>szporwolik</PublisherName>
<SuiteName>Perun</SuiteName>
<CreateWebPageOnPublish>true</CreateWebPageOnPublish>
<WebPage>Perun.htm</WebPage>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>0.9.0.%2a</ApplicationVersion>
<ApplicationVersion>0.9.2.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<CreateDesktopShortcut>true</CreateDesktopShortcut>
<PublishWizardCompleted>true</PublishWizardCompleted>

View File

@@ -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.9.0.0")]
[assembly: AssemblyFileVersion("0.9.0.0")]
[assembly: AssemblyVersion("0.9.2.0")]
[assembly: AssemblyFileVersion("0.9.2.0")]
[assembly: NeutralResourcesLanguage("en")]

View File

@@ -8,8 +8,6 @@ SET time_zone = "+00:00";
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
CREATE DATABASE IF NOT EXISTS `m1081_perun` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
USE `m1081_perun`;
DROP TABLE IF EXISTS `pe_Config`;
CREATE TABLE IF NOT EXISTS `pe_Config` (
@@ -19,7 +17,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.9.0');
(1, 'v0.9.2');
DROP TABLE IF EXISTS `pe_DataMissionHashes`;
CREATE TABLE IF NOT EXISTS `pe_DataMissionHashes` (
@@ -30,24 +28,25 @@ 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=7215 DEFAULT CHARSET=utf8;
ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `pe_DataPlayers`;
CREATE TABLE IF NOT EXISTS `pe_DataPlayers` (
`pe_DataPlayers_id` bigint(20) NOT NULL AUTO_INCREMENT,
`pe_DataPlayers_ucid` varchar(150) NOT NULL,
`pe_DataPlayers_lastname` varchar(150) NOT NULL,
`pe_DataPlayers_lastip` varchar(100) NOT NULL,
`pe_DataPlayers_lastname` varchar(150) DEFAULT NULL,
`pe_DataPlayers_lastip` varchar(100) DEFAULT NULL,
`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=226 DEFAULT CHARSET=utf8;
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `pe_DataRaw`;
CREATE TABLE IF NOT EXISTS `pe_DataRaw` (
`pe_dataraw_type` tinyint(4) NOT NULL,
`pe_dataraw_instance` smallint(5) UNSIGNED NOT NULL,
`pe_dataraw_payload` text NOT NULL,
`pe_dataraw_payload` text,
`pe_dataraw_updated` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`pe_dataraw_type`,`pe_dataraw_instance`),
KEY `pe_dataraw_type_pe_dataraw_instance` (`pe_dataraw_type`,`pe_dataraw_instance`),
@@ -61,7 +60,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=60 DEFAULT CHARSET=utf8;
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `pe_LogChat`;
CREATE TABLE IF NOT EXISTS `pe_LogChat` (
@@ -76,7 +75,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=22686 DEFAULT CHARSET=utf8;
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `pe_LogEvent`;
CREATE TABLE IF NOT EXISTS `pe_LogEvent` (
@@ -92,7 +91,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=99807 DEFAULT CHARSET=utf8;
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `pe_LogLogins`;
CREATE TABLE IF NOT EXISTS `pe_LogLogins` (
@@ -106,7 +105,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=11344 DEFAULT CHARSET=utf8;
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `pe_LogStats`;
CREATE TABLE IF NOT EXISTS `pe_LogStats` (
@@ -117,7 +116,7 @@ CREATE TABLE IF NOT EXISTS `pe_LogStats` (
`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_kills_X` 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',
`ps_ejections` int(11) UNSIGNED NOT NULL DEFAULT '0',
@@ -140,6 +139,7 @@ CREATE TABLE IF NOT EXISTS `pe_LogStats` (
`ps_farp_landings` int(11) UNSIGNED NOT NULL DEFAULT '0',
`ps_other_landings` int(10) UNSIGNED NOT NULL DEFAULT '0',
`ps_other_takeoffs` int(10) UNSIGNED NOT NULL DEFAULT '0',
`ps_time` int(10) UNSIGNED NOT NULL DEFAULT '0',
`pe_LogStats_mstatus` enum('?','RTB','MIA','KIA') DEFAULT NULL,
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,
@@ -149,7 +149,8 @@ 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=10220 DEFAULT CHARSET=utf8;
) ENGINE=InnoDB 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

View File

@@ -1,3 +1,4 @@
![Discord](https://img.shields.io/discord/641759751780302866)
![alt text](https://img.shields.io/github/license/szporwolik/perun.svg "MIT")
![alt text](https://img.shields.io/github/release-pre/szporwolik/perun.svg "Latest release")
![alt text](https://img.shields.io/github/release-date-pre/szporwolik/perun.svg "Latest release date")
@@ -5,20 +6,19 @@
![Perun logo](https://i.imgur.com/JkeHYjJ.png)
# Perun for DCS World
Included lua script extracts data from DCS World multiplayer server and sends information to TCP port and JSON file for further processing.
Included lua script extracts data from DCS World multiplayer server and sends information to TCP port for further processing.
Provided windows app puts received TCP packets to MySQL database; additionaly Perun windows application can be used to merge LotATC and DCS SRS data in one database making Perun for DCS World wannabe ultimate integration tool for the server admins.
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.
However, this software is intended to be used by experienced users - the output is MySQL data; you will need to process/display it yourself.
![Perun in action](https://i.imgur.com/JIlLENa.png)
![Data flow](https://i.imgur.com/JbNu77l.png)
Discord server: https://discord.gg/MTahREx
## Prerequisites
Core:
* For JSON Export:
* DCS World stable or DCS World beta
* **(Optional)** For MySQL Export:
* MySQL database with read/write access running at min. 5.7 server (tested with v5.7.21; native JSON support is required)
* .NET Framework 4.8.0
@@ -29,13 +29,12 @@ Core:
## Installing
* Download latest [release](https://github.com/szporwolik/perun/releases)
* Copy contents of [01_DCS](https://github.com/szporwolik/perun/tree/master/01_DCS) to your \Scripts folder (located inside DCS folder in your Saved Games)
* **optionaly** create MySQL database using SQL script located in [03_MySQL](https://github.com/szporwolik/perun/tree/master/03_MySQL); note that you need just a one database per DCS server machine - multiple instances pushing data to the one database are supported
* Create MySQL database using SQL script located in [03_MySQL](https://github.com/szporwolik/perun/tree/master/03_MySQL); note that you need just a one database per DCS server machine - multiple instances pushing data to the one database are supported
## Running
* Start DCS World and host multiplayer session
* by default the JSON is written into Scripts\Json folder located in your Saved Games DCS folder tree
* by default the TCP port 48620 is in use as target port
* **optionaly** run the Win32 application
* by default the TCP port 48620 is in use as target port - ensure that port and instance ID in the options sections of the Lua file matches data
* run the Win32 application
* set MySQL connection data
* **optionaly** point LotATC json file location
* **optionaly** point DCS SRS json file location
@@ -68,8 +67,11 @@ Due to resource limitations, "Perun for DCS World" will focus on pulling the dat
### I keep getting 1305 MySQL error
That probably means that your database does not support JSON functions, you shall upgrade your MySQL server to at lease 5.7 version.
### I keep getting 1364 MySQL error
Make sure that STRICT_TRANS_TABLES is disabled at your MySQL server, see: https://stackoverflow.com/questions/37964325/how-to-find-and-disable-mysql-strict-mode
### Carrier landing are not tracked correctly
DCS API does not track carrier landing natively, so there is a trick to achive that. You shall set your carrier to a propoer group name to have landings tracked.
DCS API does not track carrier or FARP operations natively, so there is a trick to achive that. At this point of time to detect FARP operations, the FARPs shall have "FARP" string in the group name (set in mission editor). For carrier operations the string "SHIP" is required within group name.
# API documentation (for expert users)
## MySQL database structure