- 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
|
||||
pos.y=pos.y+1
|
||||
elseif dir == 14 then -- backward_up
|
||||
yaw = yaw + pi; pos.y=pos.y-1
|
||||
yaw = yaw + pi; pos.y=pos.y+1
|
||||
end
|
||||
|
||||
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)
|
||||
local name = player:get_player_name(); if name==nil then return end
|
||||
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 meta = minetest.get_meta(ppos);
|
||||
local name = meta:get_string("name");
|
||||
@ -595,7 +595,7 @@ minetest.register_node("basic_robot:button"..number,
|
||||
on_punch = function(pos, node, player)
|
||||
local name = player:get_player_name(); if name==nil then return end
|
||||
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 meta = minetest.get_meta(ppos);
|
||||
local name = meta:get_string("name");
|
||||
@ -618,7 +618,7 @@ minetest.register_node("basic_robot:button_"..number,
|
||||
on_punch = function(pos, node, player)
|
||||
local name = player:get_player_name(); if name==nil then return end
|
||||
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 meta = minetest.get_meta(ppos);
|
||||
local name = meta:get_string("name");
|
||||
@ -640,7 +640,7 @@ minetest.register_node("basic_robot:button_"..number,
|
||||
on_punch = function(pos, node, player)
|
||||
local name = player:get_player_name(); if name==nil then return end
|
||||
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 meta = minetest.get_meta(ppos);
|
||||
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(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
|
||||
@ -1184,7 +1187,7 @@ basic_robot.commands.crypto = {encrypt = encrypt, decrypt = decrypt, scramble =
|
||||
|
||||
local is_same_block = function(pos1,pos2)
|
||||
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 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]
|
||||
|
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.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.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
|
||||
basic_robot.bad_inventory_blocks = { -- disallow taking from these nodes inventories to prevent player abuses
|
||||
["craft_guide:sign_wall"] = true,
|
||||
}
|
||||
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.version = "2017/10 /07a";
|
||||
basic_robot.version = "2017/12/18a";
|
||||
|
||||
basic_robot.data = {}; -- stores all robot data
|
||||
--[[
|
||||
[name] = { sandbox= .., bytecode = ..., ram = ..., obj = robot object,spawnpos=...}
|
||||
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
|
||||
|
||||
basic_robot.data.listening = {}; -- which robots listen to chat
|
||||
@ -38,6 +39,8 @@ local check_code, preprocess_code,is_inside_string;
|
||||
|
||||
function getSandboxEnv (name)
|
||||
|
||||
local authlevel = basic_robot.data[name].authlevel or 0;
|
||||
|
||||
local commands = basic_robot.commands;
|
||||
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,
|
||||
@ -114,17 +117,6 @@ function getSandboxEnv (name)
|
||||
return sender,mail
|
||||
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)
|
||||
if not basic_robot.data[target] then return false end
|
||||
@ -328,7 +320,7 @@ function getSandboxEnv (name)
|
||||
write = function(i,title,text)
|
||||
if i<=0 or i > 32 then return nil end
|
||||
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
|
||||
end
|
||||
},
|
||||
@ -346,7 +338,7 @@ function getSandboxEnv (name)
|
||||
end,
|
||||
|
||||
run = function(script)
|
||||
if basic_robot.data[name].isadmin ~= 1 then
|
||||
if basic_robot.data[name].authlevel < 3 then
|
||||
local err = check_code(script);
|
||||
script = preprocess_code(script);
|
||||
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
|
||||
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
|
||||
|
||||
local ispuzzle = basic_robot.data[name].ispuzzle; -- need puzzle privs
|
||||
if ispuzzle == 1 then
|
||||
if authlevel>=2 then -- puzzle privs
|
||||
basic_robot.data[name].puzzle = {};
|
||||
local data = basic_robot.data[name];
|
||||
local pdata = data.puzzle;
|
||||
@ -516,13 +521,13 @@ function getSandboxEnv (name)
|
||||
pdata = pdata,
|
||||
ItemStack = ItemStack,
|
||||
}
|
||||
|
||||
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;
|
||||
else
|
||||
env.minetest = minetest;
|
||||
@ -675,7 +680,7 @@ end
|
||||
local function setCode( name, script ) -- to run script: 1. initSandbox 2. setCode 3. runSandbox
|
||||
|
||||
local err;
|
||||
if basic_robot.data[name].isadmin~=1 then
|
||||
if basic_robot.data[name].authlevel<3 then -- not admin
|
||||
err = check_code(script);
|
||||
script = preprocess_code(script);
|
||||
end
|
||||
@ -806,9 +811,7 @@ local function init_robot(obj)
|
||||
basic_robot.data[name].quiet_mode = false; -- can chat globally
|
||||
|
||||
-- check if admin robot
|
||||
if self.isadmin then basic_robot.data[name].isadmin = 1 end
|
||||
-- can we do puzzles?
|
||||
if self.ispuzzle then basic_robot.data[name].ispuzzle = 1 end
|
||||
basic_robot.data[name].authlevel = self.authlevel or 0
|
||||
|
||||
--robot appearance,armor...
|
||||
obj:set_properties({infotext = "robot " .. name});
|
||||
@ -856,6 +859,8 @@ minetest.register_entity("basic_robot:robot",{
|
||||
end
|
||||
|
||||
self.owner = data.owner;
|
||||
self.authlevel = data.authlevel;
|
||||
|
||||
self.spawnpos = {x=data.spawnpos.x,y=data.spawnpos.y,z=data.spawnpos.z};
|
||||
init_robot(self.object);
|
||||
self.running = 1;
|
||||
@ -985,7 +990,13 @@ local spawn_robot = function(pos,node,ttl)
|
||||
basic_robot.data[name] = {}; data = basic_robot.data[name];
|
||||
meta:set_string("infotext",minetest.get_gametime().. " code changed ")
|
||||
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
|
||||
--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
|
||||
local script = meta:get_string("code");
|
||||
|
||||
if data.isadmin~=1 then
|
||||
if data.authlevel<3 then -- not admin
|
||||
err = check_code(script);
|
||||
script = preprocess_code(script);
|
||||
end
|
||||
@ -1059,8 +1070,14 @@ local spawn_robot = function(pos,node,ttl)
|
||||
luaent.name = name;
|
||||
luaent.code = meta:get_string("code");
|
||||
luaent.spawnpos = {x=pos.x,y=pos.y-1,z=pos.z};
|
||||
if meta:get_int("admin") == 1 then luaent.isadmin = 1 end
|
||||
if meta:get_int("puzzle") == 1 then luaent.ispuzzle = 1 end
|
||||
luaent.authlevel = meta:get_int("authlevel")
|
||||
|
||||
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];
|
||||
if data == nil then
|
||||
@ -1720,10 +1737,24 @@ minetest.register_node("basic_robot:spawner", {
|
||||
alpha = 150,
|
||||
after_place_node = function(pos, placer)
|
||||
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());
|
||||
if privs.privs then meta:set_int("admin",1) end
|
||||
if privs.puzzle then meta:set_int("puzzle",1) end
|
||||
local authlevel = 0;
|
||||
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_int("id",1); -- initial robot id
|
||||
@ -1827,9 +1858,9 @@ minetest.register_craftitem("basic_robot:control", {
|
||||
local owner = user:get_player_name();
|
||||
|
||||
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 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
|
||||
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!
|
||||
@ -1850,7 +1881,7 @@ minetest.register_craftitem("basic_robot:control", {
|
||||
if data and data.sandbox then
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
@ -1859,7 +1890,7 @@ minetest.register_craftitem("basic_robot:control", {
|
||||
if t1-t0<1 then return end
|
||||
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
|
||||
if not privs.privs then
|
||||
return
|
||||
@ -1872,7 +1903,7 @@ minetest.register_craftitem("basic_robot:control", {
|
||||
return
|
||||
end
|
||||
|
||||
if not data.isadmin then
|
||||
if data.authlevel<3 then
|
||||
if check_code(script)~=nil then return end
|
||||
end
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
-- SOKOBAN GAME, by rnd, robots port
|
||||
if not sokoban then
|
||||
sokoban = {};
|
||||
local players = find_player(4);
|
||||
local players = find_player(5);
|
||||
if not players then error("sokoban: no player near") end
|
||||
name = players[1];
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
if lvl == nil 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
|
||||
local str = ""; local s; local p = {x=pos.x,y=pos.y,z=pos.z}; local i,j;i=0;
|
||||
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