From 9d66792c2a06a667dc81e249e9ac81b6236b9126 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 12 May 2012 03:04:47 +0100 Subject: [PATCH 01/10] Fix mono compiler warning. Last jenkins failure looked like a glitch. --- OpenSim/Tests/Common/Helpers/SceneHelpers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs index dc24418145..78f94347bd 100644 --- a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs @@ -66,7 +66,7 @@ namespace OpenSim.Tests.Common private AgentCircuitManager m_acm = new AgentCircuitManager(); private ISimulationDataService m_simDataService = OpenSim.Server.Base.ServerUtils.LoadPlugin("OpenSim.Tests.Common.dll", null); - private IEstateDataService m_estateDataService; + private IEstateDataService m_estateDataService = null; private LocalAssetServicesConnector m_assetService; private LocalAuthenticationServicesConnector m_authenticationService; From 30a272ba318c2cacc27f6244dcf829c37a789a7c Mon Sep 17 00:00:00 2001 From: Chris Koeritz Date: Sun, 13 May 2012 16:58:47 -0400 Subject: [PATCH 02/10] Modifications for SMTP in OpenSimulator. Email size limit was fixed (was out of step with documentation at 1024, so boosted to 4096). Added configuration item for maximum email size. Redundant sleep inside email module was fixed (LSL Api was already sleeping). Added sleep time configuration item for snooze between email sending for LSL Api. Added two new configuration items (email_max_size and email_pause_time) into the example OpenSim.ini, plus fixed a spelling error (llimits) and odd tabbing. Signed-off-by: BlueWall --- .../Scripting/EMailModules/EmailModule.cs | 24 ++++------------ .../Shared/Api/Implementation/LSL_Api.cs | 28 ++++++++++++++----- bin/OpenSim.ini.example | 11 ++++++-- 3 files changed, 34 insertions(+), 29 deletions(-) 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/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 5b5cab860c..5bff2e9368 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -106,6 +106,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. public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) { @@ -113,6 +114,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host = host; m_item = item; + 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 = @@ -125,12 +138,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() @@ -2877,6 +2890,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)); } @@ -3130,7 +3144,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } emailModule.SendEmail(m_host.UUID, address, subject, message); - ScriptSleep(20000); + llSleep(EMAIL_PAUSE_TIME); } public void llGetNextEmail(string address, string subject) diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 50366a675d..8e7e45989b 100755 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -273,6 +273,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 +291,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 +682,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 +785,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 From 847127f83c4a6fbfb9be0ecef3904393e6968908 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Mon, 14 May 2012 00:15:56 -0400 Subject: [PATCH 03/10] Oops - missed the config changes --- bin/OpenSim.ini.example | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 8e7e45989b..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. From fad557485c78e15380ec35c0dbcf8556a96d29f7 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 14 May 2012 18:06:48 +0100 Subject: [PATCH 04/10] Add more region information to some teleport related logging --- .../EntityTransfer/EntityTransferModule.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index cd588e5d86..9766a25da4 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. /// @@ -531,8 +530,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; @@ -564,8 +563,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; @@ -661,8 +660,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) @@ -2014,4 +2015,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #endregion } -} +} \ No newline at end of file From c2aa3b90d9d367bcaeba93352ef6b0f513e663f7 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 14 May 2012 18:36:26 +0100 Subject: [PATCH 05/10] Set the agent in transit teleport flag at the first available opportunity (i.e. when IsInTransit() was being checked) to close down a race condition. On EntityTransferModule.DoTeleport() there was an IsInTransit() check to prevent multiple simultaneous teleport attempts. However, the SetInTransit() was only performed later on, which left a window in which multiple threads could pass the IsInTransit() check. This has been seen in the field and the results aren't pretty. This commit effectively combines the IsInTransit() and SetInTransit() checks so there is no such window. More failure cases are made to to call ResetInTransit() to adjust to this move. --- .../EntityTransfer/EntityTransferModule.cs | 54 ++++++++++++++----- 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 9766a25da4..d0aead5a7c 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -210,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"); } } @@ -384,7 +387,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.", @@ -432,8 +435,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); @@ -473,13 +479,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)) { @@ -516,8 +525,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); @@ -1956,25 +1963,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) @@ -1985,6 +2010,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return true; } } + return false; } From deeac6931242f1bbb05f0ec36c31a147b32d4b26 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 14 May 2012 18:48:40 +0100 Subject: [PATCH 06/10] minor: comment out individual attachment transfer log messages for now --- OpenSim/Region/Framework/Scenes/Scene.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 2a2830f47d..2bf3638f6c 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2576,10 +2576,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); From af6c85308adced4ac4a51bf14bd2beb7f22c6555 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 14 May 2012 18:57:02 +0100 Subject: [PATCH 07/10] minor: add explanative comment to 'missing baked texture' logging commonly seen on inter-simulator teleports where avatar baked textures are not available from the asset service. --- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 0ed10d2864..705233c2d7 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 { From d7fd9b159a7af813cfd6901a65e0ed43a6e1593d Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 14 May 2012 19:36:26 +0100 Subject: [PATCH 08/10] set executable bit for Ionic.Zip.dll for running OpenSimulator under cygwin --- bin/Ionic.Zip.dll | Bin 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 bin/Ionic.Zip.dll diff --git a/bin/Ionic.Zip.dll b/bin/Ionic.Zip.dll old mode 100644 new mode 100755 From 52a32878a9573681e3b56d0151c4a0903719eadf Mon Sep 17 00:00:00 2001 From: Oren Hurvitz Date: Thu, 3 May 2012 19:38:35 +0300 Subject: [PATCH 09/10] Save the Telehub and its Spawn Points in the OAR --- OpenSim/Framework/RegionSettings.cs | 29 ++++++++++++++- .../External/RegionSettingsSerializer.cs | 37 ++++++++++++++++++- .../Tests/RegionSettingsSerializerTests.cs | 8 ++++ .../World/Archiver/ArchiveReadRequest.cs | 25 ++++++++++++- .../ArchiveWriteRequestPreparation.cs | 2 +- .../World/Archiver/Tests/ArchiverTests.cs | 4 ++ 6 files changed, 100 insertions(+), 5 deletions(-) diff --git a/OpenSim/Framework/RegionSettings.cs b/OpenSim/Framework/RegionSettings.cs index 4ce3392057..47dbcecaeb 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 @@ -456,7 +483,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/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index a6dbaba7d7..bf0ff7516b 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) @@ -329,7 +341,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(); + } } /// @@ -505,6 +524,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); } /// From e7819ce909e7d0bd7494db9af8a8d5dc4212a6cb Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 15 May 2012 01:02:38 +0100 Subject: [PATCH 10/10] Port Avination's collision fixes to core. --- OpenSim/Data/Tests/RegionTests.cs | 1 - .../Framework/Scenes/SceneObjectGroup.cs | 11 - .../Framework/Scenes/SceneObjectPart.cs | 688 +++++------------- .../Serialization/SceneObjectSerializer.cs | 7 + .../Shared/Api/Implementation/LSL_Api.cs | 21 +- 5 files changed, 202 insertions(+), 526 deletions(-) diff --git a/OpenSim/Data/Tests/RegionTests.cs b/OpenSim/Data/Tests/RegionTests.cs index 1f03ec5c20..474609bb08 100644 --- a/OpenSim/Data/Tests/RegionTests.cs +++ b/OpenSim/Data/Tests/RegionTests.cs @@ -632,7 +632,6 @@ namespace OpenSim.Data.Tests .IgnoreProperty(x=>x.RegionUUID) .IgnoreProperty(x=>x.Scene) .IgnoreProperty(x=>x.Parts) - .IgnoreProperty(x=>x.PassCollision) .IgnoreProperty(x=>x.RootPart)); } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 05bea8dd88..20d7a01bd7 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -505,17 +505,6 @@ namespace OpenSim.Region.Framework.Scenes get { return true; } } - private bool m_passCollision; - public bool PassCollision - { - get { return m_passCollision; } - set - { - m_passCollision = value; - HasGroupChanged = true; - } - } - public bool IsSelected { get { return m_isSelected; } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index f911ef87a7..35986cf5b2 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -254,7 +254,8 @@ namespace OpenSim.Region.Framework.Scenes private readonly Stack m_undo = new Stack(5); private readonly Stack m_redo = new Stack(5); - private bool m_passTouches; + private bool m_passTouches = false; + private bool m_passCollisions = false; protected Vector3 m_acceleration; protected Vector3 m_angularVelocity; @@ -541,6 +542,7 @@ namespace OpenSim.Region.Framework.Scenes } } + [XmlIgnore] public bool PassTouches { get { return m_passTouches; } @@ -553,8 +555,18 @@ namespace OpenSim.Region.Framework.Scenes } } - - + public bool PassCollisions + { + get { return m_passCollisions; } + set + { + m_passCollisions = value; + + if (ParentGroup != null) + ParentGroup.HasGroupChanged = true; + } + } + public Dictionary CollisionFilter { get { return m_CollisionFilter; } @@ -2000,12 +2012,155 @@ namespace OpenSim.Region.Framework.Scenes { } + private bool CollisionFilteredOut(SceneObjectPart dest, UUID objectID, string objectName) + { + if(dest.CollisionFilter.Count == 0) + return false; + + if (dest.CollisionFilter.ContainsValue(objectID.ToString()) || + dest.CollisionFilter.ContainsValue(objectID.ToString() + objectName) || + dest.CollisionFilter.ContainsValue(UUID.Zero.ToString() + objectName)) + { + if (dest.CollisionFilter.ContainsKey(1)) + return false; + return true; + } + + if (dest.CollisionFilter.ContainsKey(1)) + return true; + + return false; + } + + private DetectedObject CreateDetObject(SceneObjectPart obj) + { + DetectedObject detobj = new DetectedObject(); + detobj.keyUUID = obj.UUID; + detobj.nameStr = obj.Name; + detobj.ownerUUID = obj.OwnerID; + detobj.posVector = obj.AbsolutePosition; + detobj.rotQuat = obj.GetWorldRotation(); + detobj.velVector = obj.Velocity; + detobj.colliderType = 0; + detobj.groupUUID = obj.GroupID; + + return detobj; + } + + private DetectedObject CreateDetObject(ScenePresence av) + { + DetectedObject detobj = new DetectedObject(); + detobj.keyUUID = av.UUID; + detobj.nameStr = av.ControllingClient.Name; + detobj.ownerUUID = av.UUID; + detobj.posVector = av.AbsolutePosition; + detobj.rotQuat = av.Rotation; + detobj.velVector = av.Velocity; + detobj.colliderType = 0; + detobj.groupUUID = av.ControllingClient.ActiveGroupId; + + return detobj; + } + + private DetectedObject CreateDetObjectForGround() + { + DetectedObject detobj = new DetectedObject(); + detobj.keyUUID = UUID.Zero; + detobj.nameStr = ""; + detobj.ownerUUID = UUID.Zero; + detobj.posVector = ParentGroup.RootPart.AbsolutePosition; + detobj.rotQuat = Quaternion.Identity; + detobj.velVector = Vector3.Zero; + detobj.colliderType = 0; + detobj.groupUUID = UUID.Zero; + + return detobj; + } + + private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List colliders) + { + ColliderArgs colliderArgs = new ColliderArgs(); + List colliding = new List(); + foreach (uint localId in colliders) + { + if (localId == 0) + continue; + + SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId); + if (obj != null) + { + if (!dest.CollisionFilteredOut(this, obj.UUID, obj.Name)) + colliding.Add(CreateDetObject(obj)); + } + else + { + ScenePresence av = ParentGroup.Scene.GetScenePresence(localId); + if (av != null && (!av.IsChildAgent)) + { + if (!dest.CollisionFilteredOut(this, av.UUID, av.Name)) + colliding.Add(CreateDetObject(av)); + } + } + } + + colliderArgs.Colliders = colliding; + + return colliderArgs; + } + + private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message); + + private void SendCollisionEvent(scriptEvents ev, List colliders, ScriptCollidingNotification notify) + { + bool sendToRoot = false; + ColliderArgs CollidingMessage; + + if (colliders.Count > 0) + { + if ((ScriptEvents & ev) != 0) + { + CollidingMessage = CreateColliderArgs(this, colliders); + + if (CollidingMessage.Colliders.Count > 0) + notify(LocalId, CollidingMessage); + + if (PassCollisions) + sendToRoot = true; + } + else + { + if ((ParentGroup.RootPart.ScriptEvents & ev) != 0) + sendToRoot = true; + } + if (sendToRoot && ParentGroup.RootPart != this) + { + CollidingMessage = CreateColliderArgs(ParentGroup.RootPart, colliders); + if (CollidingMessage.Colliders.Count > 0) + notify(ParentGroup.RootPart.LocalId, CollidingMessage); + } + } + } + + private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify) + { + if ((ParentGroup.RootPart.ScriptEvents & ev) != 0) + { + ColliderArgs LandCollidingMessage = new ColliderArgs(); + List colliding = new List(); + + colliding.Add(CreateDetObjectForGround()); + LandCollidingMessage.Colliders = colliding; + + notify(LocalId, LandCollidingMessage); + } + } + public void PhysicsCollision(EventArgs e) { -// m_log.DebugFormat("Invoking PhysicsCollision on {0} {1} {2}", Name, LocalId, UUID); + if (ParentGroup.Scene == null || ParentGroup.IsDeleted) + return; // single threaded here - CollisionEventUpdate a = (CollisionEventUpdate)e; Dictionary collissionswith = a.m_objCollisionList; List thisHitColliders = new List(); @@ -2018,528 +2173,41 @@ namespace OpenSim.Region.Framework.Scenes { thisHitColliders.Add(localid); if (!m_lastColliders.Contains(localid)) - { startedColliders.Add(localid); - } - //m_log.Debug("[OBJECT]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString()); } // calculate things that ended colliding foreach (uint localID in m_lastColliders) { if (!thisHitColliders.Contains(localID)) - { endedColliders.Add(localID); - } } //add the items that started colliding this time to the last colliders list. foreach (uint localID in startedColliders) - { m_lastColliders.Add(localID); - } + // remove things that ended colliding from the last colliders list foreach (uint localID in endedColliders) - { m_lastColliders.Remove(localID); - } - - if (ParentGroup.IsDeleted) - return; // play the sound. if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f) - { SendSound(CollisionSound.ToString(), CollisionSoundVolume, true, (byte)0, 0, false, false); - } - if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision_start) != 0) + SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart); + SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding); + SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd); + + if (startedColliders.Contains(0)) { - // do event notification - if (startedColliders.Count > 0) - { - ColliderArgs StartCollidingMessage = new ColliderArgs(); - List colliding = new List(); - foreach (uint localId in startedColliders) - { - if (localId == 0) - continue; - - if (ParentGroup.Scene == null) - return; - - SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId); - string data = ""; - if (obj != null) - { - if (ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) - || ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); - //If it is 1, it is to accept ONLY collisions from this object - if (found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = obj.UUID; - detobj.nameStr = obj.Name; - detobj.ownerUUID = obj.OwnerID; - detobj.posVector = obj.AbsolutePosition; - detobj.rotQuat = obj.GetWorldRotation(); - detobj.velVector = obj.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = obj.GroupID; - colliding.Add(detobj); - } - //If it is 0, it is to not accept collisions from this object - else - { - } - } - else - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); - //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work - if (!found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = obj.UUID; - detobj.nameStr = obj.Name; - detobj.ownerUUID = obj.OwnerID; - detobj.posVector = obj.AbsolutePosition; - detobj.rotQuat = obj.GetWorldRotation(); - detobj.velVector = obj.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = obj.GroupID; - colliding.Add(detobj); - } - } - } - else - { - ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence av) - { - if (av.LocalId == localId) - { - if (ParentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) - || ParentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); - //If it is 1, it is to accept ONLY collisions from this avatar - if (found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = av.UUID; - detobj.nameStr = av.ControllingClient.Name; - detobj.ownerUUID = av.UUID; - detobj.posVector = av.AbsolutePosition; - detobj.rotQuat = av.Rotation; - detobj.velVector = av.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = av.ControllingClient.ActiveGroupId; - colliding.Add(detobj); - } - //If it is 0, it is to not accept collisions from this avatar - else - { - } - } - else - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); - //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work - if (!found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = av.UUID; - detobj.nameStr = av.ControllingClient.Name; - detobj.ownerUUID = av.UUID; - detobj.posVector = av.AbsolutePosition; - detobj.rotQuat = av.Rotation; - detobj.velVector = av.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = av.ControllingClient.ActiveGroupId; - colliding.Add(detobj); - } - } - - } - }); - } - } - - if (colliding.Count > 0) - { - StartCollidingMessage.Colliders = colliding; - - if (ParentGroup.Scene == null) - return; - -// if (m_parentGroup.PassCollision == true) -// { -// //TODO: Add pass to root prim! -// } - - ParentGroup.Scene.EventManager.TriggerScriptCollidingStart(LocalId, StartCollidingMessage); - } - } - } - - if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision) != 0) - { - if (m_lastColliders.Count > 0) - { - ColliderArgs CollidingMessage = new ColliderArgs(); - List colliding = new List(); - foreach (uint localId in m_lastColliders) - { - // always running this check because if the user deletes the object it would return a null reference. - if (localId == 0) - continue; - - if (ParentGroup.Scene == null) - return; - - SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId); - string data = ""; - if (obj != null) - { - if (ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) - || ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data); - //If it is 1, it is to accept ONLY collisions from this object - if (found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = obj.UUID; - detobj.nameStr = obj.Name; - detobj.ownerUUID = obj.OwnerID; - detobj.posVector = obj.AbsolutePosition; - detobj.rotQuat = obj.GetWorldRotation(); - detobj.velVector = obj.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = obj.GroupID; - colliding.Add(detobj); - } - //If it is 0, it is to not accept collisions from this object - else - { - } - } - else - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data); - //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work - if (!found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = obj.UUID; - detobj.nameStr = obj.Name; - detobj.ownerUUID = obj.OwnerID; - detobj.posVector = obj.AbsolutePosition; - detobj.rotQuat = obj.GetWorldRotation(); - detobj.velVector = obj.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = obj.GroupID; - colliding.Add(detobj); - } - } - } - else - { - ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence av) - { - if (av.LocalId == localId) - { - if (ParentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) - || ParentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); - //If it is 1, it is to accept ONLY collisions from this avatar - if (found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = av.UUID; - detobj.nameStr = av.ControllingClient.Name; - detobj.ownerUUID = av.UUID; - detobj.posVector = av.AbsolutePosition; - detobj.rotQuat = av.Rotation; - detobj.velVector = av.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = av.ControllingClient.ActiveGroupId; - colliding.Add(detobj); - } - //If it is 0, it is to not accept collisions from this avatar - else - { - } - } - else - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); - //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work - if (!found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = av.UUID; - detobj.nameStr = av.ControllingClient.Name; - detobj.ownerUUID = av.UUID; - detobj.posVector = av.AbsolutePosition; - detobj.rotQuat = av.Rotation; - detobj.velVector = av.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = av.ControllingClient.ActiveGroupId; - colliding.Add(detobj); - } - } - - } - }); - } - } - if (colliding.Count > 0) - { - CollidingMessage.Colliders = colliding; - - if (ParentGroup.Scene == null) - return; - - ParentGroup.Scene.EventManager.TriggerScriptColliding(LocalId, CollidingMessage); - } - } - } - - if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision_end) != 0) - { - if (endedColliders.Count > 0) - { - ColliderArgs EndCollidingMessage = new ColliderArgs(); - List colliding = new List(); - foreach (uint localId in endedColliders) - { - if (localId == 0) - continue; - - if (ParentGroup.Scene == null) - return; - - SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId); - string data = ""; - if (obj != null) - { - if (ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data); - //If it is 1, it is to accept ONLY collisions from this object - if (found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = obj.UUID; - detobj.nameStr = obj.Name; - detobj.ownerUUID = obj.OwnerID; - detobj.posVector = obj.AbsolutePosition; - detobj.rotQuat = obj.GetWorldRotation(); - detobj.velVector = obj.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = obj.GroupID; - colliding.Add(detobj); - } - //If it is 0, it is to not accept collisions from this object - else - { - } - } - else - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data); - //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work - if (!found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = obj.UUID; - detobj.nameStr = obj.Name; - detobj.ownerUUID = obj.OwnerID; - detobj.posVector = obj.AbsolutePosition; - detobj.rotQuat = obj.GetWorldRotation(); - detobj.velVector = obj.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = obj.GroupID; - colliding.Add(detobj); - } - } - } - else - { - ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence av) - { - if (av.LocalId == localId) - { - if (ParentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) - || ParentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); - //If it is 1, it is to accept ONLY collisions from this avatar - if (found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = av.UUID; - detobj.nameStr = av.ControllingClient.Name; - detobj.ownerUUID = av.UUID; - detobj.posVector = av.AbsolutePosition; - detobj.rotQuat = av.Rotation; - detobj.velVector = av.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = av.ControllingClient.ActiveGroupId; - colliding.Add(detobj); - } - //If it is 0, it is to not accept collisions from this avatar - else - { - } - } - else - { - bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); - //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work - if (!found) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = av.UUID; - detobj.nameStr = av.ControllingClient.Name; - detobj.ownerUUID = av.UUID; - detobj.posVector = av.AbsolutePosition; - detobj.rotQuat = av.Rotation; - detobj.velVector = av.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = av.ControllingClient.ActiveGroupId; - colliding.Add(detobj); - } - } - - } - }); - } - } - - if (colliding.Count > 0) - { - EndCollidingMessage.Colliders = colliding; - - if (ParentGroup.Scene == null) - return; - - ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd(LocalId, EndCollidingMessage); - } - } - } - - if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_start) != 0) - { - if (startedColliders.Count > 0) - { - ColliderArgs LandStartCollidingMessage = new ColliderArgs(); - List colliding = new List(); - foreach (uint localId in startedColliders) - { - if (localId == 0) - { - //Hope that all is left is ground! - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = UUID.Zero; - detobj.nameStr = ""; - detobj.ownerUUID = UUID.Zero; - detobj.posVector = ParentGroup.RootPart.AbsolutePosition; - detobj.rotQuat = Quaternion.Identity; - detobj.velVector = Vector3.Zero; - detobj.colliderType = 0; - detobj.groupUUID = UUID.Zero; - colliding.Add(detobj); - } - } - - if (colliding.Count > 0) - { - LandStartCollidingMessage.Colliders = colliding; - - if (ParentGroup.Scene == null) - return; - - ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart(LocalId, LandStartCollidingMessage); - } - } - } - - if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.land_collision) != 0) - { - if (m_lastColliders.Count > 0) - { - ColliderArgs LandCollidingMessage = new ColliderArgs(); - List colliding = new List(); - foreach (uint localId in startedColliders) - { - if (localId == 0) - { - //Hope that all is left is ground! - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = UUID.Zero; - detobj.nameStr = ""; - detobj.ownerUUID = UUID.Zero; - detobj.posVector = ParentGroup.RootPart.AbsolutePosition; - detobj.rotQuat = Quaternion.Identity; - detobj.velVector = Vector3.Zero; - detobj.colliderType = 0; - detobj.groupUUID = UUID.Zero; - colliding.Add(detobj); - } - } - - if (colliding.Count > 0) - { - LandCollidingMessage.Colliders = colliding; - - if (ParentGroup.Scene == null) - return; - - ParentGroup.Scene.EventManager.TriggerScriptLandColliding(LocalId, LandCollidingMessage); - } - } - } - - if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_end) != 0) - { - if (endedColliders.Count > 0) - { - ColliderArgs LandEndCollidingMessage = new ColliderArgs(); - List colliding = new List(); - foreach (uint localId in startedColliders) - { - if (localId == 0) - { - //Hope that all is left is ground! - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = UUID.Zero; - detobj.nameStr = ""; - detobj.ownerUUID = UUID.Zero; - detobj.posVector = ParentGroup.RootPart.AbsolutePosition; - detobj.rotQuat = Quaternion.Identity; - detobj.velVector = Vector3.Zero; - detobj.colliderType = 0; - detobj.groupUUID = UUID.Zero; - colliding.Add(detobj); - } - } - - if (colliding.Count > 0) - { - LandEndCollidingMessage.Colliders = colliding; - - if (ParentGroup.Scene == null) - return; - - ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd(LocalId, LandEndCollidingMessage); - } - } + if (m_lastColliders.Contains(0)) + SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding); + else + SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart); } + if (endedColliders.Contains(0)) + SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd); } public void PhysicsOutOfBounds(Vector3 pos) @@ -4328,6 +3996,12 @@ namespace OpenSim.Region.Framework.Scenes ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || (CollisionSound != UUID.Zero) ) { @@ -4652,6 +4326,12 @@ namespace OpenSim.Region.Framework.Scenes ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || (CollisionSound != UUID.Zero) ) { diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index e6b88a35c5..a11dc4965d 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -301,6 +301,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization m_SOPXmlProcessors.Add("Name", ProcessName); m_SOPXmlProcessors.Add("Material", ProcessMaterial); m_SOPXmlProcessors.Add("PassTouches", ProcessPassTouches); + m_SOPXmlProcessors.Add("PassCollisions", ProcessPassCollisions); m_SOPXmlProcessors.Add("RegionHandle", ProcessRegionHandle); m_SOPXmlProcessors.Add("ScriptAccessPin", ProcessScriptAccessPin); m_SOPXmlProcessors.Add("GroupPosition", ProcessGroupPosition); @@ -485,6 +486,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization obj.PassTouches = Util.ReadBoolean(reader); } + private static void ProcessPassCollisions(SceneObjectPart obj, XmlTextReader reader) + { + obj.PassCollisions = Util.ReadBoolean(reader); + } + private static void ProcessRegionHandle(SceneObjectPart obj, XmlTextReader reader) { obj.RegionHandle = (ulong)reader.ReadElementContentAsLong("RegionHandle", String.Empty); @@ -1153,6 +1159,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization writer.WriteElementString("Name", sop.Name); writer.WriteElementString("Material", sop.Material.ToString()); writer.WriteElementString("PassTouches", sop.PassTouches.ToString().ToLower()); + writer.WriteElementString("PassCollisions", sop.PassCollisions.ToString().ToLower()); writer.WriteElementString("RegionHandle", sop.RegionHandle.ToString()); writer.WriteElementString("ScriptAccessPin", sop.ScriptAccessPin.ToString()); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 5bff2e9368..d213c353ef 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2929,14 +2929,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); m_host.CollisionFilter.Clear(); - if (id != null) - { - m_host.CollisionFilter.Add(accept,id); - } - else - { - m_host.CollisionFilter.Add(accept,name); - } + UUID objectID; + + if (!UUID.TryParse(id, out objectID)) + objectID = UUID.Zero; + + if (objectID == UUID.Zero && name == "") + return; + + m_host.CollisionFilter.Add(accept,objectID.ToString() + name); } public void llTakeControls(int controls, int accept, int pass_on) @@ -4466,11 +4467,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); if (pass == 0) { - m_host.ParentGroup.PassCollision = false; + m_host.PassCollisions = false; } else { - m_host.ParentGroup.PassCollision = true; + m_host.PassCollisions = true; } }