[Add] Persistent VFS and database aware commands.
This commit is contained in:
		
							parent
							
								
									44ca427c0e
								
							
						
					
					
						commit
						97b60488de
					
				@ -1,14 +1,5 @@
 | 
				
			|||||||
-- /bin/ls - Lists files in a directory.
 | 
					-- /bin/ls - Lists files in a directory.
 | 
				
			||||||
local dir = bettola.get_current_dir(context)
 | 
					--
 | 
				
			||||||
local output = ""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
-- Iterate over the 'children' map exposed via C++.
 | 
					-- Iterate over the 'children' map exposed via C++.
 | 
				
			||||||
for name, node in pairs(dir.children) do
 | 
					 | 
				
			||||||
  output = output .. name
 | 
					 | 
				
			||||||
  if node.type == 1 then -- 1 is DIR_NODE enum from C++.
 | 
					 | 
				
			||||||
    output = output .. "/"
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
  output = output .. " "
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
return output
 | 
					return bettola.ls(context)
 | 
				
			||||||
 | 
				
			|||||||
@ -9,9 +9,25 @@
 | 
				
			|||||||
#include "machine_manager.h"
 | 
					#include "machine_manager.h"
 | 
				
			||||||
#include "machine.h"
 | 
					#include "machine.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vfs_node* find_node_by_id(vfs_node* root, long long id) {
 | 
				
			||||||
 | 
					  if(root->id == id) {
 | 
				
			||||||
 | 
					    return root;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  for(auto const& [name, child] : root->children) {
 | 
				
			||||||
 | 
					    vfs_node* found = find_node_by_id(child, id);
 | 
				
			||||||
 | 
					    if(found) {
 | 
				
			||||||
 | 
					      return found;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return nullptr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CommandProcessor::CommandProcessor(Machine* home_machine,
 | 
					CommandProcessor::CommandProcessor(Machine* home_machine,
 | 
				
			||||||
                                   std::map<std::string, Machine*>& world_machines,
 | 
					                                   std::map<std::string, Machine*>& world_machines,
 | 
				
			||||||
                                   DatabaseManager* db_manager) :
 | 
					                                   DatabaseManager* db_manager,
 | 
				
			||||||
 | 
					                                   MachineManager* machine_manager) :
 | 
				
			||||||
 | 
					    _machine_manager(machine_manager),
 | 
				
			||||||
    _db_manager(db_manager),
 | 
					    _db_manager(db_manager),
 | 
				
			||||||
    _home_machine(home_machine),
 | 
					    _home_machine(home_machine),
 | 
				
			||||||
    _session_machine(home_machine),
 | 
					    _session_machine(home_machine),
 | 
				
			||||||
@ -36,6 +52,14 @@ CommandProcessor::get_world_machines(void) {
 | 
				
			|||||||
  return _world_machines;
 | 
					  return _world_machines;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DatabaseManager* CommandProcessor::get_db_manager(void) {
 | 
				
			||||||
 | 
					  return _db_manager;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MachineManager* CommandProcessor::get_machine_manager(void) {
 | 
				
			||||||
 | 
					  return _machine_manager;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void CommandProcessor::set_current_dir(vfs_node* node) {
 | 
					void CommandProcessor::set_current_dir(vfs_node* node) {
 | 
				
			||||||
  _current_dir = node;
 | 
					  _current_dir = node;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -67,13 +91,18 @@ std::string CommandProcessor::process_command(const std::string& command) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* Search for script in the /bin directory of the current session machine. */
 | 
					  /* Search for script in the /bin directory of the current session machine. */
 | 
				
			||||||
  std::string script_filename = command_name + ".lua";
 | 
					  std::string script_filename = command_name + ".lua";
 | 
				
			||||||
  vfs_node* root = _session_machine->vfs_root;
 | 
					  long long script_id = 0;
 | 
				
			||||||
  if(root->children.count("bin") && root->children["bin"]->children.count(script_filename)) {
 | 
					  std::string script_content;
 | 
				
			||||||
    vfs_node* script_node = root->children["bin"]->children[script_filename];
 | 
					  _db_manager->_db << "SELECT T2.id, T2.content FROM vfs_nodes AS T1 JOIN vfs_nodes AS T2 "
 | 
				
			||||||
    bool is_remote = (_session_machine != _home_machine);
 | 
					                      "ON T1.id = T2.parent_id WHERE T1.name = 'bin' AND T2.name = ? "
 | 
				
			||||||
    sol::object result = _lua->execute(script_node->content, *this, args, is_remote);
 | 
					                      "AND t1.machine_id = ?;"
 | 
				
			||||||
    return result.is<std::string>() ? result.as<std::string>() : "[Script returned an unexpected type]";
 | 
					                   << script_filename << _session_machine->id
 | 
				
			||||||
 | 
					                   >> std::tie(script_id, script_content);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if(script_id > 0) {
 | 
				
			||||||
 | 
					    bool is_remote = (_session_machine != _home_machine);
 | 
				
			||||||
 | 
					    sol::object result = _lua->execute(script_content, *this, args, is_remote);
 | 
				
			||||||
 | 
					    return result.is<std::string>() ? result.as<std::string>() : "[Script returned an unexpected type]";
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return "Unknown command: " + command_name + "\n";
 | 
					  return "Unknown command: " + command_name + "\n";
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -114,59 +143,3 @@ std::string CommandProcessor::read_file(const std::string& path) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  return "Error: file not found.";
 | 
					  return "Error: file not found.";
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
void CommandProcessor::ensure_vfs_is_writable(void) {
 | 
					 | 
				
			||||||
  if(!_session_machine->is_vfs_a_copy) {
 | 
					 | 
				
			||||||
    /* VFS shared, copy required. */
 | 
					 | 
				
			||||||
    if(_session_machine == _home_machine) {
 | 
					 | 
				
			||||||
      /* We are modifying our own home machine. */
 | 
					 | 
				
			||||||
      fprintf(stderr, "CoW: Write attempt on player's home machine."
 | 
					 | 
				
			||||||
              "Creating persistent 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;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      Machine* old_machine = _home_machine;
 | 
					 | 
				
			||||||
      _home_machine = new_machine;
 | 
					 | 
				
			||||||
      set_session_machine(new_machine);
 | 
					 | 
				
			||||||
      delete old_machine;
 | 
					 | 
				
			||||||
      _current_dir = find_node_by_path(_session_machine->vfs_root, original_path);
 | 
					 | 
				
			||||||
      if(!_current_dir) { _current_dir = _session_machine->vfs_root; }
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      /* we are modifying a remote NPC machine. */
 | 
					 | 
				
			||||||
      std::string remote_ip = "";
 | 
					 | 
				
			||||||
      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 persistent copy.\n",
 | 
					 | 
				
			||||||
                remote_ip.c_str());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        std::string original_path = get_full_path(_current_dir);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        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;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Machine* old_machine = _world_machines[remote_ip];
 | 
					 | 
				
			||||||
        _world_machines[remote_ip] = new_machine;
 | 
					 | 
				
			||||||
        set_session_machine(new_machine);
 | 
					 | 
				
			||||||
        delete old_machine;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        _current_dir = find_node_by_path(_session_machine->vfs_root, original_path);
 | 
					 | 
				
			||||||
        if(!_current_dir) { _current_dir = _session_machine->vfs_root; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -6,12 +6,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "db/database_manager.h"
 | 
					#include "db/database_manager.h"
 | 
				
			||||||
#include "machine.h"
 | 
					#include "machine.h"
 | 
				
			||||||
 | 
					#include "machine_manager.h"
 | 
				
			||||||
#include "vfs.h"
 | 
					#include "vfs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CommandProcessor {
 | 
					class CommandProcessor {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  CommandProcessor(Machine* home_machine, std::map<std::string, Machine*>& world_machines,
 | 
					  CommandProcessor(Machine* home_machine, std::map<std::string, Machine*>& world_machines,
 | 
				
			||||||
                   DatabaseManager* db_manager);
 | 
					                   DatabaseManager* db_manager, MachineManager* machine_manager);
 | 
				
			||||||
  ~CommandProcessor(void);
 | 
					  ~CommandProcessor(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::string process_command(const std::string& command);
 | 
					  std::string process_command(const std::string& command);
 | 
				
			||||||
@ -23,13 +24,14 @@ public:
 | 
				
			|||||||
  Machine* get_home_machine(void);
 | 
					  Machine* get_home_machine(void);
 | 
				
			||||||
  Machine* get_session_machine(void);
 | 
					  Machine* get_session_machine(void);
 | 
				
			||||||
  std::map<std::string, Machine*>& get_world_machines(void);
 | 
					  std::map<std::string, Machine*>& get_world_machines(void);
 | 
				
			||||||
 | 
					  DatabaseManager* get_db_manager(void);
 | 
				
			||||||
 | 
					  MachineManager* get_machine_manager(void);
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
  void set_current_dir(vfs_node* node);
 | 
					  void set_current_dir(vfs_node* node);
 | 
				
			||||||
  void set_session_machine(Machine* machine);
 | 
					  void set_session_machine(Machine* machine);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void ensure_vfs_is_writable(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
					  MachineManager* _machine_manager;
 | 
				
			||||||
  DatabaseManager* _db_manager;
 | 
					  DatabaseManager* _db_manager;
 | 
				
			||||||
  Machine* _home_machine;
 | 
					  Machine* _home_machine;
 | 
				
			||||||
  Machine* _session_machine;
 | 
					  Machine* _session_machine;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,5 @@
 | 
				
			|||||||
#include "database_manager.h"
 | 
					#include "database_manager.h"
 | 
				
			||||||
 | 
					#include "vfs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DatabaseManager::DatabaseManager(const std::string& db_path) : _db(db_path) {
 | 
					DatabaseManager::DatabaseManager(const std::string& db_path) : _db(db_path) {
 | 
				
			||||||
  /* db is opened in the construtor's init list. */
 | 
					  /* db is opened in the construtor's init list. */
 | 
				
			||||||
@ -35,7 +36,7 @@ void DatabaseManager::init(void) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool DatabaseManager::create_player(const std::string& username, const std::string& password,
 | 
					bool DatabaseManager::create_player(const std::string& username, const std::string& password,
 | 
				
			||||||
                                    const std::string& hostname) {
 | 
					                                    const std::string& hostname, vfs_node* vfs_template) {
 | 
				
			||||||
  long long player_id   = 0;
 | 
					  long long player_id   = 0;
 | 
				
			||||||
  long long machine_id  = 0;
 | 
					  long long machine_id  = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -66,13 +67,24 @@ bool DatabaseManager::create_player(const std::string& username, const std::stri
 | 
				
			|||||||
    long long root_id = _db.last_insert_rowid();
 | 
					    long long root_id = _db.last_insert_rowid();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Create default subdirs. */
 | 
					    /* Create default subdirs. */
 | 
				
			||||||
    _db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type) VALUES (?, ?, ?, 1);"
 | 
					 | 
				
			||||||
        << machine_id << root_id << "bin";
 | 
					 | 
				
			||||||
    _db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type) VALUES (?, ?, ?, 1);"
 | 
					    _db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type) VALUES (?, ?, ?, 1);"
 | 
				
			||||||
        << machine_id << root_id << "home";
 | 
					        << machine_id << root_id << "home";
 | 
				
			||||||
    _db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type) VALUES (?, ?, ?, 1);"
 | 
					    _db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type) VALUES (?, ?, ?, 1);"
 | 
				
			||||||
        << machine_id << root_id << "etc";
 | 
					        << machine_id << root_id << "etc";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Create /bing and get it's ID */
 | 
				
			||||||
 | 
					    _db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type) VALUES(?, ?, ?, 1);"
 | 
				
			||||||
 | 
					        << machine_id << root_id << "bin";
 | 
				
			||||||
 | 
					    long long bin_id = _db.last_insert_rowid();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Copy scripts from template into new machine's /bin */
 | 
				
			||||||
 | 
					    vfs_node* template_bin = vfs_template->children["bin"];
 | 
				
			||||||
 | 
					    for(auto const& [name, node] : template_bin->children) {
 | 
				
			||||||
 | 
					      _db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type, content) "
 | 
				
			||||||
 | 
					             "VALUES (?, ?, ?, ?, ?);"
 | 
				
			||||||
 | 
					          << machine_id << bin_id << name << FILE_NODE <<node->content;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _db << "COMMIT";
 | 
					    _db << "COMMIT";
 | 
				
			||||||
  } catch(const std::exception& e) {
 | 
					  } catch(const std::exception& e) {
 | 
				
			||||||
    _db << "ROLLBACK;"; /* Ensure atomicity. */
 | 
					    _db << "ROLLBACK;"; /* Ensure atomicity. */
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "vfs.h"
 | 
				
			||||||
#include "db.h"
 | 
					#include "db.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DatabaseManager {
 | 
					class DatabaseManager {
 | 
				
			||||||
@ -13,7 +14,7 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* Return true on success, false if user already exists. */
 | 
					  /* Return true on success, false if user already exists. */
 | 
				
			||||||
  bool create_player(const std::string& username, const std::string& password,
 | 
					  bool create_player(const std::string& username, const std::string& password,
 | 
				
			||||||
                     const std::string& hostname);
 | 
					                     const std::string& hostname, vfs_node* vfs_template);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Return true if creds are valid. */
 | 
					  /* Return true if creds are valid. */
 | 
				
			||||||
  bool auth_player(const std::string& username, const std::string& password);
 | 
					  bool auth_player(const std::string& username, const std::string& password);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,9 @@
 | 
				
			|||||||
 | 
					#include <sol/types.hpp>
 | 
				
			||||||
#include <sstream>
 | 
					#include <sstream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "lua_api.h"
 | 
					#include "lua_api.h"
 | 
				
			||||||
#include "command_processor.h"
 | 
					#include "command_processor.h"
 | 
				
			||||||
 | 
					#include "db/database_manager.h"
 | 
				
			||||||
#include "machine.h"
 | 
					#include "machine.h"
 | 
				
			||||||
#include "vfs.h"
 | 
					#include "vfs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -12,33 +14,47 @@ vfs_node* get_current_dir(CommandProcessor& context) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::string rm(CommandProcessor& context, const std::string& filename) {
 | 
					std::string rm(CommandProcessor& context, const std::string& filename) {
 | 
				
			||||||
  context.ensure_vfs_is_writable();
 | 
					 | 
				
			||||||
  vfs_node* current_dir = context.get_current_dir();
 | 
					  vfs_node* current_dir = context.get_current_dir();
 | 
				
			||||||
  if(!current_dir->children.count(filename)) {
 | 
					  DatabaseManager* db = context.get_db_manager();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* find the file in the database. */
 | 
				
			||||||
 | 
					  long long file_id = 0;
 | 
				
			||||||
 | 
					  int file_type = 0;
 | 
				
			||||||
 | 
					  db->_db << "SELECT id, type FROM vfs_nodes WHERE parent_id = ? AND name = ?;"
 | 
				
			||||||
 | 
					          << current_dir->id << filename
 | 
				
			||||||
 | 
					          >> std::tie(file_id, file_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if(file_id == 0) {
 | 
				
			||||||
    return "rm: cannot remove '" + filename + "': No such file or directory.";
 | 
					    return "rm: cannot remove '" + filename + "': No such file or directory.";
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  vfs_node* target_node = current_dir->children[filename];
 | 
					  if(file_type == DIR_NODE) {
 | 
				
			||||||
  if(target_node->type == DIR_NODE) {
 | 
					 | 
				
			||||||
    return "rm: cannot remove '" + filename + "': Is a directory.";
 | 
					    return "rm: cannot remove '" + filename + "': Is a directory.";
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  db->_db << "DELETE FROM vfs_nodes WHERE id = ?;" << file_id;
 | 
				
			||||||
 | 
					  /* Also remove from in-mem VFS. */
 | 
				
			||||||
 | 
					  delete current_dir->children[filename];
 | 
				
			||||||
  current_dir->children.erase(filename);
 | 
					  current_dir->children.erase(filename);
 | 
				
			||||||
  delete target_node;
 | 
					
 | 
				
			||||||
  return "";
 | 
					  return "";
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::string write_file(CommandProcessor& context, const std::string& filename,
 | 
					std::string write_file(CommandProcessor& context, const std::string& filename,
 | 
				
			||||||
                       const std::string& content) {
 | 
					                       const std::string& content) {
 | 
				
			||||||
  context.ensure_vfs_is_writable();
 | 
					 | 
				
			||||||
  vfs_node* current_dir = context.get_current_dir();
 | 
					  vfs_node* current_dir = context.get_current_dir();
 | 
				
			||||||
 | 
					  DatabaseManager* db = context.get_db_manager();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(current_dir->children.count(filename)) {
 | 
					  if(current_dir->children.count(filename)) {
 | 
				
			||||||
    vfs_node* target_node = current_dir->children[filename];
 | 
					    vfs_node* target_node = current_dir->children[filename];
 | 
				
			||||||
    if(target_node->type == DIR_NODE) {
 | 
					    db->_db << "UPDATE vfs_nodes SET content = ? WHERE id = ?;"
 | 
				
			||||||
      return "cannot write to '" + filename + "': Is a directory.";
 | 
					            << content << target_node->id;
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    target_node->content = content;
 | 
					    target_node->content = content;
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    vfs_node* new_file = new vfs_node {
 | 
					    db->_db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type, content) VALUES (?, ?, ?, ?, ?);"
 | 
				
			||||||
      .name = filename, .type = FILE_NODE, .content = content, .parent = current_dir};
 | 
					            << context.get_session_machine()->id << current_dir->id << filename << FILE_NODE << content;
 | 
				
			||||||
 | 
					    vfs_node* new_file = new_node(filename, FILE_NODE, current_dir);
 | 
				
			||||||
 | 
					    new_file->id = db->_db.last_insert_rowid();
 | 
				
			||||||
 | 
					    new_file->content = content;
 | 
				
			||||||
    current_dir->children[filename] = new_file;
 | 
					    current_dir->children[filename] = new_file;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return "";
 | 
					  return "";
 | 
				
			||||||
@ -46,23 +62,51 @@ std::string write_file(CommandProcessor& context, const std::string& filename,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
std::string cd(CommandProcessor& context, const std::string& path) {
 | 
					std::string cd(CommandProcessor& context, const std::string& path) {
 | 
				
			||||||
  vfs_node* current_dir = context.get_current_dir();
 | 
					  vfs_node* current_dir = context.get_current_dir();
 | 
				
			||||||
 | 
					  DatabaseManager* db = context.get_db_manager();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(path == "..") {
 | 
					  if(path == "..") {
 | 
				
			||||||
    if(current_dir->parent) {
 | 
					    if(current_dir->parent) {
 | 
				
			||||||
      context.set_current_dir(current_dir->parent);
 | 
					      context.set_current_dir(current_dir->parent);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else if(current_dir->children.count(path)) {
 | 
					 | 
				
			||||||
    vfs_node* target_node = current_dir->children[path];
 | 
					 | 
				
			||||||
    if(target_node->type == DIR_NODE) {
 | 
					 | 
				
			||||||
      context.set_current_dir(target_node);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      return "cd: not a directory: " + path;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
 | 
					    long long target_id = 0;
 | 
				
			||||||
 | 
					    db->_db << "SELECT id FROM vfs_nodes WHERE parent_id = ? AND name = ? AND type = 1;"
 | 
				
			||||||
 | 
					            << current_dir->id << path
 | 
				
			||||||
 | 
					            >> target_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(target_id > 0) {
 | 
				
			||||||
 | 
					      /* Inefficient, I know. */
 | 
				
			||||||
 | 
					      Machine* reloaded_machine =
 | 
				
			||||||
 | 
					        context.get_machine_manager()->load_machine(context.get_session_machine()->id, db);
 | 
				
			||||||
 | 
					      vfs_node* new_dir = find_node_by_id(reloaded_machine->vfs_root, target_id);
 | 
				
			||||||
 | 
					      context.set_current_dir(new_dir);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
      return "cd: no such file or directory: " + path;
 | 
					      return "cd: no such file or directory: " + path;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return "";
 | 
					  return "";
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string ls(CommandProcessor& context) {
 | 
				
			||||||
 | 
					  vfs_node* dir = context.get_current_dir();
 | 
				
			||||||
 | 
					  printf("DEBUG: ls command called for directory_id: %lld\n", dir->id);
 | 
				
			||||||
 | 
					  if(dir->type != DIR_NODE) {
 | 
				
			||||||
 | 
					    return "ls: not a directory";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::stringstream ss;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  context.get_db_manager()->_db << "SELECT name, type FROM vfs_nodes WHERE parent_id = ?;"
 | 
				
			||||||
 | 
					                                << dir->id
 | 
				
			||||||
 | 
					                                >> [&](std::string name, int type) {
 | 
				
			||||||
 | 
					      ss << name;
 | 
				
			||||||
 | 
					      if(type == DIR_NODE) ss << "/";
 | 
				
			||||||
 | 
					      ss << "   ";
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return ss.str();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::string ssh(CommandProcessor& context, const std::string& ip) {
 | 
					std::string ssh(CommandProcessor& context, const std::string& ip) {
 | 
				
			||||||
  if(context.get_world_machines().count(ip)) {
 | 
					  if(context.get_world_machines().count(ip)) {
 | 
				
			||||||
    context.set_session_machine(context.get_world_machines().at(ip));
 | 
					    context.set_session_machine(context.get_world_machines().at(ip));
 | 
				
			||||||
 | 
				
			|||||||
@ -12,6 +12,7 @@ vfs_node* get_current_dir(CommandProcessor& context);
 | 
				
			|||||||
std::string rm(CommandProcessor& context, const std::string& filename);
 | 
					std::string rm(CommandProcessor& context, const std::string& filename);
 | 
				
			||||||
std::string write_file(CommandProcessor& context, const std::string& filename,
 | 
					std::string write_file(CommandProcessor& context, const std::string& filename,
 | 
				
			||||||
                       const std::string& content);
 | 
					                       const std::string& content);
 | 
				
			||||||
 | 
					std::string ls(CommandProcessor& context);
 | 
				
			||||||
std::string cd(CommandProcessor& context, const std::string& path);
 | 
					std::string cd(CommandProcessor& context, const std::string& path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* NETWORK ACTIONS. */
 | 
					/* NETWORK ACTIONS. */
 | 
				
			||||||
 | 
				
			|||||||
@ -24,6 +24,7 @@ LuaProcessor::LuaProcessor(void) {
 | 
				
			|||||||
  /* Create the 'bettola' API table. */
 | 
					  /* Create the 'bettola' API table. */
 | 
				
			||||||
  sol::table bettola_api = _lua.create_named_table("bettola");
 | 
					  sol::table bettola_api = _lua.create_named_table("bettola");
 | 
				
			||||||
  bettola_api["rm"]             = &api::rm;
 | 
					  bettola_api["rm"]             = &api::rm;
 | 
				
			||||||
 | 
					  bettola_api["ls"]             = &api::ls;
 | 
				
			||||||
  bettola_api["write_file"]     = &api::write_file;
 | 
					  bettola_api["write_file"]     = &api::write_file;
 | 
				
			||||||
  bettola_api["get_current_dir"]= &api::get_current_dir;
 | 
					  bettola_api["get_current_dir"]= &api::get_current_dir;
 | 
				
			||||||
  bettola_api["cd"]             = &api::cd;
 | 
					  bettola_api["cd"]             = &api::cd;
 | 
				
			||||||
 | 
				
			|||||||
@ -8,15 +8,6 @@
 | 
				
			|||||||
#include "machine.h"
 | 
					#include "machine.h"
 | 
				
			||||||
#include "vfs.h"
 | 
					#include "vfs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Create a new node. */
 | 
					 | 
				
			||||||
vfs_node* new_node(std::string name, vfs_node_type type, vfs_node* parent) {
 | 
					 | 
				
			||||||
  vfs_node* node  = new vfs_node();
 | 
					 | 
				
			||||||
  node->name      = name;
 | 
					 | 
				
			||||||
  node->type      = type;
 | 
					 | 
				
			||||||
  node->parent    = parent;
 | 
					 | 
				
			||||||
  return node;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
vfs_node* copy_vfs_node(vfs_node* original, vfs_node* new_parent) {
 | 
					vfs_node* copy_vfs_node(vfs_node* original, vfs_node* new_parent) {
 | 
				
			||||||
  if(!original) {
 | 
					  if(!original) {
 | 
				
			||||||
    return nullptr;
 | 
					    return nullptr;
 | 
				
			||||||
@ -34,7 +25,8 @@ vfs_node* copy_vfs_node(vfs_node* original, vfs_node* new_parent) {
 | 
				
			|||||||
  return new_copy;
 | 
					  return new_copy;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MachineManager::MachineManager(void) {
 | 
					MachineManager::MachineManager(DatabaseManager* db_manager) :
 | 
				
			||||||
 | 
					    _db_manager(db_manager) {
 | 
				
			||||||
  /* Create template VFS that holds shared, read-only directories. */
 | 
					  /* Create template VFS that holds shared, read-only directories. */
 | 
				
			||||||
  _vfs_template_root = new_node("/", DIR_NODE, nullptr);
 | 
					  _vfs_template_root = new_node("/", DIR_NODE, nullptr);
 | 
				
			||||||
  vfs_node* bin = new_node("bin", DIR_NODE, _vfs_template_root);
 | 
					  vfs_node* bin = new_node("bin", DIR_NODE, _vfs_template_root);
 | 
				
			||||||
@ -107,12 +99,11 @@ void build_tree(vfs_node* parent, const std::map<long long, vfs_node*>& nodes) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Machine* MachineManager::load_machine(long long machine_id) {
 | 
					Machine* MachineManager::load_machine(long long machine_id, DatabaseManager* db_manager) {
 | 
				
			||||||
  DatabaseManager db("bettola.db"); /* Assumes multiplayer for now. */
 | 
					  printf("DEBUG: load_machine called for machine_id: %lld\n", machine_id);
 | 
				
			||||||
 | 
					 | 
				
			||||||
  std::string hostname;
 | 
					  std::string hostname;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  db._db << "SELECT hostname FROM machines WHERE id = ?;"
 | 
					  db_manager->_db << "SELECT hostname FROM machines WHERE id = ?;"
 | 
				
			||||||
         << machine_id
 | 
					         << machine_id
 | 
				
			||||||
         >> hostname;
 | 
					         >> hostname;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -122,12 +113,14 @@ Machine* MachineManager::load_machine(long long machine_id) {
 | 
				
			|||||||
  std::map<long long, vfs_node*> nodes;
 | 
					  std::map<long long, vfs_node*> nodes;
 | 
				
			||||||
  vfs_node* root = nullptr;
 | 
					  vfs_node* root = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  db._db << "SELECT id, parent_id, name, type, content FROM vfs_nodes WHERE machine_id = ?;"
 | 
					  db_manager->_db << "SELECT id, parent_id, name, type, content FROM vfs_nodes WHERE machine_id = ?;"
 | 
				
			||||||
         << machine_id
 | 
					         << machine_id
 | 
				
			||||||
         >> [&](long long id, long long parent_id, std::string name, int type, std::string content) {
 | 
					         >> [&](long long id, long long parent_id, std::string name, int type, std::string content) {
 | 
				
			||||||
      vfs_node* node = new_node(name, (vfs_node_type)type, nullptr);
 | 
					      vfs_node* node = new vfs_node();
 | 
				
			||||||
      node->id = id;
 | 
					      node->id = id;
 | 
				
			||||||
      node->parent_id = parent_id; /* Store temp id for tree building. */
 | 
					      node->parent_id = parent_id; /* Store temp id for tree building. */
 | 
				
			||||||
 | 
					      node->name = name;
 | 
				
			||||||
 | 
					      node->type = (vfs_node_type)type;
 | 
				
			||||||
      node->content = content;
 | 
					      node->content = content;
 | 
				
			||||||
      nodes[id] = node;
 | 
					      nodes[id] = node;
 | 
				
			||||||
      if(name == "/") {
 | 
					      if(name == "/") {
 | 
				
			||||||
@ -140,5 +133,4 @@ Machine* MachineManager::load_machine(long long machine_id) {
 | 
				
			|||||||
    machine->vfs_root = root;
 | 
					    machine->vfs_root = root;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return machine;
 | 
					  return machine;
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "db/database_manager.h"
 | 
				
			||||||
#include "machine.h"
 | 
					#include "machine.h"
 | 
				
			||||||
#include "vfs.h"
 | 
					#include "vfs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -10,13 +11,17 @@ vfs_node* copy_vfs_node(vfs_node* original, vfs_node* new_parent);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class MachineManager {
 | 
					class MachineManager {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  MachineManager(void);
 | 
					  MachineManager(DatabaseManager* db_manager);
 | 
				
			||||||
  ~MachineManager(void); /* TODO: Implement recursive VFS deletion. */
 | 
					  ~MachineManager(void); /* TODO: Implement recursive VFS deletion. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Machine* create_machine(uint32_t id, const std::string& hostname,
 | 
					  Machine* create_machine(uint32_t id, const std::string& hostname,
 | 
				
			||||||
                          const std::string& system_type);
 | 
					                          const std::string& system_type);
 | 
				
			||||||
  Machine* load_machine(long long machine_id);
 | 
					  Machine* load_machine(long long machine_id, DatabaseManager* db_manager);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  vfs_node* get_vfs_template(void) { return _vfs_template_root; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
					  DatabaseManager* _db_manager;
 | 
				
			||||||
  vfs_node* _vfs_template_root;
 | 
					  vfs_node* _vfs_template_root;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,14 @@
 | 
				
			|||||||
#include "vfs.h"
 | 
					#include "vfs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Create a new node. */
 | 
				
			||||||
 | 
					vfs_node* new_node(std::string name, vfs_node_type type, vfs_node* parent) {
 | 
				
			||||||
 | 
					  vfs_node* node  = new vfs_node();
 | 
				
			||||||
 | 
					  node->name      = name;
 | 
				
			||||||
 | 
					  node->type      = type;
 | 
				
			||||||
 | 
					  node->parent    = parent;
 | 
				
			||||||
 | 
					  return node;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::string get_full_path(vfs_node* node) {
 | 
					std::string get_full_path(vfs_node* node) {
 | 
				
			||||||
  if(node->parent == nullptr) {
 | 
					  if(node->parent == nullptr) {
 | 
				
			||||||
    return "/";
 | 
					    return "/";
 | 
				
			||||||
 | 
				
			|||||||
@ -27,5 +27,7 @@ struct vfs_node {
 | 
				
			|||||||
  vfs_node* parent;
 | 
					  vfs_node* parent;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vfs_node* new_node(std::string name, vfs_node_type type, vfs_node* parent);
 | 
				
			||||||
 | 
					vfs_node* find_node_by_id(vfs_node* root, long long id);
 | 
				
			||||||
std::string get_full_path(vfs_node* node);
 | 
					std::string get_full_path(vfs_node* node);
 | 
				
			||||||
void delete_vfs_tree(vfs_node* node);
 | 
					void delete_vfs_tree(vfs_node* node);
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
NetworkManager::NetworkManager(const std::string& db_path) :
 | 
					NetworkManager::NetworkManager(const std::string& db_path) :
 | 
				
			||||||
    _db_manager(std::make_unique<DatabaseManager>(db_path)),
 | 
					    _db_manager(std::make_unique<DatabaseManager>(db_path)),
 | 
				
			||||||
    _acceptor(_io_context) {
 | 
					    _acceptor(_io_context),
 | 
				
			||||||
 | 
					    _machine_manager(_db_manager.get()) {
 | 
				
			||||||
  /* World setup. */
 | 
					  /* World setup. */
 | 
				
			||||||
  _world_machines["8.8.8.8"]   = _machine_manager.create_machine(1000, "dns.google", "npc");
 | 
					  _world_machines["8.8.8.8"]   = _machine_manager.create_machine(1000, "dns.google", "npc");
 | 
				
			||||||
  _world_machines["10.0.2.15"] = _machine_manager.create_machine(1001, "corp.internal", "npc");
 | 
					  _world_machines["10.0.2.15"] = _machine_manager.create_machine(1001, "corp.internal", "npc");
 | 
				
			||||||
@ -78,7 +79,8 @@ void NetworkManager::start_accept(void) {
 | 
				
			|||||||
        Machine* player_machine = _machine_manager.create_machine(player_id, "player.home",
 | 
					        Machine* player_machine = _machine_manager.create_machine(player_id, "player.home",
 | 
				
			||||||
                                                                  "player");
 | 
					                                                                  "player");
 | 
				
			||||||
        auto new_player = std::make_unique<Player>(player_id, player_machine,
 | 
					        auto new_player = std::make_unique<Player>(player_id, player_machine,
 | 
				
			||||||
                                                   _world_machines, _db_manager.get());
 | 
					                                                   _world_machines, _db_manager.get(),
 | 
				
			||||||
 | 
					                                                   &_machine_manager);
 | 
				
			||||||
        Player* new_player_ptr = new_player.get();
 | 
					        Player* new_player_ptr = new_player.get();
 | 
				
			||||||
        _players[player_id] = std::move(new_player);
 | 
					        _players[player_id] = std::move(new_player);
 | 
				
			||||||
        new_connection->set_id(player_id);
 | 
					        new_connection->set_id(player_id);
 | 
				
			||||||
@ -129,12 +131,14 @@ void NetworkManager::on_message(std::shared_ptr<net::TcpConnection> connection,
 | 
				
			|||||||
      std::string payload = message.substr(7);
 | 
					      std::string payload = message.substr(7);
 | 
				
			||||||
      auto parts = split_message(payload, "::");
 | 
					      auto parts = split_message(payload, "::");
 | 
				
			||||||
      if(parts.size() == 3) {
 | 
					      if(parts.size() == 3) {
 | 
				
			||||||
        if(_db_manager->create_player(parts[0], parts[1], parts[2])) {
 | 
					        if(_db_manager->create_player(parts[0], parts[1], parts[2],
 | 
				
			||||||
 | 
					                                      _machine_manager.get_vfs_template())) {
 | 
				
			||||||
          long long machine_id = _db_manager->get_player_home_machine_id(parts[0]);
 | 
					          long long machine_id = _db_manager->get_player_home_machine_id(parts[0]);
 | 
				
			||||||
          Machine* home_machine = _machine_manager.load_machine(machine_id);
 | 
					          Machine* home_machine = _machine_manager.load_machine(machine_id, _db_manager.get());
 | 
				
			||||||
          delete player->cmd_processor; /* Delete old command processor. */
 | 
					          delete player->cmd_processor; /* Delete old command processor. */
 | 
				
			||||||
          player->cmd_processor = new CommandProcessor(home_machine, _world_machines,
 | 
					          player->cmd_processor = new CommandProcessor(home_machine, _world_machines,
 | 
				
			||||||
                                                       _db_manager.get());
 | 
					                                                       _db_manager.get(),
 | 
				
			||||||
 | 
					                                                       &_machine_manager);
 | 
				
			||||||
          player->state = PlayerState::ACTIVE;
 | 
					          player->state = PlayerState::ACTIVE;
 | 
				
			||||||
          connection->send("C_ACC_SUCCESS");
 | 
					          connection->send("C_ACC_SUCCESS");
 | 
				
			||||||
          /* send initial prompt. */
 | 
					          /* send initial prompt. */
 | 
				
			||||||
@ -149,10 +153,13 @@ void NetworkManager::on_message(std::shared_ptr<net::TcpConnection> connection,
 | 
				
			|||||||
      auto parts = split_message(payload, "::");
 | 
					      auto parts = split_message(payload, "::");
 | 
				
			||||||
      if(parts.size() == 2) {
 | 
					      if(parts.size() == 2) {
 | 
				
			||||||
        if(_db_manager->auth_player(parts[0], parts[1])) {
 | 
					        if(_db_manager->auth_player(parts[0], parts[1])) {
 | 
				
			||||||
          /*
 | 
					          long long machine_id = _db_manager->get_player_home_machine_id(parts[0]);
 | 
				
			||||||
           * TODO: Load the player's machine from the database.
 | 
					          printf("DEBUG: Loading machine %lld for player %s\n", machine_id, parts[0].c_str());
 | 
				
			||||||
           * For now, just auth them and use a temp machine.
 | 
					          Machine* home_machine = _machine_manager.load_machine(machine_id, _db_manager.get());
 | 
				
			||||||
           */
 | 
					          delete player->cmd_processor; /* Delete old command processor. */
 | 
				
			||||||
 | 
					          player->cmd_processor = new CommandProcessor(home_machine, _world_machines,
 | 
				
			||||||
 | 
					                                                       _db_manager.get(), &_machine_manager);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          player->state = PlayerState::ACTIVE;
 | 
					          player->state = PlayerState::ACTIVE;
 | 
				
			||||||
          connection->send("LOGIN_SUCCESS");
 | 
					          connection->send("LOGIN_SUCCESS");
 | 
				
			||||||
          /* Send initial prompt. */
 | 
					          /* Send initial prompt. */
 | 
				
			||||||
 | 
				
			|||||||
@ -37,6 +37,6 @@ private:
 | 
				
			|||||||
  uint32_t _next_player_id = 1;
 | 
					  uint32_t _next_player_id = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::map<std::string, Machine*> _world_machines; /* For NPC's. */
 | 
					  std::map<std::string, Machine*> _world_machines; /* For NPC's. */
 | 
				
			||||||
  MachineManager _machine_manager;
 | 
					 | 
				
			||||||
  std::unique_ptr<DatabaseManager> _db_manager;
 | 
					  std::unique_ptr<DatabaseManager> _db_manager;
 | 
				
			||||||
 | 
					  MachineManager _machine_manager;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -4,11 +4,12 @@
 | 
				
			|||||||
#include "machine.h"
 | 
					#include "machine.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Player::Player(uint32_t new_id, Machine* home_machine,
 | 
					Player::Player(uint32_t new_id, Machine* home_machine,
 | 
				
			||||||
               std::map<std::string, Machine*>& world_machines, DatabaseManager* db_manager) :
 | 
					               std::map<std::string, Machine*>& world_machines, DatabaseManager* db_manager,
 | 
				
			||||||
 | 
					               MachineManager* machine_manager) :
 | 
				
			||||||
    id(new_id),
 | 
					    id(new_id),
 | 
				
			||||||
    state(PlayerState::AUTHENTICATING) {
 | 
					    state(PlayerState::AUTHENTICATING) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  cmd_processor = new CommandProcessor(home_machine, world_machines, db_manager);
 | 
					  cmd_processor = new CommandProcessor(home_machine, world_machines, db_manager, machine_manager);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Player::~Player(void) {
 | 
					Player::~Player(void) {
 | 
				
			||||||
 | 
				
			|||||||
@ -7,6 +7,7 @@
 | 
				
			|||||||
#include "db/database_manager.h"
 | 
					#include "db/database_manager.h"
 | 
				
			||||||
#include "command_processor.h"
 | 
					#include "command_processor.h"
 | 
				
			||||||
#include "machine.h"
 | 
					#include "machine.h"
 | 
				
			||||||
 | 
					#include "machine_manager.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum class PlayerState {
 | 
					enum class PlayerState {
 | 
				
			||||||
  AUTHENTICATING,
 | 
					  AUTHENTICATING,
 | 
				
			||||||
@ -16,7 +17,8 @@ enum class PlayerState {
 | 
				
			|||||||
class Player {
 | 
					class Player {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  Player(uint32_t id, Machine* home_machine, std::map<std::string,
 | 
					  Player(uint32_t id, Machine* home_machine, std::map<std::string,
 | 
				
			||||||
         Machine*>& world_machines, DatabaseManager* db_manager);
 | 
					         Machine*>& world_machines, DatabaseManager* db_manager,
 | 
				
			||||||
 | 
					         MachineManager* machine_manager);
 | 
				
			||||||
  ~Player(void);
 | 
					  ~Player(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  uint32_t id;
 | 
					  uint32_t id;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user