--[[
Ideally all the level data should be read/written from storage, rather than node metadata. Maybe store in metadata until the final submission.
This would allow for a node to be connected to an already existing ID, which could be useful if a spawn changed for any reason.
This can be changed in the future I expect, as the data all exists in both locations currently.
]]

local esc = minetest.formspec_escape

local function random_pos()
   local pos_x = math.random(-30000,30000)
   local pos_y = math.random(-100,30000)
   local pos_z = math.random(-30000,30000)
   local pos = (pos_x..','..pos_y..','..pos_z)
   return pos
end

local function button_create(pos, player)
   local meta = minetest.get_meta(pos)
   local owner = meta:get_string('owner')
   local id = meta:get_string('id')
   local name = meta:get_string('name')
   local player_count = meta:get_int('player_count') or 3
   local xp = meta:get_int('xp') or 50
   local pos_string = minetest.string_to_pos(meta:get_string('pos'))
   local desc = meta:get_string('desc')
   local builders = meta:get_string('builders') or ''
   local solo = meta:get_string('solo') or 'true'
   local clean_pos = pos_string.x..','..pos_string.y..','..pos_string.z
   local formspec =
      'formspec_version[3]'..
      'size[12,8]'..
      'background[-1,-1;14,10;lobby_button_bg.png]'..
      'field[4.375,.5;3.25,.5;name;Map Name;'..esc(name)..']'..
      'tooltip[name;Will be used in chat messages and as the infotext]'..
      'checkbox[8.25,.75;solo;Allow Singleplayer;'..solo..']'..
      'field[0.5,1.5;3.25,.5;player_count;Required # of Players;'..esc(player_count)..']'..
      'field[4.375,1.5;3.25,.5;xp;Required XP;'..esc(xp)..']'..
      'field[8.25,1.5;3.25,.5;pos;Spawn POS (x,y,z);'..esc(clean_pos)..']'..
      'field[0.5,2.5;11,.5;builders;Allowed Builders;'..esc(builders)..']'..
      'tooltip[builders;List of players that should be able to visit the map as builders.]'..
      'textarea[0.5,3.5;11,3.5;desc;Description of map;'..esc(desc)..']'..
      'button[.5,7.25;2,.75;adv;Advanced]'..
      'tooltip[adv;Set advanced level options.]'..
      'button[3.5,7.25;2,.75;save;Save]'..
      'tooltip[save;Saves values without making the button active.]'..
      'button[6.5,7.25;2,.75;submit;Submit]'..
      'tooltip[submit;Saves values and makes the button active.]'..
      'button_exit[9.5,7.25;2,.75;discard;Unclaim]'..
      'tooltip[discard;Clears all values and unclaims the button.]'
   if minetest.check_player_privs(player, {server = true}) then
      local i = 2
      local ids = owner..'_'..1
      local map_id = owner..'_'..2
      local owner_length = string.len(owner)
      local current_id = string.sub(id, (owner_length+2))
      while lobby.savedata.IDs[map_id] do
         ids = ids..','..map_id
         i = i + 1
         map_id = owner..'_'..i
      end
      formspec = formspec..'label[.5,.75;Map ID:]'..
      'dropdown[1.5,.5;2.25,.5;id;'..ids..';'..current_id..']'
   else
      formspec = formspec..
      'label[.5,.75;Map ID: '..esc(id)..']'
   end
   return formspec
end

