]>
Commit | Line | Data |
---|---|---|
ce4e8c42 | 1 | #include <GameServ/DataLayer/File/FilePlayerDAO.h>\r |
2 | using GameServ::DataLayer::File::FilePlayerDAO;\r | |
e0306362 | 3 | #include <GameServ/DataLayer/File/FileItemDAO.h>\r |
4 | using GameServ::DataLayer::File::FileItemDAO;\r | |
c7b7180e | 5 | \r |
ce4e8c42 | 6 | #include <GameServ/GameLayer/GameObjects/PlayerGO.h>\r |
7 | using GameServ::GameLayer::GameObjects::PlayerGO;\r | |
8 | \r | |
9 | #include <GameServ/DataLayer/DataLayerExceptions.h>\r | |
10 | using GameServ::DataLayer::Exceptions::ResourceException;\r | |
11 | using GameServ::DataLayer::Exceptions::DataLayerException;\r | |
12 | \r | |
f4f0d89d | 13 | #include <GameServ/DataLayer/File/FileId.h>\r |
14 | using GameServ::DataLayer::File::FileId;\r | |
15 | \r | |
cce88913 | 16 | #include <boost/smart_ptr/shared_ptr.hpp>\r |
ce4e8c42 | 17 | #include <boost/format.hpp>\r |
18 | #include <boost/algorithm/string.hpp>\r | |
19 | #include <boost/lexical_cast.hpp>\r | |
20 | using boost::shared_ptr;\r | |
e0306362 | 21 | using boost::shared_static_cast;\r |
ce4e8c42 | 22 | using boost::format;\r |
23 | using boost::str;\r | |
24 | using boost::algorithm::to_upper;\r | |
cb255541 | 25 | using boost::algorithm::to_lower;\r |
ce4e8c42 | 26 | using boost::lexical_cast;\r |
9c917833 | 27 | using boost::bad_lexical_cast;\r |
ce4e8c42 | 28 | #include <boost/tokenizer.hpp>\r |
29 | typedef boost::tokenizer<boost::char_separator<char> > \r | |
30 | tokenizer;\r | |
31 | \r | |
c7b7180e | 32 | #include <boost/date_time/posix_time/posix_time.hpp>\r |
9c917833 | 33 | using namespace boost::posix_time;\r |
c7b7180e | 34 | \r |
35 | #include <time.h>\r | |
36 | \r | |
ce4e8c42 | 37 | #include <string>\r |
38 | using std::string;\r | |
39 | \r | |
40 | #include <fstream>\r | |
41 | using std::ifstream;\r | |
42 | using std::getline;\r | |
f4f0d89d | 43 | using std::ofstream;\r |
44 | using std::endl;\r | |
ce4e8c42 | 45 | \r |
f4f0d89d | 46 | #include <map>\r |
47 | using std::map;\r | |
ce4e8c42 | 48 | \r |
e823e42a | 49 | FilePlayerDAO::FilePlayerDAO() : mFilename("data\\players.dat")\r |
ce4e8c42 | 50 | {\r |
51 | Initialize(GetPlayerFilePath());\r | |
52 | }\r | |
53 | \r | |
54 | FilePlayerDAO::FilePlayerDAO(const string &filename)\r | |
55 | {\r | |
56 | Initialize(filename);\r | |
57 | }\r | |
58 | \r | |
59 | FilePlayerDAO::~FilePlayerDAO()\r | |
60 | {\r | |
61 | }\r | |
62 | \r | |
63 | void FilePlayerDAO::Initialize(const string &filename)\r | |
64 | {\r | |
65 | mFilename = filename;\r | |
f4f0d89d | 66 | LoadPlayerCache();\r |
67 | }\r | |
68 | \r | |
cb255541 | 69 | void FilePlayerDAO::LoadPlayerCache(void)\r |
f4f0d89d | 70 | {\r |
71 | assert(!mFilename.empty());\r | |
72 | spPlayerCache.clear();\r | |
73 | ifstream infile;\r | |
74 | infile.open(mFilename.c_str());\r | |
75 | if (infile.fail())\r | |
76 | {\r | |
77 | throw DataLayerException(str(format("Unable to open %1% for loading Players") % mFilename),\r | |
78 | __FILE__, __LINE__);\r | |
79 | }\r | |
80 | while (!infile.eof())\r | |
81 | {\r | |
82 | string line;\r | |
83 | shared_ptr<PlayerGO> spPlayer;\r | |
84 | getline(infile, line);\r | |
85 | spPlayer = CreatePlayerFromLine(line);\r | |
cb255541 | 86 | string id = spPlayer->Id();\r |
87 | to_lower(id);\r | |
88 | spPlayerCache[id] = spPlayer;\r | |
f4f0d89d | 89 | }\r |
90 | infile.close();\r | |
91 | }\r | |
92 | \r | |
cb255541 | 93 | void FilePlayerDAO::WritePlayerCache(void) const\r |
f4f0d89d | 94 | {\r |
95 | ofstream outfile;\r | |
96 | outfile.open(mFilename.c_str());\r | |
97 | if (outfile.fail())\r | |
98 | {\r | |
99 | throw DataLayerException(str(format("Unable to open %1% for writing Players") % mFilename),\r | |
100 | __FILE__, __LINE__);\r | |
101 | }\r | |
102 | \r | |
103 | map<string, shared_ptr<PlayerGO> >::const_iterator iter;\r | |
104 | for (iter = spPlayerCache.begin(); iter != spPlayerCache.end(); iter++)\r | |
105 | {\r | |
106 | outfile << CreateLineFromPlayer(iter->second) << endl;\r | |
107 | }\r | |
108 | outfile.close();\r | |
ce4e8c42 | 109 | }\r |
110 | \r | |
111 | string FilePlayerDAO::GetPlayerFilePath() const\r | |
112 | {\r | |
113 | return mFilename;\r | |
114 | }\r | |
115 | \r | |
116 | shared_ptr<PlayerGO> FilePlayerDAO::GetById(const string &Id) const\r | |
117 | {\r | |
e823e42a | 118 | map<string, shared_ptr<PlayerGO> >::const_iterator iter;\r |
cb255541 | 119 | string id = Id;\r |
120 | to_lower(id);\r | |
e823e42a | 121 | iter = spPlayerCache.find(id);\r |
122 | if (iter != spPlayerCache.end())\r | |
ce4e8c42 | 123 | {\r |
e823e42a | 124 | return iter->second;\r |
ce4e8c42 | 125 | }\r |
126 | return shared_ptr<PlayerGO>();\r | |
127 | }\r | |
128 | \r | |
129 | shared_ptr<PlayerGO> FilePlayerDAO::CreatePlayerFromLine(const string &line) const\r | |
130 | {\r | |
f4f0d89d | 131 | assert(!line.empty());\r |
ce4e8c42 | 132 | shared_ptr<PlayerGO> spPlayer;\r |
133 | spPlayer = shared_ptr<PlayerGO>(new PlayerGO());\r | |
2a8a990d | 134 | boost::char_separator<char> sep(" ", 0, boost::keep_empty_tokens);\r |
ce4e8c42 | 135 | tokenizer tokens(line, sep);\r |
136 | tokenizer::iterator tok_iter = tokens.begin();\r | |
137 | \r | |
f4f0d89d | 138 | spPlayer->Name((*tok_iter));\r |
139 | spPlayer->Id(FileId::CreatePlayerId(spPlayer->Name()));\r | |
140 | tok_iter++;\r | |
e823e42a | 141 | if (tok_iter == tokens.end())\r |
142 | {\r | |
143 | throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %\r | |
144 | line), __FILE__, __LINE__);\r | |
145 | }\r | |
2a8a990d | 146 | spPlayer->Level(lexical_cast<int>((*tok_iter)));\r |
147 | tok_iter++;\r | |
e823e42a | 148 | if (tok_iter == tokens.end())\r |
149 | {\r | |
150 | throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %\r | |
151 | line), __FILE__, __LINE__);\r | |
152 | }\r | |
2a8a990d | 153 | spPlayer->Experience(lexical_cast<unsigned long int>((*tok_iter)));\r |
154 | tok_iter++;\r | |
e823e42a | 155 | if (tok_iter == tokens.end())\r |
156 | {\r | |
157 | throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %\r | |
158 | line), __FILE__, __LINE__);\r | |
159 | }\r | |
2a8a990d | 160 | spPlayer->Gold(lexical_cast<unsigned long int>((*tok_iter)));\r |
161 | tok_iter++;\r | |
e823e42a | 162 | if (tok_iter == tokens.end())\r |
163 | {\r | |
164 | throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %\r | |
165 | line), __FILE__, __LINE__);\r | |
166 | }\r | |
2a8a990d | 167 | spPlayer->Bank(lexical_cast<unsigned long int>((*tok_iter)));\r |
168 | tok_iter++;\r | |
e823e42a | 169 | if (tok_iter == tokens.end())\r |
170 | {\r | |
171 | throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %\r | |
172 | line), __FILE__, __LINE__);\r | |
173 | }\r | |
2a8a990d | 174 | spPlayer->Health(lexical_cast<int>((*tok_iter)));\r |
175 | tok_iter++;\r | |
e823e42a | 176 | if (tok_iter == tokens.end())\r |
177 | {\r | |
178 | throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %\r | |
179 | line), __FILE__, __LINE__);\r | |
180 | }\r | |
2a8a990d | 181 | spPlayer->MaxHealth(lexical_cast<int>((*tok_iter)));\r |
182 | tok_iter++;\r | |
e823e42a | 183 | if (tok_iter == tokens.end())\r |
184 | {\r | |
185 | throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %\r | |
186 | line), __FILE__, __LINE__);\r | |
187 | }\r | |
2a8a990d | 188 | spPlayer->Strength(lexical_cast<int>((*tok_iter)));\r |
189 | tok_iter++;\r | |
e823e42a | 190 | if (tok_iter == tokens.end())\r |
191 | {\r | |
192 | throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %\r | |
193 | line), __FILE__, __LINE__);\r | |
194 | }\r | |
2a8a990d | 195 | spPlayer->Defense(lexical_cast<int>((*tok_iter)));\r |
196 | tok_iter++;\r | |
e823e42a | 197 | if (tok_iter == tokens.end())\r |
198 | {\r | |
199 | throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %\r | |
200 | line), __FILE__, __LINE__);\r | |
201 | }\r | |
2a8a990d | 202 | spPlayer->ForestFights(lexical_cast<int>((*tok_iter)));\r |
203 | tok_iter++;\r | |
e823e42a | 204 | if (tok_iter == tokens.end())\r |
205 | {\r | |
206 | throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %\r | |
207 | line), __FILE__, __LINE__);\r | |
208 | }\r | |
2a8a990d | 209 | spPlayer->PlayerFights(lexical_cast<int>((*tok_iter)));\r |
210 | tok_iter++;\r | |
e823e42a | 211 | if (tok_iter == tokens.end())\r |
212 | {\r | |
213 | throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %\r | |
214 | line), __FILE__, __LINE__);\r | |
215 | }\r | |
2a8a990d | 216 | int flags = lexical_cast<int>((*tok_iter));\r |
217 | SetFlags(spPlayer, flags);\r | |
218 | tok_iter++;\r | |
e823e42a | 219 | if (tok_iter == tokens.end())\r |
220 | {\r | |
221 | throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %\r | |
222 | line), __FILE__, __LINE__);\r | |
223 | }\r | |
2a8a990d | 224 | spPlayer->Password((*tok_iter));\r |
ce4e8c42 | 225 | \r |
c7b7180e | 226 | \r |
227 | tok_iter++;\r | |
e823e42a | 228 | if (tok_iter == tokens.end())\r |
229 | {\r | |
230 | throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %\r | |
231 | line), __FILE__, __LINE__);\r | |
232 | }\r | |
233 | \r | |
9c917833 | 234 | try\r |
235 | {\r | |
236 | unsigned long int intlast = lexical_cast<unsigned long int>((*tok_iter));\r | |
237 | time_t t = (time_t)intlast;\r | |
238 | spPlayer->LastLogin(from_time_t(t));\r | |
239 | }\r | |
240 | catch (bad_lexical_cast)\r | |
241 | {\r | |
242 | spPlayer->LastLogin(from_iso_string((*tok_iter)));\r | |
243 | }\r | |
c7b7180e | 244 | \r |
245 | \r | |
246 | // Weapon\r | |
247 | tok_iter++;\r | |
e823e42a | 248 | if (tok_iter == tokens.end())\r |
249 | {\r | |
250 | throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %\r | |
251 | line), __FILE__, __LINE__);\r | |
252 | }\r | |
e0306362 | 253 | FileItemDAO idao;\r |
254 | string weaponid = FileId::CreateItemId((*tok_iter));\r | |
255 | spPlayer->Weapon(boost::shared_static_cast<WeaponGO>(idao.GetById(weaponid)));\r | |
c7b7180e | 256 | \r |
257 | // Armor\r | |
258 | tok_iter++;\r | |
e823e42a | 259 | if (tok_iter == tokens.end())\r |
260 | {\r | |
261 | throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %\r | |
262 | line), __FILE__, __LINE__);\r | |
263 | }\r | |
e0306362 | 264 | string armorid = FileId::CreateItemId((*tok_iter));\r |
265 | spPlayer->Armor(boost::shared_static_cast<ArmorGO>(idao.GetById(armorid)));\r | |
eec695cf | 266 | \r |
9c917833 | 267 | tok_iter++;\r |
e823e42a | 268 | if (tok_iter == tokens.end())\r |
269 | {\r | |
270 | throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %\r | |
271 | line), __FILE__, __LINE__);\r | |
272 | }\r | |
273 | // Load all the items into the player's inventory\r | |
9c917833 | 274 | while (tok_iter != tokens.end())\r |
275 | {\r | |
e823e42a | 276 | string itemid = FileId::CreateItemId((*tok_iter));\r |
277 | shared_ptr<ItemGO> spItem = idao.GetById(itemid);\r | |
278 | tok_iter++;\r | |
279 | if (tok_iter == tokens.end())\r | |
280 | {\r | |
281 | throw DataLayerException(str(format("Corrupt %1% file: Missing item uses for item %2% on player %3%") % \r | |
282 | mFilename % itemid % spPlayer->Name()), __FILE__, __LINE__);\r | |
283 | }\r | |
284 | try\r | |
285 | {\r | |
286 | spItem->Uses(lexical_cast<int>((*tok_iter)));\r | |
287 | }\r | |
288 | catch (bad_lexical_cast)\r | |
289 | {\r | |
290 | throw DataLayerException(str(format("Corrupt %1% file: Non integer item uses for item %2% on player %3%") %\r | |
291 | mFilename % itemid % spPlayer->Name()), __FILE__, __LINE__);\r | |
292 | }\r | |
9c917833 | 293 | tok_iter++;\r |
294 | }\r | |
c7b7180e | 295 | \r |
ce4e8c42 | 296 | return spPlayer;\r |
297 | }\r | |
298 | \r | |
f4f0d89d | 299 | string FilePlayerDAO::CreateLineFromPlayer(shared_ptr<PlayerGO> spPlayer) const\r |
300 | {\r | |
301 | string line;\r | |
eec695cf | 302 | // TODO: Add weapons, armor, and items\r |
e823e42a | 303 | line = str(format("%1% %2% %3% %4% %5% %6% %7% %8% %9% %10% %11% %12% %13% %14% %15% %16%") % \r |
f4f0d89d | 304 | spPlayer->Name() % spPlayer->Level() % spPlayer->Experience() % spPlayer->Gold() %\r |
305 | spPlayer->Bank() % spPlayer->Health() % spPlayer->MaxHealth() % spPlayer->Strength() %\r | |
306 | spPlayer->Defense() % spPlayer->ForestFights() % spPlayer->PlayerFights() %\r | |
e823e42a | 307 | GetFlags(spPlayer) % spPlayer->Password() % (to_iso_string(spPlayer->LastLogin())) %\r |
308 | FileId::GetItemNumberFromId(spPlayer->Weapon()->Id()) % FileId::GetItemNumberFromId(spPlayer->Armor()->Id()));\r | |
309 | \r | |
310 | vector< shared_ptr<ItemGO> > items = spPlayer->Inventory();\r | |
311 | vector< shared_ptr<ItemGO> >::const_iterator iter;\r | |
312 | for (iter = items.begin(); iter != items.end(); iter++)\r | |
313 | {\r | |
314 | shared_ptr<ItemGO> spItem = (*iter);\r | |
315 | line += " " + FileId::GetItemNumberFromId(spItem->Id()) + " " + lexical_cast<string>(spItem->Uses());\r | |
316 | }\r | |
317 | \r | |
f4f0d89d | 318 | return line;\r |
319 | }\r | |
320 | \r | |
2a8a990d | 321 | void FilePlayerDAO::SetFlags(shared_ptr<PlayerGO> spPlayer, const int &flags) const\r |
322 | {\r | |
cb255541 | 323 | if ((flags & 0x00000001) == 0x00000001)\r |
324 | {\r | |
325 | spPlayer->FoughtMaster(true);\r | |
326 | }\r | |
327 | else\r | |
328 | {\r | |
329 | spPlayer->FoughtMaster(false);\r | |
330 | }\r | |
331 | \r | |
332 | if ((flags & 0x00000002) == 0x00000002)\r | |
333 | {\r | |
334 | spPlayer->Alive(true);\r | |
335 | }\r | |
336 | else\r | |
337 | {\r | |
338 | spPlayer->Alive(false);\r | |
339 | }\r | |
f4f0d89d | 340 | }\r |
ce4e8c42 | 341 | \r |
f4f0d89d | 342 | int FilePlayerDAO::GetFlags(shared_ptr<PlayerGO> spPlayer) const\r |
343 | {\r | |
cb255541 | 344 | int flags = 0;\r |
345 | \r | |
346 | if (spPlayer->FoughtMaster())\r | |
347 | {\r | |
348 | flags |= 0x00000001;\r | |
349 | }\r | |
350 | if (spPlayer->Alive())\r | |
351 | {\r | |
352 | flags |= 0x00000002;\r | |
353 | }\r | |
f4f0d89d | 354 | return 0;\r |
2a8a990d | 355 | }\r |
ce4e8c42 | 356 | \r |
f21affc9 | 357 | void FilePlayerDAO::Update(shared_ptr<PlayerGO> spPlayer)\r |
358 | {\r | |
f4f0d89d | 359 | assert(spPlayer != 0);\r |
360 | assert(!spPlayer->Id().empty());\r | |
361 | assert(!spPlayer->Name().empty());\r | |
362 | \r | |
eec695cf | 363 | // TODO: Lock the file\r |
f4f0d89d | 364 | if (IdExists(spPlayer->Id()))\r |
365 | {\r | |
cb255541 | 366 | string id = spPlayer->Id();\r |
367 | to_lower(id);\r | |
368 | spPlayerCache[id] = spPlayer;\r | |
eec695cf | 369 | WritePlayerCache();\r |
f4f0d89d | 370 | }\r |
371 | else\r | |
372 | {\r | |
373 | throw DataLayerException(str(format("Unable to Update Player %1%: Player does not exist") % \r | |
374 | spPlayer->Name()), __FILE__, __LINE__);\r | |
375 | }\r | |
f21affc9 | 376 | }\r |
377 | \r | |
378 | void FilePlayerDAO::Insert(shared_ptr<PlayerGO> spPlayer)\r | |
379 | {\r | |
f4f0d89d | 380 | assert(spPlayer != 0);\r |
381 | assert(!spPlayer->Name().empty());\r | |
eec695cf | 382 | // TODO: Lock the file\r |
f4f0d89d | 383 | if (!IdExists(FileId::CreatePlayerId(spPlayer->Name())))\r |
384 | {\r | |
385 | spPlayer->Id(FileId::CreatePlayerId(spPlayer->Name()));\r | |
cb255541 | 386 | string id = spPlayer->Id();\r |
387 | to_lower(id);\r | |
388 | spPlayerCache[id] = spPlayer;\r | |
e823e42a | 389 | /*ofstream outfile;\r |
eec695cf | 390 | outfile.open(mFilename.c_str(), std::ios::app);\r |
391 | if (outfile.fail())\r | |
392 | {\r | |
393 | throw ResourceException(str(format("Unable to open %1% for appending.") % mFilename), __FILE__, __LINE__);\r | |
394 | }\r | |
395 | outfile << CreateLineFromPlayer(spPlayer) << endl;\r | |
e823e42a | 396 | outfile.close();*/\r |
397 | WritePlayerCache();\r | |
f4f0d89d | 398 | }\r |
399 | else\r | |
400 | {\r | |
401 | throw DataLayerException(str(format("Unable to Insert Player %1%: Player exists") %\r | |
402 | spPlayer->Name()), __FILE__, __LINE__);\r | |
403 | }\r | |
f21affc9 | 404 | }\r |
ce4e8c42 | 405 | \r |
f21affc9 | 406 | bool FilePlayerDAO::IdExists(const string &Id) const\r |
407 | {\r | |
f4f0d89d | 408 | map<string, shared_ptr<PlayerGO> >::const_iterator iter;\r |
cb255541 | 409 | string id = Id;\r |
410 | to_lower(id);\r | |
411 | iter = spPlayerCache.find(id);\r | |
f4f0d89d | 412 | return (iter != spPlayerCache.end());\r |
f21affc9 | 413 | }\r |
414 | \r | |
415 | list<string> FilePlayerDAO::GetIdsByName(const string &Name) const\r | |
416 | {\r | |
f4f0d89d | 417 | list<string> ids;\r |
418 | if (IdExists(FileId::CreatePlayerId(Name)))\r | |
419 | {\r | |
420 | ids.push_back(FileId::CreatePlayerId(Name));\r | |
421 | }\r | |
422 | return ids;\r | |
f21affc9 | 423 | } |