void AddonMgr::LoadFromDB() { QueryResult *result = WorldDatabase.Query("SELECT * FROM clientaddons"); if(!result) { sLog.outString("Query failed: SELECT * FROM clientaddons"); return; } do { Field *field = result->Fetch(); AddonEntry *ent = new AddonEntry; ent->name = field[1].GetString(); ent->crc = field[2].GetUInt64(); ent->banned = (field[3].GetUInt32()>0? true:false); ent->isNew = false; if(result->GetFieldCount() == 5) // To avoid crashes for stilly nubs who don't update table :P ent->showinlist = (field[4].GetUInt32()>0 ? true : false); KnownAddons[ent->name] = ent; } while(result->NextRow()); delete result; }
void World::LoadAreaTriggerInformation() { QueryResult *result = NULL; // uint32 MaxID = 0; AreaTrigger *pAT = NULL; result = sDatabase.Query("SELECT * FROM areatriggers"); if(result==NULL) { sLog.outString(" Query failed."); return; } uint32 total =(uint32) result->GetRowCount(); int num = 0; do { Field *fields = result->Fetch(); pAT = new AreaTrigger; pAT->AreaTriggerID = fields[0].GetUInt32(); pAT->Type = (uint8)fields[1].GetUInt32(); pAT->Mapid = fields[2].GetUInt32(); pAT->PendingScreen = fields[3].GetUInt32(); pAT->Name= fields[4].GetString(); pAT->x = fields[5].GetFloat(); pAT->y = fields[6].GetFloat(); pAT->z = fields[7].GetFloat(); pAT->o = fields[8].GetFloat(); if(result->GetFieldCount() > 9) // bur: crash fix for lazy bastards who dont update their db >.> { pAT->required_honor_rank = fields[9].GetUInt32(); pAT->required_level = fields[10].GetUInt32(); } AddAreaTrigger(pAT); ++num; if(!(num % 10)) SetProgressBar(num, total, "Area Triggers"); } while( result->NextRow() ); delete result; ClearProgressBar(); }
std::string CreateDumpString(char const* tableName, QueryResult result) { if (!tableName || !result) return ""; std::ostringstream ss; ss << "INSERT INTO "<< _TABLE_SIM_ << tableName << _TABLE_SIM_ << " VALUES ("; Field* fields = result->Fetch(); for (uint32 i = 0; i < result->GetFieldCount(); ++i) { if (i == 0) ss << '\''; else ss << ", '"; std::string s = fields[i].GetString(); CharacterDatabase.EscapeString(s); ss << s; ss << '\''; } ss << ");"; return ss.str(); }
// Writing - High-level functions bool PlayerDumpWriter::DumpTable(std::string& dump, uint32 guid, char const*tableFrom, char const*tableTo, DumpTableType type) { GUIDs const* guids = NULL; char const* fieldname = NULL; switch (type) { case DTT_ITEM: fieldname = "guid"; guids = &items; break; case DTT_ITEM_GIFT: fieldname = "item_guid"; guids = &items; break; case DTT_PET: fieldname = "owner"; break; case DTT_PET_TABLE: fieldname = "guid"; guids = &pets; break; case DTT_MAIL: fieldname = "receiver"; break; case DTT_MAIL_ITEM: fieldname = "mail_id"; guids = &mails; break; default: fieldname = "guid"; break; } // for guid set stop if set is empty if (guids && guids->empty()) return true; // nothing to do // setup for guids case start position GUIDs::const_iterator guids_itr; if (guids) guids_itr = guids->begin(); do { std::string wherestr; if (guids) // set case, get next guids string wherestr = GenerateWhereStr(fieldname, *guids, guids_itr); else // not set case, get single guid string wherestr = GenerateWhereStr(fieldname, guid); QueryResult result = CharacterDatabase.PQuery("SELECT * FROM %s WHERE %s", tableFrom, wherestr.c_str()); if (!result) return true; do { // collect guids switch (type) { case DTT_INVENTORY: StoreGUID(result, 3, items); break; // item guid collection (character_inventory.item) case DTT_PET: StoreGUID(result, 0, pets); break; // pet petnumber collection (character_pet.id) case DTT_MAIL: StoreGUID(result, 0, mails); // mail id collection (mail.id) case DTT_MAIL_ITEM: StoreGUID(result, 1, items); break; // item guid collection (mail_items.item_guid) case DTT_CHARACTER: { if (result->GetFieldCount() <= 67) // avoid crashes on next check return true; if (result->Fetch()[67].GetUInt32()) // characters.deleteInfos_Account - if filled error return false; break; } default: break; } dump += CreateDumpString(tableTo, result); dump += "\n"; } while (result->NextRow()); } while (guids && guids_itr != guids->end()); // not set case iterate single time, set case iterate for all guids return true; }
char* DBCDatabaseLoader::Load(uint32& records, char**& indexTable) { std::string query = Trinity::StringFormat("SELECT * FROM %s ORDER BY %s DESC;", _sqlTableName, _indexName); // no error if empty set QueryResult result = WorldDatabase.Query(query.c_str()); if (!result) return nullptr; // Check if sql index pos is valid if (int32(result->GetFieldCount() - 1) < _sqlIndexPos) { ASSERT(false, "Invalid index pos for dbc: '%s'", _sqlTableName); return nullptr; } // Resize index table // database query *MUST* contain ORDER BY `index_field` DESC clause uint32 indexTableSize = std::max(records, (*result)[_sqlIndexPos].GetUInt32() + 1); if (indexTableSize > records) { char** tmpIdxTable = new char*[indexTableSize]; memset(tmpIdxTable, 0, indexTableSize * sizeof(char*)); memcpy(tmpIdxTable, indexTable, records * sizeof(char*)); delete[] indexTable; indexTable = tmpIdxTable; } std::unique_ptr<char[]> dataTable = Trinity::make_unique<char[]>(result->GetRowCount() * _recordSize); std::unique_ptr<uint32[]> newIndexes = Trinity::make_unique<uint32[]>(result->GetRowCount()); uint32 newRecords = 0; // Insert sql data into the data array do { Field* fields = result->Fetch(); uint32 indexValue = fields[_sqlIndexPos].GetUInt32(); char* dataValue = indexTable[indexValue]; if (!dataValue) { newIndexes[newRecords] = indexValue; dataValue = &dataTable[newRecords++ * _recordSize]; } else { // Attempt to overwrite existing data ASSERT(false, "Index %d already exists in dbc:'%s'", indexValue, _sqlTableName); return nullptr; } uint32 dataOffset = 0; uint32 sqlColumnNumber = 0; char const* dbcFormat = _dbcFormat; char const* sqlFormat = _formatString; for (; (*dbcFormat || *sqlFormat); ++dbcFormat, ++sqlFormat) { if (!*dbcFormat || !*sqlFormat) { ASSERT(false, "DB and DBC format strings do not have the same length for '%s'", _sqlTableName); return nullptr; } if (!*dbcFormat) break; switch (*sqlFormat) { case FT_SQL_PRESENT: switch (*dbcFormat) { case FT_FLOAT: *reinterpret_cast<float*>(&dataValue[dataOffset]) = fields[sqlColumnNumber].GetFloat(); dataOffset += sizeof(float); break; case FT_IND: case FT_INT: *reinterpret_cast<uint32*>(&dataValue[dataOffset]) = fields[sqlColumnNumber].GetUInt32(); dataOffset += sizeof(uint32); break; case FT_BYTE: *reinterpret_cast<uint8*>(&dataValue[dataOffset]) = fields[sqlColumnNumber].GetUInt8(); dataOffset += sizeof(uint8); break; case FT_STRING: *reinterpret_cast<char**>(&dataValue[dataOffset]) = CloneStringToPool(fields[sqlColumnNumber].GetString()); dataOffset += sizeof(char*); break; case FT_SORT: break; default: ASSERT(false, "Unsupported data type '%c' marked present in table '%s'", *dbcFormat, _sqlTableName); return nullptr; } ++sqlColumnNumber; break; case FT_SQL_ABSENT: switch (*dbcFormat) { case FT_FLOAT: *reinterpret_cast<float*>(&dataValue[dataOffset]) = 0.0f; dataOffset += sizeof(float); break; case FT_IND: case FT_INT: *reinterpret_cast<uint32*>(&dataValue[dataOffset]) = uint32(0); dataOffset += sizeof(uint32); break; case FT_BYTE: *reinterpret_cast<uint8*>(&dataValue[dataOffset]) = uint8(0); dataOffset += sizeof(uint8); break; case FT_STRING: *reinterpret_cast<char**>(&dataValue[dataOffset]) = const_cast<char*>(nullStr); dataOffset += sizeof(char*); break; } break; default: ASSERT(false, "Invalid DB format string for '%s'", _sqlTableName); return nullptr; } } ASSERT(sqlColumnNumber == result->GetFieldCount(), "SQL format string does not match database for table: '%s'", _sqlTableName); ASSERT(dataOffset == _recordSize); } while (result->NextRow()); ASSERT(newRecords == result->GetRowCount()); // insert new records to index table for (uint32 i = 0; i < newRecords; ++i) indexTable[newIndexes[i]] = &dataTable[i * _recordSize]; records = indexTableSize; return dataTable.release(); }
void SQLStorage::Load () { uint32 maxi; Field *fields; QueryResult *result = sDatabase.PQuery("SELECT MAX(`entry`) FROM `%s`",table); if(!result) { sLog.outError("Error loading `%s` table (not exist?)\n",table); exit(1); // Stop server at loading non exited table or not accessable table } maxi= (*result)[0].GetUInt32()+1; delete result; result = sDatabase.PQuery("SELECT COUNT(*) FROM `%s`",table); fields = result->Fetch(); RecordCount=fields[0].GetUInt32(); delete result; result = sDatabase.PQuery("SELECT * FROM `%s`",table); if(!result) { sLog.outError("`%s` table is empty!\n",table); RecordCount = 0; return; } uint32 recordsize=0; uint32 offset=0; if(iNumFields!=result->GetFieldCount()) { RecordCount = 0; sLog.outError("Error in `%s` table, probably sql file format was updated (there should be %d fields in sql).\n",table,iNumFields); delete result; exit(1); // Stop server at loading broken or non-compatiable table. } if(sizeof(char*)==sizeof(uint32)) recordsize=4*iNumFields; else { //get struct size uint32 sc=0; for(uint32 x=0;x<iNumFields;x++) if(format[x]==FT_STRING) sc++; recordsize=(iNumFields-sc)*4+sc*sizeof(char*); } char** newIndex=new char*[maxi]; memset(newIndex,0,maxi*sizeof(char*)); char * _data= new char[RecordCount *recordsize]; uint32 count=0; barGoLink bar( RecordCount ); do { fields = result->Fetch(); bar.step(); char *p=(char*)&_data[recordsize*count]; newIndex[fields[0].GetUInt32()]=p; offset=0; for(uint32 x=0;x<iNumFields;x++) switch(format[x]) { case FT_INT: *((uint32*)(&p[offset]))=fields[x].GetUInt32(); offset+=sizeof(uint32); break; case FT_FLOAT: *((float*)(&p[offset]))=fields[x].GetFloat(); offset+=sizeof(float); break; case FT_STRING: char * tmp=(char*)fields[x].GetString(); char* st; if(!tmp) { st=new char[1]; *st=0; } else { uint32 l=strlen(tmp)+1; st=new char[l]; memcpy(st,tmp,l); } *((char**)(&p[offset]))=st; offset+=sizeof(char*); break; } count++; }while( result->NextRow() ); delete result; if(data) //Reload table AddEvent((EventHandler)(&FreeStorage),this,20000); pOldData=data; pOldIndex=pIndex; iOldNumRecords=MaxEntry; pIndex =newIndex; MaxEntry=maxi; data=_data; }
void ClientMgr::LoadPlayerCreateInfo() { QueryResult *result = WorldDatabase.Query( "SELECT * FROM playercreateinfo" ); if( result == NULL ) { Log.Error("MySQL","Query failed: SELECT * FROM playercreateinfo"); return; } if( result->GetFieldCount() < 25 ) { Log.Error("PlayerCreateInfo", "Incorrect number of columns in playercreateinfo found %u, should be 25. check for sql updates", result->GetFieldCount()); delete result; return; } PlayerCreateInfo *pPlayerCreateInfo; int fieldcount = 0; do { Field *fields = result->Fetch(); fieldcount = 0; pPlayerCreateInfo = new PlayerCreateInfo; pPlayerCreateInfo->index = fields[fieldcount++].GetUInt8(); pPlayerCreateInfo->race = fields[fieldcount++].GetUInt8(); pPlayerCreateInfo->factiontemplate = fields[fieldcount++].GetUInt32(); pPlayerCreateInfo->class_ = fields[fieldcount++].GetUInt8(); pPlayerCreateInfo->mapId = fields[fieldcount++].GetUInt32(); pPlayerCreateInfo->zoneId = fields[fieldcount++].GetUInt32(); pPlayerCreateInfo->positionX = fields[fieldcount++].GetFloat(); pPlayerCreateInfo->positionY = fields[fieldcount++].GetFloat(); pPlayerCreateInfo->positionZ = fields[fieldcount++].GetFloat(); pPlayerCreateInfo->Orientation = fields[fieldcount++].GetFloat(); pPlayerCreateInfo->displayId = fields[fieldcount++].GetUInt16(); pPlayerCreateInfo->strength = fields[fieldcount++].GetUInt8(); pPlayerCreateInfo->ability = fields[fieldcount++].GetUInt8(); pPlayerCreateInfo->stamina = fields[fieldcount++].GetUInt8(); pPlayerCreateInfo->intellect = fields[fieldcount++].GetUInt8(); pPlayerCreateInfo->spirit = fields[fieldcount++].GetUInt8(); pPlayerCreateInfo->health = fields[fieldcount++].GetUInt32(); pPlayerCreateInfo->mana = fields[fieldcount++].GetUInt32(); pPlayerCreateInfo->rage = fields[fieldcount++].GetUInt32(); pPlayerCreateInfo->focus = fields[fieldcount++].GetUInt32(); pPlayerCreateInfo->energy = fields[fieldcount++].GetUInt32(); pPlayerCreateInfo->runic = fields[fieldcount++].GetUInt32(); pPlayerCreateInfo->attackpower = fields[fieldcount++].GetUInt32(); pPlayerCreateInfo->mindmg = fields[fieldcount++].GetFloat(); pPlayerCreateInfo->maxdmg = fields[fieldcount++].GetFloat(); QueryResult *sk_sql = WorldDatabase.Query("SELECT * FROM playercreateinfo_skills WHERE indexid = %u", pPlayerCreateInfo->index); if(sk_sql) { do { Field *fields = sk_sql->Fetch(); CreateInfo_SkillStruct tsk; tsk.skillid = fields[1].GetUInt32(); tsk.currentval = fields[2].GetUInt32(); tsk.maxval = fields[3].GetUInt32(); pPlayerCreateInfo->skills.push_back(tsk); } while(sk_sql->NextRow()); delete sk_sql; } QueryResult *sp_sql = WorldDatabase.Query("SELECT * FROM playercreateinfo_spells WHERE indexid = %u", pPlayerCreateInfo->index); if(sp_sql) { do { pPlayerCreateInfo->spell_list.insert(sp_sql->Fetch()[1].GetUInt32()); } while(sp_sql->NextRow()); delete sp_sql; } QueryResult *items_sql = WorldDatabase.Query("SELECT * FROM playercreateinfo_items WHERE indexid = %u", pPlayerCreateInfo->index); if(items_sql) { do { Field *fields = items_sql->Fetch(); CreateInfo_ItemStruct itm; itm.protoid = fields[1].GetUInt32(); itm.slot = fields[2].GetUInt8(); itm.amount = fields[3].GetUInt32(); pPlayerCreateInfo->items.push_back(itm); } while(items_sql->NextRow()); delete items_sql; } QueryResult *bars_sql = WorldDatabase.Query("SELECT * FROM playercreateinfo_bars WHERE class = %u",pPlayerCreateInfo->class_ ); if(bars_sql) { do { Field *fields = bars_sql->Fetch(); CreateInfo_ActionBarStruct bar; bar.button = fields[2].GetUInt32(); bar.action = fields[3].GetUInt32(); bar.type = fields[4].GetUInt32(); bar.misc = fields[5].GetUInt32(); pPlayerCreateInfo->actionbars.push_back(bar); } while(bars_sql->NextRow()); delete bars_sql; } mPlayerCreateInfo[pPlayerCreateInfo->index] = pPlayerCreateInfo; } while( result->NextRow() ); delete result; Log.Notice("ObjectMgr", "%u player create infos loaded.", mPlayerCreateInfo.size()); }
void SQLStorage::Load () { uint32 maxi; Field *fields; QueryResult *result = WorldDatabase.PQuery("SELECT MAX(%s) FROM %s",entry_field,table); if(!result) { sLog.outError("Error loading %s table (not exist?)\n",table); exit(1); // Stop server at loading non exited table or not accessable table } maxi= (*result)[0].GetUInt32()+1; delete result; result = WorldDatabase.PQuery("SELECT COUNT(*) FROM %s",table); if(result) { fields = result->Fetch(); RecordCount=fields[0].GetUInt32(); delete result; } else RecordCount = 0; result = WorldDatabase.PQuery("SELECT * FROM %s",table); if(!result) { sLog.outError("%s table is empty!\n",table); RecordCount = 0; return; } uint32 recordsize=0; uint32 offset=0; if(iNumFields!=result->GetFieldCount()) { RecordCount = 0; sLog.outError("Error in %s table, probably sql file format was updated (there should be %d fields in sql).\n",table,iNumFields); delete result; exit(1); // Stop server at loading broken or non-compatible table. } //get struct size uint32 sc=0; uint32 bo=0; uint32 bb=0; for(uint32 x=0;x<iNumFields;x++) if(format[x]==FT_STRING) ++sc; else if (format[x]==FT_LOGIC) ++bo; else if (format[x]==FT_BYTE) ++bb; recordsize=(iNumFields-sc-bo-bb)*4+sc*sizeof(char*)+bo*sizeof(bool)+bb*sizeof(char); char** newIndex=new char*[maxi]; memset(newIndex,0,maxi*sizeof(char*)); char * _data= new char[RecordCount *recordsize]; uint32 count=0; barGoLink bar( RecordCount ); do { fields = result->Fetch(); bar.step(); char *p=(char*)&_data[recordsize*count]; newIndex[fields[0].GetUInt32()]=p; offset=0; for(uint32 x=0;x<iNumFields;x++) switch(format[x]) { case FT_LOGIC: *((bool*)(&p[offset]))=(fields[x].GetUInt32()>0); offset+=sizeof(bool); break; case FT_BYTE: *((char*)(&p[offset]))=(fields[x].GetUInt8()); offset+=sizeof(char); break; case FT_INT: *((uint32*)(&p[offset]))=fields[x].GetUInt32(); offset+=sizeof(uint32); break; case FT_FLOAT: *((float*)(&p[offset]))=fields[x].GetFloat(); offset+=sizeof(float); break; case FT_STRING: char const* tmp = fields[x].GetString(); char* st; if(!tmp) { st=new char[1]; *st=0; } else { uint32 l=strlen(tmp)+1; st=new char[l]; memcpy(st,tmp,l); } *((char**)(&p[offset]))=st; offset+=sizeof(char*); break; } ++count; }while( result->NextRow() ); delete result; pIndex =newIndex; MaxEntry=maxi; data=_data; }
void LootMgr::LoadLootTables(const char * szTableName,LootStore * LootTable) { DEBUG_LOG("LootMgr","Attempting to load loot from table %s...", szTableName); vector< pair< uint32, vector< tempy > > > db_cache; vector< pair< uint32, vector< tempy > > >::iterator itr; db_cache.reserve(10000); LootStore::iterator tab; QueryResult *result = WorldDatabase.Query("SELECT * FROM %s ORDER BY entryid ASC",szTableName); if(!result) { Log.Error("LootMgr", "Loading loot from table %s failed.", szTableName); return; } bool multidifficulty = false; if((char*)szTableName == (char*)CREATURE_LOOT || (char*)szTableName == (char*)OBJECT_LOOT || (char*)szTableName == (char*)CREATURE_LOOT_GATHERING) // We have multiple difficulties. { multidifficulty = true; if(result->GetFieldCount() != 9) { Log.Error("LootMgr", "Incorrect structure in table %s(%u/9), loot loading has been cancled to prevent a crash.", szTableName, result->GetFieldCount()); return; } } else if(result->GetFieldCount() != 6) { Log.Error("LootMgr", "Incorrect structure in table %s(%u/6), loot loading has been cancled to prevent a crash.", szTableName, result->GetFieldCount()); return; } uint32 entry_id = 0; uint32 last_entry = 0; uint32 total = (uint32) result->GetRowCount(); int pos = 0; vector< tempy > ttab; tempy t; Field *fields = NULL; do { fields = result->Fetch(); entry_id = fields[0].GetUInt32(); if(entry_id < last_entry) { Log.Error("LootMgr", "WARNING: Out of order loot table being loaded."); delete result; return; } if(entry_id != last_entry) { if(last_entry != 0) db_cache.push_back( make_pair( last_entry, ttab) ); ttab.clear(); } if(multidifficulty) // We have multiple difficulties. { t.itemid = fields[1].GetUInt32(); for(int i = 0; i < 4; i++) t.chance[i] = fields[2+i].GetFloat(); t.mincount = fields[6].GetUInt32(); t.maxcount = fields[7].GetUInt32(); t.ffa_loot = fields[8].GetUInt32(); } else // We have one chance, regardless of difficulty. { t.itemid = fields[1].GetUInt32(); t.chance[0] = fields[2].GetFloat(); t.mincount = fields[3].GetUInt32(); t.maxcount = fields[4].GetUInt32(); t.ffa_loot = fields[5].GetUInt32(); for(int i = 1; i < 4; i++) // Other difficulties. t.chance[i] = 0.0f; } for(uint i = 0; i < 4; i++) if(t.chance[i] == -1.0f) t.chance[i] = RandomFloat(100); ttab.push_back( t ); last_entry = entry_id; } while( result->NextRow() ); //last list was not pushed in if(last_entry != 0 && ttab.size()) db_cache.push_back( make_pair( last_entry, ttab) ); pos = 0; total = uint32(db_cache.size()); ItemPrototype* proto = NULL; StoreLootList *list = NULL; uint32 itemid; //for(itr=loot_db.begin();itr!=loot_db.end();itr++) for( itr = db_cache.begin(); itr != db_cache.end(); itr++) { entry_id = (*itr).first; if(LootTable->end() == LootTable->find(entry_id)) { list = new StoreLootList(); //list.count = itr->second.size(); list->count = (uint32)(*itr).second.size(); list->items = new StoreLootItem[list->count]; uint32 ind = 0; //for(std::vector<loot_tb>::iterator itr2=itr->second.begin();itr2!=itr->second.end();itr2++) for(vector< tempy >::iterator itr2 = (*itr).second.begin(); itr2 != (*itr).second.end(); itr2++) { //Omit items that are not in db to prevent future bugs //uint32 itemid=(*itr2).itemid; itemid = itr2->itemid; proto = ItemPrototypeStorage.LookupEntry(itemid); if(!proto) { list->items[ind].item.itemproto=NULL; if(Config.OptionalConfig.GetBoolDefault("Server", "CleanDatabase", false)) { WorldDatabase.Query("DELETE FROM %s where entryid ='%u' AND itemid = '%u'",szTableName, entry_id, itemid); } Log.Warning("LootMgr", "Loot for %u contains non-existant item(%u). (%s)",entry_id, itemid, szTableName); } else { list->items[ind].item.itemproto=proto; list->items[ind].item.displayid=proto->DisplayInfoID; //list->items[ind].chance=(*itr2).chance; for(int i = 0; i < 4; i++) list->items[ind].chance[i] = itr2->chance[i]; list->items[ind].mincount = itr2->mincount; list->items[ind].maxcount = itr2->maxcount; list->items[ind].ffa_loot = itr2->ffa_loot; if(LootTable == &GOLoot) { if(proto->Class == ITEM_CLASS_QUEST) { //printf("Quest item \"%s\" allocated to quest ", proto->Name1.c_str()); sQuestMgr.SetGameObjectLootQuest(itr->first, itemid); quest_loot_go[entry_id].insert(proto->ItemId); } } } ++ind; } (*LootTable)[entry_id] = (*list); delete list; } } Log.Notice("LootMgr","%d loot templates loaded from %s", db_cache.size(), szTableName); delete result; }
void LootMgr::LoadLootTables(const char * szTableName,LootStore * LootTable) { /* DBCFile *dbc = new DBCFile(); dbc->open("DBC/ItemRandomProperties.dbc"); _propCount = dbc->getRecordCount(); delete dbc;*/ //HM_NAMESPACE::hash_map<uint32, std::vector<loot_tb> > loot_db; //HM_NAMESPACE::hash_map<uint32, std::vector<loot_tb> >::iterator itr; vector< pair< uint32, vector< tempy > > > db_cache; vector< pair< uint32, vector< tempy > > >::iterator itr; db_cache.reserve(10000); LootStore::iterator tab; QueryResult *result =WorldDatabase.Query("SELECT * FROM %s ORDER BY entryid ASC",szTableName); if(!result) { sLog.outError("\rWARNING: Loading loot from table %s failed.", szTableName); return; } uint32 entry_id = 0; uint32 last_entry = 0; uint32 total =(uint32) result->GetRowCount(); int pos = 0; vector< tempy > ttab; tempy t; bool d = false; do { Field *fields = result->Fetch(); entry_id = fields[1].GetUInt32(); if(entry_id < last_entry) { sLog.outError("WARNING: Out of order loot table being loaded.\n"); return; } if(entry_id != last_entry) { if(last_entry != 0) db_cache.push_back( make_pair( last_entry, ttab) ); ttab.clear(); } if(result->GetFieldCount() > 4) { t.itemid = fields[2].GetUInt32(); t.chance = fields[3].GetFloat(); t.chance_2 = fields[4].GetFloat(); t.mincount = fields[5].GetUInt32(); t.maxcount = fields[6].GetUInt32(); t.ffa_loot = fields[7].GetUInt32(); } else { if(!d) { Log.Warning("LootMgr", "Loot table %s is using old loot structure (without heroic chances column)!", szTableName); Log.Warning("LootMgr", "This will be deprecated soon!"); d=true; } t.itemid = fields[2].GetUInt32(); t.chance = fields[3].GetFloat(); t.chance_2 = t.chance; t.mincount = t.maxcount = 1; } ttab.push_back( t ); /*loot_tb t; t.itemid = fields[1].GetUInt32(); t.chance = fields[2].GetFloat(); loot_db[fields[0].GetUInt32()].push_back(t);*/ last_entry = entry_id; } while( result->NextRow() ); //last list was not pushed in if(last_entry != 0 && ttab.size()) db_cache.push_back( make_pair( last_entry, ttab) ); pos = 0; total = (uint32)db_cache.size(); ItemPrototype* proto; uint32 itemid; //for(itr=loot_db.begin();itr!=loot_db.end();++itr) for( itr = db_cache.begin(); itr != db_cache.end(); ++itr) { entry_id = (*itr).first; if(LootTable->end()==LootTable->find(entry_id)) { StoreLootList list; //list.count = itr->second.size(); list.count = (uint32)(*itr).second.size(); list.items=new StoreLootItem[list.count]; uint32 ind=0; //for(std::vector<loot_tb>::iterator itr2=itr->second.begin();itr2!=itr->second.end();++itr2) for(vector< tempy >::iterator itr2 = (*itr).second.begin(); itr2 != (*itr).second.end(); ++itr2) { //Omit items that are not in db to prevent future bugs //uint32 itemid=(*itr2).itemid; itemid = itr2->itemid; proto=ItemPrototypeStorage.LookupEntry(itemid); if(!proto) { list.items[ind].item.itemproto=NULL; sLog.outDetail("WARNING: Loot %u contains item that does not exist in the DB.",entry_id); } else { list.items[ind].item.itemproto=proto; list.items[ind].item.displayid=proto->DisplayInfoID; //list.items[ind].chance=(*itr2).chance; list.items[ind].chance= itr2->chance; list.items[ind].chance2 = itr2->chance_2; list.items[ind].mincount = itr2->mincount; list.items[ind].maxcount = itr2->maxcount; list.items[ind].ffa_loot = itr2->ffa_loot; if(LootTable == &GOLoot) { if(proto->Class == ITEM_CLASS_QUEST) { //printf("Quest item \"%s\" allocated to quest ", proto->Name1.c_str()); sQuestMgr.SetGameObjectLootQuest(itr->first, itemid); quest_loot_go[entry_id].insert(proto->ItemId); } } } ind++; } (*LootTable)[entry_id]=list; } } //sLog.outString(" %d loot templates loaded from %s", db_cache.size(), szTableName); // loot_db.clear(); delete result; }