Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
ShadowNinja committed Oct 14, 2014
0 parents commit c69d53c
Show file tree
Hide file tree
Showing 5 changed files with 580 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*~

125 changes: 125 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
Jails for Minetest 0.4
======================

Commands
--------

You can use `*` if you need to explicitly specify the default jail for a command.

* `/jail [Player] [Jail]` - Jail a player or yourself. Note that it prefers
players over jails if there are two of the same name.

/jail player
/jail player FooJail
/jail FooJail -- (the person running the command is jailed)
/jail -- ^


* `/unjail [Player]` - Unjail a player or yourself.

/unjail player
/unjail

* `/add_jail [Jail] [X Y Z|X,Y,Z]` - Adds a new jail at your coordinates or
the ones specified.

/add_jail foojail -32 8 128
/add_jail foojail
/add_jail -16 64 512 (These add a jail with the default name)
/add_jail

* `/remove_jail [Jail [NewJail]]` - Removes a jail. Note: This will unjail
any players jailed in the jail unless `newJail` is specified, in which
case it will move them to the new jail.

/remove_jail foojail barjail
/remove_jail foojail
/remove_jail * foojail (Replaces the default jail with foojail)
/remove_jail (Removes default jail)

* `/list_jails [Jail]` - Prints data about all jails or a jail, including
their location and the captives in them.
Output is in the format `jailName (X,Y,Z): [captives]`.
Coordinates are rounded.

/list_jails foojail
/list_jails

* `/move_jail [Jail] [X Y Z|X,Y,Z]` - Move a jail

/move_jail foobar 0 8 0
/move_jail 0 8 0 (uses the default jail)
/move_jail foobar (set to your position)
/move_jail


Configuration
-------------

Jails uses the main server configuration file for it's configuration.
It uses the following settings:

* `jails.announce` (default `false`) - If `true`, jailing and unjailing
players will be announced globaly.


API
---

Jails has a simple API so that your mod can manipulate the jails.
All of the functions that change data call `jails:save()`.
Functions are documented in the format `functionName(args) -> returnValue`.
Variables are documented in the format `variableName = defaultValue`.


### Functions

* `jails:jail(playerName, [jailName])` -> success, message

Jail a player in the specified jail.
if `jailName` isn't passed the default jail will be used.

* `jails:unjail(playerName)` -> success, message

Unjail a player.

* `jails:getJail(playerName)` -> (jailName, jail) or `nil`

Checks if a player is jailed and returns the jail name and jail data or `nil`.

* `jails:add(jailName, pos)` -> success, message

Adds a new jail.

* `jails:remove([jailName, [newJail]])` -> success, message

Removes a jail from the jail list, unjailing all captives or moving
them to newJail.

* `jails:load()` -> success, message

Loads jail data from the jail file, this is automaticaly done on
server startup and probably unnecessary after then.

* `jails:save()` -> success, message

Saves jails to the jail file, all of the above commands run this
automaticaly.


### Variables

* `jails.jails` - A table of jails, indexed by name. Jails are of the form:

{
pos = {x=<x>, y=<y>, z=<z>},
captives = {
<Player name> = {
privs = <Original privileges>,
pos = <Original position>,
,}
},
}

* `jails.default` - The name of the default jail. Read-only.

158 changes: 158 additions & 0 deletions api.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@

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

0 comments on commit c69d53c

Please sign in to comment.