diff --git a/dDatabase/CDClientDatabase.cpp b/dDatabase/CDClientDatabase.cpp index d61d6fe7..d09b2daa 100644 --- a/dDatabase/CDClientDatabase.cpp +++ b/dDatabase/CDClientDatabase.cpp @@ -13,3 +13,8 @@ void CDClientDatabase::Connect(const std::string& filename) { CppSQLite3Query CDClientDatabase::ExecuteQuery(const std::string& query) { return conn->execQuery(query.c_str()); } + +//! Makes prepared statements +CppSQLite3Statement CDClientDatabase::CreatePreppedStmt(const std::string& query) { + return conn->compileStatement(query.c_str()); +} diff --git a/dDatabase/CDClientDatabase.h b/dDatabase/CDClientDatabase.h index fbb1dc86..91e9ee10 100644 --- a/dDatabase/CDClientDatabase.h +++ b/dDatabase/CDClientDatabase.h @@ -40,4 +40,10 @@ namespace CDClientDatabase { */ CppSQLite3Query ExecuteQuery(const std::string& query); + //! Queries the CDClient and parses arguments + /*! + \param query The query with formatted arguments + \return prepared SQLite Statement + */ + CppSQLite3Statement CreatePreppedStmt(const std::string& query); }; diff --git a/dDatabase/Tables/CDBehaviorParameterTable.cpp b/dDatabase/Tables/CDBehaviorParameterTable.cpp index ef267425..4991ac82 100644 --- a/dDatabase/Tables/CDBehaviorParameterTable.cpp +++ b/dDatabase/Tables/CDBehaviorParameterTable.cpp @@ -4,19 +4,19 @@ //! Constructor CDBehaviorParameterTable::CDBehaviorParameterTable(void) { #ifdef CDCLIENT_CACHE_ALL - auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorParameter"); - while (!tableData.eof()) { - CDBehaviorParameter entry; - entry.behaviorID = tableData.getIntField(0, -1); - entry.parameterID = tableData.getStringField(1, ""); - entry.value = tableData.getFloatField(2, -1.0f); + auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorParameter"); + while (!tableData.eof()) { + CDBehaviorParameter entry; + entry.behaviorID = tableData.getIntField(0, -1); + entry.parameterID = tableData.getStringField(1, ""); + entry.value = tableData.getFloatField(2, -1.0f); //Check if we have an entry with this ID: auto it = m_entries.find(entry.behaviorID); if (it != m_entries.end()) { it->second.insert(std::make_pair(entry.parameterID, entry.value)); } - else { + else { //Otherwise, insert it: m_entries.insert(std::make_pair(entry.behaviorID, std::map())); auto jit = m_entries.find(entry.behaviorID); @@ -25,8 +25,8 @@ CDBehaviorParameterTable::CDBehaviorParameterTable(void) { jit->second.insert(std::make_pair(entry.parameterID, entry.value)); } - tableData.nextRow(); - } + tableData.nextRow(); + } tableData.finalize(); #endif @@ -37,7 +37,7 @@ CDBehaviorParameterTable::~CDBehaviorParameterTable(void) { } //! Returns the table's name std::string CDBehaviorParameterTable::GetName(void) const { - return "BehaviorParameter"; + return "BehaviorParameter"; } float CDBehaviorParameterTable::GetEntry(const uint32_t behaviorID, const std::string& name, const float defaultValue) @@ -59,17 +59,17 @@ float CDBehaviorParameterTable::GetEntry(const uint32_t behaviorID, const std::s } #ifndef CDCLIENT_CACHE_ALL - std::stringstream query; + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT parameterID, value FROM BehaviorParameter WHERE behaviorID = ?;"); + query.bind(1, (int) behaviorID); - query << "SELECT parameterID, value FROM BehaviorParameter WHERE behaviorID = " << std::to_string(behaviorID); - - auto tableData = CDClientDatabase::ExecuteQuery(query.str()); + auto tableData = query.execQuery(); m_Entries.insert_or_assign(behaviorID, 0); - + while (!tableData.eof()) { - const std::string parameterID = tableData.getStringField(0, ""); - const float value = tableData.getFloatField(1, 0); + const std::string parameterID = tableData.getStringField(0, ""); + const float value = tableData.getFloatField(1, 0); size_t parameterHash = 0; GeneralUtils::hash_combine(parameterHash, behaviorID); @@ -77,8 +77,8 @@ float CDBehaviorParameterTable::GetEntry(const uint32_t behaviorID, const std::s m_Entries.insert_or_assign(parameterHash, value); - tableData.nextRow(); - } + tableData.nextRow(); + } const auto& it2 = m_Entries.find(hash); if (it2 != m_Entries.end()) { diff --git a/dGame/dBehaviors/Behavior.cpp b/dGame/dBehaviors/Behavior.cpp index db5bbf2f..df24af92 100644 --- a/dGame/dBehaviors/Behavior.cpp +++ b/dGame/dBehaviors/Behavior.cpp @@ -91,21 +91,21 @@ Behavior* Behavior::GetBehavior(const uint32_t behaviorId) Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) { auto* cached = GetBehavior(behaviorId); - + if (cached != nullptr) { return cached; } - + if (behaviorId == 0) { return new EmptyBehavior(0); } - + const auto templateId = GetBehaviorTemplate(behaviorId); Behavior* behavior = nullptr; - + switch (templateId) { case BehaviorTemplates::BEHAVIOR_EMPTY: break; @@ -191,8 +191,8 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) behavior = new JetPackBehavior(behaviorId); break; case BehaviorTemplates::BEHAVIOR_SKILL_EVENT: - behavior = new SkillEventBehavior(behaviorId); - break; + behavior = new SkillEventBehavior(behaviorId); + break; case BehaviorTemplates::BEHAVIOR_CONSUME_ITEM: break; case BehaviorTemplates::BEHAVIOR_SKILL_CAST_FAILED: behavior = new SkillCastFailedBehavior(behaviorId); @@ -272,7 +272,7 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) if (behavior == nullptr) { //Game::logger->Log("Behavior", "Failed to load unimplemented template id (%i)!\n", templateId); - + behavior = new EmptyBehavior(behaviorId); } @@ -281,13 +281,12 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) return behavior; } -BehaviorTemplates Behavior::GetBehaviorTemplate(const uint32_t behaviorId) -{ - std::stringstream query; +BehaviorTemplates Behavior::GetBehaviorTemplate(const uint32_t behaviorId) { + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT templateID FROM BehaviorTemplate WHERE behaviorID = ?;"); + query.bind(1, (int) behaviorId); - query << "SELECT templateID FROM BehaviorTemplate WHERE behaviorID = " << std::to_string(behaviorId); - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = query.execQuery(); // Make sure we do not proceed if we are trying to load an invalid behavior if (result.eof()) @@ -299,7 +298,7 @@ BehaviorTemplates Behavior::GetBehaviorTemplate(const uint32_t behaviorId) return BehaviorTemplates::BEHAVIOR_EMPTY; } - + const auto id = static_cast(result.getIntField(0)); result.finalize(); @@ -325,7 +324,7 @@ void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID return; } - + auto* renderComponent = targetEntity->GetComponent(); const auto typeString = GeneralUtils::UTF16ToWTF8(type); @@ -348,28 +347,35 @@ void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID if (renderComponent == nullptr) { GameMessages::SendPlayFXEffect(targetEntity, effectId, type, pair->second, secondary, 1, 1, true); - + return; } renderComponent->PlayEffect(effectId, type, pair->second, secondary); - + return; } } - - std::stringstream query; - - if (!type.empty()) - { - query << "SELECT effectName FROM BehaviorEffect WHERE effectType = '" << typeString << "' AND effectID = " << std::to_string(effectId) << ";"; - } - else - { - query << "SELECT effectName, effectType FROM BehaviorEffect WHERE effectID = " << std::to_string(effectId) << ";"; - } - auto result = CDClientDatabase::ExecuteQuery(query.str()); + // The SQlite result object becomes invalid if the query object leaves scope. + // So both queries are defined before the if statement + CppSQLite3Query result; + auto typeQuery = CDClientDatabase::CreatePreppedStmt( + "SELECT effectName FROM BehaviorEffect WHERE effectType = ? AND effectID = ?;"); + + auto idQuery = CDClientDatabase::CreatePreppedStmt( + "SELECT effectName, effectType FROM BehaviorEffect WHERE effectID = ?;"); + + if (!type.empty()) { + typeQuery.bind(1, typeString.c_str()); + typeQuery.bind(2, (int) effectId); + + result = typeQuery.execQuery(); + } else { + idQuery.bind(1, (int) effectId); + + result = idQuery.execQuery(); + } if (result.eof() || result.fieldIsNull(0)) { @@ -381,7 +387,7 @@ void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID if (type.empty()) { const auto typeResult = result.getStringField(1); - + type = GeneralUtils::ASCIIToUTF16(typeResult); m_effectType = new std::string(typeResult); @@ -394,7 +400,7 @@ void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID if (renderComponent == nullptr) { GameMessages::SendPlayFXEffect(targetEntity, effectId, type, name, secondary, 1, 1, true); - + return; } @@ -414,15 +420,11 @@ Behavior::Behavior(const uint32_t behaviorId) this->m_templateId = BehaviorTemplates::BEHAVIOR_EMPTY; } - /* - * Get standard info - */ + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT templateID, effectID, effectHandle FROM BehaviorTemplate WHERE behaviorID = ?;"); + query.bind(1, (int) behaviorId); - std::stringstream query; - - query << "SELECT templateID, effectID, effectHandle FROM BehaviorTemplate WHERE behaviorID = " << std::to_string(behaviorId); - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = query.execQuery(); // Make sure we do not proceed if we are trying to load an invalid behavior if (result.eof()) @@ -437,7 +439,7 @@ Behavior::Behavior(const uint32_t behaviorId) } this->m_templateId = static_cast(result.getIntField(0)); - + this->m_effectId = result.getIntField(1); if (!result.fieldIsNull(2)) @@ -495,11 +497,11 @@ std::map Behavior::GetParameterNames() const { std::map parameters; - std::stringstream query; + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT parameterID, value FROM BehaviorParameter WHERE behaviorID = ?;"); + query.bind(1, (int) this->m_behaviorId); - query << "SELECT parameterID, value FROM BehaviorParameter WHERE behaviorID = " << std::to_string(this->m_behaviorId); - - auto tableData = CDClientDatabase::ExecuteQuery(query.str()); + auto tableData = query.execQuery(); while (!tableData.eof()) { diff --git a/dGame/dBehaviors/SwitchMultipleBehavior.cpp b/dGame/dBehaviors/SwitchMultipleBehavior.cpp index 691e8b53..93662060 100644 --- a/dGame/dBehaviors/SwitchMultipleBehavior.cpp +++ b/dGame/dBehaviors/SwitchMultipleBehavior.cpp @@ -39,15 +39,15 @@ void SwitchMultipleBehavior::Calculate(BehaviorContext* context, RakNet::BitStre // TODO } -void SwitchMultipleBehavior::Load() -{ - const auto b = std::to_string(this->m_behaviorId); - std::stringstream query; - query << "SELECT replace(bP1.parameterID, 'behavior ', '') as key, bP1.value as behavior, " - << "(select bP2.value FROM BehaviorParameter bP2 WHERE bP2.behaviorID = " << b << " AND bP2.parameterID LIKE 'value %' " - << "AND replace(bP1.parameterID, 'behavior ', '') = replace(bP2.parameterID, 'value ', '')) as value " - << "FROM BehaviorParameter bP1 WHERE bP1.behaviorID = " << b << " AND bP1.parameterID LIKE 'behavior %'"; - auto result = CDClientDatabase::ExecuteQuery(query.str()); +void SwitchMultipleBehavior::Load() { + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT replace(bP1.parameterID, 'behavior ', '') as key, bP1.value as behavior, " + "(select bP2.value FROM BehaviorParameter bP2 WHERE bP2.behaviorID = ?1 AND bP2.parameterID LIKE 'value %' " + "AND replace(bP1.parameterID, 'behavior ', '') = replace(bP2.parameterID, 'value ', '')) as value " + "FROM BehaviorParameter bP1 WHERE bP1.behaviorID = ?1 AND bP1.parameterID LIKE 'behavior %';"); + query.bind(1, (int) this->m_behaviorId); + + auto result = query.execQuery(); while (!result.eof()) { const auto behavior_id = static_cast(result.getFloatField(1)); diff --git a/dGame/dComponents/BaseCombatAIComponent.cpp b/dGame/dComponents/BaseCombatAIComponent.cpp index 858b129d..0903e621 100644 --- a/dGame/dComponents/BaseCombatAIComponent.cpp +++ b/dGame/dComponents/BaseCombatAIComponent.cpp @@ -35,11 +35,11 @@ BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id) m_SoftTimer = 5.0f; //Grab the aggro information from BaseCombatAI: - std::stringstream componentQuery; - - componentQuery << "SELECT aggroRadius, tetherSpeed, pursuitSpeed, softTetherRadius, hardTetherRadius FROM BaseCombatAIComponent WHERE id = " << std::to_string(id); - - auto componentResult = CDClientDatabase::ExecuteQuery(componentQuery.str()); + auto componentQuery = CDClientDatabase::CreatePreppedStmt( + "SELECT aggroRadius, tetherSpeed, pursuitSpeed, softTetherRadius, hardTetherRadius FROM BaseCombatAIComponent WHERE id = ?;"); + componentQuery.bind(1, (int) id); + + auto componentResult = componentQuery.execQuery(); if (!componentResult.eof()) { @@ -64,12 +64,11 @@ BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id) /* * Find skills */ - - std::stringstream query; - - query << "SELECT skillID, cooldown, behaviorID FROM SkillBehavior WHERE skillID IN (SELECT skillID FROM ObjectSkills WHERE objectTemplate = " << std::to_string(parent->GetLOT()) << " )"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto skillQuery = CDClientDatabase::CreatePreppedStmt( + "SELECT skillID, cooldown, behaviorID FROM SkillBehavior WHERE skillID IN (SELECT skillID FROM ObjectSkills WHERE objectTemplate = ?);"); + skillQuery.bind(1, (int) parent->GetLOT()); + + auto result = skillQuery.execQuery(); while (!result.eof()) { const auto skillId = static_cast(result.getIntField(0)); diff --git a/dGame/dComponents/BuffComponent.cpp b/dGame/dComponents/BuffComponent.cpp index 06c859c8..9c12e87d 100644 --- a/dGame/dComponents/BuffComponent.cpp +++ b/dGame/dComponents/BuffComponent.cpp @@ -371,12 +371,12 @@ const std::vector& BuffComponent::GetBuffParameters(int32_t buffI return pair->second; } - std::stringstream query; - - query << "SELECT * FROM BuffParameters WHERE BuffID = " << std::to_string(buffId) << ";"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT * FROM BuffParameters WHERE BuffID = ?;"); + query.bind(1, (int) buffId); + auto result = query.execQuery(); + std::vector parameters {}; while (!result.eof()) diff --git a/dGame/dComponents/DestroyableComponent.cpp b/dGame/dComponents/DestroyableComponent.cpp index 49b15b3f..da5db382 100644 --- a/dGame/dComponents/DestroyableComponent.cpp +++ b/dGame/dComponents/DestroyableComponent.cpp @@ -106,7 +106,7 @@ void DestroyableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIn outBitStream->Write0(); //Contains info about immunities this object has, but it's left out for now. } - outBitStream->Write(m_DirtyHealth || bIsInitialUpdate); + outBitStream->Write(m_DirtyHealth || bIsInitialUpdate); if (m_DirtyHealth || bIsInitialUpdate) { outBitStream->Write(m_iHealth); outBitStream->Write(m_fMaxHealth); @@ -114,12 +114,12 @@ void DestroyableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIn outBitStream->Write(m_fMaxArmor); outBitStream->Write(m_iImagination); outBitStream->Write(m_fMaxImagination); - + outBitStream->Write(m_DamageToAbsorb); outBitStream->Write(IsImmune()); outBitStream->Write(m_IsGMImmune); outBitStream->Write(m_IsShielded); - + outBitStream->Write(m_fMaxHealth); outBitStream->Write(m_fMaxArmor); outBitStream->Write(m_fMaxImagination); @@ -130,14 +130,14 @@ void DestroyableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIn } outBitStream->Write(m_IsSmashable); - + if (bIsInitialUpdate) { outBitStream->Write(m_IsDead); outBitStream->Write(m_IsSmashed); - + if (m_IsSmashable) { outBitStream->Write(m_HasBricks); - + if (m_ExplodeFactor != 1.0f) { outBitStream->Write1(); outBitStream->Write(m_ExplodeFactor); @@ -146,10 +146,10 @@ void DestroyableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIn } } } - + m_DirtyHealth = false; } - + if (m_DirtyThreatList || bIsInitialUpdate) { outBitStream->Write1(); outBitStream->Write(m_HasThreats); @@ -167,7 +167,7 @@ void DestroyableComponent::LoadFromXML(tinyxml2::XMLDocument* doc) { } auto* buffComponent = m_Parent->GetComponent(); - + if (buffComponent != nullptr) { buffComponent->LoadFromXML(doc); } @@ -187,9 +187,9 @@ void DestroyableComponent::UpdateXml(tinyxml2::XMLDocument* doc) { Game::logger->Log("DestroyableComponent", "Failed to find dest tag!\n"); return; } - + auto* buffComponent = m_Parent->GetComponent(); - + if (buffComponent != nullptr) { buffComponent->UpdateXml(doc); } @@ -235,7 +235,7 @@ void DestroyableComponent::SetMaxHealth(float value, bool playAnim) { args.InsertValue("amount", amount); args.InsertValue("type", type); GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", &args); - + delete amount; delete type; } @@ -283,7 +283,7 @@ void DestroyableComponent::SetMaxArmor(float value, bool playAnim) { args.InsertValue("type", type); GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", &args); - + delete amount; delete type; } @@ -329,7 +329,7 @@ void DestroyableComponent::SetMaxImagination(float value, bool playAnim) { args.InsertValue("amount", amount); args.InsertValue("type", type); GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", &args); - + delete amount; delete type; } @@ -342,7 +342,7 @@ void DestroyableComponent::SetDamageToAbsorb(int32_t value) m_DamageToAbsorb = value; } -void DestroyableComponent::SetDamageReduction(int32_t value) +void DestroyableComponent::SetDamageReduction(int32_t value) { m_DirtyHealth = true; m_DamageReduction = value; @@ -354,7 +354,7 @@ void DestroyableComponent::SetIsImmune(bool value) m_ImmuneStacks = value ? 1 : 0; } -void DestroyableComponent::SetIsGMImmune(bool value) +void DestroyableComponent::SetIsGMImmune(bool value) { m_DirtyHealth = true; m_IsGMImmune = value; @@ -375,11 +375,11 @@ void DestroyableComponent::AddFaction(const int32_t factionID, const bool ignore m_FactionIDs.push_back(factionID); m_DirtyHealth = true; - std::stringstream query; + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT enemyList FROM Factions WHERE faction = ?;"); + query.bind(1, (int) factionID); - query << "SELECT enemyList FROM Factions WHERE faction = " << std::to_string(factionID); - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = query.execQuery(); if (result.eof()) return; @@ -389,10 +389,10 @@ void DestroyableComponent::AddFaction(const int32_t factionID, const bool ignore std::stringstream ss(list_string); std::string token; - + while (std::getline(ss, token, ',')) { if (token.empty()) continue; - + auto id = std::stoi(token); auto exclude = std::find(m_FactionIDs.begin(), m_FactionIDs.end(), id) != m_FactionIDs.end(); @@ -406,7 +406,7 @@ void DestroyableComponent::AddFaction(const int32_t factionID, const bool ignore { continue; } - + AddEnemyFaction(id); } @@ -522,7 +522,7 @@ bool DestroyableComponent::CheckValidity(const LWOOBJID target, const bool ignor if (targetQuickbuild != nullptr) { const auto state = targetQuickbuild->GetState(); - + if (state != REBUILD_COMPLETED) { return false; @@ -562,7 +562,7 @@ void DestroyableComponent::Imagine(const int32_t deltaImagination) { auto current = static_cast(GetImagination()); const auto max = static_cast(GetMaxImagination()); - + current += deltaImagination; current = std::min(current, max); @@ -635,7 +635,7 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32 damage -= absorbDamage; absorb -= absorbDamage; - + const auto armorDamage = std::min(damage, armor); damage -= armorDamage; @@ -657,7 +657,7 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32 { EntityManager::Instance()->SerializeEntity(m_Parent); } - + auto* attacker = EntityManager::Instance()->GetEntity(source); m_Parent->OnHit(attacker); m_Parent->OnHitOrHealResult(attacker, sourceDamage); @@ -736,7 +736,7 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType } } } - + const auto isPlayer = m_Parent->IsPlayer(); GameMessages::SendDie(m_Parent, source, source, true, killType, deathType, 0, 0, 0, isPlayer, false, 1); @@ -765,14 +765,14 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType auto* member = EntityManager::Instance()->GetEntity(specificOwner); if (member) LootGenerator::Instance().DropLoot(member, m_Parent, lootMatrixId, GetMinCoins(), GetMaxCoins()); - } + } else { for (const auto memberId : team->members) { // Free for all auto* member = EntityManager::Instance()->GetEntity(memberId); if (member == nullptr) continue; - LootGenerator::Instance().DropLoot(member, m_Parent, lootMatrixId, GetMinCoins(), GetMaxCoins()); + LootGenerator::Instance().DropLoot(member, m_Parent, lootMatrixId, GetMinCoins(), GetMaxCoins()); } } } @@ -846,7 +846,7 @@ void DestroyableComponent::PopImmunity(int32_t stacks) m_ImmuneStacks -= stacks; } -void DestroyableComponent::FixStats() +void DestroyableComponent::FixStats() { auto* entity = GetParent(); @@ -904,7 +904,7 @@ void DestroyableComponent::FixStats() // Add the stats const auto& info = mission->GetClientInfo(); - + maxHealth += info.reward_maxhealth; maxImagination += info.reward_maximagination; } diff --git a/dGame/dComponents/InventoryComponent.cpp b/dGame/dComponents/InventoryComponent.cpp index 7235d2db..8c5ec269 100644 --- a/dGame/dComponents/InventoryComponent.cpp +++ b/dGame/dComponents/InventoryComponent.cpp @@ -51,18 +51,18 @@ InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* do auto items = inventoryComponentTable->Query([=](const CDInventoryComponent entry) { return entry.id == componentId; }); auto slot = 0u; - + for (const auto& item : items) { if (!item.equip || !Inventory::IsValidItem(item.itemid)) { continue; } - + const LWOOBJID id = ObjectIDManager::Instance()->GenerateObjectID(); const auto& info = Inventory::FindItemComponent(item.itemid); - + UpdateSlot(info.equipLocation, { id, static_cast(item.itemid), item.count, slot++ }); } } @@ -178,7 +178,7 @@ void InventoryComponent::AddItem( auto* missions = static_cast(this->m_Parent->GetComponent(COMPONENT_TYPE_MISSION)); auto* inventory = GetInventory(inventoryType); - + if (!config.empty() || bound) { const auto slot = preferredSlot != -1 && inventory->IsSlotEmpty(preferredSlot) ? preferredSlot : inventory->FindEmptySlot(); @@ -189,6 +189,7 @@ void InventoryComponent::AddItem( return; } + auto* item = new Item(lot, inventory, slot, count, config, parent, showFlyingLoot, isModMoveAndEquip, subKey, bound, lootSourceType); if (missions != nullptr && !IsTransferInventory(inventoryType)) @@ -200,7 +201,7 @@ void InventoryComponent::AddItem( } const auto info = Inventory::FindItemComponent(lot); - + auto left = count; int32_t outOfSpace = 0; @@ -215,7 +216,7 @@ void InventoryComponent::AddItem( { stack = 1; } - + auto* existing = FindItemByLot(lot, inventoryType); if (existing != nullptr) @@ -239,7 +240,7 @@ void InventoryComponent::AddItem( const auto size = std::min(left, stack); left -= size; - + int32_t slot; if (preferredSlot != -1 && inventory->IsSlotEmpty(preferredSlot)) @@ -252,7 +253,7 @@ void InventoryComponent::AddItem( { slot = inventory->FindEmptySlot(); } - + if (slot == -1) { auto* player = dynamic_cast(GetParent()); @@ -275,9 +276,9 @@ void InventoryComponent::AddItem( { GameMessages::SendDropClientLoot(this->m_Parent, this->m_Parent->GetObjectID(), lot, 0, this->m_Parent->GetPosition(), 1); } - + break; - + default: break; } @@ -326,7 +327,7 @@ void InventoryComponent::RemoveItem(const LOT lot, const uint32_t count, eInvent { break; } - + const auto delta = std::min(left, item->GetCount()); item->SetCount(item->GetCount() - delta); @@ -341,11 +342,11 @@ void InventoryComponent::MoveItemToInventory(Item* item, const eInventoryType in { return; } - + auto* origin = item->GetInventory(); - + const auto lot = item->GetLot(); - + if (item->GetConfig().empty() && !item->GetBound() || (item->GetBound() && item->GetInfo().isBOP)) { auto left = std::min(count, origin->GetLotCount(lot)); @@ -383,7 +384,7 @@ void InventoryComponent::MoveItemToInventory(Item* item, const eInventoryType in { config.push_back(data->Copy()); } - + const auto delta = std::min(item->GetCount(), count); AddItem(lot, delta, eLootSourceType::LOOT_SOURCE_NONE, inventory, config, LWOOBJID_EMPTY, showFlyingLot, isModMoveAndEquip, LWOOBJID_EMPTY, origin->GetType(), 0, item->GetBound(), preferredSlot); @@ -441,7 +442,7 @@ Item* InventoryComponent::FindItemByLot(const LOT lot, eInventoryType inventoryT return inventory->FindItemByLot(lot, ignoreEquipped, ignoreBound); } -Item* InventoryComponent::FindItemBySubKey(LWOOBJID id, eInventoryType inventoryType) +Item* InventoryComponent::FindItemBySubKey(LWOOBJID id, eInventoryType inventoryType) { if (inventoryType == INVALID) { @@ -600,7 +601,7 @@ void InventoryComponent::LoadXml(tinyxml2::XMLDocument* document) unsigned int count; bool bound; LWOOBJID subKey = LWOOBJID_EMPTY; - + itemElement->QueryAttribute("id", &id); itemElement->QueryAttribute("l", &lot); itemElement->QueryAttribute("eq", &equipped); @@ -611,23 +612,23 @@ void InventoryComponent::LoadXml(tinyxml2::XMLDocument* document) // Begin custom xml auto parent = LWOOBJID_EMPTY; - + itemElement->QueryAttribute("parent", &parent); // End custom xml std::vector config; auto* extraInfo = itemElement->FirstChildElement("x"); - + if (extraInfo) { std::string modInfo = extraInfo->Attribute("ma"); - + LDFBaseData* moduleAssembly = new LDFData(u"assemblyPartLOTs", GeneralUtils::ASCIIToUTF16(modInfo.substr(2, modInfo.size() - 1))); - + config.push_back(moduleAssembly); } - + const auto* item = new Item(id, lot, inventory, slot, count, bound, config, parent, subKey); if (equipped) @@ -705,7 +706,7 @@ void InventoryComponent::UpdateXml(tinyxml2::XMLDocument* document) bags->LinkEndChild(bag); } - + auto* items = inventoryElement->FirstChildElement("items"); if (items == nullptr) @@ -759,10 +760,10 @@ void InventoryComponent::UpdateXml(tinyxml2::XMLDocument* document) itemElement->LinkEndChild(extraInfo); } - + bagElement->LinkEndChild(itemElement); } - + items->LinkEndChild(bagElement); } } @@ -772,13 +773,13 @@ void InventoryComponent::Serialize(RakNet::BitStream* outBitStream, const bool b if (bIsInitialUpdate || m_Dirty) { outBitStream->Write(true); - + outBitStream->Write(m_Equipped.size()); for (const auto& pair : m_Equipped) { const auto item = pair.second; - + if (bIsInitialUpdate) { AddItemSkills(item.lot); @@ -786,12 +787,12 @@ void InventoryComponent::Serialize(RakNet::BitStream* outBitStream, const bool b outBitStream->Write(item.id); outBitStream->Write(item.lot); - + outBitStream->Write0(); - + outBitStream->Write(item.count > 0); if (item.count > 0) outBitStream->Write(item.count); - + outBitStream->Write(item.slot != 0); if (item.slot != 0) outBitStream->Write(item.slot); @@ -818,7 +819,7 @@ void InventoryComponent::Serialize(RakNet::BitStream* outBitStream, const bool b outBitStream->Write(ldfStream); } - outBitStream->Write1(); + outBitStream->Write1(); } m_Dirty = false; @@ -827,7 +828,7 @@ void InventoryComponent::Serialize(RakNet::BitStream* outBitStream, const bool b { outBitStream->Write(false); } - + outBitStream->Write(false); } @@ -836,7 +837,7 @@ void InventoryComponent::ResetFlags() m_Dirty = false; } -void InventoryComponent::Update(float deltaTime) +void InventoryComponent::Update(float deltaTime) { for (auto* set : m_Itemsets) { @@ -865,7 +866,7 @@ void InventoryComponent::UpdateSlot(const std::string& location, EquippedItem it UnEquipItem(old); } } - + m_Equipped.insert_or_assign(location, item); m_Dirty = true; @@ -877,14 +878,14 @@ void InventoryComponent::RemoveSlot(const std::string& location) { return; } - + m_Equipped.erase(location); m_Dirty = true; } void InventoryComponent::EquipItem(Item* item, const bool skipChecks) -{ +{ if (!Inventory::IsValidItem(item->GetLot())) { return; @@ -1030,7 +1031,7 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks) { return; } - + if (type == ITEM_TYPE_LOOT_MODEL || type == ITEM_TYPE_VEHICLE) { return; @@ -1049,7 +1050,7 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks) const auto lot = item->GetLot(); CheckItemSet(lot); - + for (auto* set : m_Itemsets) { set->OnEquip(lot); @@ -1079,7 +1080,7 @@ void InventoryComponent::UnEquipItem(Item* item) } const auto lot = item->GetLot(); - + if (!Inventory::IsValidItem(lot)) { return; @@ -1097,7 +1098,7 @@ void InventoryComponent::UnEquipItem(Item* item) RemoveItemSkills(item->GetLot()); RemoveSlot(item->GetInfo().equipLocation); - + PurgeProxies(item); EntityManager::Instance()->SerializeEntity(m_Parent); @@ -1115,7 +1116,7 @@ void InventoryComponent::ApplyBuff(Item* item) const const auto buffs = FindBuffs(item, true); for (const auto buff : buffs) - { + { SkillComponent::HandleUnmanaged(buff, m_Parent->GetObjectID()); } } @@ -1182,22 +1183,21 @@ bool InventoryComponent::IsEquipped(const LOT lot) const return false; } -void InventoryComponent::CheckItemSet(const LOT lot) -{ +void InventoryComponent::CheckItemSet(const LOT lot) { // Check if the lot is in the item set cache - if (std::find(m_ItemSetsChecked.begin(), m_ItemSetsChecked.end(), lot) != m_ItemSetsChecked.end()) - { + if (std::find(m_ItemSetsChecked.begin(), m_ItemSetsChecked.end(), lot) != m_ItemSetsChecked.end()) { return; } - std::stringstream query; + const std::string lot_query = "%" + std::to_string(lot) + "%"; - query << "SELECT setID FROM ItemSets WHERE itemIDs LIKE '%" << std::to_string(lot) << "%'"; + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT setID FROM ItemSets WHERE itemIDs LIKE ?;"); + query.bind(1, lot_query.c_str()); - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = query.execQuery(); - while (!result.eof()) - { + while (!result.eof()) { const auto id = result.getIntField(0); bool found = false; @@ -1223,11 +1223,11 @@ void InventoryComponent::CheckItemSet(const LOT lot) } m_ItemSetsChecked.push_back(lot); - + result.finalize(); } -void InventoryComponent::SetConsumable(LOT lot) +void InventoryComponent::SetConsumable(LOT lot) { m_Consumable = lot; } @@ -1247,7 +1247,7 @@ void InventoryComponent::AddItemSkills(const LOT lot) { return; } - + const auto index = m_Skills.find(slot); const auto skill = FindSkill(lot); @@ -1272,14 +1272,14 @@ void InventoryComponent::AddItemSkills(const LOT lot) void InventoryComponent::RemoveItemSkills(const LOT lot) { const auto info = Inventory::FindItemComponent(lot); - + const auto slot = FindBehaviorSlot(static_cast(info.itemType)); - + if (slot == BehaviorSlot::Invalid) { return; } - + const auto index = m_Skills.find(slot); if (index == m_Skills.end()) @@ -1292,7 +1292,7 @@ void InventoryComponent::RemoveItemSkills(const LOT lot) GameMessages::SendRemoveSkill(m_Parent, old); m_Skills.erase(slot); - + if (slot == BehaviorSlot::Primary) { m_Skills.insert_or_assign(BehaviorSlot::Primary, 1); @@ -1301,7 +1301,7 @@ void InventoryComponent::RemoveItemSkills(const LOT lot) } } -void InventoryComponent::TriggerPassiveAbility(PassiveAbilityTrigger trigger) +void InventoryComponent::TriggerPassiveAbility(PassiveAbilityTrigger trigger) { for (auto* set : m_Itemsets) { @@ -1328,7 +1328,7 @@ bool InventoryComponent::HasAnyPassive(const std::vectorGetObjectID()); @@ -1338,7 +1338,7 @@ void InventoryComponent::DespawnPet() } } -void InventoryComponent::SpawnPet(Item* item) +void InventoryComponent::SpawnPet(Item* item) { auto* current = PetComponent::GetActivePet(m_Parent->GetObjectID()); @@ -1357,11 +1357,11 @@ void InventoryComponent::SpawnPet(Item* item) info.pos = m_Parent->GetPosition(); info.rot = NiQuaternion::IDENTITY; info.spawnerID = m_Parent->GetObjectID(); - + auto* pet = EntityManager::Instance()->CreateEntity(info); auto* petComponent = pet->GetComponent(); - + if (petComponent != nullptr) { petComponent->Activate(item); @@ -1370,7 +1370,7 @@ void InventoryComponent::SpawnPet(Item* item) EntityManager::Instance()->ConstructEntity(pet); } -void InventoryComponent::SetDatabasePet(LWOOBJID id, const DatabasePet& data) +void InventoryComponent::SetDatabasePet(LWOOBJID id, const DatabasePet& data) { m_Pets.insert_or_assign(id, data); } @@ -1391,7 +1391,7 @@ bool InventoryComponent::IsPet(LWOOBJID id) const return pair != m_Pets.end(); } -void InventoryComponent::RemoveDatabasePet(LWOOBJID id) +void InventoryComponent::RemoveDatabasePet(LWOOBJID id) { m_Pets.erase(id); } @@ -1414,7 +1414,7 @@ BehaviorSlot InventoryComponent::FindBehaviorSlot(const eItemType type) } } -bool InventoryComponent::IsTransferInventory(eInventoryType type) +bool InventoryComponent::IsTransferInventory(eInventoryType type) { return type == VENDOR_BUYBACK || type == VAULT_ITEMS || type == VAULT_MODELS || type == TEMP_ITEMS || type == TEMP_MODELS; } @@ -1465,11 +1465,12 @@ std::vector InventoryComponent::FindBuffs(Item* item, bool castOnEquip continue; } - + if (missions != nullptr && castOnEquip) { missions->Progress(MissionTaskType::MISSION_TASK_TYPE_SKILL, result.skillID); } + // If item is not a proxy, add its buff to the added buffs. if (item->GetParent() == LWOOBJID_EMPTY) buffs.push_back(static_cast(entry.behaviorID)); } @@ -1478,18 +1479,18 @@ std::vector InventoryComponent::FindBuffs(Item* item, bool castOnEquip return buffs; } -void InventoryComponent::SetNPCItems(const std::vector& items) +void InventoryComponent::SetNPCItems(const std::vector& items) { m_Equipped.clear(); auto slot = 0u; - + for (const auto& item : items) { const LWOOBJID id = ObjectIDManager::Instance()->GenerateObjectID(); const auto& info = Inventory::FindItemComponent(item); - + UpdateSlot(info.equipLocation, { id, static_cast(item), 1, slot++ }, true); } @@ -1524,9 +1525,9 @@ std::vector InventoryComponent::GenerateProxies(Item* parent) { return proxies; } - + subItems.erase(std::remove_if(subItems.begin(), subItems.end(), ::isspace), subItems.end()); - + std::stringstream stream(subItems); std::string segment; std::vector lots; @@ -1541,7 +1542,7 @@ std::vector InventoryComponent::GenerateProxies(Item* parent) { Game::logger->Log("InventoryComponent", "Failed to parse proxy (%s): (%s)!\n", segment.c_str(), exception.what()); } - } + } for (const auto lot : lots) { @@ -1558,7 +1559,7 @@ std::vector InventoryComponent::GenerateProxies(Item* parent) proxies.push_back(proxy); } - + return proxies; } @@ -1567,7 +1568,7 @@ std::vector InventoryComponent::FindProxies(const LWOOBJID parent) auto* inventory = GetInventory(ITEM_SETS); std::vector proxies; - + for (const auto& pair : inventory->GetItems()) { auto* item = pair.second; @@ -1609,7 +1610,7 @@ bool InventoryComponent::IsParentValid(Item* root) } const auto id = root->GetId(); - + for (const auto& pair : m_Inventories) { const auto items = pair.second->GetItems(); @@ -1631,7 +1632,7 @@ bool InventoryComponent::IsParentValid(Item* root) void InventoryComponent::CheckProxyIntegrity() { std::vector dead; - + for (const auto& pair : m_Inventories) { const auto& items = pair.second->GetItems(); @@ -1646,7 +1647,7 @@ void InventoryComponent::CheckProxyIntegrity() { continue; } - + if (IsValidProxy(parent)) { continue; @@ -1671,7 +1672,7 @@ void InventoryComponent::CheckProxyIntegrity() for (const auto& candidate : items) { auto* item = candidate.second; - + const auto parent = item->GetParent(); if (parent != LWOOBJID_EMPTY) @@ -1703,7 +1704,7 @@ void InventoryComponent::CheckProxyIntegrity() void InventoryComponent::PurgeProxies(Item* item) { const auto root = item->GetParent(); - + if (root != LWOOBJID_EMPTY) { item = FindItemById(root); @@ -1712,7 +1713,7 @@ void InventoryComponent::PurgeProxies(Item* item) { UnEquipItem(item); } - + return; } @@ -1726,7 +1727,7 @@ void InventoryComponent::PurgeProxies(Item* item) } } -void InventoryComponent::LoadPetXml(tinyxml2::XMLDocument* document) +void InventoryComponent::LoadPetXml(tinyxml2::XMLDocument* document) { auto* petInventoryElement = document->FirstChildElement("obj")->FirstChildElement("pet"); @@ -1744,7 +1745,7 @@ void InventoryComponent::LoadPetXml(tinyxml2::XMLDocument* document) LWOOBJID id; LOT lot; int32_t moderationStatus; - + petElement->QueryAttribute("id", &id); petElement->QueryAttribute("l", &lot); petElement->QueryAttribute("m", &moderationStatus); @@ -1761,7 +1762,7 @@ void InventoryComponent::LoadPetXml(tinyxml2::XMLDocument* document) } } -void InventoryComponent::UpdatePetXml(tinyxml2::XMLDocument* document) +void InventoryComponent::UpdatePetXml(tinyxml2::XMLDocument* document) { auto* petInventoryElement = document->FirstChildElement("obj")->FirstChildElement("pet"); @@ -1783,8 +1784,7 @@ void InventoryComponent::UpdatePetXml(tinyxml2::XMLDocument* document) petElement->SetAttribute("m", pet.second.moderationState); petElement->SetAttribute("n", pet.second.name.c_str()); petElement->SetAttribute("t", 0); - + petInventoryElement->LinkEndChild(petElement); } } - diff --git a/dGame/dComponents/MissionComponent.cpp b/dGame/dComponents/MissionComponent.cpp index a0e63914..1b809f48 100644 --- a/dGame/dComponents/MissionComponent.cpp +++ b/dGame/dComponents/MissionComponent.cpp @@ -450,11 +450,11 @@ const std::vector& MissionComponent::QueryAchievements(MissionTaskType } bool MissionComponent::RequiresItem(const LOT lot) { - std::stringstream query; + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT type FROM Objects WHERE id = ?;"); + query.bind(1, (int) lot); - query << "SELECT type FROM Objects WHERE id = " << std::to_string(lot); - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = query.execQuery(); if (result.eof()) { return false; diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index 39d7eb60..a36d59e3 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -172,13 +172,12 @@ void PetComponent::OnUse(Entity* originator) std::string buildFile; - if (cached == buildCache.end()) - { - std::stringstream query; + if (cached == buildCache.end()) { + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT ValidPiecesLXF, PuzzleModelLot, Timelimit, NumValidPieces, imagCostPerBuild FROM TamingBuildPuzzles WHERE NPCLot = ?;"); + query.bind(1, (int) m_Parent->GetLOT()); - query << "SELECT ValidPiecesLXF, PuzzleModelLot, Timelimit, NumValidPieces, imagCostPerBuild FROM TamingBuildPuzzles WHERE NPCLot = " << std::to_string(m_Parent->GetLOT()) << ";"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = query.execQuery(); if (result.eof()) { diff --git a/dGame/dComponents/PropertyManagementComponent.cpp b/dGame/dComponents/PropertyManagementComponent.cpp index 0a428e04..7f82ae27 100644 --- a/dGame/dComponents/PropertyManagementComponent.cpp +++ b/dGame/dComponents/PropertyManagementComponent.cpp @@ -40,11 +40,11 @@ PropertyManagementComponent::PropertyManagementComponent(Entity* parent) : Compo const auto zoneId = worldId.GetMapID(); const auto cloneId = worldId.GetCloneID(); - std::stringstream query; + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT id FROM PropertyTemplate WHERE mapID = ?;"); + query.bind(1, (int) zoneId); - query << "SELECT id FROM PropertyTemplate WHERE mapID = " << std::to_string(zoneId) << ";"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = query.execQuery(); if (result.eof() || result.fieldIsNull(0)) { @@ -102,12 +102,12 @@ void PropertyManagementComponent::SetOwner(Entity* value) std::vector PropertyManagementComponent::GetPaths() const { const auto zoneId = dZoneManager::Instance()->GetZone()->GetWorldID(); - - std::stringstream query {}; - query << "SELECT path FROM PropertyTemplate WHERE mapID = " << std::to_string(zoneId) << ";"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT path FROM PropertyTemplate WHERE mapID = ?;"); + query.bind(1, (int) zoneId); + + auto result = query.execQuery(); std::vector paths {}; diff --git a/dGame/dComponents/RenderComponent.cpp b/dGame/dComponents/RenderComponent.cpp index aeb56f56..faec4ab6 100644 --- a/dGame/dComponents/RenderComponent.cpp +++ b/dGame/dComponents/RenderComponent.cpp @@ -198,14 +198,16 @@ void RenderComponent::PlayEffect(const int32_t effectId, const std::u16string& e return; } - std::stringstream query; + const std::string effectType_str = GeneralUtils::UTF16ToWTF8(effectType); - query << "SELECT animation_length FROM Animations WHERE animation_type IN (SELECT animationName FROM BehaviorEffect WHERE effectID = " << std::to_string(effectId) << " AND effectType = '" << GeneralUtils::UTF16ToWTF8(effectType) << "');"; + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT animation_length FROM Animations WHERE animation_type IN (SELECT animationName FROM BehaviorEffect WHERE effectID = ? AND effectType = ?);"); + query.bind(1, effectId); + query.bind(2, effectType_str.c_str()); - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = query.execQuery(); - if (result.eof() || result.fieldIsNull(0)) - { + if (result.eof() || result.fieldIsNull(0)) { result.finalize(); m_DurationCache[effectId] = 0; @@ -214,7 +216,7 @@ void RenderComponent::PlayEffect(const int32_t effectId, const std::u16string& e return; } - + effect->time = static_cast(result.getFloatField(0)); result.finalize(); diff --git a/dGame/dComponents/RocketLaunchpadControlComponent.cpp b/dGame/dComponents/RocketLaunchpadControlComponent.cpp index 8585815f..357fb2d0 100644 --- a/dGame/dComponents/RocketLaunchpadControlComponent.cpp +++ b/dGame/dComponents/RocketLaunchpadControlComponent.cpp @@ -19,11 +19,11 @@ #include "PacketUtils.h" RocketLaunchpadControlComponent::RocketLaunchpadControlComponent(Entity* parent, int rocketId) : Component(parent) { - std::stringstream query; + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT targetZone, defaultZoneID, targetScene, altLandingPrecondition, altLandingSpawnPointName FROM RocketLaunchpadControlComponent WHERE id = ?;"); + query.bind(1, rocketId); - query << "SELECT targetZone, defaultZoneID, targetScene, altLandingPrecondition, altLandingSpawnPointName FROM RocketLaunchpadControlComponent WHERE id = " << std::to_string(rocketId); - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = query.execQuery(); if (!result.eof() && !result.fieldIsNull(0)) { @@ -48,7 +48,7 @@ void RocketLaunchpadControlComponent::Launch(Entity* originator, LWOMAPID mapId, { return; } - + // This also gets triggered by a proximity monitor + item equip, I will set that up when havok is ready auto* characterComponent = originator->GetComponent(); auto* character = originator->GetCharacter(); @@ -77,11 +77,11 @@ void RocketLaunchpadControlComponent::Launch(Entity* originator, LWOMAPID mapId, character->SaveXMLToDatabase(); SetSelectedMapId(originator->GetObjectID(), zone); - - GameMessages::SendFireEventClientSide(m_Parent->GetObjectID(), originator->GetSystemAddress(), u"RocketEquipped", rocket->GetId(), cloneId, -1, originator->GetObjectID()); - GameMessages::SendChangeObjectWorldState(rocket->GetId(), WORLDSTATE_ATTACHED, UNASSIGNED_SYSTEM_ADDRESS); + GameMessages::SendFireEventClientSide(m_Parent->GetObjectID(), originator->GetSystemAddress(), u"RocketEquipped", rocket->GetId(), cloneId, -1, originator->GetObjectID()); + GameMessages::SendChangeObjectWorldState(rocket->GetId(), WORLDSTATE_ATTACHED, UNASSIGNED_SYSTEM_ADDRESS); + EntityManager::Instance()->SerializeEntity(originator); } @@ -112,7 +112,7 @@ void RocketLaunchpadControlComponent::OnProximityUpdate(Entity* entering, std::s // Proximity rockets are handled by item equipment } -void RocketLaunchpadControlComponent::SetSelectedMapId(LWOOBJID player, LWOMAPID mapID) +void RocketLaunchpadControlComponent::SetSelectedMapId(LWOOBJID player, LWOMAPID mapID) { m_SelectedMapIds[player] = mapID; } @@ -126,7 +126,7 @@ LWOMAPID RocketLaunchpadControlComponent::GetSelectedMapId(LWOOBJID player) cons return index->second; } -void RocketLaunchpadControlComponent::SetSelectedCloneId(LWOOBJID player, LWOCLONEID cloneId) +void RocketLaunchpadControlComponent::SetSelectedCloneId(LWOOBJID player, LWOCLONEID cloneId) { m_SelectedCloneIds[player] = cloneId; } diff --git a/dGame/dComponents/SkillComponent.cpp b/dGame/dComponents/SkillComponent.cpp index 483e360f..7aa29523 100644 --- a/dGame/dComponents/SkillComponent.cpp +++ b/dGame/dComponents/SkillComponent.cpp @@ -38,11 +38,11 @@ bool SkillComponent::CastPlayerSkill(const uint32_t behaviorId, const uint32_t s auto* behavior = Behavior::CreateBehavior(behaviorId); const auto branch = BehaviorBranchContext(target, 0); - + behavior->Handle(context, bitStream, branch); context->ExecuteUpdates(); - + return !context->failed; } @@ -78,24 +78,23 @@ void SkillComponent::SyncPlayerProjectile(const LWOOBJID projectileId, RakNet::B break; } } - + if (index == -1) { Game::logger->Log("SkillComponent", "Failed to find projectile id (%llu)!\n", projectileId); - + return; } const auto sync_entry = this->m_managedProjectiles.at(index); - std::stringstream query; + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT behaviorID FROM SkillBehavior WHERE skillID = (SELECT skillID FROM ObjectSkills WHERE objectTemplate = ?);"); + query.bind(1, (int) sync_entry.lot); - query << "SELECT behaviorID FROM SkillBehavior WHERE skillID = (SELECT skillID FROM ObjectSkills WHERE objectTemplate = " << std::to_string(sync_entry.lot) << ")"; + auto result = query.execQuery(); - auto result = CDClientDatabase::ExecuteQuery(query.str()); - - if (result.eof()) - { + if (result.eof()) { Game::logger->Log("SkillComponent", "Failed to find skill id for (%i)!\n", sync_entry.lot); return; @@ -115,7 +114,7 @@ void SkillComponent::SyncPlayerProjectile(const LWOOBJID projectileId, RakNet::B { branch.target = target; } - + behavior->Handle(sync_entry.context, bitStream, branch); this->m_managedProjectiles.erase(this->m_managedProjectiles.begin() + index); @@ -129,7 +128,7 @@ void SkillComponent::RegisterPlayerProjectile(const LWOOBJID projectileId, Behav entry.branchContext = branch; entry.lot = lot; entry.id = projectileId; - + this->m_managedProjectiles.push_back(entry); } @@ -141,7 +140,7 @@ void SkillComponent::Update(const float deltaTime) } std::map keep {}; - + for (const auto& pair : this->m_managedBehaviors) { auto* context = pair.second; @@ -150,7 +149,7 @@ void SkillComponent::Update(const float deltaTime) { continue; } - + if (context->clientInitalized) { context->CalculateUpdate(deltaTime); @@ -164,7 +163,7 @@ void SkillComponent::Update(const float deltaTime) if (context->syncEntries.empty() && context->timerEntries.empty()) { auto any = false; - + for (const auto& projectile : this->m_managedProjectiles) { if (projectile.context == context) @@ -180,13 +179,13 @@ void SkillComponent::Update(const float deltaTime) context->Reset(); delete context; - + context = nullptr; continue; } } - + keep.insert_or_assign(pair.first, context); } @@ -254,9 +253,9 @@ SkillExecutionResult SkillComponent::CalculateBehavior(const uint32_t skillId, c context->caster = m_Parent->GetObjectID(); context->clientInitalized = clientInitalized; - + context->foundTarget = target != LWOOBJID_EMPTY || ignoreTarget || clientInitalized; - + behavior->Calculate(context, bitStream, { target, 0}); for (auto* script : CppScripts::GetEntityScripts(m_Parent)) { @@ -278,7 +277,7 @@ SkillExecutionResult SkillComponent::CalculateBehavior(const uint32_t skillId, c { // Echo start skill GameMessages::EchoStartSkill start; - + start.iCastType = 0; start.skillID = skillId; start.uiSkillHandle = context->skillUId; @@ -353,7 +352,7 @@ void SkillComponent::CalculateUpdate(const float deltaTime) const auto targetPosition = target->GetPosition(); const auto closestPoint = Vector3::ClosestPointOnLine(entry.lastPosition, position, targetPosition); - + const auto distance = Vector3::DistanceSquared(targetPosition, closestPoint); if (distance > 3 * 3) @@ -399,12 +398,12 @@ void SkillComponent::CalculateUpdate(const float deltaTime) } entry.lastPosition = position; - + managedProjectile = entry; } - + std::vector valid; - + for (auto& entry : this->m_managedProjectiles) { if (entry.calculation) @@ -412,7 +411,7 @@ void SkillComponent::CalculateUpdate(const float deltaTime) if (entry.time >= entry.maxTime) { entry.branchContext.target = LWOOBJID_EMPTY; - + SyncProjectileCalculation(entry); continue; @@ -430,8 +429,7 @@ void SkillComponent::SyncProjectileCalculation(const ProjectileSyncEntry& entry) { auto* other = EntityManager::Instance()->GetEntity(entry.branchContext.target); - if (other == nullptr) - { + if (other == nullptr) { if (entry.branchContext.target != LWOOBJID_EMPTY) { Game::logger->Log("SkillComponent", "Invalid projectile target (%llu)!\n", entry.branchContext.target); @@ -440,14 +438,12 @@ void SkillComponent::SyncProjectileCalculation(const ProjectileSyncEntry& entry) return; } - std::stringstream query; + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT behaviorID FROM SkillBehavior WHERE skillID = (SELECT skillID FROM ObjectSkills WHERE objectTemplate = ?);"); + query.bind(1, (int) entry.lot); + auto result = query.execQuery(); - query << "SELECT behaviorID FROM SkillBehavior WHERE skillID = (SELECT skillID FROM ObjectSkills WHERE objectTemplate = " << std::to_string(entry.lot) << ")"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); - - if (result.eof()) - { + if (result.eof()) { Game::logger->Log("SkillComponent", "Failed to find skill id for (%i)!\n", entry.lot); return; @@ -456,13 +452,13 @@ void SkillComponent::SyncProjectileCalculation(const ProjectileSyncEntry& entry) const auto behaviorId = static_cast(result.getIntField(0)); result.finalize(); - + auto* behavior = Behavior::CreateBehavior(behaviorId); auto* bitStream = new RakNet::BitStream(); behavior->Calculate(entry.context, bitStream, entry.branchContext); - + GameMessages::DoClientProjectileImpact projectileImpact; projectileImpact.sBitStream.assign((char*) bitStream->GetData(), bitStream->GetNumberOfBytesUsed()); @@ -498,19 +494,19 @@ void SkillComponent::HandleUnmanaged(const uint32_t behaviorId, const LWOOBJID t delete bitStream; - delete context; + delete context; } void SkillComponent::HandleUnCast(const uint32_t behaviorId, const LWOOBJID target) { auto* context = new BehaviorContext(target); - + context->caster = target; auto* behavior = Behavior::CreateBehavior(behaviorId); behavior->UnCast(context, { target }); - + delete context; } diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index a813f6d3..58aba14d 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -2515,11 +2515,11 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent const auto zoneId = worldId.GetMapID(); const auto cloneId = worldId.GetCloneID(); - std::stringstream query; + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT id FROM PropertyTemplate WHERE mapID = ?;"); + query.bind(1, (int) zoneId); - query << "SELECT id FROM PropertyTemplate WHERE mapID = " << std::to_string(zoneId) << ";"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = query.execQuery(); if (result.eof() || result.fieldIsNull(0)) { return; diff --git a/dGame/dInventory/Item.cpp b/dGame/dInventory/Item.cpp index a8e8d408..8f464d36 100644 --- a/dGame/dInventory/Item.cpp +++ b/dGame/dInventory/Item.cpp @@ -386,11 +386,11 @@ void Item::DisassembleModel() const auto componentId = table->GetByIDAndType(GetLot(), COMPONENT_TYPE_RENDER); - std::stringstream query; + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT render_asset FROM RenderComponent WHERE id = ?;"); + query.bind(1, (int) componentId); - query << "SELECT render_asset FROM RenderComponent WHERE id = " << std::to_string(componentId) << ";"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = query.execQuery(); if (result.eof()) { diff --git a/dGame/dInventory/ItemSet.cpp b/dGame/dInventory/ItemSet.cpp index d1e74df4..feddd757 100644 --- a/dGame/dInventory/ItemSet.cpp +++ b/dGame/dInventory/ItemSet.cpp @@ -15,17 +15,17 @@ ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent) this->m_PassiveAbilities = ItemSetPassiveAbility::FindAbilities(id, m_InventoryComponent->GetParent(), this); - std::stringstream query; + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT skillSetWith2, skillSetWith3, skillSetWith4, skillSetWith5, skillSetWith6, itemIDs FROM ItemSets WHERE setID = ?;"); + query.bind(1, (int) id); - query << "SELECT skillSetWith2, skillSetWith3, skillSetWith4, skillSetWith5, skillSetWith6, itemIDs FROM ItemSets WHERE setID = " << std::to_string(id); - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = query.execQuery(); if (result.eof()) { return; } - + for (auto i = 0; i < 5; ++i) { if (result.fieldIsNull(i)) @@ -33,11 +33,11 @@ ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent) continue; } - std::stringstream skillQuery; + auto skillQuery = CDClientDatabase::CreatePreppedStmt( + "SELECT SkillID FROM ItemSetSkills WHERE SkillSetID = ?;"); + skillQuery.bind(1, result.getIntField(i)); - skillQuery << "SELECT SkillID FROM ItemSetSkills WHERE SkillSetID = " << std::to_string(result.getIntField(i)); - - auto skillResult = CDClientDatabase::ExecuteQuery(skillQuery.str()); + auto skillResult = skillQuery.execQuery(); if (skillResult.eof()) { @@ -49,10 +49,10 @@ ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent) if (skillResult.fieldIsNull(0)) { skillResult.nextRow(); - + continue; } - + const auto skillId = skillResult.getIntField(0); switch (i) @@ -75,7 +75,7 @@ ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent) default: break; } - + skillResult.nextRow(); } } @@ -83,7 +83,7 @@ ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent) std::string ids = result.getStringField(5); ids.erase(std::remove_if(ids.begin(), ids.end(), ::isspace), ids.end()); - + std::istringstream stream(ids); std::string token; @@ -99,9 +99,9 @@ ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent) m_Items.push_back(value); } } - + m_Equipped = {}; - + for (const auto item : m_Items) { if (inventoryComponent->IsEquipped(item)) @@ -141,11 +141,11 @@ void ItemSet::OnEquip(const LOT lot) auto* skillComponent = m_InventoryComponent->GetParent()->GetComponent(); auto* missionComponent = m_InventoryComponent->GetParent()->GetComponent(); - + for (const auto skill : skillSet) { auto* skillTable = CDClientManager::Instance()->GetTable("SkillBehavior"); - + const auto behaviorId = skillTable->GetSkillByID(skill).behaviorID; missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_SKILL, skill); @@ -167,11 +167,11 @@ void ItemSet::OnUnEquip(const LOT lot) { return; } - + const auto& skillSet = GetSkillSet(m_Equipped.size()); m_Equipped.erase(index); - + if (skillSet.empty()) { return; @@ -199,7 +199,7 @@ uint32_t ItemSet::GetID() const return m_ID; } -void ItemSet::Update(float deltaTime) +void ItemSet::Update(float deltaTime) { for (auto& passiveAbility : m_PassiveAbilities) { @@ -207,7 +207,7 @@ void ItemSet::Update(float deltaTime) } } -void ItemSet::TriggerPassiveAbility(PassiveAbilityTrigger trigger) +void ItemSet::TriggerPassiveAbility(PassiveAbilityTrigger trigger) { for (auto& passiveAbility : m_PassiveAbilities) { diff --git a/dGame/dUtilities/Preconditions.cpp b/dGame/dUtilities/Preconditions.cpp index b29af130..6921343b 100644 --- a/dGame/dUtilities/Preconditions.cpp +++ b/dGame/dUtilities/Preconditions.cpp @@ -15,20 +15,19 @@ std::map Preconditions::cache = {}; -Precondition::Precondition(const uint32_t condition) -{ - std::stringstream query; +Precondition::Precondition(const uint32_t condition) { + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT type, targetLOT, targetCount FROM Preconditions WHERE id = ?;"); + query.bind(1, (int) condition); - query << "SELECT type, targetLOT, targetCount FROM Preconditions WHERE id = " << std::to_string(condition) << ";"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = query.execQuery(); if (result.eof()) { this->type = PreconditionType::ItemEquipped; this->count = 1; this->values = { 0 }; - + Game::logger->Log("Precondition", "Failed to find precondition of id (%i)!\n", condition); return; @@ -99,11 +98,11 @@ bool Precondition::Check(Entity* player, bool evaluateCosts) const } auto passedAny = false; - + for (const auto value : values) { const auto passed = CheckValue(player, value, evaluateCosts); - + if (passed && any) { return true; @@ -222,7 +221,7 @@ PreconditionExpression::PreconditionExpression(const std::string& conditions) return; } - + std::stringstream a; std::stringstream b; @@ -310,16 +309,16 @@ bool PreconditionExpression::Check(Entity* player, bool evaluateCosts) const { return true; } - + const auto a = Preconditions::Check(player, condition, evaluateCosts); if (!a) { GameMessages::SendNotifyClientFailedPrecondition(player->GetObjectID(), player->GetSystemAddress(), u"", condition); } - + const auto b = next == nullptr ? true : next->Check(player); - + return m_or ? a || b : a && b; } diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 324da751..90f32f69 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -64,48 +64,48 @@ #include "ScriptedActivityComponent.h" void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entity* entity, const SystemAddress& sysAddr) { - std::string chatCommand; - std::vector args; + std::string chatCommand; + std::vector args; - uint32_t breakIndex = 0; - for (uint32_t i = 1; i < command.size(); ++i) { - if (command[i] == L' ') { - breakIndex = i; - break; - } + uint32_t breakIndex = 0; + for (uint32_t i = 1; i < command.size(); ++i) { + if (command[i] == L' ') { + breakIndex = i; + break; + } - chatCommand.push_back(static_cast(command[i])); - breakIndex++; - } + chatCommand.push_back(static_cast(command[i])); + breakIndex++; + } - uint32_t index = ++breakIndex; - while (true) { - std::string arg; + uint32_t index = ++breakIndex; + while (true) { + std::string arg; - while (index < command.size()) { - if (command[index] == L' ') { - args.push_back(arg); - arg = ""; - index++; - continue; - } + while (index < command.size()) { + if (command[index] == L' ') { + args.push_back(arg); + arg = ""; + index++; + continue; + } - arg.push_back(static_cast(command[index])); - index++; - } + arg.push_back(static_cast(command[index])); + index++; + } - if (arg != "") { - args.push_back(arg); - } + if (arg != "") { + args.push_back(arg); + } - break; - } + break; + } - //Game::logger->Log("SlashCommandHandler", "Received chat command \"%s\"\n", GeneralUtils::UTF16ToWTF8(command).c_str()); + //Game::logger->Log("SlashCommandHandler", "Received chat command \"%s\"\n", GeneralUtils::UTF16ToWTF8(command).c_str()); - User* user = UserManager::Instance()->GetUser(sysAddr); - if ((chatCommand == "setgmlevel" || chatCommand == "makegm" || chatCommand == "gmlevel") && user->GetMaxGMLevel() > GAME_MASTER_LEVEL_CIVILIAN) { - if (args.size() != 1) return; + User* user = UserManager::Instance()->GetUser(sysAddr); + if ((chatCommand == "setgmlevel" || chatCommand == "makegm" || chatCommand == "gmlevel") && user->GetMaxGMLevel() > GAME_MASTER_LEVEL_CIVILIAN) { + if (args.size() != 1) return; uint32_t level; @@ -127,10 +127,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit level = user->GetMaxGMLevel(); } - if (level == entity->GetGMLevel()) return; - bool success = user->GetMaxGMLevel() >= level; + if (level == entity->GetGMLevel()) return; + bool success = user->GetMaxGMLevel() >= level; + + if (success) { - if (success) { if (entity->GetGMLevel() > GAME_MASTER_LEVEL_CIVILIAN && level == GAME_MASTER_LEVEL_CIVILIAN) { GameMessages::SendToggleGMInvis(entity->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS); @@ -301,7 +302,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - if ((chatCommand == "leave-zone")) { + if (chatCommand == "leave-zone") { const auto currentZone = dZoneManager::Instance()->GetZone()->GetZoneID().GetMapID(); auto newZone = 0; @@ -342,7 +343,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit }); } - if ((chatCommand == "join" && !args.empty())) { + if (chatCommand == "join" && !args.empty()) { ChatPackets::SendSystemMessage(sysAddr, u"Requesting private map..."); const auto& password = args[0]; @@ -395,8 +396,8 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit auto stmt = Database::CreatePreppedStmt("INSERT INTO command_log (character_id, command) VALUES (?, ?);"); stmt->setInt(1, entity->GetCharacter()->GetID()); stmt->setString(2, GeneralUtils::UTF16ToWTF8(command).c_str()); - stmt->execute(); - delete stmt; + stmt->execute(); + delete stmt; if (chatCommand == "setminifig" && args.size() == 2 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_FORUM_MODERATOR) { // could break characters so only allow if GM > 0 int32_t minifigItemId; @@ -599,6 +600,10 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit if (chatCommand == "runmacro" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { if (args.size() != 1) return; + // Only process if input does not contain separator charaters + if (args[0].find("/") != std::string::npos) return; + if (args[0].find("\\") != std::string::npos) return; + std::ifstream infile("./res/macros/" + args[0] + ".scm"); if (infile.good()) { @@ -920,13 +925,14 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit return; } - pos.SetX(x); - pos.SetY(y); - pos.SetZ(z); + pos.SetX(x); + pos.SetY(y); + pos.SetZ(z); + + Game::logger->Log("SlashCommandHandler", "Teleporting objectID: %llu to %f, %f, %f\n", entity->GetObjectID(), pos.x, pos.y, pos.z); + GameMessages::SendTeleport(entity->GetObjectID(), pos, NiQuaternion(), sysAddr); + } else if (args.size() == 2) { - Game::logger->Log("SlashCommandHandler", "Teleporting objectID: %llu to %f, %f, %f\n", entity->GetObjectID(), pos.x, pos.y, pos.z); - GameMessages::SendTeleport(entity->GetObjectID(), pos, NiQuaternion(), sysAddr); - } else if (args.size() == 2) { float x, z; if (!GeneralUtils::TryParse(args[0], x)) @@ -945,12 +951,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit pos.SetY(0.0f); pos.SetZ(z); - - Game::logger->Log("SlashCommandHandler", "Teleporting objectID: %llu to X: %f, Z: %f\n", entity->GetObjectID(), pos.x, pos.z); - GameMessages::SendTeleport(entity->GetObjectID(), pos, NiQuaternion(), sysAddr); - } else { - ChatPackets::SendSystemMessage(sysAddr, u"Correct usage: /teleport () - if no Y given, will teleport to the height of the terrain (or any physics object)."); - } + Game::logger->Log("SlashCommandHandler", "Teleporting objectID: %llu to X: %f, Z: %f\n", entity->GetObjectID(), pos.x, pos.z); + GameMessages::SendTeleport(entity->GetObjectID(), pos, NiQuaternion(), sysAddr); + } else { + ChatPackets::SendSystemMessage(sysAddr, u"Correct usage: /teleport () - if no Y given, will teleport to the height of the terrain (or any physics object)."); + } auto* possessorComponent = entity->GetComponent(); @@ -1190,7 +1195,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit //------------------------------------------------- - if (chatCommand == "buffme" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "buffme" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { auto dest = static_cast(entity->GetComponent(COMPONENT_TYPE_DESTROYABLE)); if (dest) { dest->SetHealth(999); @@ -1200,9 +1205,8 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit dest->SetImagination(999); dest->SetMaxImagination(999.0f); } - - EntityManager::Instance()->SerializeEntity(entity); - } + EntityManager::Instance()->SerializeEntity(entity); + } if (chatCommand == "startcelebration" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 1) { int32_t celebration; @@ -1216,7 +1220,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit GameMessages::SendStartCelebrationEffect(entity, entity->GetSystemAddress(), celebration); } - if (chatCommand == "buffmed" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { + if (chatCommand == "buffmed" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { auto dest = static_cast(entity->GetComponent(COMPONENT_TYPE_DESTROYABLE)); if (dest) { dest->SetHealth(9); @@ -1226,11 +1230,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit dest->SetImagination(9); dest->SetMaxImagination(9.0f); } + EntityManager::Instance()->SerializeEntity(entity); + } - EntityManager::Instance()->SerializeEntity(entity); - } + if (chatCommand == "refillstats" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { - if (chatCommand == "refillstats" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) { auto dest = static_cast(entity->GetComponent(COMPONENT_TYPE_DESTROYABLE)); if (dest) { dest->SetHealth((int)dest->GetMaxHealth()); @@ -1238,22 +1242,28 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit dest->SetImagination((int)dest->GetMaxImagination()); } - EntityManager::Instance()->SerializeEntity(entity); - } + EntityManager::Instance()->SerializeEntity(entity); + } if (chatCommand == "lookup" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 1) { - std::string query = "SELECT `id`, `name` FROM `Objects` WHERE `displayName` LIKE '%" + args[0] + "%' OR `name` LIKE '%" + args[0] + "%' OR `description` LIKE '%" + args[0] + "%'"; - auto tables = CDClientDatabase::ExecuteQuery(query.c_str()); - while (!tables.eof()) { - std::string message = std::to_string(tables.getIntField(0)) + " - " + tables.getStringField(1); - ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(message, message.size())); - tables.nextRow(); - } - } + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT `id`, `name` FROM `Objects` WHERE `displayName` LIKE ?1 OR `name` LIKE ?1 OR `description` LIKE ?1 LIMIT 50"); - if (chatCommand == "spawn" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { - ControllablePhysicsComponent* comp = static_cast(entity->GetComponent(COMPONENT_TYPE_CONTROLLABLE_PHYSICS)); - if (!comp) return; + const std::string query_text = "%" + args[0] + "%"; + query.bind(1, query_text.c_str()); + + auto tables = query.execQuery(); + + while (!tables.eof()) { + std::string message = std::to_string(tables.getIntField(0)) + " - " + tables.getStringField(1); + ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(message, message.size())); + tables.nextRow(); + } + } + + if (chatCommand == "spawn" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) { + ControllablePhysicsComponent* comp = static_cast(entity->GetComponent(COMPONENT_TYPE_CONTROLLABLE_PHYSICS)); + if (!comp) return; uint32_t lot; @@ -1440,7 +1450,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit const auto objid = entity->GetObjectID(); - if (force || CheckIfAccessibleZone(reqZone)) { // to prevent tomfoolery + if (force || CheckIfAccessibleZone(reqZone)) { // to prevent tomfoolery bool darwin = true; //Putting this on true, as I'm sick of having to wait 3-4 seconds on a transfer while trying to quickly moderate properties Character* character = entity->GetCharacter(); @@ -1487,15 +1497,14 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit WorldPackets::SendTransferToWorld(sysAddr, serverIP, serverPort, mythranShift); }); - - return; - }); - } else { - std::string msg = "ZoneID not found or allowed: "; - msg.append(args[0]); - ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(msg, msg.size())); - } - } + return; + }); + } else { + std::string msg = "ZoneID not found or allowed: "; + msg.append(args[0]); + ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(msg, msg.size())); + } + } if (chatCommand == "createprivate" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 3) { @@ -1973,4 +1982,3 @@ void SlashCommandHandler::SendAnnouncement(const std::string& title, const std:: Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); } - diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index c23b44b7..4f1ec400 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -998,11 +998,11 @@ void HandlePacket(Packet* packet) { const auto zoneId = Game::server->GetZoneID(); const auto cloneId = g_CloneID; - std::stringstream query; + auto query = CDClientDatabase::CreatePreppedStmt( + "SELECT id FROM PropertyTemplate WHERE mapID = ?;"); + query.bind(1, (int) zoneId); - query << "SELECT id FROM PropertyTemplate WHERE mapID = " << std::to_string(zoneId) << ";"; - - auto result = CDClientDatabase::ExecuteQuery(query.str()); + auto result = query.execQuery(); if (result.eof() || result.fieldIsNull(0)) { Game::logger->Log("WorldServer", "No property templates found for zone %d, not sending BBB\n", zoneId); diff --git a/dZoneManager/dZoneManager.cpp b/dZoneManager/dZoneManager.cpp index e5de1beb..12215378 100644 --- a/dZoneManager/dZoneManager.cpp +++ b/dZoneManager/dZoneManager.cpp @@ -16,7 +16,7 @@ dZoneManager* dZoneManager::m_Address = nullptr; void dZoneManager::Initialize(const LWOZONEID& zoneID) { Game::logger->Log("dZoneManager", "Preparing zone: %i/%i/%i\n", zoneID.GetMapID(), zoneID.GetInstanceID(), zoneID.GetCloneID()); - + int64_t startTime = 0; int64_t endTime = 0; @@ -52,7 +52,7 @@ void dZoneManager::Initialize(const LWOZONEID& zoneID) { m_pZone->Initalize(); endTime = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); - + Game::logger->Log("dZoneManager", "Zone prepared in: %llu ms\n", (endTime - startTime)); VanityUtilities::SpawnVanity(); @@ -60,13 +60,13 @@ void dZoneManager::Initialize(const LWOZONEID& zoneID) { dZoneManager::~dZoneManager() { if (m_pZone) delete m_pZone; - + for (std::pair p : m_Spawners) { if (p.second) { delete p.second; p.second = nullptr; } - + m_Spawners.erase(p.first); } } @@ -146,7 +146,7 @@ void dZoneManager::Update(float deltaTime) { LWOOBJID dZoneManager::MakeSpawner(SpawnerInfo info) { auto objectId = info.spawnerID; - + if (objectId == LWOOBJID_EMPTY) { objectId = ObjectIDManager::Instance()->GenerateObjectID(); @@ -155,18 +155,18 @@ LWOOBJID dZoneManager::MakeSpawner(SpawnerInfo info) info.spawnerID = objectId; } - + auto* spawner = new Spawner(info); EntityInfo entityInfo{}; entityInfo.id = objectId; entityInfo.lot = 176; - + auto* entity = EntityManager::Instance()->CreateEntity(entityInfo, nullptr, nullptr, false, objectId); EntityManager::Instance()->ConstructEntity(entity); - + AddSpawner(objectId, spawner); return objectId; @@ -219,9 +219,9 @@ void dZoneManager::RemoveSpawner(const LWOOBJID id) spawner->Deactivate(); Game::logger->Log("dZoneManager", "Destroying spawner (%llu)\n", id); - + m_Spawners.erase(id); - + delete spawner; }