Battery and Server added

Further improvements
This commit is contained in:
Joachim Stolberg 2018-06-26 23:04:25 +02:00
parent 7babb6c89f
commit 7d22092657
12 changed files with 298 additions and 68 deletions

@ -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

@ -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
Count = Count + cnt
if Count < safer_lua.MaxTableSize 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
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
Count = Count + cnt
if i == nil then i = #new_t.__data__ + 1 end
if Count < safer_lua.MaxTableSize then
if Count + cnt < safer_lua.MaxTableSize then
table.insert(new_t.__data__,i,v)
end
Count = Count + cnt
end
end

@ -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,7 +31,8 @@ local function on_timer(pos, elapsed)
return true
end
minetest.register_node("sl_controller:battery", {
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',
@ -50,13 +56,37 @@ minetest.register_node("sl_controller:battery", {
after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos)
meta:set_int("content", sl_controller.battery_capacity)
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",
@ -65,6 +95,12 @@ minetest.register_node("sl_controller:battery", {
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",

@ -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

@ -21,7 +21,12 @@ SaferLua is a subset of Lua with the following restrictions:
- Store() as alternative to Lua tables
The controller needs a battery nearby.
Don't remove the battery, it will be destroyed!
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
]]
@ -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

@ -16,3 +16,4 @@ 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")
dofile(minetest.get_modpath("sl_controller") .. "/server.lua")

@ -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

173
sl_controller/server.lua Normal file

@ -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)'
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 B