Files
opensim/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
Dr Scofield d0753ad9ef From: Alan Webb <alan_webb@us.ibm.com>
Added two new (optional) attributes to create_user and update_user
  requests.

  <gender> - can be 'm' or 'f'. 'm' is default if not specified.
  <model>  - specifies another, existing, avatar that should be used
             as an appearance prototype for this user.

  If <model> is specified, then <gender> is ignored. If <model> is not
  specified, then 'm' implies a model avatar of "Default Male", and 'f'
  implies a default of "Default Female".

  At the moment the inventory is not copied. This change means that an
  avatar will only look like ruth if none of the possible models exist
  in the user database.
2009-04-29 09:35:35 +00:00

1998 lines
90 KiB
C#

/*
* 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;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Reflection;
using System.Timers;
using log4net;
using Nini.Config;
using Nwc.XmlRpc;
using OpenMetaverse;
using OpenSim;
using OpenSim.Framework;
using OpenSim.Framework.Communications.Cache;
using OpenSim.Framework.Console;
using OpenSim.Framework.Servers;
using OpenSim.Region.CoreModules.World.Terrain;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
namespace OpenSim.ApplicationPlugins.RemoteController
{
public class RemoteAdminPlugin : IApplicationPlugin
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static Object rslock = new Object();
private OpenSimBase m_app;
private BaseHttpServer m_httpd;
private IConfig m_config;
private IConfigSource m_configSource;
private string m_requiredPassword = String.Empty;
// TODO: required by IPlugin, but likely not at all right
private string m_name = "RemoteAdminPlugin";
private string m_version = "0.0";
public string Version
{
get { return m_version; }
}
public string Name
{
get { return m_name; }
}
public void Initialise()
{
m_log.Info("[RADMIN]: " + Name + " cannot be default-initialized!");
throw new PluginNotInitialisedException(Name);
}
public void Initialise(OpenSimBase openSim)
{
m_configSource = openSim.ConfigSource.Source;
try
{
if (m_configSource.Configs["RemoteAdmin"] == null ||
!m_configSource.Configs["RemoteAdmin"].GetBoolean("enabled", false))
{
// No config or disabled
}
else
{
m_config = m_configSource.Configs["RemoteAdmin"];
m_log.Info("[RADMIN]: Remote Admin Plugin Enabled");
m_requiredPassword = m_config.GetString("access_password", String.Empty);
m_app = openSim;
m_httpd = openSim.HttpServer;
Dictionary<string, XmlRpcMethod> availableMethods = new Dictionary<string, XmlRpcMethod>();
availableMethods["admin_create_region"] = XmlRpcCreateRegionMethod;
availableMethods["admin_delete_region"] = XmlRpcDeleteRegionMethod;
availableMethods["admin_modify_region"] = XmlRpcModifyRegionMethod;
availableMethods["admin_region_query"] = XmlRpcRegionQueryMethod;
availableMethods["admin_shutdown"] = XmlRpcShutdownMethod;
availableMethods["admin_broadcast"] = XmlRpcAlertMethod;
availableMethods["admin_restart"] = XmlRpcRestartMethod;
availableMethods["admin_load_heightmap"] = XmlRpcLoadHeightmapMethod;
// User management
availableMethods["admin_create_user"] = XmlRpcCreateUserMethod;
availableMethods["admin_create_user_email"] = XmlRpcCreateUserMethod;
availableMethods["admin_exists_user"] = XmlRpcUserExistsMethod;
availableMethods["admin_update_user"] = XmlRpcUpdateUserAccountMethod;
// Region state management
availableMethods["admin_load_xml"] = XmlRpcLoadXMLMethod;
availableMethods["admin_save_xml"] = XmlRpcSaveXMLMethod;
availableMethods["admin_load_oar"] = XmlRpcLoadOARMethod;
availableMethods["admin_save_oar"] = XmlRpcSaveOARMethod;
// Estate access list management
availableMethods["admin_acl_clear"] = XmlRpcAccessListClear;
availableMethods["admin_acl_add"] = XmlRpcAccessListAdd;
availableMethods["admin_acl_remove"] = XmlRpcAccessListRemove;
availableMethods["admin_acl_list"] = XmlRpcAccessListList;
// Either enable full remote functionality or just selected features
string enabledMethods = m_config.GetString("enabled_methods", "all");
// To get this, you must explicitly specify "all" or
// mention it in a whitelist. It won't be available
// If you just leave the option out!
//
if (!String.IsNullOrEmpty(enabledMethods))
availableMethods["admin_console_command"] = XmlRpcConsoleCommandMethod;
// The assumption here is that simply enabling Remote Admin as before will produce the same
// behavior - enable all methods unless the whitelist is in place for backward-compatibility.
if (enabledMethods.ToLower() == "all" || String.IsNullOrEmpty(enabledMethods))
{
foreach (string method in availableMethods.Keys)
{
m_httpd.AddXmlRPCHandler(method, availableMethods[method], false);
}
}
else
{
foreach (string enabledMethod in enabledMethods.Split('|'))
{
m_httpd.AddXmlRPCHandler(enabledMethod, availableMethods[enabledMethod]);
}
}
}
}
catch (NullReferenceException)
{
// Ignore.
}
}
public void PostInitialise()
{
}
public XmlRpcResponse XmlRpcRestartMethod(XmlRpcRequest request)
{
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
try
{
Hashtable requestData = (Hashtable) request.Params[0];
m_log.Info("[RADMIN]: Request to restart Region.");
checkStringParameters(request, new string[] {"password", "regionID"});
if (m_requiredPassword != String.Empty &&
(!requestData.Contains("password") || (string) requestData["password"] != m_requiredPassword))
{
throw new Exception("wrong password");
}
UUID regionID = new UUID((string) requestData["regionID"]);
responseData["accepted"] = "true";
responseData["success"] = "true";
response.Value = responseData;
Scene rebootedScene;
if (!m_app.SceneManager.TryGetScene(regionID, out rebootedScene))
throw new Exception("region not found");
responseData["rebooting"] = "true";
response.Value = responseData;
rebootedScene.Restart(30);
}
catch (Exception e)
{
m_log.ErrorFormat("[RADMIN]: Restart region: failed: {0}", e.Message);
m_log.DebugFormat("[RADMIN]: Restart region: failed: {0}", e.ToString());
responseData["accepted"] = "false";
responseData["success"] = "false";
responseData["rebooting"] = "false";
responseData["error"] = e.Message;
response.Value = responseData;
}
m_log.Info("[RADMIN]: Restart Region request complete");
return response;
}
public XmlRpcResponse XmlRpcAlertMethod(XmlRpcRequest request)
{
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
m_log.Info("[RADMIN]: Alert request started");
try
{
Hashtable requestData = (Hashtable) request.Params[0];
checkStringParameters(request, new string[] {"password", "message"});
if (m_requiredPassword != String.Empty &&
(!requestData.Contains("password") || (string) requestData["password"] != m_requiredPassword))
throw new Exception("wrong password");
string message = (string) requestData["message"];
m_log.InfoFormat("[RADMIN]: Broadcasting: {0}", message);
responseData["accepted"] = "true";
responseData["success"] = "true";
response.Value = responseData;
m_app.SceneManager.ForEachScene(
delegate(Scene scene)
{
IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
if (dialogModule != null)
dialogModule.SendGeneralAlert(message);
});
}
catch (Exception e)
{
m_log.ErrorFormat("[RADMIN]: Broadcasting: failed: {0}", e.Message);
m_log.DebugFormat("[RADMIN]: Broadcasting: failed: {0}", e.ToString());
responseData["accepted"] = "false";
responseData["success"] = "false";
responseData["error"] = e.Message;
response.Value = responseData;
}
m_log.Info("[RADMIN]: Alert request complete");
return response;
}
public XmlRpcResponse XmlRpcLoadHeightmapMethod(XmlRpcRequest request)
{
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
m_log.Info("[RADMIN]: Load height maps request started");
try
{
Hashtable requestData = (Hashtable) request.Params[0];
m_log.DebugFormat("[RADMIN]: Load Terrain: XmlRpc {0}", request.ToString());
// foreach (string k in requestData.Keys)
// {
// m_log.DebugFormat("[RADMIN]: Load Terrain: XmlRpc {0}: >{1}< {2}",
// k, (string)requestData[k], ((string)requestData[k]).Length);
// }
checkStringParameters(request, new string[] {"password", "filename", "regionid"});
if (m_requiredPassword != String.Empty &&
(!requestData.Contains("password") || (string) requestData["password"] != m_requiredPassword))
throw new Exception("wrong password");
string file = (string) requestData["filename"];
UUID regionID = (UUID) (string) requestData["regionid"];
m_log.InfoFormat("[RADMIN]: Terrain Loading: {0}", file);
responseData["accepted"] = "true";
Scene region = null;
if (!m_app.SceneManager.TryGetScene(regionID, out region))
throw new Exception("1: unable to get a scene with that name");
ITerrainModule terrainModule = region.RequestModuleInterface<ITerrainModule>();
if (null == terrainModule) throw new Exception("terrain module not available");
terrainModule.LoadFromFile(file);
responseData["success"] = "true";
response.Value = responseData;
}
catch (Exception e)
{
m_log.ErrorFormat("[RADMIN] Terrain Loading: failed: {0}", e.Message);
m_log.DebugFormat("[RADMIN] Terrain Loading: failed: {0}", e.ToString());
responseData["success"] = "false";
responseData["error"] = e.Message;
}
m_log.Info("[RADMIN]: Load height maps request complete");
return response;
}
public XmlRpcResponse XmlRpcShutdownMethod(XmlRpcRequest request)
{
m_log.Info("[RADMIN]: Received Shutdown Administrator Request");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
try
{
Hashtable requestData = (Hashtable) request.Params[0];
if (m_requiredPassword != String.Empty &&
(!requestData.Contains("password") || (string) requestData["password"] != m_requiredPassword))
throw new Exception("wrong password");
responseData["accepted"] = "true";
response.Value = responseData;
int timeout = 2000;
string message;
if (requestData.ContainsKey("shutdown")
&& ((string) requestData["shutdown"] == "delayed")
&& requestData.ContainsKey("milliseconds"))
{
timeout = (Int32) requestData["milliseconds"];
message
= "Region is going down in " + ((int) (timeout/1000)).ToString()
+ " second(s). Please save what you are doing and log out.";
}
else
{
message = "Region is going down now.";
}
m_app.SceneManager.ForEachScene(
delegate(Scene scene)
{
IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
if (dialogModule != null)
dialogModule.SendGeneralAlert(message);
});
// Perform shutdown
Timer shutdownTimer = new Timer(timeout); // Wait before firing
shutdownTimer.AutoReset = false;
shutdownTimer.Elapsed += new ElapsedEventHandler(shutdownTimer_Elapsed);
shutdownTimer.Start();
responseData["success"] = "true";
}
catch (Exception e)
{
m_log.ErrorFormat("[RADMIN] Shutdown: failed: {0}", e.Message);
m_log.DebugFormat("[RADMIN] Shutdown: failed: {0}", e.ToString());
responseData["accepted"] = "false";
responseData["error"] = e.Message;
response.Value = responseData;
}
m_log.Info("[RADMIN]: Shutdown Administrator Request complete");
return response;
}
private void shutdownTimer_Elapsed(object sender, ElapsedEventArgs e)
{
m_app.Shutdown();
}
private static void checkStringParameters(XmlRpcRequest request, string[] param)
{
Hashtable requestData = (Hashtable) request.Params[0];
foreach (string p in param)
{
if (!requestData.Contains(p))
throw new Exception(String.Format("missing string parameter {0}", p));
if (String.IsNullOrEmpty((string) requestData[p]))
throw new Exception(String.Format("parameter {0} is empty", p));
}
}
private static void checkIntegerParams(XmlRpcRequest request, string[] param)
{
Hashtable requestData = (Hashtable) request.Params[0];
foreach (string p in param)
{
if (!requestData.Contains(p))
throw new Exception(String.Format("missing integer parameter {0}", p));
}
}
private bool getBoolean(Hashtable requestData, string tag, bool defv)
{
// If an access value has been provided, apply it.
if(requestData.Contains(tag))
{
switch(((string)requestData[tag]).ToLower())
{
case "true" :
case "t" :
case "1" :
return true;
case "false" :
case "f" :
case "0" :
return false;
default :
return defv;
}
}
else
return defv;
}
/// <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)
{
m_log.Info("[RADMIN]: CreateRegion: new request");
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.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
{
// 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);
}
// 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);
// 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) Parcel.ParcelFlags.AllowVoiceChat;
parcel.landData.Flags |= (uint) Parcel.ParcelFlags.UseEstateVoiceChan;
}
}
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;
}
}
/// <summary>
/// Delete a new region.
/// <summary>
/// <param name="request">incoming XML RPC request</param>
/// <remarks>
/// XmlRpcDeleteRegionMethod 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>
/// </list>
///
/// XmlRpcDeleteRegionMethod 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>
/// </list>
/// </remarks>
public XmlRpcResponse XmlRpcDeleteRegionMethod(XmlRpcRequest request)
{
m_log.Info("[RADMIN]: DeleteRegion: new request");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
lock (rslock)
{
try
{
Hashtable requestData = (Hashtable) request.Params[0];
checkStringParameters(request, new string[] {"password", "region_name"});
Scene scene = null;
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.RemoveRegion(scene, true);
responseData["success"] = "true";
responseData["region_name"] = regionName;
response.Value = responseData;
}
catch (Exception e)
{
m_log.ErrorFormat("[RADMIN] DeleteRegion: failed {0}", e.Message);
m_log.DebugFormat("[RADMIN] DeleteRegion: failed {0}", e.ToString());
responseData["success"] = "false";
responseData["error"] = e.Message;
response.Value = responseData;
}
m_log.Info("[RADMIN]: DeleteRegion: request complete");
return response;
}
}
/// <summary>
/// Change characteristics of an existing region.
/// <summary>
/// <param name="request">incoming XML RPC request</param>
/// <remarks>
/// XmlRpcModifyRegionMethod 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>public</term>
/// <description>if true, set the region to public
/// ('true' or 'false'), else to private</description></item>
/// <item><term>enable_voice</term>
/// <description>if true, enable voice on all parcels of
/// the region, else disable</description></item>
/// </list>
///
/// XmlRpcModifyRegionMethod 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>
/// </list>
/// </remarks>
public XmlRpcResponse XmlRpcModifyRegionMethod(XmlRpcRequest request)
{
m_log.Info("[RADMIN]: ModifyRegion: new request");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
lock (rslock)
{
try
{
Hashtable requestData = (Hashtable) request.Params[0];
checkStringParameters(request, new string[] {"password", "region_name"});
Scene scene = null;
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));
// Modify access
scene.RegionInfo.EstateSettings.PublicAccess =
getBoolean(requestData,"public", scene.RegionInfo.EstateSettings.PublicAccess);
if (requestData.ContainsKey("enable_voice"))
{
bool enableVoice = getBoolean(requestData, "enable_voice", true);
List<ILandObject> parcels = ((Scene)scene).LandChannel.AllParcels();
foreach(ILandObject parcel in parcels)
{
if (enableVoice)
{
parcel.landData.Flags |= (uint)Parcel.ParcelFlags.AllowVoiceChat;
parcel.landData.Flags |= (uint)Parcel.ParcelFlags.UseEstateVoiceChan;
}
else
{
parcel.landData.Flags &= ~(uint)Parcel.ParcelFlags.AllowVoiceChat;
parcel.landData.Flags &= ~(uint)Parcel.ParcelFlags.UseEstateVoiceChan;
}
}
}
responseData["success"] = "true";
responseData["region_name"] = regionName;
response.Value = responseData;
}
catch (Exception e)
{
m_log.ErrorFormat("[RADMIN] ModifyRegion: failed {0}", e.Message);
m_log.DebugFormat("[RADMIN] ModifyRegion: failed {0}", e.ToString());
responseData["success"] = "false";
responseData["error"] = e.Message;
response.Value = responseData;
}
m_log.Info("[RADMIN]: ModifyRegion: request complete");
return response;
}
}
/// <summary>
/// Create a new user account.
/// <summary>
/// <param name="request">incoming XML RPC request</param>
/// <remarks>
/// XmlRpcCreateUserMethod 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>user_firstname</term>
/// <description>avatar's first name</description></item>
/// <item><term>user_lastname</term>
/// <description>avatar's last name</description></item>
/// <item><term>user_password</term>
/// <description>avatar's password</description></item>
/// <item><term>user_email</term>
/// <description>email of the avatar's owner (optional)</description></item>
/// <item><term>start_region_x</term>
/// <description>avatar's start region coordinates, X value</description></item>
/// <item><term>start_region_y</term>
/// <description>avatar's start region coordinates, Y value</description></item>
/// </list>
///
/// XmlRpcCreateUserMethod 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>avatar_uuid</term>
/// <description>UUID of the newly created avatar
/// account; UUID.Zero if failed.
/// </description></item>
/// </list>
/// </remarks>
public XmlRpcResponse XmlRpcCreateUserMethod(XmlRpcRequest request)
{
m_log.Info("[RADMIN]: CreateUser: new request");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
lock (rslock)
{
try
{
Hashtable requestData = (Hashtable) request.Params[0];
// check completeness
checkStringParameters(request, new string[]
{
"password", "user_firstname",
"user_lastname", "user_password",
});
checkIntegerParams(request, new string[] {"start_region_x", "start_region_y"});
// check password
if (!String.IsNullOrEmpty(m_requiredPassword) &&
(string) requestData["password"] != m_requiredPassword) throw new Exception("wrong password");
// do the job
string firstname = (string) requestData["user_firstname"];
string lastname = (string) requestData["user_lastname"];
string passwd = (string) requestData["user_password"];
uint regX = Convert.ToUInt32((Int32) requestData["start_region_x"]);
uint regY = Convert.ToUInt32((Int32) requestData["start_region_y"]);
string email = ""; // empty string for email
if (requestData.Contains("user_email"))
email = (string)requestData["user_email"];
CachedUserInfo userInfo =
m_app.CommunicationsManager.UserProfileCacheService.GetUserDetails(firstname, lastname);
if (null != userInfo)
throw new Exception(String.Format("Avatar {0} {1} already exists", firstname, lastname));
UUID userID =
m_app.CommunicationsManager.UserAdminService.AddUser(firstname, lastname,
passwd, email, regX, regY);
if (userID == UUID.Zero)
throw new Exception(String.Format("failed to create new user {0} {1}",
firstname, lastname));
// User has been created. Now establish gender and appearance.
// Default appearance is 'Default Male'. Specifying gender can
// establish "Default Female". Specifying a specific model can
// establish a specific appearance without regard for gender.
try
{
string model = "Default Male";
if (requestData.Contains("gender"))
if ((string)requestData["gender"] == "f")
model = "Default Female";
if (requestData.Contains("model"))
model = (string)requestData["model"];
string[] uname = model.Split();
UserProfileData udata = m_app.CommunicationsManager.UserService.GetUserProfile(uname[0],uname[1]);
AvatarAppearance ava = m_app.CommunicationsManager.AvatarService.GetUserAppearance(udata.ID);
m_app.CommunicationsManager.AvatarService.UpdateUserAppearance(userID, ava);
}
catch (Exception e)
{
m_log.ErrorFormat("[RADMIN] Error establishing initial appearance : {0}", e.Message);
}
responseData["success"] = "true";
responseData["avatar_uuid"] = userID.ToString();
response.Value = responseData;
m_log.InfoFormat("[RADMIN]: CreateUser: User {0} {1} created, UUID {2}", firstname, lastname, userID);
}
catch (Exception e)
{
m_log.ErrorFormat("[RADMIN] CreateUser: failed: {0}", e.Message);
m_log.DebugFormat("[RADMIN] CreateUser: failed: {0}", e.ToString());
responseData["success"] = "false";
responseData["avatar_uuid"] = UUID.Zero.ToString();
responseData["error"] = e.Message;
response.Value = responseData;
}
m_log.Info("[RADMIN]: CreateUser: request complete");
return response;
}
}
/// <summary>
/// Check whether a certain user account exists.
/// <summary>
/// <param name="request">incoming XML RPC request</param>
/// <remarks>
/// XmlRpcUserExistsMethod 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>user_firstname</term>
/// <description>avatar's first name</description></item>
/// <item><term>user_lastname</term>
/// <description>avatar's last name</description></item>
/// </list>
///
/// XmlRpcCreateUserMethod returns
/// <list type="table">
/// <listheader><term>name</term><description>description</description></listheader>
/// <item><term>user_firstname</term>
/// <description>avatar's first name</description></item>
/// <item><term>user_lastname</term>
/// <description>avatar's last name</description></item>
/// <item><term>success</term>
/// <description>true or false</description></item>
/// <item><term>error</term>
/// <description>error message if success is false</description></item>
/// </list>
/// </remarks>
public XmlRpcResponse XmlRpcUserExistsMethod(XmlRpcRequest request)
{
m_log.Info("[RADMIN]: UserExists: new request");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
try
{
Hashtable requestData = (Hashtable) request.Params[0];
// check completeness
checkStringParameters(request, new string[] {"password", "user_firstname", "user_lastname"});
string firstname = (string) requestData["user_firstname"];
string lastname = (string) requestData["user_lastname"];
CachedUserInfo userInfo
= m_app.CommunicationsManager.UserProfileCacheService.GetUserDetails(firstname, lastname);
responseData["user_firstname"] = firstname;
responseData["user_lastname"] = lastname;
if (null == userInfo)
responseData["success"] = false;
else
responseData["success"] = true;
response.Value = responseData;
}
catch (Exception e)
{
m_log.ErrorFormat("[RADMIN] UserExists: failed: {0}", e.Message);
m_log.DebugFormat("[RADMIN] UserExists: failed: {0}", e.ToString());
responseData["success"] = "false";
responseData["error"] = e.Message;
response.Value = responseData;
}
m_log.Info("[RADMIN]: UserExists: request complete");
return response;
}
/// <summary>
/// Update a user account.
/// <summary>
/// <param name="request">incoming XML RPC request</param>
/// <remarks>
/// XmlRpcUpdateUserAccountMethod takes the following XMLRPC
/// parameters (changeable ones are optional)
/// <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>user_firstname</term>
/// <description>avatar's first name (cannot be changed)</description></item>
/// <item><term>user_lastname</term>
/// <description>avatar's last name (cannot be changed)</description></item>
/// <item><term>user_password</term>
/// <description>avatar's password (changeable)</description></item>
/// <item><term>start_region_x</term>
/// <description>avatar's start region coordinates, X
/// value (changeable)</description></item>
/// <item><term>start_region_y</term>
/// <description>avatar's start region coordinates, Y
/// value (changeable)</description></item>
/// <item><term>about_real_world</term>
/// <description>"about" text of avatar owner (changeable)</description></item>
/// <item><term>about_virtual_world</term>
/// <description>"about" text of avatar (changeable)</description></item>
/// </list>
///
/// XmlRpcCreateUserMethod 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>
/// </list>
/// </remarks>
public XmlRpcResponse XmlRpcUpdateUserAccountMethod(XmlRpcRequest request)
{
m_log.Info("[RADMIN]: UpdateUserAccount: new request");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
lock (rslock)
{
try
{
Hashtable requestData = (Hashtable) request.Params[0];
// check completeness
checkStringParameters(request, new string[] {
"password", "user_firstname",
"user_lastname"});
// check password
if (!String.IsNullOrEmpty(m_requiredPassword) &&
(string) requestData["password"] != m_requiredPassword) throw new Exception("wrong password");
// do the job
string firstname = (string) requestData["user_firstname"];
string lastname = (string) requestData["user_lastname"];
string passwd = String.Empty;
uint? regX = null;
uint? regY = null;
uint? ulaX = null;
uint? ulaY = null;
uint? ulaZ = null;
uint? usaX = null;
uint? usaY = null;
uint? usaZ = null;
string aboutFirstLive = String.Empty;
string aboutAvatar = String.Empty;
if (requestData.ContainsKey("user_password")) passwd = (string) requestData["user_password"];
if (requestData.ContainsKey("start_region_x"))
regX = Convert.ToUInt32((Int32) requestData["start_region_x"]);
if (requestData.ContainsKey("start_region_y"))
regY = Convert.ToUInt32((Int32) requestData["start_region_y"]);
if (requestData.ContainsKey("start_lookat_x"))
ulaX = Convert.ToUInt32((Int32) requestData["start_lookat_x"]);
if (requestData.ContainsKey("start_lookat_y"))
ulaY = Convert.ToUInt32((Int32) requestData["start_lookat_y"]);
if (requestData.ContainsKey("start_lookat_z"))
ulaZ = Convert.ToUInt32((Int32) requestData["start_lookat_z"]);
if (requestData.ContainsKey("start_standat_x"))
usaX = Convert.ToUInt32((Int32) requestData["start_standat_x"]);
if (requestData.ContainsKey("start_standat_y"))
usaY = Convert.ToUInt32((Int32) requestData["start_standat_y"]);
if (requestData.ContainsKey("start_standat_z"))
usaZ = Convert.ToUInt32((Int32) requestData["start_standat_z"]);
if (requestData.ContainsKey("about_real_world"))
aboutFirstLive = (string)requestData["about_real_world"];
if (requestData.ContainsKey("about_virtual_world"))
aboutAvatar = (string)requestData["about_virtual_world"];
UserProfileData userProfile
= m_app.CommunicationsManager.UserService.GetUserProfile(firstname, lastname);
if (null == userProfile)
throw new Exception(String.Format("avatar {0} {1} does not exist", firstname, lastname));
if (null != passwd)
{
string md5PasswdHash = Util.Md5Hash(Util.Md5Hash(passwd) + ":" + String.Empty);
userProfile.PasswordHash = md5PasswdHash;
}
if (null != regX) userProfile.HomeRegionX = (uint) regX;
if (null != regY) userProfile.HomeRegionY = (uint) regY;
if (null != usaX) userProfile.HomeLocationX = (uint) usaX;
if (null != usaY) userProfile.HomeLocationY = (uint) usaY;
if (null != usaZ) userProfile.HomeLocationZ = (uint) usaZ;
if (null != ulaX) userProfile.HomeLookAtX = (uint) ulaX;
if (null != ulaY) userProfile.HomeLookAtY = (uint) ulaY;
if (null != ulaZ) userProfile.HomeLookAtZ = (uint) ulaZ;
if (String.Empty != aboutFirstLive) userProfile.FirstLifeAboutText = aboutFirstLive;
if (String.Empty != aboutAvatar) userProfile.AboutText = aboutAvatar;
// User has been created. Now establish gender and appearance.
// Default appearance is 'Default Male'. Specifying gender can
// establish "Default Female". Specifying a specific model can
// establish a specific appearance without regard for gender.
try
{
string model = "*none*";
if (requestData.Contains("gender"))
{
if ((string)requestData["gender"] == "f")
model = "Default Female";
else
model = "Default Male";
}
if (requestData.Contains("model"))
model = (string)requestData["model"];
if (model != "*none*")
{
string[] uname = model.Split();
UserProfileData udata = m_app.CommunicationsManager.UserService.GetUserProfile(uname[0],uname[1]);
AvatarAppearance ava = m_app.CommunicationsManager.AvatarService.GetUserAppearance(udata.ID);
m_app.CommunicationsManager.AvatarService.UpdateUserAppearance(userProfile.ID, ava);
}
}
catch (Exception e)
{
m_log.ErrorFormat("[RADMIN] Error establishing initial appearance : {0}", e.Message);
}
if (!m_app.CommunicationsManager.UserService.UpdateUserProfile(userProfile))
throw new Exception("did not manage to update user profile");
responseData["success"] = "true";
response.Value = responseData;
m_log.InfoFormat("[RADMIN]: UpdateUserAccount: account for user {0} {1} updated, UUID {2}",
firstname, lastname,
userProfile.ID);
}
catch (Exception e)
{
m_log.ErrorFormat("[RADMIN] UpdateUserAccount: failed: {0}", e.Message);
m_log.DebugFormat("[RADMIN] UpdateUserAccount: failed: {0}", e.ToString());
responseData["success"] = "false";
responseData["error"] = e.Message;
response.Value = responseData;
}
}
m_log.Info("[RADMIN]: UpdateUserAccount: request complete");
return response;
}
/// <summary>
/// Load an OAR file into a region..
/// <summary>
/// <param name="request">incoming XML RPC request</param>
/// <remarks>
/// XmlRpcLoadOARMethod 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>filename</term>
/// <description>file name of the OAR file</description></item>
/// <item><term>region_uuid</term>
/// <description>UUID of the region</description></item>
/// <item><term>region_name</term>
/// <description>region name</description></item>
/// </list>
///
/// <code>region_uuid</code> takes precedence over
/// <code>region_name</code> if both are present; one of both
/// must be present.
///
/// XmlRpcLoadOARMethod 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>
/// </list>
/// </remarks>
public XmlRpcResponse XmlRpcLoadOARMethod(XmlRpcRequest request)
{
m_log.Info("[RADMIN]: Received Load OAR Administrator Request");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
lock (rslock)
{
try
{
Hashtable requestData = (Hashtable) request.Params[0];
// check completeness
foreach (string p in new string[] {"password", "filename"})
{
if (!requestData.Contains(p))
throw new Exception(String.Format("missing parameter {0}", p));
if (String.IsNullOrEmpty((string) requestData[p]))
throw new Exception(String.Format("parameter {0} is empty"));
}
// check password
if (!String.IsNullOrEmpty(m_requiredPassword) &&
(string) requestData["password"] != m_requiredPassword) throw new Exception("wrong password");
string filename = (string) requestData["filename"];
Scene scene = null;
if (requestData.Contains("region_uuid"))
{
UUID region_uuid = (UUID) (string) requestData["region_uuid"];
if (!m_app.SceneManager.TryGetScene(region_uuid, out scene))
throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString()));
}
else if (requestData.Contains("region_name"))
{
string region_name = (string) requestData["region_name"];
if (!m_app.SceneManager.TryGetScene(region_name, out scene))
throw new Exception(String.Format("failed to switch to region {0}", region_name));
}
else throw new Exception("neither region_name nor region_uuid given");
IRegionArchiverModule archiver = scene.RequestModuleInterface<IRegionArchiverModule>();
if (archiver != null)
archiver.DearchiveRegion(filename);
else
throw new Exception("Archiver module not present for scene");
responseData["loaded"] = "true";
response.Value = responseData;
}
catch (Exception e)
{
m_log.InfoFormat("[RADMIN] LoadOAR: {0}", e.Message);
m_log.DebugFormat("[RADMIN] LoadOAR: {0}", e.ToString());
responseData["loaded"] = "false";
responseData["error"] = e.Message;
response.Value = responseData;
}
m_log.Info("[RADMIN]: Load OAR Administrator Request complete");
return response;
}
}
/// <summary>
/// Save a region to an OAR file
/// <summary>
/// <param name="request">incoming XML RPC request</param>
/// <remarks>
/// XmlRpcSaveOARMethod 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>filename</term>
/// <description>file name for the OAR file</description></item>
/// <item><term>region_uuid</term>
/// <description>UUID of the region</description></item>
/// <item><term>region_name</term>
/// <description>region name</description></item>
/// </list>
///
/// <code>region_uuid</code> takes precedence over
/// <code>region_name</code> if both are present; one of both
/// must be present.
///
/// XmlRpcLoadOARMethod 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>
/// </list>
/// </remarks>
public XmlRpcResponse XmlRpcSaveOARMethod(XmlRpcRequest request)
{
m_log.Info("[RADMIN]: Received Save OAR Administrator Request");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
try
{
Hashtable requestData = (Hashtable) request.Params[0];
// check completeness
foreach (string p in new string[] {"password", "filename"})
{
if (!requestData.Contains(p))
throw new Exception(String.Format("missing parameter {0}", p));
if (String.IsNullOrEmpty((string) requestData[p]))
throw new Exception(String.Format("parameter {0} is empty"));
}
// check password
if (!String.IsNullOrEmpty(m_requiredPassword) &&
(string) requestData["password"] != m_requiredPassword) throw new Exception("wrong password");
string filename = (string) requestData["filename"];
Scene scene = null;
if (requestData.Contains("region_uuid"))
{
UUID region_uuid = (UUID) (string) requestData["region_uuid"];
if (!m_app.SceneManager.TryGetScene(region_uuid, out scene))
throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString()));
}
else if (requestData.Contains("region_name"))
{
string region_name = (string) requestData["region_name"];
if (!m_app.SceneManager.TryGetScene(region_name, out scene))
throw new Exception(String.Format("failed to switch to region {0}", region_name));
}
else throw new Exception("neither region_name nor region_uuid given");
IRegionArchiverModule archiver = scene.RequestModuleInterface<IRegionArchiverModule>();
if (archiver != null)
archiver.ArchiveRegion(filename);
else
throw new Exception("Archiver module not present for scene");
responseData["saved"] = "true";
response.Value = responseData;
}
catch (Exception e)
{
m_log.InfoFormat("[RADMIN] SaveOAR: {0}", e.Message);
m_log.DebugFormat("[RADMIN] SaveOAR: {0}", e.ToString());
responseData["saved"] = "false";
responseData["error"] = e.Message;
response.Value = responseData;
}
m_log.Info("[RADMIN]: Save OAR Administrator Request complete");
return response;
}
public XmlRpcResponse XmlRpcLoadXMLMethod(XmlRpcRequest request)
{
m_log.Info("[RADMIN]: Received Load XML Administrator Request");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
lock (rslock)
{
try
{
Hashtable requestData = (Hashtable) request.Params[0];
// check completeness
foreach (string p in new string[] {"password", "filename"})
{
if (!requestData.Contains(p))
throw new Exception(String.Format("missing parameter {0}", p));
if (String.IsNullOrEmpty((string) requestData[p]))
throw new Exception(String.Format("parameter {0} is empty"));
}
// check password
if (!String.IsNullOrEmpty(m_requiredPassword) &&
(string) requestData["password"] != m_requiredPassword) throw new Exception("wrong password");
string filename = (string) requestData["filename"];
if (requestData.Contains("region_uuid"))
{
UUID region_uuid = (UUID) (string) requestData["region_uuid"];
if (!m_app.SceneManager.TrySetCurrentScene(region_uuid))
throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString()));
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_uuid.ToString());
}
else if (requestData.Contains("region_name"))
{
string region_name = (string) requestData["region_name"];
if (!m_app.SceneManager.TrySetCurrentScene(region_name))
throw new Exception(String.Format("failed to switch to region {0}", region_name));
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_name);
}
else throw new Exception("neither region_name nor region_uuid given");
responseData["switched"] = "true";
string xml_version = "1";
if (requestData.Contains("xml_version"))
{
xml_version = (string) requestData["xml_version"];
}
switch (xml_version)
{
case "1":
m_app.SceneManager.LoadCurrentSceneFromXml(filename, true, new Vector3(0, 0, 0));
break;
case "2":
m_app.SceneManager.LoadCurrentSceneFromXml2(filename);
break;
default:
throw new Exception(String.Format("unknown Xml{0} format", xml_version));
}
responseData["loaded"] = "true";
response.Value = responseData;
}
catch (Exception e)
{
m_log.InfoFormat("[RADMIN] LoadXml: {0}", e.Message);
m_log.DebugFormat("[RADMIN] LoadXml: {0}", e.ToString());
responseData["loaded"] = "false";
responseData["switched"] = "false";
responseData["error"] = e.Message;
response.Value = responseData;
}
m_log.Info("[RADMIN]: Load XML Administrator Request complete");
return response;
}
}
public XmlRpcResponse XmlRpcSaveXMLMethod(XmlRpcRequest request)
{
m_log.Info("[RADMIN]: Received Save XML Administrator Request");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
try
{
Hashtable requestData = (Hashtable) request.Params[0];
// check completeness
foreach (string p in new string[] {"password", "filename"})
{
if (!requestData.Contains(p))
throw new Exception(String.Format("missing parameter {0}", p));
if (String.IsNullOrEmpty((string) requestData[p]))
throw new Exception(String.Format("parameter {0} is empty"));
}
// check password
if (!String.IsNullOrEmpty(m_requiredPassword) &&
(string) requestData["password"] != m_requiredPassword) throw new Exception("wrong password");
string filename = (string) requestData["filename"];
if (requestData.Contains("region_uuid"))
{
UUID region_uuid = (UUID) (string) requestData["region_uuid"];
if (!m_app.SceneManager.TrySetCurrentScene(region_uuid))
throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString()));
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_uuid.ToString());
}
else if (requestData.Contains("region_name"))
{
string region_name = (string) requestData["region_name"];
if (!m_app.SceneManager.TrySetCurrentScene(region_name))
throw new Exception(String.Format("failed to switch to region {0}", region_name));
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_name);
}
else throw new Exception("neither region_name nor region_uuid given");
responseData["switched"] = "true";
string xml_version = "1";
if (requestData.Contains("xml_version"))
{
xml_version = (string) requestData["xml_version"];
}
switch (xml_version)
{
case "1":
m_app.SceneManager.SaveCurrentSceneToXml(filename);
break;
case "2":
m_app.SceneManager.SaveCurrentSceneToXml2(filename);
break;
default:
throw new Exception(String.Format("unknown Xml{0} format", xml_version));
}
responseData["saved"] = "true";
response.Value = responseData;
}
catch (Exception e)
{
m_log.InfoFormat("[RADMIN] SaveXml: {0}", e.Message);
m_log.DebugFormat("[RADMIN] SaveXml: {0}", e.ToString());
responseData["saved"] = "false";
responseData["switched"] = "false";
responseData["error"] = e.Message;
response.Value = responseData;
}
m_log.Info("[RADMIN]: Save XML Administrator Request complete");
return response;
}
public XmlRpcResponse XmlRpcRegionQueryMethod(XmlRpcRequest request)
{
m_log.Info("[RADMIN]: Received Query XML Administrator Request");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
try
{
responseData["success"] = "true";
Hashtable requestData = (Hashtable) request.Params[0];
// check completeness
if (!requestData.Contains("password"))
throw new Exception(String.Format("missing required parameter"));
if (!String.IsNullOrEmpty(m_requiredPassword) &&
(string) requestData["password"] != m_requiredPassword) throw new Exception("wrong password");
if (requestData.Contains("region_uuid"))
{
UUID region_uuid = (UUID) (string) requestData["region_uuid"];
if (!m_app.SceneManager.TrySetCurrentScene(region_uuid))
throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString()));
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_uuid.ToString());
}
else if (requestData.Contains("region_name"))
{
string region_name = (string) requestData["region_name"];
if (!m_app.SceneManager.TrySetCurrentScene(region_name))
throw new Exception(String.Format("failed to switch to region {0}", region_name));
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_name);
}
else throw new Exception("neither region_name nor region_uuid given");
Scene s = m_app.SceneManager.CurrentScene;
int health = s.GetHealth();
responseData["health"] = health;
response.Value = responseData;
}
catch (Exception e)
{
m_log.InfoFormat("[RADMIN] RegionQuery: {0}", e.Message);
responseData["success"] = "false";
responseData["error"] = e.Message;
response.Value = responseData;
}
m_log.Info("[RADMIN]: Query XML Administrator Request complete");
return response;
}
public XmlRpcResponse XmlRpcConsoleCommandMethod(XmlRpcRequest request)
{
m_log.Info("[RADMIN]: Received Command XML Administrator Request");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
try
{
responseData["success"] = "true";
Hashtable requestData = (Hashtable) request.Params[0];
// check completeness
if (!requestData.Contains("password"))
throw new Exception(String.Format("missing required parameter"));
if (!String.IsNullOrEmpty(m_requiredPassword) &&
(string) requestData["password"] != m_requiredPassword) throw new Exception("wrong password");
if (!requestData.Contains("command"))
throw new Exception(String.Format("missing required parameter"));
MainConsole.Instance.RunCommand(requestData["command"].ToString());
response.Value = responseData;
}
catch (Exception e)
{
m_log.InfoFormat("[RADMIN] ConsoleCommand: {0}", e.Message);
responseData["success"] = "false";
responseData["error"] = e.Message;
response.Value = responseData;
}
m_log.Info("[RADMIN]: Command XML Administrator Request complete");
return response;
}
public XmlRpcResponse XmlRpcAccessListClear(XmlRpcRequest request)
{
m_log.Info("[RADMIN]: Received Access List Clear Request");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
try
{
responseData["success"] = "true";
Hashtable requestData = (Hashtable) request.Params[0];
if (!requestData.Contains("password"))
throw new Exception(String.Format("missing required parameter"));
if (!String.IsNullOrEmpty(m_requiredPassword) &&
(string) requestData["password"] != m_requiredPassword) throw new Exception("wrong password");
if (requestData.Contains("region_uuid"))
{
UUID region_uuid = (UUID) (string) requestData["region_uuid"];
if (!m_app.SceneManager.TrySetCurrentScene(region_uuid))
throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString()));
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_uuid.ToString());
}
else if (requestData.Contains("region_name"))
{
string region_name = (string) requestData["region_name"];
if (!m_app.SceneManager.TrySetCurrentScene(region_name))
throw new Exception(String.Format("failed to switch to region {0}", region_name));
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_name);
}
else throw new Exception("neither region_name nor region_uuid given");
Scene s = m_app.SceneManager.CurrentScene;
s.RegionInfo.EstateSettings.EstateAccess = new UUID[]{};
}
catch (Exception e)
{
m_log.InfoFormat("[RADMIN] Access List Clear Request: {0}", e.Message);
responseData["success"] = "false";
responseData["error"] = e.Message;
}
finally
{
response.Value = responseData;
}
m_log.Info("[RADMIN]: Access List Clear Request complete");
return response;
}
public XmlRpcResponse XmlRpcAccessListAdd(XmlRpcRequest request)
{
m_log.Info("[RADMIN]: Received Access List Add Request");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
try
{
responseData["success"] = "true";
Hashtable requestData = (Hashtable) request.Params[0];
if (!requestData.Contains("password"))
throw new Exception(String.Format("missing required parameter"));
if (!String.IsNullOrEmpty(m_requiredPassword) &&
(string) requestData["password"] != m_requiredPassword) throw new Exception("wrong password");
if (requestData.Contains("region_uuid"))
{
UUID region_uuid = (UUID) (string) requestData["region_uuid"];
if (!m_app.SceneManager.TrySetCurrentScene(region_uuid))
throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString()));
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_uuid.ToString());
}
else if (requestData.Contains("region_name"))
{
string region_name = (string) requestData["region_name"];
if (!m_app.SceneManager.TrySetCurrentScene(region_name))
throw new Exception(String.Format("failed to switch to region {0}", region_name));
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_name);
}
else throw new Exception("neither region_name nor region_uuid given");
int addk = 0;
if (requestData.Contains("users"))
{
UserProfileCacheService ups = m_app.CommunicationsManager.UserProfileCacheService;
Scene s = m_app.SceneManager.CurrentScene;
Hashtable users = (Hashtable) requestData["users"];
List<UUID> uuids = new List<UUID>();
foreach (string name in users.Values)
{
string[] parts = name.Split();
uuids.Add(ups.GetUserDetails(parts[0],parts[1]).UserProfile.ID);
}
List<UUID> acl = new List<UUID>(s.RegionInfo.EstateSettings.EstateAccess);
foreach (UUID uuid in uuids)
{
if (!acl.Contains(uuid))
{
acl.Add(uuid);
addk++;
}
}
s.RegionInfo.EstateSettings.EstateAccess = acl.ToArray();
}
responseData["added"] = addk;
}
catch (Exception e)
{
m_log.InfoFormat("[RADMIN] Access List Add Request: {0}", e.Message);
responseData["success"] = "false";
responseData["error"] = e.Message;
}
finally
{
response.Value = responseData;
}
m_log.Info("[RADMIN]: Access List Add Request complete");
return response;
}
public XmlRpcResponse XmlRpcAccessListRemove(XmlRpcRequest request)
{
m_log.Info("[RADMIN]: Received Access List Remove Request");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
try
{
responseData["success"] = "true";
Hashtable requestData = (Hashtable) request.Params[0];
if (!requestData.Contains("password"))
throw new Exception(String.Format("missing required parameter"));
if (!String.IsNullOrEmpty(m_requiredPassword) &&
(string) requestData["password"] != m_requiredPassword) throw new Exception("wrong password");
if (requestData.Contains("region_uuid"))
{
UUID region_uuid = (UUID) (string) requestData["region_uuid"];
if (!m_app.SceneManager.TrySetCurrentScene(region_uuid))
throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString()));
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_uuid.ToString());
}
else if (requestData.Contains("region_name"))
{
string region_name = (string) requestData["region_name"];
if (!m_app.SceneManager.TrySetCurrentScene(region_name))
throw new Exception(String.Format("failed to switch to region {0}", region_name));
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_name);
}
else throw new Exception("neither region_name nor region_uuid given");
int remk = 0;
if (requestData.Contains("users"))
{
UserProfileCacheService ups = m_app.CommunicationsManager.UserProfileCacheService;
Scene s = m_app.SceneManager.CurrentScene;
Hashtable users = (Hashtable) requestData["users"];
List<UUID> uuids = new List<UUID>();
foreach (string name in users.Values)
{
string[] parts = name.Split();
uuids.Add(ups.GetUserDetails(parts[0],parts[1]).UserProfile.ID);
}
List<UUID> acl = new List<UUID>(s.RegionInfo.EstateSettings.EstateAccess);
foreach (UUID uuid in uuids)
{
if (acl.Contains(uuid))
{
acl.Remove(uuid);
remk++;
}
}
s.RegionInfo.EstateSettings.EstateAccess = acl.ToArray();
}
responseData["added"] = remk;
}
catch (Exception e)
{
m_log.InfoFormat("[RADMIN] Access List Remove Request: {0}", e.Message);
responseData["success"] = "false";
responseData["error"] = e.Message;
}
finally
{
response.Value = responseData;
}
m_log.Info("[RADMIN]: Access List Remove Request complete");
return response;
}
public XmlRpcResponse XmlRpcAccessListList(XmlRpcRequest request)
{
m_log.Info("[RADMIN]: Received Access List List Request");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable responseData = new Hashtable();
try
{
responseData["success"] = "true";
Hashtable requestData = (Hashtable) request.Params[0];
if (!requestData.Contains("password"))
throw new Exception(String.Format("missing required parameter"));
if (!String.IsNullOrEmpty(m_requiredPassword) &&
(string) requestData["password"] != m_requiredPassword) throw new Exception("wrong password");
if (requestData.Contains("region_uuid"))
{
UUID region_uuid = (UUID) (string) requestData["region_uuid"];
if (!m_app.SceneManager.TrySetCurrentScene(region_uuid))
throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString()));
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_uuid.ToString());
}
else if (requestData.Contains("region_name"))
{
string region_name = (string) requestData["region_name"];
if (!m_app.SceneManager.TrySetCurrentScene(region_name))
throw new Exception(String.Format("failed to switch to region {0}", region_name));
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_name);
}
else throw new Exception("neither region_name nor region_uuid given");
Scene s = m_app.SceneManager.CurrentScene;
UUID[] acl = s.RegionInfo.EstateSettings.EstateAccess;
Hashtable users = new Hashtable();
foreach (UUID user in acl)
{
users[user.ToString()] =
m_app.CommunicationsManager.UserProfileCacheService.GetUserDetails(user).UserProfile.Name;
}
responseData["users"] = users;
}
catch (Exception e)
{
m_log.InfoFormat("[RADMIN] Acces List List: {0}", e.Message);
responseData["success"] = "false";
responseData["error"] = e.Message;
}
finally
{
response.Value = responseData;
}
m_log.Info("[RADMIN]: Access List List Request complete");
return response;
}
public void Dispose()
{
}
}
}