]> jfr.im git - irc/gameservirc.git/blame - gameserv-2.0/libgameservgldl/src/DataLayer/File/FileItemDAO.cpp
Changed the ItemGO class to be abstract so you cannot define a simple ItemGO object...
[irc/gameservirc.git] / gameserv-2.0 / libgameservgldl / src / DataLayer / File / FileItemDAO.cpp
CommitLineData
317ce8de 1#include <GameServ/DataLayer/File/FileItemDAO.h>\r
2using GameServ::DataLayer::File::FileItemDAO;\r
3#include <GameServ/GameLayer/GameObjects/ItemGO.h>\r
4using GameServ::GameLayer::GameObjects::ItemGO;\r
5#include <GameServ/GameLayer/GameObjects/ArmorGO.h>\r
6using GameServ::GameLayer::GameObjects::ArmorGO;\r
7#include <GameServ/GameLayer/GameObjects/WeaponGO.h>\r
8using GameServ::GameLayer::GameObjects::WeaponGO;\r
9#include <GameServ/GameLayer/GameObjects/PotionGO.h>\r
10using GameServ::GameLayer::GameObjects::PotionGO;\r
11\r
12#include <GameServ/DataLayer/DataLayerExceptions.h>\r
13using GameServ::DataLayer::Exceptions::ResourceException;\r
14using GameServ::DataLayer::Exceptions::DataLayerException;\r
15\r
16#include <GameServ/DataLayer/File/FileId.h>\r
17using GameServ::DataLayer::File::FileId;\r
18\r
19#include <GameServ/Types.h>\r
20using GameServ::Types::ItemTypes;\r
21using GameServ::Types::Modifiers;\r
22using GameServ::Types::Exceptions::TypeException;\r
23\r
24#include <boost/shared_ptr.hpp>\r
25#include <boost/format.hpp>\r
26#include <boost/algorithm/string.hpp>\r
27#include <boost/lexical_cast.hpp>\r
28using boost::shared_ptr;\r
29using boost::format;\r
30using boost::str;\r
31using boost::algorithm::to_upper;\r
32using boost::lexical_cast;\r
33#include <boost/tokenizer.hpp>\r
34typedef boost::tokenizer<boost::char_separator<char> > \r
35 tokenizer;\r
36\r
37#include <string>\r
38using std::string;\r
39\r
40#include <fstream>\r
41using std::ifstream;\r
42using std::getline;\r
43using std::ofstream;\r
44using std::endl;\r
45\r
46#include <map>\r
47using std::map;\r
48\r
49// TODO: Switch filename to be loaded from a config file\r
e823e42a 50FileItemDAO::FileItemDAO() : mFilename("data\\items\\masteritems.dat")\r
317ce8de 51{\r
52 Initialize(GetItemFilePath());\r
53}\r
54\r
55FileItemDAO::FileItemDAO(const string &filename)\r
56{\r
57 Initialize(filename);\r
58}\r
59\r
60FileItemDAO::~FileItemDAO()\r
61{\r
62}\r
63\r
64void FileItemDAO::Initialize(const string &filename)\r
65{\r
66 mFilename = filename;\r
67 LoadItemCache();\r
68}\r
69\r
70string FileItemDAO::GetItemFilePath() const\r
71{\r
72 return mFilename;\r
73}\r
74\r
75shared_ptr<ItemGO> FileItemDAO::GetById(const string &Id) const\r
76{\r
4757f72f 77 map<string, shared_ptr<ItemGO> >::const_iterator iter;\r
78 iter = spItemCache.find(Id);\r
79 if (iter != spItemCache.end())\r
317ce8de 80 {\r
4757f72f 81 return shared_ptr<ItemGO>(iter->second->Clone());\r
317ce8de 82 }\r
4757f72f 83 else\r
317ce8de 84 {\r
4757f72f 85 return shared_ptr<ItemGO>();\r
317ce8de 86 }\r
317ce8de 87}\r
8e6e952d 88shared_ptr<ItemGO> FileItemDAO::CreatePotionFromLine(const string &line) const\r
89{\r
16655a31 90 assert(!line.empty());\r
8e6e952d 91 shared_ptr<PotionGO> spPotion = shared_ptr<PotionGO>(new PotionGO());\r
16655a31 92 map<Modifiers::Modifier, Range> modifiers;\r
93 boost::char_separator<char> sep("~", 0, boost::keep_empty_tokens);\r
94 tokenizer tokens(line, sep);\r
95 tokenizer::iterator tok_iter = tokens.begin();\r
96\r
97 tok_iter++;\r
98 if (tok_iter == tokens.end())\r
99 {\r
100 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
101 mFilename % line), __FILE__, __LINE__);\r
102 }\r
103 spPotion->Id(FileId::CreateItemId((*tok_iter)));\r
104\r
105 tok_iter++;\r
106 if (tok_iter == tokens.end())\r
107 {\r
108 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
109 mFilename % line), __FILE__, __LINE__);\r
110 }\r
111\r
112 spPotion->Name((*tok_iter));\r
113\r
114 tok_iter++;\r
115 if (tok_iter == tokens.end())\r
116 {\r
117 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
118 mFilename % line), __FILE__, __LINE__);\r
119 }\r
120 spPotion->Price(lexical_cast<unsigned long int>((*tok_iter)));\r
121\r
122 tok_iter++;\r
123 if (tok_iter == tokens.end())\r
124 {\r
125 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
126 mFilename % line), __FILE__, __LINE__);\r
127 }\r
128 spPotion->Uses(lexical_cast<int>((*tok_iter)));\r
129\r
130 tok_iter++;\r
131 if (tok_iter == tokens.end())\r
132 {\r
133 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
134 mFilename % line), __FILE__, __LINE__);\r
135 }\r
136 int low = lexical_cast<int>((*tok_iter));\r
137 tok_iter++;\r
138 if (tok_iter == tokens.end())\r
139 {\r
140 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
141 mFilename % line), __FILE__, __LINE__);\r
142 }\r
143 int high = lexical_cast<int>((*tok_iter));\r
144 modifiers[Modifiers::strength] = Range(high, low);\r
145 tok_iter++;\r
146 if (tok_iter == tokens.end())\r
147 {\r
148 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
149 mFilename % line), __FILE__, __LINE__);\r
150 }\r
151 low = lexical_cast<int>((*tok_iter));\r
152 tok_iter++;\r
153 if (tok_iter == tokens.end())\r
154 {\r
155 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
156 mFilename % line), __FILE__, __LINE__);\r
157 }\r
158 high = lexical_cast<int>((*tok_iter));\r
159 modifiers[Modifiers::defense] = Range(high, low);\r
160\r
161 tok_iter++;\r
162 if (tok_iter == tokens.end())\r
163 {\r
164 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
165 mFilename % line), __FILE__, __LINE__);\r
166 }\r
167 low = lexical_cast<int>((*tok_iter));\r
168 tok_iter++;\r
169 if (tok_iter == tokens.end())\r
170 {\r
171 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
172 mFilename % line), __FILE__, __LINE__);\r
173 }\r
174 high = lexical_cast<int>((*tok_iter));\r
175 modifiers[Modifiers::maxhealth] = Range(high, low);\r
176\r
177 tok_iter++;\r
178 if (tok_iter == tokens.end())\r
179 {\r
180 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
181 mFilename % line), __FILE__, __LINE__);\r
182 }\r
183 low = lexical_cast<int>((*tok_iter));\r
184 tok_iter++;\r
185 if (tok_iter == tokens.end())\r
186 {\r
187 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
188 mFilename % line), __FILE__, __LINE__);\r
189 }\r
190 high = lexical_cast<int>((*tok_iter));\r
191 modifiers[Modifiers::health] = Range(high, low);\r
192\r
193 tok_iter++;\r
194 if (tok_iter == tokens.end())\r
195 {\r
196 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
197 mFilename % line), __FILE__, __LINE__);\r
198 }\r
199 low = lexical_cast<int>((*tok_iter));\r
200 tok_iter++;\r
201 if (tok_iter == tokens.end())\r
202 {\r
203 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
204 mFilename % line), __FILE__, __LINE__);\r
205 }\r
206 high = lexical_cast<int>((*tok_iter));\r
207 modifiers[Modifiers::forestfights] = Range(high, low);\r
208\r
209 tok_iter++;\r
210 if (tok_iter == tokens.end())\r
211 {\r
212 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
213 mFilename % line), __FILE__, __LINE__);\r
214 }\r
215 low = lexical_cast<int>((*tok_iter));\r
216 tok_iter++;\r
217 if (tok_iter == tokens.end())\r
218 {\r
219 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
220 mFilename % line), __FILE__, __LINE__);\r
221 }\r
222 high = lexical_cast<int>((*tok_iter));\r
223 modifiers[Modifiers::playerfights] = Range(high, low);\r
224\r
225 tok_iter++;\r
226 if (tok_iter == tokens.end())\r
227 {\r
228 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
229 mFilename % line), __FILE__, __LINE__);\r
230 }\r
231 low = lexical_cast<int>((*tok_iter));\r
232 tok_iter++;\r
233 if (tok_iter == tokens.end())\r
234 {\r
235 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
236 mFilename % line), __FILE__, __LINE__);\r
237 }\r
238 high = lexical_cast<int>((*tok_iter));\r
239 modifiers[Modifiers::gold] = Range(high, low);\r
240\r
241 tok_iter++;\r
242 if (tok_iter == tokens.end())\r
243 {\r
244 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
245 mFilename % line), __FILE__, __LINE__);\r
246 }\r
247 low = lexical_cast<int>((*tok_iter));\r
248 tok_iter++;\r
249 if (tok_iter == tokens.end())\r
250 {\r
251 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
252 mFilename % line), __FILE__, __LINE__);\r
253 }\r
254 high = lexical_cast<int>((*tok_iter));\r
255 modifiers[Modifiers::bank] = Range(high, low);\r
8e6e952d 256\r
257 return spPotion;\r
258}\r
317ce8de 259\r
260shared_ptr<ItemGO> FileItemDAO::CreateItemFromLine(const string &line) const\r
261{\r
262 assert(!line.empty());\r
263 shared_ptr<ItemGO> spItem;\r
8e6e952d 264 map<Modifiers::Modifier, Range> modifiers;\r
317ce8de 265 boost::char_separator<char> sep("~", 0, boost::keep_empty_tokens);\r
266 tokenizer tokens(line, sep);\r
267 tokenizer::iterator tok_iter = tokens.begin();\r
268\r
269 ItemTypes::ItemType type;\r
270 \r
271 try\r
272 {\r
273 type = ItemTypes::Parse((*tok_iter));\r
274 }\r
275 catch (TypeException)\r
276 {\r
277 return shared_ptr<ItemGO>();\r
278 }\r
279\r
280 switch(type)\r
281 {\r
282 case ItemTypes::Weapon:\r
283 spItem = shared_ptr<WeaponGO>(new WeaponGO());\r
284 break;\r
285 case ItemTypes::Armor:\r
286 spItem = shared_ptr<ArmorGO>(new ArmorGO());\r
287 break;\r
288 case ItemTypes::Potion:\r
8e6e952d 289 return CreatePotionFromLine(line);\r
e823e42a 290 break;\r
317ce8de 291 default:\r
292 throw DataLayerException(str(format("Unknown Item type: %1%") % type), __FILE__, __LINE__);\r
293 }\r
294 tok_iter++;\r
e823e42a 295 if (tok_iter == tokens.end())\r
296 {\r
297 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
298 mFilename % line), __FILE__, __LINE__);\r
299 }\r
317ce8de 300 spItem->Id(FileId::CreateItemId((*tok_iter)));\r
301\r
302 tok_iter++;\r
e823e42a 303 if (tok_iter == tokens.end())\r
304 {\r
305 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
306 mFilename % line), __FILE__, __LINE__);\r
307 }\r
317ce8de 308 spItem->Name((*tok_iter));\r
309 tok_iter++;\r
e823e42a 310 if (tok_iter == tokens.end())\r
311 {\r
312 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
313 mFilename % line), __FILE__, __LINE__);\r
314 }\r
317ce8de 315 spItem->Price(lexical_cast<unsigned long int>((*tok_iter)));\r
316 tok_iter++;\r
e823e42a 317 if (tok_iter == tokens.end())\r
318 {\r
319 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
320 mFilename % line), __FILE__, __LINE__);\r
321 }\r
317ce8de 322 spItem->Uses(lexical_cast<int>((*tok_iter)));\r
323 tok_iter++;\r
e823e42a 324 if (tok_iter == tokens.end())\r
325 {\r
326 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
327 mFilename % line), __FILE__, __LINE__);\r
328 }\r
1134c368 329 if ((*tok_iter) != "0")\r
330 {\r
331 modifiers[Modifiers::strength] = Range(lexical_cast<int>((*tok_iter)), lexical_cast<int>((*tok_iter)));\r
332 }\r
317ce8de 333 tok_iter++;\r
e823e42a 334 if (tok_iter == tokens.end())\r
335 {\r
336 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
337 mFilename % line), __FILE__, __LINE__);\r
338 }\r
1134c368 339 if ((*tok_iter) != "0")\r
340 {\r
341 modifiers[Modifiers::defense] = Range(lexical_cast<int>((*tok_iter)), lexical_cast<int>((*tok_iter)));\r
342 }\r
317ce8de 343 tok_iter++;\r
e823e42a 344 if (tok_iter == tokens.end())\r
345 {\r
346 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
347 mFilename % line), __FILE__, __LINE__);\r
348 }\r
1134c368 349 if ((*tok_iter) != "0")\r
350 {\r
351 modifiers[Modifiers::maxhealth] = Range(lexical_cast<int>((*tok_iter)), lexical_cast<int>((*tok_iter)));\r
352 }\r
317ce8de 353 tok_iter++;\r
e823e42a 354 if (tok_iter == tokens.end())\r
355 {\r
356 throw DataLayerException(str(format("Corrupt %1% file. Missing information on line %2%") %\r
357 mFilename % line), __FILE__, __LINE__);\r
358 }\r
1134c368 359 if ((*tok_iter) != "0")\r
360 {\r
361 modifiers[Modifiers::health] = Range(lexical_cast<int>((*tok_iter)), lexical_cast<int>((*tok_iter)));\r
362 }\r
317ce8de 363 tok_iter++;\r
e823e42a 364 if (tok_iter == tokens.end())\r
365 {\r
1134c368 366 spItem->Modifiers(modifiers);\r
e823e42a 367 return spItem;\r
368 }\r
1134c368 369 if ((*tok_iter) != "0")\r
370 {\r
371 modifiers[Modifiers::forestfights] = Range(lexical_cast<int>((*tok_iter)), lexical_cast<int>((*tok_iter)));\r
372 }\r
317ce8de 373 tok_iter++;\r
e823e42a 374 if (tok_iter == tokens.end())\r
375 {\r
1134c368 376 spItem->Modifiers(modifiers);\r
e823e42a 377 return spItem;\r
378 }\r
1134c368 379 if ((*tok_iter) != "0")\r
380 {\r
381 modifiers[Modifiers::playerfights] = Range(lexical_cast<int>((*tok_iter)), lexical_cast<int>((*tok_iter)));\r
382 }\r
317ce8de 383 tok_iter++;\r
e823e42a 384 if (tok_iter == tokens.end())\r
385 {\r
1134c368 386 spItem->Modifiers(modifiers);\r
e823e42a 387 return spItem;\r
388 }\r
1134c368 389 if ((*tok_iter) != "0")\r
390 {\r
391 modifiers[Modifiers::gold] = Range(lexical_cast<int>((*tok_iter)), lexical_cast<int>((*tok_iter)));\r
392 }\r
317ce8de 393 tok_iter++;\r
e823e42a 394 if (tok_iter == tokens.end())\r
395 {\r
1134c368 396 spItem->Modifiers(modifiers);\r
e823e42a 397 return spItem;\r
398 }\r
1134c368 399 if ((*tok_iter) != "0")\r
400 {\r
401 modifiers[Modifiers::bank] = Range(lexical_cast<int>((*tok_iter)), lexical_cast<int>((*tok_iter)));\r
402 }\r
317ce8de 403 spItem->Modifiers(modifiers);\r
404\r
405 return spItem;\r
406}\r
407bool FileItemDAO::IdExists(const string &Id) const\r
408{\r
409 map<string, shared_ptr<ItemGO> >::const_iterator iter;\r
410 iter = spItemCache.find(Id);\r
411 return (iter != spItemCache.end());\r
412}\r
413\r
414void FileItemDAO::LoadItemCache(void)\r
415{\r
416 ifstream infile;\r
417 infile.open(mFilename.c_str());\r
418\r
419 if (infile.fail())\r
420 {\r
421 throw DataLayerException(str(format("Unable to open %1% for reading") % mFilename), __FILE__, __LINE__);\r
422 }\r
423 string line;\r
424 while (getline(infile, line))\r
425 {\r
426 if (line.length() == 0)\r
427 {\r
428 continue;\r
429 }\r
430 if (line[0] == '#')\r
431 {\r
432 continue;\r
433 }\r
434 shared_ptr<ItemGO> spItem = CreateItemFromLine(line);\r
435 if (spItem != 0)\r
436 {\r
437 spItemCache[spItem->Id()] = spItem;\r
438 }\r
439 }\r
440 infile.close();\r
441}\r