aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Scenes
diff options
context:
space:
mode:
authorCharles Krinke2008-12-14 02:17:12 +0000
committerCharles Krinke2008-12-14 02:17:12 +0000
commite6eb571c1d19972fe7eb4c3f7de113b1b91f5e02 (patch)
tree2140979c8cf3f4d4d2b60a355be65abd659508b9 /OpenSim/Region/Environment/Scenes
parentMantis#2811. Thank you kindly, Diva for a patch that resolves (diff)
downloadopensim-SC-e6eb571c1d19972fe7eb4c3f7de113b1b91f5e02.zip
opensim-SC-e6eb571c1d19972fe7eb4c3f7de113b1b91f5e02.tar.gz
opensim-SC-e6eb571c1d19972fe7eb4c3f7de113b1b91f5e02.tar.bz2
opensim-SC-e6eb571c1d19972fe7eb4c3f7de113b1b91f5e02.tar.xz
Mantis#2725. Thank you kindly, Diva, for a patch that:
Adds missing protocol pieces for EstablishAgentCommunication event which allows the client to activate CAPS and the EQ for child agents.
Diffstat (limited to 'OpenSim/Region/Environment/Scenes')
-rw-r--r--OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs87
-rw-r--r--OpenSim/Region/Environment/Scenes/Scene.cs81
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneBase.cs49
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs266
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneGraph.cs25
-rw-r--r--OpenSim/Region/Environment/Scenes/ScenePresence.cs129
6 files changed, 469 insertions, 168 deletions
diff --git a/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs
index 7505c75..4e94c52 100644
--- a/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs
+++ b/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs
@@ -108,6 +108,12 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid
108 RegionInfo reg = RequestNeighbouringRegionInfo(regionHandle); 108 RegionInfo reg = RequestNeighbouringRegionInfo(regionHandle);
109 if (reg != null) 109 if (reg != null)
110 { 110 {
111
112 uint newRegionX = (uint)(reg.RegionHandle >> 40);
113 uint newRegionY = (((uint)(reg.RegionHandle)) >> 8);
114 uint oldRegionX = (uint)(m_regionInfo.RegionHandle >> 40);
115 uint oldRegionY = (((uint)(m_regionInfo.RegionHandle)) >> 8);
116
111 /// 117 ///
112 /// Hypergrid mod start 118 /// Hypergrid mod start
113 /// 119 ///
@@ -130,11 +136,6 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid
130 if (eq == null) 136 if (eq == null)
131 avatar.ControllingClient.SendTeleportLocationStart(); 137 avatar.ControllingClient.SendTeleportLocationStart();
132 138
133 AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo();
134 agent.BaseFolder = UUID.Zero;
135 agent.InventoryFolder = UUID.Zero;
136 agent.startpos = position;
137 agent.child = true;
138 139
139 if (reg.RemotingAddress != "" && reg.RemotingPort != 0) 140 if (reg.RemotingAddress != "" && reg.RemotingPort != 0)
140 { 141 {
@@ -166,14 +167,42 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid
166 // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport 167 // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport
167 // failure at this point (unlike a border crossing failure). So perhaps this can never fail 168 // failure at this point (unlike a border crossing failure). So perhaps this can never fail
168 // once we reach here... 169 // once we reach here...
169 avatar.Scene.RemoveCapsHandler(avatar.UUID); 170 //avatar.Scene.RemoveCapsHandler(avatar.UUID);
170 agent.child = false; 171
171 m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent); 172 AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo();
173 agent.BaseFolder = UUID.Zero;
174 agent.InventoryFolder = UUID.Zero;
175 agent.startpos = position;
176 agent.child = true;
177 if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY))
178 {
179 // brand new agent
180 agent.CapsPath = Util.GetRandomCapsPath();
181 }
182 else
183 {
184 // child agent already there
185 agent.CapsPath = avatar.Scene.GetChildSeed(avatar.UUID, reg.RegionHandle);
186 }
187
188 if (!m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent))
189 {
190 avatar.ControllingClient.SendTeleportFailed("Destination is not accepting teleports.");
191 return;
192 }
193
194 // TODO Should construct this behind a method
195 string capsPath =
196 "http://" + reg.ExternalHostName + ":" + reg.HttpPort
197 + "/CAPS/" + agent.CapsPath + "0000/";
172 198
173 if (eq != null) 199 if (eq != null)
174 { 200 {
175 OSD Item = EventQueueHelper.EnableSimulator(realHandle, reg.ExternalEndPoint); 201 OSD Item = EventQueueHelper.EnableSimulator(realHandle, reg.ExternalEndPoint);
176 eq.Enqueue(Item, avatar.UUID); 202 eq.Enqueue(Item, avatar.UUID);
203
204 Item = EventQueueHelper.EstablishAgentCommunication(avatar.UUID, reg.ExternalEndPoint.ToString(), capsPath);
205 eq.Enqueue(Item, avatar.UUID);
177 } 206 }
178 else 207 else
179 { 208 {
@@ -181,18 +210,21 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid
181 // TODO: make Event Queue disablable! 210 // TODO: make Event Queue disablable!
182 } 211 }
183 212
184 m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, 213 if (!m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId,
185 position, false); 214 position, false))
186 Thread.Sleep(2000); 215 {
187 AgentCircuitData circuitdata = avatar.ControllingClient.RequestClientInfo(); 216 avatar.ControllingClient.SendTeleportFailed("Problem with destination.");
217 // We should close that agent we just created over at destination...
218 List<ulong> lst = new List<ulong>();
219 lst.Add(reg.RegionHandle);
220 SendCloseChildAgentAsync(avatar.UUID, lst);
221 return;
222 }
188 223
189 // TODO Should construct this behind a method 224 Thread.Sleep(2000);
190 string capsPath =
191 "http://" + reg.ExternalHostName + ":" + reg.HttpPort
192 + "/CAPS/" + circuitdata.CapsPath + "0000/";
193 225
194 m_log.DebugFormat( 226 m_log.DebugFormat(
195 "[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID); 227 "[CAPS]: Sending new CAPS seed url {0} to client {1}", agent.CapsPath, avatar.UUID);
196 228
197 229
198 /// 230 ///
@@ -215,7 +247,7 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid
215 /// 247 ///
216 248
217 avatar.MakeChildAgent(); 249 avatar.MakeChildAgent();
218 Thread.Sleep(7000); 250 Thread.Sleep(5000);
219 avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true); 251 avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true);
220 if (KiPrimitive != null) 252 if (KiPrimitive != null)
221 { 253 {
@@ -223,29 +255,22 @@ namespace OpenSim.Region.Environment.Scenes.Hypergrid
223 } 255 }
224 256
225 257
226 uint newRegionX = (uint)(reg.RegionHandle >> 40);
227 uint newRegionY = (((uint)(reg.RegionHandle)) >> 8);
228 uint oldRegionX = (uint)(m_regionInfo.RegionHandle >> 40);
229 uint oldRegionY = (((uint)(m_regionInfo.RegionHandle)) >> 8);
230
231 // Let's close some children agents 258 // Let's close some children agents
232 if (isHyperLink) // close them all 259 if (isHyperLink) // close them all
233 SendCloseChildAgentConnections(avatar.UUID, avatar.GetKnownRegionList()); 260 SendCloseChildAgentConnections(avatar.UUID, avatar.KnownChildRegionHandles);
234 else // close just a few 261 else // close just a few
235 avatar.CloseChildAgents(newRegionX, newRegionY); 262 avatar.CloseChildAgents(newRegionX, newRegionY);
236 263
237 avatar.Close(); 264 //avatar.Close();
238 265
239 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone 266 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
240 /// 267 ///
241 /// Hypergrid mod: extra check for isHyperLink 268 /// Hypergrid mod: extra check for isHyperLink
242 /// 269 ///
243 //if ((Util.fast_distance2d((int)(newRegionX - oldRegionX), (int)(newRegionY - oldRegionY)) > 1) || isHyperLink) 270 //if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY))
244 //if (((int)Math.Abs((int)(newRegionX - oldRegionX)) > 1) || ((int)Math.Abs((int)(newRegionY - oldRegionY)) > 1) || isHyperLink) 271 //{
245 if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY)) 272 // CloseConnection(avatar.UUID);
246 { 273 //}
247 CloseConnection(avatar.UUID);
248 }
249 // if (teleport success) // seems to be always success here 274 // if (teleport success) // seems to be always success here
250 // the user may change their profile information in other region, 275 // the user may change their profile information in other region,
251 // so the userinfo in UserProfileCache is not reliable any more, delete it 276 // so the userinfo in UserProfileCache is not reliable any more, delete it
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs
index 4087471..6ce19c6 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.cs
@@ -649,8 +649,8 @@ namespace OpenSim.Region.Environment.Scenes
649 // Kick all ROOT agents with the message, 'The simulator is going down' 649 // Kick all ROOT agents with the message, 'The simulator is going down'
650 ForEachScenePresence(delegate(ScenePresence avatar) 650 ForEachScenePresence(delegate(ScenePresence avatar)
651 { 651 {
652 if (avatar.KnownChildRegions.Contains(RegionInfo.RegionHandle)) 652 if (avatar.KnownChildRegionHandles.Contains(RegionInfo.RegionHandle))
653 avatar.KnownChildRegions.Remove(RegionInfo.RegionHandle); 653 avatar.KnownChildRegionHandles.Remove(RegionInfo.RegionHandle);
654 654
655 if (!avatar.IsChildAgent) 655 if (!avatar.IsChildAgent)
656 avatar.ControllingClient.Kick("The simulator is going down."); 656 avatar.ControllingClient.Kick("The simulator is going down.");
@@ -2657,7 +2657,7 @@ namespace OpenSim.Region.Environment.Scenes
2657 GetAvatarAppearance(client, out appearance); 2657 GetAvatarAppearance(client, out appearance);
2658 2658
2659 ScenePresence avatar = m_sceneGraph.CreateAndAddChildScenePresence(client, appearance); 2659 ScenePresence avatar = m_sceneGraph.CreateAndAddChildScenePresence(client, appearance);
2660 2660 avatar.KnownRegions = GetChildrenSeeds(avatar.UUID);
2661 return avatar; 2661 return avatar;
2662 } 2662 }
2663 2663
@@ -2706,27 +2706,23 @@ namespace OpenSim.Region.Environment.Scenes
2706 "[SCENE]: Removing {0} agent {1} from region {2}", 2706 "[SCENE]: Removing {0} agent {1} from region {2}",
2707 (childagentYN ? "child" : "root"), agentID, RegionInfo.RegionName); 2707 (childagentYN ? "child" : "root"), agentID, RegionInfo.RegionName);
2708 2708
2709 if (avatar.IsChildAgent) 2709 m_sceneGraph.removeUserCount(!childagentYN);
2710 { 2710 RemoveCapsHandler(agentID);
2711 m_sceneGraph.removeUserCount(false); 2711
2712 } 2712 CommsManager.UserProfileCacheService.RemoveUser(agentID);
2713 else 2713
2714 if (!avatar.IsChildAgent)
2714 { 2715 {
2715 m_sceneGraph.removeUserCount(true);
2716 m_sceneGridService.LogOffUser(agentID, RegionInfo.RegionID, RegionInfo.RegionHandle, avatar.AbsolutePosition, avatar.Lookat); 2716 m_sceneGridService.LogOffUser(agentID, RegionInfo.RegionID, RegionInfo.RegionHandle, avatar.AbsolutePosition, avatar.Lookat);
2717 List<ulong> childknownRegions = new List<ulong>(); 2717 //List<ulong> childknownRegions = new List<ulong>();
2718 List<ulong> ckn = avatar.GetKnownRegionList(); 2718 //List<ulong> ckn = avatar.KnownChildRegionHandles;
2719 for (int i = 0; i < ckn.Count; i++) 2719 //for (int i = 0; i < ckn.Count; i++)
2720 { 2720 //{
2721 childknownRegions.Add(ckn[i]); 2721 // childknownRegions.Add(ckn[i]);
2722 } 2722 //}
2723 m_sceneGridService.SendCloseChildAgentConnections(agentID, childknownRegions); 2723 m_sceneGridService.SendCloseChildAgentConnections(agentID, avatar.KnownChildRegionHandles);
2724
2725 RemoveCapsHandler(agentID);
2726 2724
2727 CommsManager.UserProfileCacheService.RemoveUser(agentID);
2728 } 2725 }
2729
2730 m_eventManager.TriggerClientClosed(agentID); 2726 m_eventManager.TriggerClientClosed(agentID);
2731 } 2727 }
2732 catch (NullReferenceException) 2728 catch (NullReferenceException)
@@ -2792,7 +2788,7 @@ namespace OpenSim.Region.Environment.Scenes
2792 2788
2793 for (int i = 0; i < regionslst.Count; i++) 2789 for (int i = 0; i < regionslst.Count; i++)
2794 { 2790 {
2795 av.KnownChildRegions.Remove(regionslst[i]); 2791 av.KnownChildRegionHandles.Remove(regionslst[i]);
2796 } 2792 }
2797 } 2793 }
2798 } 2794 }
@@ -2875,8 +2871,8 @@ namespace OpenSim.Region.Environment.Scenes
2875 /// <param name="agent"></param> 2871 /// <param name="agent"></param>
2876 public void NewUserConnection(AgentCircuitData agent) 2872 public void NewUserConnection(AgentCircuitData agent)
2877 { 2873 {
2878 m_log.DebugFormat("[CONNECTION DEBUGGING] Adding NewUserConnection for {0} with CC of {1}", agent.AgentID, 2874 m_log.DebugFormat("[CONNECTION DEBUGGING] Adding NewUserConnection for {0} in {1} with CC of {2}", agent.AgentID,
2879 agent.circuitcode); 2875 RegionInfo.RegionName, agent.circuitcode);
2880 2876
2881 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID)) 2877 if (m_regInfo.EstateSettings.IsBanned(agent.AgentID))
2882 { 2878 {
@@ -2885,13 +2881,16 @@ namespace OpenSim.Region.Environment.Scenes
2885 agent.AgentID, RegionInfo.RegionName); 2881 agent.AgentID, RegionInfo.RegionName);
2886 } 2882 }
2887 2883
2884 /// Diva: Horrible stuff!
2888 capsPaths[agent.AgentID] = agent.CapsPath; 2885 capsPaths[agent.AgentID] = agent.CapsPath;
2886 //m_log.DebugFormat("------------>child seeds in {0}: {1}", RegionInfo.RegionName, ((agent.ChildrenCapSeeds == null) ? "null" : agent.ChildrenCapSeeds.Count.ToString()));
2887 childrenSeeds[agent.AgentID] = ((agent.ChildrenCapSeeds == null) ? new Dictionary<ulong, string>() : agent.ChildrenCapSeeds);
2888
2889 AddCapsHandler(agent.AgentID);
2889 2890
2890 if (!agent.child) 2891 if (!agent.child)
2891 { 2892 {
2892 2893
2893 AddCapsHandler(agent.AgentID);
2894
2895 // Honor parcel landing type and position. 2894 // Honor parcel landing type and position.
2896 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y); 2895 ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
2897 if (land != null) 2896 if (land != null)
@@ -2966,14 +2965,22 @@ namespace OpenSim.Region.Environment.Scenes
2966 { 2965 {
2967 if (RegionInfo.EstateSettings.IsBanned(agentId)) 2966 if (RegionInfo.EstateSettings.IsBanned(agentId))
2968 return; 2967 return;
2968
2969
2969 String capsObjectPath = GetCapsPath(agentId); 2970 String capsObjectPath = GetCapsPath(agentId);
2970 2971
2971 m_log.DebugFormat( 2972 m_log.DebugFormat(
2972 "[CAPS]: Setting up CAPS handler for root agent {0} in {1}", 2973 "[CAPS]: Setting up CAPS handler for agent {0} in {1}",
2973 agentId, RegionInfo.RegionName); 2974 agentId, RegionInfo.RegionName);
2974 2975
2975 Caps cap = 2976 Caps cap = null;
2976 new Caps(AssetCache, m_httpListener, m_regInfo.ExternalHostName, m_httpListener.Port, 2977 if (m_capsHandlers.TryGetValue(agentId, out cap))
2978 {
2979 m_log.DebugFormat("[CAPS] Attempt at registering twice for the same agent {0}. {1}. Ignoring.", agentId, capsObjectPath);
2980 return;
2981 }
2982
2983 cap = new Caps(AssetCache, m_httpListener, m_regInfo.ExternalHostName, m_httpListener.Port,
2977 capsObjectPath, agentId, m_dumpAssetsToFile, RegionInfo.RegionName); 2984 capsObjectPath, agentId, m_dumpAssetsToFile, RegionInfo.RegionName);
2978 cap.RegisterHandlers(); 2985 cap.RegisterHandlers();
2979 2986
@@ -3005,6 +3012,12 @@ namespace OpenSim.Region.Environment.Scenes
3005 /// <param name="agentId"></param> 3012 /// <param name="agentId"></param>
3006 public void RemoveCapsHandler(UUID agentId) 3013 public void RemoveCapsHandler(UUID agentId)
3007 { 3014 {
3015 if (childrenSeeds.ContainsKey(agentId))
3016 {
3017 //Console.WriteLine(" !!! Removing seeds for {0} in {1}", agentId, RegionInfo.RegionName);
3018 childrenSeeds.Remove(agentId);
3019 }
3020
3008 lock (m_capsHandlers) 3021 lock (m_capsHandlers)
3009 { 3022 {
3010 if (m_capsHandlers.ContainsKey(agentId)) 3023 if (m_capsHandlers.ContainsKey(agentId))
@@ -3094,7 +3107,6 @@ namespace OpenSim.Region.Environment.Scenes
3094 public bool CloseConnection(UUID agentID) 3107 public bool CloseConnection(UUID agentID)
3095 { 3108 {
3096 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); 3109 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
3097
3098 if (presence != null) 3110 if (presence != null)
3099 { 3111 {
3100 // Nothing is removed here, so down count it as such 3112 // Nothing is removed here, so down count it as such
@@ -3108,11 +3120,18 @@ namespace OpenSim.Region.Environment.Scenes
3108 // } 3120 // }
3109 3121
3110 // Tell a single agent to disconnect from the region. 3122 // Tell a single agent to disconnect from the region.
3111 presence.ControllingClient.SendShutdownConnectionNotice(); 3123 IEventQueue eq = RequestModuleInterface<IEventQueue>();
3124 if (eq != null)
3125 {
3126 OSD Item = EventQueueHelper.DisableSimulator(RegionInfo.RegionHandle);
3127 eq.Enqueue(Item, agentID);
3128 }
3129 else
3130 presence.ControllingClient.SendShutdownConnectionNotice();
3112 3131
3113 presence.ControllingClient.Close(true); 3132 presence.ControllingClient.Close(true);
3133
3114 } 3134 }
3115
3116 return true; 3135 return true;
3117 } 3136 }
3118 3137
diff --git a/OpenSim/Region/Environment/Scenes/SceneBase.cs b/OpenSim/Region/Environment/Scenes/SceneBase.cs
index 9528a0d..fafa933 100644
--- a/OpenSim/Region/Environment/Scenes/SceneBase.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneBase.cs
@@ -216,8 +216,10 @@ namespace OpenSim.Region.Environment.Scenes
216 216
217 /// <summary> 217 /// <summary>
218 /// XXX These two methods are very temporary 218 /// XXX These two methods are very temporary
219 /// XXX Diva: this is really truly horrible; must...move...to...LL client...stack...
219 /// </summary> 220 /// </summary>
220 protected Dictionary<UUID, string> capsPaths = new Dictionary<UUID, string>(); 221 protected Dictionary<UUID, string> capsPaths = new Dictionary<UUID, string>();
222 protected Dictionary<UUID, Dictionary<ulong, string>> childrenSeeds = new Dictionary<UUID, Dictionary<ulong, string>>();
221 public string GetCapsPath(UUID agentId) 223 public string GetCapsPath(UUID agentId)
222 { 224 {
223 if (capsPaths.ContainsKey(agentId)) 225 if (capsPaths.ContainsKey(agentId))
@@ -227,7 +229,52 @@ namespace OpenSim.Region.Environment.Scenes
227 229
228 return null; 230 return null;
229 } 231 }
230 232 public Dictionary<ulong, string> GetChildrenSeeds(UUID agentID)
233 {
234 Dictionary<ulong, string> seeds = null;
235 if (childrenSeeds.TryGetValue(agentID, out seeds))
236 return seeds;
237 return new Dictionary<ulong, string>();
238 }
239
240 public void DropChildSeed(UUID agentID, ulong handle)
241 {
242 Dictionary<ulong, string> seeds;
243 if (childrenSeeds.TryGetValue(agentID, out seeds))
244 {
245 seeds.Remove(handle);
246 }
247 }
248
249 public string GetChildSeed(UUID agentID, ulong handle)
250 {
251 Dictionary<ulong, string> seeds;
252 if (childrenSeeds.TryGetValue(agentID, out seeds))
253 {
254 return seeds[handle];
255 }
256 return null;
257 }
258
259 public void SetChildrenSeed(UUID agentID, Dictionary<ulong, string> value)
260 {
261 //Console.WriteLine(" !!! Setting child seeds in {0} to {1}", RegionInfo.RegionName, value.Count);
262 childrenSeeds[agentID] = value;
263 }
264
265 public void DumpChildrenSeeds(UUID agentID)
266 {
267 Console.WriteLine("================ ChildrenSeed {0} ================", RegionInfo.RegionName);
268 foreach (KeyValuePair<ulong, string> kvp in childrenSeeds[agentID])
269 {
270 uint x, y;
271 Utils.LongToUInts(kvp.Key, out x, out y);
272 x = x / Constants.RegionSize;
273 y = y / Constants.RegionSize;
274 Console.WriteLine(" >> {0}, {1}: {2}", x, y, kvp.Value);
275 }
276 }
277
231 /// <summary> 278 /// <summary>
232 /// Returns a new unallocated local ID 279 /// Returns a new unallocated local ID
233 /// </summary> 280 /// </summary>
diff --git a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs
index 2b638e3..b89f753 100644
--- a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs
@@ -255,7 +255,7 @@ namespace OpenSim.Region.Environment.Scenes
255 #region Inform Client of Neighbours 255 #region Inform Client of Neighbours
256 256
257 private delegate void InformClientOfNeighbourDelegate( 257 private delegate void InformClientOfNeighbourDelegate(
258 ScenePresence avatar, AgentCircuitData a, ulong regionHandle, IPEndPoint endPoint); 258 ScenePresence avatar, AgentCircuitData a, SimpleRegionInfo reg, IPEndPoint endPoint);
259 259
260 private void InformClientOfNeighbourCompleted(IAsyncResult iar) 260 private void InformClientOfNeighbourCompleted(IAsyncResult iar)
261 { 261 {
@@ -273,28 +273,40 @@ namespace OpenSim.Region.Environment.Scenes
273 /// <param name="a"></param> 273 /// <param name="a"></param>
274 /// <param name="regionHandle"></param> 274 /// <param name="regionHandle"></param>
275 /// <param name="endPoint"></param> 275 /// <param name="endPoint"></param>
276 private void InformClientOfNeighbourAsync(ScenePresence avatar, AgentCircuitData a, ulong regionHandle, 276 private void InformClientOfNeighbourAsync(ScenePresence avatar, AgentCircuitData a, SimpleRegionInfo reg,
277 IPEndPoint endPoint) 277 IPEndPoint endPoint)
278 { 278 {
279 m_log.Info("[INTERGRID]: Starting to inform client about neighbours"); 279 uint x, y;
280 bool regionAccepted = m_commsProvider.InterRegion.InformRegionOfChildAgent(regionHandle, a); 280 Utils.LongToUInts(reg.RegionHandle, out x, out y);
281 x = x / Constants.RegionSize;
282 y = y / Constants.RegionSize;
283 m_log.Info("[INTERGRID]: Starting to inform client about neighbour " + x + ", " + y + "(" + endPoint.ToString() + ")");
284
285 string capsPath = "http://" + reg.ExternalHostName + ":" + reg.HttpPort
286 + "/CAPS/" + a.CapsPath + "0000/";
287
288 bool regionAccepted = m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, a);
281 289
282 if (regionAccepted) 290 if (regionAccepted)
283 { 291 {
284 IEventQueue eq = avatar.Scene.RequestModuleInterface<IEventQueue>(); 292 IEventQueue eq = avatar.Scene.RequestModuleInterface<IEventQueue>();
285 if (eq != null) 293 if (eq != null)
286 { 294 {
287 OSD Item = EventQueueHelper.EnableSimulator(regionHandle, endPoint); 295 OSD Item = EventQueueHelper.EnableSimulator(reg.RegionHandle, endPoint);
288 eq.Enqueue(Item, avatar.UUID); 296 eq.Enqueue(Item, avatar.UUID);
297
298 Item = EventQueueHelper.EstablishAgentCommunication(avatar.UUID, endPoint.ToString(), capsPath);
299 eq.Enqueue(Item, avatar.UUID);
300
301 m_log.DebugFormat("[CAPS]: Sending new CAPS seed url {0} to client {1} in region {2}", capsPath, avatar.UUID, avatar.Scene.RegionInfo.RegionName);
289 } 302 }
290 else 303 else
291 { 304 {
292 avatar.ControllingClient.InformClientOfNeighbour(regionHandle, endPoint); 305 avatar.ControllingClient.InformClientOfNeighbour(reg.RegionHandle, endPoint);
293 // TODO: make Event Queue disablable! 306 // TODO: make Event Queue disablable!
294 } 307 }
295 308
296 avatar.AddNeighbourRegion(regionHandle); 309 m_log.Info("[INTERGRID]: Completed inform client about neighbour " + endPoint.ToString());
297 m_log.Info("[INTERGRID]: Completed inform client about neighbours");
298 } 310 }
299 } 311 }
300 312
@@ -330,21 +342,72 @@ namespace OpenSim.Region.Environment.Scenes
330 neighbours = 342 neighbours =
331 m_commsProvider.GridService.RequestNeighbours(m_regionInfo.RegionLocX, m_regionInfo.RegionLocY); 343 m_commsProvider.GridService.RequestNeighbours(m_regionInfo.RegionLocX, m_regionInfo.RegionLocY);
332 344
333 if (neighbours != null) 345 m_log.Debug("[SCM]: EnableChildAgents from " + avatar.Scene.RegionInfo.RegionName);
346
347 /// We need to find the difference between the new regions where there are no child agents
348 /// and the regions where there are already child agents. We only send notification to the former.
349 List<ulong> neighbourHandles = NeighbourHandles(neighbours); // on this region
350 neighbourHandles.Add(avatar.Scene.RegionInfo.RegionHandle); // add this region too
351 List<ulong> previousRegionNeighbourHandles = new List<ulong>(avatar.Scene.GetChildrenSeeds(avatar.UUID).Keys);
352 List<ulong> newRegions = NewNeighbours(neighbourHandles, previousRegionNeighbourHandles);
353 List<ulong> oldRegions = OldNeighbours(neighbourHandles, previousRegionNeighbourHandles);
354
355 //Dump("Current Neighbors", neighbourHandles);
356 //Dump("Previous Neighbours", previousRegionNeighbourHandles);
357 //Dump("New Neighbours", newRegions);
358 //Dump("Old Neighbours", oldRegions);
359
360 /// Update the scene presence's known regions here on this region
361 avatar.DropOldNeighbours(oldRegions);
362
363 /// Collect as many seeds as possible
364 Dictionary<ulong, string> seeds = new Dictionary<ulong, string>(avatar.Scene.GetChildrenSeeds(avatar.UUID));
365 if (!seeds.ContainsKey(avatar.Scene.RegionInfo.RegionHandle))
366 seeds.Add(avatar.Scene.RegionInfo.RegionHandle, avatar.ControllingClient.RequestClientInfo().CapsPath);
367
368 /// Create the necessary child agents
369 List<AgentCircuitData> cagents = new List<AgentCircuitData>();
370 foreach (SimpleRegionInfo neighbour in neighbours)
334 { 371 {
335 for (int i = 0; i < neighbours.Count; i++) 372 AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo();
373 agent.BaseFolder = UUID.Zero;
374 agent.InventoryFolder = UUID.Zero;
375 agent.startpos = new Vector3(128, 128, 70);
376 agent.child = true;
377
378 if (newRegions.Contains(neighbour.RegionHandle))
336 { 379 {
337 AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); 380 agent.CapsPath = Util.GetRandomCapsPath();
338 agent.BaseFolder = UUID.Zero; 381 avatar.AddNeighbourRegion(neighbour.RegionHandle, agent.CapsPath);
339 agent.InventoryFolder = UUID.Zero; 382 seeds.Add(neighbour.RegionHandle, agent.CapsPath);
340 agent.startpos = new Vector3(128, 128, 70); 383 }
341 agent.child = true; 384 else
385 agent.CapsPath = avatar.Scene.GetChildSeed(avatar.UUID, neighbour.RegionHandle);
342 386
343 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; 387 cagents.Add(agent);
388 }
344 389
390 /// Update all child agent with everyone's seeds
391 foreach (AgentCircuitData a in cagents)
392 {
393 a.ChildrenCapSeeds = new Dictionary<ulong, string>(seeds);
394 }
395 // These two are the same thing!
396 avatar.Scene.SetChildrenSeed(avatar.UUID, seeds);
397 avatar.KnownRegions = seeds;
398 //avatar.Scene.DumpChildrenSeeds(avatar.UUID);
399 //avatar.DumpKnownRegions();
400
401 int count = 0;
402 foreach (SimpleRegionInfo neighbour in neighbours)
403 {
404 // Don't do it if there's already an agent in that region
405 if (newRegions.Contains(neighbour.RegionHandle))
406 {
407 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync;
345 try 408 try
346 { 409 {
347 d.BeginInvoke(avatar, agent, neighbours[i].RegionHandle, neighbours[i].ExternalEndPoint, 410 d.BeginInvoke(avatar, cagents[count], neighbour, neighbour.ExternalEndPoint,
348 InformClientOfNeighbourCompleted, 411 InformClientOfNeighbourCompleted,
349 d); 412 d);
350 } 413 }
@@ -352,10 +415,10 @@ namespace OpenSim.Region.Environment.Scenes
352 { 415 {
353 m_log.ErrorFormat( 416 m_log.ErrorFormat(
354 "[REGIONINFO]: Could not resolve external hostname {0} for region {1} ({2}, {3}). {4}", 417 "[REGIONINFO]: Could not resolve external hostname {0} for region {1} ({2}, {3}). {4}",
355 neighbours[i].ExternalHostName, 418 neighbour.ExternalHostName,
356 neighbours[i].RegionHandle, 419 neighbour.RegionHandle,
357 neighbours[i].RegionLocX, 420 neighbour.RegionLocX,
358 neighbours[i].RegionLocY, 421 neighbour.RegionLocY,
359 e); 422 e);
360 423
361 // FIXME: Okay, even though we've failed, we're still going to throw the exception on, 424 // FIXME: Okay, even though we've failed, we're still going to throw the exception on,
@@ -366,6 +429,11 @@ namespace OpenSim.Region.Environment.Scenes
366 429
367 } 430 }
368 } 431 }
432 else
433 m_log.Debug("[SCM]: Skipping common neighbor " + neighbour.RegionLocX + ", " + neighbour.RegionLocY);
434
435 count++;
436
369 } 437 }
370 } 438 }
371 439
@@ -373,7 +441,7 @@ namespace OpenSim.Region.Environment.Scenes
373 /// This informs a single neighboring region about agent "avatar". 441 /// This informs a single neighboring region about agent "avatar".
374 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 442 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
375 /// </summary> 443 /// </summary>
376 public void InformNeighborChildAgent(ScenePresence avatar, RegionInfo region, List<RegionInfo> neighbours) 444 public void InformNeighborChildAgent(ScenePresence avatar, SimpleRegionInfo region, List<RegionInfo> neighbours)
377 { 445 {
378 AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); 446 AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo();
379 agent.BaseFolder = UUID.Zero; 447 agent.BaseFolder = UUID.Zero;
@@ -382,7 +450,7 @@ namespace OpenSim.Region.Environment.Scenes
382 agent.child = true; 450 agent.child = true;
383 451
384 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; 452 InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync;
385 d.BeginInvoke(avatar, agent, region.RegionHandle, region.ExternalEndPoint, 453 d.BeginInvoke(avatar, agent, region, region.ExternalEndPoint,
386 InformClientOfNeighbourCompleted, 454 InformClientOfNeighbourCompleted,
387 d); 455 d);
388 } 456 }
@@ -463,10 +531,10 @@ namespace OpenSim.Region.Environment.Scenes
463 /// </summary> 531 /// </summary>
464 private void SendChildAgentDataUpdateAsync(ChildAgentDataUpdate cAgentData, ScenePresence presence) 532 private void SendChildAgentDataUpdateAsync(ChildAgentDataUpdate cAgentData, ScenePresence presence)
465 { 533 {
466 //m_log.Info("[INTERGRID]: Informing neighbors about my agent."); 534 m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + presence.Scene.RegionInfo.RegionName);
467 try 535 try
468 { 536 {
469 foreach (ulong regionHandle in presence.KnownChildRegions) 537 foreach (ulong regionHandle in presence.KnownChildRegionHandles)
470 { 538 {
471 bool regionAccepted = m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData); 539 bool regionAccepted = m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData);
472 540
@@ -508,11 +576,12 @@ namespace OpenSim.Region.Environment.Scenes
508 /// This Closes child agents on neighboring regions 576 /// This Closes child agents on neighboring regions
509 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 577 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
510 /// </summary> 578 /// </summary>
511 private void SendCloseChildAgentAsync(UUID agentID, List<ulong> regionlst) 579 protected void SendCloseChildAgentAsync(UUID agentID, List<ulong> regionlst)
512 { 580 {
513 581
514 foreach (ulong regionHandle in regionlst) 582 foreach (ulong regionHandle in regionlst)
515 { 583 {
584 m_log.Debug("[INTERGRID]: Sending close agent to " + regionHandle);
516 bool regionAccepted = m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID); 585 bool regionAccepted = m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID);
517 586
518 if (regionAccepted) 587 if (regionAccepted)
@@ -527,14 +596,14 @@ namespace OpenSim.Region.Environment.Scenes
527 } 596 }
528 597
529 } 598 }
530 // We remove the list of known regions from the agent's known region list through an event 599 //// We remove the list of known regions from the agent's known region list through an event
531 // to scene, because, if an agent logged of, it's likely that there will be no scene presence 600 //// to scene, because, if an agent logged of, it's likely that there will be no scene presence
532 // by the time we get to this part of the method. 601 //// by the time we get to this part of the method.
533 handlerRemoveKnownRegionFromAvatar = OnRemoveKnownRegionFromAvatar; 602 //handlerRemoveKnownRegionFromAvatar = OnRemoveKnownRegionFromAvatar;
534 if (handlerRemoveKnownRegionFromAvatar != null) 603 //if (handlerRemoveKnownRegionFromAvatar != null)
535 { 604 //{
536 handlerRemoveKnownRegionFromAvatar(agentID, regionlst); 605 // handlerRemoveKnownRegionFromAvatar(agentID, regionlst);
537 } 606 //}
538 } 607 }
539 608
540 private void SendCloseChildAgentCompleted(IAsyncResult iar) 609 private void SendCloseChildAgentCompleted(IAsyncResult iar)
@@ -643,12 +712,6 @@ namespace OpenSim.Region.Environment.Scenes
643 if (eq == null) 712 if (eq == null)
644 avatar.ControllingClient.SendTeleportLocationStart(); 713 avatar.ControllingClient.SendTeleportLocationStart();
645 714
646 AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo();
647 agent.BaseFolder = UUID.Zero;
648 agent.InventoryFolder = UUID.Zero;
649 agent.startpos = position;
650 agent.child = true;
651
652 if (reg.RemotingAddress != "" && reg.RemotingPort != 0) 715 if (reg.RemotingAddress != "" && reg.RemotingPort != 0)
653 { 716 {
654 // region is remote. see if it is up 717 // region is remote. see if it is up
@@ -662,6 +725,10 @@ namespace OpenSim.Region.Environment.Scenes
662 725
663 if (destRegionUp) 726 if (destRegionUp)
664 { 727 {
728 uint newRegionX = (uint)(reg.RegionHandle >> 40);
729 uint newRegionY = (((uint)(reg.RegionHandle)) >> 8);
730 uint oldRegionX = (uint)(m_regionInfo.RegionHandle >> 40);
731 uint oldRegionY = (((uint)(m_regionInfo.RegionHandle)) >> 8);
665 732
666 // Fixing a bug where teleporting while sitting results in the avatar ending up removed from 733 // Fixing a bug where teleporting while sitting results in the avatar ending up removed from
667 // both regions 734 // both regions
@@ -675,33 +742,64 @@ namespace OpenSim.Region.Environment.Scenes
675 742
676 // the avatar.Close below will clear the child region list. We need this below for (possibly) 743 // the avatar.Close below will clear the child region list. We need this below for (possibly)
677 // closing the child agents, so save it here (we need a copy as it is Clear()-ed). 744 // closing the child agents, so save it here (we need a copy as it is Clear()-ed).
678 List<ulong> childRegions = new List<ulong>(avatar.GetKnownRegionList()); 745 //List<ulong> childRegions = new List<ulong>(avatar.GetKnownRegionList());
679 // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport 746 // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport
680 // failure at this point (unlike a border crossing failure). So perhaps this can never fail 747 // failure at this point (unlike a border crossing failure). So perhaps this can never fail
681 // once we reach here... 748 // once we reach here...
682 avatar.Scene.RemoveCapsHandler(avatar.UUID); 749 //avatar.Scene.RemoveCapsHandler(avatar.UUID);
683 agent.child = false; 750
684 m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent); 751 AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo();
752 agent.BaseFolder = UUID.Zero;
753 agent.InventoryFolder = UUID.Zero;
754 agent.startpos = position;
755 agent.child = true;
756 if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY))
757 {
758 // brand new agent
759 agent.CapsPath = Util.GetRandomCapsPath();
760 }
761 else
762 {
763 // child agent already there
764 agent.CapsPath = avatar.Scene.GetChildSeed(avatar.UUID, reg.RegionHandle);
765 }
766
767 if (!m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent))
768 {
769 avatar.ControllingClient.SendTeleportFailed("Destination is not accepting teleports.");
770 return;
771 }
772
773 // TODO Should construct this behind a method
774 string capsPath =
775 "http://" + reg.ExternalHostName + ":" + reg.HttpPort
776 + "/CAPS/" + agent.CapsPath + "0000/";
685 777
686 if (eq != null) 778 if (eq != null)
687 { 779 {
688 OSD Item = EventQueueHelper.EnableSimulator(reg.RegionHandle, reg.ExternalEndPoint); 780 OSD Item = EventQueueHelper.EnableSimulator(reg.RegionHandle, reg.ExternalEndPoint);
689 eq.Enqueue(Item, avatar.UUID); 781 eq.Enqueue(Item, avatar.UUID);
782
783 Item = EventQueueHelper.EstablishAgentCommunication(avatar.UUID, reg.ExternalEndPoint.ToString(), capsPath);
784 eq.Enqueue(Item, avatar.UUID);
690 } 785 }
691 else 786 else
692 { 787 {
693 avatar.ControllingClient.InformClientOfNeighbour(reg.RegionHandle, reg.ExternalEndPoint); 788 avatar.ControllingClient.InformClientOfNeighbour(reg.RegionHandle, reg.ExternalEndPoint);
694 } 789 }
695
696 m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId,
697 position, false);
698 Thread.Sleep(2000);
699 AgentCircuitData circuitdata = avatar.ControllingClient.RequestClientInfo();
700 790
701 // TODO Should construct this behind a method 791 if (!m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId,
702 string capsPath = 792 position, false))
703 "http://" + reg.ExternalHostName + ":" + reg.HttpPort 793 {
704 + "/CAPS/" + circuitdata.CapsPath + "0000/"; 794 avatar.ControllingClient.SendTeleportFailed("Problem with destination.");
795 // We should close that agent we just created over at destination...
796 List<ulong> lst = new List<ulong>();
797 lst.Add(reg.RegionHandle);
798 SendCloseChildAgentAsync(avatar.UUID, lst);
799 return;
800 }
801
802 Thread.Sleep(2000);
705 803
706 m_log.DebugFormat( 804 m_log.DebugFormat(
707 "[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID); 805 "[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID);
@@ -720,26 +818,25 @@ namespace OpenSim.Region.Environment.Scenes
720 } 818 }
721 819
722 avatar.MakeChildAgent(); 820 avatar.MakeChildAgent();
723 Thread.Sleep(7000); 821 Thread.Sleep(5000);
724 avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true); 822 avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true);
725 if (KiPrimitive != null) 823 if (KiPrimitive != null)
726 { 824 {
727 KiPrimitive(avatar.LocalId); 825 KiPrimitive(avatar.LocalId);
728 } 826 }
729 827
730 avatar.Close();
731 828
732 uint newRegionX = (uint)(reg.RegionHandle >> 40); 829 // Let's close some children agents
733 uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); 830 avatar.CloseChildAgents(newRegionX, newRegionY);
734 uint oldRegionX = (uint)(m_regionInfo.RegionHandle >> 40); 831 // Close this ScenePresence too
735 uint oldRegionY = (((uint)(m_regionInfo.RegionHandle)) >> 8); 832 //avatar.Close();
736 833
737 if (Util.fast_distance2d((int)(newRegionX - oldRegionX), (int)(newRegionY - oldRegionY)) > 3) 834 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
738 { 835
739 //SendCloseChildAgentConnections(avatar.UUID,avatar.GetKnownRegionList()); 836 //if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY))
740 SendCloseChildAgentConnections(avatar.UUID, childRegions); 837 //{
741 CloseConnection(avatar.UUID); 838 // CloseConnection(avatar.UUID);
742 } 839 //}
743 840
744 // if (teleport success) // seems to be always success here 841 // if (teleport success) // seems to be always success here
745 // the user may change their profile information in other region, 842 // the user may change their profile information in other region,
@@ -775,6 +872,30 @@ namespace OpenSim.Region.Environment.Scenes
775 } 872 }
776 } 873 }
777 874
875 private List<ulong> NeighbourHandles(List<SimpleRegionInfo> neighbours)
876 {
877 List<ulong> handles = new List<ulong>();
878 foreach (SimpleRegionInfo reg in neighbours)
879 {
880 handles.Add(reg.RegionHandle);
881 }
882 return handles;
883 }
884
885 private List<ulong> NewNeighbours(List<ulong> currentNeighbours, List<ulong> previousNeighbours)
886 {
887 return currentNeighbours.FindAll(delegate(ulong handle) { return !previousNeighbours.Contains(handle); });
888 }
889
890 private List<ulong> CommonNeighbours(List<ulong> currentNeighbours, List<ulong> previousNeighbours)
891 {
892 return currentNeighbours.FindAll(delegate(ulong handle) { return previousNeighbours.Contains(handle); });
893 }
894
895 private List<ulong> OldNeighbours(List<ulong> currentNeighbours, List<ulong> previousNeighbours)
896 {
897 return previousNeighbours.FindAll(delegate(ulong handle) { return !currentNeighbours.Contains(handle); });
898 }
778 /// <summary> 899 /// <summary>
779 /// Inform a neighbouring region that an avatar is about to cross into it. 900 /// Inform a neighbouring region that an avatar is about to cross into it.
780 /// </summary> 901 /// </summary>
@@ -846,5 +967,18 @@ namespace OpenSim.Region.Environment.Scenes
846 { 967 {
847 return m_commsProvider.GridService.RequestNamedRegions(name, maxNumber); 968 return m_commsProvider.GridService.RequestNamedRegions(name, maxNumber);
848 } 969 }
970
971 private void Dump(string msg, List<ulong> handles)
972 {
973 Console.WriteLine("-------------- HANDLE DUMP ({0}) ---------", msg);
974 foreach (ulong handle in handles)
975 {
976 uint x, y;
977 Utils.LongToUInts(handle, out x, out y);
978 x = x / Constants.RegionSize;
979 y = y / Constants.RegionSize;
980 Console.WriteLine("({0}, {1})", x, y);
981 }
982 }
849 } 983 }
850} 984}
diff --git a/OpenSim/Region/Environment/Scenes/SceneGraph.cs b/OpenSim/Region/Environment/Scenes/SceneGraph.cs
index aed01df..b373c09 100644
--- a/OpenSim/Region/Environment/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneGraph.cs
@@ -911,17 +911,20 @@ namespace OpenSim.Region.Environment.Scenes
911 ScenePresence presence; 911 ScenePresence presence;
912 if (ScenePresences.TryGetValue(avatarId, out presence)) 912 if (ScenePresences.TryGetValue(avatarId, out presence))
913 { 913 {
914 if (!presence.IsChildAgent) 914 avatar = presence;
915 { 915 return true;
916 avatar = presence; 916
917 return true; 917 //if (!presence.IsChildAgent)
918 } 918 //{
919 else 919 // avatar = presence;
920 { 920 // return true;
921 m_log.WarnFormat( 921 //}
922 "[INNER SCENE]: Requested avatar {0} could not be found in scene {1} since it is only registered as a child agent!", 922 //else
923 avatarId, m_parentScene.RegionInfo.RegionName); 923 //{
924 } 924 // m_log.WarnFormat(
925 // "[INNER SCENE]: Requested avatar {0} could not be found in scene {1} since it is only registered as a child agent!",
926 // avatarId, m_parentScene.RegionInfo.RegionName);
927 //}
925 } 928 }
926 929
927 avatar = null; 930 avatar = null;
diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs
index 3bd6be9..f139ba5 100644
--- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs
@@ -188,8 +188,9 @@ namespace OpenSim.Region.Environment.Scenes
188 188
189 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); 189 protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>();
190 190
191 //neighbouring regions we have enabled a child agent in 191 // neighbouring regions we have enabled a child agent in
192 private readonly List<ulong> m_knownChildRegions = new List<ulong>(); 192 // holds the seed cap for the child agent in that region
193 private Dictionary<ulong, string> m_knownChildRegions = new Dictionary<ulong, string>();
193 194
194 /// <summary> 195 /// <summary>
195 /// Implemented Control Flags 196 /// Implemented Control Flags
@@ -483,9 +484,38 @@ namespace OpenSim.Region.Environment.Scenes
483 /// <summary> 484 /// <summary>
484 /// These are the region handles known by the avatar. 485 /// These are the region handles known by the avatar.
485 /// </summary> 486 /// </summary>
486 public List<ulong> KnownChildRegions 487 public List<ulong> KnownChildRegionHandles
488 {
489 get
490 {
491 if (m_knownChildRegions.Count == 0)
492 return new List<ulong>();
493 else
494 return new List<ulong>(m_knownChildRegions.Keys);
495 }
496 }
497
498 public Dictionary<ulong, string> KnownRegions
487 { 499 {
488 get { return m_knownChildRegions; } 500 get { return m_knownChildRegions; }
501 set
502 {
503 //Console.WriteLine(" !! Setting known regions in {0} to {1}", Scene.RegionInfo.RegionName, value.Count);
504 m_knownChildRegions = value;
505 }
506 }
507
508 public void DumpKnownRegions()
509 {
510 Console.WriteLine("================ KnownRegions {0} ================", Scene.RegionInfo.RegionName);
511 foreach (KeyValuePair<ulong, string> kvp in KnownRegions)
512 {
513 uint x, y;
514 Utils.LongToUInts(kvp.Key, out x, out y);
515 x = x / Constants.RegionSize;
516 y = y / Constants.RegionSize;
517 Console.WriteLine(" >> {0}, {1}: {2}", x, y, kvp.Value);
518 }
489 } 519 }
490 520
491 public AnimationSet Animations 521 public AnimationSet Animations
@@ -529,6 +559,8 @@ namespace OpenSim.Region.Environment.Scenes
529 CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(m_uuid); 559 CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(m_uuid);
530 if (userInfo != null) 560 if (userInfo != null)
531 userInfo.OnItemReceived += ItemReceived; 561 userInfo.OnItemReceived += ItemReceived;
562
563 m_log.Info("[AVATAR]: New ScenePresence in " + Scene.RegionInfo.RegionName);
532 } 564 }
533 565
534 public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, byte[] visualParams, 566 public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, byte[] visualParams,
@@ -742,7 +774,9 @@ namespace OpenSim.Region.Environment.Scenes
742 m_log.DebugFormat( 774 m_log.DebugFormat(
743 "[SCENE]: Upgrading child to root agent for {0} in {1}", 775 "[SCENE]: Upgrading child to root agent for {0} in {1}",
744 Name, m_scene.RegionInfo.RegionName); 776 Name, m_scene.RegionInfo.RegionName);
745 777
778 m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
779
746 IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); 780 IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
747 if (gm != null) 781 if (gm != null)
748 m_grouptitle = gm.GetGroupTitle(m_uuid); 782 m_grouptitle = gm.GetGroupTitle(m_uuid);
@@ -881,25 +915,43 @@ namespace OpenSim.Region.Environment.Scenes
881 SendFullUpdateToAllClients(); 915 SendFullUpdateToAllClients();
882 } 916 }
883 917
884 public void AddNeighbourRegion(ulong regionHandle) 918 public void AddNeighbourRegion(ulong regionHandle, string cap)
885 { 919 {
886 if (!m_knownChildRegions.Contains(regionHandle)) 920 lock (m_knownChildRegions)
887 { 921 {
888 m_knownChildRegions.Add(regionHandle); 922 if (!m_knownChildRegions.ContainsKey(regionHandle))
923 {
924 uint x, y;
925 Utils.LongToUInts(regionHandle, out x, out y);
926 m_knownChildRegions.Add(regionHandle, cap);
927 }
889 } 928 }
890 } 929 }
891 930
892 public void RemoveNeighbourRegion(ulong regionHandle) 931 public void RemoveNeighbourRegion(ulong regionHandle)
893 { 932 {
894 if (m_knownChildRegions.Contains(regionHandle)) 933 lock (m_knownChildRegions)
895 { 934 {
896 m_knownChildRegions.Remove(regionHandle); 935 if (m_knownChildRegions.ContainsKey(regionHandle))
936 {
937 m_knownChildRegions.Remove(regionHandle);
938 //Console.WriteLine(" !!! removing known region {0} in {1}. Count = {2}", regionHandle, Scene.RegionInfo.RegionName, m_knownChildRegions.Count);
939 }
940 }
941 }
942
943 public void DropOldNeighbours(List<ulong> oldRegions)
944 {
945 foreach (ulong handle in oldRegions)
946 {
947 RemoveNeighbourRegion(handle);
948 Scene.DropChildSeed(UUID, handle);
897 } 949 }
898 } 950 }
899 951
900 public List<ulong> GetKnownRegionList() 952 public List<ulong> GetKnownRegionList()
901 { 953 {
902 return m_knownChildRegions; 954 return new List<ulong>(m_knownChildRegions.Keys);
903 } 955 }
904 956
905 #endregion 957 #endregion
@@ -1856,6 +1908,7 @@ namespace OpenSim.Region.Environment.Scenes
1856 1908
1857 #region Overridden Methods 1909 #region Overridden Methods
1858 1910
1911 int x = 0;
1859 public override void Update() 1912 public override void Update()
1860 { 1913 {
1861 SendPrimUpdates(); 1914 SendPrimUpdates();
@@ -1896,6 +1949,9 @@ namespace OpenSim.Region.Environment.Scenes
1896 CheckForBorderCrossing(); 1949 CheckForBorderCrossing();
1897 CheckForSignificantMovement(); // sends update to the modules. 1950 CheckForSignificantMovement(); // sends update to the modules.
1898 } 1951 }
1952
1953 //if ((x++ % 30) == 0)
1954 // Console.WriteLine(" >> In {0} known regions: {0}, seeds:{1}", Scene.RegionInfo.RegionName, KnownRegions.Count, Scene.GetChildrenSeeds(UUID));
1899 } 1955 }
1900 1956
1901 #endregion 1957 #endregion
@@ -2338,7 +2394,7 @@ namespace OpenSim.Region.Environment.Scenes
2338 // When the neighbour is informed of the border crossing, it will set up CAPS handlers for the avatar 2394 // When the neighbour is informed of the border crossing, it will set up CAPS handlers for the avatar
2339 // This means we need to remove the current caps handler here and possibly compensate later, 2395 // This means we need to remove the current caps handler here and possibly compensate later,
2340 // in case both scenes are being hosted on the same region server. Messy 2396 // in case both scenes are being hosted on the same region server. Messy
2341 m_scene.RemoveCapsHandler(UUID); 2397 //m_scene.RemoveCapsHandler(UUID);
2342 newpos = newpos + (vel); 2398 newpos = newpos + (vel);
2343 2399
2344 CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(UUID); 2400 CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(UUID);
@@ -2358,10 +2414,14 @@ namespace OpenSim.Region.Environment.Scenes
2358 { 2414 {
2359 AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); 2415 AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo();
2360 2416
2417 //Console.WriteLine("BEFORE CROSS");
2418 //Scene.DumpChildrenSeeds(UUID);
2419 //DumpKnownRegions();
2420
2361 // TODO Should construct this behind a method 2421 // TODO Should construct this behind a method
2362 string capsPath = 2422 string capsPath =
2363 "http://" + neighbourRegion.ExternalHostName + ":" + neighbourRegion.HttpPort 2423 "http://" + neighbourRegion.ExternalHostName + ":" + neighbourRegion.HttpPort
2364 + "/CAPS/" + circuitdata.CapsPath + "0000/"; 2424 + "/CAPS/" + m_knownChildRegions[neighbourRegion.RegionHandle] /*circuitdata.CapsPath*/ + "0000/";
2365 2425
2366 m_log.DebugFormat("[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, m_uuid); 2426 m_log.DebugFormat("[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, m_uuid);
2367 2427
@@ -2386,6 +2446,8 @@ namespace OpenSim.Region.Environment.Scenes
2386 CrossAttachmentsIntoNewRegion(neighbourHandle, true); 2446 CrossAttachmentsIntoNewRegion(neighbourHandle, true);
2387 2447
2388 // m_scene.SendKillObject(m_localId); 2448 // m_scene.SendKillObject(m_localId);
2449 // Next, let's close the child agent connections that are too far away.
2450 CloseChildAgents(neighbourx, neighboury);
2389 2451
2390 m_scene.NotifyMyCoarseLocationChange(); 2452 m_scene.NotifyMyCoarseLocationChange();
2391 // the user may change their profile information in other region, 2453 // the user may change their profile information in other region,
@@ -2401,6 +2463,11 @@ namespace OpenSim.Region.Environment.Scenes
2401 m_scene.AddCapsHandler(UUID); 2463 m_scene.AddCapsHandler(UUID);
2402 } 2464 }
2403 } 2465 }
2466
2467 //Console.WriteLine("AFTER CROSS");
2468 //Scene.DumpChildrenSeeds(UUID);
2469 //DumpKnownRegions();
2470
2404 } 2471 }
2405 2472
2406 /// <summary> 2473 /// <summary>
@@ -2413,31 +2480,36 @@ namespace OpenSim.Region.Environment.Scenes
2413 public void CloseChildAgents(uint newRegionX, uint newRegionY) 2480 public void CloseChildAgents(uint newRegionX, uint newRegionY)
2414 { 2481 {
2415 List<ulong> byebyeRegions = new List<ulong>(); 2482 List<ulong> byebyeRegions = new List<ulong>();
2483 m_log.DebugFormat("[AVATAR]: Closing child agents. Checking {0} regions in {1}", m_knownChildRegions.Keys.Count, Scene.RegionInfo.RegionName);
2484 //DumpKnownRegions();
2416 2485
2417 foreach (ulong handle in m_knownChildRegions) 2486 lock (m_knownChildRegions)
2418 { 2487 {
2419 uint x, y; 2488 foreach (ulong handle in m_knownChildRegions.Keys)
2420 Utils.LongToUInts(handle, out x, out y);
2421 x = x / Constants.RegionSize;
2422 y = y / Constants.RegionSize;
2423
2424 if (Util.IsOutsideView(x, newRegionX, y, newRegionY))
2425 { 2489 {
2426 Console.WriteLine("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs(x-newRegionX)); 2490 uint x, y;
2427 Console.WriteLine("---> y: " + y + "; newy:" + newRegionY); 2491 Utils.LongToUInts(handle, out x, out y);
2428 byebyeRegions.Add(handle); 2492 x = x / Constants.RegionSize;
2493 y = y / Constants.RegionSize;
2494
2495 //Console.WriteLine("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX)));
2496 //Console.WriteLine("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY)));
2497 if (Util.IsOutsideView(x, newRegionX, y, newRegionY))
2498 {
2499 byebyeRegions.Add(handle);
2500 }
2429 } 2501 }
2430 } 2502 }
2431 foreach (ulong handle in byebyeRegions)
2432 {
2433 RemoveNeighbourRegion(handle);
2434 }
2435
2436 if (byebyeRegions.Count > 0) 2503 if (byebyeRegions.Count > 0)
2437 { 2504 {
2438 m_log.Info("[AVATAR]: Closing " + byebyeRegions.Count + " child agents"); 2505 m_log.Info("[AVATAR]: Closing " + byebyeRegions.Count + " child agents");
2439 m_scene.SceneGridService.SendCloseChildAgentConnections(m_controllingClient.AgentId, byebyeRegions); 2506 m_scene.SceneGridService.SendCloseChildAgentConnections(m_controllingClient.AgentId, byebyeRegions);
2440 } 2507 }
2508 foreach (ulong handle in byebyeRegions)
2509 {
2510 RemoveNeighbourRegion(handle);
2511 }
2512
2441 2513
2442 } 2514 }
2443 2515
@@ -2940,7 +3012,8 @@ namespace OpenSim.Region.Environment.Scenes
2940 3012
2941 m_DrawDistance = (float)info.GetValue("m_DrawDistance", typeof(float)); 3013 m_DrawDistance = (float)info.GetValue("m_DrawDistance", typeof(float));
2942 m_appearance = (AvatarAppearance)info.GetValue("m_appearance", typeof(AvatarAppearance)); 3014 m_appearance = (AvatarAppearance)info.GetValue("m_appearance", typeof(AvatarAppearance));
2943 m_knownChildRegions = (List<ulong>)info.GetValue("m_knownChildRegions", typeof(List<ulong>)); 3015
3016 m_knownChildRegions = (Dictionary<ulong, string>)info.GetValue("m_knownChildRegions", typeof(Dictionary<ulong, string>));
2944 3017
2945 posLastSignificantMove 3018 posLastSignificantMove
2946 = new Vector3( 3019 = new Vector3(