countdown.lua 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. if not minetest.global_exists("countdown") then countdown = {} end
  2. countdown.modpath = minetest.get_modpath("hb4")
  3. countdown.quit = false
  4. local color = minetest.get_color_escape_sequence("#ffff00")
  5. local function get_non_admin_players()
  6. local t = minetest.get_connected_players()
  7. local b = {}
  8. for k, v in ipairs(t) do
  9. if not minetest.check_player_privs(v, "server") then
  10. b[#b + 1] = v
  11. end
  12. end
  13. return b
  14. end
  15. function countdown.step(data)
  16. -- Halt when done.
  17. if countdown.quit then
  18. return
  19. end
  20. data = data or {hour = -1, min = -1, sec = -1}
  21. -- Current timestamp, as a number.
  22. local ct = os.time()
  23. -- Timestamp of next shutdown.
  24. local nt = countdown.time
  25. -- If our restart time is in the past, we're done.
  26. if nt <= ct then
  27. local message = "# Server: RESTART IMMINENT - WAITING FOR OS SIGNAL."
  28. chat_logging.log_server_message(message)
  29. minetest.chat_send_all(color .. message)
  30. countdown.quit = true
  31. return
  32. end
  33. -- Calculate remaining time (subtract future time in seconds from current time, also in seconds).
  34. local rt = nt - ct
  35. local rd = os.date("!*t", rt)
  36. local report = false
  37. local delay = 60
  38. -- Debug.
  39. --delay = 10
  40. --report = true
  41. --minetest.chat_send_all("Seconds remaining: " .. rt)
  42. local msgtype = 0
  43. -- Calculate how long until next public message.
  44. do
  45. -- Report on every hour change.
  46. if data.hour ~= rd.hour then
  47. report = true
  48. end
  49. if rd.hour > 0 then
  50. -- Report the nearest rounded hour.
  51. msgtype = 3
  52. end
  53. if rd.hour == 0 and rd.min <= 60 then
  54. msgtype = 2
  55. end
  56. -- Report every minute once there are 10 or less minutes.
  57. if rd.hour == 0 and rd.min <= 10 then
  58. if data.min ~= rd.min then
  59. report = true
  60. msgtype = 2
  61. end
  62. delay = 5
  63. end
  64. -- Report every second of the last 20 seconds.
  65. if rd.hour == 0 and rd.min == 0 and rd.sec <= 20 then
  66. report = true
  67. delay = 1
  68. msgtype = 1
  69. end
  70. -- Record time of last timecheck.
  71. data.hour = rd.hour
  72. data.min = rd.min
  73. data.sec = rd.sec
  74. end
  75. if report then
  76. local message = "# Server: Nightly restart in: " .. string.format("%02d:%02d:%02d", rd.hour, rd.min, rd.sec) .. "."
  77. if msgtype == 1 then
  78. local p = "s"
  79. if rd.sec == 1 then p = "" end
  80. message = "# Server: Restart in " .. rd.sec .. " second" .. p .. "."
  81. elseif msgtype == 2 then
  82. local h = rd.min + math.floor((rd.sec / 60) + 0.5)
  83. local p = "s"
  84. if h == 1 then p = "" end
  85. message = "# Server: Restarting in " .. h .. " minute" .. p .. "."
  86. elseif msgtype == 3 then
  87. local h = rd.hour + math.floor((rd.min / 60) + 0.5)
  88. local p = "s"
  89. if h == 1 then p = "" end
  90. message = "# Server: Nightly restart in " .. h .. " hour" .. p .. "."
  91. end
  92. -- Don't speak to empty room.
  93. if #(get_non_admin_players()) > 0 then
  94. chat_logging.log_server_message(message)
  95. minetest.chat_send_all(color .. message)
  96. end
  97. end
  98. -- Wait for next check.
  99. minetest.after(delay, countdown.step, data)
  100. end
  101. if not countdown.registered then
  102. -- Get current timestamp as a datetime table.
  103. local cd = os.date("*t")
  104. -- Should be 1 hour after midnight, CST. 6 AM UTC.
  105. local nd = table.copy(cd)
  106. nd.day = nd.day + 1
  107. nd.hour = 1
  108. nd.min = 0
  109. nd.sec = 0
  110. -- Store shutdown timestamp as time in seconds in the future.
  111. countdown.time = os.time(nd)
  112. local delay = 60
  113. -- Debug.
  114. --delay = 10
  115. minetest.after(delay, countdown.step, {})
  116. countdown.registered = true
  117. end