diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 729667c5b7..f3490fbed1 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -439,18 +439,26 @@ namespace OpenSim.ApplicationPlugins.RemoteController // k, (string)requestData[k], ((string)requestData[k]).Length); // } - CheckStringParameters(requestData, responseData, new string[] {"filename", "regionid"}); + CheckStringParameters(requestData, responseData, new string[] { "filename" }); CheckRegionParams(requestData, responseData); Scene scene = null; GetSceneFromRegionParams(requestData, responseData, out scene); - string file = (string)requestData["filename"]; - responseData["accepted"] = true; + if (scene != null) + { + string file = (string)requestData["filename"]; - LoadHeightmap(file, scene.RegionInfo.RegionID); + responseData["accepted"] = true; - responseData["success"] = true; + LoadHeightmap(file, scene.RegionInfo.RegionID); + + responseData["success"] = true; + } + else + { + responseData["success"] = false; + } m_log.Info("[RADMIN]: Load height maps request complete"); } @@ -464,23 +472,30 @@ namespace OpenSim.ApplicationPlugins.RemoteController // m_log.DebugFormat("[RADMIN]: Save Terrain: XmlRpc {0}", request.ToString()); - CheckStringParameters(requestData, responseData, new string[] { "filename", "regionid" }); + CheckStringParameters(requestData, responseData, new string[] { "filename" }); CheckRegionParams(requestData, responseData); - Scene region = null; - GetSceneFromRegionParams(requestData, responseData, out region); + Scene scene = null; + GetSceneFromRegionParams(requestData, responseData, out scene); - string file = (string)requestData["filename"]; - m_log.InfoFormat("[RADMIN]: Terrain Saving: {0}", file); + if (scene != null) + { + string file = (string)requestData["filename"]; + m_log.InfoFormat("[RADMIN]: Terrain Saving: {0}", file); - responseData["accepted"] = true; + responseData["accepted"] = true; - ITerrainModule terrainModule = region.RequestModuleInterface(); - if (null == terrainModule) throw new Exception("terrain module not available"); + ITerrainModule terrainModule = scene.RequestModuleInterface(); + if (null == terrainModule) throw new Exception("terrain module not available"); - terrainModule.SaveToFile(file); + terrainModule.SaveToFile(file); - responseData["success"] = true; + responseData["success"] = true; + } + else + { + responseData["success"] = false; + } m_log.Info("[RADMIN]: Save height maps request complete"); } diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs index 7cf1fa7458..05ee4c5628 100644 --- a/OpenSim/Framework/Monitoring/StatsManager.cs +++ b/OpenSim/Framework/Monitoring/StatsManager.cs @@ -267,7 +267,7 @@ namespace OpenSim.Framework.Monitoring public static Hashtable HandleStatsRequest(Hashtable request) { Hashtable responsedata = new Hashtable(); - string regpath = request["uri"].ToString(); +// string regpath = request["uri"].ToString(); int response_code = 200; string contenttype = "text/json"; diff --git a/OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs index 9f2aed08a0..10a4753c71 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs @@ -123,7 +123,7 @@ namespace OpenSim.Region.ClientStack.Linden if (m_URL == "localhost") { - m_log.DebugFormat("[AVATAR PICKER SEARCH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); +// m_log.DebugFormat("[AVATAR PICKER SEARCH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); caps.RegisterHandler( "AvatarPickerSearch", new AvatarPickerSearchHandler("/CAPS/" + capID + "/", m_People, "AvatarPickerSearch", "Search for avatars by name")); diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 0431b532f6..ad3f715eb8 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -106,6 +106,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP stat => stat.Value = m_udpServer.IncomingPacketsProcessed, StatVerbosity.Debug)); + StatsManager.RegisterStat( + new Stat( + "IncomingPacketsMalformedCount", + "Number of inbound UDP packets that could not be recognized as LL protocol packets.", + "", + "", + "clientstack", + scene.Name, + StatType.Pull, + MeasuresOfInterest.AverageChangeOverTime, + stat => stat.Value = m_udpServer.IncomingMalformedPacketCount, + StatVerbosity.Info)); + + StatsManager.RegisterStat( + new Stat( + "IncomingPacketsOrphanedCount", + "Number of inbound packets that were not initial connections packets and could not be associated with a viewer.", + "", + "", + "clientstack", + scene.Name, + StatType.Pull, + MeasuresOfInterest.AverageChangeOverTime, + stat => stat.Value = m_udpServer.IncomingOrphanedPacketCount, + StatVerbosity.Info)); + StatsManager.RegisterStat( new Stat( "OutgoingUDPSendsCount", @@ -272,7 +298,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP public Socket Server { get { return null; } } - private int m_malformedCount = 0; // Guard against a spamming attack + /// + /// Record how many inbound packets could not be recognized as LLUDP packets. + /// + public int IncomingMalformedPacketCount { get; private set; } + + /// + /// Record how many inbound packets could not be associated with a simulator circuit. + /// + public int IncomingOrphanedPacketCount { get; private set; } /// /// Record current outgoing client for monitoring purposes. @@ -1193,6 +1227,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; } + private void RecordMalformedInboundPacket(IPEndPoint endPoint) + { +// if (m_malformedCount < 100) +// m_log.DebugFormat("[LLUDPSERVER]: Dropped malformed packet: " + e.ToString()); + + IncomingMalformedPacketCount++; + + if ((IncomingMalformedPacketCount % 10000) == 0) + m_log.WarnFormat( + "[LLUDPSERVER]: Received {0} malformed packets so far, probable network attack. Last was from {1}", + IncomingMalformedPacketCount, endPoint); + } + public override void PacketReceived(UDPPacketBuffer buffer) { // Debugging/Profiling @@ -1214,6 +1261,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP // "[LLUDPSERVER]: Dropping undersized packet with {0} bytes received from {1} in {2}", // buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); + RecordMalformedInboundPacket(endPoint); + return; // Drop undersized packet } @@ -1232,6 +1281,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP // "[LLUDPSERVER]: Dropping packet with malformed header received from {0} in {1}", // buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); + RecordMalformedInboundPacket(endPoint); + return; // Malformed header } @@ -1247,34 +1298,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Only allocate a buffer for zerodecoding if the packet is zerocoded ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); } - catch (MalformedDataException) - { - } - catch (IndexOutOfRangeException) - { -// m_log.WarnFormat( -// "[LLUDPSERVER]: Dropping short packet received from {0} in {1}", -// buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); - - return; // Drop short packet - } catch (Exception e) { - if (m_malformedCount < 100) + if (IncomingMalformedPacketCount < 100) m_log.DebugFormat("[LLUDPSERVER]: Dropped malformed packet: " + e.ToString()); - - m_malformedCount++; - - if ((m_malformedCount % 100000) == 0) - m_log.DebugFormat("[LLUDPSERVER]: Received {0} malformed packets so far, probable network attack.", m_malformedCount); } // Fail-safe check if (packet == null) { - m_log.ErrorFormat("[LLUDPSERVER]: Malformed data, cannot parse {0} byte packet from {1}:", - buffer.DataLength, buffer.RemoteEndPoint); - m_log.Error(Utils.BytesToHexString(buffer.Data, buffer.DataLength, null)); + if (IncomingMalformedPacketCount < 100) + { + m_log.WarnFormat("[LLUDPSERVER]: Malformed data, cannot parse {0} byte packet from {1}, data {2}:", + buffer.DataLength, buffer.RemoteEndPoint, Utils.BytesToHexString(buffer.Data, buffer.DataLength, null)); + } + + RecordMalformedInboundPacket(endPoint); + return; } @@ -1337,6 +1377,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (client == null || !(client is LLClientView)) { //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); + + IncomingOrphanedPacketCount++; + + if ((IncomingOrphanedPacketCount % 10000) == 0) + m_log.WarnFormat( + "[LLUDPSERVER]: Received {0} orphaned packets so far. Last was from {1}", + IncomingOrphanedPacketCount, endPoint); + return; } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs index 1fdc410430..5a2bcee657 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs @@ -145,39 +145,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP return packet; } - // private byte[] decoded_header = new byte[10]; private static PacketType GetType(byte[] bytes) { - byte[] decoded_header = new byte[10 + 8]; ushort id; PacketFrequency freq; + bool isZeroCoded = (bytes[0] & Helpers.MSG_ZEROCODED) != 0; - if ((bytes[0] & Helpers.MSG_ZEROCODED) != 0) + if (bytes[6] == 0xFF) { - Helpers.ZeroDecode(bytes, 16, decoded_header); - } - else - { - Buffer.BlockCopy(bytes, 0, decoded_header, 0, 10); - } - - if (decoded_header[6] == 0xFF) - { - if (decoded_header[7] == 0xFF) + if (bytes[7] == 0xFF) { - id = (ushort) ((decoded_header[8] << 8) + decoded_header[9]); freq = PacketFrequency.Low; + if (isZeroCoded && bytes[8] == 0) + id = bytes[10]; + else + id = (ushort)((bytes[8] << 8) + bytes[9]); } else { - id = decoded_header[7]; freq = PacketFrequency.Medium; + id = bytes[7]; } } else { - id = decoded_header[6]; freq = PacketFrequency.High; + id = bytes[6]; } return Packet.GetType(id, freq); diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 62b25d0d9a..95cc6b7444 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -361,22 +361,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // If we're an NPC then skip all the item checks and manipulations since we don't have an // inventory right now. - SceneObjectGroup objatt - = RezSingleAttachmentFromInventoryInternal( + RezSingleAttachmentFromInventoryInternal( sp, sp.PresenceType == PresenceType.Npc ? UUID.Zero : attach.ItemID, attach.AssetID, attachmentPt, true, d); - - - if (ThrottlePer100PrimsRezzed > 0) - { - int throttleMs = (int)Math.Round((float)objatt.PrimCount / 100 * ThrottlePer100PrimsRezzed); - - if (DebugLevel > 0) - m_log.DebugFormat( - "[ATTACHMENTS MODULE]: Throttling by {0}ms after rez of {1} with {2} prims for attachment to {3} on point {4} in {5}", - throttleMs, objatt.Name, objatt.PrimCount, sp.Name, attachmentPt, m_scene.Name); - - Thread.Sleep(throttleMs); - } } catch (Exception e) { diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 35045b5008..62acd789a3 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -844,7 +844,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); TestClient tc = new TestClient(acd, sceneA); List destinationTestClients = new List(); - EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients); + EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients); ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, tc, acd); beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32); @@ -925,7 +925,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests IConfig modulesConfig = config.AddConfig("Modules"); modulesConfig.Set("EntityTransferModule", etmA.Name); modulesConfig.Set("SimulationServices", lscm.Name); - IConfig entityTransferConfig = config.AddConfig("EntityTransfer"); modulesConfig.Set("InventoryAccessModule", "BasicInventoryAccessModule"); @@ -944,7 +943,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); TestClient tc = new TestClient(acd, sceneA); List destinationTestClients = new List(); - EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients); + EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients); ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, tc, acd); beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32); @@ -966,7 +965,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests // Both these operations will occur on different threads and will wait for each other. // We have to do this via ThreadPool directly since FireAndForget has been switched to sync for the V1 // test protocol, where we are trying to avoid unpredictable async operations in regression tests. - ((TestClient)beforeTeleportSp.ControllingClient).OnTestClientSendRegionTeleport + tc.OnTestClientSendRegionTeleport += (regionHandle, simAccess, regionExternalEndPoint, locationID, flags, capsURL) => ThreadPool.UnsafeQueueUserWorkItem(o => destinationTestClients[0].CompleteMovement(), null); diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs index c04098c26d..966a05c052 100644 --- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs @@ -307,7 +307,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles } string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(targetID, out serverURI); + GetUserProfileServerURI(targetID, out serverURI); UUID creatorId = UUID.Zero; OSDMap parameters= new OSDMap(); @@ -372,7 +372,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles } string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(target, out serverURI); + GetUserProfileServerURI(target, out serverURI); object Ad = (object)ad; if(!JsonRpcRequest(ref Ad, "classifieds_info_query", serverURI, UUID.Random().ToString())) @@ -441,10 +441,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles Vector3 pos = remoteClient.SceneAgent.AbsolutePosition; ILandObject land = s.LandChannel.GetLandObject(pos.X, pos.Y); ScenePresence p = FindPresence(remoteClient.AgentId); - Vector3 avaPos = p.AbsolutePosition; +// Vector3 avaPos = p.AbsolutePosition; string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + GetUserProfileServerURI(remoteClient.AgentId, out serverURI); if (land == null) { @@ -470,7 +470,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles object Ad = ad; - OSD X = OSD.SerializeMembers(Ad); + OSD.SerializeMembers(Ad); if(!JsonRpcRequest(ref Ad, "classified_update", serverURI, UUID.Random().ToString())) { @@ -491,7 +491,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles public void ClassifiedDelete(UUID queryClassifiedID, IClientAPI remoteClient) { string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + GetUserProfileServerURI(remoteClient.AgentId, out serverURI); UUID classifiedId; OSDMap parameters= new OSDMap(); @@ -541,7 +541,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles } string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(targetId, out serverURI); + GetUserProfileServerURI(targetId, out serverURI); OSDMap parameters= new OSDMap(); parameters.Add("creatorId", OSD.FromUUID(targetId)); @@ -592,7 +592,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles UUID targetID; UUID.TryParse(args[0], out targetID); string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(targetID, out serverURI); + GetUserProfileServerURI(targetID, out serverURI); IClientAPI remoteClient = (IClientAPI)sender; UserProfilePick pick = new UserProfilePick(); @@ -660,7 +660,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles m_log.DebugFormat("[PROFILES]: Start PickInfoUpdate Name: {0} PickId: {1} SnapshotId: {2}", name, pickID.ToString(), snapshotID.ToString()); UserProfilePick pick = new UserProfilePick(); string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + GetUserProfileServerURI(remoteClient.AgentId, out serverURI); ScenePresence p = FindPresence(remoteClient.AgentId); Vector3 avaPos = p.AbsolutePosition; @@ -720,7 +720,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles public void PickDelete(IClientAPI remoteClient, UUID queryPickID) { string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + GetUserProfileServerURI(remoteClient.AgentId, out serverURI); OSDMap parameters= new OSDMap(); parameters.Add("pickId", OSD.FromUUID(queryPickID)); @@ -755,7 +755,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles IClientAPI remoteClient = (IClientAPI)sender; string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + GetUserProfileServerURI(remoteClient.AgentId, out serverURI); note.TargetId = remoteClient.AgentId; UUID.TryParse(args[0], out note.UserId); @@ -791,7 +791,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles note.Notes = queryNotes; string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + GetUserProfileServerURI(remoteClient.AgentId, out serverURI); object Note = note; if(!JsonRpcRequest(ref Note, "avatar_notes_update", serverURI, UUID.Random().ToString())) @@ -836,7 +836,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles prop.Language = languages; string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + GetUserProfileServerURI(remoteClient.AgentId, out serverURI); object Param = prop; if(!JsonRpcRequest(ref Param, "avatar_interests_update", serverURI, UUID.Random().ToString())) @@ -958,7 +958,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles prop.FirstLifeText = newProfile.FirstLifeAboutText; string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + GetUserProfileServerURI(remoteClient.AgentId, out serverURI); object Prop = prop; @@ -972,7 +972,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles } } - /// /// Gets the profile data. /// @@ -997,7 +996,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles } string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(properties.UserId, out serverURI); + GetUserProfileServerURI(properties.UserId, out serverURI); // This is checking a friend on the home grid // Not HG friend @@ -1245,11 +1244,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles return false; } - byte[] buf = new byte[8192]; Stream rstream = webResponse.GetResponseStream(); OSDMap mret = (OSDMap)OSDParser.DeserializeJson(rstream); - if(mret.ContainsKey("error")) + if (mret.ContainsKey("error")) return false; // get params... @@ -1311,7 +1309,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles return false; } - byte[] buf = new byte[8192]; Stream rstream = webResponse.GetResponseStream(); OSDMap response = new OSDMap(); diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 711167fa73..6ff9988d1c 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -317,7 +317,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2}@{3} - agent is already in transit.", sp.Name, sp.UUID, position, regionHandle); - sp.ControllingClient.SendTeleportFailed("Slow down!"); + sp.ControllingClient.SendTeleportFailed("Previous teleport process incomplete. Please retry shortly."); + return; } @@ -1034,6 +1035,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agent.SenderWantsToWaitForRoot = true; //SetCallbackURL(agent, sp.Scene.RegionInfo); + // Reset the do not close flag. This must be done before the destination opens child connections (here + // triggered by UpdateAgent) to avoid race conditions. However, we also want to reset it as late as possible + // to avoid a situation where an unexpectedly early call to Scene.NewUserConnection() wrongly results + // in no close. + sp.DoNotCloseAfterTeleport = false; + // Send the Update. If this returns true, we know the client has contacted the destination // via CompleteMovementIntoRegion, so we can let go. // If it returns false, something went wrong, and we need to abort. @@ -1060,6 +1067,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); + // Need to signal neighbours whether child agents may need closing irrespective of whether this + // one needed closing. We also need to close child agents as quickly as possible to avoid complicated + // race conditions with rapid agent releporting (e.g. from A1 to a non-neighbour B, back + // to a neighbour A2 then off to a non-neighbour C). Closing child agents any later requires complex + // distributed checks to avoid problems in rapid reteleporting scenarios and where child agents are + // abandoned without proper close by viewer but then re-used by an incoming connection. + sp.CloseChildAgents(newRegionX, newRegionY); + // May need to logout or other cleanup AgentHasMovedAway(sp, logout); @@ -1069,22 +1084,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Now let's make it officially a child agent sp.MakeChildAgent(); - // May still need to signal neighbours whether child agents may need closing irrespective of whether this - // one needed closing. Neighbour regions also contain logic to prevent a close if a subsequent move or - // teleport re-established the child connection. - // - // It may be possible to also close child agents after a pause but one needs to be very careful about - // race conditions between different regions on rapid teleporting (e.g. from A1 to a non-neighbour B, back - // to a neighbour A2 then off to a non-neighbour C. Also, closing child agents early may be more compatible - // with complicated scenarios where there a mixture of V1 and V2 teleports, though this is conjecture. It's - // easier to close immediately and greatly reduce the scope of race conditions if possible. - sp.CloseChildAgents(newRegionX, newRegionY); - // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) { - sp.DoNotCloseAfterTeleport = false; - // RED ALERT!!!! // PLEASE DO NOT DECREASE THIS WAIT TIME UNDER ANY CIRCUMSTANCES. // THE VIEWERS SEEM TO NEED SOME TIME AFTER RECEIVING MoveAgentIntoRegion @@ -1093,17 +1095,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS. Thread.Sleep(15000); - if (!sp.DoNotCloseAfterTeleport) - { - // OK, it got this agent. Let's close everything - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Closing agent {0} in {1}", sp.Name, Scene.Name); - sp.Scene.IncomingCloseAgent(sp.UUID, false); - } - else - { - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Not closing agent {0}, user is back in {1}", sp.Name, Scene.Name); - sp.DoNotCloseAfterTeleport = false; - } + // OK, it got this agent. Let's close everything + // If we shouldn't close the agent due to some other region renewing the connection + // then this will be handled in IncomingCloseAgent under lock conditions + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Closing agent {0} in {1} after teleport", sp.Name, Scene.Name); + sp.Scene.IncomingCloseAgent(sp.UUID, false); } else { diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 4fa4a7cded..56bdc636d7 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3862,21 +3862,30 @@ namespace OpenSim.Region.Framework.Scenes // In the case where, for example, an A B C D region layout, an avatar may // teleport from A -> D, but then -> C before A has asked B to close its old child agent. When C // renews the lease on the child agent at B, we must make sure that the close from A does not succeed. - if (!acd.ChildrenCapSeeds.ContainsKey(RegionInfo.RegionHandle)) - { - m_log.DebugFormat( - "[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because source will attempt close.", - sp.Name, Name); + // + // XXX: In the end, this should not be necessary if child agents are closed without delay on + // teleport, since realistically, the close request should always be processed before any other + // region tried to re-establish a child agent. This is much simpler since the logic below is + // vulnerable to an issue when a viewer quits a region without sending a proper logout but then + // re-establishes the connection on a relogin. This could wrongly set the DoNotCloseAfterTeleport + // flag when no teleport had taken place (and hence no close was going to come). +// if (!acd.ChildrenCapSeeds.ContainsKey(RegionInfo.RegionHandle)) +// { +// m_log.DebugFormat( +// "[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because source will attempt close.", +// sp.Name, Name); +// +// sp.DoNotCloseAfterTeleport = true; +// } +// else if (EntityTransferModule.IsInTransit(sp.UUID)) - sp.DoNotCloseAfterTeleport = true; - } - else if (EntityTransferModule.IsInTransit(sp.UUID)) + if (EntityTransferModule.IsInTransit(sp.UUID)) { - m_log.DebugFormat( - "[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because this region will attempt previous end-of-teleport close.", - sp.Name, Name); - sp.DoNotCloseAfterTeleport = true; + + m_log.DebugFormat( + "[SCENE]: Set DoNotCloseAfterTeleport for child scene presence {0} in {1} because this region will attempt end-of-teleport close from a previous close.", + sp.Name, Name); } } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 5301a827a8..3f4979e771 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -223,7 +223,7 @@ namespace OpenSim.Region.Framework.Scenes private float m_sitAvatarHeight = 2.0f; private Vector3 m_lastChildAgentUpdatePosition; - private Vector3 m_lastChildAgentUpdateCamPosition; +// private Vector3 m_lastChildAgentUpdateCamPosition; private const int LAND_VELOCITYMAG_MAX = 12; @@ -2108,8 +2108,7 @@ namespace OpenSim.Region.Framework.Scenes if (m_movementUpdateCount < 1) m_movementUpdateCount = 1; - - AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags; +// AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags; // Camera location in world. We'll need to raytrace // from this location from time to time. @@ -3241,7 +3240,7 @@ namespace OpenSim.Region.Framework.Scenes if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance) { m_lastChildAgentUpdatePosition = AbsolutePosition; - m_lastChildAgentUpdateCamPosition = CameraPosition; +// m_lastChildAgentUpdateCamPosition = CameraPosition; ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); cadu.ActiveGroupID = UUID.Zero.Guid; diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs index d670dad654..5b5fb9267a 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectDeRezTests.cs @@ -147,7 +147,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests AgentCircuitData acd = SceneHelpers.GenerateAgentData(uaB); TestClient clientB = new TestClient(acd, sceneB); List childClientsB = new List(); - EntityTransferHelpers.SetUpInformClientOfNeighbour(clientB, childClientsB); + EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(clientB, childClientsB); SceneHelpers.AddScenePresence(sceneB, clientB, acd); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs index 5df9aba0f2..12a778be68 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs @@ -97,7 +97,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); TestClient tc = new TestClient(acd, sceneA); List destinationTestClients = new List(); - EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients); + EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients); ScenePresence originalSp = SceneHelpers.AddScenePresence(sceneA, tc, acd); originalSp.AbsolutePosition = new Vector3(128, 32, 10); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs index afd2779994..8c25dbcf8e 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs @@ -30,6 +30,7 @@ using System.Collections.Generic; using System.IO; using System.Net; using System.Text; +using System.Threading; using Nini.Config; using NUnit.Framework; using OpenMetaverse; @@ -107,7 +108,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests } [Test] - public void TestSameSimulatorIsolatedRegions() + public void TestSameSimulatorIsolatedRegionsV1() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); @@ -146,7 +147,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests sp.AbsolutePosition = new Vector3(30, 31, 32); List destinationTestClients = new List(); - EntityTransferHelpers.SetUpInformClientOfNeighbour((TestClient)sp.ControllingClient, destinationTestClients); + EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate( + (TestClient)sp.ControllingClient, destinationTestClients); sceneA.RequestTeleportLocation( sp.ControllingClient, @@ -179,6 +181,67 @@ namespace OpenSim.Region.Framework.Scenes.Tests // Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt)); } + [Test] + public void TestSameSimulatorIsolatedRegionsV2() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID userId = TestHelpers.ParseTail(0x1); + + EntityTransferModule etmA = new EntityTransferModule(); + EntityTransferModule etmB = new EntityTransferModule(); + LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); + + IConfigSource config = new IniConfigSource(); + IConfig modulesConfig = config.AddConfig("Modules"); + modulesConfig.Set("EntityTransferModule", etmA.Name); + modulesConfig.Set("SimulationServices", lscm.Name); + + SceneHelpers sh = new SceneHelpers(); + TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); + TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1002, 1000); + + SceneHelpers.SetupSceneModules(sceneA, config, etmA); + SceneHelpers.SetupSceneModules(sceneB, config, etmB); + SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); + + Vector3 teleportPosition = new Vector3(10, 11, 12); + Vector3 teleportLookAt = new Vector3(20, 21, 22); + + ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId); + sp.AbsolutePosition = new Vector3(30, 31, 32); + + List destinationTestClients = new List(); + EntityTransferHelpers.SetupSendRegionTeleportTriggersDestinationClientCreateAndCompleteMovement( + (TestClient)sp.ControllingClient, destinationTestClients); + + sceneA.RequestTeleportLocation( + sp.ControllingClient, + sceneB.RegionInfo.RegionHandle, + teleportPosition, + teleportLookAt, + (uint)TeleportFlags.ViaLocation); + + Assert.That(sceneA.GetScenePresence(userId), Is.Null); + + ScenePresence sceneBSp = sceneB.GetScenePresence(userId); + Assert.That(sceneBSp, Is.Not.Null); + Assert.That(sceneBSp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneB.RegionInfo.RegionName)); + Assert.That(sceneBSp.AbsolutePosition, Is.EqualTo(teleportPosition)); + + Assert.That(sceneA.GetRootAgentCount(), Is.EqualTo(0)); + Assert.That(sceneA.GetChildAgentCount(), Is.EqualTo(0)); + Assert.That(sceneB.GetRootAgentCount(), Is.EqualTo(1)); + Assert.That(sceneB.GetChildAgentCount(), Is.EqualTo(0)); + + // TODO: Add assertions to check correct circuit details in both scenes. + + // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera + // position instead). +// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt)); + } + /// /// Test teleport procedures when the target simulator returns false when queried about access. /// @@ -428,7 +491,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests } [Test] - public void TestSameSimulatorNeighbouringRegions() + public void TestSameSimulatorNeighbouringRegionsV1() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); @@ -466,7 +529,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); TestClient tc = new TestClient(acd, sceneA); List destinationTestClients = new List(); - EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients); + EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients); ScenePresence beforeSceneASp = SceneHelpers.AddScenePresence(sceneA, tc, acd); beforeSceneASp.AbsolutePosition = new Vector3(30, 31, 32); @@ -510,6 +573,90 @@ namespace OpenSim.Region.Framework.Scenes.Tests // position instead). // Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt)); +// TestHelpers.DisableLogging(); + } + + [Test] + public void TestSameSimulatorNeighbouringRegionsV2() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID userId = TestHelpers.ParseTail(0x1); + + EntityTransferModule etmA = new EntityTransferModule(); + EntityTransferModule etmB = new EntityTransferModule(); + LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); + + IConfigSource config = new IniConfigSource(); + IConfig modulesConfig = config.AddConfig("Modules"); + modulesConfig.Set("EntityTransferModule", etmA.Name); + modulesConfig.Set("SimulationServices", lscm.Name); + + SceneHelpers sh = new SceneHelpers(); + TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); + TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1001, 1000); + + SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); + SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA); + SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB); + + Vector3 teleportPosition = new Vector3(10, 11, 12); + Vector3 teleportLookAt = new Vector3(20, 21, 22); + + AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); + TestClient tc = new TestClient(acd, sceneA); + List destinationTestClients = new List(); + EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients); + + ScenePresence beforeSceneASp = SceneHelpers.AddScenePresence(sceneA, tc, acd); + beforeSceneASp.AbsolutePosition = new Vector3(30, 31, 32); + + Assert.That(beforeSceneASp, Is.Not.Null); + Assert.That(beforeSceneASp.IsChildAgent, Is.False); + + ScenePresence beforeSceneBSp = sceneB.GetScenePresence(userId); + Assert.That(beforeSceneBSp, Is.Not.Null); + Assert.That(beforeSceneBSp.IsChildAgent, Is.True); + + // Here, we need to make clientA's receipt of SendRegionTeleport trigger clientB's CompleteMovement(). This + // is to operate the teleport V2 mechanism where the EntityTransferModule will first request the client to + // CompleteMovement to the region and then call UpdateAgent to the destination region to confirm the receipt + // Both these operations will occur on different threads and will wait for each other. + // We have to do this via ThreadPool directly since FireAndForget has been switched to sync for the V1 + // test protocol, where we are trying to avoid unpredictable async operations in regression tests. + tc.OnTestClientSendRegionTeleport + += (regionHandle, simAccess, regionExternalEndPoint, locationID, flags, capsURL) + => ThreadPool.UnsafeQueueUserWorkItem(o => destinationTestClients[0].CompleteMovement(), null); + + sceneA.RequestTeleportLocation( + beforeSceneASp.ControllingClient, + sceneB.RegionInfo.RegionHandle, + teleportPosition, + teleportLookAt, + (uint)TeleportFlags.ViaLocation); + + ScenePresence afterSceneASp = sceneA.GetScenePresence(userId); + Assert.That(afterSceneASp, Is.Not.Null); + Assert.That(afterSceneASp.IsChildAgent, Is.True); + + ScenePresence afterSceneBSp = sceneB.GetScenePresence(userId); + Assert.That(afterSceneBSp, Is.Not.Null); + Assert.That(afterSceneBSp.IsChildAgent, Is.False); + Assert.That(afterSceneBSp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneB.RegionInfo.RegionName)); + Assert.That(afterSceneBSp.AbsolutePosition, Is.EqualTo(teleportPosition)); + + Assert.That(sceneA.GetRootAgentCount(), Is.EqualTo(0)); + Assert.That(sceneA.GetChildAgentCount(), Is.EqualTo(1)); + Assert.That(sceneB.GetRootAgentCount(), Is.EqualTo(1)); + Assert.That(sceneB.GetChildAgentCount(), Is.EqualTo(0)); + + // TODO: Add assertions to check correct circuit details in both scenes. + + // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera + // position instead). +// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt)); + // TestHelpers.DisableLogging(); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs b/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs index 5f232a4b99..68bc1b9988 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSActorAvatarMove.cs @@ -69,7 +69,9 @@ public class BSActorAvatarMove : BSActor // BSActor.Dispose() public override void Dispose() { - Enabled = false; + base.SetEnabled(false); + // Now that turned off, remove any state we have in the scene. + Refresh(); } // Called when physical parameters (properties set in Bullet) need to be re-applied. @@ -181,7 +183,7 @@ public class BSActorAvatarMove : BSActor if (m_controllingPrim.IsColliding) { // If we are colliding with a stationary object, presume we're standing and don't move around - if (!m_controllingPrim.ColliderIsMoving) + if (!m_controllingPrim.ColliderIsMoving && !m_controllingPrim.ColliderIsVolumeDetect) { m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", m_controllingPrim.LocalID); m_controllingPrim.IsStationary = true; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 502f85f02b..291dfcd9d8 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -107,6 +107,8 @@ public sealed class BSCharacter : BSPhysObject PhysicalActors.Add(AvatarMoveActorName, m_moveActor); SetPhysicalProperties(); + + IsInitialized = true; }); return; } @@ -114,6 +116,8 @@ public sealed class BSCharacter : BSPhysObject // called when this character is being destroyed and the resources should be released public override void Destroy() { + IsInitialized = false; + base.Destroy(); DetailLog("{0},BSCharacter.Destroy", LocalID); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 27caf62873..9dc52d5a62 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -72,6 +72,8 @@ public abstract class BSPhysObject : PhysicsActor } protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName) { + IsInitialized = false; + PhysScene = parentScene; LocalID = localID; PhysObjectName = name; @@ -130,6 +132,9 @@ public abstract class BSPhysObject : PhysicsActor public string PhysObjectName { get; protected set; } public string TypeName { get; protected set; } + // Set to 'true' when the object is completely initialized. + // This mostly prevents property updates and collisions until the object is completely here. + public bool IsInitialized { get; protected set; } // Return the object mass without calculating it or having side effects public abstract float RawMass { get; } @@ -352,6 +357,8 @@ public abstract class BSPhysObject : PhysicsActor // On a collision, check the collider and remember if the last collider was moving // Used to modify the standing of avatars (avatars on stationary things stand still) public bool ColliderIsMoving; + // 'true' if the last collider was a volume detect object + public bool ColliderIsVolumeDetect; // Used by BSCharacter to manage standing (and not slipping) public bool IsStationary; @@ -431,6 +438,7 @@ public abstract class BSPhysObject : PhysicsActor // For movement tests, remember if we are colliding with an object that is moving. ColliderIsMoving = collidee != null ? (collidee.RawVelocity != OMV.Vector3.Zero) : false; + ColliderIsVolumeDetect = collidee != null ? (collidee.IsVolumeDetect) : false; // Make a collection of the collisions that happened the last simulation tick. // This is different than the collection created for sending up to the simulator as it is cleared every tick. diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 6b5dea39ff..d5b999d839 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -110,6 +110,8 @@ public class BSPrim : BSPhysObject CreateGeomAndObject(true); CurrentCollisionFlags = PhysScene.PE.GetCollisionFlags(PhysBody); + + IsInitialized = true; }); } @@ -117,6 +119,8 @@ public class BSPrim : BSPhysObject public override void Destroy() { // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); + IsInitialized = false; + base.Destroy(); // Undo any vehicle properties diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 79ac5a5ba0..88d50b438b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -639,7 +639,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters BSPhysObject pobj; if (PhysObjects.TryGetValue(entprop.ID, out pobj)) { - pobj.UpdateProperties(entprop); + if (pobj.IsInitialized) + pobj.UpdateProperties(entprop); } } } @@ -766,10 +767,13 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters // DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith); - if (collider.Collide(collidingWith, collidee, collidePoint, collideNormal, penetration)) + if (collider.IsInitialized) { - // If a collision was 'good', remember to send it to the simulator - ObjectsWithCollisions.Add(collider); + if (collider.Collide(collidingWith, collidee, collidePoint, collideNormal, penetration)) + { + // If a collision was 'good', remember to send it to the simulator + ObjectsWithCollisions.Add(collider); + } } return; diff --git a/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs b/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs index f37f2f1e24..04bb9e879c 100644 --- a/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs +++ b/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs @@ -85,7 +85,7 @@ namespace OpenSim.Server.Handlers.Hypergrid data.destinationServerURI = args["destination_serveruri"]; } - catch (InvalidCastException e) + catch (InvalidCastException) { m_log.ErrorFormat("[HOME AGENT HANDLER]: Bad cast in UnpackData"); } diff --git a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs index d9c1bd3d52..7137836839 100644 --- a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs +++ b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs @@ -453,7 +453,6 @@ namespace OpenSim.Server.Handlers.Hypergrid XmlRpcResponse response = new XmlRpcResponse(); response.Value = hash; return response; - } /// @@ -471,9 +470,7 @@ namespace OpenSim.Server.Handlers.Hypergrid //string portstr = (string)requestData["port"]; if (requestData.ContainsKey("first") && requestData.ContainsKey("last")) { - UUID userID = UUID.Zero; string first = (string)requestData["first"]; - string last = (string)requestData["last"]; UUID uuid = m_HomeUsersService.GetUUID(first, last); hash["UUID"] = uuid.ToString(); @@ -482,7 +479,6 @@ namespace OpenSim.Server.Handlers.Hypergrid XmlRpcResponse response = new XmlRpcResponse(); response.Value = hash; return response; - } } -} +} \ No newline at end of file diff --git a/OpenSim/Server/Handlers/Profiles/UserProfilesConnector.cs b/OpenSim/Server/Handlers/Profiles/UserProfilesConnector.cs index f9a520a907..28dbbc2e13 100644 --- a/OpenSim/Server/Handlers/Profiles/UserProfilesConnector.cs +++ b/OpenSim/Server/Handlers/Profiles/UserProfilesConnector.cs @@ -39,8 +39,7 @@ namespace OpenSim.Server.Handlers.Profiles { public class UserProfilesConnector: ServiceConnector { - static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - +// static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // Our Local Module public IUserProfilesService ServiceModule @@ -110,5 +109,4 @@ namespace OpenSim.Server.Handlers.Profiles Server.AddJsonRPCHandler("user_data_update", handler.UpdateUserAppData); } } -} - +} \ No newline at end of file diff --git a/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs b/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs index b36fa23899..245703cd39 100644 --- a/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs +++ b/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs @@ -98,7 +98,7 @@ namespace OpenSim.Services.Connectors catch (Exception e) { m_log.WarnFormat( - "[NEIGHBOUR SERVICE CONNCTOR]: Unable to parse uri {0} to send HelloNeighbour from {1} to {2}. Exception {3}{4}", + "[NEIGHBOUR SERVICES CONNECTOR]: Unable to parse uri {0} to send HelloNeighbour from {1} to {2}. Exception {3}{4}", uri, thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); return false; @@ -117,7 +117,7 @@ namespace OpenSim.Services.Connectors catch (Exception e) { m_log.WarnFormat( - "[NEIGHBOUR SERVICE CONNCTOR]: PackRegionInfoData failed for HelloNeighbour from {0} to {1}. Exception {2}{3}", + "[NEIGHBOUR SERVICES CONNECTOR]: PackRegionInfoData failed for HelloNeighbour from {0} to {1}. Exception {2}{3}", thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); return false; @@ -137,7 +137,7 @@ namespace OpenSim.Services.Connectors catch (Exception e) { m_log.WarnFormat( - "[NEIGHBOUR SERVICE CONNCTOR]: Exception thrown on serialization of HelloNeighbour from {0} to {1}. Exception {2}{3}", + "[NEIGHBOUR SERVICES CONNECTOR]: Exception thrown on serialization of HelloNeighbour from {0} to {1}. Exception {2}{3}", thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); return false; @@ -175,7 +175,7 @@ namespace OpenSim.Services.Connectors if (webResponse == null) { m_log.DebugFormat( - "[REST COMMS]: Null reply on DoHelloNeighbourCall post from {0} to {1}", + "[NEIGHBOUR SERVICES CONNECTOR]: Null reply on DoHelloNeighbourCall post from {0} to {1}", thisRegion.RegionName, region.RegionName); } @@ -193,7 +193,7 @@ namespace OpenSim.Services.Connectors catch (Exception e) { m_log.WarnFormat( - "[NEIGHBOUR SERVICE CONNCTOR]: Exception on reply of DoHelloNeighbourCall from {0} back to {1}. Exception {2}{3}", + "[NEIGHBOUR SERVICES CONNECTOR]: Exception on reply of DoHelloNeighbourCall from {0} back to {1}. Exception {2}{3}", region.RegionName, thisRegion.RegionName, e.Message, e.StackTrace); return false; diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianExternalCapsModule.cs b/OpenSim/Services/Connectors/SimianGrid/SimianExternalCapsModule.cs index e85b0b7e72..764e71fc31 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianExternalCapsModule.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianExternalCapsModule.cs @@ -56,11 +56,8 @@ namespace OpenSim.Services.Connectors.SimianGrid private Scene m_scene; private String m_simianURL; - private IGridUserService m_GridUserService; - #region IRegionModule Members - public string Name { get { return this.GetType().Name; } diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs index e7d2f86db6..9898da9d1c 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs @@ -29,11 +29,9 @@ using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Reflection; - using log4net; using Mono.Addins; using Nini.Config; - using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -52,7 +50,6 @@ namespace OpenSim.Services.Connectors.SimianGrid private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private IConfig m_config = null; - private bool m_enabled = true; private String m_simianURL; @@ -62,7 +59,6 @@ namespace OpenSim.Services.Connectors.SimianGrid { get { return this.GetType().Name; } } - public void Initialise(IConfigSource config) { @@ -76,7 +72,6 @@ namespace OpenSim.Services.Connectors.SimianGrid if (String.IsNullOrEmpty(m_simianURL)) { // m_log.DebugFormat("[SimianGrid] service URL is not defined"); - m_enabled = false; return; } @@ -141,6 +136,7 @@ namespace OpenSim.Services.Connectors.SimianGrid } #endregion + public static String SimulatorCapability = UUID.Zero.ToString(); public static OSDMap PostToService(string url, NameValueCollection data) { @@ -148,4 +144,4 @@ namespace OpenSim.Services.Connectors.SimianGrid return WebUtil.PostToService(url, data); } } -} +} \ No newline at end of file diff --git a/OpenSim/Tests/Common/Helpers/EntityTransferHelpers.cs b/OpenSim/Tests/Common/Helpers/EntityTransferHelpers.cs index 1b960b1f5d..ff6608d68e 100644 --- a/OpenSim/Tests/Common/Helpers/EntityTransferHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/EntityTransferHelpers.cs @@ -31,6 +31,7 @@ using System.IO; using System.Net; using System.Reflection; using System.Text; +using System.Threading; using log4net; using Nini.Config; using NUnit.Framework; @@ -59,7 +60,8 @@ namespace OpenSim.Tests.Common /// A list that will be populated with any TestClients set up in response to /// being informed about a destination region. /// - public static void SetUpInformClientOfNeighbour(TestClient tc, List neighbourTcs) + public static void SetupInformClientOfNeighbourTriggersNeighbourClientCreate( + TestClient tc, List neighbourTcs) { // XXX: Confusingly, this is also used for non-neighbour notification (as in teleports that do not use the // event queue). @@ -75,8 +77,6 @@ namespace OpenSim.Tests.Common "[TEST CLIENT]: Processing inform client of neighbour located at {0},{1} at {2}", x, y, neighbourExternalEndPoint); - // In response to this message, we are going to make a teleport to the scene we've previous been told - // about by test code (this needs to be improved). AgentCircuitData newAgent = tc.RequestClientInfo(); Scene neighbourScene; @@ -87,5 +87,42 @@ namespace OpenSim.Tests.Common neighbourScene.AddNewClient(neighbourTc, PresenceType.User); }; } + + /// + /// Set up correct handling of the InformClientOfNeighbour call from the source region that triggers the + /// viewer to setup a connection with the destination region. + /// + /// + /// + /// A list that will be populated with any TestClients set up in response to + /// being informed about a destination region. + /// + public static void SetupSendRegionTeleportTriggersDestinationClientCreateAndCompleteMovement( + TestClient client, List destinationClients) + { + client.OnTestClientSendRegionTeleport + += (regionHandle, simAccess, regionExternalEndPoint, locationID, flags, capsURL) => + { + uint x, y; + Utils.LongToUInts(regionHandle, out x, out y); + x /= Constants.RegionSize; + y /= Constants.RegionSize; + + m_log.DebugFormat( + "[TEST CLIENT]: Processing send region teleport for destination at {0},{1} at {2}", + x, y, regionExternalEndPoint); + + AgentCircuitData newAgent = client.RequestClientInfo(); + + Scene destinationScene; + SceneManager.Instance.TryGetScene(x, y, out destinationScene); + + TestClient destinationClient = new TestClient(newAgent, destinationScene); + destinationClients.Add(destinationClient); + destinationScene.AddNewClient(destinationClient, PresenceType.User); + + ThreadPool.UnsafeQueueUserWorkItem(o => destinationClient.CompleteMovement(), null); + }; + } } } \ No newline at end of file diff --git a/OpenSim/Tools/pCampBot/Bot.cs b/OpenSim/Tools/pCampBot/Bot.cs index dac8ccb49b..32bf32bb79 100644 --- a/OpenSim/Tools/pCampBot/Bot.cs +++ b/OpenSim/Tools/pCampBot/Bot.cs @@ -58,6 +58,11 @@ namespace pCampBot public delegate void AnEvent(Bot callbot, EventType someevent); // event delegate for bot events + /// + /// Controls whether bots request textures for the object information they receive + /// + public bool RequestObjectTextures { get; set; } + /// /// Bot manager. /// @@ -469,6 +474,9 @@ namespace pCampBot public void Objects_NewPrim(object sender, PrimEventArgs args) { + if (!RequestObjectTextures) + return; + Primitive prim = args.Prim; if (prim != null) diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index 397a98e37c..dee02c35ef 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -300,6 +300,7 @@ namespace pCampBot Bot pb = new Bot(bm, behaviours, firstName, lastName, password, startLocation, loginUri); pb.wear = wearSetting; pb.Client.Settings.SEND_AGENT_UPDATES = InitBotSendAgentUpdates; + pb.RequestObjectTextures = InitBotRequestObjectTextures; pb.OnConnected += handlebotEvent; pb.OnDisconnected += handlebotEvent;