aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/OpenSim.World/World.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/OpenSim.World/World.cs')
-rw-r--r--OpenSim/OpenSim.World/World.cs579
1 files changed, 579 insertions, 0 deletions
diff --git a/OpenSim/OpenSim.World/World.cs b/OpenSim/OpenSim.World/World.cs
new file mode 100644
index 0000000..d840d10
--- /dev/null
+++ b/OpenSim/OpenSim.World/World.cs
@@ -0,0 +1,579 @@
1using System;
2using libsecondlife;
3using libsecondlife.Packets;
4using System.Collections.Generic;
5using System.Text;
6using System.Reflection;
7using System.IO;
8using System.Threading;
9using OpenSim.Physics.Manager;
10using OpenSim.Framework.Interfaces;
11using OpenSim.Framework.Types;
12using OpenSim.Framework.Terrain;
13using OpenSim.Framework.Inventory;
14using OpenSim.Assets;
15//using OpenSim.world.scripting;
16using OpenSim.RegionServer.world.scripting;
17using OpenSim.Terrain;
18
19namespace OpenSim.world
20{
21 public partial class World : WorldBase, ILocalStorageReceiver, IScriptAPI
22 {
23 public object LockPhysicsEngine = new object();
24 public Dictionary<libsecondlife.LLUUID, Avatar> Avatars;
25 public Dictionary<libsecondlife.LLUUID, Primitive> Prims;
26 //public ScriptEngine Scripts;
27 public uint _localNumber = 0;
28 private PhysicsScene phyScene;
29 private float timeStep = 0.1f;
30 public ILocalStorage localStorage;
31 private Random Rand = new Random();
32 private uint _primCount = 702000;
33 private int storageCount;
34 private Dictionary<LLUUID, ScriptHandler> m_scriptHandlers;
35 private Dictionary<string, ScriptFactory> m_scripts;
36 private Mutex updateLock;
37 public string m_datastore;
38
39 #region Properties
40 public PhysicsScene PhysScene
41 {
42 set
43 {
44 this.phyScene = value;
45 }
46 get
47 {
48 return (this.phyScene);
49 }
50 }
51 #endregion
52
53 #region Constructors
54 /// <summary>
55 /// Creates a new World class, and a region to go with it.
56 /// </summary>
57 /// <param name="clientThreads">Dictionary to contain client threads</param>
58 /// <param name="regionHandle">Region Handle for this region</param>
59 /// <param name="regionName">Region Name for this region</param>
60 public World(Dictionary<uint, IClientAPI> clientThreads, RegionInfo regInfo, ulong regionHandle, string regionName)
61 {
62 try
63 {
64 updateLock = new Mutex(false);
65 m_clientThreads = clientThreads;
66 m_regionHandle = regionHandle;
67 m_regionName = regionName;
68 m_regInfo = regInfo;
69
70 m_scriptHandlers = new Dictionary<LLUUID, ScriptHandler>();
71 m_scripts = new Dictionary<string, ScriptFactory>();
72
73 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs - creating new entitities instance");
74 Entities = new Dictionary<libsecondlife.LLUUID, Entity>();
75 Avatars = new Dictionary<LLUUID, Avatar>();
76 Prims = new Dictionary<LLUUID, Primitive>();
77
78 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs - creating LandMap");
79 TerrainManager = new TerrainManager(new SecondLife());
80 Terrain = new TerrainEngine();
81 Avatar.SetupTemplate("avatar-texture.dat");
82 // MainConsole.Instance.WriteLine("World.cs - Creating script engine instance");
83 // Initialise this only after the world has loaded
84 // Scripts = new ScriptEngine(this);
85 Avatar.LoadAnims();
86 this.SetDefaultScripts();
87 this.LoadScriptEngines();
88 }
89 catch (Exception e)
90 {
91 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.CRITICAL, "World.cs: Constructor failed with exception " + e.ToString());
92 }
93 }
94 #endregion
95
96 #region Script Methods
97 /// <summary>
98 /// Loads a new script into the specified entity
99 /// </summary>
100 /// <param name="entity">Entity to be scripted</param>
101 /// <param name="script">The script to load</param>
102 public void AddScript(Entity entity, Script script)
103 {
104 try
105 {
106 ScriptHandler scriptHandler = new ScriptHandler(script, entity, this);
107 m_scriptHandlers.Add(scriptHandler.ScriptId, scriptHandler);
108 }
109 catch (Exception e)
110 {
111 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: AddScript() - Failed with exception " + e.ToString());
112 }
113 }
114
115 /// <summary>
116 /// Loads a new script into the specified entity, using a script loaded from a string.
117 /// </summary>
118 /// <param name="entity">The entity to be scripted</param>
119 /// <param name="scriptData">The string containing the script</param>
120 public void AddScript(Entity entity, string scriptData)
121 {
122 try
123 {
124 int scriptstart = 0;
125 int scriptend = 0;
126 string substring;
127 scriptstart = scriptData.LastIndexOf("<Script>");
128 scriptend = scriptData.LastIndexOf("</Script>");
129 substring = scriptData.Substring(scriptstart + 8, scriptend - scriptstart - 8);
130 substring = substring.Trim();
131 //Console.WriteLine("searching for script to add: " + substring);
132
133 ScriptFactory scriptFactory;
134 //Console.WriteLine("script string is " + substring);
135 if (substring.StartsWith("<ScriptEngine:"))
136 {
137 string substring1 = "";
138 string script = "";
139 // Console.WriteLine("searching for script engine");
140 substring1 = substring.Remove(0, 14);
141 int dev = substring1.IndexOf(',');
142 string sEngine = substring1.Substring(0, dev);
143 substring1 = substring1.Remove(0, dev + 1);
144 int end = substring1.IndexOf('>');
145 string sName = substring1.Substring(0, end);
146 //Console.WriteLine(" script info : " + sEngine + " , " + sName);
147 int startscript = substring.IndexOf('>');
148 script = substring.Remove(0, startscript + 1);
149 // Console.WriteLine("script data is " + script);
150 if (this.scriptEngines.ContainsKey(sEngine))
151 {
152 this.scriptEngines[sEngine].LoadScript(script, sName, entity.localid);
153 }
154 }
155 else if (this.m_scripts.TryGetValue(substring, out scriptFactory))
156 {
157 //Console.WriteLine("added script");
158 this.AddScript(entity, scriptFactory());
159 }
160 }
161 catch (Exception e)
162 {
163 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: AddScript() - Failed with exception " + e.ToString());
164 }
165 }
166
167 #endregion
168
169 #region Update Methods
170 /// <summary>
171 /// Performs per-frame updates on the world, this should be the central world loop
172 /// </summary>
173 public override void Update()
174 {
175 updateLock.WaitOne();
176 try
177 {
178 if (this.phyScene.IsThreaded)
179 {
180 this.phyScene.GetResults();
181
182 }
183
184 foreach (libsecondlife.LLUUID UUID in Entities.Keys)
185 {
186 Entities[UUID].addForces();
187 }
188
189 lock (this.LockPhysicsEngine)
190 {
191 this.phyScene.Simulate(timeStep);
192 }
193
194 foreach (libsecondlife.LLUUID UUID in Entities.Keys)
195 {
196 Entities[UUID].update();
197 }
198
199 foreach (ScriptHandler scriptHandler in m_scriptHandlers.Values)
200 {
201 scriptHandler.OnFrame();
202 }
203 foreach (IScriptEngine scripteng in this.scriptEngines.Values)
204 {
205 scripteng.OnFrame();
206 }
207 //backup world data
208 this.storageCount++;
209 if (storageCount > 1200) //set to how often you want to backup
210 {
211 this.Backup();
212 storageCount = 0;
213 }
214 }
215 catch (Exception e)
216 {
217 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: Update() - Failed with exception " + e.ToString());
218 }
219 updateLock.ReleaseMutex();
220 }
221
222 public bool Backup()
223 {
224 try
225 {
226 // Terrain backup routines
227 if (Terrain.tainted > 0)
228 {
229 Terrain.tainted = 0;
230 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs: Backup() - Terrain tainted, saving.");
231 localStorage.SaveMap(Terrain.getHeights1D());
232 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs: Backup() - Terrain saved, informing Physics.");
233 lock (this.LockPhysicsEngine)
234 {
235 phyScene.SetTerrain(Terrain.getHeights1D());
236 }
237 }
238
239 // Primitive backup routines
240 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs: Backup() - Backing up Primitives");
241 foreach (libsecondlife.LLUUID UUID in Entities.Keys)
242 {
243 Entities[UUID].BackUp();
244 }
245
246 // Backup successful
247 return true;
248 }
249 catch (Exception e)
250 {
251 // Backup failed
252 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.HIGH, "World.cs: Backup() - Backup Failed with exception " + e.ToString());
253 return false;
254 }
255 }
256 #endregion
257
258 #region Setup Methods
259 /// <summary>
260 /// Loads a new storage subsystem from a named library
261 /// </summary>
262 /// <param name="dllName">Storage Library</param>
263 /// <returns>Successful or not</returns>
264 public bool LoadStorageDLL(string dllName)
265 {
266 try
267 {
268 Assembly pluginAssembly = Assembly.LoadFrom(dllName);
269 ILocalStorage store = null;
270
271 foreach (Type pluginType in pluginAssembly.GetTypes())
272 {
273 if (pluginType.IsPublic)
274 {
275 if (!pluginType.IsAbstract)
276 {
277 Type typeInterface = pluginType.GetInterface("ILocalStorage", true);
278
279 if (typeInterface != null)
280 {
281 ILocalStorage plug = (ILocalStorage)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
282 store = plug;
283
284 store.Initialise(this.m_datastore);
285 break;
286 }
287
288 typeInterface = null;
289 }
290 }
291 }
292 pluginAssembly = null;
293 this.localStorage = store;
294 return (store == null);
295 }
296 catch (Exception e)
297 {
298 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: LoadStorageDLL() - Failed with exception " + e.ToString());
299 return false;
300 }
301 }
302
303 public void SetDefaultScripts()
304 {
305 this.m_scripts.Add("FollowRandomAvatar", delegate()
306 {
307 return new OpenSim.RegionServer.world.scripting.FollowRandomAvatar();
308 });
309 }
310
311 #endregion
312
313 #region Regenerate Terrain
314
315 /// <summary>
316 /// Rebuilds the terrain using a procedural algorithm
317 /// </summary>
318 public void RegenerateTerrain()
319 {
320 try
321 {
322 Terrain.hills();
323
324 lock (this.LockPhysicsEngine)
325 {
326 this.phyScene.SetTerrain(Terrain.getHeights1D());
327 }
328 this.localStorage.SaveMap(this.Terrain.getHeights1D());
329
330 foreach (ClientView client in m_clientThreads.Values)
331 {
332 this.SendLayerData(client);
333 }
334
335 foreach (libsecondlife.LLUUID UUID in Entities.Keys)
336 {
337 Entities[UUID].LandRenegerated();
338 }
339 }
340 catch (Exception e)
341 {
342 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: RegenerateTerrain() - Failed with exception " + e.ToString());
343 }
344 }
345
346 /// <summary>
347 /// Rebuilds the terrain using a 2D float array
348 /// </summary>
349 /// <param name="newMap">256,256 float array containing heights</param>
350 public void RegenerateTerrain(float[,] newMap)
351 {
352 try
353 {
354 this.Terrain.setHeights2D(newMap);
355 lock (this.LockPhysicsEngine)
356 {
357 this.phyScene.SetTerrain(this.Terrain.getHeights1D());
358 }
359 this.localStorage.SaveMap(this.Terrain.getHeights1D());
360
361 foreach (ClientView client in m_clientThreads.Values)
362 {
363 this.SendLayerData(client);
364 }
365
366 foreach (libsecondlife.LLUUID UUID in Entities.Keys)
367 {
368 Entities[UUID].LandRenegerated();
369 }
370 }
371 catch (Exception e)
372 {
373 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: RegenerateTerrain() - Failed with exception " + e.ToString());
374 }
375 }
376
377 /// <summary>
378 /// Rebuilds the terrain assuming changes occured at a specified point[?]
379 /// </summary>
380 /// <param name="changes">???</param>
381 /// <param name="pointx">???</param>
382 /// <param name="pointy">???</param>
383 public void RegenerateTerrain(bool changes, int pointx, int pointy)
384 {
385 try
386 {
387 if (changes)
388 {
389 /* Dont save here, rely on tainting system instead */
390
391 foreach (ClientView client in m_clientThreads.Values)
392 {
393 this.SendLayerData(pointx, pointy, client);
394 }
395 }
396 }
397 catch (Exception e)
398 {
399 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: RegenerateTerrain() - Failed with exception " + e.ToString());
400 }
401 }
402
403 #endregion
404
405 #region Load Terrain
406 /// <summary>
407 /// Loads the World heightmap
408 /// </summary>
409 public override void LoadWorldMap()
410 {
411 try
412 {
413 float[] map = this.localStorage.LoadWorld();
414 if (map == null)
415 {
416 Console.WriteLine("creating new terrain");
417 this.Terrain.hills();
418
419 this.localStorage.SaveMap(this.Terrain.getHeights1D());
420 }
421 else
422 {
423 this.Terrain.setHeights1D(map);
424 }
425 }
426 catch (Exception e)
427 {
428 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: LoadWorldMap() - Failed with exception " + e.ToString());
429 }
430 }
431 #endregion
432
433 #region Primitives Methods
434
435 /// <summary>
436 /// Sends prims to a client
437 /// </summary>
438 /// <param name="RemoteClient">Client to send to</param>
439 public void GetInitialPrims(ClientView RemoteClient)
440 {
441 try
442 {
443 foreach (libsecondlife.LLUUID UUID in Entities.Keys)
444 {
445 if (Entities[UUID] is Primitive)
446 {
447 Primitive primitive = Entities[UUID] as Primitive;
448 primitive.UpdateClient(RemoteClient);
449 }
450 }
451 }
452 catch (Exception e)
453 {
454 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: GetInitialPrims() - Failed with exception " + e.ToString());
455 }
456 }
457
458 /// <summary>
459 /// Loads the World's objects
460 /// </summary>
461 public void LoadPrimsFromStorage()
462 {
463 try
464 {
465 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs: LoadPrimsFromStorage() - Loading primitives");
466 this.localStorage.LoadPrimitives(this);
467 }
468 catch (Exception e)
469 {
470 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: LoadPrimsFromStorage() - Failed with exception " + e.ToString());
471 }
472 }
473
474 /// <summary>
475 /// Loads a specific object from storage
476 /// </summary>
477 /// <param name="prim">The object to load</param>
478 public void PrimFromStorage(PrimData prim)
479 {
480 try
481 {
482 if (prim.LocalID >= this._primCount)
483 {
484 _primCount = prim.LocalID + 1;
485 }
486 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs: PrimFromStorage() - Reloading prim (localId " + prim.LocalID + " ) from storage");
487 Primitive nPrim = new Primitive(m_clientThreads, m_regionHandle, this);
488 nPrim.CreateFromStorage(prim);
489 this.Entities.Add(nPrim.uuid, nPrim);
490 }
491 catch (Exception e)
492 {
493 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: PrimFromStorage() - Failed with exception " + e.ToString());
494 }
495 }
496
497 public void AddNewPrim(Packet addPacket, ClientView agentClient)
498 {
499 AddNewPrim((ObjectAddPacket)addPacket, agentClient.AgentID);
500 }
501
502 public void AddNewPrim(ObjectAddPacket addPacket, LLUUID ownerID)
503 {
504 try
505 {
506 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs: AddNewPrim() - Creating new prim");
507 Primitive prim = new Primitive(m_clientThreads, m_regionHandle, this);
508 prim.CreateFromPacket(addPacket, ownerID, this._primCount);
509 PhysicsVector pVec = new PhysicsVector(prim.Pos.X, prim.Pos.Y, prim.Pos.Z);
510 PhysicsVector pSize = new PhysicsVector(0.255f, 0.255f, 0.255f);
511 if (OpenSim.world.Avatar.PhysicsEngineFlying)
512 {
513 lock (this.LockPhysicsEngine)
514 {
515 prim.PhysActor = this.phyScene.AddPrim(pVec, pSize);
516 }
517 }
518
519 this.Entities.Add(prim.uuid, prim);
520 this._primCount++;
521 }
522 catch (Exception e)
523 {
524 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "World.cs: AddNewPrim() - Failed with exception " + e.ToString());
525 }
526 }
527
528 #endregion
529
530 #region Add/Remove Avatar Methods
531
532 public override Avatar AddViewerAgent(ClientView agentClient)
533 {
534 Avatar newAvatar = null;
535 return newAvatar;
536 }
537
538 public override void RemoveViewerAgent(ClientView agentClient)
539 {
540
541 }
542 #endregion
543
544 #region Request Avatars List Methods
545 //The idea is to have a group of method that return a list of avatars meeting some requirement
546 // ie it could be all Avatars within a certain range of the calling prim/avatar.
547
548 public List<Avatar> RequestAvatarList()
549 {
550 List<Avatar> result = new List<Avatar>();
551
552 foreach (Avatar avatar in Avatars.Values)
553 {
554 result.Add(avatar);
555 }
556
557 return result;
558 }
559 #endregion
560
561 #region ShutDown
562 /// <summary>
563 /// Tidy before shutdown
564 /// </summary>
565 public override void Close()
566 {
567 try
568 {
569 this.localStorage.ShutDown();
570 }
571 catch (Exception e)
572 {
573 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.HIGH, "World.cs: Close() - Failed with exception " + e.ToString());
574 }
575 }
576 #endregion
577
578 }
579}