local function button_create_adv(pos)
   local meta = minetest.get_meta(pos)
   local owner = meta:get_string('owner')
   local id = meta:get_string('id')
   local name = meta:get_string('name') or ''
   local spos = pos.x ..','.. pos.y ..','.. pos.z
   local cooldown = meta:get_int('cooldown') or 20
   local chance = meta:get_int('chance') or 100
   local damage = meta:get_int('damage') or 100
   local formspec =
      'formspec_version[3]'..
      'size[12,8]'..
      'background[-1,-1;14,10;lobby_button_bg.png]'..
      'style_type[textarea;textcolor=#ccddff;border=true]'..
      'label[0.5,.7;Map Name:]'..
      'textarea[3.25,.55;7,.4;;;'..esc(name)..' (by '..owner..')]'..
      'label[0.5,1.1;Map ID:]'..
      'textarea[3.25,.95;7,.4;;;'..esc(id)..']'..
      'field[3,2;2.5,.5;cooldown;Weapon Cooldown:;'..cooldown..']'..
      'field[3,3;2.5,.5;chance;Attack Chance:;'..chance..']'..
      'field[3,4;2.5,.5;damage;Attack Damage:;'..damage..']'..
      'style_type[textarea;textcolor=red;border=true]'..
      'textarea[5.75,1.5;6,6.25;;;   Weapon Cooldown:\n'..
      'How many seconds elapse until the Traitor get\'s the weapon back. Must be 20 or more. This number is quarted if the attack is not successful.\n\n'..
      '   Attack Chance:\n'..
      'What chance is there that the attack is successful, at 100% all will be, at 0% none will be.\n\n'..
      '   Attack Damage: (!!!Not Implemented!!!)\n'..
      'How much damage the player should be dealt in a percentage. (100 they die) Keep in mind players auto-heal so setting this low may make it impossible for a traitor to ever win.\n\n'..
      '    Weapon Selection:\n'..
      'Hover the weapon options to see the different range, and put the weapon you want for the level in the inventory slot to the left.]'..
      'label[0.5,1.75;Weapons List:]'..
      'label[3,5.25;Selected Weapon:]'..
      'list[detached:weapons_list;main;.5,2;2,4;]'..
      'list[nodemeta:'..spos..';weapon;3.25,5.75;1,1;]'..
      'button[.5,7.25;2,.75;back;Back]'..
      'tooltip[back;Takes you back to the previous menu.]'
   return formspec
end

local function button_display(pos)
   local meta = minetest.get_meta(pos)
   local owner = meta:get_string('owner')
   local id = meta:get_string('id')
   local name = meta:get_string('name')
   local player_count = meta:get_int('player_count') or 3
   local xp = meta:get_int('xp') or 50
   local pos = meta:get_string('pos')
   local desc = meta:get_string('desc')
   local cooldown = meta:get_int('cooldown') or 20
   local chance = meta:get_int('chance') or 100
   local formspec =
      'formspec_version[3]'..
      'size[12,8]'..
      'background[-1,-1;14,10;lobby_button_bg.png]'..
      'image_button[10.5,.5;1,1;lobby_report_icon.png;report;;;false]'..
      'tooltip[report;Report this level as incomplete.]'..
      'style_type[textarea;textcolor=#ccddff;border=true]'..
      'label[0.5,.7;Map Name:]'..
      'textarea[3.25,.55;7,.4;;;'..esc(name)..' (by '..owner..')]'..
      'label[0.5,1.1;Map ID:]'..
      'textarea[3.25,.95;7,.4;;;'..esc(id)..']'..
      'label[0.5,1.5;Req. # of Players:]'..
      'textarea[3.25,1.35;2,.4;;;'..esc(player_count)..']'..
      'label[0.5,1.9;Req. XP:]'..
      'textarea[3.25,1.75;2,.4;;;'..esc(xp)..']'..
      'label[5,1.5;Weapon Cooldown:]'..
      'textarea[7.5,1.35;2,.4;;;'..esc(cooldown)..']'..
      'label[5,1.9;Attack Chance:]'..
      'textarea[7.5,1.75;2,.4;;;'..esc(chance)..'%]'..
      'label[0.5,2.5;Description:]'..
      'textarea[0.5,2.75;11,2.75;;;'..esc(desc)..']'..
      'style_type[textarea;textcolor=#999999]'..
      'textarea[0.5,6.4;9,1.1;;;Sneak punch to visit without starting a game. Return with /lobby.\n'..
      'Be sure all interested parties are standing within three nodes of the button before punching.]'..
      'button[10,6.75;1.5,0.75;stats;Stats]'
   return formspec
end

local function button_claim(pos)
   local formspec =
      'formspec_version[3]'..
      'size[12,8]'..
      'background[-1,-1;14,10;lobby_button_bg.png]'..
      'label[4.5,1;Claim this button (15XP)]'..
      'button_exit[4,4;4,1;claim;Claim This Button]'
   return formspec
end

