From b81c829576dd916c0a7bf141919f5e13f025d818 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Wed, 28 Oct 2009 14:13:17 -0700 Subject: [PATCH] * Standalone logins will now go through the sequence of "requested region, default region, any region" before giving up * Hip offset should have been added not subtracted (it's a negative offset). This puts avatar feet closer to the ground * Improved duplicate checking for terse updates. This should reduce bandwidth and walking through walls --- .../Client/Linden/LLStandaloneLoginModule.cs | 4 +++ .../Communications/Services/LoginService.cs | 32 ++++++++---------- .../Hypergrid/HGStandaloneLoginModule.cs | 6 +++- .../Framework/Scenes/SceneObjectPart.cs | 15 ++++---- .../Region/Framework/Scenes/ScenePresence.cs | 21 +++++++----- bin/OpenMetaverseTypes.dll | Bin 102400 -> 102400 bytes 6 files changed, 43 insertions(+), 35 deletions(-) diff --git a/OpenSim/Client/Linden/LLStandaloneLoginModule.cs b/OpenSim/Client/Linden/LLStandaloneLoginModule.cs index bb9b62315e..8739ce5e52 100644 --- a/OpenSim/Client/Linden/LLStandaloneLoginModule.cs +++ b/OpenSim/Client/Linden/LLStandaloneLoginModule.cs @@ -231,6 +231,10 @@ namespace OpenSim.Client.Linden { return scene.RegionInfo; } + else if (m_scenes.Count > 0) + { + return m_scenes[0].RegionInfo; + } return null; } diff --git a/OpenSim/Framework/Communications/Services/LoginService.cs b/OpenSim/Framework/Communications/Services/LoginService.cs index 922cd4942f..b6522992b7 100644 --- a/OpenSim/Framework/Communications/Services/LoginService.cs +++ b/OpenSim/Framework/Communications/Services/LoginService.cs @@ -1031,30 +1031,26 @@ namespace OpenSim.Framework.Communications.Services return true; } - // StartLocation not available, send him to a nearby region instead - // regionInfo = m_gridService.RequestClosestRegion(""); - //m_log.InfoFormat("[LOGIN]: StartLocation not available sending to region {0}", regionInfo.regionName); + // Get the default region handle + ulong defaultHandle = Utils.UIntsToLong(m_defaultHomeX * Constants.RegionSize, m_defaultHomeY * Constants.RegionSize); - // Send him to default region instead - ulong defaultHandle = (((ulong)m_defaultHomeX * Constants.RegionSize) << 32) | - ((ulong)m_defaultHomeY * Constants.RegionSize); - - if ((regionInfo != null) && (defaultHandle == regionInfo.RegionHandle)) - { - m_log.ErrorFormat("[LOGIN]: Not trying the default region since this is the same as the selected region"); - return false; - } - - m_log.Error("[LOGIN]: Sending user to default region " + defaultHandle + " instead"); - regionInfo = GetRegionInfo(defaultHandle); + // If we haven't already tried the default region, reset regionInfo + if (regionInfo != null && defaultHandle != regionInfo.RegionHandle) + regionInfo = null; if (regionInfo == null) { - m_log.ErrorFormat("[LOGIN]: No default region available. Aborting."); - return false; + m_log.Error("[LOGIN]: Sending user to default region " + defaultHandle + " instead"); + regionInfo = GetRegionInfo(defaultHandle); } - theUser.CurrentAgent.Position = new Vector3(128, 128, 0); + if (regionInfo == null) + { + m_log.ErrorFormat("[LOGIN]: Sending user to any region"); + regionInfo = RequestClosestRegion(String.Empty); + } + + theUser.CurrentAgent.Position = new Vector3(128f, 128f, 0f); response.StartLocation = "safe"; return PrepareLoginToRegion(regionInfo, theUser, response, client); diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs index 4199c98a9d..46ee3c005a 100644 --- a/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs +++ b/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs @@ -193,6 +193,10 @@ namespace OpenSim.Region.CoreModules.Hypergrid { return scene.RegionInfo; } + else if (m_scenes.Count > 0) + { + return m_scenes[0].RegionInfo; + } return null; } @@ -248,7 +252,7 @@ namespace OpenSim.Region.CoreModules.Hypergrid { foreach (Scene nextScene in m_scenes) { - if (nextScene.RegionInfo.RegionName == regionName) + if (nextScene.RegionInfo.RegionName.Equals(regionName, StringComparison.InvariantCultureIgnoreCase)) { scene = nextScene; return true; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index a99a8026d3..c16c4fed27 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2394,18 +2394,19 @@ if (m_shape != null) { /// public void SendScheduledUpdates() { - const float VELOCITY_TOLERANCE = 0.0001f; - const float POSITION_TOLERANCE = 0.1f; + const float ROTATION_TOLERANCE = 0.01f; + const float VELOCITY_TOLERANCE = 0.001f; + const float POSITION_TOLERANCE = 0.05f; const int TIME_MS_TOLERANCE = 3000; if (m_updateFlag == 1) { // Throw away duplicate or insignificant updates - if (RotationOffset != m_lastRotation || - Acceleration != m_lastAcceleration || - (Velocity - m_lastVelocity).Length() > VELOCITY_TOLERANCE || - (RotationalVelocity - m_lastAngularVelocity).Length() > VELOCITY_TOLERANCE || - (OffsetPosition - m_lastPosition).Length() > POSITION_TOLERANCE || + if (!RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || + !Acceleration.Equals(m_lastAcceleration) || + !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || + !RotationalVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) || + !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) { AddTerseUpdateToAllAvatars(); diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 9ba19d3d73..63c979f43d 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2362,8 +2362,9 @@ namespace OpenSim.Region.Framework.Scenes public override void Update() { - const float VELOCITY_TOLERANCE = 0.0001f; - const float POSITION_TOLERANCE = 10.0f; + const float ROTATION_TOLERANCE = 0.01f; + const float VELOCITY_TOLERANCE = 0.001f; + const float POSITION_TOLERANCE = 0.05f; const int TIME_MS_TOLERANCE = 3000; SendPrimUpdates(); @@ -2377,9 +2378,9 @@ namespace OpenSim.Region.Framework.Scenes if (m_isChildAgent == false) { // Throw away duplicate or insignificant updates - if (m_bodyRot != m_lastRotation || - (m_velocity - m_lastVelocity).Length() > VELOCITY_TOLERANCE || - (m_pos - m_lastPosition).Length() > POSITION_TOLERANCE || + if (!m_bodyRot.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || + !m_velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || + !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) { SendTerseUpdateToAllClients(); @@ -2415,7 +2416,9 @@ namespace OpenSim.Region.Framework.Scenes m_perfMonMS = Environment.TickCount; Vector3 pos = m_pos; - pos.Z -= m_appearance.HipOffset; + pos.Z += m_appearance.HipOffset; + + //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, pos, m_velocity, Vector3.Zero, m_bodyRot, Vector4.UnitW, m_uuid, null, GetUpdatePriority(remoteClient))); @@ -2514,7 +2517,7 @@ namespace OpenSim.Region.Framework.Scenes return; Vector3 pos = m_pos; - pos.Z -= m_appearance.HipOffset; + pos.Z += m_appearance.HipOffset; remoteAvatar.m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, pos, m_appearance.Texture.GetBytes(), @@ -2585,7 +2588,7 @@ namespace OpenSim.Region.Framework.Scenes // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); Vector3 pos = m_pos; - pos.Z -= m_appearance.HipOffset; + pos.Z += m_appearance.HipOffset; m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot)); @@ -2694,7 +2697,7 @@ namespace OpenSim.Region.Framework.Scenes } Vector3 pos = m_pos; - pos.Z -= m_appearance.HipOffset; + pos.Z += m_appearance.HipOffset; m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot)); diff --git a/bin/OpenMetaverseTypes.dll b/bin/OpenMetaverseTypes.dll index 331d58b7229a4521e54782f1d3b5e63618288f6e..95d60217bd518fd0813e6388a60a32ae6cddd44d 100644 GIT binary patch delta 17521 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 WRjwiUyPM_IUloyqm)z4+t^Wry9HZ0# delta 17212 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