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
This commit is contained in:
69
server/Database.h
Normal file
69
server/Database.h
Normal file
@@ -0,0 +1,69 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user