]>
jfr.im git - irc/gameservirc.git/blob - gameserv-2.0/libgameservgldl/src/DataLayer/File/FilePlayerDAO.cpp
1 #include <GameServ/DataLayer/File/FilePlayerDAO.h>
2 using GameServ::DataLayer::File::FilePlayerDAO
;
3 #include <GameServ/DataLayer/File/FileItemDAO.h>
4 using GameServ::DataLayer::File::FileItemDAO
;
6 #include <GameServ/GameLayer/GameObjects/PlayerGO.h>
7 using GameServ::GameLayer::GameObjects::PlayerGO
;
9 #include <GameServ/DataLayer/DataLayerExceptions.h>
10 using GameServ::DataLayer::Exceptions::ResourceException
;
11 using GameServ::DataLayer::Exceptions::DataLayerException
;
13 #include <GameServ/DataLayer/File/FileId.h>
14 using GameServ::DataLayer::File::FileId
;
16 #include <GameServ/GameLayer/Helpers/InventoryManager.h>
17 using namespace GameServ::GameLayer::Helpers
;
19 #include <boost/smart_ptr/shared_ptr.hpp>
20 #include <boost/format.hpp>
21 #include <boost/algorithm/string.hpp>
22 #include <boost/lexical_cast.hpp>
23 using boost::shared_ptr
;
24 using boost::shared_static_cast
;
27 using boost::algorithm::to_upper
;
28 using boost::algorithm::to_lower
;
29 using boost::lexical_cast
;
30 using boost::bad_lexical_cast
;
31 #include <boost/tokenizer.hpp>
32 typedef boost::tokenizer
<boost::char_separator
<char> >
35 #include <boost/date_time/posix_time/posix_time.hpp>
36 using namespace boost::posix_time
;
52 FilePlayerDAO::FilePlayerDAO() : mFilename("data\\players.dat")
54 Initialize(GetPlayerFilePath());
57 FilePlayerDAO::FilePlayerDAO(const string
&filename
)
62 FilePlayerDAO::~FilePlayerDAO()
67 void FilePlayerDAO::Initialize(const string
&filename
)
73 void FilePlayerDAO::LoadPlayerCache(void)
75 assert(!mFilename
.empty());
76 spPlayerCache
.clear();
78 infile
.open(mFilename
.c_str());
81 throw DataLayerException(str(format("Unable to open %1% for loading Players") % mFilename
),
87 shared_ptr
<PlayerGO
> spPlayer
;
88 getline(infile
, line
);
93 else if (line
[0] == '#')
97 spPlayer
= CreatePlayerFromLine(line
);
100 string id
= spPlayer
->Id();
102 spPlayerCache
[id
] = spPlayer
;
103 // Load all the items into the player's inventory
104 shared_ptr
<InventoryManager
> inventory
= InventoryManager::Instance();
105 if (!inventory
->PlayerHasInventory(spPlayer
))
107 LoadInventoryFromLine(spPlayer
, line
);
114 void FilePlayerDAO::WritePlayerCache(void) const
117 outfile
.open(mFilename
.c_str());
120 throw DataLayerException(str(format("Unable to open %1% for writing Players") % mFilename
),
124 map
<string
, shared_ptr
<PlayerGO
> >::const_iterator iter
;
125 for (iter
= spPlayerCache
.begin(); iter
!= spPlayerCache
.end(); iter
++)
127 outfile
<< CreateLineFromPlayer(iter
->second
) << endl
;
132 string
FilePlayerDAO::GetPlayerFilePath() const
137 shared_ptr
<PlayerGO
> FilePlayerDAO::GetById(const string
&Id
) const
139 map
<string
, shared_ptr
<PlayerGO
> >::const_iterator iter
;
142 iter
= spPlayerCache
.find(id
);
143 if (iter
!= spPlayerCache
.end())
145 return shared_ptr
<PlayerGO
>(iter
->second
->Clone());
147 return shared_ptr
<PlayerGO
>();
150 shared_ptr
<PlayerGO
> FilePlayerDAO::CreatePlayerFromLine(const string
&line
) const
152 assert(!line
.empty());
153 shared_ptr
<PlayerGO
> spPlayer
;
154 spPlayer
= shared_ptr
<PlayerGO
>(new PlayerGO());
155 boost::char_separator
<char> sep(" ", 0, boost::keep_empty_tokens
);
156 tokenizer
tokens(line
, sep
);
157 tokenizer::iterator tok_iter
= tokens
.begin();
159 spPlayer
->Name((*tok_iter
));
160 spPlayer
->Id(FileId::CreatePlayerId(spPlayer
->Name()));
162 if (tok_iter
== tokens
.end())
164 throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %
165 line
), __FILE__
, __LINE__
);
167 spPlayer
->LevelNumber(lexical_cast
<unsigned int>((*tok_iter
)));
168 spPlayer
->LevelId(FileId::CreateLevelId(spPlayer
->LevelNumber()));
170 if (tok_iter
== tokens
.end())
172 throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %
173 line
), __FILE__
, __LINE__
);
175 spPlayer
->Experience(lexical_cast
<unsigned long int>((*tok_iter
)));
177 if (tok_iter
== tokens
.end())
179 throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %
180 line
), __FILE__
, __LINE__
);
182 spPlayer
->Gold(lexical_cast
<unsigned long int>((*tok_iter
)));
184 if (tok_iter
== tokens
.end())
186 throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %
187 line
), __FILE__
, __LINE__
);
189 spPlayer
->Bank(lexical_cast
<unsigned long int>((*tok_iter
)));
191 if (tok_iter
== tokens
.end())
193 throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %
194 line
), __FILE__
, __LINE__
);
196 spPlayer
->Health(lexical_cast
<int>((*tok_iter
)));
198 if (tok_iter
== tokens
.end())
200 throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %
201 line
), __FILE__
, __LINE__
);
203 spPlayer
->MaxHealth(lexical_cast
<int>((*tok_iter
)));
205 if (tok_iter
== tokens
.end())
207 throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %
208 line
), __FILE__
, __LINE__
);
210 spPlayer
->Strength(lexical_cast
<int>((*tok_iter
)));
212 if (tok_iter
== tokens
.end())
214 throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %
215 line
), __FILE__
, __LINE__
);
217 spPlayer
->Defense(lexical_cast
<int>((*tok_iter
)));
219 if (tok_iter
== tokens
.end())
221 throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %
222 line
), __FILE__
, __LINE__
);
224 spPlayer
->ForestFights(lexical_cast
<int>((*tok_iter
)));
226 if (tok_iter
== tokens
.end())
228 throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %
229 line
), __FILE__
, __LINE__
);
231 spPlayer
->PlayerFights(lexical_cast
<int>((*tok_iter
)));
233 if (tok_iter
== tokens
.end())
235 throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %
236 line
), __FILE__
, __LINE__
);
238 int flags
= lexical_cast
<int>((*tok_iter
));
239 SetFlags(spPlayer
, flags
);
241 if (tok_iter
== tokens
.end())
243 throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %
244 line
), __FILE__
, __LINE__
);
246 spPlayer
->Password((*tok_iter
));
250 if (tok_iter
== tokens
.end())
252 throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %
253 line
), __FILE__
, __LINE__
);
258 unsigned long int intlast
= lexical_cast
<unsigned long int>((*tok_iter
));
259 time_t t
= (time_t)intlast
;
260 spPlayer
->LastLogin(from_time_t(t
));
262 catch (bad_lexical_cast
)
264 spPlayer
->LastLogin(from_iso_string((*tok_iter
)));
270 if (tok_iter
== tokens
.end())
272 throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %
273 line
), __FILE__
, __LINE__
);
276 string weaponid
= FileId::CreateItemId((*tok_iter
));
277 spPlayer
->Weapon(boost::shared_static_cast
<WeaponGO
>(idao
.GetById(weaponid
)));
281 if (tok_iter
== tokens
.end())
283 throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %
284 line
), __FILE__
, __LINE__
);
286 string armorid
= FileId::CreateItemId((*tok_iter
));
287 spPlayer
->Armor(boost::shared_static_cast
<ArmorGO
>(idao
.GetById(armorid
)));
290 if (tok_iter
== tokens
.end())
292 throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %
293 line
), __FILE__
, __LINE__
);
299 void FilePlayerDAO::LoadInventoryFromLine(shared_ptr
<PlayerGO
> spPlayer
, const string
&line
) const
301 assert(!line
.empty());
302 boost::char_separator
<char> sep(" ", 0);
303 tokenizer
tokens(line
, sep
);
304 tokenizer::iterator tok_iter
= tokens
.begin();
306 for (int x
= 0; x
< 16; ++x
)
309 if (tok_iter
== tokens
.end())
311 throw DataLayerException(str(format("Corrupt player line %1%. Missing information") %
312 line
), __FILE__
, __LINE__
);
315 // Load all the items into the player's inventory
316 shared_ptr
<InventoryManager
> inventory
= InventoryManager::Instance();
318 while (tok_iter
!= tokens
.end())
320 string itemid
= FileId::CreateItemId((*tok_iter
));
321 shared_ptr
<ItemGO
> spItem
= idao
.GetById(itemid
);
323 if (tok_iter
== tokens
.end())
325 throw DataLayerException(str(format("Corrupt %1% file: Missing item uses for item %2% on player %3%") %
326 mFilename
% itemid
% spPlayer
->Name()), __FILE__
, __LINE__
);
330 spItem
->Uses(lexical_cast
<int>((*tok_iter
)));
332 catch (bad_lexical_cast
)
334 throw DataLayerException(str(format("Corrupt %1% file: Non integer item uses for item %2% on player %3%") %
335 mFilename
% itemid
% spPlayer
->Name()), __FILE__
, __LINE__
);
337 inventory
->AddItem(spPlayer
, spItem
);
342 string
FilePlayerDAO::CreateLineFromPlayer(shared_ptr
<PlayerGO
> spPlayer
) const
345 line
= str(format("%1% %2% %3% %4% %5% %6% %7% %8% %9% %10% %11% %12% %13% %14% %15% %16%") %
346 spPlayer
->Name() % FileId::GetLevelNumberFromId(spPlayer
->LevelId()) % spPlayer
->Experience() %
347 spPlayer
->Gold() % spPlayer
->Bank() % spPlayer
->Health() % spPlayer
->MaxHealth() %
348 spPlayer
->Strength() % spPlayer
->Defense() % spPlayer
->ForestFights() % spPlayer
->PlayerFights() %
349 GetFlags(spPlayer
) % spPlayer
->Password() % (to_iso_string(spPlayer
->LastLogin())) %
350 FileId::GetItemNumberFromId(spPlayer
->Weapon()->Id()) % FileId::GetItemNumberFromId(spPlayer
->Armor()->Id()));
352 shared_ptr
<InventoryManager
> spInventory
= InventoryManager::Instance();
353 ItemList inventory
= spInventory
->GetInventory(spPlayer
);
354 ItemList::const_iterator iter
;
355 for (iter
= inventory
.begin(); iter
!= inventory
.end(); iter
++)
357 shared_ptr
<ItemGO
> spItem
= (*iter
);
358 line
+= " " + FileId::GetItemNumberFromId(spItem
->Id()) + " " + lexical_cast
<string
>(spItem
->Uses());
364 void FilePlayerDAO::SetFlags(shared_ptr
<PlayerGO
> spPlayer
, const int &flags
) const
366 if ((flags
& 0x00000001) == 0x00000001)
368 spPlayer
->FoughtMaster(true);
372 spPlayer
->FoughtMaster(false);
375 if ((flags
& 0x00000002) == 0x00000002)
377 spPlayer
->Alive(true);
381 spPlayer
->Alive(false);
385 int FilePlayerDAO::GetFlags(shared_ptr
<PlayerGO
> spPlayer
) const
389 if (spPlayer
->FoughtMaster())
393 if (spPlayer
->Alive())
400 void FilePlayerDAO::Update(shared_ptr
<PlayerGO
> spPlayer
)
402 assert(spPlayer
!= 0);
403 assert(!spPlayer
->Id().empty());
404 assert(!spPlayer
->Name().empty());
406 // TODO: Lock the file
407 if (IdExists(spPlayer
->Id()))
409 string id
= spPlayer
->Id();
411 spPlayerCache
[id
] = spPlayer
;
415 throw DataLayerException(str(format("Unable to Update Player %1%: Player does not exist") %
416 spPlayer
->Name()), __FILE__
, __LINE__
);
420 void FilePlayerDAO::Insert(shared_ptr
<PlayerGO
> spPlayer
)
422 assert(spPlayer
!= 0);
423 assert(!spPlayer
->Name().empty());
424 // TODO: Lock the file
425 if (!IdExists(FileId::CreatePlayerId(spPlayer
->Name())))
427 spPlayer
->Id(FileId::CreatePlayerId(spPlayer
->Name()));
428 string id
= spPlayer
->Id();
430 spPlayerCache
[id
] = spPlayer
;
432 outfile.open(mFilename.c_str(), std::ios::app);
435 throw ResourceException(str(format("Unable to open %1% for appending.") % mFilename), __FILE__, __LINE__);
437 outfile << CreateLineFromPlayer(spPlayer) << endl;
442 throw DataLayerException(str(format("Unable to Insert Player %1%: Player exists") %
443 spPlayer
->Name()), __FILE__
, __LINE__
);
447 bool FilePlayerDAO::IdExists(const string
&Id
) const
449 map
<string
, shared_ptr
<PlayerGO
> >::const_iterator iter
;
452 iter
= spPlayerCache
.find(id
);
453 return (iter
!= spPlayerCache
.end());
456 list
<string
> FilePlayerDAO::GetIdsByName(const string
&Name
) const
459 if (IdExists(FileId::CreatePlayerId(Name
)))
461 ids
.push_back(FileId::CreatePlayerId(Name
));