Files
brandling-safari/server/Database.h
Gabe 238cd9c6c3 Brandling Safari: LAN safari-zone creature catching on the HD-2D engine
- Authoritative 30 Hz server (ENet, SQLite): accounts, characters, wild AI, tall grass /
  water / wandering spawns, fishing, captures, follower chains, clock + weather, LAN beacon
- Client: title / join / character creator / play screens, prediction + reconciliation,
  interpolated players and parties, HD-2D UI (dialogue with Professor Henry, HUD, collection)
- Shared deterministic zone generator, movement, protocol, roster, appearance
- Paper-doll character art pipeline (PixelLab base walk + per-item animation edits)
- Brandling roster from the company list (logo colors, jev types), Blender safari props
- Headless test bot
2026-10-02 15:20:27 -05:00

70 lines
2.1 KiB
C++

#pragma once
// SQLite persistence (WAL): accounts/characters, owned creatures, dex and a
// small key/value table for world state (clock, weather).
#include "Appearance.h"
#include "Protocol.h"
#include <set>
#include <string>
#include <unordered_map>
#include <vector>
struct sqlite3;
struct sqlite3_stmt;
namespace bs {
struct PlayerRow {
int64_t id = 0;
std::string token, name;
Appearance look;
float x = 0, z = 0, yaw = 0;
int capsules = 0;
bool introDone = false;
int64_t createdAt = 0, lastSeen = 0;
};
class Database {
public:
Database() = default;
Database(const Database&) = delete;
Database& operator=(const Database&) = delete;
~Database();
bool open(const std::string& path, std::string* error);
void close();
bool loadPlayer(const std::string& token, PlayerRow& out);
int64_t createPlayer(const PlayerRow& row); // returns the new id, 0 on failure
void savePlayer(const PlayerRow& row); // everything but token / created_at
void savePosition(int64_t id, float x, float z, float yaw);
std::vector<OwnedCreature> loadCreatures(int64_t owner);
uint32_t insertCreature(int64_t owner, uint16_t species, int64_t caughtAt, bool inParty); // uid, 0 on failure
void setInParty(uint32_t uid, bool inParty);
void loadDex(int64_t owner, std::set<uint16_t>& seen, std::set<uint16_t>& caught);
void markSeen(int64_t owner, uint16_t species);
void markCaught(int64_t owner, uint16_t species);
bool getWorld(const std::string& key, std::string& value);
void setWorld(const std::string& key, const std::string& value);
// Groups many writes into one transaction (shutdown, periodic saves).
void begin();
void commit();
private:
sqlite3_stmt* prepare(const char* sql); // cached, reset before reuse
bool exec(const char* sql);
sqlite3* db_ = nullptr;
std::unordered_map<const char*, sqlite3_stmt*> stmts_; // keyed by the SQL literal
};
std::string appearanceToJson(const Appearance& a);
Appearance appearanceFromJson(const std::string& s);
} // namespace bs