diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/database/database-files.cpp | 125 | ||||
-rw-r--r-- | src/database/database-files.h | 9 | ||||
-rw-r--r-- | src/remoteplayer.cpp | 116 | ||||
-rw-r--r-- | src/remoteplayer.h | 9 |
4 files changed, 115 insertions, 144 deletions
diff --git a/src/database/database-files.cpp b/src/database/database-files.cpp index d2b0b1543..529fb8763 100644 --- a/src/database/database-files.cpp +++ b/src/database/database-files.cpp @@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <cassert> #include <json/json.h> +#include "convert_json.h" #include "database-files.h" #include "remoteplayer.h" #include "settings.h" @@ -36,29 +37,117 @@ PlayerDatabaseFiles::PlayerDatabaseFiles(const std::string &savedir) : m_savedir fs::CreateDir(m_savedir); } -void PlayerDatabaseFiles::serialize(std::ostringstream &os, RemotePlayer *player) +void PlayerDatabaseFiles::deSerialize(RemotePlayer *p, std::istream &is, + const std::string &playername, PlayerSAO *sao) +{ + Settings args("PlayerArgsEnd"); + + if (!args.parseConfigLines(is)) { + throw SerializationError("PlayerArgsEnd of player " + playername + " not found!"); + } + + p->m_dirty = true; + //args.getS32("version"); // Version field value not used + const std::string &name = args.get("name"); + strlcpy(p->m_name, name.c_str(), PLAYERNAME_SIZE); + + if (sao) { + try { + sao->setHPRaw(args.getU16("hp")); + } catch(SettingNotFoundException &e) { + sao->setHPRaw(PLAYER_MAX_HP_DEFAULT); + } + + try { + sao->setBasePosition(args.getV3F("position")); + } catch (SettingNotFoundException &e) {} + + try { + sao->setLookPitch(args.getFloat("pitch")); + } catch (SettingNotFoundException &e) {} + try { + sao->setPlayerYaw(args.getFloat("yaw")); + } catch (SettingNotFoundException &e) {} + + try { + sao->setBreath(args.getU16("breath"), false); + } catch (SettingNotFoundException &e) {} + + try { + const std::string &extended_attributes = args.get("extended_attributes"); + std::istringstream iss(extended_attributes); + Json::CharReaderBuilder builder; + builder.settings_["collectComments"] = false; + std::string errs; + + Json::Value attr_root; + Json::parseFromStream(builder, iss, &attr_root, &errs); + + const Json::Value::Members attr_list = attr_root.getMemberNames(); + for (const auto &it : attr_list) { + Json::Value attr_value = attr_root[it]; + sao->getMeta().setString(it, attr_value.asString()); + } + sao->getMeta().setModified(false); + } catch (SettingNotFoundException &e) {} + } + + try { + p->inventory.deSerialize(is); + } catch (SerializationError &e) { + errorstream << "Failed to deserialize player inventory. player_name=" + << name << " " << e.what() << std::endl; + } + + if (!p->inventory.getList("craftpreview") && p->inventory.getList("craftresult")) { + // Convert players without craftpreview + p->inventory.addList("craftpreview", 1); + + bool craftresult_is_preview = true; + if(args.exists("craftresult_is_preview")) + craftresult_is_preview = args.getBool("craftresult_is_preview"); + if(craftresult_is_preview) + { + // Clear craftresult + p->inventory.getList("craftresult")->changeItem(0, ItemStack()); + } + } +} + +void PlayerDatabaseFiles::serialize(RemotePlayer *p, std::ostream &os) { // Utilize a Settings object for storing values - Settings args; + Settings args("PlayerArgsEnd"); args.setS32("version", 1); - args.set("name", player->getName()); + args.set("name", p->m_name); - sanity_check(player->getPlayerSAO()); - args.setU16("hp", player->getPlayerSAO()->getHP()); - args.setV3F("position", player->getPlayerSAO()->getBasePosition()); - args.setFloat("pitch", player->getPlayerSAO()->getLookPitch()); - args.setFloat("yaw", player->getPlayerSAO()->getRotation().Y); - args.setU16("breath", player->getPlayerSAO()->getBreath()); + // This should not happen + assert(m_sao); + args.setU16("hp", p->m_sao->getHP()); + args.setV3F("position", p->m_sao->getBasePosition()); + args.setFloat("pitch", p->m_sao->getLookPitch()); + args.setFloat("yaw", p->m_sao->getRotation().Y); + args.setU16("breath", p->m_sao->getBreath()); std::string extended_attrs; - player->serializeExtraAttributes(extended_attrs); + { + // serializeExtraAttributes + PlayerSAO *sao = p->getPlayerSAO(); + assert(sao); + Json::Value json_root; + + const StringMap &attrs = sao->getMeta().getStrings(); + for (const auto &attr : attrs) { + json_root[attr.first] = attr.second; + } + + extended_attrs = fastWriteJson(json_root); + } args.set("extended_attributes", extended_attrs); args.writeLines(os); - os << "PlayerArgsEnd\n"; - - player->inventory.serialize(os); + p->inventory.serialize(os); } void PlayerDatabaseFiles::savePlayer(RemotePlayer *player) @@ -83,7 +172,7 @@ void PlayerDatabaseFiles::savePlayer(RemotePlayer *player) return; } - testplayer.deSerialize(is, path, NULL); + deSerialize(&testplayer, is, path, NULL); is.close(); if (strcmp(testplayer.getName(), player->getName()) == 0) { path_found = true; @@ -101,7 +190,7 @@ void PlayerDatabaseFiles::savePlayer(RemotePlayer *player) // Open and serialize file std::ostringstream ss(std::ios_base::binary); - serialize(ss, player); + serialize(&testplayer, ss); if (!fs::safeWriteToFile(path, ss.str())) { infostream << "Failed to write " << path << std::endl; } @@ -121,7 +210,7 @@ bool PlayerDatabaseFiles::removePlayer(const std::string &name) if (!is.good()) continue; - temp_player.deSerialize(is, path, NULL); + deSerialize(&temp_player, is, path, NULL); is.close(); if (temp_player.getName() == name) { @@ -147,7 +236,7 @@ bool PlayerDatabaseFiles::loadPlayer(RemotePlayer *player, PlayerSAO *sao) if (!is.good()) continue; - player->deSerialize(is, path, sao); + deSerialize(player, is, path, sao); is.close(); if (player->getName() == player_to_load) @@ -180,7 +269,7 @@ void PlayerDatabaseFiles::listPlayers(std::vector<std::string> &res) // Null env & dummy peer_id PlayerSAO playerSAO(NULL, &player, 15789, false); - player.deSerialize(is, "", &playerSAO); + deSerialize(&player, is, "", &playerSAO); is.close(); res.emplace_back(player.getName()); diff --git a/src/database/database-files.h b/src/database/database-files.h index cb830a3ed..a041cb1ff 100644 --- a/src/database/database-files.h +++ b/src/database/database-files.h @@ -38,7 +38,14 @@ public: void listPlayers(std::vector<std::string> &res); private: - void serialize(std::ostringstream &os, RemotePlayer *player); + void deSerialize(RemotePlayer *p, std::istream &is, + const std::string &playername, PlayerSAO *sao); + /* + serialize() writes a bunch of text that can contain + any characters except a '\0', and such an ending that + deSerialize stops reading exactly at the right point. + */ + void serialize(RemotePlayer *p, std::ostream &os); std::string m_savedir; }; diff --git a/src/remoteplayer.cpp b/src/remoteplayer.cpp index bef60c792..925ad001b 100644 --- a/src/remoteplayer.cpp +++ b/src/remoteplayer.cpp @@ -83,122 +83,6 @@ RemotePlayer::RemotePlayer(const char *name, IItemDefManager *idef): m_star_params = sky_defaults.getStarDefaults(); } -void RemotePlayer::serializeExtraAttributes(std::string &output) -{ - assert(m_sao); - Json::Value json_root; - - const StringMap &attrs = m_sao->getMeta().getStrings(); - for (const auto &attr : attrs) { - json_root[attr.first] = attr.second; - } - - output = fastWriteJson(json_root); -} - - -void RemotePlayer::deSerialize(std::istream &is, const std::string &playername, - PlayerSAO *sao) -{ - Settings args; - - if (!args.parseConfigLines(is, "PlayerArgsEnd")) { - throw SerializationError("PlayerArgsEnd of player " + playername + " not found!"); - } - - m_dirty = true; - //args.getS32("version"); // Version field value not used - const std::string &name = args.get("name"); - strlcpy(m_name, name.c_str(), PLAYERNAME_SIZE); - - if (sao) { - try { - sao->setHPRaw(args.getU16("hp")); - } catch(SettingNotFoundException &e) { - sao->setHPRaw(PLAYER_MAX_HP_DEFAULT); - } - - try { - sao->setBasePosition(args.getV3F("position")); - } catch (SettingNotFoundException &e) {} - - try { - sao->setLookPitch(args.getFloat("pitch")); - } catch (SettingNotFoundException &e) {} - try { - sao->setPlayerYaw(args.getFloat("yaw")); - } catch (SettingNotFoundException &e) {} - - try { - sao->setBreath(args.getU16("breath"), false); - } catch (SettingNotFoundException &e) {} - - try { - const std::string &extended_attributes = args.get("extended_attributes"); - std::istringstream iss(extended_attributes); - Json::CharReaderBuilder builder; - builder.settings_["collectComments"] = false; - std::string errs; - - Json::Value attr_root; - Json::parseFromStream(builder, iss, &attr_root, &errs); - - const Json::Value::Members attr_list = attr_root.getMemberNames(); - for (const auto &it : attr_list) { - Json::Value attr_value = attr_root[it]; - sao->getMeta().setString(it, attr_value.asString()); - } - sao->getMeta().setModified(false); - } catch (SettingNotFoundException &e) {} - } - - try { - inventory.deSerialize(is); - } catch (SerializationError &e) { - errorstream << "Failed to deserialize player inventory. player_name=" - << name << " " << e.what() << std::endl; - } - - if (!inventory.getList("craftpreview") && inventory.getList("craftresult")) { - // Convert players without craftpreview - inventory.addList("craftpreview", 1); - - bool craftresult_is_preview = true; - if(args.exists("craftresult_is_preview")) - craftresult_is_preview = args.getBool("craftresult_is_preview"); - if(craftresult_is_preview) - { - // Clear craftresult - inventory.getList("craftresult")->changeItem(0, ItemStack()); - } - } -} - -void RemotePlayer::serialize(std::ostream &os) -{ - // Utilize a Settings object for storing values - Settings args; - args.setS32("version", 1); - args.set("name", m_name); - - // This should not happen - assert(m_sao); - args.setU16("hp", m_sao->getHP()); - args.setV3F("position", m_sao->getBasePosition()); - args.setFloat("pitch", m_sao->getLookPitch()); - args.setFloat("yaw", m_sao->getRotation().Y); - args.setU16("breath", m_sao->getBreath()); - - std::string extended_attrs; - serializeExtraAttributes(extended_attrs); - args.set("extended_attributes", extended_attrs); - - args.writeLines(os); - - os<<"PlayerArgsEnd\n"; - - inventory.serialize(os); -} const RemotePlayerChatResult RemotePlayer::canSendChatMessage() { diff --git a/src/remoteplayer.h b/src/remoteplayer.h index e4209c54f..b82cbc08e 100644 --- a/src/remoteplayer.h +++ b/src/remoteplayer.h @@ -44,8 +44,6 @@ public: RemotePlayer(const char *name, IItemDefManager *idef); virtual ~RemotePlayer() = default; - void deSerialize(std::istream &is, const std::string &playername, PlayerSAO *sao); - PlayerSAO *getPlayerSAO() { return m_sao; } void setPlayerSAO(PlayerSAO *sao) { m_sao = sao; } @@ -142,13 +140,6 @@ public: void onSuccessfulSave(); private: - /* - serialize() writes a bunch of text that can contain - any characters except a '\0', and such an ending that - deSerialize stops reading exactly at the right point. - */ - void serialize(std::ostream &os); - void serializeExtraAttributes(std::string &output); PlayerSAO *m_sao = nullptr; bool m_dirty = false; |