local function button_save(name, pos, fields, map_id)
   local meta = minetest.get_meta(pos)
   meta:set_string('infotext', fields.name)
   meta:set_string('name', fields.name)
   meta:set_int('player_count', fields.player_count)
   meta:set_int('xp', fields.xp)
   meta:set_string('pos', fields.pos)
   meta:set_string('desc', fields.desc)
   meta:set_string('builders', fields.builders)
   meta:set_string('id', map_id)
   local dist = tonumber(minetest.settings:get("map_generation_limit") or 31000)
   local x, y, z = string.match(fields.pos, "^(-?%d+),(-?%d+),(-?%d+)$")
   local pos_x = tonumber(x)
   local pos_y = tonumber(y)
   local pos_z = tonumber(z)
   local saveable = 0
   if fields.name == '' then
      minetest.chat_send_player(name, 'A name is required. You can always change it later')
      saveable = 1
   end
   if pos_x > dist or pos_x < -dist or pos_y > dist or pos_y < -dist or pos_z > dist or pos_z < -dist then
      minetest.chat_send_player(name, 'Double check your spawn pos, values seem to be invalid.')
      saveable = 1
   end
   if not lobby.is_integer(fields.player_count) then
      minetest.chat_send_player(name, 'An Integer is a whole number, your required player count is not.')
      saveable = 1
   end
   if not lobby.is_integer(fields.xp) then
      minetest.chat_send_player(name, 'An Integer is a whole number, your required XP amount is not.')
      saveable = 1
   end
   if saveable == 0 then
      local owner = meta:get_string('owner')
      local data = lobby.savedata.data[map_id] or {}
      data.builders = fields.builders
      data.description = fields.desc
      data.level_pos = {x = pos_x, y = pos_y+1, z = pos_z}
      data.map_name = fields.name
      data.owner_name = owner
      data.required_players = math.max(fields.player_count, 3)
      data.xp = math.max(tonumber(fields.xp),1)
      lobby.savedata.data[map_id] = data
      lobby.savedata.name_2_id[fields.name] = map_id
      lobby.savedata.id_2_name[map_id] = fields.name
      lobby.savedata.IDs[map_id] = true
      lobby.save()
      return true
   end
end

minetest.register_node('lobby:button_0', {
   description = 'Unconfigured Button',
   tiles = {'lobby_button_0.png'},
   groups = {breakable=1, not_in_creative_inventory=1},
   light_source = 5,
   after_place_node = function(pos, placer)
      local meta = minetest.get_meta(pos)
      local inv = meta:get_inventory()
      inv:set_size('weapon', 1)
      meta:set_string('infotext', 'Unconfigured/Unclaimed button')
      meta:set_string('name', '')
      meta:set_int('player_count', 3)
      meta:set_int('xp', 50)
      meta:set_int('chance', 100)
      meta:set_int('cooldown', 20)
      meta:set_string('pos', '')
      meta:set_string('desc', '')
      meta:set_string('builders', '')
      meta:set_string('solo', 'true')
   end,
   on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
      local player_name = clicker:get_player_name()
      lobby.button_pos[player_name] = pos
      local meta = minetest.get_meta(pos)
      local owner = meta:get_string('owner')
      local id = meta:get_string('id')
      if owner == '' then
         minetest.show_formspec(player_name, 'lobby:button_claim', button_claim(pos))
      elseif owner == player_name or minetest.check_player_privs(clicker, {server = true}) then
         minetest.show_formspec(player_name, 'lobby:button_create', button_create(pos, clicker))
      else
         minetest.show_formspec(player_name, 'lobby:button_display', button_display(pos))
         lobby.stat[player_name] = id
      end
   end,
   on_punch = function(pos, node, puncher, pointed_thing)
      local meta = minetest.get_meta(pos)
      local owner = meta:get_string('owner')
      local loc = meta:get_string('pos')
      local pos = minetest.string_to_pos(loc)
      local name = puncher:get_player_name()
      local map_id = meta:get_string('id')
      local builders = meta:get_string('builders')
      local player_attributes = puncher:get_meta()
      if name == owner then
         puncher:set_pos(pos)
         minetest.chat_send_player(name, 'Taking you to the level. Return to the lobby with /spawn')
         player_attributes:set_string('mode', 'builder')
         lobby.game[name] = map_id..'_builder'
      elseif minetest.check_player_privs(name, { creative = true }) and puncher:get_player_control().sneak and string.find(builders, name) then
         puncher:set_pos(pos)
         minetest.chat_send_player(name, 'Taking you to the level. Return to the lobby with /spawn')
         player_attributes:set_string('mode', 'builder')
         lobby.game[name] = map_id..'_builder'
      end
   end,
})

