From 44d84bc2779165e75224975e83ca4539a00e9d24 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 10 Feb 2012 19:58:34 +0000 Subject: Fix bug where somebody taking a copy of an object they didn't own that was rezzed before the region was restarted would wrongly place the copy in the object owner's inventory. Addresses http://opensimulator.org/mantis/view.php?id=5825 --- .../Framework/InventoryAccess/InventoryAccessModule.cs | 12 ++++++++++-- .../Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs | 3 ++- 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 8b5b1a7..63ba3d3 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -546,12 +546,20 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess return null; userID = remoteClient.AgentId; + +// m_log.DebugFormat( +// "[INVENTORY ACCESS MODULE]: Target of {0} in CreateItemForObject() is {1} {2}", +// action, remoteClient.Name, userID); } else { // All returns / deletes go to the object owner // userID = so.RootPart.OwnerID; + +// m_log.DebugFormat( +// "[INVENTORY ACCESS MODULE]: Target of {0} in CreateItemForObject() is object owner {1}", +// action, userID); } if (userID == UUID.Zero) // Can't proceed @@ -637,11 +645,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } // Override and put into where it came from, if it came - // from anywhere in inventory + // from anywhere in inventory and the owner is taking it back. // if (action == DeRezAction.Take || action == DeRezAction.TakeCopy) { - if (so.RootPart.FromFolderID != UUID.Zero) + if (so.RootPart.FromFolderID != UUID.Zero && userID == remoteClient.AgentId) { InventoryFolderBase f = new InventoryFolderBase(so.RootPart.FromFolderID, userID); folder = m_Scene.InventoryService.GetFolder(f); diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs index 5dfd3e0..f678d07 100644 --- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs +++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs @@ -148,7 +148,8 @@ namespace OpenSim.Region.Framework.Scenes x = m_inventoryDeletes.Dequeue(); m_log.DebugFormat( - "[ASYNC DELETER]: Sending object to user's inventory, action {1}, count {2}, {0} item(s) remaining.", left, x.action, x.objectGroups.Count); + "[ASYNC DELETER]: Sending object to user's inventory, action {1}, count {2}, {0} item(s) remaining.", + left, x.action, x.objectGroups.Count); try { -- cgit v1.1 From a7dc7e636e3de9028668a6c570c6a713d4cd729b Mon Sep 17 00:00:00 2001 From: PixelTomsen Date: Fri, 10 Feb 2012 21:18:43 +0100 Subject: Fix: Covenant view fails after updates or cache-clean see mantis http://opensimulator.org/mantis/view.php?id=2879 Signed-off-by: BlueWall --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index ff96f4d..d98ff68 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -7625,6 +7625,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } } + else + if (transfer.TransferInfo.SourceType == (int)SourceType.SimEstate) + { + //TransferRequestPacket does not include covenant uuid? + //get scene covenant uuid + taskID = m_scene.RegionInfo.RegionSettings.Covenant; + } MakeAssetRequest(transfer, taskID); @@ -11985,6 +11992,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP { requestID = new UUID(transferRequest.TransferInfo.Params, 80); } + else if (transferRequest.TransferInfo.SourceType == (int)SourceType.SimEstate) + { + requestID = taskID; + } + // m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); -- cgit v1.1 From b3d152f3ba5cb07c005b0163c752f2c0f97c0034 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 10 Feb 2012 21:26:05 +0000 Subject: Fix an npc delete race condition with LSL sensors where an initial presence check could succeed but then the npc removed before the subequent npc check. The resulting null would cause an exception. We now check for null before looking at SenseAsAgent. Hopefully fixes http://opensimulator.org/mantis/view.php?id=5872 --- .../Api/Implementation/Plugins/SensorRepeat.cs | 29 +++++++++++++++------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs index 3e0e452..850f50b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs @@ -445,17 +445,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins Vector3 toRegionPos; double dis; - Action senseEntity = new Action(delegate(ScenePresence presence) + Action senseEntity = new Action(presence => { - if ((ts.type & NPC) == 0 - && presence.PresenceType == PresenceType.Npc - && !npcModule.GetNPC(presence.UUID, presence.Scene).SenseAsAgent) - return; + if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc) + { + INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene); + if (npcData == null || !npcData.SenseAsAgent) + return; + } - if ((ts.type & AGENT) == 0 - && (presence.PresenceType == PresenceType.User - || npcModule.GetNPC(presence.UUID, presence.Scene).SenseAsAgent)) - return; + if ((ts.type & AGENT) == 0) + { + if (presence.PresenceType == PresenceType.User) + { + return; + } + else + { + INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene); + if (npcData != null && npcData.SenseAsAgent) + return; + } + } if (presence.IsDeleted || presence.IsChildAgent || presence.GodLevel > 0.0) return; -- cgit v1.1 From e7fd7322095d518ccd7b446cf5c0683ef8009793 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 11 Feb 2012 00:10:59 +0000 Subject: Make ScenePresence.MovementFlag a private only settable value to reduce complexity of code analysis --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 5c56150..77f7b32 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -291,13 +291,10 @@ namespace OpenSim.Region.Framework.Scenes /// public PhysicsActor PhysicsActor { get; private set; } - private byte m_movementflag; - - public byte MovementFlag - { - set { m_movementflag = value; } - get { return m_movementflag; } - } + /// + /// Record user movement inputs. + /// + public byte MovementFlag { get; private set; } private bool m_updateflag; -- cgit v1.1 From f49897a4195df5fbd00e2c16461bcebb36ce8f72 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 11 Feb 2012 02:26:53 +0000 Subject: Clamp ODE character velocity. Make ODE falling character 54m/s by default. If velocity reaches 256 in any vector then bad things happen with ODE, so we now clamp this value. In addition, a falling avatar is clamped by default at 54 m/s, which is the same as a falling skydiver. This also appears to be the value used on the linden lab grid. This should resolve http://opensimulator.org/mantis/view.php?id=5882 --- OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | 43 +++++++++++++++++++++++- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 11 ++++++ 2 files changed, 53 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index 7c1c046..6d1f41d 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -156,6 +156,22 @@ namespace OpenSim.Region.Physics.OdePlugin internal UUID m_uuid { get; private set; } internal bool bad = false; + /// + /// ODE Avatar. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// Only used right now to return information to LSL. Not actually used to set mass in ODE! + /// + /// + /// public OdeCharacter( String avName, OdeScene parent_scene, Vector3 pos, Vector3 size, float pid_d, float pid_p, float capsule_radius, float tensor, float density, @@ -786,6 +802,10 @@ namespace OpenSim.Region.Physics.OdePlugin Vector3 vec = Vector3.Zero; d.Vector3 vel = d.BodyGetLinearVel(Body); +// m_log.DebugFormat( +// "[ODE CHARACTER]: Current velocity in Move() is <{0},{1},{2}>, target {3} for {4}", +// vel.X, vel.Y, vel.Z, _target_velocity, Name); + float movementdivisor = 1f; if (!m_alwaysRun) @@ -884,18 +904,20 @@ namespace OpenSim.Region.Physics.OdePlugin if (flying) { + // This also acts as anti-gravity so that we hover when flying rather than fall. vec.Z = (_target_velocity.Z - vel.Z) * (PID_D); } } if (flying) { + // Anti-gravity so that we hover when flying rather than fall. vec.Z += ((-1 * _parent_scene.gravityz) * m_mass); //Added for auto fly height. Kitto Flora //d.Vector3 pos = d.BodyGetPosition(Body); float target_altitude = _parent_scene.GetTerrainHeightAtXY(_position.X, _position.Y) + MinimumGroundFlightOffset; - + if (_position.Z < target_altitude) { vec.Z += (target_altitude - _position.Z) * PID_P * 5.0f; @@ -921,6 +943,25 @@ namespace OpenSim.Region.Physics.OdePlugin return; } + + d.Vector3 newVel = d.BodyGetLinearVel(Body); + if (newVel.X >= 256 || newVel.X <= 256 || newVel.Y >= 256 || newVel.Y <= 256 || newVel.Z >= 256 || newVel.Z <= 256) + { +// m_log.DebugFormat( +// "[ODE CHARACTER]: Limiting falling velocity from {0} to {1} for {2}", newVel.Z, -9.8, Name); + + newVel.X = Util.Clamp(newVel.X, -255f, 255f); + newVel.Y = Util.Clamp(newVel.Y, -255f, 255f); + + if (!flying) + newVel.Z + = Util.Clamp( + newVel.Z, -_parent_scene.AvatarTerminalVelocity, _parent_scene.AvatarTerminalVelocity); + else + newVel.Z = Util.Clamp(newVel.Z, -255f, 255f); + + d.BodySetLinearVel(Body, newVel.X, newVel.Y, newVel.Z); + } } /// diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 4530c09..7d1401c 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -144,6 +144,8 @@ namespace OpenSim.Region.Physics.OdePlugin public float gravityy = 0f; public float gravityz = -9.8f; + public float AvatarTerminalVelocity { get; set; } + private float contactsurfacelayer = 0.001f; private int worldHashspaceLow = -4; @@ -459,6 +461,15 @@ namespace OpenSim.Region.Physics.OdePlugin gravityy = physicsconfig.GetFloat("world_gravityy", 0f); gravityz = physicsconfig.GetFloat("world_gravityz", -9.8f); + float avatarTerminalVelocity = physicsconfig.GetFloat("avatar_terminal_velocity", 9f); + AvatarTerminalVelocity = Util.Clamp(avatarTerminalVelocity, 0, 255f); + if (AvatarTerminalVelocity != avatarTerminalVelocity) + { + m_log.WarnFormat( + "[ODE SCENE]: avatar_terminal_velocity of {0} is invalid. Clamping to {1}", + avatarTerminalVelocity, AvatarTerminalVelocity); + } + worldHashspaceLow = physicsconfig.GetInt("world_hashspace_size_low", -4); worldHashspaceHigh = physicsconfig.GetInt("world_hashspace_size_high", 128); -- cgit v1.1 From b92b9228ef5c7833dac019aba12babb5df954d35 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 11 Feb 2012 02:29:07 +0000 Subject: correct the default avatar_terminal_velocity value that I accidentally left in whilst testing --- OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 7d1401c..598530c 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -461,7 +461,7 @@ namespace OpenSim.Region.Physics.OdePlugin gravityy = physicsconfig.GetFloat("world_gravityy", 0f); gravityz = physicsconfig.GetFloat("world_gravityz", -9.8f); - float avatarTerminalVelocity = physicsconfig.GetFloat("avatar_terminal_velocity", 9f); + float avatarTerminalVelocity = physicsconfig.GetFloat("avatar_terminal_velocity", 54f); AvatarTerminalVelocity = Util.Clamp(avatarTerminalVelocity, 0, 255f); if (AvatarTerminalVelocity != avatarTerminalVelocity) { -- cgit v1.1 From 189c67db957cadfe1bb5bd8aad0c86dec1ff295b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 13 Feb 2012 20:43:26 +0000 Subject: On object deserialization, go back to logging errors at DEBUG level rather than ERROR. Restore extra log message if shape processing fails. Logging level was DEBUG before 312e145 (Fri Feb 3 2012). 312e145 also accidentally removed the 'general error' log message if any shape deserialization failed. This commit restores it, though this has no functional impact. --- .../Scenes/Serialization/SceneObjectSerializer.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index ab02f92..0a32214 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -1470,7 +1470,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization m_SOPXmlProcessors, reader, (o, nodeName, e) - => m_log.ErrorFormat( + => m_log.DebugFormat( "[SceneObjectSerializer]: Exception while parsing {0} in object {1} {2}: {3}{4}", ((SceneObjectPart)o).Name, ((SceneObjectPart)o).UUID, nodeName, e.Message, e.StackTrace)); @@ -1535,14 +1535,18 @@ namespace OpenSim.Region.Framework.Scenes.Serialization reader.ReadStartElement(name, String.Empty); // Shape - ExternalRepresentationUtils.ExecuteReadProcessors( + errors = ExternalRepresentationUtils.ExecuteReadProcessors( shape, m_ShapeXmlProcessors, reader, (o, nodeName, e) - => m_log.ErrorFormat( - "[SceneObjectSerializer]: Exception while parsing Shape property {0}: {1}{2}", - nodeName, e.Message, e.StackTrace)); + => + { + m_log.DebugFormat( + "[SceneObjectSerializer]: Exception while parsing Shape property {0}: {1}{2}", + nodeName, e.Message, e.StackTrace); + } + ); reader.ReadEndElement(); // Shape -- cgit v1.1 From 04a195266bd68f8c62129246a98aefb3201c90f1 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Mon, 13 Feb 2012 13:21:42 -0800 Subject: short circuit the expensive parts of the permission checking code if the current user is the owner of an object. none of the later checks can reverse the outcome. --- OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index cdecd2f..f3c6a30 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -707,7 +707,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions // Object owners should be able to edit their own content if (currentUser == objectOwner) { - permission = true; + // there is no way that later code can change this back to false + // so just return true immediately and short circuit the more + // expensive group checks + return true; + + //permission = true; } else if (group.IsAttachment) { -- cgit v1.1 From e3213065173e1408a138eb0bce0c9e936073b19b Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 14 Feb 2012 00:02:53 +0100 Subject: Prevent object loss and positioning outside the region with failed object sim crossings --- .../Framework/EntityTransfer/EntityTransferModule.cs | 10 +++++----- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 4 ++++ .../Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 12 +++++++++--- 3 files changed, 18 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index f1399af..4b1c0bc 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1731,17 +1731,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID); + // Need to turn off the physics flags, otherwise the object will continue to attempt to + // move out of the region creating an infinite loop of failed attempts to cross + grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false); + // We are going to move the object back to the old position so long as the old position // is in the region oldGroupPosition.X = Util.Clamp(oldGroupPosition.X,1.0f,(float)Constants.RegionSize-1); oldGroupPosition.Y = Util.Clamp(oldGroupPosition.Y,1.0f,(float)Constants.RegionSize-1); oldGroupPosition.Z = Util.Clamp(oldGroupPosition.Z,1.0f,4096.0f); - grp.RootPart.GroupPosition = oldGroupPosition; - - // Need to turn off the physics flags, otherwise the object will continue to attempt to - // move out of the region creating an infinite loop of failed attempts to cross - grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false); + grp.AbsolutePosition = oldGroupPosition; grp.ScheduleGroupForFullUpdate(); } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 683aafc..877fe96 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -466,6 +466,10 @@ namespace OpenSim.Region.Framework.Scenes && !IsAttachmentCheckFull() && (!Scene.LoadingPrims)) { m_scene.CrossPrimGroupIntoNewRegion(val, this, true); + + if (IsDeleted) + return; + val = AbsolutePosition; } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index b0b1b16..1529140 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2188,7 +2188,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (part.ParentGroup.RootPart == part) { SceneObjectGroup parent = part.ParentGroup; - parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z)); + Util.FireAndForget(delegate(object x) { + parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z)); + }); } else { @@ -7973,7 +7975,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (part.ParentGroup.RootPart == part) { SceneObjectGroup parent = part.ParentGroup; - parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); + Util.FireAndForget(delegate(object x) { + parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); + }); } else { @@ -7990,7 +7994,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (part.ParentGroup.RootPart == part) { SceneObjectGroup parent = part.ParentGroup; - parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); + Util.FireAndForget(delegate(object x) { + parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); + }); } else { -- cgit v1.1 From 04986bbb159754cb835ef6f698b2cc9c37f02b4b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 14 Feb 2012 01:50:51 +0000 Subject: Add some more data to the new user connection logging for debug purposes. --- OpenSim/Region/Framework/Scenes/Scene.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 3347822..4c8e2d2 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3272,9 +3272,9 @@ 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}, teleportflags {6}, position {7})", - RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname, - agent.AgentID, agent.circuitcode, teleportFlags, agent.startpos); + "[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, teleportFlags, agent.startpos); if (LoginsDisabled) { -- cgit v1.1 From 4589ce61bc68311d6ab7b5e7aa40ed1def40f52e Mon Sep 17 00:00:00 2001 From: PixelTomsen Date: Sat, 11 Feb 2012 19:00:01 +0100 Subject: Fix: get embedded objects from Notecard fails with activated FreeSwitchVoiceModul http://opensimulator.org/mantis/view.php?id=2607 --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 5323a95..05678c0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -63,9 +63,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // Capability string prefixes - private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; - private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; - private static readonly string m_chatSessionRequestPath = "0009/"; + private static readonly string m_parcelVoiceInfoRequestPath = "0207/"; + private static readonly string m_provisionVoiceAccountRequestPath = "0208/"; + private static readonly string m_chatSessionRequestPath = "0209/"; // Control info private static bool m_Enabled = false; -- cgit v1.1 From a9e8bd59a377e7c7ce81e3693875467926dd7d4b Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Mon, 13 Feb 2012 19:38:22 -0800 Subject: Fix a race condition in the simian groups connector. When requests were too slow they would circumvent the cache (piling up on the network service and making the problem even worse). This condition happens frequently during permission checks. --- .../SimianGroupsServicesConnectorModule.cs | 71 +++++++++++++++++++--- 1 file changed, 63 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs index 42008da..130513d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs @@ -30,6 +30,7 @@ using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.Reflection; +using System.Threading; using Nwc.XmlRpc; @@ -167,6 +168,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private bool m_debugEnabled = false; + private Dictionary m_pendingRequests = new Dictionary(); + private ExpiringCache m_memoryCache; private int m_cacheTimeout = 30; @@ -1348,6 +1351,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Immediately forward the request if the cache is disabled. if (m_cacheTimeout == 0) { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: cache is disabled"); return WebUtil.PostToService(m_groupsServerURI, requestArgs); } @@ -1355,6 +1359,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (requestArgs["RequestMethod"] == "RemoveGeneric" || requestArgs["RequestMethod"] == "AddGeneric") { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: clearing generics cache"); + // Any and all updates cause the cache to clear m_memoryCache.Clear(); @@ -1366,18 +1372,67 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Create the cache key for the request and see if we have it cached string CacheKey = WebUtil.BuildQueryString(requestArgs); - OSDMap response = null; - if (!m_memoryCache.TryGetValue(CacheKey, out response)) + + // This code uses a leader/follower pattern. On a cache miss, the request is added + // to a queue; the first thread to add it to the queue completes the request while + // follow on threads busy wait for the results, this situation seems to happen + // often when checking permissions + while (true) { - // if it wasn't in the cache, pass the request to the Simian Grid Services - response = WebUtil.PostToService(m_groupsServerURI, requestArgs); + OSDMap response = null; + bool firstRequest = false; - // and cache the response - m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout)); + lock (m_memoryCache) + { + if (m_memoryCache.TryGetValue(CacheKey, out response)) + return response; + + if (! m_pendingRequests.ContainsKey(CacheKey)) + { + m_pendingRequests.Add(CacheKey,true); + firstRequest = true; + } + } + + if (firstRequest) + { + // if it wasn't in the cache, pass the request to the Simian Grid Services + try + { + response = WebUtil.PostToService(m_groupsServerURI, requestArgs); + } + catch (Exception e) + { + m_log.InfoFormat("[SIMIAN GROUPS CONNECTOR] request failed {0}",CacheKey); + } + + // and cache the response + lock (m_memoryCache) + { + m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout)); + m_pendingRequests.Remove(CacheKey); + } + + return response; + } + + Thread.Sleep(50); // waiting for a web request to complete, 50msecs is reasonable } - // return cached response - return response; + // if (!m_memoryCache.TryGetValue(CacheKey, out response)) + // { + // m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: query not in the cache"); + // Util.PrintCallStack(); + + // // if it wasn't in the cache, pass the request to the Simian Grid Services + // response = WebUtil.PostToService(m_groupsServerURI, requestArgs); + + // // and cache the response + // m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout)); + // } + + // // return cached response + // return response; } #endregion -- cgit v1.1 From 2d3381b795611a8857077d1effb41323c2cb8658 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 14 Feb 2012 23:16:20 +0100 Subject: Implement region crossing of sitting avatars. Edit mode and llSetPos work but unscripted default sit anim is lost. Still some Gfx glitching. Physical crossing doesn't work yet. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 3 +- .../EntityTransfer/EntityTransferModule.cs | 140 ++++++--------------- .../Framework/Interfaces/IEntityTransferModule.cs | 7 ++ .../Region/Framework/Scenes/SceneObjectGroup.cs | 89 ++++++++++++- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 139 ++++++++++++-------- 5 files changed, 221 insertions(+), 157 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 8ed250d..161feda 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -1549,7 +1549,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void SendKillObject(ulong regionHandle, List localIDs) { -// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); +// foreach (uint id in localIDs) +// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle); KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); // TODO: don't create new blocks if recycling an old packet diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 4b1c0bc..9a6dfe1 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -681,11 +681,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #region Agent Crossings - public bool Cross(ScenePresence agent, bool isFlying) + public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos) { - Scene scene = agent.Scene; - Vector3 pos = agent.AbsolutePosition; - Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z); + version = String.Empty; + newpos = new Vector3(pos.X, pos.Y, pos.Z); uint neighbourx = scene.RegionInfo.RegionLocX; uint neighboury = scene.RegionInfo.RegionLocY; const float boundaryDistance = 1.7f; @@ -706,53 +705,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) { - Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); - if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) - { - neighboury--; - newpos.Y = Constants.RegionSize - enterDistance; - } - else - { - agent.IsInTransit = true; - - neighboury = b.TriggerRegionY; - neighbourx = b.TriggerRegionX; - - Vector3 newposition = pos; - newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; - newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; - agent.ControllingClient.SendAgentAlertMessage( - String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); - InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); - return true; - } - } - - Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W); - if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) - { - neighbourx--; - newpos.X = Constants.RegionSize - enterDistance; + neighboury--; + newpos.Y = Constants.RegionSize - enterDistance; } - else - { - agent.IsInTransit = true; - - neighboury = ba.TriggerRegionY; - neighbourx = ba.TriggerRegionX; - - Vector3 newposition = pos; - newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; - newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; - agent.ControllingClient.SendAgentAlertMessage( - String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); - InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); - - - return true; - } + neighbourx--; + newpos.X = Constants.RegionSize - enterDistance; } else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) @@ -763,26 +721,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (scene.TestBorderCross(pos + southCross, Cardinals.S)) { - Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S); - if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) - { - neighboury--; - newpos.Y = Constants.RegionSize - enterDistance; - } - else - { - agent.IsInTransit = true; - - neighboury = ba.TriggerRegionY; - neighbourx = ba.TriggerRegionX; - Vector3 newposition = pos; - newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; - newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; - agent.ControllingClient.SendAgentAlertMessage( - String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); - InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); - return true; - } + neighboury--; + newpos.Y = Constants.RegionSize - enterDistance; } else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) { @@ -790,35 +730,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer neighboury += (uint)(int)(c.BorderLine.Z / (int)Constants.RegionSize); newpos.Y = enterDistance; } - - } else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) { Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); - if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) - { - neighboury--; - newpos.Y = Constants.RegionSize - enterDistance; - } - else - { - agent.IsInTransit = true; - - neighboury = b.TriggerRegionY; - neighbourx = b.TriggerRegionX; - Vector3 newposition = pos; - newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; - newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; - agent.ControllingClient.SendAgentAlertMessage( - String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); - InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); - return true; - } + neighboury--; + newpos.Y = Constants.RegionSize - enterDistance; } else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) { - Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N); neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); newpos.Y = enterDistance; @@ -849,19 +769,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } */ - ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); + xDest = neighbourx; + yDest = neighboury; int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); + ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y); + ExpiringCache r; DateTime banUntil; - if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) + if (m_bannedRegions.TryGetValue(agentID, out r)) { if (r.TryGetValue(neighbourHandle, out banUntil)) { if (DateTime.Now < banUntil) - return false; + return null; r.Remove(neighbourHandle); } } @@ -873,28 +796,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); string reason; - string version; - if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason)) + if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason)) { - agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); if (r == null) { r = new ExpiringCache(); r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); - m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); + m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45)); } else { r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); } + return null; + } + + return neighbourRegion; + } + + public bool Cross(ScenePresence agent, bool isFlying) + { + uint x; + uint y; + Vector3 newpos; + string version; + + GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos); + if (neighbourRegion == null) + { + agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); return false; } agent.IsInTransit = true; CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; - d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); + d.BeginInvoke(agent, newpos, x, y, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); return true; } @@ -951,13 +889,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer icon.EndInvoke(iar); } - public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); - /// /// This Closes child agents on neighbouring regions /// Calls an asynchronous method to do so.. so it doesn't lag the sim. /// - protected ScenePresence CrossAgentToNewRegionAsync( + public ScenePresence CrossAgentToNewRegionAsync( ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version) { diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs index c38ecd9..76f1641 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs @@ -35,6 +35,8 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.Framework.Interfaces { + public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); + public interface IEntityTransferModule { void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position, @@ -53,7 +55,12 @@ namespace OpenSim.Region.Framework.Interfaces void EnableChildAgent(ScenePresence agent, GridRegion region); + GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos); + void Cross(SceneObjectGroup sog, Vector3 position, bool silent); + + ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); + } public interface IUserAgentVerificationModule diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 877fe96..a4ca0fb 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -465,10 +465,76 @@ namespace OpenSim.Region.Framework.Scenes || Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S)) && !IsAttachmentCheckFull() && (!Scene.LoadingPrims)) { - m_scene.CrossPrimGroupIntoNewRegion(val, this, true); + IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface(); + uint x = 0; + uint y = 0; + string version = String.Empty; + Vector3 newpos = Vector3.Zero; + OpenSim.Services.Interfaces.GridRegion destination = null; + + bool canCross = true; + foreach (ScenePresence av in m_linkedAvatars) + { + // We need to cross these agents. First, let's find + // out if any of them can't cross for some reason. + // We have to deny the crossing entirely if any + // of them are banned. Alternatively, we could + // unsit banned agents.... + + + // We set the avatar position as being the object + // position to get the region to send to + if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out x, out y, out version, out newpos)) == null) + { + canCross = false; + break; + } + + m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName); + } + + if (canCross) + { + // We unparent the SP quietly so that it won't + // be made to stand up + foreach (ScenePresence av in m_linkedAvatars) + { + SceneObjectPart parentPart = m_scene.GetSceneObjectPart(av.ParentID); + if (parentPart != null) + av.ParentUUID = parentPart.UUID; + + av.ParentID = 0; + } + + m_scene.CrossPrimGroupIntoNewRegion(val, this, true); + + // Normalize + if (val.X >= Constants.RegionSize) + val.X -= Constants.RegionSize; + if (val.Y >= Constants.RegionSize) + val.Y -= Constants.RegionSize; + if (val.X < 0) + val.X += Constants.RegionSize; + if (val.Y < 0) + val.Y += Constants.RegionSize; + + // If it's deleted, crossing was successful + if (IsDeleted) + { + foreach (ScenePresence av in m_linkedAvatars) + { + m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val); + + av.IsInTransit = true; + + CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync; + d.BeginInvoke(av, val, x, y, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d); + } + + return; + } + } - if (IsDeleted) - return; val = AbsolutePosition; } } @@ -528,6 +594,23 @@ namespace OpenSim.Region.Framework.Scenes } } + private void CrossAgentToNewRegionCompleted(IAsyncResult iar) + { + CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState; + ScenePresence agent = icon.EndInvoke(iar); + + //// If the cross was successful, this agent is a child agent + //if (agent.IsChildAgent) + // agent.Reset(); + //else // Not successful + // agent.RestoreInCurrentScene(); + + // In any case + agent.IsInTransit = false; + + m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname); + } + public override uint LocalId { get { return m_rootPart.LocalId; } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index c7c90da..e44060c 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -233,6 +233,8 @@ namespace OpenSim.Region.Framework.Scenes private bool m_collisionEventFlag = false; private object m_collisionEventLock = new Object(); + private Vector3 m_prevSitOffset; + protected AvatarAppearance m_appearance; public AvatarAppearance Appearance @@ -647,6 +649,13 @@ namespace OpenSim.Region.Framework.Scenes } private uint m_parentID; + public UUID ParentUUID + { + get { return m_parentUUID; } + set { m_parentUUID = value; } + } + private UUID m_parentUUID = UUID.Zero; + public float Health { get { return m_health; } @@ -868,7 +877,26 @@ namespace OpenSim.Region.Framework.Scenes "[SCENE]: Upgrading child to root agent for {0} in {1}", Name, m_scene.RegionInfo.RegionName); - //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); + if (ParentUUID != UUID.Zero) + { + m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID); + SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID); + if (part == null) + { + m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID); + } + else + { + part.ParentGroup.AddAvatar(UUID); + if (part.SitTargetPosition != Vector3.Zero) + part.SitTargetAvatar = UUID; + ParentPosition = part.GetWorldPosition(); + ParentID = part.LocalId; + m_pos = m_prevSitOffset; + pos = ParentPosition; + } + ParentUUID = UUID.Zero; + } bool wasChild = IsChildAgent; IsChildAgent = false; @@ -881,62 +909,64 @@ namespace OpenSim.Region.Framework.Scenes m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); - // Moved this from SendInitialData to ensure that Appearance is initialized - // before the inventory is processed in MakeRootAgent. This fixes a race condition - // related to the handling of attachments - //m_scene.GetAvatarAppearance(ControllingClient, out Appearance); - if (m_scene.TestBorderCross(pos, Cardinals.E)) + if (ParentID == 0) { - Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); - pos.X = crossedBorder.BorderLine.Z - 1; - } + // Moved this from SendInitialData to ensure that Appearance is initialized + // before the inventory is processed in MakeRootAgent. This fixes a race condition + // related to the handling of attachments + //m_scene.GetAvatarAppearance(ControllingClient, out Appearance); + if (m_scene.TestBorderCross(pos, Cardinals.E)) + { + Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); + pos.X = crossedBorder.BorderLine.Z - 1; + } - if (m_scene.TestBorderCross(pos, Cardinals.N)) - { - Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); - pos.Y = crossedBorder.BorderLine.Z - 1; - } + if (m_scene.TestBorderCross(pos, Cardinals.N)) + { + Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); + pos.Y = crossedBorder.BorderLine.Z - 1; + } - CheckAndAdjustLandingPoint(ref pos); + CheckAndAdjustLandingPoint(ref pos); - if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) - { - m_log.WarnFormat( - "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", - pos, Name, UUID); + if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) + { + m_log.WarnFormat( + "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", + pos, Name, UUID); - if (pos.X < 0f) pos.X = 0f; - if (pos.Y < 0f) pos.Y = 0f; - if (pos.Z < 0f) pos.Z = 0f; - } + if (pos.X < 0f) pos.X = 0f; + if (pos.Y < 0f) pos.Y = 0f; + if (pos.Z < 0f) pos.Z = 0f; + } - float localAVHeight = 1.56f; - if (Appearance.AvatarHeight > 0) - localAVHeight = Appearance.AvatarHeight; + float localAVHeight = 1.56f; + if (Appearance.AvatarHeight > 0) + localAVHeight = Appearance.AvatarHeight; - float posZLimit = 0; + float posZLimit = 0; - if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) - posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; - - float newPosZ = posZLimit + localAVHeight / 2; - if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) - { - pos.Z = newPosZ; - } - AbsolutePosition = pos; + if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) + posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; + + float newPosZ = posZLimit + localAVHeight / 2; + if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) + { + pos.Z = newPosZ; + } + AbsolutePosition = pos; - AddToPhysicalScene(isFlying); + AddToPhysicalScene(isFlying); - if (ForceFly) - { - Flying = true; - } - else if (FlyDisabled) - { - Flying = false; + if (ForceFly) + { + Flying = true; + } + else if (FlyDisabled) + { + Flying = false; + } } - // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying // avatar to return to the standing position in mid-air. On login it looks like this is being sent // elsewhere anyway @@ -954,11 +984,13 @@ namespace OpenSim.Region.Framework.Scenes { m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments..."); // Resume scripts - foreach (SceneObjectGroup sog in m_attachments) - { - sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); - sog.ResumeScripts(); - } + Util.FireAndForget(delegate(object x) { + foreach (SceneObjectGroup sog in m_attachments) + { + sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); + sog.ResumeScripts(); + } + }); } } @@ -3112,6 +3144,9 @@ namespace OpenSim.Region.Framework.Scenes cAgent.AlwaysRun = SetAlwaysRun; cAgent.Appearance = new AvatarAppearance(Appearance); + + cAgent.ParentPart = ParentUUID; + cAgent.SitOffset = m_pos; lock (scriptedcontrols) { @@ -3171,6 +3206,8 @@ namespace OpenSim.Region.Framework.Scenes CameraAtAxis = cAgent.AtAxis; CameraLeftAxis = cAgent.LeftAxis; m_CameraUpAxis = cAgent.UpAxis; + ParentUUID = cAgent.ParentPart; + m_prevSitOffset = cAgent.SitOffset; // When we get to the point of re-computing neighbors everytime this // changes, then start using the agent's drawdistance rather than the -- cgit v1.1 From 2ebb421331c4e6c4f57e0cc1bab79cea70937172 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Tue, 14 Feb 2012 17:20:34 -0800 Subject: Refactor appearance saving for NPC to use AvatarFactoryModule interface. --- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 40 +++++++++++++++++----- .../Framework/Interfaces/IAvatarFactoryModule.cs | 1 + .../Region/OptionalModules/World/NPC/NPCModule.cs | 12 +++---- 3 files changed, 38 insertions(+), 15 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 8d503bd..c7f4c20 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -111,6 +111,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory #region IAvatarFactoryModule + /// + /// + /// + /// + public void SetAppearance(IScenePresence sp, AvatarAppearance appearance) + { + SetAppearance(sp, appearance.Texture, appearance.VisualParams); + } + /// /// Set appearance data (texture asset IDs and slider settings) /// @@ -156,14 +165,23 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; // WriteBakedTexturesReport(sp, m_log.DebugFormat); - if (!ValidateBakedTextureCache(sp)) + + // If bake textures are missing and this is not an NPC, request a rebake from client + if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc)) RequestRebake(sp, true); // This appears to be set only in the final stage of the appearance // update transaction. In theory, we should be able to do an immediate // appearance send and save here. } - + + // NPC should send to clients immediately and skip saving appearance + if (((ScenePresence)sp).PresenceType == PresenceType.Npc) + { + SendAppearance((ScenePresence)sp); + return; + } + // save only if there were changes, send no matter what (doesn't hurt to send twice) if (changed) QueueAppearanceSave(sp.ControllingClient.AgentId); @@ -174,6 +192,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString()); } + private void SendAppearance(ScenePresence sp) + { + // Send the appearance to everyone in the scene + sp.SendAppearanceToAllOtherAgents(); + + // Send animations back to the avatar as well + sp.Animator.SendAnimPack(); + } + public bool SendAppearance(UUID agentId) { // m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId); @@ -185,12 +212,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory return false; } - // Send the appearance to everyone in the scene - sp.SendAppearanceToAllOtherAgents(); - - // Send animations back to the avatar as well - sp.Animator.SendAnimPack(); - + SendAppearance(sp); return true; } @@ -626,4 +648,4 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory outputAction("{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs b/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs index 39a760c..34aca33 100644 --- a/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs @@ -35,6 +35,7 @@ namespace OpenSim.Region.Framework.Interfaces public interface IAvatarFactoryModule { + void SetAppearance(IScenePresence sp, AvatarAppearance appearance); void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams); /// diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index dc6eefc..5359354 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -96,15 +96,15 @@ namespace OpenSim.Region.OptionalModules.World.NPC if (!m_avatars.ContainsKey(agentId)) return false; + // Delete existing sp attachments scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, false); - AvatarAppearance npcAppearance = new AvatarAppearance(appearance, true); - sp.Appearance = npcAppearance; + // Set new sp appearance. Also sends to clients. + scene.RequestModuleInterface().SetAppearance(sp, new AvatarAppearance(appearance, true)); + + // Rez needed sp attachments scene.AttachmentsModule.RezAttachments(sp); - - IAvatarFactoryModule module = scene.RequestModuleInterface(); - module.SendAppearance(sp.UUID); - + return true; } -- cgit v1.1