[Add] Persist NPC machines in the database.

This commit is contained in:
Ritchie Cunningham 2025-10-07 19:32:30 +01:00
parent 97b60488de
commit 761283ca63
2 changed files with 74 additions and 7 deletions

View File

@ -18,15 +18,25 @@ NetworkManager::NetworkManager(const std::string& db_path) :
_db_manager(std::make_unique<DatabaseManager>(db_path)),
_acceptor(_io_context),
_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();
_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());
}
@ -224,3 +234,58 @@ void NetworkManager::on_disconnect(std::shared_ptr<net::TcpConnection> connectio
_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());
}
}

View File

@ -28,6 +28,8 @@ private:
const std::string& message);
void on_disconnect(std::shared_ptr<net::TcpConnection> connection);
void _seed_npc_machines(void);
asio::io_context _io_context;
std::thread _context_thread;
asio::ip::tcp::acceptor _acceptor;