diff --git a/OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs b/OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs index 9f7abd09b4..6331519e3c 100644 --- a/OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs +++ b/OpenSim/ApplicationPlugins/RegionModulesController/RegionModulesControllerPlugin.cs @@ -149,21 +149,68 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController public void AddRegionToModules (Scene scene) { + Dictionary deferredSharedModules = + new Dictionary(); + Dictionary deferredNonSharedModules = + new Dictionary(); + + Type s = scene.GetType(); + MethodInfo mi = s.GetMethod("RequestModuleInterface"); + + List sharedlist = new List(); foreach (ISharedRegionModule module in m_sharedInstances) { + Type replaceableInterface = module.ReplacableInterface; + if (replaceableInterface != null) + { + MethodInfo mii = mi.MakeGenericMethod(replaceableInterface); + + if (mii.Invoke(scene, new object[0]) != null) + { + m_log.DebugFormat("[REGIONMODULE]: Not loading {0} because another module has registered {1}", module.Name, replaceableInterface.ToString()); + continue; + } + + deferredSharedModules[replaceableInterface] = module; + m_log.DebugFormat("[REGIONMODULE]: Deferred load of {0}", module.Name); + continue; + } + m_log.DebugFormat("[REGIONMODULE]: Adding scene {0} to shared module {1}", scene.RegionInfo.RegionName, module.Name); + module.AddRegion(scene); scene.AddRegionModule(module.Name, module); + + sharedlist.Add(module); } List list = new List(); foreach (Type type in m_nonSharedModules) { INonSharedRegionModule module = (INonSharedRegionModule)Activator.CreateInstance(type); + + Type replaceableInterface = module.ReplacableInterface; + if (replaceableInterface != null) + { + MethodInfo mii = mi.MakeGenericMethod(replaceableInterface); + + if (mii.Invoke(scene, new object[0]) != null) + { + m_log.DebugFormat("[REGIONMODULE]: Not loading {0} because another module has registered {1}", module.Name, replaceableInterface.ToString()); + continue; + } + + deferredNonSharedModules[replaceableInterface] = module; + m_log.DebugFormat("[REGIONMODULE]: Deferred load of {0}", module.Name); + continue; + } + m_log.DebugFormat("[REGIONMODULE]: Adding scene {0} to non-shared module {1}", scene.RegionInfo.RegionName, module.Name); + module.Initialise(m_openSim.ConfigSource.Source); + list.Add(module); } @@ -173,6 +220,60 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController scene.AddRegionModule(module.Name, module); } + // Now all modules without a replaceable base interface are loaded + // Replaceable modules have either been skipped, or omitted. + // Now scan the deferred modules here + + foreach (ISharedRegionModule module in deferredSharedModules.Values) + { + Type replaceableInterface = module.ReplacableInterface; + MethodInfo mii = mi.MakeGenericMethod(replaceableInterface); + + if (mii.Invoke(scene, new object[0]) != null) + { + m_log.DebugFormat("[REGIONMODULE]: Not loading {0} because another module has registered {1}", module.Name, replaceableInterface.ToString()); + continue; + } + + m_log.DebugFormat("[REGIONMODULE]: Adding scene {0} to shared module {1} (deferred)", + scene.RegionInfo.RegionName, module.Name); + + module.AddRegion(scene); + scene.AddRegionModule(module.Name, module); + + sharedlist.Add(module); + } + + List deferredlist = new List(); + foreach (INonSharedRegionModule module in deferredNonSharedModules.Values) + { + Type replaceableInterface = module.ReplacableInterface; + if (replaceableInterface != null) + { + MethodInfo mii = mi.MakeGenericMethod(replaceableInterface); + + if (mii.Invoke(scene, new object[0]) != null) + { + m_log.DebugFormat("[REGIONMODULE]: Not loading {0} because another module has registered {1}", module.Name, replaceableInterface.ToString()); + continue; + } + } + + m_log.DebugFormat("[REGIONMODULE]: Adding scene {0} to non-shared module {1} (deferred)", + scene.RegionInfo.RegionName, module.Name); + + module.Initialise(m_openSim.ConfigSource.Source); + + list.Add(module); + deferredlist.Add(module); + } + + foreach (INonSharedRegionModule module in deferredlist) + { + module.AddRegion(scene); + scene.AddRegionModule(module.Name, module); + } + // This is needed for all module types. Modules will register // Interfaces with scene in AddScene, and will also need a means // to access interfaces registered by other modules. Without @@ -183,7 +284,7 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController // and unneccessary caching logic repeated in all modules. // The extra function stub is just that much cleaner // - foreach (ISharedRegionModule module in m_sharedInstances) + foreach (ISharedRegionModule module in sharedlist) { module.RegionLoaded(scene); } diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 98e7f0ecde..878e2fd069 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -457,6 +457,10 @@ namespace OpenSim.Framework.Servers.HttpServer // This has to be here to prevent a Linux/Mono crash m_log.WarnFormat("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); } + catch (IOException e) + { + m_log.Warn("[BASE HTTP SERVER] XmlRpcRequest issue: " + e.Message); + } return; } @@ -464,7 +468,8 @@ namespace OpenSim.Framework.Servers.HttpServer { foreach (string strAccept in request.AcceptTypes) { - if (strAccept.Contains("application/llsd+xml")) + if (strAccept.Contains("application/llsd+xml") || + strAccept.Contains("application/llsd+json")) { //m_log.Info("[Debug BASE HTTP SERVER]: Found an application/llsd+xml accept header"); HandleLLSDRequests(request, response); @@ -483,12 +488,14 @@ namespace OpenSim.Framework.Servers.HttpServer case "application/llsd+xml": case "application/xml+llsd": + case "application/llsd+json": //m_log.Info("[Debug BASE HTTP SERVER]: found a application/llsd+xml content type"); HandleLLSDRequests(request, response); return; case "text/xml": case "application/xml": + case "application/json": default: //m_log.Info("[Debug BASE HTTP SERVER]: in default handler"); // Point of note.. the DoWeHaveA methods check for an EXACT path @@ -529,9 +536,9 @@ namespace OpenSim.Framework.Servers.HttpServer // with the minimum first m_log.WarnFormat("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux", e); } - catch (EndOfStreamException e) + catch (IOException e) { - m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e); + m_log.ErrorFormat("[BASE HTTP SERVER] HandleRequest() threw ", e); } catch (InvalidOperationException e) { @@ -760,6 +767,10 @@ namespace OpenSim.Framework.Servers.HttpServer // This has to be here to prevent a Linux/Mono crash m_log.WarnFormat("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); } + catch (IOException e) + { + m_log.Warn("[BASE HTTP SERVER] XmlRpcRequest issue: " + e.Message); + } } return; //responseString = "Error"; @@ -793,6 +804,10 @@ namespace OpenSim.Framework.Servers.HttpServer // This has to be here to prevent a Linux/Mono crash m_log.WarnFormat("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); } + catch (IOException e) + { + m_log.Warn("[BASE HTTP SERVER] XmlRpcRequest issue: " + e.Message); + } } } @@ -823,7 +838,7 @@ namespace OpenSim.Framework.Servers.HttpServer } try { - llsdRequest = OSDParser.DeserializeLLSDXml(requestBody); + llsdRequest = OSDParser.Deserialize(requestBody); } catch (Exception ex) { @@ -873,10 +888,10 @@ namespace OpenSim.Framework.Servers.HttpServer } else { - response.ContentType = "application/llsd+xml"; - //m_log.Info("[Debug BASE HTTP SERVER]: Response: " + llsdResponse.ToString()); - buffer = OSDParser.SerializeLLSDXmlBytes(llsdResponse); + // Select an appropriate response format + buffer = BuildLLSDResponse(request, response, llsdResponse); } + response.SendChunked = false; response.ContentLength64 = buffer.Length; response.ContentEncoding = Encoding.UTF8; @@ -912,6 +927,47 @@ namespace OpenSim.Framework.Servers.HttpServer } } + private byte[] BuildLLSDResponse(OSHttpRequest request, OSHttpResponse response, OSD llsdResponse) + { + if (request.AcceptTypes != null && request.AcceptTypes.Length > 0) + { + foreach (string strAccept in request.AcceptTypes) + { + switch (strAccept) + { + case "application/llsd+xml": + case "application/xml": + case "text/xml": + response.ContentType = strAccept; + return OSDParser.SerializeLLSDXmlBytes(llsdResponse); + case "application/llsd+json": + case "application/json": + response.ContentType = strAccept; + return Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(llsdResponse)); + } + } + } + + if (!String.IsNullOrEmpty(request.ContentType)) + { + switch (request.ContentType) + { + case "application/llsd+xml": + case "application/xml": + case "text/xml": + response.ContentType = request.ContentType; + return OSDParser.SerializeLLSDXmlBytes(llsdResponse); + case "application/llsd+json": + case "application/json": + response.ContentType = request.ContentType; + return Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(llsdResponse)); + } + } + + response.ContentType = "application/llsd+json"; + return Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(llsdResponse)); + } + /// /// Checks if we have an Exact path in the LLSD handlers for the path provided /// @@ -1404,6 +1460,10 @@ namespace OpenSim.Framework.Servers.HttpServer // This has to be here to prevent a Linux/Mono crash m_log.WarnFormat("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e); } + catch (IOException e) + { + m_log.Warn("[BASE HTTP SERVER] XmlRpcRequest issue: " + e.Message); + } } } diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 0a9b67d467..65d4f4d465 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -1111,5 +1111,56 @@ namespace OpenSim.Framework return null; } + public static string[] Glob(string path) + { + string vol=String.Empty; + + if (Path.VolumeSeparatorChar != Path.DirectorySeparatorChar) + { + string[] vcomps = path.Split(new char[] {Path.VolumeSeparatorChar}, 2, StringSplitOptions.RemoveEmptyEntries); + + if (vcomps.Length > 1) + { + path = vcomps[1]; + vol = vcomps[0]; + } + } + + string[] comps = path.Split(new char[] {Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar}, StringSplitOptions.RemoveEmptyEntries); + + // Glob + + path = vol; + if (vol != String.Empty) + path += new String(new char[] {Path.VolumeSeparatorChar, Path.DirectorySeparatorChar}); + else + path = new String(new char[] {Path.DirectorySeparatorChar}); + + List paths = new List(); + List found = new List(); + paths.Add(path); + + foreach (string c in comps) + { + List addpaths = new List(); + foreach (string p in paths) + { + string[] dirs = Directory.GetDirectories(p, c); + + if (dirs.Length != 0) + { + foreach (string dir in dirs) + addpaths.Add(Path.Combine(path, dir)); + } + + string[] files = Directory.GetFiles(p, c); + foreach (string f in files) + found.Add(f); + } + paths = addpaths; + } + + return found.ToArray(); + } } } diff --git a/OpenSim/Region/Application/ConfigurationLoader.cs b/OpenSim/Region/Application/ConfigurationLoader.cs index 1be36ca851..7bb8864fa3 100644 --- a/OpenSim/Region/Application/ConfigurationLoader.cs +++ b/OpenSim/Region/Application/ConfigurationLoader.cs @@ -188,10 +188,11 @@ namespace OpenSim { string path = Path.GetFullPath( Path.Combine(Util.configDir(), file)); - if (File.Exists(path)) + string[] paths = Util.Glob(path); + foreach (string p in paths) { - if (!sources.Contains(path)) - sources.Add(path); + if (!sources.Contains(p)) + sources.Add(p); } } } diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index 4928eded0f..14cee361f0 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs @@ -202,19 +202,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where /// an account exists with the creator name. /// - //[Test] + [Test] public void TestLoadIarV0_1ExistingUsers() { TestHelper.InMethod(); - //log4net.Config.XmlConfigurator.Configure(); + log4net.Config.XmlConfigurator.Configure(); string userFirstName = "Mr"; string userLastName = "Tiddles"; UUID userUuid = UUID.Parse("00000000-0000-0000-0000-000000000555"); - string user2FirstName = "Lord"; - string user2LastName = "Lucan"; - UUID user2Uuid = UUID.Parse("00000000-0000-0000-0000-000000000666"); + string userItemCreatorFirstName = "Lord"; + string userItemCreatorLastName = "Lucan"; + UUID userItemCreatorUuid = UUID.Parse("00000000-0000-0000-0000-000000000666"); string itemName = "b.lsl"; string archiveItemName @@ -227,7 +227,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests item1.Name = itemName; item1.AssetID = UUID.Random(); item1.GroupID = UUID.Random(); - item1.CreatorId = OspResolver.MakeOspa(user2FirstName, user2LastName); + item1.CreatorId = OspResolver.MakeOspa(userItemCreatorFirstName, userItemCreatorLastName); //item1.CreatorId = userUuid.ToString(); //item1.CreatorId = "00000000-0000-0000-0000-000000000444"; item1.Owner = UUID.Zero; @@ -249,13 +249,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests userAdminService.AddUser( userFirstName, userLastName, "meowfood", String.Empty, 1000, 1000, userUuid); userAdminService.AddUser( - user2FirstName, user2LastName, "hampshire", String.Empty, 1000, 1000, user2Uuid); + userItemCreatorFirstName, userItemCreatorLastName, "hampshire", + String.Empty, 1000, 1000, userItemCreatorUuid); archiverModule.DearchiveInventory(userFirstName, userLastName, "/", archiveReadStream); CachedUserInfo userInfo = scene.CommsManager.UserProfileCacheService.GetUserDetails(userFirstName, userLastName); - userInfo.FetchInventory(); + //userInfo.FetchInventory(); + /* for (int i = 0 ; i < 50 ; i++) { if (userInfo.HasReceivedInventory == true) @@ -263,18 +265,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests Thread.Sleep(200); } Assert.That(userInfo.HasReceivedInventory, Is.True, "FetchInventory timed out (10 seconds)"); + */ InventoryItemBase foundItem = userInfo.RootFolder.FindItemByPath(itemName); Assert.That(foundItem, Is.Not.Null, "Didn't find loaded item"); Assert.That( foundItem.CreatorId, Is.EqualTo(item1.CreatorId), "Loaded item non-uuid creator doesn't match original"); Assert.That( - foundItem.CreatorIdAsUuid, Is.EqualTo(user2Uuid), + foundItem.CreatorIdAsUuid, Is.EqualTo(userItemCreatorUuid), "Loaded item uuid creator doesn't match original"); Assert.That(foundItem.Owner, Is.EqualTo(userUuid), "Loaded item owner doesn't match inventory reciever"); - - Console.WriteLine("Successfully completed {0}", MethodBase.GetCurrentMethod()); } /// @@ -367,6 +368,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests CachedUserInfo userInfo = UserProfileTestUtils.CreateUserWithInventory(commsManager); userInfo.FetchInventory(); + /* for (int i = 0 ; i < 50 ; i++) { if (userInfo.HasReceivedInventory == true) @@ -374,6 +376,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests Thread.Sleep(200); } Assert.That(userInfo.HasReceivedInventory, Is.True, "FetchInventory timed out (10 seconds)"); + */ + + Console.WriteLine("userInfo.RootFolder 1: {0}", userInfo.RootFolder); + Dictionary foldersCreated = new Dictionary(); List nodesLoaded = new List(); @@ -391,10 +397,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests = string.Format( "{0}{1}/{2}/{3}", ArchiveConstants.INVENTORY_PATH, folder1ArchiveName, folder2ArchiveName, itemName); + + Console.WriteLine("userInfo.RootFolder 2: {0}", userInfo.RootFolder); new InventoryArchiveReadRequest(userInfo, null, (Stream)null, null, null) .ReplicateArchivePathToUserInventory(itemArchivePath, false, userInfo.RootFolder, foldersCreated, nodesLoaded); - + + Console.WriteLine("userInfo.RootFolder 3: {0}", userInfo.RootFolder); InventoryFolderImpl folder1 = userInfo.RootFolder.FindFolderByPath("a"); Assert.That(folder1, Is.Not.Null, "Could not find folder a"); InventoryFolderImpl folder2 = folder1.FindFolderByPath("b"); diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs index a3043572ee..e70d985c78 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs @@ -39,7 +39,6 @@ using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; using OpenMetaverse; - namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory { public class LocalInventoryServicesConnector : ISharedRegionModule, IInventoryService diff --git a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs index 5471f9eebe..696f915092 100644 --- a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs +++ b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs @@ -41,9 +41,6 @@ using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -[assembly: Addin("SampleMoneyModule", "0.1")] -[assembly: AddinDependency("OpenSim", "0.5")] - namespace OpenSim.Region.OptionalModules.World.MoneyModule { /// diff --git a/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs b/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs index 442ff06f33..1b14abbf1f 100644 --- a/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs +++ b/OpenSim/Tests/Common/Mock/TestInventoryDataPlugin.cs @@ -39,12 +39,17 @@ namespace OpenSim.Tests.Common.Mock /// tests are single threaded. /// public class TestInventoryDataPlugin : IInventoryDataPlugin - { + { /// - /// Known inventory folders + /// Inventory folders /// private Dictionary m_folders = new Dictionary(); + //// + /// Inventory items + /// + private Dictionary m_items = new Dictionary(); + /// /// User root folders /// @@ -99,9 +104,7 @@ namespace OpenSim.Tests.Common.Mock } return folders; - } - - public InventoryItemBase getInventoryItem(UUID item) { return null; } + } public InventoryFolderBase getInventoryFolder(UUID folderId) { @@ -111,15 +114,6 @@ namespace OpenSim.Tests.Common.Mock return folder; } - public void addInventoryItem(InventoryItemBase item) {} - public void updateInventoryItem(InventoryItemBase item) {} - public void deleteInventoryItem(UUID item) {} - - public InventoryItemBase queryInventoryItem(UUID item) - { - return null; - } - public InventoryFolderBase queryInventoryFolder(UUID folderID) { return getInventoryFolder(folderID); @@ -150,6 +144,29 @@ namespace OpenSim.Tests.Common.Mock m_folders.Remove(folderId); } + public void addInventoryItem(InventoryItemBase item) { m_items[item.ID] = item; } + + public void updateInventoryItem(InventoryItemBase item) { addInventoryItem(item); } + + public void deleteInventoryItem(UUID itemId) + { + if (m_items.ContainsKey(itemId)) + m_items.Remove(itemId); + } + + public InventoryItemBase getInventoryItem(UUID itemId) + { + if (m_items.ContainsKey(itemId)) + return m_items[itemId]; + else + return null; + } + + public InventoryItemBase queryInventoryItem(UUID item) + { + return null; + } + public List fetchActiveGestures(UUID avatarID) { return null; } } } diff --git a/OpenSim/Tests/Common/TestHelper.cs b/OpenSim/Tests/Common/TestHelper.cs index f0b33769c8..4abf2e3688 100644 --- a/OpenSim/Tests/Common/TestHelper.cs +++ b/OpenSim/Tests/Common/TestHelper.cs @@ -54,7 +54,7 @@ namespace OpenSim.Tests.Common public static void InMethod() { StackTrace stackTrace = new StackTrace(); - Console.WriteLine("==> In Test Method : {0}", stackTrace.GetFrame(1).GetMethod().Name); + Console.WriteLine("===> In Test Method : {0} <===", stackTrace.GetFrame(1).GetMethod().Name); } } } diff --git a/README.txt b/README.txt index cff2b0a862..e796bb2810 100644 --- a/README.txt +++ b/README.txt @@ -89,5 +89,3 @@ OpenSim, as well as how to report bugs, and participate in the OpenSim project can always be found at http://opensimulator.org. Thanks for trying OpenSim, we hope it is a pleasant experience. - - diff --git a/addon-modules/README b/addon-modules/README new file mode 100644 index 0000000000..19f268fa52 --- /dev/null +++ b/addon-modules/README @@ -0,0 +1,5 @@ +In this directory you can place addon modules for OpenSim + +Each module should be in it's own tree and the root of the tree +should contain a file named "prebuild.xml", which will be included in the +main prebuild file. diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 6ae6a95c50..bd03652cc9 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -1362,3 +1362,11 @@ ; config-include/GridCommon.ini.example (if you're connected to a grid) ; Copy to your own .ini there (without .example extension) and edit it ; to customize your data + + + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; The below pulls in optional module config files + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[Modules] + Include-modules = "addon-modules/*/config/*.ini" diff --git a/prebuild.xml b/prebuild.xml index 07b9398c76..a34661c960 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -3877,6 +3877,8 @@ + +