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