diff --git a/design.txt b/design.txt index bc9fafd..281bb39 100644 --- a/design.txt +++ b/design.txt @@ -76,6 +76,20 @@ Example: stuff ?r extension:ecs2 +Extension structure +------------------- +extension +`-- init.lua << Loaded when the module is required + +Extension behavior +------------------ +Extensions use the new Lua 5.1/5.2 module interface. + +If an extension wish to provide an interface to sandboxed code, it should +implement function unsafe(), which returns the safe interface. + +Extensions and modules use require "buildat/extension/" to use extensions. + Network protocol ---------------- (Type, length, data) tuples on TCP. In the future TLS can be taken into use. A diff --git a/share/client/init.lua b/share/client/init.lua index a4c64a3..b9e8639 100644 --- a/share/client/init.lua +++ b/share/client/init.lua @@ -11,58 +11,11 @@ function buildat:Logger(module) return logger end -local log = buildat:Logger("__client") +local log = buildat:Logger("__client/init") log:info("init.lua loaded") -require "Polycode/Core" -scene = Scene(Scene.SCENE_2D) -scene:getActiveCamera():setOrthoSize(640, 480) -label = SceneLabel("Hello from Lua!", 32) -label:setPosition(-50, -50, 0) -scene:addChild(label) +dofile(__buildat_get_path("share").."/client/test.lua") +dofile(__buildat_get_path("share").."/client/packet.lua") +dofile(__buildat_get_path("share").."/client/sandbox.lua") -buildat.packet_subs = {} - -function buildat:sub_packet(name, cb) - buildat.packet_subs[name] = cb -end -function buildat:unsub_packet(cb) - for name, cb1 in pairs(buildat.packet_subs) do - if cb1 == cb then - buildat.packet_subs[cb] = nil - end - end -end - -function buildat:send_packet(name, data) - __buildat_send_packet(name, data) -end - -local sandbox_env = { - buildat = buildat, -} - -local function run_in_sandbox(untrusted_code) - if untrusted_code:byte(1) == 27 then return nil, "binary bytecode prohibited" end - local untrusted_function, message = loadstring(untrusted_code) - if not untrusted_function then return nil, message end - setfenv(untrusted_function, sandbox_env) - return pcall(untrusted_function) -end - -function buildat:run_script_file(name) - local code = __buildat_get_file_content(name) - if not code then - log:error("Failed to load script file: "+name) - return false - end - log:info("buildat:run_script_file("..name.."): #code="..#code) - local status, err = run_in_sandbox(code) - --local status, err = run_in_sandbox([[buildat:Logger("foo"):info("Pihvi")]]) - if status == false then - log:error("Failed to run script: "..err) - return false - end - return true -end diff --git a/share/client/packet.lua b/share/client/packet.lua new file mode 100644 index 0000000..91aa502 --- /dev/null +++ b/share/client/packet.lua @@ -0,0 +1,18 @@ +local log = buildat:Logger("__client/packet") + +__buildat_packet_subs = {} + +function buildat:sub_packet(name, cb) + __buildat_packet_subs[name] = cb +end +function buildat:unsub_packet(cb) + for name, cb1 in pairs(buildat.packet_subs) do + if cb1 == cb then + __buildat_packet_subs[cb] = nil + end + end +end + +function buildat:send_packet(name, data) + __buildat_send_packet(name, data) +end diff --git a/share/client/sandbox.lua b/share/client/sandbox.lua new file mode 100644 index 0000000..22f7c3c --- /dev/null +++ b/share/client/sandbox.lua @@ -0,0 +1,34 @@ +local log = buildat:Logger("__client/sandbox") + +local sandbox = {} + +sandbox.buildat = buildat + +sandbox.require = function(name) + error("require: \""..name.."\" not found in sandbox") +end + +local function run_in_sandbox(untrusted_code, sandbox) + if untrusted_code:byte(1) == 27 then return nil, "binary bytecode prohibited" end + local untrusted_function, message = loadstring(untrusted_code) + if not untrusted_function then return nil, message end + setfenv(untrusted_function, sandbox) + return pcall(untrusted_function) +end + +function buildat:run_script_file(name) + local code = __buildat_get_file_content(name) + if not code then + log:error("Failed to load script file: "+name) + return false + end + log:info("buildat:run_script_file("..name.."): #code="..#code) + local status, err = run_in_sandbox(code, sandbox) + --local status, err = run_in_sandbox( + -- [[buildat:Logger("foo"):info("Pihvi")]], sandbox) + if status == false then + log:error("Failed to run script: "..err) + return false + end + return true +end diff --git a/share/client/test.lua b/share/client/test.lua new file mode 100644 index 0000000..7a43771 --- /dev/null +++ b/share/client/test.lua @@ -0,0 +1,11 @@ +local log = buildat:Logger("__client/test") + +--[[ +require "Polycode/Core" +scene = Scene(Scene.SCENE_2D) +scene:getActiveCamera():setOrthoSize(640, 480) +label = SceneLabel("Hello from Lua!", 32) +label:setPosition(-50, -50, 0) +scene:addChild(label) +]] + diff --git a/src/client/app.cpp b/src/client/app.cpp index f79b202..6788218 100644 --- a/src/client/app.cpp +++ b/src/client/app.cpp @@ -278,6 +278,7 @@ struct CApp: public Polycode::EventHandler, public App } DEF_BUILDAT_FUNC(send_packet); DEF_BUILDAT_FUNC(get_file_content) + DEF_BUILDAT_FUNC(get_path) ss_ init_lua_path = g_client_config.share_path+"/client/init.lua"; int error = luaL_dofile(L, init_lua_path.c_str()); @@ -369,6 +370,22 @@ struct CApp: public Polycode::EventHandler, public App return 0; } } + + // get_path(name: string) + static int l_get_path(lua_State *L) + { + size_t name_len = 0; + const char *name_c = lua_tolstring(L, 1, &name_len); + ss_ name(name_c, name_len); + + if(name == "share"){ + ss_ path = g_client_config.share_path; + lua_pushlstring(L, path.c_str(), path.size()); + return 1; + } + log_w(MODULE, "Unknown named path: \"%s\"", cs(name)); + return 0; + } }; App* createApp(Polycode::PolycodeView *view)