diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index 32ce4ab91a..4bb33f99cf 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -46,5 +46,8 @@ namespace OpenSim.Framework public Guid AgentID; public float godlevel; public byte[] throttles; + public bool alwaysrun; + public Guid ActiveGroupID; + public uint GroupAccess; } } \ No newline at end of file diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index a84443b6a9..d163ae73e9 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -613,6 +613,9 @@ namespace OpenSim.Framework void SendAvatarProperties(LLUUID avatarID, string aboutText, string bornOn, string charterMember, string flAbout, uint flags, LLUUID flImageID, LLUUID imageID, string profileURL, LLUUID partnerID); + byte[] GetThrottlesPacked(float multiplier); + + void SetDebug(int newDebug); void InPacket(Packet NewPack); void Close(bool ShutdownCircuit); diff --git a/OpenSim/Region/Application/OpenSimMain.cs b/OpenSim/Region/Application/OpenSimMain.cs index 7d83df78e9..e84e239fee 100644 --- a/OpenSim/Region/Application/OpenSimMain.cs +++ b/OpenSim/Region/Application/OpenSimMain.cs @@ -276,8 +276,8 @@ namespace OpenSim m_dumpAssetsToFile = standaloneConfig.GetBoolean("dump_assets_to_file", false); } - if (!m_sandbox) - m_SendChildAgentTaskData = false; + //if (!m_sandbox) + //m_SendChildAgentTaskData = false; m_networkServersInfo.loadFromConfiguration(m_config); @@ -485,8 +485,8 @@ namespace OpenSim if (m_SendChildAgentTaskData) { MainLog.Instance.Error("WARNING", - "Send Child Agent Task Updates is enabled. This is for testing only. It doesn't work on grid mode!"); - Thread.Sleep(12000); + "Send Child Agent Task Updates is enabled. This is for testing only."); + //Thread.Sleep(12000); } return new Scene(regionInfo, circuitManager, permissionManager, m_commsManager, sceneGridService, m_assetCache, diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs index f37ffc9a69..9d9a792212 100644 --- a/OpenSim/Region/ClientStack/ClientView.cs +++ b/OpenSim/Region/ClientStack/ClientView.cs @@ -641,7 +641,8 @@ namespace OpenSim.Region.ClientStack } mov.Data.LookAt = look; - OutPacket(mov, ThrottleOutPacketType.Task); + // Hack to get this out immediately and skip the throttles + OutPacket(mov, ThrottleOutPacketType.Unknown); } /// @@ -824,7 +825,8 @@ namespace OpenSim.Region.ClientStack newSimPack.RegionData.SimPort = (ushort)externalIPEndPoint.Port; newSimPack.RegionData.SeedCapability = Helpers.StringToField(capsURL); - OutPacket(newSimPack, ThrottleOutPacketType.Task); + // Hack to get this out immediately and skip throttles + OutPacket(newSimPack, ThrottleOutPacketType.Unknown); } public void SendMapBlock(List mapBlocks) @@ -858,7 +860,9 @@ namespace OpenSim.Region.ClientStack tpLocal.Info.LocationID = 2; tpLocal.Info.LookAt = lookAt; tpLocal.Info.Position = position; - OutPacket(tpLocal, ThrottleOutPacketType.Task); + + // Hack to get this out immediately and skip throttles + OutPacket(tpLocal, ThrottleOutPacketType.Unknown); } public void SendRegionTeleport(ulong regionHandle, byte simAccess, IPEndPoint newRegionEndPoint, uint locationID, @@ -884,7 +888,9 @@ namespace OpenSim.Region.ClientStack teleport.Info.SimPort = (ushort)newRegionEndPoint.Port; teleport.Info.LocationID = 4; teleport.Info.TeleportFlags = 1 << 4; - OutPacket(teleport, ThrottleOutPacketType.Task); + + // Hack to get this out immediately and skip throttles. + OutPacket(teleport, ThrottleOutPacketType.Unknown); } /// @@ -895,7 +901,9 @@ namespace OpenSim.Region.ClientStack TeleportFailedPacket tpFailed = (TeleportFailedPacket)PacketPool.Instance.GetPacket(PacketType.TeleportFailed); tpFailed.Info.AgentID = AgentId; tpFailed.Info.Reason = Helpers.StringToField(reason); - OutPacket(tpFailed, ThrottleOutPacketType.Task); + + // Hack to get this out immediately and skip throttles + OutPacket(tpFailed, ThrottleOutPacketType.Unknown); } /// @@ -906,7 +914,9 @@ namespace OpenSim.Region.ClientStack //TeleportStartPacket tpStart = (TeleportStartPacket)PacketPool.Instance.GetPacket(PacketType.TeleportStart); TeleportStartPacket tpStart = new TeleportStartPacket(); tpStart.Info.TeleportFlags = 16; // Teleport via location - OutPacket(tpStart, ThrottleOutPacketType.Task); + + // Hack to get this out immediately and skip throttles + OutPacket(tpStart, ThrottleOutPacketType.Unknown); } public void SendMoneyBalance(LLUUID transaction, bool success, byte[] description, int balance) @@ -1882,7 +1892,7 @@ namespace OpenSim.Region.ClientStack objectData.PathTwistBegin = primData.PathTwistBegin; objectData.ExtraParams = primData.ExtraParams; } - + /// /// Set some default values in a ObjectUpdatePacket /// @@ -2222,6 +2232,11 @@ namespace OpenSim.Region.ClientStack */ } + public byte[] GetThrottlesPacked(float multiplier) + { + return m_packetQueue.GetThrottlesPacked(multiplier); + } + public void SetChildAgentThrottle(byte[] throttles) { m_packetQueue.SetThrottleFromClient(throttles); diff --git a/OpenSim/Region/ClientStack/PacketQueue.cs b/OpenSim/Region/ClientStack/PacketQueue.cs index 1065f63edc..685f91b97a 100644 --- a/OpenSim/Region/ClientStack/PacketQueue.cs +++ b/OpenSim/Region/ClientStack/PacketQueue.cs @@ -356,7 +356,7 @@ namespace OpenSim.Region.ClientStack return (int) (((float) value/(float) curmax)*newmax); } - private byte[] GetThrottlesPacked(float multiplier) + public byte[] GetThrottlesPacked(float multiplier) { int singlefloat = 4; float tResend = ResendThrottle.Throttle*multiplier; diff --git a/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs b/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs index 73cd061423..8429d001c8 100644 --- a/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs +++ b/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs @@ -50,6 +50,7 @@ namespace OpenSim.Region.Communications.OGS1 private LocalBackEndServices m_localBackend = new LocalBackEndServices(); private Dictionary m_remoteRegionInfoCache = new Dictionary(); private List m_knownRegions = new List(); + private Dictionary m_deadRegionCache = new Dictionary(); private Dictionary m_queuedGridSettings = new Dictionary(); public BaseHttpServer httpListener; @@ -499,79 +500,99 @@ namespace OpenSim.Region.Communications.OGS1 public bool ChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData) { - RegionInfo regInfo = null; - try + int failures = 0; + lock (m_deadRegionCache) { - if (m_localBackend.ChildAgentUpdate(regionHandle, cAgentData)) + if (m_deadRegionCache.ContainsKey(regionHandle)) { - return true; + failures = m_deadRegionCache[regionHandle]; } - - regInfo = RequestNeighbourInfo(regionHandle); - if (regInfo != null) + } + if (failures <= 3) + { + RegionInfo regInfo = null; + try { - //don't want to be creating a new link to the remote instance every time like we are here - bool retValue = false; - - - OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting) Activator.GetObject( - typeof (OGS1InterRegionRemoting), - "tcp://" + regInfo.RemotingAddress + - ":" + regInfo.RemotingPort + - "/InterRegions"); - - if (remObject != null) + if (m_localBackend.ChildAgentUpdate(regionHandle, cAgentData)) { - retValue = remObject.ChildAgentUpdate(regionHandle, cAgentData); + return true; } - else - { - Console.WriteLine("remoting object not found"); - } - remObject = null; - MainLog.Instance.Verbose("INTER", - gdebugRegionName + - ": OGS1 tried to Update Child Agent data on outside region and got " + - retValue.ToString()); - return retValue; + regInfo = RequestNeighbourInfo(regionHandle); + if (regInfo != null) + { + //don't want to be creating a new link to the remote instance every time like we are here + bool retValue = false; + + + OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject( + typeof(OGS1InterRegionRemoting), + "tcp://" + regInfo.RemotingAddress + + ":" + regInfo.RemotingPort + + "/InterRegions"); + + if (remObject != null) + { + retValue = remObject.ChildAgentUpdate(regionHandle, cAgentData); + } + else + { + Console.WriteLine("remoting object not found"); + } + remObject = null; + //MainLog.Instance.Verbose("INTER", + //gdebugRegionName + + //": OGS1 tried to Update Child Agent data on outside region and got " + + //retValue.ToString()); + + return retValue; + } + NoteDeadRegion(regionHandle); + + return false; + } + catch (RemotingException e) + { + NoteDeadRegion(regionHandle); + MainLog.Instance.Warn("Remoting Error: Unable to connect to adjacent region: " + + " " + regInfo.RegionLocX + "," + regInfo.RegionLocY); + MainLog.Instance.Debug(e.ToString()); + return false; + } + catch (SocketException e) + { + NoteDeadRegion(regionHandle); + MainLog.Instance.Warn("Socket Error: Unable to connect to adjacent region: " + " " + + regInfo.RegionLocX + "," + regInfo.RegionLocY); + MainLog.Instance.Debug(e.ToString()); + return false; + } + catch (InvalidCredentialException e) + { + NoteDeadRegion(regionHandle); + MainLog.Instance.Warn("Invalid Credentials: Unable to connect to adjacent region: " + + " " + regInfo.RegionLocX + "," + regInfo.RegionLocY); + MainLog.Instance.Debug(e.ToString()); + return false; + } + catch (AuthenticationException e) + { + NoteDeadRegion(regionHandle); + MainLog.Instance.Warn("Authentication exception: Unable to connect to adjacent region: " + + " " + regInfo.RegionLocX + "," + regInfo.RegionLocY); + MainLog.Instance.Debug(e.ToString()); + return false; + } + catch (Exception e) + { + NoteDeadRegion(regionHandle); + MainLog.Instance.Debug(e.ToString()); + return false; } - - return false; } - catch (RemotingException e) + else { - MainLog.Instance.Warn("Remoting Error: Unable to connect to adjacent region: " + regInfo.RegionName + - " " + regInfo.RegionLocX + "," + regInfo.RegionLocY); - MainLog.Instance.Debug(e.ToString()); - return false; - } - catch (SocketException e) - { - MainLog.Instance.Warn("Socket Error: Unable to connect to adjacent region: " + regInfo.RegionName + " " + - regInfo.RegionLocX + "," + regInfo.RegionLocY); - MainLog.Instance.Debug(e.ToString()); - return false; - } - catch (InvalidCredentialException e) - { - MainLog.Instance.Warn("Invalid Credentials: Unable to connect to adjacent region: " + regInfo.RegionName + - " " + regInfo.RegionLocX + "," + regInfo.RegionLocY); - MainLog.Instance.Debug(e.ToString()); - return false; - } - catch (AuthenticationException e) - { - MainLog.Instance.Warn("Authentication exception: Unable to connect to adjacent region: " + - regInfo.RegionName + " " + regInfo.RegionLocX + "," + regInfo.RegionLocY); - MainLog.Instance.Debug(e.ToString()); - return false; - } - catch (Exception e) - { - MainLog.Instance.Warn("Unknown exception: Unable to connect to adjacent region: " + regInfo.RegionName + - " " + regInfo.RegionLocX + "," + regInfo.RegionLocY); - MainLog.Instance.Debug(e.ToString()); + //MainLog.Instance.Verbose("INTERREGION", "Skipped Sending Child Update to a region because it failed too many times:" + regionHandle.ToString()); return false; } } @@ -622,11 +643,12 @@ namespace OpenSim.Region.Communications.OGS1 return retValue; } - + NoteDeadRegion(regionHandle); return false; } catch (RemotingException e) { + NoteDeadRegion(regionHandle); MainLog.Instance.Warn("Remoting Error: Unable to connect to adjacent region: " + regInfo.RegionName + " " + regInfo.RegionLocX + "," + regInfo.RegionLocY); MainLog.Instance.Debug(e.ToString()); @@ -634,6 +656,7 @@ namespace OpenSim.Region.Communications.OGS1 } catch (SocketException e) { + NoteDeadRegion(regionHandle); MainLog.Instance.Warn("Socket Error: Unable to connect to adjacent region: " + regInfo.RegionName + " " + regInfo.RegionLocX + "," + regInfo.RegionLocY); MainLog.Instance.Debug(e.ToString()); @@ -641,6 +664,7 @@ namespace OpenSim.Region.Communications.OGS1 } catch (InvalidCredentialException e) { + NoteDeadRegion(regionHandle); MainLog.Instance.Warn("Invalid Credentials: Unable to connect to adjacent region: " + regInfo.RegionName + " " + regInfo.RegionLocX + "," + regInfo.RegionLocY); MainLog.Instance.Debug(e.ToString()); @@ -648,6 +672,7 @@ namespace OpenSim.Region.Communications.OGS1 } catch (AuthenticationException e) { + NoteDeadRegion(regionHandle); MainLog.Instance.Warn("Authentication exception: Unable to connect to adjacent region: " + regInfo.RegionName + " " + regInfo.RegionLocX + "," + regInfo.RegionLocY); MainLog.Instance.Debug(e.ToString()); @@ -655,6 +680,7 @@ namespace OpenSim.Region.Communications.OGS1 } catch (Exception e) { + NoteDeadRegion(regionHandle); MainLog.Instance.Warn("Unknown exception: Unable to connect to adjacent region: " + regInfo.RegionName + " " + regInfo.RegionLocX + "," + regInfo.RegionLocY); MainLog.Instance.Debug(e.ToString()); @@ -813,11 +839,12 @@ namespace OpenSim.Region.Communications.OGS1 return retValue; } - + NoteDeadRegion(regionHandle); return false; } catch (RemotingException e) { + NoteDeadRegion(regionHandle); MainLog.Instance.Warn("Remoting Error: Unable to connect to adjacent region: " + regInfo.RegionName + " " + regInfo.RegionLocX + "," + regInfo.RegionLocY); MainLog.Instance.Debug(e.ToString()); @@ -825,6 +852,7 @@ namespace OpenSim.Region.Communications.OGS1 } catch (SocketException e) { + NoteDeadRegion(regionHandle); MainLog.Instance.Warn("Socket Error: Unable to connect to adjacent region: " + regInfo.RegionName + " " + regInfo.RegionLocX + "," + regInfo.RegionLocY); MainLog.Instance.Debug(e.ToString()); @@ -832,6 +860,7 @@ namespace OpenSim.Region.Communications.OGS1 } catch (InvalidCredentialException e) { + NoteDeadRegion(regionHandle); MainLog.Instance.Warn("Invalid Credentials: Unable to connect to adjacent region: " + regInfo.RegionName + " " + regInfo.RegionLocX + "," + regInfo.RegionLocY); MainLog.Instance.Debug(e.ToString()); @@ -839,6 +868,7 @@ namespace OpenSim.Region.Communications.OGS1 } catch (AuthenticationException e) { + NoteDeadRegion(regionHandle); MainLog.Instance.Warn("Authentication exception: Unable to connect to adjacent region: " + regInfo.RegionName + " " + regInfo.RegionLocX + "," + regInfo.RegionLocY); MainLog.Instance.Debug(e.ToString()); @@ -846,6 +876,7 @@ namespace OpenSim.Region.Communications.OGS1 } catch (Exception e) { + NoteDeadRegion(regionHandle); MainLog.Instance.Warn("Unknown exception: Unable to connect to adjacent region: " + regInfo.RegionName + " " + regInfo.RegionLocX + "," + regInfo.RegionLocY); MainLog.Instance.Debug(e.ToString()); @@ -895,10 +926,12 @@ namespace OpenSim.Region.Communications.OGS1 } //TODO need to see if we know about where this region is and use .net remoting // to inform it. + NoteDeadRegion(regionHandle); return false; } catch (RemotingException e) { + NoteDeadRegion(regionHandle); MainLog.Instance.Warn("Remoting Error: Unable to connect to adjacent region: " + regInfo.RegionName + " " + regInfo.RegionLocX + "," + regInfo.RegionLocY); MainLog.Instance.Debug(e.ToString()); @@ -906,6 +939,7 @@ namespace OpenSim.Region.Communications.OGS1 } catch { + NoteDeadRegion(regionHandle); return false; } } @@ -945,10 +979,12 @@ namespace OpenSim.Region.Communications.OGS1 } //TODO need to see if we know about where this region is and use .net remoting // to inform it. + NoteDeadRegion(regionHandle); return false; } catch (RemotingException e) { + NoteDeadRegion(regionHandle); MainLog.Instance.Warn("Remoting Error: Unable to connect to adjacent region: " + regInfo.RegionName + " " + regInfo.RegionLocX + "," + regInfo.RegionLocY); MainLog.Instance.Debug(e.ToString()); @@ -956,6 +992,7 @@ namespace OpenSim.Region.Communications.OGS1 } catch { + NoteDeadRegion(regionHandle); return false; } } @@ -994,10 +1031,12 @@ namespace OpenSim.Region.Communications.OGS1 } //TODO need to see if we know about where this region is and use .net remoting // to inform it. + NoteDeadRegion(regionHandle); return false; } catch (RemotingException e) { + NoteDeadRegion(regionHandle); MainLog.Instance.Warn("Remoting Error: Unable to connect to adjacent region to tell it to close child agents: " + regInfo.RegionName + " " + regInfo.RegionLocX + "," + regInfo.RegionLocY); //MainLog.Instance.Debug(e.ToString()); @@ -1006,6 +1045,7 @@ namespace OpenSim.Region.Communications.OGS1 catch (SocketException e) { + NoteDeadRegion(regionHandle); MainLog.Instance.Warn("Socket Error: Unable to connect to adjacent region using tcp://" + regInfo.RemotingAddress + ":" + regInfo.RemotingPort + @@ -1016,6 +1056,7 @@ namespace OpenSim.Region.Communications.OGS1 } catch (InvalidCredentialException e) { + NoteDeadRegion(regionHandle); MainLog.Instance.Warn("Invalid Credentials: Unable to connect to adjacent region using tcp://" + regInfo.RemotingAddress + ":" + regInfo.RemotingPort + @@ -1025,6 +1066,7 @@ namespace OpenSim.Region.Communications.OGS1 } catch (AuthenticationException e) { + NoteDeadRegion(regionHandle); MainLog.Instance.Warn("Authentication exception: Unable to connect to adjacent region using tcp://" + regInfo.RemotingAddress + ":" + regInfo.RemotingPort + @@ -1034,6 +1076,7 @@ namespace OpenSim.Region.Communications.OGS1 } catch (WebException e) { + NoteDeadRegion(regionHandle); MainLog.Instance.Warn("WebException exception: Unable to connect to adjacent region using tcp://" + regInfo.RemotingAddress + ":" + regInfo.RemotingPort + @@ -1043,6 +1086,7 @@ namespace OpenSim.Region.Communications.OGS1 } catch (Exception e) { + NoteDeadRegion(regionHandle); // This line errors with a Null Reference Exception.. Why? @.@ //MainLog.Instance.Warn("Unknown exception: Unable to connect to adjacent region using tcp://" + regInfo.RemotingAddress + // ":" + regInfo.RemotingPort + @@ -1091,11 +1135,21 @@ namespace OpenSim.Region.Communications.OGS1 { MainLog.Instance.Verbose("INTER", gdebugRegionName + "Incoming OGS1 RegionUpReport: " + "(" + regionData.RegionLocX + - "," + regionData.RegionLocY + ")"); + "," + regionData.RegionLocY + "). Giving this region a fresh set of 'dead' tries"); try { + lock (m_deadRegionCache) + { + if (m_deadRegionCache.ContainsKey(regionData.RegionHandle)) + { + + m_deadRegionCache.Remove(regionData.RegionHandle); + } + } + return m_localBackend.TriggerRegionUp(new RegionInfo(regionData), regionhandle); + } catch (RemotingException e) @@ -1107,7 +1161,7 @@ namespace OpenSim.Region.Communications.OGS1 public bool TriggerChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData) { - MainLog.Instance.Verbose("INTER", "Incoming OGS1 Child Agent Data Update"); + //MainLog.Instance.Verbose("INTER", "Incoming OGS1 Child Agent Data Update"); try { @@ -1227,6 +1281,20 @@ namespace OpenSim.Region.Communications.OGS1 } socket.Close(); } + public void NoteDeadRegion(ulong regionhandle) + { + lock (m_deadRegionCache) + { + if (m_deadRegionCache.ContainsKey(regionhandle)) + { + m_deadRegionCache[regionhandle] = m_deadRegionCache[regionhandle] + 1; + } + else + { + m_deadRegionCache.Add(regionhandle, 1); + } + } + } } } \ No newline at end of file diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs index 9aa3f20bab..6c0ed28636 100644 --- a/OpenSim/Region/Environment/Scenes/InnerScene.cs +++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs @@ -537,20 +537,24 @@ namespace OpenSim.Region.Environment.Scenes // the initial update for and what we'll use to limit the // space we check for new objects on movement. - if (presence.IsChildAgent) + if (presence.IsChildAgent && m_parentScene.m_sendTasksToChild) { - //Vector3 avPosition = new Vector3(presence.AbsolutePosition.X,presence.AbsolutePosition.Y,presence.AbsolutePosition.Z); - //LLVector3 oLoc = ((SceneObjectGroup)ent).AbsolutePosition; - //Vector3 objPosition = new Vector3(oLoc.X,oLoc.Y,oLoc.Z); - //float distResult = Vector3Distance(avPosition, objPosition); - //if (distResult > 512) - //{ - //int x = 0; - //} - //if (distResult < presence.DrawDistance) - //{ - ((SceneObjectGroup) ent).ScheduleFullUpdateToAvatar(presence); - //} + LLVector3 oLoc = ((SceneObjectGroup)ent).AbsolutePosition; + float distResult = (float)Util.GetDistanceTo(presence.AbsolutePosition,oLoc); + + //MainLog.Instance.Verbose("DISTANCE", distResult.ToString()); + + if (distResult > 60) + { + int x = 0; + } + if (distResult < presence.DrawDistance) + { + // Send Only if we don't already know about it. + // KnownPrim also makes the prim known when called. + if (!presence.KnownPrim(((SceneObjectGroup) ent).UUID)) + ((SceneObjectGroup) ent).ScheduleFullUpdateToAvatar(presence); + } } else { diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 64b9abb01a..f32de2e2db 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -1391,6 +1391,8 @@ namespace OpenSim.Region.Environment.Scenes m_sceneGridService.OnCloseAgentConnection += CloseConnection; m_sceneGridService.OnRegionUp += OtherRegionUp; m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate; + + @@ -1492,19 +1494,25 @@ namespace OpenSim.Region.Environment.Scenes public virtual bool IncomingChildAgentDataUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData) { ScenePresence childAgentUpdate = GetScenePresence(new LLUUID(cAgentData.AgentID)); - if (!(childAgentUpdate.Equals(null))) + if (childAgentUpdate != null) { // I can't imagine *yet* why we would get an update if the agent is a root agent.. // however to avoid a race condition crossing borders.. if (childAgentUpdate.IsChildAgent) { + uint rRegionX = (uint)(cAgentData.regionHandle >> 40); + uint rRegionY = (((uint)(cAgentData.regionHandle)) >> 8); + uint tRegionX = RegionInfo.RegionLocX; + uint tRegionY = RegionInfo.RegionLocY; //Send Data to ScenePresence - childAgentUpdate.ChildAgentDataUpdate(cAgentData); + childAgentUpdate.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY); // Not Implemented: //TODO: Do we need to pass the message on to one of our neighbors? + } + return true; } - return true; + return false; } /// @@ -1614,6 +1622,11 @@ namespace OpenSim.Region.Environment.Scenes return m_sceneGridService.CrossToNeighbouringRegion(regionHandle, agentID, position, isFlying); } + public void SendOutChildAgentUpdates(ChildAgentDataUpdate cadu, ScenePresence presence) + { + m_sceneGridService.SendChildAgentDataUpdate(cadu, presence); + } + #endregion #region Module Methods diff --git a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs index a9c2c2f782..805b44ce10 100644 --- a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs @@ -332,7 +332,7 @@ namespace OpenSim.Region.Environment.Scenes //bool val = m_commsProvider.InterRegion.RegionUp(new SearializableRegionInfo(region)); } - public delegate void SendChildAgentDataUpdateDelegate(ulong regionHandle, ChildAgentDataUpdate cAgentData); + public delegate void SendChildAgentDataUpdateDelegate(ChildAgentDataUpdate cAgentData, ScenePresence presence); /// /// This informs all neighboring regions about the settings of it's child agent. @@ -341,18 +341,22 @@ namespace OpenSim.Region.Environment.Scenes /// This contains information, such as, Draw Distance, Camera location, Current Position, Current throttle settings, etc. /// /// - private void SendChildAgentDataUpdateAsync(ulong regionHandle, ChildAgentDataUpdate cAgentData) + private void SendChildAgentDataUpdateAsync(ChildAgentDataUpdate cAgentData, ScenePresence presence) { - MainLog.Instance.Notice("INTERGRID", "Informing a neighbor about my agent."); - bool regionAccepted = m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData); + //MainLog.Instance.Notice("INTERGRID", "Informing neighbors about my agent."); - if (regionAccepted) + foreach (ulong regionHandle in presence.KnownChildRegions) { - MainLog.Instance.Notice("INTERGRID", "Completed sending a neighbor an update about my agent"); - } - else - { - MainLog.Instance.Notice("INTERGRID", "Failed sending a neighbor an update about my agent"); + bool regionAccepted = m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData); + + if (regionAccepted) + { + //MainLog.Instance.Notice("INTERGRID", "Completed sending a neighbor an update about my agent"); + } + else + { + //MainLog.Instance.Notice("INTERGRID", "Failed sending a neighbor an update about my agent"); + } } } @@ -362,11 +366,11 @@ namespace OpenSim.Region.Environment.Scenes icon.EndInvoke(iar); } - public void SendChildAgentDataUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData) + public void SendChildAgentDataUpdate(ChildAgentDataUpdate cAgentData, ScenePresence presence) { // This assumes that we know what our neighbors are. SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync; - d.BeginInvoke(regionHandle, cAgentData, + d.BeginInvoke(cAgentData,presence, SendChildAgentDataUpdateCompleted, d); } @@ -374,11 +378,8 @@ namespace OpenSim.Region.Environment.Scenes public delegate void SendCloseChildAgentDelegate( ScenePresence presence); /// - /// This informs all neighboring regions about the settings of it's child agent. + /// This Closes child agents on neighboring regions /// Calls an asynchronous method to do so.. so it doesn't lag the sim. - /// - /// This contains information, such as, Draw Distance, Camera location, Current Position, Current throttle settings, etc. - /// /// private void SendCloseChildAgentAsync(ScenePresence presence) { diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index c8310e4477..f37b38b0c1 100644 --- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs @@ -55,6 +55,7 @@ namespace OpenSim.Region.Environment.Scenes private LLVector3 m_requestedSitOffset = new LLVector3(); private float m_sitAvatarHeight = 2.0f; private float m_godlevel = 0; + private LLVector3 m_LastChildAgentUpdatePosition = new LLVector3(); private int m_perfMonMS = 0; @@ -90,6 +91,8 @@ namespace OpenSim.Region.Environment.Scenes private LLQuaternion m_headrotation = new LLQuaternion(); private byte m_state = (byte) 0; + private List m_knownPrimUUID = new List(); + // Agent's Draw distance. protected float m_DrawDistance = 0f; @@ -136,6 +139,17 @@ namespace OpenSim.Region.Environment.Scenes get { return m_physicsActor; } } + public bool KnownPrim(LLUUID primID) + { + if (m_knownPrimUUID.Contains(primID)) + { + return true; + } + m_knownPrimUUID.Add(primID); + return false; + } + + public bool Updated { set { m_updateflag = value; } @@ -499,7 +513,7 @@ namespace OpenSim.Region.Environment.Scenes m_scene.CommsManager.UserProfileCacheService.UpdateUserInventory(m_uuid); //if (!m_gotAllObjectsInScene) //{ - //m_scene.SendAllSceneObjectsToClient(this); + m_scene.SendAllSceneObjectsToClient(this); //m_gotAllObjectsInScene = true; //} } @@ -1408,6 +1422,29 @@ namespace OpenSim.Region.Environment.Scenes m_scene.NotifyMyCoarseLocationChange(); } } + + // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m + if (Util.GetDistanceTo(AbsolutePosition,m_LastChildAgentUpdatePosition) > 32) + { + ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); + cadu.ActiveGroupID=LLUUID.Zero.UUID; + cadu.AgentID = UUID.UUID; + cadu.alwaysrun = m_setAlwaysRun; + cadu.AVHeight = m_avHeight; + LLVector3 tempCameraCenter = new LLVector3(m_CameraCenter.x, m_CameraCenter.y, m_CameraCenter.z); + cadu.cameraPosition = new sLLVector3(tempCameraCenter); + cadu.drawdistance = m_DrawDistance; + cadu.godlevel = m_godlevel; + cadu.GroupAccess = 0; + cadu.Position = new sLLVector3(AbsolutePosition); + cadu.regionHandle = m_scene.RegionInfo.RegionHandle; + cadu.throttles = ControllingClient.GetThrottlesPacked(1f); + cadu.Velocity = new sLLVector3(Velocity); + m_scene.SendOutChildAgentUpdates(cadu,this); + m_LastChildAgentUpdatePosition.X = AbsolutePosition.X; + m_LastChildAgentUpdatePosition.Y = AbsolutePosition.Y; + m_LastChildAgentUpdatePosition.Z = AbsolutePosition.Z; + } } #endregion @@ -1532,15 +1569,30 @@ namespace OpenSim.Region.Environment.Scenes /// This updates important decision making data about a child agent /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region /// - public void ChildAgentDataUpdate(ChildAgentDataUpdate cAgentData) + public void ChildAgentDataUpdate(ChildAgentDataUpdate cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY) { // + int shiftx = ((int)rRegionX - (int)tRegionX) * 256; + int shifty = ((int)rRegionY - (int)tRegionY) * 256; + m_DrawDistance = cAgentData.drawdistance; - m_pos = new LLVector3(cAgentData.Position.x, cAgentData.Position.y, cAgentData.Position.z); + m_pos = new LLVector3(cAgentData.Position.x + shiftx, cAgentData.Position.y + shifty, cAgentData.Position.z); + + // It's hard to say here.. We can't really tell where the camera position is unless it's in world cordinates from the sending region m_CameraCenter = new Vector3(cAgentData.cameraPosition.x, cAgentData.cameraPosition.y, cAgentData.cameraPosition.z); + + m_godlevel = cAgentData.godlevel; + SetHeight(cAgentData.AVHeight); + ControllingClient.SetChildAgentThrottle(cAgentData.throttles); + + + + // Sends out the objects in the user's draw distance if m_sendTasksToChild is true. + if (m_scene.m_sendTasksToChild) + m_scene.SendAllSceneObjectsToClient(this); //cAgentData.AVHeight; //cAgentData.regionHandle; //m_velocity = cAgentData.Velocity; diff --git a/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs index 69060f18fc..ea1e28e766 100644 --- a/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs @@ -226,7 +226,12 @@ namespace SimpleApp public virtual void SetChildAgentThrottle(byte[] throttle) { } + public byte[] GetThrottlesPacked(float multiplier) + { + return new byte[0]; + } + public virtual void SendAnimations(LLUUID[] animations, int[] seqs, LLUUID sourceAgentId) { }