From 720451bd3832b46e1238babd4a31762d9715a5fa Mon Sep 17 00:00:00 2001 From: Sokomine Date: Mon, 30 Jul 2018 16:58:06 +0200 Subject: [PATCH] converted back to unix format --- init.lua | 1228 +++++++++++++++++++++++++++--------------------------- 1 file changed, 614 insertions(+), 614 deletions(-) diff --git a/init.lua b/init.lua index 73f4585..64a7cfc 100644 --- a/init.lua +++ b/init.lua @@ -1,614 +1,614 @@ - - - ---[[ - Shared locked objects (Mod for MineTest) - Allows to restrict usage of blocks to a certain player or a group of - players. - Copyright (C) 2013 Sokomine - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . ---]] - --- Version 1.20 - --- Changelog: --- 08.05.2014 * Changed animation of shared locked furnace (removed pipeworks overlay on front, changed to new animation type) --- 10.01.2013 * Added command to toggle for pipeworks output --- * Added pipeworks support for chests and furnace. --- 17.12.2013 * aborting input with ESC is possible again --- 01.09.2013 * fixed bug in input sanitization --- 31.08.2013 * changed receipe for key to avoid crafting conflickt with screwdriver --- 10.07.2013 * removed a potential bug (now uses string:gmatch) --- * added shared locked furnaces - - - -locks = {}; - -minetest.register_privilege("openlocks", { description = "allows to open/use all locked objects", give_to_singleplayer = false}); -minetest.register_privilege("diglocks", { description = "allows to open/use and dig up all locked objects", give_to_singleplayer = false}); - - -locks.pipeworks_enabled = false; - -if( minetest.get_modpath("pipeworks") ~= nil ) then - locks.pipeworks_enabled = true; -end - --- initializes a lock (that is: prepare the metadata so that it can store data) --- default_formspec is the formspec that will be used on right click; the input field for the commands has to exist --- Call this in on_construct in register_node. Excample: --- on_construct = function(pos) --- locks:lock_init( pos, "" ); --- end; - -function locks:lock_init( pos, default_formspec ) - - if( pos == nil ) then - print( "Error: [locks] lock_init: pos is nil"); - return; - end - - local meta = minetest.env:get_meta(pos); - if( meta == nil ) then - print( "Error: [locks] lock_init: unable to get meta data"); - return; - end - - -- this will be changed after the node is placed - meta:set_string("infotext", "Locked object"); - -- prepare the field for the owner - meta:set_string("owner", ""); - -- this is the list of players/groups that may unlock the lock even if they are not the owner - meta:set_string("allowed_users",""); - -- objects can be unlocked by passwords as well (if it is set) - meta:set_string("password",""); - -- the last player who entered the right password (to save space this is not a list) - meta:set_string("pw_user",""); - -- this formspec is presented on right-click for every user - meta:set_string("formspec", default_formspec); - -- by default, do not send output to pipework tubes - meta:set_int( "allow_pipeworks", 0 ); -end - - --- returns the information stored in the metadata strings (like owner etc.) -function locks:get_lockdata( pos ) - if( pos == nil ) then - return; - end - - local meta = minetest.env:get_meta(pos); - if( meta == nil) then - return; - end - - return{ infotext = (meta:get_string( "infotext" ) or ""), - owner = (meta:get_string( "owner" ) or ""), - allowed_users = (meta:get_string( "allowed_users" ) or ""), - password = (meta:get_string( "password" ) or ""), - pw_user = (meta:get_string( "w_user" ) or ""), - formspec = (meta:get_string( "formspec" ) or "") - }; -end - - --- sets all the metadata the look needs (used e.g. in doors) -function locks:set_lockdata( pos, data ) - if( pos == nil ) then - return; - end - - local meta = minetest.env:get_meta(pos); - if( meta == nil) then - return; - end - - meta:set_string("infotext", (data.infotext or "")); - meta:set_string("owner", (data.owner or "")); - meta:set_string("allowed_users",(data.allowed_users or "")); - meta:set_string("password", (data.password or "")); - meta:set_string("pw_user", (data.pw_user or "")); - meta:set_string("formspec", (data.formspec or "")); -end - - - - --- Set the owner of the locked object. --- Call this in after_place_node in register_node. Example: --- after_place_node = function(pos, placer) --- locks:lock_set_owner( pos, placer, "Shared locked object" ); --- end, -function locks:lock_set_owner( pos, player_or_name, description ) - - if( pos == nil or player_or_name == nil ) then - print( "Error: [locks] Missing/wrong parameters to lock_set_owner"); - return false; - end - - local meta = minetest.env:get_meta(pos); - if( meta == nil ) then - print( "Error: [locks] lock_set_owner: unable to get meta data"); - return; - end - - -- accepts a name or a player object - if( type( player_or_name )~="string") then - player_or_name = player_or_name:get_player_name(); - end - - meta:set_string("owner", player_or_name or ""); - -- add the name of the owner to the description - meta:set_string("infotext", ( description or "Shared lockecd object" ).." (owned by "..meta:get_string("owner")..")"); -end - - - --- The locked object can only be digged by the owner OR by people with the diglocks priv --- Call this in can_dig in register_node. Example: --- can_dig = function(pos,player) --- return locks:lock_allow_dig( pos, player ); --- end -function locks:lock_allow_dig( pos, player ) - - if( pos == nil or player == nil ) then - print( "Error: [locks] Missing/wrong parameters to lock_allow_dig"); - return false; - end - - local meta = minetest.env:get_meta(pos); - local lock_owner = meta:get_string("owner"); - - -- locks who lost their owner can be opened/digged by anyone - if( meta == nil or lock_owner == nil or lock_owner == "") then - return true; - end - - -- the owner can dig up his own locked objects - if( player:get_player_name() == meta:get_string("owner")) then - return true; - end - - -- players with diglocks priv can dig up locked objects as well - if( minetest.check_player_privs(player:get_player_name(), {diglocks=true})) then - return true; - end - - return false; -- fallback -end - - --- The locked object can only be used (i.e. opened, stuff taken out, changed, ... - depends on object) if this --- function returns true. Call it wherever appropriate (usually in on_punch in register_node). Example: --- on_punch = function(pos,player) --- if( !locks:lock_allow_use( pos, player ) then --- print( "Sorry, you have no access here."); --- else --- do_what_this_object_is_good_for( pos, puncher ); --- end --- end - -function locks:lock_allow_use( pos, player ) - - if( pos == nil or player == nil ) then - print( "Error: [locks] Missing/wrong parameters to lock_allow_use"); - return false; - end - - local name = player:get_player_name(); - local meta = minetest.env:get_meta(pos); - - -- pipeworks sends a special username - if( player.is_fake_player) then - if( locks:lock_allow_dig( pos, player ) and meta:get_int( 'allow_pipeworks' ) == 1 ) then - return true; - else - return false; - end - end - - -- the player has to have a key or a keychain to open his own shared locked objects - if( name == meta:get_string("owner")) then - - if( not( player:get_inventory():contains_item("main","locks:keychain 1")) - and not( player:get_inventory():contains_item("main","locks:key 1"))) then - minetest.chat_send_player( name, "You do not have a key or a keychain. Without that you can't use your shared locked objects!"); - return false; - end - - -- the player has to have a keychain to open shared locked objects of other players - else - - if( not( player:get_inventory():contains_item("main","locks:keychain 1"))) then - minetest.chat_send_player(name, "You do not have a keychain. Without that you can't open shared locked objects of other players!"); - return false; - end - end - - -- if the user would even be allowed to dig this node up, using the node is allowed as well - if( locks:lock_allow_dig( pos, player )) then - return true; - end - - - if( meta == nil ) then - minetest.chat_send_player( name, "Error: Could not access metadata of this shared locked object."); - return false; - end - - -- players with openlocks priv can open locked objects - if( minetest.check_player_privs(name, {openlocks=true})) then - return true; - end - - -- the player might be specificly allowed to use this object through allowed_users - local liste = meta:get_string("allowed_users"):split( "," ); - for i in ipairs( liste ) do - - if( liste[i] == name ) then - return true; - end - - -- the player might member of a playergroup that is allowed to use this object - if( liste[i]:sub(1,1) == ":" - and playergroups ~= nil - and playergroups:is_group_member( meta:get_string("owner"), liste[i]:sub(2), name )) then - return true; - end - - end - - - -- the player may have entered the right password - if( name == meta:get_string("pw_user")) then - return true; - end - - -- the lock may have a password set. If this is the case then ask the user for it - if( meta:get_string( "password" ) and meta:get_string( "password" ) ~= "" ) then - minetest.chat_send_player(name, "Access denied. Right-click and enter password first!"); - return false; - end - - return false; -- fallback - -end - - - --- Method for the lock to get password and configuration data --- Call in on_receive_fields in register_node. Example: --- on_receive_fields = function(pos, formname, fields, sender) --- locks:lock_handle_input( pos, formname, fields, sender ); --- end, -function locks:lock_handle_input( pos, formname, fields, player ) - - if( pos == nil or player == nil ) then - print( "Error: [locks] Missing/wrong parameters to lock_handle_input"); - return false; - end - - local meta = minetest.env:get_meta(pos); - if( meta == nil ) then - print( "Error: [locks] lock_handle_input: unable to get meta data"); - return; - end - - -- is this input the lock is supposed to handle? - if( ( not( fields.locks_sent_lock_command ) - or fields.locks_sent_lock_command == "" ) - and (fields.quit and (fields.quit==true or fields.quit=='true'))) then --- or not( fields.locks_sent_input ) - return; - end - - name = player:get_player_name(); - - if( fields.locks_sent_lock_command == "/help" ) then - - if( name == meta:get_string( "owner" )) then - minetest.chat_send_player(name, "The following commands are available to you, the owner of this object, only:\n".. - " /help Shows this help text.\n".. - " /add Player can now unlock this object with any key.\n".. - " /del Player can no longer use this object.\n".. - " /list Shows a list of players who can use this object.\n".. - " /set Sets a password. Everyone who types that in can use the object.\n".. - " /pipeworks Toggles permission for pipeworks to take inventory out of the shared locked object.\n"); - - else if( locks:lock_allow_use( pos, player )) then - minetest.chat_send_player(name, "This locked object is owned by "..tostring( meta:get_string( "owner" ))..".\n".. - "You do have access to it.\n"); - - else if( meta:get_string( "password" ) ~= "" ) then - minetest.chat_send_player(name, "This locked object is owned by "..tostring( meta:get_string( "owner" ))..".\n".. - "Enter the correct password to gain access.\n"); - - else - minetest.chat_send_player(name, "This locked object is owned by "..tostring( meta:get_string( "owner" ))..".\n".. - "There is no password set. You can only gain access if the owner grants it to you."); - - end end end -- lua is not the most intuitive language here.... - return; - end -- of /help - - -- sanitize player input - if( fields.locks_sent_lock_command:match("[^%a%d%s_%- /%:]")) then - minetest.chat_send_player(name, "Input contains unsupported characters. Allowed: a-z, A-Z, 0-9, _, -, :."); - return; - end - - if( #fields.locks_sent_lock_command > 60) then - minetest.chat_send_player(name, "Input too long. Only up to 80 characters supported."); - return; - end - - - local password = meta:get_string("password"); - -- other players can only try to input the correct password - if( name ~= meta:get_string( "owner" ) - or (password and password ~= "" and password==fields.locks_sent_lock_command) - or (name==meta:get_string("pw_user"))) then - - -- no need to bother with trying other PWs if none is set... - if( meta:get_string("password")=="" ) then - minetest.chat_send_player(name, "There is no password set. Access denied."); - return; - end - - -- the player may have entered the right password already - if( name == meta:get_string("pw_user")) then - -- nothing to do - the player entered the right pw alredy - minetest.chat_send_player(name, "You have entered the right password already. Access granted."); - return; - end - - if( fields.locks_sent_lock_command ~= meta:get_string("password")) then - minetest.chat_send_player(name, "Wrong password. Access denied."); - return; - end - - -- store the last user (this one) who entered the right pw - meta:set_string( "pw_user", name ); - - minetest.chat_send_player(name, "Password confirmed. Access granted."); - return; - end - - local txt = ""; - - - if( fields.locks_sent_lock_command == "/list" ) then - - if( meta:get_string("allowed_users")=="" ) then - txt = "No other users are allowed to use this object (except those with global privs like moderators/admins)."; - else - txt = "You granted the following users/groups of users access to this object:\n"; - local liste = meta:get_string("allowed_users"):split( "," ); - for i in ipairs( liste ) do - txt = txt.." "..tostring(liste[i]); - end - end - - if( meta:get_string( "password" ) == "" ) then - txt = txt.."\nThere is no password set. That means no one can get access through a password."; - else - txt = txt.."\nThe password for this lock is: \""..tostring( meta:get_string( "password" ).."\""); - end - - if( not( minetest.get_modpath("pipeworks") )) then - txt = txt.."\nThe pipeworks mod is not installed. Install it if you wish support for tubes."; - elseif( meta:get_int( "allow_pipeworks" ) == 1 ) then - txt = txt.."\nTubes from pipeworks may be used to extract items out of/add items to this shared locked object."; - else - txt = txt.."\nInput from tubes is accepted, but output to them is denied (default)."; - end - - minetest.chat_send_player(name, txt ); - return; - end -- of /list - - - -- toggle tube output on/off - if( fields.locks_sent_lock_command == "/pipeworks" ) then - - if( meta:get_int('allow_pipeworks') == 1 ) then - meta:set_int('allow_pipeworks', 0 ); - minetest.chat_send_player( name, 'Output to pipework tubes is now DISABLED (input is still acceped).'); - return; - else - meta:set_int('allow_pipeworks', 1 ); - minetest.chat_send_player( name, 'Output to pipework tubes is now ENABLED. Connected tubes may insert and remove items.'); - return; - end - end - --- -- all other commands take exactly one parameter - local help = fields.locks_sent_lock_command:split( " " ); - - print( tostring( help[1] )); - print( tostring( help[2] )); - - - -- set/change a password - if( help[1]=="/set" ) then - - -- if empty password then delete it - if( help[2]==nil ) then - help[2] = ""; - end - - minetest.chat_send_player(name, "Old password: \""..tostring( meta:get_string( "password" )).. - "\"\n Changed to new password: \""..tostring( help[2]).."\"."); - - - meta:set_string( "password", help[2]); - -- reset the list of users who typed the right password - meta:set_string("pw_users",""); - - if( help[2]=="") then - minetest.chat_send_player(name, "The password is empty and thus will be disabled."); - end - return; - end - - if( help[2]==nil or help[2]=="") then - minetest.chat_send_player(name, "Error: Missing parameter (player name) for command \""..tostring( help[1] ).."\"." ); - return; - end - - -- for add and del: check if the player is already in the list - - local found = false; - local anz = 0; - local liste = meta:get_string("allowed_users"):split( "," ); - for i in ipairs( liste ) do - - anz = anz + 1; -- count players - if( tostring( liste[i] ) == help[2] ) then - found = true; - end - - end - - if( help[1]=="/add" and found==true ) then - minetest.chat_send_player(name, "Player \""..tostring( help[2] ).."\" is already allowed to use this locked object. Nothing to do."); - return; - end - - if( help[1]=="/del" and found==false) then - minetest.chat_send_player(name, "Player \""..tostring( help[2] ).."\" is not amongst the players allowed to use this locked object. Nothing to do."); - return; - end - - - if( help[1]=="/add" ) then - - if( anz >= 6 ) then - minetest.chat_send_player(name, "Sorry, no more players can be added. To save space, only up to 6 players can be added. For more players please use groups!"); - return; - end - - if( name == help[2] ) then - minetest.chat_send_player(name, "You are already owner of this object."); - return; - end - - -- the player might try to add a playergroup - if( help[2]:sub(1,1) == ":" ) then - - if( not( playergroups )) then - minetest.chat_send_player(name, "Sorry, this server does not support playergroups."); - return; - end - - if( #help[2]<2 ) then - minetest.chat_send_player(name, "Please specify the name of the playergroup you want to add!"); - return; - end - - if( not( playergroups:is_playergroup(meta:get_string("owner"), help[2]:sub(2) ))) then - minetest.chat_send_player(name, "You do not have a playergroup named \""..tostring( help[2]:sub(2)).."\"."); - return; - end - - else - - -- check if the player exists - local privs = minetest.get_player_privs( help[2] ); - if( not( privs ) or not( privs.interact )) then - minetest.chat_send_player(name, "Player \""..help[2].."\" not found or has no interact privs."); - return; - end - end - - meta:set_string( "allowed_users", meta:get_string("allowed_users")..","..help[2] ); - - if( help[2]:sub(1,1) == ":" ) then - minetest.chat_send_player(name, "All members of your playergroup "..tostring(help[2]:sub(2)).." may now use/access this locked object."); - else - minetest.chat_send_player(name, help[2].." may now use/access this locked object."); - end - return; - end - - - if( help[1]=="/del" ) then - - userlist = meta:get_string("allowed_users"):split( ","..help[2] ); - meta:set_string( "allowed_users", ( userlist[1] or "" )..(userlist[2] or "" )); - - minetest.chat_send_player(name, "Access for player \""..tostring(help[2]).."\" has been revoked."); - return; - end - - minetest.chat_send_player(name, "Error: Command \""..tostring(help[1]).."\" not understood."); -end - - - --- craftitem; that can be used to craft shared locked objects -minetest.register_craftitem("locks:lock", { - description = "Lock to lock and share objects", - image = "locks_lock16.png", -}); - - -minetest.register_craft({ - output = "locks:lock 2", - recipe = { - {'default:steel_ingot', 'default:steel_ingot','default:steel_ingot'}, - {'default:steel_ingot', '', 'default:steel_ingot'}, - {'', 'default:steel_ingot',''}, - } - }); - - --- a key allowes to open your own shared locked objects -minetest.register_craftitem("locks:key", { - description = "Key to open your own shared locked objects", - image = "locks_key32.png", -}); - -minetest.register_craft({ - output = "locks:key", - recipe = { - {'', 'default:stick', ''}, - {'', 'default:steel_ingot',''}, - } - }); - - - --- in order to open shared locked objects of other players, a keychain is needed (plus the owner has to admit it via /add playername or through /set password) -minetest.register_craftitem("locks:keychain", { - description = "Keychain to open shared locked objects of others", - image = "locks_keychain32.png", -}); - -minetest.register_craft({ - output = "locks:keychain", - recipe = { - {'', 'default:steel_ingot', '' }, - {'locks:key', 'locks:key', 'locks:key'}, - } - }); - -dofile(minetest.get_modpath("locks").."/shared_locked_chest.lua"); -dofile(minetest.get_modpath("locks").."/shared_locked_sign_wall.lua"); -dofile(minetest.get_modpath("locks").."/shared_locked_xdoors2.lua"); -dofile(minetest.get_modpath("locks").."/shared_locked_furnace.lua"); - - + + + +--[[ + Shared locked objects (Mod for MineTest) + Allows to restrict usage of blocks to a certain player or a group of + players. + Copyright (C) 2013 Sokomine + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +--]] + +-- Version 1.20 + +-- Changelog: +-- 08.05.2014 * Changed animation of shared locked furnace (removed pipeworks overlay on front, changed to new animation type) +-- 10.01.2013 * Added command to toggle for pipeworks output +-- * Added pipeworks support for chests and furnace. +-- 17.12.2013 * aborting input with ESC is possible again +-- 01.09.2013 * fixed bug in input sanitization +-- 31.08.2013 * changed receipe for key to avoid crafting conflickt with screwdriver +-- 10.07.2013 * removed a potential bug (now uses string:gmatch) +-- * added shared locked furnaces + + + +locks = {}; + +minetest.register_privilege("openlocks", { description = "allows to open/use all locked objects", give_to_singleplayer = false}); +minetest.register_privilege("diglocks", { description = "allows to open/use and dig up all locked objects", give_to_singleplayer = false}); + + +locks.pipeworks_enabled = false; + +if( minetest.get_modpath("pipeworks") ~= nil ) then + locks.pipeworks_enabled = true; +end + +-- initializes a lock (that is: prepare the metadata so that it can store data) +-- default_formspec is the formspec that will be used on right click; the input field for the commands has to exist +-- Call this in on_construct in register_node. Excample: +-- on_construct = function(pos) +-- locks:lock_init( pos, "" ); +-- end; + +function locks:lock_init( pos, default_formspec ) + + if( pos == nil ) then + print( "Error: [locks] lock_init: pos is nil"); + return; + end + + local meta = minetest.env:get_meta(pos); + if( meta == nil ) then + print( "Error: [locks] lock_init: unable to get meta data"); + return; + end + + -- this will be changed after the node is placed + meta:set_string("infotext", "Locked object"); + -- prepare the field for the owner + meta:set_string("owner", ""); + -- this is the list of players/groups that may unlock the lock even if they are not the owner + meta:set_string("allowed_users",""); + -- objects can be unlocked by passwords as well (if it is set) + meta:set_string("password",""); + -- the last player who entered the right password (to save space this is not a list) + meta:set_string("pw_user",""); + -- this formspec is presented on right-click for every user + meta:set_string("formspec", default_formspec); + -- by default, do not send output to pipework tubes + meta:set_int( "allow_pipeworks", 0 ); +end + + +-- returns the information stored in the metadata strings (like owner etc.) +function locks:get_lockdata( pos ) + if( pos == nil ) then + return; + end + + local meta = minetest.env:get_meta(pos); + if( meta == nil) then + return; + end + + return{ infotext = (meta:get_string( "infotext" ) or ""), + owner = (meta:get_string( "owner" ) or ""), + allowed_users = (meta:get_string( "allowed_users" ) or ""), + password = (meta:get_string( "password" ) or ""), + pw_user = (meta:get_string( "w_user" ) or ""), + formspec = (meta:get_string( "formspec" ) or "") + }; +end + + +-- sets all the metadata the look needs (used e.g. in doors) +function locks:set_lockdata( pos, data ) + if( pos == nil ) then + return; + end + + local meta = minetest.env:get_meta(pos); + if( meta == nil) then + return; + end + + meta:set_string("infotext", (data.infotext or "")); + meta:set_string("owner", (data.owner or "")); + meta:set_string("allowed_users",(data.allowed_users or "")); + meta:set_string("password", (data.password or "")); + meta:set_string("pw_user", (data.pw_user or "")); + meta:set_string("formspec", (data.formspec or "")); +end + + + + +-- Set the owner of the locked object. +-- Call this in after_place_node in register_node. Example: +-- after_place_node = function(pos, placer) +-- locks:lock_set_owner( pos, placer, "Shared locked object" ); +-- end, +function locks:lock_set_owner( pos, player_or_name, description ) + + if( pos == nil or player_or_name == nil ) then + print( "Error: [locks] Missing/wrong parameters to lock_set_owner"); + return false; + end + + local meta = minetest.env:get_meta(pos); + if( meta == nil ) then + print( "Error: [locks] lock_set_owner: unable to get meta data"); + return; + end + + -- accepts a name or a player object + if( type( player_or_name )~="string") then + player_or_name = player_or_name:get_player_name(); + end + + meta:set_string("owner", player_or_name or ""); + -- add the name of the owner to the description + meta:set_string("infotext", ( description or "Shared lockecd object" ).." (owned by "..meta:get_string("owner")..")"); +end + + + +-- The locked object can only be digged by the owner OR by people with the diglocks priv +-- Call this in can_dig in register_node. Example: +-- can_dig = function(pos,player) +-- return locks:lock_allow_dig( pos, player ); +-- end +function locks:lock_allow_dig( pos, player ) + + if( pos == nil or player == nil ) then + print( "Error: [locks] Missing/wrong parameters to lock_allow_dig"); + return false; + end + + local meta = minetest.env:get_meta(pos); + local lock_owner = meta:get_string("owner"); + + -- locks who lost their owner can be opened/digged by anyone + if( meta == nil or lock_owner == nil or lock_owner == "") then + return true; + end + + -- the owner can dig up his own locked objects + if( player:get_player_name() == meta:get_string("owner")) then + return true; + end + + -- players with diglocks priv can dig up locked objects as well + if( minetest.check_player_privs(player:get_player_name(), {diglocks=true})) then + return true; + end + + return false; -- fallback +end + + +-- The locked object can only be used (i.e. opened, stuff taken out, changed, ... - depends on object) if this +-- function returns true. Call it wherever appropriate (usually in on_punch in register_node). Example: +-- on_punch = function(pos,player) +-- if( !locks:lock_allow_use( pos, player ) then +-- print( "Sorry, you have no access here."); +-- else +-- do_what_this_object_is_good_for( pos, puncher ); +-- end +-- end + +function locks:lock_allow_use( pos, player ) + + if( pos == nil or player == nil ) then + print( "Error: [locks] Missing/wrong parameters to lock_allow_use"); + return false; + end + + local name = player:get_player_name(); + local meta = minetest.env:get_meta(pos); + + -- pipeworks sends a special username + if( player.is_fake_player) then + if( locks:lock_allow_dig( pos, player ) and meta:get_int( 'allow_pipeworks' ) == 1 ) then + return true; + else + return false; + end + end + + -- the player has to have a key or a keychain to open his own shared locked objects + if( name == meta:get_string("owner")) then + + if( not( player:get_inventory():contains_item("main","locks:keychain 1")) + and not( player:get_inventory():contains_item("main","locks:key 1"))) then + minetest.chat_send_player( name, "You do not have a key or a keychain. Without that you can't use your shared locked objects!"); + return false; + end + + -- the player has to have a keychain to open shared locked objects of other players + else + + if( not( player:get_inventory():contains_item("main","locks:keychain 1"))) then + minetest.chat_send_player(name, "You do not have a keychain. Without that you can't open shared locked objects of other players!"); + return false; + end + end + + -- if the user would even be allowed to dig this node up, using the node is allowed as well + if( locks:lock_allow_dig( pos, player )) then + return true; + end + + + if( meta == nil ) then + minetest.chat_send_player( name, "Error: Could not access metadata of this shared locked object."); + return false; + end + + -- players with openlocks priv can open locked objects + if( minetest.check_player_privs(name, {openlocks=true})) then + return true; + end + + -- the player might be specificly allowed to use this object through allowed_users + local liste = meta:get_string("allowed_users"):split( "," ); + for i in ipairs( liste ) do + + if( liste[i] == name ) then + return true; + end + + -- the player might member of a playergroup that is allowed to use this object + if( liste[i]:sub(1,1) == ":" + and playergroups ~= nil + and playergroups:is_group_member( meta:get_string("owner"), liste[i]:sub(2), name )) then + return true; + end + + end + + + -- the player may have entered the right password + if( name == meta:get_string("pw_user")) then + return true; + end + + -- the lock may have a password set. If this is the case then ask the user for it + if( meta:get_string( "password" ) and meta:get_string( "password" ) ~= "" ) then + minetest.chat_send_player(name, "Access denied. Right-click and enter password first!"); + return false; + end + + return false; -- fallback + +end + + + +-- Method for the lock to get password and configuration data +-- Call in on_receive_fields in register_node. Example: +-- on_receive_fields = function(pos, formname, fields, sender) +-- locks:lock_handle_input( pos, formname, fields, sender ); +-- end, +function locks:lock_handle_input( pos, formname, fields, player ) + + if( pos == nil or player == nil ) then + print( "Error: [locks] Missing/wrong parameters to lock_handle_input"); + return false; + end + + local meta = minetest.env:get_meta(pos); + if( meta == nil ) then + print( "Error: [locks] lock_handle_input: unable to get meta data"); + return; + end + + -- is this input the lock is supposed to handle? + if( ( not( fields.locks_sent_lock_command ) + or fields.locks_sent_lock_command == "" ) + and (fields.quit and (fields.quit==true or fields.quit=='true'))) then +-- or not( fields.locks_sent_input ) + return; + end + + name = player:get_player_name(); + + if( fields.locks_sent_lock_command == "/help" ) then + + if( name == meta:get_string( "owner" )) then + minetest.chat_send_player(name, "The following commands are available to you, the owner of this object, only:\n".. + " /help Shows this help text.\n".. + " /add Player can now unlock this object with any key.\n".. + " /del Player can no longer use this object.\n".. + " /list Shows a list of players who can use this object.\n".. + " /set Sets a password. Everyone who types that in can use the object.\n".. + " /pipeworks Toggles permission for pipeworks to take inventory out of the shared locked object.\n"); + + else if( locks:lock_allow_use( pos, player )) then + minetest.chat_send_player(name, "This locked object is owned by "..tostring( meta:get_string( "owner" ))..".\n".. + "You do have access to it.\n"); + + else if( meta:get_string( "password" ) ~= "" ) then + minetest.chat_send_player(name, "This locked object is owned by "..tostring( meta:get_string( "owner" ))..".\n".. + "Enter the correct password to gain access.\n"); + + else + minetest.chat_send_player(name, "This locked object is owned by "..tostring( meta:get_string( "owner" ))..".\n".. + "There is no password set. You can only gain access if the owner grants it to you."); + + end end end -- lua is not the most intuitive language here.... + return; + end -- of /help + + -- sanitize player input + if( fields.locks_sent_lock_command:match("[^%a%d%s_%- /%:]")) then + minetest.chat_send_player(name, "Input contains unsupported characters. Allowed: a-z, A-Z, 0-9, _, -, :."); + return; + end + + if( #fields.locks_sent_lock_command > 60) then + minetest.chat_send_player(name, "Input too long. Only up to 80 characters supported."); + return; + end + + + local password = meta:get_string("password"); + -- other players can only try to input the correct password + if( name ~= meta:get_string( "owner" ) + or (password and password ~= "" and password==fields.locks_sent_lock_command) + or (name==meta:get_string("pw_user"))) then + + -- no need to bother with trying other PWs if none is set... + if( meta:get_string("password")=="" ) then + minetest.chat_send_player(name, "There is no password set. Access denied."); + return; + end + + -- the player may have entered the right password already + if( name == meta:get_string("pw_user")) then + -- nothing to do - the player entered the right pw alredy + minetest.chat_send_player(name, "You have entered the right password already. Access granted."); + return; + end + + if( fields.locks_sent_lock_command ~= meta:get_string("password")) then + minetest.chat_send_player(name, "Wrong password. Access denied."); + return; + end + + -- store the last user (this one) who entered the right pw + meta:set_string( "pw_user", name ); + + minetest.chat_send_player(name, "Password confirmed. Access granted."); + return; + end + + local txt = ""; + + + if( fields.locks_sent_lock_command == "/list" ) then + + if( meta:get_string("allowed_users")=="" ) then + txt = "No other users are allowed to use this object (except those with global privs like moderators/admins)."; + else + txt = "You granted the following users/groups of users access to this object:\n"; + local liste = meta:get_string("allowed_users"):split( "," ); + for i in ipairs( liste ) do + txt = txt.." "..tostring(liste[i]); + end + end + + if( meta:get_string( "password" ) == "" ) then + txt = txt.."\nThere is no password set. That means no one can get access through a password."; + else + txt = txt.."\nThe password for this lock is: \""..tostring( meta:get_string( "password" ).."\""); + end + + if( not( minetest.get_modpath("pipeworks") )) then + txt = txt.."\nThe pipeworks mod is not installed. Install it if you wish support for tubes."; + elseif( meta:get_int( "allow_pipeworks" ) == 1 ) then + txt = txt.."\nTubes from pipeworks may be used to extract items out of/add items to this shared locked object."; + else + txt = txt.."\nInput from tubes is accepted, but output to them is denied (default)."; + end + + minetest.chat_send_player(name, txt ); + return; + end -- of /list + + + -- toggle tube output on/off + if( fields.locks_sent_lock_command == "/pipeworks" ) then + + if( meta:get_int('allow_pipeworks') == 1 ) then + meta:set_int('allow_pipeworks', 0 ); + minetest.chat_send_player( name, 'Output to pipework tubes is now DISABLED (input is still acceped).'); + return; + else + meta:set_int('allow_pipeworks', 1 ); + minetest.chat_send_player( name, 'Output to pipework tubes is now ENABLED. Connected tubes may insert and remove items.'); + return; + end + end + +-- -- all other commands take exactly one parameter + local help = fields.locks_sent_lock_command:split( " " ); + + print( tostring( help[1] )); + print( tostring( help[2] )); + + + -- set/change a password + if( help[1]=="/set" ) then + + -- if empty password then delete it + if( help[2]==nil ) then + help[2] = ""; + end + + minetest.chat_send_player(name, "Old password: \""..tostring( meta:get_string( "password" )).. + "\"\n Changed to new password: \""..tostring( help[2]).."\"."); + + + meta:set_string( "password", help[2]); + -- reset the list of users who typed the right password + meta:set_string("pw_users",""); + + if( help[2]=="") then + minetest.chat_send_player(name, "The password is empty and thus will be disabled."); + end + return; + end + + if( help[2]==nil or help[2]=="") then + minetest.chat_send_player(name, "Error: Missing parameter (player name) for command \""..tostring( help[1] ).."\"." ); + return; + end + + -- for add and del: check if the player is already in the list + + local found = false; + local anz = 0; + local liste = meta:get_string("allowed_users"):split( "," ); + for i in ipairs( liste ) do + + anz = anz + 1; -- count players + if( tostring( liste[i] ) == help[2] ) then + found = true; + end + + end + + if( help[1]=="/add" and found==true ) then + minetest.chat_send_player(name, "Player \""..tostring( help[2] ).."\" is already allowed to use this locked object. Nothing to do."); + return; + end + + if( help[1]=="/del" and found==false) then + minetest.chat_send_player(name, "Player \""..tostring( help[2] ).."\" is not amongst the players allowed to use this locked object. Nothing to do."); + return; + end + + + if( help[1]=="/add" ) then + + if( anz >= 6 ) then + minetest.chat_send_player(name, "Sorry, no more players can be added. To save space, only up to 6 players can be added. For more players please use groups!"); + return; + end + + if( name == help[2] ) then + minetest.chat_send_player(name, "You are already owner of this object."); + return; + end + + -- the player might try to add a playergroup + if( help[2]:sub(1,1) == ":" ) then + + if( not( playergroups )) then + minetest.chat_send_player(name, "Sorry, this server does not support playergroups."); + return; + end + + if( #help[2]<2 ) then + minetest.chat_send_player(name, "Please specify the name of the playergroup you want to add!"); + return; + end + + if( not( playergroups:is_playergroup(meta:get_string("owner"), help[2]:sub(2) ))) then + minetest.chat_send_player(name, "You do not have a playergroup named \""..tostring( help[2]:sub(2)).."\"."); + return; + end + + else + + -- check if the player exists + local privs = minetest.get_player_privs( help[2] ); + if( not( privs ) or not( privs.interact )) then + minetest.chat_send_player(name, "Player \""..help[2].."\" not found or has no interact privs."); + return; + end + end + + meta:set_string( "allowed_users", meta:get_string("allowed_users")..","..help[2] ); + + if( help[2]:sub(1,1) == ":" ) then + minetest.chat_send_player(name, "All members of your playergroup "..tostring(help[2]:sub(2)).." may now use/access this locked object."); + else + minetest.chat_send_player(name, help[2].." may now use/access this locked object."); + end + return; + end + + + if( help[1]=="/del" ) then + + userlist = meta:get_string("allowed_users"):split( ","..help[2] ); + meta:set_string( "allowed_users", ( userlist[1] or "" )..(userlist[2] or "" )); + + minetest.chat_send_player(name, "Access for player \""..tostring(help[2]).."\" has been revoked."); + return; + end + + minetest.chat_send_player(name, "Error: Command \""..tostring(help[1]).."\" not understood."); +end + + + +-- craftitem; that can be used to craft shared locked objects +minetest.register_craftitem("locks:lock", { + description = "Lock to lock and share objects", + image = "locks_lock16.png", +}); + + +minetest.register_craft({ + output = "locks:lock 2", + recipe = { + {'default:steel_ingot', 'default:steel_ingot','default:steel_ingot'}, + {'default:steel_ingot', '', 'default:steel_ingot'}, + {'', 'default:steel_ingot',''}, + } + }); + + +-- a key allowes to open your own shared locked objects +minetest.register_craftitem("locks:key", { + description = "Key to open your own shared locked objects", + image = "locks_key32.png", +}); + +minetest.register_craft({ + output = "locks:key", + recipe = { + {'', 'default:stick', ''}, + {'', 'default:steel_ingot',''}, + } + }); + + + +-- in order to open shared locked objects of other players, a keychain is needed (plus the owner has to admit it via /add playername or through /set password) +minetest.register_craftitem("locks:keychain", { + description = "Keychain to open shared locked objects of others", + image = "locks_keychain32.png", +}); + +minetest.register_craft({ + output = "locks:keychain", + recipe = { + {'', 'default:steel_ingot', '' }, + {'locks:key', 'locks:key', 'locks:key'}, + } + }); + +dofile(minetest.get_modpath("locks").."/shared_locked_chest.lua"); +dofile(minetest.get_modpath("locks").."/shared_locked_sign_wall.lua"); +dofile(minetest.get_modpath("locks").."/shared_locked_xdoors2.lua"); +dofile(minetest.get_modpath("locks").."/shared_locked_furnace.lua"); + +