Compare commits

...

26 Commits

Author SHA1 Message Date
Chris Miles 908b826fb4 more log adjustments 2025-07-27 15:34:14 -05:00
Chris Miles 31e6f13b1d post rebase 2025-07-26 20:17:19 -05:00
Chris Miles 120d077a29 Log 2025-07-26 20:04:50 -05:00
Chris Miles 278f61e17e Logging adjustments 2025-07-26 20:04:50 -05:00
Chris Miles 6238293f22 GetDepthsOfDarkhollowRuleset, GetProphecyOfRoRuleset, GetTheSerpentsSpineRuleset, GetTheBuriedSeaRuleset 2025-07-26 20:04:50 -05:00
Chris Miles d652c129c5 Update existing rules sets and values 2025-07-26 20:04:50 -05:00
Chris Miles e95eb8971b Add era overrides 2025-07-26 20:04:50 -05:00
Chris Miles ea1195972d Update 2025-07-26 20:04:49 -05:00
Chris Miles 9d1fe011a7 Update world_content_service_rulesets.cpp 2025-07-26 20:04:49 -05:00
Chris Miles 4aa31ab77d Organize seeded rulesets 2025-07-26 20:04:49 -05:00
Chris Miles f4fd653e45 Update world_content_service.cpp 2025-07-26 20:04:49 -05:00
Chris Miles 799149ad75 Update world_content_service.cpp 2025-07-26 20:04:49 -05:00
Chris Miles 6b0ab6db90 Add rest of expansion rules 2025-07-26 20:04:49 -05:00
Chris Miles 09baa0208b Update world_content_service.cpp 2025-07-26 20:04:49 -05:00
Chris Miles 4def6210fc Designator order 2025-07-26 20:04:49 -05:00
Chris Miles 55798ab06a Kunark 2025-07-26 20:04:49 -05:00
Chris Miles 934ca1accd Add classic ruleset 2025-07-26 20:04:49 -05:00
Chris Miles 657d0b3f53 Bulk pre-fetching 2025-07-26 20:04:49 -05:00
Chris Miles 7f869442c4 Rule injection updates, notes etc 2025-07-26 20:04:49 -05:00
Chris Miles cef1649e9c Pre-seeding rule sets 2025-07-26 20:04:49 -05:00
Chris Miles 7d223ce6f2 Use local database pointer 2025-07-26 20:04:49 -05:00
Chris Miles 66cc83cb28 Cleanup 2025-07-26 20:04:49 -05:00
Chris Miles 9c450ac95b Dependency inject into world content service 2025-07-26 20:04:49 -05:00
Chris Miles ffd76f3362 Post rebase fix 2025-07-26 20:04:49 -05:00
Chris Miles b381a339f6 Changes 2025-07-26 20:04:49 -05:00
Chris Miles a65db13ec3 [Rules] Implement Targeted Rule Sets 2025-07-26 20:01:52 -05:00
18 changed files with 1332 additions and 308 deletions
+1
View File
@@ -9,6 +9,7 @@ SET(common_sources
compression.cpp
condition.cpp
content/world_content_service.cpp
content/world_content_service_rulesets.cpp
discord/discord.cpp
crash.cpp
crc16.cpp
+9 -36
View File
@@ -1,19 +1,14 @@
#include "world_content_service.h"
#include <utility>
#include <glm/vec3.hpp>
#include "../database.h"
#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"
WorldContentService::WorldContentService()
{
SetCurrentExpansion(Expansion::EXPANSION_ALL);
}
int WorldContentService::GetCurrentExpansion() const
{
return current_expansion;
@@ -27,7 +22,7 @@ WorldContentService *WorldContentService::SetExpansionContext()
// pull expansion from rules
int expansion = RuleI(Expansion, CurrentExpansion);
if (expansion >= Expansion::Classic && expansion <= Expansion::MaxId) {
WorldContentService::Instance()->SetCurrentExpansion(expansion);
SetCurrentExpansion(expansion);
}
LogInfo(
@@ -41,36 +36,27 @@ WorldContentService *WorldContentService::SetExpansionContext()
std::string WorldContentService::GetCurrentExpansionName()
{
if (WorldContentService::Instance()->GetCurrentExpansion() == Expansion::EXPANSION_ALL) {
if (GetCurrentExpansion() == Expansion::EXPANSION_ALL) {
return "All Expansions";
}
if (current_expansion >= Expansion::Classic && current_expansion <= Expansion::MaxId) {
return Expansion::ExpansionName[WorldContentService::Instance()->GetCurrentExpansion()];
return Expansion::ExpansionName[GetCurrentExpansion()];
}
return "Unknown Expansion";
}
/**
* @param current_expansion
*/
void WorldContentService::SetCurrentExpansion(int current_expansion)
{
WorldContentService::current_expansion = current_expansion;
}
/**
* @return
*/
const std::vector<ContentFlagsRepository::ContentFlags> &WorldContentService::GetContentFlags() const
{
return content_flags;
}
/**
* @return
*/
std::vector<std::string> WorldContentService::GetContentFlagsEnabled()
{
std::vector<std::string> enabled_flags;
@@ -84,9 +70,6 @@ std::vector<std::string> WorldContentService::GetContentFlagsEnabled()
return enabled_flags;
}
/**
* @return
*/
std::vector<std::string> WorldContentService::GetContentFlagsDisabled()
{
std::vector<std::string> disabled_flags;
@@ -100,18 +83,11 @@ std::vector<std::string> WorldContentService::GetContentFlagsDisabled()
return disabled_flags;
}
/**
* @param content_flags
*/
void WorldContentService::SetContentFlags(const std::vector<ContentFlagsRepository::ContentFlags> &content_flags)
{
WorldContentService::content_flags = content_flags;
}
/**
* @param content_flag
* @return
*/
bool WorldContentService::IsContentFlagEnabled(const std::string &content_flag)
{
for (auto &f: GetContentFlags()) {
@@ -123,10 +99,6 @@ bool WorldContentService::IsContentFlagEnabled(const std::string &content_flag)
return false;
}
/**
* @param content_flag
* @return
*/
bool WorldContentService::IsContentFlagDisabled(const std::string &content_flag)
{
for (auto &f: GetContentFlags()) {
@@ -195,7 +167,7 @@ Database *WorldContentService::GetDatabase() const
WorldContentService *WorldContentService::SetDatabase(Database *database)
{
WorldContentService::m_database = database;
m_database = database;
return this;
}
@@ -313,7 +285,7 @@ WorldContentService::FindZoneResult WorldContentService::FindZone(uint32 zone_id
i.notes
);
return WorldContentService::FindZoneResult{
return FindZoneResult{
.zone_id = static_cast<uint32>(z.zoneidnumber),
.instance = i,
.zone = z
@@ -322,7 +294,7 @@ WorldContentService::FindZoneResult WorldContentService::FindZone(uint32 zone_id
}
}
return WorldContentService::FindZoneResult{.zone_id = 0};
return FindZoneResult{.zone_id = 0};
}
bool WorldContentService::IsInPublicStaticInstance(uint32 instance_id)
@@ -347,3 +319,4 @@ bool WorldContentService::DoesZonePassContentFiltering(const ZoneRepository::Zon
return DoesPassContentFiltering(f);
}
+27 -9
View File
@@ -3,6 +3,7 @@
#include <string>
#include <vector>
#include "../rulesys.h"
#include "../repositories/content_flags_repository.h"
#include "../repositories/zone_repository.h"
#include "../repositories/instance_list_repository.h"
@@ -17,8 +18,10 @@ struct ContentFlags {
};
namespace Expansion {
static const int EXPANSION_ALL = -1;
static const int EXPANSION_FILTER_MAX = 99;
static constexpr int8 EXPANSION_ZERO_VALUE = -2;
static constexpr int8 EXPANSION_MAX = 98;
static const int EXPANSION_ALL = -1;
static const int EXPANSION_FILTER_MAX = 99;
enum ExpansionNumber {
Classic = 0,
@@ -81,14 +84,25 @@ namespace Expansion {
"Empires of Kunark",
"Ring of Scale",
"The Burning Lands",
"Torment of Velious",
"Torment of Velious"
};
}
class WorldContentService {
public:
WorldContentService();
// Constructor can initialize from singleton
WorldContentService()
: m_rule_manager(RuleManager::Instance())
{
SetCurrentExpansion(Expansion::EXPANSION_ALL);
}
static WorldContentService* Instance()
{
static WorldContentService instance;
return &instance;
}
std::string GetCurrentExpansionName();
int GetCurrentExpansion() const;
@@ -181,11 +195,11 @@ public:
FindZoneResult FindZone(uint32 zone_id, uint32 instance_id);
bool IsInPublicStaticInstance(uint32 instance_id);
static WorldContentService* Instance()
{
static WorldContentService instance;
return &instance;
}
// targeted rulesets
void SeedDefaultRulesets() const;
void LoadTargetedRulesets();
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{};
@@ -194,6 +208,10 @@ private:
// reference to database
Database *m_database;
Database *m_content_database;
RuleManager* m_rule_manager;
int m_zone_id = 0;
int m_instance_version = 0;
// holds a record of the zone table from the database
WorldContentService *LoadStaticGlobalZoneInstances();
@@ -0,0 +1,981 @@
#include "world_content_service.h"
#include "../repositories/rule_sets_repository.h"
#include "../repositories/rule_values_repository.h"
// RuleSet is a struct that contains a ruleset and its associated rules.
struct RuleSet {
RuleSetsRepository::RuleSets rule_set;
std::vector<RuleValuesRepository::RuleValues> rules;
};
inline RuleSet GetClassicRuleset()
{
return {
.rule_set = {
.ruleset_id = 100,
.name = "Original (Classic)",
.zone_ids = "",
.instance_versions = "",
.content_flags = "",
.content_flags_disabled = "",
.min_expansion = Expansion::Classic,
.max_expansion = Expansion::EXPANSION_MAX,
.notes = "Classic client-based ruleset",
},
.rules = {
{
.rule_name = "Character:EnableXTargetting",
.rule_value = "false",
.notes = "Added in Call of the Forsaken"
},
{
.rule_name = "Character:LeaveCorpses",
.rule_value = "true",
.notes = "Leave corpses behind"
},
{
.rule_name = "Character:LeaveNakedCorpses",
.rule_value = "false",
.notes = "Gear left on corpses until SoD"
},
{
.rule_name = "Character:MaxExpLevel",
.rule_value = "50",
.notes = "Level 50 cap until Kunark"
},
{
.rule_name = "Character:MaxLevel",
.rule_value = "50",
.notes = "Level 50 cap until Kunark"
},
{
.rule_name = "Character:RestRegenEnabled",
.rule_value = "false",
.notes = "OoC regen not added until TSS"
},
{
.rule_name = "Character:SharedBankPlat",
.rule_value = "false",
.notes = "No shared bank until LoY"
},
{
.rule_name = "Character:StatCap",
.rule_value = "255",
.notes = "Classic stat cap is 255"
},
{
.rule_name = "Character:UseOldBindWound",
.rule_value = "true",
.notes = ""
},
{
.rule_name = "Character:UseOldClassExpPenalties",
.rule_value = "true",
.notes = "Exp penalties removed in SoF"
},
{
.rule_name = "Character:UseOldConSystem",
.rule_value = "true",
.notes = "Con system changed in SoF"
},
{
.rule_name = "Character:UseOldRaceExpPenalties",
.rule_value = "true",
.notes = "Exp penalties removed in SoF"
},
{
.rule_name = "Character:UseOldRaceRezEffects",
.rule_value = "true",
.notes = "May need testing to ensure it can't be dispelled"
},
{
.rule_name = "Character:UseRaceClassExpBonuses",
.rule_value = "true",
.notes = ""
},
{
.rule_name = "Chat:EnableVoiceMacros",
.rule_value = "false",
.notes = "Introduced in GoD"
},
{
.rule_name = "Chat:ServerWideAuction",
.rule_value = "false",
.notes = "Disable Server-Wide Auction Chat"
},
{
.rule_name = "Chat:ServerWideOOC",
.rule_value = "false",
.notes = "Disable Server-Wide OOC Chat"
},
{
.rule_name = "Combat:ClassicNPCBackstab",
.rule_value = "true",
.notes = "Disables front backstab"
},
{
.rule_name = "Mail:EnableMailSystem",
.rule_value = "false",
.notes = "Mail system added in DoN"
},
{
.rule_name = "Spells:PreNerfBardAEDoT",
.rule_value = "true",
.notes = "Bard AE nerf not added until OoW"
},
{
.rule_name = "Spells:WizCritLevel",
.rule_value = "65",
.notes = "Wiz non-AA crits not until Luclin"
},
{
.rule_name = "TaskSystem:EnableTaskSystem",
.rule_value = "false",
.notes = "Task system added in OoW"
},
{
.rule_name = "World:CharacterSelectExpansionSettings",
.rule_value = "0",
.notes = "Classic Client-Based Expansion Setting"
},
{
.rule_name = "World:EnableReturnHomeButton",
.rule_value = "false",
.notes = "Return Home added in DoN"
},
{
.rule_name = "World:EnableTutorialButton",
.rule_value = "false",
.notes = "Tutorial added in DoN"
},
{
.rule_name = "World:ExpansionSettings",
.rule_value = "0",
.notes = "Classic Client-Based Expansion Setting"
},
}
};
}
inline RuleSet GetKunarkRuleset()
{
return {
.rule_set = {
.ruleset_id = 101,
.name = "Ruins of Kunark",
.zone_ids = "",
.instance_versions = "",
.content_flags = "",
.content_flags_disabled = "",
.min_expansion = Expansion::TheRuinsOfKunark,
.max_expansion = Expansion::EXPANSION_MAX,
.notes = "Kunark client-based ruleset. Level 60 cap until PoP.",
},
.rules = {
{
.rule_name = "Expansion:CurrentExpansion",
.rule_value = "1",
.notes = "Current Expansion"
},
{
.rule_name = "World:ExpansionSettings",
.rule_value = "1",
.notes = "Kunark Client-Based Expansion Setting"
},
{
.rule_name = "World:CharacterSelectExpansionSettings",
.rule_value = "1",
.notes = "Kunark Client-Based Expansion Setting"
},
{
.rule_name = "Character:MaxExpLevel",
.rule_value = "60",
.notes = "Level 60 cap until PoP"
},
{
.rule_name = "Character:MaxLevel",
.rule_value = "60",
.notes = "Level 60 cap until PoP"
},
}
};
}
inline RuleSet GetVeliousRuleset()
{
return {
.rule_set = {
.ruleset_id = 102,
.name = "Scars of Velious",
.zone_ids = "",
.instance_versions = "",
.content_flags = "",
.content_flags_disabled = "",
.min_expansion = Expansion::TheScarsOfVelious,
.max_expansion = Expansion::EXPANSION_MAX,
.notes = "Velious client-based ruleset. Level 60 cap until PoP."
},
.rules = {
{
.rule_name = "Expansion:CurrentExpansion",
.rule_value = "2",
.notes = "Current Expansion"
},
{
.rule_name = "World:ExpansionSettings",
.rule_value = "3",
.notes = "Velious Client-Based Expansion Setting"
},
{
.rule_name = "World:CharacterSelectExpansionSettings",
.rule_value = "3",
.notes = "Velious Client-Based Expansion Setting"
},
{
.rule_name = "Character:MaxExpLevel",
.rule_value = "60",
.notes = "Level 60 cap until PoP"
},
{
.rule_name = "Character:MaxLevel",
.rule_value = "60",
.notes = "Level 60 cap until PoP"
},
}
};
}
inline RuleSet GetLuclinRuleset()
{
return {
.rule_set = {
.ruleset_id = 103,
.name = "Shadows of Luclin",
.zone_ids = "",
.instance_versions = "",
.content_flags = "",
.content_flags_disabled = "",
.min_expansion = Expansion::TheShadowsOfLuclin,
.max_expansion = Expansion::EXPANSION_MAX,
.notes = "Luclin client-based ruleset. Level 60 cap. Added Wiz crits."
},
.rules = {
{
.rule_name = "Expansion:CurrentExpansion",
.rule_value = "3",
.notes = "Current Expansion"
},
{
.rule_name = "World:ExpansionSettings",
.rule_value = "7",
.notes = "Luclin Client-Based Expansion Setting"
},
{
.rule_name = "World:CharacterSelectExpansionSettings",
.rule_value = "7",
.notes = "Luclin Client-Based Expansion Setting"
},
{
.rule_name = "Spells:WizCritLevel",
.rule_value = "12",
.notes = "Wizard non-AA Criticals Not added until Luclin"
},
}
};
}
inline RuleSet GetPlanesRuleset()
{
return {
.rule_set = {
.ruleset_id = 104,
.name = "Planes of Power",
.zone_ids = "",
.instance_versions = "",
.content_flags = "",
.content_flags_disabled = "",
.min_expansion = Expansion::ThePlanesOfPower,
.max_expansion = Expansion::EXPANSION_MAX,
.notes = "PoP client-based ruleset. Level 65 cap. Stat cap increased. Bind Wound changed."
},
.rules = {
{
.rule_name = "Expansion:CurrentExpansion",
.rule_value = "4",
.notes = "Current Expansion"
},
{
.rule_name = "World:CharacterSelectExpansionSettings",
.rule_value = "15",
.notes = "Planes of Power Client-Based Expansion Setting"
},
{
.rule_name = "World:ExpansionSettings",
.rule_value = "15",
.notes = "Planes of Power Client-Based Expansion Setting"
},
{
.rule_name = "Character:MaxExpLevel",
.rule_value = "65",
.notes = "Level 65 cap until Omens of War"
},
{
.rule_name = "Character:MaxLevel",
.rule_value = "65",
.notes = "Level 65 cap until Omens of War"
},
{
.rule_name = "Character:StatCap",
.rule_value = "305",
.notes = "Stat cap raised from 255 to 305 with PoP"
},
{
.rule_name = "Character:UseOldBindWound",
.rule_value = "false",
.notes = "PoP introduced a more effective bind wound system"
},
}
};
}
// Returns a RuleSet for the Legacy of Ykesha ruleset.
inline RuleSet GetLegacyOfYkeshaRuleset()
{
return {
.rule_set = {
.ruleset_id = 105,
.name = "Legacy of Ykesha",
.zone_ids = "",
.instance_versions = "",
.content_flags = "",
.content_flags_disabled = "",
.min_expansion = Expansion::TheLegacyOfYkesha,
.max_expansion = Expansion::EXPANSION_MAX,
.notes = "LoY client-based ruleset. Shared bank introduced. Stat cap raised to 350."
},
.rules = {
{
.rule_name = "Expansion:CurrentExpansion",
.rule_value = "5",
.notes = "Current Expansion"
},
{
.rule_name = "World:CharacterSelectExpansionSettings",
.rule_value = "31",
.notes = "Legacy of Ykesha Client-Based Expansion Setting"
},
{
.rule_name = "World:ExpansionSettings",
.rule_value = "31",
.notes = "Legacy of Ykesha Client-Based Expansion Setting"
},
{
.rule_name = "Character:MaxExpLevel",
.rule_value = "65",
.notes = "Level 65 cap until Omens of War"
},
{
.rule_name = "Character:MaxLevel",
.rule_value = "65",
.notes = "Level 65 cap until Omens of War"
},
{
.rule_name = "Character:SharedBankPlat",
.rule_value = "true",
.notes = "Shared bank enabled in Legacy of Ykesha"
},
{
.rule_name = "Character:StatCap",
.rule_value = "350",
.notes = "Stat cap increased to 350 with LoY (was 305 in PoP)"
},
}
};
}
inline RuleSet GetLDoNRuleset()
{
return {
.rule_set = {
.ruleset_id = 106,
.name = "Lost Dungeons of Norrath",
.zone_ids = "",
.instance_versions = "",
.content_flags = "",
.content_flags_disabled = "",
.min_expansion = Expansion::LostDungeonsOfNorrath,
.max_expansion = Expansion::EXPANSION_MAX,
.notes = "LDoN client-based ruleset. Stat cap raised to 400."
},
.rules = {
{
.rule_name = "Expansion:CurrentExpansion",
.rule_value = "6",
.notes = "Current Expansion"
},
{
.rule_name = "World:CharacterSelectExpansionSettings",
.rule_value = "63",
.notes = "Lost Dungeons of Norrath Client-Based Expansion Setting"
},
{
.rule_name = "World:ExpansionSettings",
.rule_value = "63",
.notes = "Lost Dungeons of Norrath Client-Based Expansion Setting"
},
{
.rule_name = "Character:StatCap",
.rule_value = "400",
.notes = "Stat cap increased to 400 with LDoN (was 350 in LoY)"
},
}
};
}
inline RuleSet GetGatesOfDiscordRuleset()
{
return {
.rule_set = {
.ruleset_id = 107,
.name = "Gates of Discord",
.zone_ids = "",
.instance_versions = "",
.content_flags = "",
.content_flags_disabled = "",
.min_expansion = Expansion::GatesOfDiscord,
.max_expansion = Expansion::EXPANSION_MAX,
.notes = "GoD client-based ruleset. Voice macros introduced."
},
.rules = {
{
.rule_name = "Expansion:CurrentExpansion",
.rule_value = "7",
.notes = "Current Expansion"
},
{
.rule_name = "World:CharacterSelectExpansionSettings",
.rule_value = "127",
.notes = "Gates of Discord Client-Based Expansion Setting"
},
{
.rule_name = "World:ExpansionSettings",
.rule_value = "127",
.notes = "Gates of Discord Client-Based Expansion Setting"
},
{
.rule_name = "Chat:EnableVoiceMacros",
.rule_value = "true",
.notes = "Enable Voice Macros - Introduced in Gates of Discord"
},
}
};
}
inline RuleSet GetOmensOfWarRuleset()
{
return {
.rule_set = {
.ruleset_id = 108,
.name = "Omens of War",
.zone_ids = "",
.instance_versions = "",
.content_flags = "",
.content_flags_disabled = "",
.min_expansion = Expansion::OmensOfWar,
.max_expansion = Expansion::EXPANSION_MAX,
.notes = "OoW client-based ruleset. Level cap raised to 70. Bard AE nerfed. Task system enabled."
},
.rules = {
{
.rule_name = "Expansion:CurrentExpansion",
.rule_value = "8",
.notes = "Current Expansion"
},
{
.rule_name = "World:CharacterSelectExpansionSettings",
.rule_value = "255",
.notes = "Omens of War Client-Based Expansion Setting"
},
{
.rule_name = "World:ExpansionSettings",
.rule_value = "255",
.notes = "Omens of War Client-Based Expansion Setting"
},
{
.rule_name = "Spells:PreNerfBardAEDoT",
.rule_value = "false",
.notes = "Bard AE Nerf"
},
{
.rule_name = "TaskSystem:EnableTaskSystem",
.rule_value = "true",
.notes = "Task system was introduced in Omens of War"
},
{
.rule_name = "Character:MaxExpLevel",
.rule_value = "70",
.notes = "Level 70 cap until The Serpent's Spine"
},
{
.rule_name = "Character:MaxLevel",
.rule_value = "70",
.notes = "Level 70 cap until The Serpent's Spine"
},
}
};
}
inline RuleSet GetDragonsOfNorrathRuleset()
{
return {
.rule_set = {
.ruleset_id = 109,
.name = "Dragons of Norrath",
.zone_ids = "",
.instance_versions = "",
.content_flags = "",
.content_flags_disabled = "",
.min_expansion = Expansion::DragonsOfNorrath,
.max_expansion = Expansion::EXPANSION_MAX,
.notes = "DoN client-based ruleset. Mail system introduced. Accursed Nest unlockable."
},
.rules = {
{
.rule_name = "Expansion:CurrentExpansion",
.rule_value = "9",
.notes = "Current Expansion"
},
{
.rule_name = "World:CharacterSelectExpansionSettings",
.rule_value = "511",
.notes = "Dragons of Norrath Client-Based Expansion Setting"
},
{
.rule_name = "World:ExpansionSettings",
.rule_value = "511",
.notes = "Dragons of Norrath Client-Based Expansion Setting"
},
{
.rule_name = "Mail:EnableMailSystem",
.rule_value = "true",
.notes = "Mail System not added until Dragons of Norrath"
},
}
};
}
inline RuleSet GetEraOverridesRuleset()
{
return {
.rule_set = {
.ruleset_id = 200,
.name = "Era Overrides",
.zone_ids = "",
.instance_versions = "",
.content_flags = "",
.content_flags_disabled = "",
.min_expansion = Expansion::EXPANSION_ALL,
.max_expansion = Expansion::EXPANSION_MAX,
.notes = "If you want to override any rules for era specific rulesets, use this ruleset. It will not be used by default.",
},
.rules = {
// users will add their own dynamically
}
};
}
inline RuleSet GetDepthsOfDarkhollowRuleset()
{
return {
.rule_set = {
.ruleset_id = 110,
.name = "Depths of Darkhollow",
.zone_ids = "",
.instance_versions = "",
.content_flags = "",
.content_flags_disabled = "",
.min_expansion = Expansion::DepthsOfDarkhollow,
.max_expansion = Expansion::EXPANSION_MAX,
.notes = "DoD client-based ruleset. Introduced Shroud system.",
},
.rules = {
{
.rule_name = "Expansion:CurrentExpansion",
.rule_value = "10",
.notes = "Current Expansion",
},
{
.rule_name = "World:CharacterSelectExpansionSettings",
.rule_value = "1023",
.notes = "Depths of Darkhollow Client-Based Expansion Setting",
},
{
.rule_name = "World:ExpansionSettings",
.rule_value = "1023",
.notes = "Depths of Darkhollow Client-Based Expansion Setting",
},
{
.rule_name = "Character:EnableShroudSystem",
.rule_value = "true",
.notes = "Shroud system was introduced in Depths of Darkhollow",
},
}
};
}
inline RuleSet GetProphecyOfRoRuleset()
{
return {
.rule_set = {
.ruleset_id = 111,
.name = "Prophecy of Ro",
.zone_ids = "",
.instance_versions = "",
.content_flags = "",
.content_flags_disabled = "",
.min_expansion = Expansion::ProphecyOfRo,
.max_expansion = Expansion::EXPANSION_MAX,
.notes = "PoR client-based ruleset. Introduced aura system.",
},
.rules = {
{
.rule_name = "Expansion:CurrentExpansion",
.rule_value = "11",
.notes = "Current Expansion",
},
{
.rule_name = "World:CharacterSelectExpansionSettings",
.rule_value = "2047",
.notes = "Prophecy of Ro Client-Based Expansion Setting",
},
{
.rule_name = "World:ExpansionSettings",
.rule_value = "2047",
.notes = "Prophecy of Ro Client-Based Expansion Setting",
},
{
.rule_name = "Character:EnableAuraSystem",
.rule_value = "true",
.notes = "Aura system introduced in Prophecy of Ro",
},
}
};
}
inline RuleSet GetTheSerpentsSpineRuleset()
{
return {
.rule_set = {
.ruleset_id = 112,
.name = "The Serpent's Spine",
.zone_ids = "",
.instance_versions = "",
.content_flags = "",
.content_flags_disabled = "",
.min_expansion = Expansion::TheSerpentsSpine,
.max_expansion = Expansion::EXPANSION_MAX,
.notes = "TSS client-based ruleset. Level cap raised to 75. Out-of-combat regen enabled.",
},
.rules = {
{
.rule_name = "Expansion:CurrentExpansion",
.rule_value = "12",
.notes = "Current Expansion",
},
{
.rule_name = "World:CharacterSelectExpansionSettings",
.rule_value = "4095",
.notes = "The Serpent's Spine Client-Based Expansion Setting",
},
{
.rule_name = "World:ExpansionSettings",
.rule_value = "4095",
.notes = "The Serpent's Spine Client-Based Expansion Setting",
},
{
.rule_name = "Character:MaxExpLevel",
.rule_value = "75",
.notes = "Level 75 cap until The Buried Sea",
},
{
.rule_name = "Character:MaxLevel",
.rule_value = "75",
.notes = "Level 75 cap until The Buried Sea",
},
{
.rule_name = "Character:RestRegenEnabled",
.rule_value = "true",
.notes = "Out of combat regeneration enabled in The Serpent's Spine",
},
}
};
}
inline RuleSet GetTheBuriedSeaRuleset()
{
return {
.rule_set = {
.ruleset_id = 113,
.name = "The Buried Sea",
.zone_ids = "",
.instance_versions = "",
.content_flags = "",
.content_flags_disabled = "",
.min_expansion = Expansion::TheBuriedSea,
.max_expansion = Expansion::EXPANSION_MAX,
.notes = "TBS client-based ruleset. Fellowship and item aug system added.",
},
.rules = {
{
.rule_name = "Expansion:CurrentExpansion",
.rule_value = "13",
.notes = "Current Expansion",
},
{
.rule_name = "World:CharacterSelectExpansionSettings",
.rule_value = "8191",
.notes = "The Buried Sea Client-Based Expansion Setting",
},
{
.rule_name = "World:ExpansionSettings",
.rule_value = "8191",
.notes = "The Buried Sea Client-Based Expansion Setting",
},
{
.rule_name = "Fellowship:Enabled",
.rule_value = "true",
.notes = "Fellowships were introduced in The Buried Sea",
},
{
.rule_name = "Items:AllowItemAugmenting",
.rule_value = "true",
.notes = "Item augmenting system introduced in The Buried Sea",
},
}
};
}
inline std::vector<RuleSet> GetCustomRulesets()
{
return {
{
.rule_set = {
.ruleset_id = 300,
.name = "Double Experience",
.zone_ids = "",
.instance_versions = "",
.content_flags = "",
.content_flags_disabled = "",
.min_expansion = Expansion::EXPANSION_ZERO_VALUE,
.max_expansion = Expansion::EXPANSION_ZERO_VALUE,
.notes = "Doubles EXP globally",
},
.rules = {
{
.rule_name = "Character:FinalExpMultiplier",
.rule_value = "2"
}
}
},
{
.rule_set = {
.ruleset_id = 1000,
.name = "Custom Boundary (Put your custom rulesets after here)",
.zone_ids = "",
.instance_versions = "",
.content_flags = "",
.content_flags_disabled = "",
.min_expansion = Expansion::EXPANSION_ZERO_VALUE,
.max_expansion = Expansion::EXPANSION_ZERO_VALUE,
.notes = "You may add your own rulesets above 1000+"
},
},
};
}
inline std::vector<RuleSet> GetDefaultRulesets()
{
std::vector<RuleSet> sets = {
GetClassicRuleset(),
GetKunarkRuleset(),
GetVeliousRuleset(),
GetLuclinRuleset(),
GetPlanesRuleset(),
GetLegacyOfYkeshaRuleset(),
GetLDoNRuleset(),
GetGatesOfDiscordRuleset(),
GetOmensOfWarRuleset(),
GetDragonsOfNorrathRuleset(),
GetDepthsOfDarkhollowRuleset(),
GetProphecyOfRoRuleset(),
GetTheSerpentsSpineRuleset(),
GetTheBuriedSeaRuleset(),
GetEraOverridesRuleset()
};
// Append custom rulesets
const auto custom = GetCustomRulesets();
sets.insert(sets.end(), custom.begin(), custom.end());
return sets;
}
void WorldContentService::SeedDefaultRulesets() const
{
LogInfo("Seeding default rulesets");
// Load existing rule_sets into a map
std::unordered_map<uint32_t, RuleSetsRepository::RuleSets> existing_rulesets;
for (const auto& r : RuleSetsRepository::All(*m_database)) {
existing_rulesets[r.ruleset_id] = r;
}
// Load existing rule_values into a map<ruleset_id, map<rule_name, RuleValues>>
std::unordered_map<uint32_t, std::unordered_map<std::string, RuleValuesRepository::RuleValues>> existing_rule_values;
for (const auto& r : RuleValuesRepository::All(*m_database)) {
existing_rule_values[r.ruleset_id][r.rule_name] = r;
}
std::vector<RuleSetsRepository::RuleSets> rule_sets_to_insert;
std::vector<RuleSetsRepository::RuleSets> rule_sets_to_update;
std::vector<RuleValuesRepository::RuleValues> rule_values_to_insert;
std::unordered_map<uint32_t, std::vector<std::string>> rule_values_to_delete;
for (const auto& entry : GetDefaultRulesets()) {
const auto& rs = entry.rule_set;
const auto existing_it = existing_rulesets.find(rs.ruleset_id);
if (existing_it == existing_rulesets.end()) {
rule_sets_to_insert.push_back(rs);
}
else {
const auto& existing = existing_it->second;
if (rs.name != existing.name ||
rs.zone_ids != existing.zone_ids ||
rs.instance_versions != existing.instance_versions ||
rs.content_flags != existing.content_flags ||
rs.content_flags_disabled != existing.content_flags_disabled ||
rs.min_expansion != existing.min_expansion ||
rs.max_expansion != existing.max_expansion ||
rs.notes != existing.notes) {
rule_sets_to_update.push_back(rs);
}
}
std::unordered_set<std::string> defined_rule_names;
for (auto rule : entry.rules) {
rule.ruleset_id = rs.ruleset_id;
if (rule.notes.empty()) {
rule.notes = m_rule_manager->GetRuleNotesByName(rule.rule_name);
}
defined_rule_names.insert(rule.rule_name);
auto& existing_rules = existing_rule_values[rs.ruleset_id];
if (existing_rules.find(rule.rule_name) == existing_rules.end()) {
rule_values_to_insert.push_back(rule);
}
}
for (const auto& [rule_name, _] : existing_rule_values[rs.ruleset_id]) {
if (!defined_rule_names.count(rule_name)) {
rule_values_to_delete[rs.ruleset_id].push_back(rule_name);
}
}
}
// Insert new rule sets
for (const auto& rs : rule_sets_to_insert) {
RuleSetsRepository::InsertOne(*m_database, rs);
LogInfo("Inserted ruleset [{}] {}", rs.ruleset_id, rs.name);
}
// Update modified rule sets
for (const auto& rs : rule_sets_to_update) {
RuleSetsRepository::UpdateOne(*m_database, rs);
LogInfo("Updated ruleset metadata [{}] {}", rs.ruleset_id, rs.name);
}
// Insert new rule values
if (!rule_values_to_insert.empty()) {
RuleValuesRepository::InsertMany(*m_database, rule_values_to_insert);
LogInfo("Inserted [{}] new rule(s)]", rule_values_to_insert.size());
}
// Delete obsolete rule values in batches
for (const auto& [ruleset_id, rule_names] : rule_values_to_delete) {
if (rule_names.empty()) continue;
std::string in_clause = "'" + Strings::Join(rule_names, "','") + "'";
std::string where = fmt::format("ruleset_id = {} AND rule_name IN ({})", ruleset_id, in_clause);
int removed = RuleValuesRepository::DeleteWhere(*m_database, where);
LogInfo("Deleted [{}] obsolete rule(s) from ruleset [{}]: [{}]", removed, ruleset_id, Strings::Join(rule_names, ", "));
}
}
void WorldContentService::LoadTargetedRulesets()
{
if (!m_zone_id) {
LogError("Zone ID is not set. Cannot load targeted rulesets.");
return;
}
SeedDefaultRulesets();
LogInfo("Zone ID [{}] Instance Version [{}] - Loading targeted rulesets", m_zone_id, m_instance_version);
auto rules = RuleValuesRepository::GetWhere(*m_database, "TRUE ORDER BY ruleset_id, rule_name");
auto sets = RuleSetsRepository::GetWhere(*m_database, "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::EXPANSION_ZERO_VALUE ||
e.max_expansion != 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;
}
m_rule_manager->SetRule(r.rule_name, r.rule_value);
LogInfo(
"Loaded [{}] ruleset [{}] name [{}] value [{}]",
e.ruleset_id,
e.name,
r.rule_name,
r.rule_value
);
}
}
}
+8 -8
View File
@@ -55,7 +55,7 @@ void DatabaseUpdate::CheckDbUpdates()
}
if (UpdateManifest(manifest_entries, v.server_database_version, b.server_database_version)) {
LogInfo(
LogInfoNoFn(
"Updates ran successfully, setting database version to [{}] from [{}]",
b.server_database_version,
v.server_database_version
@@ -64,7 +64,7 @@ void DatabaseUpdate::CheckDbUpdates()
}
if (UpdateManifest(manifest_entries_custom, v.custom_database_version, b.custom_database_version)) {
LogInfo(
LogInfoNoFn(
"Updates ran successfully, setting database version to [{}] from [{}]",
b.custom_database_version,
v.custom_database_version
@@ -337,9 +337,9 @@ DatabaseUpdate *DatabaseUpdate::SetSkipBackup(bool skip)
bool DatabaseUpdate::CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b)
{
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
LogInfoNoFn("{}", Strings::Repeat("-", BREAK_LENGTH));
LogInfo(
LogInfoNoFn(
"{:>8} | database [{}] binary [{}] {}",
"Server",
v.server_database_version,
@@ -348,7 +348,7 @@ bool DatabaseUpdate::CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b)
);
if (RuleB(Bots, Enabled) && b.bots_database_version > 0) {
LogInfo(
LogInfoNoFn(
"{:>8} | database [{}] binary [{}] {}",
"Bots",
v.bots_database_version,
@@ -358,7 +358,7 @@ bool DatabaseUpdate::CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b)
}
if (b.custom_database_version > 0) {
LogInfo(
LogInfoNoFn(
"{:>8} | database [{}] binary [{}] {}",
"Custom",
v.custom_database_version,
@@ -367,9 +367,9 @@ bool DatabaseUpdate::CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b)
);
}
LogInfo("{:>8} | [server.auto_database_updates] [<green>true]", "Config");
LogInfoNoFn("{:>8} | [server.auto_database_updates] [<green>true]", "Config");
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
LogInfoNoFn("{}", Strings::Repeat("-", BREAK_LENGTH));
// server database version is required
bool server_up_to_date = v.server_database_version >= b.server_database_version;
@@ -7133,6 +7133,28 @@ 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 '';
ALTER TABLE `rule_sets`
CHANGE `ruleset_id` `ruleset_id` int NOT NULL auto_increment;
ALTER TABLE `rule_values`
CHANGE `ruleset_id` `ruleset_id` int NOT NULL DEFAULT 0;
)",
.content_schema_update = false
},
+66 -139
View File
@@ -224,48 +224,22 @@ void EQEmuLogSys::ProcessConsoleMessage(
const char *file,
const char *func,
int line
)
{
) {
bool is_error = (
log_category == Logs::LogCategory::Error ||
log_category == Logs::LogCategory::MySQLError ||
log_category == Logs::LogCategory::Crash ||
log_category == Logs::LogCategory::QuestErrors
);
bool is_warning = (
log_category == Logs::LogCategory::Warning
);
bool is_warning = (log_category == Logs::LogCategory::Warning);
(!is_error ? std::cout : std::cerr)
<< ""
<< rang::fgB::black
<< rang::style::bold
<< fmt::format("{:>6}", GetPlatformName().substr(0, 6))
<< rang::style::reset
<< rang::fgB::gray
<< " | "
<< ((is_error || is_warning) ? rang::fgB::red : rang::fgB::gray)
<< rang::style::bold
<< fmt::format("{:^10}", fmt::format("{}", Logs::LogCategoryName[log_category]).substr(0, 10))
<< rang::style::reset
<< rang::fgB::gray
<< " | "
<< rang::fgB::gray
<< rang::style::bold
<< fmt::format("{}", func)
<< rang::style::reset
<< rang::fgB::gray
<< " ";
std::ostream &out = (!is_error ? std::cout : std::cerr);
if (RuleB(Logging, PrintFileFunctionAndLine)) {
(!is_error ? std::cout : std::cerr)
<< ""
<< rang::fgB::green
<< rang::style::bold
<< fmt::format("{:}", fmt::format("{}:{}:{}", std::filesystem::path(file).filename().string(), func, line))
<< rang::style::reset
<< " | ";
}
out
<< rang::style::bold << rang::fgB::gray << GetPlatformName() << " "
<< rang::fgB::gray << Logs::LogCategoryName[log_category] << " "
// << rang::fgB::gray << func << " "
<< rang::style::reset;
if (log_category == Logs::LogCategory::MySQLQuery) {
auto s = Strings::Split(message, "--");
@@ -273,132 +247,84 @@ void EQEmuLogSys::ProcessConsoleMessage(
std::string query = Strings::Trim(s[0]);
std::string meta = Strings::Trim(s[1]);
std::cout <<
rang::fgB::green
<<
query
<<
rang::style::reset;
std::cout <<
rang::fgB::black
<<
" -- "
<<
meta
<<
rang::style::reset;
out << rang::fgB::green << query << rang::style::reset;
out << rang::fgB::black << " -- " << meta << rang::style::reset;
}
}
else if (Strings::Contains(message, "[")) {
for (auto &e: Strings::Split(message, " ")) {
if (Strings::Contains(e, "[") && Strings::Contains(e, "]")) {
e = Strings::Replace(e, "[", "");
e = Strings::Replace(e, "]", "");
} else {
std::vector<std::string> tokens = Strings::Split(message, " ");
bool is_upper = false;
for (auto &token : tokens) {
bool has_brackets = Strings::Contains(token, "[") && Strings::Contains(token, "]");
std::string clean_token = Strings::Replace(Strings::Replace(token, "[", ""), "]", "");
for (int i = 0; i < strlen(e.c_str()); i++) {
if (isupper(e[i])) {
is_upper = true;
}
}
// color matching in []
// ex: [<red>variable] would produce [variable] with red inside brackets
std::map<std::string, rang::fgB> colors = {
{"<black>", rang::fgB::black},
{"<green>", rang::fgB::green},
{"<yellow>", rang::fgB::yellow},
{"<blue>", rang::fgB::blue},
// Bracket formatting
if (has_brackets) {
static std::map<std::string, rang::fgB> color_tags = {
{"<black>", rang::fgB::black},
{"<green>", rang::fgB::green},
{"<yellow>", rang::fgB::yellow},
{"<blue>", rang::fgB::blue},
{"<magenta>", rang::fgB::magenta},
{"<cyan>", rang::fgB::cyan},
{"<gray>", rang::fgB::gray},
{"<red>", rang::fgB::red},
{"<cyan>", rang::fgB::cyan},
{"<gray>", rang::fgB::gray},
{"<red>", rang::fgB::red},
};
bool match_color = false;
for (auto &c: colors) {
if (Strings::Contains(e, c.first)) {
e = Strings::Replace(e, c.first, "");
(!is_error ? std::cout : std::cerr)
<< rang::fgB::gray
<< "["
<< rang::style::bold
<< c.second
<< e
<< rang::style::reset
<< rang::fgB::gray
<< "] ";
match_color = true;
}
}
// string match to colors
std::map<std::string, rang::fgB> matches = {
static std::map<std::string, rang::fgB> keyword_matches = {
{"missing", rang::fgB::red},
{"error", rang::fgB::red},
{"ok", rang::fgB::green},
};
for (auto &c: matches) {
if (Strings::Contains(e, c.first)) {
(!is_error ? std::cout : std::cerr)
<< rang::fgB::gray
<< "["
<< rang::style::bold
<< c.second
<< e
<< rang::style::reset
<< rang::fgB::gray
<< "] ";
match_color = true;
bool matched = false;
for (auto &[tag, color] : color_tags) {
if (Strings::Contains(clean_token, tag)) {
clean_token = Strings::Replace(clean_token, tag, "");
out << rang::fgB::gray << "["
<< rang::style::bold << color << clean_token
<< rang::style::reset << rang::fgB::gray << "] ";
matched = true;
break;
}
}
// if we don't match a color in either the string matching or
// the color tag matching, we default to yellow inside brackets
// if uppercase, does not get colored
if (!match_color) {
if (!is_upper) {
(!is_error ? std::cout : std::cerr)
<< rang::fgB::gray
<< "["
<< rang::style::bold
<< rang::fgB::yellow
<< e
<< rang::style::reset
<< rang::fgB::gray
<< "] ";
}
else {
(!is_error ? std::cout : std::cerr) << rang::fgB::gray << "[" << e << "] ";
if (!matched) {
for (auto &[keyword, color] : keyword_matches) {
if (Strings::Contains(clean_token, keyword)) {
out << rang::fgB::gray << "["
<< rang::style::bold << color << clean_token
<< rang::style::reset << rang::fgB::gray << "] ";
matched = true;
break;
}
}
}
}
else {
(!is_error ? std::cout : std::cerr)
<< (is_error ? rang::fgB::red : rang::fgB::gray)
<< e
<< " ";
if (!matched) {
bool is_upper = std::any_of(clean_token.begin(), clean_token.end(), ::isupper);
if (!is_upper) {
out << rang::fgB::gray << "["
<< rang::style::bold << "\033[92m" << clean_token
<< rang::style::reset << rang::fgB::gray << "] ";
} else {
out << rang::fgB::gray << "[" << clean_token << "] ";
}
}
} else {
out << (is_error ? rang::fgB::red : rang::fgB::gray) << token << " ";
}
}
}
else {
(!is_error ? std::cout : std::cerr)
<< (is_error ? rang::fgB::red : rang::fgB::gray)
<< message
<< " ";
// check if func is not empty
if (func && *func) {
out << rang::fgB::black << "#" << func << " ";
}
if (!origination_info.zone_short_name.empty()) {
(!is_error ? std::cout : std::cerr)
<<
rang::fgB::black
<<
"-- "
<<
fmt::format(
out << rang::fgB::black << "-- "
<< fmt::format(
"[{}] ({}) inst_id [{}]",
origination_info.zone_short_name,
origination_info.zone_long_name,
@@ -406,11 +332,12 @@ void EQEmuLogSys::ProcessConsoleMessage(
);
}
(!is_error ? std::cout : std::cerr) << rang::style::reset << std::endl;
out << rang::style::reset << std::endl;
m_on_log_console_hook(log_category, message);
}
/**
* @param str
* @return
+10
View File
@@ -449,6 +449,11 @@ inline auto logsys = EQEmuLogSys::Instance();
OutF(logsys, Logs::General, Logs::Info, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogInfoNoFn(message, ...) do {\
if (logsys->IsLogEnabled(Logs::General, Logs::Info))\
OutF(logsys, Logs::General, Logs::Info, "", "", 0, message, ##__VA_ARGS__);\
} while (0)
#define LogInfoDetail(message, ...) do {\
if (logsys->IsLogEnabled(Logs::Detail, Logs::Info))\
OutF(logsys, Logs::Detail, Logs::Info, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
@@ -459,6 +464,11 @@ inline auto logsys = EQEmuLogSys::Instance();
OutF(logsys, Logs::General, Logs::Warning, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogWarningNoFn(message, ...) do {\
if (logsys->IsLogEnabled(Logs::General, Logs::Info))\
OutF(logsys, Logs::General, Logs::Warning, "", "", 0, message, ##__VA_ARGS__);\
} while (0)
#define LogWarningDetail(message, ...) do {\
if (logsys->IsLogEnabled(Logs::Detail, Logs::Warning))\
OutF(logsys, Logs::Detail, Logs::Warning, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
+4 -4
View File
@@ -87,16 +87,16 @@ void PathManager::Init()
constexpr int break_length = 70;
LogInfo("Loading server paths");
LogInfo("{}", Strings::Repeat("-", break_length));
LogInfoNoFn("{}", Strings::Repeat("-", break_length));
for (const auto& [name, in_path] : paths) {
if (!in_path.empty()) {
LogInfo("{:>{}} > [{:<{}}]", name, name_width, in_path, path_width);
LogInfoNoFn("{:>{}} > {:<{}}", name, name_width, in_path, path_width);
}
}
auto log_paths = [&](const std::string& label, const std::vector<std::string>& paths) {
if (!paths.empty()) {
LogInfo("{:>{}} > [{:<{}}]", label, name_width - 1, Strings::Join(paths, ";"), path_width);
LogInfoNoFn("{:>{}} > {:<{}}", label, name_width, Strings::Join(paths, ";"), path_width);
}
};
@@ -104,7 +104,7 @@ void PathManager::Init()
log_paths("plugins", m_plugin_paths);
log_paths("lua_modules", m_lua_module_paths);
LogInfo("{}", Strings::Repeat("-", break_length));
LogInfoNoFn("{}", Strings::Repeat("-", break_length));
}
const std::string &PathManager::GetServerPath() const
@@ -19,8 +19,15 @@
class BaseRuleSetsRepository {
public:
struct RuleSets {
uint8_t ruleset_id;
int32_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<int32_t>(atoi(row[0])) : 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<int32_t>(atoi(row[0])) : 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<int32_t>(atoi(row[0])) : 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) + ")");
}
@@ -19,7 +19,7 @@
class BaseRuleValuesRepository {
public:
struct RuleValues {
uint8_t ruleset_id;
int32_t ruleset_id;
std::string rule_name;
std::string rule_value;
std::string notes;
@@ -127,7 +127,7 @@ public:
if (results.RowCount() == 1) {
RuleValues e{};
e.ruleset_id = row[0] ? static_cast<uint8_t>(strtoul(row[0], nullptr, 10)) : 0;
e.ruleset_id = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
e.rule_name = row[1] ? row[1] : "";
e.rule_value = row[2] ? row[2] : "";
e.notes = row[3] ? row[3] : "";
@@ -259,7 +259,7 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) {
RuleValues e{};
e.ruleset_id = row[0] ? static_cast<uint8_t>(strtoul(row[0], nullptr, 10)) : 0;
e.ruleset_id = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
e.rule_name = row[1] ? row[1] : "";
e.rule_value = row[2] ? row[2] : "";
e.notes = row[3] ? row[3] : "";
@@ -287,7 +287,7 @@ public:
for (auto row = results.begin(); row != results.end(); ++row) {
RuleValues e{};
e.ruleset_id = row[0] ? static_cast<uint8_t>(strtoul(row[0], nullptr, 10)) : 0;
e.ruleset_id = row[0] ? static_cast<int32_t>(atoi(row[0])) : 0;
e.rule_name = row[1] ? row[1] : "";
e.rule_value = row[2] ? row[2] : "";
e.notes = row[3] ? row[3] : "";
+17 -1
View File
@@ -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();
}
return true;
}
@@ -662,3 +666,15 @@ std::string RuleManager::GetStringRule(RuleManager::StringType t) const
{
return m_RuleStringValues[t];
}
std::string RuleManager::GetRuleNotesByName(std::string rule_name) const
{
for (const auto &r : s_RuleInfo) {
if (Strings::EqualFold(r.name, rule_name)) {
return r.notes;
}
}
LogRulesDetail("Unable to find rule notes for '{}'.", rule_name);
return "";
}
+11 -3
View File
@@ -40,6 +40,7 @@
RuleManager::Instance()->GetStringRule( RuleManager::String__##rule_name )
#include <functional>
#include <vector>
#include <string>
#include <map>
@@ -119,9 +120,9 @@ public:
static const uint32 RulesCount = IntRuleCount + RealRuleCount + BoolRuleCount + StringRuleCount;
//fetch routines, you should generally use the Rule* macros instead of this
int GetIntRule(IntType t) const;
float GetRealRule(RealType t) const;
bool GetBoolRule(BoolType t) const;
int GetIntRule(IntType t) const;
float GetRealRule(RealType t) const;
bool GetBoolRule(BoolType t) const;
std::string GetStringRule(StringType t) const;
//management routines
@@ -133,6 +134,8 @@ public:
static const std::string& GetRuleNotes(RealType t) { return s_RuleInfo[static_cast<int>(t) + IntRuleCount].notes; }
static const std::string& GetRuleNotes(BoolType t) { return s_RuleInfo[static_cast<int>(t) + IntRuleCount + RealRuleCount].notes; }
static const std::string& GetRuleNotes(StringType t) { return s_RuleInfo[static_cast<int>(t) + IntRuleCount + RealRuleCount + StringRuleCount].notes; }
std::string GetRuleNotesByName(std::string rule_name) const;
static uint32 CountRules() { return RulesCount; }
static CategoryType FindCategory(const std::string& category_name);
bool ListRules(const std::string& category_name, std::vector<std::string>& l);
@@ -156,6 +159,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()> cb) {
m_post_load_callback = std::move(cb);
}
private:
RuleManager();
@@ -170,6 +176,8 @@ private:
uint32 m_RuleBoolValues[BoolRuleCount];
std::string m_RuleStringValues[StringRuleCount];
std::function<void()> m_post_load_callback;
typedef enum {
IntRule,
RealRule,
+1 -1
View File
@@ -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
+55 -88
View File
@@ -419,7 +419,7 @@ void WorldBoot::CheckForPossibleConfigurationIssues()
const auto c = EQEmuConfig::get();
if (c->DisableConfigChecks) {
LogInfo("Configuration checking [disabled]");
LogInfoNoFn("Configuration checking [disabled]");
return;
}
@@ -429,17 +429,17 @@ void WorldBoot::CheckForPossibleConfigurationIssues()
const std::ifstream is_in_docker("/.dockerenv");
if (local_address.empty() && public_address.empty()) {
LogInfo("Configuration check, probes failed for local and public address, returning");
LogInfoNoFn("Configuration check, probes failed for local and public address, returning");
return;
}
LogInfo("Checking for possible configuration issues");
LogInfo("To disable configuration checks, set [server.disable_config_checks] to [true] in [{}]", config_file);
LogInfoNoFn("Checking for possible configuration issues");
LogInfoNoFn("To disable configuration checks, set [server.disable_config_checks] to [true] in [{}]", config_file);
std::string config_address = c->WorldAddress;
if (!IpUtil::IsIPAddress(config_address)) {
config_address = IpUtil::DNSLookupSync(c->WorldAddress, 9000);
LogInfo(
LogInfoNoFn(
"World config address using DNS [{}] resolves to [{}]",
c->WorldAddress,
config_address
@@ -454,16 +454,12 @@ void WorldBoot::CheckForPossibleConfigurationIssues()
&& local_address != c->LocalAddress
&& !is_in_docker
) {
LogWarning("# LAN detection (Configuration)");
LogWarning("");
LogWarning("You appear to be on a LAN and your localaddress may not be properly set!");
LogWarning("This can prevent local clients from properly connecting to your server");
LogWarning("");
LogWarning("Docs [https://docs.eqemu.io/server/installation/configure-your-eqemu_config/#world]");
LogWarning("");
LogWarning("Config file [{}] path [server.world] variable [localaddress]", config_file);
LogWarning("");
LogWarning("Local address (eqemu_config) value [{}] detected value [{}]", c->LocalAddress, local_address);
LogWarningNoFn("# LAN detection (Configuration)");
LogWarningNoFn("You appear to be on a LAN and your localaddress may not be properly set!");
LogWarningNoFn("This can prevent local clients from properly connecting to your server");
LogWarningNoFn("Docs [https://docs.eqemu.io/server/installation/configure-your-eqemu_config/#world]");
LogWarningNoFn("Config file [{}] path [server.world] variable [localaddress]", config_file);
LogWarningNoFn("Local address (eqemu_config) value [{}] detected value [{}]", c->LocalAddress, local_address);
std::cout << std::endl;
}
@@ -475,28 +471,21 @@ void WorldBoot::CheckForPossibleConfigurationIssues()
)
&& is_in_docker
) {
LogWarning("# Docker Configuration (Configuration)");
LogWarning("");
LogWarning("You appear to running EQEmu in a docker container");
LogWarning("In order for networking to work properly you will need to properly configure your server");
LogWarning("");
LogWarning(
LogWarningNoFn("# Docker Configuration (Configuration)");
LogWarningNoFn("You appear to running EQEmu in a docker container");
LogWarningNoFn("In order for networking to work properly you will need to properly configure your server");
LogWarningNoFn(
"If your Docker host is on a [LAN] or behind a NAT / Firewall, your [localaddress] variable under [server.world] will need to");
LogWarning(
LogWarningNoFn(
"be set to your LAN address on the host, not the container address. [address] will need to be your public address");
LogWarning("");
LogWarning(
LogWarningNoFn(
"If your Docker host is directly on the [public internet], your [localaddress] variable under [server.world] can be set to [127.0.0.1]."
);
LogWarning("");
LogWarning("[address] will need to be your public address");
LogWarning("");
LogWarning("Docs [https://docs.eqemu.io/server/installation/configure-your-eqemu_config/#world]");
LogWarning("");
LogWarning("Config file [{}] path [server.world] variable(s) [localaddress] [address]", config_file);
LogWarning("");
LogWarning("Local address (eqemu_config) value [{}] detected value [{}]", c->LocalAddress, local_address);
LogWarning(
LogWarningNoFn("[address] will need to be your public address");
LogWarningNoFn("Docs [https://docs.eqemu.io/server/installation/configure-your-eqemu_config/#world]");
LogWarningNoFn("Config file [{}] path [server.world] variable(s) [localaddress] [address]", config_file);
LogWarningNoFn("Local address (eqemu_config) value [{}] detected value [{}]", c->LocalAddress, local_address);
LogWarningNoFn(
"Public address (eqemu_config) value [{}] detected value [{}]",
config_address,
public_address
@@ -506,30 +495,23 @@ void WorldBoot::CheckForPossibleConfigurationIssues()
// docker LAN not set
if (c->LocalAddress.empty() && is_in_docker) {
LogWarning("# Docker LAN (Configuration)");
LogWarning("");
LogWarning("You appear to running EQEmu in a docker container");
LogWarning(
LogWarningNoFn("# Docker LAN (Configuration)");
LogWarningNoFn("You appear to running EQEmu in a docker container");
LogWarningNoFn(
"Your local address does not appear to be set, this may not be an issue if your deployment is not on a LAN"
);
LogWarning("");
LogWarning(
LogWarningNoFn(
"If your Docker host is on a [LAN] or behind a NAT / Firewall, your [localaddress] variable under [server.world] will need to");
LogWarning(
LogWarningNoFn(
"be set to your LAN address on the host, not the container address. [address] will need to be your public address");
LogWarning("");
LogWarning(
LogWarningNoFn(
"If your Docker host is directly on the [public internet], your [localaddress] variable under [server.world] can be set to [127.0.0.1]."
);
LogWarning("");
LogWarning("[address] will need to be your public address");
LogWarning("");
LogWarning("Docs [https://docs.eqemu.io/server/installation/configure-your-eqemu_config/#world]");
LogWarning("");
LogWarning("Config file [{}] path [server.world] variable(s) [localaddress] [address]", config_file);
LogWarning("");
LogWarning("Local address (eqemu_config) value [{}] detected value [{}]", c->LocalAddress, local_address);
LogWarning(
LogWarningNoFn("[address] will need to be your public address");
LogWarningNoFn("Docs [https://docs.eqemu.io/server/installation/configure-your-eqemu_config/#world]");
LogWarningNoFn("Config file [{}] path [server.world] variable(s) [localaddress] [address]", config_file);
LogWarningNoFn("Local address (eqemu_config) value [{}] detected value [{}]", c->LocalAddress, local_address);
LogWarningNoFn(
"Public address (eqemu_config) value [{}] detected value [{}]",
config_address,
public_address
@@ -539,15 +521,11 @@ void WorldBoot::CheckForPossibleConfigurationIssues()
// public address different from configuration
if (!config_address.empty() && public_address != config_address) {
LogWarning("# Public address (Configuration)");
LogWarning("");
LogWarning("Your configured public address appears to be different from what's detected!");
LogWarning("");
LogWarning("Docs [https://docs.eqemu.io/server/installation/configure-your-eqemu_config/#world]");
LogWarning("");
LogWarning("Config file [{}] path [server.world] variable [address]", config_file);
LogWarning("");
LogWarning(
LogWarningNoFn("# Public address (Configuration)");
LogWarningNoFn("Your configured public address appears to be different from what's detected!");
LogWarningNoFn("Docs [https://docs.eqemu.io/server/installation/configure-your-eqemu_config/#world]");
LogWarningNoFn("Config file [{}] path [server.world] variable [address]", config_file);
LogWarningNoFn(
"Public address (eqemu_config) value [{}] detected value [{}]",
config_address,
public_address
@@ -557,17 +535,13 @@ void WorldBoot::CheckForPossibleConfigurationIssues()
// public address set to meta-address
if (config_address == "0.0.0.0") {
LogWarning("# Public meta-address (Configuration)");
LogWarning("");
LogWarning("Your configured public address is set to a meta-address (0.0.0.0) (all-interfaces)");
LogWarning(
LogWarningNoFn("# Public meta-address (Configuration)");
LogWarningNoFn("Your configured public address is set to a meta-address (0.0.0.0) (all-interfaces)");
LogWarningNoFn(
"The meta-address may not work properly and it is recommended you configure your public address explicitly");
LogWarning("");
LogWarning("Docs [https://docs.eqemu.io/server/installation/configure-your-eqemu_config/#world]");
LogWarning("");
LogWarning("Config file [{}] path [server.world] variable [address]", config_file);
LogWarning("");
LogWarning(
LogWarningNoFn("Docs [https://docs.eqemu.io/server/installation/configure-your-eqemu_config/#world]");
LogWarningNoFn("Config file [{}] path [server.world] variable [address]", config_file);
LogWarningNoFn(
"Public address (eqemu_config) value [{}] detected value [{}]",
config_address,
public_address
@@ -577,18 +551,14 @@ void WorldBoot::CheckForPossibleConfigurationIssues()
// local address set to meta-address
if (c->LocalAddress == "0.0.0.0") {
LogWarning("# Local meta-address (Configuration)");
LogWarning("");
LogWarning("Your configured local address is set to a meta-address (0.0.0.0) (all-interfaces)");
LogWarning(
LogWarningNoFn("# Local meta-address (Configuration)");
LogWarningNoFn("Your configured local address is set to a meta-address (0.0.0.0) (all-interfaces)");
LogWarningNoFn(
"The meta-address may not work properly and it is recommended you configure your local address explicitly"
);
LogWarning("");
LogWarning("Docs [https://docs.eqemu.io/server/installation/configure-your-eqemu_config/#world]");
LogWarning("");
LogWarning("Config file [{}] path [server.world] variable [localaddress]", config_file);
LogWarning("");
LogWarning("Local address (eqemu_config) value [{}] detected value [{}]", c->LocalAddress, local_address);
LogWarningNoFn("Docs [https://docs.eqemu.io/server/installation/configure-your-eqemu_config/#world]");
LogWarningNoFn("Config file [{}] path [server.world] variable [localaddress]", config_file);
LogWarningNoFn("Local address (eqemu_config) value [{}] detected value [{}]", c->LocalAddress, local_address);
std::cout << std::endl;
}
@@ -596,16 +566,13 @@ void WorldBoot::CheckForPossibleConfigurationIssues()
if (
(!config_address.empty() && c->GetUCSHost() != config_address)
) {
LogWarning("# UCS Address Mailhost (Configuration)");
LogWarning("");
LogWarning(
LogWarningNoFn("# UCS Address Mailhost (Configuration)");
LogWarningNoFn(
"UCS (Universal Chat Service) mail or chat appears to use a different address from your main world address"
);
LogWarning("This can result in a chat service that doesn't network properly");
LogWarning("");
LogWarning("Docs [https://docs.eqemu.io/server/installation/configure-your-eqemu_config/#mailserver]");
LogWarning("");
LogWarning(
LogWarningNoFn("This can result in a chat service that doesn't network properly");
LogWarningNoFn("Docs [https://docs.eqemu.io/server/installation/configure-your-eqemu_config/#mailserver]");
LogWarningNoFn(
"[server.world.address] value [{}] [server.ucs.host] [{}]",
config_address,
c->GetUCSHost()
+5
View File
@@ -413,6 +413,11 @@ int main(int argc, char **argv)
->ReloadContentFlags();
ZoneEventScheduler::Instance()->SetDatabase(&database)->LoadScheduledEvents();
RuleManager::Instance()->SetPostLoadCallback(
[&]() {
WorldContentService::Instance()->LoadTargetedRulesets();
}
);
EQ::SayLinkEngine::LoadCachedSaylinks();
+17 -6
View File
@@ -1151,12 +1151,7 @@ bool Zone::Init(bool is_static) {
);
} // if that fails, try the file name, then load defaults
if (RuleManager::Instance()->GetActiveRulesetID() != default_ruleset) {
std::string r_name = RuleSetsRepository::GetRuleSetName(database, default_ruleset);
if (r_name.size() > 0) {
RuleManager::Instance()->LoadRules(&database, r_name, false);
}
}
LoadRules();
if (!map_name) {
LogError("No map name found for zone [{}]", GetShortName());
@@ -3559,4 +3554,20 @@ void Zone::SendPayload(int payload_id, std::string payload_value)
}
}
void Zone::LoadRules()
{
if (GetZoneID() > 0) {
WorldContentService::Instance()->SetZoneId(GetZoneID());
WorldContentService::Instance()->SetInstanceVersion(GetInstanceVersion());
}
const auto rm = RuleManager::Instance();
rm->LoadRules(&database, rm->GetActiveRuleset(), true);
if (rm->GetActiveRulesetID() != default_ruleset) {
std::string r_name = RuleSetsRepository::GetRuleSetName(database, default_ruleset);
if (r_name.size() > 0) {
rm->LoadRules(&database, r_name, false);
}
}
}
#include "zone_loot.cpp"
+1
View File
@@ -485,6 +485,7 @@ public:
void SaveZoneState();
static void ClearZoneState(uint32 zone_id, uint32 instance_id);
void ReloadMaps();
void LoadRules();
void Signal(int signal_id);
void SendPayload(int payload_id, std::string payload_value);