aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs
diff options
context:
space:
mode:
authorDr Scofield2009-02-06 16:55:34 +0000
committerDr Scofield2009-02-06 16:55:34 +0000
commit9b66108081a8c8cf79faaa6c541554091c40850e (patch)
tree095a232ae5a9de3a9244bcd34da08294f61eeea5 /OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs
parent* removed superfluous constants class (diff)
downloadopensim-SC_OLD-9b66108081a8c8cf79faaa6c541554091c40850e.zip
opensim-SC_OLD-9b66108081a8c8cf79faaa6c541554091c40850e.tar.gz
opensim-SC_OLD-9b66108081a8c8cf79faaa6c541554091c40850e.tar.bz2
opensim-SC_OLD-9b66108081a8c8cf79faaa6c541554091c40850e.tar.xz
This changeset is the step 1 of 2 in refactoring
OpenSim.Region.Environment into a "framework" part and a modules only part. This first changeset refactors OpenSim.Region.Environment.Scenes, OpenSim.Region.Environment.Interfaces, and OpenSim.Region.Interfaces into OpenSim.Region.Framework.{Interfaces,Scenes} leaving only region modules in OpenSim.Region.Environment. The next step will be to move region modules up from OpenSim.Region.Environment.Modules to OpenSim.Region.CoreModules and then sort out which modules are really core modules and which should move out to forge. I've been very careful to NOT BREAK anything. i hope i've succeeded. as this is the work of a whole week i hope i managed to keep track with the applied patches of the last week --- could any of you that did check in stuff have a look at whether it survived? thx!
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs360
1 files changed, 360 insertions, 0 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs
new file mode 100644
index 0000000..d0dc4f7
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Hypergrid/HGSceneCommunicationService.cs
@@ -0,0 +1,360 @@
1/**
2 * Copyright (c) 2008, Contributors. All rights reserved.
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the Organizations nor the names of Individual
14 * Contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
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
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,
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
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
25 * OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29using System;
30using System.Collections.Generic;
31using System.Net;
32using System.Reflection;
33using System.Threading;
34using log4net;
35using OpenMetaverse;
36using OSD = OpenMetaverse.StructuredData.OSD;
37using OpenSim.Framework;
38using OpenSim.Framework.Communications;
39using OpenSim.Framework.Communications.Cache;
40using OpenSim.Framework.Communications.Capabilities;
41using OpenSim.Region.Framework.Scenes;
42// using OpenSim.Region.Environment;
43using OpenSim.Region.Framework.Interfaces;
44
45namespace OpenSim.Region.Framework.Scenes.Hypergrid
46{
47 public class HGSceneCommunicationService : SceneCommunicationService
48 {
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50
51 public readonly IHyperlink m_hg;
52
53 public HGSceneCommunicationService(CommunicationsManager commsMan, IHyperlink hg) : base(commsMan)
54 {
55 m_hg = hg;
56 }
57
58
59 /// <summary>
60 /// Try to teleport an agent to a new region.
61 /// </summary>
62 /// <param name="remoteClient"></param>
63 /// <param name="RegionHandle"></param>
64 /// <param name="position"></param>
65 /// <param name="lookAt"></param>
66 /// <param name="flags"></param>
67 public override void RequestTeleportToLocation(ScenePresence avatar, ulong regionHandle, Vector3 position,
68 Vector3 lookAt, uint teleportFlags)
69 {
70 if (!avatar.Scene.Permissions.CanTeleport(avatar.UUID))
71 return;
72
73 bool destRegionUp = true;
74
75 IEventQueue eq = avatar.Scene.RequestModuleInterface<IEventQueue>();
76
77 if (regionHandle == m_regionInfo.RegionHandle)
78 {
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)
81 {
82 Vector3 emergencyPos = new Vector3(128, 128, 128);
83
84 m_log.WarnFormat(
85 "[HGSceneCommService]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}",
86 position, avatar.Name, avatar.UUID, emergencyPos);
87 position = emergencyPos;
88 }
89 // TODO: Get proper AVG Height
90 float localAVHeight = 1.56f;
91 float posZLimit = (float)avatar.Scene.GetLandHeight((int)position.X, (int)position.Y);
92 float newPosZ = posZLimit + localAVHeight;
93 if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
94 {
95 position.Z = newPosZ;
96 }
97
98 // Only send this if the event queue is null
99 if (eq == null)
100 avatar.ControllingClient.SendTeleportLocationStart();
101
102
103 avatar.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags);
104 avatar.Teleport(position);
105 }
106 else
107 {
108 RegionInfo reg = RequestNeighbouringRegionInfo(regionHandle);
109 if (reg != null)
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
117 ///
118 /// Hypergrid mod start
119 ///
120 ///
121 bool isHyperLink = m_hg.IsHyperlinkRegion(reg.RegionHandle);
122 bool isHomeUser = true;
123 ulong realHandle = regionHandle;
124 CachedUserInfo uinfo = m_commsProvider.UserProfileCacheService.GetUserDetails(avatar.UUID);
125 if (uinfo != null)
126 {
127 isHomeUser = HGNetworkServersInfo.Singleton.IsLocalUser(uinfo.UserProfile);
128 realHandle = m_hg.FindRegionHandle(regionHandle);
129 Console.WriteLine("XXX ---- home user? " + isHomeUser + " --- hyperlink? " + isHyperLink + " --- real handle: " + realHandle.ToString());
130 }
131 ///
132 /// Hypergrid mod stop
133 ///
134 ///
135
136 if (eq == null)
137 avatar.ControllingClient.SendTeleportLocationStart();
138
139
140 // Let's do DNS resolution only once in this process, please!
141 // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field,
142 // it's actually doing a lot of work.
143 IPEndPoint endPoint = reg.ExternalEndPoint;
144 if (endPoint.Address == null)
145 {
146 // Couldn't resolve the name. Can't TP, because the viewer wants IP addresses.
147 destRegionUp = false;
148 }
149
150 if (destRegionUp)
151 {
152 // Fixing a bug where teleporting while sitting results in the avatar ending up removed from
153 // both regions
154 if (avatar.ParentID != (uint)0)
155 avatar.StandUp();
156
157 if (!avatar.ValidateAttachments())
158 {
159 avatar.ControllingClient.SendTeleportFailed("Inconsistent attachment state");
160 return;
161 }
162
163 // the avatar.Close below will clear the child region list. We need this below for (possibly)
164 // closing the child agents, so save it here (we need a copy as it is Clear()-ed).
165 //List<ulong> childRegions = new List<ulong>(avatar.GetKnownRegionList());
166 // 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 // once we reach here...
169 //avatar.Scene.RemoveCapsHandler(avatar.UUID);
170
171 string capsPath = String.Empty;
172 AgentCircuitData agentCircuit = avatar.ControllingClient.RequestClientInfo();
173 agentCircuit.BaseFolder = UUID.Zero;
174 agentCircuit.InventoryFolder = UUID.Zero;
175 agentCircuit.startpos = position;
176 agentCircuit.child = true;
177 if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY))
178 {
179 // brand new agent, let's create a new caps seed
180 agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
181 }
182
183 //if (!m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agentCircuit))
184 if (!m_interregionCommsOut.SendCreateChildAgent(reg.RegionHandle, agentCircuit))
185 {
186 avatar.ControllingClient.SendTeleportFailed("Destination is not accepting teleports.");
187 return;
188 }
189
190 // Let's close some agents
191 if (isHyperLink) // close them all except this one
192 {
193 List<ulong> regions = new List<ulong>(avatar.KnownChildRegionHandles);
194 regions.Remove(avatar.Scene.RegionInfo.RegionHandle);
195 SendCloseChildAgentConnections(avatar.UUID, regions);
196 }
197 else // close just a few
198 avatar.CloseChildAgents(newRegionX, newRegionY);
199
200 if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY) || isHyperLink)
201 {
202 capsPath
203 = "http://"
204 + reg.ExternalHostName
205 + ":"
206 + reg.HttpPort
207 + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
208
209 if (eq != null)
210 {
211 eq.EnableSimulator(realHandle, endPoint, avatar.UUID);
212
213 // ES makes the client send a UseCircuitCode message to the destination,
214 // which triggers a bunch of things there.
215 // So let's wait
216 Thread.Sleep(2000);
217
218 eq.EstablishAgentCommunication(avatar.UUID, endPoint, capsPath);
219 }
220 else
221 {
222 avatar.ControllingClient.InformClientOfNeighbour(realHandle, endPoint);
223 // TODO: make Event Queue disablable!
224 }
225 }
226 else
227 {
228 // child agent already there
229 agentCircuit.CapsPath = avatar.Scene.CapsModule.GetChildSeed(avatar.UUID, reg.RegionHandle);
230 capsPath = "http://" + reg.ExternalHostName + ":" + reg.HttpPort
231 + "/CAPS/" + agentCircuit.CapsPath + "0000/";
232 }
233
234 //m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId,
235 // position, false);
236
237 //if (!m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId,
238 // position, false))
239 //{
240 // avatar.ControllingClient.SendTeleportFailed("Problem with destination.");
241 // // We should close that agent we just created over at destination...
242 // List<ulong> lst = new List<ulong>();
243 // lst.Add(realHandle);
244 // SendCloseChildAgentAsync(avatar.UUID, lst);
245 // return;
246 //}
247
248 SetInTransit(avatar.UUID);
249 // Let's send a full update of the agent. This is a synchronous call.
250 AgentData agent = new AgentData();
251 avatar.CopyTo(agent);
252 agent.Position = position;
253 agent.CallbackURI = "http://" + m_regionInfo.ExternalHostName + ":" + m_regionInfo.HttpPort +
254 "/agent/" + avatar.UUID.ToString() + "/" + avatar.Scene.RegionInfo.RegionHandle.ToString() + "/release/";
255
256 m_interregionCommsOut.SendChildAgentUpdate(reg.RegionHandle, agent);
257
258 m_log.DebugFormat(
259 "[CAPS]: Sending new CAPS seed url {0} to client {1}", agentCircuit.CapsPath, avatar.UUID);
260
261
262 ///
263 /// Hypergrid mod: realHandle instead of reg.RegionHandle
264 ///
265 ///
266 if (eq != null)
267 {
268 eq.TeleportFinishEvent(realHandle, 13, endPoint,
269 4, teleportFlags, capsPath, avatar.UUID);
270 }
271 else
272 {
273 avatar.ControllingClient.SendRegionTeleport(realHandle, 13, endPoint, 4,
274 teleportFlags, capsPath);
275 }
276 ///
277 /// Hypergrid mod stop
278 ///
279
280
281 // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which
282 // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation
283 // that the client contacted the destination before we send the attachments and close things here.
284 if (!WaitForCallback(avatar.UUID))
285 {
286 // Client never contacted destination. Let's restore everything back
287 avatar.ControllingClient.SendTeleportFailed("Problems connecting to destination.");
288
289 ResetFromTransit(avatar.UUID);
290 // Yikes! We should just have a ref to scene here.
291 avatar.Scene.InformClientOfNeighbours(avatar);
292
293 // Finally, kill the agent we just created at the destination.
294 m_interregionCommsOut.SendCloseAgent(reg.RegionHandle, avatar.UUID);
295
296 return;
297 }
298
299 // Can't go back from here
300 if (KiPrimitive != null)
301 {
302 KiPrimitive(avatar.LocalId);
303 }
304
305 avatar.MakeChildAgent();
306
307 // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it
308 avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true);
309
310
311 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
312 ///
313 /// Hypergrid mod: extra check for isHyperLink
314 ///
315 if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY) || isHyperLink)
316 {
317 Thread.Sleep(5000);
318 avatar.Close();
319 CloseConnection(avatar.UUID);
320 }
321 // if (teleport success) // seems to be always success here
322 // the user may change their profile information in other region,
323 // so the userinfo in UserProfileCache is not reliable any more, delete it
324 if (avatar.Scene.NeedSceneCacheClear(avatar.UUID) || isHyperLink)
325 {
326 m_commsProvider.UserProfileCacheService.RemoveUser(avatar.UUID);
327 m_log.DebugFormat(
328 "[HGSceneCommService]: User {0} is going to another region, profile cache removed",
329 avatar.UUID);
330 }
331 }
332 else
333 {
334 avatar.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
335 }
336 }
337 else
338 {
339 // TP to a place that doesn't exist (anymore)
340 // Inform the viewer about that
341 avatar.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore");
342
343 // and set the map-tile to '(Offline)'
344 uint regX, regY;
345 Utils.LongToUInts(regionHandle, out regX, out regY);
346
347 MapBlockData block = new MapBlockData();
348 block.X = (ushort)(regX / Constants.RegionSize);
349 block.Y = (ushort)(regY / Constants.RegionSize);
350 block.Access = 254; // == not there
351
352 List<MapBlockData> blocks = new List<MapBlockData>();
353 blocks.Add(block);
354 avatar.ControllingClient.SendMapBlock(blocks, 0);
355 }
356 }
357 }
358
359 }
360}