From 9b66108081a8c8cf79faaa6c541554091c40850e Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Fri, 6 Feb 2009 16:55:34 +0000 Subject: This changeset is the step 1 of 2 in refactoring OpenSim.Region.Environment into a "framework" part and a modules only part. This first changeset refactors OpenSim.Region.Environment.Scenes, OpenSim.Region.Environment.Interfaces, and OpenSim.Region.Interfaces into OpenSim.Region.Framework.{Interfaces,Scenes} leaving only region modules in OpenSim.Region.Environment. The next step will be to move region modules up from OpenSim.Region.Environment.Modules to OpenSim.Region.CoreModules and then sort out which modules are really core modules and which should move out to forge. I've been very careful to NOT BREAK anything. i hope i've succeeded. as this is the work of a whole week i hope i managed to keep track with the applied patches of the last week --- could any of you that did check in stuff have a look at whether it survived? thx! --- OpenSim/Region/Framework/Scenes/SceneManager.cs | 669 ++++++++++++++++++++++++ 1 file changed, 669 insertions(+) create mode 100644 OpenSim/Region/Framework/Scenes/SceneManager.cs (limited to 'OpenSim/Region/Framework/Scenes/SceneManager.cs') 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 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Net; +using System.Reflection; +using OpenMetaverse; +using log4net; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; + +namespace OpenSim.Region.Framework.Scenes +{ + public delegate void RestartSim(RegionInfo thisregion); + + /// + /// Manager for adding, closing and restarting scenes. + /// + public class SceneManager + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public event RestartSim OnRestartSim; + + private readonly List m_localScenes; + private Scene m_currentScene = null; + + public List Scenes + { + get { return m_localScenes; } + } + + public Scene CurrentScene + { + get { return m_currentScene; } + } + + public Scene CurrentOrFirstScene + { + get + { + if (m_currentScene == null) + { + return m_localScenes[0]; + } + else + { + return m_currentScene; + } + } + } + + public SceneManager() + { + m_localScenes = new List(); + } + + public void Close() + { + // collect known shared modules in sharedModules + Dictionary sharedModules = new Dictionary(); + for (int i = 0; i < m_localScenes.Count; i++) + { + // extract known shared modules from scene + foreach (string k in m_localScenes[i].Modules.Keys) + { + if (m_localScenes[i].Modules[k].IsSharedModule && + !sharedModules.ContainsKey(k)) + sharedModules[k] = m_localScenes[i].Modules[k]; + } + // close scene/region + m_localScenes[i].Close(); + } + + // all regions/scenes are now closed, we can now safely + // close all shared modules + foreach (IRegionModule mod in sharedModules.Values) + { + mod.Close(); + } + } + + public void Close(Scene cscene) + { + if (m_localScenes.Contains(cscene)) + { + for (int i = 0; i < m_localScenes.Count; i++) + { + if (m_localScenes[i].Equals(cscene)) + { + m_localScenes[i].Close(); + } + } + } + } + + public void Add(Scene scene) + { + scene.OnRestart += HandleRestart; + m_localScenes.Add(scene); + } + + public void HandleRestart(RegionInfo rdata) + { + m_log.Error("[SCENEMANAGER]: Got Restart message for region:" + rdata.RegionName + " Sending up to main"); + int RegionSceneElement = -1; + for (int i = 0; i < m_localScenes.Count; i++) + { + if (rdata.RegionName == m_localScenes[i].RegionInfo.RegionName) + { + RegionSceneElement = i; + } + } + + // Now we make sure the region is no longer known about by the SceneManager + // Prevents duplicates. + + if (RegionSceneElement >= 0) + { + m_localScenes.RemoveAt(RegionSceneElement); + } + + // Send signal to main that we're restarting this sim. + OnRestartSim(rdata); + } + + public void SendSimOnlineNotification(ulong regionHandle) + { + RegionInfo Result = null; + + for (int i = 0; i < m_localScenes.Count; i++) + { + if (m_localScenes[i].RegionInfo.RegionHandle == regionHandle) + { + // Inform other regions to tell their avatar about me + Result = m_localScenes[i].RegionInfo; + } + } + if (Result != null) + { + for (int i = 0; i < m_localScenes.Count; i++) + { + if (m_localScenes[i].RegionInfo.RegionHandle != regionHandle) + { + // Inform other regions to tell their avatar about me + //m_localScenes[i].OtherRegionUp(Result); + } + } + } + else + { + m_log.Error("[REGION]: Unable to notify Other regions of this Region coming up"); + } + } + + /// + /// Save the prims in the current scene to an xml file in OpenSimulator's original 'xml' format + /// + /// + public void SaveCurrentSceneToXml(string filename) + { + IRegionSerialiserModule serialiser = CurrentOrFirstScene.RequestModuleInterface(); + if (serialiser != null) + serialiser.SavePrimsToXml(CurrentOrFirstScene, filename); + } + + /// + /// Load an xml file of prims in OpenSimulator's original 'xml' file format to the current scene + /// + /// + /// + /// + public void LoadCurrentSceneFromXml(string filename, bool generateNewIDs, Vector3 loadOffset) + { + IRegionSerialiserModule serialiser = CurrentOrFirstScene.RequestModuleInterface(); + if (serialiser != null) + serialiser.LoadPrimsFromXml(CurrentOrFirstScene, filename, generateNewIDs, loadOffset); + } + + /// + /// Save the prims in the current scene to an xml file in OpenSimulator's current 'xml2' format + /// + /// + public void SaveCurrentSceneToXml2(string filename) + { + IRegionSerialiserModule serialiser = CurrentOrFirstScene.RequestModuleInterface(); + if (serialiser != null) + serialiser.SavePrimsToXml2(CurrentOrFirstScene, filename); + } + + public void SaveNamedPrimsToXml2(string primName, string filename) + { + IRegionSerialiserModule serialiser = CurrentOrFirstScene.RequestModuleInterface(); + if (serialiser != null) + serialiser.SaveNamedPrimsToXml2(CurrentOrFirstScene, primName, filename); + } + + /// + /// Load an xml file of prims in OpenSimulator's current 'xml2' file format to the current scene + /// + public void LoadCurrentSceneFromXml2(string filename) + { + IRegionSerialiserModule serialiser = CurrentOrFirstScene.RequestModuleInterface(); + if (serialiser != null) + serialiser.LoadPrimsFromXml2(CurrentOrFirstScene, filename); + } + + /// + /// Save the current scene to an OpenSimulator archive. This archive will eventually include the prim's assets + /// as well as the details of the prims themselves. + /// + /// + public void SaveCurrentSceneToArchive(string filename) + { + IRegionArchiverModule archiver = CurrentOrFirstScene.RequestModuleInterface(); + if (archiver != null) + archiver.ArchiveRegion(filename); + } + + /// + /// Load an OpenSim archive into the current scene. This will load both the shapes of the prims and upload + /// their assets to the asset service. + /// + /// + public void LoadArchiveToCurrentScene(string filename) + { + IRegionArchiverModule archiver = CurrentOrFirstScene.RequestModuleInterface(); + if (archiver != null) + archiver.DearchiveRegion(filename); + } + + public string SaveCurrentSceneMapToXmlString() + { + return CurrentOrFirstScene.Heightmap.SaveToXmlString(); + } + + public void LoadCurrenSceneMapFromXmlString(string mapData) + { + CurrentOrFirstScene.Heightmap.LoadFromXmlString(mapData); + } + + public void SendCommandToPluginModules(string[] cmdparams) + { + ForEachCurrentScene(delegate(Scene scene) { scene.SendCommandToPlugins(cmdparams); }); + } + + public void SetBypassPermissionsOnCurrentScene(bool bypassPermissions) + { + ForEachCurrentScene(delegate(Scene scene) { scene.Permissions.SetBypassPermissions(bypassPermissions); }); + } + + private void ForEachCurrentScene(Action func) + { + if (m_currentScene == null) + { + m_localScenes.ForEach(func); + } + else + { + func(m_currentScene); + } + } + + public void RestartCurrentScene() + { + ForEachCurrentScene(delegate(Scene scene) { scene.RestartNow(); }); + } + + public void BackupCurrentScene() + { + ForEachCurrentScene(delegate(Scene scene) { scene.Backup(); }); + } + + public void HandleAlertCommandOnCurrentScene(string[] cmdparams) + { + ForEachCurrentScene(delegate(Scene scene) { scene.HandleAlertCommand(cmdparams); }); + } + + public void SendGeneralMessage(string msg) + { + ForEachCurrentScene(delegate(Scene scene) { scene.HandleAlertCommand(new string[] { "general", msg }); }); + } + + public bool TrySetCurrentScene(string regionName) + { + if ((String.Compare(regionName, "root") == 0) + || (String.Compare(regionName, "..") == 0) + || (String.Compare(regionName, "/") == 0)) + { + m_currentScene = null; + return true; + } + else + { + foreach (Scene scene in m_localScenes) + { + if (String.Compare(scene.RegionInfo.RegionName, regionName, true) == 0) + { + m_currentScene = scene; + return true; + } + } + + return false; + } + } + + public bool TrySetCurrentScene(UUID regionID) + { + Console.WriteLine("Searching for Region: '{0}'", regionID.ToString()); + + foreach (Scene scene in m_localScenes) + { + if (scene.RegionInfo.RegionID == regionID) + { + m_currentScene = scene; + return true; + } + } + + return false; + } + + public bool TryGetScene(string regionName, out Scene scene) + { + foreach (Scene mscene in m_localScenes) + { + if (String.Compare(mscene.RegionInfo.RegionName, regionName, true) == 0) + { + scene = mscene; + return true; + } + } + scene = null; + return false; + } + + public bool TryGetScene(UUID regionID, out Scene scene) + { + foreach (Scene mscene in m_localScenes) + { + if (mscene.RegionInfo.RegionID == regionID) + { + scene = mscene; + return true; + } + } + + scene = null; + return false; + } + + public bool TryGetScene(uint locX, uint locY, out Scene scene) + { + foreach (Scene mscene in m_localScenes) + { + if (mscene.RegionInfo.RegionLocX == locX && + mscene.RegionInfo.RegionLocY == locY) + { + scene = mscene; + return true; + } + } + + scene = null; + return false; + } + + public bool TryGetScene(IPEndPoint ipEndPoint, out Scene scene) + { + foreach (Scene mscene in m_localScenes) + { + if ((mscene.RegionInfo.InternalEndPoint.Equals(ipEndPoint.Address)) && + (mscene.RegionInfo.InternalEndPoint.Port == ipEndPoint.Port)) + { + scene = mscene; + return true; + } + } + + scene = null; + return false; + } + + /// + /// Set the debug packet level on the current scene. This level governs which packets are printed out to the + /// console. + /// + /// + public void SetDebugPacketLevelOnCurrentScene(int newDebug) + { + ForEachCurrentScene(delegate(Scene scene) + { + List scenePresences = scene.GetScenePresences(); + + foreach (ScenePresence scenePresence in scenePresences) + { + if (!scenePresence.IsChildAgent) + { + m_log.ErrorFormat("Packet debug for {0} {1} set to {2}", + scenePresence.Firstname, + scenePresence.Lastname, + newDebug); + + scenePresence.ControllingClient.SetDebugPacketLevel(newDebug); + } + } + }); + } + + public List GetCurrentSceneAvatars() + { + List avatars = new List(); + + ForEachCurrentScene(delegate(Scene scene) + { + List scenePresences = scene.GetScenePresences(); + + foreach (ScenePresence scenePresence in scenePresences) + { + if (!scenePresence.IsChildAgent) + { + avatars.Add(scenePresence); + } + } + }); + + return avatars; + } + + public List GetCurrentScenePresences() + { + List presences = new List(); + + ForEachCurrentScene(delegate(Scene scene) + { + List scenePresences = scene.GetScenePresences(); + presences.AddRange(scenePresences); + }); + + return presences; + } + + public RegionInfo GetRegionInfo(ulong regionHandle) + { + foreach (Scene scene in m_localScenes) + { + if (scene.RegionInfo.RegionHandle == regionHandle) + { + return scene.RegionInfo; + } + } + + return null; + } + + public void ForceCurrentSceneClientUpdate() + { + ForEachCurrentScene(delegate(Scene scene) { scene.ForceClientUpdate(); }); + } + + public void HandleEditCommandOnCurrentScene(string[] cmdparams) + { + ForEachCurrentScene(delegate(Scene scene) { scene.HandleEditCommand(cmdparams); }); + } + + public bool TryGetAvatar(UUID avatarId, out ScenePresence avatar) + { + foreach (Scene scene in m_localScenes) + { + if (scene.TryGetAvatar(avatarId, out avatar)) + { + return true; + } + } + + avatar = null; + return false; + } + + public bool TryGetAvatarsScene(UUID avatarId, out Scene scene) + { + ScenePresence avatar = null; + foreach (Scene mScene in m_localScenes) + { + if (mScene.TryGetAvatar(avatarId, out avatar)) + { + scene = mScene; + return true; + } + } + + scene = null; + return false; + } + + public void CloseScene(Scene scene) + { + m_localScenes.Remove(scene); + scene.Close(); + } + + public bool TryGetAvatarByName(string avatarName, out ScenePresence avatar) + { + foreach (Scene scene in m_localScenes) + { + if (scene.TryGetAvatarByName(avatarName, out avatar)) + { + return true; + } + } + + avatar = null; + return false; + } + + public void ForEachScene(Action action) + { + m_localScenes.ForEach(action); + } + + public void CacheJ2kDecode(int threads) + { + if (threads < 1) threads = 1; + + IJ2KDecoder m_decoder = m_localScenes[0].RequestModuleInterface(); + + List assetRequestList = new List(); + + #region AssetGathering! + foreach (Scene scene in m_localScenes) + { + List entitles = scene.GetEntities(); + foreach (EntityBase entity in entitles) + { + if (entity is SceneObjectGroup) + { + SceneObjectGroup sog = (SceneObjectGroup) entity; + foreach (SceneObjectPart part in sog.Children.Values) + { + if (part.Shape != null) + { + if (part.Shape.TextureEntry.Length > 0) + { + OpenMetaverse.Primitive.TextureEntry te = + new Primitive.TextureEntry(part.Shape.TextureEntry, 0, + part.Shape.TextureEntry.Length); + if (te.DefaultTexture != null) // this has been null for some reason... + { + if (te.DefaultTexture.TextureID != UUID.Zero) + assetRequestList.Add(te.DefaultTexture.TextureID); + } + for (int i=0; i arrvalus = new List(); + + //split into separate arrays + for (int j = 0; j < threads; j++) + { + List val = new List(); + + for (int k = j * entries_per_thread; k < ((j + 1) * entries_per_thread); k++) + { + if (k < arrAssetRequestList.Length) + { + val.Add(arrAssetRequestList[k]); + } + + } + arrvalus.Add(val.ToArray()); + } + + for (int l = 0; l < arrvalus.Count; l++) + { + DecodeThreadContents threadworkItem = new DecodeThreadContents(); + threadworkItem.sn = m_localScenes[0]; + threadworkItem.j2kdecode = m_decoder; + threadworkItem.arrassets = arrvalus[l]; + + System.Threading.Thread decodethread = + new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(threadworkItem.run)); + + threadworkItem.SetThread(decodethread); + + decodethread.Priority = System.Threading.ThreadPriority.Lowest; + decodethread.Name = "J2kCacheDecodeThread_" + l + 1; + ThreadTracker.Add(decodethread); + decodethread.Start(); + + } + } + } + + public class DecodeThreadContents + { + public Scene sn; + public UUID[] arrassets; + public IJ2KDecoder j2kdecode; + private System.Threading.Thread thisthread; + + public void run( object o) + { + for (int i=0;i