diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index 5beb37d64c..91df64d15b 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -431,6 +431,8 @@ namespace OpenSim.Framework // The code to pack textures, visuals, wearables and attachments // should be removed; packed appearance contains the full appearance // This is retained for backward compatibility only + +/* then lets remove if (Appearance.Texture != null) { byte[] rawtextures = Appearance.Texture.GetBytes(); @@ -459,7 +461,7 @@ namespace OpenSim.Framework args["attachments"] = attachs; } // End of code to remove - +*/ if ((Controllers != null) && (Controllers.Length > 0)) { OSDArray controls = new OSDArray(Controllers.Length); @@ -647,58 +649,71 @@ namespace OpenSim.Framework // AgentTextures[i++] = o.AsUUID(); //} - Appearance = new AvatarAppearance(); - // The code to unpack textures, visuals, wearables and attachments - // should be removed; packed appearance contains the full appearance - // This is retained for backward compatibility only - if (args["texture_entry"] != null) + // packed_appearence should contain all appearance information + if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map) { - byte[] rawtextures = args["texture_entry"].AsBinary(); - Primitive.TextureEntry textures = new Primitive.TextureEntry(rawtextures,0,rawtextures.Length); - Appearance.SetTextureEntries(textures); + m_log.WarnFormat("[CHILDAGENTDATAUPDATE] got packed appearance"); + Appearance = new AvatarAppearance((OSDMap)args["packed_appearance"]); } - - if (args["visual_params"] != null) - Appearance.SetVisualParams(args["visual_params"].AsBinary()); - - if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array) + else { - OSDArray wears = (OSDArray)(args["wearables"]); + // if missing try the old pack method + m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance, checking old method"); - int count = wears.Count; - if (count > AvatarWearable.MAX_WEARABLES) - count = AvatarWearable.MAX_WEARABLES; + Appearance = new AvatarAppearance(); - for (int i = 0; i < count / 2; i++) + // The code to unpack textures, visuals, wearables and attachments + // should be removed; packed appearance contains the full appearance + // This is retained for backward compatibility only + if (args["texture_entry"] != null) { - AvatarWearable awear = new AvatarWearable((OSDArray)wears[i]); - Appearance.SetWearable(i,awear); + byte[] rawtextures = args["texture_entry"].AsBinary(); + Primitive.TextureEntry textures = new Primitive.TextureEntry(rawtextures, 0, rawtextures.Length); + Appearance.SetTextureEntries(textures); } - } - if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array) - { - OSDArray attachs = (OSDArray)(args["attachments"]); - foreach (OSD o in attachs) + if (args["visual_params"] != null) + Appearance.SetVisualParams(args["visual_params"].AsBinary()); + + if ((args["wearables"] != null) && (args["wearables"]).Type == OSDType.Array) { - if (o.Type == OSDType.Map) + OSDArray wears = (OSDArray)(args["wearables"]); + + int count = wears.Count; + if (count > AvatarWearable.MAX_WEARABLES) + count = AvatarWearable.MAX_WEARABLES; + + for (int i = 0; i < count / 2; i++) { - // We know all of these must end up as attachments so we - // append rather than replace to ensure multiple attachments - // per point continues to work -// m_log.DebugFormat("[CHILDAGENTDATAUPDATE]: Appending attachments for {0}", AgentID); - Appearance.AppendAttachment(new AvatarAttachment((OSDMap)o)); + AvatarWearable awear = new AvatarWearable((OSDArray)wears[i]); + Appearance.SetWearable(i, awear); } } - } - // end of code to remove + if ((args["attachments"] != null) && (args["attachments"]).Type == OSDType.Array) + { + OSDArray attachs = (OSDArray)(args["attachments"]); + foreach (OSD o in attachs) + { + if (o.Type == OSDType.Map) + { + // We know all of these must end up as attachments so we + // append rather than replace to ensure multiple attachments + // per point continues to work + // m_log.DebugFormat("[CHILDAGENTDATAUPDATE]: Appending attachments for {0}", AgentID); + Appearance.AppendAttachment(new AvatarAttachment((OSDMap)o)); + } + } + } + // end of code to remove + } +/* moved above if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map) Appearance = new AvatarAppearance((OSDMap)args["packed_appearance"]); else m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance"); - +*/ if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array) { OSDArray controls = (OSDArray)(args["controllers"]); diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 22cc79da33..3b0430bed0 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -755,6 +755,8 @@ namespace OpenSim.Framework /// bool IsActive { get; set; } + int PingTimeMS { get; } + /// /// Set if the client is closing due to a logout request /// diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs index 33ef8e01c7..86e529399b 100644 --- a/OpenSim/Framework/WebUtil.cs +++ b/OpenSim/Framework/WebUtil.cs @@ -81,7 +81,7 @@ namespace OpenSim.Framework /// Number of milliseconds a call can take before it is considered /// a "long" call for warning & debugging purposes /// - public const int LongCallTime = 3000; + public const int LongCallTime = 500; /// /// The maximum length of any data logged because of a long request time. @@ -208,6 +208,9 @@ namespace OpenSim.Framework string errorMessage = "unknown error"; int tickstart = Util.EnvironmentTickCount(); int tickdata = 0; + int tickcompressdata = 0; + int tickJsondata = 0; + int compsize = 0; string strBuffer = null; try @@ -225,6 +228,8 @@ namespace OpenSim.Framework { strBuffer = OSDParser.SerializeJsonString(data); + tickJsondata = Util.EnvironmentTickCountSubtract(tickstart); + if (DebugLevel >= 5) LogOutgoingDetail(strBuffer); @@ -243,13 +248,19 @@ namespace OpenSim.Framework // gets written on the strteam upon Dispose() } byte[] buf = ms.ToArray(); + + tickcompressdata = Util.EnvironmentTickCountSubtract(tickstart); + request.ContentLength = buf.Length; //Count bytes to send + compsize = buf.Length; using (Stream requestStream = request.GetRequestStream()) requestStream.Write(buf, 0, (int)buf.Length); } } else { + tickcompressdata = tickJsondata; + compsize = buffer.Length; request.ContentType = "application/json"; request.ContentLength = buffer.Length; //Count bytes to send using (Stream requestStream = request.GetRequestStream()) @@ -291,12 +302,16 @@ namespace OpenSim.Framework int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); if (tickdiff > LongCallTime) m_log.InfoFormat( - "[WEB UTIL]: Slow ServiceOSD request {0} {1} {2} took {3}ms, {4}ms writing, {5}", + "[WEB UTIL]: Slow ServiceOSD request {0} {1} {2} took {3}ms, {4}ms writing({5} at Json; {6} at comp), {7} bytes ({8} uncomp): {9}", reqnum, method, url, tickdiff, tickdata, + tickJsondata, + tickcompressdata, + compsize, + strBuffer != null ? strBuffer.Length : 0, strBuffer != null ? (strBuffer.Length > MaxRequestDiagLength ? strBuffer.Remove(MaxRequestDiagLength) : strBuffer) : ""); diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 85049c9e56..e1e3d87f89 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -978,15 +978,25 @@ namespace OpenSim cdt.AddColumn("Circuit code", 12); cdt.AddColumn("Endpoint", 23); cdt.AddColumn("Active?", 7); + cdt.AddColumn("ChildAgent?", 7); + cdt.AddColumn("ping(ms)", 8); SceneManager.ForEachScene( s => s.ForEachClient( - c => cdt.AddRow( - s.Name, - c.Name, - c.CircuitCode.ToString(), - c.RemoteEndPoint.ToString(), - c.IsActive.ToString()))); + c => + { + bool child = false; + if(c.SceneAgent != null && c.SceneAgent.IsChildAgent) + child = true; + cdt.AddRow( + s.Name, + c.Name, + c.CircuitCode.ToString(), + c.RemoteEndPoint.ToString(), + c.IsActive.ToString(), + child.ToString(), + c.PingTimeMS); + })); MainConsole.Instance.Output(cdt.ToString()); } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 59d1c69137..b0cb4ea7a8 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -358,7 +358,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // protected HashSet m_attachmentsSent; private bool m_deliverPackets = true; - private int m_animationSequenceNumber = 1; + private bool m_SendLogoutPacketWhenClosing = true; /// @@ -419,6 +419,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } } public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); } + public int PingTimeMS + { + get + { + if (UDPClient != null) + return UDPClient.PingTimeMS; + return 0; + } + } + /// /// Entity update queues /// @@ -440,7 +450,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP public string Name { get { return FirstName + " " + LastName; } } public uint CircuitCode { get { return m_circuitCode; } } - public int NextAnimationSequenceNumber { get { return m_animationSequenceNumber++; } } + public int NextAnimationSequenceNumber + { + get { return m_udpServer.NextAnimationSequenceNumber; } + } /// /// As well as it's function in IClientAPI, in LLClientView we are locking on this property in order to @@ -461,6 +474,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP set { m_disableFacelights = value; } } + public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } } @@ -1638,6 +1652,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP pc.PingID.OldestUnacked = 0; OutPacket(pc, ThrottleOutPacketType.Unknown); + UDPClient.m_lastStartpingTimeMS = Util.EnvironmentTickCount(); } public void SendKillObject(List localIDs) @@ -3813,8 +3828,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { SceneObjectPart e = (SceneObjectPart)entity; SceneObjectGroup g = e.ParentGroup; - if (g.RootPart.Shape.State > 30 && g.RootPart.Shape.State < 39) // HUD - if (g.OwnerID != AgentId) + if (g.HasPrivateAttachmentPoint && g.OwnerID != AgentId) return; // Don't send updates for other people's HUDs } @@ -3932,8 +3946,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (part.ParentGroup.IsAttachment) { // Someone else's HUD, why are we getting these? - if (part.ParentGroup.OwnerID != AgentId && - part.ParentGroup.RootPart.Shape.State > 30 && part.ParentGroup.RootPart.Shape.State < 39) + if (part.ParentGroup.OwnerID != AgentId && part.ParentGroup.HasPrivateAttachmentPoint) continue; ScenePresence sp; // Owner is not in the sim, don't update it to @@ -5278,16 +5291,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP byte[] objectData = new byte[76]; - data.CollisionPlane.ToBytes(objectData, 0); - offsetPosition.ToBytes(objectData, 16); Vector3 velocity = new Vector3(0, 0, 0); Vector3 acceleration = new Vector3(0, 0, 0); + rotation.Normalize(); + Vector3 vrot = new Vector3(rotation.X, rotation.Y, rotation.Z); + + data.CollisionPlane.ToBytes(objectData, 0); + offsetPosition.ToBytes(objectData, 16); velocity.ToBytes(objectData, 28); acceleration.ToBytes(objectData, 40); -// data.Velocity.ToBytes(objectData, 28); -// data.Acceleration.ToBytes(objectData, 40); - rotation.ToBytes(objectData, 52); - //data.AngularVelocity.ToBytes(objectData, 64); + vrot.ToBytes(objectData, 52); + data.AngularVelocity.ToBytes(objectData, 64); ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); @@ -5343,15 +5357,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP data.RelativePosition.ToBytes(objectData, 0); data.Velocity.ToBytes(objectData, 12); data.Acceleration.ToBytes(objectData, 24); - try - { - data.RotationOffset.ToBytes(objectData, 36); - } - catch (Exception e) - { - m_log.Warn("[LLClientView]: exception converting quaternion to bytes, using Quaternion.Identity. Exception: " + e.ToString()); - OpenMetaverse.Quaternion.Identity.ToBytes(objectData, 36); - } + + Quaternion rotation = data.RotationOffset; + rotation.Normalize(); + Vector3 vrot = new Vector3(rotation.X, rotation.Y, rotation.Z); + vrot.ToBytes(objectData, 36); data.AngularVelocity.ToBytes(objectData, 48); ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs index bd4e617da9..fe31bd9b79 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs @@ -163,6 +163,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP private int m_maxRTO = 60000; public bool m_deliverPackets = true; + public int m_lastStartpingTimeMS; + public int m_pingMS; + + public int PingTimeMS + { + get + { + if (m_pingMS < 10) + return 10; + if(m_pingMS > 2000) + return 2000; + return m_pingMS; + } + } + /// /// This is the percentage of the udp texture queue to add to the task queue since /// textures are now generally handled through http. @@ -225,6 +240,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Initialize this to a sane value to prevent early disconnects TickLastPacketReceived = Environment.TickCount & Int32.MaxValue; + m_pingMS = (int)(3.0 * server.TickCountResolution); // so filter doesnt start at 0; } /// diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index fe79f870a9..3b0312da3b 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -293,6 +293,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Flag to signal when clients should send pings protected bool m_sendPing; + private int m_animationSequenceNumber; + + public int NextAnimationSequenceNumber + { + get + { + m_animationSequenceNumber++; + if (m_animationSequenceNumber > 2147482624) + m_animationSequenceNumber = 1; + return m_animationSequenceNumber; + } + } + + + private ExpiringCache> m_pendingCache = new ExpiringCache>(); /// @@ -369,16 +384,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Measure the resolution of Environment.TickCount TickCountResolution = 0f; - for (int i = 0; i < 5; i++) + for (int i = 0; i < 10; i++) { int start = Environment.TickCount; int now = start; while (now == start) now = Environment.TickCount; - TickCountResolution += (float)(now - start) * 0.2f; + TickCountResolution += (float)(now - start) * 0.1f; } - m_log.Info("[LLUDPSERVER]: Average Environment.TickCount resolution: " + TickCountResolution + "ms"); TickCountResolution = (float)Math.Ceiling(TickCountResolution); + m_log.Info("[LLUDPSERVER]: Average Environment.TickCount resolution: " + TickCountResolution + "ms"); #endregion Environment.TickCount Measurement @@ -386,6 +401,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP int sceneThrottleBps = 0; bool usePools = false; + + IConfig config = configSource.Configs["ClientStack.LindenUDP"]; if (config != null) { @@ -435,6 +452,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_throttle = new TokenBucket(null, sceneThrottleBps); ThrottleRates = new ThrottleRates(configSource); + Random rnd = new Random(Util.EnvironmentTickCount()); + m_animationSequenceNumber = rnd.Next(11474826); + if (usePools) EnablePools(); } @@ -1128,6 +1148,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP pc.PingID.OldestUnacked = 0; SendPacket(udpClient, pc, ThrottleOutPacketType.Unknown, false, null); + udpClient.m_lastStartpingTimeMS = Util.EnvironmentTickCount(); } public void CompletePing(LLUDPClient udpClient, byte pingID) @@ -1567,7 +1588,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // We don't need to do anything else with ping checks StartPingCheckPacket startPing = (StartPingCheckPacket)packet; CompletePing(udpClient, startPing.PingID.PingID); - + if ((Environment.TickCount - m_elapsedMSSinceLastStatReport) >= 3000) { udpClient.SendPacketStats(); @@ -1577,7 +1598,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else if (packet.Type == PacketType.CompletePingCheck) { - // We don't currently track client ping times + int t = Util.EnvironmentTickCountSubtract(udpClient.m_lastStartpingTimeMS); + int c = udpClient.m_pingMS; + c = 800 * c + 200 * t; + c /= 1000; + udpClient.m_pingMS = c; return; } diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs index de8925db9c..498cc2f752 100644 --- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs @@ -120,10 +120,16 @@ namespace OpenSim.Region.CoreModules.Framework public void CreateCaps(UUID agentId, uint circuitCode) { +// int ts = Util.EnvironmentTickCount(); +/* this as no business here... + * must be done elsewhere ( and is ) int flags = m_scene.GetUserFlags(agentId); + + m_log.ErrorFormat("[CreateCaps]: banCheck {0} ", Util.EnvironmentTickCountSubtract(ts)); + if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId, flags)) return; - +*/ Caps caps; String capsObjectPath = GetCapsPath(agentId); @@ -132,19 +138,27 @@ namespace OpenSim.Region.CoreModules.Framework if (m_capsObjects.ContainsKey(circuitCode)) { Caps oldCaps = m_capsObjects[circuitCode]; - - //m_log.WarnFormat( - // "[CAPS]: Recreating caps for agent {0} in region {1}. Old caps path {2}, new caps path {3}. ", - // agentId, m_scene.RegionInfo.RegionName, oldCaps.CapsObjectPath, capsObjectPath); + +// if (capsObjectPath == oldCaps.CapsObjectPath) +// { +// m_log.WarnFormat( +// "[CAPS]: Reusing caps for agent {0} in region {1}. Old caps path {2}, new caps path {3}. ", +// agentId, m_scene.RegionInfo.RegionName, oldCaps.CapsObjectPath, capsObjectPath); +// return; +// } } caps = new Caps(MainServer.Instance, m_scene.RegionInfo.ExternalHostName, (MainServer.Instance == null) ? 0: MainServer.Instance.Port, capsObjectPath, agentId, m_scene.RegionInfo.RegionName); +// m_log.ErrorFormat("[CreateCaps]: new caps {0} ", Util.EnvironmentTickCountSubtract(ts)); + m_capsObjects[circuitCode] = caps; } m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps); +// m_log.ErrorFormat("[CreateCaps]: end {0} ", Util.EnvironmentTickCountSubtract(ts)); + } public void RemoveCaps(UUID agentId, uint circuitCode) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 71148eaeaa..d5eca03f09 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -430,7 +430,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } // TODO: Get proper AVG Height - float localAVHeight = 1.56f; + float localHalfAVHeight = 0.8f; + if (sp.Appearance != null) + localHalfAVHeight = sp.Appearance.AvatarHeight / 2; + float posZLimit = 22; // TODO: Check other Scene HeightField @@ -439,10 +442,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; } - float newPosZ = posZLimit + localAVHeight; - if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) + posZLimit += localHalfAVHeight + 0.1f; + + if ((position.Z < posZLimit) && !(Single.IsInfinity(posZLimit) || Single.IsNaN(posZLimit))) { - position.Z = newPosZ; + position.Z = posZLimit; } if (sp.Flying) @@ -720,7 +724,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); agentCircuit.startpos = position; agentCircuit.child = true; - agentCircuit.Appearance = sp.Appearance; + +// agentCircuit.Appearance = sp.Appearance; +// agentCircuit.Appearance = new AvatarAppearance(sp.Appearance, true, false); + agentCircuit.Appearance = new AvatarAppearance(); + agentCircuit.Appearance.AvatarHeight = sp.Appearance.AvatarHeight; + if (currentAgentCircuit != null) { agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs; @@ -971,7 +980,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } // May need to logout or other cleanup - AgentHasMovedAway(sp, logout); +// AgentHasMovedAway(sp, logout); + AgentHasMovedAway(sp, true); // until logout use is checked // Well, this is it. The agent is over there. KillEntity(sp.Scene, sp.LocalId); @@ -1138,7 +1148,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.CloseChildAgents(newRegionX, newRegionY); // May need to logout or other cleanup - AgentHasMovedAway(sp, logout); +// AgentHasMovedAway(sp, logout); + AgentHasMovedAway(sp, true); // Well, this is it. The agent is over there. KillEntity(sp.Scene, sp.LocalId); @@ -1253,7 +1264,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout) { if (sp.Scene.AttachmentsModule != null) - sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, true); + sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, logout); } protected void KillEntity(Scene scene, uint localID) @@ -1381,10 +1392,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #region Agent Crossings - public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos) + { + string r = String.Empty; + return GetDestination(scene, agentID, pos, out xDest, out yDest, out version, out newpos, out r); + } + + public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos, out string reason) { version = String.Empty; + reason = String.Empty; newpos = pos; // m_log.DebugFormat( @@ -1498,8 +1515,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); - - string reason; + if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason)) { if (r == null) @@ -1525,11 +1541,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer uint y; Vector3 newpos; string version; + string reason; - GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos); + GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos, out reason); if (neighbourRegion == null) { - agent.ControllingClient.SendAlertMessage("Cannot region cross into void"); + if (reason == String.Empty) + agent.ControllingClient.SendAlertMessage("Cannot cross to region"); + else + agent.ControllingClient.SendAlertMessage("Cannot cross to region: " + reason); return false; } @@ -1656,10 +1676,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying) { + int ts = Util.EnvironmentTickCount(); try { + AgentData cAgent = new AgentData(); agent.CopyTo(cAgent); + +// agent.Appearance.WearableCacheItems = null; + cAgent.Position = pos + agent.Velocity; if (isFlying) cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; @@ -1686,6 +1711,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return false; } + m_log.DebugFormat("[CrossAgentIntoNewRegionMain] ok, time {0}ms",Util.EnvironmentTickCountSubtract(ts)); + } catch (Exception e) { @@ -1703,6 +1730,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version) { + agent.ControllingClient.RequestClientInfo(); string agentcaps; @@ -1714,6 +1742,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } // No turning back + + + agent.IsChildAgent = true; string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); @@ -1737,12 +1768,25 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer capsPath); } + // Backwards compatibility. Best effort + if (version == "Unknown" || version == string.Empty) + { + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); + Thread.Sleep(3000); // wait a little now that we're not waiting for the callback + CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); + } + // SUCCESS! m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); + // this may need the attachments + agent.parcelRegionCross(); + + AgentHasMovedAway(agent, true); + agent.MakeChildAgent(); // FIXME: Possibly this should occur lower down after other commands to close other agents, @@ -1756,16 +1800,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // agent.SendOtherAgentsAvatarDataToMe(); // agent.SendOtherAgentsAppearanceToMe(); - agent.parcelRegionCross(false); - - // Backwards compatibility. Best effort - if (version == "Unknown" || version == string.Empty) - { - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); - Thread.Sleep(3000); // wait a little now that we're not waiting for the callback - CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); - } - // Next, let's close the child agent connections that are too far away. uint neighbourx; uint neighboury; @@ -1777,7 +1811,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agent.CloseChildAgents(neighbourx, neighboury); - AgentHasMovedAway(agent, false); + // the user may change their profile information in other region, // so the userinfo in UserProfileCache is not reliable any more, delete it @@ -1817,7 +1851,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #region Enable Child Agent /// - /// This informs a single neighbouring region about agent "avatar". + /// This informs a single neighbouring region about agent "avatar", and avatar about it /// Calls an asynchronous method to do so.. so it doesn't lag the sim. /// /// @@ -1833,8 +1867,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agent.startpos = new Vector3(128, 128, 70); agent.child = true; - //agent.Appearance = sp.Appearance; - agent.Appearance = new AvatarAppearance(sp.Appearance, true, false); // guess this should be a lot less + agent.Appearance = new AvatarAppearance(); + agent.Appearance.AvatarHeight = sp.Appearance.AvatarHeight; agent.CapsPath = CapsUtil.GetRandomCapsObjectPath(); @@ -1866,6 +1900,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agent.Id0 = currentAgentCircuit.Id0; } + Thread.Sleep(200); // the original delay that was at InformClientOfNeighbourAsync start + IPEndPoint external = region.ExternalEndPoint; if (external != null) { @@ -1884,6 +1920,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// /// This informs all neighbouring regions about agent "avatar". + /// and as important informs the avatar about then /// /// public void EnableChildAgents(ScenePresence sp) @@ -1900,81 +1937,77 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.Debug("[ENTITY TRANSFER MODULE]: m_regionInfo was null in EnableChildAgents, is this a NPC?"); } - /// We need to find the difference between the new regions where there are no child agents - /// and the regions where there are already child agents. We only send notification to the former. - List neighbourHandles = NeighbourHandles(neighbours); // on this region - neighbourHandles.Add(sp.Scene.RegionInfo.RegionHandle); // add this region too - List previousRegionNeighbourHandles; + LinkedList previousRegionNeighbourHandles; - if (sp.Scene.CapsModule != null) - { - previousRegionNeighbourHandles = - new List(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID).Keys); - } - else - { - previousRegionNeighbourHandles = new List(); - } - - List newRegions = NewNeighbours(neighbourHandles, previousRegionNeighbourHandles); - List oldRegions = OldNeighbours(neighbourHandles, previousRegionNeighbourHandles); - -// Dump("Current Neighbors", neighbourHandles); -// Dump("Previous Neighbours", previousRegionNeighbourHandles); -// Dump("New Neighbours", newRegions); -// Dump("Old Neighbours", oldRegions); - - /// Update the scene presence's known regions here on this region - sp.DropOldNeighbours(oldRegions); - - /// Collect as many seeds as possible Dictionary seeds; - if (sp.Scene.CapsModule != null) - seeds = new Dictionary(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID)); - else - seeds = new Dictionary(); - //m_log.Debug(" !!! No. of seeds: " + seeds.Count); + if (sp.Scene.CapsModule != null) + { + seeds = new Dictionary(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID)); + previousRegionNeighbourHandles = new LinkedList(seeds.Keys); + } + else + { + seeds = new Dictionary(); + previousRegionNeighbourHandles = new LinkedList(); + } + if (!seeds.ContainsKey(sp.Scene.RegionInfo.RegionHandle)) seeds.Add(sp.Scene.RegionInfo.RegionHandle, sp.ControllingClient.RequestClientInfo().CapsPath); - /// Create the necessary child agents + AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); + + List newneighbours = new List(); List cagents = new List(); + + ulong currentRegionHandler = sp.Scene.RegionInfo.RegionHandle; + foreach (GridRegion neighbour in neighbours) { - if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) + ulong handler = neighbour.RegionHandle; + + if (handler == currentRegionHandler) + continue; + + AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); + agent.BaseFolder = UUID.Zero; + agent.InventoryFolder = UUID.Zero; + agent.startpos = sp.AbsolutePosition + CalculateOffset(sp, neighbour); + agent.child = true; + agent.Appearance = new AvatarAppearance(); + agent.Appearance.AvatarHeight = sp.Appearance.AvatarHeight; + + if (currentAgentCircuit != null) { - AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); - AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); - agent.BaseFolder = UUID.Zero; - agent.InventoryFolder = UUID.Zero; - agent.startpos = sp.AbsolutePosition + CalculateOffset(sp, neighbour); - agent.child = true; - // agent.Appearance = sp.Appearance; - agent.Appearance = new AvatarAppearance(sp.Appearance, true, false); // guess this should be a lot less - if (currentAgentCircuit != null) - { - agent.ServiceURLs = currentAgentCircuit.ServiceURLs; - agent.IPAddress = currentAgentCircuit.IPAddress; - agent.Viewer = currentAgentCircuit.Viewer; - agent.Channel = currentAgentCircuit.Channel; - agent.Mac = currentAgentCircuit.Mac; - agent.Id0 = currentAgentCircuit.Id0; - } - - if (newRegions.Contains(neighbour.RegionHandle)) - { - agent.CapsPath = CapsUtil.GetRandomCapsObjectPath(); - sp.AddNeighbourRegion(neighbour.RegionHandle, agent.CapsPath); - seeds.Add(neighbour.RegionHandle, agent.CapsPath); - } - else - { - agent.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, neighbour.RegionHandle); - } - - cagents.Add(agent); + agent.ServiceURLs = currentAgentCircuit.ServiceURLs; + agent.IPAddress = currentAgentCircuit.IPAddress; + agent.Viewer = currentAgentCircuit.Viewer; + agent.Channel = currentAgentCircuit.Channel; + agent.Mac = currentAgentCircuit.Mac; + agent.Id0 = currentAgentCircuit.Id0; } + + if (previousRegionNeighbourHandles.Contains(handler)) + { + previousRegionNeighbourHandles.Remove(handler); + agent.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, handler); + } + else + { + newneighbours.Add(handler); + agent.CapsPath = CapsUtil.GetRandomCapsObjectPath(); + sp.AddNeighbourRegion(handler, agent.CapsPath); + seeds.Add(handler, agent.CapsPath); + } + + cagents.Add(agent); + } + + //sp.DropOldNeighbours(previousRegionNeighbourHandles); + foreach (ulong handle in previousRegionNeighbourHandles) + { + sp.RemoveNeighbourRegion(handle); + Scene.CapsModule.DropChildSeed(sp.UUID, handle); } /// Update all child agent with everyone's seeds @@ -1987,34 +2020,23 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { sp.Scene.CapsModule.SetChildrenSeed(sp.UUID, seeds); } + sp.KnownRegions = seeds; //avatar.Scene.DumpChildrenSeeds(avatar.UUID); //avatar.DumpKnownRegions(); - bool newAgent = false; - int count = 0; - foreach (GridRegion neighbour in neighbours) + Util.FireAndForget(delegate { - //m_log.WarnFormat("--> Going to send child agent to {0}", neighbour.RegionName); - // Don't do it if there's already an agent in that region - if (newRegions.Contains(neighbour.RegionHandle)) - newAgent = true; - else - newAgent = false; -// continue; + Thread.Sleep(200); // the original delay that was at InformClientOfNeighbourAsync start + int count = 0; + bool newagent; - if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) + foreach (GridRegion neighbour in neighbours) { try { - // Let's put this back at sync, so that it doesn't clog - // the network, especially for regions in the same physical server. - // We're really not in a hurry here. - InformClientOfNeighbourAsync(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent); - //InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; - //d.BeginInvoke(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent, - // InformClientOfNeighbourCompleted, - // d); + newagent = newneighbours.Contains(neighbour.RegionHandle); + InformClientOfNeighbourAsync(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newagent); } catch (ArgumentOutOfRangeException) @@ -2022,9 +2044,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.ErrorFormat( "[ENTITY TRANSFER MODULE]: Neighbour Regions response included the current region in the neighbour list. The following region will not display to the client: {0} for region {1} ({2}, {3}).", neighbour.ExternalHostName, - neighbour.RegionHandle, - neighbour.RegionLocX, - neighbour.RegionLocY); + neighbour.RegionHandle, + neighbour.RegionLocX, + neighbour.RegionLocY); } catch (Exception e) { @@ -2041,11 +2063,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // XXX: Well, decided to swallow the exception instead for now. Let us see how that goes. // throw e; - } + count++; } - count++; - } + }); } Vector3 CalculateOffset(ScenePresence sp, GridRegion neighbour) @@ -2079,11 +2100,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer private void InformClientOfNeighbourAsync(ScenePresence sp, AgentCircuitData a, GridRegion reg, IPEndPoint endPoint, bool newAgent) { - // Let's wait just a little to give time to originating regions to catch up with closing child agents - // after a cross here - Thread.Sleep(500); - - Scene scene = sp.Scene; + Scene scene = sp.Scene; + if (!newAgent) + return; m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Informing {0} {1} about neighbour {2} {3} at ({4},{5})", @@ -2097,6 +2116,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (regionAccepted && newAgent) { + // give time for createAgent to finish, since it is async and does grid services access + Thread.Sleep(500); + if (m_eqModule != null) { #region IP Translation for NAT diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index ecd6a09a9b..668087f6b3 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -557,6 +557,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation /// public void SendAnimPack(UUID[] animations, int[] seqs, UUID[] objectIDs) { +/* if (m_scenePresence.IsChildAgent) return; @@ -571,6 +572,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation { client.SendAnimations(animations, seqs, m_scenePresence.ControllingClient.AgentId, objectIDs); }); + */ + m_scenePresence.SendAnimPack(animations, seqs, objectIDs); } public void SendAnimPackToClient(IClientAPI client) @@ -602,7 +605,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs); - SendAnimPack(animIDs, sequenceNums, objectIDs); +// SendAnimPack(animIDs, sequenceNums, objectIDs); + m_scenePresence.SendAnimPack(animIDs, sequenceNums, objectIDs); } public string GetAnimName(UUID animId) diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index ddae0735fc..19d268943a 100644 --- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs @@ -91,6 +91,11 @@ namespace OpenSim.Region.Framework.Scenes return 0; uint priority; + + + // HACK + return GetPriorityByBestAvatarResponsiveness(client, entity); + switch (m_scene.UpdatePrioritizationScheme) { @@ -157,30 +162,31 @@ namespace OpenSim.Region.Framework.Scenes private uint GetPriorityByBestAvatarResponsiveness(IClientAPI client, ISceneEntity entity) { - uint pqueue = ComputeDistancePriority(client,entity,false); + uint pqueue = 2; // keep compiler happy ScenePresence presence = m_scene.GetScenePresence(client.AgentId); if (presence != null) { - if (!presence.IsChildAgent) - { - // All avatars other than our own go into pqueue 1 - if (entity is ScenePresence) - return 1; - - if (entity is SceneObjectPart) - { - // Attachments are high priority, - if (((SceneObjectPart)entity).ParentGroup.IsAttachment) - return 1; + // All avatars other than our own go into pqueue 1 + if (entity is ScenePresence) + return 1; - // Non physical prims are lower priority than physical prims - PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor; - if (physActor == null || !physActor.IsPhysical) - pqueue++; - } + if (entity is SceneObjectPart) + { + // Attachments are high priority, + if (((SceneObjectPart)entity).ParentGroup.IsAttachment) + return 1; + + pqueue = ComputeDistancePriority(client, entity, false); + + // Non physical prims are lower priority than physical prims + PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor; + if (physActor == null || !physActor.IsPhysical) + pqueue++; } } + else + pqueue = ComputeDistancePriority(client, entity, false); return pqueue; } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 0f67d07881..a0c3ba985c 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1400,7 +1400,7 @@ namespace OpenSim.Region.Framework.Scenes else Animator.ResetAnimations(); - + // m_log.DebugFormat( // "[SCENE PRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", // Name, UUID, m_scene.RegionInfo.RegionName); @@ -1754,7 +1754,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void CompleteMovement(IClientAPI client, bool openChildAgents) { -// DateTime startTime = DateTime.Now; + int ts = Util.EnvironmentTickCount(); m_log.InfoFormat( "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}", @@ -1767,6 +1767,7 @@ namespace OpenSim.Region.Framework.Scenes // Make sure it's not a login agent. We don't want to wait for updates during login if (!isNPC && (m_teleportFlags & TeleportFlags.ViaLogin) == 0) { + // Let's wait until UpdateAgent (called by departing region) is done if (!WaitForUpdateAgent(client)) // The sending region never sent the UpdateAgent data, we have to refuse @@ -1786,6 +1787,9 @@ namespace OpenSim.Region.Framework.Scenes AbsolutePosition = pos; } */ + + m_log.DebugFormat("[CompleteMovement] WaitForUpdateAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); if (!MakeRootAgent(AbsolutePosition, flying)) { @@ -1796,6 +1800,8 @@ namespace OpenSim.Region.Framework.Scenes return; } + m_log.DebugFormat("[CompleteMovement] MakeRootAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + Vector3 look = Lookat; if ((Math.Abs(look.X) < 0.01) && (Math.Abs(look.Y) < 0.01)) { @@ -1806,6 +1812,17 @@ namespace OpenSim.Region.Framework.Scenes look = new Vector3(0.99f, 0.042f, 0); } + if (!IsChildAgent) + { + InventoryFolderBase cof = m_scene.InventoryService.GetFolderForType(client.AgentId, (AssetType)46); + if (cof == null) + COF = UUID.Zero; + else + COF = cof.ID; + + m_log.DebugFormat("[ScenePresence]: CompleteMovement COF for {0} is {1}", client.AgentId, COF); + } + // Tell the client that we're totally ready ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); @@ -1816,6 +1833,8 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat("[SCENE PRESENCE] Completed movement"); + m_log.DebugFormat("[CompleteMovement] MoveAgentIntoRegion: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + if (!string.IsNullOrEmpty(m_callbackURI)) { // We cannot sleep here since this would hold up the inbound packet processing thread, as @@ -1844,6 +1863,8 @@ namespace OpenSim.Region.Framework.Scenes // client.Name, client.AgentId, m_scene.RegionInfo.RegionName); // } + m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + m_previusParcelHide = false; m_previusParcelUUID = UUID.Zero; m_currentParcelHide = false; @@ -1856,15 +1877,12 @@ namespace OpenSim.Region.Framework.Scenes if (!IsChildAgent) { - newhide = m_currentParcelHide; - m_currentParcelHide = false; - // take this region out of children Neighbours list - // possible should be done elsewhere - DropThisRootRegionFromNeighbours(); ValidateAndSendAppearanceAndAgentData(); + m_log.DebugFormat("[CompleteMovement] ValidateAndSendAppearanceAndAgentData: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + // attachments if (isNPC || (TeleportFlags & TeleportFlags.ViaLogin) != 0) { @@ -1877,23 +1895,46 @@ namespace OpenSim.Region.Framework.Scenes } else { - List attachments = GetAttachments(); - - if (attachments.Count > 0) + if (m_attachments.Count > 0) { m_log.DebugFormat( "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); + List kk = new List(); + // Resume scripts this possible should also be moved down after sending the avatar to viewer ? - foreach (SceneObjectGroup sog in attachments) + foreach (SceneObjectGroup sog in m_attachments) { - sog.ScheduleGroupForFullUpdate(); + foreach (SceneObjectPart part in sog.Parts) + kk.Add(part.LocalId); + + sog.SendFullUpdateToClient(ControllingClient); + SendFullUpdateToClient(ControllingClient); + + // sog.ScheduleGroupForFullUpdate(); + m_scene.ForEachScenePresence(delegate(ScenePresence p) + { + if (p == this) + return; + if (sog.HasPrivateAttachmentPoint) + return; + if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200) + return; + + p.ControllingClient.SendKillObject(kk); + sog.SendFullUpdateToClient(p.ControllingClient); + SendFullUpdateToClient(p.ControllingClient); // resend our data by updates path + }); + sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); sog.ResumeScripts(); + kk.Clear(); } } } + m_log.DebugFormat("[CompleteMovement] attachments: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + // Create child agents in neighbouring regions if (openChildAgents) { @@ -1903,10 +1944,14 @@ namespace OpenSim.Region.Framework.Scenes } } + m_log.DebugFormat("[CompleteMovement] openChildAgents: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + // send the rest of the world - if (m_teleportFlags > 0 && !isNPC) + if (m_teleportFlags > 0 && !isNPC || m_currentParcelHide) SendInitialDataToMe(); + m_log.DebugFormat("[CompleteMovement] SendInitialDataToMe: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + if (!IsChildAgent) { // moved from makeroot missing in sendInitialDataToMe @@ -1923,6 +1968,8 @@ namespace OpenSim.Region.Framework.Scenes IFriendsModule friendsModule = m_scene.RequestModuleInterface(); if (friendsModule != null) friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); + + m_log.DebugFormat("[CompleteMovement] friendsModule: {0}ms", Util.EnvironmentTickCountSubtract(ts)); } } } @@ -1931,11 +1978,13 @@ namespace OpenSim.Region.Framework.Scenes m_inTransit = false; } // if hide force a check - if (!IsChildAgent && newhide) - { - ParcelLoginCheck(m_currentParcelUUID); - m_currentParcelHide = newhide; - } + // if (!IsChildAgent && newhide) + // { + // ParcelLoginCheck(m_currentParcelUUID); + // m_currentParcelHide = newhide; + // } + + m_log.DebugFormat("[CompleteMovement] end: {0}ms", Util.EnvironmentTickCountSubtract(ts)); } /// @@ -2776,34 +2825,15 @@ namespace OpenSim.Region.Framework.Scenes if (satOnObject) { -// SendAvatarDataToAllAgents(); m_requestedSitTargetID = 0; - part.RemoveSittingAvatar(UUID); - part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); - } - else if (PhysicsActor == null) - AddToPhysicalScene(false); + SendAvatarDataToAllAgents(); + } Animator.TrySetMovementAnimation("STAND"); - if (satOnObject) - { - ILandObject land = m_scene.LandChannel.GetLandObject(AbsolutePosition.X,AbsolutePosition.Y); - if (land != null) - { - UUID parcelID = land.LandData.GlobalID; - if (m_currentParcelUUID != parcelID) - currentParcelUUID = parcelID; - else - SendAvatarDataToAllAgents(); - } - else - SendAvatarDataToAllAgents(); - } - TriggerScenePresenceUpdated(); } @@ -3078,11 +3108,14 @@ namespace OpenSim.Region.Framework.Scenes ParentPart = part; ParentID = part.LocalId; + + SendAvatarDataToAllAgents(); + if(status == 3) Animator.TrySetMovementAnimation("SIT_GROUND"); else Animator.TrySetMovementAnimation("SIT"); - SendAvatarDataToAllAgents(); + part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); } @@ -3182,13 +3215,14 @@ namespace OpenSim.Region.Framework.Scenes Velocity = Vector3.Zero; RemoveFromPhysicalScene(); + SendAvatarDataToAllAgents(); + String sitAnimation = "SIT"; if (!String.IsNullOrEmpty(part.SitAnimation)) { sitAnimation = part.SitAnimation; } Animator.TrySetMovementAnimation(sitAnimation); - SendAvatarDataToAllAgents(); TriggerScenePresenceUpdated(); } } @@ -3349,8 +3383,30 @@ namespace OpenSim.Region.Framework.Scenes #region Update Client(s) + public void SendUpdateToAgent(ScenePresence p) + { + IClientAPI remoteClient = p.ControllingClient; + + if (remoteClient.IsActive) + { + //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity); + remoteClient.SendEntityUpdate(this, PrimUpdateFlags.FullUpdate); + m_scene.StatsReporter.AddAgentUpdates(1); + } + } + + public void SendFullUpdateToClient(IClientAPI remoteClient) + { + if (remoteClient.IsActive) + { + //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity); + remoteClient.SendEntityUpdate(this, PrimUpdateFlags.FullUpdate); + m_scene.StatsReporter.AddAgentUpdates(1); + } + } + // this is diferente from SendTerseUpdateToClient - // this sends bypassing ententies updates + // this sends bypassing entities updates public void SendAgentTerseUpdate(ISceneEntity p) { ControllingClient.SendAgentTerseUpdate(p); @@ -3377,7 +3433,7 @@ namespace OpenSim.Region.Framework.Scenes } } - public void SendTerseUpdateToAgentClient(ScenePresence p) + public void SendTerseUpdateToAgent(ScenePresence p) { IClientAPI remoteClient = p.ControllingClient; @@ -3396,6 +3452,18 @@ namespace OpenSim.Region.Framework.Scenes m_scene.StatsReporter.AddAgentUpdates(1); } + public void SendTerseUpdateToAgentNF(ScenePresence p) + { + IClientAPI remoteClient = p.ControllingClient; + if (remoteClient.IsActive) + { + //m_log.DebugFormat("[SCENE PRESENCE]: " + Name + " sending TerseUpdate to " + remoteClient.Name + " : Pos={0} Rot={1} Vel={2}", m_pos, Rotation, m_velocity); + remoteClient.SendEntityUpdate(this, PrimUpdateFlags.FullUpdate); + m_scene.StatsReporter.AddAgentUpdates(1); + } + } + + // vars to support reduced update frequency when velocity is unchanged private Vector3 lastVelocitySentToAllClients = Vector3.Zero; private Vector3 lastPositionSentToAllClients = Vector3.Zero; @@ -3437,7 +3505,7 @@ namespace OpenSim.Region.Framework.Scenes // Console.WriteLine("Scheduled update for {0} in {1}", Name, Scene.Name); // m_scene.ForEachClient(SendTerseUpdateToClient); - m_scene.ForEachScenePresence(SendTerseUpdateToAgentClient); + m_scene.ForEachScenePresence(SendTerseUpdateToAgent); } TriggerScenePresenceUpdated(); } @@ -3478,8 +3546,8 @@ namespace OpenSim.Region.Framework.Scenes landch.sendClientInitialLandInfo(ControllingClient); } } - SendOtherAgentsAvatarDataToMe(); - SendOtherAgentsAppearanceToMe(); + + SendOtherAgentsAvatarFullToMe(); EntityBase[] entities = Scene.Entities.GetEntities(); foreach (EntityBase e in entities) @@ -3508,40 +3576,56 @@ namespace OpenSim.Region.Framework.Scenes // to see if all the baked textures are already here. if (m_scene.AvatarFactory != null) cachedappearance = m_scene.AvatarFactory.ValidateBakedTextureCache(this); - + // If we aren't using a cached appearance, then clear out the baked textures if (!cachedappearance) { -// Appearance.ResetAppearance(); -// save what ???? -// maybe needed so the tryretry repair works? if (m_scene.AvatarFactory != null) m_scene.AvatarFactory.QueueAppearanceSave(UUID); } + bool newhide = m_currentParcelHide; + m_currentParcelHide = false; - // This agent just became root. We are going to tell everyone about it. The process of - // getting other avatars information was initiated elsewhere immediately after the child circuit connected... don't do it - // again here... this comes after the cached appearance check because the avatars - // appearance goes into the avatar update packet SendAvatarDataToAllAgents(); - // This invocation always shows up in the viewer logs as an error. Is it needed? - // send all information we have - // possible not needed since viewer should ask about it - // least it all ask for baked + if (newhide) + { + ParcelLoginCheck(m_currentParcelUUID); + m_currentParcelHide = true; + } + SendAppearanceToAgent(this); - // If we are using the the cached appearance then send it out to everyone - // send even grays - if (cachedappearance) +// if (cachedappearance) +// { + SendAppearanceToAllOtherAgents(); +// } + if(Animator!= null) + Animator.SendAnimPack(); + } + + /// + /// Send avatar full data appearance and animations for all other root agents to this agent, this agent + /// can be either a child or root + /// + public void SendOtherAgentsAvatarFullToMe() + { + int count = 0; + m_scene.ForEachRootScenePresence(delegate(ScenePresence scenePresence) { -// m_log.DebugFormat("[SCENE PRESENCE]: Baked textures are in the cache for {0} in {1}", Name, m_scene.Name); - // If the avatars baked textures are all in the cache, then we have a - // complete appearance... send it out, if not, then we'll send it when - // the avatar finishes updating its appearance - SendAppearanceToAllOtherAgents(); - } + // only send information about other root agents + if (scenePresence.UUID == UUID) + return; + + scenePresence.SendAvatarDataToAgent(this); + scenePresence.SendAppearanceToAgent(this); + scenePresence.SendAnimPackToAgent(this); + // for now attachments are sent with all SOG + count++; + }); + + m_scene.StatsReporter.AddAgentUpdates(count); } /// @@ -3566,33 +3650,12 @@ namespace OpenSim.Region.Framework.Scenes m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) { - SendAvatarDataToAgent(scenePresence); - count++; + SendAvatarDataToAgent(scenePresence); + count++; }); m_scene.StatsReporter.AddAgentUpdates(count); } - - /// - /// Send avatar data for all other root agents to this agent, this agent - /// can be either a child or root - /// - public void SendOtherAgentsAvatarDataToMe() - { - int count = 0; - - m_scene.ForEachRootScenePresence(delegate(ScenePresence scenePresence) - { - // only send information about other root agents - if (scenePresence.UUID == UUID) - return; - - scenePresence.SendAvatarDataToAgent(this); - count++; - }); - - m_scene.StatsReporter.AddAgentUpdates(count); - } /// /// Send avatar data to an agent. @@ -3604,7 +3667,11 @@ namespace OpenSim.Region.Framework.Scenes if (ParcelHideThisAvatar && currentParcelUUID != avatar.currentParcelUUID && avatar.GodLevel < 200) return; avatar.ControllingClient.SendAvatarDataImmediate(this); - Animator.SendAnimPackToClient(avatar.ControllingClient); + } + + public void SendAvatarDataToAgentNF(ScenePresence avatar) + { + avatar.ControllingClient.SendAvatarDataImmediate(this); } /// @@ -3638,28 +3705,6 @@ namespace OpenSim.Region.Framework.Scenes m_scene.StatsReporter.AddAgentUpdates(count); } - /// - /// Send appearance from all other root agents to this agent. this agent - /// can be either root or child - /// - public void SendOtherAgentsAppearanceToMe() - { -// m_log.DebugFormat("[SCENE PRESENCE] SendOtherAgentsAppearanceToMe: {0} {1}", Name, UUID); - - int count = 0; - m_scene.ForEachRootScenePresence(delegate(ScenePresence scenePresence) - { - // only send information about other root agents - if (scenePresence.UUID == UUID) - return; - - scenePresence.SendAppearanceToAgent(this); - count++; - }); - - m_scene.StatsReporter.AddAgentUpdates(count); - } - /// /// Send appearance data to an agent. /// @@ -3674,6 +3719,30 @@ namespace OpenSim.Region.Framework.Scenes UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); } + public void SendAnimPackToAgent(ScenePresence p) + { + if (IsChildAgent || Animator == null) + return; + + if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200) + return; + + Animator.SendAnimPackToClient(p.ControllingClient); + } + + public void SendAnimPack(UUID[] animations, int[] seqs, UUID[] objectIDs) + { + if (IsChildAgent) + return; + + m_scene.ForEachScenePresence(delegate(ScenePresence p) + { + if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200) + return; + p.ControllingClient.SendAnimations(animations, seqs, ControllingClient.AgentId, objectIDs); + }); + } + #endregion #region Significant Movement Method @@ -4193,13 +4262,15 @@ namespace OpenSim.Region.Framework.Scenes } catch { } + Animator.ResetAnimations(); + // FIXME: Why is this null check necessary? Where are the cases where we get a null Anims object? - if (cAgent.Anims != null) - Animator.Animations.FromArray(cAgent.Anims); if (cAgent.DefaultAnim != null) Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero); if (cAgent.AnimState != null) Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero); + if (cAgent.Anims != null) + Animator.Animations.FromArray(cAgent.Anims); if (Scene.AttachmentsModule != null) Scene.AttachmentsModule.CopyAttachments(cAgent, this); @@ -4653,18 +4724,186 @@ namespace OpenSim.Region.Framework.Scenes return validated; } - - public void SendAttachmentsToClient(IClientAPI client) + public void SendAttachmentsToAllAgents() { lock (m_attachments) { - foreach (SceneObjectGroup gobj in m_attachments) + foreach (SceneObjectGroup sog in m_attachments) { - gobj.SendFullUpdateToClient(client); + m_scene.ForEachScenePresence(delegate(ScenePresence p) + { + if (p != this && sog.HasPrivateAttachmentPoint) + return; + if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200) + return; + sog.SendFullUpdateToClient(p.ControllingClient); + SendFullUpdateToClient(p.ControllingClient); // resend our data by updates path + }); } } } + // send attachments to a client without filters except for huds + // for now they are checked in several places down the line... + public void SendAttachmentsToAgentNF(ScenePresence p) + { + lock (m_attachments) + { + foreach (SceneObjectGroup sog in m_attachments) + { + if (p == this || !sog.HasPrivateAttachmentPoint) + sog.SendFullUpdateToClient(p.ControllingClient); + } + SendFullUpdateToClient(p.ControllingClient); // resend our data by updates path + } + } + + public void SendAttachmentsToAgentNFPK(ScenePresence p) + { + lock (m_attachments) + { + List pk = new List(); + foreach (SceneObjectGroup sog in m_attachments) + { + foreach (SceneObjectPart part in sog.Parts) + pk.Add(part.LocalId); + } + + p.ControllingClient.SendKillObject(pk); + + foreach (SceneObjectGroup sog in m_attachments) + { + if (p == this || !sog.HasPrivateAttachmentPoint) + sog.SendFullUpdateToClient(p.ControllingClient); + } + SendFullUpdateToClient(p.ControllingClient); // resend our data by updates path + } + } + + + public void SendAttachmentScheduleUpdate(SceneObjectGroup sog) + { + if (IsChildAgent) + return; + + m_scene.ForEachScenePresence(delegate(ScenePresence p) + { + if (p != this && sog.HasPrivateAttachmentPoint) + return; + if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200) + return; + + SceneObjectPart[] parts = sog.Parts; + + for (int i = 0; i < parts.Length; i++) + { + SceneObjectPart part = parts[i]; + if (part.UpdateFlag == UpdateRequired.TERSE) + { + p.ControllingClient.SendEntityUpdate(part, + PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity + | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); + part.UpdateFlag = 0; + } + else if (part.UpdateFlag == UpdateRequired.FULL) + { + p.ControllingClient.SendEntityUpdate(part, PrimUpdateFlags.FullUpdate); + part.UpdateFlag = 0; + } + } + }); + } + + public void SendAttachmentScheduleUpdate(SceneObjectPart part) + { + if (IsChildAgent) + return; + + m_scene.ForEachScenePresence(delegate(ScenePresence p) + { + if (p != this && part.ParentGroup.HasPrivateAttachmentPoint) + return; + + if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200) + return; + + if (part.UpdateFlag == UpdateRequired.TERSE) + { + p.ControllingClient.SendEntityUpdate(part, + PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity + | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); + part.UpdateFlag = 0; + } + else if (part.UpdateFlag == UpdateRequired.FULL) + { + p.ControllingClient.SendEntityUpdate(part, PrimUpdateFlags.FullUpdate); + part.UpdateFlag = 0; + } + }); + } + + public void SendAttachmentUpdate(SceneObjectGroup sog, UpdateRequired UpdateFlag) + { + if (IsChildAgent) + return; + + m_scene.ForEachScenePresence(delegate(ScenePresence p) + { + if (p != this && sog.HasPrivateAttachmentPoint) + return; + + if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200) + return; + + SceneObjectPart[] parts = sog.Parts; + + for (int i = 0; i < parts.Length; i++) + { + SceneObjectPart part = parts[i]; + if (UpdateFlag == UpdateRequired.TERSE) + { + p.ControllingClient.SendEntityUpdate(part, + PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity + | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); + part.UpdateFlag = 0; + } + else if (UpdateFlag == UpdateRequired.FULL) + { + p.ControllingClient.SendEntityUpdate(part, PrimUpdateFlags.FullUpdate); + part.UpdateFlag = 0; + } + } + }); + } + + public void SendAttachmentUpdate(SceneObjectPart part, UpdateRequired UpdateFlag) + { + if (IsChildAgent) + return; + + m_scene.ForEachScenePresence(delegate(ScenePresence p) + { + if (p != this && part.ParentGroup.HasPrivateAttachmentPoint) + return; + + if (ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && p.GodLevel < 200) + return; + + if (UpdateFlag == UpdateRequired.TERSE) + { + p.ControllingClient.SendEntityUpdate(part, + PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity + | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); + part.UpdateFlag = 0; + } + else if (UpdateFlag == UpdateRequired.FULL) + { + p.ControllingClient.SendEntityUpdate(part, PrimUpdateFlags.FullUpdate); + part.UpdateFlag = 0; + } + }); + } + /// /// Send a script event to this scene presence's attachments /// @@ -5436,12 +5675,12 @@ namespace OpenSim.Region.Framework.Scenes { if (p.IsChildAgent) continue; - m_log.Debug("[AVATAR]: viewMe: " + Lastname + " " + p.Lastname); - ControllingClient.SendAvatarDataImmediate(p); + + p.SendAvatarDataToAgentNF(this); p.SendAppearanceToAgent(this); - p.SendAttachmentsToClient(ControllingClient); if (p.Animator != null) p.Animator.SendAnimPackToClient(ControllingClient); + p.SendAttachmentsToAgentNFPK(this); } } } @@ -5476,7 +5715,7 @@ namespace OpenSim.Region.Framework.Scenes private void ParcelLoginCheck(UUID currentParcelID) { List killsToSendto = new List(); - List killsToSendme = new List(); + List killsToSendme = new List(); List viewsToSendto = new List(); List viewsToSendme = new List(); List allpresences = null; @@ -5492,8 +5731,8 @@ namespace OpenSim.Region.Framework.Scenes { if (p.GodLevel < 200) killsToSendto.Add(p); - if (GodLevel < 200 && p.ParcelHideThisAvatar) - killsToSendme.Add(p); +// if (GodLevel < 200 && p.ParcelHideThisAvatar) +// killsToSendme.Add(p.LocalId); } else { @@ -5517,14 +5756,15 @@ namespace OpenSim.Region.Framework.Scenes if (killsToSendme.Count > 0) { - foreach (ScenePresence p in killsToSendme) + m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + killsToSendme.Count.ToString()); + try { - m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); - try { ControllingClient.SendKillObject(new List { p.LocalId }); } - catch (NullReferenceException) { } + ControllingClient.SendKillObject(killsToSendme); } - } + catch (NullReferenceException) { } + } +/* if (viewsToSendto.Count > 0 && PresenceType != PresenceType.Npc) { foreach (ScenePresence p in viewsToSendto) @@ -5552,81 +5792,46 @@ namespace OpenSim.Region.Framework.Scenes p.Animator.SendAnimPackToClient(ControllingClient); } } +*/ } - public void parcelRegionCross(bool abort) + + public void parcelRegionCross() { - if (!ParcelHideThisAvatar) + if (!ParcelHideThisAvatar || GodLevel >= 200) return; List allpresences = null; allpresences = m_scene.GetScenePresences(); - if (abort) + List killsToSendme = new List(); + + foreach (ScenePresence p in allpresences) { - List viewsToSendme = new List(); + if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive) + continue; - foreach (ScenePresence p in allpresences) + if (p.currentParcelUUID == m_currentParcelUUID) { - if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive) - continue; - - if (p.currentParcelUUID == m_currentParcelUUID) - { - viewsToSendme.Add(p); - } - } - - if (viewsToSendme.Count > 0) - { - foreach (ScenePresence p in viewsToSendme) - { - if (p.IsChildAgent) - continue; -// m_log.Debug("[AVATAR]: viewMe: " + Lastname + " " + p.Lastname); - ControllingClient.SendAvatarDataImmediate(p); - p.SendAppearanceToAgent(this); - p.SendAttachmentsToClient(ControllingClient); - if (p.Animator != null) - p.Animator.SendAnimPackToClient(ControllingClient); - } + killsToSendme.Add(p.LocalId); } } - else + + if (killsToSendme.Count > 0) { - if (GodLevel >= 200) - return; - - List killsToSendme = new List(); - foreach (ScenePresence p in allpresences) + try { - if (p.IsDeleted || p == this || p.ControllingClient == null || !p.ControllingClient.IsActive) - continue; - - if (p.currentParcelUUID == m_currentParcelUUID) - { - killsToSendme.Add(p); - } - } - - if (killsToSendme.Count > 0) - { - foreach (ScenePresence p in killsToSendme) - { - m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); - try { ControllingClient.SendKillObject(new List { p.LocalId }); } - catch (NullReferenceException) { } - } + ControllingClient.SendKillObject(killsToSendme); } + catch (NullReferenceException) { } } } - private void ParcelCrossCheck(UUID currentParcelID,UUID previusParcelID, bool currentParcelHide, bool previusParcelHide, bool oldhide,bool check) { List killsToSendto = new List(); - List killsToSendme = new List(); + List killsToSendme = new List(); List viewsToSendto = new List(); List viewsToSendme = new List(); List allpresences = null; @@ -5697,7 +5902,7 @@ namespace OpenSim.Region.Framework.Scenes if(p.GodLevel < 200) killsToSendto.Add(p); // they dont see me if(GodLevel < 200) - killsToSendme.Add(p); // i dont see them + killsToSendme.Add(p.LocalId); // i dont see them } // only those on new parcel need see if (currentParcelID == p.currentParcelUUID) @@ -5746,7 +5951,7 @@ namespace OpenSim.Region.Framework.Scenes // only those old parcel need receive kills if (previusParcelID == p.currentParcelUUID && GodLevel < 200) { - killsToSendme.Add(p); // i dont see them + killsToSendme.Add(p.LocalId); // i dont see them } else { @@ -5771,26 +5976,26 @@ namespace OpenSim.Region.Framework.Scenes } } - if (killsToSendme.Count > 0 ) + if (killsToSendme.Count > 0) { - foreach (ScenePresence p in killsToSendme) + m_log.Debug("[AVATAR]: killtoMe: " + Lastname + " " + killsToSendme.Count.ToString()); + try { - m_log.Debug("[AVATAR]: killMe: " + Lastname + " " + p.Lastname); - try {ControllingClient.SendKillObject(new List { p.LocalId }); } - catch (NullReferenceException) { } + ControllingClient.SendKillObject(killsToSendme); } + catch (NullReferenceException) { } + } if (viewsToSendto.Count > 0 && PresenceType != PresenceType.Npc) { foreach (ScenePresence p in viewsToSendto) { - p.ControllingClient.SendAvatarDataImmediate(this); -// m_log.Debug("[AVATAR]: viewTo: " + Lastname + " " + p.Lastname); + SendAvatarDataToAgentNF(p); SendAppearanceToAgent(p); - SendAttachmentsToClient(p.ControllingClient); if (Animator != null) Animator.SendAnimPackToClient(p.ControllingClient); + SendAttachmentsToAgentNFPK(p); } } @@ -5801,11 +6006,12 @@ namespace OpenSim.Region.Framework.Scenes if (p.IsChildAgent) continue; // m_log.Debug("[AVATAR]: viewMe: " + Lastname + "<-" + p.Lastname); - ControllingClient.SendAvatarDataImmediate(p); + + p.SendAvatarDataToAgentNF(this); p.SendAppearanceToAgent(this); - p.SendAttachmentsToClient(ControllingClient); if (p.Animator != null) p.Animator.SendAnimPackToClient(ControllingClient); + p.SendAttachmentsToAgentNFPK(this); } } } diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 373ed418fd..f35ea92caf 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -58,6 +58,8 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server public ISceneAgent SceneAgent { get; set; } + public int PingTimeMS { get { return 0; } } + private string m_username; private string m_nick; diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index c88ccc5e86..7002d75869 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -81,6 +81,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC get { return m_scene; } } + public int PingTimeMS { get { return 0; } } + public UUID OwnerID { get { return m_ownerID; } diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 52e0134aff..f3eaed3a2a 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -379,6 +379,8 @@ namespace OpenSim.Tests.Common.Mock get { return FirstName + " " + LastName; } } + public int PingTimeMS { get { return 0; } } + public bool IsActive { get { return true; }