public SaveRegionToFile ( string description, string filename ) : void | ||
description | string | |
filename | string | |
return | void |
/// <summary> /// Create a new region. /// <summary> /// <param name="request">incoming XML RPC request</param> /// <remarks> /// XmlRpcCreateRegionMethod takes the following XMLRPC /// parameters /// <list type="table"> /// <listheader><term>parameter name</term><description>description</description></listheader> /// <item><term>password</term> /// <description>admin password as set in OpenSim.ini</description></item> /// <item><term>region_name</term> /// <description>desired region name</description></item> /// <item><term>region_id</term> /// <description>(optional) desired region UUID</description></item> /// <item><term>region_x</term> /// <description>desired region X coordinate (integer)</description></item> /// <item><term>region_y</term> /// <description>desired region Y coordinate (integer)</description></item> /// <item><term>estate_owner_first</term> /// <description>firstname of estate owner (formerly region master) /// (required if new estate is being created, optional otherwise)</description></item> /// <item><term>estate_owner_last</term> /// <description>lastname of estate owner (formerly region master) /// (required if new estate is being created, optional otherwise)</description></item> /// <item><term>estate_owner_uuid</term> /// <description>explicit UUID to use for estate owner (optional)</description></item> /// <item><term>listen_ip</term> /// <description>internal IP address (dotted quad)</description></item> /// <item><term>listen_port</term> /// <description>internal port (integer)</description></item> /// <item><term>external_address</term> /// <description>external IP address</description></item> /// <item><term>persist</term> /// <description>if true, persist the region info /// ('true' or 'false')</description></item> /// <item><term>public</term> /// <description>if true, the region is public /// ('true' or 'false') (optional, default: true)</description></item> /// <item><term>enable_voice</term> /// <description>if true, enable voice on all parcels, /// ('true' or 'false') (optional, default: false)</description></item> /// <item><term>estate_name</term> /// <description>the name of the estate to join (or to create if it doesn't /// already exist)</description></item> /// <item><term>region_file</term> /// <description>The name of the file to persist the region specifications to. /// If omitted, the region_file_template setting from OpenSim.ini will be used. (optional)</description></item> /// </list> /// /// XmlRpcCreateRegionMethod returns /// <list type="table"> /// <listheader><term>name</term><description>description</description></listheader> /// <item><term>success</term> /// <description>true or false</description></item> /// <item><term>error</term> /// <description>error message if success is false</description></item> /// <item><term>region_uuid</term> /// <description>UUID of the newly created region</description></item> /// <item><term>region_name</term> /// <description>name of the newly created region</description></item> /// </list> /// </remarks> public XmlRpcResponse XmlRpcCreateRegionMethod(XmlRpcRequest request, IPEndPoint remoteClient) { m_log.Info("[RADMIN]: CreateRegion: new request"); FailIfRemoteAdminDisabled("CreateRegion"); XmlRpcResponse response = new XmlRpcResponse(); Hashtable responseData = new Hashtable(); lock (m_requestLock) { int m_regionLimit = m_config.GetInt("region_limit", 0); bool m_enableVoiceForNewRegions = m_config.GetBoolean("create_region_enable_voice", false); bool m_publicAccess = m_config.GetBoolean("create_region_public", true); try { Hashtable requestData = (Hashtable) request.Params[0]; CheckStringParameters(request, new string[] { "password", "region_name", "listen_ip", "external_address", "estate_name" }); CheckIntegerParams(request, new string[] {"region_x", "region_y", "listen_port"}); // check password if (!String.IsNullOrEmpty(m_requiredPassword) && (string) requestData["password"] != m_requiredPassword) throw new Exception("wrong password"); // check whether we still have space left (iff we are using limits) if (m_regionLimit != 0 && m_application.SceneManager.Scenes.Count >= m_regionLimit) throw new Exception(String.Format("cannot instantiate new region, server capacity {0} already reached; delete regions first", m_regionLimit)); // extract or generate region ID now Scene scene = null; UUID regionID = UUID.Zero; if (requestData.ContainsKey("region_id") && !String.IsNullOrEmpty((string) requestData["region_id"])) { regionID = (UUID) (string) requestData["region_id"]; if (m_application.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 { regionID = UUID.Random(); m_log.DebugFormat("[RADMIN] CreateRegion: new region UUID {0}", regionID); } // create volatile or persistent region info 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"]); // check for collisions: region name, region UUID, // region location if (m_application.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_application.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)); region.InternalEndPoint = new IPEndPoint(IPAddress.Parse((string) requestData["listen_ip"]), 0); region.InternalEndPoint.Port = Convert.ToInt32(requestData["listen_port"]); if (0 == region.InternalEndPoint.Port) throw new Exception("listen_port is 0"); if (m_application.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"]; bool persist = Convert.ToBoolean((string) requestData["persist"]); if (persist) { // default place for region configuration files is in the // Regions directory of the config dir (aka /bin) string regionConfigPath = Path.Combine(Util.configDir(), "Regions"); try { // OpenSim.ini can specify a different regions dir IConfig startupConfig = (IConfig) m_configSource.Configs["Startup"]; regionConfigPath = startupConfig.GetString("regionload_regionsdir", regionConfigPath).Trim(); } catch (Exception) { // No INI setting recorded. } string regionIniPath; if (requestData.Contains("region_file")) { // Make sure that the file to be created is in a subdirectory of the region storage directory. string requestedFilePath = Path.Combine(regionConfigPath, (string) requestData["region_file"]); string requestedDirectory = Path.GetDirectoryName(Path.GetFullPath(requestedFilePath)); if (requestedDirectory.StartsWith(Path.GetFullPath(regionConfigPath))) regionIniPath = requestedFilePath; else throw new Exception("Invalid location for region file."); } else { regionIniPath = Path.Combine(regionConfigPath, String.Format( m_config.GetString("region_file_template", "{0}x{1}-{2}.ini"), region.RegionLocX.ToString(), region.RegionLocY.ToString(), regionID.ToString(), region.InternalEndPoint.Port.ToString(), region.RegionName.Replace(" ", "_").Replace(":", "_"). Replace("/", "_"))); } m_log.DebugFormat("[RADMIN] CreateRegion: persisting region {0} to {1}", region.RegionID, regionIniPath); region.SaveRegionToFile("dynamic region", regionIniPath); } else { region.Persistent = false; } // Set the estate // Check for an existing estate List<int> estateIDs = m_application.EstateDataService.GetEstates((string) requestData["estate_name"]); if (estateIDs.Count < 1) { UUID userID = UUID.Zero; if (requestData.ContainsKey("estate_owner_uuid")) { // ok, client wants us to use an explicit UUID // regardless of what the avatar name provided userID = new UUID((string) requestData["estate_owner_uuid"]); // Check that the specified user exists Scene currentOrFirst = m_application.SceneManager.CurrentOrFirstScene; IUserAccountService accountService = currentOrFirst.UserAccountService; UserAccount user = accountService.GetUserAccount(currentOrFirst.RegionInfo.ScopeID, userID); if (user == null) throw new Exception("Specified user was not found."); } else if (requestData.ContainsKey("estate_owner_first") & requestData.ContainsKey("estate_owner_last")) { // We need to look up the UUID for the avatar with the provided name. string ownerFirst = (string) requestData["estate_owner_first"]; string ownerLast = (string) requestData["estate_owner_last"]; Scene currentOrFirst = m_application.SceneManager.CurrentOrFirstScene; IUserAccountService accountService = currentOrFirst.UserAccountService; UserAccount user = accountService.GetUserAccount(currentOrFirst.RegionInfo.ScopeID, ownerFirst, ownerLast); // Check that the specified user exists if (user == null) throw new Exception("Specified user was not found."); userID = user.PrincipalID; } else { throw new Exception("Estate owner details not provided."); } // Create a new estate with the name provided region.EstateSettings = m_application.EstateDataService.CreateNewEstate(); region.EstateSettings.EstateName = (string) requestData["estate_name"]; region.EstateSettings.EstateOwner = userID; // Persistence does not seem to effect the need to save a new estate region.EstateSettings.Save(); if (!m_application.EstateDataService.LinkRegion(region.RegionID, (int) region.EstateSettings.EstateID)) throw new Exception("Failed to join estate."); } else { int estateID = estateIDs[0]; region.EstateSettings = m_application.EstateDataService.LoadEstateSettings(region.RegionID, false); if (region.EstateSettings.EstateID != estateID) { // The region is already part of an estate, but not the one we want. region.EstateSettings = m_application.EstateDataService.LoadEstateSettings(estateID); if (!m_application.EstateDataService.LinkRegion(region.RegionID, estateID)) throw new Exception("Failed to join estate."); } } // Create the region and perform any initial initialization IScene newScene; m_application.CreateRegion(region, out newScene); // If an access specification was provided, use it. // Otherwise accept the default. newScene.RegionInfo.EstateSettings.PublicAccess = GetBoolean(requestData, "public", m_publicAccess); newScene.RegionInfo.EstateSettings.Save(); // enable voice on newly created region if // requested by either the XmlRpc request or the // configuration if (GetBoolean(requestData, "enable_voice", m_enableVoiceForNewRegions)) { List<ILandObject> parcels = ((Scene)newScene).LandChannel.AllParcels(); foreach (ILandObject parcel in parcels) { parcel.LandData.Flags |= (uint) ParcelFlags.AllowVoiceChat; parcel.LandData.Flags |= (uint) ParcelFlags.UseEstateVoiceChan; ((Scene)newScene).LandChannel.UpdateLandObject(parcel.LandData.LocalID, parcel.LandData); } } responseData["success"] = true; responseData["region_name"] = region.RegionName; responseData["region_uuid"] = region.RegionID.ToString(); response.Value = responseData; } catch (Exception e) { m_log.ErrorFormat("[RADMIN] CreateRegion: failed {0} {1}", e.Message, e.StackTrace); responseData["success"] = false; responseData["error"] = e.Message; response.Value = responseData; } m_log.Info("[RADMIN]: CreateRegion: request complete"); return response; } }
/// <summary> /// Create a new region. /// <summary> /// <param name="request">incoming XML RPC request</param> /// <remarks> /// XmlRpcCreateRegionMethod takes the following XMLRPC /// parameters /// <list type="table"> /// <listheader><term>parameter name</term><description>description</description></listheader> /// <item><term>password</term> /// <description>admin password as set in OpenSim.ini</description></item> /// <item><term>region_name</term> /// <description>desired region name</description></item> /// <item><term>region_id</term> /// <description>(optional) desired region UUID</description></item> /// <item><term>region_x</term> /// <description>desired region X coordinate (integer)</description></item> /// <item><term>region_y</term> /// <description>desired region Y coordinate (integer)</description></item> /// <item><term>region_master_first</term> /// <description>firstname of region master</description></item> /// <item><term>region_master_last</term> /// <description>lastname of region master</description></item> /// <item><term>region_master_uuid</term> /// <description>explicit UUID to use for master avatar (optional)</description></item> /// <item><term>listen_ip</term> /// <description>internal IP address (dotted quad)</description></item> /// <item><term>listen_port</term> /// <description>internal port (integer)</description></item> /// <item><term>external_address</term> /// <description>external IP address</description></item> /// <item><term>persist</term> /// <description>if true, persist the region info /// ('true' or 'false')</description></item> /// <item><term>public</term> /// <description>if true, the region is public /// ('true' or 'false') (optional, default: true)</description></item> /// <item><term>enable_voice</term> /// <description>if true, enable voice on all parcels, /// ('true' or 'false') (optional, default: false)</description></item> /// </list> /// /// XmlRpcCreateRegionMethod returns /// <list type="table"> /// <listheader><term>name</term><description>description</description></listheader> /// <item><term>success</term> /// <description>true or false</description></item> /// <item><term>error</term> /// <description>error message if success is false</description></item> /// <item><term>region_uuid</term> /// <description>UUID of the newly created region</description></item> /// <item><term>region_name</term> /// <description>name of the newly created region</description></item> /// </list> /// </remarks> public XmlRpcResponse XmlRpcCreateRegionMethod(XmlRpcRequest request, IPEndPoint remoteClient) { m_log.Info("[RADMIN]: CreateRegion: new request"); FailIfRemoteAdminDisabled("CreateRegion"); XmlRpcResponse response = new XmlRpcResponse(); Hashtable responseData = new Hashtable(); lock (rslock) { int m_regionLimit = m_config.GetInt("region_limit", 0); bool m_enableVoiceForNewRegions = m_config.GetBoolean("create_region_enable_voice", false); bool m_publicAccess = m_config.GetBoolean("create_region_public", true); try { Hashtable requestData = (Hashtable) request.Params[0]; checkStringParameters(request, new string[] { "password", "region_name", "region_master_first", "region_master_last", "region_master_password", "listen_ip", "external_address" }); checkIntegerParams(request, new string[] {"region_x", "region_y", "listen_port"}); // check password if (!String.IsNullOrEmpty(m_requiredPassword) && (string) requestData["password"] != m_requiredPassword) throw new Exception("wrong password"); // check whether we still have space left (iff we are using limits) if (m_regionLimit != 0 && m_app.SceneManager.Scenes.Count >= m_regionLimit) throw new Exception(String.Format("cannot instantiate new region, server capacity {0} already reached; delete regions first", m_regionLimit)); // extract or generate region ID now Scene scene = null; UUID regionID = UUID.Zero; if (requestData.ContainsKey("region_id") && !String.IsNullOrEmpty((string) requestData["region_id"])) { regionID = (UUID) (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 { regionID = UUID.Random(); m_log.DebugFormat("[RADMIN] CreateRegion: new region UUID {0}", regionID); } // create volatile or persistent region info 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"]); // 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)); region.InternalEndPoint = new IPEndPoint(IPAddress.Parse((string) requestData["listen_ip"]), 0); region.InternalEndPoint.Port = Convert.ToInt32(requestData["listen_port"]); if (0 == region.InternalEndPoint.Port) throw new Exception("listen_port is 0"); 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"]; string masterFirst = (string) requestData["region_master_first"]; string masterLast = (string) requestData["region_master_last"]; string masterPassword = (string) requestData["region_master_password"]; UUID userID = UUID.Zero; if (requestData.ContainsKey("region_master_uuid")) { // ok, client wants us to use an explicit UUID // regardless of what the avatar name provided userID = new UUID((string) requestData["region_master_uuid"]); } else { if (masterFirst != String.Empty && masterLast != String.Empty) // User requests a master avatar { // no client supplied UUID: look it up... CachedUserInfo userInfo = m_app.CommunicationsManager.UserProfileCacheService.GetUserDetails( masterFirst, masterLast); if (null == userInfo) { m_log.InfoFormat("master avatar does not exist, creating it"); // ...or create new user userID = m_app.CommunicationsManager.UserAdminService.AddUser( masterFirst, masterLast, masterPassword, "", region.RegionLocX, region.RegionLocY); if (userID == UUID.Zero) throw new Exception(String.Format("failed to create new user {0} {1}", masterFirst, masterLast)); } else { userID = userInfo.UserProfile.ID; } } } region.MasterAvatarFirstName = masterFirst; region.MasterAvatarLastName = masterLast; region.MasterAvatarSandboxPassword = masterPassword; region.MasterAvatarAssignedUUID = userID; bool persist = Convert.ToBoolean((string) requestData["persist"]); if (persist) { // default place for region XML files is in the // Regions directory of the config dir (aka /bin) string regionConfigPath = Path.Combine(Util.configDir(), "Regions"); try { // OpenSim.ini can specify a different regions dir IConfig startupConfig = (IConfig) m_configSource.Configs["Startup"]; regionConfigPath = startupConfig.GetString("regionload_regionsdir", regionConfigPath).Trim(); } catch (Exception) { // No INI setting recorded. } string regionXmlPath = Path.Combine(regionConfigPath, String.Format( m_config.GetString("region_file_template", "{0}x{1}-{2}.xml"), region.RegionLocX.ToString(), region.RegionLocY.ToString(), regionID.ToString(), region.InternalEndPoint.Port.ToString(), region.RegionName.Replace(" ", "_").Replace(":", "_"). Replace("/", "_"))); m_log.DebugFormat("[RADMIN] CreateRegion: persisting region {0} to {1}", region.RegionID, regionXmlPath); region.SaveRegionToFile("dynamic region", regionXmlPath); } else { region.Persistent = false; } // Create the region and perform any initial initialization IScene newscene; m_app.CreateRegion(region, out newscene); // If an access specification was provided, use it. // Otherwise accept the default. newscene.RegionInfo.EstateSettings.PublicAccess = getBoolean(requestData, "public", m_publicAccess); if (persist) newscene.RegionInfo.EstateSettings.Save(); // enable voice on newly created region if // requested by either the XmlRpc request or the // configuration if (getBoolean(requestData, "enable_voice", m_enableVoiceForNewRegions)) { List<ILandObject> parcels = ((Scene)newscene).LandChannel.AllParcels(); foreach (ILandObject parcel in parcels) { parcel.LandData.Flags |= (uint) ParcelFlags.AllowVoiceChat; parcel.LandData.Flags |= (uint) ParcelFlags.UseEstateVoiceChan; ((Scene)newscene).LandChannel.UpdateLandObject(parcel.LandData.LocalID, parcel.LandData); } } responseData["success"] = true; responseData["region_name"] = region.RegionName; responseData["region_uuid"] = region.RegionID.ToString(); response.Value = responseData; } 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; response.Value = responseData; } m_log.Info("[RADMIN]: CreateRegion: request complete"); return response; } }