diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs index ed419785e8..67402a2214 100644 --- a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs +++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs @@ -106,7 +106,7 @@ namespace OpenSim.Groups sendData["OP"] = "UPDATE"; Dictionary ret = MakeRequest("PUTGROUP", sendData); - if (ret == null || (ret != null && ret["RESULT"].ToString() == "NULL")) + if (ret == null || (ret != null && (!ret.ContainsKey("RESULT") || ret["RESULT"].ToString() == "NULL"))) return null; return GroupsDataUtils.GroupRecord((Dictionary)ret["RESULT"]); @@ -127,7 +127,7 @@ namespace OpenSim.Groups Dictionary ret = MakeRequest("GETGROUP", sendData); - if (ret == null || (ret != null && ret["RESULT"].ToString() == "NULL")) + if (ret == null || (ret != null && (!ret.ContainsKey("RESULT") || ret["RESULT"].ToString() == "NULL"))) return null; return GroupsDataUtils.GroupRecord((Dictionary)ret["RESULT"]); @@ -267,6 +267,7 @@ namespace OpenSim.Groups if (ret["RESULT"].ToString() == "NULL") return members; + foreach (object v in ((Dictionary)ret["RESULT"]).Values) { ExtendedGroupMembersData m = GroupsDataUtils.GroupMembersData((Dictionary)v); @@ -357,6 +358,7 @@ namespace OpenSim.Groups if (ret["RESULT"].ToString() == "NULL") return roles; + foreach (object v in ((Dictionary)ret["RESULT"]).Values) { GroupRolesData m = GroupsDataUtils.GroupRolesData((Dictionary)v); @@ -667,7 +669,7 @@ namespace OpenSim.Groups return replyData; } - #endregion + #endregion } -} +} \ No newline at end of file diff --git a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs index 9a6ca8640a..b222d4bc7d 100644 --- a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs +++ b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs @@ -238,7 +238,15 @@ namespace OpenSim.Capabilities.Handlers if (folderID != UUID.Zero) { - contents = m_InventoryService.GetFolderContent(agentID, folderID); + InventoryCollection fetchedContents = m_InventoryService.GetFolderContent(agentID, folderID); + + if (fetchedContents == null) + { + m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Could not get contents of folder {0} for user {1}", folderID, agentID); + return contents; + } + + contents = fetchedContents; InventoryFolderBase containingFolder = new InventoryFolderBase(); containingFolder.ID = folderID; containingFolder.Owner = agentID; diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 7bc8176a18..c7377b85fc 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -1745,6 +1745,30 @@ namespace OpenSim.Framework return data; } + /// + /// Pretty format the hashtable contents to a single line. + /// + /// + /// Used for debugging output. + /// + /// + public static string PrettyFormatToSingleLine(Hashtable ht) + { + StringBuilder sb = new StringBuilder(); + + int i = 0; + + foreach (string key in ht.Keys) + { + sb.AppendFormat("{0}:{1}", key, ht[key]); + + if (++i < ht.Count) + sb.AppendFormat(", "); + } + + return sb.ToString(); + } + /// /// Used to trigger an early library load on Windows systems. /// diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 77b94408d8..3d80c6eefc 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -559,7 +559,7 @@ namespace OpenSim { scene.ForEachSOG(delegate(SceneObjectGroup sog) { - if (sog.AttachmentPoint == 0) + if (!sog.IsAttachment) { sog.RootPart.UpdateRotation(rot * sog.GroupRotation); Vector3 offset = sog.AbsolutePosition - center; @@ -588,7 +588,7 @@ namespace OpenSim { scene.ForEachSOG(delegate(SceneObjectGroup sog) { - if (sog.AttachmentPoint == 0) + if (!sog.IsAttachment) { if (sog.RootPart.AbsolutePosition.Z < minZ) minZ = sog.RootPart.AbsolutePosition.Z; @@ -600,7 +600,7 @@ namespace OpenSim { scene.ForEachSOG(delegate(SceneObjectGroup sog) { - if (sog.AttachmentPoint == 0) + if (!sog.IsAttachment) { Vector3 tmpRootPos = sog.RootPart.AbsolutePosition; tmpRootPos.Z -= minZ; @@ -640,7 +640,7 @@ namespace OpenSim { scene.ForEachSOG(delegate(SceneObjectGroup sog) { - if (sog.AttachmentPoint == 0) + if (!sog.IsAttachment) sog.UpdateGroupPosition(sog.AbsolutePosition + offset); }); }); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index f98337dd8d..b162bb9289 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -229,12 +229,18 @@ namespace OpenSim.Region.ClientStack.Linden lock (queue) queue.Enqueue(ev); } - else + else if (DebugLevel > 0) { - OSDMap evMap = (OSDMap)ev; - m_log.WarnFormat( - "[EVENTQUEUE]: (Enqueue) No queue found for agent {0} when placing message {1} in region {2}", - avatarID, evMap["message"], m_scene.Name); + ScenePresence sp = m_scene.GetScenePresence(avatarID); + + // This assumes that an NPC should never have a queue. + if (sp != null && sp.PresenceType != PresenceType.Npc) + { + OSDMap evMap = (OSDMap)ev; + m_log.WarnFormat( + "[EVENTQUEUE]: (Enqueue) No queue found for agent {0} {1} when placing message {2} in region {3}", + sp.Name, sp.UUID, evMap["message"], m_scene.Name); + } } } catch (NullReferenceException e) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs index 9e24bcef15..fb24f586e2 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs @@ -26,6 +26,7 @@ */ using System; +using System.Collections; using System.Collections.Generic; using System.Net; using log4net.Config; @@ -33,11 +34,14 @@ using Nini.Config; using NUnit.Framework; using OpenMetaverse; using OpenMetaverse.Packets; +using OpenMetaverse.StructuredData; using OpenSim.Framework; using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.ClientStack.Linden; using OpenSim.Region.CoreModules.Framework; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.OptionalModules.World.NPC; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; @@ -47,6 +51,8 @@ namespace OpenSim.Region.ClientStack.Linden.Tests public class EventQueueTests : OpenSimTestCase { private TestScene m_scene; + private EventQueueGetModule m_eqgMod; + private NPCModule m_npcMod; [SetUp] public override void SetUp() @@ -69,10 +75,15 @@ namespace OpenSim.Region.ClientStack.Linden.Tests config.Configs["Startup"].Set("EventQueue", "true"); CapabilitiesModule capsModule = new CapabilitiesModule(); - EventQueueGetModule eqgModule = new EventQueueGetModule(); + m_eqgMod = new EventQueueGetModule(); + + // For NPC test support + config.AddConfig("NPC"); + config.Configs["NPC"].Set("Enabled", "true"); + m_npcMod = new NPCModule(); m_scene = new SceneHelpers().SetupScene(); - SceneHelpers.SetupSceneModules(m_scene, config, capsModule, eqgModule); + SceneHelpers.SetupSceneModules(m_scene, config, capsModule, m_eqgMod, m_npcMod); } [Test] @@ -101,5 +112,80 @@ namespace OpenSim.Region.ClientStack.Linden.Tests // TODO: Add more assertions for the other aspects of event queues Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0)); } + + [Test] + public void TestEnqueueMessage() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); + + string messageName = "TestMessage"; + + m_eqgMod.Enqueue(m_eqgMod.BuildEvent(messageName, new OSDMap()), sp.UUID); + + Hashtable eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID); + + Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.OK)); + +// Console.WriteLine("Response [{0}]", (string)eventsResponse["str_response_string"]); + + OSDMap rawOsd = (OSDMap)OSDParser.DeserializeLLSDXml((string)eventsResponse["str_response_string"]); + OSDArray eventsOsd = (OSDArray)rawOsd["events"]; + + bool foundUpdate = false; + foreach (OSD osd in eventsOsd) + { + OSDMap eventOsd = (OSDMap)osd; + + if (eventOsd["message"] == messageName) + foundUpdate = true; + } + + Assert.That(foundUpdate, Is.True, string.Format("Did not find {0} in response", messageName)); + } + + /// + /// Test an attempt to put a message on the queue of a user that is not in the region. + /// + [Test] + public void TestEnqueueMessageNoUser() + { + TestHelpers.InMethod(); + TestHelpers.EnableLogging(); + + string messageName = "TestMessage"; + + m_eqgMod.Enqueue(m_eqgMod.BuildEvent(messageName, new OSDMap()), TestHelpers.ParseTail(0x1)); + + Hashtable eventsResponse = m_eqgMod.GetEvents(UUID.Zero, TestHelpers.ParseTail(0x1)); + + Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.BadGateway)); + } + + /// + /// NPCs do not currently have an event queue but a caller may try to send a message anyway, so check behaviour. + /// + [Test] + public void TestEnqueueMessageToNpc() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID npcId + = m_npcMod.CreateNPC( + "John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, new AvatarAppearance()); + + ScenePresence npc = m_scene.GetScenePresence(npcId); + + string messageName = "TestMessage"; + + m_eqgMod.Enqueue(m_eqgMod.BuildEvent(messageName, new OSDMap()), npc.UUID); + + Hashtable eventsResponse = m_eqgMod.GetEvents(UUID.Zero, npc.UUID); + + Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.BadGateway)); + } } } \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 09cc9983a8..cdad729a26 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -687,187 +687,238 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory m_scene.EventManager.TriggerAvatarAppearanceChanged(sp); } + /// + /// For a given set of appearance items, check whether the items are valid and add their asset IDs to + /// appearance data. + /// + /// + /// private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance) { IInventoryService invService = m_scene.InventoryService; - bool resetwearable = false; + if (invService.GetRootFolder(userID) != null) { for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) { for (int j = 0; j < appearance.Wearables[i].Count; j++) { - // Check if the default wearables are not set if (appearance.Wearables[i][j].ItemID == UUID.Zero) { - switch ((WearableType) i) - { - case WearableType.Eyes: - case WearableType.Hair: - case WearableType.Shape: - case WearableType.Skin: - //case WearableType.Underpants: - TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance); - resetwearable = true; - m_log.Warn("[AVFACTORY]: UUID.Zero Wearables, passing fake values."); - resetwearable = true; - break; + m_log.WarnFormat( + "[AVFACTORY]: Wearable item {0}:{1} for user {2} unexpectedly UUID.Zero. Ignoring.", + i, j, userID); - } continue; } - // Ignore ruth's assets except for the body parts! missing body parts fail avatar appearance on V1 + // Ignore ruth's assets if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID) - { - switch ((WearableType)i) - { - case WearableType.Eyes: - case WearableType.Hair: - case WearableType.Shape: - case WearableType.Skin: - //case WearableType.Underpants: - TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance); - - m_log.WarnFormat("[AVFACTORY]: {0} Default Wearables, passing existing values.", (WearableType)i); - resetwearable = true; - break; - - } continue; - } - + InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); baseItem = invService.GetItem(baseItem); if (baseItem != null) { appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID); - int unmodifiedWearableIndexForClosure = i; - m_scene.AssetService.Get(baseItem.AssetID.ToString(), this, - delegate(string x, object y, AssetBase z) - { - if (z == null) - { - TryAndRepairBrokenWearable( - (WearableType)unmodifiedWearableIndexForClosure, invService, - userID, appearance); - } - }); } else { - m_log.ErrorFormat( + m_log.WarnFormat( "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default", appearance.Wearables[i][j].ItemID, (WearableType)i); - TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance); - resetwearable = true; - + appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID); } } } - - // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason.... - if (appearance.Wearables[(int) WearableType.Eyes] == null) - { - m_log.WarnFormat("[AVFACTORY]: {0} Eyes are Null, passing existing values.", (WearableType.Eyes)); - - TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance); - resetwearable = true; - } - else - { - if (appearance.Wearables[(int) WearableType.Eyes][0].ItemID == UUID.Zero) - { - m_log.WarnFormat("[AVFACTORY]: Eyes are UUID.Zero are broken, {0} {1}", - appearance.Wearables[(int) WearableType.Eyes][0].ItemID, - appearance.Wearables[(int) WearableType.Eyes][0].AssetID); - TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance); - resetwearable = true; - - } - - } - // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason.... - if (appearance.Wearables[(int)WearableType.Shape] == null) - { - m_log.WarnFormat("[AVFACTORY]: {0} shape is Null, passing existing values.", (WearableType.Shape)); - - TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance); - resetwearable = true; - } - else - { - if (appearance.Wearables[(int)WearableType.Shape][0].ItemID == UUID.Zero) - { - m_log.WarnFormat("[AVFACTORY]: Shape is UUID.Zero and broken, {0} {1}", - appearance.Wearables[(int)WearableType.Shape][0].ItemID, - appearance.Wearables[(int)WearableType.Shape][0].AssetID); - TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance); - resetwearable = true; - - } - - } - // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason.... - if (appearance.Wearables[(int)WearableType.Hair] == null) - { - m_log.WarnFormat("[AVFACTORY]: {0} Hair is Null, passing existing values.", (WearableType.Hair)); - - TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance); - resetwearable = true; - } - else - { - if (appearance.Wearables[(int)WearableType.Hair][0].ItemID == UUID.Zero) - { - m_log.WarnFormat("[AVFACTORY]: Hair is UUID.Zero and broken, {0} {1}", - appearance.Wearables[(int)WearableType.Hair][0].ItemID, - appearance.Wearables[(int)WearableType.Hair][0].AssetID); - TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance); - resetwearable = true; - - } - - } - // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason.... - if (appearance.Wearables[(int)WearableType.Skin] == null) - { - m_log.WarnFormat("[AVFACTORY]: {0} Skin is Null, passing existing values.", (WearableType.Skin)); - - TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance); - resetwearable = true; - } - else - { - if (appearance.Wearables[(int)WearableType.Skin][0].ItemID == UUID.Zero) - { - m_log.WarnFormat("[AVFACTORY]: Skin is UUID.Zero and broken, {0} {1}", - appearance.Wearables[(int)WearableType.Skin][0].ItemID, - appearance.Wearables[(int)WearableType.Skin][0].AssetID); - TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance); - resetwearable = true; - - } - - } - if (resetwearable) - { - ScenePresence presence = null; - if (m_scene.TryGetScenePresence(userID, out presence)) - { - presence.ControllingClient.SendWearables(presence.Appearance.Wearables, - presence.Appearance.Serial++); - } - } - } else { m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID); } + +// IInventoryService invService = m_scene.InventoryService; +// bool resetwearable = false; +// if (invService.GetRootFolder(userID) != null) +// { +// for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) +// { +// for (int j = 0; j < appearance.Wearables[i].Count; j++) +// { +// // Check if the default wearables are not set +// if (appearance.Wearables[i][j].ItemID == UUID.Zero) +// { +// switch ((WearableType) i) +// { +// case WearableType.Eyes: +// case WearableType.Hair: +// case WearableType.Shape: +// case WearableType.Skin: +// //case WearableType.Underpants: +// TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance); +// resetwearable = true; +// m_log.Warn("[AVFACTORY]: UUID.Zero Wearables, passing fake values."); +// resetwearable = true; +// break; +// +// } +// continue; +// } +// +// // Ignore ruth's assets except for the body parts! missing body parts fail avatar appearance on V1 +// if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID) +// { +// switch ((WearableType)i) +// { +// case WearableType.Eyes: +// case WearableType.Hair: +// case WearableType.Shape: +// case WearableType.Skin: +// //case WearableType.Underpants: +// TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance); +// +// m_log.WarnFormat("[AVFACTORY]: {0} Default Wearables, passing existing values.", (WearableType)i); +// resetwearable = true; +// break; +// +// } +// continue; +// } +// +// InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); +// baseItem = invService.GetItem(baseItem); +// +// if (baseItem != null) +// { +// appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID); +// int unmodifiedWearableIndexForClosure = i; +// m_scene.AssetService.Get(baseItem.AssetID.ToString(), this, +// delegate(string x, object y, AssetBase z) +// { +// if (z == null) +// { +// TryAndRepairBrokenWearable( +// (WearableType)unmodifiedWearableIndexForClosure, invService, +// userID, appearance); +// } +// }); +// } +// else +// { +// m_log.ErrorFormat( +// "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default", +// appearance.Wearables[i][j].ItemID, (WearableType)i); +// +// TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance); +// resetwearable = true; +// +// } +// } +// } +// +// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason.... +// if (appearance.Wearables[(int) WearableType.Eyes] == null) +// { +// m_log.WarnFormat("[AVFACTORY]: {0} Eyes are Null, passing existing values.", (WearableType.Eyes)); +// +// TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance); +// resetwearable = true; +// } +// else +// { +// if (appearance.Wearables[(int) WearableType.Eyes][0].ItemID == UUID.Zero) +// { +// m_log.WarnFormat("[AVFACTORY]: Eyes are UUID.Zero are broken, {0} {1}", +// appearance.Wearables[(int) WearableType.Eyes][0].ItemID, +// appearance.Wearables[(int) WearableType.Eyes][0].AssetID); +// TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance); +// resetwearable = true; +// +// } +// +// } +// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason.... +// if (appearance.Wearables[(int)WearableType.Shape] == null) +// { +// m_log.WarnFormat("[AVFACTORY]: {0} shape is Null, passing existing values.", (WearableType.Shape)); +// +// TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance); +// resetwearable = true; +// } +// else +// { +// if (appearance.Wearables[(int)WearableType.Shape][0].ItemID == UUID.Zero) +// { +// m_log.WarnFormat("[AVFACTORY]: Shape is UUID.Zero and broken, {0} {1}", +// appearance.Wearables[(int)WearableType.Shape][0].ItemID, +// appearance.Wearables[(int)WearableType.Shape][0].AssetID); +// TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance); +// resetwearable = true; +// +// } +// +// } +// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason.... +// if (appearance.Wearables[(int)WearableType.Hair] == null) +// { +// m_log.WarnFormat("[AVFACTORY]: {0} Hair is Null, passing existing values.", (WearableType.Hair)); +// +// TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance); +// resetwearable = true; +// } +// else +// { +// if (appearance.Wearables[(int)WearableType.Hair][0].ItemID == UUID.Zero) +// { +// m_log.WarnFormat("[AVFACTORY]: Hair is UUID.Zero and broken, {0} {1}", +// appearance.Wearables[(int)WearableType.Hair][0].ItemID, +// appearance.Wearables[(int)WearableType.Hair][0].AssetID); +// TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance); +// resetwearable = true; +// +// } +// +// } +// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason.... +// if (appearance.Wearables[(int)WearableType.Skin] == null) +// { +// m_log.WarnFormat("[AVFACTORY]: {0} Skin is Null, passing existing values.", (WearableType.Skin)); +// +// TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance); +// resetwearable = true; +// } +// else +// { +// if (appearance.Wearables[(int)WearableType.Skin][0].ItemID == UUID.Zero) +// { +// m_log.WarnFormat("[AVFACTORY]: Skin is UUID.Zero and broken, {0} {1}", +// appearance.Wearables[(int)WearableType.Skin][0].ItemID, +// appearance.Wearables[(int)WearableType.Skin][0].AssetID); +// TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance); +// resetwearable = true; +// +// } +// +// } +// if (resetwearable) +// { +// ScenePresence presence = null; +// if (m_scene.TryGetScenePresence(userID, out presence)) +// { +// presence.ControllingClient.SendWearables(presence.Appearance.Wearables, +// presence.Appearance.Serial++); +// } +// } +// +// } +// else +// { +// m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID); +// } } + private void TryAndRepairBrokenWearable(WearableType type, IInventoryService invService, UUID userID,AvatarAppearance appearance) { UUID defaultwearable = GetDefaultItem(type); @@ -957,6 +1008,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory } } } + private UUID GetDefaultItem(WearableType wearable) { // These are ruth diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs index 7bf19c268f..c51b30fe6e 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs @@ -282,7 +282,17 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage string uasURL = circuit.ServiceURLs["HomeURI"].ToString(); m_log.DebugFormat("[HG MESSAGE TRANSFER]: getting UUI of user {0} from {1}", toAgent, uasURL); UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uasURL); - return uasConn.GetUUI(fromAgent, toAgent); + + string agentUUI = string.Empty; + try + { + agentUUI = uasConn.GetUUI(fromAgent, toAgent); + } + catch (Exception e) { + m_log.Debug("[HG MESSAGE TRANSFER]: GetUUI call failed ", e); + } + + return agentUUI; } } } diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs index 2da0a7461c..f3e757acf3 100644 --- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs @@ -1164,7 +1164,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles UserAgentServiceConnector uConn = new UserAgentServiceConnector(home_url); - Dictionary account = uConn.GetUserInfo(userID); + Dictionary account; + try + { + account = uConn.GetUserInfo(userID); + } + catch (Exception e) + { + m_log.Debug("[PROFILES]: GetUserInfo call failed ", e); + account = new Dictionary(); + } if (account.Count > 0) { diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index a038f73733..c9adc37eb1 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -464,7 +464,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.Name, position, sp.Scene.RegionInfo.RegionName); // Teleport within the same region - if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) + if (!sp.Scene.PositionIsInCurrentRegion(position) || position.Z < 0) { Vector3 emergencyPos = new Vector3(128, 128, 128); @@ -580,7 +580,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer MapBlockData block = new MapBlockData(); block.X = (ushort)regX; block.Y = (ushort)regY; - block.Access = 254; // == not there + block.Access = (byte)SimAccess.Down; List blocks = new List(); blocks.Add(block); @@ -713,10 +713,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - uint newRegionX = (uint)(reg.RegionHandle >> 40); - uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); - uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); - uint oldRegionY = (((uint)(sp.Scene.RegionInfo.RegionHandle)) >> 8); + uint newRegionX, newRegionY, oldRegionX, oldRegionY; + Util.RegionHandleToRegionLoc(reg.RegionHandle, out newRegionX, out newRegionY); + Util.RegionHandleToRegionLoc(sp.Scene.RegionInfo.RegionHandle, out oldRegionX, out oldRegionY); ulong destinationHandle = finalDestination.RegionHandle; @@ -1333,6 +1332,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return region; } + // This returns 'true' if the new region already has a child agent for our + // incoming agent. The implication is that, if 'false', we have to create the + // child and then teleport into the region. protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY) { if (m_regionCombinerModule != null && m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID)) @@ -1357,20 +1359,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY); } - protected virtual bool IsOutsideRegion(Scene s, Vector3 pos) - { - if (s.TestBorderCross(pos, Cardinals.N)) - return true; - if (s.TestBorderCross(pos, Cardinals.S)) - return true; - if (s.TestBorderCross(pos, Cardinals.E)) - return true; - if (s.TestBorderCross(pos, Cardinals.W)) - return true; - - return false; - } - #endregion #region Landmark Teleport @@ -1455,10 +1443,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // see that it is actually outside the current region), find the new region that the // point is actually in. // Returns the coordinates and information of the new region or 'null' of it doesn't exist. - public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos) + public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, + out string version, out Vector3 newpos, out string failureReason) { version = String.Empty; newpos = pos; + failureReason = string.Empty; // m_log.DebugFormat( // "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); @@ -1475,12 +1465,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (neighbourRegion != null) { // Compute the entity's position relative to the new region - newpos = new Vector3( (float)(presenceWorldX - (double)neighbourRegion.RegionLocX), + newpos = new Vector3((float)(presenceWorldX - (double)neighbourRegion.RegionLocX), (float)(presenceWorldY - (double)neighbourRegion.RegionLocY), pos.Z); if (m_bannedRegionCache.IfBanned(neighbourRegion.RegionHandle, agentID)) { + failureReason = "Cannot region cross into banned parcel"; neighbourRegion = null; } else @@ -1490,15 +1481,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } // Check to see if we have access to the target region. - string reason; if (neighbourRegion != null - && !scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason)) + && !scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out failureReason)) { // remember banned m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID); neighbourRegion = null; } } + else + { + // The destination region just doesn't exist + failureReason = "Cannot cross into non-existant region"; + } if (neighbourRegion == null) m_log.DebugFormat("{0} GetDestination: region not found. Old region name={1} at <{2},{3}> of size <{4},{5}>. Old pos={6}", @@ -1521,11 +1516,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer uint y; Vector3 newpos; string version; + string failureReason; - GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out version, out newpos); + GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, + out version, out newpos, out failureReason); if (neighbourRegion == null) { - agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); + agent.ControllingClient.SendAlertMessage(failureReason); return false; } @@ -1534,6 +1531,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); + Scene.EventManager.TriggerCrossAgentToNewRegion(agent, isFlying, neighbourRegion); + return true; } @@ -2077,7 +2076,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public NotFoundLocationCache() { } - // Add an area to the lost of 'not found' places. The area is the snapped region + // Add an area to the list of 'not found' places. The area is the snapped region // area around the added point. public void Add(double pX, double pY) { @@ -2305,22 +2304,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// private void GetMegaregionViewRange(out Vector2 swCorner, out Vector2 neCorner) { - Border[] northBorders = Scene.NorthBorders.ToArray(); - Border[] eastBorders = Scene.EastBorders.ToArray(); - Vector2 extent = Vector2.Zero; - for (int i = 0; i < eastBorders.Length; i++) - { - extent.X = (eastBorders[i].BorderLine.Z > extent.X) ? eastBorders[i].BorderLine.Z : extent.X; - } - for (int i = 0; i < northBorders.Length; i++) - { - extent.Y = (northBorders[i].BorderLine.Z > extent.Y) ? northBorders[i].BorderLine.Z : extent.Y; - } - // Loss of fraction on purpose - extent.X = ((int)extent.X / (int)Constants.RegionSize); - extent.Y = ((int)extent.Y / (int)Constants.RegionSize); + if (m_regionCombinerModule != null) + { + Vector2 megaRegionSize = m_regionCombinerModule.GetSizeOfMegaregion(Scene.RegionInfo.RegionID); + extent.X = (float)Util.WorldToRegionLoc((uint)megaRegionSize.X); + extent.Y = (float)Util.WorldToRegionLoc((uint)megaRegionSize.Y); + } swCorner.X = Scene.RegionInfo.RegionLocX - 1; swCorner.Y = Scene.RegionInfo.RegionLocY - 1; diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 09b19757ee..e354522624 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -462,7 +462,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer IUserAgentService userAgentService = new UserAgentServiceConnector(aCircuit.ServiceURLs["HomeURI"].ToString()); Vector3 position = Vector3.UnitY, lookAt = Vector3.UnitY; - GridRegion finalDestination = userAgentService.GetHomeRegion(aCircuit.AgentID, out position, out lookAt); + + GridRegion finalDestination = null; + try + { + finalDestination = userAgentService.GetHomeRegion(aCircuit.AgentID, out position, out lookAt); + } + catch (Exception e) + { + m_log.Debug("[HG ENTITY TRANSFER MODULE]: GetHomeRegion call failed ", e); + } + if (finalDestination == null) { client.SendTeleportFailed("Your home region could not be found"); diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs index 245c808b6c..7b89c2c94f 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs @@ -130,7 +130,17 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement } UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uriStr); - UUID userID = uasConn.GetUUID(names[0], names[1]); + + UUID userID = UUID.Zero; + try + { + userID = uasConn.GetUUID(names[0], names[1]); + } + catch (Exception e) + { + m_log.Debug("[USER MANAGEMENT MODULE]: GetUUID call failed ", e); + } + if (!userID.Equals(UUID.Zero)) { UserData ud = new UserData(); diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index 3fb51958e9..9f0a7198ab 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -473,7 +473,16 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement // serverType, userdata.HomeURL, userID); UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL); - userdata.ServerURLs = uConn.GetServerURLs(userID); + try + { + userdata.ServerURLs = uConn.GetServerURLs(userID); + } + catch (Exception e) + { + m_log.Debug("[USER MANAGEMENT MODULE]: GetServerURLs call failed ", e); + userdata.ServerURLs = new Dictionary(); + } + if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null) return userdata.ServerURLs[serverType].ToString(); } diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs index 79a409dad5..8a649ab721 100644 --- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs +++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs @@ -126,7 +126,8 @@ namespace OpenSim.Region.CoreModules.Hypergrid foreach (MapBlockData b in mapBlocks) { b.Name = string.Empty; - b.Access = 254; // means 'simulator is offline'. We need this because the viewer ignores 255's + // Set 'simulator is offline'. We need this because the viewer ignores SimAccess.Unknown (255) + b.Access = (byte)SimAccess.Down; } m_log.DebugFormat("[HG MAP]: Resetting {0} blocks", mapBlocks.Count); diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/LocalNeighbourServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/LocalNeighbourServiceConnector.cs index 56d99372e1..bda354fd94 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/LocalNeighbourServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/LocalNeighbourServiceConnector.cs @@ -125,14 +125,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour public OpenSim.Services.Interfaces.GridRegion HelloNeighbour(ulong regionHandle, RegionInfo thisRegion) { uint x, y; - Utils.LongToUInts(regionHandle, out x, out y); + Util.RegionHandleToRegionLoc(regionHandle, out x, out y); foreach (Scene s in m_Scenes) { if (s.RegionInfo.RegionHandle == regionHandle) { m_log.DebugFormat("[LOCAL NEIGHBOUR SERVICE CONNECTOR]: HelloNeighbour from region {0} to neighbour {1} at {2}-{3}", - thisRegion.RegionName, s.Name, Util.WorldToRegionLoc(x), Util.WorldToRegionLoc(y) ); + thisRegion.RegionName, s.Name, x, y ); //m_log.Debug("[NEIGHBOUR CONNECTOR]: Found region to SendHelloNeighbour"); return s.IncomingHelloNeighbour(thisRegion); diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index 0c4b79b948..2e638d4cc2 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -483,7 +483,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); // Happily this does not do much to the object since it hasn't been added to the scene yet - if (sceneObject.AttachmentPoint == 0) + if (!sceneObject.IsAttachment) { if (m_displacement != Vector3.Zero || m_rotation != 0f) { diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs index 5728731a24..be328a7b54 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs @@ -631,16 +631,29 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap private warp_Texture GetTexture(UUID id) { warp_Texture ret = null; + byte[] asset = m_scene.AssetService.GetData(id.ToString()); + if (asset != null) { IJ2KDecoder imgDecoder = m_scene.RequestModuleInterface(); - Bitmap img = (Bitmap) imgDecoder.DecodeToImage(asset); + Bitmap img = null; + + try + { + img = (Bitmap)imgDecoder.DecodeToImage(asset); + } + catch (Exception e) + { + m_log.Warn(string.Format("[WARP 3D IMAGE MODULE]: Failed to decode asset {0}, exception ", id), e); + } + if (img != null) { return new warp_Texture(img); } } + return ret; } diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs index 1fb1aba7e2..c35f6b7535 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs @@ -214,7 +214,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap // final block, closing the search result MapBlockData data = new MapBlockData(); data.Agents = 0; - data.Access = 255; + data.Access = (byte)SimAccess.NonExistent; data.MapImageId = UUID.Zero; data.Name = ""; data.RegionFlags = 0; diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs index 709d8fc2ee..5d07a5f63c 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs @@ -92,11 +92,12 @@ namespace OpenSim.Region.Framework.Interfaces void EnableChildAgent(ScenePresence agent, GridRegion region); - GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos); + GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, + out Vector3 newpos, out string reason); void Cross(SceneObjectGroup sog, Vector3 position, bool silent); - ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version); + ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version); } public interface IUserAgentVerificationModule diff --git a/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs index e03ac5a26f..c6f531edd2 100644 --- a/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs @@ -55,5 +55,10 @@ namespace OpenSim.Region.Framework.Interfaces /// Currently, will throw an exception if this does not match a root region. /// Vector2 GetSizeOfMegaregion(UUID regionId); + + /// + /// Tests to see of position (relative to the region) is within the megaregion + /// + bool PositionIsInMegaregion(UUID currentRegion, int xx, int yy); } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 37b5776766..ba79964bcb 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -430,6 +430,9 @@ namespace OpenSim.Region.Framework.Scenes public delegate void IncomingInstantMessage(GridInstantMessage message); public event IncomingInstantMessage OnIncomingInstantMessage; + public delegate void CrossAgentToNewRegion(ScenePresence sp, bool isFlying, GridRegion newRegion); + public event CrossAgentToNewRegion OnCrossAgentToNewRegion; + public event IncomingInstantMessage OnUnhandledInstantMessage; public delegate void ClientClosed(UUID clientID, Scene scene); @@ -1960,6 +1963,27 @@ namespace OpenSim.Region.Framework.Scenes } } + public void TriggerCrossAgentToNewRegion(ScenePresence agent, bool isFlying, GridRegion newRegion) + { + CrossAgentToNewRegion handlerCrossAgentToNewRegion = OnCrossAgentToNewRegion; + if (handlerCrossAgentToNewRegion != null) + { + foreach (CrossAgentToNewRegion d in handlerCrossAgentToNewRegion.GetInvocationList()) + { + try + { + d(agent, isFlying, newRegion); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[EVENT MANAGER]: Delegate for TriggerCrossAgentToNewRegion failed - continuing. {0} {1}", + e.Message, e.StackTrace); + } + } + } + } + public void TriggerIncomingInstantMessage(GridInstantMessage message) { IncomingInstantMessage handlerIncomingInstantMessage = OnIncomingInstantMessage; diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 2f666c032c..676c000462 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -160,11 +160,6 @@ namespace OpenSim.Region.Framework.Scenes /// public SimStatsReporter StatsReporter { get; private set; } - public List NorthBorders = new List(); - public List EastBorders = new List(); - public List SouthBorders = new List(); - public List WestBorders = new List(); - /// /// Controls whether physics can be applied to prims. Even if false, prims still have entries in a /// PhysicsScene in order to perform collision detection @@ -218,7 +213,14 @@ namespace OpenSim.Region.Framework.Scenes protected float m_defaultDrawDistance = 255.0f; public float DefaultDrawDistance { - get { return m_defaultDrawDistance; } + // get { return m_defaultDrawDistance; } + get { + if (RegionInfo != null) + { + m_defaultDrawDistance = Math.Max(RegionInfo.RegionSizeX, RegionInfo.RegionSizeY); + } + return m_defaultDrawDistance; + } } private List m_AllowedViewers = new List(); @@ -349,7 +351,6 @@ namespace OpenSim.Region.Framework.Scenes // TODO: Possibly stop other classes being able to manipulate this directly. private SceneGraph m_sceneGraph; - private volatile int m_bordersLocked; private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing private volatile bool m_backingup; private Dictionary m_returns = new Dictionary(); @@ -426,18 +427,6 @@ namespace OpenSim.Region.Framework.Scenes set { m_splitRegionID = value; } } - public bool BordersLocked - { - get { return m_bordersLocked == 1; } - set - { - if (value == true) - m_bordersLocked = 1; - else - m_bordersLocked = 0; - } - } - public new float TimeDilation { get { return m_sceneGraph.PhysicsScene.TimeDilation; } @@ -1031,28 +1020,6 @@ namespace OpenSim.Region.Framework.Scenes PeriodicBackup = true; UseBackup = true; - BordersLocked = true; - Border northBorder = new Border(); - northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (float)RegionInfo.RegionSizeY); //<--- - northBorder.CrossDirection = Cardinals.N; - NorthBorders.Add(northBorder); - - Border southBorder = new Border(); - southBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue,0); //---> - southBorder.CrossDirection = Cardinals.S; - SouthBorders.Add(southBorder); - - Border eastBorder = new Border(); - eastBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (float)RegionInfo.RegionSizeY); //<--- - eastBorder.CrossDirection = Cardinals.E; - EastBorders.Add(eastBorder); - - Border westBorder = new Border(); - westBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue,0); //---> - westBorder.CrossDirection = Cardinals.W; - WestBorders.Add(westBorder); - BordersLocked = false; - m_eventManager = new EventManager(); m_permissions = new ScenePermissions(this); @@ -2445,201 +2412,34 @@ namespace OpenSim.Region.Framework.Scenes } // Simple test to see if a position is in the current region. - // Resuming the position is relative to the region so anything outside its bounds. + // This test is mostly used to see if a region crossing is necessary. + // Assuming the position is relative to the region so anything outside its bounds. // Return 'true' if position inside region. public bool PositionIsInCurrentRegion(Vector3 pos) { - bool ret = true; + bool ret = false; int xx = (int)Math.Floor(pos.X); int yy = (int)Math.Floor(pos.Y); - if (xx < 0 - || xx >= RegionInfo.RegionSizeX - || yy < 0 - || yy >= RegionInfo.RegionSizeY) - ret = false; + if (xx < 0 || yy < 0) + return false; + + IRegionCombinerModule regionCombinerModule = RequestModuleInterface(); + if (regionCombinerModule == null) + { + // Regular region. Just check for region size + if (xx < RegionInfo.RegionSizeX && yy < RegionInfo.RegionSizeY ) + ret = true; + } + else + { + // We're in a mega-region so see if we are still in that larger region + ret = regionCombinerModule.PositionIsInMegaregion(this.RegionInfo.RegionID, xx, yy); + } + return ret; } - public Border GetCrossedBorder(Vector3 position, Cardinals gridline) - { - if (BordersLocked) - { - switch (gridline) - { - case Cardinals.N: - lock (NorthBorders) - { - foreach (Border b in NorthBorders) - { - if (b.TestCross(position)) - return b; - } - } - break; - case Cardinals.S: - lock (SouthBorders) - { - foreach (Border b in SouthBorders) - { - if (b.TestCross(position)) - return b; - } - } - - break; - case Cardinals.E: - lock (EastBorders) - { - foreach (Border b in EastBorders) - { - if (b.TestCross(position)) - return b; - } - } - - break; - case Cardinals.W: - - lock (WestBorders) - { - foreach (Border b in WestBorders) - { - if (b.TestCross(position)) - return b; - } - } - break; - - } - } - else - { - switch (gridline) - { - case Cardinals.N: - foreach (Border b in NorthBorders) - { - if (b.TestCross(position)) - return b; - } - - break; - case Cardinals.S: - foreach (Border b in SouthBorders) - { - if (b.TestCross(position)) - return b; - } - break; - case Cardinals.E: - foreach (Border b in EastBorders) - { - if (b.TestCross(position)) - return b; - } - - break; - case Cardinals.W: - foreach (Border b in WestBorders) - { - if (b.TestCross(position)) - return b; - } - break; - - } - } - - return null; - } - - public bool TestBorderCross(Vector3 position, Cardinals border) - { - if (BordersLocked) - { - switch (border) - { - case Cardinals.N: - lock (NorthBorders) - { - foreach (Border b in NorthBorders) - { - if (b.TestCross(position)) - return true; - } - } - break; - case Cardinals.E: - lock (EastBorders) - { - foreach (Border b in EastBorders) - { - if (b.TestCross(position)) - return true; - } - } - break; - case Cardinals.S: - lock (SouthBorders) - { - foreach (Border b in SouthBorders) - { - if (b.TestCross(position)) - return true; - } - } - break; - case Cardinals.W: - lock (WestBorders) - { - foreach (Border b in WestBorders) - { - if (b.TestCross(position)) - return true; - } - } - break; - } - } - else - { - switch (border) - { - case Cardinals.N: - foreach (Border b in NorthBorders) - { - if (b.TestCross(position)) - return true; - } - break; - case Cardinals.E: - foreach (Border b in EastBorders) - { - if (b.TestCross(position)) - return true; - } - break; - case Cardinals.S: - foreach (Border b in SouthBorders) - { - if (b.TestCross(position)) - return true; - } - break; - case Cardinals.W: - foreach (Border b in WestBorders) - { - if (b.TestCross(position)) - return true; - } - break; - } - } - return false; - } - - /// /// Called when objects or attachments cross the border, or teleport, between regions. /// @@ -3874,61 +3674,11 @@ namespace OpenSim.Region.Framework.Scenes { // CleanDroppedAttachments(); - if (TestBorderCross(acd.startpos, Cardinals.E)) - { - Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.E); - acd.startpos.X = crossedBorder.BorderLine.Z - 1; - m_log.DebugFormat("{0} NewUserConnection Adjusted border E. startpos={1}", LogHeader, acd.startpos); - } - - if (TestBorderCross(acd.startpos, Cardinals.N)) - { - Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.N); - acd.startpos.Y = crossedBorder.BorderLine.Z - 1; - } - - //Mitigate http://opensimulator.org/mantis/view.php?id=3522 - // Check if start position is outside of region - // If it is, check the Z start position also.. if not, leave it alone. - if (BordersLocked) - { - lock (EastBorders) - { - if (acd.startpos.X > EastBorders[0].BorderLine.Z) - { - m_log.Warn("FIX AGENT POSITION"); - acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; - if (acd.startpos.Z > 720) - acd.startpos.Z = 720; - } - } - lock (NorthBorders) - { - if (acd.startpos.Y > NorthBorders[0].BorderLine.Z) - { - m_log.Warn("FIX Agent POSITION"); - acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; - if (acd.startpos.Z > 720) - acd.startpos.Z = 720; - } - } - } else - { - if (acd.startpos.X > EastBorders[0].BorderLine.Z) - { - m_log.Warn("FIX AGENT POSITION"); - acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; - if (acd.startpos.Z > 720) - acd.startpos.Z = 720; - } - if (acd.startpos.Y > NorthBorders[0].BorderLine.Z) - { - m_log.Warn("FIX Agent POSITION"); - acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; - if (acd.startpos.Z > 720) - acd.startpos.Z = 720; - } - } + // Make sure avatar position is in the region (why it wouldn't be is a mystery but do sanity checking) + if (acd.startpos.X < 0) acd.startpos.X = 1f; + if (acd.startpos.X >= RegionInfo.RegionSizeX) acd.startpos.X = RegionInfo.RegionSizeX - 1f; + if (acd.startpos.Y < 0) acd.startpos.Y = 1f; + if (acd.startpos.Y >= RegionInfo.RegionSizeY) acd.startpos.Y = RegionInfo.RegionSizeY - 1f; // m_log.DebugFormat( // "[SCENE]: Found telehub object {0} for new user connection {1} to {2}", diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index c6b98ca6f2..73a30f3d32 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -429,7 +429,7 @@ namespace OpenSim.Region.Framework.Scenes /// public bool IsAttachmentCheckFull() { - return (IsAttachment || (m_rootPart.Shape.PCode == 9 && m_rootPart.Shape.State != 0)); + return (IsAttachment || (m_rootPart.Shape.PCode == (byte)PCodeEnum.Primitive && m_rootPart.Shape.State != 0)); } private struct avtocrossInfo @@ -451,23 +451,15 @@ namespace OpenSim.Region.Framework.Scenes if (Scene != null) { if ( - // (Scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) - // || Scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W) - // || Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) - // || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S)) - // Experimental change for better border crossings. - // The commented out original lines above would, it seems, trigger - // a border crossing a little early or late depending on which - // direction the object was moving. - (Scene.TestBorderCross(val, Cardinals.E) - || Scene.TestBorderCross(val, Cardinals.W) - || Scene.TestBorderCross(val, Cardinals.N) - || Scene.TestBorderCross(val, Cardinals.S)) - && !IsAttachmentCheckFull() && (!Scene.LoadingPrims)) + !Scene.PositionIsInCurrentRegion(val) + && !IsAttachmentCheckFull() + && (!Scene.LoadingPrims) + ) { IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface(); string version = String.Empty; Vector3 newpos = Vector3.Zero; + string failureReason = String.Empty; OpenSim.Services.Interfaces.GridRegion destination = null; if (m_rootPart.KeyframeMotion != null) @@ -485,7 +477,7 @@ namespace OpenSim.Region.Framework.Scenes // We set the avatar position as being the object // position to get the region to send to - if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out version, out newpos)) == null) + if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out version, out newpos, out failureReason)) == null) { canCross = false; break; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 1cf77267e4..db4e285014 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2479,13 +2479,10 @@ namespace OpenSim.Region.Framework.Scenes if (pa != null) { - Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); - - if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N) - | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S) - | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E) - | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W)) + Vector3 newpos = pa.Position; + if (!ParentGroup.Scene.PositionIsInCurrentRegion(newpos)) { + // Setting position outside current region will start region crossing ParentGroup.AbsolutePosition = newpos; return; } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 715a9b67a1..d4af9fc11f 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1057,30 +1057,32 @@ namespace OpenSim.Region.Framework.Scenes m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); - UUID groupUUID = UUID.Zero; - string GroupName = string.Empty; + UUID groupUUID = ControllingClient.ActiveGroupId; + string groupName = string.Empty; ulong groupPowers = 0; // ---------------------------------- // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status try { - if (gm != null) + if (groupUUID != UUID.Zero && gm != null) { - groupUUID = ControllingClient.ActiveGroupId; GroupRecord record = gm.GetGroupRecord(groupUUID); if (record != null) - GroupName = record.GroupName; + groupName = record.GroupName; + GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid); + if (groupMembershipData != null) groupPowers = groupMembershipData.GroupPowers; } - ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName, - Grouptitle); + + ControllingClient.SendAgentDataUpdate( + m_uuid, groupUUID, Firstname, Lastname, groupPowers, groupName, Grouptitle); } catch (Exception e) { - m_log.Debug("[AGENTUPDATE]: " + e.ToString()); + m_log.Error("[AGENTUPDATE]: Error ", e); } // ------------------------------------ @@ -3471,8 +3473,6 @@ namespace OpenSim.Region.Framework.Scenes Vector3 pos2 = AbsolutePosition; Vector3 origPosition = pos2; Vector3 vel = Velocity; - int neighbor = 0; - int[] fix = new int[2]; // Compute the avatar position in the next physics tick. // If the avatar will be crossing, we force the crossing to happen now @@ -3505,23 +3505,13 @@ namespace OpenSim.Region.Framework.Scenes if (m_requestedSitTargetUUID == UUID.Zero) { m_log.DebugFormat("{0} CheckForBorderCrossing: Crossing failed. Restoring old position.", LogHeader); - const float borderFudge = 0.1f; - if (origPosition.X < 0) - origPosition.X = borderFudge; - else if (origPosition.X > (float)m_scene.RegionInfo.RegionSizeX) - origPosition.X = (float)m_scene.RegionInfo.RegionSizeX - borderFudge; - if (origPosition.Y < 0) - origPosition.Y = borderFudge; - else if (origPosition.Y > (float)m_scene.RegionInfo.RegionSizeY) - origPosition.Y = (float)m_scene.RegionInfo.RegionSizeY - borderFudge; Velocity = Vector3.Zero; - AbsolutePosition = origPosition; + AbsolutePosition = EnforceSanityOnPosition(origPosition); AddToPhysicalScene(isFlying); } } - } } else @@ -3539,6 +3529,36 @@ namespace OpenSim.Region.Framework.Scenes } } + // Given a position, make sure it is within the current region. + // If just outside some border, the returned position will be just inside the border on that side. + private Vector3 EnforceSanityOnPosition(Vector3 origPosition) + { + const float borderFudge = 0.1f; + Vector3 ret = origPosition; + + // Sanity checking on the position to make sure it is in the region we couldn't cross from + float extentX = (float)m_scene.RegionInfo.RegionSizeX; + float extentY = (float)m_scene.RegionInfo.RegionSizeY; + IRegionCombinerModule combiner = m_scene.RequestModuleInterface(); + if (combiner != null) + { + // If a mega-region, the size could be much bigger + Vector2 megaExtent = combiner.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID); + extentX = megaExtent.X; + extentY = megaExtent.Y; + } + if (ret.X < 0) + ret.X = borderFudge; + else if (ret.X >= extentX) + ret.X = extentX - borderFudge; + if (ret.Y < 0) + ret.Y = borderFudge; + else if (ret.Y >= extentY) + ret.Y = extentY - borderFudge; + + return ret; + } + /// /// Moves the agent outside the region bounds /// Tells neighbor region that we're crossing to it diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index e28d0c2da3..a040f43d66 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -1012,7 +1012,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups Hashtable respData = (Hashtable)resp.Value; if (respData.Contains("error") && !respData.Contains("succeed")) { - LogRespDataToConsoleError(respData); + LogRespDataToConsoleError(requestingAgentID, function, param, respData); } return respData; @@ -1040,20 +1040,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return error; } - private void LogRespDataToConsoleError(Hashtable respData) + private void LogRespDataToConsoleError(UUID requestingAgentID, string function, Hashtable param, Hashtable respData) { - m_log.Error("[XMLRPC-GROUPS-CONNECTOR]: Error:"); - - foreach (string key in respData.Keys) - { - m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: Key: {0}", key); - - string[] lines = respData[key].ToString().Split(new char[] { '\n' }); - foreach (string line in lines) - { - m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0}", line); - } - } + m_log.ErrorFormat( + "[XMLRPC-GROUPS-CONNECTOR]: Error when calling {0} for {1} with params {2}. Response params are {3}", + function, requestingAgentID, Util.PrettyFormatToSingleLine(param), Util.PrettyFormatToSingleLine(respData)); } /// diff --git a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs index 29b39e031a..5fb74b01ea 100644 --- a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs +++ b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs @@ -116,37 +116,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments + "If teleport is true then some extra teleport debug information is logged.\n" + "If updates is true then any frame which exceeds double the maximum desired frame time is logged.", HandleDebugSceneSetCommand); - - scene.AddCommand( - "Regions", - this, "show borders", "show borders", "Show border information for regions", HandleShowBordersCommand); - } - - private void HandleShowBordersCommand(string module, string[] args) - { - StringBuilder sb = new StringBuilder(); - sb.AppendFormat("Borders for {0}:\n", m_scene.Name); - - ConsoleDisplayTable cdt = new ConsoleDisplayTable(); - cdt.AddColumn("Cross Direction", 15); - cdt.AddColumn("Line", 34); - cdt.AddColumn("Trigger Region", 14); - - foreach (Border b in m_scene.NorthBorders) - cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY)); - - foreach (Border b in m_scene.EastBorders) - cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY)); - - foreach (Border b in m_scene.SouthBorders) - cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY)); - - foreach (Border b in m_scene.WestBorders) - cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY)); - - cdt.AddToStringBuilder(sb); - - MainConsole.Instance.Output(sb.ToString()); } private void HandleDebugSceneGetCommand(string module, string[] args) diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index 7127c73c18..a7ffad08c0 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -44,6 +44,7 @@ namespace OpenSim.Region.RegionCombinerModule public class RegionCombinerModule : ISharedRegionModule, IRegionCombinerModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static string LogHeader = "[REGION COMBINER MODULE]"; public string Name { @@ -134,6 +135,49 @@ namespace OpenSim.Region.RegionCombinerModule throw new Exception(string.Format("Region with id {0} not found", regionId)); } + // Test to see if this postiion (relative to the region) is within the area covered + // by this megaregion. + public bool PositionIsInMegaregion(UUID currentRegion, int xx, int yy) + { + bool ret = false; + if (xx < 0 || yy < 0) + return ret; + + foreach (RegionConnections rootRegion in m_regions.Values) + { + if (currentRegion == rootRegion.RegionId) + { + // The caller is in the root region so this is an easy test + if (xx < rootRegion.XEnd && yy < rootRegion.YEnd) + { + ret = true; + } + break; + } + else + { + // Maybe the caller is in one of the sub-regions + foreach (RegionData childRegion in rootRegion.ConnectedRegions) + { + if (currentRegion == childRegion.RegionId) + { + // This is a child. Diddle the offsets and check if in + Vector3 positionInMegaregion = childRegion.Offset; + positionInMegaregion.X += xx; + positionInMegaregion.Y += yy; + if (positionInMegaregion.X < rootRegion.XEnd && positionInMegaregion.Y < rootRegion.YEnd) + { + ret = true; + } + break; + } + } + } + } + + return ret; + } + private void NewPresence(ScenePresence presence) { if (presence.IsChildAgent) @@ -220,27 +264,6 @@ namespace OpenSim.Region.RegionCombinerModule // */ - // Give each region a standard set of non-infinite borders - Border northBorder = new Border(); - northBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, (int)Constants.RegionSize); //<--- - northBorder.CrossDirection = Cardinals.N; - scene.NorthBorders[0] = northBorder; - - Border southBorder = new Border(); - southBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, 0); //---> - southBorder.CrossDirection = Cardinals.S; - scene.SouthBorders[0] = southBorder; - - Border eastBorder = new Border(); - eastBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, (int)Constants.RegionSize); //<--- - eastBorder.CrossDirection = Cardinals.E; - scene.EastBorders[0] = eastBorder; - - Border westBorder = new Border(); - westBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, 0); //---> - westBorder.CrossDirection = Cardinals.W; - scene.WestBorders[0] = westBorder; - RegionConnections newConn = new RegionConnections(); newConn.ConnectedRegions = new List(); newConn.RegionScene = scene; @@ -248,8 +271,8 @@ namespace OpenSim.Region.RegionCombinerModule newConn.RegionId = scene.RegionInfo.originRegionID; newConn.X = scene.RegionInfo.RegionLocX; newConn.Y = scene.RegionInfo.RegionLocY; - newConn.XEnd = (int)Constants.RegionSize; - newConn.YEnd = (int)Constants.RegionSize; + newConn.XEnd = scene.RegionInfo.RegionSizeX; + newConn.YEnd = scene.RegionInfo.RegionSizeX; lock (m_regions) { @@ -415,6 +438,11 @@ namespace OpenSim.Region.RegionCombinerModule */ #endregion + + // Check to see if this new region is adjacent to the root region. + // Note that we expect the regions to be combined from the root region outward + // thus the requirement for the ordering in the configuration files. + // If we're one region over +x y (i.e. root region is to the west) //xxx //xxy @@ -431,7 +459,7 @@ namespace OpenSim.Region.RegionCombinerModule //xxx if (rootConn.PosX >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY) { - connectedYN = DoWorkForOneRegionOverXPlusY(rootConn, newConn, scene); + connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene); break; } @@ -441,9 +469,8 @@ namespace OpenSim.Region.RegionCombinerModule //xxx if (rootConn.PosX + rootConn.XEnd >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY) { - connectedYN = DoWorkForOneRegionOverPlusXPlusY(rootConn, newConn, scene); + connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene); break; - } } @@ -453,20 +480,20 @@ namespace OpenSim.Region.RegionCombinerModule DoWorkForRootRegion(newConn, scene); } } - - // Set up infinite borders around the entire AABB of the combined ConnectedRegions - AdjustLargeRegionBounds(); } private bool DoWorkForOneRegionOverPlusXY(RegionConnections rootConn, RegionConnections newConn, Scene scene) { + // Offset (in meters) from the base of this region to the base of the root region. Vector3 offset = Vector3.Zero; offset.X = newConn.PosX - rootConn.PosX; offset.Y = newConn.PosY - rootConn.PosY; + // The new total size of the region (in meters) + // We just extend the X and Y dimensions so the extent might temporarily include areas without regions. Vector3 extents = Vector3.Zero; - extents.Y = rootConn.YEnd; - extents.X = rootConn.XEnd + newConn.XEnd; + extents.X = Math.Max(rootConn.XEnd, offset.X + newConn.RegionScene.RegionInfo.RegionSizeX); + extents.Y = Math.Max(rootConn.YEnd, offset.Y + newConn.RegionScene.RegionInfo.RegionSizeY); rootConn.UpdateExtents(extents); @@ -475,9 +502,6 @@ namespace OpenSim.Region.RegionCombinerModule rootConn.RegionScene.RegionInfo.RegionName, newConn.RegionScene.RegionInfo.RegionName, offset, extents); - scene.BordersLocked = true; - rootConn.RegionScene.BordersLocked = true; - RegionData ConnectedRegion = new RegionData(); ConnectedRegion.Offset = offset; ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; @@ -490,34 +514,10 @@ namespace OpenSim.Region.RegionCombinerModule // Inform Child region that it needs to forward it's terrain to the root region scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); - // Extend the borders as appropriate - lock (rootConn.RegionScene.EastBorders) - rootConn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; - - lock (rootConn.RegionScene.NorthBorders) - rootConn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize; - - lock (rootConn.RegionScene.SouthBorders) - rootConn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize; - - lock (scene.WestBorders) - { - scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - rootConn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West - - // Trigger auto teleport to root region - scene.WestBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; - scene.WestBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; - } - // Reset Terrain.. since terrain loads before we get here, we need to load // it again so it loads in the root region - scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); - // Unlock borders - rootConn.RegionScene.BordersLocked = false; - scene.BordersLocked = false; - // Create a client event forwarder and add this region's events to the root region. if (rootConn.ClientEventForwarder != null) rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); @@ -525,6 +525,9 @@ namespace OpenSim.Region.RegionCombinerModule return true; } + /* + * 20140215 radams1: The border stuff was removed and the addition of regions to the mega-regions + * was generalized. These functions are not needed for the generalized solution but left for reference. private bool DoWorkForOneRegionOverXPlusY(RegionConnections rootConn, RegionConnections newConn, Scene scene) { Vector3 offset = Vector3.Zero; @@ -536,9 +539,6 @@ namespace OpenSim.Region.RegionCombinerModule extents.X = rootConn.XEnd; rootConn.UpdateExtents(extents); - scene.BordersLocked = true; - rootConn.RegionScene.BordersLocked = true; - RegionData ConnectedRegion = new RegionData(); ConnectedRegion.Offset = offset; ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; @@ -553,30 +553,11 @@ namespace OpenSim.Region.RegionCombinerModule rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); - lock (rootConn.RegionScene.NorthBorders) - rootConn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; - - lock (rootConn.RegionScene.EastBorders) - rootConn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; - - lock (rootConn.RegionScene.WestBorders) - rootConn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; - - lock (scene.SouthBorders) - { - scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - rootConn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south - scene.SouthBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; - scene.SouthBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; - } - // Reset Terrain.. since terrain normally loads first. //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); - scene.BordersLocked = false; - rootConn.RegionScene.BordersLocked = false; - if (rootConn.ClientEventForwarder != null) rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); @@ -600,9 +581,6 @@ namespace OpenSim.Region.RegionCombinerModule extents.Y = rootConn.YEnd; extents.X = rootConn.XEnd; - scene.BordersLocked = true; - rootConn.RegionScene.BordersLocked = true; - RegionData ConnectedRegion = new RegionData(); ConnectedRegion.Offset = offset; ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; @@ -618,67 +596,10 @@ namespace OpenSim.Region.RegionCombinerModule rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); - lock (rootConn.RegionScene.NorthBorders) - { - if (rootConn.RegionScene.NorthBorders.Count == 1)// && 2) - { - //compound border - // already locked above - rootConn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; - - lock (rootConn.RegionScene.EastBorders) - rootConn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; - - lock (rootConn.RegionScene.WestBorders) - rootConn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; - } - } - - lock (scene.SouthBorders) - { - scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - rootConn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south - scene.SouthBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; - scene.SouthBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; - } - - lock (rootConn.RegionScene.EastBorders) - { - if (rootConn.RegionScene.EastBorders.Count == 1)// && conn.RegionScene.EastBorders.Count == 2) - { - rootConn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; - - lock (rootConn.RegionScene.NorthBorders) - rootConn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize; - - lock (rootConn.RegionScene.SouthBorders) - rootConn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize; - } - } - - lock (scene.WestBorders) - { - scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - rootConn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West - scene.WestBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; - scene.WestBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; - } - - /* - else - { - conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; - conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; - conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; - scene.SouthBorders[0].BorderLine.Z += (int)Constants.RegionSize; //auto teleport south - } - */ - - // Reset Terrain.. since terrain normally loads first. //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); - scene.BordersLocked = false; - rootConn.RegionScene.BordersLocked = false; if (rootConn.ClientEventForwarder != null) rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); @@ -687,6 +608,7 @@ namespace OpenSim.Region.RegionCombinerModule //scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset,extents); } + */ private void DoWorkForRootRegion(RegionConnections rootConn, Scene scene) { @@ -885,125 +807,6 @@ namespace OpenSim.Region.RegionCombinerModule // } // } - // Create a set of infinite borders around the whole aabb of the combined island. - private void AdjustLargeRegionBounds() - { - lock (m_regions) - { - foreach (RegionConnections rconn in m_regions.Values) - { - Vector3 offset = Vector3.Zero; - rconn.RegionScene.BordersLocked = true; - foreach (RegionData rdata in rconn.ConnectedRegions) - { - if (rdata.Offset.X > offset.X) offset.X = rdata.Offset.X; - if (rdata.Offset.Y > offset.Y) offset.Y = rdata.Offset.Y; - } - - lock (rconn.RegionScene.NorthBorders) - { - Border northBorder = null; - // If we don't already have an infinite border, create one. - if (!TryGetInfiniteBorder(rconn.RegionScene.NorthBorders, out northBorder)) - { - northBorder = new Border(); - rconn.RegionScene.NorthBorders.Add(northBorder); - } - - northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, - offset.Y + (int) Constants.RegionSize); //<--- - northBorder.CrossDirection = Cardinals.N; - } - - lock (rconn.RegionScene.SouthBorders) - { - Border southBorder = null; - // If we don't already have an infinite border, create one. - if (!TryGetInfiniteBorder(rconn.RegionScene.SouthBorders, out southBorder)) - { - southBorder = new Border(); - rconn.RegionScene.SouthBorders.Add(southBorder); - } - southBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, 0); //---> - southBorder.CrossDirection = Cardinals.S; - } - - lock (rconn.RegionScene.EastBorders) - { - Border eastBorder = null; - // If we don't already have an infinite border, create one. - if (!TryGetInfiniteBorder(rconn.RegionScene.EastBorders, out eastBorder)) - { - eastBorder = new Border(); - rconn.RegionScene.EastBorders.Add(eastBorder); - } - eastBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, offset.X + (int)Constants.RegionSize); - //<--- - eastBorder.CrossDirection = Cardinals.E; - } - - lock (rconn.RegionScene.WestBorders) - { - Border westBorder = null; - // If we don't already have an infinite border, create one. - if (!TryGetInfiniteBorder(rconn.RegionScene.WestBorders, out westBorder)) - { - westBorder = new Border(); - rconn.RegionScene.WestBorders.Add(westBorder); - - } - westBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, 0); //---> - westBorder.CrossDirection = Cardinals.W; - } - - rconn.RegionScene.BordersLocked = false; - } - } - } - - /// - /// Try and get an Infinite border out of a listT of borders - /// - /// - /// - /// - public static bool TryGetInfiniteBorder(List borders, out Border oborder) - { - // Warning! Should be locked before getting here! - foreach (Border b in borders) - { - if (b.BorderLine.X == float.MinValue && b.BorderLine.Y == float.MaxValue) - { - oborder = b; - return true; - } - } - - oborder = null; - return false; - } - - public RegionData GetRegionFromPosition(Vector3 pPosition) - { - pPosition = pPosition/(int) Constants.RegionSize; - int OffsetX = (int) pPosition.X; - int OffsetY = (int) pPosition.Y; - - lock (m_regions) - { - foreach (RegionConnections regConn in m_regions.Values) - { - foreach (RegionData reg in regConn.ConnectedRegions) - { - if (reg.Offset.X == OffsetX && reg.Offset.Y == OffsetY) - return reg; - } - } - } - - return new RegionData(); - } - public void ForwardPermissionRequests(RegionConnections BigRegion, Scene VirtualRegion) { if (BigRegion.PermissionModule == null) diff --git a/OpenSim/Region/RegionCombinerModule/RegionData.cs b/OpenSim/Region/RegionCombinerModule/RegionData.cs index bd0e398acd..42fca9f4bc 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionData.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionData.cs @@ -34,6 +34,7 @@ namespace OpenSim.Region.RegionCombinerModule { public UUID RegionId; public Scene RegionScene; + // Offset of this region from the base of the root region. public Vector3 Offset; } } \ No newline at end of file diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs index 20397a1cd2..f869060177 100644 --- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs @@ -78,7 +78,8 @@ namespace OpenSim.Services.Connectors.Hypergrid m_log.DebugFormat("[USER AGENT CONNECTOR]: Malformed Uri {0}: {1}", m_ServerURL, e.Message); } } - m_log.DebugFormat("[USER AGENT CONNECTOR]: new connector to {0} ({1})", url, m_ServerURL); + + //m_log.DebugFormat("[USER AGENT CONNECTOR]: new connector to {0} ({1})", url, m_ServerURL); } public UserAgentServiceConnector(IConfigSource config) @@ -190,6 +191,40 @@ namespace OpenSim.Services.Connectors.Hypergrid // no-op } + private Hashtable CallServer(string methodName, Hashtable hash) + { + IList paramList = new ArrayList(); + paramList.Add(hash); + + XmlRpcRequest request = new XmlRpcRequest(methodName, paramList); + + // Send and get reply + XmlRpcResponse response = null; + try + { + response = request.Send(m_ServerURL, 10000); + } + catch (Exception e) + { + m_log.DebugFormat("[USER AGENT CONNECTOR]: {0} call to {1} failed: {2}", methodName, m_ServerURL, e.Message); + throw; + } + + if (response.IsFault) + { + throw new Exception(string.Format("[USER AGENT CONNECTOR]: {0} call to {1} returned an error: {2}", methodName, m_ServerURL, response.FaultString)); + } + + hash = (Hashtable)response.Value; + + if (hash == null) + { + throw new Exception(string.Format("[USER AGENT CONNECTOR]: {0} call to {1} returned null", methodName, m_ServerURL)); + } + + return hash; + } + public GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt) { position = Vector3.UnitY; lookAt = Vector3.UnitY; @@ -197,101 +232,58 @@ namespace OpenSim.Services.Connectors.Hypergrid Hashtable hash = new Hashtable(); hash["userID"] = userID.ToString(); - IList paramList = new ArrayList(); - paramList.Add(hash); + hash = CallServer("get_home_region", hash); - XmlRpcRequest request = new XmlRpcRequest("get_home_region", paramList); - XmlRpcResponse response = null; - try - { - response = request.Send(m_ServerURL, 10000); - } - catch (Exception) - { + bool success; + if (!Boolean.TryParse((string)hash["result"], out success) || !success) return null; - } - if (response.IsFault) + GridRegion region = new GridRegion(); + + UUID.TryParse((string)hash["uuid"], out region.RegionID); + //m_log.Debug(">> HERE, uuid: " + region.RegionID); + int n = 0; + if (hash["x"] != null) { - return null; + Int32.TryParse((string)hash["x"], out n); + region.RegionLocX = n; + //m_log.Debug(">> HERE, x: " + region.RegionLocX); } - - hash = (Hashtable)response.Value; - //foreach (Object o in hash) - // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value); - try + if (hash["y"] != null) { - bool success = false; - Boolean.TryParse((string)hash["result"], out success); - if (success) - { - GridRegion region = new GridRegion(); - - UUID.TryParse((string)hash["uuid"], out region.RegionID); - //m_log.Debug(">> HERE, uuid: " + region.RegionID); - int n = 0; - if (hash["x"] != null) - { - Int32.TryParse((string)hash["x"], out n); - region.RegionLocX = n; - //m_log.Debug(">> HERE, x: " + region.RegionLocX); - } - if (hash["y"] != null) - { - Int32.TryParse((string)hash["y"], out n); - region.RegionLocY = n; - //m_log.Debug(">> HERE, y: " + region.RegionLocY); - } - if (hash["size_x"] != null) - { - Int32.TryParse((string)hash["size_x"], out n); - region.RegionSizeX = n; - //m_log.Debug(">> HERE, x: " + region.RegionLocX); - } - if (hash["size_y"] != null) - { - Int32.TryParse((string)hash["size_y"], out n); - region.RegionSizeY = n; - //m_log.Debug(">> HERE, y: " + region.RegionLocY); - } - if (hash["region_name"] != null) - { - region.RegionName = (string)hash["region_name"]; - //m_log.Debug(">> HERE, name: " + region.RegionName); - } - if (hash["hostname"] != null) - region.ExternalHostName = (string)hash["hostname"]; - if (hash["http_port"] != null) - { - uint p = 0; - UInt32.TryParse((string)hash["http_port"], out p); - region.HttpPort = p; - } - if (hash.ContainsKey("server_uri") && hash["server_uri"] != null) - region.ServerURI = (string)hash["server_uri"]; - - if (hash["internal_port"] != null) - { - int p = 0; - Int32.TryParse((string)hash["internal_port"], out p); - region.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), p); - } - if (hash["position"] != null) - Vector3.TryParse((string)hash["position"], out position); - if (hash["lookAt"] != null) - Vector3.TryParse((string)hash["lookAt"], out lookAt); - - // Successful return - return region; - } - + Int32.TryParse((string)hash["y"], out n); + region.RegionLocY = n; + //m_log.Debug(">> HERE, y: " + region.RegionLocY); } - catch (Exception) + if (hash["region_name"] != null) { - return null; + region.RegionName = (string)hash["region_name"]; + //m_log.Debug(">> HERE, name: " + region.RegionName); } + if (hash["hostname"] != null) + region.ExternalHostName = (string)hash["hostname"]; + if (hash["http_port"] != null) + { + uint p = 0; + UInt32.TryParse((string)hash["http_port"], out p); + region.HttpPort = p; + } + if (hash.ContainsKey("server_uri") && hash["server_uri"] != null) + region.ServerURI = (string)hash["server_uri"]; - return null; + if (hash["internal_port"] != null) + { + int p = 0; + Int32.TryParse((string)hash["internal_port"], out p); + region.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), p); + } + if (hash["position"] != null) + Vector3.TryParse((string)hash["position"], out position); + if (hash["lookAt"] != null) + Vector3.TryParse((string)hash["lookAt"], out lookAt); + + // Successful return + return region; } public bool IsAgentComingHome(UUID sessionID, string thisGridExternalName) @@ -500,50 +492,16 @@ namespace OpenSim.Services.Connectors.Hypergrid Hashtable hash = new Hashtable(); hash["userID"] = userID.ToString(); - IList paramList = new ArrayList(); - paramList.Add(hash); - - XmlRpcRequest request = new XmlRpcRequest("get_user_info", paramList); + hash = CallServer("get_user_info", hash); Dictionary info = new Dictionary(); - XmlRpcResponse response = null; - try - { - response = request.Send(m_ServerURL, 10000); - } - catch - { - m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for GetUserInfo", m_ServerURL); - return info; - } - if (response.IsFault) + foreach (object key in hash.Keys) { - m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for GetServerURLs returned an error: {1}", m_ServerURL, response.FaultString); - return info; - } - - hash = (Hashtable)response.Value; - try - { - if (hash == null) + if (hash[key] != null) { - m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetUserInfo Got null response from {0}! THIS IS BAAAAD", m_ServerURL); - return info; + info.Add(key.ToString(), hash[key]); } - - // Here is the actual response - foreach (object key in hash.Keys) - { - if (hash[key] != null) - { - info.Add(key.ToString(), hash[key]); - } - } - } - catch - { - m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response."); } return info; @@ -554,60 +512,16 @@ namespace OpenSim.Services.Connectors.Hypergrid Hashtable hash = new Hashtable(); hash["userID"] = userID.ToString(); - IList paramList = new ArrayList(); - paramList.Add(hash); - - XmlRpcRequest request = new XmlRpcRequest("get_server_urls", paramList); -// string reason = string.Empty; - - // Send and get reply - Dictionary serverURLs = new Dictionary(); - XmlRpcResponse response = null; - try + hash = CallServer("get_server_urls", hash); + + Dictionary serverURLs = new Dictionary(); + foreach (object key in hash.Keys) { - response = request.Send(m_ServerURL, 10000); - } - catch - { - m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for GetServerURLs for user {1}", m_ServerURL, userID); -// reason = "Exception: " + e.Message; - return serverURLs; - } - - if (response.IsFault) - { - m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for GetServerURLs returned an error: {1}", m_ServerURL, response.FaultString); -// reason = "XMLRPC Fault"; - return serverURLs; - } - - hash = (Hashtable)response.Value; - //foreach (Object o in hash) - // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value); - try - { - if (hash == null) + if (key is string && ((string)key).StartsWith("SRV_") && hash[key] != null) { - m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetServerURLs Got null response from {0}! THIS IS BAAAAD", m_ServerURL); -// reason = "Internal error 1"; - return serverURLs; + string serverType = key.ToString().Substring(4); // remove "SRV_" + serverURLs.Add(serverType, hash[key].ToString()); } - - // Here is the actual response - foreach (object key in hash.Keys) - { - if (key is string && ((string)key).StartsWith("SRV_") && hash[key] != null) - { - string serverType = key.ToString().Substring(4); // remove "SRV_" - serverURLs.Add(serverType, hash[key].ToString()); - } - } - - } - catch - { - m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response."); -// reason = "Exception: " + e.Message; } return serverURLs; @@ -618,55 +532,13 @@ namespace OpenSim.Services.Connectors.Hypergrid Hashtable hash = new Hashtable(); hash["userID"] = userID.ToString(); - IList paramList = new ArrayList(); - paramList.Add(hash); + hash = CallServer("locate_user", hash); - XmlRpcRequest request = new XmlRpcRequest("locate_user", paramList); -// string reason = string.Empty; - - // Send and get reply string url = string.Empty; - XmlRpcResponse response = null; - try - { - response = request.Send(m_ServerURL, 10000); - } - catch - { - m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for LocateUser", m_ServerURL); -// reason = "Exception: " + e.Message; - return url; - } - if (response.IsFault) - { - m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for LocateUser returned an error: {1}", m_ServerURL, response.FaultString); -// reason = "XMLRPC Fault"; - return url; - } - - hash = (Hashtable)response.Value; - //foreach (Object o in hash) - // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value); - try - { - if (hash == null) - { - m_log.ErrorFormat("[USER AGENT CONNECTOR]: LocateUser Got null response from {0}! THIS IS BAAAAD", m_ServerURL); -// reason = "Internal error 1"; - return url; - } - - // Here's the actual response - if (hash.ContainsKey("URL")) - url = hash["URL"].ToString(); - - } - catch - { - m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on LocateUser response."); -// reason = "Exception: " + e.Message; - } + // Here's the actual response + if (hash.ContainsKey("URL")) + url = hash["URL"].ToString(); return url; } @@ -677,55 +549,13 @@ namespace OpenSim.Services.Connectors.Hypergrid hash["userID"] = userID.ToString(); hash["targetUserID"] = targetUserID.ToString(); - IList paramList = new ArrayList(); - paramList.Add(hash); + hash = CallServer("get_uui", hash); - XmlRpcRequest request = new XmlRpcRequest("get_uui", paramList); -// string reason = string.Empty; - - // Send and get reply string uui = string.Empty; - XmlRpcResponse response = null; - try - { - response = request.Send(m_ServerURL, 10000); - } - catch - { - m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for GetUUI", m_ServerURL); -// reason = "Exception: " + e.Message; - return uui; - } - if (response.IsFault) - { - m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for GetUUI returned an error: {1}", m_ServerURL, response.FaultString); -// reason = "XMLRPC Fault"; - return uui; - } - - hash = (Hashtable)response.Value; - //foreach (Object o in hash) - // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value); - try - { - if (hash == null) - { - m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetUUI Got null response from {0}! THIS IS BAAAAD", m_ServerURL); -// reason = "Internal error 1"; - return uui; - } - - // Here's the actual response - if (hash.ContainsKey("UUI")) - uui = hash["UUI"].ToString(); - - } - catch - { - m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetUUI response."); -// reason = "Exception: " + e.Message; - } + // Here's the actual response + if (hash.ContainsKey("UUI")) + uui = hash["UUI"].ToString(); return uui; } @@ -736,54 +566,17 @@ namespace OpenSim.Services.Connectors.Hypergrid hash["first"] = first; hash["last"] = last; - IList paramList = new ArrayList(); - paramList.Add(hash); + hash = CallServer("get_uuid", hash); - XmlRpcRequest request = new XmlRpcRequest("get_uuid", paramList); - // string reason = string.Empty; - - // Send and get reply - UUID uuid = UUID.Zero; - XmlRpcResponse response = null; - try + if (!hash.ContainsKey("UUID")) { - response = request.Send(m_ServerURL, 10000); - } - catch - { - m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for GetUUID", m_ServerURL); - // reason = "Exception: " + e.Message; - return uuid; + throw new Exception(string.Format("[USER AGENT CONNECTOR]: get_uuid call to {0} didn't return a UUID", m_ServerURL)); } - if (response.IsFault) + UUID uuid; + if (!UUID.TryParse(hash["UUID"].ToString(), out uuid)) { - m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for GetUUID returned an error: {1}", m_ServerURL, response.FaultString); - // reason = "XMLRPC Fault"; - return uuid; - } - - hash = (Hashtable)response.Value; - //foreach (Object o in hash) - // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value); - try - { - if (hash == null) - { - m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetUUDI Got null response from {0}! THIS IS BAAAAD", m_ServerURL); - // reason = "Internal error 1"; - return uuid; - } - - // Here's the actual response - if (hash.ContainsKey("UUID")) - UUID.TryParse(hash["UUID"].ToString(), out uuid); - - } - catch - { - m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on UUID response."); - // reason = "Exception: " + e.Message; + throw new Exception(string.Format("[USER AGENT CONNECTOR]: get_uuid call to {0} returned an invalid UUID: {1}", m_ServerURL, hash["UUID"].ToString())); } return uuid; diff --git a/OpenSim/Services/HypergridService/HGInstantMessageService.cs b/OpenSim/Services/HypergridService/HGInstantMessageService.cs index e8d7ccac48..9b7b278bde 100644 --- a/OpenSim/Services/HypergridService/HGInstantMessageService.cs +++ b/OpenSim/Services/HypergridService/HGInstantMessageService.cs @@ -215,7 +215,15 @@ namespace OpenSim.Services.HypergridService { // Let's check with the UAS if the user is elsewhere m_log.DebugFormat("[HG IM SERVICE]: User is not present. Checking location with User Agent service"); - url = m_UserAgentService.LocateUser(toAgentID); + try + { + url = m_UserAgentService.LocateUser(toAgentID); + } + catch (Exception e) + { + m_log.Warn("[HG IM SERVICE]: LocateUser call failed ", e); + url = string.Empty; + } } // check if we've tried this before.. diff --git a/OpenSim/Services/Interfaces/IHypergridServices.cs b/OpenSim/Services/Interfaces/IHypergridServices.cs index 05e175a243..bece4c7b4a 100644 --- a/OpenSim/Services/Interfaces/IHypergridServices.cs +++ b/OpenSim/Services/Interfaces/IHypergridServices.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -47,15 +47,47 @@ namespace OpenSim.Services.Interfaces { bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, bool fromLogin, out string reason); void LogoutAgent(UUID userID, UUID sessionID); - GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt); - Dictionary GetServerURLs(UUID userID); - Dictionary GetUserInfo(UUID userID); + /// + /// Returns the home region of a remote user. + /// + /// On success: the user's home region. If the user doesn't exist: null. + /// Throws an exception if an error occurs (e.g., can't contact the server). + GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt); + + /// + /// Returns the Server URLs of a remote user. + /// + /// On success: the user's Server URLs. If the user doesn't exist: an empty dictionary. + /// Throws an exception if an error occurs (e.g., can't contact the server). + Dictionary GetServerURLs(UUID userID); + + /// + /// Returns the UserInfo of a remote user. + /// + /// On success: the user's UserInfo. If the user doesn't exist: an empty dictionary. + /// Throws an exception if an error occurs (e.g., can't contact the server). + Dictionary GetUserInfo(UUID userID); + + /// + /// Returns the current location of a remote user. + /// + /// On success: the user's Server URLs. If the user doesn't exist: "". + /// Throws an exception if an error occurs (e.g., can't contact the server). string LocateUser(UUID userID); - // Tries to get the universal user identifier for the targetUserId - // on behalf of the userID + + /// + /// Returns the Universal User Identifier for 'targetUserID' on behalf of 'userID'. + /// + /// On success: the user's UUI. If the user doesn't exist: "". + /// Throws an exception if an error occurs (e.g., can't contact the server). string GetUUI(UUID userID, UUID targetUserID); + /// + /// Returns the remote user that has the given name. + /// + /// On success: the user's UUID. If the user doesn't exist: UUID.Zero. + /// Throws an exception if an error occurs (e.g., can't contact the server). UUID GetUUID(String first, String last); // Returns the local friends online diff --git a/OpenSim/Services/Interfaces/IInventoryService.cs b/OpenSim/Services/Interfaces/IInventoryService.cs index a8bfe479a7..36634a379e 100644 --- a/OpenSim/Services/Interfaces/IInventoryService.cs +++ b/OpenSim/Services/Interfaces/IInventoryService.cs @@ -91,7 +91,7 @@ namespace OpenSim.Services.Interfaces /// /// /// - /// + /// Inventory content. null if the request failed. InventoryCollection GetFolderContent(UUID userID, UUID folderID); /// diff --git a/OpenSim/Services/UserAccountService/GridUserService.cs b/OpenSim/Services/UserAccountService/GridUserService.cs index bfc27b518c..5aa2078e9e 100644 --- a/OpenSim/Services/UserAccountService/GridUserService.cs +++ b/OpenSim/Services/UserAccountService/GridUserService.cs @@ -120,11 +120,13 @@ namespace OpenSim.Services.UserAccountService MainConsole.Instance.OutputFormat("Users online: {0}", onlineRecentlyCount); } - public virtual GridUserInfo GetGridUserInfo(string userID) + private GridUserData GetGridUserData(string userID) { GridUserData d = null; if (userID.Length > 36) // it's a UUI + { d = m_Database.Get(userID); + } else // it's a UUID { GridUserData[] ds = m_Database.GetAll(userID); @@ -140,6 +142,13 @@ namespace OpenSim.Services.UserAccountService } } + return d; + } + + public virtual GridUserInfo GetGridUserInfo(string userID) + { + GridUserData d = GetGridUserData(userID); + if (d == null) return null; @@ -173,7 +182,8 @@ namespace OpenSim.Services.UserAccountService public GridUserInfo LoggedIn(string userID) { m_log.DebugFormat("[GRID USER SERVICE]: User {0} is online", userID); - GridUserData d = m_Database.Get(userID); + + GridUserData d = GetGridUserData(userID); if (d == null) { @@ -192,7 +202,8 @@ namespace OpenSim.Services.UserAccountService public bool LoggedOut(string userID, UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt) { m_log.DebugFormat("[GRID USER SERVICE]: User {0} is offline", userID); - GridUserData d = m_Database.Get(userID); + + GridUserData d = GetGridUserData(userID); if (d == null) { @@ -211,7 +222,8 @@ namespace OpenSim.Services.UserAccountService public bool SetHome(string userID, UUID homeID, Vector3 homePosition, Vector3 homeLookAt) { - GridUserData d = m_Database.Get(userID); + GridUserData d = GetGridUserData(userID); + if (d == null) { d = new GridUserData(); @@ -229,7 +241,8 @@ namespace OpenSim.Services.UserAccountService { // m_log.DebugFormat("[GRID USER SERVICE]: SetLastPosition for {0}", userID); - GridUserData d = m_Database.Get(userID); + GridUserData d = GetGridUserData(userID); + if (d == null) { d = new GridUserData(); @@ -243,4 +256,4 @@ namespace OpenSim.Services.UserAccountService return m_Database.Store(d); } } -} +} \ No newline at end of file diff --git a/prebuild.xml b/prebuild.xml index 5b18195f60..dfb30dc813 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -3325,6 +3325,7 @@ + @@ -3334,6 +3335,7 @@ +