@@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
19
19
20
20
#include < cassert>
21
21
#include < json/json.h>
22
+ #include " convert_json.h"
22
23
#include " database-files.h"
23
24
#include " remoteplayer.h"
24
25
#include " settings.h"
@@ -36,29 +37,117 @@ PlayerDatabaseFiles::PlayerDatabaseFiles(const std::string &savedir) : m_savedir
36
37
fs::CreateDir (m_savedir);
37
38
}
38
39
39
- void PlayerDatabaseFiles::serialize (std::ostringstream &os, RemotePlayer *player)
40
+ void PlayerDatabaseFiles::deSerialize (RemotePlayer *p, std::istream &is,
41
+ const std::string &playername, PlayerSAO *sao)
42
+ {
43
+ Settings args (" PlayerArgsEnd" );
44
+
45
+ if (!args.parseConfigLines (is)) {
46
+ throw SerializationError (" PlayerArgsEnd of player " + playername + " not found!" );
47
+ }
48
+
49
+ p->m_dirty = true ;
50
+ // args.getS32("version"); // Version field value not used
51
+ const std::string &name = args.get (" name" );
52
+ strlcpy (p->m_name , name.c_str (), PLAYERNAME_SIZE);
53
+
54
+ if (sao) {
55
+ try {
56
+ sao->setHPRaw (args.getU16 (" hp" ));
57
+ } catch (SettingNotFoundException &e) {
58
+ sao->setHPRaw (PLAYER_MAX_HP_DEFAULT);
59
+ }
60
+
61
+ try {
62
+ sao->setBasePosition (args.getV3F (" position" ));
63
+ } catch (SettingNotFoundException &e) {}
64
+
65
+ try {
66
+ sao->setLookPitch (args.getFloat (" pitch" ));
67
+ } catch (SettingNotFoundException &e) {}
68
+ try {
69
+ sao->setPlayerYaw (args.getFloat (" yaw" ));
70
+ } catch (SettingNotFoundException &e) {}
71
+
72
+ try {
73
+ sao->setBreath (args.getU16 (" breath" ), false );
74
+ } catch (SettingNotFoundException &e) {}
75
+
76
+ try {
77
+ const std::string &extended_attributes = args.get (" extended_attributes" );
78
+ std::istringstream iss (extended_attributes);
79
+ Json::CharReaderBuilder builder;
80
+ builder.settings_ [" collectComments" ] = false ;
81
+ std::string errs;
82
+
83
+ Json::Value attr_root;
84
+ Json::parseFromStream (builder, iss, &attr_root, &errs);
85
+
86
+ const Json::Value::Members attr_list = attr_root.getMemberNames ();
87
+ for (const auto &it : attr_list) {
88
+ Json::Value attr_value = attr_root[it];
89
+ sao->getMeta ().setString (it, attr_value.asString ());
90
+ }
91
+ sao->getMeta ().setModified (false );
92
+ } catch (SettingNotFoundException &e) {}
93
+ }
94
+
95
+ try {
96
+ p->inventory .deSerialize (is);
97
+ } catch (SerializationError &e) {
98
+ errorstream << " Failed to deserialize player inventory. player_name="
99
+ << name << " " << e.what () << std::endl;
100
+ }
101
+
102
+ if (!p->inventory .getList (" craftpreview" ) && p->inventory .getList (" craftresult" )) {
103
+ // Convert players without craftpreview
104
+ p->inventory .addList (" craftpreview" , 1 );
105
+
106
+ bool craftresult_is_preview = true ;
107
+ if (args.exists (" craftresult_is_preview" ))
108
+ craftresult_is_preview = args.getBool (" craftresult_is_preview" );
109
+ if (craftresult_is_preview)
110
+ {
111
+ // Clear craftresult
112
+ p->inventory .getList (" craftresult" )->changeItem (0 , ItemStack ());
113
+ }
114
+ }
115
+ }
116
+
117
+ void PlayerDatabaseFiles::serialize (RemotePlayer *p, std::ostream &os)
40
118
{
41
119
// Utilize a Settings object for storing values
42
- Settings args;
120
+ Settings args ( " PlayerArgsEnd " ) ;
43
121
args.setS32 (" version" , 1 );
44
- args.set (" name" , player-> getName () );
122
+ args.set (" name" , p-> m_name );
45
123
46
- sanity_check (player->getPlayerSAO ());
47
- args.setU16 (" hp" , player->getPlayerSAO ()->getHP ());
48
- args.setV3F (" position" , player->getPlayerSAO ()->getBasePosition ());
49
- args.setFloat (" pitch" , player->getPlayerSAO ()->getLookPitch ());
50
- args.setFloat (" yaw" , player->getPlayerSAO ()->getRotation ().Y );
51
- args.setU16 (" breath" , player->getPlayerSAO ()->getBreath ());
124
+ // This should not happen
125
+ assert (m_sao);
126
+ args.setU16 (" hp" , p->m_sao ->getHP ());
127
+ args.setV3F (" position" , p->m_sao ->getBasePosition ());
128
+ args.setFloat (" pitch" , p->m_sao ->getLookPitch ());
129
+ args.setFloat (" yaw" , p->m_sao ->getRotation ().Y );
130
+ args.setU16 (" breath" , p->m_sao ->getBreath ());
52
131
53
132
std::string extended_attrs;
54
- player->serializeExtraAttributes (extended_attrs);
133
+ {
134
+ // serializeExtraAttributes
135
+ PlayerSAO *sao = p->getPlayerSAO ();
136
+ assert (sao);
137
+ Json::Value json_root;
138
+
139
+ const StringMap &attrs = sao->getMeta ().getStrings ();
140
+ for (const auto &attr : attrs) {
141
+ json_root[attr.first ] = attr.second ;
142
+ }
143
+
144
+ extended_attrs = fastWriteJson (json_root);
145
+ }
55
146
args.set (" extended_attributes" , extended_attrs);
56
147
57
148
args.writeLines (os);
58
149
59
- os << " PlayerArgsEnd\n " ;
60
-
61
- player->inventory .serialize (os);
150
+ p->inventory .serialize (os);
62
151
}
63
152
64
153
void PlayerDatabaseFiles::savePlayer (RemotePlayer *player)
@@ -83,7 +172,7 @@ void PlayerDatabaseFiles::savePlayer(RemotePlayer *player)
83
172
return ;
84
173
}
85
174
86
- testplayer. deSerialize (is, path, NULL );
175
+ deSerialize (&testplayer, is, path, NULL );
87
176
is.close ();
88
177
if (strcmp (testplayer.getName (), player->getName ()) == 0 ) {
89
178
path_found = true ;
@@ -101,7 +190,7 @@ void PlayerDatabaseFiles::savePlayer(RemotePlayer *player)
101
190
102
191
// Open and serialize file
103
192
std::ostringstream ss (std::ios_base::binary);
104
- serialize (ss, player );
193
+ serialize (&testplayer, ss );
105
194
if (!fs::safeWriteToFile (path, ss.str ())) {
106
195
infostream << " Failed to write " << path << std::endl;
107
196
}
@@ -121,7 +210,7 @@ bool PlayerDatabaseFiles::removePlayer(const std::string &name)
121
210
if (!is.good ())
122
211
continue ;
123
212
124
- temp_player. deSerialize (is, path, NULL );
213
+ deSerialize (&temp_player, is, path, NULL );
125
214
is.close ();
126
215
127
216
if (temp_player.getName () == name) {
@@ -147,7 +236,7 @@ bool PlayerDatabaseFiles::loadPlayer(RemotePlayer *player, PlayerSAO *sao)
147
236
if (!is.good ())
148
237
continue ;
149
238
150
- player-> deSerialize (is, path, sao);
239
+ deSerialize (player, is, path, sao);
151
240
is.close ();
152
241
153
242
if (player->getName () == player_to_load)
@@ -180,7 +269,7 @@ void PlayerDatabaseFiles::listPlayers(std::vector<std::string> &res)
180
269
// Null env & dummy peer_id
181
270
PlayerSAO playerSAO (NULL , &player, 15789 , false );
182
271
183
- player. deSerialize (is, " " , &playerSAO);
272
+ deSerialize (&player, is, " " , &playerSAO);
184
273
is.close ();
185
274
186
275
res.emplace_back (player.getName ());
0 commit comments