diff --git a/OpenSim/Framework/RegionSettings.cs b/OpenSim/Framework/RegionSettings.cs index c142bd9ae0..47a27807b2 100644 --- a/OpenSim/Framework/RegionSettings.cs +++ b/OpenSim/Framework/RegionSettings.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; using System.IO; using OpenMetaverse; +using System.Runtime.Serialization; namespace OpenSim.Framework { @@ -71,6 +72,32 @@ namespace OpenSim.Framework return pos + offset; } + + /// + /// Returns a string representation of this SpawnPoint. + /// + /// + public override string ToString() + { + return string.Format("{0},{1},{2}", Yaw, Pitch, Distance); + } + + /// + /// Generate a SpawnPoint from a string + /// + /// + public static SpawnPoint Parse(string str) + { + string[] parts = str.Split(','); + if (parts.Length != 3) + throw new ArgumentException("Invalid string: " + str); + + SpawnPoint sp = new SpawnPoint(); + sp.Yaw = float.Parse(parts[0]); + sp.Pitch = float.Parse(parts[1]); + sp.Distance = float.Parse(parts[2]); + return sp; + } } public class RegionSettings @@ -478,7 +505,7 @@ namespace OpenSim.Framework } // Connected Telehub object - private UUID m_TelehubObject; + private UUID m_TelehubObject = UUID.Zero; public UUID TelehubObject { get diff --git a/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs b/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs index 931898ce10..f18435d308 100644 --- a/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs +++ b/OpenSim/Framework/Serialization/External/RegionSettingsSerializer.cs @@ -30,6 +30,8 @@ using System.Text; using System.Xml; using OpenMetaverse; using OpenSim.Framework; +using log4net; +using System.Reflection; namespace OpenSim.Framework.Serialization.External { @@ -187,7 +189,29 @@ namespace OpenSim.Framework.Serialization.External break; } } - + + xtr.ReadEndElement(); + + if (xtr.IsStartElement("Telehub")) + { + xtr.ReadStartElement("Telehub"); + + while (xtr.Read() && xtr.NodeType != XmlNodeType.EndElement) + { + switch (xtr.Name) + { + case "TelehubObject": + settings.TelehubObject = UUID.Parse(xtr.ReadElementContentAsString()); + break; + case "SpawnPoint": + string str = xtr.ReadElementContentAsString(); + SpawnPoint sp = SpawnPoint.Parse(str); + settings.AddSpawnPoint(sp); + break; + } + } + } + xtr.Close(); sr.Close(); @@ -243,7 +267,16 @@ namespace OpenSim.Framework.Serialization.External xtw.WriteElementString("SunPosition", settings.SunPosition.ToString()); // Note: 'SunVector' isn't saved because this value is owned by the Sun Module, which // calculates it automatically according to the date and other factors. - xtw.WriteEndElement(); + xtw.WriteEndElement(); + + xtw.WriteStartElement("Telehub"); + if (settings.TelehubObject != UUID.Zero) + { + xtw.WriteElementString("TelehubObject", settings.TelehubObject.ToString()); + foreach (SpawnPoint sp in settings.SpawnPoints()) + xtw.WriteElementString("SpawnPoint", sp.ToString()); + } + xtw.WriteEndElement(); xtw.WriteEndElement(); diff --git a/OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs b/OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs index a61e4af65d..09b6f6ddad 100644 --- a/OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs +++ b/OpenSim/Framework/Serialization/Tests/RegionSettingsSerializerTests.cs @@ -78,6 +78,10 @@ namespace OpenSim.Framework.Serialization.Tests true 12 + + 00000000-0000-0000-0000-111111111111 + 1,-2,0.33 + "; private RegionSettings m_rs; @@ -116,6 +120,8 @@ namespace OpenSim.Framework.Serialization.Tests m_rs.TerrainTexture4 = UUID.Parse("00000000-0000-0000-0000-000000000080"); m_rs.UseEstateSun = true; m_rs.WaterHeight = 23; + m_rs.TelehubObject = UUID.Parse("00000000-0000-0000-0000-111111111111"); + m_rs.AddSpawnPoint(SpawnPoint.Parse("1,-2,0.33")); } [Test] @@ -129,6 +135,8 @@ namespace OpenSim.Framework.Serialization.Tests Assert.That(deserRs.TerrainTexture2, Is.EqualTo(m_rs.TerrainTexture2)); Assert.That(deserRs.DisablePhysics, Is.EqualTo(m_rs.DisablePhysics)); Assert.That(deserRs.TerrainLowerLimit, Is.EqualTo(m_rs.TerrainLowerLimit)); + Assert.That(deserRs.TelehubObject, Is.EqualTo(m_rs.TelehubObject)); + Assert.That(deserRs.SpawnPoints()[0].ToString(), Is.EqualTo(m_rs.SpawnPoints()[0].ToString())); } } } diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index d98ea39d1d..875c073419 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -371,11 +371,21 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory if (missingTexturesOnly) { if (m_scene.AssetService.Get(face.TextureID.ToString()) != null) + { continue; + } else + { + // On inter-simulator teleports, this occurs if baked textures are not being stored by the + // grid asset service (which means that they are not available to the new region and so have + // to be re-requested from the client). + // + // The only available core OpenSimulator behaviour right now + // is not to store these textures, temporarily or otherwise. m_log.DebugFormat( "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.", face.TextureID, idx, sp.Name); + } } else { diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index d4fbdce48c..514a65b282 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -53,7 +53,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public const int DefaultMaxTransferDistance = 4095; public const bool EnableWaitForCallbackFromTeleportDestDefault = true; - /// /// The maximum distance, in standard region units (256m) that an agent is allowed to transfer. /// @@ -211,6 +210,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName, e.Message, e.StackTrace); + // Make sure that we clear the in-transit flag so that future teleport attempts don't always fail. + ResetFromTransit(sp.UUID); + sp.ControllingClient.SendTeleportFailed("Internal error"); } } @@ -386,7 +388,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - if (IsInTransit(sp.UUID)) // Avie is already on the way. Caller shouldn't do this. + if (!SetInTransit(sp.UUID)) // Avie is already on the way. Caller shouldn't do this. { m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2} ({3}) {4}/{5} - agent is already in transit.", @@ -434,8 +436,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (!m_aScene.SimulationService.QueryAccess(finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) { sp.ControllingClient.SendTeleportFailed("Teleport failed: " + reason); + ResetFromTransit(sp.UUID); + return; } + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); sp.ControllingClient.SendTeleportStart(teleportFlags); @@ -475,13 +480,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer bool logout = false; if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) { - sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", - reason)); + sp.ControllingClient.SendTeleportFailed( + String.Format("Teleport refused: {0}", reason)); + ResetFromTransit(sp.UUID); + return; } // OK, it got this agent. Let's close some child agents sp.CloseChildAgents(newRegionX, newRegionY); + IClientIPEndpoint ipepClient; if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) { @@ -518,8 +526,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); } - SetInTransit(sp.UUID); - // Let's send a full update of the agent. This is a synchronous call. AgentData agent = new AgentData(); sp.CopyTo(agent); @@ -532,8 +538,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { // Region doesn't take it m_log.WarnFormat( - "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Returning avatar to source region.", - sp.Name, finalDestination.RegionName); + "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Returning avatar to source region.", + sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); Fail(sp, finalDestination, logout); return; @@ -565,8 +571,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (EnableWaitForCallbackFromTeleportDest && !WaitForCallback(sp.UUID)) { m_log.WarnFormat( - "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} failed due to no callback from destination region. Returning avatar to source region.", - sp.Name, finalDestination.RegionName); + "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", + sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); Fail(sp, finalDestination, logout); return; @@ -662,8 +668,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected virtual void SetCallbackURL(AgentData agent, RegionInfo region) { agent.CallbackURI = region.ServerURI + "agent/" + agent.AgentID.ToString() + "/" + region.RegionID.ToString() + "/release/"; - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Set callback URL to {0}", agent.CallbackURI); + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Set release callback URL to {0} in {1}", + agent.CallbackURI, region.RegionName); } protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout) @@ -1921,25 +1929,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return count > 0; } - protected void SetInTransit(UUID id) + /// + /// Set that an agent is in the process of being teleported. + /// + /// The ID of the agent being teleported + /// true if the agent was not already in transit, false if it was + protected bool SetInTransit(UUID id) { lock (m_agentsInTransit) { if (!m_agentsInTransit.Contains(id)) + { m_agentsInTransit.Add(id); - } - } - - protected bool IsInTransit(UUID id) - { - lock (m_agentsInTransit) - { - if (m_agentsInTransit.Contains(id)) return true; + } } + return false; } + /// + /// Show whether the given agent is being teleported. + /// + /// true if the agent is in the process of being teleported, false otherwise. + /// The agent ID + protected bool IsInTransit(UUID id) + { + lock (m_agentsInTransit) + return m_agentsInTransit.Contains(id); + } + + /// + /// Set that an agent is no longer being teleported. + /// + /// + /// + /// true if the agent was flagged as being teleported when this method was called, false otherwise + /// protected bool ResetFromTransit(UUID id) { lock (m_agentsInTransit) @@ -1950,6 +1976,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return true; } } + return false; } @@ -1980,4 +2007,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #endregion } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs index 9255791c76..e91e8b9f45 100644 --- a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs @@ -64,6 +64,8 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules private TimeSpan m_QueueTimeout = new TimeSpan(2, 0, 0); // 2 hours without llGetNextEmail drops the queue private string m_InterObjectHostname = "lsl.opensim.local"; + private int m_MaxEmailSize = 4096; // largest email allowed by default, as per lsl docs. + // Scenes by Region Handle private Dictionary m_Scenes = new Dictionary(); @@ -127,6 +129,7 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules SMTP_SERVER_PORT = SMTPConfig.GetInt("SMTP_SERVER_PORT", SMTP_SERVER_PORT); SMTP_SERVER_LOGIN = SMTPConfig.GetString("SMTP_SERVER_LOGIN", SMTP_SERVER_LOGIN); SMTP_SERVER_PASSWORD = SMTPConfig.GetString("SMTP_SERVER_PASSWORD", SMTP_SERVER_PASSWORD); + m_MaxEmailSize = SMTPConfig.GetInt("email_max_size", m_MaxEmailSize); } catch (Exception e) { @@ -176,18 +179,6 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules get { return true; } } - /// - /// Delay function using thread in seconds - /// - /// - private void DelayInSeconds(int delay) - { - delay = (int)((float)delay * 1000); - if (delay == 0) - return; - System.Threading.Thread.Sleep(delay); - } - private bool IsLocal(UUID objectID) { string unused; @@ -267,10 +258,9 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules m_log.Error("[EMAIL] REGEX Problem in EMail Address: "+address); return; } - //FIXME:Check if subject + body = 4096 Byte - if ((subject.Length + body.Length) > 1024) + if ((subject.Length + body.Length) > m_MaxEmailSize) { - m_log.Error("[EMAIL] subject + body > 1024 Byte"); + m_log.Error("[EMAIL] subject + body larger than limit of " + m_MaxEmailSize + " bytes"); return; } @@ -345,10 +335,6 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules // TODO FIX } } - - //DONE: Message as Second Life style - //20 second delay - AntiSpam System - for now only 10 seconds - DelayInSeconds(10); } /// diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index 38db23924f..0c4069fe54 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -245,6 +245,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver // Reload serialized prims m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count); + UUID oldTelehubUUID = m_scene.RegionInfo.RegionSettings.TelehubObject; + IRegionSerialiserModule serialiser = m_scene.RequestModuleInterface(); int sceneObjectsLoadedCount = 0; @@ -266,11 +268,21 @@ namespace OpenSim.Region.CoreModules.World.Archiver SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); + bool isTelehub = (sceneObject.UUID == oldTelehubUUID); + // For now, give all incoming scene objects new uuids. This will allow scenes to be cloned // on the same region server and multiple examples a single object archive to be imported // to the same scene (when this is possible). sceneObject.ResetIDs(); + if (isTelehub) + { + // Change the Telehub Object to the new UUID + m_scene.RegionInfo.RegionSettings.TelehubObject = sceneObject.UUID; + m_scene.RegionInfo.RegionSettings.Save(); + oldTelehubUUID = UUID.Zero; + } + // Try to retain the original creator/owner/lastowner if their uuid is present on this grid // or creator data is present. Otherwise, use the estate owner instead. foreach (SceneObjectPart part in sceneObject.Parts) @@ -347,7 +359,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver int ignoredObjects = serialisedSceneObjects.Count - sceneObjectsLoadedCount; if (ignoredObjects > 0) - m_log.WarnFormat("[ARCHIVER]: Ignored {0} scene objects that already existed in the scene", ignoredObjects); + m_log.WarnFormat("[ARCHIVER]: Ignored {0} scene objects that already existed in the scene", ignoredObjects); + + if (oldTelehubUUID != UUID.Zero) + { + m_log.WarnFormat("Telehub object not found: {0}", oldTelehubUUID); + m_scene.RegionInfo.RegionSettings.TelehubObject = UUID.Zero; + m_scene.RegionInfo.RegionSettings.ClearSpawnPoints(); + } } /// @@ -523,6 +542,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver currentRegionSettings.TerrainTexture4 = loadedRegionSettings.TerrainTexture4; currentRegionSettings.UseEstateSun = loadedRegionSettings.UseEstateSun; currentRegionSettings.WaterHeight = loadedRegionSettings.WaterHeight; + currentRegionSettings.TelehubObject = loadedRegionSettings.TelehubObject; + currentRegionSettings.ClearSpawnPoints(); + foreach (SpawnPoint sp in loadedRegionSettings.SpawnPoints()) + currentRegionSettings.AddSpawnPoint(sp); currentRegionSettings.Save(); diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index eabe46e936..5679ad5dcb 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs @@ -328,7 +328,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver /// public string CreateControlFile(Dictionary options) { - int majorVersion = MAX_MAJOR_VERSION, minorVersion = 7; + int majorVersion = MAX_MAJOR_VERSION, minorVersion = 8; // // if (options.ContainsKey("version")) // { diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index 053c6f59d4..394ca27123 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs @@ -534,6 +534,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests rs.TerrainTexture4 = UUID.Parse("00000000-0000-0000-0000-000000000080"); rs.UseEstateSun = true; rs.WaterHeight = 23; + rs.TelehubObject = UUID.Parse("00000000-0000-0000-0000-111111111111"); + rs.AddSpawnPoint(SpawnPoint.Parse("1,-2,0.33")); tar.WriteFile(ArchiveConstants.SETTINGS_PATH + "region1.xml", RegionSettingsSerializer.Serialize(rs)); @@ -580,6 +582,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests Assert.That(loadedRs.TerrainTexture4, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000080"))); Assert.That(loadedRs.UseEstateSun, Is.True); Assert.That(loadedRs.WaterHeight, Is.EqualTo(23)); + Assert.AreEqual(UUID.Zero, loadedRs.TelehubObject); // because no object was found with the original UUID + Assert.AreEqual(0, loadedRs.SpawnPoints().Count); } /// diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 89cde057b7..3e11db3f6f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -591,6 +591,15 @@ namespace OpenSim.Region.Framework.Scenes get { return m_sceneGraph.Entities; } } + // can be closest/random/sequence + private string m_SpawnPointRouting = "closest"; + // used in sequence see: SpawnPoint() + private int m_SpawnPoint; + public string SpawnPointRouting + { + get { return m_SpawnPointRouting; } + } + #endregion Properties #region Constructors @@ -608,7 +617,7 @@ namespace OpenSim.Region.Framework.Scenes Random random = new Random(); - m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue/2))+(uint)(uint.MaxValue/4); + m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue / 2)) + (uint)(uint.MaxValue / 4); m_moduleLoader = moduleLoader; m_authenticateHandler = authen; m_sceneGridService = sceneGridService; @@ -728,6 +737,8 @@ namespace OpenSim.Region.Framework.Scenes m_maxPhys = RegionInfo.PhysPrimMax; } + m_SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest"); + // Here, if clamping is requested in either global or // local config, it will be used // @@ -2684,10 +2695,10 @@ namespace OpenSim.Region.Framework.Scenes { SceneObjectGroup grp = sceneObject; - m_log.DebugFormat( - "[ATTACHMENT]: Received attachment {0}, inworld asset id {1}", grp.FromItemID, grp.UUID); - m_log.DebugFormat( - "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); +// m_log.DebugFormat( +// "[ATTACHMENT]: Received attachment {0}, inworld asset id {1}", grp.FromItemID, grp.UUID); +// m_log.DebugFormat( +// "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); RootPrim.RemFlag(PrimFlags.TemporaryOnRez); @@ -3554,7 +3565,7 @@ namespace OpenSim.Region.Framework.Scenes public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, out string reason, bool requirePresenceLookup) { bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 || - (teleportFlags & (uint)TPFlags.ViaHGLogin) != 0); + (teleportFlags & (uint)TPFlags.ViaHGLogin) != 0); bool viahome = ((teleportFlags & (uint)TPFlags.ViaHome) != 0); bool godlike = ((teleportFlags & (uint)TPFlags.Godlike) != 0); @@ -3570,8 +3581,17 @@ namespace OpenSim.Region.Framework.Scenes // Don't disable this log message - it's too helpful m_log.DebugFormat( "[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, IP {6}, viewer {7}, teleportflags ({8}), position {9})", - RegionInfo.RegionName, (agent.child ? "child" : "root"),agent.firstname, agent.lastname, - agent.AgentID, agent.circuitcode, agent.IPAddress, agent.Viewer, ((TPFlags)teleportFlags).ToString(), agent.startpos); + RegionInfo.RegionName, + (agent.child ? "child" : "root"), + agent.firstname, + agent.lastname, + agent.AgentID, + agent.circuitcode, + agent.IPAddress, + agent.Viewer, + ((TPFlags)teleportFlags).ToString(), + agent.startpos + ); if (LoginsDisabled) { @@ -3586,7 +3606,11 @@ namespace OpenSim.Region.Framework.Scenes // We have a zombie from a crashed session. // Or the same user is trying to be root twice here, won't work. // Kill it. - m_log.DebugFormat("[SCENE]: Zombie scene presence detected for {0} in {1}", agent.AgentID, RegionInfo.RegionName); + m_log.DebugFormat( + "[SCENE]: Zombie scene presence detected for {0} in {1}", + agent.AgentID, + RegionInfo.RegionName + ); sp.ControllingClient.Close(); sp = null; } @@ -3613,8 +3637,7 @@ namespace OpenSim.Region.Framework.Scenes { if (!VerifyUserPresence(agent, out reason)) return false; - } - catch (Exception e) + } catch (Exception e) { m_log.ErrorFormat( "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); @@ -3649,8 +3672,7 @@ namespace OpenSim.Region.Framework.Scenes CapsModule.SetAgentCapsSeeds(agent); CapsModule.CreateCaps(agent.AgentID); } - } - else + } else { // Let the SP know how we got here. This has a lot of interesting // uses down the line. @@ -3673,7 +3695,7 @@ namespace OpenSim.Region.Framework.Scenes agent.teleportFlags = teleportFlags; m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent); - if (vialogin) + if (vialogin) { // CleanDroppedAttachments(); @@ -3714,8 +3736,7 @@ namespace OpenSim.Region.Framework.Scenes agent.startpos.Z = 720; } } - } - else + } else { if (agent.startpos.X > EastBorders[0].BorderLine.Z) { @@ -3741,10 +3762,19 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup telehub = GetSceneObjectGroup(RegionInfo.RegionSettings.TelehubObject); // Can have multiple SpawnPoints List spawnpoints = RegionInfo.RegionSettings.SpawnPoints(); - if ( spawnpoints.Count > 1) + if (spawnpoints.Count > 1) { - // We have multiple SpawnPoints, Route the agent to a random one - agent.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count)].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); + // We have multiple SpawnPoints, Route the agent to a random or sequential one + if (SpawnPointRouting == "random") + agent.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation( + telehub.AbsolutePosition, + telehub.GroupRotation + ); + else + agent.startpos = spawnpoints[SpawnPoint()].GetLocation( + telehub.AbsolutePosition, + telehub.GroupRotation + ); } else { @@ -5640,5 +5670,19 @@ Environment.Exit(1); } } } + + // manage and select spawn points in sequence + public int SpawnPoint() + { + int spawnpoints = RegionInfo.RegionSettings.SpawnPoints().Count; + + if (spawnpoints == 0) + return 0; + + m_SpawnPoint++; + if (m_SpawnPoint > spawnpoints) + m_SpawnPoint = 1; + return m_SpawnPoint - 1; + } } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 1a8caaec30..34362bf670 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -4134,28 +4134,93 @@ namespace OpenSim.Region.Framework.Scenes if (spawnPoints.Length == 0) return; - float distance = 9999; - int closest = -1; + int index; + bool selected = false; - for (int i = 0 ; i < spawnPoints.Length ; i++) + switch (m_scene.SpawnPointRouting) { - Vector3 spawnPosition = spawnPoints[i].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); - Vector3 offset = spawnPosition - pos; - float d = Vector3.Mag(offset); - if (d >= distance) - continue; - ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y); - if (land == null) - continue; - if (land.IsEitherBannedOrRestricted(UUID)) - continue; - distance = d; - closest = i; - } - if (closest == -1) - return; + case "closest": - pos = spawnPoints[closest].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); + float distance = 9999; + int closest = -1; + + for (int i = 0; i < spawnPoints.Length; i++) + { + Vector3 spawnPosition = spawnPoints[i].GetLocation( + telehub.AbsolutePosition, + telehub.GroupRotation + ); + Vector3 offset = spawnPosition - pos; + float d = Vector3.Mag(offset); + if (d >= distance) + continue; + ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y); + if (land == null) + continue; + if (land.IsEitherBannedOrRestricted(UUID)) + continue; + distance = d; + closest = i; + } + if (closest == -1) + return; + + pos = spawnPoints[closest].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); + return; + + case "random": + + do + { + index = Util.RandomClass.Next(spawnPoints.Length - 1); + + Vector3 spawnPosition = spawnPoints[index].GetLocation( + telehub.AbsolutePosition, + telehub.GroupRotation + ); + // SpawnPoint sp = spawnPoints[index]; + + ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y); + if (land == null || land.IsEitherBannedOrRestricted(UUID)) + selected = false; + else + selected = true; + + } while ( selected == false); + + pos = spawnPoints[index].GetLocation( + telehub.AbsolutePosition, + telehub.GroupRotation + ); + return; + + case "sequence": + + do + { + index = m_scene.SpawnPoint(); + + Vector3 spawnPosition = spawnPoints[index].GetLocation( + telehub.AbsolutePosition, + telehub.GroupRotation + ); + // SpawnPoint sp = spawnPoints[index]; + + ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y); + if (land == null || land.IsEitherBannedOrRestricted(UUID)) + selected = false; + else + selected = true; + + } while (selected == false); + + pos = spawnPoints[index].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); + ; + return; + + default: + return; + } } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 5bd781cb0b..8c4ee414fd 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -111,6 +111,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected IUrlModule m_UrlModule = null; protected Dictionary m_userInfoCache = new Dictionary(); + protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. protected Timer m_ShoutSayTimer; protected int m_SayShoutCount = 0; @@ -127,6 +128,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_item = item; m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false); + LoadLimits(); // read script limits from config. + + m_TransferModule = + m_ScriptEngine.World.RequestModuleInterface(); + m_UrlModule = m_ScriptEngine.World.RequestModuleInterface(); + + AsyncCommands = new AsyncCommandManager(ScriptEngine); + } + + /* load configuration items that affect script, object and run-time behavior. */ + private void LoadLimits() + { m_ScriptDelayFactor = m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); m_ScriptDistanceFactor = @@ -139,12 +152,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_ScriptEngine.Config.GetInt("NotecardLineReadCharsMax", 255); if (m_notecardLineReadCharsMax > 65535) m_notecardLineReadCharsMax = 65535; - - m_TransferModule = - m_ScriptEngine.World.RequestModuleInterface(); - m_UrlModule = m_ScriptEngine.World.RequestModuleInterface(); - - AsyncCommands = new AsyncCommandManager(ScriptEngine); + // load limits for particular subsystems. + IConfig SMTPConfig; + if ((SMTPConfig = m_ScriptEngine.ConfigSource.Configs["SMTP"]) != null) { + // there's an smtp config, so load in the snooze time. + EMAIL_PAUSE_TIME = SMTPConfig.GetInt("email_pause_time", EMAIL_PAUSE_TIME); + } } public override Object InitializeLifetimeService() @@ -3127,6 +3140,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public virtual void llSleep(double sec) { +// m_log.Info("llSleep snoozing " + sec + "s."); m_host.AddScriptLPS(1); Thread.Sleep((int)(sec * 1000)); } @@ -3413,7 +3427,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } emailModule.SendEmail(m_host.UUID, address, subject, message); - ScriptSleep(15000); + ScriptSleep(EMAIL_PAUSE_TIME * 1000); } public void llGetNextEmail(string address, string subject) diff --git a/bin/Ionic.Zip.dll b/bin/Ionic.Zip.dll old mode 100644 new mode 100755 diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 50366a675d..9b88816893 100755 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -241,6 +241,14 @@ ;; server to send mail through. ; emailmodule = DefaultEmailModule + ;# {SpawnPointRouting} {} {Set routing method for Telehub Spawnpoints} {closest random sequential} closest + ;; SpawnPointRouting adjusts the landing for incoming avatars. + ;; "closest" will place the avatar at the SpawnPoint located in the closest + ;; available spot to the destination (typically map click/landmark). + ;; "random" will place the avatar on a randomly selected spawnpoint; + ;; "sequential" will place the avatar on the next sequential SpawnPoint + ; SpawnPointRouting = closest + [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. @@ -273,6 +281,12 @@ ;# {host_domain_header_from} {[Startup]emailmodule:DefaultEmailModule enabled:true} {From address to use in the sent email header?} {} 127.0.0.1 ; host_domain_header_from = "127.0.0.1" + ;# {email_pause_time} {[Startup]emailmodule:DefaultEmailModule enabled:true} {Period in seconds to delay after an email is sent.} {} 20 + ; email_pause_time = 20 + + ;# {email_max_size} {[Startup]emailmodule:DefaultEmailModule enabled:true} {Maximum total size of email in bytes.} {} 4096 + ; email_max_size = 4096 + ;# {SMTP_SERVER_HOSTNAME} {[Startup]emailmodule:DefaultEmailModule enabled:true} {SMTP server name?} {} 127.0.0.1 ; SMTP_SERVER_HOSTNAME = "127.0.0.1" @@ -285,7 +299,6 @@ ;# {SMTP_SERVER_PASSWORD} {[Startup]emailmodule:DefaultEmailModule enabled:true} {SMTP server password} {} ; SMTP_SERVER_PASSWORD = "" - [Network] ;; Configure the remote console user here. This will not actually be used ;; unless you use -console=rest at startup. @@ -677,7 +690,7 @@ ;; Sets the multiplier for the scripting delays ; ScriptDelayFactor = 1.0 - ;; The factor the 10 m distances llimits are multiplied by + ;; The factor the 10 m distances limits are multiplied by ; ScriptDistanceLimitFactor = 1.0 ;; Maximum length of notecard line read @@ -780,7 +793,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