minetest.register_node('lobby:button_1', {
   description = 'Configured Button',
   tiles = {'lobby_button_1.png'},
   groups = {not_in_creative_inventory=1},
   drop = 'lobby:button_0',
   light_source = 14,
   on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
      local meta = minetest.get_meta(pos)
      local id = meta:get_string('id')
      local item = itemstack:get_name()
      local player_name = clicker:get_player_name()
      local owner = meta:get_string('owner')
      if item == 'creative:tool_breaking' or item == 'tasks:configurator' then
         if owner == player_name or minetest.check_player_privs(clicker, {server = true}) then
            minetest.swap_node(pos, {name = 'lobby:button_0'})
         end
      else
         minetest.show_formspec(player_name, 'lobby:button_display', button_display(pos))
         lobby.stat[player_name] = id
      end
   end,
   on_punch = function(pos, node, puncher, pointed_thing)
      local name = puncher:get_player_name()
      local meta = minetest.get_meta(pos)
      local map_id = meta:get_string('id')
      local game_data = lobby.savedata.data[map_id]
      local game_pos = game_data['level_pos']
      local builders = meta:get_string('builders')
      local player_attributes = puncher:get_meta()
      if minetest.check_player_privs(name, { creative = true }) and puncher:get_player_control().sneak and string.find(builders, name) then
         puncher:set_pos({x=game_pos.x+(math.random(-2,2)),y=game_pos.y+2,z=game_pos.z+(math.random(-2,2))})
         minetest.chat_send_player(name, 'Taking you to the level. Return to the lobby with /spawn')
         player_attributes:set_string('mode', 'builder')
         lobby.game[name] = map_id..'_builder'
      else
         local needed_players = game_data['required_players']
         local objs = minetest.get_objects_inside_radius(pos, 3)
         local player_count = 0
         local map_players = {}
         for _, obj in pairs(objs) do
            if obj:is_player() then
               player_count = player_count + 1
               local player_name = obj:get_player_name()
               table.insert(map_players, player_name)
            end
         end
         if player_count >= needed_players then
            if lobby.map[map_id] == 0 or lobby.map[map_id] == nil then
               minetest.chat_send_player(name, 'you can start the game!')
               lobby.play_time[map_id] = minetest.get_us_time()
               minetest.log('action', name..' just started a game on '..map_id)
               lobby.map[map_id] = player_count
               lobby.update_stats(map_id, 'player', '', player_count)
               local traitor = math.random(1, player_count)
               local inv = meta:get_inventory()
               local weapon = inv:get_stack('weapon', 1):get_name()
               print (weapon)
               if weapon == '' then
                  weapon = 'lobby:shank'
               end
               lobby.xp[map_id] = 0
               lobby.votes[map_id] = 0
               lobby.corpses[map_id] = {}
               lobby.sabotage[map_id] = false
               lobby.sabotage_level[map_id] = 5
               sabotage.timer[map_id] = 0
               for i=1,player_count do
                  minetest.chat_send_player(map_players[i], 'Hold tight, loading the level.')
                  local player = minetest.get_player_by_name(map_players[i])
                  local player_attributes = player:get_meta()
                  player_attributes:set_string('voting', 'false')
                  player_attributes:set_string('mode', 'player')
                  lobby.voted[map_players[i]] = true
                  if i == traitor then
                     local cooldown = 20
                     local data = lobby.savedata.data[map_id]
                     if data and data.cooldown then
                        cooldown = data.cooldown * 2
                     end
                     minetest.chat_send_player(map_players[i], 'You\'re the imposter. Try to kill all the other players.')
                     minetest.chat_send_player(map_players[i], 'You\'ll get a weapon in a '..cooldown..' seconds.')
                     lobby.traitors[map_id] = map_players[i]
                     local player = minetest.get_player_by_name(map_players[i])
                     local player_inv = player:get_inventory()
                     minetest.after(cooldown, function()
                        player_inv:add_item('main', weapon)
                     end)
                     player_attributes:set_string('mode', 'traitor')
                  end
                  local privs = minetest.get_player_privs(map_players[i])
                  local player_inv = player:get_inventory()
                  player_inv:set_list('main', {})
                  player_inv:set_size('main', 16)
                  lobby.game[map_players[i]] = map_id
                  player:set_pos({x=game_pos.x+(math.random(-2,2)),y=game_pos.y,z=game_pos.z+(math.random(-2,2))})
                  privs.fly = nil
                  privs.fast = nil
                  privs.creative = nil
                  privs.areas = nil
                  minetest.set_player_privs(map_players[i], privs)
               end
               lobby.voting_formspec(map_id, true)
            else
               minetest.chat_send_player(puncher:get_player_name(), 'You can\'t join an in progress game.\nYou can possibly play solo by sneak+punching.')
            end
         elseif puncher:get_player_control().sneak then
            local solo = meta:get_string('solo')
            if solo == 'true' then
               lobby.update_stats(map_id, 'solo')
               local name = puncher:get_player_name()
               puncher:set_nametag_attributes({
                  color = {a = 0, r = 255, g = 255, b = 255}
               })
               puncher:set_properties({visual_size = {x = 0, y = 0}, collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3}})
               lobby.builder_to_player(puncher)
               puncher:set_pos(game_pos)
               lobby.game[name] = map_id..'_solo'
               minetest.chat_send_player(name, 'Travel back to the lobby with the /lobby chat command.')
            else
               minetest.chat_send_player(name, 'Sorry this level is not able to be played solo.')
            end
         else
            minetest.chat_send_player(puncher:get_player_name(), 'Maybe not enough players? Right click the button for more information.')
         end
      end
   end,
})

