Loading...   

  • Created By Uleat On: 08:26 PM January 10, 2019
  • Link

 changelog.txt        |  4 ++++
 common/rulesys.cpp   | 39 +++++++++++++++++++++++++++++++++------
 common/rulesys.h     |  6 +++---
 ucs/ucs.cpp          |  5 +++--
 world/net.cpp        |  6 +++---
 world/zoneserver.cpp |  4 ++--
 zone/command.cpp     | 14 +++++++-------
 zone/net.cpp         |  4 ++--
 zone/worldserver.cpp |  2 +-
 zone/zone.cpp        |  2 +-
 10 files changed, 59 insertions(+), 27 deletions(-)

diff --git a/changelog.txt b/changelog.txt
index 3e2c4f67..72dcc72c 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,6 +1,10 @@
 EQEMu Changelog (Started on Sept 24, 2003 15:50)
 -------------------------------------------------------
 
+== 1/10/2019 ==
+Uleat: Modified rules system to ignore all runtime modifications of client expansion-related
+       fields due to inherit problems of running server and clients with conflicting values.
+
 == 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 61bb7235..d4ff3d4d 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 25c3a401..710c6d61 100644
--- a/common/rulesys.h
+++ b/common/rulesys.h
@@ -102,7 +102,7 @@ public:
 	bool ListRules(const char *catname, std::vector<const char *> &into);
 	bool ListCategories(std::vector<const char *> &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<int, std::string> &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 b9e7f41b..21e525cb 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 7065ea6c..77deec26 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 7d638d10..7eaa7e3c 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 bccf0747..f65a4cd1 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 641c6924..9e896fea 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 7b552460..e187a314 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 3fa3e537..923e37a3 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);
 		}
 	}
 

Raw Paste Data