From b3892096f3bbdb3310abd9feb341b3a040bbf081 Mon Sep 17 00:00:00 2001 From: Justin Clarke Casey Date: Fri, 11 Apr 2008 15:00:41 +0000 Subject: * From: Dr Scofield * This patch adds support for saving a dynamically generated region to the filesystem (as a region xml file) * Also adds some error checknig to make sure the dynamically generated region name, id or location are not already taken. * Thanks Dr Scofield --- .../RemoteController/RemoteAdminPlugin.cs | 97 ++++++++++++++-------- OpenSim/Framework/RegionInfo.cs | 61 +++++++++++++- OpenSim/Region/Environment/Scenes/SceneManager.cs | 32 +++++++ 3 files changed, 155 insertions(+), 35 deletions(-) diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 9d4bfea..f1b3ade 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -282,7 +282,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions /// public XmlRpcResponse XmlRpcCreateRegionMethod(XmlRpcRequest request) { - m_log.Info("[RADMIN]: Received Create Region Administrator Request"); + m_log.Info("[RADMIN]: CreateRegion: new request"); XmlRpcResponse response = new XmlRpcResponse(); Hashtable requestData = (Hashtable) request.Params[0]; Hashtable responseData = new Hashtable(); @@ -291,7 +291,8 @@ namespace OpenSim.ApplicationPlugins.LoadRegions // check completeness foreach (string p in new string[] { "password", "region_name", "region_x", "region_y", - "region_master_first", "region_master_last", + "region_master_first", "region_master_last", + "region_master_password", "listen_ip", "listen_port", "external_address"}) { if (!requestData.Contains(p)) @@ -302,51 +303,79 @@ namespace OpenSim.ApplicationPlugins.LoadRegions if (!String.IsNullOrEmpty(requiredPassword) && (string)requestData["password"] != requiredPassword) throw new Exception("wrong password"); - // bool persist = Convert.ToBoolean((string)requestData["persist"]); - RegionInfo region = null; - // if (!persist) - // { - // region = new RegionInfo(); - // } - // else - // { - // region = new RegionInfo("DEFAULT REGION CONFIG", - // Path.Combine(regionConfigPath, "default.xml"), false); - // } - region = new RegionInfo(); - - + // extract or generate region ID now + Scene scene = null; + LLUUID regionID = LLUUID.Zero; if (requestData.ContainsKey("region_id") && - !String.IsNullOrEmpty((string) requestData["region_id"])) + !String.IsNullOrEmpty((string)requestData["region_id"])) { - // FIXME: need to check whether region_id already - // in use - region.RegionID = (string) requestData["region_id"]; + regionID = (string) requestData["region_id"]; + if (m_app.SceneManager.TryGetScene(regionID, out scene)) + throw new Exception(String.Format("region UUID already in use by region {0}, UUID {1}, <{2},{3}>", + scene.RegionInfo.RegionName, scene.RegionInfo.RegionID, + scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY)); } else { - region.RegionID = LLUUID.Random(); + regionID = LLUUID.Random(); + m_log.DebugFormat("[RADMIN] CreateRegion: new region UUID {0}", regionID); } - // FIXME: need to check whether region_name already - // in use + // create volatile or persistent region info + RegionInfo region = new RegionInfo(); + + region.RegionID = regionID; region.RegionName = (string) requestData["region_name"]; region.RegionLocX = Convert.ToUInt32((Int32) requestData["region_x"]); region.RegionLocY = Convert.ToUInt32((Int32) requestData["region_y"]); + + // check for collisions: region name, region UUID, + // region location + if (m_app.SceneManager.TryGetScene(region.RegionName, out scene)) + throw new Exception(String.Format("region name already in use by region {0}, UUID {1}, <{2},{3}>", + scene.RegionInfo.RegionName, scene.RegionInfo.RegionID, + scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY)); + + if (m_app.SceneManager.TryGetScene(region.RegionLocX, region.RegionLocY, out scene)) + throw new Exception(String.Format("region location <{0},{1}> already in use by region {2}, UUID {3}, <{4},{5}>", + region.RegionLocX, region.RegionLocY, + scene.RegionInfo.RegionName, scene.RegionInfo.RegionID, + scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY)); - // Security risk - if (requestData.ContainsKey("datastore")) - region.DataStore = (string) requestData["datastore"]; + // Security risk [and apparently not used] + // if (requestData.ContainsKey("datastore")) + // region.DataStore = (string) requestData["datastore"]; region.InternalEndPoint = new IPEndPoint(IPAddress.Parse((string) requestData["listen_ip"]), 0); - // FIXME: need to check whether listen_port already in use! region.InternalEndPoint.Port = (Int32) requestData["listen_port"]; + if (m_app.SceneManager.TryGetScene(region.InternalEndPoint, out scene)) + throw new Exception(String.Format("region internal IP {0} and port {1} already in use by region {2}, UUID {3}, <{4},{5}>", + region.InternalEndPoint.Address, + region.InternalEndPoint.Port, + scene.RegionInfo.RegionName, scene.RegionInfo.RegionID, + scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY)); + + region.ExternalHostName = (string) requestData["external_address"]; region.MasterAvatarFirstName = (string) requestData["region_master_first"]; region.MasterAvatarLastName = (string) requestData["region_master_last"]; + region.MasterAvatarSandboxPassword = (string) requestData["region_master_password"]; + + bool persist = Convert.ToBoolean((string)requestData["persist"]); + if (persist) + { + string regionConfigPath = Path.Combine(Path.Combine(Util.configDir(), "Regions"), + String.Format("{0}x{1}-{2}.xml", + region.RegionLocX.ToString(), + region.RegionLocY.ToString(), + regionID.ToString())); + m_log.DebugFormat("[RADMIN] CreateRegion: persisting region {0} to {1}", + region.RegionID, regionConfigPath); + region.SaveRegionToFile("dynamic region", regionConfigPath); + } m_app.CreateRegion(region, true); @@ -358,6 +387,9 @@ namespace OpenSim.ApplicationPlugins.LoadRegions } catch (Exception e) { + m_log.ErrorFormat("[RADMIN] CreateRegion: failed {0}", e.Message); + m_log.DebugFormat("[RADMIN] CreateRegion: failed {0}", e.ToString()); + responseData["success"] = "false"; responseData["error"] = e.Message; @@ -405,7 +437,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions /// public XmlRpcResponse XmlRpcCreateUserMethod(XmlRpcRequest request) { - m_log.Info("[RADMIN]: Received Create User Administrator Request"); + m_log.Info("[RADMIN]: CreateUser: new request"); XmlRpcResponse response = new XmlRpcResponse(); Hashtable requestData = (Hashtable) request.Params[0]; Hashtable responseData = new Hashtable(); @@ -444,12 +476,12 @@ namespace OpenSim.ApplicationPlugins.LoadRegions response.Value = responseData; - m_log.InfoFormat("[RADMIN]: User {0} {1} created, UUID {2}", firstname, lastname, userID); + m_log.InfoFormat("[RADMIN]: CreateUser: User {0} {1} created, UUID {2}", firstname, lastname, userID); } catch (Exception e) { - m_log.ErrorFormat("[RADMIN] create user: failed: {0}", e.Message); - m_log.DebugFormat("[RADMIN] create user: failed: {0}", e.ToString()); + m_log.ErrorFormat("[RADMIN] CreateUser: failed: {0}", e.Message); + m_log.DebugFormat("[RADMIN] CreateUser: failed: {0}", e.ToString()); responseData["success"] = "false"; responseData["avatar_uuid"] = LLUUID.Zero.ToString(); @@ -471,8 +503,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions try { // check completeness - foreach (string p in new string[] { "password", - "region_name", "filename" }) + foreach (string p in new string[] { "password", "region_name", "filename" }) { if (!requestData.Contains(p)) throw new Exception(String.Format("missing parameter {0}", p)); diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs index 7f284d3..da20edc 100644 --- a/OpenSim/Framework/RegionInfo.cs +++ b/OpenSim/Framework/RegionInfo.cs @@ -38,8 +38,8 @@ namespace OpenSim.Framework [Serializable] public class SimpleRegionInfo { -// private static readonly log4net.ILog m_log -// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + // private static readonly log4net.ILog m_log + // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); public SimpleRegionInfo() { @@ -200,6 +200,9 @@ namespace OpenSim.Framework public class RegionInfo : SimpleRegionInfo { + // private static readonly log4net.ILog m_log + // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + public string RegionName = String.Empty; public string DataStore = String.Empty; @@ -343,6 +346,60 @@ namespace OpenSim.Framework } } + public bool ignoreIncomingConfiguration(string configuration_key, object configuration_result) + { + return true; + } + + public void SaveRegionToFile(string description, string filename) { + configMember = new ConfigurationMember(filename, description, loadConfigurationOptionsFromMe, + ignoreIncomingConfiguration, false); + configMember.performConfigurationRetrieve(); + } + + public void loadConfigurationOptionsFromMe() + { + configMember.addConfigurationOption("sim_UUID", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, + "UUID of Region (Default is recommended, random UUID)", + RegionID.ToString(), true); + configMember.addConfigurationOption("sim_name", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "Region Name", RegionName, true); + configMember.addConfigurationOption("sim_location_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Grid Location (X Axis)", m_regionLocX.ToString(), true); + configMember.addConfigurationOption("sim_location_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, + "Grid Location (Y Axis)", m_regionLocY.ToString(), true); + //configMember.addConfigurationOption("datastore", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Filename for local storage", "OpenSim.db", false); + configMember.addConfigurationOption("internal_ip_address", + ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS, + "Internal IP Address for incoming UDP client connections", + m_internalEndPoint.Address.ToString(), + true); + configMember.addConfigurationOption("internal_ip_port", ConfigurationOption.ConfigurationTypes.TYPE_INT32, + "Internal IP Port for incoming UDP client connections", + m_internalEndPoint.Port.ToString(), true); + configMember.addConfigurationOption("allow_alternate_ports", + ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN, + "Allow sim to find alternate UDP ports when ports are in use?", + m_allow_alternate_ports.ToString(), true); + configMember.addConfigurationOption("external_host_name", + ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "External Host Name", m_externalHostName, true); + configMember.addConfigurationOption("master_avatar_uuid", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, + "Master Avatar UUID", MasterAvatarAssignedUUID.ToString(), true); + configMember.addConfigurationOption("estate_covanant_uuid", + ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, "Estate Covenant", + CovenantID.ToString(), true); + configMember.addConfigurationOption("master_avatar_first", + ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "First Name of Master Avatar", MasterAvatarFirstName, true); + configMember.addConfigurationOption("master_avatar_last", + ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, + "Last Name of Master Avatar", MasterAvatarLastName, true); + configMember.addConfigurationOption("master_avatar_pass", ConfigurationOption.ConfigurationTypes.TYPE_STRING, + "(Sandbox Mode Only)Password for Master Avatar account", + MasterAvatarSandboxPassword, true); + } + public void loadConfigurationOptions() { configMember.addConfigurationOption("sim_UUID", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, diff --git a/OpenSim/Region/Environment/Scenes/SceneManager.cs b/OpenSim/Region/Environment/Scenes/SceneManager.cs index 62994df..fbaf655 100644 --- a/OpenSim/Region/Environment/Scenes/SceneManager.cs +++ b/OpenSim/Region/Environment/Scenes/SceneManager.cs @@ -27,6 +27,8 @@ using System; using System.Collections.Generic; +using System.Net; +using System.Net.Sockets; using libsecondlife; using OpenSim.Framework; using OpenSim.Framework.Console; @@ -276,6 +278,36 @@ namespace OpenSim.Region.Environment.Scenes 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.Address == ipEndPoint.Address && + mscene.RegionInfo.InternalEndPoint.Port == ipEndPoint.Port) + { + scene = mscene; + return true; + } + } + scene = null; + return false; + } + public void SetDebugPacketOnCurrentScene(int newDebug) { ForEachCurrentScene(delegate(Scene scene) -- cgit v1.1