yl_ticker/globalsteps.lua
2024-05-29 01:15:44 +02:00

88 lines
3.0 KiB
Lua

local function calculate_bucket(bucket, data) -- This is per bucket
if type(bucket) ~= "number" then bucket = tonumber(bucket) end
local affected_announcements = {}
for _, announcement in ipairs(data) do
if announcement.frequency == bucket then
table.insert(affected_announcements, announcement)
end
end
-- Prevent division by 0
if (#affected_announcements == 0) then
-- We should never reach this code. If there are members of the bucket,
-- then there must be affected announcements.
minetest.log("error",
"[yl_announcements] globalstep division by zero, no members of bucket = " ..
dump(bucket))
return
end
-- Let's calculate the distance
local distance = bucket / #affected_announcements
local n = 0
for _, announcement in ipairs(affected_announcements) do
announcement._next_runtime = os.time() + n * distance
n = n + 1
end
end
local tick = 1
local timer = 0
local gs = function(dtime)
timer = timer + dtime
if timer <= tick then return end
timer = timer - tick
-- payload
local success, data = yl_announcements.list()
if ((success == false) or (data == nil)) then
return false, "Could not retrieve list"
end
local current_time = os.time()
local affected_bucket = {}
-- Check if any announcement should be displayed
for _, announcement in pairs(data) do
-- Check if any announcement needs to be removed from the list due to runtime expired.
if ((type(announcement.runtime) == "number") and
(current_time >= (announcement.creation_date + announcement.runtime))) then
yl_announcements.delete(announcement.id)
elseif current_time >= (announcement._next_runtime or 0) then
if (type(announcement._next_runtime) ~= "number") then
table.insert(affected_bucket, announcement.frequency)
else
local a_success, message =
yl_announcements.say(announcement.id, "*")
if (a_success == false) then
minetest.log("error",
"[yl_announcements] globalstep cannot send to target, message = " ..
dump(message) .. " : announcement = " ..
dump(announcement))
return
end
announcement._next_runtime =
announcement._next_runtime + (announcement.frequency or 3600)
end
yl_announcements.log(os.date("!%H:%M:%S", os.time()) .. "=" ..
tostring(announcement.id))
end
end
-- If there were any announcements that had no _next_runtime, then we need to recalculate their bucket
for _, bucket in ipairs(affected_bucket) do
calculate_bucket(bucket, data)
end
end
minetest.register_globalstep(gs)