diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework/EntityTransfer')
-rw-r--r-- | OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 421 |
1 files changed, 372 insertions, 49 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index af004b0..44d3858 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -46,15 +46,16 @@ using Nini.Config; | |||
46 | 46 | ||
47 | namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | 47 | namespace OpenSim.Region.CoreModules.Framework.EntityTransfer |
48 | { | 48 | { |
49 | public class AgentTransferModule : ISharedRegionModule, IEntityTransferModule | 49 | public class EntityTransferModule : ISharedRegionModule, IEntityTransferModule |
50 | { | 50 | { |
51 | #region ISharedRegionModule | 51 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
52 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
53 | 52 | ||
54 | private bool m_Enabled = false; | 53 | private bool m_Enabled = false; |
55 | protected Scene m_aScene; | 54 | protected Scene m_aScene; |
56 | protected List<UUID> m_agentsInTransit; | 55 | protected List<UUID> m_agentsInTransit; |
57 | 56 | ||
57 | #region ISharedRegionModule | ||
58 | |||
58 | public Type ReplaceableInterface | 59 | public Type ReplaceableInterface |
59 | { | 60 | { |
60 | get { return null; } | 61 | get { return null; } |
@@ -62,7 +63,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
62 | 63 | ||
63 | public string Name | 64 | public string Name |
64 | { | 65 | { |
65 | get { return "AgentTransferModule"; } | 66 | get { return "BasicEntityTransferModule"; } |
66 | } | 67 | } |
67 | 68 | ||
68 | public virtual void Initialise(IConfigSource source) | 69 | public virtual void Initialise(IConfigSource source) |
@@ -70,12 +71,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
70 | IConfig moduleConfig = source.Configs["Modules"]; | 71 | IConfig moduleConfig = source.Configs["Modules"]; |
71 | if (moduleConfig != null) | 72 | if (moduleConfig != null) |
72 | { | 73 | { |
73 | string name = moduleConfig.GetString("AgentTransferModule", ""); | 74 | string name = moduleConfig.GetString("EntityTransferModule", ""); |
74 | if (name == Name) | 75 | if (name == Name) |
75 | { | 76 | { |
76 | m_agentsInTransit = new List<UUID>(); | 77 | m_agentsInTransit = new List<UUID>(); |
77 | m_Enabled = true; | 78 | m_Enabled = true; |
78 | m_log.Info("[AGENT TRANSFER MODULE]: Enabled."); | 79 | m_log.InfoFormat("[ENTITY TRANSFER MODULE]: {0} nabled.", Name); |
79 | } | 80 | } |
80 | } | 81 | } |
81 | } | 82 | } |
@@ -120,7 +121,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
120 | 121 | ||
121 | #endregion | 122 | #endregion |
122 | 123 | ||
123 | #region Teleports | 124 | #region Agent Teleports |
124 | 125 | ||
125 | public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) | 126 | public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) |
126 | { | 127 | { |
@@ -137,7 +138,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
137 | if (regionHandle == sp.Scene.RegionInfo.RegionHandle) | 138 | if (regionHandle == sp.Scene.RegionInfo.RegionHandle) |
138 | { | 139 | { |
139 | m_log.DebugFormat( | 140 | m_log.DebugFormat( |
140 | "[AGENT TRANSFER MODULE]: RequestTeleportToLocation {0} within {1}", | 141 | "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation {0} within {1}", |
141 | position, sp.Scene.RegionInfo.RegionName); | 142 | position, sp.Scene.RegionInfo.RegionName); |
142 | 143 | ||
143 | // Teleport within the same region | 144 | // Teleport within the same region |
@@ -146,7 +147,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
146 | Vector3 emergencyPos = new Vector3(128, 128, 128); | 147 | Vector3 emergencyPos = new Vector3(128, 128, 128); |
147 | 148 | ||
148 | m_log.WarnFormat( | 149 | m_log.WarnFormat( |
149 | "[AGENT TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", | 150 | "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", |
150 | position, sp.Name, sp.UUID, emergencyPos); | 151 | position, sp.Name, sp.UUID, emergencyPos); |
151 | position = emergencyPos; | 152 | position = emergencyPos; |
152 | } | 153 | } |
@@ -183,7 +184,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
183 | if (reg != null) | 184 | if (reg != null) |
184 | { | 185 | { |
185 | m_log.DebugFormat( | 186 | m_log.DebugFormat( |
186 | "[AGENT TRANSFER MODULE]: RequestTeleportToLocation to {0} in {1}", | 187 | "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation to {0} in {1}", |
187 | position, reg.RegionName); | 188 | position, reg.RegionName); |
188 | 189 | ||
189 | uint newRegionX = (uint)(reg.RegionHandle >> 40); | 190 | uint newRegionX = (uint)(reg.RegionHandle >> 40); |
@@ -338,7 +339,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
338 | m_aScene.SimulationService.UpdateAgent(reg, agent); | 339 | m_aScene.SimulationService.UpdateAgent(reg, agent); |
339 | 340 | ||
340 | m_log.DebugFormat( | 341 | m_log.DebugFormat( |
341 | "[AGENT TRANSFER MODULE]: Sending new AGENT TRANSFER MODULE seed url {0} to client {1}", capsPath, sp.UUID); | 342 | "[ENTITY TRANSFER MODULE]: Sending new ENTITY TRANSFER MODULE seed url {0} to client {1}", capsPath, sp.UUID); |
342 | 343 | ||
343 | 344 | ||
344 | if (eq != null) | 345 | if (eq != null) |
@@ -377,7 +378,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
377 | sp.MakeChildAgent(); | 378 | sp.MakeChildAgent(); |
378 | 379 | ||
379 | // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it | 380 | // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it |
380 | sp.CrossAttachmentsIntoNewRegion(reg, true); | 381 | CrossAttachmentsIntoNewRegion(reg, sp, true); |
381 | 382 | ||
382 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone | 383 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone |
383 | 384 | ||
@@ -396,7 +397,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
396 | if (sp.Scene.NeedSceneCacheClear(sp.UUID)) | 397 | if (sp.Scene.NeedSceneCacheClear(sp.UUID)) |
397 | { | 398 | { |
398 | m_log.DebugFormat( | 399 | m_log.DebugFormat( |
399 | "[AGENT TRANSFER MODULE]: User {0} is going to another region, profile cache removed", | 400 | "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", |
400 | sp.UUID); | 401 | sp.UUID); |
401 | } | 402 | } |
402 | } | 403 | } |
@@ -470,28 +471,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
470 | 471 | ||
471 | #endregion | 472 | #endregion |
472 | 473 | ||
473 | #region Enable Child Agent | 474 | #region Agent Crossings |
474 | /// <summary> | ||
475 | /// This informs a single neighboring region about agent "avatar". | ||
476 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. | ||
477 | /// </summary> | ||
478 | public void EnableChildAgent(ScenePresence sp, GridRegion region) | ||
479 | { | ||
480 | AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); | ||
481 | agent.BaseFolder = UUID.Zero; | ||
482 | agent.InventoryFolder = UUID.Zero; | ||
483 | agent.startpos = new Vector3(128, 128, 70); | ||
484 | agent.child = true; | ||
485 | agent.Appearance = sp.Appearance; | ||
486 | |||
487 | InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; | ||
488 | d.BeginInvoke(sp, agent, region, region.ExternalEndPoint, true, | ||
489 | InformClientOfNeighbourCompleted, | ||
490 | d); | ||
491 | } | ||
492 | #endregion | ||
493 | |||
494 | #region Crossings | ||
495 | 475 | ||
496 | public void Cross(ScenePresence agent, bool isFlying) | 476 | public void Cross(ScenePresence agent, bool isFlying) |
497 | { | 477 | { |
@@ -700,7 +680,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
700 | new Byte[0]); | 680 | new Byte[0]); |
701 | im.SendInstantMessage(m, delegate(bool success) | 681 | im.SendInstantMessage(m, delegate(bool success) |
702 | { | 682 | { |
703 | m_log.DebugFormat("[AGENT TRANSFER MODULE]: Client Initiating Teleport sending IM success = {0}", success); | 683 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Client Initiating Teleport sending IM success = {0}", success); |
704 | }); | 684 | }); |
705 | 685 | ||
706 | } | 686 | } |
@@ -721,7 +701,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
721 | /// </summary> | 701 | /// </summary> |
722 | protected ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, bool isFlying) | 702 | protected ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, bool isFlying) |
723 | { | 703 | { |
724 | m_log.DebugFormat("[AGENT TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3}", agent.Firstname, agent.Lastname, neighbourx, neighboury); | 704 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3}", agent.Firstname, agent.Lastname, neighbourx, neighboury); |
725 | 705 | ||
726 | Scene m_scene = agent.Scene; | 706 | Scene m_scene = agent.Scene; |
727 | ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); | 707 | ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); |
@@ -756,7 +736,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
756 | string agentcaps; | 736 | string agentcaps; |
757 | if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) | 737 | if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) |
758 | { | 738 | { |
759 | m_log.ErrorFormat("[AGENT TRANSFER MODULE]: No AGENT TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", | 739 | m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", |
760 | neighbourRegion.RegionHandle); | 740 | neighbourRegion.RegionHandle); |
761 | return agent; | 741 | return agent; |
762 | } | 742 | } |
@@ -765,7 +745,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
765 | "http://" + neighbourRegion.ExternalHostName + ":" + neighbourRegion.HttpPort | 745 | "http://" + neighbourRegion.ExternalHostName + ":" + neighbourRegion.HttpPort |
766 | + "/CAPS/" + agentcaps /*circuitdata.CapsPath*/ + "0000/"; | 746 | + "/CAPS/" + agentcaps /*circuitdata.CapsPath*/ + "0000/"; |
767 | 747 | ||
768 | m_log.DebugFormat("[AGENT TRANSFER MODULE]: Sending new AGENT TRANSFER MODULE seed url {0} to client {1}", capsPath, agent.UUID); | 748 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new ENTITY TRANSFER MODULE seed url {0} to client {1}", capsPath, agent.UUID); |
769 | 749 | ||
770 | IEventQueue eq = agent.Scene.RequestModuleInterface<IEventQueue>(); | 750 | IEventQueue eq = agent.Scene.RequestModuleInterface<IEventQueue>(); |
771 | if (eq != null) | 751 | if (eq != null) |
@@ -781,7 +761,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
781 | 761 | ||
782 | if (!WaitForCallback(agent.UUID)) | 762 | if (!WaitForCallback(agent.UUID)) |
783 | { | 763 | { |
784 | m_log.Debug("[AGENT TRANSFER MODULE]: Callback never came in crossing agent"); | 764 | m_log.Debug("[ENTITY TRANSFER MODULE]: Callback never came in crossing agent"); |
785 | ResetFromTransit(agent.UUID); | 765 | ResetFromTransit(agent.UUID); |
786 | 766 | ||
787 | // Yikes! We should just have a ref to scene here. | 767 | // Yikes! We should just have a ref to scene here. |
@@ -795,7 +775,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
795 | // now we have a child agent in this region. Request all interesting data about other (root) agents | 775 | // now we have a child agent in this region. Request all interesting data about other (root) agents |
796 | agent.SendInitialFullUpdateToAllClients(); | 776 | agent.SendInitialFullUpdateToAllClients(); |
797 | 777 | ||
798 | agent.CrossAttachmentsIntoNewRegion(neighbourRegion, true); | 778 | CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); |
799 | 779 | ||
800 | // m_scene.SendKillObject(m_localId); | 780 | // m_scene.SendKillObject(m_localId); |
801 | 781 | ||
@@ -806,7 +786,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
806 | if (agent.Scene.NeedSceneCacheClear(agent.UUID)) | 786 | if (agent.Scene.NeedSceneCacheClear(agent.UUID)) |
807 | { | 787 | { |
808 | m_log.DebugFormat( | 788 | m_log.DebugFormat( |
809 | "[AGENT TRANSFER MODULE]: User {0} is going to another region", agent.UUID); | 789 | "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); |
810 | } | 790 | } |
811 | } | 791 | } |
812 | 792 | ||
@@ -830,11 +810,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
830 | // In any case | 810 | // In any case |
831 | agent.NotInTransit(); | 811 | agent.NotInTransit(); |
832 | 812 | ||
833 | //m_log.DebugFormat("[AGENT TRANSFER MODULE]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname); | 813 | //m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname); |
834 | } | 814 | } |
835 | 815 | ||
836 | #endregion | 816 | #endregion |
837 | 817 | ||
818 | #region Enable Child Agent | ||
819 | /// <summary> | ||
820 | /// This informs a single neighboring region about agent "avatar". | ||
821 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. | ||
822 | /// </summary> | ||
823 | public void EnableChildAgent(ScenePresence sp, GridRegion region) | ||
824 | { | ||
825 | AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); | ||
826 | agent.BaseFolder = UUID.Zero; | ||
827 | agent.InventoryFolder = UUID.Zero; | ||
828 | agent.startpos = new Vector3(128, 128, 70); | ||
829 | agent.child = true; | ||
830 | agent.Appearance = sp.Appearance; | ||
831 | |||
832 | InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; | ||
833 | d.BeginInvoke(sp, agent, region, region.ExternalEndPoint, true, | ||
834 | InformClientOfNeighbourCompleted, | ||
835 | d); | ||
836 | } | ||
837 | #endregion | ||
838 | 838 | ||
839 | #region Enable Child Agents | 839 | #region Enable Child Agents |
840 | 840 | ||
@@ -856,7 +856,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
856 | } | 856 | } |
857 | else | 857 | else |
858 | { | 858 | { |
859 | m_log.Debug("[AGENT TRANSFER MODULE]: m_regionInfo was null in EnableChildAgents, is this a NPC?"); | 859 | m_log.Debug("[ENTITY TRANSFER MODULE]: m_regionInfo was null in EnableChildAgents, is this a NPC?"); |
860 | } | 860 | } |
861 | 861 | ||
862 | /// We need to find the difference between the new regions where there are no child agents | 862 | /// We need to find the difference between the new regions where there are no child agents |
@@ -963,7 +963,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
963 | catch (ArgumentOutOfRangeException) | 963 | catch (ArgumentOutOfRangeException) |
964 | { | 964 | { |
965 | m_log.ErrorFormat( | 965 | m_log.ErrorFormat( |
966 | "[AGENT TRANSFER MODULE]: Neighbour Regions response included the current region in the neighbor list. The following region will not display to the client: {0} for region {1} ({2}, {3}).", | 966 | "[ENTITY TRANSFER MODULE]: Neighbour Regions response included the current region in the neighbor list. The following region will not display to the client: {0} for region {1} ({2}, {3}).", |
967 | neighbour.ExternalHostName, | 967 | neighbour.ExternalHostName, |
968 | neighbour.RegionHandle, | 968 | neighbour.RegionHandle, |
969 | neighbour.RegionLocX, | 969 | neighbour.RegionLocX, |
@@ -972,7 +972,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
972 | catch (Exception e) | 972 | catch (Exception e) |
973 | { | 973 | { |
974 | m_log.ErrorFormat( | 974 | m_log.ErrorFormat( |
975 | "[AGENT TRANSFER MODULE]: Could not resolve external hostname {0} for region {1} ({2}, {3}). {4}", | 975 | "[ENTITY TRANSFER MODULE]: Could not resolve external hostname {0} for region {1} ({2}, {3}). {4}", |
976 | neighbour.ExternalHostName, | 976 | neighbour.ExternalHostName, |
977 | neighbour.RegionHandle, | 977 | neighbour.RegionHandle, |
978 | neighbour.RegionLocX, | 978 | neighbour.RegionLocX, |
@@ -1021,7 +1021,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1021 | Utils.LongToUInts(reg.RegionHandle, out x, out y); | 1021 | Utils.LongToUInts(reg.RegionHandle, out x, out y); |
1022 | x = x / Constants.RegionSize; | 1022 | x = x / Constants.RegionSize; |
1023 | y = y / Constants.RegionSize; | 1023 | y = y / Constants.RegionSize; |
1024 | m_log.Info("[AGENT TRANSFER MODULE]: Starting to inform client about neighbour " + x + ", " + y + "(" + endPoint.ToString() + ")"); | 1024 | m_log.Info("[ENTITY TRANSFER MODULE]: Starting to inform client about neighbour " + x + ", " + y + "(" + endPoint.ToString() + ")"); |
1025 | 1025 | ||
1026 | string capsPath = "http://" + reg.ExternalHostName + ":" + reg.HttpPort | 1026 | string capsPath = "http://" + reg.ExternalHostName + ":" + reg.HttpPort |
1027 | + "/CAPS/" + a.CapsPath + "0000/"; | 1027 | + "/CAPS/" + a.CapsPath + "0000/"; |
@@ -1046,7 +1046,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1046 | 1046 | ||
1047 | eq.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID); | 1047 | eq.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID); |
1048 | eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); | 1048 | eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); |
1049 | m_log.DebugFormat("[AGENT TRANSFER MODULE]: Sending new AGENT TRANSFER MODULE seed url {0} to client {1} in region {2}", | 1049 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new ENTITY TRANSFER MODULE seed url {0} to client {1} in region {2}", |
1050 | capsPath, sp.UUID, sp.Scene.RegionInfo.RegionName); | 1050 | capsPath, sp.UUID, sp.Scene.RegionInfo.RegionName); |
1051 | } | 1051 | } |
1052 | else | 1052 | else |
@@ -1055,7 +1055,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1055 | // TODO: make Event Queue disablable! | 1055 | // TODO: make Event Queue disablable! |
1056 | } | 1056 | } |
1057 | 1057 | ||
1058 | m_log.Info("[AGENT TRANSFER MODULE]: Completed inform client about neighbour " + endPoint.ToString()); | 1058 | m_log.Info("[ENTITY TRANSFER MODULE]: Completed inform client about neighbour " + endPoint.ToString()); |
1059 | 1059 | ||
1060 | } | 1060 | } |
1061 | 1061 | ||
@@ -1154,6 +1154,329 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1154 | 1154 | ||
1155 | #endregion | 1155 | #endregion |
1156 | 1156 | ||
1157 | #region Object Crossings | ||
1158 | /// <summary> | ||
1159 | /// Move the given scene object into a new region depending on which region its absolute position has moved | ||
1160 | /// into. | ||
1161 | /// | ||
1162 | /// This method locates the new region handle and offsets the prim position for the new region | ||
1163 | /// </summary> | ||
1164 | /// <param name="attemptedPosition">the attempted out of region position of the scene object</param> | ||
1165 | /// <param name="grp">the scene object that we're crossing</param> | ||
1166 | public void Cross(SceneObjectGroup grp, Vector3 attemptedPosition, bool silent) | ||
1167 | { | ||
1168 | if (grp == null) | ||
1169 | return; | ||
1170 | if (grp.IsDeleted) | ||
1171 | return; | ||
1172 | |||
1173 | Scene scene = grp.Scene; | ||
1174 | if (scene == null) | ||
1175 | return; | ||
1176 | |||
1177 | if (grp.RootPart.DIE_AT_EDGE) | ||
1178 | { | ||
1179 | // We remove the object here | ||
1180 | try | ||
1181 | { | ||
1182 | scene.DeleteSceneObject(grp, false); | ||
1183 | } | ||
1184 | catch (Exception) | ||
1185 | { | ||
1186 | m_log.Warn("[DATABASE]: exception when trying to remove the prim that crossed the border."); | ||
1187 | } | ||
1188 | return; | ||
1189 | } | ||
1190 | |||
1191 | int thisx = (int)scene.RegionInfo.RegionLocX; | ||
1192 | int thisy = (int)scene.RegionInfo.RegionLocY; | ||
1193 | Vector3 EastCross = new Vector3(0.1f, 0, 0); | ||
1194 | Vector3 WestCross = new Vector3(-0.1f, 0, 0); | ||
1195 | Vector3 NorthCross = new Vector3(0, 0.1f, 0); | ||
1196 | Vector3 SouthCross = new Vector3(0, -0.1f, 0); | ||
1197 | |||
1198 | |||
1199 | // use this if no borders were crossed! | ||
1200 | ulong newRegionHandle | ||
1201 | = Util.UIntsToLong((uint)((thisx) * Constants.RegionSize), | ||
1202 | (uint)((thisy) * Constants.RegionSize)); | ||
1203 | |||
1204 | Vector3 pos = attemptedPosition; | ||
1205 | |||
1206 | int changeX = 1; | ||
1207 | int changeY = 1; | ||
1208 | |||
1209 | if (scene.TestBorderCross(attemptedPosition + WestCross, Cardinals.W)) | ||
1210 | { | ||
1211 | if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S)) | ||
1212 | { | ||
1213 | |||
1214 | Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W); | ||
1215 | |||
1216 | if (crossedBorderx.BorderLine.Z > 0) | ||
1217 | { | ||
1218 | pos.X = ((pos.X + crossedBorderx.BorderLine.Z)); | ||
1219 | changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize); | ||
1220 | } | ||
1221 | else | ||
1222 | pos.X = ((pos.X + Constants.RegionSize)); | ||
1223 | |||
1224 | Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S); | ||
1225 | //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize) | ||
1226 | |||
1227 | if (crossedBordery.BorderLine.Z > 0) | ||
1228 | { | ||
1229 | pos.Y = ((pos.Y + crossedBordery.BorderLine.Z)); | ||
1230 | changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize); | ||
1231 | } | ||
1232 | else | ||
1233 | pos.Y = ((pos.Y + Constants.RegionSize)); | ||
1234 | |||
1235 | |||
1236 | |||
1237 | newRegionHandle | ||
1238 | = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize), | ||
1239 | (uint)((thisy - changeY) * Constants.RegionSize)); | ||
1240 | // x - 1 | ||
1241 | // y - 1 | ||
1242 | } | ||
1243 | else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N)) | ||
1244 | { | ||
1245 | Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W); | ||
1246 | |||
1247 | if (crossedBorderx.BorderLine.Z > 0) | ||
1248 | { | ||
1249 | pos.X = ((pos.X + crossedBorderx.BorderLine.Z)); | ||
1250 | changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize); | ||
1251 | } | ||
1252 | else | ||
1253 | pos.X = ((pos.X + Constants.RegionSize)); | ||
1254 | |||
1255 | |||
1256 | Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S); | ||
1257 | //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize) | ||
1258 | |||
1259 | if (crossedBordery.BorderLine.Z > 0) | ||
1260 | { | ||
1261 | pos.Y = ((pos.Y + crossedBordery.BorderLine.Z)); | ||
1262 | changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize); | ||
1263 | } | ||
1264 | else | ||
1265 | pos.Y = ((pos.Y + Constants.RegionSize)); | ||
1266 | |||
1267 | newRegionHandle | ||
1268 | = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize), | ||
1269 | (uint)((thisy + changeY) * Constants.RegionSize)); | ||
1270 | // x - 1 | ||
1271 | // y + 1 | ||
1272 | } | ||
1273 | else | ||
1274 | { | ||
1275 | Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W); | ||
1276 | |||
1277 | if (crossedBorderx.BorderLine.Z > 0) | ||
1278 | { | ||
1279 | pos.X = ((pos.X + crossedBorderx.BorderLine.Z)); | ||
1280 | changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize); | ||
1281 | } | ||
1282 | else | ||
1283 | pos.X = ((pos.X + Constants.RegionSize)); | ||
1284 | |||
1285 | newRegionHandle | ||
1286 | = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize), | ||
1287 | (uint)(thisy * Constants.RegionSize)); | ||
1288 | // x - 1 | ||
1289 | } | ||
1290 | } | ||
1291 | else if (scene.TestBorderCross(attemptedPosition + EastCross, Cardinals.E)) | ||
1292 | { | ||
1293 | if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S)) | ||
1294 | { | ||
1295 | |||
1296 | pos.X = ((pos.X - Constants.RegionSize)); | ||
1297 | Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S); | ||
1298 | //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize) | ||
1299 | |||
1300 | if (crossedBordery.BorderLine.Z > 0) | ||
1301 | { | ||
1302 | pos.Y = ((pos.Y + crossedBordery.BorderLine.Z)); | ||
1303 | changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize); | ||
1304 | } | ||
1305 | else | ||
1306 | pos.Y = ((pos.Y + Constants.RegionSize)); | ||
1307 | |||
1308 | |||
1309 | newRegionHandle | ||
1310 | = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize), | ||
1311 | (uint)((thisy - changeY) * Constants.RegionSize)); | ||
1312 | // x + 1 | ||
1313 | // y - 1 | ||
1314 | } | ||
1315 | else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N)) | ||
1316 | { | ||
1317 | pos.X = ((pos.X - Constants.RegionSize)); | ||
1318 | pos.Y = ((pos.Y - Constants.RegionSize)); | ||
1319 | newRegionHandle | ||
1320 | = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize), | ||
1321 | (uint)((thisy + changeY) * Constants.RegionSize)); | ||
1322 | // x + 1 | ||
1323 | // y + 1 | ||
1324 | } | ||
1325 | else | ||
1326 | { | ||
1327 | pos.X = ((pos.X - Constants.RegionSize)); | ||
1328 | newRegionHandle | ||
1329 | = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize), | ||
1330 | (uint)(thisy * Constants.RegionSize)); | ||
1331 | // x + 1 | ||
1332 | } | ||
1333 | } | ||
1334 | else if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S)) | ||
1335 | { | ||
1336 | Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S); | ||
1337 | //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize) | ||
1338 | |||
1339 | if (crossedBordery.BorderLine.Z > 0) | ||
1340 | { | ||
1341 | pos.Y = ((pos.Y + crossedBordery.BorderLine.Z)); | ||
1342 | changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize); | ||
1343 | } | ||
1344 | else | ||
1345 | pos.Y = ((pos.Y + Constants.RegionSize)); | ||
1346 | |||
1347 | newRegionHandle | ||
1348 | = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - changeY) * Constants.RegionSize)); | ||
1349 | // y - 1 | ||
1350 | } | ||
1351 | else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N)) | ||
1352 | { | ||
1353 | |||
1354 | pos.Y = ((pos.Y - Constants.RegionSize)); | ||
1355 | newRegionHandle | ||
1356 | = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + changeY) * Constants.RegionSize)); | ||
1357 | // y + 1 | ||
1358 | } | ||
1359 | |||
1360 | // Offset the positions for the new region across the border | ||
1361 | Vector3 oldGroupPosition = grp.RootPart.GroupPosition; | ||
1362 | grp.OffsetForNewRegion(pos); | ||
1363 | |||
1364 | // If we fail to cross the border, then reset the position of the scene object on that border. | ||
1365 | uint x = 0, y = 0; | ||
1366 | Utils.LongToUInts(newRegionHandle, out x, out y); | ||
1367 | GridRegion destination = scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y); | ||
1368 | if (destination != null && !CrossPrimGroupIntoNewRegion(destination, grp, silent)) | ||
1369 | { | ||
1370 | grp.OffsetForNewRegion(oldGroupPosition); | ||
1371 | grp.ScheduleGroupForFullUpdate(); | ||
1372 | } | ||
1373 | } | ||
1374 | |||
1375 | |||
1376 | /// <summary> | ||
1377 | /// Move the given scene object into a new region | ||
1378 | /// </summary> | ||
1379 | /// <param name="newRegionHandle"></param> | ||
1380 | /// <param name="grp">Scene Object Group that we're crossing</param> | ||
1381 | /// <returns> | ||
1382 | /// true if the crossing itself was successful, false on failure | ||
1383 | /// FIMXE: we still return true if the crossing object was not successfully deleted from the originating region | ||
1384 | /// </returns> | ||
1385 | protected bool CrossPrimGroupIntoNewRegion(GridRegion destination, SceneObjectGroup grp, bool silent) | ||
1386 | { | ||
1387 | //m_log.Debug(" >>> CrossPrimGroupIntoNewRegion <<<"); | ||
1388 | |||
1389 | bool successYN = false; | ||
1390 | grp.RootPart.UpdateFlag = 0; | ||
1391 | //int primcrossingXMLmethod = 0; | ||
1392 | |||
1393 | if (destination != null) | ||
1394 | { | ||
1395 | //string objectState = grp.GetStateSnapshot(); | ||
1396 | |||
1397 | //successYN | ||
1398 | // = m_sceneGridService.PrimCrossToNeighboringRegion( | ||
1399 | // newRegionHandle, grp.UUID, m_serialiser.SaveGroupToXml2(grp), primcrossingXMLmethod); | ||
1400 | //if (successYN && (objectState != "") && m_allowScriptCrossings) | ||
1401 | //{ | ||
1402 | // successYN = m_sceneGridService.PrimCrossToNeighboringRegion( | ||
1403 | // newRegionHandle, grp.UUID, objectState, 100); | ||
1404 | //} | ||
1405 | |||
1406 | //// And the new channel... | ||
1407 | //if (m_interregionCommsOut != null) | ||
1408 | // successYN = m_interregionCommsOut.SendCreateObject(newRegionHandle, grp, true); | ||
1409 | if (m_aScene.SimulationService != null) | ||
1410 | successYN = m_aScene.SimulationService.CreateObject(destination, grp, true); | ||
1411 | |||
1412 | if (successYN) | ||
1413 | { | ||
1414 | // We remove the object here | ||
1415 | try | ||
1416 | { | ||
1417 | grp.Scene.DeleteSceneObject(grp, silent); | ||
1418 | } | ||
1419 | catch (Exception e) | ||
1420 | { | ||
1421 | m_log.ErrorFormat( | ||
1422 | "[ENTITY TRANSFER MODULE]: Exception deleting the old object left behind on a border crossing for {0}, {1}", | ||
1423 | grp, e); | ||
1424 | } | ||
1425 | } | ||
1426 | else | ||
1427 | { | ||
1428 | if (!grp.IsDeleted) | ||
1429 | { | ||
1430 | if (grp.RootPart.PhysActor != null) | ||
1431 | { | ||
1432 | grp.RootPart.PhysActor.CrossingFailure(); | ||
1433 | } | ||
1434 | } | ||
1435 | |||
1436 | m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); | ||
1437 | } | ||
1438 | } | ||
1439 | else | ||
1440 | { | ||
1441 | m_log.Error("[ENTITY TRANSFER MODULE]: destination was unexpectedly null in Scene.CrossPrimGroupIntoNewRegion()"); | ||
1442 | } | ||
1443 | |||
1444 | return successYN; | ||
1445 | } | ||
1446 | |||
1447 | protected bool CrossAttachmentsIntoNewRegion(GridRegion destination, ScenePresence sp, bool silent) | ||
1448 | { | ||
1449 | List<SceneObjectGroup> m_attachments = sp.Attachments; | ||
1450 | lock (m_attachments) | ||
1451 | { | ||
1452 | // Validate | ||
1453 | foreach (SceneObjectGroup gobj in m_attachments) | ||
1454 | { | ||
1455 | if (gobj == null || gobj.IsDeleted) | ||
1456 | return false; | ||
1457 | } | ||
1458 | |||
1459 | foreach (SceneObjectGroup gobj in m_attachments) | ||
1460 | { | ||
1461 | // If the prim group is null then something must have happened to it! | ||
1462 | if (gobj != null && gobj.RootPart != null) | ||
1463 | { | ||
1464 | // Set the parent localID to 0 so it transfers over properly. | ||
1465 | gobj.RootPart.SetParentLocalId(0); | ||
1466 | gobj.AbsolutePosition = gobj.RootPart.AttachedPos; | ||
1467 | gobj.RootPart.IsAttachment = false; | ||
1468 | //gobj.RootPart.LastOwnerID = gobj.GetFromAssetID(); | ||
1469 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", gobj.UUID, destination.RegionName); | ||
1470 | CrossPrimGroupIntoNewRegion(destination, gobj, silent); | ||
1471 | } | ||
1472 | } | ||
1473 | m_attachments.Clear(); | ||
1474 | |||
1475 | return true; | ||
1476 | } | ||
1477 | } | ||
1478 | |||
1479 | #endregion | ||
1157 | 1480 | ||
1158 | #region Misc | 1481 | #region Misc |
1159 | 1482 | ||