198 lines
4.7 KiB
Lua
198 lines
4.7 KiB
Lua
local S = axinite.intllib
|
|
|
|
----------- SET POINT
|
|
|
|
setpoint = {}
|
|
|
|
local point_file = minetest.get_worldpath() .. "/point"
|
|
local pointpos = {}
|
|
|
|
local function load_point()
|
|
local input = io.open(point_file, "r")
|
|
if not input then
|
|
return -- no longer an error
|
|
end
|
|
|
|
-- Iterate over all stored positions in the format "x y z player" for each line
|
|
for pos, name in input:read("*a"):gmatch("(%S+ %S+ %S+)%s([%w_-]+)[\r\n]") do
|
|
pointpos[name] = minetest.string_to_pos(pos)
|
|
end
|
|
input:close()
|
|
end
|
|
|
|
load_point()
|
|
|
|
setpoint.set = function(name, pos)
|
|
local player = minetest.get_player_by_name(name)
|
|
if not player or not pos then
|
|
return false
|
|
end
|
|
|
|
local data = {}
|
|
local output, err = io.open(point_file, "w")
|
|
if output then
|
|
pointpos[name] = pos
|
|
for i, v in pairs(pointpos) do
|
|
table.insert(data, string.format("%.1f %.1f %.1f %s\n", v.x, v.y, v.z, i))
|
|
end
|
|
output:write(table.concat(data))
|
|
io.close(output)
|
|
return true
|
|
end
|
|
minetest.log("action", "Unable to write to player homes file: " .. err)
|
|
return false
|
|
end
|
|
|
|
setpoint.get = function(name)
|
|
local pos = pointpos[name]
|
|
if pos then
|
|
return vector.new(pos)
|
|
else
|
|
return nil
|
|
end
|
|
end
|
|
|
|
setpoint.go = function(name)
|
|
local player = minetest.get_player_by_name(name)
|
|
if player and pointpos[name] then
|
|
player:setpos(pointpos[name])
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
minetest.register_privilege("home", {
|
|
description = S("Can use /setpoint and /point"),
|
|
give_to_singleplayer = false
|
|
})
|
|
|
|
minetest.register_chatcommand("point", {
|
|
description = S("Teleport you to your second_home point"),
|
|
privs = {home = true},
|
|
func = function(name)
|
|
if not mana.checkmana(name, 0.8) then return end
|
|
|
|
if setpoint.go(name) then
|
|
return true, S("Teleported to point!")
|
|
end
|
|
return false, S("Set a point using /setpoint")
|
|
end,
|
|
})
|
|
|
|
minetest.register_chatcommand("setpoint", {
|
|
description = S("Set your point"),
|
|
privs = {home = true},
|
|
func = function(name)
|
|
name = name or "" -- fallback to blank name if nil
|
|
local player = minetest.get_player_by_name(name)
|
|
if player and setpoint.set(name, player:getpos()) then
|
|
return true, S("Point set!")
|
|
end
|
|
return false, "Player not found!"
|
|
end,
|
|
})
|
|
|
|
------------- NO KILL
|
|
|
|
-- Prevent certain players from killing / PvP
|
|
|
|
minetest.register_privilege("nokill", "Per-player hit prevention")
|
|
|
|
-- The admin always has all privileges, including the hit prevention
|
|
-- so we track the admin as a special case
|
|
local ADMIN = minetest.setting_get("name")
|
|
|
|
local ALLOWPUNCH = false
|
|
local DENYPUNCH = true
|
|
|
|
minetest.register_on_punchplayer(function(target, hitter, time_from_last_punch, tool_capabilities, dir, damage)
|
|
if not hitter:is_player() then
|
|
return ALLOWPUNCH
|
|
end
|
|
|
|
local hittername = hitter:get_player_name()
|
|
|
|
local preventkill = minetest.check_player_privs(hitter:get_player_name(), {nokill=true})
|
|
local isplayer = target:is_player()
|
|
|
|
return isplayer and preventkill and hittername ~= ADMIN
|
|
end)
|
|
|
|
--[[ Truth study
|
|
|
|
PLAYER NOKILL-on DENY
|
|
true true true
|
|
false true false
|
|
true false false
|
|
false false false
|
|
|
|
Operation: AND
|
|
--]]
|
|
|
|
-- Enable Sneak glitch
|
|
|
|
minetest.register_on_joinplayer(function(player)
|
|
local override_table = player:get_physics_override()
|
|
override_table.sneak_glitch = true
|
|
player:set_physics_override(override_table)
|
|
end)
|
|
|
|
--------------- SPAWN COMMAND
|
|
|
|
spawn_command = {}
|
|
spawn_command.pos = {x=0, y=3, z=0}
|
|
|
|
if minetest.setting_get_pos("static_spawnpoint") then
|
|
spawn_command.pos = minetest.setting_get_pos("static_spawnpoint")
|
|
end
|
|
|
|
minetest.register_chatcommand("spawn", {
|
|
description = S("Teleport you to spawn point."),
|
|
func = function(name)
|
|
if not mana.checkmana(name, 0.7) then return end
|
|
|
|
local player = minetest.get_player_by_name(name)
|
|
if player == nil then
|
|
-- just a check to prevent the server crashing
|
|
return false
|
|
end
|
|
local pos = player:getpos()
|
|
if pos.x>-20 and pos.x<20 and pos.y>-20 and pos.z>-20 and pos.z<20 then return
|
|
else
|
|
player:setpos(spawn_command.pos)
|
|
minetest.chat_send_player(name, S("Teleported to spawn!"))
|
|
end
|
|
end,
|
|
})
|
|
|
|
--------------- CONNECTED PLAYERS
|
|
|
|
local interval = tonumber(minetest.settings:get("connected_players.interval")) or 25
|
|
local players_file = minetest.get_worldpath() .. "/connected_players.txt"
|
|
local timer = 0
|
|
|
|
|
|
local function save_data()
|
|
local file, err = io.open(players_file, "w")
|
|
if file then
|
|
for i,player in ipairs(minetest.get_connected_players()) do
|
|
local name = player:get_player_name()
|
|
file:write(name .. "\n")
|
|
end
|
|
io.close(file)
|
|
return true
|
|
end
|
|
minetest.log("info", "Could not write players file: " .. err)
|
|
return false
|
|
end
|
|
|
|
minetest.register_globalstep(function(dtime)
|
|
timer = timer + dtime
|
|
if timer >= interval then
|
|
save_data()
|
|
timer = 0
|
|
else
|
|
return
|
|
end
|
|
end)
|