minetest.register_on_player_receive_fields(function(player, formname, fields)
   if formname == 'lobby:button_display' then
      local name = player:get_player_name()
      local map_id = lobby.stat[name]
      print (map_id)
      if fields.stats then
         minetest.show_formspec(name, 'lobby:stats', lobby.retrieve_stats(map_id))
      elseif fields.report then
         if not lobby.is_builder(player) then
            minetest.chat_send_player(name, 'Sorry, only builders can report levels.')
         else
            minetest.show_formspec(name, 'lobby:report', lobby.report_level(map_id))
         end
      end
   elseif formname == 'lobby:report' then
      local name = player:get_player_name()
      local map_id = lobby.stat[name]
      if fields.save then
         local reason = fields.reason
         if reason then
            local input = fields.input
            minetest.chat_send_player(name, 'Thanks for your report')
            local map_name = lobby.savedata.id_2_name[map_id] or map_id
            local data = lobby.savedata.data[map_id]
            local map_owner = data.owner_name
            local src = 'system'
            local dst = 'Admin, '..map_owner..', '..name
            local subject = name..' reported '..reason..' on '..map_name
            local body = input..'\n\n\nThis is an automated message, please do not respond.'
            mail.send(src, dst, subject, body)
         else
            minetest.chat_send_player(name, 'You need to select a reason.')
         end
      end
   elseif formname == 'lobby:button_claim' then
      if fields.claim then
         local name = player:get_player_name()
         if lobby.is_builder(player) then
            if lobby.take_xp(player, 15) then
               local pos = lobby.button_pos[name]
               local meta = minetest.get_meta(pos)
               minetest.show_formspec(name, 'lobby:get_started', lobby.getting_started)
               meta:set_string('owner', name)
               local map_id = lobby.create_id(name)
               meta:set_string('id', map_id)
               local pos_string = random_pos()
               local pos = minetest.string_to_pos(pos_string)
               local run = true
               while run do
                  if not minetest.is_protected(pos, player) and run then
                     minetest.load_area(pos)
                     meta:set_string('pos', pos_string)
                     worldedit.cube(pos, 5, 1, 5, 'color:grey_blocks', false)
                     minetest.set_node(pos, {name = 'lights:block_4'})
                     run = false
                  end
               end
            end
         else
            minetest.chat_send_player(name, 'You need more XP!')
         end
      end
   elseif formname == 'lobby:button_create' then
      local name = player:get_player_name()
      local pos = lobby.button_pos[name]
      local meta = minetest.get_meta(pos)
      local map_id = meta:get_string('id')
      local owner = meta:get_string('owner')
      if owner == name or minetest.check_player_privs(player, {server = true}) then
         if fields.id and fields.id ~= map_id then
            local stats = lobby.savedata.stats[map_id]
            if not stats then
               lobby.savedata.IDs[map_id] = nil
               lobby.savedata.data[map_id] = nil
               lobby.savedata.id_2_name[map_id] = nil
            end
            local map_id = fields.id
            local data = lobby.savedata.data[map_id]
            if data and data.map_name then
               meta:set_string('id', map_id)
               minetest.show_formspec(name, 'lobby:button_create', button_create(pos, player))
            else
               minetest.chat_send_player(name, 'That ID never had any data saved.')
            end
         end
         if not string.find(map_id, owner) then --Using old player assigned IDs
            local map_id_new = lobby.create_id(owner)
            lobby.savedata.IDs[map_id_new] = true
            meta:set_string('id', map_id_new)
            if lobby.savedata.stats[map_id] then
               local stats = lobby.savedata.stats[map_id] or {}
               local stats_new = {}
               stats_new.solo_play = stats.solo_play or 0
               stats_new.multi_play = stats.multi_play or 0
               stats_new.winner_traitor = stats.winner_traitor or 0
               stats_new.winner_team = stats.winner_team or 0
               stats_new.player_count = stats.player_count or 0
               stats_new.max_players = stats.max_players or 0
               lobby.savedata.stats[map_id_new] = stats_new
               lobby.savedata.IDs[map_id] = nil
               lobby.savedata.stats[map_id] = nil
               lobby.savedata.data[map_id] = nil
            end
            map_id = map_id_new
         end
         if fields.solo then
            meta:set_string('solo', fields.solo)
         elseif fields.adv then
            if button_save(name, pos, fields, map_id) then
               minetest.show_formspec(name, 'lobby:button_create_adv', button_create_adv(pos))
            end
         elseif fields.save then
            if button_save(name, pos, fields, map_id) then
               minetest.close_formspec(name, 'lobby:button_create')
            end
         elseif fields.submit then
            if button_save(name, pos, fields, map_id) then
               minetest.swap_node(pos, {name = 'lobby:button_1'})
               minetest.close_formspec(name, 'lobby:button_create')
            end
         elseif fields.discard then
            meta:set_string('owner', '')
            meta:set_string('infotext', 'Unconfigured/Unclaimed Button')
            meta:set_string('id', '')
            meta:set_string('name', '')
            meta:set_int('player_count', '3')
            meta:set_int('xp', '50')
            meta:set_string('pos', '')
            meta:set_string('desc', '')
            meta:set_string('builders', '')
            meta:set_string('solo', 'true')
            local stats = lobby.savedata.stats[map_id]
            if not stats then
               lobby.savedata.IDs[map_id] = nil
               lobby.savedata.data[map_id] = nil
               lobby.savedata.id_2_name[map_id] = nil
            end
            lobby.give_xp(player, 15)
         end
      end
   elseif formname == 'lobby:button_create_adv' then
      local name = player:get_player_name()
      local pos = lobby.button_pos[name]
      if fields.back then
         local cooldown = fields.cooldown
         local chance = fields.chance
         if lobby.is_integer(cooldown) and lobby.is_integer(chance) then
            cooldown = math.max(cooldown, 20)
            chance = math.max(0, math.min(100, chance))
            local meta = minetest.get_meta(pos)
            local map_id = meta:get_string('id')
            meta:set_int('cooldown', cooldown)
            meta:set_int('chance', chance)
            local data = lobby.savedata.data[map_id]
            data.cooldown = cooldown
            data.chance = chance
            lobby.savedata.data[map_id] = data
            lobby.save()
            minetest.show_formspec(name, 'lobby:button_create', button_create(pos, player))
         else
            minetest.chat_send_player(name, 'Uhhh, so you need a number, specifically an integer for the weapon cooldown.')
         end
      end
   end
end)

