From 0965047f89571b40bc8e11552afb7dc344bf6eb0 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sat, 27 Sep 2014 09:54:53 +0300 Subject: [PATCH] client: buildat.disconnect() --- client/api.lua | 2 ++ client/init.lua | 8 +++++- client/packet.lua | 5 ++++ client/sandbox.lua | 16 +++-------- doc/client_api.txt | 4 +++ extensions/urho3d/safe_classes.lua | 8 ++++++ extensions/urho3d/safe_events.lua | 3 ++ src/client/app.cpp | 33 +++++++++++++++++++++- src/client/app.h | 1 + src/client/main.cpp | 29 +++++++++++-------- test/testmodules/test1/client_lua/init.lua | 13 +++++++-- 11 files changed, 95 insertions(+), 27 deletions(-) diff --git a/client/api.lua b/client/api.lua index 988e62c..7740205 100644 --- a/client/api.lua +++ b/client/api.lua @@ -6,4 +6,6 @@ local log = buildat.Logger("__client/api") buildat.connect_server = __buildat_connect_server buildat.extension_path = __buildat_extension_path +buildat.safe.disconnect = __buildat_disconnect + -- vim: set noet ts=4 sw=4: diff --git a/client/init.lua b/client/init.lua index 8a414ea..0b701e0 100644 --- a/client/init.lua +++ b/client/init.lua @@ -1,7 +1,8 @@ -- Buildat: client/init.lua -- http://www.apache.org/licenses/LICENSE-2.0 -- Copyright 2014 Perttu Ahola -buildat = {} +buildat = {safe = {}} + function buildat.bytes(data) local result = {} for i=1,#data do @@ -9,6 +10,8 @@ function buildat.bytes(data) end return result end +buildat.safe.bytes = buildat.bytes + function buildat.dump(thing) if type(thing) == 'string' then return '"'..thing..'"' @@ -35,6 +38,8 @@ function buildat.dump(thing) end return type(thing) end +buildat.safe.dump = buildat.dump + function buildat.Logger(module) local logger = {} function fix_text(text) @@ -65,6 +70,7 @@ function buildat.Logger(module) end return logger end +buildat.safe.Logger = buildat.Logger local log = buildat.Logger("__client/init") diff --git a/client/packet.lua b/client/packet.lua index 063b098..a257352 100644 --- a/client/packet.lua +++ b/client/packet.lua @@ -15,6 +15,8 @@ end function buildat.sub_packet(name, cb) packet_subs[name] = cb end +buildat.safe.sub_packet = buildat.sub_packet + function buildat.unsub_packet(cb) for name, cb1 in pairs(buildat.packet_subs) do if cb1 == cb then @@ -22,8 +24,11 @@ function buildat.unsub_packet(cb) end end end +buildat.safe.unsub_packet = buildat.unsub_packet function buildat.send_packet(name, data) __buildat_send_packet(name, data) end +buildat.safe.send_packet = buildat.send_packet + -- vim: set noet ts=4 sw=4: diff --git a/client/sandbox.lua b/client/sandbox.lua index ea08620..2874f6c 100644 --- a/client/sandbox.lua +++ b/client/sandbox.lua @@ -150,23 +150,15 @@ function buildat.run_script_file(name) log:info("buildat.run_script_file("..name.."): code length: "..#code) return __buildat_run_code_in_sandbox(code) end +buildat.safe.run_script_file = buildat.run_script_file -- --- buildat namespace whitelist +-- Insert buildat.safe into sandbox as buildat -- --- Whitelist the buildat namespace into the sandbox -local buildat_safe_list = { - "bytes", - "dump", - "Logger", - "run_script_file", - "sub_packet", - "send_packet", -} __buildat_sandbox_environment.buildat = {} -for _, name in ipairs(buildat_safe_list) do - __buildat_sandbox_environment.buildat[name] = buildat[name] +for k, v in pairs(buildat.safe) do + __buildat_sandbox_environment.buildat[k] = v end log:info("sandbox.lua loaded") diff --git a/doc/client_api.txt b/doc/client_api.txt index 28b53f2..ca6b8ac 100644 --- a/doc/client_api.txt +++ b/doc/client_api.txt @@ -60,6 +60,10 @@ buildat.make_global(table) still not leak into the scope of other files running in the sandbox. Useful if you want to remove the "namespace table" of an extension. +buildat.disconnect() +- If connected from menu, quit to menu (client state is reset by restarting it) +- If connected from command line, close the client + Safe interfaces of built-in extensions ====================================== diff --git a/extensions/urho3d/safe_classes.lua b/extensions/urho3d/safe_classes.lua index 9834a7a..15f85d6 100644 --- a/extensions/urho3d/safe_classes.lua +++ b/extensions/urho3d/safe_classes.lua @@ -14,6 +14,14 @@ function M.define(dst, util) "SetFloat", {}, {"VariantMap", "string", "number"}), GetFloat = util.self_function( "GetFloat", {"number"}, {"VariantMap", "string"}), + SetInt = util.self_function( + "SetInt", {}, {"VariantMap", "string", "number"}), + GetInt = util.self_function( + "GetInt", {"number"}, {"VariantMap", "string"}), + SetString = util.self_function( + "SetString", {}, {"VariantMap", "string", "string"}), + GetString = util.self_function( + "GetString", {"string"}, {"VariantMap", "string"}), } }) diff --git a/extensions/urho3d/safe_events.lua b/extensions/urho3d/safe_events.lua index cf41ba2..75275f8 100644 --- a/extensions/urho3d/safe_events.lua +++ b/extensions/urho3d/safe_events.lua @@ -6,5 +6,8 @@ return { Update = { TimeStep = {variant = "Float", safe = "number"}, }, + KeyDown = { + Key = {variant = "Int", safe = "number"}, + }, } -- vim: set noet ts=4 sw=4: diff --git a/src/client/app.cpp b/src/client/app.cpp index e2e3364..ce1be43 100644 --- a/src/client/app.cpp +++ b/src/client/app.cpp @@ -25,7 +25,7 @@ extern "C" { #include #include #include -#define MODULE "__main" +#define MODULE "__app" namespace magic = Urho3D; extern client::Config g_client_config; @@ -39,6 +39,7 @@ struct CApp: public App, public magic::Application magic::LuaScript *m_script; lua_State *L; int64_t m_last_script_tick_us; + bool m_reboot_requested = false; CApp(magic::Context *context): magic::Application(context), @@ -46,6 +47,8 @@ struct CApp: public App, public magic::Application L(nullptr), m_last_script_tick_us(get_timeofday_us()) { + log_v(MODULE, "constructor()"); + sv_ resource_paths = { g_client_config.cache_path+"/tmp", g_client_config.share_path+"/extensions", // Could be unsafe @@ -95,10 +98,16 @@ struct CApp: public App, public magic::Application void shutdown() { + log_v(MODULE, "shutdown()"); magic::Engine *engine = GetSubsystem(); engine->Exit(); } + bool reboot_requested() + { + return m_reboot_requested; + } + void run_script(const ss_ &script) { log_v(MODULE, "run_script():\n%s", cs(script)); @@ -155,6 +164,8 @@ struct CApp: public App, public magic::Application void Start() { + log_v(MODULE, "Start()"); + // Set graphics mode magic::Graphics *magic_graphics = GetSubsystem(); int w = 1024; @@ -195,6 +206,7 @@ struct CApp: public App, public magic::Application DEF_BUILDAT_FUNC(cereal_binary_output) DEF_BUILDAT_FUNC(connect_server) DEF_BUILDAT_FUNC(fatal_error) + DEF_BUILDAT_FUNC(disconnect) ss_ init_lua_path = g_client_config.share_path+"/client/init.lua"; int error = luaL_dofile(L, init_lua_path.c_str()); @@ -834,6 +846,25 @@ struct CApp: public App, public magic::Application throw Exception("Fatal error from Lua"); return 0; } + + // disconnect() + static int l_disconnect(lua_State *L) + { + lua_getfield(L, LUA_REGISTRYINDEX, "__buildat_app"); + CApp *self = (CApp*)lua_touserdata(L, -1); + lua_pop(L, 1); + + if(g_client_config.boot_to_menu){ + // If menu, reboot client into menu + self->m_reboot_requested = true; + self->shutdown(); + } else { + // If no menu, shutdown client + self->shutdown(); + } + + return 0; + } }; App* createApp(magic::Context *context) diff --git a/src/client/app.h b/src/client/app.h index 62ed3db..abcd904 100644 --- a/src/client/app.h +++ b/src/client/app.h @@ -23,6 +23,7 @@ namespace app virtual void set_state(sp_ state) = 0; virtual int run() = 0; virtual void shutdown() = 0; + virtual bool reboot_requested() = 0; virtual void run_script(const ss_ &script) = 0; virtual bool run_script_no_sandbox(const ss_ &script) = 0; virtual void handle_packet(const ss_ &name, const ss_ &data) = 0; diff --git a/src/client/main.cpp b/src/client/main.cpp index 260b8f1..a9ebb2f 100644 --- a/src/client/main.cpp +++ b/src/client/main.cpp @@ -99,18 +99,25 @@ int main(int argc, char *argv[]) return 1; } - magic::Context context; - sp_ app0(app::createApp(&context)); - sp_ state(client::createState(app0)); - app0->set_state(state); + int exit_status = 0; + while(exit_status == 0){ + magic::Context context; + sp_ app0(app::createApp(&context)); + sp_ state(client::createState(app0)); + app0->set_state(state); - if(config.server_address != ""){ - if(!state->connect(config.server_address, "20000")) - return 1; - } else { - config.boot_to_menu = true; + if(config.server_address != ""){ + if(!state->connect(config.server_address, "20000")) + return 1; + } else { + config.boot_to_menu = true; + } + + exit_status = app0->run(); + + if(!app0->reboot_requested()) + break; } - - return app0->run(); + return exit_status; } // vim: set noet ts=4 sw=4: diff --git a/test/testmodules/test1/client_lua/init.lua b/test/testmodules/test1/client_lua/init.lua index d03b793..531d4e6 100644 --- a/test/testmodules/test1/client_lua/init.lua +++ b/test/testmodules/test1/client_lua/init.lua @@ -180,12 +180,21 @@ function move_box_by_user_input(dt) end end -function handle_update(eventType, eventData) +function handle_update(event_type, event_data) --log:info("handle_update() in test1/init.lua") - local dt = eventData:GetFloat("TimeStep") + local dt = event_data:GetFloat("TimeStep") --node:Rotate(Quaternion(50, 80*dt, 0, 0)) move_box_by_user_input(dt) end magic.SubscribeToEvent("Update", "handle_update") +function handle_keydown(event_type, event_data) + local key = event_data:GetInt("Key") + if key == magic.KEY_ESC then + log:info("KEY_ESC pressed") + buildat.disconnect() + end +end +magic.SubscribeToEvent("KeyDown", "handle_keydown") + -- vim: set noet ts=4 sw=4: