[Refactor] Abstract database logic with Repository classes.
This commit is contained in:
		
							parent
							
								
									e156eb6391
								
							
						
					
					
						commit
						2a50d937ea
					
				@ -1,8 +1,13 @@
 | 
			
		||||
#include "database_manager.h"
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include "vfs.h"
 | 
			
		||||
 | 
			
		||||
DatabaseManager::DatabaseManager(const std::string& db_path) : _db(db_path) {
 | 
			
		||||
  /* db is opened in the construtor's init list. */
 | 
			
		||||
DatabaseManager::DatabaseManager(const std::string& db_path) :
 | 
			
		||||
    _db(db_path) {
 | 
			
		||||
  _player_repository  = std::make_unique<PlayerRepository>(_db);
 | 
			
		||||
  _machine_repository = std::make_unique<MachineRepository>(_db);
 | 
			
		||||
  _service_repository = std::make_unique<ServiceRepository>(_db);
 | 
			
		||||
  _vfs_repository     = std::make_unique<VFSRepository>(_db);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DatabaseManager::~DatabaseManager(void) {
 | 
			
		||||
@ -49,51 +54,33 @@ bool DatabaseManager::create_player(const std::string& username, const std::stri
 | 
			
		||||
  try {
 | 
			
		||||
    _db << "BEGIN;";
 | 
			
		||||
 | 
			
		||||
    /* Create the player. */
 | 
			
		||||
    _db << "INSERT INTO players (username, password, hostname) VALUES (?, ?, ?);"
 | 
			
		||||
        << username
 | 
			
		||||
        << password
 | 
			
		||||
        << hostname;
 | 
			
		||||
    player_id = _db.last_insert_rowid();
 | 
			
		||||
    player_id = _player_repository->create(username, password, hostname);
 | 
			
		||||
 | 
			
		||||
    /* Create the home machine. */
 | 
			
		||||
    /* TODO: Implement real IP allication. */
 | 
			
		||||
    std::string ip_address = "192.168.1." + std::to_string(player_id);
 | 
			
		||||
    _db << "INSERT INTO machines (owner_id, hostname, ip_address) VALUES (?, ?, ?);"
 | 
			
		||||
        << player_id << hostname << ip_address;
 | 
			
		||||
    machine_id = _db.last_insert_rowid();
 | 
			
		||||
    machine_id = _machine_repository->create(player_id, hostname, ip_address);
 | 
			
		||||
 | 
			
		||||
    /* Link player to their new machine. */
 | 
			
		||||
    _db << "UPDATE players SET home_machine_id = ? WHERE id = ?;"
 | 
			
		||||
        << machine_id << player_id;
 | 
			
		||||
    _player_repository->set_home_machine_id(player_id, machine_id);
 | 
			
		||||
 | 
			
		||||
    /* Create the root dir for the new machine's VFS. */
 | 
			
		||||
    _db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type) VALUES(?, NULL, ?, 1);"
 | 
			
		||||
        << machine_id << "/";
 | 
			
		||||
    long long root_id = _db.last_insert_rowid();
 | 
			
		||||
    long long root_id = _vfs_repository->create_node(machine_id, nullptr, "/", DIR_NODE);
 | 
			
		||||
 | 
			
		||||
    /* Create default subdirs. */
 | 
			
		||||
    _db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type) VALUES (?, ?, ?, 1);"
 | 
			
		||||
        << machine_id << root_id << "home";
 | 
			
		||||
    _db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type) VALUES (?, ?, ?, 1);"
 | 
			
		||||
        << machine_id << root_id << "etc";
 | 
			
		||||
    _vfs_repository->create_node(machine_id, &root_id, "home", DIR_NODE);
 | 
			
		||||
    _vfs_repository->create_node(machine_id, &root_id, "etc", DIR_NODE);
 | 
			
		||||
 | 
			
		||||
    /* 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();
 | 
			
		||||
    /* Create /bin and get it's ID */
 | 
			
		||||
    long long bin_id = _vfs_repository->create_node(machine_id, &root_id, "bin", DIR_NODE);
 | 
			
		||||
 | 
			
		||||
    /* 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;
 | 
			
		||||
      _vfs_repository->create_node(machine_id, &bin_id, name, FILE_NODE, node->content);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Add default SSH service. */
 | 
			
		||||
    _db << "INSERT INTO services (machine_id, port, name) VALUES (?, ?, ?);"
 | 
			
		||||
        << machine_id << 22 << "SSH";
 | 
			
		||||
    _service_repository->create(machine_id, 22, "SSH");
 | 
			
		||||
 | 
			
		||||
    _db << "COMMIT";
 | 
			
		||||
  } catch(const std::exception& e) {
 | 
			
		||||
@ -102,21 +89,3 @@ bool DatabaseManager::create_player(const std::string& username, const std::stri
 | 
			
		||||
  }
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool DatabaseManager::auth_player(const std::string& username, const std::string& password) {
 | 
			
		||||
  bool authed = false;
 | 
			
		||||
  _db << "SELECT id FROM players WHERE username = ? AND password = ?;"
 | 
			
		||||
      << username
 | 
			
		||||
      << password
 | 
			
		||||
      >> [&](long long id) { authed = true; };
 | 
			
		||||
 | 
			
		||||
  return authed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
long long DatabaseManager::get_player_home_machine_id(const std::string& username) {
 | 
			
		||||
  long long machine_id = -1; /* Return -1 if not found. */
 | 
			
		||||
  _db << "SELECT home_machine_id FROM players WHERE username = ?;"
 | 
			
		||||
      << username
 | 
			
		||||
      >> machine_id;
 | 
			
		||||
  return machine_id;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,14 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
#include "service_repository.h"
 | 
			
		||||
#include "player_repository.h"
 | 
			
		||||
#include "machine_repository.h"
 | 
			
		||||
#include "vfs_repository.h"
 | 
			
		||||
#include "sqlite_modern_cpp.h"
 | 
			
		||||
#include "vfs.h"
 | 
			
		||||
#include "db.h"
 | 
			
		||||
 | 
			
		||||
class DatabaseManager {
 | 
			
		||||
public:
 | 
			
		||||
@ -16,10 +21,16 @@ public:
 | 
			
		||||
  bool create_player(const std::string& username, const std::string& password,
 | 
			
		||||
                     const std::string& hostname, vfs_node* vfs_template);
 | 
			
		||||
 | 
			
		||||
  /* Return true if creds are valid. */
 | 
			
		||||
  bool auth_player(const std::string& username, const std::string& password);
 | 
			
		||||
 | 
			
		||||
  long long get_player_home_machine_id(const std::string& username);
 | 
			
		||||
  PlayerRepository& players(void)   { return *_player_repository;  }
 | 
			
		||||
  MachineRepository& machines(void) { return *_machine_repository; }
 | 
			
		||||
  ServiceRepository& services(void) { return *_service_repository; }
 | 
			
		||||
  VFSRepository& vfs(void)          { return *_vfs_repository;     }
 | 
			
		||||
 | 
			
		||||
  sqlite::database _db;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  std::unique_ptr<PlayerRepository> _player_repository;
 | 
			
		||||
  std::unique_ptr<MachineRepository> _machine_repository;
 | 
			
		||||
  std::unique_ptr<ServiceRepository> _service_repository;
 | 
			
		||||
  std::unique_ptr<VFSRepository> _vfs_repository;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										32
									
								
								common/src/db/machine_repository.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								common/src/db/machine_repository.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,32 @@
 | 
			
		||||
#include "machine_repository.h"
 | 
			
		||||
#include "sqlite_modern_cpp.h"
 | 
			
		||||
 | 
			
		||||
MachineRepository::MachineRepository(sqlite::database& db) : _db(db) {}
 | 
			
		||||
 | 
			
		||||
long long MachineRepository::create(std::optional<long long> owner_id,
 | 
			
		||||
                                    const std::string& hostname,
 | 
			
		||||
                                    const std::string& ip_address) {
 | 
			
		||||
  if(owner_id.has_value()) {
 | 
			
		||||
    _db << "INSERT INTO machines (owner_id, hostname, ip_address) VALUES(?, ?, ?);"
 | 
			
		||||
        << owner_id.value() << hostname << ip_address;
 | 
			
		||||
  } else {
 | 
			
		||||
    _db << "INSERT INTO machines (owner_id, hostname, ip_address) VALUES (NULL, ?, ?);"
 | 
			
		||||
        << hostname << ip_address;
 | 
			
		||||
  }
 | 
			
		||||
  return _db.last_insert_rowid();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int MachineRepository::get_npc_count(void) {
 | 
			
		||||
  int count = 0;
 | 
			
		||||
  _db << "SELECT count(*) FROM machines WHERE owner_id IS NULL;" >> count;
 | 
			
		||||
  return count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<MachineData> MachineRepository::get_all_npcs(void) {
 | 
			
		||||
  std::vector<MachineData> machines;
 | 
			
		||||
  _db << "SELECT id, ip_address FROM machines WHERE owner_id IS NULL;"
 | 
			
		||||
      >> [&](long long id, std::string ip_address) {
 | 
			
		||||
        machines.push_back({id, ip_address});
 | 
			
		||||
    };
 | 
			
		||||
  return machines;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										26
									
								
								common/src/db/machine_repository.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								common/src/db/machine_repository.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,26 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <optional>
 | 
			
		||||
#include "sqlite_modern_cpp.h"
 | 
			
		||||
 | 
			
		||||
/* Struct to hold machine data. */
 | 
			
		||||
struct MachineData {
 | 
			
		||||
  long long id;
 | 
			
		||||
  std::string ip_address;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class MachineRepository {
 | 
			
		||||
public:
 | 
			
		||||
  MachineRepository(sqlite::database& db);
 | 
			
		||||
 | 
			
		||||
  long long create(std::optional<long long> owner_id, const std::string& hostname,
 | 
			
		||||
                   const std::string& ip_address);
 | 
			
		||||
  int get_npc_count(void);
 | 
			
		||||
  std::vector<MachineData> get_all_npcs(void);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  sqlite::database& _db;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										34
									
								
								common/src/db/player_repository.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								common/src/db/player_repository.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
			
		||||
#include "player_repository.h"
 | 
			
		||||
 | 
			
		||||
PlayerRepository::PlayerRepository(sqlite::database& db) : _db(db) {}
 | 
			
		||||
 | 
			
		||||
long long PlayerRepository::create(const std::string& username, const std::string& password,
 | 
			
		||||
                         const std::string& hostname) {
 | 
			
		||||
  _db << "INSERT INTO players (username, password, hostname) VALUES (?, ?, ?);"
 | 
			
		||||
      << username
 | 
			
		||||
      << password
 | 
			
		||||
      << hostname;
 | 
			
		||||
  return _db.last_insert_rowid();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool PlayerRepository::authenticate(const std::string& username, const std::string& password) {
 | 
			
		||||
  bool authed = false;
 | 
			
		||||
  _db << "SELECT id FROM players WHERE username = ? AND password = ?;"
 | 
			
		||||
      << username
 | 
			
		||||
      << password
 | 
			
		||||
      >> [&](long long id) {authed = true;};
 | 
			
		||||
  return authed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
long long PlayerRepository::get_home_machine_id(const std::string& username) {
 | 
			
		||||
  long long machine_id = -1;
 | 
			
		||||
  _db << "SELECT home_machine_id FROM players WHERE username = ?;"
 | 
			
		||||
      << username
 | 
			
		||||
      >> machine_id;
 | 
			
		||||
  return machine_id;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PlayerRepository::set_home_machine_id(long long player_id, long long machine_id) {
 | 
			
		||||
  _db << "UPDATE players SET home_machine_id = ? WHERE id = ?;"
 | 
			
		||||
      << machine_id << player_id;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										19
									
								
								common/src/db/player_repository.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								common/src/db/player_repository.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "sqlite_modern_cpp.h"
 | 
			
		||||
 | 
			
		||||
class PlayerRepository {
 | 
			
		||||
public:
 | 
			
		||||
  PlayerRepository(sqlite::database& db);
 | 
			
		||||
 | 
			
		||||
  long long create(const std::string& username, const std::string& password,
 | 
			
		||||
                   const std::string& hostname);
 | 
			
		||||
  bool authenticate(const std::string& username, const std::string& password);
 | 
			
		||||
  long long get_home_machine_id(const std::string& username);
 | 
			
		||||
  void set_home_machine_id(long long player_id, long long machine_id);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  sqlite::database& _db;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										19
									
								
								common/src/db/service_repository.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								common/src/db/service_repository.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
			
		||||
#include "service_repository.h"
 | 
			
		||||
#include "sqlite_modern_cpp.h"
 | 
			
		||||
 | 
			
		||||
ServiceRepository::ServiceRepository(sqlite::database& db) : _db(db) {}
 | 
			
		||||
 | 
			
		||||
void ServiceRepository::create(long long machine_id, int port, const std::string& name) {
 | 
			
		||||
  _db << "INSERT INTO services (machine_id, port, name) VALUES (?, ?, ?);"
 | 
			
		||||
      << machine_id << port << name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::map<int, std::string> ServiceRepository::get_for_machine(long long machine_id) {
 | 
			
		||||
  std::map<int, std::string> services;
 | 
			
		||||
  _db << "SELECT port, name FROM services WHERE machine_id = ?;"
 | 
			
		||||
      << machine_id
 | 
			
		||||
      >> [&](int port, std::string name) {
 | 
			
		||||
        services[port] = name;
 | 
			
		||||
    };
 | 
			
		||||
  return services;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								common/src/db/service_repository.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								common/src/db/service_repository.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <map>
 | 
			
		||||
 | 
			
		||||
#include "sqlite_modern_cpp.h"
 | 
			
		||||
 | 
			
		||||
class ServiceRepository {
 | 
			
		||||
public:
 | 
			
		||||
  ServiceRepository(sqlite::database& db);
 | 
			
		||||
 | 
			
		||||
  void create(long long machine_id, int port, const std::string& name);
 | 
			
		||||
  std::map<int, std::string> get_for_machine(long long machine_id);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  sqlite::database& _db;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										35
									
								
								common/src/db/vfs_repository.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								common/src/db/vfs_repository.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
			
		||||
#include "vfs_repository.h"
 | 
			
		||||
 | 
			
		||||
VFSRepository::VFSRepository(sqlite::database& db) : _db(db) {}
 | 
			
		||||
 | 
			
		||||
long long VFSRepository::create_node(long long machine_id, long long* parent_id,
 | 
			
		||||
                                     const std::string& name, vfs_node_type type,
 | 
			
		||||
                                     const std::string& content) {
 | 
			
		||||
  if(parent_id) {
 | 
			
		||||
    _db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type, content) "
 | 
			
		||||
           "VALUES (?, ?, ?, ?, ?);"
 | 
			
		||||
        << machine_id << *parent_id << name << type << content;
 | 
			
		||||
  } else {
 | 
			
		||||
    _db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type, content) "
 | 
			
		||||
           "VALUES (?, NULL, ?, ?, ?);"
 | 
			
		||||
        << machine_id << name << type << content;
 | 
			
		||||
  }
 | 
			
		||||
  return _db.last_insert_rowid();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<vfs_node*> VFSRepository::get_nodes_for_machine(long long machine_id) {
 | 
			
		||||
  std::vector<vfs_node*> nodes;
 | 
			
		||||
  _db << "SELECT id, parent_id, name, type, content FROM vfs_nodes WHERE machine_id = ?;"
 | 
			
		||||
      << machine_id
 | 
			
		||||
      >> [&](long long id, long long parent_id, std::string name, int type, std::string content) {
 | 
			
		||||
        vfs_node* node  = new vfs_node();
 | 
			
		||||
        node->id        = id;
 | 
			
		||||
        node->parent_id = parent_id;
 | 
			
		||||
        node->name      = name;
 | 
			
		||||
        node->type      = (vfs_node_type) type;
 | 
			
		||||
        node->content   = content;
 | 
			
		||||
 | 
			
		||||
        nodes.push_back(node);
 | 
			
		||||
    };
 | 
			
		||||
  return nodes;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								common/src/db/vfs_repository.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								common/src/db/vfs_repository.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "vfs.h"
 | 
			
		||||
#include "sqlite_modern_cpp.h"
 | 
			
		||||
 | 
			
		||||
class VFSRepository {
 | 
			
		||||
public:
 | 
			
		||||
  VFSRepository(sqlite::database& db);
 | 
			
		||||
 | 
			
		||||
  long long create_node(long long machine_id, long long* parent_id,
 | 
			
		||||
                        const std::string& name, vfs_node_type type,
 | 
			
		||||
                        const std::string& content = "");
 | 
			
		||||
  std::vector<vfs_node*> get_nodes_for_machine(long long machine_id);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  sqlite::database& _db;
 | 
			
		||||
};
 | 
			
		||||
@ -107,32 +107,21 @@ Machine* MachineManager::load_machine(long long machine_id, DatabaseManager* db_
 | 
			
		||||
  Machine* machine = new Machine(machine_id, hostname);
 | 
			
		||||
 | 
			
		||||
  /* Load all VFS nodes for this machine from the database. */
 | 
			
		||||
  std::map<long long, vfs_node*> nodes;
 | 
			
		||||
  std::map<long long, vfs_node*> node_map;
 | 
			
		||||
  vfs_node* root = nullptr;
 | 
			
		||||
 | 
			
		||||
  db_manager->_db << "SELECT id, parent_id, name, type, content FROM vfs_nodes WHERE machine_id = ?;"
 | 
			
		||||
         << machine_id
 | 
			
		||||
         >> [&](long long id, long long parent_id, std::string name, int type, std::string content) {
 | 
			
		||||
      vfs_node* node = new vfs_node();
 | 
			
		||||
      node->id = id;
 | 
			
		||||
      node->parent_id = parent_id; /* Store temp id for tree building. */
 | 
			
		||||
      node->name = name;
 | 
			
		||||
      node->type = (vfs_node_type)type;
 | 
			
		||||
      node->content = content;
 | 
			
		||||
      nodes[id] = node;
 | 
			
		||||
      if(name == "/") {
 | 
			
		||||
        root = node;
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
  auto nodes = db_manager->vfs().get_nodes_for_machine(machine_id);
 | 
			
		||||
  for(vfs_node* node : nodes) {
 | 
			
		||||
    node_map[node->id] = node;
 | 
			
		||||
    if(node->name == "/") {
 | 
			
		||||
      root = node;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  db_manager->_db << "SELECT port, name FROM services WHERE machine_id = ?;"
 | 
			
		||||
                  << machine_id
 | 
			
		||||
                  >> [&](int port, std::string name) {
 | 
			
		||||
      machine->services[port] = name;
 | 
			
		||||
    };
 | 
			
		||||
  machine->services = _db_manager->services().get_for_machine(machine_id);
 | 
			
		||||
 | 
			
		||||
  if(root) {
 | 
			
		||||
    build_tree(root, nodes);
 | 
			
		||||
    build_tree(root, node_map);
 | 
			
		||||
    machine->vfs_root = root;
 | 
			
		||||
  }
 | 
			
		||||
  return machine;
 | 
			
		||||
 | 
			
		||||
@ -23,10 +23,11 @@ NetworkManager::NetworkManager(const std::string& db_path) :
 | 
			
		||||
  _seed_npc_machines();
 | 
			
		||||
 | 
			
		||||
  /* Load NPC machines from the database. */
 | 
			
		||||
  _db_manager->_db << "SELECT id, ip_address FROM machines WHERE owner_id IS NULL;"
 | 
			
		||||
                   >> [&](long long id, std::string ip_address) {
 | 
			
		||||
      _world_machines[ip_address] = _machine_manager.load_machine(id, _db_manager.get());
 | 
			
		||||
    };
 | 
			
		||||
  auto npc_machines = _db_manager->machines().get_all_npcs();
 | 
			
		||||
  for(const auto& machine_data : npc_machines) {
 | 
			
		||||
    _world_machines[machine_data.ip_address] =
 | 
			
		||||
      _machine_manager.load_machine(machine_data.id, _db_manager.get());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  fprintf(stderr, "Created world with %zu networks\n", _world_machines.size());
 | 
			
		||||
}
 | 
			
		||||
@ -133,7 +134,7 @@ void NetworkManager::on_message(std::shared_ptr<net::TcpConnection> connection,
 | 
			
		||||
      if(parts.size() == 3) {
 | 
			
		||||
        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->players().get_home_machine_id(parts[0]);
 | 
			
		||||
          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,
 | 
			
		||||
@ -152,8 +153,8 @@ void NetworkManager::on_message(std::shared_ptr<net::TcpConnection> connection,
 | 
			
		||||
      std::string payload = message.substr(7);
 | 
			
		||||
      auto parts = split_message(payload, "::");
 | 
			
		||||
      if(parts.size() == 2) {
 | 
			
		||||
        if(_db_manager->auth_player(parts[0], parts[1])) {
 | 
			
		||||
          long long machine_id = _db_manager->get_player_home_machine_id(parts[0]);
 | 
			
		||||
        if(_db_manager->players().authenticate(parts[0], parts[1])) {
 | 
			
		||||
          long long machine_id = _db_manager->players().get_home_machine_id(parts[0]);
 | 
			
		||||
          printf("DEBUG: Loading machine %lld for player %s\n", machine_id, parts[0].c_str());
 | 
			
		||||
          Machine* home_machine = _machine_manager.load_machine(machine_id, _db_manager.get());
 | 
			
		||||
          delete player->cmd_processor; /* Delete old command processor. */
 | 
			
		||||
@ -226,8 +227,7 @@ void NetworkManager::on_disconnect(std::shared_ptr<net::TcpConnection> connectio
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NetworkManager::_seed_npc_machines(void) {
 | 
			
		||||
  int npc_count = 0;
 | 
			
		||||
  _db_manager->_db << "SELECT count(*) FROM machines WHERE owner_id IS NULL;" >> npc_count;
 | 
			
		||||
  int npc_count = _db_manager->machines().get_npc_count();
 | 
			
		||||
 | 
			
		||||
  if(npc_count > 0) {
 | 
			
		||||
    return; /* NPC already in db. */
 | 
			
		||||
@ -248,38 +248,22 @@ void NetworkManager::_seed_npc_machines(void) {
 | 
			
		||||
 | 
			
		||||
  try {
 | 
			
		||||
    for(const auto& def : npc_defs) {
 | 
			
		||||
      _db_manager->_db << "INSERT INTO machines (hostname, ip_address) "
 | 
			
		||||
                          "VALUES(?, ?);"
 | 
			
		||||
                       << def.hostname << def.ip;
 | 
			
		||||
      long long machine_id = _db_manager->_db.last_insert_rowid();
 | 
			
		||||
      long long machine_id = _db_manager->machines().create({}, def.hostname, def.ip);
 | 
			
		||||
 | 
			
		||||
      /* Create a basic VFS for the NPC machines. */
 | 
			
		||||
      _db_manager->_db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type) "
 | 
			
		||||
                          "VALUES (?, NULL, ?, 1);"
 | 
			
		||||
                       << machine_id << "/";
 | 
			
		||||
      long long root_id = _db_manager->_db.last_insert_rowid();
 | 
			
		||||
      long long root_id = _db_manager->vfs().create_node(machine_id, nullptr, "/", DIR_NODE);
 | 
			
		||||
 | 
			
		||||
      _db_manager->_db  << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type) "
 | 
			
		||||
                           "VALUES (?, ?, ?, 1);"
 | 
			
		||||
                        << machine_id << root_id << "etc";
 | 
			
		||||
      long long etc_id = _db_manager->_db.last_insert_rowid();
 | 
			
		||||
      _db_manager->vfs().create_node(machine_id, &root_id, "etc", DIR_NODE);
 | 
			
		||||
 | 
			
		||||
      _db_manager->_db  << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type) "
 | 
			
		||||
                           "VALUES (?, ?, ?, 1);"
 | 
			
		||||
                        << machine_id << root_id << "bin";
 | 
			
		||||
      long long bin_id = _db_manager->_db.last_insert_rowid();
 | 
			
		||||
      long long bin_id = _db_manager->vfs().create_node(machine_id, &root_id, "bin", DIR_NODE);
 | 
			
		||||
 | 
			
		||||
      vfs_node* template_bin = _machine_manager.get_vfs_template()->children["bin"];
 | 
			
		||||
      for(auto const& [name, node] : template_bin->children) {
 | 
			
		||||
        _db_manager->_db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type, content) "
 | 
			
		||||
                            "VALUES(?, ?, ?, ?, ?);"
 | 
			
		||||
                         << machine_id << bin_id << name << FILE_NODE << node->content;
 | 
			
		||||
        _db_manager->vfs().create_node(machine_id, &bin_id, name, FILE_NODE, node->content);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      for(const auto& service : def.services) {
 | 
			
		||||
        _db_manager->_db << "INSERT INTO services (machine_id, port, name) "
 | 
			
		||||
                            "VALUES (?, ?, ?);"
 | 
			
		||||
                         << machine_id << service.first << service.second;
 | 
			
		||||
        _db_manager->services().create(machine_id, service.first, service.second);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } catch(const std::exception& e) {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user