[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 "database_manager.h"
 | 
				
			||||||
 | 
					#include <memory>
 | 
				
			||||||
#include "vfs.h"
 | 
					#include "vfs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DatabaseManager::DatabaseManager(const std::string& db_path) : _db(db_path) {
 | 
					DatabaseManager::DatabaseManager(const std::string& db_path) :
 | 
				
			||||||
  /* db is opened in the construtor's init list. */
 | 
					    _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) {
 | 
					DatabaseManager::~DatabaseManager(void) {
 | 
				
			||||||
@ -49,51 +54,33 @@ bool DatabaseManager::create_player(const std::string& username, const std::stri
 | 
				
			|||||||
  try {
 | 
					  try {
 | 
				
			||||||
    _db << "BEGIN;";
 | 
					    _db << "BEGIN;";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Create the player. */
 | 
					    player_id = _player_repository->create(username, password, hostname);
 | 
				
			||||||
    _db << "INSERT INTO players (username, password, hostname) VALUES (?, ?, ?);"
 | 
					 | 
				
			||||||
        << username
 | 
					 | 
				
			||||||
        << password
 | 
					 | 
				
			||||||
        << hostname;
 | 
					 | 
				
			||||||
    player_id = _db.last_insert_rowid();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Create the home machine. */
 | 
					    /* Create the home machine. */
 | 
				
			||||||
    /* TODO: Implement real IP allication. */
 | 
					    /* TODO: Implement real IP allication. */
 | 
				
			||||||
    std::string ip_address = "192.168.1." + std::to_string(player_id);
 | 
					    std::string ip_address = "192.168.1." + std::to_string(player_id);
 | 
				
			||||||
    _db << "INSERT INTO machines (owner_id, hostname, ip_address) VALUES (?, ?, ?);"
 | 
					    machine_id = _machine_repository->create(player_id, hostname, ip_address);
 | 
				
			||||||
        << player_id << hostname << ip_address;
 | 
					 | 
				
			||||||
    machine_id = _db.last_insert_rowid();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Link player to their new machine. */
 | 
					    _player_repository->set_home_machine_id(player_id, machine_id);
 | 
				
			||||||
    _db << "UPDATE players SET home_machine_id = ? WHERE id = ?;"
 | 
					 | 
				
			||||||
        << machine_id << player_id;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Create the root dir for the new machine's VFS. */
 | 
					    /* Create the root dir for the new machine's VFS. */
 | 
				
			||||||
    _db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type) VALUES(?, NULL, ?, 1);"
 | 
					    long long root_id = _vfs_repository->create_node(machine_id, nullptr, "/", DIR_NODE);
 | 
				
			||||||
        << machine_id << "/";
 | 
					 | 
				
			||||||
    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);"
 | 
					    _vfs_repository->create_node(machine_id, &root_id, "home", DIR_NODE);
 | 
				
			||||||
        << machine_id << root_id << "home";
 | 
					    _vfs_repository->create_node(machine_id, &root_id, "etc", DIR_NODE);
 | 
				
			||||||
    _db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type) VALUES (?, ?, ?, 1);"
 | 
					 | 
				
			||||||
        << machine_id << root_id << "etc";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Create /bing and get it's ID */
 | 
					    /* Create /bin and get it's ID */
 | 
				
			||||||
    _db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type) VALUES(?, ?, ?, 1);"
 | 
					    long long bin_id = _vfs_repository->create_node(machine_id, &root_id, "bin", DIR_NODE);
 | 
				
			||||||
        << machine_id << root_id << "bin";
 | 
					 | 
				
			||||||
    long long bin_id = _db.last_insert_rowid();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Copy scripts from template into new machine's /bin */
 | 
					    /* Copy scripts from template into new machine's /bin */
 | 
				
			||||||
    vfs_node* template_bin = vfs_template->children["bin"];
 | 
					    vfs_node* template_bin = vfs_template->children["bin"];
 | 
				
			||||||
    for(auto const& [name, node] : template_bin->children) {
 | 
					    for(auto const& [name, node] : template_bin->children) {
 | 
				
			||||||
      _db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type, content) "
 | 
					      _vfs_repository->create_node(machine_id, &bin_id, name, FILE_NODE, node->content);
 | 
				
			||||||
             "VALUES (?, ?, ?, ?, ?);"
 | 
					 | 
				
			||||||
          << machine_id << bin_id << name << FILE_NODE <<node->content;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Add default SSH service. */
 | 
					    /* Add default SSH service. */
 | 
				
			||||||
    _db << "INSERT INTO services (machine_id, port, name) VALUES (?, ?, ?);"
 | 
					    _service_repository->create(machine_id, 22, "SSH");
 | 
				
			||||||
        << machine_id << 22 << "SSH";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _db << "COMMIT";
 | 
					    _db << "COMMIT";
 | 
				
			||||||
  } catch(const std::exception& e) {
 | 
					  } catch(const std::exception& e) {
 | 
				
			||||||
@ -102,21 +89,3 @@ bool DatabaseManager::create_player(const std::string& username, const std::stri
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  return true;
 | 
					  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
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <string>
 | 
					#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 "vfs.h"
 | 
				
			||||||
#include "db.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DatabaseManager {
 | 
					class DatabaseManager {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
@ -16,10 +21,16 @@ public:
 | 
				
			|||||||
  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, vfs_node* vfs_template);
 | 
					                     const std::string& hostname, vfs_node* vfs_template);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Return true if creds are valid. */
 | 
					  PlayerRepository& players(void)   { return *_player_repository;  }
 | 
				
			||||||
  bool auth_player(const std::string& username, const std::string& password);
 | 
					  MachineRepository& machines(void) { return *_machine_repository; }
 | 
				
			||||||
 | 
					  ServiceRepository& services(void) { return *_service_repository; }
 | 
				
			||||||
  long long get_player_home_machine_id(const std::string& username);
 | 
					  VFSRepository& vfs(void)          { return *_vfs_repository;     }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  sqlite::database _db;
 | 
					  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);
 | 
					  Machine* machine = new Machine(machine_id, hostname);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Load all VFS nodes for this machine from the database. */
 | 
					  /* 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;
 | 
					  vfs_node* root = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  db_manager->_db << "SELECT id, parent_id, name, type, content FROM vfs_nodes WHERE machine_id = ?;"
 | 
					  auto nodes = db_manager->vfs().get_nodes_for_machine(machine_id);
 | 
				
			||||||
         << machine_id
 | 
					  for(vfs_node* node : nodes) {
 | 
				
			||||||
         >> [&](long long id, long long parent_id, std::string name, int type, std::string content) {
 | 
					    node_map[node->id] = node;
 | 
				
			||||||
      vfs_node* node = new vfs_node();
 | 
					    if(node->name == "/") {
 | 
				
			||||||
      node->id = id;
 | 
					      root = node;
 | 
				
			||||||
      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;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  db_manager->_db << "SELECT port, name FROM services WHERE machine_id = ?;"
 | 
					  machine->services = _db_manager->services().get_for_machine(machine_id);
 | 
				
			||||||
                  << machine_id
 | 
					 | 
				
			||||||
                  >> [&](int port, std::string name) {
 | 
					 | 
				
			||||||
      machine->services[port] = name;
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(root) {
 | 
					  if(root) {
 | 
				
			||||||
    build_tree(root, nodes);
 | 
					    build_tree(root, node_map);
 | 
				
			||||||
    machine->vfs_root = root;
 | 
					    machine->vfs_root = root;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return machine;
 | 
					  return machine;
 | 
				
			||||||
 | 
				
			|||||||
@ -23,10 +23,11 @@ NetworkManager::NetworkManager(const std::string& db_path) :
 | 
				
			|||||||
  _seed_npc_machines();
 | 
					  _seed_npc_machines();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* Load NPC machines from the database. */
 | 
					  /* Load NPC machines from the database. */
 | 
				
			||||||
  _db_manager->_db << "SELECT id, ip_address FROM machines WHERE owner_id IS NULL;"
 | 
					  auto npc_machines = _db_manager->machines().get_all_npcs();
 | 
				
			||||||
                   >> [&](long long id, std::string ip_address) {
 | 
					  for(const auto& machine_data : npc_machines) {
 | 
				
			||||||
      _world_machines[ip_address] = _machine_manager.load_machine(id, _db_manager.get());
 | 
					    _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());
 | 
					  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(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())) {
 | 
					                                      _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());
 | 
					          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,
 | 
				
			||||||
@ -152,8 +153,8 @@ 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() == 2) {
 | 
					      if(parts.size() == 2) {
 | 
				
			||||||
        if(_db_manager->auth_player(parts[0], parts[1])) {
 | 
					        if(_db_manager->players().authenticate(parts[0], parts[1])) {
 | 
				
			||||||
          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]);
 | 
				
			||||||
          printf("DEBUG: Loading machine %lld for player %s\n", machine_id, parts[0].c_str());
 | 
					          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());
 | 
					          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. */
 | 
				
			||||||
@ -226,8 +227,7 @@ void NetworkManager::on_disconnect(std::shared_ptr<net::TcpConnection> connectio
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void NetworkManager::_seed_npc_machines(void) {
 | 
					void NetworkManager::_seed_npc_machines(void) {
 | 
				
			||||||
  int npc_count = 0;
 | 
					  int npc_count = _db_manager->machines().get_npc_count();
 | 
				
			||||||
  _db_manager->_db << "SELECT count(*) FROM machines WHERE owner_id IS NULL;" >> npc_count;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(npc_count > 0) {
 | 
					  if(npc_count > 0) {
 | 
				
			||||||
    return; /* NPC already in db. */
 | 
					    return; /* NPC already in db. */
 | 
				
			||||||
@ -248,38 +248,22 @@ void NetworkManager::_seed_npc_machines(void) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  try {
 | 
					  try {
 | 
				
			||||||
    for(const auto& def : npc_defs) {
 | 
					    for(const auto& def : npc_defs) {
 | 
				
			||||||
      _db_manager->_db << "INSERT INTO machines (hostname, ip_address) "
 | 
					      long long machine_id = _db_manager->machines().create({}, def.hostname, def.ip);
 | 
				
			||||||
                          "VALUES(?, ?);"
 | 
					 | 
				
			||||||
                       << def.hostname << def.ip;
 | 
					 | 
				
			||||||
      long long machine_id = _db_manager->_db.last_insert_rowid();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      /* Create a basic VFS for the NPC machines. */
 | 
					      /* Create a basic VFS for the NPC machines. */
 | 
				
			||||||
      _db_manager->_db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type) "
 | 
					      long long root_id = _db_manager->vfs().create_node(machine_id, nullptr, "/", DIR_NODE);
 | 
				
			||||||
                          "VALUES (?, NULL, ?, 1);"
 | 
					 | 
				
			||||||
                       << machine_id << "/";
 | 
					 | 
				
			||||||
      long long root_id = _db_manager->_db.last_insert_rowid();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      _db_manager->_db  << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type) "
 | 
					      _db_manager->vfs().create_node(machine_id, &root_id, "etc", DIR_NODE);
 | 
				
			||||||
                           "VALUES (?, ?, ?, 1);"
 | 
					 | 
				
			||||||
                        << machine_id << root_id << "etc";
 | 
					 | 
				
			||||||
      long long etc_id = _db_manager->_db.last_insert_rowid();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      _db_manager->_db  << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type) "
 | 
					      long long bin_id = _db_manager->vfs().create_node(machine_id, &root_id, "bin", DIR_NODE);
 | 
				
			||||||
                           "VALUES (?, ?, ?, 1);"
 | 
					 | 
				
			||||||
                        << machine_id << root_id << "bin";
 | 
					 | 
				
			||||||
      long long bin_id = _db_manager->_db.last_insert_rowid();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      vfs_node* template_bin = _machine_manager.get_vfs_template()->children["bin"];
 | 
					      vfs_node* template_bin = _machine_manager.get_vfs_template()->children["bin"];
 | 
				
			||||||
      for(auto const& [name, node] : template_bin->children) {
 | 
					      for(auto const& [name, node] : template_bin->children) {
 | 
				
			||||||
        _db_manager->_db << "INSERT INTO vfs_nodes (machine_id, parent_id, name, type, content) "
 | 
					        _db_manager->vfs().create_node(machine_id, &bin_id, name, FILE_NODE, node->content);
 | 
				
			||||||
                            "VALUES(?, ?, ?, ?, ?);"
 | 
					 | 
				
			||||||
                         << machine_id << bin_id << name << FILE_NODE << node->content;
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      for(const auto& service : def.services) {
 | 
					      for(const auto& service : def.services) {
 | 
				
			||||||
        _db_manager->_db << "INSERT INTO services (machine_id, port, name) "
 | 
					        _db_manager->services().create(machine_id, service.first, service.second);
 | 
				
			||||||
                            "VALUES (?, ?, ?);"
 | 
					 | 
				
			||||||
                         << machine_id << service.first << service.second;
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } catch(const std::exception& e) {
 | 
					  } catch(const std::exception& e) {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user