minetest.register_lbm({
   label = 'Frees abandoned buttons',
   name = 'lobby:clean_buttons',
   run_at_every_load = true,
   nodenames = {'lobby:button_0'},
   action = function(pos, node)
      local meta = minetest.get_meta(pos)
      local owner = meta:get_string('owner')
      local pauth = core.get_auth_handler().get_auth(owner)
      if pauth and pauth.last_login and pauth.last_login ~= -1 then
         local diff = math.ceil(os.difftime(pauth.last_login, os.time())/86400)
         if diff < -60 then
            local name = meta:get_string('name')
            minetest.log('info', 'Unclaimed '..owner..'\'s button at '..minetest.pos_to_string(pos)..' due to abandonment.')
            meta:set_string('owner', '')
            meta:set_string('infotext', 'Unconfigured/Unclaimed Button')
            meta:set_string('id', '')
            meta:set_string('name', '')
            meta:set_int('player_count', '3')
            meta:set_int('xp', '50')
            meta:set_string('pos', '')
            meta:set_string('desc', '')
            meta:set_string('builders', '')
            meta:set_string('solo', 'true')
            local src = 'system'
            local dst = 'Admin, '..owner
            local subject = 'Abandoned level button cleared'
            local body = 'This is just to let you know that one of your '..name..' buttons was unclaimed due to inactivity. You can claim a new button and ask an Admin to repopulate it with the old data.\n\n\nThis is an automated message, please do not respond.'
            mail.send(src, dst, subject, body)
         end
      end
   end
})
