From 7d220926579f742d88bffe67160a01775195277f Mon Sep 17 00:00:00 2001 From: Joachim Stolberg Date: Tue, 26 Jun 2018 23:04:25 +0200 Subject: [PATCH] Battery and Server added Further improvements --- safer_lua/environ.lua | 2 +- safer_lua/store.lua | 38 ++-- sl_controller/battery.lua | 116 ++++++++---- sl_controller/config.lua | 2 +- sl_controller/controller.lua | 29 +-- sl_controller/init.lua | 3 +- sl_controller/readme.md | 3 +- sl_controller/server.lua | 173 ++++++++++++++++++ .../textures/sl_controller_server_back.png | Bin 0 -> 351 bytes .../textures/sl_controller_server_front.png | Bin 0 -> 326 bytes .../textures/sl_controller_server_side.png | Bin 0 -> 279 bytes .../textures/sl_controller_server_top.png | Bin 0 -> 265 bytes 12 files changed, 298 insertions(+), 68 deletions(-) create mode 100644 sl_controller/server.lua create mode 100644 sl_controller/textures/sl_controller_server_back.png create mode 100644 sl_controller/textures/sl_controller_server_front.png create mode 100644 sl_controller/textures/sl_controller_server_side.png create mode 100644 sl_controller/textures/sl_controller_server_top.png diff --git a/safer_lua/environ.lua b/safer_lua/environ.lua index 29eb0f1..8ea752f 100644 --- a/safer_lua/environ.lua +++ b/safer_lua/environ.lua @@ -12,7 +12,7 @@ ]]-- -safer_lua.MaxCodeSize = 1000 -- size in length of byte code +safer_lua.MaxCodeSize = 2000 -- size in length of byte code safer_lua.MaxTableSize = 1000 -- number of table entries considering string lenghts diff --git a/safer_lua/store.lua b/safer_lua/store.lua index 4dcc068..96b6b18 100644 --- a/safer_lua/store.lua +++ b/safer_lua/store.lua @@ -35,6 +35,7 @@ safer_lua.StoreHelp = [[ tbl.set(key, value) --> add/set a value tbl.get(key) --> read a value tbl.size() --> return the table size + tbl.capa() --> return the max. capacity tbl.insert(pos, value) --> insert into list tbl.remove(pos) --> return and remove from list tbl.sort() -- sort list @@ -79,14 +80,27 @@ function safer_lua.Store(...) end new_t.set = function(k,v) - if type(k) == "string" or type(k) == "number" then - Count = Count - mt.count(rawget(new_t.__data__, k)) + if type(k) == "number" then local cnt = mt.count(v) - if cnt then + cnt = cnt - mt.count(rawget(new_t.__data__, k)) + if Count + cnt < safer_lua.MaxTableSize then + rawset(new_t.__data__,k,v) + Count = Count + cnt + end + elseif type(k) == "string" then + local cnt = mt.count(rawget(new_t.__data__, k)) + if cnt == 0 then -- new entry? + cnt = mt.count(v) + cnt = cnt + mt.count(k) + elseif v == nil then -- delete entry? + cnt = - cnt - mt.count(k) + else -- overwrite + cnt = mt.count(v) - cnt + end + + if Count + cnt < safer_lua.MaxTableSize then + rawset(new_t.__data__,k,v) Count = Count + cnt - if Count < safer_lua.MaxTableSize then - rawset(new_t.__data__,k,v) - end end end end @@ -99,14 +113,16 @@ function safer_lua.Store(...) return Count end + new_t.capa = function(t) + return safer_lua.MaxTableSize + end + new_t.insert = function(v, i) local cnt = mt.count(v) - if cnt then + if i == nil then i = #new_t.__data__ + 1 end + if Count + cnt < safer_lua.MaxTableSize then + table.insert(new_t.__data__,i,v) Count = Count + cnt - if i == nil then i = #new_t.__data__ + 1 end - if Count < safer_lua.MaxTableSize then - table.insert(new_t.__data__,i,v) - end end end diff --git a/sl_controller/battery.lua b/sl_controller/battery.lua index 9b93ceb..b2d85d5 100644 --- a/sl_controller/battery.lua +++ b/sl_controller/battery.lua @@ -12,10 +12,15 @@ ]]-- +local function calc_percent(content) + local val = (sl_controller.battery_capacity - + math.min(content or 0, sl_controller.battery_capacity)) + return 100 - math.floor((val * 100.0 / sl_controller.battery_capacity)) +end + local function on_timer(pos, elapsed) local meta = minetest.get_meta(pos) - local percent = (sl_controller.battery_capacity - meta:get_int("content")) - percent = 100 - math.floor((percent * 100.0 / sl_controller.battery_capacity)) + local percent = calc_percent(meta:get_int("content")) meta:set_string("infotext", "Battery ("..percent.."%)") if percent == 0 then local node = minetest.get_node(pos) @@ -26,45 +31,76 @@ local function on_timer(pos, elapsed) return true end -minetest.register_node("sl_controller:battery", { - description = "Battery", - inventory_image = 'sl_controller_battery_inventory.png', - wield_image = 'sl_controller_battery_inventory.png', - tiles = { - -- up, down, right, left, back, front - "smartline.png", - "smartline.png", - "smartline.png", - "smartline.png", - "smartline.png", - "smartline.png^sl_controller_battery_green.png", - }, - - drawtype = "nodebox", - node_box = { - type = "fixed", - fixed = { - { -6/32, -6/32, 14/32, 6/32, 6/32, 16/32}, +local function register_battery(ext, percent) + minetest.register_node("sl_controller:battery"..ext, { + description = "Battery", + inventory_image = 'sl_controller_battery_inventory.png', + wield_image = 'sl_controller_battery_inventory.png', + tiles = { + -- up, down, right, left, back, front + "smartline.png", + "smartline.png", + "smartline.png", + "smartline.png", + "smartline.png", + "smartline.png^sl_controller_battery_green.png", }, - }, - - after_place_node = function(pos, placer) - local meta = minetest.get_meta(pos) - meta:set_int("content", sl_controller.battery_capacity) - on_timer(pos, 1) - minetest.get_node_timer(pos):start(30) - end, - - on_timer = on_timer, - - paramtype = "light", - sunlight_propagates = true, - paramtype2 = "facedir", - groups = {choppy=1, cracky=1, crumbly=1}, - drop = "", - is_ground_content = false, - sounds = default.node_sound_stone_defaults(), -}) + + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + { -6/32, -6/32, 14/32, 6/32, 6/32, 16/32}, + }, + }, + + after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos) + meta:set_int("content", sl_controller.battery_capacity * percent) + local node = minetest.get_node(pos) + node.name = "sl_controller:battery" + minetest.swap_node(pos, node) + on_timer(pos, 1) + minetest.get_node_timer(pos):start(30) + end, + + on_timer = on_timer, + + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + local percent = calc_percent(tonumber(oldmetadata.fields.content)) + print("percent", percent) + local stack + if percent > 95 then + stack = ItemStack("sl_controller:battery") + elseif percent > 75 then + stack = ItemStack("sl_controller:battery75") + elseif percent > 50 then + stack = ItemStack("sl_controller:battery50") + elseif percent > 25 then + stack = ItemStack("sl_controller:battery25") + else + return + end + print("percent", percent) + local inv = minetest.get_inventory({type="player", name=digger:get_player_name()}) + inv:add_item("main", stack) + end, + + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "facedir", + groups = {choppy=1, cracky=1, crumbly=1}, + drop = "", + is_ground_content = false, + sounds = default.node_sound_stone_defaults(), + }) +end + +register_battery("", 1.0) +register_battery("75", 0.75) +register_battery("50", 0.5) +register_battery("25", 0.25) minetest.register_node("sl_controller:battery_empty", { description = "Battery", diff --git a/sl_controller/config.lua b/sl_controller/config.lua index cfdf0f6..407c516 100644 --- a/sl_controller/config.lua +++ b/sl_controller/config.lua @@ -1,2 +1,2 @@ -- Battery capacity in usec CPU time -sl_controller.battery_capacity = tonumber(minetest.setting_get("battery_capacity")) or 10000000 +sl_controller.battery_capacity = tonumber(minetest.setting_get("battery_capacity")) or 5000000 diff --git a/sl_controller/controller.lua b/sl_controller/controller.lua index 73b2bac..03b101b 100644 --- a/sl_controller/controller.lua +++ b/sl_controller/controller.lua @@ -14,16 +14,21 @@ local sHELP = [[SaferLua Controller -SaferLua is a subset of Lua with the following restrictions: - - No loop keywords like: for, while, repeat,... - - No table construction {..} - - Limited set of available functions - - Store() as alternative to Lua tables + SaferLua is a subset of Lua with the following restrictions: + - No loop keywords like: for, while, repeat,... + - No table construction {..} + - Limited set of available functions + - Store() as alternative to Lua tables -The controller needs a battery nearby. -Don't remove the battery, it will be destroyed! + The controller needs a battery nearby. + + The controller will be restarted with every + server start. That means, init() will be + called again and all variables are reset. + To store the data non-volatile, use a Server. + commands: $server_read(), $server_write(). -See: goo.gl/WRWZgt + See: goo.gl/WRWZgt ]] local Cache = {} @@ -189,7 +194,7 @@ local function compile(pos, meta, number) local loop = meta:get_string("loop") local owner = meta:get_string("owner") local env = table.copy(tCommands) - env.meta = {pos=pos, owner=owner, number=number} + env.meta = {pos=pos, owner=owner, number=number, error=error} local code = safer_lua.init(pos, init, loop, env, error) if code then @@ -282,12 +287,8 @@ local function on_timer(pos, elapsed) no_battery(pos) return false end - else - stop_controller(pos) end return res - else - stop_controller(pos) end return false end @@ -329,6 +330,8 @@ local function on_receive_fields(pos, formname, fields, player) meta:set_string("formspec", formspec5(sFunctionList, 1, sHELP)) elseif fields.start == "Start" then start_controller(pos) + minetest.log("action", player:get_player_name() .. + " starts the sl_controller at ".. minetest.pos_to_string(pos)) elseif fields.stop == "Stop" then stop_controller(pos) elseif fields.functions then diff --git a/sl_controller/init.lua b/sl_controller/init.lua index ccec043..10290c2 100644 --- a/sl_controller/init.lua +++ b/sl_controller/init.lua @@ -15,4 +15,5 @@ sl_controller = {} dofile(minetest.get_modpath("sl_controller") .. "/config.lua") dofile(minetest.get_modpath("sl_controller") .. "/controller.lua") dofile(minetest.get_modpath("sl_controller") .. "/commands.lua") -dofile(minetest.get_modpath("sl_controller") .. "/battery.lua") \ No newline at end of file +dofile(minetest.get_modpath("sl_controller") .. "/battery.lua") +dofile(minetest.get_modpath("sl_controller") .. "/server.lua") \ No newline at end of file diff --git a/sl_controller/readme.md b/sl_controller/readme.md index 2bb9b76..919e750 100644 --- a/sl_controller/readme.md +++ b/sl_controller/readme.md @@ -1,4 +1,4 @@ -SaferLua Controller [sl_controller] v0.01 +SaferLua Controller [sl_controller] v0.02 ========================================= @@ -17,3 +17,4 @@ tubelib, safer_lua ### History - 2018-06-24 v0.01 * first draft +- 2018-06-26 v0.02 * Battery and Server added diff --git a/sl_controller/server.lua b/sl_controller/server.lua new file mode 100644 index 0000000..be549ae --- /dev/null +++ b/sl_controller/server.lua @@ -0,0 +1,173 @@ +--[[ + + sl_controller + ============= + + Copyright (C) 2018 Joachim Stolberg + + LGPLv2.1+ + See LICENSE.txt for more information + + server.lua: + +]]-- + +local SERVER_CAPA = 5000 +local DEFAULT_MEM = { + size=0, + data={ + version = 1, + info = "SaferLua key/value Server", + } +} + + +local function on_time(pos, elasped) + local meta = minetest.get_meta(pos) + local number = meta:get_string("number") + local mem = tubelib.get_data(number, "memory") or DEFAULT_MEM + meta:set_string("infotext", "Server "..number..": ("..(mem.size or 0).."/"..SERVER_CAPA..")") + return true +end + +minetest.register_node("sl_controller:server", { + description = "Central Server", + tiles = { + -- up, down, right, left, back, front + "sl_controller_server_top.png", + "sl_controller_server_top.png", + "sl_controller_server_side.png", + "sl_controller_server_side.png^[transformFX", + "sl_controller_server_back.png", + { + image = "sl_controller_server_front.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 32, + aspect_h = 32, + length = 1, + }, + }, + }, + + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + { -3/16, -8/16, -7/16, 3/16, 6/16, 7/16}, + }, + }, + + after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos) + local number = tubelib.add_node(pos, "sl_controller:server") + meta:set_string("owner", placer:get_player_name()) + meta:set_string("number", number) + tubelib.set_data(number, "memory", DEFAULT_MEM) + on_time(pos, 0) + minetest.get_node_timer(pos):start(20) + end, + + on_dig = function(pos, node, puncher, pointed_thing) + if minetest.is_protected(pos, puncher:get_player_name()) then + return + end + + minetest.node_dig(pos, node, puncher, pointed_thing) + tubelib.remove_node(pos) + end, + + on_timer = on_time, + + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "facedir", + groups = {choppy=1, cracky=1, crumbly=1}, + drop = "", + is_ground_content = false, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_craft({ + output = "sl_controller:server", + recipe = { + {"", "", ""}, + {"default:mese_crystal_fragment", "tubelib:wlanchip", "default:mese_crystal_fragment"}, + {"", "default:copper_ingot", ""}, + }, +}) + +local function calc_size(v) + if type(v) == "number" then + return 1 + elseif v == nil then + return 0 + elseif type(v) == "string" then + return #v + else + return nil + end +end + +local function write_value(mem, key, value) + if mem and mem.size < SERVER_CAPA then + if value == nil then + mem.size = mem.size - calc_size(mem.data[key]) + else + mem.size = mem.size - calc_size(mem.data[key]) + mem.size = mem.size + calc_size(value) + end + mem.data[key] = value + end +end + +tubelib.register_node("sl_controller:server", {}, { + on_recv_message = function(pos, topic, payload) + local meta = minetest.get_meta(pos) + if meta then + local number = meta:get_string("number") + local mem = tubelib.get_data(number, "memory") or DEFAULT_MEM + if topic == "read" then + return mem.data[payload] + elseif topic == "write" then + write_value(mem, payload.key, payload.value) + tubelib.set_data(number, "memory", mem) + else + return "unsupported" + end + end + end, +}) + + +sl_controller.register_function("server_read", { + cmnd = function(self, num, key) + if type(key) == "string" then + return tubelib.send_request(num, "read", key) + else + self.error("Invalid server_read parameter") + end + end, + help = " $server_read(num, key)\n".. + " Read a value from the server.\n".. + " 'key' must be a string.\n".. + ' example: state = $server_read("0123", "state")' +}) + +sl_controller.register_action("server_write", { + cmnd = function(self, num, key, value) + if type(key) == "string" and type(value) == "string" or type(value) == "number" then + tubelib.send_message(num, self.meta.owner, nil, "write", {key=key, value=value}) + else + self.error("Invalid server_write parameter") + end + end, + help = " $server_write(num, key, value)\n".. + " Store a value on the server under the key 'key'.\n".. + " 'key' must be a string. 'value' can be\n".. + " either a number or a string.\n".. + ' example: $server_write("0123", "state", state)' +}) + + diff --git a/sl_controller/textures/sl_controller_server_back.png b/sl_controller/textures/sl_controller_server_back.png new file mode 100644 index 0000000000000000000000000000000000000000..f2500168d870b0404745b1edca048f628df7692d GIT binary patch literal 351 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzwj^(N7X}^%W(MZve|F9Vif|Tq zL>4nJa0`PlBg3pY5H=O_D5_|f@~(f+fINCkSuYHC~?lu%}vcKVQ?-=O)N=G zQ7F$W$xv|j^bH7a7!q+fIYEL|S=M0Ef^YV^XVMgp9=Y8=UudacXxOX_ zFdh=h)qgR(EOr}tQJs6vcxr_#5q4VH#M(>!MP|ku_QG` zp**uBL&4qCHz2%`PaLRdou`XqNXEUlGaR`b97NjUi&&=5xUKQXXoj%g=@D?7bo|;s(!_|tImOu zE1-c%WWj@IE~U2$p?BxJa}+!={f>R(>MfqD>(nPrUo5x4mdK II;Vst0Om?_-v9sr literal 0 HcmV?d00001 diff --git a/sl_controller/textures/sl_controller_server_side.png b/sl_controller/textures/sl_controller_server_side.png new file mode 100644 index 0000000000000000000000000000000000000000..ed7e4e48c0758f80994ec1ebdb6134cc2fe3f370 GIT binary patch literal 279 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzwj^(N7X}^%W(MZve|F9Vif|Tq zL>4nJa0`PlBg3pY5H=O_D5_|g6uMh5`lYxLXst}5hc#~xw)x%B@E6*sfi`2 zDGKG8B^e6tp1uL$jeO!jMfIL8jv*0;lM^IZm1PYMNo<$5|9k$xfdc`dQHKhCKl7ax zwQAM6a~rCT7P+wjfmq4OtJ>2po3hMcv*L1-HF(t!$lha>aD{O(pG4__70hhQnGZ2B zv0Y^&77rcaO%QgpaHL1Kjf1A~f9Ew|Z^ S*;zoRFnGH9xvX4nJa0`PlBg3pY5H=O_D5_|f*kxwc06ly)U-%*?j4(PqM_ zX51V3D!#rFJ>2^F`3gBEpBGHqIRRr3Y3pyU7~7 yY6xWSv4RRQT(ng-G&E#mc2-_=wT~%@k>RMdU|r{gwV^=E89ZJ6T-G@yGywoSEm9c( literal 0 HcmV?d00001