diff options
author | Charles Krinke | 2008-12-14 02:17:12 +0000 |
---|---|---|
committer | Charles Krinke | 2008-12-14 02:17:12 +0000 |
commit | e6eb571c1d19972fe7eb4c3f7de113b1b91f5e02 (patch) | |
tree | 2140979c8cf3f4d4d2b60a355be65abd659508b9 /OpenSim/Region/Environment/Scenes | |
parent | Mantis#2811. Thank you kindly, Diva for a patch that resolves (diff) | |
download | opensim-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')
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( |