[Add] Persist NPC machines in the database.
This commit is contained in:
		
							parent
							
								
									97b60488de
								
							
						
					
					
						commit
						761283ca63
					
				@ -18,15 +18,25 @@ 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()) {
 | 
					    _machine_manager(_db_manager.get()) {
 | 
				
			||||||
  /* World setup. */
 | 
					 | 
				
			||||||
  _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");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* Specific npc services. */
 | 
					 | 
				
			||||||
  _world_machines["8.8.8.8"]->services[80] = "HTTPD v2.4";
 | 
					 | 
				
			||||||
  _world_machines["10.0.2.15"]->services[21] = "FTPd v3.0";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _db_manager->init();
 | 
					  _db_manager->init();
 | 
				
			||||||
 | 
					  _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());
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					   * TODO: Services are not yet persistant. I'll add them in-mem for now.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  if(_world_machines.count("8.8.8.8")) {
 | 
				
			||||||
 | 
					    _world_machines["8.8.8.8"]->services[80] = "HTTPD v2.4";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if(_world_machines.count("10.0.2.15")) {
 | 
				
			||||||
 | 
					    _world_machines["10.0.2.15"]->services[21] = "FTPd v3.0";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  fprintf(stderr, "Created world with %zu networks\n", _world_machines.size());
 | 
					  fprintf(stderr, "Created world with %zu networks\n", _world_machines.size());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -224,3 +234,58 @@ void NetworkManager::on_disconnect(std::shared_ptr<net::TcpConnection> connectio
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  _players.erase(player_id);
 | 
					  _players.erase(player_id);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void NetworkManager::_seed_npc_machines(void) {
 | 
				
			||||||
 | 
					  int npc_count = 0;
 | 
				
			||||||
 | 
					  _db_manager->_db << "SELECT count(*) FROM machines WHERE owner_id IS NULL;" >> npc_count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if(npc_count > 0) {
 | 
				
			||||||
 | 
					    return; /* NPC already in db. */
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  fprintf(stderr, "First run: Seeding NPC machines into database...\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  struct NpcDef {
 | 
				
			||||||
 | 
					    std::string hostname;
 | 
				
			||||||
 | 
					    std::string ip;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::vector<NpcDef> npc_defs = {
 | 
				
			||||||
 | 
					    {"dns.google", "8.8.8.8"},
 | 
				
			||||||
 | 
					    {"corp.internal", "10.0.2.15"}
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  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();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      /* 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();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      _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->_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();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      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;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } catch(const std::exception& e) {
 | 
				
			||||||
 | 
					    fprintf(stderr, "Error seeding NPCs: %s. Database may be in an inconsistent state.\n", e.what());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -28,6 +28,8 @@ private:
 | 
				
			|||||||
                  const std::string& message);
 | 
					                  const std::string& message);
 | 
				
			||||||
  void on_disconnect(std::shared_ptr<net::TcpConnection> connection);
 | 
					  void on_disconnect(std::shared_ptr<net::TcpConnection> connection);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void _seed_npc_machines(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  asio::io_context _io_context;
 | 
					  asio::io_context _io_context;
 | 
				
			||||||
  std::thread _context_thread;
 | 
					  std::thread _context_thread;
 | 
				
			||||||
  asio::ip::tcp::acceptor _acceptor;
 | 
					  asio::ip::tcp::acceptor _acceptor;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user