[Feature] Extend Spell Buckets Functionality (#4441)

This commit is contained in:
Alex King 2024-08-22 18:49:52 -04:00 committed by GitHub
parent e3588781aa
commit b7f8d0f179
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 79 additions and 95 deletions

View File

@ -5717,6 +5717,22 @@ CREATE TABLE `buyer_trade_items` (
COLLATE='latin1_swedish_ci' COLLATE='latin1_swedish_ci'
ENGINE=InnoDB ENGINE=InnoDB
AUTO_INCREMENT=1; AUTO_INCREMENT=1;
)"
},
ManifestEntry{
.version = 9282,
.description = "2024_08_02_spell_buckets_comparison.sql",
.check = "SHOW COLUMNS FROM `spell_buckets` LIKE 'bucket_comparison'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `spell_buckets`
CHANGE COLUMN `spellid` `spell_id` int UNSIGNED NOT NULL FIRST,
CHANGE COLUMN `key` `bucket_name` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT '' AFTER `spell_id`,
CHANGE COLUMN `value` `bucket_value` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT '' AFTER `bucket_name`,
ADD COLUMN `bucket_comparison` tinyint UNSIGNED NOT NULL DEFAULT 0 AFTER `bucket_value`,
DROP PRIMARY KEY,
ADD PRIMARY KEY (`spell_id`) USING BTREE;
)" )"
} }
// -- template; copy/paste this when you need to create a new entry // -- template; copy/paste this when you need to create a new entry

View File

