aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Application/OpenSim.cs8
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs16
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs90
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs340
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs12
-rw-r--r--OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs11
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs71
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs14
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs12
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs11
-rw-r--r--OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs3
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/LocalNeighbourServiceConnector.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs15
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs5
-rw-r--r--OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs24
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs302
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs22
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs9
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs64
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs19
-rw-r--r--OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs31
-rw-r--r--OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs321
-rw-r--r--OpenSim/Region/RegionCombinerModule/RegionData.cs1
26 files changed, 582 insertions, 832 deletions
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index 77b9440..3d80c6e 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -559,7 +559,7 @@ namespace OpenSim
559 { 559 {
560 scene.ForEachSOG(delegate(SceneObjectGroup sog) 560 scene.ForEachSOG(delegate(SceneObjectGroup sog)
561 { 561 {
562 if (sog.AttachmentPoint == 0) 562 if (!sog.IsAttachment)
563 { 563 {
564 sog.RootPart.UpdateRotation(rot * sog.GroupRotation); 564 sog.RootPart.UpdateRotation(rot * sog.GroupRotation);
565 Vector3 offset = sog.AbsolutePosition - center; 565 Vector3 offset = sog.AbsolutePosition - center;
@@ -588,7 +588,7 @@ namespace OpenSim
588 { 588 {
589 scene.ForEachSOG(delegate(SceneObjectGroup sog) 589 scene.ForEachSOG(delegate(SceneObjectGroup sog)
590 { 590 {
591 if (sog.AttachmentPoint == 0) 591 if (!sog.IsAttachment)
592 { 592 {
593 if (sog.RootPart.AbsolutePosition.Z < minZ) 593 if (sog.RootPart.AbsolutePosition.Z < minZ)
594 minZ = sog.RootPart.AbsolutePosition.Z; 594 minZ = sog.RootPart.AbsolutePosition.Z;
@@ -600,7 +600,7 @@ namespace OpenSim
600 { 600 {
601 scene.ForEachSOG(delegate(SceneObjectGroup sog) 601 scene.ForEachSOG(delegate(SceneObjectGroup sog)
602 { 602 {
603 if (sog.AttachmentPoint == 0) 603 if (!sog.IsAttachment)
604 { 604 {
605 Vector3 tmpRootPos = sog.RootPart.AbsolutePosition; 605 Vector3 tmpRootPos = sog.RootPart.AbsolutePosition;
606 tmpRootPos.Z -= minZ; 606 tmpRootPos.Z -= minZ;
@@ -640,7 +640,7 @@ namespace OpenSim
640 { 640 {
641 scene.ForEachSOG(delegate(SceneObjectGroup sog) 641 scene.ForEachSOG(delegate(SceneObjectGroup sog)
642 { 642 {
643 if (sog.AttachmentPoint == 0) 643 if (!sog.IsAttachment)
644 sog.UpdateGroupPosition(sog.AbsolutePosition + offset); 644 sog.UpdateGroupPosition(sog.AbsolutePosition + offset);
645 }); 645 });
646 }); 646 });
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
index f98337d..b162bb9 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
229 lock (queue) 229 lock (queue)
230 queue.Enqueue(ev); 230 queue.Enqueue(ev);
231 } 231 }
232 else 232 else if (DebugLevel > 0)
233 { 233 {
234 OSDMap evMap = (OSDMap)ev; 234 ScenePresence sp = m_scene.GetScenePresence(avatarID);
235 m_log.WarnFormat( 235
236 "[EVENTQUEUE]: (Enqueue) No queue found for agent {0} when placing message {1} in region {2}", 236 // This assumes that an NPC should never have a queue.
237 avatarID, evMap["message"], m_scene.Name); 237 if (sp != null && sp.PresenceType != PresenceType.Npc)
238 {
239 OSDMap evMap = (OSDMap)ev;
240 m_log.WarnFormat(
241 "[EVENTQUEUE]: (Enqueue) No queue found for agent {0} {1} when placing message {2} in region {3}",
242 sp.Name, sp.UUID, evMap["message"], m_scene.Name);
243 }
238 } 244 }
239 } 245 }
240 catch (NullReferenceException e) 246 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 9e24bce..fb24f58 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 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections;
29using System.Collections.Generic; 30using System.Collections.Generic;
30using System.Net; 31using System.Net;
31using log4net.Config; 32using log4net.Config;
@@ -33,11 +34,14 @@ using Nini.Config;
33using NUnit.Framework; 34using NUnit.Framework;
34using OpenMetaverse; 35using OpenMetaverse;
35using OpenMetaverse.Packets; 36using OpenMetaverse.Packets;
37using OpenMetaverse.StructuredData;
36using OpenSim.Framework; 38using OpenSim.Framework;
37using OpenSim.Framework.Servers; 39using OpenSim.Framework.Servers;
38using OpenSim.Framework.Servers.HttpServer; 40using OpenSim.Framework.Servers.HttpServer;
39using OpenSim.Region.ClientStack.Linden; 41using OpenSim.Region.ClientStack.Linden;
40using OpenSim.Region.CoreModules.Framework; 42using OpenSim.Region.CoreModules.Framework;
43using OpenSim.Region.Framework.Scenes;
44using OpenSim.Region.OptionalModules.World.NPC;
41using OpenSim.Tests.Common; 45using OpenSim.Tests.Common;
42using OpenSim.Tests.Common.Mock; 46using OpenSim.Tests.Common.Mock;
43 47
@@ -47,6 +51,8 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
47 public class EventQueueTests : OpenSimTestCase 51 public class EventQueueTests : OpenSimTestCase
48 { 52 {
49 private TestScene m_scene; 53 private TestScene m_scene;
54 private EventQueueGetModule m_eqgMod;
55 private NPCModule m_npcMod;
50 56
51 [SetUp] 57 [SetUp]
52 public override void SetUp() 58 public override void SetUp()
@@ -69,10 +75,15 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
69 config.Configs["Startup"].Set("EventQueue", "true"); 75 config.Configs["Startup"].Set("EventQueue", "true");
70 76
71 CapabilitiesModule capsModule = new CapabilitiesModule(); 77 CapabilitiesModule capsModule = new CapabilitiesModule();
72 EventQueueGetModule eqgModule = new EventQueueGetModule(); 78 m_eqgMod = new EventQueueGetModule();
79
80 // For NPC test support
81 config.AddConfig("NPC");
82 config.Configs["NPC"].Set("Enabled", "true");
83 m_npcMod = new NPCModule();
73 84
74 m_scene = new SceneHelpers().SetupScene(); 85 m_scene = new SceneHelpers().SetupScene();
75 SceneHelpers.SetupSceneModules(m_scene, config, capsModule, eqgModule); 86 SceneHelpers.SetupSceneModules(m_scene, config, capsModule, m_eqgMod, m_npcMod);
76 } 87 }
77 88
78 [Test] 89 [Test]
@@ -101,5 +112,80 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
101 // TODO: Add more assertions for the other aspects of event queues 112 // TODO: Add more assertions for the other aspects of event queues
102 Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0)); 113 Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0));
103 } 114 }
115
116 [Test]
117 public void TestEnqueueMessage()
118 {
119 TestHelpers.InMethod();
120// log4net.Config.XmlConfigurator.Configure();
121
122 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
123
124 string messageName = "TestMessage";
125
126 m_eqgMod.Enqueue(m_eqgMod.BuildEvent(messageName, new OSDMap()), sp.UUID);
127
128 Hashtable eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID);
129
130 Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.OK));
131
132// Console.WriteLine("Response [{0}]", (string)eventsResponse["str_response_string"]);
133
134 OSDMap rawOsd = (OSDMap)OSDParser.DeserializeLLSDXml((string)eventsResponse["str_response_string"]);
135 OSDArray eventsOsd = (OSDArray)rawOsd["events"];
136
137 bool foundUpdate = false;
138 foreach (OSD osd in eventsOsd)
139 {
140 OSDMap eventOsd = (OSDMap)osd;
141
142 if (eventOsd["message"] == messageName)
143 foundUpdate = true;
144 }
145
146 Assert.That(foundUpdate, Is.True, string.Format("Did not find {0} in response", messageName));
147 }
148
149 /// <summary>
150 /// Test an attempt to put a message on the queue of a user that is not in the region.
151 /// </summary>
152 [Test]
153 public void TestEnqueueMessageNoUser()
154 {
155 TestHelpers.InMethod();
156 TestHelpers.EnableLogging();
157
158 string messageName = "TestMessage";
159
160 m_eqgMod.Enqueue(m_eqgMod.BuildEvent(messageName, new OSDMap()), TestHelpers.ParseTail(0x1));
161
162 Hashtable eventsResponse = m_eqgMod.GetEvents(UUID.Zero, TestHelpers.ParseTail(0x1));
163
164 Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.BadGateway));
165 }
166
167 /// <summary>
168 /// NPCs do not currently have an event queue but a caller may try to send a message anyway, so check behaviour.
169 /// </summary>
170 [Test]
171 public void TestEnqueueMessageToNpc()
172 {
173 TestHelpers.InMethod();
174// TestHelpers.EnableLogging();
175
176 UUID npcId
177 = m_npcMod.CreateNPC(
178 "John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, new AvatarAppearance());
179
180 ScenePresence npc = m_scene.GetScenePresence(npcId);
181
182 string messageName = "TestMessage";
183
184 m_eqgMod.Enqueue(m_eqgMod.BuildEvent(messageName, new OSDMap()), npc.UUID);
185
186 Hashtable eventsResponse = m_eqgMod.GetEvents(UUID.Zero, npc.UUID);
187
188 Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.BadGateway));
189 }
104 } 190 }
105} \ No newline at end of file 191} \ 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 09cc998..cdad729 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
687 m_scene.EventManager.TriggerAvatarAppearanceChanged(sp); 687 m_scene.EventManager.TriggerAvatarAppearanceChanged(sp);
688 } 688 }
689 689
690 /// <summary>
691 /// For a given set of appearance items, check whether the items are valid and add their asset IDs to
692 /// appearance data.
693 /// </summary>
694 /// <param name='userID'></param>
695 /// <param name='appearance'></param>
690 private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance) 696 private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance)
691 { 697 {
692 IInventoryService invService = m_scene.InventoryService; 698 IInventoryService invService = m_scene.InventoryService;
693 bool resetwearable = false; 699
694 if (invService.GetRootFolder(userID) != null) 700 if (invService.GetRootFolder(userID) != null)
695 { 701 {
696 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) 702 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
697 { 703 {
698 for (int j = 0; j < appearance.Wearables[i].Count; j++) 704 for (int j = 0; j < appearance.Wearables[i].Count; j++)
699 { 705 {
700 // Check if the default wearables are not set
701 if (appearance.Wearables[i][j].ItemID == UUID.Zero) 706 if (appearance.Wearables[i][j].ItemID == UUID.Zero)
702 { 707 {
703 switch ((WearableType) i) 708 m_log.WarnFormat(
704 { 709 "[AVFACTORY]: Wearable item {0}:{1} for user {2} unexpectedly UUID.Zero. Ignoring.",
705 case WearableType.Eyes: 710 i, j, userID);
706 case WearableType.Hair: 711
707 case WearableType.Shape:
708 case WearableType.Skin:
709 //case WearableType.Underpants:
710 TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
711 resetwearable = true;
712 m_log.Warn("[AVFACTORY]: UUID.Zero Wearables, passing fake values.");
713 resetwearable = true;
714 break;
715
716 }
717 continue; 712 continue;
718 } 713 }
719 714
720 // Ignore ruth's assets except for the body parts! missing body parts fail avatar appearance on V1 715 // Ignore ruth's assets
721 if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID) 716 if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
722 {
723 switch ((WearableType)i)
724 {
725 case WearableType.Eyes:
726 case WearableType.Hair:
727 case WearableType.Shape:
728 case WearableType.Skin:
729 //case WearableType.Underpants:
730 TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
731
732 m_log.WarnFormat("[AVFACTORY]: {0} Default Wearables, passing existing values.", (WearableType)i);
733 resetwearable = true;
734 break;
735
736 }
737 continue; 717 continue;
738 } 718
739
740 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); 719 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
741 baseItem = invService.GetItem(baseItem); 720 baseItem = invService.GetItem(baseItem);
742 721
743 if (baseItem != null) 722 if (baseItem != null)
744 { 723 {
745 appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID); 724 appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID);
746 int unmodifiedWearableIndexForClosure = i;
747 m_scene.AssetService.Get(baseItem.AssetID.ToString(), this,
748 delegate(string x, object y, AssetBase z)
749 {
750 if (z == null)
751 {
752 TryAndRepairBrokenWearable(
753 (WearableType)unmodifiedWearableIndexForClosure, invService,
754 userID, appearance);
755 }
756 });
757 } 725 }
758 else 726 else
759 { 727 {
760 m_log.ErrorFormat( 728 m_log.WarnFormat(
761 "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default", 729 "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default",
762 appearance.Wearables[i][j].ItemID, (WearableType)i); 730 appearance.Wearables[i][j].ItemID, (WearableType)i);
763 731
764 TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance); 732 appearance.Wearables[i].RemoveItem(appearance.Wearables[i][j].ItemID);
765 resetwearable = true;
766
767 } 733 }
768 } 734 }
769 } 735 }
770
771 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
772 if (appearance.Wearables[(int) WearableType.Eyes] == null)
773 {
774 m_log.WarnFormat("[AVFACTORY]: {0} Eyes are Null, passing existing values.", (WearableType.Eyes));
775
776 TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
777 resetwearable = true;
778 }
779 else
780 {
781 if (appearance.Wearables[(int) WearableType.Eyes][0].ItemID == UUID.Zero)
782 {
783 m_log.WarnFormat("[AVFACTORY]: Eyes are UUID.Zero are broken, {0} {1}",
784 appearance.Wearables[(int) WearableType.Eyes][0].ItemID,
785 appearance.Wearables[(int) WearableType.Eyes][0].AssetID);
786 TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
787 resetwearable = true;
788
789 }
790
791 }
792 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
793 if (appearance.Wearables[(int)WearableType.Shape] == null)
794 {
795 m_log.WarnFormat("[AVFACTORY]: {0} shape is Null, passing existing values.", (WearableType.Shape));
796
797 TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
798 resetwearable = true;
799 }
800 else
801 {
802 if (appearance.Wearables[(int)WearableType.Shape][0].ItemID == UUID.Zero)
803 {
804 m_log.WarnFormat("[AVFACTORY]: Shape is UUID.Zero and broken, {0} {1}",
805 appearance.Wearables[(int)WearableType.Shape][0].ItemID,
806 appearance.Wearables[(int)WearableType.Shape][0].AssetID);
807 TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
808 resetwearable = true;
809
810 }
811
812 }
813 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
814 if (appearance.Wearables[(int)WearableType.Hair] == null)
815 {
816 m_log.WarnFormat("[AVFACTORY]: {0} Hair is Null, passing existing values.", (WearableType.Hair));
817
818 TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
819 resetwearable = true;
820 }
821 else
822 {
823 if (appearance.Wearables[(int)WearableType.Hair][0].ItemID == UUID.Zero)
824 {
825 m_log.WarnFormat("[AVFACTORY]: Hair is UUID.Zero and broken, {0} {1}",
826 appearance.Wearables[(int)WearableType.Hair][0].ItemID,
827 appearance.Wearables[(int)WearableType.Hair][0].AssetID);
828 TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
829 resetwearable = true;
830
831 }
832
833 }
834 // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
835 if (appearance.Wearables[(int)WearableType.Skin] == null)
836 {
837 m_log.WarnFormat("[AVFACTORY]: {0} Skin is Null, passing existing values.", (WearableType.Skin));
838
839 TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
840 resetwearable = true;
841 }
842 else
843 {
844 if (appearance.Wearables[(int)WearableType.Skin][0].ItemID == UUID.Zero)
845 {
846 m_log.WarnFormat("[AVFACTORY]: Skin is UUID.Zero and broken, {0} {1}",
847 appearance.Wearables[(int)WearableType.Skin][0].ItemID,
848 appearance.Wearables[(int)WearableType.Skin][0].AssetID);
849 TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
850 resetwearable = true;
851
852 }
853
854 }
855 if (resetwearable)
856 {
857 ScenePresence presence = null;
858 if (m_scene.TryGetScenePresence(userID, out presence))
859 {
860 presence.ControllingClient.SendWearables(presence.Appearance.Wearables,
861 presence.Appearance.Serial++);
862 }
863 }
864
865 } 736 }
866 else 737 else
867 { 738 {
868 m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID); 739 m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
869 } 740 }
741
742// IInventoryService invService = m_scene.InventoryService;
743// bool resetwearable = false;
744// if (invService.GetRootFolder(userID) != null)
745// {
746// for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
747// {
748// for (int j = 0; j < appearance.Wearables[i].Count; j++)
749// {
750// // Check if the default wearables are not set
751// if (appearance.Wearables[i][j].ItemID == UUID.Zero)
752// {
753// switch ((WearableType) i)
754// {
755// case WearableType.Eyes:
756// case WearableType.Hair:
757// case WearableType.Shape:
758// case WearableType.Skin:
759// //case WearableType.Underpants:
760// TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
761// resetwearable = true;
762// m_log.Warn("[AVFACTORY]: UUID.Zero Wearables, passing fake values.");
763// resetwearable = true;
764// break;
765//
766// }
767// continue;
768// }
769//
770// // Ignore ruth's assets except for the body parts! missing body parts fail avatar appearance on V1
771// if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
772// {
773// switch ((WearableType)i)
774// {
775// case WearableType.Eyes:
776// case WearableType.Hair:
777// case WearableType.Shape:
778// case WearableType.Skin:
779// //case WearableType.Underpants:
780// TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
781//
782// m_log.WarnFormat("[AVFACTORY]: {0} Default Wearables, passing existing values.", (WearableType)i);
783// resetwearable = true;
784// break;
785//
786// }
787// continue;
788// }
789//
790// InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
791// baseItem = invService.GetItem(baseItem);
792//
793// if (baseItem != null)
794// {
795// appearance.Wearables[i].Add(appearance.Wearables[i][j].ItemID, baseItem.AssetID);
796// int unmodifiedWearableIndexForClosure = i;
797// m_scene.AssetService.Get(baseItem.AssetID.ToString(), this,
798// delegate(string x, object y, AssetBase z)
799// {
800// if (z == null)
801// {
802// TryAndRepairBrokenWearable(
803// (WearableType)unmodifiedWearableIndexForClosure, invService,
804// userID, appearance);
805// }
806// });
807// }
808// else
809// {
810// m_log.ErrorFormat(
811// "[AVFACTORY]: Can't find inventory item {0} for {1}, setting to default",
812// appearance.Wearables[i][j].ItemID, (WearableType)i);
813//
814// TryAndRepairBrokenWearable((WearableType)i, invService, userID, appearance);
815// resetwearable = true;
816//
817// }
818// }
819// }
820//
821// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
822// if (appearance.Wearables[(int) WearableType.Eyes] == null)
823// {
824// m_log.WarnFormat("[AVFACTORY]: {0} Eyes are Null, passing existing values.", (WearableType.Eyes));
825//
826// TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
827// resetwearable = true;
828// }
829// else
830// {
831// if (appearance.Wearables[(int) WearableType.Eyes][0].ItemID == UUID.Zero)
832// {
833// m_log.WarnFormat("[AVFACTORY]: Eyes are UUID.Zero are broken, {0} {1}",
834// appearance.Wearables[(int) WearableType.Eyes][0].ItemID,
835// appearance.Wearables[(int) WearableType.Eyes][0].AssetID);
836// TryAndRepairBrokenWearable(WearableType.Eyes, invService, userID, appearance);
837// resetwearable = true;
838//
839// }
840//
841// }
842// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
843// if (appearance.Wearables[(int)WearableType.Shape] == null)
844// {
845// m_log.WarnFormat("[AVFACTORY]: {0} shape is Null, passing existing values.", (WearableType.Shape));
846//
847// TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
848// resetwearable = true;
849// }
850// else
851// {
852// if (appearance.Wearables[(int)WearableType.Shape][0].ItemID == UUID.Zero)
853// {
854// m_log.WarnFormat("[AVFACTORY]: Shape is UUID.Zero and broken, {0} {1}",
855// appearance.Wearables[(int)WearableType.Shape][0].ItemID,
856// appearance.Wearables[(int)WearableType.Shape][0].AssetID);
857// TryAndRepairBrokenWearable(WearableType.Shape, invService, userID, appearance);
858// resetwearable = true;
859//
860// }
861//
862// }
863// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
864// if (appearance.Wearables[(int)WearableType.Hair] == null)
865// {
866// m_log.WarnFormat("[AVFACTORY]: {0} Hair is Null, passing existing values.", (WearableType.Hair));
867//
868// TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
869// resetwearable = true;
870// }
871// else
872// {
873// if (appearance.Wearables[(int)WearableType.Hair][0].ItemID == UUID.Zero)
874// {
875// m_log.WarnFormat("[AVFACTORY]: Hair is UUID.Zero and broken, {0} {1}",
876// appearance.Wearables[(int)WearableType.Hair][0].ItemID,
877// appearance.Wearables[(int)WearableType.Hair][0].AssetID);
878// TryAndRepairBrokenWearable(WearableType.Hair, invService, userID, appearance);
879// resetwearable = true;
880//
881// }
882//
883// }
884// // I don't know why we have to test for this again... but the above switches do not capture these scenarios for some reason....
885// if (appearance.Wearables[(int)WearableType.Skin] == null)
886// {
887// m_log.WarnFormat("[AVFACTORY]: {0} Skin is Null, passing existing values.", (WearableType.Skin));
888//
889// TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
890// resetwearable = true;
891// }
892// else
893// {
894// if (appearance.Wearables[(int)WearableType.Skin][0].ItemID == UUID.Zero)
895// {
896// m_log.WarnFormat("[AVFACTORY]: Skin is UUID.Zero and broken, {0} {1}",
897// appearance.Wearables[(int)WearableType.Skin][0].ItemID,
898// appearance.Wearables[(int)WearableType.Skin][0].AssetID);
899// TryAndRepairBrokenWearable(WearableType.Skin, invService, userID, appearance);
900// resetwearable = true;
901//
902// }
903//
904// }
905// if (resetwearable)
906// {
907// ScenePresence presence = null;
908// if (m_scene.TryGetScenePresence(userID, out presence))
909// {
910// presence.ControllingClient.SendWearables(presence.Appearance.Wearables,
911// presence.Appearance.Serial++);
912// }
913// }
914//
915// }
916// else
917// {
918// m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
919// }
870 } 920 }
921
871 private void TryAndRepairBrokenWearable(WearableType type, IInventoryService invService, UUID userID,AvatarAppearance appearance) 922 private void TryAndRepairBrokenWearable(WearableType type, IInventoryService invService, UUID userID,AvatarAppearance appearance)
872 { 923 {
873 UUID defaultwearable = GetDefaultItem(type); 924 UUID defaultwearable = GetDefaultItem(type);
@@ -957,6 +1008,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
957 } 1008 }
958 } 1009 }
959 } 1010 }
1011
960 private UUID GetDefaultItem(WearableType wearable) 1012 private UUID GetDefaultItem(WearableType wearable)
961 { 1013 {
962 // These are ruth 1014 // These are ruth
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs
index 7bf19c2..c51b30f 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
282 string uasURL = circuit.ServiceURLs["HomeURI"].ToString(); 282 string uasURL = circuit.ServiceURLs["HomeURI"].ToString();
283 m_log.DebugFormat("[HG MESSAGE TRANSFER]: getting UUI of user {0} from {1}", toAgent, uasURL); 283 m_log.DebugFormat("[HG MESSAGE TRANSFER]: getting UUI of user {0} from {1}", toAgent, uasURL);
284 UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uasURL); 284 UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uasURL);
285 return uasConn.GetUUI(fromAgent, toAgent); 285
286 string agentUUI = string.Empty;
287 try
288 {
289 agentUUI = uasConn.GetUUI(fromAgent, toAgent);
290 }
291 catch (Exception e) {
292 m_log.Debug("[HG MESSAGE TRANSFER]: GetUUI call failed ", e);
293 }
294
295 return agentUUI;
286 } 296 }
287 } 297 }
288 } 298 }
diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs
index 2da0a74..f3e757a 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
1164 1164
1165 UserAgentServiceConnector uConn = new UserAgentServiceConnector(home_url); 1165 UserAgentServiceConnector uConn = new UserAgentServiceConnector(home_url);
1166 1166
1167 Dictionary<string, object> account = uConn.GetUserInfo(userID); 1167 Dictionary<string, object> account;
1168 try
1169 {
1170 account = uConn.GetUserInfo(userID);
1171 }
1172 catch (Exception e)
1173 {
1174 m_log.Debug("[PROFILES]: GetUserInfo call failed ", e);
1175 account = new Dictionary<string, object>();
1176 }
1168 1177
1169 if (account.Count > 0) 1178 if (account.Count > 0)
1170 { 1179 {
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index a038f73..c9adc37 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
464 sp.Name, position, sp.Scene.RegionInfo.RegionName); 464 sp.Name, position, sp.Scene.RegionInfo.RegionName);
465 465
466 // Teleport within the same region 466 // Teleport within the same region
467 if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) 467 if (!sp.Scene.PositionIsInCurrentRegion(position) || position.Z < 0)
468 { 468 {
469 Vector3 emergencyPos = new Vector3(128, 128, 128); 469 Vector3 emergencyPos = new Vector3(128, 128, 128);
470 470
@@ -580,7 +580,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
580 MapBlockData block = new MapBlockData(); 580 MapBlockData block = new MapBlockData();
581 block.X = (ushort)regX; 581 block.X = (ushort)regX;
582 block.Y = (ushort)regY; 582 block.Y = (ushort)regY;
583 block.Access = 254; // == not there 583 block.Access = (byte)SimAccess.Down;
584 584
585 List<MapBlockData> blocks = new List<MapBlockData>(); 585 List<MapBlockData> blocks = new List<MapBlockData>();
586 blocks.Add(block); 586 blocks.Add(block);
@@ -713,10 +713,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
713 return; 713 return;
714 } 714 }
715 715
716 uint newRegionX = (uint)(reg.RegionHandle >> 40); 716 uint newRegionX, newRegionY, oldRegionX, oldRegionY;
717 uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); 717 Util.RegionHandleToRegionLoc(reg.RegionHandle, out newRegionX, out newRegionY);
718 uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); 718 Util.RegionHandleToRegionLoc(sp.Scene.RegionInfo.RegionHandle, out oldRegionX, out oldRegionY);
719 uint oldRegionY = (((uint)(sp.Scene.RegionInfo.RegionHandle)) >> 8);
720 719
721 ulong destinationHandle = finalDestination.RegionHandle; 720 ulong destinationHandle = finalDestination.RegionHandle;
722 721
@@ -1333,6 +1332,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1333 return region; 1332 return region;
1334 } 1333 }
1335 1334
1335 // This returns 'true' if the new region already has a child agent for our
1336 // incoming agent. The implication is that, if 'false', we have to create the
1337 // child and then teleport into the region.
1336 protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY) 1338 protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY)
1337 { 1339 {
1338 if (m_regionCombinerModule != null && m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID)) 1340 if (m_regionCombinerModule != null && m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID))
@@ -1357,20 +1359,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1357 return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY); 1359 return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY);
1358 } 1360 }
1359 1361
1360 protected virtual bool IsOutsideRegion(Scene s, Vector3 pos)
1361 {
1362 if (s.TestBorderCross(pos, Cardinals.N))
1363 return true;
1364 if (s.TestBorderCross(pos, Cardinals.S))
1365 return true;
1366 if (s.TestBorderCross(pos, Cardinals.E))
1367 return true;
1368 if (s.TestBorderCross(pos, Cardinals.W))
1369 return true;
1370
1371 return false;
1372 }
1373
1374 #endregion 1362 #endregion
1375 1363
1376 #region Landmark Teleport 1364 #region Landmark Teleport
@@ -1455,10 +1443,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1455 // see that it is actually outside the current region), find the new region that the 1443 // see that it is actually outside the current region), find the new region that the
1456 // point is actually in. 1444 // point is actually in.
1457 // Returns the coordinates and information of the new region or 'null' of it doesn't exist. 1445 // Returns the coordinates and information of the new region or 'null' of it doesn't exist.
1458 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos) 1446 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos,
1447 out string version, out Vector3 newpos, out string failureReason)
1459 { 1448 {
1460 version = String.Empty; 1449 version = String.Empty;
1461 newpos = pos; 1450 newpos = pos;
1451 failureReason = string.Empty;
1462 1452
1463// m_log.DebugFormat( 1453// m_log.DebugFormat(
1464// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); 1454// "[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
1475 if (neighbourRegion != null) 1465 if (neighbourRegion != null)
1476 { 1466 {
1477 // Compute the entity's position relative to the new region 1467 // Compute the entity's position relative to the new region
1478 newpos = new Vector3( (float)(presenceWorldX - (double)neighbourRegion.RegionLocX), 1468 newpos = new Vector3((float)(presenceWorldX - (double)neighbourRegion.RegionLocX),
1479 (float)(presenceWorldY - (double)neighbourRegion.RegionLocY), 1469 (float)(presenceWorldY - (double)neighbourRegion.RegionLocY),
1480 pos.Z); 1470 pos.Z);
1481 1471
1482 if (m_bannedRegionCache.IfBanned(neighbourRegion.RegionHandle, agentID)) 1472 if (m_bannedRegionCache.IfBanned(neighbourRegion.RegionHandle, agentID))
1483 { 1473 {
1474 failureReason = "Cannot region cross into banned parcel";
1484 neighbourRegion = null; 1475 neighbourRegion = null;
1485 } 1476 }
1486 else 1477 else
@@ -1490,15 +1481,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1490 } 1481 }
1491 1482
1492 // Check to see if we have access to the target region. 1483 // Check to see if we have access to the target region.
1493 string reason;
1494 if (neighbourRegion != null 1484 if (neighbourRegion != null
1495 && !scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason)) 1485 && !scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out failureReason))
1496 { 1486 {
1497 // remember banned 1487 // remember banned
1498 m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID); 1488 m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID);
1499 neighbourRegion = null; 1489 neighbourRegion = null;
1500 } 1490 }
1501 } 1491 }
1492 else
1493 {
1494 // The destination region just doesn't exist
1495 failureReason = "Cannot cross into non-existant region";
1496 }
1502 1497
1503 if (neighbourRegion == null) 1498 if (neighbourRegion == null)
1504 m_log.DebugFormat("{0} GetDestination: region not found. Old region name={1} at <{2},{3}> of size <{4},{5}>. Old pos={6}", 1499 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
1521 uint y; 1516 uint y;
1522 Vector3 newpos; 1517 Vector3 newpos;
1523 string version; 1518 string version;
1519 string failureReason;
1524 1520
1525 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out version, out newpos); 1521 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition,
1522 out version, out newpos, out failureReason);
1526 if (neighbourRegion == null) 1523 if (neighbourRegion == null)
1527 { 1524 {
1528 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); 1525 agent.ControllingClient.SendAlertMessage(failureReason);
1529 return false; 1526 return false;
1530 } 1527 }
1531 1528
@@ -1534,6 +1531,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1534 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; 1531 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
1535 d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); 1532 d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
1536 1533
1534 Scene.EventManager.TriggerCrossAgentToNewRegion(agent, isFlying, neighbourRegion);
1535
1537 return true; 1536 return true;
1538 } 1537 }
1539 1538
@@ -2077,7 +2076,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2077 public NotFoundLocationCache() 2076 public NotFoundLocationCache()
2078 { 2077 {
2079 } 2078 }
2080 // Add an area to the lost of 'not found' places. The area is the snapped region 2079 // Add an area to the list of 'not found' places. The area is the snapped region
2081 // area around the added point. 2080 // area around the added point.
2082 public void Add(double pX, double pY) 2081 public void Add(double pX, double pY)
2083 { 2082 {
@@ -2305,23 +2304,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2305 /// <param name='neCorner'></param> 2304 /// <param name='neCorner'></param>
2306 private void GetMegaregionViewRange(out Vector2 swCorner, out Vector2 neCorner) 2305 private void GetMegaregionViewRange(out Vector2 swCorner, out Vector2 neCorner)
2307 { 2306 {
2308 Border[] northBorders = Scene.NorthBorders.ToArray();
2309 Border[] eastBorders = Scene.EastBorders.ToArray();
2310
2311 Vector2 extent = Vector2.Zero; 2307 Vector2 extent = Vector2.Zero;
2312 for (int i = 0; i < eastBorders.Length; i++) 2308
2313 { 2309 if (m_regionCombinerModule != null)
2314 extent.X = (eastBorders[i].BorderLine.Z > extent.X) ? eastBorders[i].BorderLine.Z : extent.X;
2315 }
2316 for (int i = 0; i < northBorders.Length; i++)
2317 { 2310 {
2318 extent.Y = (northBorders[i].BorderLine.Z > extent.Y) ? northBorders[i].BorderLine.Z : extent.Y; 2311 Vector2 megaRegionSize = m_regionCombinerModule.GetSizeOfMegaregion(Scene.RegionInfo.RegionID);
2312 extent.X = (float)Util.WorldToRegionLoc((uint)megaRegionSize.X);
2313 extent.Y = (float)Util.WorldToRegionLoc((uint)megaRegionSize.Y);
2319 } 2314 }
2320 2315
2321 // Loss of fraction on purpose
2322 extent.X = ((int)extent.X / (int)Constants.RegionSize);
2323 extent.Y = ((int)extent.Y / (int)Constants.RegionSize);
2324
2325 swCorner.X = Scene.RegionInfo.RegionLocX - 1; 2316 swCorner.X = Scene.RegionInfo.RegionLocX - 1;
2326 swCorner.Y = Scene.RegionInfo.RegionLocY - 1; 2317 swCorner.Y = Scene.RegionInfo.RegionLocY - 1;
2327 neCorner.X = Scene.RegionInfo.RegionLocX + extent.X; 2318 neCorner.X = Scene.RegionInfo.RegionLocX + extent.X;
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index 09b1975..e354522 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -462,7 +462,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
462 462
463 IUserAgentService userAgentService = new UserAgentServiceConnector(aCircuit.ServiceURLs["HomeURI"].ToString()); 463 IUserAgentService userAgentService = new UserAgentServiceConnector(aCircuit.ServiceURLs["HomeURI"].ToString());
464 Vector3 position = Vector3.UnitY, lookAt = Vector3.UnitY; 464 Vector3 position = Vector3.UnitY, lookAt = Vector3.UnitY;
465 GridRegion finalDestination = userAgentService.GetHomeRegion(aCircuit.AgentID, out position, out lookAt); 465
466 GridRegion finalDestination = null;
467 try
468 {
469 finalDestination = userAgentService.GetHomeRegion(aCircuit.AgentID, out position, out lookAt);
470 }
471 catch (Exception e)
472 {
473 m_log.Debug("[HG ENTITY TRANSFER MODULE]: GetHomeRegion call failed ", e);
474 }
475
466 if (finalDestination == null) 476 if (finalDestination == null)
467 { 477 {
468 client.SendTeleportFailed("Your home region could not be found"); 478 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 245c808..7b89c2c 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
130 } 130 }
131 131
132 UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uriStr); 132 UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uriStr);
133 UUID userID = uasConn.GetUUID(names[0], names[1]); 133
134 UUID userID = UUID.Zero;
135 try
136 {
137 userID = uasConn.GetUUID(names[0], names[1]);
138 }
139 catch (Exception e)
140 {
141 m_log.Debug("[USER MANAGEMENT MODULE]: GetUUID call failed ", e);
142 }
143
134 if (!userID.Equals(UUID.Zero)) 144 if (!userID.Equals(UUID.Zero))
135 { 145 {
136 UserData ud = new UserData(); 146 UserData ud = new UserData();
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index 3fb5195..9f0a719 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
473 // serverType, userdata.HomeURL, userID); 473 // serverType, userdata.HomeURL, userID);
474 474
475 UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL); 475 UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL);
476 userdata.ServerURLs = uConn.GetServerURLs(userID); 476 try
477 {
478 userdata.ServerURLs = uConn.GetServerURLs(userID);
479 }
480 catch (Exception e)
481 {
482 m_log.Debug("[USER MANAGEMENT MODULE]: GetServerURLs call failed ", e);
483 userdata.ServerURLs = new Dictionary<string, object>();
484 }
485
477 if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null) 486 if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null)
478 return userdata.ServerURLs[serverType].ToString(); 487 return userdata.ServerURLs[serverType].ToString();
479 } 488 }
diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
index 79a409d..8a649ab 100644
--- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
@@ -126,7 +126,8 @@ namespace OpenSim.Region.CoreModules.Hypergrid
126 foreach (MapBlockData b in mapBlocks) 126 foreach (MapBlockData b in mapBlocks)
127 { 127 {
128 b.Name = string.Empty; 128 b.Name = string.Empty;
129 b.Access = 254; // means 'simulator is offline'. We need this because the viewer ignores 255's 129 // Set 'simulator is offline'. We need this because the viewer ignores SimAccess.Unknown (255)
130 b.Access = (byte)SimAccess.Down;
130 } 131 }
131 132
132 m_log.DebugFormat("[HG MAP]: Resetting {0} blocks", mapBlocks.Count); 133 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 56d9937..bda354f 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
125 public OpenSim.Services.Interfaces.GridRegion HelloNeighbour(ulong regionHandle, RegionInfo thisRegion) 125 public OpenSim.Services.Interfaces.GridRegion HelloNeighbour(ulong regionHandle, RegionInfo thisRegion)
126 { 126 {
127 uint x, y; 127 uint x, y;
128 Utils.LongToUInts(regionHandle, out x, out y); 128 Util.RegionHandleToRegionLoc(regionHandle, out x, out y);
129 129
130 foreach (Scene s in m_Scenes) 130 foreach (Scene s in m_Scenes)
131 { 131 {
132 if (s.RegionInfo.RegionHandle == regionHandle) 132 if (s.RegionInfo.RegionHandle == regionHandle)
133 { 133 {
134 m_log.DebugFormat("[LOCAL NEIGHBOUR SERVICE CONNECTOR]: HelloNeighbour from region {0} to neighbour {1} at {2}-{3}", 134 m_log.DebugFormat("[LOCAL NEIGHBOUR SERVICE CONNECTOR]: HelloNeighbour from region {0} to neighbour {1} at {2}-{3}",
135 thisRegion.RegionName, s.Name, Util.WorldToRegionLoc(x), Util.WorldToRegionLoc(y) ); 135 thisRegion.RegionName, s.Name, x, y );
136 136
137 //m_log.Debug("[NEIGHBOUR CONNECTOR]: Found region to SendHelloNeighbour"); 137 //m_log.Debug("[NEIGHBOUR CONNECTOR]: Found region to SendHelloNeighbour");
138 return s.IncomingHelloNeighbour(thisRegion); 138 return s.IncomingHelloNeighbour(thisRegion);
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index 0c4b79b..2e638d4 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
483 SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); 483 SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject);
484 484
485 // Happily this does not do much to the object since it hasn't been added to the scene yet 485 // Happily this does not do much to the object since it hasn't been added to the scene yet
486 if (sceneObject.AttachmentPoint == 0) 486 if (!sceneObject.IsAttachment)
487 { 487 {
488 if (m_displacement != Vector3.Zero || m_rotation != 0f) 488 if (m_displacement != Vector3.Zero || m_rotation != 0f)
489 { 489 {
diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
index 5728731..be328a7 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
631 private warp_Texture GetTexture(UUID id) 631 private warp_Texture GetTexture(UUID id)
632 { 632 {
633 warp_Texture ret = null; 633 warp_Texture ret = null;
634
634 byte[] asset = m_scene.AssetService.GetData(id.ToString()); 635 byte[] asset = m_scene.AssetService.GetData(id.ToString());
636
635 if (asset != null) 637 if (asset != null)
636 { 638 {
637 IJ2KDecoder imgDecoder = m_scene.RequestModuleInterface<IJ2KDecoder>(); 639 IJ2KDecoder imgDecoder = m_scene.RequestModuleInterface<IJ2KDecoder>();
638 Bitmap img = (Bitmap) imgDecoder.DecodeToImage(asset); 640 Bitmap img = null;
641
642 try
643 {
644 img = (Bitmap)imgDecoder.DecodeToImage(asset);
645 }
646 catch (Exception e)
647 {
648 m_log.Warn(string.Format("[WARP 3D IMAGE MODULE]: Failed to decode asset {0}, exception ", id), e);
649 }
650
639 if (img != null) 651 if (img != null)
640 { 652 {
641 return new warp_Texture(img); 653 return new warp_Texture(img);
642 } 654 }
643 } 655 }
656
644 return ret; 657 return ret;
645 } 658 }
646 659
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
index 1fb1aba..c35f6b7 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
214 // final block, closing the search result 214 // final block, closing the search result
215 MapBlockData data = new MapBlockData(); 215 MapBlockData data = new MapBlockData();
216 data.Agents = 0; 216 data.Agents = 0;
217 data.Access = 255; 217 data.Access = (byte)SimAccess.NonExistent;
218 data.MapImageId = UUID.Zero; 218 data.MapImageId = UUID.Zero;
219 data.Name = ""; 219 data.Name = "";
220 data.RegionFlags = 0; 220 data.RegionFlags = 0;
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
index 709d8fc..5d07a5f 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
@@ -92,11 +92,12 @@ namespace OpenSim.Region.Framework.Interfaces
92 92
93 void EnableChildAgent(ScenePresence agent, GridRegion region); 93 void EnableChildAgent(ScenePresence agent, GridRegion region);
94 94
95 GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos); 95 GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version,
96 out Vector3 newpos, out string reason);
96 97
97 void Cross(SceneObjectGroup sog, Vector3 position, bool silent); 98 void Cross(SceneObjectGroup sog, Vector3 position, bool silent);
98 99
99 ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version); 100 ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version);
100 } 101 }
101 102
102 public interface IUserAgentVerificationModule 103 public interface IUserAgentVerificationModule
diff --git a/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs
index e03ac5a..c6f531e 100644
--- a/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs
@@ -55,5 +55,10 @@ namespace OpenSim.Region.Framework.Interfaces
55 /// Currently, will throw an exception if this does not match a root region. 55 /// Currently, will throw an exception if this does not match a root region.
56 /// </param> 56 /// </param>
57 Vector2 GetSizeOfMegaregion(UUID regionId); 57 Vector2 GetSizeOfMegaregion(UUID regionId);
58
59 /// <summary>
60 /// Tests to see of position (relative to the region) is within the megaregion
61 /// </summary>
62 bool PositionIsInMegaregion(UUID currentRegion, int xx, int yy);
58 } 63 }
59} \ No newline at end of file 64} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 37b5776..ba79964 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -430,6 +430,9 @@ namespace OpenSim.Region.Framework.Scenes
430 public delegate void IncomingInstantMessage(GridInstantMessage message); 430 public delegate void IncomingInstantMessage(GridInstantMessage message);
431 public event IncomingInstantMessage OnIncomingInstantMessage; 431 public event IncomingInstantMessage OnIncomingInstantMessage;
432 432
433 public delegate void CrossAgentToNewRegion(ScenePresence sp, bool isFlying, GridRegion newRegion);
434 public event CrossAgentToNewRegion OnCrossAgentToNewRegion;
435
433 public event IncomingInstantMessage OnUnhandledInstantMessage; 436 public event IncomingInstantMessage OnUnhandledInstantMessage;
434 437
435 public delegate void ClientClosed(UUID clientID, Scene scene); 438 public delegate void ClientClosed(UUID clientID, Scene scene);
@@ -1960,6 +1963,27 @@ namespace OpenSim.Region.Framework.Scenes
1960 } 1963 }
1961 } 1964 }
1962 1965
1966 public void TriggerCrossAgentToNewRegion(ScenePresence agent, bool isFlying, GridRegion newRegion)
1967 {
1968 CrossAgentToNewRegion handlerCrossAgentToNewRegion = OnCrossAgentToNewRegion;
1969 if (handlerCrossAgentToNewRegion != null)
1970 {
1971 foreach (CrossAgentToNewRegion d in handlerCrossAgentToNewRegion.GetInvocationList())
1972 {
1973 try
1974 {
1975 d(agent, isFlying, newRegion);
1976 }
1977 catch (Exception e)
1978 {
1979 m_log.ErrorFormat(
1980 "[EVENT MANAGER]: Delegate for TriggerCrossAgentToNewRegion failed - continuing. {0} {1}",
1981 e.Message, e.StackTrace);
1982 }
1983 }
1984 }
1985 }
1986
1963 public void TriggerIncomingInstantMessage(GridInstantMessage message) 1987 public void TriggerIncomingInstantMessage(GridInstantMessage message)
1964 { 1988 {
1965 IncomingInstantMessage handlerIncomingInstantMessage = OnIncomingInstantMessage; 1989 IncomingInstantMessage handlerIncomingInstantMessage = OnIncomingInstantMessage;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 2f666c0..676c000 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -160,11 +160,6 @@ namespace OpenSim.Region.Framework.Scenes
160 /// </summary> 160 /// </summary>
161 public SimStatsReporter StatsReporter { get; private set; } 161 public SimStatsReporter StatsReporter { get; private set; }
162 162
163 public List<Border> NorthBorders = new List<Border>();
164 public List<Border> EastBorders = new List<Border>();
165 public List<Border> SouthBorders = new List<Border>();
166 public List<Border> WestBorders = new List<Border>();
167
168 /// <summary> 163 /// <summary>
169 /// Controls whether physics can be applied to prims. Even if false, prims still have entries in a 164 /// Controls whether physics can be applied to prims. Even if false, prims still have entries in a
170 /// PhysicsScene in order to perform collision detection 165 /// PhysicsScene in order to perform collision detection
@@ -218,7 +213,14 @@ namespace OpenSim.Region.Framework.Scenes
218 protected float m_defaultDrawDistance = 255.0f; 213 protected float m_defaultDrawDistance = 255.0f;
219 public float DefaultDrawDistance 214 public float DefaultDrawDistance
220 { 215 {
221 get { return m_defaultDrawDistance; } 216 // get { return m_defaultDrawDistance; }
217 get {
218 if (RegionInfo != null)
219 {
220 m_defaultDrawDistance = Math.Max(RegionInfo.RegionSizeX, RegionInfo.RegionSizeY);
221 }
222 return m_defaultDrawDistance;
223 }
222 } 224 }
223 225
224 private List<string> m_AllowedViewers = new List<string>(); 226 private List<string> m_AllowedViewers = new List<string>();
@@ -349,7 +351,6 @@ namespace OpenSim.Region.Framework.Scenes
349 351
350 // TODO: Possibly stop other classes being able to manipulate this directly. 352 // TODO: Possibly stop other classes being able to manipulate this directly.
351 private SceneGraph m_sceneGraph; 353 private SceneGraph m_sceneGraph;
352 private volatile int m_bordersLocked;
353 private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing 354 private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing
354 private volatile bool m_backingup; 355 private volatile bool m_backingup;
355 private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>(); 356 private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>();
@@ -426,18 +427,6 @@ namespace OpenSim.Region.Framework.Scenes
426 set { m_splitRegionID = value; } 427 set { m_splitRegionID = value; }
427 } 428 }
428 429
429 public bool BordersLocked
430 {
431 get { return m_bordersLocked == 1; }
432 set
433 {
434 if (value == true)
435 m_bordersLocked = 1;
436 else
437 m_bordersLocked = 0;
438 }
439 }
440
441 public new float TimeDilation 430 public new float TimeDilation
442 { 431 {
443 get { return m_sceneGraph.PhysicsScene.TimeDilation; } 432 get { return m_sceneGraph.PhysicsScene.TimeDilation; }
@@ -1031,28 +1020,6 @@ namespace OpenSim.Region.Framework.Scenes
1031 PeriodicBackup = true; 1020 PeriodicBackup = true;
1032 UseBackup = true; 1021 UseBackup = true;
1033 1022
1034 BordersLocked = true;
1035 Border northBorder = new Border();
1036 northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (float)RegionInfo.RegionSizeY); //<---
1037 northBorder.CrossDirection = Cardinals.N;
1038 NorthBorders.Add(northBorder);
1039
1040 Border southBorder = new Border();
1041 southBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue,0); //--->
1042 southBorder.CrossDirection = Cardinals.S;
1043 SouthBorders.Add(southBorder);
1044
1045 Border eastBorder = new Border();
1046 eastBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, (float)RegionInfo.RegionSizeY); //<---
1047 eastBorder.CrossDirection = Cardinals.E;
1048 EastBorders.Add(eastBorder);
1049
1050 Border westBorder = new Border();
1051 westBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue,0); //--->
1052 westBorder.CrossDirection = Cardinals.W;
1053 WestBorders.Add(westBorder);
1054 BordersLocked = false;
1055
1056 m_eventManager = new EventManager(); 1023 m_eventManager = new EventManager();
1057 1024
1058 m_permissions = new ScenePermissions(this); 1025 m_permissions = new ScenePermissions(this);
@@ -2445,201 +2412,34 @@ namespace OpenSim.Region.Framework.Scenes
2445 } 2412 }
2446 2413
2447 // Simple test to see if a position is in the current region. 2414 // Simple test to see if a position is in the current region.
2448 // Resuming the position is relative to the region so anything outside its bounds. 2415 // This test is mostly used to see if a region crossing is necessary.
2416 // Assuming the position is relative to the region so anything outside its bounds.
2449 // Return 'true' if position inside region. 2417 // Return 'true' if position inside region.
2450 public bool PositionIsInCurrentRegion(Vector3 pos) 2418 public bool PositionIsInCurrentRegion(Vector3 pos)
2451 { 2419 {
2452 bool ret = true; 2420 bool ret = false;
2453 int xx = (int)Math.Floor(pos.X); 2421 int xx = (int)Math.Floor(pos.X);
2454 int yy = (int)Math.Floor(pos.Y); 2422 int yy = (int)Math.Floor(pos.Y);
2455 if (xx < 0 2423 if (xx < 0 || yy < 0)
2456 || xx >= RegionInfo.RegionSizeX 2424 return false;
2457 || yy < 0
2458 || yy >= RegionInfo.RegionSizeY)
2459 ret = false;
2460 return ret;
2461
2462 }
2463 2425
2464 public Border GetCrossedBorder(Vector3 position, Cardinals gridline) 2426 IRegionCombinerModule regionCombinerModule = RequestModuleInterface<IRegionCombinerModule>();
2465 { 2427 if (regionCombinerModule == null)
2466 if (BordersLocked)
2467 { 2428 {
2468 switch (gridline) 2429 // Regular region. Just check for region size
2469 { 2430 if (xx < RegionInfo.RegionSizeX && yy < RegionInfo.RegionSizeY )
2470 case Cardinals.N: 2431 ret = true;
2471 lock (NorthBorders)
2472 {
2473 foreach (Border b in NorthBorders)
2474 {
2475 if (b.TestCross(position))
2476 return b;
2477 }
2478 }
2479 break;
2480 case Cardinals.S:
2481 lock (SouthBorders)
2482 {
2483 foreach (Border b in SouthBorders)
2484 {
2485 if (b.TestCross(position))
2486 return b;
2487 }
2488 }
2489
2490 break;
2491 case Cardinals.E:
2492 lock (EastBorders)
2493 {
2494 foreach (Border b in EastBorders)
2495 {
2496 if (b.TestCross(position))
2497 return b;
2498 }
2499 }
2500
2501 break;
2502 case Cardinals.W:
2503
2504 lock (WestBorders)
2505 {
2506 foreach (Border b in WestBorders)
2507 {
2508 if (b.TestCross(position))
2509 return b;
2510 }
2511 }
2512 break;
2513
2514 }
2515 } 2432 }
2516 else 2433 else
2517 { 2434 {
2518 switch (gridline) 2435 // We're in a mega-region so see if we are still in that larger region
2519 { 2436 ret = regionCombinerModule.PositionIsInMegaregion(this.RegionInfo.RegionID, xx, yy);
2520 case Cardinals.N:
2521 foreach (Border b in NorthBorders)
2522 {
2523 if (b.TestCross(position))
2524 return b;
2525 }
2526
2527 break;
2528 case Cardinals.S:
2529 foreach (Border b in SouthBorders)
2530 {
2531 if (b.TestCross(position))
2532 return b;
2533 }
2534 break;
2535 case Cardinals.E:
2536 foreach (Border b in EastBorders)
2537 {
2538 if (b.TestCross(position))
2539 return b;
2540 }
2541
2542 break;
2543 case Cardinals.W:
2544 foreach (Border b in WestBorders)
2545 {
2546 if (b.TestCross(position))
2547 return b;
2548 }
2549 break;
2550
2551 }
2552 } 2437 }
2553 2438
2554 return null; 2439 return ret;
2555 }
2556 2440
2557 public bool TestBorderCross(Vector3 position, Cardinals border)
2558 {
2559 if (BordersLocked)
2560 {
2561 switch (border)
2562 {
2563 case Cardinals.N:
2564 lock (NorthBorders)
2565 {
2566 foreach (Border b in NorthBorders)
2567 {
2568 if (b.TestCross(position))
2569 return true;
2570 }
2571 }
2572 break;
2573 case Cardinals.E:
2574 lock (EastBorders)
2575 {
2576 foreach (Border b in EastBorders)
2577 {
2578 if (b.TestCross(position))
2579 return true;
2580 }
2581 }
2582 break;
2583 case Cardinals.S:
2584 lock (SouthBorders)
2585 {
2586 foreach (Border b in SouthBorders)
2587 {
2588 if (b.TestCross(position))
2589 return true;
2590 }
2591 }
2592 break;
2593 case Cardinals.W:
2594 lock (WestBorders)
2595 {
2596 foreach (Border b in WestBorders)
2597 {
2598 if (b.TestCross(position))
2599 return true;
2600 }
2601 }
2602 break;
2603 }
2604 }
2605 else
2606 {
2607 switch (border)
2608 {
2609 case Cardinals.N:
2610 foreach (Border b in NorthBorders)
2611 {
2612 if (b.TestCross(position))
2613 return true;
2614 }
2615 break;
2616 case Cardinals.E:
2617 foreach (Border b in EastBorders)
2618 {
2619 if (b.TestCross(position))
2620 return true;
2621 }
2622 break;
2623 case Cardinals.S:
2624 foreach (Border b in SouthBorders)
2625 {
2626 if (b.TestCross(position))
2627 return true;
2628 }
2629 break;
2630 case Cardinals.W:
2631 foreach (Border b in WestBorders)
2632 {
2633 if (b.TestCross(position))
2634 return true;
2635 }
2636 break;
2637 }
2638 }
2639 return false;
2640 } 2441 }
2641 2442
2642
2643 /// <summary> 2443 /// <summary>
2644 /// Called when objects or attachments cross the border, or teleport, between regions. 2444 /// Called when objects or attachments cross the border, or teleport, between regions.
2645 /// </summary> 2445 /// </summary>
@@ -3874,61 +3674,11 @@ namespace OpenSim.Region.Framework.Scenes
3874 { 3674 {
3875// CleanDroppedAttachments(); 3675// CleanDroppedAttachments();
3876 3676
3877 if (TestBorderCross(acd.startpos, Cardinals.E)) 3677 // Make sure avatar position is in the region (why it wouldn't be is a mystery but do sanity checking)
3878 { 3678 if (acd.startpos.X < 0) acd.startpos.X = 1f;
3879 Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.E); 3679 if (acd.startpos.X >= RegionInfo.RegionSizeX) acd.startpos.X = RegionInfo.RegionSizeX - 1f;
3880 acd.startpos.X = crossedBorder.BorderLine.Z - 1; 3680 if (acd.startpos.Y < 0) acd.startpos.Y = 1f;
3881 m_log.DebugFormat("{0} NewUserConnection Adjusted border E. startpos={1}", LogHeader, acd.startpos); 3681 if (acd.startpos.Y >= RegionInfo.RegionSizeY) acd.startpos.Y = RegionInfo.RegionSizeY - 1f;
3882 }
3883
3884 if (TestBorderCross(acd.startpos, Cardinals.N))
3885 {
3886 Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.N);
3887 acd.startpos.Y = crossedBorder.BorderLine.Z - 1;
3888 }
3889
3890 //Mitigate http://opensimulator.org/mantis/view.php?id=3522
3891 // Check if start position is outside of region
3892 // If it is, check the Z start position also.. if not, leave it alone.
3893 if (BordersLocked)
3894 {
3895 lock (EastBorders)
3896 {
3897 if (acd.startpos.X > EastBorders[0].BorderLine.Z)
3898 {
3899 m_log.Warn("FIX AGENT POSITION");
3900 acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f;
3901 if (acd.startpos.Z > 720)
3902 acd.startpos.Z = 720;
3903 }
3904 }
3905 lock (NorthBorders)
3906 {
3907 if (acd.startpos.Y > NorthBorders[0].BorderLine.Z)
3908 {
3909 m_log.Warn("FIX Agent POSITION");
3910 acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f;
3911 if (acd.startpos.Z > 720)
3912 acd.startpos.Z = 720;
3913 }
3914 }
3915 } else
3916 {
3917 if (acd.startpos.X > EastBorders[0].BorderLine.Z)
3918 {
3919 m_log.Warn("FIX AGENT POSITION");
3920 acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f;
3921 if (acd.startpos.Z > 720)
3922 acd.startpos.Z = 720;
3923 }
3924 if (acd.startpos.Y > NorthBorders[0].BorderLine.Z)
3925 {
3926 m_log.Warn("FIX Agent POSITION");
3927 acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f;
3928 if (acd.startpos.Z > 720)
3929 acd.startpos.Z = 720;
3930 }
3931 }
3932 3682
3933// m_log.DebugFormat( 3683// m_log.DebugFormat(
3934// "[SCENE]: Found telehub object {0} for new user connection {1} to {2}", 3684// "[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 c6b98ca..73a30f3 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -429,7 +429,7 @@ namespace OpenSim.Region.Framework.Scenes
429 /// <returns></returns> 429 /// <returns></returns>
430 public bool IsAttachmentCheckFull() 430 public bool IsAttachmentCheckFull()
431 { 431 {
432 return (IsAttachment || (m_rootPart.Shape.PCode == 9 && m_rootPart.Shape.State != 0)); 432 return (IsAttachment || (m_rootPart.Shape.PCode == (byte)PCodeEnum.Primitive && m_rootPart.Shape.State != 0));
433 } 433 }
434 434
435 private struct avtocrossInfo 435 private struct avtocrossInfo
@@ -451,23 +451,15 @@ namespace OpenSim.Region.Framework.Scenes
451 if (Scene != null) 451 if (Scene != null)
452 { 452 {
453 if ( 453 if (
454 // (Scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) 454 !Scene.PositionIsInCurrentRegion(val)
455 // || Scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W) 455 && !IsAttachmentCheckFull()
456 // || Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) 456 && (!Scene.LoadingPrims)
457 // || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S)) 457 )
458 // Experimental change for better border crossings.
459 // The commented out original lines above would, it seems, trigger
460 // a border crossing a little early or late depending on which
461 // direction the object was moving.
462 (Scene.TestBorderCross(val, Cardinals.E)
463 || Scene.TestBorderCross(val, Cardinals.W)
464 || Scene.TestBorderCross(val, Cardinals.N)
465 || Scene.TestBorderCross(val, Cardinals.S))
466 && !IsAttachmentCheckFull() && (!Scene.LoadingPrims))
467 { 458 {
468 IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 459 IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
469 string version = String.Empty; 460 string version = String.Empty;
470 Vector3 newpos = Vector3.Zero; 461 Vector3 newpos = Vector3.Zero;
462 string failureReason = String.Empty;
471 OpenSim.Services.Interfaces.GridRegion destination = null; 463 OpenSim.Services.Interfaces.GridRegion destination = null;
472 464
473 if (m_rootPart.KeyframeMotion != null) 465 if (m_rootPart.KeyframeMotion != null)
@@ -485,7 +477,7 @@ namespace OpenSim.Region.Framework.Scenes
485 477
486 // We set the avatar position as being the object 478 // We set the avatar position as being the object
487 // position to get the region to send to 479 // position to get the region to send to
488 if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out version, out newpos)) == null) 480 if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out version, out newpos, out failureReason)) == null)
489 { 481 {
490 canCross = false; 482 canCross = false;
491 break; 483 break;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 1cf7726..db4e285 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -2479,13 +2479,10 @@ namespace OpenSim.Region.Framework.Scenes
2479 2479
2480 if (pa != null) 2480 if (pa != null)
2481 { 2481 {
2482 Vector3 newpos = new Vector3(pa.Position.GetBytes(), 0); 2482 Vector3 newpos = pa.Position;
2483 2483 if (!ParentGroup.Scene.PositionIsInCurrentRegion(newpos))
2484 if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
2485 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
2486 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
2487 | ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2488 { 2484 {
2485 // Setting position outside current region will start region crossing
2489 ParentGroup.AbsolutePosition = newpos; 2486 ParentGroup.AbsolutePosition = newpos;
2490 return; 2487 return;
2491 } 2488 }
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 715a9b6..d4af9fc 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1057,30 +1057,32 @@ namespace OpenSim.Region.Framework.Scenes
1057 1057
1058 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); 1058 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
1059 1059
1060 UUID groupUUID = UUID.Zero; 1060 UUID groupUUID = ControllingClient.ActiveGroupId;
1061 string GroupName = string.Empty; 1061 string groupName = string.Empty;
1062 ulong groupPowers = 0; 1062 ulong groupPowers = 0;
1063 1063
1064 // ---------------------------------- 1064 // ----------------------------------
1065 // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status 1065 // Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
1066 try 1066 try
1067 { 1067 {
1068 if (gm != null) 1068 if (groupUUID != UUID.Zero && gm != null)
1069 { 1069 {
1070 groupUUID = ControllingClient.ActiveGroupId;
1071 GroupRecord record = gm.GetGroupRecord(groupUUID); 1070 GroupRecord record = gm.GetGroupRecord(groupUUID);
1072 if (record != null) 1071 if (record != null)
1073 GroupName = record.GroupName; 1072 groupName = record.GroupName;
1073
1074 GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid); 1074 GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid);
1075
1075 if (groupMembershipData != null) 1076 if (groupMembershipData != null)
1076 groupPowers = groupMembershipData.GroupPowers; 1077 groupPowers = groupMembershipData.GroupPowers;
1077 } 1078 }
1078 ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName, 1079
1079 Grouptitle); 1080 ControllingClient.SendAgentDataUpdate(
1081 m_uuid, groupUUID, Firstname, Lastname, groupPowers, groupName, Grouptitle);
1080 } 1082 }
1081 catch (Exception e) 1083 catch (Exception e)
1082 { 1084 {
1083 m_log.Debug("[AGENTUPDATE]: " + e.ToString()); 1085 m_log.Error("[AGENTUPDATE]: Error ", e);
1084 } 1086 }
1085 // ------------------------------------ 1087 // ------------------------------------
1086 1088
@@ -3471,8 +3473,6 @@ namespace OpenSim.Region.Framework.Scenes
3471 Vector3 pos2 = AbsolutePosition; 3473 Vector3 pos2 = AbsolutePosition;
3472 Vector3 origPosition = pos2; 3474 Vector3 origPosition = pos2;
3473 Vector3 vel = Velocity; 3475 Vector3 vel = Velocity;
3474 int neighbor = 0;
3475 int[] fix = new int[2];
3476 3476
3477 // Compute the avatar position in the next physics tick. 3477 // Compute the avatar position in the next physics tick.
3478 // If the avatar will be crossing, we force the crossing to happen now 3478 // If the avatar will be crossing, we force the crossing to happen now
@@ -3505,23 +3505,13 @@ namespace OpenSim.Region.Framework.Scenes
3505 if (m_requestedSitTargetUUID == UUID.Zero) 3505 if (m_requestedSitTargetUUID == UUID.Zero)
3506 { 3506 {
3507 m_log.DebugFormat("{0} CheckForBorderCrossing: Crossing failed. Restoring old position.", LogHeader); 3507 m_log.DebugFormat("{0} CheckForBorderCrossing: Crossing failed. Restoring old position.", LogHeader);
3508 const float borderFudge = 0.1f; 3508
3509
3510 if (origPosition.X < 0)
3511 origPosition.X = borderFudge;
3512 else if (origPosition.X > (float)m_scene.RegionInfo.RegionSizeX)
3513 origPosition.X = (float)m_scene.RegionInfo.RegionSizeX - borderFudge;
3514 if (origPosition.Y < 0)
3515 origPosition.Y = borderFudge;
3516 else if (origPosition.Y > (float)m_scene.RegionInfo.RegionSizeY)
3517 origPosition.Y = (float)m_scene.RegionInfo.RegionSizeY - borderFudge;
3518 Velocity = Vector3.Zero; 3509 Velocity = Vector3.Zero;
3519 AbsolutePosition = origPosition; 3510 AbsolutePosition = EnforceSanityOnPosition(origPosition);
3520 3511
3521 AddToPhysicalScene(isFlying); 3512 AddToPhysicalScene(isFlying);
3522 } 3513 }
3523 } 3514 }
3524
3525 } 3515 }
3526 } 3516 }
3527 else 3517 else
@@ -3539,6 +3529,36 @@ namespace OpenSim.Region.Framework.Scenes
3539 } 3529 }
3540 } 3530 }
3541 3531
3532 // Given a position, make sure it is within the current region.
3533 // If just outside some border, the returned position will be just inside the border on that side.
3534 private Vector3 EnforceSanityOnPosition(Vector3 origPosition)
3535 {
3536 const float borderFudge = 0.1f;
3537 Vector3 ret = origPosition;
3538
3539 // Sanity checking on the position to make sure it is in the region we couldn't cross from
3540 float extentX = (float)m_scene.RegionInfo.RegionSizeX;
3541 float extentY = (float)m_scene.RegionInfo.RegionSizeY;
3542 IRegionCombinerModule combiner = m_scene.RequestModuleInterface<IRegionCombinerModule>();
3543 if (combiner != null)
3544 {
3545 // If a mega-region, the size could be much bigger
3546 Vector2 megaExtent = combiner.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID);
3547 extentX = megaExtent.X;
3548 extentY = megaExtent.Y;
3549 }
3550 if (ret.X < 0)
3551 ret.X = borderFudge;
3552 else if (ret.X >= extentX)
3553 ret.X = extentX - borderFudge;
3554 if (ret.Y < 0)
3555 ret.Y = borderFudge;
3556 else if (ret.Y >= extentY)
3557 ret.Y = extentY - borderFudge;
3558
3559 return ret;
3560 }
3561
3542 /// <summary> 3562 /// <summary>
3543 /// Moves the agent outside the region bounds 3563 /// Moves the agent outside the region bounds
3544 /// Tells neighbor region that we're crossing to it 3564 /// 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 e28d0c2..a040f43 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
1012 Hashtable respData = (Hashtable)resp.Value; 1012 Hashtable respData = (Hashtable)resp.Value;
1013 if (respData.Contains("error") && !respData.Contains("succeed")) 1013 if (respData.Contains("error") && !respData.Contains("succeed"))
1014 { 1014 {
1015 LogRespDataToConsoleError(respData); 1015 LogRespDataToConsoleError(requestingAgentID, function, param, respData);
1016 } 1016 }
1017 1017
1018 return respData; 1018 return respData;
@@ -1040,20 +1040,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1040 return error; 1040 return error;
1041 } 1041 }
1042 1042
1043 private void LogRespDataToConsoleError(Hashtable respData) 1043 private void LogRespDataToConsoleError(UUID requestingAgentID, string function, Hashtable param, Hashtable respData)
1044 { 1044 {
1045 m_log.Error("[XMLRPC-GROUPS-CONNECTOR]: Error:"); 1045 m_log.ErrorFormat(
1046 1046 "[XMLRPC-GROUPS-CONNECTOR]: Error when calling {0} for {1} with params {2}. Response params are {3}",
1047 foreach (string key in respData.Keys) 1047 function, requestingAgentID, Util.PrettyFormatToSingleLine(param), Util.PrettyFormatToSingleLine(respData));
1048 {
1049 m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: Key: {0}", key);
1050
1051 string[] lines = respData[key].ToString().Split(new char[] { '\n' });
1052 foreach (string line in lines)
1053 {
1054 m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0}", line);
1055 }
1056 }
1057 } 1048 }
1058 1049
1059 /// <summary> 1050 /// <summary>
diff --git a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs
index 29b39e0..5fb74b0 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
116 + "If teleport is true then some extra teleport debug information is logged.\n" 116 + "If teleport is true then some extra teleport debug information is logged.\n"
117 + "If updates is true then any frame which exceeds double the maximum desired frame time is logged.", 117 + "If updates is true then any frame which exceeds double the maximum desired frame time is logged.",
118 HandleDebugSceneSetCommand); 118 HandleDebugSceneSetCommand);
119
120 scene.AddCommand(
121 "Regions",
122 this, "show borders", "show borders", "Show border information for regions", HandleShowBordersCommand);
123 }
124
125 private void HandleShowBordersCommand(string module, string[] args)
126 {
127 StringBuilder sb = new StringBuilder();
128 sb.AppendFormat("Borders for {0}:\n", m_scene.Name);
129
130 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
131 cdt.AddColumn("Cross Direction", 15);
132 cdt.AddColumn("Line", 34);
133 cdt.AddColumn("Trigger Region", 14);
134
135 foreach (Border b in m_scene.NorthBorders)
136 cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY));
137
138 foreach (Border b in m_scene.EastBorders)
139 cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY));
140
141 foreach (Border b in m_scene.SouthBorders)
142 cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY));
143
144 foreach (Border b in m_scene.WestBorders)
145 cdt.AddRow(b.CrossDirection, b.BorderLine, string.Format("{0}, {1}", b.TriggerRegionX, b.TriggerRegionY));
146
147 cdt.AddToStringBuilder(sb);
148
149 MainConsole.Instance.Output(sb.ToString());
150 } 119 }
151 120
152 private void HandleDebugSceneGetCommand(string module, string[] args) 121 private void HandleDebugSceneGetCommand(string module, string[] args)
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs
index 7127c73..a7ffad0 100644
--- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs
+++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs
@@ -44,6 +44,7 @@ namespace OpenSim.Region.RegionCombinerModule
44 public class RegionCombinerModule : ISharedRegionModule, IRegionCombinerModule 44 public class RegionCombinerModule : ISharedRegionModule, IRegionCombinerModule
45 { 45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47 private static string LogHeader = "[REGION COMBINER MODULE]";
47 48
48 public string Name 49 public string Name
49 { 50 {
@@ -134,6 +135,49 @@ namespace OpenSim.Region.RegionCombinerModule
134 throw new Exception(string.Format("Region with id {0} not found", regionId)); 135 throw new Exception(string.Format("Region with id {0} not found", regionId));
135 } 136 }
136 137
138 // Test to see if this postiion (relative to the region) is within the area covered
139 // by this megaregion.
140 public bool PositionIsInMegaregion(UUID currentRegion, int xx, int yy)
141 {
142 bool ret = false;
143 if (xx < 0 || yy < 0)
144 return ret;
145
146 foreach (RegionConnections rootRegion in m_regions.Values)
147 {
148 if (currentRegion == rootRegion.RegionId)
149 {
150 // The caller is in the root region so this is an easy test
151 if (xx < rootRegion.XEnd && yy < rootRegion.YEnd)
152 {
153 ret = true;
154 }
155 break;
156 }
157 else
158 {
159 // Maybe the caller is in one of the sub-regions
160 foreach (RegionData childRegion in rootRegion.ConnectedRegions)
161 {
162 if (currentRegion == childRegion.RegionId)
163 {
164 // This is a child. Diddle the offsets and check if in
165 Vector3 positionInMegaregion = childRegion.Offset;
166 positionInMegaregion.X += xx;
167 positionInMegaregion.Y += yy;
168 if (positionInMegaregion.X < rootRegion.XEnd && positionInMegaregion.Y < rootRegion.YEnd)
169 {
170 ret = true;
171 }
172 break;
173 }
174 }
175 }
176 }
177
178 return ret;
179 }
180
137 private void NewPresence(ScenePresence presence) 181 private void NewPresence(ScenePresence presence)
138 { 182 {
139 if (presence.IsChildAgent) 183 if (presence.IsChildAgent)
@@ -220,27 +264,6 @@ namespace OpenSim.Region.RegionCombinerModule
220 // 264 //
221*/ 265*/
222 266
223 // Give each region a standard set of non-infinite borders
224 Border northBorder = new Border();
225 northBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, (int)Constants.RegionSize); //<---
226 northBorder.CrossDirection = Cardinals.N;
227 scene.NorthBorders[0] = northBorder;
228
229 Border southBorder = new Border();
230 southBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, 0); //--->
231 southBorder.CrossDirection = Cardinals.S;
232 scene.SouthBorders[0] = southBorder;
233
234 Border eastBorder = new Border();
235 eastBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, (int)Constants.RegionSize); //<---
236 eastBorder.CrossDirection = Cardinals.E;
237 scene.EastBorders[0] = eastBorder;
238
239 Border westBorder = new Border();
240 westBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, 0); //--->
241 westBorder.CrossDirection = Cardinals.W;
242 scene.WestBorders[0] = westBorder;
243
244 RegionConnections newConn = new RegionConnections(); 267 RegionConnections newConn = new RegionConnections();
245 newConn.ConnectedRegions = new List<RegionData>(); 268 newConn.ConnectedRegions = new List<RegionData>();
246 newConn.RegionScene = scene; 269 newConn.RegionScene = scene;
@@ -248,8 +271,8 @@ namespace OpenSim.Region.RegionCombinerModule
248 newConn.RegionId = scene.RegionInfo.originRegionID; 271 newConn.RegionId = scene.RegionInfo.originRegionID;
249 newConn.X = scene.RegionInfo.RegionLocX; 272 newConn.X = scene.RegionInfo.RegionLocX;
250 newConn.Y = scene.RegionInfo.RegionLocY; 273 newConn.Y = scene.RegionInfo.RegionLocY;
251 newConn.XEnd = (int)Constants.RegionSize; 274 newConn.XEnd = scene.RegionInfo.RegionSizeX;
252 newConn.YEnd = (int)Constants.RegionSize; 275 newConn.YEnd = scene.RegionInfo.RegionSizeX;
253 276
254 lock (m_regions) 277 lock (m_regions)
255 { 278 {
@@ -415,6 +438,11 @@ namespace OpenSim.Region.RegionCombinerModule
415 */ 438 */
416 #endregion 439 #endregion
417 440
441
442 // Check to see if this new region is adjacent to the root region.
443 // Note that we expect the regions to be combined from the root region outward
444 // thus the requirement for the ordering in the configuration files.
445
418 // If we're one region over +x y (i.e. root region is to the west) 446 // If we're one region over +x y (i.e. root region is to the west)
419 //xxx 447 //xxx
420 //xxy 448 //xxy
@@ -431,7 +459,7 @@ namespace OpenSim.Region.RegionCombinerModule
431 //xxx 459 //xxx
432 if (rootConn.PosX >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY) 460 if (rootConn.PosX >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY)
433 { 461 {
434 connectedYN = DoWorkForOneRegionOverXPlusY(rootConn, newConn, scene); 462 connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene);
435 break; 463 break;
436 } 464 }
437 465
@@ -441,9 +469,8 @@ namespace OpenSim.Region.RegionCombinerModule
441 //xxx 469 //xxx
442 if (rootConn.PosX + rootConn.XEnd >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY) 470 if (rootConn.PosX + rootConn.XEnd >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY)
443 { 471 {
444 connectedYN = DoWorkForOneRegionOverPlusXPlusY(rootConn, newConn, scene); 472 connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene);
445 break; 473 break;
446
447 } 474 }
448 } 475 }
449 476
@@ -453,20 +480,20 @@ namespace OpenSim.Region.RegionCombinerModule
453 DoWorkForRootRegion(newConn, scene); 480 DoWorkForRootRegion(newConn, scene);
454 } 481 }
455 } 482 }
456
457 // Set up infinite borders around the entire AABB of the combined ConnectedRegions
458 AdjustLargeRegionBounds();
459 } 483 }
460 484
461 private bool DoWorkForOneRegionOverPlusXY(RegionConnections rootConn, RegionConnections newConn, Scene scene) 485 private bool DoWorkForOneRegionOverPlusXY(RegionConnections rootConn, RegionConnections newConn, Scene scene)
462 { 486 {
487 // Offset (in meters) from the base of this region to the base of the root region.
463 Vector3 offset = Vector3.Zero; 488 Vector3 offset = Vector3.Zero;
464 offset.X = newConn.PosX - rootConn.PosX; 489 offset.X = newConn.PosX - rootConn.PosX;
465 offset.Y = newConn.PosY - rootConn.PosY; 490 offset.Y = newConn.PosY - rootConn.PosY;
466 491
492 // The new total size of the region (in meters)
493 // We just extend the X and Y dimensions so the extent might temporarily include areas without regions.
467 Vector3 extents = Vector3.Zero; 494 Vector3 extents = Vector3.Zero;
468 extents.Y = rootConn.YEnd; 495 extents.X = Math.Max(rootConn.XEnd, offset.X + newConn.RegionScene.RegionInfo.RegionSizeX);
469 extents.X = rootConn.XEnd + newConn.XEnd; 496 extents.Y = Math.Max(rootConn.YEnd, offset.Y + newConn.RegionScene.RegionInfo.RegionSizeY);
470 497
471 rootConn.UpdateExtents(extents); 498 rootConn.UpdateExtents(extents);
472 499
@@ -475,9 +502,6 @@ namespace OpenSim.Region.RegionCombinerModule
475 rootConn.RegionScene.RegionInfo.RegionName, 502 rootConn.RegionScene.RegionInfo.RegionName,
476 newConn.RegionScene.RegionInfo.RegionName, offset, extents); 503 newConn.RegionScene.RegionInfo.RegionName, offset, extents);
477 504
478 scene.BordersLocked = true;
479 rootConn.RegionScene.BordersLocked = true;
480
481 RegionData ConnectedRegion = new RegionData(); 505 RegionData ConnectedRegion = new RegionData();
482 ConnectedRegion.Offset = offset; 506 ConnectedRegion.Offset = offset;
483 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; 507 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID;
@@ -490,34 +514,10 @@ namespace OpenSim.Region.RegionCombinerModule
490 // Inform Child region that it needs to forward it's terrain to the root region 514 // Inform Child region that it needs to forward it's terrain to the root region
491 scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); 515 scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero);
492 516
493 // Extend the borders as appropriate
494 lock (rootConn.RegionScene.EastBorders)
495 rootConn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize;
496
497 lock (rootConn.RegionScene.NorthBorders)
498 rootConn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
499
500 lock (rootConn.RegionScene.SouthBorders)
501 rootConn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
502
503 lock (scene.WestBorders)
504 {
505 scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - rootConn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West
506
507 // Trigger auto teleport to root region
508 scene.WestBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX;
509 scene.WestBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY;
510 }
511
512 // Reset Terrain.. since terrain loads before we get here, we need to load 517 // Reset Terrain.. since terrain loads before we get here, we need to load
513 // it again so it loads in the root region 518 // it again so it loads in the root region
514
515 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); 519 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
516 520
517 // Unlock borders
518 rootConn.RegionScene.BordersLocked = false;
519 scene.BordersLocked = false;
520
521 // Create a client event forwarder and add this region's events to the root region. 521 // Create a client event forwarder and add this region's events to the root region.
522 if (rootConn.ClientEventForwarder != null) 522 if (rootConn.ClientEventForwarder != null)
523 rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); 523 rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene);
@@ -525,6 +525,9 @@ namespace OpenSim.Region.RegionCombinerModule
525 return true; 525 return true;
526 } 526 }
527 527
528 /*
529 * 20140215 radams1: The border stuff was removed and the addition of regions to the mega-regions
530 * was generalized. These functions are not needed for the generalized solution but left for reference.
528 private bool DoWorkForOneRegionOverXPlusY(RegionConnections rootConn, RegionConnections newConn, Scene scene) 531 private bool DoWorkForOneRegionOverXPlusY(RegionConnections rootConn, RegionConnections newConn, Scene scene)
529 { 532 {
530 Vector3 offset = Vector3.Zero; 533 Vector3 offset = Vector3.Zero;
@@ -536,9 +539,6 @@ namespace OpenSim.Region.RegionCombinerModule
536 extents.X = rootConn.XEnd; 539 extents.X = rootConn.XEnd;
537 rootConn.UpdateExtents(extents); 540 rootConn.UpdateExtents(extents);
538 541
539 scene.BordersLocked = true;
540 rootConn.RegionScene.BordersLocked = true;
541
542 RegionData ConnectedRegion = new RegionData(); 542 RegionData ConnectedRegion = new RegionData();
543 ConnectedRegion.Offset = offset; 543 ConnectedRegion.Offset = offset;
544 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; 544 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID;
@@ -553,30 +553,11 @@ namespace OpenSim.Region.RegionCombinerModule
553 rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); 553 rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents);
554 scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); 554 scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero);
555 555
556 lock (rootConn.RegionScene.NorthBorders)
557 rootConn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize;
558
559 lock (rootConn.RegionScene.EastBorders)
560 rootConn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize;
561
562 lock (rootConn.RegionScene.WestBorders)
563 rootConn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize;
564
565 lock (scene.SouthBorders)
566 {
567 scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - rootConn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south
568 scene.SouthBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX;
569 scene.SouthBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY;
570 }
571
572 // Reset Terrain.. since terrain normally loads first. 556 // Reset Terrain.. since terrain normally loads first.
573 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); 557 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
574 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); 558 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
575 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); 559 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
576 560
577 scene.BordersLocked = false;
578 rootConn.RegionScene.BordersLocked = false;
579
580 if (rootConn.ClientEventForwarder != null) 561 if (rootConn.ClientEventForwarder != null)
581 rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); 562 rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene);
582 563
@@ -600,9 +581,6 @@ namespace OpenSim.Region.RegionCombinerModule
600 extents.Y = rootConn.YEnd; 581 extents.Y = rootConn.YEnd;
601 extents.X = rootConn.XEnd; 582 extents.X = rootConn.XEnd;
602 583
603 scene.BordersLocked = true;
604 rootConn.RegionScene.BordersLocked = true;
605
606 RegionData ConnectedRegion = new RegionData(); 584 RegionData ConnectedRegion = new RegionData();
607 ConnectedRegion.Offset = offset; 585 ConnectedRegion.Offset = offset;
608 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; 586 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID;
@@ -618,67 +596,10 @@ namespace OpenSim.Region.RegionCombinerModule
618 rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); 596 rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents);
619 scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); 597 scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero);
620 598
621 lock (rootConn.RegionScene.NorthBorders)
622 {
623 if (rootConn.RegionScene.NorthBorders.Count == 1)// && 2)
624 {
625 //compound border
626 // already locked above
627 rootConn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize;
628
629 lock (rootConn.RegionScene.EastBorders)
630 rootConn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize;
631
632 lock (rootConn.RegionScene.WestBorders)
633 rootConn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize;
634 }
635 }
636
637 lock (scene.SouthBorders)
638 {
639 scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - rootConn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south
640 scene.SouthBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX;
641 scene.SouthBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY;
642 }
643
644 lock (rootConn.RegionScene.EastBorders)
645 {
646 if (rootConn.RegionScene.EastBorders.Count == 1)// && conn.RegionScene.EastBorders.Count == 2)
647 {
648 rootConn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize;
649
650 lock (rootConn.RegionScene.NorthBorders)
651 rootConn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
652
653 lock (rootConn.RegionScene.SouthBorders)
654 rootConn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
655 }
656 }
657
658 lock (scene.WestBorders)
659 {
660 scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - rootConn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West
661 scene.WestBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX;
662 scene.WestBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY;
663 }
664
665 /*
666 else
667 {
668 conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize;
669 conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize;
670 conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize;
671 scene.SouthBorders[0].BorderLine.Z += (int)Constants.RegionSize; //auto teleport south
672 }
673 */
674
675
676 // Reset Terrain.. since terrain normally loads first. 599 // Reset Terrain.. since terrain normally loads first.
677 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); 600 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
678 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); 601 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
679 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); 602 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
680 scene.BordersLocked = false;
681 rootConn.RegionScene.BordersLocked = false;
682 603
683 if (rootConn.ClientEventForwarder != null) 604 if (rootConn.ClientEventForwarder != null)
684 rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); 605 rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene);
@@ -687,6 +608,7 @@ namespace OpenSim.Region.RegionCombinerModule
687 608
688 //scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset,extents); 609 //scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset,extents);
689 } 610 }
611 */
690 612
691 private void DoWorkForRootRegion(RegionConnections rootConn, Scene scene) 613 private void DoWorkForRootRegion(RegionConnections rootConn, Scene scene)
692 { 614 {
@@ -885,125 +807,6 @@ namespace OpenSim.Region.RegionCombinerModule
885// } 807// }
886// } 808// }
887 809
888 // Create a set of infinite borders around the whole aabb of the combined island.
889 private void AdjustLargeRegionBounds()
890 {
891 lock (m_regions)
892 {
893 foreach (RegionConnections rconn in m_regions.Values)
894 {
895 Vector3 offset = Vector3.Zero;
896 rconn.RegionScene.BordersLocked = true;
897 foreach (RegionData rdata in rconn.ConnectedRegions)
898 {
899 if (rdata.Offset.X > offset.X) offset.X = rdata.Offset.X;
900 if (rdata.Offset.Y > offset.Y) offset.Y = rdata.Offset.Y;
901 }
902
903 lock (rconn.RegionScene.NorthBorders)
904 {
905 Border northBorder = null;
906 // If we don't already have an infinite border, create one.
907 if (!TryGetInfiniteBorder(rconn.RegionScene.NorthBorders, out northBorder))
908 {
909 northBorder = new Border();
910 rconn.RegionScene.NorthBorders.Add(northBorder);
911 }
912
913 northBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue,
914 offset.Y + (int) Constants.RegionSize); //<---
915 northBorder.CrossDirection = Cardinals.N;
916 }
917
918 lock (rconn.RegionScene.SouthBorders)
919 {
920 Border southBorder = null;
921 // If we don't already have an infinite border, create one.
922 if (!TryGetInfiniteBorder(rconn.RegionScene.SouthBorders, out southBorder))
923 {
924 southBorder = new Border();
925 rconn.RegionScene.SouthBorders.Add(southBorder);
926 }
927 southBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, 0); //--->
928 southBorder.CrossDirection = Cardinals.S;
929 }
930
931 lock (rconn.RegionScene.EastBorders)
932 {
933 Border eastBorder = null;
934 // If we don't already have an infinite border, create one.
935 if (!TryGetInfiniteBorder(rconn.RegionScene.EastBorders, out eastBorder))
936 {
937 eastBorder = new Border();
938 rconn.RegionScene.EastBorders.Add(eastBorder);
939 }
940 eastBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, offset.X + (int)Constants.RegionSize);
941 //<---
942 eastBorder.CrossDirection = Cardinals.E;
943 }
944
945 lock (rconn.RegionScene.WestBorders)
946 {
947 Border westBorder = null;
948 // If we don't already have an infinite border, create one.
949 if (!TryGetInfiniteBorder(rconn.RegionScene.WestBorders, out westBorder))
950 {
951 westBorder = new Border();
952 rconn.RegionScene.WestBorders.Add(westBorder);
953
954 }
955 westBorder.BorderLine = new Vector3(float.MinValue, float.MaxValue, 0); //--->
956 westBorder.CrossDirection = Cardinals.W;
957 }
958
959 rconn.RegionScene.BordersLocked = false;
960 }
961 }
962 }
963
964 /// <summary>
965 /// Try and get an Infinite border out of a listT of borders
966 /// </summary>
967 /// <param name="borders"></param>
968 /// <param name="oborder"></param>
969 /// <returns></returns>
970 public static bool TryGetInfiniteBorder(List<Border> borders, out Border oborder)
971 {
972 // Warning! Should be locked before getting here!
973 foreach (Border b in borders)
974 {
975 if (b.BorderLine.X == float.MinValue && b.BorderLine.Y == float.MaxValue)
976 {
977 oborder = b;
978 return true;
979 }
980 }
981
982 oborder = null;
983 return false;
984 }
985
986 public RegionData GetRegionFromPosition(Vector3 pPosition)
987 {
988 pPosition = pPosition/(int) Constants.RegionSize;
989 int OffsetX = (int) pPosition.X;
990 int OffsetY = (int) pPosition.Y;
991
992 lock (m_regions)
993 {
994 foreach (RegionConnections regConn in m_regions.Values)
995 {
996 foreach (RegionData reg in regConn.ConnectedRegions)
997 {
998 if (reg.Offset.X == OffsetX && reg.Offset.Y == OffsetY)
999 return reg;
1000 }
1001 }
1002 }
1003
1004 return new RegionData();
1005 }
1006
1007 public void ForwardPermissionRequests(RegionConnections BigRegion, Scene VirtualRegion) 810 public void ForwardPermissionRequests(RegionConnections BigRegion, Scene VirtualRegion)
1008 { 811 {
1009 if (BigRegion.PermissionModule == null) 812 if (BigRegion.PermissionModule == null)
diff --git a/OpenSim/Region/RegionCombinerModule/RegionData.cs b/OpenSim/Region/RegionCombinerModule/RegionData.cs
index bd0e398..42fca9f 100644
--- a/OpenSim/Region/RegionCombinerModule/RegionData.cs
+++ b/OpenSim/Region/RegionCombinerModule/RegionData.cs
@@ -34,6 +34,7 @@ namespace OpenSim.Region.RegionCombinerModule
34 { 34 {
35 public UUID RegionId; 35 public UUID RegionId;
36 public Scene RegionScene; 36 public Scene RegionScene;
37 // Offset of this region from the base of the root region.
37 public Vector3 Offset; 38 public Vector3 Offset;
38 } 39 }
39} \ No newline at end of file 40} \ No newline at end of file