- authlevel to set levels of access player has in robot sandbox (0 = ordinary, 1 = robot, 2 = puzzle, 3 = admin)
- authlevel is stored in metadata of robot and digitally signed using server private password to prevent abuses - minor bugfixes - new giver and checker blocks for puzzle, can create locks and keys now
This commit is contained in:
parent
046bcc445a
commit
8a8d22416d
15
commands.lua
15
commands.lua
@ -49,7 +49,7 @@ local function pos_in_dir(obj, dir) -- position after we move in specified direc
|
|||||||
elseif dir == 13 then -- forward_up
|
elseif dir == 13 then -- forward_up
|
||||||
pos.y=pos.y+1
|
pos.y=pos.y+1
|
||||||
elseif dir == 14 then -- backward_up
|
elseif dir == 14 then -- backward_up
|
||||||
yaw = yaw + pi; pos.y=pos.y-1
|
yaw = yaw + pi; pos.y=pos.y+1
|
||||||
end
|
end
|
||||||
|
|
||||||
if dir ~= 5 and dir ~= 6 then
|
if dir ~= 5 and dir ~= 6 then
|
||||||
@ -571,7 +571,7 @@ local register_robot_button = function(R,G,B,type)
|
|||||||
on_punch = function(pos, node, player)
|
on_punch = function(pos, node, player)
|
||||||
local name = player:get_player_name(); if name==nil then return end
|
local name = player:get_player_name(); if name==nil then return end
|
||||||
local round = math.floor;
|
local round = math.floor;
|
||||||
local r = 32; local ry = 2*r; -- note: this is skyblock adjusted
|
local r = basic_robot.radius; local ry = 2*r; -- note: this is skyblock adjusted
|
||||||
local ppos = {x=round(pos.x/r+0.5)*r,y=round(pos.y/ry+0.5)*ry+1,z=round(pos.z/r+0.5)*r}; -- just on top of basic_protect:protector!
|
local ppos = {x=round(pos.x/r+0.5)*r,y=round(pos.y/ry+0.5)*ry+1,z=round(pos.z/r+0.5)*r}; -- just on top of basic_protect:protector!
|
||||||
local meta = minetest.get_meta(ppos);
|
local meta = minetest.get_meta(ppos);
|
||||||
local name = meta:get_string("name");
|
local name = meta:get_string("name");
|
||||||
@ -595,7 +595,7 @@ minetest.register_node("basic_robot:button"..number,
|
|||||||
on_punch = function(pos, node, player)
|
on_punch = function(pos, node, player)
|
||||||
local name = player:get_player_name(); if name==nil then return end
|
local name = player:get_player_name(); if name==nil then return end
|
||||||
local round = math.floor;
|
local round = math.floor;
|
||||||
local r = 32; local ry = 2*r;
|
local r = basic_robot.radius; local ry = 2*r;
|
||||||
local ppos = {x=round(pos.x/r+0.5)*r,y=round(pos.y/ry+0.5)*ry+1,z=round(pos.z/r+0.5)*r};
|
local ppos = {x=round(pos.x/r+0.5)*r,y=round(pos.y/ry+0.5)*ry+1,z=round(pos.z/r+0.5)*r};
|
||||||
local meta = minetest.get_meta(ppos);
|
local meta = minetest.get_meta(ppos);
|
||||||
local name = meta:get_string("name");
|
local name = meta:get_string("name");
|
||||||
@ -618,7 +618,7 @@ minetest.register_node("basic_robot:button_"..number,
|
|||||||
on_punch = function(pos, node, player)
|
on_punch = function(pos, node, player)
|
||||||
local name = player:get_player_name(); if name==nil then return end
|
local name = player:get_player_name(); if name==nil then return end
|
||||||
local round = math.floor;
|
local round = math.floor;
|
||||||
local r = 32; local ry = 2*r;
|
local r = basic_robot.radius; local ry = 2*r;
|
||||||
local ppos = {x=round(pos.x/r+0.5)*r,y=round(pos.y/ry+0.5)*ry+1,z=round(pos.z/r+0.5)*r};
|
local ppos = {x=round(pos.x/r+0.5)*r,y=round(pos.y/ry+0.5)*ry+1,z=round(pos.z/r+0.5)*r};
|
||||||
local meta = minetest.get_meta(ppos);
|
local meta = minetest.get_meta(ppos);
|
||||||
local name = meta:get_string("name");
|
local name = meta:get_string("name");
|
||||||
@ -640,7 +640,7 @@ minetest.register_node("basic_robot:button_"..number,
|
|||||||
on_punch = function(pos, node, player)
|
on_punch = function(pos, node, player)
|
||||||
local name = player:get_player_name(); if name==nil then return end
|
local name = player:get_player_name(); if name==nil then return end
|
||||||
local round = math.floor;
|
local round = math.floor;
|
||||||
local r = 32; local ry = 2*r;
|
local r = basic_robot.radius; local ry = 2*r;
|
||||||
local ppos = {x=round(pos.x/r+0.5)*r,y=round(pos.y/ry+0.5)*ry+1,z=round(pos.z/r+0.5)*r};
|
local ppos = {x=round(pos.x/r+0.5)*r,y=round(pos.y/ry+0.5)*ry+1,z=round(pos.z/r+0.5)*r};
|
||||||
local meta = minetest.get_meta(ppos);
|
local meta = minetest.get_meta(ppos);
|
||||||
local name = meta:get_string("name");
|
local name = meta:get_string("name");
|
||||||
@ -675,6 +675,9 @@ register_robot_button_custom(281,"puzzle_NOT")
|
|||||||
register_robot_button_custom(282,"puzzle_delayer")
|
register_robot_button_custom(282,"puzzle_delayer")
|
||||||
register_robot_button_custom(283,"puzzle_platform")
|
register_robot_button_custom(283,"puzzle_platform")
|
||||||
|
|
||||||
|
register_robot_button_custom(284,"puzzle_giver")
|
||||||
|
register_robot_button_custom(285,"puzzle_checker")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- interactive button for robot: place robot on top of protector to intercept events
|
-- interactive button for robot: place robot on top of protector to intercept events
|
||||||
@ -1184,7 +1187,7 @@ basic_robot.commands.crypto = {encrypt = encrypt, decrypt = decrypt, scramble =
|
|||||||
|
|
||||||
local is_same_block = function(pos1,pos2)
|
local is_same_block = function(pos1,pos2)
|
||||||
local round = math.floor;
|
local round = math.floor;
|
||||||
local r = 32; local ry = 2*r; -- note: this is skyblock adjusted
|
local r = basic_robot.radius; local ry = 2*r; -- note: this is skyblock adjusted
|
||||||
local ppos1 = {round(pos1.x/r+0.5)*r,round(pos1.y/ry+0.5)*ry,round(pos1.z/r+0.5)*r};
|
local ppos1 = {round(pos1.x/r+0.5)*r,round(pos1.y/ry+0.5)*ry,round(pos1.z/r+0.5)*r};
|
||||||
local ppos2 = {round(pos2.x/r+0.5)*r,round(pos2.y/ry+0.5)*ry,round(pos2.z/r+0.5)*r};
|
local ppos2 = {round(pos2.x/r+0.5)*r,round(pos2.y/ry+0.5)*ry,round(pos2.z/r+0.5)*r};
|
||||||
return ppos1[1]==ppos2[1] and ppos1[2]==ppos2[2] and ppos1[3] == ppos2[3]
|
return ppos1[1]==ppos2[1] and ppos1[2]==ppos2[2] and ppos1[3] == ppos2[3]
|
||||||
|
107
init.lua
107
init.lua
@ -6,9 +6,10 @@ basic_robot = {};
|
|||||||
basic_robot.call_limit = 48; -- how many execution calls per script run allowed
|
basic_robot.call_limit = 48; -- how many execution calls per script run allowed
|
||||||
basic_robot.entry_count = 2 -- how many robot ordinary player can have
|
basic_robot.entry_count = 2 -- how many robot ordinary player can have
|
||||||
basic_robot.advanced_count = 16 -- how many robots player with robot privs can have
|
basic_robot.advanced_count = 16 -- how many robots player with robot privs can have
|
||||||
|
basic_robot.radius = 32; -- divide whole world into blocks of this size - used for managing events like keyboard punches
|
||||||
|
basic_robot.password = "robot passw0rd"; -- IMPORTANT: change it before running mod, server private password used for authentifications
|
||||||
|
|
||||||
|
basic_robot.bad_inventory_blocks = { -- disallow taking from these nodes inventories to prevent player abuses
|
||||||
basic_robot.bad_inventory_blocks = { -- disallow taking from these nodes inventories
|
|
||||||
["craft_guide:sign_wall"] = true,
|
["craft_guide:sign_wall"] = true,
|
||||||
}
|
}
|
||||||
basic_robot.maxoperations = 2; -- how many operations (dig, generate energy,..) available per run, 0 = unlimited
|
basic_robot.maxoperations = 2; -- how many operations (dig, generate energy,..) available per run, 0 = unlimited
|
||||||
@ -17,14 +18,14 @@ basic_robot.dig_require_energy = true; -- does robot require energy to dig?
|
|||||||
|
|
||||||
basic_robot.http_api = minetest.request_http_api();
|
basic_robot.http_api = minetest.request_http_api();
|
||||||
|
|
||||||
basic_robot.version = "2017/10 /07a";
|
basic_robot.version = "2017/12/18a";
|
||||||
|
|
||||||
basic_robot.data = {}; -- stores all robot data
|
basic_robot.data = {}; -- stores all robot data
|
||||||
--[[
|
--[[
|
||||||
[name] = { sandbox= .., bytecode = ..., ram = ..., obj = robot object,spawnpos=...}
|
[name] = { sandbox= .., bytecode = ..., ram = ..., obj = robot object,spawnpos=...}
|
||||||
robot object = object of entity, used to manipulate movements and more
|
robot object = object of entity, used to manipulate movements and more
|
||||||
--]]
|
--]]
|
||||||
basic_robot.ids = {}; -- stores maxid for all players
|
basic_robot.ids = {}; -- stores maxid for each player
|
||||||
--[name] = {id = .., maxid = .. }, current id, how many robot ids player can use
|
--[name] = {id = .., maxid = .. }, current id, how many robot ids player can use
|
||||||
|
|
||||||
basic_robot.data.listening = {}; -- which robots listen to chat
|
basic_robot.data.listening = {}; -- which robots listen to chat
|
||||||
@ -38,6 +39,8 @@ local check_code, preprocess_code,is_inside_string;
|
|||||||
|
|
||||||
function getSandboxEnv (name)
|
function getSandboxEnv (name)
|
||||||
|
|
||||||
|
local authlevel = basic_robot.data[name].authlevel or 0;
|
||||||
|
|
||||||
local commands = basic_robot.commands;
|
local commands = basic_robot.commands;
|
||||||
local directions = {left = 1, right = 2, forward = 3, backward = 4, up = 5, down = 6,
|
local directions = {left = 1, right = 2, forward = 3, backward = 4, up = 5, down = 6,
|
||||||
left_down = 7, right_down = 8, forward_down = 9, backward_down = 10,
|
left_down = 7, right_down = 8, forward_down = 9, backward_down = 10,
|
||||||
@ -114,17 +117,6 @@ function getSandboxEnv (name)
|
|||||||
return sender,mail
|
return sender,mail
|
||||||
end,
|
end,
|
||||||
|
|
||||||
read_form = function()
|
|
||||||
local fields = basic_robot.data[name].read_form;
|
|
||||||
local sender = basic_robot.data[name].form_sender;
|
|
||||||
basic_robot.data[name].read_form = nil;
|
|
||||||
basic_robot.data[name].form_sender = nil;
|
|
||||||
return sender,fields
|
|
||||||
end,
|
|
||||||
|
|
||||||
show_form = function(playername, form)
|
|
||||||
commands.show_form(name, playername, form)
|
|
||||||
end,
|
|
||||||
|
|
||||||
send_mail = function(target,mail)
|
send_mail = function(target,mail)
|
||||||
if not basic_robot.data[target] then return false end
|
if not basic_robot.data[target] then return false end
|
||||||
@ -328,7 +320,7 @@ function getSandboxEnv (name)
|
|||||||
write = function(i,title,text)
|
write = function(i,title,text)
|
||||||
if i<=0 or i > 32 then return nil end
|
if i<=0 or i > 32 then return nil end
|
||||||
local inv = minetest.get_meta(basic_robot.data[name].spawnpos):get_inventory();
|
local inv = minetest.get_meta(basic_robot.data[name].spawnpos):get_inventory();
|
||||||
local stack = basic_robot.commands.write_book(name,title,text);
|
local stack = basic_robot.commands.write_book(basic_robot.data[name].owner,title,text);
|
||||||
if stack then inv:set_stack("library", i, stack) end
|
if stack then inv:set_stack("library", i, stack) end
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
@ -346,7 +338,7 @@ function getSandboxEnv (name)
|
|||||||
end,
|
end,
|
||||||
|
|
||||||
run = function(script)
|
run = function(script)
|
||||||
if basic_robot.data[name].isadmin ~= 1 then
|
if basic_robot.data[name].authlevel < 3 then
|
||||||
local err = check_code(script);
|
local err = check_code(script);
|
||||||
script = preprocess_code(script);
|
script = preprocess_code(script);
|
||||||
if err then
|
if err then
|
||||||
@ -485,10 +477,23 @@ function getSandboxEnv (name)
|
|||||||
env.write_text[dir] = function(text) return commands.write_text(name, dir_id,text) end
|
env.write_text[dir] = function(text) return commands.write_text(name, dir_id,text) end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if authlevel>=1 then -- robot privs
|
||||||
|
env.self.read_form = function()
|
||||||
|
local fields = basic_robot.data[name].read_form;
|
||||||
|
local sender = basic_robot.data[name].form_sender;
|
||||||
|
basic_robot.data[name].read_form = nil;
|
||||||
|
basic_robot.data[name].form_sender = nil;
|
||||||
|
return sender,fields
|
||||||
|
end
|
||||||
|
|
||||||
|
env.self.show_form = function(playername, form)
|
||||||
|
commands.show_form(name, playername, form)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- set up sandbox for puzzle
|
-- set up sandbox for puzzle
|
||||||
|
|
||||||
local ispuzzle = basic_robot.data[name].ispuzzle; -- need puzzle privs
|
if authlevel>=2 then -- puzzle privs
|
||||||
if ispuzzle == 1 then
|
|
||||||
basic_robot.data[name].puzzle = {};
|
basic_robot.data[name].puzzle = {};
|
||||||
local data = basic_robot.data[name];
|
local data = basic_robot.data[name];
|
||||||
local pdata = data.puzzle;
|
local pdata = data.puzzle;
|
||||||
@ -516,13 +521,13 @@ function getSandboxEnv (name)
|
|||||||
pdata = pdata,
|
pdata = pdata,
|
||||||
ItemStack = ItemStack,
|
ItemStack = ItemStack,
|
||||||
}
|
}
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--special sandbox for admin
|
|
||||||
local isadmin=basic_robot.data[name].isadmin
|
|
||||||
|
|
||||||
if isadmin~=1 then
|
--special sandbox for admin
|
||||||
|
if authlevel<3 then -- is admin?
|
||||||
env._G = env;
|
env._G = env;
|
||||||
else
|
else
|
||||||
env.minetest = minetest;
|
env.minetest = minetest;
|
||||||
@ -675,7 +680,7 @@ end
|
|||||||
local function setCode( name, script ) -- to run script: 1. initSandbox 2. setCode 3. runSandbox
|
local function setCode( name, script ) -- to run script: 1. initSandbox 2. setCode 3. runSandbox
|
||||||
|
|
||||||
local err;
|
local err;
|
||||||
if basic_robot.data[name].isadmin~=1 then
|
if basic_robot.data[name].authlevel<3 then -- not admin
|
||||||
err = check_code(script);
|
err = check_code(script);
|
||||||
script = preprocess_code(script);
|
script = preprocess_code(script);
|
||||||
end
|
end
|
||||||
@ -806,9 +811,7 @@ local function init_robot(obj)
|
|||||||
basic_robot.data[name].quiet_mode = false; -- can chat globally
|
basic_robot.data[name].quiet_mode = false; -- can chat globally
|
||||||
|
|
||||||
-- check if admin robot
|
-- check if admin robot
|
||||||
if self.isadmin then basic_robot.data[name].isadmin = 1 end
|
basic_robot.data[name].authlevel = self.authlevel or 0
|
||||||
-- can we do puzzles?
|
|
||||||
if self.ispuzzle then basic_robot.data[name].ispuzzle = 1 end
|
|
||||||
|
|
||||||
--robot appearance,armor...
|
--robot appearance,armor...
|
||||||
obj:set_properties({infotext = "robot " .. name});
|
obj:set_properties({infotext = "robot " .. name});
|
||||||
@ -856,6 +859,8 @@ minetest.register_entity("basic_robot:robot",{
|
|||||||
end
|
end
|
||||||
|
|
||||||
self.owner = data.owner;
|
self.owner = data.owner;
|
||||||
|
self.authlevel = data.authlevel;
|
||||||
|
|
||||||
self.spawnpos = {x=data.spawnpos.x,y=data.spawnpos.y,z=data.spawnpos.z};
|
self.spawnpos = {x=data.spawnpos.x,y=data.spawnpos.y,z=data.spawnpos.z};
|
||||||
init_robot(self.object);
|
init_robot(self.object);
|
||||||
self.running = 1;
|
self.running = 1;
|
||||||
@ -985,7 +990,13 @@ local spawn_robot = function(pos,node,ttl)
|
|||||||
basic_robot.data[name] = {}; data = basic_robot.data[name];
|
basic_robot.data[name] = {}; data = basic_robot.data[name];
|
||||||
meta:set_string("infotext",minetest.get_gametime().. " code changed ")
|
meta:set_string("infotext",minetest.get_gametime().. " code changed ")
|
||||||
data.owner = owner;
|
data.owner = owner;
|
||||||
if meta:get_int("admin") == 1 then data.isadmin = 1 end
|
data.authlevel = meta:get_int("authlevel")
|
||||||
|
|
||||||
|
local sec_hash = minetest.get_password_hash("",data.authlevel.. owner .. basic_robot.password)
|
||||||
|
if meta:get_string("sec_hash")~= sec_hash then
|
||||||
|
minetest.chat_send_all("#ROBOT: " .. name .. " is using fake auth level. dig and place again.")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
if not data.obj then
|
if not data.obj then
|
||||||
--create virtual robot that reports position and other properties
|
--create virtual robot that reports position and other properties
|
||||||
@ -1008,7 +1019,7 @@ local spawn_robot = function(pos,node,ttl)
|
|||||||
if not data.bytecode then
|
if not data.bytecode then
|
||||||
local script = meta:get_string("code");
|
local script = meta:get_string("code");
|
||||||
|
|
||||||
if data.isadmin~=1 then
|
if data.authlevel<3 then -- not admin
|
||||||
err = check_code(script);
|
err = check_code(script);
|
||||||
script = preprocess_code(script);
|
script = preprocess_code(script);
|
||||||
end
|
end
|
||||||
@ -1059,8 +1070,14 @@ local spawn_robot = function(pos,node,ttl)
|
|||||||
luaent.name = name;
|
luaent.name = name;
|
||||||
luaent.code = meta:get_string("code");
|
luaent.code = meta:get_string("code");
|
||||||
luaent.spawnpos = {x=pos.x,y=pos.y-1,z=pos.z};
|
luaent.spawnpos = {x=pos.x,y=pos.y-1,z=pos.z};
|
||||||
if meta:get_int("admin") == 1 then luaent.isadmin = 1 end
|
luaent.authlevel = meta:get_int("authlevel")
|
||||||
if meta:get_int("puzzle") == 1 then luaent.ispuzzle = 1 end
|
|
||||||
|
local sec_hash = minetest.get_password_hash("",luaent.authlevel.. owner .. basic_robot.password)
|
||||||
|
if meta:get_string("sec_hash")~= sec_hash then
|
||||||
|
minetest.chat_send_all("#ROBOT: " .. name .. " is using fake auth level. dig and place again.")
|
||||||
|
obj:remove();
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local data = basic_robot.data[name];
|
local data = basic_robot.data[name];
|
||||||
if data == nil then
|
if data == nil then
|
||||||
@ -1720,10 +1737,24 @@ minetest.register_node("basic_robot:spawner", {
|
|||||||
alpha = 150,
|
alpha = 150,
|
||||||
after_place_node = function(pos, placer)
|
after_place_node = function(pos, placer)
|
||||||
local meta = minetest.env:get_meta(pos)
|
local meta = minetest.env:get_meta(pos)
|
||||||
meta:set_string("owner", placer:get_player_name());
|
local owner = placer:get_player_name();
|
||||||
|
meta:set_string("owner", owner);
|
||||||
|
|
||||||
local privs = minetest.get_player_privs(placer:get_player_name());
|
local privs = minetest.get_player_privs(placer:get_player_name());
|
||||||
if privs.privs then meta:set_int("admin",1) end
|
local authlevel = 0;
|
||||||
if privs.puzzle then meta:set_int("puzzle",1) end
|
if privs.privs then -- set auth level depending on privs
|
||||||
|
authlevel = 3
|
||||||
|
elseif privs.puzzle then
|
||||||
|
authlevel = 2
|
||||||
|
elseif privs.robot then
|
||||||
|
authlevel = 1
|
||||||
|
else
|
||||||
|
authlevel = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
meta:set_int("authlevel",authlevel)
|
||||||
|
local sec_hash = minetest.get_password_hash("",authlevel .. owner .. basic_robot.password) -- 'digitally sign' authlevel using password
|
||||||
|
meta:set_string("sec_hash", sec_hash);
|
||||||
|
|
||||||
meta:set_string("code","");
|
meta:set_string("code","");
|
||||||
meta:set_int("id",1); -- initial robot id
|
meta:set_int("id",1); -- initial robot id
|
||||||
@ -1827,9 +1858,9 @@ minetest.register_craftitem("basic_robot:control", {
|
|||||||
local owner = user:get_player_name();
|
local owner = user:get_player_name();
|
||||||
|
|
||||||
local script = itemstack:get_metadata();
|
local script = itemstack:get_metadata();
|
||||||
if script == "@" then -- remote control as a tool - notify robot in current block of pointed position
|
if script == "@" then -- remote control as a tool - notify robot in current block of pointed position, using keyboard event type 0
|
||||||
local round = math.floor;
|
local round = math.floor;
|
||||||
local r = 32; local ry = 2*r; -- note: this is skyblock adjusted
|
local r = basic_robot.radius; local ry = 2*r; -- note: this is skyblock adjusted
|
||||||
local pos = pointed_thing.under
|
local pos = pointed_thing.under
|
||||||
if not pos then return end
|
if not pos then return end
|
||||||
local ppos = {x=round(pos.x/r+0.5)*r,y=round(pos.y/ry+0.5)*ry+1,z=round(pos.z/r+0.5)*r}; -- just on top of basic_protect:protector!
|
local ppos = {x=round(pos.x/r+0.5)*r,y=round(pos.y/ry+0.5)*ry+1,z=round(pos.z/r+0.5)*r}; -- just on top of basic_protect:protector!
|
||||||
@ -1850,7 +1881,7 @@ minetest.register_craftitem("basic_robot:control", {
|
|||||||
if data and data.sandbox then
|
if data and data.sandbox then
|
||||||
|
|
||||||
else
|
else
|
||||||
minetest.chat_send_player(name, "#remote control: your robot must be running");
|
minetest.chat_send_player(owner, "#remote control: your robot must be running");
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1859,7 +1890,7 @@ minetest.register_craftitem("basic_robot:control", {
|
|||||||
if t1-t0<1 then return end
|
if t1-t0<1 then return end
|
||||||
data.remoteuse = t1;
|
data.remoteuse = t1;
|
||||||
|
|
||||||
if data.isadmin == 1 then
|
if data.authlevel >= 3 then
|
||||||
local privs = minetest.get_player_privs(owner); -- only admin can run admin robot
|
local privs = minetest.get_player_privs(owner); -- only admin can run admin robot
|
||||||
if not privs.privs then
|
if not privs.privs then
|
||||||
return
|
return
|
||||||
@ -1872,7 +1903,7 @@ minetest.register_craftitem("basic_robot:control", {
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if not data.isadmin then
|
if data.authlevel<3 then
|
||||||
if check_code(script)~=nil then return end
|
if check_code(script)~=nil then return end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
-- SOKOBAN GAME, by rnd, robots port
|
-- SOKOBAN GAME, by rnd, robots port
|
||||||
if not sokoban then
|
if not sokoban then
|
||||||
sokoban = {};
|
sokoban = {};
|
||||||
local players = find_player(4);
|
local players = find_player(5);
|
||||||
if not players then error("sokoban: no player near") end
|
if not players then error("sokoban: no player near") end
|
||||||
name = players[1];
|
name = players[1];
|
||||||
|
|
||||||
@ -37,7 +37,7 @@
|
|||||||
if lvl == nil then return end
|
if lvl == nil then return end
|
||||||
if lvl <0 or lvl >89 then return end
|
if lvl <0 or lvl >89 then return end
|
||||||
|
|
||||||
local file = _G.io.open(minetest.get_modpath("basic_robot").."/scripts/sokoban.txt","r")
|
local file = _G.io.open(minetest.get_modpath("basic_robot").."\\scripts\\sokoban.txt","r")
|
||||||
if not file then return end
|
if not file then return end
|
||||||
local str = ""; local s; local p = {x=pos.x,y=pos.y,z=pos.z}; local i,j;i=0;
|
local str = ""; local s; local p = {x=pos.x,y=pos.y,z=pos.z}; local i,j;i=0;
|
||||||
local lvl_found = false
|
local lvl_found = false
|
||||||
|
BIN
textures/puzzle_checker.png
Normal file
BIN
textures/puzzle_checker.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 732 B |
BIN
textures/puzzle_giver.png
Normal file
BIN
textures/puzzle_giver.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 762 B |
Loading…
x
Reference in New Issue
Block a user