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