159 lines
3.8 KiB
Lua
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
|
|
|