jails/api.lua
2014-10-14 11:20:19 -04:00

159 lines
3.8 KiB
Lua

function jails:jail(playerName, jailName)
jailName = jailName or self.default
local jail = self.jails[jailName]
if not jail then
return false, "Jail does not exist."
end
if self:getJail(playerName) then
return false, "Already jailed."
end
if not self:playerExists(playerName) then
return false, "Player does not exist."
end
local pos, message
local player = minetest.get_player_by_name(playerName)
if player then
pos = player:getpos()
player:setpos(jail.pos)
if jails.announce then
minetest.chat_send_all(playerName.." has been jailed!")
else
minetest.chat_send_player(playerName, "You have been jailed.")
end
else
message = "That player is not online right now."
.." They will be jailed when they next connect."
end
jail.captives[playerName] = {
privs = minetest.get_player_privs(playerName),
pos = pos,
}
minetest.set_player_privs(playerName, {})
local ok, msg = self:save()
if not ok then return ok, msg end
return true, message
end
function jails:unjail(playerName)
for name, jail in pairs(self.jails) do
local playerData = jail.captives[playerName]
if playerData then
self:release(playerName, playerData)
jail.captives[playerName] = nil
return self:save()
end
end
return false, "Player not jailed."
end
function jails:getJail(playerName)
for jailName, jail in pairs(self.jails) do
if jail.captives[playerName] then
return jailName, jail
end
end
end
function jails:add(jailName, pos)
self.jails[jailName] = {
pos = pos,
captives = {},
}
return self:save()
end
function jails:remove(jailName, newJailName)
jailName = jailName or self.default
local jail = self.jails[jailName]
if not jail then
return false, "Jail does not exist."
end
local newJail
if newJailName then
if newJailName == jailName then
return false, "Cannot replace a jail with itself."
end
newJail = self.jails[newJailName]
if not newJail then
return false, "Jail to transfer to does not exist."
end
for playerName, playerData in pairs(jail.captives) do
newJail.captives[playerName] = playerData
local player = minetest.get_player_by_name(playerName)
if player then
player:setpos(newJail.pos)
end
end
else
for playerName, playerData in pairs(jail.captives) do
self:release(playerName, playerData)
end
end
self.jails[jailName] = nil
return self:save()
end
local fallbackSpawn = {x=0, y=8, z=0}
function jails:getSpawnPos(oldCaptivePos)
return oldCaptivePos or minetest.setting_get_pos("static_spawnpoint") or fallbackSpawn
end
function jails:save()
local dataStr = minetest.serialize(self.jails)
if not dataStr then
minetest.log("error", "[jails] Failed to serialize jail data!")
return false, "Serialization failed!"
end
local file, err = io.open(self.filename, "w")
if err then
minetest.log("error", "[jails] Failed to open jail file for saving!")
return false, err
end
file:write(dataStr)
file:close()
return true
end
function jails:load()
local file, err = io.open(self.filename, "r")
if err then return false, err end
local str = file:read("*a")
file:close()
if str == "" then return false, "Jail file is empty!" end
local jails = minetest.deserialize(str)
if not jails then return false, "Failed to deserialize jail data!" end
self.jails = jails
return true
end
--------------
-- Internal --
--------------
function jails:playerExists(playerName)
return (minetest.builtin_auth_handler or minetest.auth_handler)
.get_auth(playerName) and true or false
end
function jails:release(playerName, playerData)
local player = minetest.get_player_by_name(playerName)
if player then
player:setpos(self:getSpawnPos(playerData.pos))
end
minetest.set_player_privs(playerName, playerData.privs)
if self.announce then
minetest.chat_send_all(playerName.." has been freed from jail!")
else
minetest.chat_send_player(playerName, "You have been freed from jail.")
end
end