diff --git a/dCommon/dEnums/eCSRCommand.h b/dCommon/dEnums/eCSRCommand.h new file mode 100644 index 000000000..107d82bb1 --- /dev/null +++ b/dCommon/dEnums/eCSRCommand.h @@ -0,0 +1,55 @@ +#ifndef __ECSRCOMMAND__H__ +#define __ECSRCOMMAND__H__ + +#include + +enum class eCSRCommand : uint32_t { + QUERY_SERVER_STATUS = 0, + QUERY_CHARACTER_LOCATION, + QUERY_CHARACTER_ONLINE_STATUS, + INVENTORY_ADD_ITEM, + INVENTORY_DELETE_ITEM, + MODERATE_MUTE_ACCOUNT, + MODERATE_BAN_ACCOUNT, + MODERATE_EDUCATE_CHARACTER, + MODERATE_KICK_CHARACTER, + MODERATE_WARN_CHARACTER, + MODERATE_RENAME_CHARACTER, + MODERATE_DELETE_CHARACTER_FRIEND, + MODERATE_KILL_CHARACTER, + UPDATE_CHARACTER_HEALTH, + UPDATE_CHARACTER_ARMOR, + UPDATE_CHARACTER_IMAGINATION, + UPDATE_CHARACTER_MAX_HEALTH, + UPDATE_CHARACTER_MAX_ARMOR, + UPDATE_CHARACTER_MAX_IMAGINATION, + UPDATE_CHARACTER_CURRENCY, + UPDATE_CHARACTER_REPUTATION, + UPDATE_CHARACTER_LEGO_SCORE, + UPDATE_CHARACTER_EMOTES, + UPDATE_CHARACTER_ADD_ACHIEVEMENT, + UPDATE_CHARACTER_COMPLETE_ACHIEVEMENT, + UPDATE_CHARACTER_REMOVE_ACHIEVEMENT, + UPDATE_CHARACTER_POSITION_OFFLINE, + UPDATE_CHARACTER_INV_SLOT_AMOUNT, + UTILITY_SAVE_CHARACTER, + UTILITY_SEND_MAIL, + UTILITY_GIVE_ITEM_TO_ALL_PLAYERS_ONLINE, + METRICS_CONFIGURE, + DISABLE_ZONE, + INIT_DONATION_AMOUNT, + KILL_SERVERS_COUNTDOWN, + DISABLE_FAQ, + THROTTLEQUEUE, + GATEGM_ACCESS, + RECONNECT_CRISP, + MODERATE_KICK_ACCOUNT, + TOGGLE_CRISP_SERVER, + QUICK_DRAIN_SERVER, + QUICK_DRAIN_SERVER_RENEW, + REPLICATE_CHARACTER, + GET_SERVER_STATUS, + RELOAD_SERVER_INIS +}; + +#endif //!__ECSRCOMMAND__H__ diff --git a/dCommon/dEnums/eDeletionRestrictionsCheckType.h b/dCommon/dEnums/eDeletionRestrictionsCheckType.h new file mode 100644 index 000000000..af4f18ea6 --- /dev/null +++ b/dCommon/dEnums/eDeletionRestrictionsCheckType.h @@ -0,0 +1,16 @@ +#ifndef __EDELETIONRESTRICTIONSCHECKTYPE__H__ +#define __EDELETIONRESTRICTIONSCHECKTYPE__H__ + +#include + +enum class eDeletionRestrictionsCheckType : uint32_t { + INCLUDE_LOTS, + EXCLUDE_LOTS, + ANY_OF_THESE, + ALL_OF_THESE, + WHILE_IN_ZONE, + ALWAYS_RESTRICTED, + MAX +}; + +#endif //!__EDELETIONRESTRICTIONSCHECKTYPE__H__ diff --git a/dDatabase/CDClientDatabase/CDClientManager.cpp b/dDatabase/CDClientDatabase/CDClientManager.cpp index 6ecfb0ad0..e1802d267 100644 --- a/dDatabase/CDClientDatabase/CDClientManager.cpp +++ b/dDatabase/CDClientDatabase/CDClientManager.cpp @@ -41,6 +41,7 @@ #include "CDRailActivatorComponent.h" #include "CDRewardCodesTable.h" #include "CDPetComponentTable.h" +#include "CDDeletionRestrictionsTable.h" #ifndef CDCLIENT_CACHE_ALL // Uncomment this to cache the full cdclient database into memory. This will make the server load faster, but will use more memory. @@ -103,6 +104,7 @@ DEFINE_TABLE_STORAGE(CDSkillBehaviorTable); DEFINE_TABLE_STORAGE(CDTamingBuildPuzzleTable); DEFINE_TABLE_STORAGE(CDVendorComponentTable); DEFINE_TABLE_STORAGE(CDZoneTableTable); +DEFINE_TABLE_STORAGE(CDDeletionRestrictionsTable) void CDClientManager::LoadValuesFromDatabase() { if (!CDClientDatabase::isConnected) { @@ -150,6 +152,7 @@ void CDClientManager::LoadValuesFromDatabase() { CDTamingBuildPuzzleTable::Instance().LoadValuesFromDatabase(); CDVendorComponentTable::Instance().LoadValuesFromDatabase(); CDZoneTableTable::Instance().LoadValuesFromDatabase(); + CDDeletionRestrictionsTable::Instance().LoadValuesFromDatabase(); } void CDClientManager::LoadValuesFromDefaults() { diff --git a/dDatabase/CDClientDatabase/CDClientTables/CDDeletionRestrictionsTable.cpp b/dDatabase/CDClientDatabase/CDClientTables/CDDeletionRestrictionsTable.cpp new file mode 100644 index 000000000..4cef80415 --- /dev/null +++ b/dDatabase/CDClientDatabase/CDClientTables/CDDeletionRestrictionsTable.cpp @@ -0,0 +1,45 @@ +#include "CDDeletionRestrictionsTable.h" +#include "GeneralUtils.h" +#include "eDeletionRestrictionsCheckType.h" + +CDDeletionRestriction CDDeletionRestrictionsTable::Default = { + .id = 0, + .restricted = false, + .ids = {}, + .checkType = eDeletionRestrictionsCheckType::MAX +}; + +void CDDeletionRestrictionsTable::LoadValuesFromDatabase() { + auto& entries = GetEntriesMutable(); + + auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM DeletionRestrictions"); + while (!tableData.eof()) { + CDDeletionRestriction entry; + entry.id = tableData.getIntField("id", -1); + if (entry.id == -1) continue; + entry.restricted = tableData.getIntField("restricted", -1); + const std::string raw_ids = tableData.getStringField("ids", ""); + if (!raw_ids.empty()) { + for (const auto& idstr : GeneralUtils::SplitString(raw_ids, ',')) { + if (!idstr.empty()) { + const auto id = GeneralUtils::TryParse(idstr); + if (id) entry.ids.push_back(id.value()); + } + } + } + entry.checkType = static_cast(tableData.getIntField("checkType", static_cast(eDeletionRestrictionsCheckType::MAX))); + + entries.insert(std::make_pair(entry.id, entry)); + tableData.nextRow(); + } + +} + +const CDDeletionRestriction& CDDeletionRestrictionsTable::GetByID(uint32_t id) { + auto& entries = GetEntries(); + const auto& it = entries.find(id); + if (it != entries.end()) { + return it->second; + } + return Default; +} diff --git a/dDatabase/CDClientDatabase/CDClientTables/CDDeletionRestrictionsTable.h b/dDatabase/CDClientDatabase/CDClientTables/CDDeletionRestrictionsTable.h new file mode 100644 index 000000000..a09ee60da --- /dev/null +++ b/dDatabase/CDClientDatabase/CDClientTables/CDDeletionRestrictionsTable.h @@ -0,0 +1,20 @@ +#pragma once + +#include "CDTable.h" + +enum class eDeletionRestrictionsCheckType : uint32_t; + +struct CDDeletionRestriction { + uint32_t id; + bool restricted; + std::vector ids; + eDeletionRestrictionsCheckType checkType; +}; + +class CDDeletionRestrictionsTable : public CDTable> { +public: + void LoadValuesFromDatabase(); + const CDDeletionRestriction& GetByID(uint32_t id); + + static CDDeletionRestriction Default; +}; diff --git a/dDatabase/CDClientDatabase/CDClientTables/CDItemComponentTable.h b/dDatabase/CDClientDatabase/CDClientTables/CDItemComponentTable.h index 60a3e4129..58bee024a 100644 --- a/dDatabase/CDClientDatabase/CDClientTables/CDItemComponentTable.h +++ b/dDatabase/CDClientDatabase/CDClientTables/CDItemComponentTable.h @@ -33,7 +33,7 @@ struct CDItemComponent { uint32_t itemRating; //!< ??? bool isTwoHanded; //!< Whether or not the item is double handed uint32_t minNumRequired; //!< Maybe the minimum number required for a mission, or to own this object? - uint32_t delResIndex; //!< ??? + uint32_t delResIndex; //!< Relates to DeletionRestrictions Table uint32_t currencyLOT; //!< ??? uint32_t altCurrencyCost; //!< ??? std::string subItems; //!< A comma seperate string of sub items (maybe for multi-itemed things like faction test gear set) diff --git a/dDatabase/CDClientDatabase/CDClientTables/CMakeLists.txt b/dDatabase/CDClientDatabase/CDClientTables/CMakeLists.txt index f45516463..300c54b61 100644 --- a/dDatabase/CDClientDatabase/CDClientTables/CMakeLists.txt +++ b/dDatabase/CDClientDatabase/CDClientTables/CMakeLists.txt @@ -38,4 +38,6 @@ set(DDATABASE_CDCLIENTDATABASE_CDCLIENTTABLES_SOURCES "CDActivitiesTable.cpp" "CDSkillBehaviorTable.cpp" "CDTamingBuildPuzzleTable.cpp" "CDVendorComponentTable.cpp" - "CDZoneTableTable.cpp" PARENT_SCOPE) + "CDZoneTableTable.cpp" + "CDDeletionRestrictionsTable.cpp" +PARENT_SCOPE) diff --git a/dGame/dInventory/Item.cpp b/dGame/dInventory/Item.cpp index 326037614..9ef816637 100644 --- a/dGame/dInventory/Item.cpp +++ b/dGame/dInventory/Item.cpp @@ -21,11 +21,13 @@ #include "eUseItemResponse.h" #include "dZoneManager.h" #include "ChatPackets.h" +#include "eDeletionRestrictionsCheckType.h" #include "CDBrickIDTableTable.h" #include "CDObjectSkillsTable.h" #include "CDComponentsRegistryTable.h" #include "CDPackageComponentTable.h" +#include "CDDeletionRestrictionsTable.h" namespace { const std::map ExtraSettingAbbreviations = { @@ -568,3 +570,43 @@ void Item::LoadConfigXml(const tinyxml2::XMLElement& i) { config.push_back(LDFBaseData::DataFromString(value)); } } + +bool Item::CanDeleteItem(Item* item) { + if (!item) return false; + // TODO: + // Check if item is being possessed + // Check if the owner is mounting item? (how is this different than the above) + // Allow GM 9 to freely delete + // Finally, check Deletion Restriction + const auto& itemComponent = item->inventory->FindItemComponent(item->lot); + if (itemComponent.delResIndex == -1) return true; + return CheckDeletionRestriction(itemComponent.delResIndex, item->lot); +} + +bool Item::CheckDeletionRestriction(uint32_t delResIndex, LOT item) { + auto* delresTable = CDClientManager::GetTable(); + const auto restriction = delresTable->GetByID(delResIndex); + + switch(restriction.checkType) { + case eDeletionRestrictionsCheckType::INCLUDE_LOTS: + if (std::ranges::find(restriction.ids, item) != restriction.ids.end()) return false; + else return true; + case eDeletionRestrictionsCheckType::EXCLUDE_LOTS: + if (std::ranges::find(restriction.ids, item) != restriction.ids.end()) return true; + else return false; + case eDeletionRestrictionsCheckType::ANY_OF_THESE: + // TODO: Implement + return true; + case eDeletionRestrictionsCheckType::ALL_OF_THESE: + // TODO: Implement + return true; + case eDeletionRestrictionsCheckType::WHILE_IN_ZONE: + if (std::ranges::find(restriction.ids, Game::zoneManager->GetZoneID().GetMapID()) != restriction.ids.end()) return false; + else return true; + case eDeletionRestrictionsCheckType::ALWAYS_RESTRICTED: + return false; + case eDeletionRestrictionsCheckType::MAX: + default: + return true; + } +} diff --git a/dGame/dInventory/Item.h b/dGame/dInventory/Item.h index 72ff264c7..b5e4e9f2e 100644 --- a/dGame/dInventory/Item.h +++ b/dGame/dInventory/Item.h @@ -228,6 +228,13 @@ class Item final void LoadConfigXml(const tinyxml2::XMLElement& i); + bool CanDeleteItem(Item* item); + + bool CheckDeletionRestriction(uint32_t delResIndex, LOT item); + + bool CheckDeletionRestrictionRecursion(std::set& delResIndexs, uint32_t delResIndex); + + private: /** * The object ID of this item