mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-22 19:31:29 +00:00
[Rules] Implement Targeted Rule Sets
This commit is contained in:
parent
b8884d6572
commit
a65db13ec3
@ -6,6 +6,8 @@
|
||||
#include "../rulesys.h"
|
||||
#include "../eqemu_logsys.h"
|
||||
#include "../repositories/instance_list_repository.h"
|
||||
#include "../repositories/rule_sets_repository.h"
|
||||
#include "../repositories/rule_values_repository.h"
|
||||
#include "../zone_store.h"
|
||||
|
||||
|
||||
@ -347,3 +349,70 @@ bool WorldContentService::DoesZonePassContentFiltering(const ZoneRepository::Zon
|
||||
|
||||
return DoesPassContentFiltering(f);
|
||||
}
|
||||
|
||||
void WorldContentService::LoadTargetedRulesets(Database* db)
|
||||
{
|
||||
if (!m_zone_id) {
|
||||
LogError("Zone ID is not set. Cannot load targeted rulesets.");
|
||||
return;
|
||||
}
|
||||
|
||||
LogInfo("Zone ID [{}] Instance Version [{}] - Loading targeted rulesets", m_zone_id, m_instance_version);
|
||||
|
||||
constexpr int8 EXPANSION_ZERO_VALUE = -2;
|
||||
|
||||
auto rules = RuleValuesRepository::GetWhere(*db, "TRUE ORDER BY ruleset_id, rule_name");
|
||||
auto inst = RuleManager::Instance();
|
||||
auto sets = RuleSetsRepository::GetWhere(*db, "TRUE ORDER BY ruleset_id");
|
||||
for (auto& e : sets) {
|
||||
bool has_filters =
|
||||
!e.zone_ids.empty() ||
|
||||
!e.instance_versions.empty() ||
|
||||
!e.content_flags.empty() ||
|
||||
!e.content_flags_disabled.empty() ||
|
||||
e.min_expansion != EXPANSION_ZERO_VALUE ||
|
||||
e.max_expansion != EXPANSION_ZERO_VALUE;
|
||||
if (!has_filters) {
|
||||
continue; // not a targeted ruleset
|
||||
}
|
||||
|
||||
auto zone_id = std::to_string(m_zone_id);
|
||||
if (!e.zone_ids.empty() && !Strings::Contains(e.zone_ids, zone_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto instance_id = std::to_string(m_instance_version);
|
||||
if (!e.instance_versions.empty() && !Strings::Contains(e.instance_versions, instance_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!DoesPassContentFiltering(
|
||||
ContentFlags{
|
||||
.min_expansion = e.min_expansion,
|
||||
.max_expansion = e.max_expansion,
|
||||
.content_flags = e.content_flags,
|
||||
.content_flags_disabled = e.content_flags_disabled
|
||||
}
|
||||
)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto &r : rules) {
|
||||
if (r.ruleset_id != e.ruleset_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
inst->SetRule(r.rule_name, r.rule_value);
|
||||
|
||||
LogInfo(
|
||||
"Loading targeted rule from ruleset [{}] ruleset_name [{}] rule_name [{}] rule_value [{}]",
|
||||
e.ruleset_id,
|
||||
e.name,
|
||||
r.rule_name,
|
||||
r.rule_value
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@ -187,6 +187,11 @@ public:
|
||||
return &instance;
|
||||
}
|
||||
|
||||
// targeted rulesets
|
||||
void LoadTargetedRulesets(Database* db);
|
||||
inline void SetZoneId(int zone_id) { m_zone_id = zone_id; }
|
||||
inline void SetInstanceVersion(int instance_version) { m_instance_version = instance_version; }
|
||||
|
||||
private:
|
||||
int current_expansion{};
|
||||
std::vector<ContentFlagsRepository::ContentFlags> content_flags;
|
||||
@ -195,6 +200,9 @@ private:
|
||||
Database *m_database;
|
||||
Database *m_content_database;
|
||||
|
||||
int m_zone_id = 0;
|
||||
int m_instance_version = 0;
|
||||
|
||||
// holds a record of the zone table from the database
|
||||
WorldContentService *LoadStaticGlobalZoneInstances();
|
||||
std::vector<InstanceListRepository::InstanceList> m_zone_static_instances;
|
||||
|
||||
@ -7133,6 +7133,24 @@ CREATE INDEX idx_event_type_char_id ON player_event_logs (event_type_id, charact
|
||||
.sql = R"(
|
||||
ALTER TABLE `character_corpses`
|
||||
ADD COLUMN `entity_variables` TEXT DEFAULT NULL AFTER `rezzable`;
|
||||
)",
|
||||
.content_schema_update = false
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9326,
|
||||
.description = "2025_06_16_rule_set_expansion.sql",
|
||||
.check = "SHOW COLUMNS FROM `rule_sets` LIKE 'zone_ids'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `rule_sets`
|
||||
ADD COLUMN `zone_ids` TEXT NOT NULL DEFAULT '',
|
||||
ADD COLUMN `instance_versions` TEXT NOT NULL DEFAULT '',
|
||||
ADD COLUMN `content_flags` TEXT NOT NULL DEFAULT '',
|
||||
ADD COLUMN `content_flags_disabled` TEXT NOT NULL DEFAULT '',
|
||||
ADD COLUMN `min_expansion` TINYINT NOT NULL DEFAULT -2,
|
||||
ADD COLUMN `max_expansion` TINYINT NOT NULL DEFAULT -2,
|
||||
ADD COLUMN `notes` VARCHAR(255) NOT NULL DEFAULT '';
|
||||
)",
|
||||
.content_schema_update = false
|
||||
},
|
||||
|
||||
@ -21,6 +21,13 @@ public:
|
||||
struct RuleSets {
|
||||
uint8_t ruleset_id;
|
||||
std::string name;
|
||||
std::string zone_ids;
|
||||
std::string instance_versions;
|
||||
std::string content_flags;
|
||||
std::string content_flags_disabled;
|
||||
int8_t min_expansion;
|
||||
int8_t max_expansion;
|
||||
std::string notes;
|
||||
};
|
||||
|
||||
static std::string PrimaryKey()
|
||||
@ -33,6 +40,13 @@ public:
|
||||
return {
|
||||
"ruleset_id",
|
||||
"name",
|
||||
"zone_ids",
|
||||
"instance_versions",
|
||||
"content_flags",
|
||||
"content_flags_disabled",
|
||||
"min_expansion",
|
||||
"max_expansion",
|
||||
"notes",
|
||||
};
|
||||
}
|
||||
|
||||
@ -41,6 +55,13 @@ public:
|
||||
return {
|
||||
"ruleset_id",
|
||||
"name",
|
||||
"zone_ids",
|
||||
"instance_versions",
|
||||
"content_flags",
|
||||
"content_flags_disabled",
|
||||
"min_expansion",
|
||||
"max_expansion",
|
||||
"notes",
|
||||
};
|
||||
}
|
||||
|
||||
@ -81,8 +102,15 @@ public:
|
||||
{
|
||||
RuleSets e{};
|
||||
|
||||
e.ruleset_id = 0;
|
||||
e.name = "";
|
||||
e.ruleset_id = 0;
|
||||
e.name = "";
|
||||
e.zone_ids = "";
|
||||
e.instance_versions = "";
|
||||
e.content_flags = "";
|
||||
e.content_flags_disabled = "";
|
||||
e.min_expansion = -2;
|
||||
e.max_expansion = -2;
|
||||
e.notes = "";
|
||||
|
||||
return e;
|
||||
}
|
||||
@ -119,8 +147,15 @@ public:
|
||||
if (results.RowCount() == 1) {
|
||||
RuleSets e{};
|
||||
|
||||
e.ruleset_id = row[0] ? static_cast<uint8_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.name = row[1] ? row[1] : "";
|
||||
e.ruleset_id = row[0] ? static_cast<uint8_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.name = row[1] ? row[1] : "";
|
||||
e.zone_ids = row[2] ? row[2] : "";
|
||||
e.instance_versions = row[3] ? row[3] : "";
|
||||
e.content_flags = row[4] ? row[4] : "";
|
||||
e.content_flags_disabled = row[5] ? row[5] : "";
|
||||
e.min_expansion = row[6] ? static_cast<int8_t>(atoi(row[6])) : -2;
|
||||
e.max_expansion = row[7] ? static_cast<int8_t>(atoi(row[7])) : -2;
|
||||
e.notes = row[8] ? row[8] : "";
|
||||
|
||||
return e;
|
||||
}
|
||||
@ -155,6 +190,13 @@ public:
|
||||
auto columns = Columns();
|
||||
|
||||
v.push_back(columns[1] + " = '" + Strings::Escape(e.name) + "'");
|
||||
v.push_back(columns[2] + " = '" + Strings::Escape(e.zone_ids) + "'");
|
||||
v.push_back(columns[3] + " = '" + Strings::Escape(e.instance_versions) + "'");
|
||||
v.push_back(columns[4] + " = '" + Strings::Escape(e.content_flags) + "'");
|
||||
v.push_back(columns[5] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||
v.push_back(columns[6] + " = " + std::to_string(e.min_expansion));
|
||||
v.push_back(columns[7] + " = " + std::to_string(e.max_expansion));
|
||||
v.push_back(columns[8] + " = '" + Strings::Escape(e.notes) + "'");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@ -178,6 +220,13 @@ public:
|
||||
|
||||
v.push_back(std::to_string(e.ruleset_id));
|
||||
v.push_back("'" + Strings::Escape(e.name) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.zone_ids) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.instance_versions) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.content_flags) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||
v.push_back(std::to_string(e.min_expansion));
|
||||
v.push_back(std::to_string(e.max_expansion));
|
||||
v.push_back("'" + Strings::Escape(e.notes) + "'");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@ -209,6 +258,13 @@ public:
|
||||
|
||||
v.push_back(std::to_string(e.ruleset_id));
|
||||
v.push_back("'" + Strings::Escape(e.name) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.zone_ids) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.instance_versions) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.content_flags) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||
v.push_back(std::to_string(e.min_expansion));
|
||||
v.push_back(std::to_string(e.max_expansion));
|
||||
v.push_back("'" + Strings::Escape(e.notes) + "'");
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
@ -242,8 +298,15 @@ public:
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
RuleSets e{};
|
||||
|
||||
e.ruleset_id = row[0] ? static_cast<uint8_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.name = row[1] ? row[1] : "";
|
||||
e.ruleset_id = row[0] ? static_cast<uint8_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.name = row[1] ? row[1] : "";
|
||||
e.zone_ids = row[2] ? row[2] : "";
|
||||
e.instance_versions = row[3] ? row[3] : "";
|
||||
e.content_flags = row[4] ? row[4] : "";
|
||||
e.content_flags_disabled = row[5] ? row[5] : "";
|
||||
e.min_expansion = row[6] ? static_cast<int8_t>(atoi(row[6])) : -2;
|
||||
e.max_expansion = row[7] ? static_cast<int8_t>(atoi(row[7])) : -2;
|
||||
e.notes = row[8] ? row[8] : "";
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@ -268,8 +331,15 @@ public:
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
RuleSets e{};
|
||||
|
||||
e.ruleset_id = row[0] ? static_cast<uint8_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.name = row[1] ? row[1] : "";
|
||||
e.ruleset_id = row[0] ? static_cast<uint8_t>(strtoul(row[0], nullptr, 10)) : 0;
|
||||
e.name = row[1] ? row[1] : "";
|
||||
e.zone_ids = row[2] ? row[2] : "";
|
||||
e.instance_versions = row[3] ? row[3] : "";
|
||||
e.content_flags = row[4] ? row[4] : "";
|
||||
e.content_flags_disabled = row[5] ? row[5] : "";
|
||||
e.min_expansion = row[6] ? static_cast<int8_t>(atoi(row[6])) : -2;
|
||||
e.max_expansion = row[7] ? static_cast<int8_t>(atoi(row[7])) : -2;
|
||||
e.notes = row[8] ? row[8] : "";
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@ -346,6 +416,13 @@ public:
|
||||
|
||||
v.push_back(std::to_string(e.ruleset_id));
|
||||
v.push_back("'" + Strings::Escape(e.name) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.zone_ids) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.instance_versions) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.content_flags) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||
v.push_back(std::to_string(e.min_expansion));
|
||||
v.push_back(std::to_string(e.max_expansion));
|
||||
v.push_back("'" + Strings::Escape(e.notes) + "'");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@ -370,6 +447,13 @@ public:
|
||||
|
||||
v.push_back(std::to_string(e.ruleset_id));
|
||||
v.push_back("'" + Strings::Escape(e.name) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.zone_ids) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.instance_versions) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.content_flags) + "'");
|
||||
v.push_back("'" + Strings::Escape(e.content_flags_disabled) + "'");
|
||||
v.push_back(std::to_string(e.min_expansion));
|
||||
v.push_back(std::to_string(e.max_expansion));
|
||||
v.push_back("'" + Strings::Escape(e.notes) + "'");
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
|
||||
#include "../common/repositories/rule_sets_repository.h"
|
||||
#include "../common/repositories/rule_values_repository.h"
|
||||
#include "../common/content/world_content_service.h"
|
||||
|
||||
const char *RuleManager::s_categoryNames[_CatCount + 1] = {
|
||||
#define RULE_CATEGORY(category_name) \
|
||||
@ -268,7 +269,6 @@ bool RuleManager::LoadRules(Database *db, const std::string &rule_set_name, bool
|
||||
|
||||
const std::string default_ruleset_name = "default";
|
||||
bool is_default = rule_set_name == default_ruleset_name;
|
||||
|
||||
if (!is_default) {
|
||||
const auto default_rule_set_id = RuleSetsRepository::GetRuleSetID(*db, default_ruleset_name);
|
||||
|
||||
@ -327,6 +327,10 @@ bool RuleManager::LoadRules(Database *db, const std::string &rule_set_name, bool
|
||||
rule_set_id
|
||||
);
|
||||
|
||||
if (m_post_load_callback) {
|
||||
m_post_load_callback(db);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -661,4 +665,4 @@ bool RuleManager::GetBoolRule(RuleManager::BoolType t) const
|
||||
std::string RuleManager::GetStringRule(RuleManager::StringType t) const
|
||||
{
|
||||
return m_RuleStringValues[t];
|
||||
}
|
||||
}
|
||||
@ -40,6 +40,7 @@
|
||||
RuleManager::Instance()->GetStringRule( RuleManager::String__##rule_name )
|
||||
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
@ -156,6 +157,9 @@ public:
|
||||
bool UpdateInjectedRules(Database* db, const std::string& rule_set_name, bool quiet_update = false);
|
||||
bool UpdateOrphanedRules(Database* db, bool quiet_update = false);
|
||||
bool RestoreRuleNotes(Database* db);
|
||||
void SetPostLoadCallback(std::function<void(Database*)> cb) {
|
||||
m_post_load_callback = std::move(cb);
|
||||
}
|
||||
|
||||
private:
|
||||
RuleManager();
|
||||
@ -170,6 +174,8 @@ private:
|
||||
uint32 m_RuleBoolValues[BoolRuleCount];
|
||||
std::string m_RuleStringValues[StringRuleCount];
|
||||
|
||||
std::function<void(Database*)> m_post_load_callback;
|
||||
|
||||
typedef enum {
|
||||
IntRule,
|
||||
RealRule,
|
||||
|
||||
@ -42,7 +42,7 @@
|
||||
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9325
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9326
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9054
|
||||
#define CUSTOM_BINARY_DATABASE_VERSION 0
|
||||
|
||||
|
||||
@ -413,6 +413,11 @@ int main(int argc, char **argv)
|
||||
->ReloadContentFlags();
|
||||
|
||||
ZoneEventScheduler::Instance()->SetDatabase(&database)->LoadScheduledEvents();
|
||||
RuleManager::Instance()->SetPostLoadCallback(
|
||||
[&](Database* db) {
|
||||
WorldContentService::Instance()->LoadTargetedRulesets(db);
|
||||
}
|
||||
);
|
||||
|
||||
EQ::SayLinkEngine::LoadCachedSaylinks();
|
||||
|
||||
|
||||
@ -1151,6 +1151,10 @@ bool Zone::Init(bool is_static) {
|
||||
);
|
||||
} // if that fails, try the file name, then load defaults
|
||||
|
||||
content_service.SetZoneId(GetZoneID());
|
||||
content_service.SetInstanceVersion(GetInstanceVersion());
|
||||
RuleManager::Instance()->LoadRules(&database, RuleManager::Instance()->GetActiveRuleset(), true);
|
||||
|
||||
if (RuleManager::Instance()->GetActiveRulesetID() != default_ruleset) {
|
||||
std::string r_name = RuleSetsRepository::GetRuleSetName(database, default_ruleset);
|
||||
if (r_name.size() > 0) {
|
||||
@ -1293,7 +1297,6 @@ void Zone::ReloadStaticData() {
|
||||
|
||||
WorldContentService::Instance()->SetExpansionContext()->ReloadContentFlags();
|
||||
|
||||
|
||||
LogInfo("Zone Static Data Reloaded");
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user