From 6c44922de4f98e7cbdea81821c75bf9fb4a1462f Mon Sep 17 00:00:00 2001
From: Rye Mutt <rye@alchemyviewer.org>
Date: Tue, 24 Mar 2020 07:04:19 -0400
Subject: [PATCH] Add support for including files in settings files - Shyotl

---
 indra/llxml/llcontrol.cpp                     |  25 +++
 indra/llxml/llcontrol.h                       |   2 +
 indra/newview/app_settings/settings.xml       |   4 +
 .../newview/app_settings/settings_alchemy.xml | 204 ++++++++++++++++++
 4 files changed, 235 insertions(+)
 create mode 100644 indra/newview/app_settings/settings_alchemy.xml

diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp
index d72d6736614..382026e53ed 100644
--- a/indra/llxml/llcontrol.cpp
+++ b/indra/llxml/llcontrol.cpp
@@ -946,6 +946,11 @@ U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only
 
 U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_values, bool save_values)
 {
+	if (!mIncludedFiles.insert(filename).second)
+	{
+		return 0; //Already included this file.
+	}
+
 	LLSD settings;
 	llifstream infile;
 	infile.open(filename);
@@ -971,6 +976,26 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
 		std::string const & name = itr->first;
 		LLSD const & control_map = itr->second;
 		
+		if(name == "Include")
+		{
+			if(control_map.isArray())
+			{
+#if LL_WINDOWS
+				size_t pos = filename.find_last_of('\\');
+#else
+				size_t pos = filename.find_last_of('/');
+#endif			
+				if(pos != std::string::npos)
+				{
+					const std::string dir = filename.substr(0,++pos);
+					for(LLSD::array_const_iterator array_itr = control_map.beginArray(), array_end = control_map.endArray();
+						array_itr != array_end; ++array_itr)
+						validitems+=loadFromFile(dir+(*array_itr).asString(),set_default_values);
+				}
+			}
+			continue;
+		}
+
 		if(control_map.has("Persist")) 
 		{
 			persist = control_map["Persist"].asInteger()?
diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h
index b68187e196b..5ba25ab0f2d 100644
--- a/indra/llxml/llcontrol.h
+++ b/indra/llxml/llcontrol.h
@@ -196,6 +196,8 @@ class LLControlGroup : public LLInstanceTracker<LLControlGroup, std::string>
 	ctrl_name_table_t mNameTable;
 	static const std::string mTypeString[TYPE_COUNT];
 
+	std::set<std::string> mIncludedFiles;
+
 public:
 	static eControlType typeStringToEnum(const std::string& typestr);
 	static std::string typeEnumToString(eControlType typeenum);	
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index a120f9ecd03..f852af847bd 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -2,6 +2,10 @@
 <llsd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:noNamespaceSchemaLocation="llsd.xsd">
 <map>
+    <key>Include</key>
+    <array>
+      <string>settings_alchemy.xml</string>
+    </array>
     <key>RestrainedLove</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/app_settings/settings_alchemy.xml b/indra/newview/app_settings/settings_alchemy.xml
new file mode 100644
index 00000000000..d8438d902f9
--- /dev/null
+++ b/indra/newview/app_settings/settings_alchemy.xml
@@ -0,0 +1,204 @@
+<?xml version="1.0" ?>
+<llsd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:noNamespaceSchemaLocation="llsd.xsd">
+  <map>
+    <key>AlchemyChatCommandAnimationOverride</key>
+    <map>
+      <key>Comment</key>
+      <string>Command to control ao</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>/ao</string>
+    </map>
+    <key>AlchemyChatCommandCalc</key>
+    <map>
+      <key>Comment</key>
+      <string>Command to calculate expressions</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>/calc</string>
+    </map>
+    <key>AlchemyChatCommandClearNearby</key>
+    <map>
+      <key>Comment</key>
+      <string>Command to set clear nearby chat history for this session.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>/clr</string>
+    </map>
+    <key>AlchemyChatCommandDrawDistance</key>
+    <map>
+      <key>Comment</key>
+      <string>Command to set draw distance</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>/dd</string>
+    </map>
+    <key>AlchemyChatCommandEnable</key>
+    <map>
+      <key>Comment</key>
+      <string>Enable chat bar command line</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>AlchemyChatCommandGround</key>
+    <map>
+      <key>Comment</key>
+      <string>Command to teleport to ground</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>/flr</string>
+    </map>
+    <key>AlchemyChatCommandHeight</key>
+    <map>
+      <key>Comment</key>
+      <string>Command to teleport to specified height</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>/gth</string>
+    </map>
+    <key>AlchemyChatCommandHoverHeight</key>
+    <map>
+      <key>Comment</key>
+      <string>Command to hover your height or something</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>/hover</string>
+    </map>
+    <key>AlchemyChatCommandHome</key>
+    <map>
+      <key>Comment</key>
+      <string>Command to send avatar home</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>/home</string>
+    </map>
+    <key>AlchemyChatCommandMapto</key>
+    <map>
+      <key>Comment</key>
+      <string>Command to teleport to another region</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>/mapto</string>
+    </map>
+    <key>AlchemyChatCommandPos</key>
+    <map>
+      <key>Comment</key>
+      <string>Command to teleport to position</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>/pos</string>
+    </map>
+    <key>AlchemyChatCommandSetChatChannel</key>
+    <map>
+      <key>Comment</key>
+      <string>Command to set nearby chat channel</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>/setchannel</string>
+    </map>
+    <key>AlchemyChatCommandRegionMessage</key>
+    <map>
+      <key>Comment</key>
+      <string>Command to send a region message</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>/regionmsg</string>
+    </map>
+    <key>AlchemyChatCommandResyncAnim</key>
+    <map>
+      <key>Comment</key>
+      <string>Command to stop/start in order to resync animations</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>/resync</string>
+    </map>
+    <key>AlchemyChatCommandRezPlat</key>
+    <map>
+      <key>Comment</key>
+      <string>Rez a platform</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>/plat</string>
+    </map>
+    <key>AlchemyChatCommandRezPlatSize</key>
+    <map>
+      <key>Comment</key>
+      <string>Default size of platform to rez</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <string>20</string>
+    </map>
+    <key>AlchemyChatCommandSetHome</key>
+    <map>
+      <key>Comment</key>
+      <string>Command to set the avatar home</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>/sethome</string>
+    </map>
+    <key>AlchemyChatCommandTeleportToCam</key>
+    <map>
+      <key>Comment</key>
+      <string>Command to teleport to cam</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>/tp2cam</string>
+    </map>
+  </map>
+</llsd>
-- 
GitLab