Index: game/LootMgr.cpp =================================================================== --- game/LootMgr.cpp (revision 3551) +++ game/LootMgr.cpp (working copy) @@ -53,6 +53,38 @@ LootTemplates_Disenchant.clear(); } +char const *formatString2( char const *format, ... ) +{ + va_list argptr; + #define MAX_FMT_STRING 32000 + static char temp_buffer[MAX_FMT_STRING]; + static char string[MAX_FMT_STRING]; + static int index = 0; + char *buf; + int len; + + va_start(argptr, format); + vsnprintf(temp_buffer,MAX_FMT_STRING, format, argptr); + va_end(argptr); + + len = strlen(temp_buffer); + + if( len >= MAX_FMT_STRING ) + return "ERROR"; + + if (len + index >= MAX_FMT_STRING-1) + { + index = 0; + } + + buf = &string[index]; + memcpy( buf, temp_buffer, len+1 ); + + index += len + 1; + + return buf; +} + void LoadLootTable(LootStore& lootstore,char const* tablename) { LootStore::iterator tab; @@ -63,41 +95,115 @@ int32 questchance; uint32 count = 0; bool is_ffa = true; + FILE *pOut, *pIn; sLog.outString( "%s :", tablename); - QueryResult *result = sDatabase.PQuery("SELECT `entry`, `item`, `ChanceOrRef`, `QuestChanceOrGroup`, `mincount`, `maxcount`, `quest_freeforall` FROM `%s`",tablename); + if ( (pIn = fopen( formatString2("cache/%s.cache", tablename), "rb")) == NULL ) + {// UQ1: Trying .cache file for faster loading time... If one does not exist, create it from DB. + // Make a cache directory... + system("mkdir cache"); - if (result) - { - barGoLink bar(result->GetRowCount()); + if ( (pOut = fopen( formatString2("cache/%s.cache", tablename), "wb")) == NULL ) + { + } - std::ostringstream ssNonLootableItems; + QueryResult *result = sDatabase.PQuery("SELECT `entry`, `item`, `ChanceOrRef`, `QuestChanceOrGroup`, `mincount`, `maxcount`, `quest_freeforall` FROM `%s`",tablename); - do - { - Field *fields = result->Fetch(); - bar.step(); + uint64 row_count = result->GetRowCount(); + fwrite( &row_count, sizeof(uint64), 1, pOut ); - entry = fields[0].GetUInt32(); - item = fields[1].GetUInt32();; - chance = fields[2].GetFloat(); - questchance = int32(fields[3].GetUInt32()); - mincount = fields[4].GetUInt32(); - maxcount = fields[5].GetUInt32(); - is_ffa = fields[6].GetBool(); + if (result) + { + barGoLink bar(result->GetRowCount()); - ItemPrototype const *proto = objmgr.GetItemPrototype(item); + std::ostringstream ssNonLootableItems; - if(!proto) + do { - ssNonLootableItems << "loot entry = " << entry << " item = " << item << " mincount = " << mincount << " maxcount = " << maxcount << " (not exist)\n"; - continue; - } + Field *fields = result->Fetch(); + bar.step(); - displayid = proto->DisplayInfoID; + entry = fields[0].GetUInt32(); + fwrite( &entry, sizeof(uint32), 1, pOut ); + item = fields[1].GetUInt32();; + fwrite( &item, sizeof(uint32), 1, pOut ); + chance = fields[2].GetFloat(); + fwrite( &chance, sizeof(float), 1, pOut ); + questchance = int32(fields[3].GetUInt32()); + fwrite( &questchance, sizeof(uint32), 1, pOut ); + mincount = fields[4].GetUInt32(); + fwrite( &mincount, sizeof(uint32), 1, pOut ); + maxcount = fields[5].GetUInt32(); + fwrite( &maxcount, sizeof(uint32), 1, pOut ); + is_ffa = fields[6].GetBool(); + fwrite( &is_ffa, sizeof(bool), 1, pOut ); - // non-quest (maybe group) loot with low chance + ItemPrototype const *proto = objmgr.GetItemPrototype(item); + + if(!proto) + { + ssNonLootableItems << "loot entry = " << entry << " item = " << item << " mincount = " << mincount << " maxcount = " << maxcount << " (not exist)\n"; + continue; + } + + displayid = proto->DisplayInfoID; + fwrite( &displayid, sizeof(uint32), 1, pOut ); + + // non-quest (maybe group) loot with low chance + if( chance >= 0 && chance < 0.000001 && questchance <= 0 ) + { + ssNonLootableItems << "loot entry = " << entry << " item = " << item << " mincount = " << mincount << " maxcount = " << maxcount << " (no chance)\n"; + continue; + } + + lootstore[entry].push_back( LootStoreItem(item, displayid, chance, questchance,is_ffa,mincount,maxcount) ); + + count++; + } while (result->NextRow()); + + delete result; + + sLog.outString( "" ); + sLog.outString( ">> Loaded %u loot definitions", count ); + sLog.outString( ">> Cache file %s created for next boot.", formatString2("cache/%s.cache", tablename) ); + if(ssNonLootableItems.str().size() > 0) + sLog.outErrorDb("Some items can't be succesfully looted: not exist or have in chance field value < 0.000001 with quest chance ==0 in `%s` DB table . List:\n%s",tablename,ssNonLootableItems.str().c_str()); + } + else + { + sLog.outString( "" ); + sLog.outErrorDb( ">> Loaded 0 loot definitions. DB table `%s` is empty.",tablename ); + } + + fclose( pOut ); + } + else + {// Use .cache file! + int loop = 0; + uint64 row_count = 0; + + fread( &row_count, sizeof(uint64), 1, pIn ); + + barGoLink bar(row_count); + + std::ostringstream ssNonLootableItems; + + for (loop = 0; loop < row_count; loop++) + { + bar.step(); + + fread( &entry, sizeof(uint32), 1, pIn ); + fread( &item, sizeof(uint32), 1, pIn ); + fread( &chance, sizeof(float), 1, pIn ); + fread( &questchance, sizeof(uint32), 1, pIn ); + fread( &mincount, sizeof(uint32), 1, pIn ); + fread( &maxcount, sizeof(uint32), 1, pIn ); + fread( &is_ffa, sizeof(bool), 1, pIn ); + + fread( &displayid, sizeof(uint32), 1, pIn ); + + // non-quest (maybe group) loot with low chance if( chance >= 0 && chance < 0.000001 && questchance <= 0 ) { ssNonLootableItems << "loot entry = " << entry << " item = " << item << " mincount = " << mincount << " maxcount = " << maxcount << " (no chance)\n"; @@ -106,21 +212,13 @@ lootstore[entry].push_back( LootStoreItem(item, displayid, chance, questchance,is_ffa,mincount,maxcount) ); - count++; - } while (result->NextRow()); + count++; + } - delete result; + fclose( pIn ); - sLog.outString( "" ); - sLog.outString( ">> Loaded %u loot definitions", count ); - if(ssNonLootableItems.str().size() > 0) - sLog.outErrorDb("Some items can't be succesfully looted: not exist or have in chance field value < 0.000001 with quest chance ==0 in `%s` DB table . List:\n%s",tablename,ssNonLootableItems.str().c_str()); - } - else - { - sLog.outString( "" ); - sLog.outErrorDb( ">> Loaded 0 loot definitions. DB table `%s` is empty.",tablename ); - } + sLog.outString( ">> Loaded %u loot definitions from cache.", count ); + } } void LoadLootTables()