diff --git a/dDatabase/GameDatabase/GameDatabase.h b/dDatabase/GameDatabase/GameDatabase.h index f52c8c4e2..dcfac4a23 100644 --- a/dDatabase/GameDatabase/GameDatabase.h +++ b/dDatabase/GameDatabase/GameDatabase.h @@ -24,6 +24,7 @@ #include "IIgnoreList.h" #include "IAccountsRewardCodes.h" #include "IBehaviors.h" +#include "IUgcModularBuild.h" namespace sql { class Statement; @@ -42,7 +43,7 @@ class GameDatabase : public IPropertyContents, public IProperty, public IPetNames, public ICharXml, public IMigrationHistory, public IUgc, public IFriends, public ICharInfo, public IAccounts, public IActivityLog, public IAccountsRewardCodes, public IIgnoreList, - public IBehaviors { + public IBehaviors, public IUgcModularBuild { public: virtual ~GameDatabase() = default; // TODO: These should be made private. diff --git a/dDatabase/GameDatabase/ITables/IUgcModularBuild.h b/dDatabase/GameDatabase/ITables/IUgcModularBuild.h new file mode 100644 index 000000000..4aa2e312b --- /dev/null +++ b/dDatabase/GameDatabase/ITables/IUgcModularBuild.h @@ -0,0 +1,14 @@ +#ifndef IUGCMODULARBUILD_H +#define IUGCMODULARBUILD_H + +#include +#include +#include + +class IUgcModularBuild { +public: + virtual void InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional characterId) = 0; + virtual void DeleteUgcBuild(const LWOOBJID bigId) = 0; +}; + +#endif //!IUGCMODULARBUILD_H diff --git a/dDatabase/GameDatabase/MySQL/MySQLDatabase.h b/dDatabase/GameDatabase/MySQL/MySQLDatabase.h index f30e33cee..4d11622da 100644 --- a/dDatabase/GameDatabase/MySQL/MySQLDatabase.h +++ b/dDatabase/GameDatabase/MySQL/MySQLDatabase.h @@ -7,6 +7,7 @@ #include "GameDatabase.h" typedef std::unique_ptr& UniquePreppedStmtRef; +typedef std::unique_ptr UniqueResultSet; // Purposefully no definition for this to provide linker errors in the case someone tries to // bind a parameter to a type that isn't defined. @@ -113,6 +114,8 @@ class MySQLDatabase : public GameDatabase { void RemoveBehavior(const int32_t characterId) override; void UpdateAccountGmLevel(const uint32_t accountId, const eGameMasterLevel gmLevel) override; std::optional GetProperties(const IProperty::PropertyLookup& params) override; + void InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional characterId) override; + void DeleteUgcBuild(const LWOOBJID bigId) override; private: // Generic query functions that can be used for any query. diff --git a/dDatabase/GameDatabase/MySQL/Tables/CMakeLists.txt b/dDatabase/GameDatabase/MySQL/Tables/CMakeLists.txt index 47cd220ea..2f1fa6de7 100644 --- a/dDatabase/GameDatabase/MySQL/Tables/CMakeLists.txt +++ b/dDatabase/GameDatabase/MySQL/Tables/CMakeLists.txt @@ -20,6 +20,7 @@ set(DDATABASES_DATABASES_MYSQL_TABLES_SOURCES "PropertyContents.cpp" "Servers.cpp" "Ugc.cpp" + "UgcModularBuild.cpp" PARENT_SCOPE ) diff --git a/dDatabase/GameDatabase/MySQL/Tables/UgcModularBuild.cpp b/dDatabase/GameDatabase/MySQL/Tables/UgcModularBuild.cpp new file mode 100644 index 000000000..a95735157 --- /dev/null +++ b/dDatabase/GameDatabase/MySQL/Tables/UgcModularBuild.cpp @@ -0,0 +1,9 @@ +#include "MySQLDatabase.h" + +void MySQLDatabase::InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional characterId) { + ExecuteInsert("INSERT INTO ugc_modular_build (ugc_id, ldf_config, character_id) VALUES (?,?,?)", bigId, modules, characterId); +} + +void MySQLDatabase::DeleteUgcBuild(const LWOOBJID bigId) { + ExecuteDelete("DELETE FROM ugc_modular_build WHERE ugc_id = ?;", bigId); +} diff --git a/dDatabase/GameDatabase/TestSQL/TestSQLDatabase.h b/dDatabase/GameDatabase/TestSQL/TestSQLDatabase.h index 1fbb18451..2135f05ad 100644 --- a/dDatabase/GameDatabase/TestSQL/TestSQLDatabase.h +++ b/dDatabase/GameDatabase/TestSQL/TestSQLDatabase.h @@ -91,6 +91,8 @@ class TestSQLDatabase : public GameDatabase { void RemoveBehavior(const int32_t behaviorId) override; void UpdateAccountGmLevel(const uint32_t accountId, const eGameMasterLevel gmLevel) override; std::optional GetProperties(const IProperty::PropertyLookup& params) override { return {}; }; + void InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional characterId) override {}; + void DeleteUgcBuild(const LWOOBJID bigId) override {}; }; #endif //!TESTSQLDATABASE_H diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index fc77e6904..be034e466 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -5066,9 +5066,7 @@ void GameMessages::HandleModularBuildConvertModel(RakNet::BitStream& inStream, E item->Disassemble(TEMP_MODELS); - std::unique_ptr stmt(Database::Get()->CreatePreppedStmt("DELETE FROM ugc_modular_build where ugc_id = ?")); - stmt->setUInt64(1, item->GetSubKey()); - stmt->execute(); + Database::Get()->DeleteUgcBuild(item->GetSubKey()); item->SetCount(item->GetCount() - 1, false, false, true, eLootSourceType::QUICKBUILD); } @@ -5394,6 +5392,8 @@ void GameMessages::HandleRemoveItemFromInventory(RakNet::BitStream& inStream, En const auto itemType = static_cast(item->GetInfo().itemType); if (itemType == eItemType::MODEL || itemType == eItemType::LOOT_MODEL) { item->DisassembleModel(iStackCount); + } else if (itemType == eItemType::VEHICLE) { + Database::Get()->DeleteUgcBuild(item->GetSubKey()); } auto lot = item->GetLot(); item->SetCount(item->GetCount() - iStackCount, true); @@ -5569,12 +5569,8 @@ void GameMessages::HandleModularBuildFinish(RakNet::BitStream& inStream, Entity* inv->AddItem(8092, 1, eLootSourceType::QUICKBUILD, eInventoryType::MODELS, config, LWOOBJID_EMPTY, true, false, newIdBig); } - std::unique_ptr stmt(Database::Get()->CreatePreppedStmt("INSERT INTO ugc_modular_build (ugc_id, ldf_config, character_id) VALUES (?,?,?)")); - stmt->setUInt64(1, newIdBig); - stmt->setString(2, GeneralUtils::UTF16ToWTF8(modules).c_str()); auto* pCharacter = character->GetCharacter(); - pCharacter ? stmt->setUInt(3, pCharacter->GetID()) : stmt->setNull(3, sql::DataType::BIGINT); - stmt->execute(); + Database::Get()->InsertUgcBuild(GeneralUtils::UTF16ToWTF8(modules), newIdBig, pCharacter ? std::optional(character->GetCharacter()->GetID()) : std::nullopt); auto* missionComponent = character->GetComponent();