mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-11-06 11:57:13 +00:00
feat: deletion restrictions
Deleting an item now follows the item's DeletionRestrictions row (ItemComponent.delResIndex), as the client's LWOInventoryComponent_Common::CanRemoveFromInventory (0x00ce0d20) and CheckDeletionRestrictionIndex (0x00c94c20) do: an item the player is driving or riding can't be deleted, an operator can delete anything, and otherwise the row decides: - LOTS_INCLUDED: only while the player has another item of any of the LOTs (the last rocket can't be deleted) - LOTS_EXCLUDED: only while the player has other items of all of the LOTs - ANY_RESTRICTION / ALL_RESTRICTIONS: any / all of the listed rows allow it (a row that names itself again allows it) - ZONE: only in the listed zones - ALWAYS_RESTRICTED: never A missing, unrestricted or bad row (no valid ids, unknown check type) allows it. The client checks first and shows the row's failure reason; the server checks again and ignores a client's forceDeletion. Refs issue 960 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -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.
|
||||
@@ -102,6 +103,7 @@ DEFINE_TABLE_STORAGE(CDScriptComponentTable);
|
||||
DEFINE_TABLE_STORAGE(CDSkillBehaviorTable);
|
||||
DEFINE_TABLE_STORAGE(CDTamingBuildPuzzleTable);
|
||||
DEFINE_TABLE_STORAGE(CDVendorComponentTable);
|
||||
DEFINE_TABLE_STORAGE(CDDeletionRestrictionsTable);
|
||||
|
||||
void CDClientManager::LoadValuesFromDatabase() {
|
||||
if (!CDClientDatabase::isConnected) {
|
||||
@@ -149,6 +151,7 @@ void CDClientManager::LoadValuesFromDatabase() {
|
||||
CDTamingBuildPuzzleTable::Instance().LoadValuesFromDatabase();
|
||||
CDVendorComponentTable::Instance().LoadValuesFromDatabase();
|
||||
CDZoneTableTable::LoadValuesFromDatabase();
|
||||
CDDeletionRestrictionsTable::Instance().LoadValuesFromDatabase();
|
||||
}
|
||||
|
||||
void CDClientManager::LoadValuesFromDefaults() {
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#include "CDDeletionRestrictionsTable.h"
|
||||
#include "GeneralUtils.h"
|
||||
#include "eDeletionRestrictionsCheckType.h"
|
||||
|
||||
void CDDeletionRestrictionsTable::LoadValuesFromDatabase() {
|
||||
auto& entries = GetEntriesMutable();
|
||||
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM DeletionRestrictions");
|
||||
while (!tableData.eof()) {
|
||||
CDDeletionRestriction entry;
|
||||
entry.id = tableData.getIntField("id", 0);
|
||||
entry.restricted = tableData.getIntField("restricted", 0) != 0;
|
||||
for (auto id : GeneralUtils::SplitString(tableData.getStringField("ids", ""), ',')) {
|
||||
// The ids are written with spaces around them
|
||||
id.erase(0, id.find_first_not_of(" \t"));
|
||||
id.erase(id.find_last_not_of(" \t") + 1);
|
||||
const auto parsed = GeneralUtils::TryParse<uint32_t>(id);
|
||||
if (parsed) entry.ids.push_back(*parsed);
|
||||
}
|
||||
entry.checkType = static_cast<eDeletionRestrictionsCheckType>(tableData.getIntField("checkType", static_cast<int>(eDeletionRestrictionsCheckType::MAX)));
|
||||
|
||||
entries.insert_or_assign(entry.id, entry);
|
||||
tableData.nextRow();
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<CDDeletionRestriction> CDDeletionRestrictionsTable::GetByID(const uint32_t id) const {
|
||||
const auto& entries = GetEntries();
|
||||
const auto it = entries.find(id);
|
||||
if (it == entries.end()) return std::nullopt;
|
||||
return it->second;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "CDTable.h"
|
||||
|
||||
#include <optional>
|
||||
|
||||
enum class eDeletionRestrictionsCheckType : uint32_t;
|
||||
|
||||
struct CDDeletionRestriction {
|
||||
uint32_t id{};
|
||||
bool restricted{};
|
||||
// LOTs, zone ids or other rows of this table, depending on checkType; ids that aren't numbers are left out
|
||||
std::vector<uint32_t> ids;
|
||||
eDeletionRestrictionsCheckType checkType{};
|
||||
};
|
||||
|
||||
class CDDeletionRestrictionsTable : public CDTable<CDDeletionRestrictionsTable, std::map<uint32_t, CDDeletionRestriction>> {
|
||||
public:
|
||||
void LoadValuesFromDatabase();
|
||||
std::optional<CDDeletionRestriction> GetByID(uint32_t id) const;
|
||||
};
|
||||
@@ -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)
|
||||
|
||||
@@ -39,4 +39,5 @@ set(DDATABASE_CDCLIENTDATABASE_CDCLIENTTABLES_SOURCES "CDActivitiesTable.cpp"
|
||||
"CDSkillBehaviorTable.cpp"
|
||||
"CDTamingBuildPuzzleTable.cpp"
|
||||
"CDVendorComponentTable.cpp"
|
||||
"CDZoneTableTable.cpp" PARENT_SCOPE)
|
||||
"CDZoneTableTable.cpp"
|
||||
"CDDeletionRestrictionsTable.cpp" PARENT_SCOPE)
|
||||
|
||||
Reference in New Issue
Block a user