@ -19,31 +19,34 @@
class BaseSpellBucketsRepository { class BaseSpellBucketsRepository {
public: public:
struct SpellBuckets { struct SpellBuckets {
uint64_t spellid; uint32_t spell_id;
std::string key_; std::string bucket_name;
std::string value; std::string bucket_value;
uint8_t bucket_comparison;
}; };
static std::string PrimaryKey() static std::string PrimaryKey()
{ {
return std::string("spellid"); return std::string("spell_id");
} }
static std::vector<std::string> Columns() static std::vector<std::string> Columns()
{ {
return { return {
"spellid", "spell_id",
"`key`", "bucket_name",
"value", "bucket_value",
"bucket_comparison",
}; };
} }
static std::vector<std::string> SelectColumns() static std::vector<std::string> SelectColumns()
{ {
return { return {
"spellid", "spell_id",
"`key`", "bucket_name",
"value", "bucket_value",
"bucket_comparison",
}; };
} }
@ -84,9 +87,10 @@ public:
{ {
SpellBuckets e{}; SpellBuckets e{};
e.spellid = 0; e.spell_id = 0;
e.key_ = ""; e.bucket_name = "";
e.value = ""; e.bucket_value = "";
e.bucket_comparison = 0;
return e; return e;
} }
@ -97,7 +101,7 @@ public:
) )
{ {
for (auto &spell_buckets : spell_bucketss) { for (auto &spell_buckets : spell_bucketss) {
if (spell_buckets.spellid == spell_buckets_id) { if (spell_buckets.spell_id == spell_buckets_id) {
return spell_buckets; return spell_buckets;
} }
} }
@ -123,9 +127,10 @@ public:
if (results.RowCount() == 1) { if (results.RowCount() == 1) {
SpellBuckets e{}; SpellBuckets e{};
e.spellid = row[0] ? strtoull(row[0], nullptr, 10) : 0; e.spell_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.key_ = row[1] ? row[1] : ""; e.bucket_name = row[1] ? row[1] : "";
e.value = row[2] ? row[2] : ""; e.bucket_value = row[2] ? row[2] : "";
e.bucket_comparison = row[3] ? static_cast<uint8_t>(strtoul(row[3], nullptr, 10)) : 0;
return e; return e;
} }
@ -159,9 +164,10 @@ public:
auto columns = Columns(); auto columns = Columns();
v.push_back(columns[0] + " = " + std::to_string(e.spellid)); v.push_back(columns[0] + " = " + std::to_string(e.spell_id));
v.push_back(columns[1] + " = '" + Strings::Escape(e.key_) + "'"); v.push_back(columns[1] + " = '" + Strings::Escape(e.bucket_name) + "'");
v.push_back(columns[2] + " = '" + Strings::Escape(e.value) + "'"); v.push_back(columns[2] + " = '" + Strings::Escape(e.bucket_value) + "'");
v.push_back(columns[3] + " = " + std::to_string(e.bucket_comparison));
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
@ -169,7 +175,7 @@ public:
TableName(), TableName(),
Strings::Implode(", ", v), Strings::Implode(", ", v),
PrimaryKey(), PrimaryKey(),
e.spellid e.spell_id
) )
); );
@ -183,9 +189,10 @@ public:
{ {
std::vector<std::string> v; std::vector<std::string> v;
v.push_back(std::to_string(e.spellid)); v.push_back(std::to_string(e.spell_id));
v.push_back("'" + Strings::Escape(e.key_) + "'"); v.push_back("'" + Strings::Escape(e.bucket_name) + "'");
v.push_back("'" + Strings::Escape(e.value) + "'"); v.push_back("'" + Strings::Escape(e.bucket_value) + "'");
v.push_back(std::to_string(e.bucket_comparison));
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
@ -196,7 +203,7 @@ public:
); );
if (results.Success()) { if (results.Success()) {
e.spellid = results.LastInsertedID(); e.spell_id = results.LastInsertedID();
return e; return e;
} }
@ -215,9 +222,10 @@ public:
for (auto &e: entries) { for (auto &e: entries) {
std::vector<std::string> v; std::vector<std::string> v;
v.push_back(std::to_string(e.spellid)); v.push_back(std::to_string(e.spell_id));
v.push_back("'" + Strings::Escape(e.key_) + "'"); v.push_back("'" + Strings::Escape(e.bucket_name) + "'");
v.push_back("'" + Strings::Escape(e.value) + "'"); v.push_back("'" + Strings::Escape(e.bucket_value) + "'");
v.push_back(std::to_string(e.bucket_comparison));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")"); insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
} }
@ -251,9 +259,10 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
SpellBuckets e{}; SpellBuckets e{};
e.spellid = row[0] ? strtoull(row[0], nullptr, 10) : 0; e.spell_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.key_ = row[1] ? row[1] : ""; e.bucket_name = row[1] ? row[1] : "";
e.value = row[2] ? row[2] : ""; e.bucket_value = row[2] ? row[2] : "";
e.bucket_comparison = row[3] ? static_cast<uint8_t>(strtoul(row[3], nullptr, 10)) : 0;
all_entries.push_back(e); all_entries.push_back(e);
} }
@ -278,9 +287,10 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) { for (auto row = results.begin(); row != results.end(); ++row) {
SpellBuckets e{}; SpellBuckets e{};
e.spellid = row[0] ? strtoull(row[0], nullptr, 10) : 0; e.spell_id = row[0] ? static_cast<uint32_t>(strtoul(row[0], nullptr, 10)) : 0;
e.key_ = row[1] ? row[1] : ""; e.bucket_name = row[1] ? row[1] : "";
e.value = row[2] ? row[2] : ""; e.bucket_value = row[2] ? row[2] : "";
e.bucket_comparison = row[3] ? static_cast<uint8_t>(strtoul(row[3], nullptr, 10)) : 0;
all_entries.push_back(e); all_entries.push_back(e);
} }
@ -355,9 +365,10 @@ public:
{ {
std::vector<std::string> v; std::vector<std::string> v;
v.push_back(std::to_string(e.spellid)); v.push_back(std::to_string(e.spell_id));
v.push_back("'" + Strings::Escape(e.key_) + "'"); v.push_back("'" + Strings::Escape(e.bucket_name) + "'");
v.push_back("'" + Strings::Escape(e.value) + "'"); v.push_back("'" + Strings::Escape(e.bucket_value) + "'");
v.push_back(std::to_string(e.bucket_comparison));
auto results = db.QueryDatabase( auto results = db.QueryDatabase(
fmt::format( fmt::format(
@ -380,9 +391,10 @@ public:
for (auto &e: entries) { for (auto &e: entries) {
std::vector<std::string> v; std::vector<std::string> v;
v.push_back(std::to_string(e.spellid)); v.push_back(std::to_string(e.spell_id));
v.push_back("'" + Strings::Escape(e.key_) + "'"); v.push_back("'" + Strings::Escape(e.bucket_name) + "'");
v.push_back("'" + Strings::Escape(e.value) + "'"); v.push_back("'" + Strings::Escape(e.bucket_value) + "'");
v.push_back(std::to_string(e.bucket_comparison));
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")"); insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
} }

View File

@ -42,7 +42,7 @@
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt * Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
*/ */
#define CURRENT_BINARY_DATABASE_VERSION 9281 #define CURRENT_BINARY_DATABASE_VERSION 9282
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9044 #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9044
#endif #endif

View File

@ -78,6 +78,7 @@ Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
#include "../common/misc_functions.h" #include "../common/misc_functions.h"
#include "../common/events/player_event_logs.h" #include "../common/events/player_event_logs.h"
#include "../common/repositories/character_corpses_repository.h" #include "../common/repositories/character_corpses_repository.h"
#include "../common/repositories/spell_buckets_repository.h"
#include "data_bucket.h" #include "data_bucket.h"
#include "quest_parser_collection.h" #include "quest_parser_collection.h"
@ -6239,65 +6240,20 @@ bool Client::SpellGlobalCheck(uint16 spell_id, uint32 character_id) {
return false; return false;
} }
bool Client::SpellBucketCheck(uint16 spell_id, uint32 character_id) { bool Client::SpellBucketCheck(uint16 spell_id, uint32 character_id)
auto query = fmt::format( {
"SELECT `key`, value FROM spell_buckets WHERE spellid = {}", const auto& e = SpellBucketsRepository::FindOne(database, spell_id);
spell_id if (!e.spell_id || e.bucket_name.empty() || e.bucket_value.empty()) {
); return true;
auto results = database.QueryDatabase(query);
if (!results.Success()) {
return false; // Query failed, do not allow scribing.
} }
if (!results.RowCount()) { auto k = GetScopedBucketKeys();
return true; // Spell ID isn't listed in the spell_buckets table, allow scribing.
}
auto row = results.begin(); k.key = e.bucket_name;
std::string spell_bucket_name = row[0];
std::string spell_bucket_value = row[1];
if (spell_bucket_name.empty()) { const auto& b = DataBucket::GetData(k);
return true; // If the entry in the spell_buckets table has nothing set for the qglobal name, allow scribing.
}
DataBucketKey k = GetScopedBucketKeys(); return zone->CompareDataBucket(e.bucket_comparison, e.bucket_value, b.value);
k.key = spell_bucket_name;
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 (b.value == spell_bucket_value) {
return true; // If value is equal to spell bucket value, allow scribing.
}
}
}
auto old_bucket_name = fmt::format(
"{}-{}",
character_id,
spell_bucket_name
);
std::string 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)) {
return true; // If value is greater than or equal to spell bucket value, allow scribing.
}
} else {
if (bucket_value == spell_bucket_value) {
return true; // If value is equal to spell bucket value, allow scribing.
}
}
}
return false;
} }
// TODO get rid of this // TODO get rid of this