From c4707a284ffecf81e8ca60a1019e234339222631 Mon Sep 17 00:00:00 2001
From: Adam Frisby
Date: Mon, 22 Oct 2007 15:23:48 +0000
Subject: * Major ass commit. * Sqlite Storage Engine now supports terrain --
 however be aware that every terrain revision stored will at 512KB to your
 database file. At the moment it is storing every revision from the first. *
 Fixed an issue where by noverbose mode would display lots of useless junk.
 Noverbose mode is now quite usable. * Fixed a whole bunch of console message
 issues such as naming and categorisation

---
 .../Framework/Communications/Cache/AssetCache.cs   |   4 +-
 .../Framework/Communications/Cache/AssetServer.cs  |   4 +-
 .../Communications/Cache/AssetServerBase.cs        |   4 +-
 .../Communications/Cache/SQLAssetServer.cs         |   4 +-
 .../Communications/InventoryServiceBase.cs         |   2 +-
 OpenSim/Framework/Communications/LoginService.cs   |   2 +-
 OpenSim/Framework/Console/LogBase.cs               |  63 +--
 OpenSim/Framework/General/Types/EstateSettings.cs  |   8 +-
 OpenSim/Framework/Servers/BaseHttpServer.cs        |   2 +-
 OpenSim/Region/Application/OpenSimMain.cs          |  18 +-
 .../Environment/Interfaces/IRegionDataStore.cs     |   4 +-
 OpenSim/Region/Environment/ModuleLoader.cs         | 428 ++++++++++-----------
 OpenSim/Region/Environment/Modules/ChatModule.cs   | 381 ++++++++----------
 OpenSim/Region/Environment/Scenes/Scene.cs         |   8 +-
 .../Region/ExtensionsScriptModule/ScriptManager.cs |   4 +-
 .../Region/Physics/Manager/PhysicsPluginManager.cs |   2 +-
 .../MonoSqliteDataStore.cs                         | 121 +++++-
 .../OpenSim.DataStore.NullStorage/NullDataStore.cs |   4 +-
 18 files changed, 568 insertions(+), 495 deletions(-)

(limited to 'OpenSim')

diff --git a/OpenSim/Framework/Communications/Cache/AssetCache.cs b/OpenSim/Framework/Communications/Cache/AssetCache.cs
index 17829b2..9dbd50e 100644
--- a/OpenSim/Framework/Communications/Cache/AssetCache.cs
+++ b/OpenSim/Framework/Communications/Cache/AssetCache.cs
@@ -72,7 +72,7 @@ namespace OpenSim.Framework.Communications.Cache
         /// </summary>
         public AssetCache(IAssetServer assetServer)
         {
-            System.Console.WriteLine("Creating Asset cache");
+            OpenSim.Framework.Console.MainLog.Instance.Verbose("ASSETSTORAGE","Creating Asset cache");
             _assetServer = assetServer;
             _assetServer.SetReceiver(this);
             Assets = new Dictionary<LLUUID, AssetInfo>();
@@ -89,7 +89,7 @@ namespace OpenSim.Framework.Communications.Cache
 
         public AssetCache(string assetServerDLLName, string assetServerURL, string assetServerKey)
         {
-            System.Console.WriteLine("Creating Asset cache");
+            OpenSim.Framework.Console.MainLog.Instance.Verbose("ASSETSTORAGE", "Creating Asset cache");
             _assetServer = this.LoadAssetDll(assetServerDLLName);
 
 
diff --git a/OpenSim/Framework/Communications/Cache/AssetServer.cs b/OpenSim/Framework/Communications/Cache/AssetServer.cs
index 22bdc5c..aebda00 100644
--- a/OpenSim/Framework/Communications/Cache/AssetServer.cs
+++ b/OpenSim/Framework/Communications/Cache/AssetServer.cs
@@ -51,7 +51,7 @@ namespace OpenSim.Framework.Communications.Cache
             yapfile = File.Exists(Path.Combine(Util.dataDir(), "regionassets.yap"));
 
             db = Db4oFactory.OpenFile(Path.Combine(Util.dataDir(), "regionassets.yap"));
-            MainLog.Instance.Verbose("Db4 Asset database  creation");
+            MainLog.Instance.Verbose("ASSETS","Db4 Asset database  creation");
 
             if (!yapfile)
             {
@@ -75,7 +75,7 @@ namespace OpenSim.Framework.Communications.Cache
 
             if (db != null)
             {
-                MainLog.Instance.Verbose("Closing local asset server database");
+                MainLog.Instance.Verbose("ASSETSERVER","Closing local asset server database");
                 db.Close();
             }
         }
diff --git a/OpenSim/Framework/Communications/Cache/AssetServerBase.cs b/OpenSim/Framework/Communications/Cache/AssetServerBase.cs
index 08d5b87..685c0b9 100644
--- a/OpenSim/Framework/Communications/Cache/AssetServerBase.cs
+++ b/OpenSim/Framework/Communications/Cache/AssetServerBase.cs
@@ -36,8 +36,8 @@ namespace OpenSim.Framework.Communications.Cache
 
 
         public AssetServerBase()
-        {
-            System.Console.WriteLine("Starting Db4o asset storage system");            
+        {
+            OpenSim.Framework.Console.MainLog.Instance.Verbose("ASSETSERVER","Starting Db4o asset storage system");
             this._assetRequests = new BlockingQueue<ARequest>();
 
             this._localAssetServerThread = new Thread( RunRequests );
diff --git a/OpenSim/Framework/Communications/Cache/SQLAssetServer.cs b/OpenSim/Framework/Communications/Cache/SQLAssetServer.cs
index 69f83d2..580e5c4 100644
--- a/OpenSim/Framework/Communications/Cache/SQLAssetServer.cs
+++ b/OpenSim/Framework/Communications/Cache/SQLAssetServer.cs
@@ -68,7 +68,7 @@ namespace OpenSim.Framework.Communications.Cache
                         m_assetProviderPlugin = plug;
                         m_assetProviderPlugin.Initialise();
 
-                        MainLog.Instance.Verbose("AssetStorage: Added " + m_assetProviderPlugin.Name + " " + m_assetProviderPlugin.Version);
+                        MainLog.Instance.Verbose("AssetStorage","Added " + m_assetProviderPlugin.Name + " " + m_assetProviderPlugin.Version);
                     }
 
                     typeInterface = null;
@@ -92,7 +92,7 @@ namespace OpenSim.Framework.Communications.Cache
             {
                 ARequest req = this._assetRequests.Dequeue();
 
-                MainLog.Instance.Verbose("Requesting asset: " + req.AssetID);
+                MainLog.Instance.Verbose("AssetStorage","Requesting asset: " + req.AssetID);
 
                 AssetBase asset = null;
                 lock (syncLock)
diff --git a/OpenSim/Framework/Communications/InventoryServiceBase.cs b/OpenSim/Framework/Communications/InventoryServiceBase.cs
index 65eb509..06a1ca8 100644
--- a/OpenSim/Framework/Communications/InventoryServiceBase.cs
+++ b/OpenSim/Framework/Communications/InventoryServiceBase.cs
@@ -70,7 +70,7 @@ namespace OpenSim.Framework.Communications
                                 (IInventoryData)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
                             plug.Initialise();
                             this.m_plugins.Add(plug.getName(), plug);
-                            MainLog.Instance.Verbose("Inventorystorage: Added IInventoryData Interface");
+                            MainLog.Instance.Verbose("INVENTORY","Added IInventoryData Interface");
                         }
                     }
                 }
diff --git a/OpenSim/Framework/Communications/LoginService.cs b/OpenSim/Framework/Communications/LoginService.cs
index 674c746..f4648df 100644
--- a/OpenSim/Framework/Communications/LoginService.cs
+++ b/OpenSim/Framework/Communications/LoginService.cs
@@ -66,7 +66,7 @@ namespace OpenSim.Framework.UserManagement
         public XmlRpcResponse XmlRpcLoginMethod(XmlRpcRequest request)
         {
 
-            MainLog.Instance.Verbose("Attempting login now...");
+            MainLog.Instance.Verbose("LOGIN","Attempting login now...");
             XmlRpcResponse response = new XmlRpcResponse();
             Hashtable requestData = (Hashtable)request.Params[0];
 
diff --git a/OpenSim/Framework/Console/LogBase.cs b/OpenSim/Framework/Console/LogBase.cs
index 5a7ce4d..246afa1 100644
--- a/OpenSim/Framework/Console/LogBase.cs
+++ b/OpenSim/Framework/Console/LogBase.cs
@@ -170,8 +170,11 @@ namespace OpenSim.Framework.Console
         /// <param name="args">WriteLine-style message arguments</param>
         public void Verbose(string format, params object[] args)
         {
-            WriteNewLine(ConsoleColor.Gray, format, args);
-            return;
+            if (!m_silent)
+            {
+                WriteNewLine(ConsoleColor.Gray, format, args);
+                return;
+            }
         }
 
         /// <summary>
@@ -182,9 +185,12 @@ namespace OpenSim.Framework.Console
         /// <param name="args">WriteLine-style message arguments</param>
         public void Verbose(string sender, string format, params object[] args)
         {
-            WritePrefixLine(DeriveColor(sender), sender);
-            WriteNewLine(ConsoleColor.Gray, format, args);
-            return;
+            if (!m_silent)
+            {
+                WritePrefixLine(DeriveColor(sender), sender);
+                WriteNewLine(ConsoleColor.Gray, format, args);
+                return;
+            }
         }
 
         /// <summary>
@@ -234,22 +240,20 @@ namespace OpenSim.Framework.Console
                 Log.Write(now);
                 Log.WriteLine(format, args);
                 Log.Flush();
-                if (!m_silent)
+
+                System.Console.Write(now);
+                try
                 {
-                    System.Console.Write(now);
-                    try
-                    {
-                        if (color != ConsoleColor.White)
-                            System.Console.ForegroundColor = color;
+                    if (color != ConsoleColor.White)
+                        System.Console.ForegroundColor = color;
 
-                        System.Console.WriteLine(format, args);
-                        System.Console.ResetColor();
-                    }
-                    catch (ArgumentNullException)
-                    {
-                        // Some older systems dont support coloured text.
-                        System.Console.WriteLine(format, args);
-                    }
+                    System.Console.WriteLine(format, args);
+                    System.Console.ResetColor();
+                }
+                catch (ArgumentNullException)
+                {
+                    // Some older systems dont support coloured text.
+                    System.Console.WriteLine(format, args);
                 }
                 return;
             }
@@ -265,19 +269,16 @@ namespace OpenSim.Framework.Console
 
                 System.Console.Write("[");
 
-                if (!m_silent)
+                try
                 {
-                    try
-                    {
-                        System.Console.ForegroundColor = color;
-                        System.Console.Write(sender);
-                        System.Console.ResetColor();
-                    }
-                    catch (ArgumentNullException)
-                    {
-                        // Some older systems dont support coloured text.
-                        System.Console.WriteLine(sender);
-                    }
+                    System.Console.ForegroundColor = color;
+                    System.Console.Write(sender);
+                    System.Console.ResetColor();
+                }
+                catch (ArgumentNullException)
+                {
+                    // Some older systems dont support coloured text.
+                    System.Console.WriteLine(sender);
                 }
 
                 System.Console.Write("] \t");
diff --git a/OpenSim/Framework/General/Types/EstateSettings.cs b/OpenSim/Framework/General/Types/EstateSettings.cs
index abdcf6f..2675e52 100644
--- a/OpenSim/Framework/General/Types/EstateSettings.cs
+++ b/OpenSim/Framework/General/Types/EstateSettings.cs
@@ -557,8 +557,12 @@ namespace OpenSim.Framework.Types
         private ConfigurationMember configMember;
         public EstateSettings()
         {
-            configMember = new ConfigurationMember(Path.Combine(Util.configDir(),"estate_settings.xml"), "ESTATE SETTINGS", this.loadConfigurationOptions, this.handleIncomingConfiguration);
-            configMember.performConfigurationRetrieve();
+            // Temporary hack to prevent multiple loadings.
+            if (configMember == null)
+            {
+                configMember = new ConfigurationMember(Path.Combine(Util.configDir(), "estate_settings.xml"), "ESTATE SETTINGS", this.loadConfigurationOptions, this.handleIncomingConfiguration);
+                configMember.performConfigurationRetrieve();
+            }
         }
 
         public void loadConfigurationOptions()
diff --git a/OpenSim/Framework/Servers/BaseHttpServer.cs b/OpenSim/Framework/Servers/BaseHttpServer.cs
index 6d432fd..179a651 100644
--- a/OpenSim/Framework/Servers/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/BaseHttpServer.cs
@@ -224,7 +224,7 @@ namespace OpenSim.Framework.Servers
         {
             try
             {
-                MainLog.Instance.Status("HTTPD", "Spawned main thread OK");
+                MainLog.Instance.Verbose("HTTPD", "Spawned main thread OK");
                 m_httpListener = new HttpListener();
 
                 m_httpListener.Prefixes.Add("http://+:" + m_port + "/");
diff --git a/OpenSim/Region/Application/OpenSimMain.cs b/OpenSim/Region/Application/OpenSimMain.cs
index d2f5648..9de3831 100644
--- a/OpenSim/Region/Application/OpenSimMain.cs
+++ b/OpenSim/Region/Application/OpenSimMain.cs
@@ -262,8 +262,10 @@ namespace OpenSim
             }
             else
             {
-                MainLog.Instance.Verbose("No startup command script specified. Moving on...");
+                MainLog.Instance.Verbose("STARTUP","No startup command script specified. Moving on...");
             }
+
+            MainLog.Instance.Status("STARTUP","Startup complete, serving " + m_udpServers.Count.ToString() + " region(s)");
         }
 
         private static void CreateDefaultRegionInfoXml(string fileName)
@@ -361,11 +363,11 @@ namespace OpenSim
                 RunCommandScript(m_shutdownCommandsFile);
             }
 
-            m_log.Verbose("Closing all threads");
-            m_log.Verbose("Killing listener thread");
-            m_log.Verbose("Killing clients");
+            m_log.Verbose("SHUTDOWN", "Closing all threads");
+            m_log.Verbose("SHUTDOWN", "Killing listener thread");
+            m_log.Verbose("SHUTDOWN", "Killing clients");
             // IMPLEMENT THIS
-            m_log.Verbose("Closing console and terminating");
+            m_log.Verbose("SHUTDOWN", "Closing console and terminating");
 
             m_sceneManager.Close();
 
@@ -380,7 +382,7 @@ namespace OpenSim
         /// <param name="fileName"></param>
         private void RunCommandScript(string fileName)
         {
-            MainLog.Instance.Verbose("Running command script (" + fileName + ")");
+            MainLog.Instance.Verbose("COMMANDFILE", "Running " + fileName);
             if (File.Exists(fileName))
             {
                 StreamReader readFile = File.OpenText(fileName);
@@ -389,14 +391,14 @@ namespace OpenSim
                 {
                     if (currentCommand != "")
                     {
-                        MainLog.Instance.Verbose("Running '" + currentCommand + "'");
+                        MainLog.Instance.Verbose("COMMANDFILE", "Running '" + currentCommand + "'");
                         MainLog.Instance.MainLogRunCommand(currentCommand);
                     }
                 }
             }
             else
             {
-                MainLog.Instance.Error("Command script missing. Can not run commands");
+                MainLog.Instance.Error("COMMANDFILE","Command script missing. Can not run commands");
             }
         }
 
diff --git a/OpenSim/Region/Environment/Interfaces/IRegionDataStore.cs b/OpenSim/Region/Environment/Interfaces/IRegionDataStore.cs
index 1a00f2c..e375343 100644
--- a/OpenSim/Region/Environment/Interfaces/IRegionDataStore.cs
+++ b/OpenSim/Region/Environment/Interfaces/IRegionDataStore.cs
@@ -47,8 +47,8 @@ namespace OpenSim.Region.Environment.Interfaces
 
         List<SceneObjectGroup> LoadObjects(LLUUID regionUUID);
 
-        void StoreTerrain(double[,] terrain);
-        double[,] LoadTerrain();
+        void StoreTerrain(double[,] terrain, LLUUID regionID);
+        double[,] LoadTerrain(LLUUID regionID);
 
         void StoreParcel(Land Parcel);
         void RemoveLandObject(uint ID);
diff --git a/OpenSim/Region/Environment/ModuleLoader.cs b/OpenSim/Region/Environment/ModuleLoader.cs
index 4c66d2e..4fc45a0 100644
--- a/OpenSim/Region/Environment/ModuleLoader.cs
+++ b/OpenSim/Region/Environment/ModuleLoader.cs
@@ -1,214 +1,214 @@
-/*
-* Copyright (c) Contributors, http://opensimulator.org/
-* See CONTRIBUTORS.TXT for a full list of copyright holders.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions are met:
-*     * Redistributions of source code must retain the above copyright
-*       notice, this list of conditions and the following disclaimer.
-*     * Redistributions in binary form must reproduce the above copyright
-*       notice, this list of conditions and the following disclaimer in the
-*       documentation and/or other materials provided with the distribution.
-*     * Neither the name of the OpenSim Project nor the
-*       names of its contributors may be used to endorse or promote products
-*       derived from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
-* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
-* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-* 
-*/
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Reflection;
-using OpenSim.Framework.Console;
-using OpenSim.Region.Environment.Interfaces;
-using OpenSim.Region.Environment.Modules;
-using OpenSim.Region.Environment.Scenes;
-using Nini.Config;
-
-namespace OpenSim.Region.Environment
-{
-    public class ModuleLoader
-    {
-        public Dictionary<string, Assembly> LoadedAssemblys = new Dictionary<string, Assembly>();
-
-        public List<IRegionModule> LoadedModules = new List<IRegionModule>();
-        public Dictionary<string, IRegionModule> LoadedSharedModules = new Dictionary<string, IRegionModule>();
-        private readonly LogBase m_log;
-        private IConfigSource m_config;
-
-        public ModuleLoader(LogBase log, IConfigSource config)
-        {
-            m_log = log;
-            m_config = config;
-        }
-
-        public void PickupModules(Scene scene, string moduleDir)
-        {
-            DirectoryInfo dir = new DirectoryInfo(moduleDir);
-
-            foreach (FileInfo fileInfo in dir.GetFiles("*.dll"))
-            {
-                LoadRegionModules(fileInfo.FullName, scene);
-            }
-        }
-
-        public void LoadDefaultSharedModules()
-        {
-            DynamicTextureModule dynamicModule = new DynamicTextureModule();
-            LoadedSharedModules.Add(dynamicModule.Name, dynamicModule);
-            ChatModule chat = new ChatModule();
-            LoadedSharedModules.Add(chat.Name, chat);
-            InstantMessageModule imMod = new InstantMessageModule();
-            LoadedSharedModules.Add(imMod.Name, imMod);
-            LoadImageURLModule loadMod = new LoadImageURLModule();
-            LoadedSharedModules.Add(loadMod.Name, loadMod);
-        }
-
-        public void InitialiseSharedModules(Scene scene)
-        {
-            foreach (IRegionModule module in LoadedSharedModules.Values)
-            {
-                module.Initialise(scene, m_config);
-                scene.AddModule(module.Name, module); //should be doing this?
-            }
-        }
-
-        public void InitializeModule(IRegionModule module, Scene scene)
-        {
-            module.Initialise(scene, m_config);
-            scene.AddModule(module.Name, module);
-            LoadedModules.Add(module);
-        }
-
-        /// <summary>
-        ///  Loads/initialises a Module instance that can be used by mutliple Regions
-        /// </summary>
-        /// <param name="dllName"></param>
-        /// <param name="moduleName"></param>
-        /// <param name="scene"></param>
-        public void LoadSharedModule(string dllName, string moduleName)
-        {
-            IRegionModule module = LoadModule(dllName, moduleName);
-            if (module != null)
-            {
-                LoadedSharedModules.Add(module.Name, module);
-            }
-        }
-
-        public void LoadRegionModules(string dllName, Scene scene)
-        {
-            IRegionModule[] modules = LoadModules(dllName);
-
-            if (modules.Length > 0)
-            {
-                m_log.Verbose("MODULES", "Found Module Library [{0}]", dllName );
-                foreach (IRegionModule module in modules)
-                {
-                    if (!module.IsSharedModule)
-                    {
-                        m_log.Verbose("MODULES", "   [{0}]: Initializing.", module.Name);
-                        InitializeModule(module, scene);
-                    }
-                }
-            }
-        }
-
-        public void LoadRegionModule(string dllName, string moduleName, Scene scene)
-        {
-            IRegionModule module = LoadModule(dllName, moduleName);
-            if (module != null)
-            {
-                InitializeModule(module, scene);
-            }
-        }
-
-        /// <summary>
-        /// Loads a external Module (if not already loaded) and creates a new instance of it.
-        /// </summary>
-        /// <param name="dllName"></param>
-        /// <param name="moduleName"></param>
-        /// <param name="scene"></param>
-        public IRegionModule LoadModule(string dllName, string moduleName)
-        {
-            IRegionModule[] modules = LoadModules(dllName);
-
-            foreach (IRegionModule module in modules)
-            {
-                if ((module != null) && (module.Name == moduleName))
-                {
-                    return module;
-                }
-            }
-
-            return null;
-        }
-
-        public IRegionModule[] LoadModules(string dllName)
-        {
-            List<IRegionModule> modules = new List<IRegionModule>();
-
-            Assembly pluginAssembly;
-            if (!LoadedAssemblys.TryGetValue(dllName, out pluginAssembly ))
-            {
-                try
-                {
-                    pluginAssembly = Assembly.LoadFrom(dllName);
-                    LoadedAssemblys.Add(dllName, pluginAssembly);
-                }
-                catch( BadImageFormatException e )
-                {
-                    m_log.Warn( "MODULES", "The file [{0}] is not a module assembly.", e.FileName );
-                }
-            }
-
-
-            if (pluginAssembly != null)
-            {
-                foreach (Type pluginType in pluginAssembly.GetTypes())
-                {
-                    if (pluginType.IsPublic)
-                    {
-                        if (!pluginType.IsAbstract)
-                        {
-                            if( pluginType.GetInterface("IRegionModule") != null )
-                            {
-                                modules.Add((IRegionModule) Activator.CreateInstance(pluginType));
-                            }
-                        }
-                    }
-                }
-            }
-
-            return modules.ToArray();
-        }
-
-        public void PostInitialise()
-        {
-            foreach (IRegionModule module in LoadedSharedModules.Values)
-            {
-                module.PostInitialise();
-            }
-
-            foreach (IRegionModule module in LoadedModules)
-            {
-                module.PostInitialise();
-            }
-        }
-
-        public void ClearCache()
-        {
-            LoadedAssemblys.Clear();
-        }
-    }
-}
+/*
+* Copyright (c) Contributors, http://opensimulator.org/
+* See CONTRIBUTORS.TXT for a full list of copyright holders.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*     * Redistributions of source code must retain the above copyright
+*       notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above copyright
+*       notice, this list of conditions and the following disclaimer in the
+*       documentation and/or other materials provided with the distribution.
+*     * Neither the name of the OpenSim Project nor the
+*       names of its contributors may be used to endorse or promote products
+*       derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+* 
+*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using OpenSim.Framework.Console;
+using OpenSim.Region.Environment.Interfaces;
+using OpenSim.Region.Environment.Modules;
+using OpenSim.Region.Environment.Scenes;
+using Nini.Config;
+
+namespace OpenSim.Region.Environment
+{
+    public class ModuleLoader
+    {
+        public Dictionary<string, Assembly> LoadedAssemblys = new Dictionary<string, Assembly>();
+
+        public List<IRegionModule> LoadedModules = new List<IRegionModule>();
+        public Dictionary<string, IRegionModule> LoadedSharedModules = new Dictionary<string, IRegionModule>();
+        private readonly LogBase m_log;
+        private IConfigSource m_config;
+
+        public ModuleLoader(LogBase log, IConfigSource config)
+        {
+            m_log = log;
+            m_config = config;
+        }
+
+        public void PickupModules(Scene scene, string moduleDir)
+        {
+            DirectoryInfo dir = new DirectoryInfo(moduleDir);
+
+            foreach (FileInfo fileInfo in dir.GetFiles("*.dll"))
+            {
+                LoadRegionModules(fileInfo.FullName, scene);
+            }
+        }
+
+        public void LoadDefaultSharedModules()
+        {
+            DynamicTextureModule dynamicModule = new DynamicTextureModule();
+            LoadedSharedModules.Add(dynamicModule.Name, dynamicModule);
+            ChatModule chat = new ChatModule();
+            LoadedSharedModules.Add(chat.Name, chat);
+            InstantMessageModule imMod = new InstantMessageModule();
+            LoadedSharedModules.Add(imMod.Name, imMod);
+            LoadImageURLModule loadMod = new LoadImageURLModule();
+            LoadedSharedModules.Add(loadMod.Name, loadMod);
+        }
+
+        public void InitialiseSharedModules(Scene scene)
+        {
+            foreach (IRegionModule module in LoadedSharedModules.Values)
+            {
+                module.Initialise(scene, m_config);
+                scene.AddModule(module.Name, module); //should be doing this?
+            }
+        }
+
+        public void InitializeModule(IRegionModule module, Scene scene)
+        {
+            module.Initialise(scene, m_config);
+            scene.AddModule(module.Name, module);
+            LoadedModules.Add(module);
+        }
+
+        /// <summary>
+        ///  Loads/initialises a Module instance that can be used by mutliple Regions
+        /// </summary>
+        /// <param name="dllName"></param>
+        /// <param name="moduleName"></param>
+        /// <param name="scene"></param>
+        public void LoadSharedModule(string dllName, string moduleName)
+        {
+            IRegionModule module = LoadModule(dllName, moduleName);
+            if (module != null)
+            {
+                LoadedSharedModules.Add(module.Name, module);
+            }
+        }
+
+        public void LoadRegionModules(string dllName, Scene scene)
+        {
+            IRegionModule[] modules = LoadModules(dllName);
+
+            if (modules.Length > 0)
+            {
+                m_log.Verbose("MODULES", "Found Module Library [{0}]", dllName );
+                foreach (IRegionModule module in modules)
+                {
+                    if (!module.IsSharedModule)
+                    {
+                        m_log.Verbose("MODULES", "   [{0}]: Initializing.", module.Name);
+                        InitializeModule(module, scene);
+                    }
+                }
+            }
+        }
+
+        public void LoadRegionModule(string dllName, string moduleName, Scene scene)
+        {
+            IRegionModule module = LoadModule(dllName, moduleName);
+            if (module != null)
+            {
+                InitializeModule(module, scene);
+            }
+        }
+
+        /// <summary>
+        /// Loads a external Module (if not already loaded) and creates a new instance of it.
+        /// </summary>
+        /// <param name="dllName"></param>
+        /// <param name="moduleName"></param>
+        /// <param name="scene"></param>
+        public IRegionModule LoadModule(string dllName, string moduleName)
+        {
+            IRegionModule[] modules = LoadModules(dllName);
+
+            foreach (IRegionModule module in modules)
+            {
+                if ((module != null) && (module.Name == moduleName))
+                {
+                    return module;
+                }
+            }
+
+            return null;
+        }
+
+        public IRegionModule[] LoadModules(string dllName)
+        {
+            List<IRegionModule> modules = new List<IRegionModule>();
+
+            Assembly pluginAssembly;
+            if (!LoadedAssemblys.TryGetValue(dllName, out pluginAssembly ))
+            {
+                try
+                {
+                    pluginAssembly = Assembly.LoadFrom(dllName);
+                    LoadedAssemblys.Add(dllName, pluginAssembly);
+                }
+                catch( BadImageFormatException e )
+                {
+                    m_log.Verbose( "MODULES", "The file [{0}] is not a module assembly.", e.FileName );
+                }
+            }
+
+
+            if (pluginAssembly != null)
+            {
+                foreach (Type pluginType in pluginAssembly.GetTypes())
+                {
+                    if (pluginType.IsPublic)
+                    {
+                        if (!pluginType.IsAbstract)
+                        {
+                            if( pluginType.GetInterface("IRegionModule") != null )
+                            {
+                                modules.Add((IRegionModule) Activator.CreateInstance(pluginType));
+                            }
+                        }
+                    }
+                }
+            }
+
+            return modules.ToArray();
+        }
+
+        public void PostInitialise()
+        {
+            foreach (IRegionModule module in LoadedSharedModules.Values)
+            {
+                module.PostInitialise();
+            }
+
+            foreach (IRegionModule module in LoadedModules)
+            {
+                module.PostInitialise();
+            }
+        }
+
+        public void ClearCache()
+        {
+            LoadedAssemblys.Clear();
+        }
+    }
+}
diff --git a/OpenSim/Region/Environment/Modules/ChatModule.cs b/OpenSim/Region/Environment/Modules/ChatModule.cs
index 58b9d7b..1f488b0 100644
--- a/OpenSim/Region/Environment/Modules/ChatModule.cs
+++ b/OpenSim/Region/Environment/Modules/ChatModule.cs
@@ -45,26 +45,55 @@ namespace OpenSim.Region.Environment.Modules
         private List<Scene> m_scenes = new List<Scene>();
         private LogBase m_log;
 
+        private string m_server = null;
+        private int m_port = 6668;
+        private string m_user = "USER OpenSimBot 8 * :I'm a OpenSim to irc bot";
+        private string m_nick = null;
+        private string m_channel = null;
+
         private int m_whisperdistance = 10;
         private int m_saydistance = 30;
         private int m_shoutdistance = 100;
 
-        private IRCChatModule m_irc = null;
+        private NetworkStream m_stream;
+        private TcpClient m_irc;
+        private StreamWriter m_ircWriter;
+        private StreamReader m_ircReader;
+        
+        private Thread pingSender;
+        private Thread listener;
+
+        private bool m_enable_irc = false;
+        private bool connected = false;
 
         public ChatModule()
         {
+            m_nick = "OSimBot" + Util.RandomClass.Next(1, 99);
+            m_irc = null;
+            m_ircWriter = null;
+            m_ircReader = null;
+
             m_log = OpenSim.Framework.Console.MainLog.Instance;
         }
 
         public void Initialise(Scene scene, Nini.Config.IConfigSource config)
         {
-            // wrap this in a try block so that defaults will work if
-            // the config file doesn't specify otherwise.
             try {
-                m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance",  m_whisperdistance);
-                m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance);
-                m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance);
-            } catch (Exception e) {}
+                m_server = config.Configs["IRC"].GetString("server");
+                m_nick = config.Configs["IRC"].GetString("nick");
+                m_channel = config.Configs["IRC"].GetString("channel");
+                m_port = config.Configs["IRC"].GetInt("port", m_port);
+                m_user = config.Configs["IRC"].GetString("username", m_user);
+                if (m_server != null && m_nick != null && m_channel != null) {
+                    m_enable_irc = true;
+                }
+            } catch (Exception e) {
+                OpenSim.Framework.Console.MainLog.Instance.Verbose("No IRC config information, skipping IRC bridge configuration");
+            }
+
+            m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance");
+            m_saydistance = config.Configs["Chat"].GetInt("say_distance");
+            m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance");
 
             if (!m_scenes.Contains(scene))
             {
@@ -72,21 +101,43 @@ namespace OpenSim.Region.Environment.Modules
                 scene.EventManager.OnNewClient += NewClient;
                 scene.RegisterModuleInterface<ISimChat>(this);
             }
-            
-            // setup IRC Relay
-            m_irc = new IRCChatModule(config);
         }
 
         public void PostInitialise()
         {
-
-            if (m_irc.Enabled) {
-                m_irc.Connect(m_scenes);
+            if( m_enable_irc ) {
+                try
+                {
+                    m_irc = new TcpClient(m_server, m_port);
+                    m_stream = m_irc.GetStream();
+                    m_ircReader = new StreamReader(m_stream);
+                    m_ircWriter = new StreamWriter(m_stream);
+                    
+                    pingSender = new Thread(new ThreadStart(this.PingRun));
+                    pingSender.Start();
+                    
+                    listener = new Thread(new ThreadStart(this.ListenerRun));
+                    listener.Start();
+                    
+                    m_ircWriter.WriteLine(m_user);
+                    m_ircWriter.Flush();
+                    m_ircWriter.WriteLine("NICK " + m_nick);
+                    m_ircWriter.Flush();
+                    m_ircWriter.WriteLine("JOIN " + m_channel);
+                    m_ircWriter.Flush();
+                    connected = true;
+                }
+                catch (Exception e)
+                {
+                    Console.WriteLine(e.ToString());
+                }
             }
         }
 
-        public void Close() 
+        public void Close()
         {
+            m_ircWriter.Close();
+            m_ircReader.Close();
             m_irc.Close();
         }
 
@@ -105,6 +156,43 @@ namespace OpenSim.Region.Environment.Modules
             client.OnChatFromViewer += SimChat;
         }
 
+        public void PingRun()
+        {
+            while (true)
+            {
+                m_ircWriter.WriteLine("PING :" + m_server);
+                m_ircWriter.Flush();
+                Thread.Sleep(15000);
+            }
+        }
+
+        public void ListenerRun()
+        {
+            string inputLine;
+            LLVector3 pos = new LLVector3(128, 128, 20);
+            while (true)
+            {
+                while ((inputLine = m_ircReader.ReadLine()) != null)
+                {
+                    Console.WriteLine(inputLine);
+                    if (inputLine.Contains(m_channel))
+                    {
+                        string mess = inputLine.Substring(inputLine.IndexOf(m_channel));
+                        foreach (Scene m_scene in m_scenes)
+                        {
+                            m_scene.Broadcast(delegate(IClientAPI client)
+                                                             {
+                                                                 client.SendChatMessage(
+                                                                     Helpers.StringToField(mess), 255, pos, "IRC:",
+                                                                     LLUUID.Zero);
+                                                             });
+                        }
+                    }
+                }
+                Thread.Sleep(50);
+            }
+        }
+
         public void SimChat(Object sender, ChatFromViewerArgs e)
         {
             ScenePresence avatar = null;
@@ -158,215 +246,80 @@ namespace OpenSim.Region.Environment.Modules
 
             m_log.Verbose("CHAT", fromName + " (" + e.Channel + " @ " + scene.RegionInfo.RegionName + ") " + typeName + ": " + e.Message);
 
-           if (m_irc.Connected) 
-           {
-               m_irc.PrivMsg(fromName, scene.RegionInfo.RegionName, e.Message);
-           }
-           
-           if (e.Channel == 0)
-           {
-               foreach (Scene m_scene in m_scenes)
-               {
-                   m_scene.ForEachScenePresence(delegate(ScenePresence presence)
-                                                {
-                                                    int dis = -100000;
-
-                                                    LLVector3 avatarRegionPos = presence.AbsolutePosition + new LLVector3(scene.RegionInfo.RegionLocX * 256, scene.RegionInfo.RegionLocY * 256, 0);
-                                                    dis = Math.Abs((int)avatarRegionPos.GetDistanceTo(fromRegionPos));
-
-                                                    switch (e.Type)
-                                                    {
-                                                    case ChatTypeEnum.Whisper:
-                                                        if (dis < m_whisperdistance)
-                                                        {
-                                                            //should change so the message is sent through the avatar rather than direct to the ClientView
-                                                            presence.ControllingClient.SendChatMessage(message,
-                                                                                                       type,
-                                                                                                       fromPos,
-                                                                                                       fromName,
-                                                                                                       fromAgentID);
-                                                        }
-                                                        break;
-                                                    case ChatTypeEnum.Say:
-                                                        if (dis < m_saydistance)
-                                                        {
-                                                            //Console.WriteLine("sending chat");
-                                                            presence.ControllingClient.SendChatMessage(message,
-                                                                                                       type,
-                                                                                                       fromPos,
-                                                                                                       fromName,
-                                                                                                       fromAgentID);
-                                                        }
-                                                        break;
-                                                    case ChatTypeEnum.Shout:
-                                                        if (dis < m_shoutdistance)
-                                                        {
-                                                            presence.ControllingClient.SendChatMessage(message,
-                                                                                                       type,
-                                                                                                       fromPos,
-                                                                                                       fromName,
-                                                                                                       fromAgentID);
-                                                        }
-                                                        break;
-                                                        
-                                                    case ChatTypeEnum.Broadcast:
-                                                        presence.ControllingClient.SendChatMessage(message, type,
-                                                                                                   fromPos,
-                                                                                                   fromName,
-                                                                                                   fromAgentID);
-                                                        break;
-                                                    default:
-                                                        break;
-                                                    }
-                                                });
+            if (connected)
+            {
+                try
+                {
+                    m_ircWriter.WriteLine("PRIVMSG " + m_channel + " :" + "<" + fromName + " in " + scene.RegionInfo.RegionName + ">:  " +
+                                          e.Message);
+                    m_ircWriter.Flush();
                 }
-            }
-        }
-    }
-
-    class IRCChatModule {
-        private string m_server = null;
-        private int m_port = 6668;
-        private string m_user = "USER OpenSimBot 8 * :I'm a OpenSim to irc bot";
-        private string m_nick = null;
-        private string m_channel = null;
-
-        private NetworkStream m_stream;
-        private TcpClient m_tcp;
-        private StreamWriter m_writer;
-        private StreamReader m_reader;
-        
-        private Thread pingSender;
-        private Thread listener;
-
-        private bool m_enabled = false;
-        private bool m_connected = false;
-
-        private List<Scene> m_scenes = null;
-        private LogBase m_log;
-
-        public IRCChatModule(Nini.Config.IConfigSource config) {
-            m_nick = "OSimBot" + Util.RandomClass.Next(1, 99);
-            m_tcp = null;
-            m_writer = null;
-            m_reader = null;
-
-            try {
-                m_server = config.Configs["IRC"].GetString("server");
-                m_nick = config.Configs["IRC"].GetString("nick");
-                m_channel = config.Configs["IRC"].GetString("channel");
-                m_port = config.Configs["IRC"].GetInt("port", m_port);
-                m_user = config.Configs["IRC"].GetString("username", m_user);
-                if (m_server != null && m_nick != null && m_channel != null) {
-                    m_enabled = true;
+                catch (IOException)
+                {
+                    m_log.Error("IRC","Disconnected from IRC server.");
+                    listener.Abort();
+                    pingSender.Abort();
+                    connected = false;
                 }
-            } catch (Exception e) {
-                Console.WriteLine("No IRC config information, skipping IRC bridge configuration");
             }
-            m_log = OpenSim.Framework.Console.MainLog.Instance;
-        }
 
-        public bool Connect(List<Scene> scenes) {
-            try {
-                m_scenes = scenes;
-
-                m_tcp = new TcpClient(m_server, m_port);
-                m_log.Verbose("IRC", "Connecting...");
-                m_stream = m_tcp.GetStream();
-                m_log.Verbose("IRC", "Connected to " + m_server);
-                m_reader = new StreamReader(m_stream);
-                m_writer = new StreamWriter(m_stream);
-                    
-                pingSender = new Thread(new ThreadStart(this.PingRun));
-                pingSender.Start();
-                    
-                listener = new Thread(new ThreadStart(this.ListenerRun));
-                listener.Start();
-                
-                m_writer.WriteLine(m_user);
-                m_writer.Flush();
-                m_writer.WriteLine("NICK " + m_nick);
-                m_writer.Flush();
-                m_writer.WriteLine("JOIN " + m_channel);
-                m_writer.Flush();
-                m_log.Verbose("IRC", "Connection fully established");
-                m_connected = true;
-            } catch (Exception e) {
-                Console.WriteLine(e.ToString());
-            }
-            return m_connected;
-        }
-
-        public bool Enabled 
-        {
-            get { return m_enabled; }
-        }
-        
-        public bool Connected
-        {
-            get { return m_connected; }
-        }
-
-        public void PrivMsg(string from, string region, string msg) {
-            try {
-                m_writer.WriteLine("PRIVMSG {0} :<{1} in {2}>: {3}", m_channel, from, region, msg);
-                m_writer.Flush();
-            } catch (IOException) {
-                m_log.Error("IRC","Disconnected from IRC server.");
-                listener.Abort();
-                pingSender.Abort();
-                m_connected = false;
-            }
-        }
-
-
-        public void PingRun()
-        {
-            while (true)
-            {
-                m_writer.WriteLine("PING :" + m_server);
-                m_writer.Flush();
-                Thread.Sleep(15000);
-            }
-        }
-
-        public void ListenerRun()
-        {
-            string inputLine;
-            LLVector3 pos = new LLVector3(128, 128, 20);
-            while (true)
+            if (e.Channel == 0)
             {
-                while ((inputLine = m_reader.ReadLine()) != null)
+                foreach (Scene m_scene in m_scenes)
                 {
-                    Console.WriteLine(inputLine);
-                    if (inputLine.Contains(m_channel))
-                    {
-                        string mess = inputLine.Substring(inputLine.IndexOf(m_channel));
-                        foreach (Scene m_scene in m_scenes)
-                        {
-                            m_scene.ForEachScenePresence(delegate(ScenePresence avatar)
-                                                             {
-                                                                 if (!avatar.IsChildAgent)
-                                                                 {
-                                                                     avatar.ControllingClient.SendChatMessage(
-                                                                         Helpers.StringToField(mess), 255, pos, "IRC:",
-                                                                         LLUUID.Zero);
+                    m_scene.ForEachScenePresence(delegate(ScenePresence presence)
+                                                     {
+                                                         int dis = -100000;
+
+                                                         LLVector3 avatarRegionPos = presence.AbsolutePosition + new LLVector3(scene.RegionInfo.RegionLocX * 256, scene.RegionInfo.RegionLocY * 256, 0);
+                                                         dis = Math.Abs((int)avatarRegionPos.GetDistanceTo(fromRegionPos));
+
+                                                         switch (e.Type)
+                                                         {
+                                                             case ChatTypeEnum.Whisper:
+                                                                 if (dis < m_whisperdistance)
+                                                                 {
+                                                                     //should change so the message is sent through the avatar rather than direct to the ClientView
+                                                                     presence.ControllingClient.SendChatMessage(message,
+                                                                                                                type,
+                                                                                                                fromPos,
+                                                                                                                fromName,
+                                                                                                                fromAgentID);
                                                                  }
-                                                             });
-                        }
-                    }
+                                                                 break;
+                                                             default:
+                                                             case ChatTypeEnum.Say:
+                                                                 if (dis < m_saydistance)
+                                                                 {
+                                                                     //Console.WriteLine("sending chat");
+                                                                     presence.ControllingClient.SendChatMessage(message,
+                                                                                                                type,
+                                                                                                                fromPos,
+                                                                                                                fromName,
+                                                                                                                fromAgentID);
+                                                                 }
+                                                                 break;
+                                                             case ChatTypeEnum.Shout:
+                                                                 if (dis < m_shoutdistance)
+                                                                 {
+                                                                     presence.ControllingClient.SendChatMessage(message,
+                                                                                                                type,
+                                                                                                                fromPos,
+                                                                                                                fromName,
+                                                                                                                fromAgentID);
+                                                                 }
+                                                                 break;
+
+                                                             case ChatTypeEnum.Broadcast:
+                                                                 presence.ControllingClient.SendChatMessage(message, type,
+                                                                                                            fromPos,
+                                                                                                            fromName,
+                                                                                                            fromAgentID);
+                                                                 break;
+                                                         }
+                                                     });
                 }
-                Thread.Sleep(50);
             }
         }
-
-
-        public void Close() {
-            listener.Abort();
-            pingSender.Abort();
-            m_writer.Close();
-            m_reader.Close();
-            m_tcp.Close();
-        }
     }
 }
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs
index 553e55f..fe2e470 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.cs
@@ -370,7 +370,7 @@ namespace OpenSim.Region.Environment.Scenes
                         phyScene.SetTerrain(Terrain.GetHeights1D());
                     }
 
-                    storageManager.DataStore.StoreTerrain(Terrain.GetHeights2DD());
+                    storageManager.DataStore.StoreTerrain(Terrain.GetHeights2DD(),RegionInfo.RegionID);
 
                     float[] terData = Terrain.GetHeights1D();
 
@@ -466,7 +466,7 @@ namespace OpenSim.Region.Environment.Scenes
         {
             try
             {
-                double[,] map = storageManager.DataStore.LoadTerrain();
+                double[,] map = storageManager.DataStore.LoadTerrain(RegionInfo.RegionID);
                 if (map == null)
                 {
                     if (string.IsNullOrEmpty(m_regInfo.estateSettings.terrainFile))
@@ -474,7 +474,7 @@ namespace OpenSim.Region.Environment.Scenes
                         MainLog.Instance.Verbose("TERRAIN", "No default terrain. Generating a new terrain.");
                         Terrain.HillsGenerator();
 
-                        storageManager.DataStore.StoreTerrain(Terrain.GetHeights2DD());
+                        storageManager.DataStore.StoreTerrain(Terrain.GetHeights2DD(),RegionInfo.RegionID);
                     }
                     else
                     {
@@ -488,7 +488,7 @@ namespace OpenSim.Region.Environment.Scenes
                             MainLog.Instance.Verbose("TERRAIN", "No terrain found in database or default. Generating a new terrain.");
                             Terrain.HillsGenerator();
                         }
-                        storageManager.DataStore.StoreTerrain(Terrain.GetHeights2DD());
+                        storageManager.DataStore.StoreTerrain(Terrain.GetHeights2DD(), RegionInfo.RegionID);
                     }
                 }
                 else
diff --git a/OpenSim/Region/ExtensionsScriptModule/ScriptManager.cs b/OpenSim/Region/ExtensionsScriptModule/ScriptManager.cs
index be27a0b..74bd856 100644
--- a/OpenSim/Region/ExtensionsScriptModule/ScriptManager.cs
+++ b/OpenSim/Region/ExtensionsScriptModule/ScriptManager.cs
@@ -69,8 +69,8 @@ namespace OpenSim.Region.ExtensionsScriptModule
         }
 
         public void Initialise(Scene scene, IConfigSource config)
-        {
-            System.Console.WriteLine("Initialising Extensions Scripting Module");
+        {
+            OpenSim.Framework.Console.MainLog.Instance.Verbose("SCRIPTMODULE", "Initialising Extensions Scripting Module");
             m_scene = scene;
 
             m_scene.RegisterModuleInterface<IExtensionScriptModule>(this);
diff --git a/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs b/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs
index 87b6d34..81bc938 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs
@@ -93,7 +93,7 @@ namespace OpenSim.Region.Physics.Manager
 							IPhysicsPlugin plug = (IPhysicsPlugin)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
 							plug.Init();
 							this._plugins.Add(plug.GetName(),plug);
-                            Console.WriteLine("added physics engine: " + plug.GetName());
+                            OpenSim.Framework.Console.MainLog.Instance.Verbose("PHYSICS","Added physics engine: " + plug.GetName());
 							
 						}	
 						
diff --git a/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs b/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs
index 733e4c4..cc0ff7a 100644
--- a/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs
+++ b/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs
@@ -43,10 +43,12 @@ namespace OpenSim.DataStore.MonoSqlite
     {
         private const string primSelect = "select * from prims";
         private const string shapeSelect = "select * from primshapes";
+        private const string terrainSelect = "select * from terrain";
 
         private DataSet ds;
         private SqliteDataAdapter primDa;
         private SqliteDataAdapter shapeDa;
+        private SqliteDataAdapter terrainDa;
 
         /***********************************************************************
          *
@@ -70,6 +72,8 @@ namespace OpenSim.DataStore.MonoSqlite
             shapeDa = new SqliteDataAdapter(shapeSelectCmd);
             // SqliteCommandBuilder shapeCb = new SqliteCommandBuilder(shapeDa);
 
+            SqliteCommand terrainSelectCmd = new SqliteCommand(terrainSelect, conn);
+            terrainDa = new SqliteDataAdapter(terrainSelectCmd);
 
             // We fill the data set, now we've got copies in memory for the information
             // TODO: see if the linkage actually holds.
@@ -83,6 +87,10 @@ namespace OpenSim.DataStore.MonoSqlite
                 
                 ds.Tables.Add(createShapeTable());
                 setupShapeCommands(shapeDa, conn);
+
+                ds.Tables.Add(createTerrainTable());
+                setupTerrainCommands(terrainDa, conn);
+                terrainDa.Fill(ds.Tables["terrain"]);
                 
                 // WORKAROUND: This is a work around for sqlite on
                 // windows, which gets really unhappy with blob columns
@@ -210,14 +218,57 @@ namespace OpenSim.DataStore.MonoSqlite
         }
 
 
-        public void StoreTerrain(double[,] ter)
+        public void StoreTerrain(double[,] ter, LLUUID regionID)
         {
+            int revision = OpenSim.Framework.Utilities.Util.UnixTimeSinceEpoch();
+
+            MainLog.Instance.Verbose("DATASTORE", "Storing terrain revision r" + revision.ToString());
+
+            DataTable terrain = ds.Tables["terrain"];
+
+            DataRow newrow = terrain.NewRow();
+            fillTerrainRow(newrow, regionID, revision, ter);
+            terrain.Rows.Add(newrow);
 
+            Commit();
         }
 
-        public double[,] LoadTerrain()
+        public double[,] LoadTerrain(LLUUID regionID)
         {
-            return null;
+            double[,] terret = new double[256, 256];
+            terret.Initialize();
+
+            DataTable terrain = ds.Tables["terrain"];
+
+            DataRow[] rows = terrain.Select("RegionUUID = '" + regionID.ToString() + "'","Revision DESC");
+
+            int rev = 0;
+
+            if (rows.Length > 0)
+            {
+                DataRow row = rows[0];
+
+                byte[] heightmap = (byte[])row["Heightfield"];
+                for (int x = 0; x < 256; x++)
+                {
+                    for (int y = 0; y < 256; y++)
+                    {
+                        terret[x, y] = BitConverter.ToDouble(heightmap, ((x * 256) + y) * 8);
+                    }
+                }
+
+                rev = (int)row["Revision"];
+            }
+            else
+            {
+                MainLog.Instance.Verbose("DATASTORE", "No terrain found for region");
+                return null;
+            }
+
+
+            MainLog.Instance.Verbose("DATASTORE", "Loaded terrain revision r" + rev.ToString());
+
+            return terret;
         }
 
         public void RemoveLandObject(uint id)
@@ -240,6 +291,7 @@ namespace OpenSim.DataStore.MonoSqlite
             lock (ds) {
                 primDa.Update(ds, "prims");
                 shapeDa.Update(ds, "primshapes");
+                terrainDa.Update(ds, "terrain");
                 ds.AcceptChanges();
             }
         }
@@ -263,6 +315,22 @@ namespace OpenSim.DataStore.MonoSqlite
             dt.Columns.Add(col);
         }
 
+        private DataTable createTerrainTable()
+        {
+            DataTable terrain = new DataTable("terrain");
+
+            createCol(terrain, "RegionUUID", typeof(System.String));
+            createCol(terrain, "Revision", typeof(System.Int32));
+            createCol(terrain, "Heightfield", typeof(System.Byte[]));
+
+            /* // Attempting to work out requirements to get SQLite to actually *save* the data.
+            createCol(terrain, "PrIndex", typeof(System.String));
+            terrain.PrimaryKey = new DataColumn[] { terrain.Columns["PrIndex"] };
+            */
+
+            return terrain;
+        }
+
         private DataTable createPrimTable()
         {
             DataTable prims = new DataTable("prims");
@@ -431,6 +499,22 @@ namespace OpenSim.DataStore.MonoSqlite
             return prim;
         }
 
+        private void fillTerrainRow(DataRow row, LLUUID regionUUID, int rev, double[,] val)
+        {
+            row["RegionUUID"] = regionUUID;
+            row["Revision"] = rev;
+
+            System.IO.MemoryStream str = new System.IO.MemoryStream(65536 * sizeof(double));
+            System.IO.BinaryWriter bw = new System.IO.BinaryWriter(str);
+
+            // TODO: COMPATIBILITY - Add byte-order conversions
+            for (int x = 0; x < 256; x++)
+                for (int y = 0; y < 256; y++)
+                    bw.Write(val[x, y]);
+
+            row["Heightfield"] = str.ToArray();
+        }
+
         private void fillPrimRow(DataRow row, SceneObjectPart prim, LLUUID sceneGroupID, LLUUID regionUUID)
         {
             row["UUID"] = prim.UUID;
@@ -692,7 +776,7 @@ namespace OpenSim.DataStore.MonoSqlite
                     subsql += ",\n";
                 }
                 subsql += col.ColumnName + " " + sqliteType(col.DataType);
-                if (col == dt.PrimaryKey[0])
+                if (dt.PrimaryKey.Length > 0 && col == dt.PrimaryKey[0])
                 {
                     subsql += " primary key";
                 }
@@ -746,6 +830,12 @@ namespace OpenSim.DataStore.MonoSqlite
             da.DeleteCommand = delete;
         }
 
+        private void setupTerrainCommands(SqliteDataAdapter da, SqliteConnection conn)
+        {
+            da.InsertCommand = createInsertCommand("terrain", ds.Tables["terrain"]);
+            da.InsertCommand.Connection = conn;
+        }
+
         private void setupShapeCommands(SqliteDataAdapter da, SqliteConnection conn)
         {
             da.InsertCommand = createInsertCommand("primshapes", ds.Tables["primshapes"]);
@@ -764,12 +854,15 @@ namespace OpenSim.DataStore.MonoSqlite
         {
             string createPrims = defineTable(createPrimTable());
             string createShapes = defineTable(createShapeTable());
+            string createTerrain = defineTable(createTerrainTable());
 
             SqliteCommand pcmd = new SqliteCommand(createPrims, conn);
             SqliteCommand scmd = new SqliteCommand(createShapes, conn);
+            SqliteCommand tcmd = new SqliteCommand(createTerrain, conn);
             conn.Open();
             pcmd.ExecuteNonQuery();
             scmd.ExecuteNonQuery();
+            tcmd.ExecuteNonQuery();
             conn.Close();
         }
 
@@ -779,12 +872,15 @@ namespace OpenSim.DataStore.MonoSqlite
             SqliteDataAdapter pDa = new SqliteDataAdapter(primSelectCmd);
             SqliteCommand shapeSelectCmd = new SqliteCommand(shapeSelect, conn);
             SqliteDataAdapter sDa = new SqliteDataAdapter(shapeSelectCmd);
+            SqliteCommand terrainSelectCmd = new SqliteCommand(terrainSelect, conn);
+            SqliteDataAdapter tDa = new SqliteDataAdapter(terrainSelectCmd);
 
             DataSet tmpDS = new DataSet();
             try
             {
                 pDa.Fill(tmpDS, "prims");
                 sDa.Fill(tmpDS, "primshapes");
+                tDa.Fill(tmpDS, "terrain");
             }
             catch (Mono.Data.SqliteClient.SqliteSyntaxException)
             {
@@ -794,6 +890,7 @@ namespace OpenSim.DataStore.MonoSqlite
 
             pDa.Fill(tmpDS, "prims");
             sDa.Fill(tmpDS, "primshapes");
+            tDa.Fill(tmpDS, "terrain");
 
             foreach (DataColumn col in createPrimTable().Columns)
             {
@@ -811,6 +908,14 @@ namespace OpenSim.DataStore.MonoSqlite
                     return false;
                 }
             }
+            foreach (DataColumn col in createTerrainTable().Columns)
+            {
+                if (!tmpDS.Tables["terrain"].Columns.Contains(col.ColumnName))
+                {
+                    MainLog.Instance.Verbose("DATASTORE", "Missing require column:" + col.ColumnName);
+                    return false;
+                }
+            }
             return true;
         }
 
@@ -834,6 +939,14 @@ namespace OpenSim.DataStore.MonoSqlite
             {
                 return DbType.Double;
             }
+            else if (type == typeof(System.Byte))
+            {
+                return DbType.Byte;
+            }
+            else if (type == typeof(System.Double))
+            {
+                return DbType.Double;
+            }
             else if (type == typeof(System.Byte[]))
             {
                 return DbType.Binary;
diff --git a/OpenSim/Region/Storage/OpenSim.DataStore.NullStorage/NullDataStore.cs b/OpenSim/Region/Storage/OpenSim.DataStore.NullStorage/NullDataStore.cs
index 91b1914..f726ea2 100644
--- a/OpenSim/Region/Storage/OpenSim.DataStore.NullStorage/NullDataStore.cs
+++ b/OpenSim/Region/Storage/OpenSim.DataStore.NullStorage/NullDataStore.cs
@@ -61,12 +61,12 @@ namespace OpenSim.DataStore.NullStorage
             return new List<SceneObjectGroup>();
         }
 
-        public void StoreTerrain(double[,] ter)
+        public void StoreTerrain(double[,] ter, LLUUID regionID)
         {
 
         }
 
-        public double[,] LoadTerrain()
+        public double[,] LoadTerrain(LLUUID regionID)
         {
             return null;
         }
-- 
cgit v1.1