From c48da1d737a2bb4d65d53f0b193b48989779293e Mon Sep 17 00:00:00 2001 From: Aaron Suen Date: Thu, 19 Mar 2020 06:51:03 -0400 Subject: [PATCH] Mod to list cumulative online players periodically. --- szutil_nowonline/README | 16 ++++++++++ szutil_nowonline/init.lua | 67 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 szutil_nowonline/README create mode 100644 szutil_nowonline/init.lua diff --git a/szutil_nowonline/README b/szutil_nowonline/README new file mode 100644 index 0000000..6f0ff11 --- /dev/null +++ b/szutil_nowonline/README @@ -0,0 +1,16 @@ +------------------------------------------------------------------------ + +When players log in or log out, reannounce the cumulative list of online +players. This is particularly useful for szutil_chatsocket connections +to external chat bridges, where no command is provided for getting the +list of online players. + +Player lists are only sent if either a certain amount of time has +passed, or a certain number of public chat lines, since the last +announcement (configurable) to prevent a ton of noise on busy servers. + +The maximum number of names listed is configurable; beyond that limit, +a random sample of players will be shown, and "(# more)" displayed at +the end of the list. + +------------------------------------------------------------------------ diff --git a/szutil_nowonline/init.lua b/szutil_nowonline/init.lua new file mode 100644 index 0000000..f831c17 --- /dev/null +++ b/szutil_nowonline/init.lua @@ -0,0 +1,67 @@ +-- LUALOCALS < --------------------------------------------------------- +local math, minetest, pairs, table, tonumber, tostring + = math, minetest, pairs, table, tonumber, tostring +local math_random, table_concat, table_remove, table_sort + = math.random, table.concat, table.remove, table.sort +-- LUALOCALS > --------------------------------------------------------- + +local modname = minetest.get_current_modname() + +local timedelay = tonumber(minetest.settings:get(modname .. "_time")) or 300 +local linedelay = tonumber(minetest.settings:get(modname .. "_lines")) or 25 +local maxnames = tonumber(minetest.settings:get(modname .. "_names")) or 50 + +local lines = 0 +local exp = 0 + +local function delaymsg(msg) + return minetest.after(0, function() + return minetest.chat_send_all(msg) + end) +end + +local function sendall(isann) + lines = lines + 1 + if not isann then return end + + local now = minetest.get_us_time() / 1000000 + if (lines < linedelay) or (now < exp) then return end + + exp = now + timedelay + lines = 0 + local names = {} + for _, player in pairs(minetest.get_connected_players()) do + names[#names + 1] = player:get_player_name() + end + table_sort(names) + + local more = 0 + while #names > maxnames do + table_remove(names, math_random(1, #names)) + more = more + 1 + end + if more > 0 then + names[#names + 1] = "(" .. more .. " more)" + end + + if #names > 0 then + delaymsg("*** Online: " .. table_concat(names, ", ")) + else + delaymsg("*** Server is empty.") + end +end + +do + local old_sendall = minetest.chat_send_all + function minetest.chat_send_all(text, ...) + sendall(tostring(text):match("^%s*%*%*%*%s")) + return old_sendall(text, ...) + end +end + +minetest.register_on_chat_message(function(pname, text) + if text:sub(1, 1) ~= "/" + and minetest.check_player_privs(pname, "shout") then + sendall() + end + end)