From 525ab2c2780d093e6f72d2054dca998620dd4629 Mon Sep 17 00:00:00 2001 From: Charles Krinke Date: Wed, 8 Jul 2009 20:53:22 +0000 Subject: [PATCH] Thank you kindly, RandomHuman for a patch that: The admin_close_region method removes a region from the simulator without deleting it. The region can then be recreated by calling admin_create_region with the same UUID. There is also a change to admin_create_region to facilitate this.The reason I want to have this functionality is to make it possible to detach regions when they are idle and recreate them on demand through a web interface. It's probably doable using the existing methods by saving and loading oars, but it also doesn't seem like that should be necessary. --- .../RemoteController/RemoteAdminPlugin.cs | 94 +++++++++++++++++++ OpenSim/Region/Application/OpenSimBase.cs | 31 ++++++ 2 files changed, 125 insertions(+) diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 23b1cc9970..99505340c5 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -107,6 +107,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController Dictionary availableMethods = new Dictionary(); availableMethods["admin_create_region"] = XmlRpcCreateRegionMethod; availableMethods["admin_delete_region"] = XmlRpcDeleteRegionMethod; + availableMethods["admin_close_region"] = XmlRpcCloseRegionMethod; availableMethods["admin_modify_region"] = XmlRpcModifyRegionMethod; availableMethods["admin_region_query"] = XmlRpcRegionQueryMethod; availableMethods["admin_shutdown"] = XmlRpcShutdownMethod; @@ -507,6 +508,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController RegionInfo region = new RegionInfo(); region.RegionID = regionID; + region.originRegionID = regionID; region.RegionName = (string) requestData["region_name"]; region.RegionLocX = Convert.ToUInt32(requestData["region_x"]); region.RegionLocY = Convert.ToUInt32(requestData["region_y"]); @@ -735,6 +737,98 @@ namespace OpenSim.ApplicationPlugins.RemoteController return response; } } + + /// + /// Close a region. + /// + /// incoming XML RPC request + /// + /// XmlRpcCloseRegionMethod takes the following XMLRPC + /// parameters + /// + /// parameter namedescription + /// password + /// admin password as set in OpenSim.ini + /// region_name + /// desired region name + /// region_id + /// (optional) desired region UUID + /// + /// + /// XmlRpcShutdownRegionMethod returns + /// + /// namedescription + /// success + /// true or false + /// region_name + /// the region name if success is true + /// error + /// error message if success is false + /// + /// + public XmlRpcResponse XmlRpcCloseRegionMethod(XmlRpcRequest request, IPEndPoint remoteClient) + { + m_log.Info("[RADMIN]: CloseRegion: new request"); + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable responseData = new Hashtable(); + Scene scene = null; + + lock (rslock) + { + try + { + Hashtable requestData = (Hashtable) request.Params[0]; + checkStringParameters(request, new string[] {"password"}); + + if (requestData.ContainsKey("region_id") && + !String.IsNullOrEmpty((string) requestData["region_id"])) + { + // Region specified by UUID + UUID regionID = (UUID) (string) requestData["region_id"]; + if (!m_app.SceneManager.TryGetScene(regionID, out scene)) + throw new Exception(String.Format("region \"{0}\" does not exist", regionID)); + + m_app.CloseRegion(scene); + + responseData["success"] = true; + responseData["region_id"] = regionID; + + response.Value = responseData; + } + else if (requestData.ContainsKey("region_name") && + !String.IsNullOrEmpty((string) requestData["region_name"])) + { + // Region specified by name + + string regionName = (string) requestData["region_name"]; + if (!m_app.SceneManager.TryGetScene(regionName, out scene)) + throw new Exception(String.Format("region \"{0}\" does not exist", regionName)); + + m_app.CloseRegion(scene); + + responseData["success"] = true; + responseData["region_name"] = regionName; + + response.Value = responseData; + } + else + throw new Exception("no region specified"); + } + catch (Exception e) + { + m_log.ErrorFormat("[RADMIN] CloseRegion: failed {0}", e.Message); + m_log.DebugFormat("[RADMIN] CloseRegion: failed {0}", e.ToString()); + + responseData["success"] = false; + responseData["error"] = e.Message; + + response.Value = responseData; + } + + m_log.Info("[RADMIN]: CloseRegion: request complete"); + return response; + } + } /// /// Change characteristics of an existing region. diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 9e3dafb394..a42fd3dcee 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -503,6 +503,37 @@ namespace OpenSim RemoveRegion(target, cleanUp); } + /// + /// Remove a region from the simulator without deleting it permanently. + /// + /// + /// + public void CloseRegion(Scene scene) + { + // only need to check this if we are not at the + // root level + if ((m_sceneManager.CurrentScene != null) && + (m_sceneManager.CurrentScene.RegionInfo.RegionID == scene.RegionInfo.RegionID)) + { + m_sceneManager.TrySetCurrentScene(".."); + } + + m_sceneManager.CloseScene(scene); + + } + + /// + /// Remove a region from the simulator without deleting it permanently. + /// + /// + /// + public void CloseRegion(string name) + { + Scene target; + if (m_sceneManager.TryGetScene(name, out target)) + CloseRegion(target); + } + /// /// Create a scene and its initial base structures. ///