]> jfr.im git - irc/gameservirc.git/blame - gameserv-2.0/libgameservgldl/src/DataLayer/File/FilePlayerDAO.cpp
Almost have FilePlayerDAO 100% working
[irc/gameservirc.git] / gameserv-2.0 / libgameservgldl / src / DataLayer / File / FilePlayerDAO.cpp
CommitLineData
ce4e8c42 1#include <GameServ/DataLayer/File/FilePlayerDAO.h>\r
2using GameServ::DataLayer::File::FilePlayerDAO;\r
e0306362 3#include <GameServ/DataLayer/File/FileItemDAO.h>\r
4using GameServ::DataLayer::File::FileItemDAO;\r
c7b7180e 5\r
ce4e8c42 6#include <GameServ/GameLayer/GameObjects/PlayerGO.h>\r
7using GameServ::GameLayer::GameObjects::PlayerGO;\r
8\r
9#include <GameServ/DataLayer/DataLayerExceptions.h>\r
10using GameServ::DataLayer::Exceptions::ResourceException;\r
11using GameServ::DataLayer::Exceptions::DataLayerException;\r
12\r
f4f0d89d 13#include <GameServ/DataLayer/File/FileId.h>\r
14using 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
20using boost::shared_ptr;\r
e0306362 21using boost::shared_static_cast;\r
ce4e8c42 22using boost::format;\r
23using boost::str;\r
24using boost::algorithm::to_upper;\r
cb255541 25using boost::algorithm::to_lower;\r
ce4e8c42 26using boost::lexical_cast;\r
9c917833 27using boost::bad_lexical_cast;\r
ce4e8c42 28#include <boost/tokenizer.hpp>\r
29typedef 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 33using namespace boost::posix_time;\r
c7b7180e 34\r
35#include <time.h>\r
36\r
ce4e8c42 37#include <string>\r
38using std::string;\r
39\r
40#include <fstream>\r
41using std::ifstream;\r
42using std::getline;\r
f4f0d89d 43using std::ofstream;\r
44using std::endl;\r
ce4e8c42 45\r
f4f0d89d 46#include <map>\r
47using std::map;\r
ce4e8c42 48\r
e823e42a 49FilePlayerDAO::FilePlayerDAO() : mFilename("data\\players.dat")\r
ce4e8c42 50{\r
51 Initialize(GetPlayerFilePath());\r
52}\r
53\r
54FilePlayerDAO::FilePlayerDAO(const string &filename)\r
55{\r
56 Initialize(filename);\r
57}\r
58\r
59FilePlayerDAO::~FilePlayerDAO()\r
60{\r
61}\r
62\r
63void FilePlayerDAO::Initialize(const string &filename)\r
64{\r
65 mFilename = filename;\r
f4f0d89d 66 LoadPlayerCache();\r
67}\r
68\r
cb255541 69void 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 93void 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
111string FilePlayerDAO::GetPlayerFilePath() const\r
112{\r
113 return mFilename;\r
114}\r
115\r
116shared_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
129shared_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 299string 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 321void 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 342int 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 357void 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
378void 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 406bool 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
415list<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}