+#include <GameServ/DataLayer/File/FileMonsterDAO.h>\r
+using GameServ::DataLayer::File::FileMonsterDAO;\r
+\r
+#include <GameServ/GameLayer/GameObjects/MonsterGO.h>\r
+using GameServ::GameLayer::GameObjects::MonsterGO;\r
+\r
+#include <GameServ/DataLayer/DataLayerExceptions.h>\r
+using GameServ::DataLayer::Exceptions::ResourceException;\r
+using GameServ::DataLayer::Exceptions::DataLayerException;\r
+\r
+#include <GameServ/DataLayer/File/FileId.h>\r
+using GameServ::DataLayer::File::FileId;\r
+\r
+#include <boost/smart_ptr/shared_ptr.hpp>\r
+#include <boost/format.hpp>\r
+#include <boost/algorithm/string.hpp>\r
+#include <boost/lexical_cast.hpp>\r
+using boost::shared_ptr;\r
+using boost::shared_static_cast;\r
+using boost::format;\r
+using boost::str;\r
+using boost::algorithm::to_upper;\r
+using boost::algorithm::to_lower;\r
+using boost::lexical_cast;\r
+using boost::bad_lexical_cast;\r
+#include <boost/tokenizer.hpp>\r
+typedef boost::tokenizer<boost::char_separator<char> > \r
+ tokenizer;\r
+\r
+#include <string>\r
+using std::string;\r
+\r
+#include <fstream>\r
+using std::ifstream;\r
+using std::getline;\r
+using std::ofstream;\r
+using std::endl;\r
+\r
+#include <map>\r
+using std::map;\r
+\r
+FileMonsterDAO::FileMonsterDAO() : mFilename("data\\monsters.dat")\r
+{\r
+ Initialize(GetMonsterFilePath());\r
+}\r
+\r
+FileMonsterDAO::FileMonsterDAO(const string &filename)\r
+{\r
+ Initialize(filename);\r
+}\r
+\r
+FileMonsterDAO::~FileMonsterDAO()\r
+{\r
+}\r
+\r
+void FileMonsterDAO::Initialize(const string &filename)\r
+{\r
+ mFilename = filename;\r
+ LoadMonsterCache();\r
+}\r
+\r
+void FileMonsterDAO::LoadMonsterCache(void)\r
+{\r
+ assert(!mFilename.empty());\r
+ spMonsterCache.clear();\r
+ ifstream infile;\r
+ infile.open(mFilename.c_str());\r
+ if (infile.fail())\r
+ {\r
+ throw DataLayerException(str(format("Unable to open %1% for loading Monsters") % mFilename),\r
+ __FILE__, __LINE__);\r
+ }\r
+ while (!infile.eof())\r
+ {\r
+ string line;\r
+ shared_ptr<MonsterGO> spMonster;\r
+ getline(infile, line);\r
+ if (line.empty())\r
+ {\r
+ continue;\r
+ }\r
+ else if (line[0] == '#')\r
+ {\r
+ continue;\r
+ }\r
+ spMonster = CreateMonsterFromLine(line);\r
+ string id = spMonster->Id();\r
+ to_lower(id);\r
+ spMonsterCache[id] = spMonster;\r
+ }\r
+ infile.close();\r
+}\r
+\r
+string FileMonsterDAO::GetMonsterFilePath() const\r
+{\r
+ return mFilename;\r
+}\r
+\r
+shared_ptr<MonsterGO> FileMonsterDAO::GetById(const string &Id) const\r
+{\r
+ map<string, shared_ptr<MonsterGO> >::const_iterator iter;\r
+ string id = Id;\r
+ to_lower(id);\r
+ iter = spMonsterCache.find(id);\r
+ if (iter != spMonsterCache.end())\r
+ {\r
+ return shared_ptr<MonsterGO>(iter->second->Clone());\r
+ }\r
+ return shared_ptr<MonsterGO>();\r
+}\r
+\r
+shared_ptr<MonsterGO> FileMonsterDAO::CreateMonsterFromLine(const string &line) const\r
+{\r
+ assert(!line.empty());\r
+ shared_ptr<MonsterGO> spMonster;\r
+ spMonster = shared_ptr<MonsterGO>(new MonsterGO());\r
+ boost::char_separator<char> sep("~", 0);\r
+ tokenizer tokens(line, sep);\r
+ tokenizer::iterator tok_iter = tokens.begin();\r
+\r
+ try\r
+ {\r
+ spMonster->LevelId(FileId::CreateLevelId(lexical_cast<unsigned int>((*tok_iter))));\r
+ }\r
+ catch (bad_lexical_cast)\r
+ {\r
+ throw DataLayerException(str(format("Corrupt monster line %1%. Improperly formatted level.") %\r
+ line), __FILE__, __LINE__);\r
+ }\r
+\r
+ tok_iter++;\r
+ if (tok_iter == tokens.end())\r
+ {\r
+ throw DataLayerException(str(format("Corrupt monster line %1%. Missing information") %\r
+ line), __FILE__, __LINE__);\r
+ }\r
+ spMonster->Name((*tok_iter));\r
+ spMonster->Id(FileId::CreateMonsterId(spMonster->LevelId(), spMonster->Name()));\r
+ tok_iter++;\r
+ if (tok_iter == tokens.end())\r
+ {\r
+ throw DataLayerException(str(format("Corrupt monster line %1%. Missing information") %\r
+ line), __FILE__, __LINE__);\r
+ }\r
+ spMonster->WeaponName((*tok_iter));\r
+ tok_iter++;\r
+ if (tok_iter == tokens.end())\r
+ {\r
+ throw DataLayerException(str(format("Corrupt monster line %1%. Missing information") %\r
+ line), __FILE__, __LINE__);\r
+ }\r
+ spMonster->DeathCry((*tok_iter));\r
+\r
+ return spMonster;\r
+}\r
+\r
+bool FileMonsterDAO::IdExists(const string &Id) const\r
+{\r
+ map<string, shared_ptr<MonsterGO> >::const_iterator iter;\r
+ string id = Id;\r
+ to_lower(id);\r
+ iter = spMonsterCache.find(id);\r
+ return (iter != spMonsterCache.end());\r
+}\r
+\r
+vector<string> FileMonsterDAO::GetMonsterIdsByLevelId(const string &LevelId) const\r
+{\r
+ static map<string, vector<string> > MonsterLevelIndex;\r
+ map<string, vector<string> >::const_iterator leveliter;\r
+ leveliter = MonsterLevelIndex.find(LevelId);\r
+ if (leveliter == MonsterLevelIndex.end())\r
+ {\r
+ vector<string> monsterIds;\r
+ map<string, shared_ptr<MonsterGO> >::const_iterator iter;\r
+ for (iter = spMonsterCache.begin(); iter != spMonsterCache.end(); iter++)\r
+ {\r
+ if (iter->second->LevelId() == LevelId)\r
+ {\r
+ monsterIds.push_back(iter->second->Id());\r
+ }\r
+ }\r
+ MonsterLevelIndex[LevelId] = monsterIds;\r
+ return monsterIds;\r
+ }\r
+ else\r
+ {\r
+ return MonsterLevelIndex[LevelId];\r
+ }\r
+}\r