From 4c2f9a44235c30be6ed285093311686a0545cb6b Mon Sep 17 00:00:00 2001 From: Chris Miles Date: Tue, 18 Jul 2023 17:18:36 -0500 Subject: [PATCH] [Databuckets] Fix issue with expired databuckets not being expired and returned properly (#3504) --- zone/data_bucket.cpp | 64 +++++++++++++++----------------------------- zone/data_bucket.h | 2 +- zone/exp.cpp | 8 +++--- zone/mob.cpp | 6 ++--- zone/spells.cpp | 12 ++++----- 5 files changed, 35 insertions(+), 57 deletions(-) diff --git a/zone/data_bucket.cpp b/zone/data_bucket.cpp index b00695fc6..a2951e9df 100644 --- a/zone/data_bucket.cpp +++ b/zone/data_bucket.cpp @@ -21,20 +21,11 @@ void DataBucket::SetData(const std::string &bucket_key, const std::string &bucke void DataBucket::SetData(const DataBucketKey &k) { - auto r = DataBucketsRepository::GetWhere( - database, - fmt::format( - "{} `key` = '{}' AND (`expires` > {} OR `expires` = 0) LIMIT 1", - DataBucket::GetScopedDbFilters(k), - Strings::Escape(k.key), - (long long) std::time(nullptr) - ) - ); - - // if we have an entry, use it auto b = DataBucketsRepository::NewEntity(); - if (!r.empty()) { - b = r[0]; + auto r = GetData(k); + // if we have an entry, use it + if (r.id > 0) { + b = r; } if (k.character_id > 0) { @@ -72,18 +63,17 @@ std::string DataBucket::GetData(const std::string &bucket_key) { DataBucketKey k = {}; k.key = bucket_key; - return GetData(k); + return GetData(k).value; } -std::string DataBucket::GetData(const DataBucketKey &k) +DataBucketsRepository::DataBuckets DataBucket::GetData(const DataBucketKey &k) { auto r = DataBucketsRepository::GetWhere( database, fmt::format( - "{} `key` = '{}' AND (`expires` > {} OR `expires` = 0) LIMIT 1", + "{} `key` = '{}' LIMIT 1", DataBucket::GetScopedDbFilters(k), - k.key, - (long long) std::time(nullptr) + k.key ) ); @@ -91,7 +81,13 @@ std::string DataBucket::GetData(const DataBucketKey &k) return {}; } - return r[0].value; + // if the entry has expired, delete it + if (r[0].expires > 0 && r[0].expires < (long long) std::time(nullptr)) { + DeleteData(k); + return {}; + } + + return r[0]; } std::string DataBucket::GetDataExpires(const std::string &bucket_key) @@ -174,40 +170,22 @@ bool DataBucket::DeleteData(const DataBucketKey &k) std::string DataBucket::GetDataExpires(const DataBucketKey &k) { - auto r = DataBucketsRepository::GetWhere( - database, - fmt::format( - "{} `key` = '{}' AND (`expires` > {} OR `expires` = 0) LIMIT 1", - DataBucket::GetScopedDbFilters(k), - k.key, - (long long) std::time(nullptr) - ) - ); - - if (r.empty()) { + auto r = GetData(k); + if (r.id == 0) { return {}; } - return fmt::format("{}", r[0].expires); + return fmt::format("{}", r.expires); } std::string DataBucket::GetDataRemaining(const DataBucketKey &k) { - auto r = DataBucketsRepository::GetWhere( - database, - fmt::format( - "{} `key` = '{}' AND (`expires` > {} OR `expires` = 0) LIMIT 1", - DataBucket::GetScopedDbFilters(k), - k.key, - (long long) std::time(nullptr) - ) - ); - - if (r.empty()) { + auto r = GetData(k); + if (r.id == 0) { return "0"; } - return fmt::format("{}", r[0].expires - (long long) std::time(nullptr)); + return fmt::format("{}", r.expires - (long long) std::time(nullptr)); } std::string DataBucket::GetScopedDbFilters(const DataBucketKey &k) diff --git a/zone/data_bucket.h b/zone/data_bucket.h index 7b4d1d5c2..e966c2b9d 100644 --- a/zone/data_bucket.h +++ b/zone/data_bucket.h @@ -34,7 +34,7 @@ public: // scoped bucket methods static void SetData(const DataBucketKey& k); static bool DeleteData(const DataBucketKey& k); - static std::string GetData(const DataBucketKey& k); + static DataBucketsRepository::DataBuckets GetData(const DataBucketKey& k); static std::string GetDataExpires(const DataBucketKey& k); static std::string GetDataRemaining(const DataBucketKey& k); static std::string CheckBucketKey(const Mob* mob, const DataBucketKey& k); diff --git a/zone/exp.cpp b/zone/exp.cpp index 9bcf879b2..65a93e8c1 100644 --- a/zone/exp.cpp +++ b/zone/exp.cpp @@ -1276,10 +1276,10 @@ uint8 Client::GetCharMaxLevelFromBucket() DataBucketKey k = GetScopedBucketKeys(); k.key = "CharMaxLevel"; - auto bucket_value = DataBucket::GetData(k); - if (!bucket_value.empty()) { - if (Strings::IsNumber(bucket_value)) { - return static_cast(Strings::ToUnsignedInt(bucket_value)); + auto b = DataBucket::GetData(k); + if (!b.value.empty()) { + if (Strings::IsNumber(b.value)) { + return static_cast(Strings::ToUnsignedInt(b.value)); } } diff --git a/zone/mob.cpp b/zone/mob.cpp index 93dda587f..7ffaad109 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -8062,9 +8062,9 @@ std::string Mob::GetBucket(std::string bucket_name) DataBucketKey k = GetScopedBucketKeys(); k.key = bucket_name; - std::string bucket_value = DataBucket::GetData(k); - if (!bucket_value.empty()) { - return bucket_value; + auto b = DataBucket::GetData(k); + if (!b.value.empty()) { + return b.value; } return {}; } diff --git a/zone/spells.cpp b/zone/spells.cpp index fcd1d674c..e58c08ab1 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -5880,14 +5880,14 @@ bool Client::SpellBucketCheck(uint16 spell_id, uint32 character_id) { DataBucketKey k = GetScopedBucketKeys(); k.key = spell_bucket_name; - auto bucket_value = DataBucket::GetData(k); - if (!bucket_value.empty()) { - if (Strings::IsNumber(bucket_value) && Strings::IsNumber(spell_bucket_value)) { - if (Strings::ToInt(bucket_value) >= Strings::ToInt(spell_bucket_value)) { + auto b = DataBucket::GetData(k); + if (!b.value.empty()) { + if (Strings::IsNumber(b.value) && Strings::IsNumber(spell_bucket_value)) { + if (Strings::ToInt(b.value) >= Strings::ToInt(spell_bucket_value)) { return true; // If value is greater than or equal to spell bucket value, allow scribing. } } else { - if (bucket_value == spell_bucket_value) { + if (b.value == spell_bucket_value) { return true; // If value is equal to spell bucket value, allow scribing. } } @@ -5899,7 +5899,7 @@ bool Client::SpellBucketCheck(uint16 spell_id, uint32 character_id) { spell_bucket_name ); - bucket_value = DataBucket::GetData(old_bucket_name); + auto bucket_value = DataBucket::GetData(old_bucket_name); if (!bucket_value.empty()) { if (Strings::IsNumber(bucket_value) && Strings::IsNumber(spell_bucket_value)) { if (Strings::ToInt(bucket_value) >= Strings::ToInt(spell_bucket_value)) {