diff --git a/client/src/game_state.cpp b/client/src/game_state.cpp index 52e8b73..0d51a83 100644 --- a/client/src/game_state.cpp +++ b/client/src/game_state.cpp @@ -358,6 +358,12 @@ void GameState::send_file_read_request(uint32_t session_id, const std::string& p {std::to_string(session_id), path})); } +void GameState::send_build_file_request(uint32_t session_id, const std::string& path, + const std::string& content) { + _network->send(net_protocol::build_message(net_protocol::Opcode::C2S_BUILD_FILE, + {std::to_string(session_id), path, content})); +} + void GameState::send_create_session_request(void) { if(_network && _network->is_connected()) { _network->send(net_protocol::build_message(net_protocol::Opcode::C2S_CREATE_SESSION)); diff --git a/client/src/game_state.h b/client/src/game_state.h index 185922c..0bb4ce1 100644 --- a/client/src/game_state.h +++ b/client/src/game_state.h @@ -35,6 +35,7 @@ public: /* Public network interface for UI components. */ void send_network_command(uint32_t session_id, const std::string& command); void send_file_write_request(uint32_t session_id, const std::string& path, const std::string& content); + void send_build_file_request(uint32_t session_id, const std::string& path, const std::string& content); void send_file_read_request(uint32_t session_id, const std::string& path); void send_create_session_request(void); diff --git a/client/src/ui/desktop.cpp b/client/src/ui/desktop.cpp index 19cd4a2..aa2a21c 100644 --- a/client/src/ui/desktop.cpp +++ b/client/src/ui/desktop.cpp @@ -200,6 +200,12 @@ void Desktop::update(float dt, int screen_width, int screen_height) { } break; } + case ActionType::BUILD_FILE: { + if(session_id != 0) { + _game_state->send_build_file_request(session_id, action.payload1, action.payload2); + } + break; + } default: break; } diff --git a/client/src/ui/editor.cpp b/client/src/ui/editor.cpp index 45e5b8a..c9bf4dd 100644 --- a/client/src/ui/editor.cpp +++ b/client/src/ui/editor.cpp @@ -14,6 +14,10 @@ Editor::Editor(void) _menu_bar->add_menu_item("File", "Save", [this]() { _pending_action = {ActionType::WRITE_FILE, _filename, _buffer.get_text()}; }); + _menu_bar->add_menu("Build"); + _menu_bar->add_menu_item("Build", "Run Build", [this]() { + _pending_action = {ActionType::BUILD_FILE, _filename, _buffer.get_text()}; + }); } Editor::Editor(const std::string& filename) @@ -25,6 +29,10 @@ Editor::Editor(const std::string& filename) _menu_bar->add_menu_item("File", "Save", [this]() { _pending_action = {ActionType::WRITE_FILE, _filename, _buffer.get_text()}; }); + _menu_bar->add_menu("Build"); + _menu_bar->add_menu_item("Build", "Run Build", [this]() { + _pending_action = {ActionType::BUILD_FILE, _filename, _buffer.get_text()}; + }); } Editor::~Editor(void) {} diff --git a/client/src/ui/window_action.h b/client/src/ui/window_action.h index 6ef47f8..64b7034 100644 --- a/client/src/ui/window_action.h +++ b/client/src/ui/window_action.h @@ -6,6 +6,7 @@ enum class ActionType { NONE, WRITE_FILE, READ_FILE, + BUILD_FILE, CLOSE_WINDOW }; diff --git a/common/src/lua_processor.cpp b/common/src/lua_processor.cpp index a6c307f..590ec16 100644 --- a/common/src/lua_processor.cpp +++ b/common/src/lua_processor.cpp @@ -9,7 +9,7 @@ #include "vfs.h" LuaProcessor::LuaProcessor(Session& context) { - _lua.open_libraries(sol::lib::base, sol::lib::string, sol::lib::io, sol::lib::table); + _lua.open_libraries(sol::lib::base, sol::lib::string, sol::lib::table); /* Expose vfs_node struct members to Lua. */ _lua.new_usertype("vfs_node", diff --git a/common/src/net/message_protocol.h b/common/src/net/message_protocol.h index e747be1..dc492fc 100644 --- a/common/src/net/message_protocol.h +++ b/common/src/net/message_protocol.h @@ -20,6 +20,7 @@ enum class Opcode : uint8_t { C2S_COMMAND, /* args: [session_id, command] */ C2S_WRITE_FILE, /* args: [session_id, path, content] */ C2S_READ_FILE, /* args: [session_id, path] */ + C2S_BUILD_FILE, /* args: [session_id, path, content] */ /* Server -> Client messages. */ S2C_CREATE_ACCOUNT_SUCCESS, diff --git a/server/src/network_manager.cpp b/server/src/network_manager.cpp index acf06b5..ad5bc53 100644 --- a/server/src/network_manager.cpp +++ b/server/src/network_manager.cpp @@ -5,6 +5,7 @@ #include #include "network_manager.h" +#include "lua_api.h" #include "net/message_protocol.h" #include "db/database_manager.h" @@ -210,6 +211,28 @@ void NetworkManager::on_message(std::shared_ptr connection, } } break; + case net_protocol::Opcode::C2S_BUILD_FILE: + if(args.size() == 3) { + uint32_t session_id = std::stoul(args[0]); + if(player->sessions.count(session_id)) { + Session* session = player->sessions.at(session_id).get(); + const std::string& path = args[1]; + const std::string& content = args[2]; + + /* Save the file to ensure the VFS is up to date. */ + session->write_file(path, content); + + /* The 'build.lua' script is just a wrapper around 'api::create_executable'. */ + std::string exec_path = path; + size_t dot_pos = exec_path.rfind(".lua"); + if(dot_pos != std::string::npos) { + exec_path.erase(dot_pos); + } + /* The api function returns an error string, but we'll ignore it here for now. */ + api::create_executable(*session, exec_path, content); + } + } + break; default: fprintf(stderr, "Received invalid opcode %d from active player.\n", static_cast(opcode));