diff --git a/mods/whoison/functions.lua b/mods/whoison/functions.lua new file mode 100644 index 00000000..e5189136 --- /dev/null +++ b/mods/whoison/functions.lua @@ -0,0 +1,74 @@ +-- Functions +-- + +function whoison.functions.load(param) + --[[ + Values for param : + * `E` : Everyone + * : name + ]]-- + + if param == "E" then + for line in whoison.presence_file:lines() do + local datas = minetest.deserialize(line) + if not datas then + minetest.log("error", "[whoison] Cannot load line (" .. line .. + ") : invalid line") + return false + end + return {[datas.name] = datas.time} + end + return table + elseif minetest.get_player_by_name(param) then + for line in whoison.presence_file:lines() do + local datas = minetest.deserialize(line) + if datas then + if datas.name == name then + return datas.time + end + end + end + minetest.log("error", "[whoison] Cannot load datas for " .. param .. + " : player not registered") + return false + else + minetest.log("error", "[whoison] Cannot load datas for " .. param .. + " : not a player nor 'Everyone'") + return false + end +end + +function whoison.functions.save(param) + --[[ + Values for param : + * E : Everyone + * : name + ]]-- + + if param == "E" then + -- TODO + else + for line in whoison.presence_file:lines() do + local datas = minetest.deserialize(line) + if datas then + if datas.name == name then + -- Erase line + local i = 0 + whoison.presence_file:seek(string.len(line),"cur") + while i < string.len(line) do + whoison.presence_file:write("\b") + i = i + 1 + end + whoison.presence_file:write(minetest.serialize( + {name = param, time = whoison.datas[param]} + ) .. "\n") + return true + end + end + end + whoison.presence_file:write(minetest.serialize( + {name = param, time = whoison.datas[param]} + ) .. "\n") + return true + end +end diff --git a/mods/whoison/init.lua b/mods/whoison/init.lua old mode 100755 new mode 100644 index 31b8ffb4..263ccace --- a/mods/whoison/init.lua +++ b/mods/whoison/init.lua @@ -1,129 +1,71 @@ +-- Rewrite of whoison mod, LeMagnesium +-- + whoison = {} -whoison.lastrun = os.time() -whoison.lastseen = {} +whoison.datas = {} +whoison.config = {} +whoison.config.save_interval = 10 +whoison.functions = {} -local filename = minetest.get_worldpath().."/online-players" -local seenfile = minetest.get_worldpath().."/last-seen" +dofile(minetest.get_modpath("whoison") .. "/functions.lua") -function whoison.createFile(loopit) - local file = io.open(filename, "w") - file:write(os.time().."\n") - file:write(minetest.get_server_status().."\n") - for _,player in ipairs(minetest.get_connected_players()) do - - local name = player:get_player_name() - whoison.updateStats(name) - local ppos = minetest.pos_to_string(player:getpos()) - local datastring = name.."|"..ppos.."\n" - file:write( datastring ) - end - file:close() - minetest.log("action","Updated online player file") - if ( loopit == true ) then - minetest.after(300,whoison.createFile,true) - end - whoison.lastrun = os.time() +-- Boot, Step 0, open presence file +whoison.presence_file = io.open(minetest.get_worldpath() .. "/whoison.wio","r+") +if not whoison.presence_file then + --minetest.log("error", "[whoison] Cannot open presence file! Mod disabled.") + whoison.presence_file = io.open(minetest.get_worldpath() .. "/whoison.wio","w") + return end -function whoison.saveLastSeen() - local f = io.open(seenfile,"w") - f:write(minetest.serialize(whoison.lastseen)) - f:close() +whoison.datas = whoison.functions.load("E") +if not whoison.datas then + whoison.datas = {} end -function whoison.loadLastSeen() - local f = io.open(seenfile,"r") - if ( f ~= nil ) then - local ls = f:read("*all") - f:close() - if ( ls ~= nil and ls ~= "" ) then - whoison.lastseen = minetest.deserialize(ls) - end - end + +-- Boot, Step 1, define callbacks + +function whoison.functions.on_newplayer(player) + whoison.datas[player:get_player_name()] = 0 end -function whoison.getLastOnline(name) - whoison.updateFormat(name) - return whoison.lastseen[name]['lastonline'] +function whoison.functions.on_joinplayer(player) + local time = whoison.functions.load(player:get_player_name()) + if not time then + minetest.log("error", "[whoison] Reading failed. Player " .. + player:get_player_name()) + whoison.datas[player:get_player_name()] = 0 + + return + end + whoison.datas[player:get_player_name()] = time end -function whoison.getTimeOnline(name) - whoison.updateFormat(name) - return whoison.lastseen[name]['timeonline'] +function whoison.functions.on_leaveplayer(player) + local name = player:get_player_name() + local auth = minetest.get_auth_handler().get_auth(name) + if auth and auth.last_login then + local last_login = auth.last_login + local uptime = os.difftime(os.time(),last_login) + whoison.datas[name] = whoison.datas[name] + uptime + local success = whoison.functions.save(name) + if not success then + minetest.log("error", "[whoison] Something went wrong while saving " .. + name .. "'s file") + end + else + minetest.log("error", "[whoison] Couldn't get " .. name .. "'s uptime") + return + end end -function whoison.updateStats(name) - whoison.updateFormat(name) - whoison.lastseen[name]['timeonline'] = whoison.lastseen[name]['timeonline'] + ( os.time() - whoison.lastrun ) - whoison.lastseen[name]['lastonline'] = os.time() +function whoison.functions.on_shutdown() + for index, player in pairs(minetest.get_connected_players()) do + whoison.functions.on_leaveplayer(player) + end end -function whoison.updateFormat(name) - if ( type(whoison.lastseen[name]) ~= "table" ) then - -- update old data to new format - minetest.log("action",name.." lastseen is not a table... fixing...") - local lo = whoison.lastseen[name] - whoison.lastseen[name] = {timeonline=0,lastonline=lo} - end -end - -minetest.register_on_joinplayer(function (player) - whoison.createFile(false) - whoison.saveLastSeen() -end) - -minetest.register_on_leaveplayer(function (player) - whoison.createFile(false) - whoison.saveLastSeen() -end) - -minetest.register_chatcommand("seen",{ - param = "", - description = "Tells the last time a player was online", - func = function (name, param) - if ( param ~= nil ) then - local t = whoison.getLastOnline(param) - if ( t ~= nil ) then - local diff = (os.time() - t) - minetest.chat_send_player(name,param.." was last online "..breakdowntime(diff).." ago") - else - minetest.chat_send_player(name,"Sorry, I have no record of "..param) - end - else - minetest.chat_send_player(name,"Usage is /seen ") - end - end -}) - -minetest.register_chatcommand("timeonline",{ - param = "", - description = "Shows the cumulative time a player has been online", - func = function (name, param) - if ( param ~= nil ) then - local t = whoison.getTimeOnline(param) - if ( t ~= nil ) then - minetest.chat_send_player(name,param.." has been online for "..breakdowntime(t)) - else - minetest.chat_send_player(name,"Sorry, I have no record of "..param) - end - else - minetest.chat_send_player(name,"Usage is /timeonline ") - end - end -}) - -function breakdowntime(t) - local eng = {"Seconds","Minutes","Hours","Days","Weeks","Months","Years"} - local inc = {60,60,24,7,4,12,1} - for k,v in ipairs(inc) do - if ( t > v ) then - t = math.floor( (t / v) ) - else - return tostring(t).." "..eng[k] - end - end -end - -minetest.after(10,whoison.createFile,true) - -whoison.loadLastSeen() +minetest.register_on_joinplayer(whoison.functions.on_joinplayer) +minetest.register_on_newplayer(whoison.functions.on_newplayer) +minetest.register_on_leaveplayer(whoison.functions.on_leaveplayer) +minetest.register_on_shutdown(whoison.functions.on_shutdown) diff --git a/mods/whoison/init.lua.old b/mods/whoison/init.lua.old new file mode 100755 index 00000000..31b8ffb4 --- /dev/null +++ b/mods/whoison/init.lua.old @@ -0,0 +1,129 @@ +whoison = {} +whoison.lastrun = os.time() +whoison.lastseen = {} + +local filename = minetest.get_worldpath().."/online-players" +local seenfile = minetest.get_worldpath().."/last-seen" + +function whoison.createFile(loopit) + local file = io.open(filename, "w") + file:write(os.time().."\n") + file:write(minetest.get_server_status().."\n") + for _,player in ipairs(minetest.get_connected_players()) do + + local name = player:get_player_name() + whoison.updateStats(name) + local ppos = minetest.pos_to_string(player:getpos()) + local datastring = name.."|"..ppos.."\n" + file:write( datastring ) + end + file:close() + minetest.log("action","Updated online player file") + if ( loopit == true ) then + minetest.after(300,whoison.createFile,true) + end + whoison.lastrun = os.time() +end + +function whoison.saveLastSeen() + local f = io.open(seenfile,"w") + f:write(minetest.serialize(whoison.lastseen)) + f:close() +end + +function whoison.loadLastSeen() + local f = io.open(seenfile,"r") + if ( f ~= nil ) then + local ls = f:read("*all") + f:close() + if ( ls ~= nil and ls ~= "" ) then + whoison.lastseen = minetest.deserialize(ls) + end + end +end + +function whoison.getLastOnline(name) + whoison.updateFormat(name) + return whoison.lastseen[name]['lastonline'] +end + +function whoison.getTimeOnline(name) + whoison.updateFormat(name) + return whoison.lastseen[name]['timeonline'] +end + +function whoison.updateStats(name) + whoison.updateFormat(name) + whoison.lastseen[name]['timeonline'] = whoison.lastseen[name]['timeonline'] + ( os.time() - whoison.lastrun ) + whoison.lastseen[name]['lastonline'] = os.time() +end + +function whoison.updateFormat(name) + if ( type(whoison.lastseen[name]) ~= "table" ) then + -- update old data to new format + minetest.log("action",name.." lastseen is not a table... fixing...") + local lo = whoison.lastseen[name] + whoison.lastseen[name] = {timeonline=0,lastonline=lo} + end +end + +minetest.register_on_joinplayer(function (player) + whoison.createFile(false) + whoison.saveLastSeen() +end) + +minetest.register_on_leaveplayer(function (player) + whoison.createFile(false) + whoison.saveLastSeen() +end) + +minetest.register_chatcommand("seen",{ + param = "", + description = "Tells the last time a player was online", + func = function (name, param) + if ( param ~= nil ) then + local t = whoison.getLastOnline(param) + if ( t ~= nil ) then + local diff = (os.time() - t) + minetest.chat_send_player(name,param.." was last online "..breakdowntime(diff).." ago") + else + minetest.chat_send_player(name,"Sorry, I have no record of "..param) + end + else + minetest.chat_send_player(name,"Usage is /seen ") + end + end +}) + +minetest.register_chatcommand("timeonline",{ + param = "", + description = "Shows the cumulative time a player has been online", + func = function (name, param) + if ( param ~= nil ) then + local t = whoison.getTimeOnline(param) + if ( t ~= nil ) then + minetest.chat_send_player(name,param.." has been online for "..breakdowntime(t)) + else + minetest.chat_send_player(name,"Sorry, I have no record of "..param) + end + else + minetest.chat_send_player(name,"Usage is /timeonline ") + end + end +}) + +function breakdowntime(t) + local eng = {"Seconds","Minutes","Hours","Days","Weeks","Months","Years"} + local inc = {60,60,24,7,4,12,1} + for k,v in ipairs(inc) do + if ( t > v ) then + t = math.floor( (t / v) ) + else + return tostring(t).." "..eng[k] + end + end +end + +minetest.after(10,whoison.createFile,true) + +whoison.loadLastSeen()