From b33e3b7f2e772e39fb0303781d4e6c6c6c68eae3 Mon Sep 17 00:00:00 2001 From: hbeni Date: Thu, 21 Mar 2024 18:21:35 +0100 Subject: [PATCH] Server/Bots: Implemented asking for missing data - checkMissingPluginData(client, askForMissingDataAfter=30) added to fgcom-sharedFunctions - This will check for missing metadata. - If client is supplied, and askForMissingDataAfter is >0, it will emit a ICANHAZDATAPLZ packet to the client in question - It will return a table containing detected missing fields. So calling with client=nil can be used to just check for missing data. - The status and recorder bot will now ask for data if it misses it for too long. --- server/fgcom-radio-recorder.bot.lua | 5 +- server/fgcom-sharedFunctions.inc.lua | 65 +++++++++++++++++++++++++- server/statuspage/fgcom-status.bot.lua | 4 +- 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/server/fgcom-radio-recorder.bot.lua b/server/fgcom-radio-recorder.bot.lua index 4128a83..a5e2424 100644 --- a/server/fgcom-radio-recorder.bot.lua +++ b/server/fgcom-radio-recorder.bot.lua @@ -38,7 +38,7 @@ Installation of this plugin is described in the projects readme: https://github. ]] dofile("fgcom-sharedFunctions.inc.lua") -- include shared functions -fgcom.botversion = "1.8.1" +fgcom.botversion = "1.8.2" local botname = "FGCOM-Recorder" fgcom.callsign = "FGCOM-REC" local voiceBuffer = Queue:new() @@ -286,6 +286,9 @@ client:hook("OnPluginData", function(client, event) -- clean up stale entries fgcom.data.cleanupPluginData() + + -- check for missing data and ask for it if neccesary + local missing_data = fgcom.data.checkMissingPluginData(client); end) diff --git a/server/fgcom-sharedFunctions.inc.lua b/server/fgcom-sharedFunctions.inc.lua index cadf169..b41e967 100644 --- a/server/fgcom-sharedFunctions.inc.lua +++ b/server/fgcom-sharedFunctions.inc.lua @@ -317,7 +317,8 @@ fgcom = { lon="", alt="", radios={}, - lastUpdate=0 + lastUpdate=0, + missingDataSince=0 -- 0: need to check; >0: missing-timestamp; -1: verified ok } if fgcom.hooks.parsePluginData_newClient ~= nil then fgcom.hooks.parsePluginData_newClient(sid, iid) end end @@ -436,6 +437,68 @@ fgcom = { end end end + end, + + -- Check if data is missing for an extended period of time, and ask for more. + -- fgcom.data.askForMissingDataAfter variable defines how long we wait for complete data before asking. + -- You can "just check" without asking if supplying nil as client param. + -- @param mumble.client instance. If nil, no sending for the ask package is performed + -- @param int (optional) timeout in secs, after which to ask for data + -- @return array with missing data: ({ {sid=n, iid=n, missing_data={list, of, missing, data, field, names}}, {...} }) + checkMissingPluginData = function(client, askForMissingDataAfter) + askForMissingDataAfter = askForMissingDataAfter or 30 + local missing_data_return = {} + + local allUsers = {} -- sid=>mumbleUser table + if client then + for i, mc in ipairs(client:getUsers()) do allUsers[mc:getSession()] = mc end + end + + for sid,remote_client in pairs(fgcom_clients) do + for iid,idty in pairs(remote_client) do + fgcom.dbg("checking for missing fgcom.clients data: sid="..sid.."; idty="..iid.."...") + if idty.missingDataSince == -1 then + -- no further checks needed (-1) + fgcom.dbg(" all data already complete") + else + -- see if data is missing + local missing_data = {} + if idty.callsign == "" then table.insert(missing_data, "callsign") end + if idty.lat == "" then table.insert(missing_data, "lat") end + if idty.lon == "" then table.insert(missing_data, "lon") end + if idty.alt == "" then table.insert(missing_data, "alt") end + + if #missing_data == 0 then + -- all needed data there, mark identity as finally checked + fgcom.dbg(" all data is now complete, no further checks needed") + idty.missingDataSince = -1 + else + -- we really still miss data. See if we already need to ask. + if idty.missingDataSince == 0 then + -- first check, store timestamp for later checks + fgcom.dbg(" missing data ("..table.concat(missing_data, ", ").."), marking for further checks") + idty.missingDataSince = os.time() + else + -- consecutive checks, see if timeout exceeded + local missing_since = os.time() - idty.missingDataSince + fgcom.dbg(" missing data ("..table.concat(missing_data, ", ").."), since "..missing_since.."s") + if client and askForMissingDataAfter > 0 and missing_since > askForMissingDataAfter then + fgcom.dbg(" data missing for too long; asking sid="..sid.." for data") + client:sendPluginData("FGCOM:ICANHAZDATAPLZ", "orly!", {allUsers[sid]}) + for iid,idty in pairs(remote_client) do + idty.missingDataSince = 0 -- mark for checking again + end + end + end + + -- add data to return structure + table.insert(missing_data_return, {sid=sid, iid=iid, missing=missing_data}) + end + + end + end + end + return missing_data_return end }, diff --git a/server/statuspage/fgcom-status.bot.lua b/server/statuspage/fgcom-status.bot.lua index 085a49e..0651f2f 100644 --- a/server/statuspage/fgcom-status.bot.lua +++ b/server/statuspage/fgcom-status.bot.lua @@ -243,7 +243,6 @@ updateAllChannelUsersforSend = function(cl) playback_targets = ch:getUsers() end - -- Timed loop to update the database local dbUpdateTimer = mumble.timer() dbUpdateTimer_func = function(t) @@ -281,6 +280,9 @@ dbUpdateTimer_func = function(t) -- clean up stale entries fgcom.data.cleanupTimeout = 60 -- enhance timeout, so we can display them longer fgcom.data.cleanupPluginData() + + -- check for missing data and ask for it if neccesary + local missing_data = fgcom.data.checkMissingPluginData(client); else fgcom.log("ERROR: unable to open db: "..tmpdb)