--[[ This file is part of Ice Lua Components. Ice Lua Components is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Ice Lua Components is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with Ice Lua Components. If not, see . ]] HB_VERSION = 2 heartbeat_sockfd = nil heartbeat_t_nextmsg = nil heartbeat_t_nextburst = nil heartbeat_burstsleft = nil heartbeat_cooloff = true local function pad_nul(n, s) while s:len() < n do s = s .. "\0" end if s:len() > n then s = s:sub(1, n) end return s end function heartbeat_init() -- check if we have this actually enabled if not server_config.heartbeat_send then return end -- open the socket heartbeat_sockfd = common.udp_open() end function heartbeat_update(sec_current, sec_delta) -- we need to let the timer "cool off" as the first few values are just plain wrong. if heartbeat_cooloff then if sec_current < 60 and sec_current >= 2 then heartbeat_cooloff = nil end return end -- if we're using the wrong heartbeat and/or iceball version, -- heartbeat_sockfd will be nil, -- because we have given up. -- (it'll also be nil if we haven't enabled the heartbeat client.) if not heartbeat_sockfd then return end -- versions before 0.1.1-4 don't have server.port, -- so we need to rip the port from server.hook_connect. if not server.port then return end -- check if we received any messages while true do local msg, host, port = common.udp_recvfrom(heartbeat_sockfd) if msg == "" then break elseif msg == false then print("*** UDP socket used to connect to master servers broke horribly. What the hell?!") irc.write("*** UDP socket used to connect to master servers broke horribly. What the hell?!") heartbeat_t_burstsleft = nil heartbeat_t_nextmsg = nil elseif msg:len() >= 4 and msg:sub(1,4) == "MSOK" then -- send handshake common.udp_sendto(heartbeat_sockfd, "HSHK" .. msg:sub(5), host, port) elseif msg == "BADF" then print("*** heartbeat server \""..host.."\" port "..port.." reports bad packet format - FIX ME OR REMOVE THIS SERVER") irc.write("*** heartbeat server \""..host.."\" port "..port.." reports bad packet format - FIX ME OR REMOVE THIS SERVER") heartbeat_t_burstsleft = nil heartbeat_t_nextmsg = nil heartbeat_t_nextburst = heartbeat_t_nextburst + 60*30 elseif msg:len() >= 4 and msg:sub(1,4) == "BADV" then print("*** heartbeat server \""..host.."\" port "..port.." reports bad version - UPGRADE OR REMOVE THIS SERVER") irc.write("*** heartbeat server \""..host.."\" port "..port.." reports bad version - UPGRADE OR REMOVE THIS SERVER") heartbeat_t_burstsleft = nil heartbeat_t_nextmsg = nil heartbeat_t_nextburst = heartbeat_t_nextburst + 60*30 end end -- check if we need to send a new burst heartbeat_t_nextburst = heartbeat_t_nextburst or sec_current if sec_current >= heartbeat_t_nextburst then heartbeat_t_burstsleft = 5 heartbeat_t_nextmsg = heartbeat_t_nextburst heartbeat_t_nextburst = heartbeat_t_nextburst + 40 end -- check if we need to send a new message if heartbeat_t_burstsleft and heartbeat_t_nextmsg and sec_current >= heartbeat_t_nextmsg then -- get player count local players_max = players.max local players_current = 0 local i for i=1,players_max do if players[i] then players_current = players_current + 1 end end -- assemble message local msg = "1CEB" .. common.net_pack("HI", HB_VERSION, common.version.num) msg = msg .. common.net_pack("HHH", server.port, players_current, players_max) msg = msg .. pad_nul(30, server_config.name) msg = msg .. pad_nul(10, game_hb_mode) msg = msg .. pad_nul(30, map_name) --print("HEARTBEAT MESSAGE") -- send message local i local hbl = server_config.heartbeat for i=1,#hbl do local host, port = hbl[i][1], hbl[i][2] common.udp_sendto(heartbeat_sockfd, msg, host, port) end -- give time for next message if necessary heartbeat_t_burstsleft = heartbeat_t_burstsleft - 1 if heartbeat_t_burstsleft <= 0 then heartbeat_t_burstsleft = nil heartbeat_t_nextmsg = nil else heartbeat_t_nextmsg = heartbeat_t_nextmsg + 1 end end end