diff --git a/changelog.txt b/changelog.txt index 3e2c4f671..51b8821a0 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,14 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 1/11/2019 == +Uleat: Modified rules system to ignore all runtime modifications of 'World:ExpansionSettings' and 'World:UseClientBasedExpansionSettings' fields. + - These fields are no longer allowed to be changed during server runtime through the command system + - Major syncronization issues between server and clients result when these fields are altered in-game + - It is not recommended to update these fields via sql queries while the server is in operation + - Failure to observe these warnings will result in abhorant behavior and loss of items + - Modify these fields during server operation at your own risk! + == 1/4/2019 == Akkadius: [Scaling] Global base scaling data has been updated in new database binary revision diff --git a/common/rulesys.cpp b/common/rulesys.cpp index 61bb72357..d4ff3d4d9 100644 --- a/common/rulesys.cpp +++ b/common/rulesys.cpp @@ -61,7 +61,7 @@ RuleManager::RuleManager() : m_activeRuleset(0), m_activeName("default") { - ResetRules(); + ResetRules(false); } RuleManager::CategoryType RuleManager::FindCategory(const char *catname) { @@ -126,7 +126,7 @@ bool RuleManager::GetRule(const char *rule_name, std::string &return_value) { return true; } -bool RuleManager::SetRule(const char *rule_name, const char *rule_value, Database *database, bool db_save) { +bool RuleManager::SetRule(const char *rule_name, const char *rule_value, Database *database, bool db_save, bool reload) { if(rule_name == nullptr || rule_value == nullptr) return(false); @@ -135,6 +135,13 @@ bool RuleManager::SetRule(const char *rule_name, const char *rule_value, Databas if(!_FindRule(rule_name, type, index)) return(false); + if (reload) { + if (strcasecmp(rule_name, "World:ExpansionSettings") == 0) + return(false); + if (strcasecmp(rule_name, "World:UseClientBasedExpansionSettings") == 0) + return(false); + } + switch(type) { case IntRule: m_RuleIntValues[index] = atoi(rule_value); @@ -160,7 +167,16 @@ bool RuleManager::SetRule(const char *rule_name, const char *rule_value, Databas return(true); } -void RuleManager::ResetRules() { +void RuleManager::ResetRules(bool reload) { + std::string expansion1; + std::string expansion2; + + // these rules must not change during server runtime + if (reload) { + GetRule("World:ExpansionSettings", expansion1); + GetRule("World:UseClientBasedExpansionSettings", expansion2); + } + Log(Logs::Detail, Logs::Rules, "Resetting running rules to default values"); #define RULE_INT(cat, rule, default_value) \ m_RuleIntValues[ Int__##rule ] = default_value; @@ -169,6 +185,12 @@ void RuleManager::ResetRules() { #define RULE_BOOL(cat, rule, default_value) \ m_RuleBoolValues[ Bool__##rule ] = default_value; #include "ruletypes.h" + + // restore these rules to their pre-reset values + if (reload) { + SetRule("World:ExpansionSettings", expansion1.c_str(), nullptr, false, false); + SetRule("World:UseClientBasedExpansionSettings", expansion2.c_str(), nullptr, false, false); + } } bool RuleManager::_FindRule(const char *rule_name, RuleType &type_into, uint16 &index_into) { @@ -235,7 +257,7 @@ void RuleManager::SaveRules(Database *database, const char *ruleset_name) { } } -bool RuleManager::LoadRules(Database *database, const char *ruleset_name) { +bool RuleManager::LoadRules(Database *database, const char *ruleset_name, bool reload) { int ruleset_id = this->GetRulesetID(database, ruleset_name); if (ruleset_id < 0) { @@ -269,7 +291,7 @@ bool RuleManager::LoadRules(Database *database, const char *ruleset_name) { return false; for (auto row = results.begin(); row != results.end(); ++row) - if (!SetRule(row[0], row[1], nullptr, false)) + if (!SetRule(row[0], row[1], nullptr, false, reload)) Log(Logs::Detail, Logs::Rules, "Unable to interpret rule record for %s", row[0]); } @@ -279,7 +301,7 @@ bool RuleManager::LoadRules(Database *database, const char *ruleset_name) { return false; for (auto row = results.begin(); row != results.end(); ++row) - if (!SetRule(row[0], row[1], nullptr, false)) + if (!SetRule(row[0], row[1], nullptr, false, reload)) Log(Logs::Detail, Logs::Rules, "Unable to interpret rule record for %s", row[0]); return true; @@ -288,6 +310,11 @@ bool RuleManager::LoadRules(Database *database, const char *ruleset_name) { void RuleManager::_SaveRule(Database *database, RuleType type, uint16 index) { char value_string[100]; + if (type == IntRule && strcasecmp(_GetRuleName(type, index), "World:ExpansionSettings") == 0) + return; + if (type == BoolRule && strcasecmp(_GetRuleName(type, index), "World:UseClientBasedExpansionSettings") == 0) + return; + switch (type) { case IntRule: sprintf(value_string, "%d", m_RuleIntValues[index]); diff --git a/common/rulesys.h b/common/rulesys.h index 25c3a4019..710c6d612 100644 --- a/common/rulesys.h +++ b/common/rulesys.h @@ -102,7 +102,7 @@ public: bool ListRules(const char *catname, std::vector &into); bool ListCategories(std::vector &into); bool GetRule(const char *rule_name, std::string &ret_val); - bool SetRule(const char *rule_name, const char *rule_value, Database *db = nullptr, bool db_save = false); + bool SetRule(const char *rule_name, const char *rule_value, Database *db = nullptr, bool db_save = false, bool reload = false); int GetActiveRulesetID() const { return(m_activeRuleset); } const char *GetActiveRuleset() const { return(m_activeName.c_str()); } @@ -110,8 +110,8 @@ public: static std::string GetRulesetName(Database *db, int id); static bool ListRulesets(Database *db, std::map &into); - void ResetRules(); - bool LoadRules(Database *db, const char *ruleset = nullptr); + void ResetRules(bool reload = false); + bool LoadRules(Database *db, const char *ruleset = nullptr, bool reload = false); void SaveRules(Database *db, const char *ruleset = nullptr); private: diff --git a/ucs/ucs.cpp b/ucs/ucs.cpp index b9e7f41b4..21e525cbe 100644 --- a/ucs/ucs.cpp +++ b/ucs/ucs.cpp @@ -102,13 +102,14 @@ int main() { char tmp[64]; + // ucs has no 'reload rules' handler if (database.GetVariable("RuleSet", tmp, sizeof(tmp)-1)) { Log(Logs::General, Logs::UCS_Server, "Loading rule set '%s'", tmp); - if(!RuleManager::Instance()->LoadRules(&database, tmp)) { + if(!RuleManager::Instance()->LoadRules(&database, tmp, false)) { Log(Logs::General, Logs::UCS_Server, "Failed to load ruleset '%s', falling back to defaults.", tmp); } } else { - if(!RuleManager::Instance()->LoadRules(&database, "default")) { + if(!RuleManager::Instance()->LoadRules(&database, "default", false)) { Log(Logs::General, Logs::UCS_Server, "No rule set configured, using default rules"); } else { Log(Logs::General, Logs::UCS_Server, "Loaded default rule set 'default'", tmp); diff --git a/world/net.cpp b/world/net.cpp index 7065ea6c3..77deec265 100644 --- a/world/net.cpp +++ b/world/net.cpp @@ -336,12 +336,12 @@ int main(int argc, char** argv) { std::string tmp; if (database.GetVariable("RuleSet", tmp)) { Log(Logs::General, Logs::World_Server, "Loading rule set '%s'", tmp.c_str()); - if (!RuleManager::Instance()->LoadRules(&database, tmp.c_str())) { + if (!RuleManager::Instance()->LoadRules(&database, tmp.c_str(), false)) { Log(Logs::General, Logs::World_Server, "Failed to load ruleset '%s', falling back to defaults.", tmp.c_str()); } } else { - if (!RuleManager::Instance()->LoadRules(&database, "default")) { + if (!RuleManager::Instance()->LoadRules(&database, "default", false)) { Log(Logs::General, Logs::World_Server, "No rule set configured, using default rules"); } else { @@ -622,4 +622,4 @@ void CheckForServerScript(bool force_download) { system("wget -N --no-check-certificate --quiet -O eqemu_server.pl https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_server.pl"); #endif } -} \ No newline at end of file +} diff --git a/world/zoneserver.cpp b/world/zoneserver.cpp index 7d638d100..7eaa7e3c1 100644 --- a/world/zoneserver.cpp +++ b/world/zoneserver.cpp @@ -814,12 +814,12 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) { } case ServerOP_ReloadRules: { zoneserver_list.SendPacket(pack); - RuleManager::Instance()->LoadRules(&database, "default"); + RuleManager::Instance()->LoadRules(&database, "default", true); break; } case ServerOP_ReloadRulesWorld: { - RuleManager::Instance()->LoadRules(&database, "default"); + RuleManager::Instance()->LoadRules(&database, "default", true); break; } case ServerOP_ReloadPerlExportSettings: diff --git a/zone/command.cpp b/zone/command.cpp index bccf0747a..f65a4cd11 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -8345,7 +8345,7 @@ void command_rules(Client *c, const Seperator *sep) { c->Message(0, "(%d) %s", cur->first, cur->second.c_str()); } } else if(!strcasecmp(sep->arg[1], "reload")) { - RuleManager::Instance()->LoadRules(&database, RuleManager::Instance()->GetActiveRuleset()); + RuleManager::Instance()->LoadRules(&database, RuleManager::Instance()->GetActiveRuleset(), true); c->Message(0, "The active ruleset (%s (%d)) has been reloaded", RuleManager::Instance()->GetActiveRuleset(), RuleManager::Instance()->GetActiveRulesetID()); } else if(!strcasecmp(sep->arg[1], "switch")) { @@ -8361,7 +8361,7 @@ void command_rules(Client *c, const Seperator *sep) { } //TODO: we likely want to reload this ruleset everywhere... - RuleManager::Instance()->LoadRules(&database, sep->arg[2]); + RuleManager::Instance()->LoadRules(&database, sep->arg[2], true); c->Message(0, "The selected ruleset has been changed to (%s (%d)) and reloaded locally", sep->arg[2], rsid); } else if(!strcasecmp(sep->arg[1], "load")) { @@ -8371,7 +8371,7 @@ void command_rules(Client *c, const Seperator *sep) { c->Message(13, "Unknown rule set '%s'", sep->arg[2]); return; } - RuleManager::Instance()->LoadRules(&database, sep->arg[2]); + RuleManager::Instance()->LoadRules(&database, sep->arg[2], true); c->Message(0, "Loaded ruleset '%s' (%d) locally", sep->arg[2], rsid); } else if(!strcasecmp(sep->arg[1], "store")) { if(sep->argnum == 1) { @@ -8395,9 +8395,9 @@ void command_rules(Client *c, const Seperator *sep) { return; } } else if(!strcasecmp(sep->arg[1], "reset")) { - RuleManager::Instance()->ResetRules(); + RuleManager::Instance()->ResetRules(true); c->Message(0, "The running ruleset has been set to defaults"); - + } else if(!strcasecmp(sep->arg[1], "get")) { if(sep->argnum != 2) { c->Message(13, "Invalid argument count, see help."); @@ -8414,7 +8414,7 @@ void command_rules(Client *c, const Seperator *sep) { c->Message(13, "Invalid argument count, see help."); return; } - if(!RuleManager::Instance()->SetRule(sep->arg[2], sep->arg[3])) { + if(!RuleManager::Instance()->SetRule(sep->arg[2], sep->arg[3], nullptr, false, true)) { c->Message(13, "Failed to modify rule"); } else { c->Message(0, "Rule modified locally."); @@ -8424,7 +8424,7 @@ void command_rules(Client *c, const Seperator *sep) { c->Message(13, "Invalid argument count, see help."); return; } - if(!RuleManager::Instance()->SetRule(sep->arg[2], sep->arg[3], &database, true)) { + if(!RuleManager::Instance()->SetRule(sep->arg[2], sep->arg[3], &database, true, true)) { c->Message(13, "Failed to modify rule"); } else { c->Message(0, "Rule modified locally and in the database."); diff --git a/zone/net.cpp b/zone/net.cpp index 641c69248..9e896fead 100644 --- a/zone/net.cpp +++ b/zone/net.cpp @@ -362,12 +362,12 @@ int main(int argc, char** argv) { std::string tmp; if (database.GetVariable("RuleSet", tmp)) { Log(Logs::General, Logs::Zone_Server, "Loading rule set '%s'", tmp.c_str()); - if (!RuleManager::Instance()->LoadRules(&database, tmp.c_str())) { + if (!RuleManager::Instance()->LoadRules(&database, tmp.c_str(), false)) { Log(Logs::General, Logs::Error, "Failed to load ruleset '%s', falling back to defaults.", tmp.c_str()); } } else { - if (!RuleManager::Instance()->LoadRules(&database, "default")) { + if (!RuleManager::Instance()->LoadRules(&database, "default", false)) { Log(Logs::General, Logs::Zone_Server, "No rule set configured, using default rules"); } else { diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index 7b5524605..e187a3144 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -1772,7 +1772,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) zone->GetLongName(), zone->GetInstanceID() ); - RuleManager::Instance()->LoadRules(&database, RuleManager::Instance()->GetActiveRuleset()); + RuleManager::Instance()->LoadRules(&database, RuleManager::Instance()->GetActiveRuleset(), true); break; } case ServerOP_ReloadLogs: { diff --git a/zone/zone.cpp b/zone/zone.cpp index 3fa3e5370..923e37a39 100755 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -904,7 +904,7 @@ bool Zone::Init(bool iStaticZone) { std::string r_name = RuleManager::Instance()->GetRulesetName(&database, default_ruleset); if(r_name.size() > 0) { - RuleManager::Instance()->LoadRules(&database, r_name.c_str()); + RuleManager::Instance()->LoadRules(&database, r_name.c_str(), false); } }