OregonCore  revision fb2a440-git
Your Favourite TBC server
PlayerDump.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the OregonCore Project. See AUTHORS file for Copyright information
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2 of the License, or (at your
7  * option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "Common.h"
19 #include "PlayerDump.h"
20 #include "Database/DatabaseEnv.h"
21 #include "Database/SQLStorage.h"
22 #include "UpdateFields.h"
23 #include "ObjectMgr.h"
24 #include "AccountMgr.h"
25 
26 // Character Dump tables
27 #define DUMP_TABLE_COUNT 19
28 
29 struct DumpTable
30 {
31  char const* name;
33 };
34 
35 static DumpTable dumpTables[DUMP_TABLE_COUNT] =
36 {
37  { "characters", DTT_CHARACTER },
38  { "character_queststatus", DTT_CHAR_TABLE },
39  { "character_reputation", DTT_CHAR_TABLE },
40  { "character_spell", DTT_CHAR_TABLE },
41  { "character_spell_cooldown", DTT_CHAR_TABLE },
42  { "character_action", DTT_CHAR_TABLE },
43  { "character_aura", DTT_CHAR_TABLE },
44  { "character_homebind", DTT_CHAR_TABLE },
45  { "character_skills", DTT_CHAR_TABLE },
46  { "character_inventory", DTT_INVENTORY },
47  { "mail", DTT_MAIL },
48  { "mail_items", DTT_MAIL_ITEM },
49  { "item_instance", DTT_ITEM },
50  { "character_gifts", DTT_ITEM_GIFT },
51  { "item_text", DTT_ITEM_TEXT },
52  { "character_pet", DTT_PET },
53  { "pet_aura", DTT_PET_TABLE },
54  { "pet_spell", DTT_PET_TABLE },
55  { "pet_spell_cooldown", DTT_PET_TABLE },
56 };
57 
58 // Low level functions
59 static bool findtoknth(std::string& str, int n, std::string::size_type& s, std::string::size_type& e)
60 {
61  int i;
62  s = e = 0;
63  std::string::size_type size = str.size();
64  for (i = 1; s < size && i < n; s++) if (str[s] == ' ') ++i;
65  if (i < n)
66  return false;
67 
68  e = str.find(' ', s);
69 
70  return e != std::string::npos;
71 }
72 
73 std::string gettoknth(std::string& str, int n)
74 {
75  std::string::size_type s = 0, e = 0;
76  if (!findtoknth(str, n, s, e))
77  return "";
78 
79  return str.substr(s, e - s);
80 }
81 
82 bool findnth(std::string& str, int n, std::string::size_type& s, std::string::size_type& e)
83 {
84  s = str.find("VALUES ('") + 9;
85  if (s == std::string::npos) return false;
86 
87  do
88  {
89  e = str.find("'", s);
90  if (e == std::string::npos) return false;
91  }
92  while (str[e - 1] == '\\');
93 
94  for (int i = 1; i < n; ++i)
95  {
96  do
97  {
98  s = e + 4;
99  e = str.find("'", s);
100  if (e == std::string::npos) return false;
101  }
102  while (str[e - 1] == '\\');
103  }
104  return true;
105 }
106 
107 std::string gettablename(std::string& str)
108 {
109  std::string::size_type s = 13;
110  std::string::size_type e = str.find(_TABLE_SIM_, s);
111  if (e == std::string::npos)
112  return "";
113 
114  return str.substr(s, e - s);
115 }
116 
117 bool changenth(std::string& str, int n, const char* with, bool insert = false, bool nonzero = false)
118 {
119  std::string::size_type s, e;
120  if (!findnth(str, n, s, e))
121  return false;
122 
123  if (nonzero && str.substr(s, e - s) == "0")
124  return true; // not an error
125  if (!insert)
126  str.replace(s, e - s, with);
127  else
128  str.insert(s, with);
129 
130  return true;
131 }
132 
133 std::string getnth(std::string& str, int n)
134 {
135  std::string::size_type s, e;
136  if (!findnth(str, n, s, e))
137  return "";
138 
139  return str.substr(s, e - s);
140 }
141 
142 bool changetoknth(std::string& str, int n, const char* with, bool insert = false, bool nonzero = false)
143 {
144  std::string::size_type s = 0, e = 0;
145  if (!findtoknth(str, n, s, e))
146  return false;
147  if (nonzero && str.substr(s, e - s) == "0")
148  return true; // not an error
149  if (!insert)
150  str.replace(s, e - s, with);
151  else
152  str.insert(s, with);
153 
154  return true;
155 }
156 
157 uint32 registerNewGuid(uint32 oldGuid, std::map<uint32, uint32>& guidMap, uint32 hiGuid)
158 {
159  std::map<uint32, uint32>::iterator itr = guidMap.find(oldGuid);
160  if (itr != guidMap.end())
161  return itr->second;
162 
163  uint32 newguid = hiGuid + guidMap.size();
164  guidMap[oldGuid] = newguid;
165  return newguid;
166 }
167 
168 bool changeGuid(std::string& str, int n, std::map<uint32, uint32>& guidMap, uint32 hiGuid, bool nonzero = false)
169 {
170  char chritem[20];
171  uint32 oldGuid = atoi(getnth(str, n).c_str());
172  if (nonzero && oldGuid == 0)
173  return true; // not an error
174 
175  uint32 newGuid = registerNewGuid(oldGuid, guidMap, hiGuid);
176  snprintf(chritem, 20, "%d", newGuid);
177 
178  return changenth(str, n, chritem, false, nonzero);
179 }
180 
181 bool changetokGuid(std::string& str, int n, std::map<uint32, uint32>& guidMap, uint32 hiGuid, bool nonzero = false)
182 {
183  char chritem[20];
184  uint32 oldGuid = atoi(gettoknth(str, n).c_str());
185  if (nonzero && oldGuid == 0)
186  return true; // not an error
187 
188  uint32 newGuid = registerNewGuid(oldGuid, guidMap, hiGuid);
189  snprintf(chritem, 20, "%d", newGuid);
190 
191  return changetoknth(str, n, chritem, false, nonzero);
192 }
193 
194 void fixNULLfields(std::string& line)
195 {
196  std::string nullString("'NULL'");
197  size_t pos = line.find(nullString);
198  while (pos != std::string::npos)
199  {
200  line.replace(pos, nullString.length(), "NULL");
201  pos = line.find(nullString);
202  }
203 }
204 
205 std::string CreateDumpString(char const* tableName, QueryResult_AutoPtr result)
206 {
207  if (!tableName || !result) return "";
208  std::ostringstream ss;
209  ss << "INSERT INTO " << _TABLE_SIM_ << tableName << _TABLE_SIM_ << " VALUES (";
210  Field* fields = result->Fetch();
211  for (uint32 i = 0; i < result->GetFieldCount(); ++i)
212  {
213  if (i == 0) ss << "'";
214  else ss << ", '";
215 
216  std::string s = fields[i].GetCppString();
218  ss << s;
219 
220  ss << "'";
221  }
222  ss << ");";
223  return ss.str();
224 }
225 
226 std::string PlayerDumpWriter::GenerateWhereStr(char const* field, uint32 guid)
227 {
228  std::ostringstream wherestr;
229  wherestr << field << " = '" << guid << "'";
230  return wherestr.str();
231 }
232 
233 std::string PlayerDumpWriter::GenerateWhereStr(char const* field, GUIDs const& guids, GUIDs::const_iterator& itr)
234 {
235  std::ostringstream wherestr;
236  wherestr << field << " IN ('";
237  for (; itr != guids.end(); ++itr)
238  {
239  wherestr << *itr;
240 
241  if (wherestr.str().size() > MAX_QUERY_LEN - 50) // near to max query
242  {
243  ++itr;
244  break;
245  }
246 
247  GUIDs::const_iterator itr2 = itr;
248  if (++itr2 != guids.end())
249  wherestr << "','";
250  }
251  wherestr << "')";
252  return wherestr.str();
253 }
254 
255 void StoreGUID(QueryResult_AutoPtr result, uint32 field, std::set<uint32>& guids)
256 {
257  Field* fields = result->Fetch();
258  uint32 guid = fields[field].GetUInt32();
259  if (guid)
260  guids.insert(guid);
261 }
262 
263 void StoreGUID(QueryResult_AutoPtr result, uint32 data, uint32 field, std::set<uint32>& guids)
264 {
265  Field* fields = result->Fetch();
266  std::string dataStr = fields[data].GetCppString();
267  uint32 guid = atoi(gettoknth(dataStr, field).c_str());
268  if (guid)
269  guids.insert(guid);
270 }
271 
272 // Writing - High-level functions
273 void PlayerDumpWriter::DumpTable(std::string& dump, uint32 guid, char const* tableFrom, char const* tableTo, DumpTableType type)
274 {
275  GUIDs const* guids = NULL;
276  char const* fieldname = NULL;
277 
278  switch (type)
279  {
280  case DTT_ITEM:
281  fieldname = "guid";
282  guids = &items;
283  break;
284  case DTT_ITEM_GIFT:
285  fieldname = "item_guid";
286  guids = &items;
287  break;
288  case DTT_PET:
289  fieldname = "owner";
290  break;
291  case DTT_PET_TABLE:
292  fieldname = "guid";
293  guids = &pets;
294  break;
295  case DTT_MAIL:
296  fieldname = "receiver";
297  break;
298  case DTT_MAIL_ITEM:
299  fieldname = "mail_id";
300  guids = &mails;
301  break;
302  case DTT_ITEM_TEXT:
303  fieldname = "id";
304  guids = &texts;
305  break;
306  default:
307  fieldname = "guid";
308  break;
309  }
310 
311  // for guid set stop if set is empty
312  if (guids && guids->empty())
313  return; // nothing to do
314 
315  // setup for guids case start position
316  GUIDs::const_iterator guids_itr;
317  if (guids)
318  guids_itr = guids->begin();
319 
320  do
321  {
322  std::string wherestr;
323 
324  if (guids) // set case, get next guids string
325  wherestr = GenerateWhereStr(fieldname, *guids, guids_itr);
326  else // not set case, get single guid string
327  wherestr = GenerateWhereStr(fieldname, guid);
328 
329  QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT * FROM %s WHERE %s", tableFrom, wherestr.c_str());
330  if (!result)
331  return;
332 
333  do
334  {
335  // collect guids
336  switch (type)
337  {
338  case DTT_INVENTORY:
339  StoreGUID(result, 3, items);
340  break; // item guid collection
341  case DTT_ITEM:
342  StoreGUID(result, 0, ITEM_FIELD_ITEM_TEXT_ID, texts);
343  break;
344  // item text id collection
345  case DTT_PET:
346  StoreGUID(result, 0, pets);
347  break; // pet guid collection
348  case DTT_MAIL:
349  StoreGUID(result, 0, mails); // mail id collection
350  StoreGUID(result, 6, texts);
351  break; // item text id collection
352  case DTT_MAIL_ITEM:
353  StoreGUID(result, 1, items);
354  break; // item guid collection
355  default:
356  break;
357  }
358 
359  dump += CreateDumpString(tableTo, result);
360  dump += "\n";
361  }
362  while (result->NextRow());
363  }
364  while (guids && guids_itr != guids->end()); // not set case iterate single time, set case iterate for all guids
365 }
366 
368 {
369  std::string dump;
370 
371  dump += "IMPORTANT NOTE: This sql queries not created for apply directly, use '.pdump load' command in console or client chat instead.\n";
372  dump += "IMPORTANT NOTE: NOT APPLY ITS DIRECTLY to character DB or you will DAMAGE and CORRUPT character DB\n\n";
373 
374  for (int i = 0; i < DUMP_TABLE_COUNT; ++i)
375  DumpTable(dump, guid, dumpTables[i].name, dumpTables[i].name, dumpTables[i].type);
376 
377  // @todo Add instance/group..
378  // @todo Add a dump level option to skip some non-important tables
379 
380  return dump;
381 }
382 
383 DumpReturn PlayerDumpWriter::WriteDump(const std::string& file, uint32 guid)
384 {
385  FILE* fout = fopen(file.c_str(), "w");
386  if (!fout)
387  return DUMP_FILE_OPEN_ERROR;
388 
389  std::string dump = GetDump(guid);
390 
391  fprintf(fout, "%s\n", dump.c_str());
392  fclose(fout);
393  return DUMP_SUCCESS;
394 }
395 
396 // Reading - High-level functions
397 #define ROLLBACK(DR) {CharacterDatabase.RollbackTransaction(); fclose(fin); return (DR);}
398 
399 DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, std::string name, uint32 guid)
400 {
401  // check character count
402  uint32 charcount = sAccountMgr->GetCharactersCount(account);
403  if (charcount >= 10)
404  return DUMP_TOO_MANY_CHARS;
405 
406  FILE* fin = fopen(file.c_str(), "r");
407  if (!fin)
408  return DUMP_FILE_OPEN_ERROR;
409 
411  char newguid[20], chraccount[20], newpetid[20], currpetid[20], lastpetid[20];
412 
413  // make sure the same guid doesn't already exist and is safe to use
414  bool incHighest = true;
415  if (guid != 0 && guid < sObjectMgr.m_hiCharGuid)
416  {
417  result = CharacterDatabase.PQuery("SELECT 1 FROM characters WHERE guid = '%d'", guid);
418  if (result)
419  guid = sObjectMgr.m_hiCharGuid; // use first free if exists
420  else incHighest = false;
421  }
422  else
423  guid = sObjectMgr.m_hiCharGuid;
424 
425  // normalize the name if specified and check if it exists
426  if (!normalizePlayerName(name))
427  name = "";
428 
429  if (ObjectMgr::IsValidName(name, true))
430  {
431  CharacterDatabase.escape_string(name); // for safe, we use name only for sql quearies anyway
432  result = CharacterDatabase.PQuery("SELECT 1 FROM characters WHERE name = '%s'", name.c_str());
433  if (result)
434  name = ""; // use the one from the dump
435  }
436  else
437  name = "";
438 
439  // name encoded or empty
440 
441  snprintf(newguid, 20, "%d", guid);
442  snprintf(chraccount, 20, "%d", account);
443  snprintf(newpetid, 20, "%d", sObjectMgr.GeneratePetNumber());
444  snprintf(lastpetid, 20, "%s", "");
445 
446  std::map<uint32, uint32> items;
447  std::map<uint32, uint32> mails;
448  char buf[32000] = "";
449 
450  typedef std::map<uint32, uint32> PetIds; // old->new petid relation
451  typedef PetIds::value_type PetIdsPair;
452  PetIds petids;
453 
455  while (!feof(fin))
456  {
457  if (!fgets(buf, 32000, fin))
458  {
459  if (feof(fin)) break;
461  }
462 
463  std::string line;
464  line.assign(buf);
465 
466  // skip empty strings
467  size_t nw_pos = line.find_first_not_of(" \t\n\r\7");
468  if (nw_pos == std::string::npos)
469  continue;
470 
471  // skip NOTE
472  if (line.substr(nw_pos, 15) == "IMPORTANT NOTE:")
473  continue;
474 
475  // determine table name and load type
476  std::string tn = gettablename(line);
477  if (tn.empty())
478  {
479  sLog.outError("LoadPlayerDump: Can't extract table name from line: '%s'!", line.c_str());
481  }
482 
484  uint8 i;
485  for (i = 0; i < DUMP_TABLE_COUNT; ++i)
486  {
487  if (tn == dumpTables[i].name)
488  {
489  type = dumpTables[i].type;
490  break;
491  }
492  }
493 
494  if (i == DUMP_TABLE_COUNT)
495  {
496  sLog.outError("LoadPlayerDump: Unknown table: '%s'!", tn.c_str());
498  }
499 
500  // change the data to server values
501  switch (type)
502  {
503  case DTT_CHAR_TABLE:
504  if (!changenth(line, 1, newguid))
506  break;
507 
508  case DTT_CHARACTER: // character t.
509  {
510  if (!changenth(line, 1, newguid))
512 
513  // guid, data field:guid, items
514  if (!changenth(line, 2, chraccount))
516  std::string vals = getnth(line, 3);
517  if (!changetoknth(vals, OBJECT_FIELD_GUID + 1, newguid))
519  for (uint16 field = PLAYER_FIELD_INV_SLOT_HEAD; field < PLAYER_FARSIGHT; field++)
520  if (!changetokGuid(vals, field + 1, items, sObjectMgr.m_hiItemGuid, true))
522  if (!changenth(line, 3, vals.c_str()))
524  if (name == "")
525  {
526  // check if the original name already exists
527  name = getnth(line, 4);
529 
530  result = CharacterDatabase.PQuery("SELECT 1 FROM characters WHERE name = '%s'", name.c_str());
531  if (result)
532  {
533  if (!changenth(line, 30, "1")) // rename on login: `at_login` field 30 in raw field list
535  }
536  }
537  else if (!changenth(line, 4, name.c_str()))
539 
540  const char null[5] = "NULL";
541  if (!changenth(line, 59, null))
543  if (!changenth(line, 60, null))
545  if (!changenth(line, 61, null))
547 
548  break;
549  }
550  case DTT_INVENTORY: // character_inventory t.
551  {
552  if (!changenth(line, 1, newguid))
554 
555  // bag, item
556  if (!changeGuid(line, 2, items, sObjectMgr.m_hiItemGuid, true))
558  if (!changeGuid(line, 4, items, sObjectMgr.m_hiItemGuid))
560  break;
561  }
562  case DTT_ITEM: // item_instance t.
563  {
564  // item, owner, data field:item, owner guid
565  if (!changeGuid(line, 1, items, sObjectMgr.m_hiItemGuid))
567  if (!changenth(line, 2, newguid))
569  std::string vals = getnth(line, 3);
570  if (!changetokGuid(vals, OBJECT_FIELD_GUID + 1, items, sObjectMgr.m_hiItemGuid))
572  if (!changetoknth(vals, ITEM_FIELD_OWNER + 1, newguid))
574  if (!changenth(line, 3, vals.c_str()))
576  break;
577  }
578  case DTT_ITEM_GIFT: // character_gift
579  {
580  // guid,item_guid,
581  if (!changenth(line, 1, newguid))
583  if (!changeGuid(line, 2, items, sObjectMgr.m_hiItemGuid))
585  break;
586  }
587  case DTT_PET: // character_pet t
588  {
589  //store a map of old pet id to new inserted pet id for use by type 5 tables
590  snprintf(currpetid, 20, "%s", getnth(line, 1).c_str());
591  if (strlen(lastpetid) == 0) snprintf(lastpetid, 20, "%s", currpetid);
592  if (strcmp(lastpetid, currpetid) != 0)
593  {
594  snprintf(newpetid, 20, "%d", sObjectMgr.GeneratePetNumber());
595  snprintf(lastpetid, 20, "%s", currpetid);
596  }
597 
598  std::map<uint32, uint32> :: const_iterator petids_iter = petids.find(atoi(currpetid));
599 
600  if (petids_iter == petids.end())
601  petids.insert(PetIdsPair(atoi(currpetid), atoi(newpetid)));
602 
603  // item, entry, owner, ...
604  if (!changenth(line, 1, newpetid))
606  if (!changenth(line, 3, newguid))
608 
609  break;
610  }
611  case DTT_PET_TABLE: // pet_aura, pet_spell, pet_spell_cooldown t
612  {
613  snprintf(currpetid, 20, "%s", getnth(line, 1).c_str());
614 
615  // lookup currpetid and match to new inserted pet id
616  std::map<uint32, uint32> :: const_iterator petids_iter = petids.find(atoi(currpetid));
617  if (petids_iter == petids.end()) // couldn't find new inserted id
619 
620  snprintf(newpetid, 20, "%d", petids_iter->second);
621 
622  if (!changenth(line, 1, newpetid))
624 
625  break;
626  }
627  case DTT_MAIL: // mail
628  {
629  // id,messageType,stationery,sender,receiver
630  if (!changeGuid(line, 1, mails, sObjectMgr.m_mailid))
632  if (!changenth(line, 5, newguid))
634  break;
635  }
636  case DTT_MAIL_ITEM: // mail_items
637  {
638  // mail_id,item_guid,item_template,receiver
639  if (!changeGuid(line, 1, mails, sObjectMgr.m_mailid))
641  if (!changeGuid(line, 2, items, sObjectMgr.m_hiItemGuid))
643  if (!changenth(line, 4, newguid))
645  break;
646  }
647  default:
648  sLog.outError("Unknown dump table type: %u", type);
649  break;
650  }
651 
652  fixNULLfields(line);
653 
654  if (!CharacterDatabase.Execute(line.c_str()))
656  }
657 
659 
660  sObjectMgr.m_hiItemGuid += items.size();
661  sObjectMgr.m_mailid += mails.size();
662 
663  if (incHighest)
664  ++sObjectMgr.m_hiCharGuid;
665 
666  fclose(fin);
667 
668  return DUMP_SUCCESS;
669 }
670 
#define ROLLBACK(DR)
Definition: PlayerDump.cpp:397
#define DUMP_TABLE_COUNT
Definition: PlayerDump.cpp:27
#define snprintf
Definition: Common.h:129
uint32 registerNewGuid(uint32 oldGuid, std::map< uint32, uint32 > &guidMap, uint32 hiGuid)
Definition: PlayerDump.cpp:157
std::set< uint32 > GUIDs
Definition: PlayerDump.h:75
DumpReturn
Definition: PlayerDump.h:52
std::string gettoknth(std::string &str, int n)
Definition: PlayerDump.cpp:73
void StoreGUID(QueryResult_AutoPtr result, uint32 field, std::set< uint32 > &guids)
Definition: PlayerDump.cpp:255
bool BeginTransaction()
Definition: Database.cpp:533
DumpTableType type
Definition: PlayerDump.cpp:32
QueryResult_AutoPtr PQuery(const char *format,...) ATTR_PRINTF(2
Definition: Database.cpp:400
char const * name
Definition: PlayerDump.cpp:31
Definition: Field.h:24
bool Execute(const char *sql)
Definition: Database.cpp:420
#define sLog
Log class singleton.
Definition: Log.h:187
unsigned long escape_string(char *to, const char *from, unsigned long length)
Definition: Database.cpp:212
void DumpTable(std::string &dump, uint32 guid, char const *tableFrom, char const *tableTo, DumpTableType type)
Definition: PlayerDump.cpp:273
DumpTableType
Definition: PlayerDump.h:25
#define sObjectMgr
Definition: ObjectMgr.h:1285
static bool IsValidName(const std::string &name, bool create=false)
Definition: ObjectMgr.cpp:6634
bool CommitTransaction()
Definition: Database.cpp:551
std::string CreateDumpString(char const *tableName, QueryResult_AutoPtr result)
Definition: PlayerDump.cpp:205
std::string GenerateWhereStr(char const *field, GUIDs const &guids, GUIDs::const_iterator &itr)
Definition: PlayerDump.cpp:233
DumpReturn WriteDump(const std::string &file, uint32 guid)
Definition: PlayerDump.cpp:383
bool normalizePlayerName(std::string &name)
Definition: ObjectMgr.cpp:225
ACE_UINT8 uint8
Definition: Define.h:73
std::string GetCppString() const
Definition: Field.h:52
std::string getnth(std::string &str, int n)
Definition: PlayerDump.cpp:133
bool findnth(std::string &str, int n, std::string::size_type &s, std::string::size_type &e)
Definition: PlayerDump.cpp:82
#define _TABLE_SIM_
Definition: DatabaseEnv.h:31
std::string gettablename(std::string &str)
Definition: PlayerDump.cpp:107
#define sAccountMgr
Definition: AccountMgr.h:60
bool changetoknth(std::string &str, int n, const char *with, bool insert=false, bool nonzero=false)
Definition: PlayerDump.cpp:142
ACE_Refcounted_Auto_Ptr< QueryResult, ACE_Null_Mutex > QueryResult_AutoPtr
Definition: QueryResult.h:113
bool changenth(std::string &str, int n, const char *with, bool insert=false, bool nonzero=false)
Definition: PlayerDump.cpp:117
bool changeGuid(std::string &str, int n, std::map< uint32, uint32 > &guidMap, uint32 hiGuid, bool nonzero=false)
Definition: PlayerDump.cpp:168
void fixNULLfields(std::string &line)
Definition: PlayerDump.cpp:194
DumpReturn LoadDump(const std::string &file, uint32 account, std::string name, uint32 guid)
Definition: PlayerDump.cpp:399
DatabaseType CharacterDatabase
Accessor to the character database.
Definition: Main.cpp:54
ACE_UINT16 uint16
Definition: Define.h:72
ACE_UINT32 uint32
Definition: Define.h:71
bool changetokGuid(std::string &str, int n, std::map< uint32, uint32 > &guidMap, uint32 hiGuid, bool nonzero=false)
Definition: PlayerDump.cpp:181
std::string GetDump(uint32 guid)
Definition: PlayerDump.cpp:367
#define MAX_QUERY_LEN
Definition: Database.h:44