aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/OpenSim.Region/Scene/World.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/OpenSim.Region/Scene/World.cs')
-rw-r--r--OpenSim/OpenSim.Region/Scene/World.cs711
1 files changed, 711 insertions, 0 deletions
diff --git a/OpenSim/OpenSim.Region/Scene/World.cs b/OpenSim/OpenSim.Region/Scene/World.cs
new file mode 100644
index 0000000..40eb7ef
--- /dev/null
+++ b/OpenSim/OpenSim.Region/Scene/World.cs
@@ -0,0 +1,711 @@
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.Region.Estate;
46
47
48namespace OpenSim.Region
49{
50 public delegate bool FilterAvatarList(Avatar avatar);
51
52 public partial class World : WorldBase, ILocalStorageReceiver, IScriptAPI
53 {
54 protected System.Timers.Timer m_heartbeatTimer = new System.Timers.Timer();
55 protected Dictionary<libsecondlife.LLUUID, Avatar> Avatars;
56 protected Dictionary<libsecondlife.LLUUID, Primitive> Prims;
57 private PhysicsScene phyScene;
58 private float timeStep = 0.1f;
59 public ILocalStorage localStorage;
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 public string m_datastore;
67 protected AuthenticateSessionsBase authenticateHandler;
68 protected RegionCommsHostBase regionCommsHost;
69 protected RegionServerCommsManager commsManager;
70
71 public ParcelManager parcelManager;
72 public EstateManager estateManager;
73
74 #region Properties
75 /// <summary>
76 ///
77 /// </summary>
78 public PhysicsScene PhysScene
79 {
80 set
81 {
82 this.phyScene = value;
83 }
84 get
85 {
86 return (this.phyScene);
87 }
88 }
89
90 #endregion
91
92 #region Constructors
93 /// <summary>
94 /// Creates a new World class, and a region to go with it.
95 /// </summary>
96 /// <param name="clientThreads">Dictionary to contain client threads</param>
97 /// <param name="regionHandle">Region Handle for this region</param>
98 /// <param name="regionName">Region Name for this region</param>
99 public World(Dictionary<uint, IClientAPI> clientThreads, RegionInfo regInfo, AuthenticateSessionsBase authen, RegionServerCommsManager commsMan)
100 {
101 try
102 {
103 updateLock = new Mutex(false);
104 this.authenticateHandler = authen;
105 this.commsManager = commsMan;
106 m_clientThreads = clientThreads;
107 m_regInfo = regInfo;
108 m_regionHandle = m_regInfo.RegionHandle;
109 m_regionName = m_regInfo.RegionName;
110 this.m_datastore = m_regInfo.DataStore;
111 this.RegisterRegionWithComms();
112
113 parcelManager = new ParcelManager(this, this.m_regInfo);
114 estateManager = new EstateManager(this, this.m_regInfo);
115
116 m_scriptHandlers = new Dictionary<LLUUID, ScriptHandler>();
117 m_scripts = new Dictionary<string, ScriptFactory>();
118
119 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs - creating new entitities instance");
120 Entities = new Dictionary<libsecondlife.LLUUID, Entity>();
121 Avatars = new Dictionary<LLUUID, Avatar>();
122 Prims = new Dictionary<LLUUID, Primitive>();
123
124 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs - creating LandMap");
125 TerrainManager = new TerrainManager(new SecondLife());
126 Terrain = new TerrainEngine();
127 Avatar.SetupTemplate("avatar-texture.dat");
128
129 Avatar.LoadAnims();
130
131 //this.SetDefaultScripts();
132 //this.LoadScriptEngines();
133
134
135 }
136 catch (Exception e)
137 {
138 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.CRITICAL, "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].addForces();
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 foreach (ScriptHandler scriptHandler in m_scriptHandlers.Values)
197 {
198 scriptHandler.OnFrame();
199 }
200 foreach (IScriptEngine scripteng in this.scriptEngines.Values)
201 {
202 scripteng.OnFrame();
203 }
204 //backup world data
205 this.storageCount++;
206 if (storageCount > 1200) //set to how often you want to backup
207 {
208 this.Backup();
209 storageCount = 0;
210 }
211 }
212 catch (Exception e)
213 {
214 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: Update() - Failed with exception " + e.ToString());
215 }
216 updateLock.ReleaseMutex();
217 }
218
219 /// <summary>
220 ///
221 /// </summary>
222 /// <returns></returns>
223 public bool Backup()
224 {
225 try
226 {
227 // Terrain backup routines
228 if (Terrain.tainted > 0)
229 {
230 Terrain.tainted = 0;
231 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs: Backup() - Terrain tainted, saving.");
232 localStorage.SaveMap(Terrain.getHeights1D());
233 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs: Backup() - Terrain saved, informing Physics.");
234 lock (this.m_syncRoot)
235 {
236 phyScene.SetTerrain(Terrain.getHeights1D());
237 }
238 }
239
240 // Primitive backup routines
241 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs: Backup() - Backing up Primitives");
242 foreach (libsecondlife.LLUUID UUID in Entities.Keys)
243 {
244 Entities[UUID].BackUp();
245 }
246
247 //Parcel backup routines
248 ParcelData[] parcels = new ParcelData[parcelManager.parcelList.Count];
249 int i = 0;
250 foreach (OpenSim.Region.Parcel parcel in parcelManager.parcelList.Values)
251 {
252 parcels[i] = parcel.parcelData;
253 i++;
254 }
255 localStorage.SaveParcels(parcels);
256
257 // Backup successful
258 return true;
259 }
260 catch (Exception e)
261 {
262 // Backup failed
263 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.HIGH, "World.cs: Backup() - Backup Failed with exception " + e.ToString());
264 return false;
265 }
266 }
267 #endregion
268
269 #region Setup Methods
270 /// <summary>
271 /// Loads a new storage subsystem from a named library
272 /// </summary>
273 /// <param name="dllName">Storage Library</param>
274 /// <returns>Successful or not</returns>
275 public bool LoadStorageDLL(string dllName)
276 {
277 try
278 {
279 Assembly pluginAssembly = Assembly.LoadFrom(dllName);
280 ILocalStorage store = null;
281
282 foreach (Type pluginType in pluginAssembly.GetTypes())
283 {
284 if (pluginType.IsPublic)
285 {
286 if (!pluginType.IsAbstract)
287 {
288 Type typeInterface = pluginType.GetInterface("ILocalStorage", true);
289
290 if (typeInterface != null)
291 {
292 ILocalStorage plug = (ILocalStorage)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
293 store = plug;
294
295 store.Initialise(this.m_datastore);
296 break;
297 }
298
299 typeInterface = null;
300 }
301 }
302 }
303 pluginAssembly = null;
304 this.localStorage = store;
305 return (store == null);
306 }
307 catch (Exception e)
308 {
309 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: LoadStorageDLL() - Failed with exception " + e.ToString());
310 return false;
311 }
312 }
313
314 #endregion
315
316
317 #region Regenerate Terrain
318
319 /// <summary>
320 /// Rebuilds the terrain using a procedural algorithm
321 /// </summary>
322 public void RegenerateTerrain()
323 {
324 try
325 {
326 Terrain.hills();
327
328 lock (this.m_syncRoot)
329 {
330 this.phyScene.SetTerrain(Terrain.getHeights1D());
331 }
332 this.localStorage.SaveMap(this.Terrain.getHeights1D());
333
334 foreach (IClientAPI client in m_clientThreads.Values)
335 {
336 this.SendLayerData(client);
337 }
338
339 foreach (libsecondlife.LLUUID UUID in Entities.Keys)
340 {
341 Entities[UUID].LandRenegerated();
342 }
343 }
344 catch (Exception e)
345 {
346 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: RegenerateTerrain() - Failed with exception " + e.ToString());
347 }
348 }
349
350 /// <summary>
351 /// Rebuilds the terrain using a 2D float array
352 /// </summary>
353 /// <param name="newMap">256,256 float array containing heights</param>
354 public void RegenerateTerrain(float[,] newMap)
355 {
356 try
357 {
358 this.Terrain.setHeights2D(newMap);
359 lock (this.m_syncRoot)
360 {
361 this.phyScene.SetTerrain(this.Terrain.getHeights1D());
362 }
363 this.localStorage.SaveMap(this.Terrain.getHeights1D());
364
365 foreach (IClientAPI client in m_clientThreads.Values)
366 {
367 this.SendLayerData(client);
368 }
369
370 foreach (libsecondlife.LLUUID UUID in Entities.Keys)
371 {
372 Entities[UUID].LandRenegerated();
373 }
374 }
375 catch (Exception e)
376 {
377 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: RegenerateTerrain() - Failed with exception " + e.ToString());
378 }
379 }
380
381 /// <summary>
382 /// Rebuilds the terrain assuming changes occured at a specified point[?]
383 /// </summary>
384 /// <param name="changes">???</param>
385 /// <param name="pointx">???</param>
386 /// <param name="pointy">???</param>
387 public void RegenerateTerrain(bool changes, int pointx, int pointy)
388 {
389 try
390 {
391 if (changes)
392 {
393 /* Dont save here, rely on tainting system instead */
394
395 foreach (IClientAPI client in m_clientThreads.Values)
396 {
397 this.SendLayerData(pointx, pointy, client);
398 }
399 }
400 }
401 catch (Exception e)
402 {
403 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: RegenerateTerrain() - Failed with exception " + e.ToString());
404 }
405 }
406
407 #endregion
408
409 #region Load Terrain
410 /// <summary>
411 /// Loads the World heightmap
412 /// </summary>
413 public override void LoadWorldMap()
414 {
415 try
416 {
417 float[] map = this.localStorage.LoadWorld();
418 if (map == null)
419 {
420 Console.WriteLine("creating new terrain");
421 this.Terrain.hills();
422
423 this.localStorage.SaveMap(this.Terrain.getHeights1D());
424 }
425 else
426 {
427 this.Terrain.setHeights1D(map);
428 }
429 }
430 catch (Exception e)
431 {
432 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: LoadWorldMap() - Failed with exception " + e.ToString());
433 }
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.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs: LoadPrimsFromStorage() - Loading primitives");
448 this.localStorage.LoadPrimitives(this);
449 }
450 catch (Exception e)
451 {
452 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "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 // MainConsole.Instance.Notice("World.cs: AddNewPrim() - Creating new prim");
485 Primitive prim = new Primitive(m_regionHandle, this, addPacket, ownerID, this._primCount);
486
487 this.Entities.Add(prim.uuid, prim);
488 this._primCount++;
489 }
490 catch (Exception e)
491 {
492 // MainConsole.Instance.Warn("World.cs: AddNewPrim() - Failed with exception " + e.ToString());
493 }
494 }
495
496 #endregion
497
498 #region Add/Remove Avatar Methods
499
500 /// <summary>
501 ///
502 /// </summary>
503 /// <param name="remoteClient"></param
504 /// <param name="agentID"></param>
505 /// <param name="child"></param>
506 public override void AddNewAvatar(IClientAPI remoteClient, LLUUID agentID, bool child)
507 {
508 remoteClient.OnRegionHandShakeReply += new GenericCall(this.SendLayerData);
509 //remoteClient.OnRequestWearables += new GenericCall(this.GetInitialPrims);
510 remoteClient.OnChatFromViewer += new ChatFromViewer(this.SimChat);
511 remoteClient.OnRequestWearables += new GenericCall(this.InformClientOfNeighbours);
512 remoteClient.OnAddPrim += new GenericCall4(this.AddNewPrim);
513 remoteClient.OnUpdatePrimPosition += new UpdatePrimVector(this.UpdatePrimPosition);
514
515 /* remoteClient.OnParcelPropertiesRequest += new ParcelPropertiesRequest(parcelManager.handleParcelPropertiesRequest);
516 remoteClient.OnParcelDivideRequest += new ParcelDivideRequest(parcelManager.handleParcelDivideRequest);
517 remoteClient.OnParcelJoinRequest += new ParcelJoinRequest(parcelManager.handleParcelJoinRequest);
518 remoteClient.OnParcelPropertiesUpdateRequest += new ParcelPropertiesUpdateRequest(parcelManager.handleParcelPropertiesUpdateRequest);
519 remoteClient.OnEstateOwnerMessage += new EstateOwnerMessageRequest(estateManager.handleEstateOwnerMessage);
520 */
521
522 Avatar newAvatar = null;
523 try
524 {
525 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs:AddViewerAgent() - Creating new avatar for remote viewer agent");
526 newAvatar = new Avatar(remoteClient, this, m_clientThreads, this.m_regInfo);
527 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs:AddViewerAgent() - Adding new avatar to world");
528 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs:AddViewerAgent() - Starting RegionHandshake ");
529
530 //newAvatar.SendRegionHandshake();
531 this.estateManager.sendRegionHandshake(remoteClient);
532
533 PhysicsVector pVec = new PhysicsVector(newAvatar.Pos.X, newAvatar.Pos.Y, newAvatar.Pos.Z);
534 lock (this.m_syncRoot)
535 {
536 newAvatar.PhysActor = this.phyScene.AddAvatar(pVec);
537 }
538
539 lock (Entities)
540 {
541 if (!Entities.ContainsKey(agentID))
542 {
543 this.Entities.Add(agentID, newAvatar);
544 }
545 else
546 {
547 Entities[agentID] = newAvatar;
548 }
549 }
550 lock (Avatars)
551 {
552 if (Avatars.ContainsKey(agentID))
553 {
554 Avatars[agentID] = newAvatar;
555 }
556 else
557 {
558 this.Avatars.Add(agentID, newAvatar);
559 }
560 }
561 }
562 catch (Exception e)
563 {
564 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: AddViewerAgent() - Failed with exception " + e.ToString());
565 }
566 return;
567 }
568
569 /// <summary>
570 ///
571 /// </summary>
572 protected void InformClientOfNeighbours(IClientAPI remoteClient)
573 {
574 // Console.WriteLine("informing client of neighbouring regions");
575 List<RegionInfo> neighbours = this.commsManager.GridServer.RequestNeighbours(this.m_regInfo);
576
577 //Console.WriteLine("we have " + neighbours.Count + " neighbouring regions");
578 if (neighbours != null)
579 {
580 for (int i = 0; i < neighbours.Count; i++)
581 {
582 // Console.WriteLine("sending neighbours data");
583 AgentCircuitData agent = remoteClient.RequestClientInfo();
584 agent.BaseFolder = LLUUID.Zero;
585 agent.InventoryFolder = LLUUID.Zero;
586 agent.startpos = new LLVector3(128, 128, 70);
587 this.commsManager.InterSims.InformNeighbourOfChildAgent(neighbours[i].RegionHandle, agent);
588 remoteClient.InformClientOfNeighbour(neighbours[i].RegionHandle, System.Net.IPAddress.Parse(neighbours[i].IPListenAddr), (ushort)neighbours[i].IPListenPort);
589 }
590 }
591 }
592
593 /// <summary>
594 ///
595 /// </summary>
596 /// <param name="agentID"></param>
597 public override void RemoveAvatar(LLUUID agentID)
598 {
599 return;
600 }
601 #endregion
602
603 #region Request Avatars List Methods
604 //The idea is to have a group of method that return a list of avatars meeting some requirement
605 // ie it could be all Avatars within a certain range of the calling prim/avatar.
606
607 /// <summary>
608 /// Request a List of all Avatars in this World
609 /// </summary>
610 /// <returns></returns>
611 public List<Avatar> RequestAvatarList()
612 {
613 List<Avatar> result = new List<Avatar>();
614
615 foreach (Avatar avatar in Avatars.Values)
616 {
617 result.Add(avatar);
618 }
619
620 return result;
621 }
622
623 /// <summary>
624 /// Request a filtered list of Avatars in this World
625 /// </summary>
626 /// <returns></returns>
627 public List<Avatar> RequestAvatarList(FilterAvatarList filter)
628 {
629 List<Avatar> result = new List<Avatar>();
630
631 foreach (Avatar avatar in Avatars.Values)
632 {
633 if (filter(avatar))
634 {
635 result.Add(avatar);
636 }
637 }
638
639 return result;
640 }
641
642 public Avatar RequestAvatar(LLUUID avatarID)
643 {
644 if (this.Avatars.ContainsKey(avatarID))
645 {
646 return Avatars[avatarID];
647 }
648 return null;
649 }
650 #endregion
651
652 #region ShutDown
653 /// <summary>
654 /// Tidy before shutdown
655 /// </summary>
656 public override void Close()
657 {
658 try
659 {
660 this.localStorage.ShutDown();
661 }
662 catch (Exception e)
663 {
664 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.HIGH, "World.cs: Close() - Failed with exception " + e.ToString());
665 }
666 }
667 #endregion
668
669 #region RegionCommsHost
670
671 /// <summary>
672 ///
673 /// </summary>
674 public void RegisterRegionWithComms()
675 {
676 this.regionCommsHost = this.commsManager.GridServer.RegisterRegion(this.m_regInfo);
677 if (this.regionCommsHost != null)
678 {
679 this.regionCommsHost.OnExpectUser += new ExpectUserDelegate(this.NewUserConnection);
680 }
681 }
682
683 /// <summary>
684 ///
685 /// </summary>
686 /// <param name="regionHandle"></param>
687 /// <param name="agent"></param>
688 public void NewUserConnection(ulong regionHandle, AgentCircuitData agent)
689 {
690 // Console.WriteLine("World.cs - add new user connection");
691 //should just check that its meant for this region
692 if (regionHandle == this.m_regInfo.RegionHandle)
693 {
694 this.authenticateHandler.AddNewCircuit(agent.circuitcode, agent);
695 }
696 }
697
698 #endregion
699
700 /// <summary>
701 ///
702 /// </summary>
703 /// <param name="px"></param>
704 /// <param name="py"></param>
705 /// <param name="RemoteClient"></param>
706 public override void SendLayerData(int px, int py, IClientAPI RemoteClient)
707 {
708 RemoteClient.SendLayerData( Terrain.getHeights1D() );
709 }
710 }
711}