diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index e45cb895f7..7384e399ce 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -1618,7 +1618,8 @@ namespace OpenSim.Framework.Servers.HttpServer m_httpListener2.Start(64); // Long Poll Service Manager with 3 worker threads a 25 second timeout for no events - m_PollServiceManager = new PollServiceRequestManager(this, 3, 25000); +// m_PollServiceManager = new PollServiceRequestManager(this, 3, 25000); + m_PollServiceManager = new PollServiceRequestManager(this, 4, 25000); HTTPDRunning = true; //HttpListenerContext context; diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs index ebfebc4443..78636c46e6 100644 --- a/OpenSim/Region/Application/Application.cs +++ b/OpenSim/Region/Application/Application.cs @@ -27,6 +27,7 @@ using System; using System.IO; +using System.Net; using System.Reflection; using log4net; using log4net.Config; @@ -73,6 +74,7 @@ namespace OpenSim AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); + ServicePointManager.DefaultConnectionLimit = 6; // Add the arguments supplied when running the application to the configuration ArgvConfigSource configSource = new ArgvConfigSource(args); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs index b9222e3fb1..7dcf137f3c 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs @@ -151,6 +151,12 @@ namespace OpenSim.Region.ClientStack.Linden ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint, uint locationID, uint flags, string capsURL, UUID agentID) { + // not sure why flags get overwritten here + if ((flags & (uint)TeleportFlags.IsFlying) != 0) + flags = (uint)TeleportFlags.ViaLocation | (uint)TeleportFlags.IsFlying; + else + flags = (uint)TeleportFlags.ViaLocation; + OSDMap info = new OSDMap(); info.Add("AgentID", OSD.FromUUID(agentID)); info.Add("LocationID", OSD.FromInteger(4)); // TODO what is this? @@ -159,7 +165,8 @@ namespace OpenSim.Region.ClientStack.Linden info.Add("SimAccess", OSD.FromInteger(simAccess)); info.Add("SimIP", OSD.FromBinary(regionExternalEndPoint.Address.GetAddressBytes())); info.Add("SimPort", OSD.FromInteger(regionExternalEndPoint.Port)); - info.Add("TeleportFlags", OSD.FromULong(1L << 4)); // AgentManager.TeleportFlags.ViaLocation +// info.Add("TeleportFlags", OSD.FromULong(1L << 4)); // AgentManager.TeleportFlags.ViaLocation + info.Add("TeleportFlags", OSD.FromUInteger(flags)); OSDArray infoArr = new OSDArray(); infoArr.Add(info); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index b77ead325e..e996fe8df2 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -60,11 +60,11 @@ namespace OpenSim.Region.ClientStack.Linden private WebFetchInvDescHandler m_webFetchHandler; - private ManualResetEvent m_ev = new ManualResetEvent(true); private object m_lock = new object(); private Dictionary m_capsDict = new Dictionary(); private Dictionary m_requests = new Dictionary(); + bool m_busy = false; #region ISharedRegionModule Members @@ -116,7 +116,9 @@ namespace OpenSim.Region.ClientStack.Linden string capUrl = "/CAPS/" + UUID.Random() + "/"; // Register this as a poll service + // absurd large timeout to tune later to make a bit less than viewer PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, agentID, 300000); + args.Type = PollServiceEventArgs.EventType.Inventory; MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args); @@ -133,6 +135,8 @@ namespace OpenSim.Region.ClientStack.Linden caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl)); m_capsDict[agentID] = capUrl; + + m_busy = false; } private void DeregisterCaps(UUID agentID, Caps caps) @@ -149,25 +153,22 @@ namespace OpenSim.Region.ClientStack.Linden public void HttpRequestHandler(UUID requestID, Hashtable request) { // m_log.DebugFormat("[FETCH2]: Received request {0}", requestID); - m_requests[requestID] = request; + lock(m_lock) + m_requests[requestID] = request; } private bool HasEvents(UUID requestID, UUID sessionID) { lock (m_lock) { - if (m_ev.WaitOne(0)) - { - m_ev.Reset(); - return true; - } - return false; + return !m_busy; } } private Hashtable NoEvents(UUID requestID, UUID sessionID) { - m_requests.Remove(requestID); + lock(m_lock) + m_requests.Remove(requestID); Hashtable response = new Hashtable(); @@ -177,11 +178,17 @@ namespace OpenSim.Region.ClientStack.Linden response["keepalive"] = false; response["reusecontext"] = false; + lock (m_lock) + m_busy = false; + return response; } private Hashtable GetEvents(UUID requestID, UUID sessionID, string request) { + lock (m_lock) + m_busy = true; + Hashtable response = new Hashtable(); response["int_response_code"] = 500; @@ -192,20 +199,23 @@ namespace OpenSim.Region.ClientStack.Linden try { + Hashtable requestHash; - if (!m_requests.TryGetValue(requestID, out requestHash)) + lock (m_lock) { - lock (m_lock) - m_ev.Set(); - response["str_response_string"] = "Invalid request"; - return response; + if (!m_requests.TryGetValue(requestID, out requestHash)) + { + m_busy = false; + response["str_response_string"] = "Invalid request"; + return response; + } + m_requests.Remove(requestID); } // m_log.DebugFormat("[FETCH2]: Processed request {0}", requestID); string reply = m_webFetchHandler.FetchInventoryDescendentsRequest(requestHash["body"].ToString(), String.Empty, String.Empty, null, null); - - m_requests.Remove(requestID); + response["int_response_code"] = 200; response["str_response_string"] = reply; @@ -213,7 +223,7 @@ namespace OpenSim.Region.ClientStack.Linden finally { lock (m_lock) - m_ev.Set(); + m_busy = false; } return response; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 7e51638211..74b27d7bf4 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -807,7 +807,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType); handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes; - OutPacket(handshake, ThrottleOutPacketType.Task); +// OutPacket(handshake, ThrottleOutPacketType.Task); + // use same as MoveAgentIntoRegion (both should be task ) + OutPacket(handshake, ThrottleOutPacketType.Unknown); } public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look) @@ -8748,16 +8750,61 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region Parcel related packets + // acumulate several HandleRegionHandleRequest consecutive overlaping requests + // to be done with minimal resources as possible + // variables temporary here while in test + + Queue RegionHandleRequests = new Queue(); + bool RegionHandleRequestsInService = false; + private bool HandleRegionHandleRequest(IClientAPI sender, Packet Pack) { - RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; + UUID currentUUID; RegionHandleRequest handlerRegionHandleRequest = OnRegionHandleRequest; - if (handlerRegionHandleRequest != null) + + if (handlerRegionHandleRequest == null) + return true; + + RegionHandleRequestPacket rhrPack = (RegionHandleRequestPacket)Pack; + + lock (RegionHandleRequests) { - handlerRegionHandleRequest(this, rhrPack.RequestBlock.RegionID); + if (RegionHandleRequestsInService) + { + // we are already busy doing a previus request + // so enqueue it + RegionHandleRequests.Enqueue(rhrPack.RequestBlock.RegionID); + return true; + } + + // else do it + currentUUID = rhrPack.RequestBlock.RegionID; + RegionHandleRequestsInService = true; } - return true; + + while (true) + { + handlerRegionHandleRequest(this, currentUUID); + + lock (RegionHandleRequests) + { + // exit condition, nothing to do or closed + // current code seems to assume we may loose the handler at anytime, + // so keep checking it + handlerRegionHandleRequest = OnRegionHandleRequest; + + if (RegionHandleRequests.Count == 0 || !IsActive || handlerRegionHandleRequest == null) + { + RegionHandleRequests.Clear(); + RegionHandleRequestsInService = false; + return true; + } + currentUUID = RegionHandleRequests.Dequeue(); + } + } + + return true; // actually unreached } private bool HandleParcelInfoRequest(IClientAPI sender, Packet Pack) diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs index 1406aaec25..0c067d7c61 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs @@ -137,6 +137,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage { UUID toAgentID = new UUID(im.toAgentID); + if (toAgentID == UUID.Zero) + return; + // Try root avatar only first foreach (Scene scene in m_Scenes) { diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 538dd5f6b5..486f9d2067 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -220,7 +220,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// /// /// - /// private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) { m_log.DebugFormat( @@ -264,6 +264,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer position.Z = newPosZ; } + if (sp.Flying) + teleportFlags |= (uint)TeleportFlags.IsFlying; + m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); sp.ControllingClient.SendTeleportStart(teleportFlags); @@ -471,6 +474,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (sp.ParentID != (uint)0) sp.StandUp(); + else if (sp.Flying) + teleportFlags |= (uint)TeleportFlags.IsFlying; + sp.ControllingClient.SendTeleportStart(teleportFlags); // the avatar.Close below will clear the child region list. We need this below for (possibly) @@ -982,7 +988,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agent.IsInTransit = true; CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; - d.BeginInvoke(agent, newpos, x, y, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); + d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); return true; } @@ -1039,42 +1045,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer icon.EndInvoke(iar); } + public bool CrossAgentToNewRegionPrep(ScenePresence agent, GridRegion neighbourRegion) + { + if (neighbourRegion == null) + return false; + + m_entityTransferStateMachine.SetInTransit(agent.UUID); + + agent.RemoveFromPhysicalScene(); + + return true; + } + /// /// This Closes child agents on neighbouring regions /// Calls an asynchronous method to do so.. so it doesn't lag the sim. /// public ScenePresence CrossAgentToNewRegionAsync( - ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, + ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version) { - if (neighbourRegion == null) + if (!CrossAgentToNewRegionPrep(agent, neighbourRegion)) return agent; + if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying)) + return agent; + + CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version); + return agent; + } + + public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying) + { try { - m_entityTransferStateMachine.SetInTransit(agent.UUID); - - ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); - - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", - agent.Firstname, agent.Lastname, neighbourx, neighboury, version); - - Scene m_scene = agent.Scene; - - if (!agent.ValidateAttachments()) - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.", - agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName); - - pos = pos + agent.Velocity; - Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); - - agent.RemoveFromPhysicalScene(); - AgentData cAgent = new AgentData(); agent.CopyTo(cAgent); - cAgent.Position = pos; + cAgent.Position = pos + agent.Velocity; if (isFlying) cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; @@ -1084,7 +1091,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Beyond this point, extra cleanup is needed beyond removing transit state m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); - if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) + if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) { // region doesn't take it m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); @@ -1093,82 +1100,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agent.AddToPhysicalScene(isFlying); m_entityTransferStateMachine.ResetFromTransit(agent.UUID); - return agent; + return false; } - //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); - agent.ControllingClient.RequestClientInfo(); - - //m_log.Debug("BEFORE CROSS"); - //Scene.DumpChildrenSeeds(UUID); - //DumpKnownRegions(); - string agentcaps; - if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) - { - m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", - neighbourRegion.RegionHandle); - return agent; - } - // No turning back - agent.IsChildAgent = true; - - string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); - - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); - - if (m_eqModule != null) - { - m_eqModule.CrossRegion( - neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, - capsPath, agent.UUID, agent.ControllingClient.SessionId); - } - else - { - agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, - capsPath); - } - - // 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); - - agent.MakeChildAgent(); - - // FIXME: Possibly this should occur lower down after other commands to close other agents, - // but not sure yet what the side effects would be. - m_entityTransferStateMachine.ResetFromTransit(agent.UUID); - - // now we have a child agent in this region. Request all interesting data about other (root) agents - agent.SendOtherAgentsAvatarDataToMe(); - agent.SendOtherAgentsAppearanceToMe(); - - // 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. - 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 - // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! - if (agent.Scene.NeedSceneCacheClear(agent.UUID)) - { - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); - } - - //m_log.Debug("AFTER CROSS"); - //Scene.DumpChildrenSeeds(UUID); - //DumpKnownRegions(); } catch (Exception e) { @@ -1177,9 +1111,97 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. + return false; } - return agent; + return true; + } + + public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, + bool isFlying, string version) + { + agent.ControllingClient.RequestClientInfo(); + + string agentcaps; + if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) + { + m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", + neighbourRegion.RegionHandle); + return; + } + + // No turning back + agent.IsChildAgent = true; + + string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); + + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); + + Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); + + if (m_eqModule != null) + { + m_eqModule.CrossRegion( + neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, + capsPath, agent.UUID, agent.ControllingClient.SessionId); + } + else + { + agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint, + capsPath); + } + + // 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); + + agent.MakeChildAgent(); + + // FIXME: Possibly this should occur lower down after other commands to close other agents, + // but not sure yet what the side effects would be. + m_entityTransferStateMachine.ResetFromTransit(agent.UUID); + + // now we have a child agent in this region. Request all interesting data about other (root) agents + agent.SendOtherAgentsAvatarDataToMe(); + agent.SendOtherAgentsAppearanceToMe(); + + // 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; + + Utils.LongToUInts(neighbourRegion.RegionHandle, out neighbourx, out neighboury); + + neighbourx /= Constants.RegionSize; + neighboury /= Constants.RegionSize; + + 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 + // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! + if (agent.Scene.NeedSceneCacheClear(agent.UUID)) + { + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); + } + + //m_log.Debug("AFTER CROSS"); + //Scene.DumpChildrenSeeds(UUID); + //DumpKnownRegions(); + + return; } private void CrossAgentToNewRegionCompleted(IAsyncResult iar) diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index 32a4c889cd..99ffbe7c50 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -189,9 +189,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp args.Type = PollServiceEventArgs.EventType.LslHttp; m_HttpServer.AddPollServiceHTTPHandler(uri, args); - m_log.DebugFormat( - "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}", - uri, itemID, host.Name, host.LocalId); +// m_log.DebugFormat( +// "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}", +// uri, itemID, host.Name, host.LocalId); engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); } @@ -235,9 +235,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp args.Type = PollServiceEventArgs.EventType.LslHttp; m_HttpsServer.AddPollServiceHTTPHandler(uri, args); - m_log.DebugFormat( - "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}", - uri, itemID, host.Name, host.LocalId); +// m_log.DebugFormat( +// "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}", +// uri, itemID, host.Name, host.LocalId); engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); } diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 51dcb67fb7..aae6603d57 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -86,7 +86,10 @@ namespace OpenSim.Region.CoreModules.World.Land /// /// Land objects keyed by local id /// - private readonly Dictionary m_landList = new Dictionary(); +// private readonly Dictionary m_landList = new Dictionary(); + + //ubit: removed the readonly so i can move it around + private Dictionary m_landList = new Dictionary(); private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; @@ -242,15 +245,19 @@ namespace OpenSim.Region.CoreModules.World.Land { LandData newData = data.Copy(); newData.LocalID = local_id; + ILandObject landobj = null; lock (m_landList) { if (m_landList.ContainsKey(local_id)) { m_landList[local_id].LandData = newData; - m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, m_landList[local_id]); + landobj = m_landList[local_id]; +// m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, m_landList[local_id]); } } + if(landobj != null) + m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, landobj); } public bool AllowedForcefulBans @@ -280,14 +287,14 @@ namespace OpenSim.Region.CoreModules.World.Land protected ILandObject CreateDefaultParcel() { m_log.DebugFormat( - "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName); - - ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); + "[LAND MANAGEMENT MODULE]: Creating default parcel for region {0}", m_scene.RegionInfo.RegionName); + + ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); fullSimParcel.SetLandBitmap(fullSimParcel.GetSquareLandBitmap(0, 0, (int)Constants.RegionSize, (int)Constants.RegionSize)); fullSimParcel.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; fullSimParcel.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); - - return AddLandObject(fullSimParcel); + + return AddLandObject(fullSimParcel); } public List AllParcels() @@ -394,30 +401,51 @@ namespace OpenSim.Region.CoreModules.World.Land public void SendLandUpdate(ScenePresence avatar, bool force) { + + /* stop sendind same data twice + ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), + (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); + + if (over != null) + { + + if (force) + { + if (!avatar.IsChildAgent) + { + over.SendLandUpdateToClient(avatar.ControllingClient); + m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, + m_scene.RegionInfo.RegionID); + } + } + + if (avatar.currentParcelUUID != over.LandData.GlobalID) + { + if (!avatar.IsChildAgent) + { + over.SendLandUpdateToClient(avatar.ControllingClient); + avatar.currentParcelUUID = over.LandData.GlobalID; + m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, + m_scene.RegionInfo.RegionID); + } + } + */ + if (avatar.IsChildAgent) + return; + ILandObject over = GetLandObject((int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.X))), - (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); + (int)Math.Min(((int)Constants.RegionSize - 1), Math.Max(0, Math.Round(avatar.AbsolutePosition.Y)))); if (over != null) { - if (force) + bool NotsameID = (avatar.currentParcelUUID != over.LandData.GlobalID); + if (force || NotsameID) { - if (!avatar.IsChildAgent) - { - over.SendLandUpdateToClient(avatar.ControllingClient); - m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, - m_scene.RegionInfo.RegionID); - } - } - - if (avatar.currentParcelUUID != over.LandData.GlobalID) - { - if (!avatar.IsChildAgent) - { - over.SendLandUpdateToClient(avatar.ControllingClient); + over.SendLandUpdateToClient(avatar.ControllingClient); + if (NotsameID) avatar.currentParcelUUID = over.LandData.GlobalID; - m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, - m_scene.RegionInfo.RegionID); - } + m_scene.EventManager.TriggerAvatarEnteringNewParcel(avatar, over.LandData.LocalID, + m_scene.RegionInfo.RegionID); } } } @@ -617,21 +645,28 @@ namespace OpenSim.Region.CoreModules.World.Land /// public void Clear(bool setupDefaultParcel) { + Dictionary landworkList; + // move to work pointer since we are deleting it all lock (m_landList) { - foreach (ILandObject lo in m_landList.Values) - { - //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID); - m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID); - } - - m_landList.Clear(); - - ResetSimLandObjects(); - - if (setupDefaultParcel) - CreateDefaultParcel(); + landworkList = m_landList; + m_landList = new Dictionary(); } + + // this 2 methods have locks (now) + ResetSimLandObjects(); + + if (setupDefaultParcel) + CreateDefaultParcel(); + + // fire outside events unlocked + foreach (ILandObject lo in landworkList.Values) + { + //m_scene.SimulationDataService.RemoveLandObject(lo.LandData.GlobalID); + m_scene.EventManager.TriggerLandObjectRemoved(lo.LandData.GlobalID); + } + landworkList.Clear(); + } private void performFinalLandJoin(ILandObject master, ILandObject slave) @@ -1324,20 +1359,30 @@ namespace OpenSim.Region.CoreModules.World.Land public void EventManagerOnIncomingLandDataFromStorage(List data) { + Dictionary landworkList; + // move to work pointer since we are deleting it all + lock (m_landList) + { + landworkList = m_landList; + m_landList = new Dictionary(); + } + + //Remove all the land objects in the sim and then process our new data + foreach (int n in landworkList.Keys) + { + m_scene.EventManager.TriggerLandObjectRemoved(landworkList[n].LandData.GlobalID); + } + landworkList.Clear(); + lock (m_landList) { - //Remove all the land objects in the sim and then process our new data - foreach (int n in m_landList.Keys) - { - m_scene.EventManager.TriggerLandObjectRemoved(m_landList[n].LandData.GlobalID); - } m_landIDList.Initialize(); m_landList.Clear(); + } - for (int i = 0; i < data.Count; i++) - { - IncomingLandObjectFromStorage(data[i]); - } + for (int i = 0; i < data.Count; i++) + { + IncomingLandObjectFromStorage(data[i]); } } @@ -1366,7 +1411,8 @@ namespace OpenSim.Region.CoreModules.World.Land public void EventManagerOnNoLandDataFromStorage() { - lock (m_landList) + // called methods already have locks +// lock (m_landList) { ResetSimLandObjects(); CreateDefaultParcel(); diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs index 5bc8e51759..1949a9007a 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs @@ -35,7 +35,7 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.Framework.Interfaces { - public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); + public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version); public interface IEntityTransferModule { @@ -76,7 +76,7 @@ namespace OpenSim.Region.Framework.Interfaces void Cross(SceneObjectGroup sog, Vector3 position, bool silent); - ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); + ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version); } diff --git a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs index e4e6f2c882..233e559c13 100644 --- a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs +++ b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs @@ -272,8 +272,6 @@ namespace OpenSim.Region.Framework.Scenes newmotion.m_basePosition = m_basePosition; newmotion.m_baseRotation = m_baseRotation; - newmotion.m_currentFrame = m_currentFrame; - if (m_selected) newmotion.m_serializedPosition = m_serializedPosition; else @@ -284,6 +282,8 @@ namespace OpenSim.Region.Framework.Scenes newmotion.m_serializedPosition = m_serializedPosition; } + newmotion.m_currentFrame = m_currentFrame; + newmotion.m_iterations = m_iterations; newmotion.m_running = m_running; diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 3af1060435..66cce60442 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2931,9 +2931,11 @@ namespace OpenSim.Region.Framework.Scenes { EventManager.TriggerOnClientLogin(client); // Send initial parcel data +/* this is done on TriggerOnNewClient by landmanegement respective event handler Vector3 pos = sp.AbsolutePosition; ILandObject land = LandChannel.GetLandObject(pos.X, pos.Y); land.SendLandUpdateToClient(client); +*/ } return sp; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 38dbaa9c52..18e74c1cbc 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -581,7 +581,7 @@ namespace OpenSim.Region.Framework.Scenes av.IsInTransit = true; CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync; - d.BeginInvoke(av, val, x, y, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d); + d.BeginInvoke(av, val, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d); } else m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar alreasy in transit {0} to {1}", av.Name, val); @@ -2159,6 +2159,7 @@ namespace OpenSim.Region.Framework.Scenes dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); dupe.m_rootPart.LinkNum = m_rootPart.LinkNum; + if (userExposed) dupe.m_rootPart.TrimPermissions(); @@ -2209,6 +2210,9 @@ namespace OpenSim.Region.Framework.Scenes if (userExposed) newPart.ApplyPhysics((uint)newPart.Flags,newPart.VolumeDetectActive,true); // } + // copy keyframemotion + if (part.KeyframeMotion != null) + newPart.KeyframeMotion = part.KeyframeMotion.Copy(dupe); } if (userExposed) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 8e419f9d86..4af508eccf 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2110,8 +2110,8 @@ namespace OpenSim.Region.Framework.Scenes Array.Copy(Shape.ExtraParams, extraP, extraP.Length); dupe.Shape.ExtraParams = extraP; - if (KeyframeMotion != null) - dupe.KeyframeMotion = KeyframeMotion.Copy(null); + // safeguard actual copy is done in sog.copy + dupe.KeyframeMotion = null; if (userExposed) { diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 0176921795..adb3d386bd 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1266,7 +1266,8 @@ namespace OpenSim.Region.Framework.Scenes Vector3 look = Velocity; - if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) + // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) + if ((Math.Abs(look.X) < 0.1) && (Math.Abs(look.Y) < 0.1) && (Math.Abs(look.Z) < 0.1)) { look = new Vector3(0.99f, 0.042f, 0); } @@ -1316,13 +1317,15 @@ namespace OpenSim.Region.Framework.Scenes // Create child agents in neighbouring regions if (openChildAgents && !IsChildAgent) { + IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface(); if (m_agentTransfer != null) - Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); }); + m_agentTransfer.EnableChildAgents(this); IFriendsModule friendsModule = m_scene.RequestModuleInterface(); if (friendsModule != null) friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); + } // m_log.DebugFormat( @@ -3438,7 +3441,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void PhysicsCollisionUpdate(EventArgs e) { - if (IsChildAgent) + if (IsChildAgent || Animator == null) return; //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs index 20919a1982..756b1f44cd 100644 --- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs +++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs @@ -438,23 +438,26 @@ namespace OpenSim.Region.Framework.Scenes } // Extra statistics that aren't currently sent to clients - lock (m_lastReportedExtraSimStats) + if (m_scene.PhysicsScene != null) { - m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates / m_statsUpdateFactor; - - Dictionary physicsStats = m_scene.PhysicsScene.GetStats(); - - if (physicsStats != null) + lock (m_lastReportedExtraSimStats) { - foreach (KeyValuePair tuple in physicsStats) + m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates / m_statsUpdateFactor; + + Dictionary physicsStats = m_scene.PhysicsScene.GetStats(); + + if (physicsStats != null) { - // FIXME: An extremely dirty hack to divide MS stats per frame rather than per second - // Need to change things so that stats source can indicate whether they are per second or - // per frame. - if (tuple.Key.EndsWith("MS")) - m_lastReportedExtraSimStats[tuple.Key] = tuple.Value * perframe; - else - m_lastReportedExtraSimStats[tuple.Key] = tuple.Value / m_statsUpdateFactor; + foreach (KeyValuePair tuple in physicsStats) + { + // FIXME: An extremely dirty hack to divide MS stats per frame rather than per second + // Need to change things so that stats source can indicate whether they are per second or + // per frame. + if (tuple.Key.EndsWith("MS")) + m_lastReportedExtraSimStats[tuple.Key] = tuple.Value * perframe; + else + m_lastReportedExtraSimStats[tuple.Key] = tuple.Value / m_statsUpdateFactor; + } } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 19694920ea..957066910d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3386,7 +3386,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llInstantMessage(string user, string message) { UUID result; - if (!UUID.TryParse(user, out result)) + if (!UUID.TryParse(user, out result) || result == UUID.Zero) { ShoutError("An invalid key was passed to llInstantMessage"); ScriptSleep(2000); diff --git a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs index 45ebf3abef..9e04601a6f 100644 --- a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs +++ b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs @@ -126,7 +126,10 @@ namespace OpenSim.Services.Connectors // m_log.DebugFormat("[ASSET]: Using {0} for host name for prefix {1}", host, prefix); - return serverUri.Uri.AbsoluteUri; + string ret = serverUri.Uri.AbsoluteUri; + if (ret.EndsWith("/")) + ret = ret.Substring(0, ret.Length - 1); + return ret; } protected void retryCheck(object source, ElapsedEventArgs e) diff --git a/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs index 3fd0c53633..6cd21d155e 100644 --- a/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs +++ b/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs @@ -144,44 +144,48 @@ namespace OpenSim.Services.Connectors.Friends private bool Call(GridRegion region, Dictionary sendData) { - string reqString = ServerUtils.BuildQueryString(sendData); - //m_log.DebugFormat("[FRIENDS SIM CONNECTOR]: queryString = {0}", reqString); - if (region == null) - return false; + Util.FireAndForget(x => { + string reqString = ServerUtils.BuildQueryString(sendData); + //m_log.DebugFormat("[FRIENDS SIM CONNECTOR]: queryString = {0}", reqString); + if (region == null) + return; - string path = ServicePath(); - if (!region.ServerURI.EndsWith("/")) - path = "/" + path; - string uri = region.ServerURI + path; - m_log.DebugFormat("[FRIENDS SIM CONNECTOR]: calling {0}", uri); + string path = ServicePath(); + if (!region.ServerURI.EndsWith("/")) + path = "/" + path; + string uri = region.ServerURI + path; + m_log.DebugFormat("[FRIENDS SIM CONNECTOR]: calling {0}", uri); - try - { - string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); - if (reply != string.Empty) + try { - Dictionary replyData = ServerUtils.ParseXmlResponse(reply); - - if (replyData.ContainsKey("RESULT")) + string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); + if (reply != string.Empty) { - if (replyData["RESULT"].ToString().ToLower() == "true") - return true; + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData.ContainsKey("RESULT")) + { +// if (replyData["RESULT"].ToString().ToLower() == "true") +// return; +// else + return; + } else - return false; + m_log.DebugFormat("[FRIENDS SIM CONNECTOR]: reply data does not contain result field"); + } else - m_log.DebugFormat("[FRIENDS SIM CONNECTOR]: reply data does not contain result field"); - + m_log.DebugFormat("[FRIENDS SIM CONNECTOR]: received empty reply"); + } + catch (Exception e) + { + m_log.DebugFormat("[FRIENDS SIM CONNECTOR]: Exception when contacting remote sim at {0}: {1}", uri, e.Message); } - else - m_log.DebugFormat("[FRIENDS SIM CONNECTOR]: received empty reply"); - } - catch (Exception e) - { - m_log.DebugFormat("[FRIENDS SIM CONNECTOR]: Exception when contacting remote sim at {0}: {1}", uri, e.Message); - } - return false; + return; + }); + + return true; } } } diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index e1c2243316..508baf7e5d 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -395,17 +395,18 @@ namespace OpenSim.Services.Connectors.Simulation private bool CloseAgent(GridRegion destination, UUID id, bool ChildOnly) { // m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: CloseAgent start"); + Util.FireAndForget(x => { + string uri = destination.ServerURI + AgentPath() + id + "/" + destination.RegionID.ToString() + "/"; - string uri = destination.ServerURI + AgentPath() + id + "/" + destination.RegionID.ToString() + "/"; - - try - { - WebUtil.ServiceOSDRequest(uri, null, "DELETE", 10000, false); - } - catch (Exception e) - { - m_log.WarnFormat("[REMOTE SIMULATION CONNECTOR] CloseAgent failed with exception; {0}",e.ToString()); - } + try + { + WebUtil.ServiceOSDRequest(uri, null, "DELETE", 10000, false); + } + catch (Exception e) + { + m_log.WarnFormat("[REMOTE SIMULATION CONNECTOR] CloseAgent failed with exception; {0}",e.ToString()); + } + }); return true; }