diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs | 526 |
1 files changed, 263 insertions, 263 deletions
diff --git a/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs index 501584a..9eb331a 100644 --- a/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs +++ b/OpenSim/Region/Environment/Scenes/Hypergrid/HGSceneCommunicationService.cs | |||
@@ -1,263 +1,263 @@ | |||
1 | /** | 1 | /** |
2 | * Copyright (c) 2008, Contributors. All rights reserved. | 2 | * Copyright (c) 2008, Contributors. All rights reserved. |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without modification, | 5 | * Redistribution and use in source and binary forms, with or without modification, |
6 | * are permitted provided that the following conditions are met: | 6 | * are permitted provided that the following conditions are met: |
7 | * | 7 | * |
8 | * * Redistributions of source code must retain the above copyright notice, | 8 | * * Redistributions of source code must retain the above copyright notice, |
9 | * this list of conditions and the following disclaimer. | 9 | * this list of conditions and the following disclaimer. |
10 | * * Redistributions in binary form must reproduce the above copyright notice, | 10 | * * Redistributions in binary form must reproduce the above copyright notice, |
11 | * this list of conditions and the following disclaimer in the documentation | 11 | * this list of conditions and the following disclaimer in the documentation |
12 | * and/or other materials provided with the distribution. | 12 | * and/or other materials provided with the distribution. |
13 | * * Neither the name of the Organizations nor the names of Individual | 13 | * * Neither the name of the Organizations nor the names of Individual |
14 | * Contributors may be used to endorse or promote products derived from | 14 | * Contributors may be used to endorse or promote products derived from |
15 | * this software without specific prior written permission. | 15 | * this software without specific prior written permission. |
16 | * | 16 | * |
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL |
20 | * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 20 | * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
21 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE | 21 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
22 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | 22 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
24 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | 24 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
25 | * OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | * | 26 | * |
27 | */ | 27 | */ |
28 | 28 | ||
29 | using System; | 29 | using System; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using System.Threading; | 32 | using System.Threading; |
33 | 33 | ||
34 | using OpenMetaverse; | 34 | using OpenMetaverse; |
35 | 35 | ||
36 | using log4net; | 36 | using log4net; |
37 | using OpenSim.Framework; | 37 | using OpenSim.Framework; |
38 | using OpenSim.Framework.Communications; | 38 | using OpenSim.Framework.Communications; |
39 | using OpenSim.Framework.Communications.Cache; | 39 | using OpenSim.Framework.Communications.Cache; |
40 | using OpenSim.Region.Environment.Scenes; | 40 | using OpenSim.Region.Environment.Scenes; |
41 | using OpenSim.Region.Environment; | 41 | using OpenSim.Region.Environment; |
42 | using OpenSim.Region.Interfaces; | 42 | using OpenSim.Region.Interfaces; |
43 | using OSD = OpenMetaverse.StructuredData.OSD; | 43 | using OSD = OpenMetaverse.StructuredData.OSD; |
44 | 44 | ||
45 | namespace OpenSim.Region.Environment.Scenes.Hypergrid | 45 | namespace OpenSim.Region.Environment.Scenes.Hypergrid |
46 | { | 46 | { |
47 | public class HGSceneCommunicationService : SceneCommunicationService | 47 | public class HGSceneCommunicationService : SceneCommunicationService |
48 | { | 48 | { |
49 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 49 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
50 | 50 | ||
51 | private IHyperlink m_hg; | 51 | private IHyperlink m_hg; |
52 | 52 | ||
53 | public HGSceneCommunicationService(CommunicationsManager commsMan, IHyperlink hg) : base(commsMan) | 53 | public HGSceneCommunicationService(CommunicationsManager commsMan, IHyperlink hg) : base(commsMan) |
54 | { | 54 | { |
55 | m_hg = hg; | 55 | m_hg = hg; |
56 | } | 56 | } |
57 | 57 | ||
58 | 58 | ||
59 | /// <summary> | 59 | /// <summary> |
60 | /// Try to teleport an agent to a new region. | 60 | /// Try to teleport an agent to a new region. |
61 | /// </summary> | 61 | /// </summary> |
62 | /// <param name="remoteClient"></param> | 62 | /// <param name="remoteClient"></param> |
63 | /// <param name="RegionHandle"></param> | 63 | /// <param name="RegionHandle"></param> |
64 | /// <param name="position"></param> | 64 | /// <param name="position"></param> |
65 | /// <param name="lookAt"></param> | 65 | /// <param name="lookAt"></param> |
66 | /// <param name="flags"></param> | 66 | /// <param name="flags"></param> |
67 | public override void RequestTeleportToLocation(ScenePresence avatar, ulong regionHandle, Vector3 position, | 67 | public override void RequestTeleportToLocation(ScenePresence avatar, ulong regionHandle, Vector3 position, |
68 | Vector3 lookAt, uint teleportFlags) | 68 | Vector3 lookAt, uint teleportFlags) |
69 | { | 69 | { |
70 | if (!avatar.Scene.Permissions.CanTeleport(avatar.UUID)) | 70 | if (!avatar.Scene.Permissions.CanTeleport(avatar.UUID)) |
71 | return; | 71 | return; |
72 | 72 | ||
73 | bool destRegionUp = false; | 73 | bool destRegionUp = false; |
74 | 74 | ||
75 | IEventQueue eq = avatar.Scene.RequestModuleInterface<IEventQueue>(); | 75 | IEventQueue eq = avatar.Scene.RequestModuleInterface<IEventQueue>(); |
76 | 76 | ||
77 | if (regionHandle == m_regionInfo.RegionHandle) | 77 | if (regionHandle == m_regionInfo.RegionHandle) |
78 | { | 78 | { |
79 | // Teleport within the same region | 79 | // Teleport within the same region |
80 | if (position.X < 0 || position.X > Constants.RegionSize || position.Y < 0 || position.Y > Constants.RegionSize || position.Z < 0) | 80 | if (position.X < 0 || position.X > Constants.RegionSize || position.Y < 0 || position.Y > Constants.RegionSize || position.Z < 0) |
81 | { | 81 | { |
82 | Vector3 emergencyPos = new Vector3(128, 128, 128); | 82 | Vector3 emergencyPos = new Vector3(128, 128, 128); |
83 | 83 | ||
84 | m_log.WarnFormat( | 84 | m_log.WarnFormat( |
85 | "[HGSceneCommService]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", | 85 | "[HGSceneCommService]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", |
86 | position, avatar.Name, avatar.UUID, emergencyPos); | 86 | position, avatar.Name, avatar.UUID, emergencyPos); |
87 | position = emergencyPos; | 87 | position = emergencyPos; |
88 | } | 88 | } |
89 | // TODO: Get proper AVG Height | 89 | // TODO: Get proper AVG Height |
90 | float localAVHeight = 1.56f; | 90 | float localAVHeight = 1.56f; |
91 | float posZLimit = (float)avatar.Scene.GetLandHeight((int)position.X, (int)position.Y); | 91 | float posZLimit = (float)avatar.Scene.GetLandHeight((int)position.X, (int)position.Y); |
92 | float newPosZ = posZLimit + localAVHeight; | 92 | float newPosZ = posZLimit + localAVHeight; |
93 | if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) | 93 | if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) |
94 | { | 94 | { |
95 | position.Z = newPosZ; | 95 | position.Z = newPosZ; |
96 | } | 96 | } |
97 | 97 | ||
98 | // Only send this if the event queue is null | 98 | // Only send this if the event queue is null |
99 | if (eq == null) | 99 | if (eq == null) |
100 | avatar.ControllingClient.SendTeleportLocationStart(); | 100 | avatar.ControllingClient.SendTeleportLocationStart(); |
101 | 101 | ||
102 | 102 | ||
103 | avatar.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); | 103 | avatar.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); |
104 | avatar.Teleport(position); | 104 | avatar.Teleport(position); |
105 | } | 105 | } |
106 | else | 106 | else |
107 | { | 107 | { |
108 | RegionInfo reg = RequestNeighbouringRegionInfo(regionHandle); | 108 | RegionInfo reg = RequestNeighbouringRegionInfo(regionHandle); |
109 | if (reg != null) | 109 | if (reg != null) |
110 | { | 110 | { |
111 | /// | 111 | /// |
112 | /// Hypergrid mod start | 112 | /// Hypergrid mod start |
113 | /// | 113 | /// |
114 | /// | 114 | /// |
115 | bool isHyperLink = m_hg.IsHyperlinkRegion(reg.RegionHandle); | 115 | bool isHyperLink = m_hg.IsHyperlinkRegion(reg.RegionHandle); |
116 | bool isHomeUser = true; | 116 | bool isHomeUser = true; |
117 | ulong realHandle = regionHandle; | 117 | ulong realHandle = regionHandle; |
118 | CachedUserInfo uinfo = m_commsProvider.UserProfileCacheService.GetUserDetails(avatar.UUID); | 118 | CachedUserInfo uinfo = m_commsProvider.UserProfileCacheService.GetUserDetails(avatar.UUID); |
119 | if (uinfo != null) | 119 | if (uinfo != null) |
120 | { | 120 | { |
121 | isHomeUser = HGNetworkServersInfo.Singleton.IsLocalUser(uinfo.UserProfile.UserAssetURI); | 121 | isHomeUser = HGNetworkServersInfo.Singleton.IsLocalUser(uinfo.UserProfile.UserAssetURI); |
122 | realHandle = m_hg.FindRegionHandle(regionHandle); | 122 | realHandle = m_hg.FindRegionHandle(regionHandle); |
123 | Console.WriteLine("XXX ---- home user? " + isHomeUser + " --- hyperlink? " + isHyperLink + " --- real handle: " + realHandle.ToString()); | 123 | Console.WriteLine("XXX ---- home user? " + isHomeUser + " --- hyperlink? " + isHyperLink + " --- real handle: " + realHandle.ToString()); |
124 | } | 124 | } |
125 | /// | 125 | /// |
126 | /// Hypergrid mod stop | 126 | /// Hypergrid mod stop |
127 | /// | 127 | /// |
128 | /// | 128 | /// |
129 | 129 | ||
130 | if (eq == null) | 130 | if (eq == null) |
131 | avatar.ControllingClient.SendTeleportLocationStart(); | 131 | avatar.ControllingClient.SendTeleportLocationStart(); |
132 | 132 | ||
133 | AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); | 133 | AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); |
134 | agent.BaseFolder = UUID.Zero; | 134 | agent.BaseFolder = UUID.Zero; |
135 | agent.InventoryFolder = UUID.Zero; | 135 | agent.InventoryFolder = UUID.Zero; |
136 | agent.startpos = position; | 136 | agent.startpos = position; |
137 | agent.child = true; | 137 | agent.child = true; |
138 | 138 | ||
139 | if (reg.RemotingAddress != "" && reg.RemotingPort != 0) | 139 | if (reg.RemotingAddress != "" && reg.RemotingPort != 0) |
140 | { | 140 | { |
141 | // region is remote. see if it is up | 141 | // region is remote. see if it is up |
142 | destRegionUp = m_commsProvider.InterRegion.CheckRegion(reg.RemotingAddress, reg.RemotingPort); | 142 | destRegionUp = m_commsProvider.InterRegion.CheckRegion(reg.RemotingAddress, reg.RemotingPort); |
143 | } | 143 | } |
144 | else | 144 | else |
145 | { | 145 | { |
146 | // assume local regions are always up | 146 | // assume local regions are always up |
147 | destRegionUp = true; | 147 | destRegionUp = true; |
148 | } | 148 | } |
149 | 149 | ||
150 | if (destRegionUp) | 150 | if (destRegionUp) |
151 | { | 151 | { |
152 | // Fixing a bug where teleporting while sitting results in the avatar ending up removed from | 152 | // Fixing a bug where teleporting while sitting results in the avatar ending up removed from |
153 | // both regions | 153 | // both regions |
154 | if (avatar.ParentID != (uint)0) | 154 | if (avatar.ParentID != (uint)0) |
155 | avatar.StandUp(); | 155 | avatar.StandUp(); |
156 | if (!avatar.ValidateAttachments()) | 156 | if (!avatar.ValidateAttachments()) |
157 | { | 157 | { |
158 | avatar.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); | 158 | avatar.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); |
159 | return; | 159 | return; |
160 | } | 160 | } |
161 | 161 | ||
162 | // the avatar.Close below will clear the child region list. We need this below for (possibly) | 162 | // the avatar.Close below will clear the child region list. We need this below for (possibly) |
163 | // closing the child agents, so save it here (we need a copy as it is Clear()-ed). | 163 | // closing the child agents, so save it here (we need a copy as it is Clear()-ed). |
164 | List<ulong> childRegions = new List<ulong>(avatar.GetKnownRegionList()); | 164 | List<ulong> childRegions = new List<ulong>(avatar.GetKnownRegionList()); |
165 | // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport | 165 | // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport |
166 | // failure at this point (unlike a border crossing failure). So perhaps this can never fail | 166 | // failure at this point (unlike a border crossing failure). So perhaps this can never fail |
167 | // once we reach here... | 167 | // once we reach here... |
168 | avatar.Scene.RemoveCapsHandler(avatar.UUID); | 168 | avatar.Scene.RemoveCapsHandler(avatar.UUID); |
169 | agent.child = false; | 169 | agent.child = false; |
170 | m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent); | 170 | m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agent); |
171 | 171 | ||
172 | m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, | 172 | m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, |
173 | position, false); | 173 | position, false); |
174 | Thread.Sleep(2000); | 174 | Thread.Sleep(2000); |
175 | AgentCircuitData circuitdata = avatar.ControllingClient.RequestClientInfo(); | 175 | AgentCircuitData circuitdata = avatar.ControllingClient.RequestClientInfo(); |
176 | 176 | ||
177 | // TODO Should construct this behind a method | 177 | // TODO Should construct this behind a method |
178 | string capsPath = | 178 | string capsPath = |
179 | "http://" + reg.ExternalHostName + ":" + reg.HttpPort | 179 | "http://" + reg.ExternalHostName + ":" + reg.HttpPort |
180 | + "/CAPS/" + circuitdata.CapsPath + "0000/"; | 180 | + "/CAPS/" + circuitdata.CapsPath + "0000/"; |
181 | 181 | ||
182 | m_log.DebugFormat( | 182 | m_log.DebugFormat( |
183 | "[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID); | 183 | "[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID); |
184 | 184 | ||
185 | 185 | ||
186 | /// | 186 | /// |
187 | /// Hypergrid mod: realHandle instead of reg.RegionHandle | 187 | /// Hypergrid mod: realHandle instead of reg.RegionHandle |
188 | /// | 188 | /// |
189 | /// | 189 | /// |
190 | if (eq != null) | 190 | if (eq != null) |
191 | { | 191 | { |
192 | OSD Item = EventQueueHelper.TeleportFinishEvent(realHandle, 13, reg.ExternalEndPoint, | 192 | OSD Item = EventQueueHelper.TeleportFinishEvent(realHandle, 13, reg.ExternalEndPoint, |
193 | 4, teleportFlags, capsPath, avatar.UUID); | 193 | 4, teleportFlags, capsPath, avatar.UUID); |
194 | eq.Enqueue(Item, avatar.UUID); | 194 | eq.Enqueue(Item, avatar.UUID); |
195 | } | 195 | } |
196 | else | 196 | else |
197 | { | 197 | { |
198 | avatar.ControllingClient.SendRegionTeleport(realHandle, 13, reg.ExternalEndPoint, 4, | 198 | avatar.ControllingClient.SendRegionTeleport(realHandle, 13, reg.ExternalEndPoint, 4, |
199 | teleportFlags, capsPath); | 199 | teleportFlags, capsPath); |
200 | } | 200 | } |
201 | /// | 201 | /// |
202 | /// Hypergrid mod stop | 202 | /// Hypergrid mod stop |
203 | /// | 203 | /// |
204 | 204 | ||
205 | avatar.MakeChildAgent(); | 205 | avatar.MakeChildAgent(); |
206 | Thread.Sleep(7000); | 206 | Thread.Sleep(7000); |
207 | avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true); | 207 | avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true); |
208 | if (KiPrimitive != null) | 208 | if (KiPrimitive != null) |
209 | { | 209 | { |
210 | KiPrimitive(avatar.LocalId); | 210 | KiPrimitive(avatar.LocalId); |
211 | } | 211 | } |
212 | 212 | ||
213 | avatar.Close(); | 213 | avatar.Close(); |
214 | 214 | ||
215 | uint newRegionX = (uint)(reg.RegionHandle >> 40); | 215 | uint newRegionX = (uint)(reg.RegionHandle >> 40); |
216 | uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); | 216 | uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); |
217 | uint oldRegionX = (uint)(m_regionInfo.RegionHandle >> 40); | 217 | uint oldRegionX = (uint)(m_regionInfo.RegionHandle >> 40); |
218 | uint oldRegionY = (((uint)(m_regionInfo.RegionHandle)) >> 8); | 218 | uint oldRegionY = (((uint)(m_regionInfo.RegionHandle)) >> 8); |
219 | /// | 219 | /// |
220 | /// Hypergrid mod: extra check for isHyperLink | 220 | /// Hypergrid mod: extra check for isHyperLink |
221 | /// | 221 | /// |
222 | if ((Util.fast_distance2d((int)(newRegionX - oldRegionX), (int)(newRegionY - oldRegionY)) > 3) || isHyperLink) | 222 | if ((Util.fast_distance2d((int)(newRegionX - oldRegionX), (int)(newRegionY - oldRegionY)) > 3) || isHyperLink) |
223 | { | 223 | { |
224 | //SendCloseChildAgentConnections(avatar.UUID, avatar.GetKnownRegionList()); | 224 | //SendCloseChildAgentConnections(avatar.UUID, avatar.GetKnownRegionList()); |
225 | SendCloseChildAgentConnections(avatar.UUID, childRegions); | 225 | SendCloseChildAgentConnections(avatar.UUID, childRegions); |
226 | CloseConnection(avatar.UUID); | 226 | CloseConnection(avatar.UUID); |
227 | } | 227 | } |
228 | // if (teleport success) // seems to be always success here | 228 | // if (teleport success) // seems to be always success here |
229 | // the user may change their profile information in other region, | 229 | // the user may change their profile information in other region, |
230 | // so the userinfo in UserProfileCache is not reliable any more, delete it | 230 | // so the userinfo in UserProfileCache is not reliable any more, delete it |
231 | if (avatar.Scene.NeedSceneCacheClear(avatar.UUID)) | 231 | if (avatar.Scene.NeedSceneCacheClear(avatar.UUID)) |
232 | m_commsProvider.UserProfileCacheService.RemoveUser(avatar.UUID); | 232 | m_commsProvider.UserProfileCacheService.RemoveUser(avatar.UUID); |
233 | m_log.InfoFormat("[HGSceneCommService]: User {0} is going to another region, profile cache removed", avatar.UUID); | 233 | m_log.InfoFormat("[HGSceneCommService]: User {0} is going to another region, profile cache removed", avatar.UUID); |
234 | } | 234 | } |
235 | else | 235 | else |
236 | { | 236 | { |
237 | avatar.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); | 237 | avatar.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); |
238 | } | 238 | } |
239 | } | 239 | } |
240 | else | 240 | else |
241 | { | 241 | { |
242 | // TP to a place that doesn't exist (anymore) | 242 | // TP to a place that doesn't exist (anymore) |
243 | // Inform the viewer about that | 243 | // Inform the viewer about that |
244 | avatar.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); | 244 | avatar.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); |
245 | 245 | ||
246 | // and set the map-tile to '(Offline)' | 246 | // and set the map-tile to '(Offline)' |
247 | uint regX, regY; | 247 | uint regX, regY; |
248 | Utils.LongToUInts(regionHandle, out regX, out regY); | 248 | Utils.LongToUInts(regionHandle, out regX, out regY); |
249 | 249 | ||
250 | MapBlockData block = new MapBlockData(); | 250 | MapBlockData block = new MapBlockData(); |
251 | block.X = (ushort)(regX / Constants.RegionSize); | 251 | block.X = (ushort)(regX / Constants.RegionSize); |
252 | block.Y = (ushort)(regY / Constants.RegionSize); | 252 | block.Y = (ushort)(regY / Constants.RegionSize); |
253 | block.Access = 254; // == not there | 253 | block.Access = 254; // == not there |
254 | 254 | ||
255 | List<MapBlockData> blocks = new List<MapBlockData>(); | 255 | List<MapBlockData> blocks = new List<MapBlockData>(); |
256 | blocks.Add(block); | 256 | blocks.Add(block); |
257 | avatar.ControllingClient.SendMapBlock(blocks, 0); | 257 | avatar.ControllingClient.SendMapBlock(blocks, 0); |
258 | } | 258 | } |
259 | } | 259 | } |
260 | } | 260 | } |
261 | 261 | ||
262 | } | 262 | } |
263 | } | 263 | } |