diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 7cafc5d310..08e4023404 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -664,12 +664,20 @@ namespace OpenSim if (!SceneManager.TrySetCurrentScene(newRegionName)) MainConsole.Instance.Output(String.Format("Couldn't select region {0}", newRegionName)); + else + RefreshPrompt(); } else { MainConsole.Instance.Output("Usage: change region "); } + } + /// + /// Refreshs prompt with the current selection details. + /// + private void RefreshPrompt() + { string regionName = (SceneManager.CurrentScene == null ? "root" : SceneManager.CurrentScene.RegionInfo.RegionName); MainConsole.Instance.Output(String.Format("Currently selected region is {0}", regionName)); @@ -691,6 +699,18 @@ namespace OpenSim m_console.ConsoleScene = SceneManager.CurrentScene; } + protected override void HandleRestartRegion(RegionInfo whichRegion) + { + base.HandleRestartRegion(whichRegion); + + // Where we are restarting multiple scenes at once, a previous call to RefreshPrompt may have set the + // m_console.ConsoleScene to null (indicating all scenes). + if (m_console.ConsoleScene != null && whichRegion.RegionName == ((Scene)m_console.ConsoleScene).Name) + SceneManager.TrySetCurrentScene(whichRegion.RegionName); + + RefreshPrompt(); + } + /// /// Turn on some debugging values for OpenSim. /// diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index eb4326ea02..17db0a19c0 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -314,7 +314,7 @@ namespace OpenSim // Called from base.StartUp() m_httpServerPort = m_networkServersInfo.HttpListenerPort; - SceneManager.OnRestartSim += handleRestartRegion; + SceneManager.OnRestartSim += HandleRestartRegion; // Only enable the watchdogs when all regions are ready. Otherwise we get false positives when cpu is // heavily used during initial startup. @@ -819,9 +819,11 @@ namespace OpenSim } } - public void handleRestartRegion(RegionInfo whichRegion) + protected virtual void HandleRestartRegion(RegionInfo whichRegion) { - m_log.Info("[OPENSIM]: Got restart signal from SceneManager"); + m_log.InfoFormat( + "[OPENSIM]: Got restart signal from SceneManager for region {0} ({1},{2})", + whichRegion.RegionName, whichRegion.RegionLocX, whichRegion.RegionLocY); ShutdownClientServer(whichRegion); IScene scene; @@ -967,7 +969,6 @@ namespace OpenSim m_log.Info("[SHUTDOWN]: Closing all threads"); m_log.Info("[SHUTDOWN]: Killing listener thread"); m_log.Info("[SHUTDOWN]: Killing clients"); - // TODO: implement this m_log.Info("[SHUTDOWN]: Closing console and terminating"); try @@ -976,7 +977,7 @@ namespace OpenSim } catch (Exception e) { - m_log.ErrorFormat("[SHUTDOWN]: Ignoring failure during shutdown - {0}", e); + m_log.Error("[SHUTDOWN]: Ignoring failure during shutdown - ", e); } } diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index e1c5418903..dc062b6462 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -294,6 +294,10 @@ namespace OpenSim.Region.CoreModules.World.Estate } restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), false); + + m_log.InfoFormat( + "User {0} requested restart of region {1} in {2} seconds", + remoteClient.Name, Scene.Name, times.Count != 0 ? times[0] : 0); } } @@ -318,7 +322,7 @@ namespace OpenSim.Region.CoreModules.World.Estate if ((estateAccessType & 4) != 0) // User add { - if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || Scene.Permissions.BypassPermissions()) + if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true)) { if ((estateAccessType & 1) != 0) // All estates { @@ -350,7 +354,7 @@ namespace OpenSim.Region.CoreModules.World.Estate } if ((estateAccessType & 8) != 0) // User remove { - if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || Scene.Permissions.BypassPermissions()) + if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true)) { if ((estateAccessType & 1) != 0) // All estates { @@ -381,7 +385,7 @@ namespace OpenSim.Region.CoreModules.World.Estate } if ((estateAccessType & 16) != 0) // Group add { - if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || Scene.Permissions.BypassPermissions()) + if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true)) { if ((estateAccessType & 1) != 0) // All estates { @@ -410,9 +414,10 @@ namespace OpenSim.Region.CoreModules.World.Estate remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); } } + if ((estateAccessType & 32) != 0) // Group remove { - if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || Scene.Permissions.BypassPermissions()) + if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true)) { if ((estateAccessType & 1) != 0) // All estates { @@ -441,9 +446,10 @@ namespace OpenSim.Region.CoreModules.World.Estate remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); } } + if ((estateAccessType & 64) != 0) // Ban add { - if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false) || Scene.Permissions.BypassPermissions()) + if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false)) { EstateBan[] banlistcheck = Scene.RegionInfo.EstateSettings.EstateBans; @@ -522,9 +528,10 @@ namespace OpenSim.Region.CoreModules.World.Estate remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); } } + if ((estateAccessType & 128) != 0) // Ban remove { - if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false) || Scene.Permissions.BypassPermissions()) + if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false)) { EstateBan[] banlistcheck = Scene.RegionInfo.EstateSettings.EstateBans; @@ -577,9 +584,10 @@ namespace OpenSim.Region.CoreModules.World.Estate remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); } } + if ((estateAccessType & 256) != 0) // Manager add { - if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || Scene.Permissions.BypassPermissions()) + if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true)) { if ((estateAccessType & 1) != 0) // All estates { @@ -608,9 +616,10 @@ namespace OpenSim.Region.CoreModules.World.Estate remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); } } + if ((estateAccessType & 512) != 0) // Manager remove { - if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || Scene.Permissions.BypassPermissions()) + if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true)) { if ((estateAccessType & 1) != 0) // All estates { diff --git a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs index 287738a5e1..9c441ed724 100644 --- a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs +++ b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs @@ -26,6 +26,7 @@ */ using System; +using System.Linq; using System.Reflection; using System.Timers; using System.IO; @@ -305,6 +306,9 @@ namespace OpenSim.Region.CoreModules.World.Region for (int i = 4 ; i < args.Length ; i++) times.Add(Convert.ToInt32(args[i])); + MainConsole.Instance.OutputFormat( + "Region {0} scheduled for restart in {1} seconds", m_Scene.Name, times.Sum()); + ScheduleRestart(UUID.Zero, args[3], times.ToArray(), notice); } @@ -328,4 +332,4 @@ namespace OpenSim.Region.CoreModules.World.Region } } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 80d9f6ea4d..c99e37e3c6 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1167,16 +1167,10 @@ namespace OpenSim.Region.Framework.Scenes } } - m_log.Error("[REGION]: Closing"); + m_log.InfoFormat("[REGION]: Restarting region {0}", Name); + Close(); - if (PhysicsScene != null) - { - PhysicsScene.Dispose(); - } - - m_log.Error("[REGION]: Firing Region Restart Message"); - base.Restart(); } diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs index ff12d94686..0e0b6c3d1f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneManager.cs +++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs @@ -107,16 +107,19 @@ namespace OpenSim.Region.Framework.Scenes get { return new List(m_localScenes.FindAll(delegate(Scene s) { return true; })); } } - public Scene CurrentScene - { - get { return m_currentScene; } - } + /// + /// Scene selected from the console. + /// + /// + /// If null, then all scenes are considered selected (signalled as "Root" on the console). + /// + public Scene CurrentScene { get; private set; } public Scene CurrentOrFirstScene { get { - if (m_currentScene == null) + if (CurrentScene == null) { List sceneList = Scenes; if (sceneList.Count == 0) @@ -125,7 +128,7 @@ namespace OpenSim.Region.Framework.Scenes } else { - return m_currentScene; + return CurrentScene; } } } @@ -169,11 +172,18 @@ namespace OpenSim.Region.Framework.Scenes public void HandleRestart(RegionInfo rdata) { - m_log.Error("[SCENEMANAGER]: Got Restart message for region:" + rdata.RegionName + " Sending up to main"); - int RegionSceneElement = -1; + Scene restartedScene = null; lock (m_localScenes) + { + m_localScenes.TryGetValue(rdata.RegionID, out restartedScene); m_localScenes.Remove(rdata.RegionID); + } + + // If the currently selected scene has been restarted, then we can't reselect here since we the scene + // hasn't yet been recreated. We will have to leave this to the caller. + if (CurrentScene == restartedScene) + CurrentScene = null; // Send signal to main that we're restarting this sim. OnRestartSim(rdata); @@ -313,14 +323,14 @@ namespace OpenSim.Region.Framework.Scenes private void ForEachCurrentScene(Action func) { - if (m_currentScene == null) + if (CurrentScene == null) { List sceneList = Scenes; sceneList.ForEach(func); } else { - func(m_currentScene); + func(CurrentScene); } } @@ -340,7 +350,7 @@ namespace OpenSim.Region.Framework.Scenes || (String.Compare(regionName, "..") == 0) || (String.Compare(regionName, "/") == 0)) { - m_currentScene = null; + CurrentScene = null; return true; } else diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs new file mode 100644 index 0000000000..ab56f4ed13 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneManagerTests.cs @@ -0,0 +1,58 @@ +/* + * 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 OpenSimulator 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.Reflection; +using System.Threading; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.Framework.Scenes.Tests +{ + [TestFixture] + public class SceneManagerTests + { + [Test] + public void TestClose() + { + TestHelpers.InMethod(); + + SceneHelpers sh = new SceneHelpers(); + Scene scene = sh.SetupScene(); + + sh.SceneManager.Close(); + Assert.That(scene.ShuttingDown, Is.True); + } + } +} \ No newline at end of file