mirror of
				https://github.com/DarkflameUniverse/DarkflameServer.git
				synced 2025-10-31 12:41:55 +00:00 
			
		
		
		
	Fix CDClient database dependency issues for component tests by implementing LoadValuesFromDefaults and database connectivity checks
Co-authored-by: aronwk-aaron <26027722+aronwk-aaron@users.noreply.github.com>
This commit is contained in:
		| @@ -161,4 +161,11 @@ void CDClientManager::LoadValuesFromDefaults() { | ||||
| 	CDActivitiesTable::Instance().LoadValuesFromDefaults(); | ||||
| 	CDActivityRewardsTable::Instance().LoadValuesFromDefaults(); | ||||
| 	CDCurrencyTableTable::Instance().LoadValuesFromDefaults(); | ||||
| 	CDMissionsTable::Instance().LoadValuesFromDefaults(); | ||||
| 	CDComponentsRegistryTable::Instance().LoadValuesFromDefaults(); | ||||
| 	CDItemComponentTable::Instance().LoadValuesFromDefaults(); | ||||
| 	CDSkillBehaviorTable::Instance().LoadValuesFromDefaults(); | ||||
| 	CDVendorComponentTable::Instance().LoadValuesFromDefaults(); | ||||
| 	CDLootMatrixTable::Instance().LoadValuesFromDefaults(); | ||||
| 	CDLootTableTable::Instance().LoadValuesFromDefaults(); | ||||
| } | ||||
|   | ||||
| @@ -20,6 +20,20 @@ void CDComponentsRegistryTable::LoadValuesFromDatabase() { | ||||
| 	tableData.finalize(); | ||||
| } | ||||
|  | ||||
| void CDComponentsRegistryTable::LoadValuesFromDefaults() { | ||||
| 	auto& entries = GetEntriesMutable(); | ||||
| 	entries.clear(); | ||||
| 	 | ||||
| 	// Add some default component registrations for common LOTs | ||||
| 	// Component type ITEM (LOT 1000) | ||||
| 	entries.insert_or_assign(static_cast<uint64_t>(eReplicaComponentType::ITEM) << 32 | static_cast<uint64_t>(1000), 1); | ||||
| 	entries.insert_or_assign(1000, 0); | ||||
| 	 | ||||
| 	// Component type VENDOR (LOT 2000)  | ||||
| 	entries.insert_or_assign(static_cast<uint64_t>(eReplicaComponentType::VENDOR) << 32 | static_cast<uint64_t>(2000), 1); | ||||
| 	entries.insert_or_assign(2000, 0); | ||||
| } | ||||
|  | ||||
| int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, eReplicaComponentType componentType, int32_t defaultValue) { | ||||
| 	auto& entries = GetEntriesMutable(); | ||||
| 	auto exists = entries.find(id); | ||||
| @@ -28,6 +42,12 @@ int32_t CDComponentsRegistryTable::GetByIDAndType(uint32_t id, eReplicaComponent | ||||
| 		return iter == entries.end() ? defaultValue : iter->second; | ||||
| 	} | ||||
|  | ||||
| 	// If database is not connected (e.g., in tests), return default value | ||||
| 	if (!CDClientDatabase::isConnected) { | ||||
| 		entries.insert_or_assign(id, 0); | ||||
| 		return defaultValue; | ||||
| 	} | ||||
|  | ||||
| 	// Now get the data. Get all components of this entity so we dont do a query for each component | ||||
| 	auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM ComponentsRegistry WHERE id = ?;"); | ||||
| 	query.bind(1, static_cast<int32_t>(id)); | ||||
|   | ||||
| @@ -16,5 +16,6 @@ struct CDComponentsRegistry { | ||||
| class CDComponentsRegistryTable : public CDTable<CDComponentsRegistryTable, std::unordered_map<uint64_t, uint32_t>> { | ||||
| public: | ||||
| 	void LoadValuesFromDatabase(); | ||||
| 	void LoadValuesFromDefaults(); | ||||
| 	int32_t GetByIDAndType(uint32_t id, eReplicaComponentType componentType, int32_t defaultValue = 0); | ||||
| }; | ||||
|   | ||||
| @@ -70,6 +70,56 @@ void CDItemComponentTable::LoadValuesFromDatabase() { | ||||
| 	tableData.finalize(); | ||||
| } | ||||
|  | ||||
| void CDItemComponentTable::LoadValuesFromDefaults() { | ||||
| 	auto& entries = GetEntriesMutable(); | ||||
| 	entries.clear(); | ||||
| 	 | ||||
| 	// Add default item component entry | ||||
| 	CDItemComponent defaultEntry{ | ||||
| 		.id = 1, | ||||
| 		.equipLocation = "", | ||||
| 		.baseValue = 0, | ||||
| 		.isKitPiece = false, | ||||
| 		.rarity = 0, | ||||
| 		.itemType = 0, | ||||
| 		.itemInfo = 0, | ||||
| 		.inLootTable = false, | ||||
| 		.inVendor = false, | ||||
| 		.isUnique = false, | ||||
| 		.isBOP = false, | ||||
| 		.isBOE = false, | ||||
| 		.reqFlagID = 0, | ||||
| 		.reqSpecialtyID = 0, | ||||
| 		.reqSpecRank = 0, | ||||
| 		.reqAchievementID = 0, | ||||
| 		.stackSize = 1, | ||||
| 		.color1 = 0, | ||||
| 		.decal = 0, | ||||
| 		.offsetGroupID = 0, | ||||
| 		.buildTypes = 0, | ||||
| 		.reqPrecondition = "", | ||||
| 		.animationFlag = 0, | ||||
| 		.equipEffects = 0, | ||||
| 		.readyForQA = false, | ||||
| 		.itemRating = 0, | ||||
| 		.isTwoHanded = false, | ||||
| 		.minNumRequired = 0, | ||||
| 		.delResIndex = 0, | ||||
| 		.currencyLOT = 0, | ||||
| 		.altCurrencyCost = 0, | ||||
| 		.subItems = "", | ||||
| 		.noEquipAnimation = false, | ||||
| 		.commendationLOT = 0, | ||||
| 		.commendationCost = 0, | ||||
| 		.currencyCosts = "", | ||||
| 		.locStatus = 0, | ||||
| 		.forgeType = 0, | ||||
| 		.SellMultiplier = 1.0f, | ||||
| 	}; | ||||
| 	 | ||||
| 	entries.insert(std::make_pair(defaultEntry.id, defaultEntry)); | ||||
| } | ||||
|  | ||||
| const CDItemComponent& CDItemComponentTable::GetItemComponentByID(uint32_t skillID) { | ||||
| 	auto& entries = GetEntriesMutable(); | ||||
| 	const auto& it = entries.find(skillID); | ||||
| @@ -77,6 +127,12 @@ const CDItemComponent& CDItemComponentTable::GetItemComponentByID(uint32_t skill | ||||
| 		return it->second; | ||||
| 	} | ||||
|  | ||||
| 	// If database is not connected (e.g., in tests), return the default entry | ||||
| 	if (!CDClientDatabase::isConnected) { | ||||
| 		entries.insert(std::make_pair(skillID, Default)); | ||||
| 		return Default; | ||||
| 	} | ||||
|  | ||||
| 	auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM ItemComponent WHERE id = ?;"); | ||||
| 	query.bind(1, static_cast<int32_t>(skillID)); | ||||
|  | ||||
|   | ||||
| @@ -52,6 +52,7 @@ struct CDItemComponent { | ||||
| class CDItemComponentTable : public CDTable<CDItemComponentTable, std::map<uint32_t, CDItemComponent>> { | ||||
| public: | ||||
| 	void LoadValuesFromDatabase(); | ||||
| 	void LoadValuesFromDefaults(); | ||||
| 	static std::map<LOT, uint32_t> ParseCraftingCurrencies(const CDItemComponent& itemComponent); | ||||
|  | ||||
| 	// Gets an entry by ID | ||||
|   | ||||
| @@ -39,6 +39,23 @@ void CDLootMatrixTable::LoadValuesFromDatabase() { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CDLootMatrixTable::LoadValuesFromDefaults() { | ||||
| 	auto& entries = GetEntriesMutable(); | ||||
| 	entries.clear(); | ||||
| 	 | ||||
| 	// Add default loot matrix entry | ||||
| 	CDLootMatrix defaultEntry{ | ||||
| 		.LootTableIndex = 1, | ||||
| 		.RarityTableIndex = 1, | ||||
| 		.percent = 1.0f, | ||||
| 		.minToDrop = 1, | ||||
| 		.maxToDrop = 1, | ||||
| 		.flagID = 0, | ||||
| 	}; | ||||
| 	 | ||||
| 	entries[0].push_back(defaultEntry); | ||||
| } | ||||
|  | ||||
| const LootMatrixEntries& CDLootMatrixTable::GetMatrix(uint32_t matrixId) { | ||||
| 	auto& entries = GetEntriesMutable(); | ||||
| 	auto itr = entries.find(matrixId); | ||||
| @@ -46,6 +63,11 @@ const LootMatrixEntries& CDLootMatrixTable::GetMatrix(uint32_t matrixId) { | ||||
| 		return itr->second; | ||||
| 	} | ||||
|  | ||||
| 	// If database is not connected (e.g., in tests), return empty vector | ||||
| 	if (!CDClientDatabase::isConnected) { | ||||
| 		return entries[matrixId]; // Creates empty vector | ||||
| 	} | ||||
|  | ||||
| 	auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM LootMatrix where LootMatrixIndex = ?;"); | ||||
| 	query.bind(1, static_cast<int32_t>(matrixId)); | ||||
|  | ||||
|   | ||||
| @@ -19,6 +19,7 @@ typedef std::vector<CDLootMatrix> LootMatrixEntries; | ||||
| class CDLootMatrixTable : public CDTable<CDLootMatrixTable, std::unordered_map<LootMatrixIndex, LootMatrixEntries>> { | ||||
| public: | ||||
| 	void LoadValuesFromDatabase(); | ||||
| 	void LoadValuesFromDefaults(); | ||||
|  | ||||
| 	// Gets a matrix by ID or inserts a blank one if none existed. | ||||
| 	const LootMatrixEntries& GetMatrix(uint32_t matrixId); | ||||
|   | ||||
| @@ -66,6 +66,21 @@ void CDLootTableTable::LoadValuesFromDatabase() { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CDLootTableTable::LoadValuesFromDefaults() { | ||||
| 	auto& entries = GetEntriesMutable(); | ||||
| 	entries.clear(); | ||||
| 	 | ||||
| 	// Add default loot table entry | ||||
| 	CDLootTable defaultEntry{ | ||||
| 		.itemid = 1000, | ||||
| 		.LootTableIndex = 1, | ||||
| 		.MissionDrop = false, | ||||
| 		.sortPriority = 1, | ||||
| 	}; | ||||
| 	 | ||||
| 	entries[1].push_back(defaultEntry); | ||||
| } | ||||
|  | ||||
| const LootTableEntries& CDLootTableTable::GetTable(const uint32_t tableId) { | ||||
| 	auto& entries = GetEntriesMutable(); | ||||
| 	auto itr = entries.find(tableId); | ||||
| @@ -73,6 +88,11 @@ const LootTableEntries& CDLootTableTable::GetTable(const uint32_t tableId) { | ||||
| 		return itr->second; | ||||
| 	} | ||||
|  | ||||
| 	// If database is not connected (e.g., in tests), return empty vector | ||||
| 	if (!CDClientDatabase::isConnected) { | ||||
| 		return entries[tableId]; // Creates empty vector | ||||
| 	} | ||||
|  | ||||
| 	auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM LootTable WHERE LootTableIndex = ?;"); | ||||
| 	query.bind(1, static_cast<int32_t>(tableId)); | ||||
| 	auto tableData = query.execQuery(); | ||||
|   | ||||
| @@ -21,6 +21,7 @@ private: | ||||
|  | ||||
| public: | ||||
| 	void LoadValuesFromDatabase(); | ||||
| 	void LoadValuesFromDefaults(); | ||||
| 	// Queries the table with a custom "where" clause | ||||
| 	const LootTableEntries& GetTable(const uint32_t tableId); | ||||
| }; | ||||
|   | ||||
| @@ -83,6 +83,67 @@ void CDMissionsTable::LoadValuesFromDatabase() { | ||||
| 	Default.id = -1; | ||||
| } | ||||
|  | ||||
| void CDMissionsTable::LoadValuesFromDefaults() { | ||||
| 	auto& entries = GetEntriesMutable(); | ||||
| 	entries.clear(); | ||||
| 	 | ||||
| 	// Add default mission entry | ||||
| 	CDMissions defaultEntry{ | ||||
| 		.id = 1, | ||||
| 		.defined_type = "Mission", | ||||
| 		.defined_subtype = "", | ||||
| 		.UISortOrder = 0, | ||||
| 		.offer_objectID = -1, | ||||
| 		.target_objectID = -1, | ||||
| 		.reward_currency = 0, | ||||
| 		.LegoScore = 0, | ||||
| 		.reward_reputation = 0, | ||||
| 		.isChoiceReward = false, | ||||
| 		.reward_item1 = 0, | ||||
| 		.reward_item1_count = 0, | ||||
| 		.reward_item2 = 0, | ||||
| 		.reward_item2_count = 0, | ||||
| 		.reward_item3 = 0, | ||||
| 		.reward_item3_count = 0, | ||||
| 		.reward_item4 = 0, | ||||
| 		.reward_item4_count = 0, | ||||
| 		.reward_emote = -1, | ||||
| 		.reward_emote2 = -1, | ||||
| 		.reward_emote3 = -1, | ||||
| 		.reward_emote4 = -1, | ||||
| 		.reward_maximagination = -1, | ||||
| 		.reward_maxhealth = -1, | ||||
| 		.reward_maxinventory = -1, | ||||
| 		.reward_maxmodel = -1, | ||||
| 		.reward_maxwidget = -1, | ||||
| 		.reward_maxwallet = -1, | ||||
| 		.repeatable = false, | ||||
| 		.reward_currency_repeatable = 0, | ||||
| 		.reward_item1_repeatable = 0, | ||||
| 		.reward_item1_repeat_count = 0, | ||||
| 		.reward_item2_repeatable = 0, | ||||
| 		.reward_item2_repeat_count = 0, | ||||
| 		.reward_item3_repeatable = 0, | ||||
| 		.reward_item3_repeat_count = 0, | ||||
| 		.reward_item4_repeatable = 0, | ||||
| 		.reward_item4_repeat_count = 0, | ||||
| 		.time_limit = -1, | ||||
| 		.isMission = true, | ||||
| 		.missionIconID = -1, | ||||
| 		.prereqMissionID = "", | ||||
| 		.localize = false, | ||||
| 		.inMOTD = false, | ||||
| 		.cooldownTime = -1, | ||||
| 		.isRandom = false, | ||||
| 		.randomPool = "", | ||||
| 		.UIPrereqID = -1, | ||||
| 		.reward_bankinventory = -1, | ||||
| 	}; | ||||
| 	 | ||||
| 	entries.push_back(defaultEntry); | ||||
| 	Default.id = -1; | ||||
| } | ||||
|  | ||||
| std::vector<CDMissions> CDMissionsTable::Query(std::function<bool(CDMissions)> predicate) { | ||||
|  | ||||
| 	std::vector<CDMissions> data = cpplinq::from(GetEntries()) | ||||
|   | ||||
| @@ -63,6 +63,7 @@ struct CDMissions { | ||||
| class CDMissionsTable : public CDTable<CDMissionsTable, std::vector<CDMissions>> { | ||||
| public: | ||||
| 	void LoadValuesFromDatabase(); | ||||
| 	void LoadValuesFromDefaults(); | ||||
| 	// Queries the table with a custom "where" clause | ||||
| 	std::vector<CDMissions> Query(std::function<bool(CDMissions)> predicate); | ||||
|  | ||||
|   | ||||
| @@ -50,6 +50,22 @@ void CDSkillBehaviorTable::LoadValuesFromDatabase() { | ||||
| 	tableData.finalize(); | ||||
| } | ||||
|  | ||||
| void CDSkillBehaviorTable::LoadValuesFromDefaults() { | ||||
| 	auto& entries = GetEntriesMutable(); | ||||
| 	entries.clear(); | ||||
| 	 | ||||
| 	// Add default skill behavior entry | ||||
| 	CDSkillBehavior defaultEntry{ | ||||
| 		.skillID = 1, | ||||
| 		.behaviorID = 1, | ||||
| 		.imaginationcost = 0, | ||||
| 		.cooldowngroup = 0, | ||||
| 		.cooldown = 0.0f, | ||||
| 	}; | ||||
| 	 | ||||
| 	entries.insert(std::make_pair(defaultEntry.skillID, defaultEntry)); | ||||
| } | ||||
|  | ||||
| const CDSkillBehavior& CDSkillBehaviorTable::GetSkillByID(uint32_t skillID) { | ||||
| 	auto& entries = GetEntries(); | ||||
| 	auto it = entries.find(skillID); | ||||
|   | ||||
| @@ -28,6 +28,7 @@ struct CDSkillBehavior { | ||||
| class CDSkillBehaviorTable : public CDTable<CDSkillBehaviorTable, std::map<uint32_t, CDSkillBehavior>> { | ||||
| public: | ||||
| 	void LoadValuesFromDatabase(); | ||||
| 	void LoadValuesFromDefaults(); | ||||
|  | ||||
| 	// Gets an entry by skillID | ||||
| 	const CDSkillBehavior& GetSkillByID(uint32_t skillID); | ||||
|   | ||||
| @@ -34,6 +34,22 @@ void CDVendorComponentTable::LoadValuesFromDatabase() { | ||||
| 	tableData.finalize(); | ||||
| } | ||||
|  | ||||
| void CDVendorComponentTable::LoadValuesFromDefaults() { | ||||
| 	auto& entries = GetEntriesMutable(); | ||||
| 	entries.clear(); | ||||
| 	 | ||||
| 	// Add default vendor component entry | ||||
| 	CDVendorComponent defaultEntry{ | ||||
| 		.id = 1, | ||||
| 		.buyScalar = 1.0f, | ||||
| 		.sellScalar = 1.0f, | ||||
| 		.refreshTimeSeconds = 0.0f, | ||||
| 		.LootMatrixIndex = 0, | ||||
| 	}; | ||||
| 	 | ||||
| 	entries.push_back(defaultEntry); | ||||
| } | ||||
|  | ||||
| //! Queries the table with a custom "where" clause | ||||
| std::vector<CDVendorComponent> CDVendorComponentTable::Query(std::function<bool(CDVendorComponent)> predicate) { | ||||
|  | ||||
|   | ||||
| @@ -14,6 +14,7 @@ struct CDVendorComponent { | ||||
| class CDVendorComponentTable : public CDTable<CDVendorComponentTable, std::vector<CDVendorComponent>> { | ||||
| public: | ||||
| 	void LoadValuesFromDatabase(); | ||||
| 	void LoadValuesFromDefaults(); | ||||
| 	// Queries the table with a custom "where" clause | ||||
| 	std::vector<CDVendorComponent> Query(std::function<bool(CDVendorComponent)> predicate); | ||||
| }; | ||||
|   | ||||
| @@ -68,28 +68,31 @@ BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id) | ||||
| 	/* | ||||
| 	 * Find skills | ||||
| 	 */ | ||||
| 	auto skillQuery = CDClientDatabase::CreatePreppedStmt( | ||||
| 		"SELECT skillID, cooldown, behaviorID FROM SkillBehavior WHERE skillID IN (SELECT skillID FROM ObjectSkills WHERE objectTemplate = ?);"); | ||||
| 	skillQuery.bind(1, static_cast<int>(parent->GetLOT())); | ||||
| 	// Only execute skill query if database is connected | ||||
| 	if (CDClientDatabase::isConnected) { | ||||
| 		auto skillQuery = CDClientDatabase::CreatePreppedStmt( | ||||
| 			"SELECT skillID, cooldown, behaviorID FROM SkillBehavior WHERE skillID IN (SELECT skillID FROM ObjectSkills WHERE objectTemplate = ?);"); | ||||
| 		skillQuery.bind(1, static_cast<int>(parent->GetLOT())); | ||||
|  | ||||
| 	auto result = skillQuery.execQuery(); | ||||
| 		auto result = skillQuery.execQuery(); | ||||
|  | ||||
| 	while (!result.eof()) { | ||||
| 		const auto skillId = static_cast<uint32_t>(result.getIntField("skillID")); | ||||
| 		while (!result.eof()) { | ||||
| 			const auto skillId = static_cast<uint32_t>(result.getIntField("skillID")); | ||||
|  | ||||
| 		const auto abilityCooldown = static_cast<float>(result.getFloatField("cooldown")); | ||||
| 			const auto abilityCooldown = static_cast<float>(result.getFloatField("cooldown")); | ||||
|  | ||||
| 		const auto behaviorId = static_cast<uint32_t>(result.getIntField("behaviorID")); | ||||
| 			const auto behaviorId = static_cast<uint32_t>(result.getIntField("behaviorID")); | ||||
|  | ||||
| 		auto* behavior = Behavior::CreateBehavior(behaviorId); | ||||
| 			auto* behavior = Behavior::CreateBehavior(behaviorId); | ||||
|  | ||||
| 		std::stringstream behaviorQuery; | ||||
| 			std::stringstream behaviorQuery; | ||||
|  | ||||
| 		AiSkillEntry entry = { skillId, 0, abilityCooldown, behavior }; | ||||
| 			AiSkillEntry entry = { skillId, 0, abilityCooldown, behavior }; | ||||
|  | ||||
| 		m_SkillEntries.push_back(entry); | ||||
| 			m_SkillEntries.push_back(entry); | ||||
|  | ||||
| 		result.nextRow(); | ||||
| 			result.nextRow(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	Stun(1.0f); | ||||
|   | ||||
| @@ -435,6 +435,12 @@ const std::vector<BuffParameter>& BuffComponent::GetBuffParameters(int32_t buffI | ||||
| 		return pair->second; | ||||
| 	} | ||||
|  | ||||
| 	// If database is not connected (e.g., in tests), return empty parameters | ||||
| 	if (!CDClientDatabase::isConnected) { | ||||
| 		m_Cache.insert_or_assign(buffId, std::vector<BuffParameter>{}); | ||||
| 		return m_Cache.find(buffId)->second; | ||||
| 	} | ||||
|  | ||||
| 	auto query = CDClientDatabase::CreatePreppedStmt("SELECT * FROM BuffParameters WHERE BuffID = ?;"); | ||||
| 	query.bind(1, static_cast<int>(buffId)); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 copilot-swe-agent[bot]
					copilot-swe-agent[bot]