diff --git a/doc/client_api.txt b/doc/client_api.txt index 2b5bfdd..916d720 100644 --- a/doc/client_api.txt +++ b/doc/client_api.txt @@ -43,18 +43,31 @@ If an extension wish to provide an interface to sandboxed code, it should implement table "safe", which contains the safe interface. When sandboxed code requires the module, it only gets the plain safe interface. -Extensions and modules use require("buildat/extension/") to use extensions. +Extensions and modules use require("buildat/extension/") to get access to the interface of an extension. + +If an extension wants to purely use the safe interface of an extension, it is +recommended to do this: + = require("buildat/extension/").safe + +API specific to the extension environment: buildat.connect_server(address) - Address may include port in format "host:port" or "[host]:port" buildat.extension_path(name) + The sandbox environment ======================= All code sent by the server to the client is run in the sandbox environment. +Extensions are accessed by using require("buildat/extension/"); this is +the equivalent of using require("buildat/extension/").safe in the +extension environment. + +API specific to the sandbox environment: + sandbox.make_global(table) - Copies contents table into the current global sandbox environemnt. It will still not leak into the scope of other files running in the sandbox. Useful if @@ -161,6 +174,12 @@ replicate.main_scene Urho3D. With urho3d.REPLICATED (native default) they will end up in the synchronized ID space and will be overridden by data coming from the server. +ui_utils +-------- +UI utiltiies. + +show_message_dialog(message) + Unsafe interfaces of built-in extensions ======================================== diff --git a/doc/todo.txt b/doc/todo.txt index c4cd985..db203f9 100644 --- a/doc/todo.txt +++ b/doc/todo.txt @@ -32,5 +32,4 @@ Buildat TODO - Precompiled mode - Singleplayer UI - Modules with no C++ code (eg. just a client-side library) -- ui_utils.message_dialog -- Show exceptions and errors on client using dialog +- Show exceptions and errors on client using ui_utils.show_message_dialog diff --git a/extensions/__menu/init.lua b/extensions/__menu/init.lua index af4478d..6218bd3 100644 --- a/extensions/__menu/init.lua +++ b/extensions/__menu/init.lua @@ -2,61 +2,18 @@ -- http://www.apache.org/licenses/LICENSE-2.0 -- Copyright 2014 Perttu Ahola local log = buildat.Logger("extension/__menu") +local dump = buildat.dump local magic = require("buildat/extension/urho3d").safe local uistack = require("buildat/extension/uistack") -local dump = buildat.dump +local ui_utils = require("buildat/extension/ui_utils").safe local M = {safe = nil} -log:info("extension/__menu/init.lua: Loading") - -local ui_stack = uistack.main local function show_error(message) - local root = ui_stack:push({desc="show_error"}) - - local style = magic.cache:GetResource("XMLFile", "__menu/res/main_style.xml") - root.defaultStyle = style - - local window = root:CreateChild("Window") - window:SetStyleAuto() - window:SetName("show_error window") - window:SetLayout(LM_VERTICAL, 10, magic.IntRect(10, 10, 10, 10)) - window:SetAlignment(HA_LEFT, VA_CENTER) - - local message_text = window:CreateChild("Text") - message_text:SetName("message_text") - message_text:SetStyleAuto() - message_text.text = message - message_text:SetTextAlignment(HA_CENTER) - - local ok_button = window:CreateChild("Button") - ok_button:SetStyleAuto() - ok_button:SetName("Button") - ok_button:SetLayout(LM_VERTICAL, 10, magic.IntRect(0, 0, 0, 0)) - ok_button.minHeight = 20 - local ok_button_text = ok_button:CreateChild("Text") - ok_button_text:SetName("ButtonText") - ok_button_text:SetStyleAuto() - ok_button_text.text = "Ok" - ok_button_text:SetTextAlignment(HA_CENTER) - ok_button:SetFocus(true) - - magic.SubscribeToEvent(ok_button, "Released", - function(self, event_type, event_data) - log:info("ok_button: Released") - ui_stack:pop(root) - end) - - root:SubscribeToStackEvent("KeyDown", function(event_type, event_data) - local key = event_data:GetInt("Key") - if key == KEY_ESC then - log:info("KEY_ESC pressed at show_error level") - ui_stack:pop(root) - end - end) + ui_utils.show_message_dialog(message) end local function show_connect_to_server() - local root = ui_stack:push({desc="connect_to_server"}) + local root = uistack.main:push({desc="connect_to_server"}) local style = magic.cache:GetResource("XMLFile", "__menu/res/main_style.xml") root.defaultStyle = style @@ -90,7 +47,7 @@ local function show_connect_to_server() local ok, err = buildat.connect_server(line_edit:GetText()) if ok then log:info("buildat.connect_server() returned true") - local root = ui_stack:push({desc="empty (game is running)"}) + local root = uistack.main:push({desc="empty (game is running)"}) magic.ui:SetFocusElement(nil) else log:info("buildat.connect_server() returned false") @@ -114,13 +71,13 @@ local function show_connect_to_server() local key = event_data:GetInt("Key") if key == KEY_ESC then log:info("KEY_ESC pressed at connect_to_server level") - ui_stack:pop(root) + uistack.main:pop(root) end end) end function M.boot() - local root = ui_stack:push("boot") + local root = uistack.main:push("boot") local style = magic.cache:GetResource("XMLFile", "__menu/res/boot_style.xml") root.defaultStyle = style diff --git a/extensions/__menu/res/main_style.xml b/extensions/__menu/res/main_style.xml index f56a440..c428a80 100644 --- a/extensions/__menu/res/main_style.xml +++ b/extensions/__menu/res/main_style.xml @@ -9,8 +9,6 @@ - - diff --git a/extensions/sandbox_test/try_exploit.lua b/extensions/sandbox_test/try_exploit.lua index 79b2f1c..b5c8797 100644 --- a/extensions/sandbox_test/try_exploit.lua +++ b/extensions/sandbox_test/try_exploit.lua @@ -2,9 +2,10 @@ -- http://www.apache.org/licenses/LICENSE-2.0 -- Copyright 2014 Perttu Ahola local log = buildat.Logger("try_exploit.lua") +local dump = buildat.dump local magic = require("buildat/extension/urho3d").safe local uistack = require("buildat/extension/uistack") -local dump = buildat.dump +local ui_utils = require("buildat/extension/ui_utils").safe local M = {} -- Have a list of things to search for @@ -295,7 +296,7 @@ function M.run() end message = message.." Checked "..num_checked_values.." values." log:info("Result: "..message) - M.show_result_dialog(message) + ui_utils.show_message_dialog(message) end function M.search_single_value(value) @@ -332,73 +333,10 @@ function M.search_single_value(value) " Checked "..num_checked_values.." values." log:warning("Result: "..message) - M.show_result_dialog(message) + ui_utils.show_message_dialog(message) error("Value is exploitable") end -local result_dialog_handle = nil - -function M.show_result_dialog(message) - -- Don't stack multiple dialogs - if result_dialog_handle then - result_dialog_handle.append(message) - return - end - - local root = uistack.main:push({desc="show_result_dialog"}) - - local style = magic.cache:GetResource("XMLFile", "__menu/res/main_style.xml") - root.defaultStyle = style - - local window = root:CreateChild("Window") - window:SetStyleAuto() - window:SetName("show_result_dialog window") - window:SetLayout(LM_VERTICAL, 10, magic.IntRect(10, 10, 10, 10)) - window:SetAlignment(HA_LEFT, VA_CENTER) - - local message_text = window:CreateChild("Text") - message_text:SetName("message_text") - message_text:SetStyleAuto() - message_text.text = message - message_text:SetTextAlignment(HA_LEFT) - - local ok_button = window:CreateChild("Button") - ok_button:SetStyleAuto() - ok_button:SetName("Button") - ok_button:SetLayout(LM_VERTICAL, 10, magic.IntRect(0, 0, 0, 0)) - ok_button.minHeight = 20 - local ok_button_text = ok_button:CreateChild("Text") - ok_button_text:SetName("ButtonText") - ok_button_text:SetStyleAuto() - ok_button_text.text = "Ok" - ok_button_text:SetTextAlignment(HA_CENTER) - ok_button:SetFocus(true) - - result_dialog_handle = { - append = function(text) - if #message_text.text < 1000 then - message_text.text = message_text.text.."\n"..text - end - end, - } - - magic.SubscribeToEvent(ok_button, "Released", - function(self, event_type, event_data) - log:info("ok_button: Released") - uistack.main:pop(root) - result_dialog_handle = nil - end) - - root:SubscribeToStackEvent("KeyDown", function(event_type, event_data) - local key = event_data:GetInt("Key") - if key == KEY_ESC then - log:info("KEY_ESC pressed at show_result_dialog level") - uistack.main:pop(root) - result_dialog_handle = nil - end - end) -end - return M -- vim: set noet ts=4 sw=4: diff --git a/extensions/ui_utils/init.lua b/extensions/ui_utils/init.lua new file mode 100644 index 0000000..03a4f0f --- /dev/null +++ b/extensions/ui_utils/init.lua @@ -0,0 +1,77 @@ +-- http://www.apache.org/licenses/LICENSE-2.0 +-- Copyright 2014 Perttu Ahola +local log = buildat.Logger("ui_utils") +local magic = require("buildat/extension/urho3d").safe +local uistack = require("buildat/extension/uistack") +local M = {safe = {}} + +-- API naming: +-- show_*_notification() +-- show_*_dialog() +-- show_*_window() (?) + +local message_handle = nil + +function M.safe.show_message_dialog(message) + -- Don't stack multiple dialogs + if message_handle then + message_handle.append(message) + return + end + + local root = uistack.main:push({desc="show_message_dialog"}) + + local style = magic.cache:GetResource("XMLFile", "__menu/res/main_style.xml") + root.defaultStyle = style + + local window = root:CreateChild("Window") + window:SetStyleAuto() + window:SetName("show_message_dialog window") + window:SetLayout(LM_VERTICAL, 10, magic.IntRect(10, 10, 10, 10)) + window:SetAlignment(HA_LEFT, VA_CENTER) + + local message_text = window:CreateChild("Text") + message_text:SetName("message_text") + message_text:SetStyleAuto() + message_text.text = message + message_text:SetTextAlignment(HA_LEFT) + + local ok_button = window:CreateChild("Button") + ok_button:SetStyleAuto() + ok_button:SetName("Button") + ok_button:SetLayout(LM_VERTICAL, 10, magic.IntRect(0, 0, 0, 0)) + ok_button.minHeight = 20 + local ok_button_text = ok_button:CreateChild("Text") + ok_button_text:SetName("ButtonText") + ok_button_text:SetStyleAuto() + ok_button_text.text = "Ok" + ok_button_text:SetTextAlignment(HA_CENTER) + ok_button:SetFocus(true) + + message_handle = { + append = function(text) + if #message_text.text < 1000 then + message_text.text = message_text.text.."\n"..text + end + end, + } + + magic.SubscribeToEvent(ok_button, "Released", + function(self, event_type, event_data) + log:info("show_message_dialog: ok_button clicked") + uistack.main:pop(root) + message_handle = nil + end) + + root:SubscribeToStackEvent("KeyDown", function(event_type, event_data) + local key = event_data:GetInt("Key") + if key == KEY_ESC then + log:info("show_message_dialog: KEY_ESC pressed") + uistack.main:pop(root) + message_handle = nil + end + end) +end + +return M +-- vim: set noet ts=4 sw=4: