diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index e0a96e76ad..de5a6fc04b 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -86,6 +86,7 @@ what it is today. * Grumly57 * GuduleLapointe * Ewe Loon +* Fernando Oliveira * Fly-Man * Flyte Xevious * Imaze Rhiano @@ -135,6 +136,7 @@ what it is today. * Ruud Lathorp * SachaMagne * Salahzar Stenvaag +* satguru p srivastava * sempuki * SignpostMarv * SpotOn3D diff --git a/OpenSim/Framework/SLUtil.cs b/OpenSim/Framework/SLUtil.cs index b337e034fa..f9cb851a9e 100644 --- a/OpenSim/Framework/SLUtil.cs +++ b/OpenSim/Framework/SLUtil.cs @@ -28,6 +28,7 @@ using System; using System.Collections.Generic; using System.Reflection; +using System.Xml; using log4net; using OpenMetaverse; @@ -39,6 +40,13 @@ namespace OpenSim.Framework #region SL / file extension / content-type conversions + public static Dictionary DefaultAvatarAnimations = new Dictionary(); + + static SLUtil() + { + DefaultAvatarAnimations = LoadDefaultAvatarAnimations("data/avataranimations.xml"); + } + public static string SLAssetTypeToContentType(int assetType) { switch ((AssetType)assetType) @@ -374,5 +382,47 @@ namespace OpenSim.Framework return output; } + + /// + /// Load the default SL avatar animations. + /// + /// + public static Dictionary LoadDefaultAvatarAnimations(string path) + { + Dictionary animations = new Dictionary(); + + using (XmlTextReader reader = new XmlTextReader(path)) + { + XmlDocument doc = new XmlDocument(); + doc.Load(reader); + if (doc.DocumentElement != null) + { + foreach (XmlNode nod in doc.DocumentElement.ChildNodes) + { + if (nod.Attributes["name"] != null) + { + string name = nod.Attributes["name"].Value.ToLower(); + string id = nod.InnerText; + animations.Add(name, (UUID)id); + } + } + } + } + + return animations; + } + + /// + /// Get the default SL avatar animation with the given name. + /// + /// + /// + public static UUID GetDefaultAvatarAnimation(string name) + { + if (DefaultAvatarAnimations.ContainsKey(name)) + return DefaultAvatarAnimations[name]; + + return UUID.Zero; + } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index d3c1102fce..c6956fc2b9 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -28,6 +28,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Net; using System.Reflection; using System.Text; @@ -67,6 +68,9 @@ namespace OpenSim private const string PLUGIN_ASSET_CACHE = "/OpenSim/AssetCache"; private const string PLUGIN_ASSET_SERVER_CLIENT = "/OpenSim/AssetClient"; + // OpenSim.ini Section name for ESTATES Settings + public const string ESTATE_SECTION_NAME = "Estates"; + protected string proxyUrl; protected int proxyOffset = 0; @@ -445,12 +449,42 @@ namespace OpenSim { RegionInfo regionInfo = scene.RegionInfo; + string estateOwnerFirstName = null; + string estateOwnerLastName = null; + string estateOwnerEMail = null; + string estateOwnerPassword = null; + string rawEstateOwnerUuid = null; + + if (m_config.Source.Configs[ESTATE_SECTION_NAME] != null) + { + string defaultEstateOwnerName + = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerName", "").Trim(); + string[] ownerNames = defaultEstateOwnerName.Split(' '); + + if (ownerNames.Length >= 2) + { + estateOwnerFirstName = ownerNames[0]; + estateOwnerLastName = ownerNames[1]; + } + + // Info to be used only on Standalone Mode + rawEstateOwnerUuid = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerUUID", null); + estateOwnerEMail = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerEMail", null); + estateOwnerPassword = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerPassword", null); + } + MainConsole.Instance.OutputFormat("Estate {0} has no owner set.", regionInfo.EstateSettings.EstateName); List excluded = new List(new char[1]{' '}); - string first = MainConsole.Instance.CmdPrompt("Estate owner first name", "Test", excluded); - string last = MainConsole.Instance.CmdPrompt("Estate owner last name", "User", excluded); - UserAccount account = scene.UserAccountService.GetUserAccount(regionInfo.ScopeID, first, last); + + if (estateOwnerFirstName == null || estateOwnerLastName == null) + { + estateOwnerFirstName = MainConsole.Instance.CmdPrompt("Estate owner first name", "Test", excluded); + estateOwnerLastName = MainConsole.Instance.CmdPrompt("Estate owner last name", "User", excluded); + } + + UserAccount account + = scene.UserAccountService.GetUserAccount(regionInfo.ScopeID, estateOwnerFirstName, estateOwnerLastName); if (account == null) { @@ -469,23 +503,35 @@ namespace OpenSim if (scene.UserAccountService is UserAccountService) { - string password = MainConsole.Instance.PasswdPrompt("Password"); - string email = MainConsole.Instance.CmdPrompt("Email", ""); + if (estateOwnerPassword == null) + estateOwnerPassword = MainConsole.Instance.PasswdPrompt("Password"); - string rawPrincipalId = MainConsole.Instance.CmdPrompt("User ID", UUID.Random().ToString()); + if (estateOwnerEMail == null) + estateOwnerEMail = MainConsole.Instance.CmdPrompt("Email"); + + if (rawEstateOwnerUuid == null) + rawEstateOwnerUuid = MainConsole.Instance.CmdPrompt("User ID", UUID.Random().ToString()); - UUID principalId = UUID.Zero; - if (!UUID.TryParse(rawPrincipalId, out principalId)) + UUID estateOwnerUuid = UUID.Zero; + if (!UUID.TryParse(rawEstateOwnerUuid, out estateOwnerUuid)) { - m_log.ErrorFormat("[OPENSIM]: ID {0} is not a valid UUID", rawPrincipalId); + m_log.ErrorFormat("[OPENSIM]: ID {0} is not a valid UUID", rawEstateOwnerUuid); return; } + // If we've been given a zero uuid then this signals that we should use a random user id + if (estateOwnerUuid == UUID.Zero) + estateOwnerUuid = UUID.Random(); + account = ((UserAccountService)scene.UserAccountService).CreateUser( - regionInfo.ScopeID, principalId, first, last, password, email); + regionInfo.ScopeID, + estateOwnerUuid, + estateOwnerFirstName, + estateOwnerLastName, + estateOwnerPassword, + estateOwnerEMail); } -// } } if (account == null) @@ -885,15 +931,21 @@ namespace OpenSim /// This method doesn't allow an estate to be created with the same name as existing estates. /// /// - /// A list of estate names that already exist. + /// A list of estate names that already exist. + /// Estate name to create if already known /// true if the estate was created, false otherwise - public bool CreateEstate(RegionInfo regInfo, List existingNames) + public bool CreateEstate(RegionInfo regInfo, Dictionary estatesByName, string estateName) { // Create a new estate regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, true); - string newName = MainConsole.Instance.CmdPrompt("New estate name", regInfo.EstateSettings.EstateName); - if (existingNames.Contains(newName)) + string newName; + if (estateName != null && estateName != "") + newName = estateName; + else + newName = MainConsole.Instance.CmdPrompt("New estate name", regInfo.EstateSettings.EstateName); + + if (estatesByName.ContainsKey(newName)) { MainConsole.Instance.OutputFormat("An estate named {0} already exists. Please try again.", newName); return false; @@ -920,66 +972,102 @@ namespace OpenSim if (EstateDataService != null) regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, false); - if (regInfo.EstateSettings.EstateID == 0) // No record at all + if (regInfo.EstateSettings.EstateID != 0) + return; + + m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName); + + List estates = EstateDataService.LoadEstateSettingsAll(); + Dictionary estatesByName = new Dictionary(); + + foreach (EstateSettings estate in estates) + estatesByName[estate.EstateName] = estate; + + string defaultEstateName = null; + + if (m_config.Source.Configs[ESTATE_SECTION_NAME] != null) { - m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName); - - List estates = EstateDataService.LoadEstateSettingsAll(); - List estateNames = new List(); - foreach (EstateSettings estate in estates) - estateNames.Add(estate.EstateName); - - while (true) + defaultEstateName = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateName", null); + + if (defaultEstateName != null) { - if (estates.Count == 0) - { - m_log.Info("[ESTATE] No existing estates found. You must create a new one."); - - if (CreateEstate(regInfo, estateNames)) - break; + EstateSettings defaultEstate; + bool defaultEstateJoined = false; + + if (estatesByName.ContainsKey(defaultEstateName)) + { + defaultEstate = estatesByName[defaultEstateName]; + + if (EstateDataService.LinkRegion(regInfo.RegionID, (int)defaultEstate.EstateID)) + defaultEstateJoined = true; + } + else + { + if (CreateEstate(regInfo, estatesByName, defaultEstateName)) + defaultEstateJoined = true; + } + + if (defaultEstateJoined) + return; + else + m_log.ErrorFormat( + "[OPENSIM BASE]: Joining default estate {0} failed", defaultEstateName); + } + } + + // If we have no default estate or creation of the default estate failed then ask the user. + while (true) + { + if (estates.Count == 0) + { + m_log.Info("[ESTATE]: No existing estates found. You must create a new one."); + + if (CreateEstate(regInfo, estatesByName, null)) + break; + else + continue; + } + else + { + string response + = MainConsole.Instance.CmdPrompt( + string.Format( + "Do you wish to join region {0} to an existing estate (yes/no)?", regInfo.RegionName), + "yes", + new List() { "yes", "no" }); + + if (response == "no") + { + if (CreateEstate(regInfo, estatesByName, null)) + break; else continue; } else { - string response + string[] estateNames = estatesByName.Keys.ToArray(); + response = MainConsole.Instance.CmdPrompt( string.Format( - "Do you wish to join region {0} to an existing estate (yes/no)?", regInfo.RegionName), - "yes", - new List() { "yes", "no" }); - - if (response == "no") + "Name of estate to join. Existing estate names are ({0})", + string.Join(", ", estateNames)), + estateNames[0]); + + List estateIDs = EstateDataService.GetEstates(response); + if (estateIDs.Count < 1) { - if (CreateEstate(regInfo, estateNames)) - break; - else - continue; - } - else - { - response - = MainConsole.Instance.CmdPrompt( - string.Format( - "Name of estate to join. Existing estate names are ({0})", string.Join(", ", estateNames.ToArray())), - estateNames[0]); - - List estateIDs = EstateDataService.GetEstates(response); - if (estateIDs.Count < 1) - { - MainConsole.Instance.Output("The name you have entered matches no known estate. Please try again."); - continue; - } - - int estateID = estateIDs[0]; - - regInfo.EstateSettings = EstateDataService.LoadEstateSettings(estateID); - - if (EstateDataService.LinkRegion(regInfo.RegionID, estateID)) - break; - - MainConsole.Instance.Output("Joining the estate failed. Please try again."); + MainConsole.Instance.Output("The name you have entered matches no known estate. Please try again."); + continue; } + + int estateID = estateIDs[0]; + + regInfo.EstateSettings = EstateDataService.LoadEstateSettings(estateID); + + if (EstateDataService.LinkRegion(regInfo.RegionID, estateID)) + break; + + MainConsole.Instance.Output("Joining the estate failed. Please try again."); } } } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index d98ff68d39..b388b10b8a 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -317,7 +317,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP protected readonly UUID m_agentId; private readonly uint m_circuitCode; private readonly byte[] m_channelVersion = Utils.EmptyBytes; - private readonly Dictionary m_defaultAnimations = new Dictionary(); private readonly IGroupsModule m_GroupsModule; private int m_cachedTextureSerial; @@ -452,10 +451,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP RegisterInterface(this); RegisterInterface(this); - InitDefaultAnimations(); - m_scene = scene; - m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); m_entityProps = new PriorityQueue(m_scene.Entities.Count); m_fullUpdateDataBlocksBuilder = new List(); @@ -11210,30 +11206,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(scriptQuestion, ThrottleOutPacketType.Task); } - private void InitDefaultAnimations() - { - using (XmlTextReader reader = new XmlTextReader("data/avataranimations.xml")) - { - XmlDocument doc = new XmlDocument(); - doc.Load(reader); - if (doc.DocumentElement != null) - foreach (XmlNode nod in doc.DocumentElement.ChildNodes) - { - if (nod.Attributes["name"] != null) - { - string name = nod.Attributes["name"].Value.ToLower(); - string id = nod.InnerText; - m_defaultAnimations.Add(name, (UUID)id); - } - } - } - } - public UUID GetDefaultAnimation(string name) { - if (m_defaultAnimations.ContainsKey(name)) - return m_defaultAnimations[name]; - return UUID.Zero; + return SLUtil.GetDefaultAvatarAnimation(name); } /// diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index 523832566d..a26c73a07c 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs @@ -270,12 +270,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver m_archiveWriter = new TarArchiveWriter(m_saveStream); + m_log.InfoFormat("[INVENTORY ARCHIVER]: Adding control file to archive."); + // Write out control file. This has to be done first so that subsequent loaders will see this file first // XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this // not sure how to fix this though, short of going with a completely different file format. m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options)); - m_log.InfoFormat("[INVENTORY ARCHIVER]: Added control file to archive."); - + if (inventoryFolder != null) { m_log.DebugFormat( diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs index 9ec4ebe8da..c179a34b38 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs @@ -108,12 +108,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver // "[ARCHIVER]: Received {0} of {1} assets requested", // assetsFoundUuids.Count, assetsFoundUuids.Count + assetsNotFoundUuids.Count); + m_log.InfoFormat("[ARCHIVER]: Adding region settings to archive."); + // Write out region settings string settingsPath = String.Format("{0}{1}.xml", ArchiveConstants.SETTINGS_PATH, m_scene.RegionInfo.RegionName); m_archiveWriter.WriteFile(settingsPath, RegionSettingsSerializer.Serialize(m_scene.RegionInfo.RegionSettings)); - m_log.InfoFormat("[ARCHIVER]: Added region settings to archive."); + m_log.InfoFormat("[ARCHIVER]: Adding parcel settings to archive."); // Write out land data (aka parcel) settings ListlandObjects = m_scene.LandChannel.AllParcels(); @@ -124,7 +126,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver landData.GlobalID.ToString()); m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData)); } - m_log.InfoFormat("[ARCHIVER]: Added parcel settings to archive."); + + m_log.InfoFormat("[ARCHIVER]: Adding terrain information to archive."); // Write out terrain string terrainPath @@ -135,7 +138,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver m_archiveWriter.WriteFile(terrainPath, ms.ToArray()); ms.Close(); - m_log.InfoFormat("[ARCHIVER]: Added terrain information to archive."); + m_log.InfoFormat("[ARCHIVER]: Adding scene objects to archive."); // Write out scene object metadata foreach (SceneObjectGroup sceneObject in m_sceneObjects) @@ -145,10 +148,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver string serializedObject = m_serialiser.SerializeGroupToXml2(sceneObject, m_options); m_archiveWriter.WriteFile(ArchiveHelpers.CreateObjectPath(sceneObject), serializedObject); } - - m_log.InfoFormat("[ARCHIVER]: Added scene objects to archive."); } - - } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index ffcf063121..4d459bf2d6 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs @@ -219,12 +219,19 @@ namespace OpenSim.Region.CoreModules.World.Archiver m_log.InfoFormat("[ARCHIVER]: Added control file to archive."); if (SaveAssets) - new AssetsRequest( - new AssetsArchiver(archiveWriter), assetUuids, - m_scene.AssetService, m_scene.UserAccountService, - m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets).Execute(); + { + AssetsRequest ar + = new AssetsRequest( + new AssetsArchiver(archiveWriter), assetUuids, + m_scene.AssetService, m_scene.UserAccountService, + m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets); + + Util.FireAndForget(o => ar.Execute()); + } else + { awre.ReceivedAllAssets(new List(), new List()); + } } catch (Exception) { diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs index 8e29e3ca9b..55110dcc86 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs @@ -141,13 +141,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver PerformAssetsRequestCallback(null); return; } - - foreach (KeyValuePair kvp in m_uuids) - { - m_assetService.Get(kvp.Key.ToString(), kvp.Value, PreAssetRequestCallback); - } m_requestCallbackTimer.Enabled = true; + + foreach (KeyValuePair kvp in m_uuids) + { +// m_assetService.Get(kvp.Key.ToString(), kvp.Value, PreAssetRequestCallback); + AssetBase asset = m_assetService.Get(kvp.Key.ToString()); + PreAssetRequestCallback(kvp.Key.ToString(), kvp.Value, asset); + } } protected void OnRequestCallbackTimeout(object source, ElapsedEventArgs args) diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index be0d56e0dc..24b9e6b4b1 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -34,6 +34,9 @@ using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.CoreModules.World.Estate; +using log4net; +using System.Reflection; +using System.Xml; namespace OpenSim.Region.OptionalModules.World.NPC { @@ -132,7 +135,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC public UUID GetDefaultAnimation(string name) { - return UUID.Zero; + return SLUtil.GetDefaultAvatarAnimation(name); } public Vector3 Position diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index eb633b33bb..a142f26be2 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -712,7 +712,7 @@ namespace OpenSim.Region.RegionCombinerModule List CoarseLocations = new List(); List AvatarUUIDs = new List(); - + connectiondata.RegionScene.ForEachRootScenePresence(delegate(ScenePresence sp) { if (sp.UUID != presence.UUID) diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index a820ddf93f..08a6194fb2 100755 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -36,7 +36,6 @@ [Startup] - ;# {ConsolePrompt} {} {ConsolePrompt} {} "Region (\R) " ;; Console prompt ;; Certain special characters can be used to customize the prompt @@ -232,6 +231,24 @@ ;; server to send mail through. ; emailmodule = DefaultEmailModule +[Estates] + ; If these values are commented out then the user will be asked for estate details when required (this is the normal case). + ; If these values are uncommented then they will be used to create a default estate as necessary. + ; New regions will be automatically assigned to that default estate. + + ; DefaultEstateName = My Estate + ; DefaultEstateOwnerName = FirstName LastName + + ; The following parameters will only be used on a standalone system to create an estate owner that does not already exist + + ; If DefaultEstateOwnerUUID is left at UUID.Zero (as below) then a random UUID will be assigned. + ; This is normally what you want + ; DefaultEstateOwnerUUID = 00000000-0000-0000-0000-000000000000 + + ; DefaultEstateOwnerEMail = owner@domain.com + ; DefaultEstateOwnerPassword = password + + [SMTP] ;; The SMTP server enabled the email module to send email to external ;; destinations. @@ -753,8 +770,7 @@ ;; groups service if the service is using these keys ; XmlRpcServiceReadKey = 1234 ; XmlRpcServiceWriteKey = 1234 - - + [InterestManagement] ;# {UpdatePrioritizationScheme} {} {Update prioritization scheme?} {BestAvatarResponsiveness Time Distance SimpleAngularDistance FrontBack} BestAvatarResponsiveness ;; This section controls how state updates are prioritized for each client