diff options
Diffstat (limited to 'src/database/database-leveldb.cpp')
-rw-r--r-- | src/database/database-leveldb.cpp | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/src/database/database-leveldb.cpp b/src/database/database-leveldb.cpp index 1aab4c43d..1976ae13d 100644 --- a/src/database/database-leveldb.cpp +++ b/src/database/database-leveldb.cpp @@ -26,6 +26,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "log.h" #include "filesys.h" #include "exceptions.h" +#include "remoteplayer.h" +#include "server/player_sao.h" #include "util/serialize.h" #include "util/string.h" @@ -98,6 +100,116 @@ void Database_LevelDB::listAllLoadableBlocks(std::vector<v3s16> &dst) delete it; } +PlayerDatabaseLevelDB::PlayerDatabaseLevelDB(const std::string &savedir) +{ + leveldb::Options options; + options.create_if_missing = true; + leveldb::Status status = leveldb::DB::Open(options, + savedir + DIR_DELIM + "players.db", &m_database); + ENSURE_STATUS_OK(status); +} + +PlayerDatabaseLevelDB::~PlayerDatabaseLevelDB() +{ + delete m_database; +} + +void PlayerDatabaseLevelDB::savePlayer(RemotePlayer *player) +{ + /* + u8 version = 1 + u16 hp + v3f position + f32 pitch + f32 yaw + u16 breath + u32 attribute_count + for each attribute { + std::string name + std::string (long) value + } + std::string (long) serialized_inventory + */ + + std::ostringstream os; + writeU8(os, 1); + + PlayerSAO *sao = player->getPlayerSAO(); + sanity_check(sao); + writeU16(os, sao->getHP()); + writeV3F32(os, sao->getBasePosition()); + writeF32(os, sao->getLookPitch()); + writeF32(os, sao->getRotation().Y); + writeU16(os, sao->getBreath()); + + StringMap stringvars = sao->getMeta().getStrings(); + writeU32(os, stringvars.size()); + for (const auto &it : stringvars) { + os << serializeString(it.first); + os << serializeLongString(it.second); + } + + player->inventory.serialize(os); + + leveldb::Status status = m_database->Put(leveldb::WriteOptions(), + player->getName(), os.str()); + ENSURE_STATUS_OK(status); + player->onSuccessfulSave(); +} + +bool PlayerDatabaseLevelDB::removePlayer(const std::string &name) +{ + leveldb::Status s = m_database->Delete(leveldb::WriteOptions(), name); + return s.ok(); +} + +bool PlayerDatabaseLevelDB::loadPlayer(RemotePlayer *player, PlayerSAO *sao) +{ + std::string raw; + leveldb::Status s = m_database->Get(leveldb::ReadOptions(), + player->getName(), &raw); + if (!s.ok()) + return false; + std::istringstream is(raw); + + if (readU8(is) > 1) + return false; + + sao->setHPRaw(readU16(is)); + sao->setBasePosition(readV3F32(is)); + sao->setLookPitch(readF32(is)); + sao->setPlayerYaw(readF32(is)); + sao->setBreath(readU16(is), false); + + u32 attribute_count = readU32(is); + for (u32 i = 0; i < attribute_count; i++) { + std::string name = deSerializeString(is); + std::string value = deSerializeLongString(is); + sao->getMeta().setString(name, value); + } + sao->getMeta().setModified(false); + + // This should always be last. + try { + player->inventory.deSerialize(is); + } catch (SerializationError &e) { + errorstream << "Failed to deserialize player inventory. player_name=" + << player->getName() << " " << e.what() << std::endl; + } + + return true; +} + +void PlayerDatabaseLevelDB::listPlayers(std::vector<std::string> &res) +{ + leveldb::Iterator* it = m_database->NewIterator(leveldb::ReadOptions()); + res.clear(); + for (it->SeekToFirst(); it->Valid(); it->Next()) { + res.push_back(it->key().ToString()); + } + delete it; +} + AuthDatabaseLevelDB::AuthDatabaseLevelDB(const std::string &savedir) { leveldb::Options options; |