Version 2.3.3

Small fixes
This commit is contained in:
Christian Franz 2024-09-26 07:53:42 +02:00
parent bfb24bf074
commit a2e8ead577
6 changed files with 36 additions and 55 deletions

Binary file not shown.

Binary file not shown.

View File

@ -544,7 +544,7 @@ function airtank.readConfigZone()
end end
end end
-- add own troop carriers -- add own troop carriers -- superceded by airTankSpecs
if theZone:hasProperty("airtanks") then if theZone:hasProperty("airtanks") then
local tc = theZone:getStringFromZoneProperty("airtanks", "UH-1D") local tc = theZone:getStringFromZoneProperty("airtanks", "UH-1D")
tc = dcsCommon.splitString(tc, ",") tc = dcsCommon.splitString(tc, ",")

View File

@ -1,5 +1,5 @@
persistence = {} persistence = {}
persistence.version = "3.0.0" persistence.version = "3.0.1"
persistence.ups = 1 -- once every 1 seconds persistence.ups = 1 -- once every 1 seconds
persistence.verbose = false persistence.verbose = false
persistence.active = false persistence.active = false
@ -18,6 +18,10 @@ persistence.requiredLibs = {
2.0.0 - dml zones, OOP 2.0.0 - dml zones, OOP
cleanup cleanup
3.0.0 - shared data 3.0.0 - shared data
3.0.1 - shared data validations/fallback
API cleanup
shared text data "flase" typo corrected (no impact)
code cleanup
PROVIDES LOAD/SAVE ABILITY TO MODULES PROVIDES LOAD/SAVE ABILITY TO MODULES
PROVIDES STANDALONE/HOSTED SERVER COMPATIBILITY PROVIDES STANDALONE/HOSTED SERVER COMPATIBILITY
@ -99,15 +103,6 @@ function persistence.getSavedDataForModule(name, sharedDataName)
return persistence.missionData[name] -- simply get the modules data block return persistence.missionData[name] -- simply get the modules data block
end end
--
-- Shared Data API
--
function persistence.getSharedDataFor(name, item) -- not yet finalized
end
function persistence.putSharedDataFor(data, name, item) -- not yet finalized
end
-- --
-- helper meths -- helper meths
-- --
@ -144,33 +139,28 @@ function persistence.saveText(theString, fileName, shared, append)
trigger.action.outText("+++persistence: saveText without fileName", 30) trigger.action.outText("+++persistence: saveText without fileName", 30)
return false return false
end end
if not shared then shared = flase end if not shared then shared = false end
if not theString then theString = "" end if not theString then theString = "" end
local path = persistence.missionDir .. fileName local path = persistence.missionDir .. fileName
if shared then if shared then
-- we would now change the path -- we would now change the path
trigger.action.outText("+++persistence: NYI: shared", 30) trigger.action.outText("+++persistence: NYI: shared", 30)
return return false
end end
local theFile = nil local theFile = nil
if append then if append then
theFile = io.open(path, "a") theFile = io.open(path, "a")
else else
theFile = io.open(path, "w") theFile = io.open(path, "w")
end end
if not theFile then if not theFile then
trigger.action.outText("+++persistence: saveText - unable to open " .. path, 30) trigger.action.outText("+++persistence: saveText - unable to open " .. path, 30)
return false return false
end end
theFile:write(theString) theFile:write(theString)
theFile:close() theFile:close()
return true return true
end end
@ -181,9 +171,7 @@ function persistence.saveTable(theTable, fileName, shared, append)
if not shared then shared = false end if not shared then shared = false end
local theString = net.lua2json(theTable) local theString = net.lua2json(theTable)
if not theString then theString = "" end if not theString then theString = "" end
local path = persistence.missionDir .. fileName local path = persistence.missionDir .. fileName
if shared then if shared then
-- we change the path to shared -- we change the path to shared
@ -191,46 +179,35 @@ function persistence.saveTable(theTable, fileName, shared, append)
end end
local theFile = nil local theFile = nil
if append then if append then
theFile = io.open(path, "a") theFile = io.open(path, "a")
else else
theFile = io.open(path, "w") theFile = io.open(path, "w")
end end
if not theFile then if not theFile then
return false return false
end end
theFile:write(theString) theFile:write(theString)
theFile:close() theFile:close()
return true return true
end end
function persistence.loadText(fileName, hasPath) -- load file as text function persistence.loadText(fileName, hasPath) -- load file as text
if not persistence.active then return nil end if not persistence.active then return nil end
if not fileName then return nil end if not fileName then return nil end
local path local path
if hasPath then if hasPath then
path = fileName path = fileName
else else
path = persistence.missionDir .. fileName path = persistence.missionDir .. fileName
end end
if persistence.verbose then if persistence.verbose then
trigger.action.outText("persistence: will load text file <" .. path .. ">", 30) trigger.action.outText("persistence: will load text file <" .. path .. ">", 30)
end end
local theFile = io.open(path, "r") local theFile = io.open(path, "r")
if not theFile then return nil end if not theFile then return nil end
local t = theFile:read("*a") local t = theFile:read("*a")
theFile:close() theFile:close()
return t return t
end end
@ -238,13 +215,9 @@ function persistence.loadTable(fileName, hasPath) -- load file as table
if not persistence.active then return nil end if not persistence.active then return nil end
if not fileName then return nil end if not fileName then return nil end
if not hasPath then hasPath = false end if not hasPath then hasPath = false end
local t = persistence.loadText(fileName, hasPath) local t = persistence.loadText(fileName, hasPath)
if not t then return nil end if not t then return nil end
local tab = net.json2lua(t) local tab = net.json2lua(t)
return tab return tab
end end
@ -380,7 +353,7 @@ function persistence.saveMissionData()
if not specificShared then specificShared = {} end if not specificShared then specificShared = {} end
specificShared[moduleName] = moduleData specificShared[moduleName] = moduleData
allSharedData[sharedName] = specificShared -- write back allSharedData[sharedName] = specificShared -- write back
end end -- !NO ELSE! WE ALSO STORE IN MAIN DATA FOR REDUNDANCY
myData[moduleName] = moduleData myData[moduleName] = moduleData
if persistence.verbose then if persistence.verbose then
trigger.action.outText("+++persistence: gathered data from <" .. moduleName .. ">", 30) trigger.action.outText("+++persistence: gathered data from <" .. moduleName .. ">", 30)

View File

@ -1,5 +1,5 @@
cfxPlayerScoreUI = {} cfxPlayerScoreUI = {}
cfxPlayerScoreUI.version = "3.0.0" cfxPlayerScoreUI.version = "3.0.1"
cfxPlayerScoreUI.verbose = false cfxPlayerScoreUI.verbose = false
--[[-- VERSION HISTORY --[[-- VERSION HISTORY
@ -12,6 +12,7 @@ cfxPlayerScoreUI.verbose = false
- allowAll - allowAll
- 2.1.1 - minor cleanup - 2.1.1 - minor cleanup
- 3.0.0 - compatible with dynamic groups/units in DCS 2.9.6 - 3.0.0 - compatible with dynamic groups/units in DCS 2.9.6
- 3.0.1 - more hardening
--]]-- --]]--
cfxPlayerScoreUI.requiredLibs = { cfxPlayerScoreUI.requiredLibs = {
@ -34,6 +35,7 @@ function cfxPlayerScoreUI.doCommandX(args)
local playerName = args[2] local playerName = args[2]
local what = args[3] -- "score" or other commands local what = args[3] -- "score" or other commands
local theGroup = Group.getByName(groupName) local theGroup = Group.getByName(groupName)
if not theGroup then return end -- should not happen
local gid = theGroup:getID() local gid = theGroup:getID()
local coa = theGroup:getCoalition() local coa = theGroup:getCoalition()

View File

@ -1,5 +1,5 @@
scribe = {} scribe = {}
scribe.version = "2.0.2" scribe.version = "2.0.3"
scribe.requiredLibs = { scribe.requiredLibs = {
"dcsCommon", -- always "dcsCommon", -- always
"cfxZones", -- Zones, of course "cfxZones", -- Zones, of course
@ -16,6 +16,9 @@ VERSION HISTORY
2.0.1 Hardening for DCS Jul 11 patch issues 2.0.1 Hardening for DCS Jul 11 patch issues
2.0.2 Secondary landing events correction 2.0.2 Secondary landing events correction
support for DCS dynamic player spawns support for DCS dynamic player spawns
2.0.3 switch to polled tickTime counting instead of
uDelta, limiting max error to tickTime seconds
code cleanup
--]]-- --]]--
scribe.verbose = true scribe.verbose = true
@ -28,9 +31,11 @@ scribe.dynamicPlayers = {}
ttime -- total time in seconds ttime -- total time in seconds
airTime -- total air time airTime -- total air time
landings -- number of landings landings -- number of landings
lastLanding -- time of last landing OR DEPARTURE. lastLanding -- time of last landing !!OR!! DEPARTURE.
departures -- toital take-offs departures -- toital take-offs
crashes -- number of total crashes, deaths etc crashes -- number of total crashes, deaths etc
lastTime -- timestamp of last recording. NO LONGER USED
--]]-- --]]--
function scribe.createUnitEntry() function scribe.createUnitEntry()
@ -91,8 +96,15 @@ function scribe.tickEntry(theEntry)
local now = timer.getTime() local now = timer.getTime()
local uEntry = theEntry.units[theEntry.lastUnitType] local uEntry = theEntry.units[theEntry.lastUnitType]
if not uEntry then return 0 end -- can happen on idling server that has reloaded. all last players have invalid last units if not uEntry then return 0 end -- can happen on idling server that has reloaded. all last players have invalid last units
local delta = now - uEntry.lastTime local delta = now - uEntry.lastTime -- lastTime should be < now
if delta < 0 then delta = 0 end if delta < 0 then -- lastTime was later than now! reload?
delta = 0
elseif delta > scribe.tickTime then -- limit error to tick time interval
if scribe.verbose then
trigger.action.outText("Shortened tickEntry time from <" .. delta .. "> s to <" .. scribe.tickTime .. "> s", 30)
end
delta = scribe.tickTime
end -- NEW: max tickTime to limit error
uEntry.lastTime = now uEntry.lastTime = now
uEntry.ttime = uEntry.ttime + delta uEntry.ttime = uEntry.ttime + delta
return delta return delta
@ -107,8 +119,7 @@ function scribe.finalizeEntry(theEntry)
local uEntry = theEntry.units[theEntry.lastUnitType] local uEntry = theEntry.units[theEntry.lastUnitType]
if uEntry then if uEntry then
uEntry.lastTime = 99999999 -- NOT math.huge uEntry.lastTime = 99999999 -- NOT math.huge
--local deltaTime = dcsCommon.processHMS("<:h>:<:m>:<:s>", delta)
local deltaTime = dcsCommon.processHMS("<:h>:<:m>:<:s>", delta)
local fullTime = dcsCommon.processHMS("<:h>:<:m>:<:s>", uEntry.ttime) local fullTime = dcsCommon.processHMS("<:h>:<:m>:<:s>", uEntry.ttime)
if scribe.byePlayer then if scribe.byePlayer then
trigger.action.outText("Player " .. theEntry.playerName .. " left " .. theEntry.lastUnitName .. " (a " .. theEntry.lastUnitType .. "), total time in aircraft " .. fullTime ..".", 30) trigger.action.outText("Player " .. theEntry.playerName .. " left " .. theEntry.lastUnitName .. " (a " .. theEntry.lastUnitType .. "), total time in aircraft " .. fullTime ..".", 30)
@ -298,7 +309,6 @@ function scribe.playerLanded(playerName)
delta = now - uEntry.lastLanding delta = now - uEntry.lastLanding
if delta > scribe.landingCD then -- or delta < 0 then if delta > scribe.landingCD then -- or delta < 0 then
uEntry.landings = uEntry.landings + 1 uEntry.landings = uEntry.landings + 1
-- trigger.action.outText("+++scrb: added landing for " .. playerName .. ", delta is <" .. delta .. ">.", 30)
else else
if scribe.verbose then if scribe.verbose then
trigger.action.outText("+++scb: landing ignored: cooldown active", 30) trigger.action.outText("+++scb: landing ignored: cooldown active", 30)
@ -328,7 +338,6 @@ function scribe.playerDeparted(playerName)
end end
end end
uEntry.lastLanding = now -- also for Departures! uEntry.lastLanding = now -- also for Departures!
end end
-- --
@ -378,12 +387,10 @@ function scribe:onEvent(theEvent)
return return
end end
-- when we get here we have a player event -- when we get here we have a player event
-- trigger.action.outText("+++scrb: player event <" .. theEvent.id .. ">", 30)
-- players can only ever activate by birth event -- players can only ever activate by birth event
if theEvent.id == 15 if theEvent.id == 15
or theEvent == 20 or theEvent == 20
then -- birth / enter unit then -- birth / enter unit
-- trigger.action.outText("+++scrb: player <" .. playerName .. "> entered unit.", 30)
scribe.playerBirthedIn(playerName, theUnit) -- reset timer for landings / take-off scribe.playerBirthedIn(playerName, theUnit) -- reset timer for landings / take-off
scribe.playerUnits[uName] = playerName -- for crash helo detection scribe.playerUnits[uName] = playerName -- for crash helo detection
end end
@ -410,7 +417,6 @@ function scribe:onEvent(theEvent)
if theEvent.id == 3 or -- take-off if theEvent.id == 3 or -- take-off
theEvent.id == 54 then -- postponed take-off, corrected to 54 theEvent.id == 54 then -- postponed take-off, corrected to 54
scribe.playerDeparted(playerName) scribe.playerDeparted(playerName)
-- trigger.action.outText("departure detected", 30)
end end
if theEvent.id == 18 then -- engine start if theEvent.id == 18 then -- engine start
@ -479,7 +485,7 @@ end
-- GC -- detect player leaving -- GC -- detect player leaving
-- --
function scribe.GC() function scribe.GC()
timer.scheduleFunction(scribe.GC, {}, timer.getTime() + 1) timer.scheduleFunction(scribe.GC, {}, timer.getTime() + scribe.tickTime)
-- iterate through all players in DB and see if they -- iterate through all players in DB and see if they
-- are still on-line. -- are still on-line.
for pName, theEntry in pairs(scribe.db) do for pName, theEntry in pairs(scribe.db) do
@ -487,7 +493,8 @@ function scribe.GC()
-- this player is on the books as in the game -- this player is on the books as in the game
local theUnit = Unit.getByName(theEntry.lastUnitName) local theUnit = Unit.getByName(theEntry.lastUnitName)
if theUnit and Unit.isExist(theUnit) and theUnit:getLife() >= 1 then if theUnit and Unit.isExist(theUnit) and theUnit:getLife() >= 1 then
-- all is fine, go on -- all is fine, add a tick
scribe.tickEntry(theEntry)
else else
-- this unit no longer exists and we finalize player -- this unit no longer exists and we finalize player
if scribe.verbose then if scribe.verbose then
@ -523,14 +530,12 @@ function scribe.installDynamicPlayerMenu(theUnit)
unitInfo.gID = theGroup:getID() unitInfo.gID = theGroup:getID()
unitInfo.uID = theUnit:getID() unitInfo.uID = theUnit:getID()
unitInfo.theType = theType unitInfo.theType = theType
-- unitInfo.cat = cfxMX.groupTypeByName[gName]
unitInfo.root = missionCommands.addSubMenuForGroup(unitInfo.gID, scribe.uiMenu, mainMenu) unitInfo.root = missionCommands.addSubMenuForGroup(unitInfo.gID, scribe.uiMenu, mainMenu)
unitInfo.checkData = missionCommands.addCommandForGroup(unitInfo.gID, "Get Pilot's Statistics", unitInfo.root, scribe.redirectCheckData, unitInfo) unitInfo.checkData = missionCommands.addCommandForGroup(unitInfo.gID, "Get Pilot's Statistics", unitInfo.root, scribe.redirectCheckData, unitInfo)
end end
function scribe.startPlayerGUI() function scribe.startPlayerGUI()
-- scan all mx players -- scan all mx players
-- note: currently assumes single-player groups
-- in preparation of single-player 'commandForUnit' -- in preparation of single-player 'commandForUnit'
-- ASSUMES SINGLE-UNIT PLAYER GROUPS! -- ASSUMES SINGLE-UNIT PLAYER GROUPS!
local mainMenu = nil local mainMenu = nil
@ -592,6 +597,7 @@ function scribe.readConfigZone()
end end
end end
scribe.tickTime = theZone:getNumberFromZoneProperty("tickTime", 5) -- every 5 seconds, 5 second error max
scribe.greetPlayer = theZone:getBoolFromZoneProperty("greetPlayer", true) scribe.greetPlayer = theZone:getBoolFromZoneProperty("greetPlayer", true)
scribe.byePlayer = theZone:getBoolFromZoneProperty("byebyePlayer", true) scribe.byePlayer = theZone:getBoolFromZoneProperty("byebyePlayer", true)
@ -697,7 +703,7 @@ function scribe.start()
end end
-- start GC -- start GC
timer.scheduleFunction(scribe.GC, {}, timer.getTime() + 1) timer.scheduleFunction(scribe.GC, {}, timer.getTime() + 1) -- in one second (fixed)
-- say hi! -- say hi!
trigger.action.outText("cfx scribe v" .. scribe.version .. " started.", 30) trigger.action.outText("cfx scribe v" .. scribe.version .. " started.", 30)