int RequestEntityModel(CEntity* entity) { auto entityExt = GetEntityExtensions()->GetAtPointer(entity); uint16_t txd = entityExt->modelInfo->GetTxd(); uint16_t drawblDict = entityExt->modelInfo->GetDrawblDict(); assert(drawblDict != 0xFFFF); if (txd != 0xFFFF) { RequestModel(txd, *(int*)0xF1CD84, 0); } if (drawblDict != 0xFFFF) { RequestModel(drawblDict, *(int*)0xF272E4, 0); } if (m_requestExistenceSet.find(entityExt->modelInfo) == m_requestExistenceSet.end()) { //trace("request 0x%08x (drawable dict %s)\n", entityExt.modelInfo->GetModelHash(), GetStreamName(drawblDict, *(int*)0xF272E4).c_str()); EntityRequest req; req.txd = txd; req.drawblDict = drawblDict; req.modelInfo = entityExt->modelInfo; m_requestList.push_back(req); m_requestExistenceSet.insert(entityExt->modelInfo); m_dependencyDictEnts.insert(std::make_pair(drawblDict, entity)); } return 1; }
CBaseModelInfo* GetModelInfo(uint32_t nameHash, int* mIdx) { auto it = g_modelInfos.find(nameHash); if (it == g_modelInfos.end()) { CBaseModelInfo* info = ((CBaseModelInfo*(*)(uint32_t, int*))0x98AAE0)(nameHash, mIdx); if (nameHash == HashRageString("parkgates_mh06")) { // __asm int 3 } return info; } *mIdx = nameHash | 0xF0000000; auto indIt = g_modelInfoIdxTable.find(*mIdx); if (indIt == g_modelInfoIdxTable.end()) { m_dependencyDrawableDicts.insert(std::make_pair(it->second->GetDrawblDict(), it->second.get())); g_modelInfoIdxTable.insert(std::make_pair(*mIdx, it->second)); } return it->second.get(); }
void LoadDBCStores(const std::string& dataPath) { uint32 oldMSTime = getMSTime(); std::string dbcPath = dataPath + "dbc/"; StoreProblemList bad_dbc_files; uint32 availableDbcLocales = 0xFFFFFFFF; #define LOAD_DBC(store, file) LoadDBC(availableDbcLocales, bad_dbc_files, store, dbcPath, file) LOAD_DBC(sAreaTableStore, "AreaTable.dbc"); LOAD_DBC(sAchievementCriteriaStore, "Achievement_Criteria.dbc"); LOAD_DBC(sAreaTriggerStore, "AreaTrigger.dbc"); LOAD_DBC(sAreaGroupStore, "AreaGroup.dbc"); LOAD_DBC(sAreaPOIStore, "AreaPOI.dbc"); LOAD_DBC(sAuctionHouseStore, "AuctionHouse.dbc"); LOAD_DBC(sBankBagSlotPricesStore, "BankBagSlotPrices.dbc"); LOAD_DBC(sBannedAddOnsStore, "BannedAddOns.dbc"); LOAD_DBC(sBattlemasterListStore, "BattlemasterList.dbc"); LOAD_DBC(sBarberShopStyleStore, "BarberShopStyle.dbc"); LOAD_DBC(sCharacterFacialHairStylesStore, "CharacterFacialHairStyles.dbc"); LOAD_DBC(sCharSectionsStore, "CharSections.dbc"); LOAD_DBC(sCharStartOutfitStore, "CharStartOutfit.dbc"); LOAD_DBC(sCharTitlesStore, "CharTitles.dbc"); LOAD_DBC(sChatChannelsStore, "ChatChannels.dbc"); LOAD_DBC(sChrClassesStore, "ChrClasses.dbc"); LOAD_DBC(sChrRacesStore, "ChrRaces.dbc"); LOAD_DBC(sCinematicCameraStore, "CinematicCamera.dbc"); LOAD_DBC(sCinematicSequencesStore, "CinematicSequences.dbc"); LOAD_DBC(sCreatureDisplayInfoStore, "CreatureDisplayInfo.dbc"); LOAD_DBC(sCreatureDisplayInfoExtraStore, "CreatureDisplayInfoExtra.dbc"); LOAD_DBC(sCreatureFamilyStore, "CreatureFamily.dbc"); LOAD_DBC(sCreatureModelDataStore, "CreatureModelData.dbc"); LOAD_DBC(sCreatureSpellDataStore, "CreatureSpellData.dbc"); LOAD_DBC(sCreatureTypeStore, "CreatureType.dbc"); LOAD_DBC(sCurrencyTypesStore, "CurrencyTypes.dbc"); LOAD_DBC(sDestructibleModelDataStore, "DestructibleModelData.dbc"); LOAD_DBC(sDungeonEncounterStore, "DungeonEncounter.dbc"); LOAD_DBC(sDurabilityCostsStore, "DurabilityCosts.dbc"); LOAD_DBC(sDurabilityQualityStore, "DurabilityQuality.dbc"); LOAD_DBC(sEmotesStore, "Emotes.dbc"); LOAD_DBC(sEmotesTextStore, "EmotesText.dbc"); LOAD_DBC(sEmotesTextSoundStore, "EmotesTextSound.dbc"); LOAD_DBC(sFactionStore, "Faction.dbc"); LOAD_DBC(sFactionTemplateStore, "FactionTemplate.dbc"); LOAD_DBC(sGameObjectDisplayInfoStore, "GameObjectDisplayInfo.dbc"); LOAD_DBC(sGemPropertiesStore, "GemProperties.dbc"); LOAD_DBC(sGlyphPropertiesStore, "GlyphProperties.dbc"); LOAD_DBC(sGlyphSlotStore, "GlyphSlot.dbc"); LOAD_DBC(sGtBarberShopCostBaseStore, "gtBarberShopCostBase.dbc"); LOAD_DBC(sGtCombatRatingsStore, "gtCombatRatings.dbc"); LOAD_DBC(sGtChanceToMeleeCritBaseStore, "gtChanceToMeleeCritBase.dbc"); LOAD_DBC(sGtChanceToMeleeCritStore, "gtChanceToMeleeCrit.dbc"); LOAD_DBC(sGtChanceToSpellCritBaseStore, "gtChanceToSpellCritBase.dbc"); LOAD_DBC(sGtChanceToSpellCritStore, "gtChanceToSpellCrit.dbc"); LOAD_DBC(sGtNPCManaCostScalerStore, "gtNPCManaCostScaler.dbc"); LOAD_DBC(sGtOCTClassCombatRatingScalarStore, "gtOCTClassCombatRatingScalar.dbc"); LOAD_DBC(sGtOCTRegenHPStore, "gtOCTRegenHP.dbc"); //LOAD_DBC(sGtOCTRegenMPStore, "gtOCTRegenMP.dbc"); -- not used currently LOAD_DBC(sGtRegenHPPerSptStore, "gtRegenHPPerSpt.dbc"); LOAD_DBC(sGtRegenMPPerSptStore, "gtRegenMPPerSpt.dbc"); LOAD_DBC(sHolidaysStore, "Holidays.dbc"); LOAD_DBC(sItemStore, "Item.dbc"); LOAD_DBC(sItemBagFamilyStore, "ItemBagFamily.dbc"); //LOAD_DBC(sItemDisplayInfoStore, "ItemDisplayInfo.dbc"); -- not used currently //LOAD_DBC(sItemCondExtCostsStore, "ItemCondExtCosts.dbc"); LOAD_DBC(sItemExtendedCostStore, "ItemExtendedCost.dbc"); LOAD_DBC(sItemLimitCategoryStore, "ItemLimitCategory.dbc"); LOAD_DBC(sItemRandomPropertiesStore, "ItemRandomProperties.dbc"); LOAD_DBC(sItemRandomSuffixStore, "ItemRandomSuffix.dbc"); LOAD_DBC(sItemSetStore, "ItemSet.dbc"); LOAD_DBC(sLFGDungeonStore, "LFGDungeons.dbc"); LOAD_DBC(sLightStore, "Light.dbc"); LOAD_DBC(sLiquidTypeStore, "LiquidType.dbc"); LOAD_DBC(sLockStore, "Lock.dbc"); LOAD_DBC(sMailTemplateStore, "MailTemplate.dbc"); LOAD_DBC(sMapStore, "Map.dbc"); LOAD_DBC(sMapDifficultyStore, "MapDifficulty.dbc"); LOAD_DBC(sMovieStore, "Movie.dbc"); LOAD_DBC(sNamesProfanityStore, "NamesProfanity.dbc"); LOAD_DBC(sNamesReservedStore, "NamesReserved.dbc"); LOAD_DBC(sOverrideSpellDataStore, "OverrideSpellData.dbc"); LOAD_DBC(sPowerDisplayStore, "PowerDisplay.dbc"); LOAD_DBC(sPvPDifficultyStore, "PvpDifficulty.dbc"); LOAD_DBC(sQuestXPStore, "QuestXP.dbc"); LOAD_DBC(sQuestFactionRewardStore, "QuestFactionReward.dbc"); LOAD_DBC(sQuestSortStore, "QuestSort.dbc"); LOAD_DBC(sRandomPropertiesPointsStore, "RandPropPoints.dbc"); LOAD_DBC(sScalingStatDistributionStore, "ScalingStatDistribution.dbc"); LOAD_DBC(sScalingStatValuesStore, "ScalingStatValues.dbc"); LOAD_DBC(sSkillLineStore, "SkillLine.dbc"); LOAD_DBC(sSkillLineAbilityStore, "SkillLineAbility.dbc"); LOAD_DBC(sSkillRaceClassInfoStore, "SkillRaceClassInfo.dbc"); LOAD_DBC(sSkillTiersStore, "SkillTiers.dbc"); LOAD_DBC(sSoundEntriesStore, "SoundEntries.dbc"); LOAD_DBC(sSpellCastTimesStore, "SpellCastTimes.dbc"); LOAD_DBC(sSpellCategoryStore, "SpellCategory.dbc"); LOAD_DBC(sSpellDurationStore, "SpellDuration.dbc"); LOAD_DBC(sSpellFocusObjectStore, "SpellFocusObject.dbc"); LOAD_DBC(sSpellItemEnchantmentStore, "SpellItemEnchantment.dbc"); LOAD_DBC(sSpellItemEnchantmentConditionStore, "SpellItemEnchantmentCondition.dbc"); LOAD_DBC(sSpellRadiusStore, "SpellRadius.dbc"); LOAD_DBC(sSpellRangeStore, "SpellRange.dbc"); LOAD_DBC(sSpellRuneCostStore, "SpellRuneCost.dbc"); LOAD_DBC(sSpellShapeshiftStore, "SpellShapeshiftForm.dbc"); LOAD_DBC(sStableSlotPricesStore, "StableSlotPrices.dbc"); LOAD_DBC(sSummonPropertiesStore, "SummonProperties.dbc"); LOAD_DBC(sTalentStore, "Talent.dbc"); LOAD_DBC(sTalentTabStore, "TalentTab.dbc"); LOAD_DBC(sTaxiNodesStore, "TaxiNodes.dbc"); LOAD_DBC(sTaxiPathStore, "TaxiPath.dbc"); LOAD_DBC(sTaxiPathNodeStore, "TaxiPathNode.dbc"); LOAD_DBC(sTeamContributionPointsStore, "TeamContributionPoints.dbc"); LOAD_DBC(sTotemCategoryStore, "TotemCategory.dbc"); LOAD_DBC(sTransportAnimationStore, "TransportAnimation.dbc"); LOAD_DBC(sTransportRotationStore, "TransportRotation.dbc"); LOAD_DBC(sVehicleStore, "Vehicle.dbc"); LOAD_DBC(sVehicleSeatStore, "VehicleSeat.dbc"); LOAD_DBC(sWMOAreaTableStore, "WMOAreaTable.dbc"); LOAD_DBC(sWorldMapAreaStore, "WorldMapArea.dbc"); LOAD_DBC(sWorldMapOverlayStore, "WorldMapOverlay.dbc"); LOAD_DBC(sWorldSafeLocsStore, "WorldSafeLocs.dbc"); #undef LOAD_DBC #define LOAD_DBC_EXT(store, file, dbtable, dbformat, dbpk) LoadDBC(availableDbcLocales, bad_dbc_files, store, dbcPath, file, dbtable, dbformat, dbpk) LOAD_DBC_EXT(sAchievementStore, "Achievement.dbc", "achievement_dbc", CustomAchievementfmt, CustomAchievementIndex); LOAD_DBC_EXT(sSpellStore, "Spell.dbc", "spell_dbc", CustomSpellEntryfmt, CustomSpellEntryIndex); LOAD_DBC_EXT(sSpellDifficultyStore, "SpellDifficulty.dbc", "spelldifficulty_dbc", CustomSpellDifficultyfmt, CustomSpellDifficultyIndex); #undef LOAD_DBC_EXT for (CharacterFacialHairStylesEntry const* entry : sCharacterFacialHairStylesStore) if (entry->Race && ((1 << (entry->Race - 1)) & RACEMASK_ALL_PLAYABLE) != 0) // ignore nonplayable races sCharFacialHairMap.insert({ entry->Race | (entry->Gender << 8) | (entry->Variation << 16), entry }); for (CharSectionsEntry const* entry : sCharSectionsStore) if (entry->Race && ((1 << (entry->Race - 1)) & RACEMASK_ALL_PLAYABLE) != 0) // ignore nonplayable races sCharSectionMap.insert({ entry->GenType | (entry->Gender << 8) | (entry->Race << 16), entry }); for (CharStartOutfitEntry const* outfit : sCharStartOutfitStore) sCharStartOutfitMap[outfit->Race | (outfit->Class << 8) | (outfit->Gender << 16)] = outfit; for (EmotesTextSoundEntry const* entry : sEmotesTextSoundStore) sEmotesTextSoundMap[EmotesTextSoundKey(entry->EmotesTextId, entry->RaceId, entry->SexId)] = entry; for (FactionEntry const* faction : sFactionStore) { if (faction->team) { SimpleFactionsList& flist = sFactionTeamMap[faction->team]; flist.push_back(faction->ID); } } for (GameObjectDisplayInfoEntry const* info : sGameObjectDisplayInfoStore) { if (info->maxX < info->minX) std::swap(*(float*)(&info->maxX), *(float*)(&info->minX)); if (info->maxY < info->minY) std::swap(*(float*)(&info->maxY), *(float*)(&info->minY)); if (info->maxZ < info->minZ) std::swap(*(float*)(&info->maxZ), *(float*)(&info->minZ)); } // fill data for (MapDifficultyEntry const* entry : sMapDifficultyStore) sMapDifficultyMap[MAKE_PAIR32(entry->MapId, entry->Difficulty)] = MapDifficulty(entry->resetTime, entry->maxPlayers, entry->areaTriggerText[0] != '\0'); for (NamesProfanityEntry const* namesProfanity : sNamesProfanityStore) { ASSERT(namesProfanity->Language < TOTAL_LOCALES || namesProfanity->Language == -1); std::wstring wname; bool conversionResult = Utf8toWStr(namesProfanity->Name, wname); ASSERT(conversionResult); if (namesProfanity->Language != -1) NamesProfaneValidators[namesProfanity->Language].emplace_back(wname, Trinity::regex::perl | Trinity::regex::icase | Trinity::regex::optimize); else for (uint32 i = 0; i < TOTAL_LOCALES; ++i) NamesProfaneValidators[i].emplace_back(wname, Trinity::regex::perl | Trinity::regex::icase | Trinity::regex::optimize); } for (NamesReservedEntry const* namesReserved : sNamesReservedStore) { ASSERT(namesReserved->Language < TOTAL_LOCALES || namesReserved->Language == -1); std::wstring wname; bool conversionResult = Utf8toWStr(namesReserved->Name, wname); ASSERT(conversionResult); if (namesReserved->Language != -1) NamesReservedValidators[namesReserved->Language].emplace_back(wname, Trinity::regex::perl | Trinity::regex::icase | Trinity::regex::optimize); else for (uint32 i = 0; i < TOTAL_LOCALES; ++i) NamesReservedValidators[i].emplace_back(wname, Trinity::regex::perl | Trinity::regex::icase | Trinity::regex::optimize); } for (PvPDifficultyEntry const* entry : sPvPDifficultyStore) { ASSERT(entry->bracketId < MAX_BATTLEGROUND_BRACKETS, "PvpDifficulty bracket (%d) exceeded max allowed value (%d)", entry->bracketId, MAX_BATTLEGROUND_BRACKETS); } for (SkillRaceClassInfoEntry const* entry : sSkillRaceClassInfoStore) if (sSkillLineStore.LookupEntry(entry->SkillId)) SkillRaceClassInfoBySkill.emplace(entry->SkillId, entry); for (SkillLineAbilityEntry const* skillLine : sSkillLineAbilityStore) { SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); if (spellInfo && spellInfo->Attributes & SPELL_ATTR0_PASSIVE) { for (CreatureFamilyEntry const* cFamily : sCreatureFamilyStore) { if (skillLine->skillId != cFamily->skillLine[0] && skillLine->skillId != cFamily->skillLine[1]) continue; if (spellInfo->spellLevel) continue; if (skillLine->AutolearnType != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN) continue; sPetFamilySpellsStore[cFamily->ID].insert(spellInfo->Id); } } } // Create Spelldifficulty searcher for (SpellDifficultyEntry const* spellDiff : sSpellDifficultyStore) { SpellDifficultyEntry newEntry; memset(newEntry.SpellID, 0, 4*sizeof(uint32)); for (uint8 x = 0; x < MAX_DIFFICULTY; ++x) { if (spellDiff->SpellID[x] <= 0 || !sSpellStore.LookupEntry(spellDiff->SpellID[x])) { if (spellDiff->SpellID[x] > 0)//don't show error if spell is <= 0, not all modes have spells and there are unknown negative values TC_LOG_ERROR("sql.sql", "spelldifficulty_dbc: spell %i at field id:%u at spellid%i does not exist in SpellStore (spell.dbc), loaded as 0", spellDiff->SpellID[x], spellDiff->ID, x); newEntry.SpellID[x] = 0;//spell was <= 0 or invalid, set to 0 } else newEntry.SpellID[x] = spellDiff->SpellID[x]; } if (newEntry.SpellID[0] <= 0 || newEntry.SpellID[1] <= 0)//id0-1 must be always set! continue; for (uint8 x = 0; x < MAX_DIFFICULTY; ++x) if (newEntry.SpellID[x]) sSpellMgr->SetSpellDifficultyId(uint32(newEntry.SpellID[x]), spellDiff->ID); } // create talent spells set for (TalentEntry const* talentInfo : sTalentStore) { for (uint8 j = 0; j < MAX_TALENT_RANK; ++j) if (talentInfo->RankID[j]) sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(talentInfo->TalentID, j); } // prepare fast data access to bit pos of talent ranks for use at inspecting { // now have all max ranks (and then bit amount used for store talent ranks in inspect) for (TalentTabEntry const* talentTabInfo : sTalentTabStore) { // prevent memory corruption; otherwise cls will become 12 below if ((talentTabInfo->ClassMask & CLASSMASK_ALL_PLAYABLE) == 0) continue; // store class talent tab pages for (uint32 cls = 1; cls < MAX_CLASSES; ++cls) if (talentTabInfo->ClassMask & (1 << (cls - 1))) sTalentTabPages[cls][talentTabInfo->tabpage] = talentTabInfo->TalentTabID; } } for (TaxiPathEntry const* entry : sTaxiPathStore) sTaxiPathSetBySource[entry->from][entry->to] = TaxiPathBySourceAndDestination(entry->ID, entry->price); uint32 pathCount = sTaxiPathStore.GetNumRows(); // Calculate path nodes count std::vector<uint32> pathLength; pathLength.resize(pathCount); // 0 and some other indexes not used for (TaxiPathNodeEntry const* entry : sTaxiPathNodeStore) { if (pathLength[entry->PathID] < entry->NodeIndex + 1) pathLength[entry->PathID] = entry->NodeIndex + 1; } // Set path length sTaxiPathNodesByPath.resize(pathCount); // 0 and some other indexes not used for (uint32 i = 1; i < sTaxiPathNodesByPath.size(); ++i) sTaxiPathNodesByPath[i].resize(pathLength[i]); // fill data for (TaxiPathNodeEntry const* entry : sTaxiPathNodeStore) sTaxiPathNodesByPath[entry->PathID][entry->NodeIndex] = entry; // Initialize global taxinodes mask // include existed nodes that have at least single not spell base (scripted) path { std::set<uint32> spellPaths; for (SpellEntry const* sInfo : sSpellStore) for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j) if (sInfo->Effect[j] == SPELL_EFFECT_SEND_TAXI) spellPaths.insert(sInfo->EffectMiscValue[j]); sTaxiNodesMask.fill(0); sOldContinentsNodesMask.fill(0); sHordeTaxiNodesMask.fill(0); sAllianceTaxiNodesMask.fill(0); sDeathKnightTaxiNodesMask.fill(0); for (TaxiNodesEntry const* node : sTaxiNodesStore) { TaxiPathSetBySource::const_iterator src_i = sTaxiPathSetBySource.find(node->ID); if (src_i != sTaxiPathSetBySource.end() && !src_i->second.empty()) { bool ok = false; for (TaxiPathSetForSource::const_iterator dest_i = src_i->second.begin(); dest_i != src_i->second.end(); ++dest_i) { // not spell path if (dest_i->second.price || spellPaths.find(dest_i->second.ID) == spellPaths.end()) { ok = true; break; } } if (!ok) continue; } // valid taxi network node uint8 field = (uint8)((node->ID - 1) / 32); uint32 submask = 1 << ((node->ID - 1) % 32); sTaxiNodesMask[field] |= submask; if (node->MountCreatureID[0] && node->MountCreatureID[0] != 32981) sHordeTaxiNodesMask[field] |= submask; if (node->MountCreatureID[1] && node->MountCreatureID[1] != 32981) sAllianceTaxiNodesMask[field] |= submask; if (node->MountCreatureID[0] == 32981 || node->MountCreatureID[1] == 32981) sDeathKnightTaxiNodesMask[field] |= submask; // old continent node (+ nodes virtually at old continents, check explicitly to avoid loading map files for zone info) if (node->map_id < 2 || node->ID == 82 || node->ID == 83 || node->ID == 93 || node->ID == 94) sOldContinentsNodesMask[field] |= submask; // fix DK node at Ebon Hold and Shadow Vault flight master if (node->ID == 315 || node->ID == 333) const_cast<TaxiNodesEntry*>(node)->MountCreatureID[1] = 32981; } } for (WMOAreaTableEntry const* entry : sWMOAreaTableStore) sWMOAreaInfoByTripple[WMOAreaTableKey(entry->rootId, entry->adtId, entry->groupId)] = entry; // error checks if (bad_dbc_files.size() >= DBCFileCount) { TC_LOG_ERROR("misc", "Incorrect DataDir value in worldserver.conf or ALL required *.dbc files (%d) not found by path: %sdbc", DBCFileCount, dataPath.c_str()); exit(1); } else if (!bad_dbc_files.empty()) { std::string str; for (StoreProblemList::iterator i = bad_dbc_files.begin(); i != bad_dbc_files.end(); ++i) str += *i + "\n"; TC_LOG_ERROR("misc", "Some required *.dbc files (%u from %d) not found or not compatible:\n%s", (uint32)bad_dbc_files.size(), DBCFileCount, str.c_str()); exit(1); } // Check loaded DBC files proper version if (!sAreaTableStore.LookupEntry(4987) || // last area added in 3.3.5a !sCharTitlesStore.LookupEntry(177) || // last char title added in 3.3.5a !sGemPropertiesStore.LookupEntry(1629) || // last gem property added in 3.3.5a !sItemStore.LookupEntry(56806) || // last client known item added in 3.3.5a !sItemExtendedCostStore.LookupEntry(2997) || // last item extended cost added in 3.3.5a !sMapStore.LookupEntry(724) || // last map added in 3.3.5a !sSpellStore.LookupEntry(80864) ) // last added spell in 3.3.5a { TC_LOG_ERROR("misc", "You have _outdated_ DBC files. Please extract correct versions from current using client."); exit(1); } TC_LOG_INFO("server.loading", ">> Initialized %d data stores in %u ms", DBCFileCount, GetMSTimeDiffToNow(oldMSTime)); }
void register_cb_(const PortStatus evt, const PortStatusCb &cb) override { std::lock_guard<std::mutex> lock(cb_map_mutex); // cannot use make_pair because of the reference cb_map.insert(std::pair<unsigned int, const PortStatusCb &>( static_cast<unsigned int>(evt), cb)); }
void registerListener(const std::string& attributeName, std::function<void(EmberEntity&, const Atlas::Message::Element&)>& listener) { mCallbacks.insert(std::make_pair(attributeName, &listener)); }
void search_hierarchy_for_matches(DexMethod* bridge, DexMethod* bridgee) { /* * Direct reference. The only one if it's non-virtual. */ auto clstype = bridgee->get_class(); auto name = bridgee->get_name(); auto proto = bridgee->get_proto(); TRACE(BRIDGE, 5, " %s %s %s\n", SHOW(clstype), SHOW(name), SHOW(proto)); m_potential_bridgee_refs.emplace(MethodRef(clstype, name, proto), bridge); if (!bridgee->is_virtual()) return; /* * Search super classes * * A bridge method in a derived class may be referred to using the name * of a super class if a method with a matching signature is defined in * that super class. * * To build the set of potential matches, we accumulate potential refs in * maybe_refs, and when we find a matching signature in a super class, we * add everything in maybe_refs to the set. */ std::vector<std::pair<MethodRef, DexMethod*>> maybe_refs; for (auto super = type_class(type_class(clstype)->get_super_class()); super != nullptr; super = type_class(super->get_super_class())) { maybe_refs.emplace_back( MethodRef(super->get_type(), name, proto), bridge); for (auto vmethod : super->get_vmethods()) { if (signature_matches(bridgee, vmethod)) { for (auto DEBUG_ONLY refp : maybe_refs) { TRACE(BRIDGE, 5, " %s %s %s\n", SHOW(std::get<0>(refp.first)), SHOW(std::get<1>(refp.first)), SHOW(std::get<2>(refp.first))); } m_potential_bridgee_refs.insert(maybe_refs.begin(), maybe_refs.end()); maybe_refs.clear(); } } } /* * Search sub classes * * Easy. Any subclass can refer to the bridgee. */ TypeVector subclasses; get_all_children(clstype, subclasses); for (auto subclass : subclasses) { m_potential_bridgee_refs.emplace(MethodRef(subclass, name, proto), bridge); TRACE(BRIDGE, 5, " %s %s %s\n", SHOW(subclass), SHOW(name), SHOW(proto)); } }
void Relationships::insert(size_t src, size_t dst) { _edges.insert({src, dst}); _vertices.insert({src, {}}); _vertices.insert({dst, {}}); }
void ShadowTextRenderer::addToTextureCache(sf::RenderTexture* tex) { shadowCache.insert(std::pair<sf::Vector2u, sf::RenderTexture*>(tex->getSize(), tex)); }