aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneManager.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneManager.cs669
1 files changed, 669 insertions, 0 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs
new file mode 100644
index 0000000..180f8a1
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs
@@ -0,0 +1,669 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.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 System.Collections.Generic;
30using System.Net;
31using System.Reflection;
32using OpenMetaverse;
33using log4net;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36
37namespace OpenSim.Region.Framework.Scenes
38{
39 public delegate void RestartSim(RegionInfo thisregion);
40
41 /// <summary>
42 /// Manager for adding, closing and restarting scenes.
43 /// </summary>
44 public class SceneManager
45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 public event RestartSim OnRestartSim;
49
50 private readonly List<Scene> m_localScenes;
51 private Scene m_currentScene = null;
52
53 public List<Scene> Scenes
54 {
55 get { return m_localScenes; }
56 }
57
58 public Scene CurrentScene
59 {
60 get { return m_currentScene; }
61 }
62
63 public Scene CurrentOrFirstScene
64 {
65 get
66 {
67 if (m_currentScene == null)
68 {
69 return m_localScenes[0];
70 }
71 else
72 {
73 return m_currentScene;
74 }
75 }
76 }
77
78 public SceneManager()
79 {
80 m_localScenes = new List<Scene>();
81 }
82
83 public void Close()
84 {
85 // collect known shared modules in sharedModules
86 Dictionary<string, IRegionModule> sharedModules = new Dictionary<string, IRegionModule>();
87 for (int i = 0; i < m_localScenes.Count; i++)
88 {
89 // extract known shared modules from scene
90 foreach (string k in m_localScenes[i].Modules.Keys)
91 {
92 if (m_localScenes[i].Modules[k].IsSharedModule &&
93 !sharedModules.ContainsKey(k))
94 sharedModules[k] = m_localScenes[i].Modules[k];
95 }
96 // close scene/region
97 m_localScenes[i].Close();
98 }
99
100 // all regions/scenes are now closed, we can now safely
101 // close all shared modules
102 foreach (IRegionModule mod in sharedModules.Values)
103 {
104 mod.Close();
105 }
106 }
107
108 public void Close(Scene cscene)
109 {
110 if (m_localScenes.Contains(cscene))
111 {
112 for (int i = 0; i < m_localScenes.Count; i++)
113 {
114 if (m_localScenes[i].Equals(cscene))
115 {
116 m_localScenes[i].Close();
117 }
118 }
119 }
120 }
121
122 public void Add(Scene scene)
123 {
124 scene.OnRestart += HandleRestart;
125 m_localScenes.Add(scene);
126 }
127
128 public void HandleRestart(RegionInfo rdata)
129 {
130 m_log.Error("[SCENEMANAGER]: Got Restart message for region:" + rdata.RegionName + " Sending up to main");
131 int RegionSceneElement = -1;
132 for (int i = 0; i < m_localScenes.Count; i++)
133 {
134 if (rdata.RegionName == m_localScenes[i].RegionInfo.RegionName)
135 {
136 RegionSceneElement = i;
137 }
138 }
139
140 // Now we make sure the region is no longer known about by the SceneManager
141 // Prevents duplicates.
142
143 if (RegionSceneElement >= 0)
144 {
145 m_localScenes.RemoveAt(RegionSceneElement);
146 }
147
148 // Send signal to main that we're restarting this sim.
149 OnRestartSim(rdata);
150 }
151
152 public void SendSimOnlineNotification(ulong regionHandle)
153 {
154 RegionInfo Result = null;
155
156 for (int i = 0; i < m_localScenes.Count; i++)
157 {
158 if (m_localScenes[i].RegionInfo.RegionHandle == regionHandle)
159 {
160 // Inform other regions to tell their avatar about me
161 Result = m_localScenes[i].RegionInfo;
162 }
163 }
164 if (Result != null)
165 {
166 for (int i = 0; i < m_localScenes.Count; i++)
167 {
168 if (m_localScenes[i].RegionInfo.RegionHandle != regionHandle)
169 {
170 // Inform other regions to tell their avatar about me
171 //m_localScenes[i].OtherRegionUp(Result);
172 }
173 }
174 }
175 else
176 {
177 m_log.Error("[REGION]: Unable to notify Other regions of this Region coming up");
178 }
179 }
180
181 /// <summary>
182 /// Save the prims in the current scene to an xml file in OpenSimulator's original 'xml' format
183 /// </summary>
184 /// <param name="filename"></param>
185 public void SaveCurrentSceneToXml(string filename)
186 {
187 IRegionSerialiserModule serialiser = CurrentOrFirstScene.RequestModuleInterface<IRegionSerialiserModule>();
188 if (serialiser != null)
189 serialiser.SavePrimsToXml(CurrentOrFirstScene, filename);
190 }
191
192 /// <summary>
193 /// Load an xml file of prims in OpenSimulator's original 'xml' file format to the current scene
194 /// </summary>
195 /// <param name="filename"></param>
196 /// <param name="generateNewIDs"></param>
197 /// <param name="loadOffset"></param>
198 public void LoadCurrentSceneFromXml(string filename, bool generateNewIDs, Vector3 loadOffset)
199 {
200 IRegionSerialiserModule serialiser = CurrentOrFirstScene.RequestModuleInterface<IRegionSerialiserModule>();
201 if (serialiser != null)
202 serialiser.LoadPrimsFromXml(CurrentOrFirstScene, filename, generateNewIDs, loadOffset);
203 }
204
205 /// <summary>
206 /// Save the prims in the current scene to an xml file in OpenSimulator's current 'xml2' format
207 /// </summary>
208 /// <param name="filename"></param>
209 public void SaveCurrentSceneToXml2(string filename)
210 {
211 IRegionSerialiserModule serialiser = CurrentOrFirstScene.RequestModuleInterface<IRegionSerialiserModule>();
212 if (serialiser != null)
213 serialiser.SavePrimsToXml2(CurrentOrFirstScene, filename);
214 }
215
216 public void SaveNamedPrimsToXml2(string primName, string filename)
217 {
218 IRegionSerialiserModule serialiser = CurrentOrFirstScene.RequestModuleInterface<IRegionSerialiserModule>();
219 if (serialiser != null)
220 serialiser.SaveNamedPrimsToXml2(CurrentOrFirstScene, primName, filename);
221 }
222
223 /// <summary>
224 /// Load an xml file of prims in OpenSimulator's current 'xml2' file format to the current scene
225 /// </summary>
226 public void LoadCurrentSceneFromXml2(string filename)
227 {
228 IRegionSerialiserModule serialiser = CurrentOrFirstScene.RequestModuleInterface<IRegionSerialiserModule>();
229 if (serialiser != null)
230 serialiser.LoadPrimsFromXml2(CurrentOrFirstScene, filename);
231 }
232
233 /// <summary>
234 /// Save the current scene to an OpenSimulator archive. This archive will eventually include the prim's assets
235 /// as well as the details of the prims themselves.
236 /// </summary>
237 /// <param name="filename"></param>
238 public void SaveCurrentSceneToArchive(string filename)
239 {
240 IRegionArchiverModule archiver = CurrentOrFirstScene.RequestModuleInterface<IRegionArchiverModule>();
241 if (archiver != null)
242 archiver.ArchiveRegion(filename);
243 }
244
245 /// <summary>
246 /// Load an OpenSim archive into the current scene. This will load both the shapes of the prims and upload
247 /// their assets to the asset service.
248 /// </summary>
249 /// <param name="filename"></param>
250 public void LoadArchiveToCurrentScene(string filename)
251 {
252 IRegionArchiverModule archiver = CurrentOrFirstScene.RequestModuleInterface<IRegionArchiverModule>();
253 if (archiver != null)
254 archiver.DearchiveRegion(filename);
255 }
256
257 public string SaveCurrentSceneMapToXmlString()
258 {
259 return CurrentOrFirstScene.Heightmap.SaveToXmlString();
260 }
261
262 public void LoadCurrenSceneMapFromXmlString(string mapData)
263 {
264 CurrentOrFirstScene.Heightmap.LoadFromXmlString(mapData);
265 }
266
267 public void SendCommandToPluginModules(string[] cmdparams)
268 {
269 ForEachCurrentScene(delegate(Scene scene) { scene.SendCommandToPlugins(cmdparams); });
270 }
271
272 public void SetBypassPermissionsOnCurrentScene(bool bypassPermissions)
273 {
274 ForEachCurrentScene(delegate(Scene scene) { scene.Permissions.SetBypassPermissions(bypassPermissions); });
275 }
276
277 private void ForEachCurrentScene(Action<Scene> func)
278 {
279 if (m_currentScene == null)
280 {
281 m_localScenes.ForEach(func);
282 }
283 else
284 {
285 func(m_currentScene);
286 }
287 }
288
289 public void RestartCurrentScene()
290 {
291 ForEachCurrentScene(delegate(Scene scene) { scene.RestartNow(); });
292 }
293
294 public void BackupCurrentScene()
295 {
296 ForEachCurrentScene(delegate(Scene scene) { scene.Backup(); });
297 }
298
299 public void HandleAlertCommandOnCurrentScene(string[] cmdparams)
300 {
301 ForEachCurrentScene(delegate(Scene scene) { scene.HandleAlertCommand(cmdparams); });
302 }
303
304 public void SendGeneralMessage(string msg)
305 {
306 ForEachCurrentScene(delegate(Scene scene) { scene.HandleAlertCommand(new string[] { "general", msg }); });
307 }
308
309 public bool TrySetCurrentScene(string regionName)
310 {
311 if ((String.Compare(regionName, "root") == 0)
312 || (String.Compare(regionName, "..") == 0)
313 || (String.Compare(regionName, "/") == 0))
314 {
315 m_currentScene = null;
316 return true;
317 }
318 else
319 {
320 foreach (Scene scene in m_localScenes)
321 {
322 if (String.Compare(scene.RegionInfo.RegionName, regionName, true) == 0)
323 {
324 m_currentScene = scene;
325 return true;
326 }
327 }
328
329 return false;
330 }
331 }
332
333 public bool TrySetCurrentScene(UUID regionID)
334 {
335 Console.WriteLine("Searching for Region: '{0}'", regionID.ToString());
336
337 foreach (Scene scene in m_localScenes)
338 {
339 if (scene.RegionInfo.RegionID == regionID)
340 {
341 m_currentScene = scene;
342 return true;
343 }
344 }
345
346 return false;
347 }
348
349 public bool TryGetScene(string regionName, out Scene scene)
350 {
351 foreach (Scene mscene in m_localScenes)
352 {
353 if (String.Compare(mscene.RegionInfo.RegionName, regionName, true) == 0)
354 {
355 scene = mscene;
356 return true;
357 }
358 }
359 scene = null;
360 return false;
361 }
362
363 public bool TryGetScene(UUID regionID, out Scene scene)
364 {
365 foreach (Scene mscene in m_localScenes)
366 {
367 if (mscene.RegionInfo.RegionID == regionID)
368 {
369 scene = mscene;
370 return true;
371 }
372 }
373
374 scene = null;
375 return false;
376 }
377
378 public bool TryGetScene(uint locX, uint locY, out Scene scene)
379 {
380 foreach (Scene mscene in m_localScenes)
381 {
382 if (mscene.RegionInfo.RegionLocX == locX &&
383 mscene.RegionInfo.RegionLocY == locY)
384 {
385 scene = mscene;
386 return true;
387 }
388 }
389
390 scene = null;
391 return false;
392 }
393
394 public bool TryGetScene(IPEndPoint ipEndPoint, out Scene scene)
395 {
396 foreach (Scene mscene in m_localScenes)
397 {
398 if ((mscene.RegionInfo.InternalEndPoint.Equals(ipEndPoint.Address)) &&
399 (mscene.RegionInfo.InternalEndPoint.Port == ipEndPoint.Port))
400 {
401 scene = mscene;
402 return true;
403 }
404 }
405
406 scene = null;
407 return false;
408 }
409
410 /// <summary>
411 /// Set the debug packet level on the current scene. This level governs which packets are printed out to the
412 /// console.
413 /// </summary>
414 /// <param name="newDebug"></param>
415 public void SetDebugPacketLevelOnCurrentScene(int newDebug)
416 {
417 ForEachCurrentScene(delegate(Scene scene)
418 {
419 List<ScenePresence> scenePresences = scene.GetScenePresences();
420
421 foreach (ScenePresence scenePresence in scenePresences)
422 {
423 if (!scenePresence.IsChildAgent)
424 {
425 m_log.ErrorFormat("Packet debug for {0} {1} set to {2}",
426 scenePresence.Firstname,
427 scenePresence.Lastname,
428 newDebug);
429
430 scenePresence.ControllingClient.SetDebugPacketLevel(newDebug);
431 }
432 }
433 });
434 }
435
436 public List<ScenePresence> GetCurrentSceneAvatars()
437 {
438 List<ScenePresence> avatars = new List<ScenePresence>();
439
440 ForEachCurrentScene(delegate(Scene scene)
441 {
442 List<ScenePresence> scenePresences = scene.GetScenePresences();
443
444 foreach (ScenePresence scenePresence in scenePresences)
445 {
446 if (!scenePresence.IsChildAgent)
447 {
448 avatars.Add(scenePresence);
449 }
450 }
451 });
452
453 return avatars;
454 }
455
456 public List<ScenePresence> GetCurrentScenePresences()
457 {
458 List<ScenePresence> presences = new List<ScenePresence>();
459
460 ForEachCurrentScene(delegate(Scene scene)
461 {
462 List<ScenePresence> scenePresences = scene.GetScenePresences();
463 presences.AddRange(scenePresences);
464 });
465
466 return presences;
467 }
468
469 public RegionInfo GetRegionInfo(ulong regionHandle)
470 {
471 foreach (Scene scene in m_localScenes)
472 {
473 if (scene.RegionInfo.RegionHandle == regionHandle)
474 {
475 return scene.RegionInfo;
476 }
477 }
478
479 return null;
480 }
481
482 public void ForceCurrentSceneClientUpdate()
483 {
484 ForEachCurrentScene(delegate(Scene scene) { scene.ForceClientUpdate(); });
485 }
486
487 public void HandleEditCommandOnCurrentScene(string[] cmdparams)
488 {
489 ForEachCurrentScene(delegate(Scene scene) { scene.HandleEditCommand(cmdparams); });
490 }
491
492 public bool TryGetAvatar(UUID avatarId, out ScenePresence avatar)
493 {
494 foreach (Scene scene in m_localScenes)
495 {
496 if (scene.TryGetAvatar(avatarId, out avatar))
497 {
498 return true;
499 }
500 }
501
502 avatar = null;
503 return false;
504 }
505
506 public bool TryGetAvatarsScene(UUID avatarId, out Scene scene)
507 {
508 ScenePresence avatar = null;
509 foreach (Scene mScene in m_localScenes)
510 {
511 if (mScene.TryGetAvatar(avatarId, out avatar))
512 {
513 scene = mScene;
514 return true;
515 }
516 }
517
518 scene = null;
519 return false;
520 }
521
522 public void CloseScene(Scene scene)
523 {
524 m_localScenes.Remove(scene);
525 scene.Close();
526 }
527
528 public bool TryGetAvatarByName(string avatarName, out ScenePresence avatar)
529 {
530 foreach (Scene scene in m_localScenes)
531 {
532 if (scene.TryGetAvatarByName(avatarName, out avatar))
533 {
534 return true;
535 }
536 }
537
538 avatar = null;
539 return false;
540 }
541
542 public void ForEachScene(Action<Scene> action)
543 {
544 m_localScenes.ForEach(action);
545 }
546
547 public void CacheJ2kDecode(int threads)
548 {
549 if (threads < 1) threads = 1;
550
551 IJ2KDecoder m_decoder = m_localScenes[0].RequestModuleInterface<IJ2KDecoder>();
552
553 List<UUID> assetRequestList = new List<UUID>();
554
555 #region AssetGathering!
556 foreach (Scene scene in m_localScenes)
557 {
558 List<EntityBase> entitles = scene.GetEntities();
559 foreach (EntityBase entity in entitles)
560 {
561 if (entity is SceneObjectGroup)
562 {
563 SceneObjectGroup sog = (SceneObjectGroup) entity;
564 foreach (SceneObjectPart part in sog.Children.Values)
565 {
566 if (part.Shape != null)
567 {
568 if (part.Shape.TextureEntry.Length > 0)
569 {
570 OpenMetaverse.Primitive.TextureEntry te =
571 new Primitive.TextureEntry(part.Shape.TextureEntry, 0,
572 part.Shape.TextureEntry.Length);
573 if (te.DefaultTexture != null) // this has been null for some reason...
574 {
575 if (te.DefaultTexture.TextureID != UUID.Zero)
576 assetRequestList.Add(te.DefaultTexture.TextureID);
577 }
578 for (int i=0; i<te.FaceTextures.Length; i++)
579 {
580 if (te.FaceTextures[i] != null)
581 {
582 if (te.FaceTextures[i].TextureID != UUID.Zero)
583 {
584 assetRequestList.Add(te.FaceTextures[i].TextureID);
585 }
586 }
587 }
588 }
589 if (part.Shape.SculptTexture != UUID.Zero)
590 {
591 assetRequestList.Add(part.Shape.SculptTexture);
592 }
593
594 }
595 }
596 }
597 }
598 }
599 #endregion
600
601 int entries_per_thread = (assetRequestList.Count / threads) + 1;
602
603 UUID[] arrAssetRequestList = assetRequestList.ToArray();
604
605 List<UUID[]> arrvalus = new List<UUID[]>();
606
607 //split into separate arrays
608 for (int j = 0; j < threads; j++)
609 {
610 List<UUID> val = new List<UUID>();
611
612 for (int k = j * entries_per_thread; k < ((j + 1) * entries_per_thread); k++)
613 {
614 if (k < arrAssetRequestList.Length)
615 {
616 val.Add(arrAssetRequestList[k]);
617 }
618
619 }
620 arrvalus.Add(val.ToArray());
621 }
622
623 for (int l = 0; l < arrvalus.Count; l++)
624 {
625 DecodeThreadContents threadworkItem = new DecodeThreadContents();
626 threadworkItem.sn = m_localScenes[0];
627 threadworkItem.j2kdecode = m_decoder;
628 threadworkItem.arrassets = arrvalus[l];
629
630 System.Threading.Thread decodethread =
631 new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(threadworkItem.run));
632
633 threadworkItem.SetThread(decodethread);
634
635 decodethread.Priority = System.Threading.ThreadPriority.Lowest;
636 decodethread.Name = "J2kCacheDecodeThread_" + l + 1;
637 ThreadTracker.Add(decodethread);
638 decodethread.Start();
639
640 }
641 }
642 }
643
644 public class DecodeThreadContents
645 {
646 public Scene sn;
647 public UUID[] arrassets;
648 public IJ2KDecoder j2kdecode;
649 private System.Threading.Thread thisthread;
650
651 public void run( object o)
652 {
653 for (int i=0;i<arrassets.Length;i++)
654 {
655 AssetBase ab = sn.AssetCache.GetAsset(arrassets[i], true);
656 if (ab != null && ab.Data != null)
657 {
658 j2kdecode.syncdecode(arrassets[i], ab.Data);
659 }
660 }
661 ThreadTracker.Remove(thisthread);
662 }
663
664 public void SetThread(System.Threading.Thread thr)
665 {
666 thisthread = thr;
667 }
668 }
669}