init.lua 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. if not minetest.global_exists("status") then status = {} end
  2. status.modpath = minetest.get_modpath("status")
  3. status.motd = minetest.settings:get("motd") or ""
  4. local WEBADDR = minetest.settings:get("server_address")
  5. -- Get text color.
  6. local STATUS_COLOR = core.get_color_escape_sequence("#0d9b7b")
  7. status.color = STATUS_COLOR
  8. function status.chat_players(user, param)
  9. do
  10. -- Serialize player names to string.
  11. local players = minetest.get_connected_players()
  12. local clients = "{"
  13. local num_clients = 0
  14. for k, v in ipairs(players) do
  15. local hide = minetest.check_player_privs(v:get_player_name(), {statushide=true})
  16. if hide == false then
  17. clients = clients .. rename.gpn(v:get_player_name()) .. ", "
  18. num_clients = num_clients + 1
  19. end
  20. end
  21. clients = clients .. "}"
  22. clients = string.gsub(clients, ", }", "}")
  23. -- Build status string.
  24. local final =
  25. STATUS_COLOR .. "# Server: Players Online (" .. num_clients .. "): " .. clients .. "."
  26. minetest.chat_send_player(user, final)
  27. end
  28. do
  29. -- Serialize player names to string.
  30. local channel = shout.player_channel(user)
  31. if channel and channel ~= "" then
  32. local players = shout.channel_players(channel)
  33. local clients = "{"
  34. local num_clients = 0
  35. for k, v in ipairs(players) do
  36. local hide = minetest.check_player_privs(v, {statushide=true})
  37. if hide == false then
  38. clients = clients .. rename.gpn(v) .. ", "
  39. num_clients = num_clients + 1
  40. end
  41. end
  42. clients = clients .. "}"
  43. clients = string.gsub(clients, ", }", "}")
  44. -- Build status string.
  45. local final =
  46. STATUS_COLOR .. "# Server: Players In Channel '" .. channel .. "' (" .. num_clients .. "): " .. clients .. "."
  47. minetest.chat_send_player(user, final)
  48. end
  49. end
  50. return true
  51. end
  52. function status.chat_status(user, param)
  53. local p1, p2
  54. -- Get uptime.
  55. local status_str = status.original_status()
  56. p1, p2 = string.find(status_str, "uptime:[^|]+")
  57. local uptime = "uptime: unknown"
  58. if p1 and p2 then
  59. uptime = string.sub(status_str, p1, p2)
  60. uptime = string.gsub(uptime, "uptime: ", "Uptime: ")
  61. uptime = string.trim(uptime)
  62. end
  63. p1, p2 = string.find(status_str, "max lag:[^|]+")
  64. local max_lag = "max lag: unknown"
  65. if p1 and p2 then
  66. max_lag = string.sub(status_str, p1, p2)
  67. max_lag = string.gsub(max_lag, "max lag: ", "Max Lag: ")
  68. max_lag = string.trim(max_lag)
  69. end
  70. -- Get MoTD.
  71. local motd2 = status.motd
  72. if not motd2 or motd2 == "" then
  73. motd2 = "Daily message has not been set!"
  74. end
  75. -- Get version string.
  76. local version = "version: unknown"
  77. p1, p2 = string.find(status_str, "version:[^|]+")
  78. if p1 and p2 then
  79. version = string.sub(status_str, p1, p2)
  80. version = string.trim(version)
  81. end
  82. version = string.gsub(version, "version: ", "Version: ")
  83. version = string.gsub(version, "-dev", "-DEV")
  84. -- Build status string.
  85. local final =
  86. STATUS_COLOR .. "# Server: " .. version .. ", " .. uptime .. ", " .. max_lag .. ".\n" ..
  87. STATUS_COLOR .. "# Server: " .. motd2 .. "\n" ..
  88. STATUS_COLOR .. "# Server: More info can be found at http://" .. WEBADDR .. "/."
  89. minetest.chat_send_player(user, final)
  90. return true
  91. end
  92. function status.chat_short_status(user, param, last_login)
  93. -- Serialize player names to string.
  94. local players = minetest.get_connected_players()
  95. local clients = "{"
  96. local num_clients = 0
  97. for k, v in ipairs(players) do
  98. local pname = v:get_player_name()
  99. local hide = minetest.check_player_privs(pname, {statushide=true})
  100. if pname == user then
  101. hide = true
  102. end
  103. if hide == false then
  104. clients = clients .. rename.gpn(pname) .. ", "
  105. num_clients = num_clients + 1
  106. end
  107. end
  108. clients = clients .. "}"
  109. clients = string.gsub(clients, ", }", "}")
  110. local sare = "are"
  111. local splayers = "players"
  112. if num_clients == 1 then
  113. sare = "is"
  114. splayers = "player"
  115. end
  116. local tail = ": " .. clients .. "."
  117. if num_clients == 0 then
  118. tail = "."
  119. end
  120. local final = STATUS_COLOR .. "# Server: " ..
  121. "Welcome back, <" .. rename.gpn(user) .. ">! There " .. sare ..
  122. " currently " ..
  123. num_clients .. " " .. splayers .. " online" .. tail
  124. minetest.chat_send_player(user, final)
  125. if last_login then
  126. local days = math.floor((os.time() - last_login) / (60 * 60 * 24))
  127. local hours = math.floor((os.time() - last_login) / (60 * 60))
  128. local logintime = "Your last login was on " .. os.date("!%Y/%m/%d, %H:%M UTC", last_login) .. " "
  129. local loginhours = ""
  130. if hours == 1 then
  131. loginhours = ", 1 hour ago"
  132. else
  133. loginhours = ", " .. hours .. " hours ago"
  134. end
  135. if days <= 0 then
  136. logintime = logintime .. "(Today" .. loginhours .. ")"
  137. elseif days == 1 then
  138. logintime = logintime .. "(Yesterday" .. loginhours .. ")"
  139. else
  140. logintime = logintime .. "(" .. days .. " days" .. loginhours .. ")"
  141. end
  142. minetest.chat_send_player(user, STATUS_COLOR .. "# Server: " .. logintime)
  143. end
  144. end
  145. function status.chat_admin(name, param)
  146. minetest.chat_send_player(name,
  147. STATUS_COLOR .. "# Server: The administrator of this server is <" .. utility.get_admin_name() .. ">. " ..
  148. "You may send me messages using the email interface found through the Key of Citizenship.")
  149. return true
  150. end
  151. function status.on_joinplayer(player, last_login)
  152. local pname = player:get_player_name()
  153. -- Don't show /status info to registered players rejoining the server.
  154. -- It's just noise, if they want it they can type /status manually.
  155. if not passport.player_registered(pname) then
  156. status.chat_status(pname, "")
  157. else
  158. status.chat_short_status(pname, "", last_login)
  159. end
  160. end
  161. if not status.registered then
  162. -- Save original function.
  163. status.original_status = minetest.get_server_status
  164. -- Override builtin status function to prevent showing this message on player join!
  165. function minetest.get_server_status(pname, joined)
  166. return nil
  167. end
  168. -- Override the /status chat command.
  169. minetest.override_chatcommand("status", {
  170. params = "",
  171. description = "Show the server's current status.",
  172. privs = {},
  173. func = function(...) return status.chat_status(...) end,
  174. })
  175. minetest.register_chatcommand("players", {
  176. params = "",
  177. description = "Show list of players currently online.",
  178. privs = {},
  179. func = function(...) return status.chat_players(...) end,
  180. })
  181. minetest.override_chatcommand("admin", {
  182. params = "",
  183. description = "Show the name of the server owner and primary operator.",
  184. privs = {},
  185. func = function(...) return status.chat_admin(...) end,
  186. })
  187. local timefunc = minetest.registered_chatcommands["time"].func
  188. assert(type(timefunc) == "function")
  189. minetest.override_chatcommand("time", {
  190. description = "Set or get the current time of day.",
  191. func = function(name, param)
  192. local result, message = timefunc(name, param)
  193. message = STATUS_COLOR .. "# Server: " .. message
  194. minetest.chat_send_player(name, message)
  195. return true
  196. end,
  197. })
  198. local daysfunc = minetest.registered_chatcommands["days"].func
  199. assert(type(daysfunc) == "function")
  200. minetest.override_chatcommand("days", {
  201. description = "Display day count.",
  202. func = function(name, param)
  203. local result, message = daysfunc(name, param)
  204. message = STATUS_COLOR ..
  205. "# Server: " .. message .. " " ..
  206. string.gsub(hud_clock.get_date_string(), "\n+", ", ")
  207. minetest.chat_send_player(name, message)
  208. return true
  209. end,
  210. })
  211. minetest.register_privilege("statushide", {
  212. description = "Player's name will not be shown in the server's status string.",
  213. give_to_singleplayer = false,
  214. })
  215. -- Send status string to players on join.
  216. -- The engine status string is disabled in server config.
  217. minetest.register_on_joinplayer(function(...) return status.on_joinplayer(...) end)
  218. reload.register_file("status:core", status.modpath .. "/init.lua", false)
  219. status.registered = true
  220. end