diff --git a/BUILDING.txt b/BUILDING.txt index e929cbf602..0fb68cb5ba 100644 --- a/BUILDING.txt +++ b/BUILDING.txt @@ -12,7 +12,7 @@ Steps: === Building on Linux === Prereqs: - * Mono >= 2.4.2 + * Mono >= 2.4.3 * Nant >= 0.85 * On some Linux distributions you may need to install additional packages. See http://opensimulator.org/wiki/Dependencies for more information. @@ -28,5 +28,3 @@ From the distribution type: Helpful resources: * http://opensimulator.org/wiki/Build_Instructions - - diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 1149bd7e35..3bf2ffd373 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -121,7 +121,7 @@ namespace OpenSim Util.FireAndForgetMethod = asyncCallMethod; stpMaxThreads = startupConfig.GetInt("MaxPoolThreads", 15); - m_consolePrompt = startupConfig.GetString("console_prompt", @"Region (\R) "); + m_consolePrompt = startupConfig.GetString("ConsolePrompt", @"Region (\R) "); } if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index cf09cc92ee..2e76acb5ca 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -1553,41 +1553,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP kill.Header.Reliable = true; kill.Header.Zerocoded = true; - lock (m_killRecord) + if (localIDs.Count == 1 && m_scene.GetScenePresence(localIDs[0]) != null) { - if (localIDs.Count == 1) + OutPacket(kill, ThrottleOutPacketType.State); + } + else + { + // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race + // condition where a kill can be processed before an out-of-date update for the same object. + // ProcessEntityUpdates() also takes the m_killRecord lock. + lock (m_killRecord) { - if (m_scene.GetScenePresence(localIDs[0]) != null) - { - OutPacket(kill, ThrottleOutPacketType.State); - return; - } - m_killRecord.Add(localIDs[0]); - } - else - { - lock (m_entityUpdates.SyncRoot) - { - foreach (uint localID in localIDs) - m_killRecord.Add(localID); - } + foreach (uint localID in localIDs) + m_killRecord.Add(localID); + + // The throttle queue used here must match that being used for updates. Otherwise, there is a + // chance that a kill packet put on a separate queue will be sent to the client before an existing + // update packet on another queue. Receiving updates after kills results in unowned and undeletable + // scene objects in a viewer until that viewer is relogged in. + OutPacket(kill, ThrottleOutPacketType.Task); } } - - // The throttle queue used here must match that being used for - // updates. Otherwise, there is a chance that a kill packet put - // on a separate queue will be sent to the client before an - // existing update packet on another queue. Receiving updates - // after kills results in unowned and undeletable - // scene objects in a viewer until that viewer is relogged in. - OutPacket(kill, ThrottleOutPacketType.Task); } /// /// Send information about the items contained in a folder to the client. - /// - /// XXX This method needs some refactoring loving /// + /// + /// XXX This method needs some refactoring loving + /// /// The owner of the folder /// The id of the folder /// The items contained in the folder identified by folderID diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index fe2dfefb2d..087697f480 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -164,7 +164,11 @@ namespace OpenSim.Region.Framework.Scenes private uint m_requestedSitTargetID; private UUID m_requestedSitTargetUUID; - public bool SitGround = false; + + /// + /// Are we sitting on the ground? + /// + public bool SitGround { get; private set; } private SendCourseLocationsMethod m_sendCourseLocationsMethod; @@ -189,20 +193,12 @@ namespace OpenSim.Region.Framework.Scenes private readonly Vector3[] Dir_Vectors = new Vector3[11]; - protected Timer m_reprioritization_timer; protected bool m_reprioritizing; protected bool m_reprioritization_called; private Quaternion m_headrotation = Quaternion.Identity; - //Reuse the Vector3 instead of creating a new one on the UpdateMovement method -// private Vector3 movementvector; - - private bool m_autopilotMoving; - private Vector3 m_autoPilotTarget; - private bool m_sitAtAutoTarget; - private string m_nextSitAnimation = String.Empty; //PauPaw:Proper PID Controler for autopilot************ @@ -1422,20 +1418,8 @@ namespace OpenSim.Region.Framework.Scenes } } - if (m_autopilotMoving) - CheckAtSitTarget(); - if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) - { - m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick. - Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); - - // TODO: This doesn't prevent the user from walking yet. - // Setting parent ID would fix this, if we knew what value - // to use. Or we could add a m_isSitting variable. - //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); - SitGround = true; - } + HandleAgentSitOnGround(); // In the future, these values might need to go global. // Here's where you get them. @@ -1641,111 +1625,109 @@ namespace OpenSim.Region.Framework.Scenes // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", // allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); - if (!m_autopilotMoving) - { - double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget); + double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget); + // m_log.DebugFormat( // "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", // Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); - // Check the error term of the current position in relation to the target position - if (distanceToTarget <= 1) + // Check the error term of the current position in relation to the target position + if (distanceToTarget <= 1) + { + // We are close enough to the target + AbsolutePosition = MoveToPositionTarget; + ResetMoveToTarget(); + updated = true; + } + else + { + try { - // We are close enough to the target - AbsolutePosition = MoveToPositionTarget; - ResetMoveToTarget(); - updated = true; - } - else - { - try - { - // move avatar in 3D at one meter/second towards target, in avatar coordinate frame. - // This movement vector gets added to the velocity through AddNewMovement(). - // Theoretically we might need a more complex PID approach here if other - // unknown forces are acting on the avatar and we need to adaptively respond - // to such forces, but the following simple approach seems to works fine. - Vector3 LocalVectorToTarget3D = - (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords - * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords - // Ignore z component of vector + // move avatar in 3D at one meter/second towards target, in avatar coordinate frame. + // This movement vector gets added to the velocity through AddNewMovement(). + // Theoretically we might need a more complex PID approach here if other + // unknown forces are acting on the avatar and we need to adaptively respond + // to such forces, but the following simple approach seems to works fine. + Vector3 LocalVectorToTarget3D = + (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords + * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords + // Ignore z component of vector // Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); - LocalVectorToTarget3D.Normalize(); + LocalVectorToTarget3D.Normalize(); - // update avatar movement flags. the avatar coordinate system is as follows: - // - // +X (forward) - // - // ^ - // | - // | - // | - // | - // (left) +Y <--------o--------> -Y - // avatar - // | - // | - // | - // | - // v - // -X - // + // update avatar movement flags. the avatar coordinate system is as follows: + // + // +X (forward) + // + // ^ + // | + // | + // | + // | + // (left) +Y <--------o--------> -Y + // avatar + // | + // | + // | + // | + // v + // -X + // - // based on the above avatar coordinate system, classify the movement into - // one of left/right/back/forward. - if (LocalVectorToTarget3D.X < 0) //MoveBack - { - MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; - updated = true; - } - else if (LocalVectorToTarget3D.X > 0) //Move Forward - { - MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; - updated = true; - } + // based on the above avatar coordinate system, classify the movement into + // one of left/right/back/forward. + if (LocalVectorToTarget3D.X < 0) //MoveBack + { + MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; + updated = true; + } + else if (LocalVectorToTarget3D.X > 0) //Move Forward + { + MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; + updated = true; + } - if (LocalVectorToTarget3D.Y > 0) //MoveLeft - { - MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; - updated = true; - } - else if (LocalVectorToTarget3D.Y < 0) //MoveRight - { - MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; - updated = true; - } + if (LocalVectorToTarget3D.Y > 0) //MoveLeft + { + MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; + updated = true; + } + else if (LocalVectorToTarget3D.Y < 0) //MoveRight + { + MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; + updated = true; + } - if (LocalVectorToTarget3D.Z > 0) //Up - { - // Don't set these flags for up or down - doing so will make the avatar crouch or - // keep trying to jump even if walking along level ground - //MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP; - //AgentControlFlags - //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP; - updated = true; - } - else if (LocalVectorToTarget3D.Z < 0) //Down - { - //MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN; - //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN; - updated = true; - } + if (LocalVectorToTarget3D.Z > 0) //Up + { + // Don't set these flags for up or down - doing so will make the avatar crouch or + // keep trying to jump even if walking along level ground + //MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP; + //AgentControlFlags + //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP; + updated = true; + } + else if (LocalVectorToTarget3D.Z < 0) //Down + { + //MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN; + //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN; + updated = true; + } // m_log.DebugFormat( // "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}", // LocalVectorToTarget3D, agent_control_v3, Name); - agent_control_v3 += LocalVectorToTarget3D; - } - catch (Exception e) - { - //Avoid system crash, can be slower but... - m_log.DebugFormat("Crash! {0}", e.ToString()); - } + agent_control_v3 += LocalVectorToTarget3D; + } + catch (Exception e) + { + //Avoid system crash, can be slower but... + m_log.DebugFormat("Crash! {0}", e.ToString()); } } @@ -1847,58 +1829,20 @@ namespace OpenSim.Region.Framework.Scenes AgentControlFlags = (uint)AgentManager.ControlFlags.NONE; } - private void CheckAtSitTarget() - { - //m_log.Debug("[AUTOPILOT]: " + Util.GetDistanceTo(AbsolutePosition, m_autoPilotTarget).ToString()); - if (Util.GetDistanceTo(AbsolutePosition, m_autoPilotTarget) <= 1.5) - { - if (m_sitAtAutoTarget) - { - SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetUUID); - if (part != null) - { - AbsolutePosition = part.AbsolutePosition; - Velocity = Vector3.Zero; - SendAvatarDataToAllAgents(); - - //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); - } - //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); - m_requestedSitTargetUUID = UUID.Zero; - } - /* - else - { - //ControllingClient.SendAlertMessage("Autopilot cancelled"); - //SendTerseUpdateToAllClients(); - //PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; - //proxy.PCode = (byte)PCode.ParticleSystem; - ////uint nextUUID = m_scene.NextLocalId; - - //proxyObjectGroup = new SceneObjectGroup(m_scene, m_scene.RegionInfo.RegionHandle, UUID, nextUUID, m_autoPilotTarget, Quaternion.Identity, proxy); - //if (proxyObjectGroup != null) - //{ - //proxyObjectGroup.SendGroupFullUpdate(); - //ControllingClient.SendSitResponse(UUID.Zero, m_autoPilotTarget, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); - //m_scene.DeleteSceneObject(proxyObjectGroup); - //} - } - */ - m_autoPilotTarget = Vector3.Zero; - m_autopilotMoving = false; - } - } /// /// Perform the logic necessary to stand the avatar up. This method also executes /// the stand animation. /// public void StandUp() { +// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name); + SitGround = false; + if (PhysicsActor == null) + AddToPhysicalScene(false); if (ParentID != 0) { - m_log.Debug("StandupCode Executed"); SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID); if (part != null) { @@ -1926,11 +1870,6 @@ namespace OpenSim.Region.Framework.Scenes ControllingClient.SendClearFollowCamProperties(part.ParentUUID); } - if (PhysicsActor == null) - { - AddToPhysicalScene(false); - } - m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight); ParentPosition = Vector3.Zero; @@ -1987,9 +1926,8 @@ namespace OpenSim.Region.Framework.Scenes return targetPart; } - private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) + private void SendSitResponse(UUID targetID, Vector3 offset, Quaternion pSitOrientation) { - bool autopilot = true; Vector3 pos = new Vector3(); Quaternion sitOrientation = pSitOrientation; Vector3 cameraEyeOffset = Vector3.Zero; @@ -1997,89 +1935,87 @@ namespace OpenSim.Region.Framework.Scenes bool forceMouselook = false; SceneObjectPart part = FindNextAvailableSitTarget(targetID); - if (part != null) - { - // TODO: determine position to sit at based on scene geometry; don't trust offset from client - // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it + if (part == null) + return; - // Is a sit target available? - Vector3 avSitOffSet = part.SitTargetPosition; - Quaternion avSitOrientation = part.SitTargetOrientation; - UUID avOnTargetAlready = part.SitTargetAvatar; + // TODO: determine position to sit at based on scene geometry; don't trust offset from client + // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it - bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); - bool SitTargetisSet = - (!(avSitOffSet == Vector3.Zero && - ( - avSitOrientation == Quaternion.Identity // Valid Zero Rotation quaternion - || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point - || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion - ) - )); + // Is a sit target available? + Vector3 avSitOffSet = part.SitTargetPosition; + Quaternion avSitOrientation = part.SitTargetOrientation; + UUID avOnTargetAlready = part.SitTargetAvatar; + + bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); + bool SitTargetisSet = + (!(avSitOffSet == Vector3.Zero && + ( + avSitOrientation == Quaternion.Identity // Valid Zero Rotation quaternion + || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point + || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion + ) + )); // m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied); - if (SitTargetisSet && SitTargetUnOccupied) + if (PhysicsActor != null) + m_sitAvatarHeight = m_physicsActor.Size.Z; + + bool canSit = false; + pos = part.AbsolutePosition + offset; + + if (SitTargetisSet) + { + if (SitTargetUnOccupied) { + m_log.DebugFormat( + "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied", + Name, part.Name, part.LocalId); + part.SitTargetAvatar = UUID; offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); sitOrientation = avSitOrientation; - autopilot = false; + canSit = true; } - pos = part.AbsolutePosition + offset; - //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) - //{ - // offset = pos; - //autopilot = false; - //} + } + else + { + if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) + { + m_log.DebugFormat( + "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m", + Name, part.Name, part.LocalId); + + AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); + canSit = true; + } + } + + if (canSit) + { if (PhysicsActor != null) { - // If we're not using the client autopilot, we're immediately warping the avatar to the location // We can remove the physicsActor until they stand up. - m_sitAvatarHeight = PhysicsActor.Size.Z; - - if (autopilot) - { - if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) - { - autopilot = false; - - RemoveFromPhysicalScene(); - AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); - } - } - else - { - RemoveFromPhysicalScene(); - } + RemoveFromPhysicalScene(); } cameraAtOffset = part.GetCameraAtOffset(); cameraEyeOffset = part.GetCameraEyeOffset(); forceMouselook = part.GetForceMouselook(); - } - ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); - m_requestedSitTargetUUID = targetID; + ControllingClient.SendSitResponse( + targetID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook); - // This calls HandleAgentSit twice, once from here, and the client calls - // HandleAgentSit itself after it gets to the location - // It doesn't get to the location until we've moved them there though - // which happens in HandleAgentSit :P - m_autopilotMoving = autopilot; - m_autoPilotTarget = pos; - m_sitAtAutoTarget = autopilot; - if (!autopilot) - HandleAgentSit(remoteClient, UUID); + m_requestedSitTargetUUID = targetID; - // Moved here to avoid a race with default sit anim - // The script event needs to be raised after the default sit anim is set. - if (part != null) + HandleAgentSit(ControllingClient, UUID); + + // Moved here to avoid a race with default sit anim + // The script event needs to be raised after the default sit anim is set. part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); - + } } - // public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset, string sitAnimation) public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset) { if (ParentID != 0) @@ -2105,11 +2041,11 @@ namespace OpenSim.Region.Framework.Scenes { m_nextSitAnimation = part.SitAnimation; } + m_requestedSitTargetID = part.LocalId; - //m_requestedSitOffset = offset; m_requestedSitTargetUUID = targetID; - m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset); +// m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset); if (m_scene.PhysicsScene.SupportsRayCast()) { @@ -2123,7 +2059,7 @@ namespace OpenSim.Region.Framework.Scenes m_log.Warn("Sit requested on unknown object: " + targetID.ToString()); } - SendSitResponse(remoteClient, targetID, offset, Quaternion.Identity); + SendSitResponse(targetID, offset, Quaternion.Identity); } /* @@ -2334,45 +2270,42 @@ namespace OpenSim.Region.Framework.Scenes { SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); - if (m_sitAtAutoTarget || !m_autopilotMoving) + if (part != null) { - if (part != null) + if (part.SitTargetAvatar == UUID) { - if (part.SitTargetAvatar == UUID) - { - Vector3 sitTargetPos = part.SitTargetPosition; - Quaternion sitTargetOrient = part.SitTargetOrientation; + Vector3 sitTargetPos = part.SitTargetPosition; + Quaternion sitTargetOrient = part.SitTargetOrientation; // m_log.DebugFormat( // "[SCENE PRESENCE]: Sitting {0} at sit target {1}, {2} on {3} {4}", // Name, sitTargetPos, sitTargetOrient, part.Name, part.LocalId); - //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0); - //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w); + //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0); + //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w); - //Quaternion result = (sitTargetOrient * vq) * nq; + //Quaternion result = (sitTargetOrient * vq) * nq; - m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT; - Rotation = sitTargetOrient; - ParentPosition = part.AbsolutePosition; - part.ParentGroup.AddAvatar(UUID); - } - else - { - m_pos -= part.AbsolutePosition; - ParentPosition = part.AbsolutePosition; - part.ParentGroup.AddAvatar(UUID); + m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT; + Rotation = sitTargetOrient; + ParentPosition = part.AbsolutePosition; + part.ParentGroup.AddAvatar(UUID); + } + else + { + m_pos -= part.AbsolutePosition; + ParentPosition = part.AbsolutePosition; + part.ParentGroup.AddAvatar(UUID); // m_log.DebugFormat( // "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", // Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId); - } - } - else - { - return; } } + else + { + return; + } ParentID = m_requestedSitTargetID; @@ -2383,6 +2316,19 @@ namespace OpenSim.Region.Framework.Scenes SendAvatarDataToAllAgents(); } + public void HandleAgentSitOnGround() + { + m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick. + Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); + + // TODO: This doesn't prevent the user from walking yet. + // Setting parent ID would fix this, if we knew what value + // to use. Or we could add a m_isSitting variable. + //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); + SitGround = true; + RemoveFromPhysicalScene(); + } + /// /// Event handler for the 'Always run' setting on the client /// Tells the physics plugin to increase speed of movement. diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs new file mode 100644 index 0000000000..b7b8db445e --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs @@ -0,0 +1,176 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using Nini.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Servers; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; +using System.Threading; + +namespace OpenSim.Region.Framework.Scenes.Tests +{ + [TestFixture] + public class ScenePresenceSitTests + { + private TestScene m_scene; + private ScenePresence m_sp; + + [SetUp] + public void Init() + { + m_scene = SceneHelpers.SetupScene(); + m_sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); + } + + [Test] + public void TestSitOutsideRangeNoTarget() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + // More than 10 meters away from 0, 0, 0 (default part position) + Vector3 startPos = new Vector3(10.1f, 0, 0); + m_sp.AbsolutePosition = startPos; + + SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene); + + m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); + + Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); + Assert.That(m_sp.ParentID, Is.EqualTo(0)); + } + + [Test] + public void TestSitWithinRangeNoTarget() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + // Less than 10 meters away from 0, 0, 0 (default part position) + Vector3 startPos = new Vector3(9.9f, 0, 0); + m_sp.AbsolutePosition = startPos; + + SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene); + + m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); + + Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); + Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId)); + } + + [Test] + public void TestSitAndStandWithNoSitTarget() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + // Make sure we're within range to sit + Vector3 startPos = new Vector3(1, 1, 1); + m_sp.AbsolutePosition = startPos; + + SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene); + + m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); + + Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); + Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId)); + Assert.That(m_sp.PhysicsActor, Is.Null); + + // FIXME: This is different for live avatars - z position is adjusted. This is half the height of the + // default avatar. + // Curiously, Vector3.ToString() will not display the last two places of the float. For example, + // printing out npc.AbsolutePosition will give <0, 0, 0.8454993> not <0, 0, 0.845499337> + Assert.That( + m_sp.AbsolutePosition, + Is.EqualTo(part.AbsolutePosition + new Vector3(0, 0, 0.845499337f))); + + m_sp.StandUp(); + + Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); + Assert.That(m_sp.ParentID, Is.EqualTo(0)); + Assert.That(m_sp.PhysicsActor, Is.Not.Null); + } + + [Test] + public void TestSitAndStandWithSitTarget() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + // If a prim has a sit target then we can sit from any distance away + Vector3 startPos = new Vector3(128, 128, 30); + m_sp.AbsolutePosition = startPos; + + SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene); + part.SitTargetPosition = new Vector3(0, 0, 1); + + m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); + + Assert.That(part.SitTargetAvatar, Is.EqualTo(m_sp.UUID)); + Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId)); + Assert.That( + m_sp.AbsolutePosition, + Is.EqualTo(part.AbsolutePosition + part.SitTargetPosition + ScenePresence.SIT_TARGET_ADJUSTMENT)); + Assert.That(m_sp.PhysicsActor, Is.Null); + + m_sp.StandUp(); + + Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); + Assert.That(m_sp.ParentID, Is.EqualTo(0)); + Assert.That(m_sp.PhysicsActor, Is.Not.Null); + } + + [Test] + public void TestSitAndStandOnGround() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + // If a prim has a sit target then we can sit from any distance away +// Vector3 startPos = new Vector3(128, 128, 30); +// sp.AbsolutePosition = startPos; + + m_sp.HandleAgentSitOnGround(); + + Assert.That(m_sp.SitGround, Is.True); + Assert.That(m_sp.PhysicsActor, Is.Null); + + m_sp.StandUp(); + + Assert.That(m_sp.SitGround, Is.False); + Assert.That(m_sp.PhysicsActor, Is.Not.Null); + } + } +} \ No newline at end of file diff --git a/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs b/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs index cf7496f434..d5a6521ca6 100644 --- a/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs +++ b/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs @@ -125,6 +125,13 @@ namespace OpenSim.Services.AuthenticationService m_log.DebugFormat("[PASS AUTH]: {0} {1} impersonating {2}, proceeding with login", a.FirstName, a.LastName, principalID); return GetToken(principalID, lifetime); } + else + { + m_log.DebugFormat( + "[AUTH SERVICE]: Salted hash {0} of given password did not match salted hash of {1} for PrincipalID {2}. Authentication failure.", + principalID); + return String.Empty; + } } m_log.DebugFormat("[PASS AUTH]: Impersonation of {0} failed", principalID);