aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Scenes/Scene.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Environment/Scenes/Scene.cs')
-rw-r--r--OpenSim/Region/Environment/Scenes/Scene.cs784
1 files changed, 784 insertions, 0 deletions
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs
new file mode 100644
index 0000000..8c912d0
--- /dev/null
+++ b/OpenSim/Region/Environment/Scenes/Scene.cs
@@ -0,0 +1,784 @@
1/*
2* Copyright (c) Contributors, http://www.openmetaverse.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28using System;
29using libsecondlife;
30using libsecondlife.Packets;
31using System.Collections.Generic;
32using System.Text;
33using System.Reflection;
34using System.IO;
35using System.Threading;
36using System.Timers;
37using OpenSim.Physics.Manager;
38using OpenSim.Framework.Interfaces;
39using OpenSim.Framework.Types;
40using OpenSim.Framework.Inventory;
41using OpenSim.Framework;
42using OpenSim.Region.Terrain;
43using OpenSim.Framework.Communications;
44using OpenSim.Region.Caches;
45using OpenSim.Region.Environment;
46using OpenSim.Framework.Servers;
47using OpenSim.Region.Enviorment.Scripting;
48using OpenSim.Region.Capabilities;
49using Caps = OpenSim.Region.Capabilities.Caps;
50
51namespace OpenSim.Region.Environment.Scenes
52{
53 public delegate bool FilterAvatarList(ScenePresence avatar);
54
55 public partial class Scene : SceneBase, ILocalStorageReceiver
56 {
57 protected System.Timers.Timer m_heartbeatTimer = new System.Timers.Timer();
58 protected Dictionary<libsecondlife.LLUUID, ScenePresence> Avatars;
59 protected Dictionary<libsecondlife.LLUUID, Primitive> Prims;
60 private PhysicsScene phyScene;
61 private float timeStep = 0.1f;
62 private Random Rand = new Random();
63 private uint _primCount = 702000;
64 private int storageCount;
65 private Mutex updateLock;
66
67 protected AuthenticateSessionsBase authenticateHandler;
68 protected RegionCommsListener regionCommsHost;
69 protected CommunicationsManager commsManager;
70
71 protected Dictionary<LLUUID,Caps> capsHandlers = new Dictionary<LLUUID, Caps>();
72 protected BaseHttpServer httpListener;
73
74 public ParcelManager parcelManager;
75 public EstateManager estateManager;
76 public EventManager eventManager;
77 public ScriptManager scriptManager;
78
79 #region Properties
80 /// <summary>
81 ///
82 /// </summary>
83 public PhysicsScene PhysScene
84 {
85 set
86 {
87 this.phyScene = value;
88 }
89 get
90 {
91 return (this.phyScene);
92 }
93 }
94
95 #endregion
96
97 #region Constructors
98 /// <summary>
99 /// Creates a new World class, and a region to go with it.
100 /// </summary>
101 /// <param name="clientThreads">Dictionary to contain client threads</param>
102 /// <param name="regionHandle">Region Handle for this region</param>
103 /// <param name="regionName">Region Name for this region</param>
104 public Scene(Dictionary<uint, IClientAPI> clientThreads, RegionInfo regInfo, AuthenticateSessionsBase authen, CommunicationsManager commsMan, AssetCache assetCach, BaseHttpServer httpServer)
105 {
106 try
107 {
108 updateLock = new Mutex(false);
109 this.authenticateHandler = authen;
110 this.commsManager = commsMan;
111 this.assetCache = assetCach;
112 m_clientThreads = clientThreads;
113 m_regInfo = regInfo;
114 m_regionHandle = m_regInfo.RegionHandle;
115 m_regionName = m_regInfo.RegionName;
116 this.m_datastore = m_regInfo.DataStore;
117 this.RegisterRegionWithComms();
118
119 parcelManager = new ParcelManager(this, this.m_regInfo);
120 estateManager = new EstateManager(this, this.m_regInfo);
121 scriptManager = new ScriptManager(this);
122 eventManager = new EventManager();
123
124 OpenSim.Framework.Console.MainLog.Instance.Verbose( "World.cs - creating new entitities instance");
125 Entities = new Dictionary<libsecondlife.LLUUID, Entity>();
126 Avatars = new Dictionary<LLUUID, ScenePresence>();
127 Prims = new Dictionary<LLUUID, Primitive>();
128
129 OpenSim.Framework.Console.MainLog.Instance.Verbose( "World.cs - creating LandMap");
130 Terrain = new TerrainEngine();
131
132 ScenePresence.LoadAnims();
133 this.httpListener = httpServer;
134
135 }
136 catch (Exception e)
137 {
138 OpenSim.Framework.Console.MainLog.Instance.Error( "World.cs: Constructor failed with exception " + e.ToString());
139 }
140 }
141 #endregion
142
143 /// <summary>
144 ///
145 /// </summary>
146 public void StartTimer()
147 {
148 m_heartbeatTimer.Enabled = true;
149 m_heartbeatTimer.Interval = 100;
150 m_heartbeatTimer.Elapsed += new ElapsedEventHandler(this.Heartbeat);
151 }
152
153
154 #region Update Methods
155
156
157 /// <summary>
158 /// Performs per-frame updates regularly
159 /// </summary>
160 /// <param name="sender"></param>
161 /// <param name="e"></param>
162 void Heartbeat(object sender, System.EventArgs e)
163 {
164 this.Update();
165 }
166
167 /// <summary>
168 /// Performs per-frame updates on the world, this should be the central world loop
169 /// </summary>
170 public override void Update()
171 {
172 updateLock.WaitOne();
173 try
174 {
175 if (this.phyScene.IsThreaded)
176 {
177 this.phyScene.GetResults();
178
179 }
180
181 foreach (libsecondlife.LLUUID UUID in Entities.Keys)
182 {
183 Entities[UUID].updateMovement();
184 }
185
186 lock (this.m_syncRoot)
187 {
188 this.phyScene.Simulate(timeStep);
189 }
190
191 foreach (libsecondlife.LLUUID UUID in Entities.Keys)
192 {
193 Entities[UUID].update();
194 }
195
196 // General purpose event manager
197 eventManager.TriggerOnFrame();
198
199 //backup world data
200 this.storageCount++;
201 if (storageCount > 1200) //set to how often you want to backup
202 {
203 this.Backup();
204 storageCount = 0;
205 }
206 }
207 catch (Exception e)
208 {
209 OpenSim.Framework.Console.MainLog.Instance.Warn("World.cs: Update() - Failed with exception " + e.ToString());
210 }
211 updateLock.ReleaseMutex();
212
213 }
214
215 /// <summary>
216 ///
217 /// </summary>
218 /// <returns></returns>
219 public bool Backup()
220 {
221 /*
222 try
223 {
224 // Terrain backup routines
225 if (Terrain.tainted > 0)
226 {
227 Terrain.tainted = 0;
228 OpenSim.Framework.Console.MainLog.Instance.Verbose( "World.cs: Backup() - Terrain tainted, saving.");
229 localStorage.SaveMap(Terrain.getHeights1D());
230 OpenSim.Framework.Console.MainLog.Instance.Verbose( "World.cs: Backup() - Terrain saved, informing Physics.");
231 lock (this.m_syncRoot)
232 {
233 phyScene.SetTerrain(Terrain.getHeights1D());
234 }
235 }
236
237 // Primitive backup routines
238 OpenSim.Framework.Console.MainLog.Instance.Verbose( "World.cs: Backup() - Backing up Primitives");
239 foreach (libsecondlife.LLUUID UUID in Entities.Keys)
240 {
241 Entities[UUID].BackUp();
242 }
243
244 //Parcel backup routines
245 ParcelData[] parcels = new ParcelData[parcelManager.parcelList.Count];
246 int i = 0;
247 foreach (OpenSim.Region.Parcel parcel in parcelManager.parcelList.Values)
248 {
249 parcels[i] = parcel.parcelData;
250 i++;
251 }
252 localStorage.SaveParcels(parcels);
253
254 // Backup successful
255 return true;
256 }
257 catch (Exception e)
258 {
259 // Backup failed
260 OpenSim.Framework.Console.MainLog.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.HIGH, "World.cs: Backup() - Backup Failed with exception " + e.ToString());
261 return false;
262 }
263 */
264 return true;
265 }
266 #endregion
267
268 #region Regenerate Terrain
269
270 /// <summary>
271 /// Rebuilds the terrain using a procedural algorithm
272 /// </summary>
273 public void RegenerateTerrain()
274 {
275 try
276 {
277 Terrain.hills();
278
279 lock (this.m_syncRoot)
280 {
281 this.phyScene.SetTerrain(Terrain.getHeights1D());
282 }
283 this.localStorage.SaveMap(this.Terrain.getHeights1D());
284
285 foreach (IClientAPI client in m_clientThreads.Values)
286 {
287 this.SendLayerData(client);
288 }
289
290 foreach (libsecondlife.LLUUID UUID in Entities.Keys)
291 {
292 Entities[UUID].LandRenegerated();
293 }
294 }
295 catch (Exception e)
296 {
297 OpenSim.Framework.Console.MainLog.Instance.Warn("World.cs: RegenerateTerrain() - Failed with exception " + e.ToString());
298 }
299 }
300
301 /// <summary>
302 /// Rebuilds the terrain using a 2D float array
303 /// </summary>
304 /// <param name="newMap">256,256 float array containing heights</param>
305 public void RegenerateTerrain(float[,] newMap)
306 {
307 try
308 {
309 this.Terrain.setHeights2D(newMap);
310 lock (this.m_syncRoot)
311 {
312 this.phyScene.SetTerrain(this.Terrain.getHeights1D());
313 }
314 this.localStorage.SaveMap(this.Terrain.getHeights1D());
315
316 foreach (IClientAPI client in m_clientThreads.Values)
317 {
318 this.SendLayerData(client);
319 }
320
321 foreach (libsecondlife.LLUUID UUID in Entities.Keys)
322 {
323 Entities[UUID].LandRenegerated();
324 }
325 }
326 catch (Exception e)
327 {
328 OpenSim.Framework.Console.MainLog.Instance.Warn("World.cs: RegenerateTerrain() - Failed with exception " + e.ToString());
329 }
330 }
331
332 /// <summary>
333 /// Rebuilds the terrain assuming changes occured at a specified point[?]
334 /// </summary>
335 /// <param name="changes">???</param>
336 /// <param name="pointx">???</param>
337 /// <param name="pointy">???</param>
338 public void RegenerateTerrain(bool changes, int pointx, int pointy)
339 {
340 try
341 {
342 if (changes)
343 {
344 /* Dont save here, rely on tainting system instead */
345
346 foreach (IClientAPI client in m_clientThreads.Values)
347 {
348 this.SendLayerData(pointx, pointy, client);
349 }
350 }
351 }
352 catch (Exception e)
353 {
354 OpenSim.Framework.Console.MainLog.Instance.Warn("World.cs: RegenerateTerrain() - Failed with exception " + e.ToString());
355 }
356 }
357
358 #endregion
359
360 #region Load Terrain
361 /// <summary>
362 /// Loads the World heightmap
363 /// </summary>
364 ///
365 public override void LoadWorldMap()
366 {
367 try
368 {
369 float[] map = this.localStorage.LoadWorld();
370 if (map == null)
371 {
372 if (string.IsNullOrEmpty(this.m_regInfo.estateSettings.terrainFile))
373 {
374 Console.WriteLine("No default terrain, procedurally generating...");
375 this.Terrain.hills();
376
377 this.localStorage.SaveMap(this.Terrain.getHeights1D());
378 }
379 else
380 {
381 try
382 {
383 this.Terrain.loadFromFileF32(this.m_regInfo.estateSettings.terrainFile);
384 this.Terrain *= this.m_regInfo.estateSettings.terrainMultiplier;
385 }
386 catch
387 {
388 Console.WriteLine("Unable to load default terrain, procedurally generating instead...");
389 Terrain.hills();
390 }
391 this.localStorage.SaveMap(this.Terrain.getHeights1D());
392 }
393 }
394 else
395 {
396 this.Terrain.setHeights1D(map);
397 }
398
399 CreateTerrainTexture();
400
401 }
402 catch (Exception e)
403 {
404 OpenSim.Framework.Console.MainLog.Instance.Warn("World.cs: LoadWorldMap() - Failed with exception " + e.ToString());
405 }
406 }
407
408 /// <summary>
409 ///
410 /// </summary>
411 private void CreateTerrainTexture()
412 {
413 //create a texture asset of the terrain
414 byte[] data = this.Terrain.exportJpegImage("defaultstripe.png");
415 this.m_regInfo.estateSettings.terrainImageID = LLUUID.Random();
416 AssetBase asset = new AssetBase();
417 asset.FullID = this.m_regInfo.estateSettings.terrainImageID;
418 asset.Data = data;
419 asset.Name = "terrainImage";
420 asset.Type = 0;
421 this.assetCache.AddAsset(asset);
422 }
423 #endregion
424
425 #region Primitives Methods
426
427
428 /// <summary>
429 /// Loads the World's objects
430 /// </summary>
431 public void LoadPrimsFromStorage()
432 {
433 try
434 {
435 OpenSim.Framework.Console.MainLog.Instance.Verbose( "World.cs: LoadPrimsFromStorage() - Loading primitives");
436 this.localStorage.LoadPrimitives(this);
437 }
438 catch (Exception e)
439 {
440 OpenSim.Framework.Console.MainLog.Instance.Warn("World.cs: LoadPrimsFromStorage() - Failed with exception " + e.ToString());
441 }
442 }
443
444 /// <summary>
445 /// Loads a specific object from storage
446 /// </summary>
447 /// <param name="prim">The object to load</param>
448 public void PrimFromStorage(PrimData prim)
449 {
450
451 }
452
453 /// <summary>
454 ///
455 /// </summary>
456 /// <param name="addPacket"></param>
457 /// <param name="agentClient"></param>
458 public void AddNewPrim(Packet addPacket, IClientAPI agentClient)
459 {
460 AddNewPrim((ObjectAddPacket)addPacket, agentClient.AgentId);
461 }
462
463 /// <summary>
464 ///
465 /// </summary>
466 /// <param name="addPacket"></param>
467 /// <param name="ownerID"></param>
468 public void AddNewPrim(ObjectAddPacket addPacket, LLUUID ownerID)
469 {
470 try
471 {
472 Primitive prim = new Primitive(m_regionHandle, this, addPacket, ownerID, this._primCount);
473
474 this.Entities.Add(prim.uuid, prim);
475 this._primCount++;
476
477 // Trigger event for listeners
478 eventManager.TriggerOnNewPrimitive(prim);
479 }
480 catch (Exception e)
481 {
482 OpenSim.Framework.Console.MainLog.Instance.Warn("World.cs: AddNewPrim() - Failed with exception " + e.ToString());
483 }
484 }
485
486 #endregion
487
488 #region Add/Remove Avatar Methods
489
490 /// <summary>
491 ///
492 /// </summary>
493 /// <param name="remoteClient"></param
494 /// <param name="agentID"></param>
495 /// <param name="child"></param>
496 public override void AddNewClient(IClientAPI remoteClient, LLUUID agentID, bool child)
497 {
498 remoteClient.OnRegionHandShakeReply += this.SendLayerData;
499 //remoteClient.OnRequestWearables += new GenericCall(this.GetInitialPrims);
500 remoteClient.OnChatFromViewer += this.SimChat;
501 remoteClient.OnRequestWearables += this.InformClientOfNeighbours;
502 remoteClient.OnAddPrim += this.AddNewPrim;
503 remoteClient.OnUpdatePrimPosition += this.UpdatePrimPosition;
504 remoteClient.OnRequestMapBlocks += this.RequestMapBlocks;
505 remoteClient.OnTeleportLocationRequest += this.RequestTeleportLocation;
506 //remoteClient.OnObjectSelect += this.SelectPrim;
507 remoteClient.OnGrapUpdate += this.MoveObject;
508 remoteClient.OnNameFromUUIDRequest += this.commsManager.HandleUUIDNameRequest;
509
510 /* remoteClient.OnParcelPropertiesRequest += new ParcelPropertiesRequest(parcelManager.handleParcelPropertiesRequest);
511 remoteClient.OnParcelDivideRequest += new ParcelDivideRequest(parcelManager.handleParcelDivideRequest);
512 remoteClient.OnParcelJoinRequest += new ParcelJoinRequest(parcelManager.handleParcelJoinRequest);
513 remoteClient.OnParcelPropertiesUpdateRequest += new ParcelPropertiesUpdateRequest(parcelManager.handleParcelPropertiesUpdateRequest);
514 remoteClient.OnEstateOwnerMessage += new EstateOwnerMessageRequest(estateManager.handleEstateOwnerMessage);
515 */
516
517 ScenePresence newAvatar = null;
518 try
519 {
520
521 OpenSim.Framework.Console.MainLog.Instance.Verbose( "World.cs:AddViewerAgent() - Creating new avatar for remote viewer agent");
522 newAvatar = new ScenePresence(remoteClient, this, this.m_regInfo);
523 OpenSim.Framework.Console.MainLog.Instance.Verbose( "World.cs:AddViewerAgent() - Adding new avatar to world");
524 OpenSim.Framework.Console.MainLog.Instance.Verbose( "World.cs:AddViewerAgent() - Starting RegionHandshake ");
525
526 //newAvatar.SendRegionHandshake();
527 this.estateManager.sendRegionHandshake(remoteClient);
528
529 PhysicsVector pVec = new PhysicsVector(newAvatar.Pos.X, newAvatar.Pos.Y, newAvatar.Pos.Z);
530 lock (this.m_syncRoot)
531 {
532 newAvatar.PhysActor = this.phyScene.AddAvatar(pVec);
533 }
534
535 lock (Entities)
536 {
537 if (!Entities.ContainsKey(agentID))
538 {
539 this.Entities.Add(agentID, newAvatar);
540 }
541 else
542 {
543 Entities[agentID] = newAvatar;
544 }
545 }
546 lock (Avatars)
547 {
548 if (Avatars.ContainsKey(agentID))
549 {
550 Avatars[agentID] = newAvatar;
551 }
552 else
553 {
554 this.Avatars.Add(agentID, newAvatar);
555 }
556 }
557 }
558 catch (Exception e)
559 {
560 OpenSim.Framework.Console.MainLog.Instance.Warn("World.cs: AddViewerAgent() - Failed with exception " + e.ToString());
561 }
562 return;
563 }
564
565
566
567 /// <summary>
568 ///
569 /// </summary>
570 /// <param name="agentID"></param>
571 public override void RemoveClient(LLUUID agentID)
572 {
573 eventManager.TriggerOnRemovePresence(agentID);
574
575 return;
576 }
577 #endregion
578
579 #region Request Avatars List Methods
580 //The idea is to have a group of method that return a list of avatars meeting some requirement
581 // ie it could be all Avatars within a certain range of the calling prim/avatar.
582
583 /// <summary>
584 /// Request a List of all Avatars in this World
585 /// </summary>
586 /// <returns></returns>
587 public List<ScenePresence> RequestAvatarList()
588 {
589 List<ScenePresence> result = new List<ScenePresence>();
590
591 foreach (ScenePresence avatar in Avatars.Values)
592 {
593 result.Add(avatar);
594 }
595
596 return result;
597 }
598
599 /// <summary>
600 /// Request a filtered list of Avatars in this World
601 /// </summary>
602 /// <returns></returns>
603 public List<ScenePresence> RequestAvatarList(FilterAvatarList filter)
604 {
605 List<ScenePresence> result = new List<ScenePresence>();
606
607 foreach (ScenePresence avatar in Avatars.Values)
608 {
609 if (filter(avatar))
610 {
611 result.Add(avatar);
612 }
613 }
614
615 return result;
616 }
617
618 /// <summary>
619 /// Request a Avatar by UUID
620 /// </summary>
621 /// <param name="avatarID"></param>
622 /// <returns></returns>
623 public ScenePresence RequestAvatar(LLUUID avatarID)
624 {
625 if (this.Avatars.ContainsKey(avatarID))
626 {
627 return Avatars[avatarID];
628 }
629 return null;
630 }
631 #endregion
632
633
634 #region RegionCommsHost
635
636 /// <summary>
637 ///
638 /// </summary>
639 public void RegisterRegionWithComms()
640 {
641 GridInfo gridSettings = new GridInfo();
642 this.regionCommsHost = this.commsManager.GridServer.RegisterRegion(this.m_regInfo,gridSettings);
643 if (this.regionCommsHost != null)
644 {
645 this.regionCommsHost.OnExpectUser += new ExpectUserDelegate(this.NewUserConnection);
646 this.regionCommsHost.OnAvatarCrossingIntoRegion += new AgentCrossing(this.AgentCrossing);
647 }
648 }
649
650 /// <summary>
651 ///
652 /// </summary>
653 /// <param name="regionHandle"></param>
654 /// <param name="agent"></param>
655 public void NewUserConnection(ulong regionHandle, AgentCircuitData agent)
656 {
657 // Console.WriteLine("World.cs - add new user connection");
658 //should just check that its meant for this region
659 if (regionHandle == this.m_regInfo.RegionHandle)
660 {
661 if (agent.CapsPath != "")
662 {
663 //Console.WriteLine("new user, so creating caps handler for it");
664 Caps cap = new Caps(this.assetCache, httpListener, this.m_regInfo.CommsIPListenAddr, 9000, agent.CapsPath, agent.AgentID);
665 cap.RegisterHandlers();
666 this.capsHandlers.Add(agent.AgentID, cap);
667 }
668 this.authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
669 }
670 }
671
672 public void AgentCrossing(ulong regionHandle, libsecondlife.LLUUID agentID, libsecondlife.LLVector3 position)
673 {
674 if (regionHandle == this.m_regInfo.RegionHandle)
675 {
676 if (this.Avatars.ContainsKey(agentID))
677 {
678 this.Avatars[agentID].MakeAvatar(position);
679 }
680 }
681 }
682
683 /// <summary>
684 ///
685 /// </summary>
686 public void InformClientOfNeighbours(IClientAPI remoteClient)
687 {
688 // Console.WriteLine("informing client of neighbouring regions");
689 List<RegionInfo> neighbours = this.commsManager.GridServer.RequestNeighbours(this.m_regInfo);
690
691 //Console.WriteLine("we have " + neighbours.Count + " neighbouring regions");
692 if (neighbours != null)
693 {
694 for (int i = 0; i < neighbours.Count; i++)
695 {
696 // Console.WriteLine("sending neighbours data");
697 AgentCircuitData agent = remoteClient.RequestClientInfo();
698 agent.BaseFolder = LLUUID.Zero;
699 agent.InventoryFolder = LLUUID.Zero;
700 agent.startpos = new LLVector3(128, 128, 70);
701 agent.child = true;
702 this.commsManager.InterRegion.InformRegionOfChildAgent(neighbours[i].RegionHandle, agent);
703 remoteClient.InformClientOfNeighbour(neighbours[i].RegionHandle, System.Net.IPAddress.Parse(neighbours[i].CommsIPListenAddr), (ushort)neighbours[i].CommsIPListenPort);
704 //this.capsHandlers[remoteClient.AgentId].CreateEstablishAgentComms("", System.Net.IPAddress.Parse(neighbours[i].CommsIPListenAddr) + ":" + neighbours[i].CommsIPListenPort);
705 }
706 }
707 }
708
709 /// <summary>
710 ///
711 /// </summary>
712 /// <param name="regionHandle"></param>
713 /// <returns></returns>
714 public RegionInfo RequestNeighbouringRegionInfo(ulong regionHandle)
715 {
716 return this.commsManager.GridServer.RequestNeighbourInfo(regionHandle);
717 }
718
719 /// <summary>
720 ///
721 /// </summary>
722 /// <param name="minX"></param>
723 /// <param name="minY"></param>
724 /// <param name="maxX"></param>
725 /// <param name="maxY"></param>
726 public void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY)
727 {
728 List<MapBlockData> mapBlocks;
729 mapBlocks = this.commsManager.GridServer.RequestNeighbourMapBlocks(minX, minY, maxX, maxY);
730 remoteClient.SendMapBlock(mapBlocks);
731 }
732
733 /// <summary>
734 ///
735 /// </summary>
736 /// <param name="remoteClient"></param>
737 /// <param name="RegionHandle"></param>
738 /// <param name="position"></param>
739 /// <param name="lookAt"></param>
740 /// <param name="flags"></param>
741 public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, LLVector3 position, LLVector3 lookAt, uint flags)
742 {
743 if (regionHandle == this.m_regionHandle)
744 {
745 if (this.Avatars.ContainsKey(remoteClient.AgentId))
746 {
747 remoteClient.SendTeleportLocationStart();
748 remoteClient.SendLocalTeleport(position, lookAt, flags);
749 this.Avatars[remoteClient.AgentId].Teleport(position);
750 }
751 }
752 else
753 {
754 RegionInfo reg = this.RequestNeighbouringRegionInfo(regionHandle);
755 if (reg != null)
756 {
757 remoteClient.SendTeleportLocationStart();
758 AgentCircuitData agent = remoteClient.RequestClientInfo();
759 agent.BaseFolder = LLUUID.Zero;
760 agent.InventoryFolder = LLUUID.Zero;
761 agent.startpos = new LLVector3(128, 128, 70);
762 agent.child = true;
763 this.commsManager.InterRegion.InformRegionOfChildAgent(regionHandle, agent);
764 this.commsManager.InterRegion.ExpectAvatarCrossing(regionHandle, remoteClient.AgentId, position);
765 remoteClient.SendRegionTeleport(regionHandle, 13, reg.CommsIPListenAddr, (ushort)reg.CommsIPListenPort, 4, (1 << 4));
766 }
767 //remoteClient.SendTeleportCancel();
768 }
769 }
770
771 /// <summary>
772 ///
773 /// </summary>
774 /// <param name="regionhandle"></param>
775 /// <param name="agentID"></param>
776 /// <param name="position"></param>
777 public bool InformNeighbourOfCrossing(ulong regionhandle, LLUUID agentID, LLVector3 position)
778 {
779 return this.commsManager.InterRegion.ExpectAvatarCrossing(regionhandle, agentID, position);
780 }
781
782 #endregion
783 }
784}