예제 #1
0
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;
}
예제 #2
0
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();
}
예제 #3
0
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();
}
예제 #4
0
// 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;
}
예제 #5
0
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();
}
예제 #6
0
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;
}
예제 #7
0
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());
}
예제 #8
0
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;
}
예제 #9
0
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;
}
예제 #10
0
파일: LootMgr.cpp 프로젝트: Goatform/ascent
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;
}