diff --git a/common/src/command_processor.cpp b/common/src/command_processor.cpp index 45dd038..2bde667 100644 --- a/common/src/command_processor.cpp +++ b/common/src/command_processor.cpp @@ -83,55 +83,57 @@ vfs_node* find_node_by_path(vfs_node* root, const std::string& path) { return current; } -/* Recursively set all nodes in a VFS tree to writeable. */ -void make_vfs_writable(vfs_node* node) { - if(!node) return; - node->read_only = false; - for(auto const& [key, child] : node->children) { - make_vfs_writable(child); - } -} - std::string CommandProcessor::_handle_vfs_action(sol::table action) { std::string action_name = action["action"].get_or(""); /* Make the CoW check universal for any write operation. */ if(action_name == "rm" || action_name == "write_file") { - if(_current_dir->read_only) { - std::string remote_ip = ""; - /* Check if we are on a known remote system. */ - if(!_session_machine->is_vfs_a_copy) { + if(!_session_machine->is_vfs_a_copy) { + /* VFS is shared, a copy is required. */ + if(_session_machine == _home_machine) { + /* We are modifying our own home machine. */ + fprintf(stderr, "CoW: Write attempt on player's home machine" + "Creating persistant copy.\n"); + std::string original_path = get_full_path(_current_dir); + + vfs_node* new_vfs_root = copy_vfs_node(_home_machine->vfs_root, nullptr); + auto* new_machine = new Machine(_home_machine->id, _home_machine->hostname); + new_machine->vfs_root = new_vfs_root; + new_machine->services = _home_machine->services; + new_machine->is_vfs_a_copy = true; /* Mark as copy. */ + + _home_machine = new_machine; + _session_machine = new_machine; + _current_dir = find_node_by_path(_session_machine->vfs_root, original_path); + if(!_current_dir) { _current_dir = _session_machine->vfs_root; } + } else { + std::string remote_ip = ""; + /* Check if we are on a known remote system. */ for(auto const& [ip, machine] : _world_machines) { if(machine == _session_machine) { remote_ip = ip; break; } } - } + if(!remote_ip.empty()) { + fprintf(stderr, "CoW: Write attempt on remote machine '%s'. " + "Creating persistant copy.\n", + remote_ip.c_str()); + std::string original_path = get_full_path(_current_dir); - if(!remote_ip.empty()) { - /* This machine is using a shared VFS. Copy it! ;) */ - fprintf(stderr, "CoW: Write attempt on read-only remote system '%s'." - "Creating persistant copy.\n", remote_ip.c_str()); - std::string original_path = get_full_path(_current_dir); - /* Copy the sh.t out of the VFS. */ - vfs_node* new_vfs_root = copy_vfs_node(_session_machine->vfs_root, nullptr); - make_vfs_writable(new_vfs_root); + vfs_node* new_vfs_root = copy_vfs_node(_session_machine->vfs_root, nullptr); + auto* new_machine = new Machine(_session_machine->id, _session_machine->hostname); + new_machine->vfs_root = new_vfs_root; + new_machine->services = _session_machine->services; + new_machine->is_vfs_a_copy = true; /* Mark as copy. */ - /* Create the new machine that will hold the copied VFS. */ - auto* new_machine = new Machine(_session_machine->id, _session_machine->hostname); - new_machine->vfs_root = new_vfs_root; - new_machine->services = _session_machine->services; - new_machine->is_vfs_a_copy = true; /* Mark as copy. */ + _world_machines[remote_ip] = new_machine; + _session_machine = new_machine; - /* Update the world map and the current session. */ - _world_machines[remote_ip] = new_machine; - _session_machine = new_machine; - - /* Update _current_dir to point to the equivalent dir in the new VFS. */ - _current_dir = find_node_by_path(_session_machine->vfs_root, original_path); - if(!_current_dir) { _current_dir = _session_machine->vfs_root; } - } else { - return "Permission denied: Filesystem is read-only and not part of the world."; + _current_dir = find_node_by_path(_session_machine->vfs_root, original_path); + if(!_current_dir) { _current_dir = _session_machine->vfs_root; } + } else { + return "Permission denied: Filesystem is read-only and not part of the world."; + } } } } @@ -148,6 +150,7 @@ std::string CommandProcessor::_handle_vfs_action(sol::table action) { } _current_dir->children.erase(path); delete target_node; + return ""; /* Success. */ } else if(action_name == "write_file") { std::string filename = action["target"].get_or(""); std::string content = action["content"].get_or(""); @@ -163,7 +166,7 @@ std::string CommandProcessor::_handle_vfs_action(sol::table action) { target_node->content = content; } else { vfs_node* new_file = new vfs_node { - .name = filename, .type = FILE_NODE, .read_only = false, .content = content, + .name = filename, .type = FILE_NODE, .content = content, .parent = _current_dir }; _current_dir->children[filename] = new_file; diff --git a/common/src/lua_processor.cpp b/common/src/lua_processor.cpp index 4fbff64..da056d5 100644 --- a/common/src/lua_processor.cpp +++ b/common/src/lua_processor.cpp @@ -12,7 +12,6 @@ LuaProcessor::LuaProcessor(void) { "name", &vfs_node::name, "type", &vfs_node::type, "children", &vfs_node::children, - "read_only", &vfs_node::read_only, "content", &vfs_node::content); } LuaProcessor::~LuaProcessor(void) {} diff --git a/common/src/machine_manager.cpp b/common/src/machine_manager.cpp index 6b3e47d..0dd883d 100644 --- a/common/src/machine_manager.cpp +++ b/common/src/machine_manager.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include "machine_manager.h" #include "machine.h" @@ -13,7 +12,6 @@ vfs_node* new_node(std::string name, vfs_node_type type, vfs_node* parent) { node->name = name; node->type = type; node->parent = parent; - node->read_only = false; /* Writable by default. */ return node; } @@ -24,7 +22,6 @@ vfs_node* copy_vfs_node(vfs_node* original, vfs_node* new_parent) { /* Create the new node and copy its properties. */ vfs_node* new_copy = new_node(original->name, original->type, new_parent); - new_copy->read_only = original->read_only; /* Preserver read-only status. */ new_copy->content = original->content; /* Recursively copy all children. */ @@ -41,9 +38,6 @@ MachineManager::MachineManager(void) { vfs_node* bin = new_node("bin", DIR_NODE, _vfs_template_root); _vfs_template_root->children["bin"] = bin; - _vfs_template_root->read_only = true; - bin->read_only = true; - /* Load all scripts from assets/scripts/bin into the VFS. */ const std::string path = "assets/scripts/bin"; for(const auto & entry : std::filesystem::directory_iterator(path)) { @@ -62,7 +56,6 @@ MachineManager::MachineManager(void) { MachineManager::~MachineManager(void) { /* TODO: Implement recursive deletion of all created VFS nodes.*/ - //delete _vfs_root; } Machine* MachineManager::create_machine(uint32_t id, const std::string& hostname, diff --git a/common/src/vfs.h b/common/src/vfs.h index 4e3d704..1f02dc1 100644 --- a/common/src/vfs.h +++ b/common/src/vfs.h @@ -16,7 +16,6 @@ enum vfs_node_type { struct vfs_node { std::string name; vfs_node_type type; - bool read_only; /* Files. */ std::string content;