From a49c524c9e93db1409f1f05d7b881922e178927c Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 15 Nov 2009 20:22:15 +0000 Subject: Add the ability to send messages to users ir regions via remote admin --- .../RemoteController/RemoteAdminPlugin.cs | 48 ++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 3149eaa..3bc557d 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -123,6 +123,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController availableMethods["admin_region_query"] = XmlRpcRegionQueryMethod; availableMethods["admin_shutdown"] = XmlRpcShutdownMethod; availableMethods["admin_broadcast"] = XmlRpcAlertMethod; + availableMethods["admin_dialog"] = XmlRpcDialogMethod; availableMethods["admin_restart"] = XmlRpcRestartMethod; availableMethods["admin_load_heightmap"] = XmlRpcLoadHeightmapMethod; // User management @@ -277,6 +278,53 @@ namespace OpenSim.ApplicationPlugins.RemoteController m_log.Info("[RADMIN]: Alert request complete"); return response; } + public XmlRpcResponse XmlRpcDialogMethod(XmlRpcRequest request, IPEndPoint remoteClient) + { + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable responseData = new Hashtable(); + + m_log.Info("[RADMIN]: Dialog request started"); + + try + { + Hashtable requestData = (Hashtable)request.Params[0]; + + checkStringParameters(request, new string[] { "password", "from", "message" }); + + if (m_requiredPassword != String.Empty && + (!requestData.Contains("password") || (string)requestData["password"] != m_requiredPassword)) + throw new Exception("wrong password"); + + string message = (string)requestData["message"]; + string fromuuid = (string)requestData["from"]; + 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(); + if (dialogModule != null) + dialogModule.SendNotificationToUsersInRegion(UUID.Zero, fromuuid, 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, IPEndPoint remoteClient) { -- cgit v1.1 From ac2fcbe224d4877dccc4d73e9c58771e40a4ae1c Mon Sep 17 00:00:00 2001 From: CasperW Date: Thu, 26 Nov 2009 15:17:44 +0100 Subject: Improvements to rAdmin admin_shutdown and admin_restart. Both methods can now accept a parameter of noticetype = dialog in order to display a blue persistant dropdown instead of a short notice. Added an optional and configurable delay to the restart method, defaulting at 30 seconds as before. Both methods can also accept a noticetype = none dialog in order to act silently. --- .../RemoteController/RemoteAdminPlugin.cs | 74 +++++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 3bc557d..325816d 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -213,9 +213,59 @@ namespace OpenSim.ApplicationPlugins.RemoteController if (!m_app.SceneManager.TryGetScene(regionID, out rebootedScene)) throw new Exception("region not found"); + int timeout = 30000; + string message; + + if (requestData.ContainsKey("restart") + && ((string)requestData["restart"] == "delayed") + && requestData.ContainsKey("milliseconds")) + { + timeout = Int32.Parse(requestData["milliseconds"].ToString()); + + if (timeout < 15000) + { + //It must be at least 15 seconds or we'll cancel the reboot request + timeout = 15000; + } + + message + = "Region is restarting in " + ((int)(timeout / 1000)).ToString() + + " second(s). Please save what you are doing and log out."; + } + else + { + message = "Region is restarting in 30 second(s). Please save what you are doing and log out."; + } + + if (requestData.ContainsKey("noticetype") + && ((string)requestData["noticetype"] == "dialog")) + { + m_app.SceneManager.ForEachScene( + delegate(Scene scene) + { + IDialogModule dialogModule = scene.RequestModuleInterface(); + if (dialogModule != null) + dialogModule.SendNotificationToUsersInRegion(UUID.Zero, "System", message); + }); + } + else + { + if (!requestData.ContainsKey("noticetype") + || ((string)requestData["noticetype"] != "none")) + { + m_app.SceneManager.ForEachScene( + delegate(Scene scene) + { + IDialogModule dialogModule = scene.RequestModuleInterface(); + if (dialogModule != null) + dialogModule.SendGeneralAlert(message); + }); + } + } + responseData["rebooting"] = true; response.Value = responseData; - rebootedScene.Restart(30); + rebootedScene.Restart(timeout / 1000,false); } catch (Exception e) { @@ -419,13 +469,33 @@ namespace OpenSim.ApplicationPlugins.RemoteController message = "Region is going down now."; } - m_app.SceneManager.ForEachScene( + if (requestData.ContainsKey("noticetype") + && ((string) requestData["noticetype"] == "dialog")) + { + m_app.SceneManager.ForEachScene( delegate(Scene scene) { IDialogModule dialogModule = scene.RequestModuleInterface(); if (dialogModule != null) + dialogModule.SendNotificationToUsersInRegion(UUID.Zero, "System", message); + }); + } + else + { + if (!requestData.ContainsKey("noticetype") + || ((string)requestData["noticetype"] != "none")) + { + m_app.SceneManager.ForEachScene( + delegate(Scene scene) + { + IDialogModule dialogModule = scene.RequestModuleInterface(); + if (dialogModule != null) dialogModule.SendGeneralAlert(message); }); + } + } + + // Perform shutdown System.Timers.Timer shutdownTimer = new System.Timers.Timer(timeout); // Wait before firing -- cgit v1.1 From 55f124745ffe743a2d93c2ef93cb5c2f4fe06178 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 18 May 2010 19:25:40 +0200 Subject: Allow remote admin to be used on a different port from the main region port --- OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index d7904a6..ed43363 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -63,7 +63,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController private static Object SOLock = new Object(); private OpenSimBase m_app; - private BaseHttpServer m_httpd; + private IHttpServer m_httpd; private IConfig m_config; private IConfigSource m_configSource; private string m_requiredPassword = String.Empty; @@ -113,9 +113,10 @@ namespace OpenSim.ApplicationPlugins.RemoteController m_config = m_configSource.Configs["RemoteAdmin"]; m_log.Info("[RADMIN]: Remote Admin Plugin Enabled"); m_requiredPassword = m_config.GetString("access_password", String.Empty); + int port = m_config.GetInt("port", 0); m_app = openSim; - m_httpd = openSim.HttpServer; + m_httpd = MainServer.GetHttpServer((uint)port); Dictionary availableMethods = new Dictionary(); availableMethods["admin_create_region"] = XmlRpcCreateRegionMethod; -- cgit v1.1 From d5d0e81df2415203711fc418ac901b007f1e6607 Mon Sep 17 00:00:00 2001 From: mores Date: Tue, 2 Nov 2010 21:46:45 -0400 Subject: Admin Server can now bind to a private ip address Signed-off-by: Melanie --- OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 4ac9ada..946f1b2 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -116,7 +116,9 @@ namespace OpenSim.ApplicationPlugins.RemoteController int port = m_config.GetInt("port", 0); m_application = openSim; - m_httpServer = MainServer.GetHttpServer((uint)port); + string bind_ip_address = m_config.GetString("bind_ip_address", "127.0.0.1"); + IPAddress ipaddr = IPAddress.Parse( bind_ip_address ); + m_httpServer = MainServer.GetHttpServer((uint)port,ipaddr); Dictionary availableMethods = new Dictionary(); availableMethods["admin_create_region"] = XmlRpcCreateRegionMethod; -- cgit v1.1 From 636ca6218d2ad63cdec7f0b68d84a565542c1fe2 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 3 Nov 2010 01:11:04 +0000 Subject: Change the default of the new bind_ip_address RemoteAdmin option to 0.0.0.0 so it reflects the prior default. We are not in the habot of changing default behavior without good reason and making localhost the default would break most current use cases. --- OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 946f1b2..ba95426 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -116,7 +116,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController int port = m_config.GetInt("port", 0); m_application = openSim; - string bind_ip_address = m_config.GetString("bind_ip_address", "127.0.0.1"); + string bind_ip_address = m_config.GetString("bind_ip_address", "0.0.0.0"); IPAddress ipaddr = IPAddress.Parse( bind_ip_address ); m_httpServer = MainServer.GetHttpServer((uint)port,ipaddr); -- cgit v1.1 From e74b0deb4ebc46b2688368e2e793f9fd1defd322 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 25 Nov 2010 03:43:23 +0000 Subject: Fix up remote controller. --- .../RemoteController/RemoteAdminPlugin.cs | 37 +++++++++++++++++----- 1 file changed, 29 insertions(+), 8 deletions(-) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 7be152b..27e73f6 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -216,18 +216,41 @@ namespace OpenSim.ApplicationPlugins.RemoteController if (!m_application.SceneManager.TryGetScene(regionID, out rebootedScene)) throw new Exception("region not found"); - int timeout = 30; string message; + List times = new List(); - if (requestData.ContainsKey("restart") - && ((string)requestData["restart"] == "delayed") - && requestData.ContainsKey("milliseconds")) + if (requestData.ContainsKey("alerts")) { - timeout = Int32.Parse(requestData["milliseconds"].ToString()) / 1000; + string[] alertTimes = requestData["alerts"].ToString().Split( new char[] {','}); + foreach (string a in alertTimes) + times.Add(Convert.ToInt32(a)); } + else + { + int timeout = 30; + if (requestData.ContainsKey("milliseconds")) + timeout = Int32.Parse(requestData["milliseconds"].ToString()) / 1000; + while (timeout > 0) + { + times.Add(timeout); + if (timeout > 300) + timeout -= 120; + else if (timeout > 30) + timeout -= 30; + else + timeout -= 15; + } + } + + if (requestData.ContainsKey("restart") + && ((string)requestData["restart"] == "delayed")) + message = "Region is restarting in {0}. Please save what you are doing and log out."; + if (requestData.ContainsKey("message")) + message = requestData["message"].ToString(); + bool notice = true; if (requestData.ContainsKey("noticetype") && ((string)requestData["noticetype"] == "dialog")) @@ -240,9 +263,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController IRestartModule restartModule = rebootedScene.RequestModuleInterface(); if (restartModule != null) { - List times = new List { 30, 15 }; - - restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), notice); + restartModule.ScheduleRestart(UUID.Zero, message, times.ToArray(), notice); responseData["success"] = true; } response.Value = responseData; -- cgit v1.1 From efb03f6f9985bab215e1e1e8bcc159cc86d2ad02 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 25 Nov 2010 03:59:57 +0100 Subject: Fix a bug caused by leftover code --- OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs | 4 ---- 1 file changed, 4 deletions(-) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 27e73f6..f3f79bc 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -242,10 +242,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController } } - if (requestData.ContainsKey("restart") - && ((string)requestData["restart"] == "delayed")) - - message = "Region is restarting in {0}. Please save what you are doing and log out."; if (requestData.ContainsKey("message")) -- cgit v1.1 From b94092517365fd557ca85142d315e746056dcfeb Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 3 Dec 2010 07:27:29 +0100 Subject: Improve health reporting --- OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index f3f79bc..a75cc60 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -2632,8 +2632,12 @@ namespace OpenSim.ApplicationPlugins.RemoteController else throw new Exception("neither region_name nor region_uuid given"); Scene scene = m_application.SceneManager.CurrentScene; - int health = scene.GetHealth(); + int flags; + string text; + int health = scene.GetHealth(out flags, out text); responseData["health"] = health; + responseData["flags"] = health; + responseData["message"] = health; response.Value = responseData; } -- cgit v1.1 From 4407c4700ff67a0c64918765b8f6cae155ec015c Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 3 Dec 2010 19:02:42 +0100 Subject: Fix status responses in remote admin --- OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index a75cc60..9659883 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -2636,8 +2636,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController string text; int health = scene.GetHealth(out flags, out text); responseData["health"] = health; - responseData["flags"] = health; - responseData["message"] = health; + responseData["flags"] = flags; + responseData["message"] = text; response.Value = responseData; } -- cgit v1.1 From 603ad905e19f9ebaab39a1b926cc41093a224151 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 8 Dec 2011 03:53:09 +0000 Subject: Adapt to justincc's remote admin refactor --- .../RemoteController/RemoteAdminPlugin.cs | 3970 +++++++++----------- 1 file changed, 1810 insertions(+), 2160 deletions(-) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 256a971..1cc0da2 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -124,38 +124,38 @@ namespace OpenSim.ApplicationPlugins.RemoteController m_httpServer = MainServer.GetHttpServer((uint)port,ipaddr); Dictionary availableMethods = new Dictionary(); - availableMethods["admin_create_region"] = XmlRpcCreateRegionMethod; - availableMethods["admin_delete_region"] = XmlRpcDeleteRegionMethod; - availableMethods["admin_close_region"] = XmlRpcCloseRegionMethod; - availableMethods["admin_modify_region"] = XmlRpcModifyRegionMethod; - availableMethods["admin_region_query"] = XmlRpcRegionQueryMethod; - availableMethods["admin_shutdown"] = XmlRpcShutdownMethod; - availableMethods["admin_broadcast"] = XmlRpcAlertMethod; - availableMethods["admin_dialog"] = XmlRpcDialogMethod; - availableMethods["admin_restart"] = XmlRpcRestartMethod; - availableMethods["admin_load_heightmap"] = XmlRpcLoadHeightmapMethod; - availableMethods["admin_save_heightmap"] = XmlRpcSaveHeightmapMethod; + availableMethods["admin_create_region"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcCreateRegionMethod); + availableMethods["admin_delete_region"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcDeleteRegionMethod); + availableMethods["admin_close_region"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcCloseRegionMethod); + availableMethods["admin_modify_region"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcModifyRegionMethod); + availableMethods["admin_region_query"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRegionQueryMethod); + availableMethods["admin_shutdown"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcShutdownMethod); + availableMethods["admin_broadcast"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAlertMethod); + availableMethods["admin_dialog"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcDialogMethod); + availableMethods["admin_restart"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRestartMethod); + availableMethods["admin_load_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcLoadHeightmapMethod); + availableMethods["admin_save_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcSaveHeightmapMethod); // Agent management - availableMethods["admin_teleport_agent"] = XmlRpcTeleportAgentMethod; + availableMethods["admin_teleport_agent"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcTeleportAgentMethod); // User management - availableMethods["admin_create_user"] = XmlRpcCreateUserMethod; - availableMethods["admin_create_user_email"] = XmlRpcCreateUserMethod; - availableMethods["admin_exists_user"] = XmlRpcUserExistsMethod; - availableMethods["admin_update_user"] = XmlRpcUpdateUserAccountMethod; + availableMethods["admin_create_user"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcCreateUserMethod); + availableMethods["admin_create_user_email"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcCreateUserMethod); + availableMethods["admin_exists_user"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcUserExistsMethod); + availableMethods["admin_update_user"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcUpdateUserAccountMethod); // Region state management - availableMethods["admin_load_xml"] = XmlRpcLoadXMLMethod; - availableMethods["admin_save_xml"] = XmlRpcSaveXMLMethod; - availableMethods["admin_load_oar"] = XmlRpcLoadOARMethod; - availableMethods["admin_save_oar"] = XmlRpcSaveOARMethod; + availableMethods["admin_load_xml"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcLoadXMLMethod); + availableMethods["admin_save_xml"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcSaveXMLMethod); + availableMethods["admin_load_oar"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcLoadOARMethod); + availableMethods["admin_save_oar"] = (req, ep) => InvokeXmlRpcMethod(req, ep, 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; + availableMethods["admin_acl_clear"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListClear); + availableMethods["admin_acl_add"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListAdd); + availableMethods["admin_acl_remove"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListRemove); + availableMethods["admin_acl_list"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListList); // Either enable full remote functionality or just selected features string enabledMethods = m_config.GetString("enabled_methods", "all"); @@ -165,7 +165,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController // If you just leave the option out! // if (!String.IsNullOrEmpty(enabledMethods)) - availableMethods["admin_console_command"] = XmlRpcConsoleCommandMethod; + availableMethods["admin_console_command"] = (req, ep) => InvokeXmlRpcMethod(req, ep, 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. @@ -199,34 +199,67 @@ namespace OpenSim.ApplicationPlugins.RemoteController } } - private void FailIfRemoteAdminNotAllowed(string password, string check_ip_address) + /// + /// Invoke an XmlRpc method with the standard actions (password check, etc.) + /// + /// + private XmlRpcResponse InvokeXmlRpcMethod( + XmlRpcRequest request, IPEndPoint remoteClient, Action method) + { + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable responseData = new Hashtable(); + response.Value = responseData; + + try + { + Hashtable requestData = (Hashtable) request.Params[0]; + + m_log.Info("[RADMIN]: Request to restart Region."); + CheckStringParameters(requestData, responseData, new string[] {"password"}); + + FailIfRemoteAdminNotAllowed((string)requestData["password"], responseData, remoteClient.Address.ToString()); + + method(request, response, remoteClient); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[RADMIN]: Method {0} failed. Exception {1}{2}", request.MethodName, e.Message, e.StackTrace); + + responseData["success"] = false; + responseData["error"] = e.Message; + } + + return response; + } + + private void FailIfRemoteAdminNotAllowed(string password, Hashtable responseData, string check_ip_address) { if (m_accessIP.Count > 0 && !m_accessIP.Contains(check_ip_address)) { - m_log.WarnFormat("[RADMIN]: Unauthorized acess blocked from IP {0}", check_ip_address); + m_log.WarnFormat("[RADMIN]: Unauthorized access blocked from IP {0}", check_ip_address); + responseData["accepted"] = false; throw new Exception("not authorized"); } if (m_requiredPassword != String.Empty && password != m_requiredPassword) { m_log.WarnFormat("[RADMIN]: Wrong password, blocked access from IP {0}", check_ip_address); + responseData["accepted"] = false; throw new Exception("wrong password"); } } - public XmlRpcResponse XmlRpcRestartMethod(XmlRpcRequest request, IPEndPoint remoteClient) + private void XmlRpcRestartMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { - XmlRpcResponse response = new XmlRpcResponse(); - Hashtable responseData = new Hashtable(); + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; try { - Hashtable requestData = (Hashtable) request.Params[0]; - m_log.Info("[RADMIN]: Request to restart Region."); - CheckStringParameters(request, new string[] {"password", "regionID"}); - FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); + CheckStringParameters(requestData, responseData, new string[] {"regionID"}); UUID regionID = new UUID((string) requestData["regionID"]); @@ -237,6 +270,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController if (!m_application.SceneManager.TryGetScene(regionID, out rebootedScene)) throw new Exception("region not found"); + responseData["rebooting"] = true; + string message; List times = new List(); @@ -275,78 +310,51 @@ namespace OpenSim.ApplicationPlugins.RemoteController notice = false; } - responseData["rebooting"] = true; - IRestartModule restartModule = rebootedScene.RequestModuleInterface(); if (restartModule != null) { restartModule.ScheduleRestart(UUID.Zero, message, times.ToArray(), notice); responseData["success"] = true; } - - response.Value = responseData; } catch (Exception e) { - m_log.ErrorFormat("[RADMIN]: Restart region: failed: {0} {1}", e.Message, e.StackTrace); - responseData["accepted"] = false; - responseData["success"] = false; +// m_log.ErrorFormat("[RADMIN]: Restart region: failed: {0} {1}", e.Message, e.StackTrace); responseData["rebooting"] = false; - responseData["error"] = e.Message; - response.Value = responseData; + + throw e; } m_log.Info("[RADMIN]: Restart Region request complete"); - return response; } - public XmlRpcResponse XmlRpcAlertMethod(XmlRpcRequest request, IPEndPoint remoteClient) + private void XmlRpcAlertMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { - 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"}); - - FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; - string message = (string) requestData["message"]; - m_log.InfoFormat("[RADMIN]: Broadcasting: {0}", message); - - responseData["accepted"] = true; - responseData["success"] = true; - response.Value = responseData; + string message = (string) requestData["message"]; + m_log.InfoFormat("[RADMIN]: Broadcasting: {0}", message); - m_application.SceneManager.ForEachScene( - delegate(Scene scene) - { - IDialogModule dialogModule = scene.RequestModuleInterface(); - if (dialogModule != null) - dialogModule.SendGeneralAlert(message); - }); - } - catch (Exception e) - { - m_log.ErrorFormat("[RADMIN]: Broadcasting: failed: {0}", e.Message, e.StackTrace); + responseData["accepted"] = true; + responseData["success"] = true; - responseData["accepted"] = false; - responseData["success"] = false; - responseData["error"] = e.Message; - response.Value = responseData; - } + m_application.SceneManager.ForEachScene( + delegate(Scene scene) + { + IDialogModule dialogModule = scene.RequestModuleInterface(); + if (dialogModule != null) + dialogModule.SendGeneralAlert(message); + }); m_log.Info("[RADMIN]: Alert request complete"); - return response; } - public XmlRpcResponse XmlRpcDialogMethod(XmlRpcRequest request, IPEndPoint remoteClient) + + public void XmlRpcDialogMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { - XmlRpcResponse response = new XmlRpcResponse(); - Hashtable responseData = new Hashtable(); + Hashtable responseData = (Hashtable)response.Value; m_log.Info("[RADMIN]: Dialog request started"); @@ -354,19 +362,12 @@ namespace OpenSim.ApplicationPlugins.RemoteController { Hashtable requestData = (Hashtable)request.Params[0]; - CheckStringParameters(request, new string[] { "password", "from", "message" }); - - if (m_requiredPassword != String.Empty && - (!requestData.Contains("password") || (string)requestData["password"] != m_requiredPassword)) - throw new Exception("wrong password"); - string message = (string)requestData["message"]; string fromuuid = (string)requestData["from"]; m_log.InfoFormat("[RADMIN]: Broadcasting: {0}", message); responseData["accepted"] = true; responseData["success"] = true; - response.Value = responseData; m_application.SceneManager.ForEachScene( delegate(Scene scene) @@ -384,197 +385,139 @@ namespace OpenSim.ApplicationPlugins.RemoteController 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, IPEndPoint remoteClient) + private void XmlRpcLoadHeightmapMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { - 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); - // foreach (string k in requestData.Keys) - // { - // m_log.DebugFormat("[RADMIN]: Load Terrain: XmlRpc {0}: >{1}< {2}", - // k, (string)requestData[k], ((string)requestData[k]).Length); - // } + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; - CheckStringParameters(request, new string[] {"password", "filename", "regionid"}); +// m_log.DebugFormat("[RADMIN]: Load Terrain: XmlRpc {0}", request); + // foreach (string k in requestData.Keys) + // { + // m_log.DebugFormat("[RADMIN]: Load Terrain: XmlRpc {0}: >{1}< {2}", + // k, (string)requestData[k], ((string)requestData[k]).Length); + // } - FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); + CheckStringParameters(requestData, responseData, new string[] {"filename", "regionid"}); - string file = (string) requestData["filename"]; - UUID regionID = (UUID) (string) requestData["regionid"]; - m_log.InfoFormat("[RADMIN]: Terrain Loading: {0}", file); - - responseData["accepted"] = true; - - LoadHeightmap(file, regionID); + string file = (string) requestData["filename"]; + UUID regionID = (UUID) (string) requestData["regionid"]; + m_log.InfoFormat("[RADMIN]: Terrain Loading: {0}", file); - responseData["success"] = false; + responseData["accepted"] = true; - response.Value = responseData; - } - catch (Exception e) - { - m_log.ErrorFormat("[RADMIN]: Terrain Loading: failed: {0} {1}", e.Message, e.StackTrace); + LoadHeightmap(file, regionID); - responseData["success"] = false; - responseData["error"] = e.Message; - } + responseData["success"] = false; m_log.Info("[RADMIN]: Load height maps request complete"); - - return response; } - public XmlRpcResponse XmlRpcSaveHeightmapMethod(XmlRpcRequest request, IPEndPoint remoteClient) + private void XmlRpcSaveHeightmapMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { - XmlRpcResponse response = new XmlRpcResponse(); - Hashtable responseData = new Hashtable(); - m_log.Info("[RADMIN]: Save height maps request started"); - try - { - Hashtable requestData = (Hashtable)request.Params[0]; - - m_log.DebugFormat("[RADMIN]: Save Terrain: XmlRpc {0}", request.ToString()); + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; - CheckStringParameters(request, new string[] { "password", "filename", "regionid" }); - - FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); - - string file = (string)requestData["filename"]; - UUID regionID = (UUID)(string)requestData["regionid"]; - m_log.InfoFormat("[RADMIN]: Terrain Saving: {0}", file); - - responseData["accepted"] = true; +// m_log.DebugFormat("[RADMIN]: Save Terrain: XmlRpc {0}", request.ToString()); - Scene region = null; + CheckStringParameters(requestData, responseData, new string[] { "filename", "regionid" }); - if (!m_application.SceneManager.TryGetScene(regionID, out region)) - throw new Exception("1: unable to get a scene with that name"); + string file = (string)requestData["filename"]; + UUID regionID = (UUID)(string)requestData["regionid"]; + m_log.InfoFormat("[RADMIN]: Terrain Saving: {0}", file); - ITerrainModule terrainModule = region.RequestModuleInterface(); - if (null == terrainModule) throw new Exception("terrain module not available"); + responseData["accepted"] = true; - terrainModule.SaveToFile(file); + Scene region = null; - responseData["success"] = false; + if (!m_application.SceneManager.TryGetScene(regionID, out region)) + throw new Exception("1: unable to get a scene with that name"); - response.Value = responseData; - } - catch (Exception e) - { - m_log.ErrorFormat("[RADMIN]: Terrain Saving: failed: {0}", e.Message); - m_log.DebugFormat("[RADMIN]: Terrain Saving: failed: {0}", e.ToString()); + ITerrainModule terrainModule = region.RequestModuleInterface(); + if (null == terrainModule) throw new Exception("terrain module not available"); - responseData["success"] = false; - responseData["error"] = e.Message; + terrainModule.SaveToFile(file); - } + responseData["success"] = false; m_log.Info("[RADMIN]: Save height maps request complete"); - - return response; } - public XmlRpcResponse XmlRpcShutdownMethod(XmlRpcRequest request, IPEndPoint remoteClient) + private void XmlRpcShutdownMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { m_log.Info("[RADMIN]: Received Shutdown Administrator Request"); - XmlRpcResponse response = new XmlRpcResponse(); - Hashtable responseData = new Hashtable(); + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; - try - { - Hashtable requestData = (Hashtable) request.Params[0]; + responseData["accepted"] = true; + response.Value = responseData; - FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); + int timeout = 2000; + string message; - responseData["accepted"] = true; - response.Value = responseData; + if (requestData.ContainsKey("shutdown") + && ((string) requestData["shutdown"] == "delayed") + && requestData.ContainsKey("milliseconds")) + { + timeout = Int32.Parse(requestData["milliseconds"].ToString()); - int timeout = 2000; - string message; + 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."; + } - if (requestData.ContainsKey("shutdown") - && ((string) requestData["shutdown"] == "delayed") - && requestData.ContainsKey("milliseconds")) - { - timeout = Int32.Parse(requestData["milliseconds"].ToString()); + if (requestData.ContainsKey("noticetype") + && ((string) requestData["noticetype"] == "dialog")) + { + m_application.SceneManager.ForEachScene( - message - = "Region is going down in " + ((int) (timeout/1000)).ToString() - + " second(s). Please save what you are doing and log out."; - } - else + delegate(Scene scene) { - message = "Region is going down now."; - } - - if (requestData.ContainsKey("noticetype") - && ((string) requestData["noticetype"] == "dialog")) + IDialogModule dialogModule = scene.RequestModuleInterface(); + if (dialogModule != null) + dialogModule.SendNotificationToUsersInRegion(UUID.Zero, "System", message); + }); + } + else + { + if (!requestData.ContainsKey("noticetype") + || ((string)requestData["noticetype"] != "none")) { m_application.SceneManager.ForEachScene( delegate(Scene scene) - { - IDialogModule dialogModule = scene.RequestModuleInterface(); - if (dialogModule != null) - dialogModule.SendNotificationToUsersInRegion(UUID.Zero, "System", message); - }); - } - else - { - if (!requestData.ContainsKey("noticetype") - || ((string)requestData["noticetype"] != "none")) { - m_application.SceneManager.ForEachScene( - delegate(Scene scene) - { - IDialogModule dialogModule = scene.RequestModuleInterface(); - if (dialogModule != null) - dialogModule.SendGeneralAlert(message); - }); - } - } - - - - // Perform shutdown - System.Timers.Timer shutdownTimer = new System.Timers.Timer(timeout); // Wait before firing - shutdownTimer.AutoReset = false; - shutdownTimer.Elapsed += new ElapsedEventHandler(shutdownTimer_Elapsed); - lock (shutdownTimer) - { - shutdownTimer.Start(); + IDialogModule dialogModule = scene.RequestModuleInterface(); + if (dialogModule != null) + dialogModule.SendGeneralAlert(message); + }); } - - responseData["success"] = true; } - catch (Exception e) - { - m_log.ErrorFormat("[RADMIN]: Shutdown: failed: {0} {1}", e.Message, e.StackTrace); - responseData["accepted"] = false; - responseData["error"] = e.Message; - - response.Value = responseData; + // Perform shutdown + System.Timers.Timer shutdownTimer = new System.Timers.Timer(timeout); // Wait before firing + shutdownTimer.AutoReset = false; + shutdownTimer.Elapsed += new ElapsedEventHandler(shutdownTimer_Elapsed); + lock (shutdownTimer) + { + shutdownTimer.Start(); } + + responseData["success"] = true; m_log.Info("[RADMIN]: Shutdown Administrator Request complete"); - return response; } private void shutdownTimer_Elapsed(object sender, ElapsedEventArgs e) @@ -645,12 +588,12 @@ namespace OpenSim.ApplicationPlugins.RemoteController /// name of the newly created region /// /// - public XmlRpcResponse XmlRpcCreateRegionMethod(XmlRpcRequest request, IPEndPoint remoteClient) + private void XmlRpcCreateRegionMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { m_log.Info("[RADMIN]: CreateRegion: new request"); - XmlRpcResponse response = new XmlRpcResponse(); - Hashtable responseData = new Hashtable(); + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; lock (m_requestLock) { @@ -658,255 +601,235 @@ namespace OpenSim.ApplicationPlugins.RemoteController bool m_enableVoiceForNewRegions = m_config.GetBoolean("create_region_enable_voice", false); bool m_publicAccess = m_config.GetBoolean("create_region_public", true); - try + CheckStringParameters(requestData, responseData, new string[] + { + "region_name", + "listen_ip", "external_address", + "estate_name" + }); + CheckIntegerParams(requestData, responseData, new string[] {"region_x", "region_y", "listen_port"}); + + // 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"])) { - 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"}); - - FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); - - // 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 { - 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)); + // OpenSim.ini can specify a different regions dir + IConfig startupConfig = (IConfig) m_configSource.Configs["Startup"]; + regionConfigPath = startupConfig.GetString("regionload_regionsdir", regionConfigPath).Trim(); } - else + catch (Exception) { - regionID = UUID.Random(); - m_log.DebugFormat("[RADMIN] CreateRegion: new region UUID {0}", regionID); + // No INI setting recorded. } - - // 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) + + string regionIniPath; + + if (requestData.Contains("region_file")) { - // 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."); - } + // 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 - { - 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); + throw new Exception("Invalid location for region file."); } else { - region.Persistent = false; + 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("/", "_"))); } - - // Set the estate - // Check for an existing estate - List estateIDs = m_application.EstateDataService.GetEstates((string) requestData["estate_name"]); - if (estateIDs.Count < 1) + 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 estateIDs = m_application.EstateDataService.GetEstates((string) requestData["estate_name"]); + if (estateIDs.Count < 1) + { + UUID userID = UUID.Zero; + if (requestData.ContainsKey("estate_owner_uuid")) { - 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."); - } + // ok, client wants us to use an explicit UUID + // regardless of what the avatar name provided + userID = new UUID((string) requestData["estate_owner_uuid"]); - // 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."); + // 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 { - 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."); - } + throw new Exception("Estate owner details not provided."); } - // Create the region and perform any initial initialization + // 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(); - IScene newScene; - m_application.CreateRegion(region, out newScene); + if (!m_application.EstateDataService.LinkRegion(region.RegionID, (int) region.EstateSettings.EstateID)) + throw new Exception("Failed to join estate."); + } + else + { + int estateID = estateIDs[0]; - // 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(); + region.EstateSettings = m_application.EstateDataService.LoadEstateSettings(region.RegionID, false); - // enable voice on newly created region if - // requested by either the XmlRpc request or the - // configuration - if (GetBoolean(requestData, "enable_voice", m_enableVoiceForNewRegions)) + if (region.EstateSettings.EstateID != estateID) { - List parcels = ((Scene)newScene).LandChannel.AllParcels(); + // The region is already part of an estate, but not the one we want. + region.EstateSettings = m_application.EstateDataService.LoadEstateSettings(estateID); - 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); - } + if (!m_application.EstateDataService.LinkRegion(region.RegionID, estateID)) + throw new Exception("Failed to join estate."); } + } + + // Create the region and perform any initial initialization - //Load Heightmap if specified to new region - if (requestData.Contains("heightmap_file")) - { - LoadHeightmap((string)requestData["heightmap_file"], region.RegionID); - } + IScene newScene; + m_application.CreateRegion(region, out newScene); - responseData["success"] = true; - responseData["region_name"] = region.RegionName; - responseData["region_uuid"] = region.RegionID.ToString(); + // 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(); - response.Value = responseData; - } - catch (Exception e) + // enable voice on newly created region if + // requested by either the XmlRpc request or the + // configuration + if (GetBoolean(requestData, "enable_voice", m_enableVoiceForNewRegions)) { - m_log.ErrorFormat("[RADMIN] CreateRegion: failed {0} {1}", e.Message, e.StackTrace); + List parcels = ((Scene)newScene).LandChannel.AllParcels(); - responseData["success"] = false; - responseData["error"] = e.Message; + 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); + } + } - response.Value = responseData; + //Load Heightmap if specified to new region + if (requestData.Contains("heightmap_file")) + { + LoadHeightmap((string)requestData["heightmap_file"], region.RegionID); } + responseData["success"] = true; + responseData["region_name"] = region.RegionName; + responseData["region_uuid"] = region.RegionID.ToString(); + m_log.Info("[RADMIN]: CreateRegion: request complete"); - return response; } } @@ -936,46 +859,28 @@ namespace OpenSim.ApplicationPlugins.RemoteController /// error message if success is false /// /// - public XmlRpcResponse XmlRpcDeleteRegionMethod(XmlRpcRequest request, IPEndPoint remoteClient) + private void XmlRpcDeleteRegionMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { m_log.Info("[RADMIN]: DeleteRegion: new request"); - XmlRpcResponse response = new XmlRpcResponse(); - Hashtable responseData = new Hashtable(); + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; lock (m_requestLock) { - try - { - Hashtable requestData = (Hashtable) request.Params[0]; - CheckStringParameters(request, new string[] {"password", "region_name"}); - - FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); - - Scene scene = null; - string regionName = (string) requestData["region_name"]; - if (!m_application.SceneManager.TryGetScene(regionName, out scene)) - throw new Exception(String.Format("region \"{0}\" does not exist", regionName)); - - m_application.RemoveRegion(scene, true); - - responseData["success"] = true; - responseData["region_name"] = regionName; + CheckStringParameters(requestData, responseData, new string[] {"region_name"}); - response.Value = responseData; - } - catch (Exception e) - { - m_log.ErrorFormat("[RADMIN] DeleteRegion: failed {0} {1}", e.Message, e.StackTrace); + Scene scene = null; + string regionName = (string) requestData["region_name"]; + if (!m_application.SceneManager.TryGetScene(regionName, out scene)) + throw new Exception(String.Format("region \"{0}\" does not exist", regionName)); - responseData["success"] = false; - responseData["error"] = e.Message; + m_application.RemoveRegion(scene, true); - response.Value = responseData; - } + responseData["success"] = true; + responseData["region_name"] = regionName; m_log.Info("[RADMIN]: DeleteRegion: request complete"); - return response; } } @@ -1007,69 +912,52 @@ namespace OpenSim.ApplicationPlugins.RemoteController /// error message if success is false /// /// - public XmlRpcResponse XmlRpcCloseRegionMethod(XmlRpcRequest request, IPEndPoint remoteClient) + private void XmlRpcCloseRegionMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { m_log.Info("[RADMIN]: CloseRegion: new request"); - XmlRpcResponse response = new XmlRpcResponse(); - Hashtable responseData = new Hashtable(); + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; Scene scene = null; lock (m_requestLock) { - try + if (requestData.ContainsKey("region_id") && + !String.IsNullOrEmpty((string) requestData["region_id"])) { - Hashtable requestData = (Hashtable) request.Params[0]; - CheckStringParameters(request, new string[] {"password"}); + // Region specified by UUID + UUID regionID = (UUID) (string) requestData["region_id"]; + if (!m_application.SceneManager.TryGetScene(regionID, out scene)) + throw new Exception(String.Format("region \"{0}\" does not exist", regionID)); - FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); + m_application.CloseRegion(scene); - if (requestData.ContainsKey("region_id") && - !String.IsNullOrEmpty((string) requestData["region_id"])) - { - // Region specified by UUID - UUID regionID = (UUID) (string) requestData["region_id"]; - if (!m_application.SceneManager.TryGetScene(regionID, out scene)) - throw new Exception(String.Format("region \"{0}\" does not exist", regionID)); - - m_application.CloseRegion(scene); - - responseData["success"] = true; - responseData["region_id"] = regionID; - - response.Value = responseData; - } - else if (requestData.ContainsKey("region_name") && - !String.IsNullOrEmpty((string) requestData["region_name"])) - { - // Region specified by name + responseData["success"] = true; + responseData["region_id"] = regionID; - string regionName = (string) requestData["region_name"]; - if (!m_application.SceneManager.TryGetScene(regionName, out scene)) - throw new Exception(String.Format("region \"{0}\" does not exist", regionName)); + response.Value = responseData; + } + else if ( + requestData.ContainsKey("region_name") + && !String.IsNullOrEmpty((string) requestData["region_name"])) + { + // Region specified by name - m_application.CloseRegion(scene); + string regionName = (string) requestData["region_name"]; + if (!m_application.SceneManager.TryGetScene(regionName, out scene)) + throw new Exception(String.Format("region \"{0}\" does not exist", regionName)); - responseData["success"] = true; - responseData["region_name"] = regionName; + m_application.CloseRegion(scene); - response.Value = responseData; - } - else - throw new Exception("no region specified"); + responseData["success"] = true; + responseData["region_name"] = regionName; } - catch (Exception e) + else { - m_log.ErrorFormat("[RADMIN]: CloseRegion: failed {0} {1}", e.Message, e.StackTrace); - - responseData["success"] = false; - responseData["error"] = e.Message; - - response.Value = responseData; + throw new Exception("no region specified"); } m_log.Info("[RADMIN]: CloseRegion: request complete"); - return response; } } @@ -1105,70 +993,53 @@ namespace OpenSim.ApplicationPlugins.RemoteController /// error message if success is false /// /// - public XmlRpcResponse XmlRpcModifyRegionMethod(XmlRpcRequest request, IPEndPoint remoteClient) + private void XmlRpcModifyRegionMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { m_log.Info("[RADMIN]: ModifyRegion: new request"); - XmlRpcResponse response = new XmlRpcResponse(); - Hashtable responseData = new Hashtable(); + + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; lock (m_requestLock) { - try - { - Hashtable requestData = (Hashtable) request.Params[0]; - CheckStringParameters(request, new string[] {"password", "region_name"}); + CheckStringParameters(requestData, responseData, new string[] {"region_name"}); - FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); + Scene scene = null; + string regionName = (string) requestData["region_name"]; + if (!m_application.SceneManager.TryGetScene(regionName, out scene)) + throw new Exception(String.Format("region \"{0}\" does not exist", regionName)); - Scene scene = null; - string regionName = (string) requestData["region_name"]; - if (!m_application.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 (scene.RegionInfo.Persistent) + scene.RegionInfo.EstateSettings.Save(); - // Modify access - scene.RegionInfo.EstateSettings.PublicAccess = - GetBoolean(requestData,"public", scene.RegionInfo.EstateSettings.PublicAccess); - if (scene.RegionInfo.Persistent) - scene.RegionInfo.EstateSettings.Save(); + if (requestData.ContainsKey("enable_voice")) + { + bool enableVoice = GetBoolean(requestData, "enable_voice", true); + List parcels = ((Scene)scene).LandChannel.AllParcels(); - if (requestData.ContainsKey("enable_voice")) + foreach (ILandObject parcel in parcels) { - bool enableVoice = GetBoolean(requestData, "enable_voice", true); - List parcels = ((Scene)scene).LandChannel.AllParcels(); - - foreach (ILandObject parcel in parcels) + if (enableVoice) { - if (enableVoice) - { - parcel.LandData.Flags |= (uint)ParcelFlags.AllowVoiceChat; - parcel.LandData.Flags |= (uint)ParcelFlags.UseEstateVoiceChan; - } - else - { - parcel.LandData.Flags &= ~(uint)ParcelFlags.AllowVoiceChat; - parcel.LandData.Flags &= ~(uint)ParcelFlags.UseEstateVoiceChan; - } - scene.LandChannel.UpdateLandObject(parcel.LandData.LocalID, parcel.LandData); + parcel.LandData.Flags |= (uint)ParcelFlags.AllowVoiceChat; + parcel.LandData.Flags |= (uint)ParcelFlags.UseEstateVoiceChan; } + else + { + parcel.LandData.Flags &= ~(uint)ParcelFlags.AllowVoiceChat; + parcel.LandData.Flags &= ~(uint)ParcelFlags.UseEstateVoiceChan; + } + scene.LandChannel.UpdateLandObject(parcel.LandData.LocalID, parcel.LandData); } - - responseData["success"] = true; - responseData["region_name"] = regionName; - - response.Value = responseData; } - catch (Exception e) - { - m_log.ErrorFormat("[RADMIN] ModifyRegion: failed {0} {1}", e.Message, e.StackTrace); - responseData["success"] = false; - responseData["error"] = e.Message; - - response.Value = responseData; - } + responseData["success"] = true; + responseData["region_name"] = regionName; m_log.Info("[RADMIN]: ModifyRegion: request complete"); - return response; } } @@ -1210,28 +1081,24 @@ namespace OpenSim.ApplicationPlugins.RemoteController /// /// /// - public XmlRpcResponse XmlRpcCreateUserMethod(XmlRpcRequest request, IPEndPoint remoteClient) + private void XmlRpcCreateUserMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { m_log.Info("[RADMIN]: CreateUser: new request"); - XmlRpcResponse response = new XmlRpcResponse(); - Hashtable responseData = new Hashtable(); + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; lock (m_requestLock) { try { - Hashtable requestData = (Hashtable) request.Params[0]; - // check completeness - CheckStringParameters(request, new string[] + CheckStringParameters(requestData, responseData, new string[] { - "password", "user_firstname", + "user_firstname", "user_lastname", "user_password", }); - CheckIntegerParams(request, new string[] {"start_region_x", "start_region_y"}); - - FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); + CheckIntegerParams(requestData, responseData, new string[] {"start_region_x", "start_region_y"}); // do the job string firstName = (string) requestData["user_firstname"]; @@ -1258,9 +1125,12 @@ namespace OpenSim.ApplicationPlugins.RemoteController GridRegion home = scene.GridService.GetRegionByPosition(scopeID, (int)(regionXLocation * Constants.RegionSize), (int)(regionYLocation * Constants.RegionSize)); - if (null == home) { + if (null == home) + { m_log.WarnFormat("[RADMIN]: Unable to set home region for newly created user account {0} {1}", firstName, lastName); - } else { + } + else + { scene.GridUserService.SetHome(account.PrincipalID.ToString(), home.RegionID, new Vector3(128, 128, 0), new Vector3(0, 1, 0)); m_log.DebugFormat("[RADMIN]: Set home region {0} for updated user account {1} {2}", home.RegionID, firstName, lastName); } @@ -1272,22 +1142,16 @@ namespace OpenSim.ApplicationPlugins.RemoteController responseData["success"] = true; responseData["avatar_uuid"] = account.PrincipalID.ToString(); - response.Value = responseData; - m_log.InfoFormat("[RADMIN]: CreateUser: User {0} {1} created, UUID {2}", firstName, lastName, account.PrincipalID); } catch (Exception e) { - m_log.ErrorFormat("[RADMIN]: CreateUser: failed: {0} {1}", e.Message, e.StackTrace); - - responseData["success"] = false; responseData["avatar_uuid"] = UUID.Zero.ToString(); - responseData["error"] = e.Message; - response.Value = responseData; + throw e; } + m_log.Info("[RADMIN]: CreateUser: request complete"); - return response; } } @@ -1323,62 +1187,43 @@ namespace OpenSim.ApplicationPlugins.RemoteController /// error message if success is false /// /// - public XmlRpcResponse XmlRpcUserExistsMethod(XmlRpcRequest request, IPEndPoint remoteClient) + private void XmlRpcUserExistsMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { 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"}); - - FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); - - string firstName = (string) requestData["user_firstname"]; - string lastName = (string) requestData["user_lastname"]; + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; - responseData["user_firstname"] = firstName; - responseData["user_lastname"] = lastName; + // check completeness + CheckStringParameters(requestData, responseData, new string[] {"user_firstname", "user_lastname"}); - UUID scopeID = m_application.SceneManager.CurrentOrFirstScene.RegionInfo.ScopeID; + string firstName = (string) requestData["user_firstname"]; + string lastName = (string) requestData["user_lastname"]; - UserAccount account = m_application.SceneManager.CurrentOrFirstScene.UserAccountService.GetUserAccount(scopeID, firstName, lastName); + responseData["user_firstname"] = firstName; + responseData["user_lastname"] = lastName; - if (null == account) - { - responseData["success"] = false; - responseData["lastlogin"] = 0; - } - else - { - GridUserInfo userInfo = m_application.SceneManager.CurrentOrFirstScene.GridUserService.GetGridUserInfo(account.PrincipalID.ToString()); - if (userInfo != null) - responseData["lastlogin"] = userInfo.Login; - else - responseData["lastlogin"] = 0; + UUID scopeID = m_application.SceneManager.CurrentOrFirstScene.RegionInfo.ScopeID; - responseData["success"] = true; - } + UserAccount account = m_application.SceneManager.CurrentOrFirstScene.UserAccountService.GetUserAccount(scopeID, firstName, lastName); - response.Value = responseData; - } - catch (Exception e) + if (null == account) { - m_log.ErrorFormat("[RADMIN]: UserExists: failed: {0} {1}", e.Message, e.StackTrace); - responseData["success"] = false; - responseData["error"] = e.Message; + responseData["lastlogin"] = 0; + } + else + { + GridUserInfo userInfo = m_application.SceneManager.CurrentOrFirstScene.GridUserService.GetGridUserInfo(account.PrincipalID.ToString()); + if (userInfo != null) + responseData["lastlogin"] = userInfo.Login; + else + responseData["lastlogin"] = 0; - response.Value = responseData; + responseData["success"] = true; } m_log.Info("[RADMIN]: UserExists: request complete"); - return response; } /// @@ -1423,27 +1268,23 @@ namespace OpenSim.ApplicationPlugins.RemoteController /// /// /// - public XmlRpcResponse XmlRpcUpdateUserAccountMethod(XmlRpcRequest request, IPEndPoint remoteClient) + private void XmlRpcUpdateUserAccountMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { m_log.Info("[RADMIN]: UpdateUserAccount: new request"); m_log.Warn("[RADMIN]: This method needs update for 0.7"); - XmlRpcResponse response = new XmlRpcResponse(); - Hashtable responseData = new Hashtable(); + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; lock (m_requestLock) { try { - Hashtable requestData = (Hashtable) request.Params[0]; - // check completeness - CheckStringParameters(request, new string[] { - "password", "user_firstname", + CheckStringParameters(requestData, responseData, new string[] { + "user_firstname", "user_lastname"}); - FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); - // do the job string firstName = (string) requestData["user_firstname"]; string lastName = (string) requestData["user_lastname"]; @@ -1529,1874 +1370,1683 @@ namespace OpenSim.ApplicationPlugins.RemoteController responseData["success"] = true; responseData["avatar_uuid"] = account.PrincipalID.ToString(); - response.Value = responseData; - m_log.InfoFormat("[RADMIN]: UpdateUserAccount: account for user {0} {1} updated, UUID {2}", firstName, lastName, account.PrincipalID); } catch (Exception e) { - m_log.ErrorFormat("[RADMIN] UpdateUserAccount: failed: {0} {1}", e.Message, e.StackTrace); - - responseData["success"] = false; responseData["avatar_uuid"] = UUID.Zero.ToString(); - responseData["error"] = e.Message; - response.Value = responseData; + throw e; } m_log.Info("[RADMIN]: UpdateUserAccount: request complete"); - return response; } } /// - /// This method is called by the user-create and user-modify methods to establish - /// or change, the user's appearance. Default avatar names can be specified via - /// the config file, but must correspond to avatars in the default appearance - /// file, or pre-existing in the user database. - /// This should probably get moved into somewhere more core eventually. - /// - private void UpdateUserAppearance(Hashtable responseData, Hashtable requestData, UUID userid) + /// Load an OAR file into a region.. + /// + /// incoming XML RPC request + /// + /// XmlRpcLoadOARMethod takes the following XMLRPC + /// parameters + /// + /// parameter namedescription + /// password + /// admin password as set in OpenSim.ini + /// filename + /// file name of the OAR file + /// region_uuid + /// UUID of the region + /// region_name + /// region name + /// merge + /// true if oar should be merged + /// skip-assets + /// true if assets should be skiped + /// + /// + /// region_uuid takes precedence over + /// region_name if both are present; one of both + /// must be present. + /// + /// XmlRpcLoadOARMethod returns + /// + /// namedescription + /// success + /// true or false + /// error + /// error message if success is false + /// + /// + private void XmlRpcLoadOARMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { - m_log.DebugFormat("[RADMIN]: updateUserAppearance"); - - string defaultMale = m_config.GetString("default_male", "Default Male"); - string defaultFemale = m_config.GetString("default_female", "Default Female"); - string defaultNeutral = m_config.GetString("default_female", "Default Default"); - string model = String.Empty; + m_log.Info("[RADMIN]: Received Load OAR Administrator Request"); - // Has a gender preference been supplied? + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; - if (requestData.Contains("gender")) + lock (m_requestLock) { - switch ((string)requestData["gender"]) + try { - case "m" : - case "male" : - model = defaultMale; - break; - case "f" : - case "female" : - model = defaultFemale; - break; - case "n" : - case "neutral" : - default : - model = defaultNeutral; - break; - } - } + CheckStringParameters(requestData, responseData, new string[] {"filename"}); - // Has an explicit model been specified? + string filename = (string) requestData["filename"]; + Scene scene = null; + if (requestData.Contains("region_uuid")) + { + UUID region_uuid = (UUID) (string) requestData["region_uuid"]; + if (!m_application.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_application.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"); + + bool mergeOar = false; + bool skipAssets = false; - if (requestData.Contains("model") && (String.IsNullOrEmpty((string)requestData["gender"]))) - { - model = (string)requestData["model"]; - } + if ((string)requestData["merge"] == "true") + { + mergeOar = true; + } + if ((string)requestData["skip-assets"] == "true") + { + skipAssets = true; + } - // No appearance attributes were set + IRegionArchiverModule archiver = scene.RequestModuleInterface(); + if (archiver != null) + archiver.DearchiveRegion(filename, mergeOar, skipAssets, Guid.Empty); + else + throw new Exception("Archiver module not present for scene"); - if (String.IsNullOrEmpty(model)) - { - m_log.DebugFormat("[RADMIN]: Appearance update not requested"); - return; - } + responseData["loaded"] = true; + } + catch (Exception e) + { + responseData["loaded"] = false; - m_log.DebugFormat("[RADMIN]: Setting appearance for avatar {0}, using model <{1}>", userid, model); + throw e; + } - string[] modelSpecifiers = model.Split(); - if (modelSpecifiers.Length != 2) - { - m_log.WarnFormat("[RADMIN]: User appearance not set for {0}. Invalid model name : <{1}>", userid, model); - // modelSpecifiers = dmodel.Split(); - return; - } - - Scene scene = m_application.SceneManager.CurrentOrFirstScene; - UUID scopeID = scene.RegionInfo.ScopeID; - UserAccount modelProfile = scene.UserAccountService.GetUserAccount(scopeID, modelSpecifiers[0], modelSpecifiers[1]); - - if (modelProfile == null) - { - m_log.WarnFormat("[RADMIN]: Requested model ({0}) not found. Appearance unchanged", model); - return; + m_log.Info("[RADMIN]: Load OAR Administrator Request complete"); } - - // Set current user's appearance. This bit is easy. The appearance structure is populated with - // actual asset ids, however to complete the magic we need to populate the inventory with the - // assets in question. - - EstablishAppearance(userid, modelProfile.PrincipalID); - - m_log.DebugFormat("[RADMIN]: Finished setting appearance for avatar {0}, using model {1}", - userid, model); } /// - /// This method is called by updateAvatarAppearance once any specified model has been - /// ratified, or an appropriate default value has been adopted. The intended prototype - /// is known to exist, as is the target avatar. - /// - private void EstablishAppearance(UUID destination, UUID source) + /// Save a region to an OAR file + /// + /// incoming XML RPC request + /// + /// XmlRpcSaveOARMethod takes the following XMLRPC + /// parameters + /// + /// parameter namedescription + /// password + /// admin password as set in OpenSim.ini + /// filename + /// file name for the OAR file + /// region_uuid + /// UUID of the region + /// region_name + /// region name + /// profile + /// profile url + /// noassets + /// true if no assets should be saved + /// perm + /// C and/or T + /// + /// + /// region_uuid takes precedence over + /// region_name if both are present; one of both + /// must be present. + /// + /// XmlRpcLoadOARMethod returns + /// + /// namedescription + /// success + /// true or false + /// error + /// error message if success is false + /// + /// + private void XmlRpcSaveOARMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { - m_log.DebugFormat("[RADMIN]: Initializing inventory for {0} from {1}", destination, source); - Scene scene = m_application.SceneManager.CurrentOrFirstScene; - - // If the model has no associated appearance we're done. - AvatarAppearance avatarAppearance = scene.AvatarService.GetAppearance(source); - if (avatarAppearance == null) - return; + m_log.Info("[RADMIN]: Received Save OAR Administrator Request"); - // Simple appearance copy or copy Clothing and Bodyparts folders? - bool copyFolders = m_config.GetBoolean("copy_folders", false); + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; - if (!copyFolders) + try { - // Simple copy of wearables and appearance update - try + CheckStringParameters(requestData, responseData, new string[] {"filename"}); + + string filename = (string)requestData["filename"]; + Scene scene = null; + if (requestData.Contains("region_uuid")) { - CopyWearablesAndAttachments(destination, source, avatarAppearance); + UUID region_uuid = (UUID) (string) requestData["region_uuid"]; + if (!m_application.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_application.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"); - scene.AvatarService.SetAppearance(destination, avatarAppearance); + Dictionary options = new Dictionary(); + + //if (requestData.Contains("version")) + //{ + // options["version"] = (string)requestData["version"]; + //} + + if (requestData.Contains("profile")) + { + options["profile"] = (string)requestData["profile"]; } - catch (Exception e) + + if (requestData["noassets"] == "true") { - m_log.WarnFormat("[RADMIN]: Error transferring appearance for {0} : {1}", - destination, e.Message); + options["noassets"] = (string)requestData["noassets"] ; } - return; - } + if (requestData.Contains("perm")) + { + options["checkPermissions"] = (string)requestData["perm"]; + } - // Copy Clothing and Bodypart folders and appearance update - try - { - Dictionary inventoryMap = new Dictionary(); - CopyInventoryFolders(destination, source, AssetType.Clothing, inventoryMap, avatarAppearance); - CopyInventoryFolders(destination, source, AssetType.Bodypart, inventoryMap, avatarAppearance); + IRegionArchiverModule archiver = scene.RequestModuleInterface(); - AvatarWearable[] wearables = avatarAppearance.Wearables; + if (archiver != null) + { + scene.EventManager.OnOarFileSaved += RemoteAdminOarSaveCompleted; + archiver.ArchiveRegion(filename, options); - for (int i=0; i - /// This method is called by establishAppearance to do a copy all inventory items - /// worn or attached to the Clothing inventory folder of the receiving avatar. - /// In parallel the avatar wearables and attachments are updated. - /// - private void CopyWearablesAndAttachments(UUID destination, UUID source, AvatarAppearance avatarAppearance) + private void RemoteAdminOarSaveCompleted(Guid uuid, string name) { - IInventoryService inventoryService = m_application.SceneManager.CurrentOrFirstScene.InventoryService; - - // Get Clothing folder of receiver - InventoryFolderBase destinationFolder = inventoryService.GetFolderForType(destination, AssetType.Clothing); - - if (destinationFolder == null) - throw new Exception("Cannot locate folder(s)"); + m_log.DebugFormat("[RADMIN]: File processing complete for {0}", name); + lock (m_saveOarLock) + Monitor.Pulse(m_saveOarLock); + } - // Missing destination folder? This should *never* be the case - if (destinationFolder.Type != (short)AssetType.Clothing) - { - destinationFolder = new InventoryFolderBase(); - - destinationFolder.ID = UUID.Random(); - destinationFolder.Name = "Clothing"; - destinationFolder.Owner = destination; - destinationFolder.Type = (short)AssetType.Clothing; - destinationFolder.ParentID = inventoryService.GetRootFolder(destination).ID; - destinationFolder.Version = 1; - inventoryService.AddFolder(destinationFolder); // store base record - m_log.ErrorFormat("[RADMIN]: Created folder for destination {0}", source); - } + private void XmlRpcLoadXMLMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + { + m_log.Info("[RADMIN]: Received Load XML Administrator Request"); - // Wearables - AvatarWearable[] wearables = avatarAppearance.Wearables; - AvatarWearable wearable; + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; - for (int i = 0; i attachments = avatarAppearance.GetAttachments(); + m_log.InfoFormat("[RADMIN]: Switched to region {0}", region_name); + } + else throw new Exception("neither region_name nor region_uuid given"); - foreach (AvatarAttachment attachment in attachments) - { - int attachpoint = attachment.AttachPoint; - UUID itemID = attachment.ItemID; + responseData["switched"] = true; - if (itemID != UUID.Zero) - { - // Get inventory item and copy it - InventoryItemBase item = new InventoryItemBase(itemID, source); - item = inventoryService.GetItem(item); + string xml_version = "1"; + if (requestData.Contains("xml_version")) + { + xml_version = (string) requestData["xml_version"]; + } - if (item != null) + switch (xml_version) { - InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination); - destinationItem.Name = item.Name; - destinationItem.Owner = destination; - destinationItem.Description = item.Description; - destinationItem.InvType = item.InvType; - destinationItem.CreatorId = item.CreatorId; - destinationItem.CreatorIdAsUuid = item.CreatorIdAsUuid; - destinationItem.CreatorData = item.CreatorData; - destinationItem.NextPermissions = item.NextPermissions; - destinationItem.CurrentPermissions = item.CurrentPermissions; - destinationItem.BasePermissions = item.BasePermissions; - destinationItem.EveryOnePermissions = item.EveryOnePermissions; - destinationItem.GroupPermissions = item.GroupPermissions; - destinationItem.AssetType = item.AssetType; - destinationItem.AssetID = item.AssetID; - destinationItem.GroupID = item.GroupID; - destinationItem.GroupOwned = item.GroupOwned; - destinationItem.SalePrice = item.SalePrice; - destinationItem.SaleType = item.SaleType; - destinationItem.Flags = item.Flags; - destinationItem.CreationDate = item.CreationDate; - destinationItem.Folder = destinationFolder.ID; - ApplyNextOwnerPermissions(destinationItem); + case "1": + m_application.SceneManager.LoadCurrentSceneFromXml(filename, true, new Vector3(0, 0, 0)); + break; - m_application.SceneManager.CurrentOrFirstScene.AddInventoryItem(destinationItem); - m_log.DebugFormat("[RADMIN]: Added item {0} to folder {1}", destinationItem.ID, destinationFolder.ID); + case "2": + m_application.SceneManager.LoadCurrentSceneFromXml2(filename); + break; - // Attach item - avatarAppearance.SetAttachment(attachpoint, destinationItem.ID, destinationItem.AssetID); - m_log.DebugFormat("[RADMIN]: Attached {0}", destinationItem.ID); - } - else - { - m_log.WarnFormat("[RADMIN]: Error transferring {0} to folder {1}", itemID, destinationFolder.ID); + default: + throw new Exception(String.Format("unknown Xml{0} format", xml_version)); } + + responseData["loaded"] = true; + } + catch (Exception e) + { + responseData["loaded"] = false; + responseData["switched"] = false; + + throw e; } + + m_log.Info("[RADMIN]: Load XML Administrator Request complete"); } } - /// - /// This method is called by establishAppearance to copy inventory folders to make - /// copies of Clothing and Bodyparts inventory folders and attaches worn attachments - /// - private void CopyInventoryFolders(UUID destination, UUID source, AssetType assetType, Dictionary inventoryMap, - AvatarAppearance avatarAppearance) + private void XmlRpcSaveXMLMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { - IInventoryService inventoryService = m_application.SceneManager.CurrentOrFirstScene.InventoryService; - - InventoryFolderBase sourceFolder = inventoryService.GetFolderForType(source, assetType); - InventoryFolderBase destinationFolder = inventoryService.GetFolderForType(destination, assetType); + m_log.Info("[RADMIN]: Received Save XML Administrator Request"); - if (sourceFolder == null || destinationFolder == null) - throw new Exception("Cannot locate folder(s)"); + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; - // Missing source folder? This should *never* be the case - if (sourceFolder.Type != (short)assetType) + try { - sourceFolder = new InventoryFolderBase(); - sourceFolder.ID = UUID.Random(); - if (assetType == AssetType.Clothing) { - sourceFolder.Name = "Clothing"; - } else { - sourceFolder.Name = "Body Parts"; - } - sourceFolder.Owner = source; - sourceFolder.Type = (short)assetType; - sourceFolder.ParentID = inventoryService.GetRootFolder(source).ID; - sourceFolder.Version = 1; - inventoryService.AddFolder(sourceFolder); // store base record - m_log.ErrorFormat("[RADMIN] Created folder for source {0}", source); - } + CheckStringParameters(requestData, responseData, new string[] {"filename"}); - // Missing destination folder? This should *never* be the case - if (destinationFolder.Type != (short)assetType) - { - destinationFolder = new InventoryFolderBase(); - destinationFolder.ID = UUID.Random(); - if (assetType == AssetType.Clothing) + string filename = (string) requestData["filename"]; + if (requestData.Contains("region_uuid")) { - destinationFolder.Name = "Clothing"; + UUID region_uuid = (UUID) (string) requestData["region_uuid"]; + if (!m_application.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 + else if (requestData.Contains("region_name")) { - destinationFolder.Name = "Body Parts"; + string region_name = (string) requestData["region_name"]; + if (!m_application.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); } - destinationFolder.Owner = destination; - destinationFolder.Type = (short)assetType; - destinationFolder.ParentID = inventoryService.GetRootFolder(destination).ID; - destinationFolder.Version = 1; - inventoryService.AddFolder(destinationFolder); // store base record - m_log.ErrorFormat("[RADMIN]: Created folder for destination {0}", source); - } - - InventoryFolderBase extraFolder; - List folders = inventoryService.GetFolderContent(source, sourceFolder.ID).Folders; - - foreach (InventoryFolderBase folder in folders) - { - extraFolder = new InventoryFolderBase(); - extraFolder.ID = UUID.Random(); - extraFolder.Name = folder.Name; - extraFolder.Owner = destination; - extraFolder.Type = folder.Type; - extraFolder.Version = folder.Version; - extraFolder.ParentID = destinationFolder.ID; - inventoryService.AddFolder(extraFolder); + else throw new Exception("neither region_name nor region_uuid given"); - m_log.DebugFormat("[RADMIN]: Added folder {0} to folder {1}", extraFolder.ID, sourceFolder.ID); + responseData["switched"] = true; - List items = inventoryService.GetFolderContent(source, folder.ID).Items; + string xml_version = "1"; + if (requestData.Contains("xml_version")) + { + xml_version = (string) requestData["xml_version"]; + } - foreach (InventoryItemBase item in items) + switch (xml_version) { - InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination); - destinationItem.Name = item.Name; - destinationItem.Owner = destination; - destinationItem.Description = item.Description; - destinationItem.InvType = item.InvType; - destinationItem.CreatorId = item.CreatorId; - destinationItem.CreatorIdAsUuid = item.CreatorIdAsUuid; - destinationItem.CreatorData = item.CreatorData; - destinationItem.NextPermissions = item.NextPermissions; - destinationItem.CurrentPermissions = item.CurrentPermissions; - destinationItem.BasePermissions = item.BasePermissions; - destinationItem.EveryOnePermissions = item.EveryOnePermissions; - destinationItem.GroupPermissions = item.GroupPermissions; - destinationItem.AssetType = item.AssetType; - destinationItem.AssetID = item.AssetID; - destinationItem.GroupID = item.GroupID; - destinationItem.GroupOwned = item.GroupOwned; - destinationItem.SalePrice = item.SalePrice; - destinationItem.SaleType = item.SaleType; - destinationItem.Flags = item.Flags; - destinationItem.CreationDate = item.CreationDate; - destinationItem.Folder = extraFolder.ID; - ApplyNextOwnerPermissions(destinationItem); + case "1": + m_application.SceneManager.SaveCurrentSceneToXml(filename); + break; - m_application.SceneManager.CurrentOrFirstScene.AddInventoryItem(destinationItem); - inventoryMap.Add(item.ID, destinationItem.ID); - m_log.DebugFormat("[RADMIN]: Added item {0} to folder {1}", destinationItem.ID, extraFolder.ID); + case "2": + m_application.SceneManager.SaveCurrentSceneToXml2(filename); + break; - // Attach item, if original is attached - int attachpoint = avatarAppearance.GetAttachpoint(item.ID); - if (attachpoint != 0) - { - avatarAppearance.SetAttachment(attachpoint, destinationItem.ID, destinationItem.AssetID); - m_log.DebugFormat("[RADMIN]: Attached {0}", destinationItem.ID); - } + default: + throw new Exception(String.Format("unknown Xml{0} format", xml_version)); } + + responseData["saved"] = true; } + catch (Exception e) + { + responseData["saved"] = false; + responseData["switched"] = false; + + throw e; + } + + m_log.Info("[RADMIN]: Save XML Administrator Request complete"); } - /// - /// Apply next owner permissions. - /// - private void ApplyNextOwnerPermissions(InventoryItemBase item) + private void XmlRpcRegionQueryMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { - if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) + m_log.Info("[RADMIN]: Received Query XML Administrator Request"); + + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; + + responseData["success"] = true; + + if (requestData.Contains("region_uuid")) { - if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) - item.CurrentPermissions &= ~(uint)PermissionMask.Copy; - if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) - item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; - if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) - item.CurrentPermissions &= ~(uint)PermissionMask.Modify; + UUID region_uuid = (UUID) (string) requestData["region_uuid"]; + if (!m_application.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()); } - item.CurrentPermissions &= item.NextPermissions; - item.BasePermissions &= item.NextPermissions; - item.EveryOnePermissions &= item.NextPermissions; - // item.OwnerChanged = true; - // item.PermsMask = 0; - // item.PermsGranter = UUID.Zero; - } + else if (requestData.Contains("region_name")) + { + string region_name = (string) requestData["region_name"]; + if (!m_application.SceneManager.TrySetCurrentScene(region_name)) + throw new Exception(String.Format("failed to switch to region {0}", region_name)); - /// - /// This method is called if a given model avatar name can not be found. If the external - /// file has already been loaded once, then control returns immediately. If not, then it - /// looks for a default appearance file. This file contains XML definitions of zero or more named - /// avatars, each avatar can specify zero or more "outfits". Each outfit is a collection - /// of items that together, define a particular ensemble for the avatar. Each avatar should - /// indicate which outfit is the default, and this outfit will be automatically worn. The - /// other outfits are provided to allow "real" avatars a way to easily change their outfits. - /// - private bool CreateDefaultAvatars() - { - // Only load once - if (m_defaultAvatarsLoaded) + m_log.InfoFormat("[RADMIN]: Switched to region {0}", region_name); + } + else { - return false; + throw new Exception("neither region_name nor region_uuid given"); } - m_log.DebugFormat("[RADMIN]: Creating default avatar entries"); + Scene scene = m_application.SceneManager.CurrentScene; - m_defaultAvatarsLoaded = true; + int flags; + string text; + int health = scene.GetHealth(out flags, out text); + responseData["health"] = health; + responseData["flags"] = flags; + responseData["message"] = text; - // Load processing starts here... + m_log.Info("[RADMIN]: Query XML Administrator Request complete"); + } - try - { - string defaultAppearanceFileName = null; + private void XmlRpcConsoleCommandMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + { + m_log.Info("[RADMIN]: Received Command XML Administrator Request"); - //m_config may be null if RemoteAdmin configuration secition is missing or disabled in OpenSim.ini - if (m_config != null) - { - defaultAppearanceFileName = m_config.GetString("default_appearance", "default_appearance.xml"); - } + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; - if (File.Exists(defaultAppearanceFileName)) - { - XmlDocument doc = new XmlDocument(); - string name = "*unknown*"; - string email = "anon@anon"; - uint regionXLocation = 1000; - uint regionYLocation = 1000; - string password = UUID.Random().ToString(); // No requirement to sign-in. - UUID ID = UUID.Zero; - AvatarAppearance avatarAppearance; - XmlNodeList avatars; - XmlNodeList assets; - XmlNode perms = null; - bool include = false; - bool select = false; + CheckStringParameters(requestData, responseData, new string[] {"command"}); - Scene scene = m_application.SceneManager.CurrentOrFirstScene; - IInventoryService inventoryService = scene.InventoryService; - IAssetService assetService = scene.AssetService; + MainConsole.Instance.RunCommand(requestData["command"].ToString()); - doc.LoadXml(File.ReadAllText(defaultAppearanceFileName)); + m_log.Info("[RADMIN]: Command XML Administrator Request complete"); + } - // Load up any included assets. Duplicates will be ignored - assets = doc.GetElementsByTagName("RequiredAsset"); - foreach (XmlNode assetNode in assets) - { - AssetBase asset = new AssetBase(UUID.Random(), GetStringAttribute(assetNode, "name", ""), SByte.Parse(GetStringAttribute(assetNode, "type", "")), UUID.Zero.ToString()); - asset.Description = GetStringAttribute(assetNode,"desc",""); - asset.Local = Boolean.Parse(GetStringAttribute(assetNode,"local","")); - asset.Temporary = Boolean.Parse(GetStringAttribute(assetNode,"temporary","")); - asset.Data = Convert.FromBase64String(assetNode.InnerText); - assetService.Store(asset); - } + private void XmlRpcAccessListClear(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + { + m_log.Info("[RADMIN]: Received Access List Clear Request"); - avatars = doc.GetElementsByTagName("Avatar"); + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; - // The document may contain multiple avatars + responseData["success"] = true; - foreach (XmlElement avatar in avatars) + if (requestData.Contains("region_uuid")) + { + UUID region_uuid = (UUID) (string) requestData["region_uuid"]; + if (!m_application.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_application.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 scene = m_application.SceneManager.CurrentScene; + scene.RegionInfo.EstateSettings.EstateAccess = new UUID[]{}; + + if (scene.RegionInfo.Persistent) + scene.RegionInfo.EstateSettings.Save(); + + m_log.Info("[RADMIN]: Access List Clear Request complete"); + } + + private void XmlRpcAccessListAdd(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + { + m_log.Info("[RADMIN]: Received Access List Add Request"); + + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; + + if (requestData.Contains("region_uuid")) + { + UUID region_uuid = (UUID) (string) requestData["region_uuid"]; + if (!m_application.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_application.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 addedUsers = 0; + + if (requestData.Contains("users")) + { + UUID scopeID = m_application.SceneManager.CurrentOrFirstScene.RegionInfo.ScopeID; + IUserAccountService userService = m_application.SceneManager.CurrentOrFirstScene.UserAccountService; + Scene scene = m_application.SceneManager.CurrentScene; + Hashtable users = (Hashtable) requestData["users"]; + List uuids = new List(); + foreach (string name in users.Values) + { + string[] parts = name.Split(); + UserAccount account = userService.GetUserAccount(scopeID, parts[0], parts[1]); + if (account != null) { - m_log.DebugFormat("[RADMIN]: Loading appearance for {0}, gender = {1}", - GetStringAttribute(avatar,"name","?"), GetStringAttribute(avatar,"gender","?")); + uuids.Add(account.PrincipalID); + m_log.DebugFormat("[RADMIN]: adding \"{0}\" to ACL for \"{1}\"", name, scene.RegionInfo.RegionName); + } + } + List accessControlList = new List(scene.RegionInfo.EstateSettings.EstateAccess); + foreach (UUID uuid in uuids) + { + if (!accessControlList.Contains(uuid)) + { + accessControlList.Add(uuid); + addedUsers++; + } + } + scene.RegionInfo.EstateSettings.EstateAccess = accessControlList.ToArray(); + if (scene.RegionInfo.Persistent) + scene.RegionInfo.EstateSettings.Save(); + } - // Create the user identified by the avatar entry + responseData["added"] = addedUsers; - try - { - // Only the name value is mandatory - name = GetStringAttribute(avatar,"name",name); - email = GetStringAttribute(avatar,"email",email); - regionXLocation = GetUnsignedAttribute(avatar,"regx",regionXLocation); - regionYLocation = GetUnsignedAttribute(avatar,"regy",regionYLocation); - password = GetStringAttribute(avatar,"password",password); + m_log.Info("[RADMIN]: Access List Add Request complete"); + } - string[] names = name.Split(); - UUID scopeID = scene.RegionInfo.ScopeID; - UserAccount account = scene.UserAccountService.GetUserAccount(scopeID, names[0], names[1]); - if (null == account) - { - account = CreateUser(scopeID, names[0], names[1], password, email); - if (null == account) - { - m_log.ErrorFormat("[RADMIN]: Avatar {0} {1} was not created", names[0], names[1]); - return false; - } - } + private void XmlRpcAccessListRemove(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + { + m_log.Info("[RADMIN]: Received Access List Remove Request"); - // Set home position + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; - GridRegion home = scene.GridService.GetRegionByPosition(scopeID, - (int)(regionXLocation * Constants.RegionSize), (int)(regionYLocation * Constants.RegionSize)); - if (null == home) { - m_log.WarnFormat("[RADMIN]: Unable to set home region for newly created user account {0} {1}", names[0], names[1]); - } else { - scene.GridUserService.SetHome(account.PrincipalID.ToString(), home.RegionID, new Vector3(128, 128, 0), new Vector3(0, 1, 0)); - m_log.DebugFormat("[RADMIN]: Set home region {0} for updated user account {1} {2}", home.RegionID, names[0], names[1]); - } + responseData["success"] = true; - ID = account.PrincipalID; + if (requestData.Contains("region_uuid")) + { + UUID region_uuid = (UUID) (string) requestData["region_uuid"]; + if (!m_application.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_application.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"); - m_log.DebugFormat("[RADMIN]: User {0}[{1}] created or retrieved", name, ID); - include = true; - } - catch (Exception e) - { - m_log.DebugFormat("[RADMIN]: Error creating user {0} : {1}", name, e.Message); - include = false; - } + int removedUsers = 0; - // OK, User has been created OK, now we can install the inventory. - // First retrieve the current inventory (the user may already exist) - // Note that althought he inventory is retrieved, the hierarchy has - // not been interpreted at all. + if (requestData.Contains("users")) + { + UUID scopeID = m_application.SceneManager.CurrentOrFirstScene.RegionInfo.ScopeID; + IUserAccountService userService = m_application.SceneManager.CurrentOrFirstScene.UserAccountService; + //UserProfileCacheService ups = m_application.CommunicationsManager.UserProfileCacheService; + Scene scene = m_application.SceneManager.CurrentScene; + Hashtable users = (Hashtable) requestData["users"]; + List uuids = new List(); + foreach (string name in users.Values) + { + string[] parts = name.Split(); + UserAccount account = userService.GetUserAccount(scopeID, parts[0], parts[1]); + if (account != null) + { + uuids.Add(account.PrincipalID); + } + } + List accessControlList = new List(scene.RegionInfo.EstateSettings.EstateAccess); + foreach (UUID uuid in uuids) + { + if (accessControlList.Contains(uuid)) + { + accessControlList.Remove(uuid); + removedUsers++; + } + } + scene.RegionInfo.EstateSettings.EstateAccess = accessControlList.ToArray(); + if (scene.RegionInfo.Persistent) + scene.RegionInfo.EstateSettings.Save(); + } - if (include) - { - // Setup for appearance processing - avatarAppearance = scene.AvatarService.GetAppearance(ID); - if (avatarAppearance == null) - avatarAppearance = new AvatarAppearance(); + responseData["removed"] = removedUsers; - AvatarWearable[] wearables = avatarAppearance.Wearables; - for (int i=0; i folders = inventoryService.GetFolderContent(ID, clothingFolder.ID).Folders; - extraFolder = null; + private void XmlRpcTeleportAgentMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + { + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; - foreach (InventoryFolderBase folder in folders) - { - if (folder.Name == outfitName) - { - extraFolder = folder; - break; - } - } + UUID agentId; + string regionName = null; + Vector3 pos, lookAt; + ScenePresence sp = null; - // Otherwise, we must create the folder. - if (extraFolder == null) - { - m_log.DebugFormat("[RADMIN]: Creating outfit folder {0} for {1}", outfitName, name); - extraFolder = new InventoryFolderBase(); - extraFolder.ID = UUID.Random(); - extraFolder.Name = outfitName; - extraFolder.Owner = ID; - extraFolder.Type = (short)AssetType.Clothing; - extraFolder.Version = 1; - extraFolder.ParentID = clothingFolder.ID; - inventoryService.AddFolder(extraFolder); - m_log.DebugFormat("[RADMIN]: Adding outfile folder {0} to folder {1}", extraFolder.ID, clothingFolder.ID); - } + if (requestData.Contains("agent_first_name") && requestData.Contains("agent_last_name")) + { + string firstName = requestData["agent_first_name"].ToString(); + string lastName = requestData["agent_last_name"].ToString(); + m_application.SceneManager.TryGetRootScenePresenceByName(firstName, lastName, out sp); - // Now get the pieces that make up the outfit - XmlNodeList items = outfit.GetElementsByTagName("Item"); + if (sp == null) + throw new Exception( + string.Format( + "No agent found with agent_first_name {0} and agent_last_name {1}", firstName, lastName)); + } + else if (requestData.Contains("agent_id")) + { + string rawAgentId = (string)requestData["agent_id"]; - foreach (XmlElement item in items) - { - assetid = UUID.Zero; - XmlNodeList children = item.ChildNodes; - foreach (XmlNode child in children) - { - switch (child.Name) - { - case "Permissions" : - m_log.DebugFormat("[RADMIN]: Permissions specified"); - perms = child; - break; - case "Asset" : - assetid = new UUID(child.InnerText); - break; - } - } + if (!UUID.TryParse(rawAgentId, out agentId)) + throw new Exception(string.Format("agent_id {0} does not have the correct id format", rawAgentId)); - InventoryItemBase inventoryItem = null; + m_application.SceneManager.TryGetRootScenePresence(agentId, out sp); - // Check if asset is in inventory already - inventoryItem = null; - List inventoryItems = inventoryService.GetFolderContent(ID, extraFolder.ID).Items; + if (sp == null) + throw new Exception(string.Format("No agent with agent_id {0} found in this simulator", agentId)); + } + else + { + throw new Exception("No agent_id or agent_first_name and agent_last_name parameters specified"); + } - foreach (InventoryItemBase listItem in inventoryItems) - { - if (listItem.AssetID == assetid) - { - inventoryItem = listItem; - break; - } - } + if (requestData.Contains("region_name")) + regionName = (string)requestData["region_name"]; - // Create inventory item - if (inventoryItem == null) - { - inventoryItem = new InventoryItemBase(UUID.Random(), ID); - inventoryItem.Name = GetStringAttribute(item,"name",""); - inventoryItem.Description = GetStringAttribute(item,"desc",""); - inventoryItem.InvType = GetIntegerAttribute(item,"invtype",-1); - inventoryItem.CreatorId = GetStringAttribute(item,"creatorid",""); - inventoryItem.CreatorIdAsUuid = (UUID)GetStringAttribute(item,"creatoruuid",""); - inventoryItem.CreatorData = GetStringAttribute(item, "creatordata", ""); - inventoryItem.NextPermissions = GetUnsignedAttribute(perms, "next", 0x7fffffff); - inventoryItem.CurrentPermissions = GetUnsignedAttribute(perms,"current",0x7fffffff); - inventoryItem.BasePermissions = GetUnsignedAttribute(perms,"base",0x7fffffff); - inventoryItem.EveryOnePermissions = GetUnsignedAttribute(perms,"everyone",0x7fffffff); - inventoryItem.GroupPermissions = GetUnsignedAttribute(perms,"group",0x7fffffff); - inventoryItem.AssetType = GetIntegerAttribute(item,"assettype",-1); - inventoryItem.AssetID = assetid; // associated asset - inventoryItem.GroupID = (UUID)GetStringAttribute(item,"groupid",""); - inventoryItem.GroupOwned = (GetStringAttribute(item,"groupowned","false") == "true"); - inventoryItem.SalePrice = GetIntegerAttribute(item,"saleprice",0); - inventoryItem.SaleType = (byte)GetIntegerAttribute(item,"saletype",0); - inventoryItem.Flags = GetUnsignedAttribute(item,"flags",0); - inventoryItem.CreationDate = GetIntegerAttribute(item,"creationdate",Util.UnixTimeSinceEpoch()); - inventoryItem.Folder = extraFolder.ID; // Parent folder - - m_application.SceneManager.CurrentOrFirstScene.AddInventoryItem(inventoryItem); - m_log.DebugFormat("[RADMIN]: Added item {0} to folder {1}", inventoryItem.ID, extraFolder.ID); - } - - // Attach item, if attachpoint is specified - int attachpoint = GetIntegerAttribute(item,"attachpoint",0); - if (attachpoint != 0) - { - avatarAppearance.SetAttachment(attachpoint, inventoryItem.ID, inventoryItem.AssetID); - m_log.DebugFormat("[RADMIN]: Attached {0}", inventoryItem.ID); - } + pos.X = ParseFloat(requestData, "pos_x", sp.AbsolutePosition.X); + pos.Y = ParseFloat(requestData, "pos_y", sp.AbsolutePosition.Y); + pos.Z = ParseFloat(requestData, "pos_z", sp.AbsolutePosition.Z); + lookAt.X = ParseFloat(requestData, "lookat_x", sp.Lookat.X); + lookAt.Y = ParseFloat(requestData, "lookat_y", sp.Lookat.Y); + lookAt.Z = ParseFloat(requestData, "lookat_z", sp.Lookat.Z); - // Record whether or not the item is to be initially worn - try - { - if (select && (GetStringAttribute(item, "wear", "false") == "true")) - { - avatarAppearance.Wearables[inventoryItem.Flags].Wear(inventoryItem.ID, inventoryItem.AssetID); - } - } - catch (Exception e) - { - m_log.WarnFormat("[RADMIN]: Error wearing item {0} : {1}", inventoryItem.ID, e.Message); - } - } // foreach item in outfit - m_log.DebugFormat("[RADMIN]: Outfit {0} load completed", outfitName); - } // foreach outfit - m_log.DebugFormat("[RADMIN]: Inventory update complete for {0}", name); - scene.AvatarService.SetAppearance(ID, avatarAppearance); - } - catch (Exception e) - { - m_log.WarnFormat("[RADMIN]: Inventory processing incomplete for user {0} : {1}", - name, e.Message); - } - } // End of include - } - m_log.DebugFormat("[RADMIN]: Default avatar loading complete"); - } - else - { - m_log.DebugFormat("[RADMIN]: No default avatar information available"); - return false; - } - } - catch (Exception e) - { - m_log.WarnFormat("[RADMIN]: Exception whilst loading default avatars ; {0}", e.Message); - return false; - } + sp.Scene.RequestTeleportLocation( + sp.ControllingClient, regionName, pos, lookAt, (uint)Constants.TeleportFlags.ViaLocation); - return true; + // We have no way of telling the failure of the actual teleport + responseData["success"] = true; } /// - /// Load an OAR file into a region.. - /// - /// incoming XML RPC request + /// Parse a float with the given parameter name from a request data hash table. + /// /// - /// XmlRpcLoadOARMethod takes the following XMLRPC - /// parameters - /// - /// parameter namedescription - /// password - /// admin password as set in OpenSim.ini - /// filename - /// file name of the OAR file - /// region_uuid - /// UUID of the region - /// region_name - /// region name - /// merge - /// true if oar should be merged - /// skip-assets - /// true if assets should be skiped - /// - /// - /// region_uuid takes precedence over - /// region_name if both are present; one of both - /// must be present. - /// - /// XmlRpcLoadOARMethod returns - /// - /// namedescription - /// success - /// true or false - /// error - /// error message if success is false - /// + /// Will throw an exception if parameter is not a float. + /// Will not throw if parameter is not found, passes back default value instead. /// - public XmlRpcResponse XmlRpcLoadOARMethod(XmlRpcRequest request, IPEndPoint remoteClient) + /// + /// + /// + /// + private static float ParseFloat(Hashtable requestData, string paramName, float defaultVal) { - m_log.Info("[RADMIN]: Received Load OAR Administrator Request"); + if (requestData.Contains(paramName)) + { + string rawVal = (string)requestData[paramName]; + float val; - XmlRpcResponse response = new XmlRpcResponse(); - Hashtable responseData = new Hashtable(); + if (!float.TryParse(rawVal, out val)) + throw new Exception(string.Format("{0} {1} is not a valid float", paramName, rawVal)); + else + return val; + } + else + { + return defaultVal; + } + } - lock (m_requestLock) + private static void CheckStringParameters(Hashtable requestData, Hashtable responseData, string[] param) + { + foreach (string parameter in param) { - try + if (!requestData.Contains(parameter)) { - Hashtable requestData = (Hashtable) request.Params[0]; - - CheckStringParameters(request, new string[] { - "password", "filename"}); - - FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); - - string filename = (string) requestData["filename"]; - Scene scene = null; - if (requestData.Contains("region_uuid")) - { - UUID region_uuid = (UUID) (string) requestData["region_uuid"]; - if (!m_application.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_application.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"); - - bool mergeOar = false; - bool skipAssets = false; - - if ((string)requestData["merge"] == "true") - { - mergeOar = true; - } - if ((string)requestData["skip-assets"] == "true") - { - skipAssets = true; - } - - IRegionArchiverModule archiver = scene.RequestModuleInterface(); - if (archiver != null) - archiver.DearchiveRegion(filename, mergeOar, skipAssets, Guid.Empty); - else - throw new Exception("Archiver module not present for scene"); - - responseData["loaded"] = true; - - response.Value = responseData; + responseData["accepted"] = false; + throw new Exception(String.Format("missing string parameter {0}", parameter)); } - catch (Exception e) + if (String.IsNullOrEmpty((string) requestData[parameter])) { - m_log.ErrorFormat("[RADMIN]: LoadOAR: {0} {1}", e.Message, e.StackTrace); - - responseData["loaded"] = false; - responseData["error"] = e.Message; - - response.Value = responseData; + responseData["accepted"] = false; + throw new Exception(String.Format("parameter {0} is empty", parameter)); } - - m_log.Info("[RADMIN]: Load OAR Administrator Request complete"); - return response; } } - /// - /// Save a region to an OAR file - /// - /// incoming XML RPC request - /// - /// XmlRpcSaveOARMethod takes the following XMLRPC - /// parameters - /// - /// parameter namedescription - /// password - /// admin password as set in OpenSim.ini - /// filename - /// file name for the OAR file - /// region_uuid - /// UUID of the region - /// region_name - /// region name - /// profile - /// profile url - /// noassets - /// true if no assets should be saved - /// perm - /// C and/or T - /// - /// - /// region_uuid takes precedence over - /// region_name if both are present; one of both - /// must be present. - /// - /// XmlRpcLoadOARMethod returns - /// - /// namedescription - /// success - /// true or false - /// error - /// error message if success is false - /// - /// - public XmlRpcResponse XmlRpcSaveOARMethod(XmlRpcRequest request, IPEndPoint remoteClient) + private static void CheckIntegerParams(Hashtable requestData, Hashtable responseData, string[] param) { - m_log.Info("[RADMIN]: Received Save OAR Administrator Request"); - - XmlRpcResponse response = new XmlRpcResponse(); - Hashtable responseData = new Hashtable(); - - try + foreach (string parameter in param) { - Hashtable requestData = (Hashtable) request.Params[0]; - - CheckStringParameters(request, new string[] { - "password", "filename"}); - - FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); - - string filename = (string) requestData["filename"]; - Scene scene = null; - if (requestData.Contains("region_uuid")) - { - UUID region_uuid = (UUID) (string) requestData["region_uuid"]; - if (!m_application.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")) + if (!requestData.Contains(parameter)) { - string region_name = (string) requestData["region_name"]; - if (!m_application.SceneManager.TryGetScene(region_name, out scene)) - throw new Exception(String.Format("failed to switch to region {0}", region_name)); + responseData["accepted"] = false; + throw new Exception(String.Format("missing integer parameter {0}", parameter)); } - else throw new Exception("neither region_name nor region_uuid given"); - - Dictionary options = new Dictionary(); + } + } - //if (requestData.Contains("version")) - //{ - // options["version"] = (string)requestData["version"]; - //} - - if (requestData.Contains("profile")) - { - options["profile"] = (string)requestData["profile"]; - } - - if (requestData["noassets"] == "true") - { - options["noassets"] = (string)requestData["noassets"] ; - } - - if (requestData.Contains("perm")) - { - options["checkPermissions"] = (string)requestData["perm"]; - } - - IRegionArchiverModule archiver = scene.RequestModuleInterface(); - - if (archiver != null) - { - scene.EventManager.OnOarFileSaved += RemoteAdminOarSaveCompleted; - archiver.ArchiveRegion(filename, options); - - lock (m_saveOarLock) - Monitor.Wait(m_saveOarLock,5000); - - scene.EventManager.OnOarFileSaved -= RemoteAdminOarSaveCompleted; - } - else + private bool GetBoolean(Hashtable requestData, string tag, bool defaultValue) + { + // If an access value has been provided, apply it. + if (requestData.Contains(tag)) + { + switch (((string)requestData[tag]).ToLower()) { - throw new Exception("Archiver module not present for scene"); + case "true" : + case "t" : + case "1" : + return true; + case "false" : + case "f" : + case "0" : + return false; + default : + return defaultValue; } - - responseData["saved"] = true; - - response.Value = responseData; } - catch (Exception e) - { - m_log.ErrorFormat("[RADMIN]: SaveOAR: {0} {1}", e.Message, e.StackTrace); - - responseData["saved"] = false; - responseData["error"] = e.Message; + else + return defaultValue; + } - response.Value = responseData; - } + private int GetIntegerAttribute(XmlNode node, string attribute, int defaultValue) + { + try { return Convert.ToInt32(node.Attributes[attribute].Value); } catch{} + return defaultValue; + } - m_log.Info("[RADMIN]: Save OAR Administrator Request complete"); - return response; + private uint GetUnsignedAttribute(XmlNode node, string attribute, uint defaultValue) + { + try { return Convert.ToUInt32(node.Attributes[attribute].Value); } catch{} + return defaultValue; } - private void RemoteAdminOarSaveCompleted(Guid uuid, string name) + private string GetStringAttribute(XmlNode node, string attribute, string defaultValue) { - m_log.DebugFormat("[RADMIN]: File processing complete for {0}", name); - lock (m_saveOarLock) Monitor.Pulse(m_saveOarLock); + try { return node.Attributes[attribute].Value; } catch{} + return defaultValue; } - public XmlRpcResponse XmlRpcLoadXMLMethod(XmlRpcRequest request, IPEndPoint remoteClient) + public void Dispose() { - m_log.Info("[RADMIN]: Received Load XML Administrator Request"); + } - XmlRpcResponse response = new XmlRpcResponse(); - Hashtable responseData = new Hashtable(); + /// + /// Create a user + /// + /// + /// + /// + /// + /// + private UserAccount CreateUser(UUID scopeID, string firstName, string lastName, string password, string email) + { + Scene scene = m_application.SceneManager.CurrentOrFirstScene; + IUserAccountService userAccountService = scene.UserAccountService; + IGridService gridService = scene.GridService; + IAuthenticationService authenticationService = scene.AuthenticationService; + IGridUserService gridUserService = scene.GridUserService; + IInventoryService inventoryService = scene.InventoryService; - lock (m_requestLock) + UserAccount account = userAccountService.GetUserAccount(scopeID, firstName, lastName); + if (null == account) { - try + account = new UserAccount(scopeID, UUID.Random(), firstName, lastName, email); + if (account.ServiceURLs == null || (account.ServiceURLs != null && account.ServiceURLs.Count == 0)) { - Hashtable requestData = (Hashtable) request.Params[0]; - - CheckStringParameters(request, new string[] { - "password", "filename"}); - - FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); + account.ServiceURLs = new Dictionary(); + account.ServiceURLs["HomeURI"] = string.Empty; + account.ServiceURLs["GatekeeperURI"] = string.Empty; + account.ServiceURLs["InventoryServerURI"] = string.Empty; + account.ServiceURLs["AssetServerURI"] = string.Empty; + } - string filename = (string) requestData["filename"]; - if (requestData.Contains("region_uuid")) + if (userAccountService.StoreUserAccount(account)) + { + bool success; + if (authenticationService != null) { - UUID region_uuid = (UUID) (string) requestData["region_uuid"]; - if (!m_application.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()); + success = authenticationService.SetPassword(account.PrincipalID, password); + if (!success) + m_log.WarnFormat("[RADMIN]: Unable to set password for account {0} {1}.", + firstName, lastName); } - else if (requestData.Contains("region_name")) + + GridRegion home = null; + if (gridService != null) { - string region_name = (string) requestData["region_name"]; - if (!m_application.SceneManager.TrySetCurrentScene(region_name)) - throw new Exception(String.Format("failed to switch to region {0}", region_name)); + List defaultRegions = gridService.GetDefaultRegions(UUID.Zero); + if (defaultRegions != null && defaultRegions.Count >= 1) + home = defaultRegions[0]; - m_log.InfoFormat("[RADMIN]: Switched to region {0}", region_name); + if (gridUserService != null && home != null) + gridUserService.SetHome(account.PrincipalID.ToString(), home.RegionID, new Vector3(128, 128, 0), new Vector3(0, 1, 0)); + else + m_log.WarnFormat("[RADMIN]: Unable to set home for account {0} {1}.", + firstName, lastName); } - else throw new Exception("neither region_name nor region_uuid given"); - - responseData["switched"] = true; + else + m_log.WarnFormat("[RADMIN]: Unable to retrieve home region for account {0} {1}.", + firstName, lastName); - string xml_version = "1"; - if (requestData.Contains("xml_version")) + if (inventoryService != null) { - xml_version = (string) requestData["xml_version"]; + success = inventoryService.CreateUserInventory(account.PrincipalID); + if (!success) + m_log.WarnFormat("[RADMIN]: Unable to create inventory for account {0} {1}.", + firstName, lastName); } - switch (xml_version) - { - case "1": - m_application.SceneManager.LoadCurrentSceneFromXml(filename, true, new Vector3(0, 0, 0)); - break; + m_log.InfoFormat("[RADMIN]: Account {0} {1} created successfully", firstName, lastName); + return account; + } else { + m_log.ErrorFormat("[RADMIN]: Account creation failed for account {0} {1}", firstName, lastName); + } + } + else + { + m_log.ErrorFormat("[RADMIN]: A user with the name {0} {1} already exists!", firstName, lastName); + } + return null; + } - case "2": - m_application.SceneManager.LoadCurrentSceneFromXml2(filename); - break; + /// + /// Change password + /// + /// + /// + /// + private bool ChangeUserPassword(string firstName, string lastName, string password) + { + Scene scene = m_application.SceneManager.CurrentOrFirstScene; + IUserAccountService userAccountService = scene.UserAccountService; + IAuthenticationService authenticationService = scene.AuthenticationService; - default: - throw new Exception(String.Format("unknown Xml{0} format", xml_version)); - } + UserAccount account = userAccountService.GetUserAccount(UUID.Zero, firstName, lastName); + if (null != account) + { + bool success = false; + if (authenticationService != null) + success = authenticationService.SetPassword(account.PrincipalID, password); - responseData["loaded"] = true; - response.Value = responseData; - } - catch (Exception e) + if (!success) { - m_log.ErrorFormat("[RADMIN] LoadXml: {0} {1}", e.Message, e.StackTrace); - - responseData["loaded"] = false; - responseData["switched"] = false; - responseData["error"] = e.Message; - - response.Value = responseData; + m_log.WarnFormat("[RADMIN]: Unable to set password for account {0} {1}.", + firstName, lastName); + return false; } - - m_log.Info("[RADMIN]: Load XML Administrator Request complete"); - return response; + return true; + } + else + { + m_log.ErrorFormat("[RADMIN]: No such user"); + return false; } } - public XmlRpcResponse XmlRpcSaveXMLMethod(XmlRpcRequest request, IPEndPoint remoteClient) + private bool LoadHeightmap(string file, UUID regionID) { - m_log.Info("[RADMIN]: Received Save XML Administrator Request"); + m_log.InfoFormat("[RADMIN]: Terrain Loading: {0}", file); - XmlRpcResponse response = new XmlRpcResponse(); - Hashtable responseData = new Hashtable(); + Scene region = null; - try + if (!m_application.SceneManager.TryGetScene(regionID, out region)) { - Hashtable requestData = (Hashtable) request.Params[0]; - - CheckStringParameters(request, new string[] { - "password", "filename"}); - - FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); + m_log.InfoFormat("[RADMIN]: unable to get a scene with that name: {0}", regionID.ToString()); + return false; + } - string filename = (string) requestData["filename"]; - if (requestData.Contains("region_uuid")) - { - UUID region_uuid = (UUID) (string) requestData["region_uuid"]; - if (!m_application.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")) + ITerrainModule terrainModule = region.RequestModuleInterface(); + if (null == terrainModule) throw new Exception("terrain module not available"); + if (Uri.IsWellFormedUriString(file, UriKind.Absolute)) + { + m_log.Info("[RADMIN]: Terrain path is URL"); + Uri result; + if (Uri.TryCreate(file, UriKind.RelativeOrAbsolute, out result)) { - string region_name = (string) requestData["region_name"]; - if (!m_application.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); + // the url is valid + string fileType = file.Substring(file.LastIndexOf('/') + 1); + terrainModule.LoadFromStream(fileType, result); } - 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_application.SceneManager.SaveCurrentSceneToXml(filename); - break; - - case "2": - m_application.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) + else { - m_log.ErrorFormat("[RADMIN]: SaveXml: {0} {1}", e.Message, e.StackTrace); - - responseData["saved"] = false; - responseData["switched"] = false; - responseData["error"] = e.Message; - - response.Value = responseData; + terrainModule.LoadFromFile(file); } - m_log.Info("[RADMIN]: Save XML Administrator Request complete"); - return response; - } - - public XmlRpcResponse XmlRpcRegionQueryMethod(XmlRpcRequest request, IPEndPoint remoteClient) - { - m_log.Info("[RADMIN]: Received Query XML Administrator Request"); - - XmlRpcResponse response = new XmlRpcResponse(); - Hashtable responseData = new Hashtable(); + m_log.Info("[RADMIN]: Load height maps request complete"); - try - { - responseData["success"] = true; + return true; + } - Hashtable requestData = (Hashtable) request.Params[0]; - CheckStringParameters(request, new string[] { - "password"}); + /// + /// This method is called by the user-create and user-modify methods to establish + /// or change, the user's appearance. Default avatar names can be specified via + /// the config file, but must correspond to avatars in the default appearance + /// file, or pre-existing in the user database. + /// This should probably get moved into somewhere more core eventually. + /// + private void UpdateUserAppearance(Hashtable responseData, Hashtable requestData, UUID userid) + { + m_log.DebugFormat("[RADMIN]: updateUserAppearance"); - FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); + string defaultMale = m_config.GetString("default_male", "Default Male"); + string defaultFemale = m_config.GetString("default_female", "Default Female"); + string defaultNeutral = m_config.GetString("default_female", "Default Default"); + string model = String.Empty; - if (requestData.Contains("region_uuid")) - { - UUID region_uuid = (UUID) (string) requestData["region_uuid"]; - if (!m_application.SceneManager.TrySetCurrentScene(region_uuid)) - throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString())); + // Has a gender preference been supplied? - m_log.InfoFormat("[RADMIN]: Switched to region {0}", region_uuid.ToString()); - } - else if (requestData.Contains("region_name")) + if (requestData.Contains("gender")) + { + switch ((string)requestData["gender"]) { - string region_name = (string) requestData["region_name"]; - if (!m_application.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); + case "m" : + case "male" : + model = defaultMale; + break; + case "f" : + case "female" : + model = defaultFemale; + break; + case "n" : + case "neutral" : + default : + model = defaultNeutral; + break; } - else throw new Exception("neither region_name nor region_uuid given"); - - Scene scene = m_application.SceneManager.CurrentScene; - int flags; - string text; - int health = scene.GetHealth(out flags, out text); - responseData["health"] = health; - responseData["flags"] = flags; - responseData["message"] = text; - - response.Value = responseData; } - catch (Exception e) - { - m_log.InfoFormat("[RADMIN]: RegionQuery: {0}", e.Message); - responseData["success"] = false; - responseData["error"] = e.Message; + // Has an explicit model been specified? - response.Value = responseData; + if (requestData.Contains("model") && (String.IsNullOrEmpty((string)requestData["gender"]))) + { + model = (string)requestData["model"]; } - m_log.Info("[RADMIN]: Query XML Administrator Request complete"); - - return response; - } - - public XmlRpcResponse XmlRpcConsoleCommandMethod(XmlRpcRequest request, IPEndPoint remoteClient) - { - m_log.Info("[RADMIN]: Received Command XML Administrator Request"); - - XmlRpcResponse response = new XmlRpcResponse(); - Hashtable responseData = new Hashtable(); + // No appearance attributes were set - try + if (String.IsNullOrEmpty(model)) { - responseData["success"] = true; - - Hashtable requestData = (Hashtable) request.Params[0]; + m_log.DebugFormat("[RADMIN]: Appearance update not requested"); + return; + } - CheckStringParameters(request, new string[] { - "password", "command"}); + m_log.DebugFormat("[RADMIN]: Setting appearance for avatar {0}, using model <{1}>", userid, model); - FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); + string[] modelSpecifiers = model.Split(); + if (modelSpecifiers.Length != 2) + { + m_log.WarnFormat("[RADMIN]: User appearance not set for {0}. Invalid model name : <{1}>", userid, model); + // modelSpecifiers = dmodel.Split(); + return; + } - MainConsole.Instance.RunCommand(requestData["command"].ToString()); + Scene scene = m_application.SceneManager.CurrentOrFirstScene; + UUID scopeID = scene.RegionInfo.ScopeID; + UserAccount modelProfile = scene.UserAccountService.GetUserAccount(scopeID, modelSpecifiers[0], modelSpecifiers[1]); - response.Value = responseData; - } - catch (Exception e) + if (modelProfile == null) { - m_log.InfoFormat("[RADMIN]: ConsoleCommand: {0}", e.Message); + m_log.WarnFormat("[RADMIN]: Requested model ({0}) not found. Appearance unchanged", model); + return; + } - responseData["success"] = false; - responseData["error"] = e.Message; + // Set current user's appearance. This bit is easy. The appearance structure is populated with + // actual asset ids, however to complete the magic we need to populate the inventory with the + // assets in question. - response.Value = responseData; - } + EstablishAppearance(userid, modelProfile.PrincipalID); - m_log.Info("[RADMIN]: Command XML Administrator Request complete"); - return response; + m_log.DebugFormat("[RADMIN]: Finished setting appearance for avatar {0}, using model {1}", + userid, model); } - public XmlRpcResponse XmlRpcAccessListClear(XmlRpcRequest request, IPEndPoint remoteClient) + /// + /// This method is called by updateAvatarAppearance once any specified model has been + /// ratified, or an appropriate default value has been adopted. The intended prototype + /// is known to exist, as is the target avatar. + /// + private void EstablishAppearance(UUID destination, UUID source) { - 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]; + m_log.DebugFormat("[RADMIN]: Initializing inventory for {0} from {1}", destination, source); + Scene scene = m_application.SceneManager.CurrentOrFirstScene; - CheckStringParameters(request, new string[] { - "password"}); + // If the model has no associated appearance we're done. + AvatarAppearance avatarAppearance = scene.AvatarService.GetAppearance(source); + if (avatarAppearance == null) + return; - FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); + // Simple appearance copy or copy Clothing and Bodyparts folders? + bool copyFolders = m_config.GetBoolean("copy_folders", false); - if (requestData.Contains("region_uuid")) + if (!copyFolders) + { + // Simple copy of wearables and appearance update + try { - UUID region_uuid = (UUID) (string) requestData["region_uuid"]; - if (!m_application.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()); + CopyWearablesAndAttachments(destination, source, avatarAppearance); + + scene.AvatarService.SetAppearance(destination, avatarAppearance); } - else if (requestData.Contains("region_name")) + catch (Exception e) { - string region_name = (string) requestData["region_name"]; - if (!m_application.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); + m_log.WarnFormat("[RADMIN]: Error transferring appearance for {0} : {1}", + destination, e.Message); } - else throw new Exception("neither region_name nor region_uuid given"); - - Scene scene = m_application.SceneManager.CurrentScene; - scene.RegionInfo.EstateSettings.EstateAccess = new UUID[]{}; - if (scene.RegionInfo.Persistent) - scene.RegionInfo.EstateSettings.Save(); + return; } - catch (Exception e) + + // Copy Clothing and Bodypart folders and appearance update + try { - m_log.ErrorFormat("[RADMIN]: Access List Clear Request: {0} {1}", e.Message, e.StackTrace); + Dictionary inventoryMap = new Dictionary(); + CopyInventoryFolders(destination, source, AssetType.Clothing, inventoryMap, avatarAppearance); + CopyInventoryFolders(destination, source, AssetType.Bodypart, inventoryMap, avatarAppearance); - responseData["success"] = false; - responseData["error"] = e.Message; + AvatarWearable[] wearables = avatarAppearance.Wearables; + + for (int i=0; i + /// This method is called by establishAppearance to do a copy all inventory items + /// worn or attached to the Clothing inventory folder of the receiving avatar. + /// In parallel the avatar wearables and attachments are updated. + /// + private void CopyWearablesAndAttachments(UUID destination, UUID source, AvatarAppearance avatarAppearance) { - 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]; + IInventoryService inventoryService = m_application.SceneManager.CurrentOrFirstScene.InventoryService; - CheckStringParameters(request, new string[] { - "password"}); + // Get Clothing folder of receiver + InventoryFolderBase destinationFolder = inventoryService.GetFolderForType(destination, AssetType.Clothing); - FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); + if (destinationFolder == null) + throw new Exception("Cannot locate folder(s)"); - if (requestData.Contains("region_uuid")) - { - UUID region_uuid = (UUID) (string) requestData["region_uuid"]; - if (!m_application.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_application.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"); + // Missing destination folder? This should *never* be the case + if (destinationFolder.Type != (short)AssetType.Clothing) + { + destinationFolder = new InventoryFolderBase(); + + destinationFolder.ID = UUID.Random(); + destinationFolder.Name = "Clothing"; + destinationFolder.Owner = destination; + destinationFolder.Type = (short)AssetType.Clothing; + destinationFolder.ParentID = inventoryService.GetRootFolder(destination).ID; + destinationFolder.Version = 1; + inventoryService.AddFolder(destinationFolder); // store base record + m_log.ErrorFormat("[RADMIN]: Created folder for destination {0}", source); + } - int addedUsers = 0; + // Wearables + AvatarWearable[] wearables = avatarAppearance.Wearables; + AvatarWearable wearable; - if (requestData.Contains("users")) + for (int i = 0; i uuids = new List(); - foreach (string name in users.Values) + // Get inventory item and copy it + InventoryItemBase item = new InventoryItemBase(wearable[0].ItemID, source); + item = inventoryService.GetItem(item); + + if (item != null) { - string[] parts = name.Split(); - UserAccount account = userService.GetUserAccount(scopeID, parts[0], parts[1]); - if (account != null) - { - uuids.Add(account.PrincipalID); - m_log.DebugFormat("[RADMIN]: adding \"{0}\" to ACL for \"{1}\"", name, scene.RegionInfo.RegionName); - } + InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination); + destinationItem.Name = item.Name; + destinationItem.Owner = destination; + destinationItem.Description = item.Description; + destinationItem.InvType = item.InvType; + destinationItem.CreatorId = item.CreatorId; + destinationItem.CreatorIdAsUuid = item.CreatorIdAsUuid; + destinationItem.CreatorData = item.CreatorData; + destinationItem.NextPermissions = item.NextPermissions; + destinationItem.CurrentPermissions = item.CurrentPermissions; + destinationItem.BasePermissions = item.BasePermissions; + destinationItem.EveryOnePermissions = item.EveryOnePermissions; + destinationItem.GroupPermissions = item.GroupPermissions; + destinationItem.AssetType = item.AssetType; + destinationItem.AssetID = item.AssetID; + destinationItem.GroupID = item.GroupID; + destinationItem.GroupOwned = item.GroupOwned; + destinationItem.SalePrice = item.SalePrice; + destinationItem.SaleType = item.SaleType; + destinationItem.Flags = item.Flags; + destinationItem.CreationDate = item.CreationDate; + destinationItem.Folder = destinationFolder.ID; + ApplyNextOwnerPermissions(destinationItem); + + m_application.SceneManager.CurrentOrFirstScene.AddInventoryItem(destinationItem); + m_log.DebugFormat("[RADMIN]: Added item {0} to folder {1}", destinationItem.ID, destinationFolder.ID); + + // Wear item + AvatarWearable newWearable = new AvatarWearable(); + newWearable.Wear(destinationItem.ID, wearable[0].AssetID); + avatarAppearance.SetWearable(i, newWearable); } - List accessControlList = new List(scene.RegionInfo.EstateSettings.EstateAccess); - foreach (UUID uuid in uuids) + else { - if (!accessControlList.Contains(uuid)) - { - accessControlList.Add(uuid); - addedUsers++; - } + m_log.WarnFormat("[RADMIN]: Error transferring {0} to folder {1}", wearable[0].ItemID, destinationFolder.ID); } - scene.RegionInfo.EstateSettings.EstateAccess = accessControlList.ToArray(); - if (scene.RegionInfo.Persistent) - scene.RegionInfo.EstateSettings.Save(); } - - responseData["added"] = addedUsers; - } - catch (Exception e) - { - m_log.ErrorFormat("[RADMIN]: Access List Add Request: {0} {1}", e.Message, e.StackTrace); - - 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, IPEndPoint remoteClient) - { - m_log.Info("[RADMIN]: Received Access List Remove Request"); - - XmlRpcResponse response = new XmlRpcResponse(); - Hashtable responseData = new Hashtable(); + // Attachments + List attachments = avatarAppearance.GetAttachments(); - try + foreach (AvatarAttachment attachment in attachments) { - responseData["success"] = true; - - Hashtable requestData = (Hashtable) request.Params[0]; - - CheckStringParameters(request, new string[] { - "password"}); - - FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); + int attachpoint = attachment.AttachPoint; + UUID itemID = attachment.ItemID; - if (requestData.Contains("region_uuid")) - { - UUID region_uuid = (UUID) (string) requestData["region_uuid"]; - if (!m_application.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")) + if (itemID != UUID.Zero) { - string region_name = (string) requestData["region_name"]; - if (!m_application.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 removedUsers = 0; + // Get inventory item and copy it + InventoryItemBase item = new InventoryItemBase(itemID, source); + item = inventoryService.GetItem(item); - if (requestData.Contains("users")) - { - UUID scopeID = m_application.SceneManager.CurrentOrFirstScene.RegionInfo.ScopeID; - IUserAccountService userService = m_application.SceneManager.CurrentOrFirstScene.UserAccountService; - //UserProfileCacheService ups = m_application.CommunicationsManager.UserProfileCacheService; - Scene scene = m_application.SceneManager.CurrentScene; - Hashtable users = (Hashtable) requestData["users"]; - List uuids = new List(); - foreach (string name in users.Values) + if (item != null) { - string[] parts = name.Split(); - UserAccount account = userService.GetUserAccount(scopeID, parts[0], parts[1]); - if (account != null) - { - uuids.Add(account.PrincipalID); - } + InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination); + destinationItem.Name = item.Name; + destinationItem.Owner = destination; + destinationItem.Description = item.Description; + destinationItem.InvType = item.InvType; + destinationItem.CreatorId = item.CreatorId; + destinationItem.CreatorIdAsUuid = item.CreatorIdAsUuid; + destinationItem.CreatorData = item.CreatorData; + destinationItem.NextPermissions = item.NextPermissions; + destinationItem.CurrentPermissions = item.CurrentPermissions; + destinationItem.BasePermissions = item.BasePermissions; + destinationItem.EveryOnePermissions = item.EveryOnePermissions; + destinationItem.GroupPermissions = item.GroupPermissions; + destinationItem.AssetType = item.AssetType; + destinationItem.AssetID = item.AssetID; + destinationItem.GroupID = item.GroupID; + destinationItem.GroupOwned = item.GroupOwned; + destinationItem.SalePrice = item.SalePrice; + destinationItem.SaleType = item.SaleType; + destinationItem.Flags = item.Flags; + destinationItem.CreationDate = item.CreationDate; + destinationItem.Folder = destinationFolder.ID; + ApplyNextOwnerPermissions(destinationItem); + + m_application.SceneManager.CurrentOrFirstScene.AddInventoryItem(destinationItem); + m_log.DebugFormat("[RADMIN]: Added item {0} to folder {1}", destinationItem.ID, destinationFolder.ID); + + // Attach item + avatarAppearance.SetAttachment(attachpoint, destinationItem.ID, destinationItem.AssetID); + m_log.DebugFormat("[RADMIN]: Attached {0}", destinationItem.ID); } - List accessControlList = new List(scene.RegionInfo.EstateSettings.EstateAccess); - foreach (UUID uuid in uuids) + else { - if (accessControlList.Contains(uuid)) - { - accessControlList.Remove(uuid); - removedUsers++; - } + m_log.WarnFormat("[RADMIN]: Error transferring {0} to folder {1}", itemID, destinationFolder.ID); } - scene.RegionInfo.EstateSettings.EstateAccess = accessControlList.ToArray(); - if (scene.RegionInfo.Persistent) - scene.RegionInfo.EstateSettings.Save(); } - - responseData["removed"] = removedUsers; - } - catch (Exception e) - { - m_log.ErrorFormat("[RADMIN]: Access List Remove Request: {0} {1}", e.Message, e.StackTrace); - - 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, IPEndPoint remoteClient) + /// + /// This method is called by establishAppearance to copy inventory folders to make + /// copies of Clothing and Bodyparts inventory folders and attaches worn attachments + /// + private void CopyInventoryFolders(UUID destination, UUID source, AssetType assetType, Dictionary inventoryMap, + AvatarAppearance avatarAppearance) { - 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]; + IInventoryService inventoryService = m_application.SceneManager.CurrentOrFirstScene.InventoryService; - CheckStringParameters(request, new string[] { - "password"}); + InventoryFolderBase sourceFolder = inventoryService.GetFolderForType(source, assetType); + InventoryFolderBase destinationFolder = inventoryService.GetFolderForType(destination, assetType); - FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); + if (sourceFolder == null || destinationFolder == null) + throw new Exception("Cannot locate folder(s)"); - if (requestData.Contains("region_uuid")) - { - UUID region_uuid = (UUID) (string) requestData["region_uuid"]; - if (!m_application.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()); + // Missing source folder? This should *never* be the case + if (sourceFolder.Type != (short)assetType) + { + sourceFolder = new InventoryFolderBase(); + sourceFolder.ID = UUID.Random(); + if (assetType == AssetType.Clothing) { + sourceFolder.Name = "Clothing"; + } else { + sourceFolder.Name = "Body Parts"; } - else if (requestData.Contains("region_name")) + sourceFolder.Owner = source; + sourceFolder.Type = (short)assetType; + sourceFolder.ParentID = inventoryService.GetRootFolder(source).ID; + sourceFolder.Version = 1; + inventoryService.AddFolder(sourceFolder); // store base record + m_log.ErrorFormat("[RADMIN] Created folder for source {0}", source); + } + + // Missing destination folder? This should *never* be the case + if (destinationFolder.Type != (short)assetType) + { + destinationFolder = new InventoryFolderBase(); + destinationFolder.ID = UUID.Random(); + if (assetType == AssetType.Clothing) { - string region_name = (string) requestData["region_name"]; - if (!m_application.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); + destinationFolder.Name = "Clothing"; } - else throw new Exception("neither region_name nor region_uuid given"); - - Scene scene = m_application.SceneManager.CurrentScene; - UUID[] accessControlList = scene.RegionInfo.EstateSettings.EstateAccess; - Hashtable users = new Hashtable(); - - foreach (UUID user in accessControlList) + else { - UUID scopeID = m_application.SceneManager.CurrentOrFirstScene.RegionInfo.ScopeID; - UserAccount account = m_application.SceneManager.CurrentOrFirstScene.UserAccountService.GetUserAccount(scopeID, user); - if (account != null) - { - users[user.ToString()] = account.FirstName + " " + account.LastName; - } + destinationFolder.Name = "Body Parts"; } - - responseData["users"] = users; + destinationFolder.Owner = destination; + destinationFolder.Type = (short)assetType; + destinationFolder.ParentID = inventoryService.GetRootFolder(destination).ID; + destinationFolder.Version = 1; + inventoryService.AddFolder(destinationFolder); // store base record + m_log.ErrorFormat("[RADMIN]: Created folder for destination {0}", source); } - catch (Exception e) - { - m_log.ErrorFormat("[RADMIN]: Access List List: {0} {1}", e.Message, e.StackTrace); - responseData["success"] = false; - responseData["error"] = e.Message; - } - finally - { - response.Value = responseData; - } + InventoryFolderBase extraFolder; + List folders = inventoryService.GetFolderContent(source, sourceFolder.ID).Folders; - m_log.Info("[RADMIN]: Access List List Request complete"); - return response; - } - - public XmlRpcResponse XmlRpcTeleportAgentMethod(XmlRpcRequest request, IPEndPoint remoteClient) - { - XmlRpcResponse response = new XmlRpcResponse(); - Hashtable responseData = new Hashtable(); - - try + foreach (InventoryFolderBase folder in folders) { - responseData["success"] = true; - - Hashtable requestData = (Hashtable)request.Params[0]; - - CheckStringParameters(request, new string[] {"password"}); - - FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); + extraFolder = new InventoryFolderBase(); + extraFolder.ID = UUID.Random(); + extraFolder.Name = folder.Name; + extraFolder.Owner = destination; + extraFolder.Type = folder.Type; + extraFolder.Version = folder.Version; + extraFolder.ParentID = destinationFolder.ID; + inventoryService.AddFolder(extraFolder); - UUID agentId; - string regionName = null; - Vector3 pos, lookAt; - bool agentSpecified = false; - ScenePresence sp = null; + m_log.DebugFormat("[RADMIN]: Added folder {0} to folder {1}", extraFolder.ID, sourceFolder.ID); - if (requestData.Contains("agent_first_name") && requestData.Contains("agent_last_name")) - { - string firstName = requestData["agent_first_name"].ToString(); - string lastName = requestData["agent_last_name"].ToString(); - m_application.SceneManager.TryGetRootScenePresenceByName(firstName, lastName, out sp); + List items = inventoryService.GetFolderContent(source, folder.ID).Items; - if (sp == null) - throw new Exception( - string.Format( - "No agent found with agent_first_name {0} and agent_last_name {1}", firstName, lastName)); - } - else if (requestData.Contains("agent_id")) + foreach (InventoryItemBase item in items) { - string rawAgentId = (string)requestData["agent_id"]; - - if (!UUID.TryParse(rawAgentId, out agentId)) - throw new Exception(string.Format("agent_id {0} does not have the correct id format", rawAgentId)); + InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination); + destinationItem.Name = item.Name; + destinationItem.Owner = destination; + destinationItem.Description = item.Description; + destinationItem.InvType = item.InvType; + destinationItem.CreatorId = item.CreatorId; + destinationItem.CreatorIdAsUuid = item.CreatorIdAsUuid; + destinationItem.CreatorData = item.CreatorData; + destinationItem.NextPermissions = item.NextPermissions; + destinationItem.CurrentPermissions = item.CurrentPermissions; + destinationItem.BasePermissions = item.BasePermissions; + destinationItem.EveryOnePermissions = item.EveryOnePermissions; + destinationItem.GroupPermissions = item.GroupPermissions; + destinationItem.AssetType = item.AssetType; + destinationItem.AssetID = item.AssetID; + destinationItem.GroupID = item.GroupID; + destinationItem.GroupOwned = item.GroupOwned; + destinationItem.SalePrice = item.SalePrice; + destinationItem.SaleType = item.SaleType; + destinationItem.Flags = item.Flags; + destinationItem.CreationDate = item.CreationDate; + destinationItem.Folder = extraFolder.ID; + ApplyNextOwnerPermissions(destinationItem); - m_application.SceneManager.TryGetRootScenePresence(agentId, out sp); + m_application.SceneManager.CurrentOrFirstScene.AddInventoryItem(destinationItem); + inventoryMap.Add(item.ID, destinationItem.ID); + m_log.DebugFormat("[RADMIN]: Added item {0} to folder {1}", destinationItem.ID, extraFolder.ID); - if (sp == null) - throw new Exception(string.Format("No agent with agent_id {0} found in this simulator", agentId)); - } - else - { - throw new Exception("No agent_id or agent_first_name and agent_last_name parameters specified"); + // Attach item, if original is attached + int attachpoint = avatarAppearance.GetAttachpoint(item.ID); + if (attachpoint != 0) + { + avatarAppearance.SetAttachment(attachpoint, destinationItem.ID, destinationItem.AssetID); + m_log.DebugFormat("[RADMIN]: Attached {0}", destinationItem.ID); + } } - - if (requestData.Contains("region_name")) - regionName = (string)requestData["region_name"]; - - pos.X = ParseFloat(requestData, "pos_x", sp.AbsolutePosition.X); - pos.Y = ParseFloat(requestData, "pos_y", sp.AbsolutePosition.Y); - pos.Z = ParseFloat(requestData, "pos_z", sp.AbsolutePosition.Z); - lookAt.X = ParseFloat(requestData, "lookat_x", sp.Lookat.X); - lookAt.Y = ParseFloat(requestData, "lookat_y", sp.Lookat.Y); - lookAt.Z = ParseFloat(requestData, "lookat_z", sp.Lookat.Z); - - sp.Scene.RequestTeleportLocation( - sp.ControllingClient, regionName, pos, lookAt, (uint)Constants.TeleportFlags.ViaLocation); - } - catch (Exception e) - { - m_log.ErrorFormat("[RADMIN]: admin_teleport_agent exception: {0}{1}", e.Message, e.StackTrace); - - responseData["success"] = false; - responseData["error"] = e.Message; - } - finally - { - response.Value = responseData; } - - return response; } /// - /// Parse a float with the given parameter name from a request data hash table. + /// Apply next owner permissions. /// - /// - /// Will throw an exception if parameter is not a float. - /// Will not throw if parameter is not found, passes back default value instead. - /// - /// - /// - /// - /// - private static float ParseFloat(Hashtable requestData, string paramName, float defaultVal) + private void ApplyNextOwnerPermissions(InventoryItemBase item) { - if (requestData.Contains(paramName)) - { - string rawVal = (string)requestData[paramName]; - float val; - - if (!float.TryParse(rawVal, out val)) - throw new Exception(string.Format("{0} {1} is not a valid float", paramName, rawVal)); - else - return val; - } - else + if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) { - return defaultVal; + if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) + item.CurrentPermissions &= ~(uint)PermissionMask.Copy; + if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) + item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; + if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) + item.CurrentPermissions &= ~(uint)PermissionMask.Modify; } + item.CurrentPermissions &= item.NextPermissions; + item.BasePermissions &= item.NextPermissions; + item.EveryOnePermissions &= item.NextPermissions; + // item.OwnerChanged = true; + // item.PermsMask = 0; + // item.PermsGranter = UUID.Zero; } - private static void CheckStringParameters(XmlRpcRequest request, string[] param) + /// + /// This method is called if a given model avatar name can not be found. If the external + /// file has already been loaded once, then control returns immediately. If not, then it + /// looks for a default appearance file. This file contains XML definitions of zero or more named + /// avatars, each avatar can specify zero or more "outfits". Each outfit is a collection + /// of items that together, define a particular ensemble for the avatar. Each avatar should + /// indicate which outfit is the default, and this outfit will be automatically worn. The + /// other outfits are provided to allow "real" avatars a way to easily change their outfits. + /// + private bool CreateDefaultAvatars() { - Hashtable requestData = (Hashtable) request.Params[0]; - foreach (string parameter in param) + // Only load once + if (m_defaultAvatarsLoaded) { - if (!requestData.Contains(parameter)) - throw new Exception(String.Format("missing string parameter {0}", parameter)); - if (String.IsNullOrEmpty((string) requestData[parameter])) - throw new Exception(String.Format("parameter {0} is empty", parameter)); + return false; } - } - private static void CheckIntegerParams(XmlRpcRequest request, string[] param) - { - Hashtable requestData = (Hashtable) request.Params[0]; - foreach (string parameter in param) - { - if (!requestData.Contains(parameter)) - throw new Exception(String.Format("missing integer parameter {0}", parameter)); - } - } + m_log.DebugFormat("[RADMIN]: Creating default avatar entries"); - private bool GetBoolean(Hashtable requestData, string tag, bool defaultValue) - { - // If an access value has been provided, apply it. - if (requestData.Contains(tag)) + m_defaultAvatarsLoaded = true; + + // Load processing starts here... + + try { - switch (((string)requestData[tag]).ToLower()) + string defaultAppearanceFileName = null; + + //m_config may be null if RemoteAdmin configuration secition is missing or disabled in OpenSim.ini + if (m_config != null) { - case "true" : - case "t" : - case "1" : - return true; - case "false" : - case "f" : - case "0" : - return false; - default : - return defaultValue; + defaultAppearanceFileName = m_config.GetString("default_appearance", "default_appearance.xml"); } - } - else - return defaultValue; - } - private int GetIntegerAttribute(XmlNode node, string attribute, int defaultValue) - { - try { return Convert.ToInt32(node.Attributes[attribute].Value); } catch{} - return defaultValue; - } + if (File.Exists(defaultAppearanceFileName)) + { + XmlDocument doc = new XmlDocument(); + string name = "*unknown*"; + string email = "anon@anon"; + uint regionXLocation = 1000; + uint regionYLocation = 1000; + string password = UUID.Random().ToString(); // No requirement to sign-in. + UUID ID = UUID.Zero; + AvatarAppearance avatarAppearance; + XmlNodeList avatars; + XmlNodeList assets; + XmlNode perms = null; + bool include = false; + bool select = false; - private uint GetUnsignedAttribute(XmlNode node, string attribute, uint defaultValue) - { - try { return Convert.ToUInt32(node.Attributes[attribute].Value); } catch{} - return defaultValue; - } + Scene scene = m_application.SceneManager.CurrentOrFirstScene; + IInventoryService inventoryService = scene.InventoryService; + IAssetService assetService = scene.AssetService; - private string GetStringAttribute(XmlNode node, string attribute, string defaultValue) - { - try { return node.Attributes[attribute].Value; } catch{} - return defaultValue; - } + doc.LoadXml(File.ReadAllText(defaultAppearanceFileName)); - public void Dispose() - { - } + // Load up any included assets. Duplicates will be ignored + assets = doc.GetElementsByTagName("RequiredAsset"); + foreach (XmlNode assetNode in assets) + { + AssetBase asset = new AssetBase(UUID.Random(), GetStringAttribute(assetNode, "name", ""), SByte.Parse(GetStringAttribute(assetNode, "type", "")), UUID.Zero.ToString()); + asset.Description = GetStringAttribute(assetNode,"desc",""); + asset.Local = Boolean.Parse(GetStringAttribute(assetNode,"local","")); + asset.Temporary = Boolean.Parse(GetStringAttribute(assetNode,"temporary","")); + asset.Data = Convert.FromBase64String(assetNode.InnerText); + assetService.Store(asset); + } - /// - /// Create a user - /// - /// - /// - /// - /// - /// - private UserAccount CreateUser(UUID scopeID, string firstName, string lastName, string password, string email) - { - Scene scene = m_application.SceneManager.CurrentOrFirstScene; - IUserAccountService userAccountService = scene.UserAccountService; - IGridService gridService = scene.GridService; - IAuthenticationService authenticationService = scene.AuthenticationService; - IGridUserService gridUserService = scene.GridUserService; - IInventoryService inventoryService = scene.InventoryService; + avatars = doc.GetElementsByTagName("Avatar"); - UserAccount account = userAccountService.GetUserAccount(scopeID, firstName, lastName); - if (null == account) - { - account = new UserAccount(scopeID, UUID.Random(), firstName, lastName, email); - if (account.ServiceURLs == null || (account.ServiceURLs != null && account.ServiceURLs.Count == 0)) - { - account.ServiceURLs = new Dictionary(); - account.ServiceURLs["HomeURI"] = string.Empty; - account.ServiceURLs["GatekeeperURI"] = string.Empty; - account.ServiceURLs["InventoryServerURI"] = string.Empty; - account.ServiceURLs["AssetServerURI"] = string.Empty; - } + // The document may contain multiple avatars - if (userAccountService.StoreUserAccount(account)) - { - bool success; - if (authenticationService != null) + foreach (XmlElement avatar in avatars) { - success = authenticationService.SetPassword(account.PrincipalID, password); - if (!success) - m_log.WarnFormat("[RADMIN]: Unable to set password for account {0} {1}.", - firstName, lastName); - } + m_log.DebugFormat("[RADMIN]: Loading appearance for {0}, gender = {1}", + GetStringAttribute(avatar,"name","?"), GetStringAttribute(avatar,"gender","?")); - GridRegion home = null; - if (gridService != null) - { - List defaultRegions = gridService.GetDefaultRegions(UUID.Zero); - if (defaultRegions != null && defaultRegions.Count >= 1) - home = defaultRegions[0]; + // Create the user identified by the avatar entry - if (gridUserService != null && home != null) - gridUserService.SetHome(account.PrincipalID.ToString(), home.RegionID, new Vector3(128, 128, 0), new Vector3(0, 1, 0)); - else - m_log.WarnFormat("[RADMIN]: Unable to set home for account {0} {1}.", - firstName, lastName); - } - else - m_log.WarnFormat("[RADMIN]: Unable to retrieve home region for account {0} {1}.", - firstName, lastName); + try + { + // Only the name value is mandatory + name = GetStringAttribute(avatar,"name",name); + email = GetStringAttribute(avatar,"email",email); + regionXLocation = GetUnsignedAttribute(avatar,"regx",regionXLocation); + regionYLocation = GetUnsignedAttribute(avatar,"regy",regionYLocation); + password = GetStringAttribute(avatar,"password",password); - if (inventoryService != null) - { - success = inventoryService.CreateUserInventory(account.PrincipalID); - if (!success) - m_log.WarnFormat("[RADMIN]: Unable to create inventory for account {0} {1}.", - firstName, lastName); - } + string[] names = name.Split(); + UUID scopeID = scene.RegionInfo.ScopeID; + UserAccount account = scene.UserAccountService.GetUserAccount(scopeID, names[0], names[1]); + if (null == account) + { + account = CreateUser(scopeID, names[0], names[1], password, email); + if (null == account) + { + m_log.ErrorFormat("[RADMIN]: Avatar {0} {1} was not created", names[0], names[1]); + return false; + } + } - m_log.InfoFormat("[RADMIN]: Account {0} {1} created successfully", firstName, lastName); - return account; - } else { - m_log.ErrorFormat("[RADMIN]: Account creation failed for account {0} {1}", firstName, lastName); - } - } - else - { - m_log.ErrorFormat("[RADMIN]: A user with the name {0} {1} already exists!", firstName, lastName); - } - return null; - } + // Set home position - /// - /// Change password - /// - /// - /// - /// - private bool ChangeUserPassword(string firstName, string lastName, string password) - { - Scene scene = m_application.SceneManager.CurrentOrFirstScene; - IUserAccountService userAccountService = scene.UserAccountService; - IAuthenticationService authenticationService = scene.AuthenticationService; + GridRegion home = scene.GridService.GetRegionByPosition(scopeID, + (int)(regionXLocation * Constants.RegionSize), (int)(regionYLocation * Constants.RegionSize)); + if (null == home) { + m_log.WarnFormat("[RADMIN]: Unable to set home region for newly created user account {0} {1}", names[0], names[1]); + } else { + scene.GridUserService.SetHome(account.PrincipalID.ToString(), home.RegionID, new Vector3(128, 128, 0), new Vector3(0, 1, 0)); + m_log.DebugFormat("[RADMIN]: Set home region {0} for updated user account {1} {2}", home.RegionID, names[0], names[1]); + } - UserAccount account = userAccountService.GetUserAccount(UUID.Zero, firstName, lastName); - if (null != account) - { - bool success = false; - if (authenticationService != null) - success = authenticationService.SetPassword(account.PrincipalID, password); + ID = account.PrincipalID; - if (!success) - { - m_log.WarnFormat("[RADMIN]: Unable to set password for account {0} {1}.", - firstName, lastName); - return false; - } - return true; - } - else - { - m_log.ErrorFormat("[RADMIN]: No such user"); - return false; - } - } + m_log.DebugFormat("[RADMIN]: User {0}[{1}] created or retrieved", name, ID); + include = true; + } + catch (Exception e) + { + m_log.DebugFormat("[RADMIN]: Error creating user {0} : {1}", name, e.Message); + include = false; + } - private bool LoadHeightmap(string file, UUID regionID) - { - m_log.InfoFormat("[RADMIN]: Terrain Loading: {0}", file); + // OK, User has been created OK, now we can install the inventory. + // First retrieve the current inventory (the user may already exist) + // Note that althought he inventory is retrieved, the hierarchy has + // not been interpreted at all. - Scene region = null; + if (include) + { + // Setup for appearance processing + avatarAppearance = scene.AvatarService.GetAppearance(ID); + if (avatarAppearance == null) + avatarAppearance = new AvatarAppearance(); - if (!m_application.SceneManager.TryGetScene(regionID, out region)) - { - m_log.InfoFormat("[RADMIN]: unable to get a scene with that name: {0}", regionID.ToString()); - return false; - } + AvatarWearable[] wearables = avatarAppearance.Wearables; + for (int i=0; i(); - if (null == terrainModule) throw new Exception("terrain module not available"); - if (Uri.IsWellFormedUriString(file, UriKind.Absolute)) - { - m_log.Info("[RADMIN]: Terrain path is URL"); - Uri result; - if (Uri.TryCreate(file, UriKind.RelativeOrAbsolute, out result)) + try + { + // m_log.DebugFormat("[RADMIN] {0} folders, {1} items in inventory", + // uic.folders.Count, uic.items.Count); + + InventoryFolderBase clothingFolder = inventoryService.GetFolderForType(ID, AssetType.Clothing); + + // This should *never* be the case + if (clothingFolder == null || clothingFolder.Type != (short)AssetType.Clothing) + { + clothingFolder = new InventoryFolderBase(); + clothingFolder.ID = UUID.Random(); + clothingFolder.Name = "Clothing"; + clothingFolder.Owner = ID; + clothingFolder.Type = (short)AssetType.Clothing; + clothingFolder.ParentID = inventoryService.GetRootFolder(ID).ID; + clothingFolder.Version = 1; + inventoryService.AddFolder(clothingFolder); // store base record + m_log.ErrorFormat("[RADMIN]: Created clothing folder for {0}/{1}", name, ID); + } + + // OK, now we have an inventory for the user, read in the outfits from the + // default appearance XMl file. + + XmlNodeList outfits = avatar.GetElementsByTagName("Ensemble"); + InventoryFolderBase extraFolder; + string outfitName; + UUID assetid; + + foreach (XmlElement outfit in outfits) + { + m_log.DebugFormat("[RADMIN]: Loading outfit {0} for {1}", + GetStringAttribute(outfit,"name","?"), GetStringAttribute(avatar,"name","?")); + + outfitName = GetStringAttribute(outfit,"name",""); + select = (GetStringAttribute(outfit,"default","no") == "yes"); + + // If the folder already exists, re-use it. The defaults may + // change over time. Augment only. + + List folders = inventoryService.GetFolderContent(ID, clothingFolder.ID).Folders; + extraFolder = null; + + foreach (InventoryFolderBase folder in folders) + { + if (folder.Name == outfitName) + { + extraFolder = folder; + break; + } + } + + // Otherwise, we must create the folder. + if (extraFolder == null) + { + m_log.DebugFormat("[RADMIN]: Creating outfit folder {0} for {1}", outfitName, name); + extraFolder = new InventoryFolderBase(); + extraFolder.ID = UUID.Random(); + extraFolder.Name = outfitName; + extraFolder.Owner = ID; + extraFolder.Type = (short)AssetType.Clothing; + extraFolder.Version = 1; + extraFolder.ParentID = clothingFolder.ID; + inventoryService.AddFolder(extraFolder); + m_log.DebugFormat("[RADMIN]: Adding outfile folder {0} to folder {1}", extraFolder.ID, clothingFolder.ID); + } + + // Now get the pieces that make up the outfit + XmlNodeList items = outfit.GetElementsByTagName("Item"); + + foreach (XmlElement item in items) + { + assetid = UUID.Zero; + XmlNodeList children = item.ChildNodes; + foreach (XmlNode child in children) + { + switch (child.Name) + { + case "Permissions" : + m_log.DebugFormat("[RADMIN]: Permissions specified"); + perms = child; + break; + case "Asset" : + assetid = new UUID(child.InnerText); + break; + } + } + + InventoryItemBase inventoryItem = null; + + // Check if asset is in inventory already + inventoryItem = null; + List inventoryItems = inventoryService.GetFolderContent(ID, extraFolder.ID).Items; + + foreach (InventoryItemBase listItem in inventoryItems) + { + if (listItem.AssetID == assetid) + { + inventoryItem = listItem; + break; + } + } + + // Create inventory item + if (inventoryItem == null) + { + inventoryItem = new InventoryItemBase(UUID.Random(), ID); + inventoryItem.Name = GetStringAttribute(item,"name",""); + inventoryItem.Description = GetStringAttribute(item,"desc",""); + inventoryItem.InvType = GetIntegerAttribute(item,"invtype",-1); + inventoryItem.CreatorId = GetStringAttribute(item,"creatorid",""); + inventoryItem.CreatorIdAsUuid = (UUID)GetStringAttribute(item,"creatoruuid",""); + inventoryItem.CreatorData = GetStringAttribute(item, "creatordata", ""); + inventoryItem.NextPermissions = GetUnsignedAttribute(perms, "next", 0x7fffffff); + inventoryItem.CurrentPermissions = GetUnsignedAttribute(perms,"current",0x7fffffff); + inventoryItem.BasePermissions = GetUnsignedAttribute(perms,"base",0x7fffffff); + inventoryItem.EveryOnePermissions = GetUnsignedAttribute(perms,"everyone",0x7fffffff); + inventoryItem.GroupPermissions = GetUnsignedAttribute(perms,"group",0x7fffffff); + inventoryItem.AssetType = GetIntegerAttribute(item,"assettype",-1); + inventoryItem.AssetID = assetid; // associated asset + inventoryItem.GroupID = (UUID)GetStringAttribute(item,"groupid",""); + inventoryItem.GroupOwned = (GetStringAttribute(item,"groupowned","false") == "true"); + inventoryItem.SalePrice = GetIntegerAttribute(item,"saleprice",0); + inventoryItem.SaleType = (byte)GetIntegerAttribute(item,"saletype",0); + inventoryItem.Flags = GetUnsignedAttribute(item,"flags",0); + inventoryItem.CreationDate = GetIntegerAttribute(item,"creationdate",Util.UnixTimeSinceEpoch()); + inventoryItem.Folder = extraFolder.ID; // Parent folder + + m_application.SceneManager.CurrentOrFirstScene.AddInventoryItem(inventoryItem); + m_log.DebugFormat("[RADMIN]: Added item {0} to folder {1}", inventoryItem.ID, extraFolder.ID); + } + + // Attach item, if attachpoint is specified + int attachpoint = GetIntegerAttribute(item,"attachpoint",0); + if (attachpoint != 0) + { + avatarAppearance.SetAttachment(attachpoint, inventoryItem.ID, inventoryItem.AssetID); + m_log.DebugFormat("[RADMIN]: Attached {0}", inventoryItem.ID); + } + + // Record whether or not the item is to be initially worn + try + { + if (select && (GetStringAttribute(item, "wear", "false") == "true")) + { + avatarAppearance.Wearables[inventoryItem.Flags].Wear(inventoryItem.ID, inventoryItem.AssetID); + } + } + catch (Exception e) + { + m_log.WarnFormat("[RADMIN]: Error wearing item {0} : {1}", inventoryItem.ID, e.Message); + } + } // foreach item in outfit + m_log.DebugFormat("[RADMIN]: Outfit {0} load completed", outfitName); + } // foreach outfit + m_log.DebugFormat("[RADMIN]: Inventory update complete for {0}", name); + scene.AvatarService.SetAppearance(ID, avatarAppearance); + } + catch (Exception e) + { + m_log.WarnFormat("[RADMIN]: Inventory processing incomplete for user {0} : {1}", + name, e.Message); + } + } // End of include + } + m_log.DebugFormat("[RADMIN]: Default avatar loading complete"); + } + else { - // the url is valid - string fileType = file.Substring(file.LastIndexOf('/') + 1); - terrainModule.LoadFromStream(fileType, result); + m_log.DebugFormat("[RADMIN]: No default avatar information available"); + return false; } } - else + catch (Exception e) { - terrainModule.LoadFromFile(file); + m_log.WarnFormat("[RADMIN]: Exception whilst loading default avatars ; {0}", e.Message); + return false; } - m_log.Info("[RADMIN]: Load height maps request complete"); - return true; } } -- cgit v1.1 From 1e4842eabad7ccd1429161b98588220da1d8b657 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 8 Dec 2011 05:28:54 +0100 Subject: Remove superfluous try block --- .../RemoteController/RemoteAdminPlugin.cs | 41 ++++++++-------------- 1 file changed, 14 insertions(+), 27 deletions(-) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 9298726..7a1956f 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -214,7 +214,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController { Hashtable requestData = (Hashtable) request.Params[0]; - m_log.Info("[RADMIN]: Request to restart Region."); CheckStringParameters(requestData, responseData, new string[] {"password"}); FailIfRemoteAdminNotAllowed((string)requestData["password"], responseData, remoteClient.Address.ToString()); @@ -358,36 +357,24 @@ namespace OpenSim.ApplicationPlugins.RemoteController m_log.Info("[RADMIN]: Dialog request started"); - try - { - Hashtable requestData = (Hashtable)request.Params[0]; - - string message = (string)requestData["message"]; - string fromuuid = (string)requestData["from"]; - m_log.InfoFormat("[RADMIN]: Broadcasting: {0}", message); + Hashtable requestData = (Hashtable)request.Params[0]; - responseData["accepted"] = true; - responseData["success"] = true; + string message = (string)requestData["message"]; + string fromuuid = (string)requestData["from"]; + m_log.InfoFormat("[RADMIN]: Broadcasting: {0}", message); - m_application.SceneManager.ForEachScene( - delegate(Scene scene) - { - IDialogModule dialogModule = scene.RequestModuleInterface(); - if (dialogModule != null) - dialogModule.SendNotificationToUsersInRegion(UUID.Zero, fromuuid, message); - }); - } - catch (Exception e) - { - m_log.ErrorFormat("[RADMIN]: Broadcasting: failed: {0}", e.Message); - m_log.DebugFormat("[RADMIN]: Broadcasting: failed: {0}", e.ToString()); + responseData["accepted"] = true; + responseData["success"] = true; - responseData["accepted"] = false; - responseData["success"] = false; - responseData["error"] = e.Message; - } + m_application.SceneManager.ForEachScene( + delegate(Scene scene) + { + IDialogModule dialogModule = scene.RequestModuleInterface(); + if (dialogModule != null) + dialogModule.SendNotificationToUsersInRegion(UUID.Zero, fromuuid, message); + }); - m_log.Info("[RADMIN]: Alert request complete"); + m_log.Info("[RADMIN]: Dialog request complete"); } private void XmlRpcLoadHeightmapMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) -- cgit v1.1 From afab4b276ebc87f70307ac65e158bb3489d7634b Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 12 Dec 2011 13:51:31 +0100 Subject: Remove spammy log messages when querying sim health --- OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs | 8 -------- 1 file changed, 8 deletions(-) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 7a1956f..2930753 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -1724,8 +1724,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController private void XmlRpcRegionQueryMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { - m_log.Info("[RADMIN]: Received Query XML Administrator Request"); - Hashtable responseData = (Hashtable)response.Value; Hashtable requestData = (Hashtable)request.Params[0]; @@ -1736,16 +1734,12 @@ namespace OpenSim.ApplicationPlugins.RemoteController UUID region_uuid = (UUID) (string) requestData["region_uuid"]; if (!m_application.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_application.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 { @@ -1760,8 +1754,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController responseData["health"] = health; responseData["flags"] = flags; responseData["message"] = text; - - m_log.Info("[RADMIN]: Query XML Administrator Request complete"); } private void XmlRpcConsoleCommandMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) -- cgit v1.1 From 7c824f02b445579c0ef54a2212f851ae811a639d Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 28 Jan 2012 22:19:10 +0100 Subject: Add the ability to abort a pending restart using the viewer UI or a RemoteAdmin message --- .../RemoteController/RemoteAdminPlugin.cs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index dcc88c4..914e4d6 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -263,6 +263,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController Scene rebootedScene = null; GetSceneFromRegionParams(requestData, responseData, out rebootedScene); + IRestartModule restartModule = rebootedScene.RequestModuleInterface(); + responseData["success"] = false; responseData["accepted"] = true; responseData["rebooting"] = true; @@ -273,6 +275,23 @@ namespace OpenSim.ApplicationPlugins.RemoteController if (requestData.ContainsKey("alerts")) { string[] alertTimes = requestData["alerts"].ToString().Split( new char[] {','}); + if (alertTimes.Length == 1 && Convert.ToInt32(alertTimes[0]) == -1) + { + if (restartModule != null) + { + message = "Restart has been cancelled"; + + if (requestData.ContainsKey("message")) + message = requestData["message"].ToString(); + + restartModule.AbortRestart(message); + + responseData["success"] = true; + responseData["rebooting"] = false; + + return; + } + } foreach (string a in alertTimes) times.Add(Convert.ToInt32(a)); } @@ -305,7 +324,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController notice = false; } - IRestartModule restartModule = rebootedScene.RequestModuleInterface(); if (restartModule != null) { restartModule.ScheduleRestart(UUID.Zero, message, times.ToArray(), notice); -- cgit v1.1 From ca3b229e941512b3d05793f9fbbede7702eeeb38 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 28 May 2012 09:15:24 +0200 Subject: If a region is not found on a simulator, make the health query return 0 to indicate it's still starting rather than an error. There are other methods that can discover the presence of a region and slow starting regions may cause the watchdog to kill them while they start, --- .../RemoteController/RemoteAdminPlugin.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 49a8e64..9e72a98 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -1673,16 +1673,25 @@ namespace OpenSim.ApplicationPlugins.RemoteController Hashtable responseData = (Hashtable)response.Value; Hashtable requestData = (Hashtable)request.Params[0]; + int flags = 0; + string text = String.Empty; + int health = 0; responseData["success"] = true; CheckRegionParams(requestData, responseData); Scene scene = null; - GetSceneFromRegionParams(requestData, responseData, out scene); + try + { + GetSceneFromRegionParams(requestData, responseData, out scene); + health = scene.GetHealth(out flags, out text); + } + catch (Exception e) + { + responseData["error"] = null; + } - int flags; - string text; - int health = scene.GetHealth(out flags, out text); + responseData["success"] = true; responseData["health"] = health; responseData["flags"] = flags; responseData["message"] = text; -- cgit v1.1 From 207a5f17b58d58be249387c2195554d58f72a525 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 3 Jun 2012 13:43:39 +0200 Subject: When regions are set to shut down the instance, always send notifications to all affected regions and disregard the region id parameter. --- .../RemoteController/RemoteAdminPlugin.cs | 36 ++++++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 9e72a98..437d150 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -258,10 +258,25 @@ namespace OpenSim.ApplicationPlugins.RemoteController { m_log.Info("[RADMIN]: Request to restart Region."); - CheckRegionParams(requestData, responseData); - Scene rebootedScene = null; - GetSceneFromRegionParams(requestData, responseData, out rebootedScene); + bool restartAll = false; + + IConfig startupConfig = m_configSource.Configs["Startup"]; + if (startupConfig != null) + { + if (startupConfig.GetBoolean("InworldRestartShutsDown", false)) + { + rebootedScene = m_application.SceneManager.CurrentOrFirstScene; + restartAll = true; + } + } + + if (rebootedScene == null) + { + CheckRegionParams(requestData, responseData); + + GetSceneFromRegionParams(requestData, responseData, out rebootedScene); + } IRestartModule restartModule = rebootedScene.RequestModuleInterface(); @@ -324,11 +339,20 @@ namespace OpenSim.ApplicationPlugins.RemoteController notice = false; } - if (restartModule != null) + List restartList; + + if (restartAll) + restartList = m_application.SceneManager.Scenes; + else + restartList = new List() { rebootedScene }; + + foreach (Scene s in m_application.SceneManager.Scenes) { - restartModule.ScheduleRestart(UUID.Zero, message, times.ToArray(), notice); - responseData["success"] = true; + restartModule = s.RequestModuleInterface(); + if (restartModule != null) + restartModule.ScheduleRestart(UUID.Zero, message, times.ToArray(), notice); } + responseData["success"] = true; } catch (Exception e) { -- cgit v1.1 From 451b6c0e82f0bf850c5e2da1aafbcd48d676dc52 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 16 Jan 2013 14:52:04 +0100 Subject: Add admin_refresh_search command to RemoteAdmin --- .../RemoteController/RemoteAdminPlugin.cs | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 3d80eb6..9f3844b 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -157,6 +157,9 @@ namespace OpenSim.ApplicationPlugins.RemoteController availableMethods["admin_acl_remove"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListRemove); availableMethods["admin_acl_list"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListList); + // Misc + availableMethods["admin_refresh_search"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRefreshSearch); + // Either enable full remote functionality or just selected features string enabledMethods = m_config.GetString("enabled_methods", "all"); @@ -1948,6 +1951,32 @@ namespace OpenSim.ApplicationPlugins.RemoteController responseData["success"] = true; } + private void XmlRpcRefreshSearch(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + { + m_log.Info("[RADMIN]: Received Refresh Search Request"); + + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; + + CheckRegionParams(requestData, responseData); + + Scene scene = null; + GetSceneFromRegionParams(requestData, responseData, out scene); + + ISearchModule searchModule = scene.RequestModuleInterface(); + if (searchModule != null) + { + searchModule.Refresh(); + responseData["success"] = true; + } + else + { + responseData["success"] = false; + } + + m_log.Info("[RADMIN]: Refresh Search Request complete"); + } + /// /// Parse a float with the given parameter name from a request data hash table. /// -- cgit v1.1 From 8c6984eac140ed48f10ac3f3db533d0c9b1d084a Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 23 Jan 2013 23:12:48 +0100 Subject: Implement get version RemoteAdmin call --- .../RemoteController/RemoteAdminPlugin.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 9f3844b..49fc566 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -70,6 +70,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController private string m_name = "RemoteAdminPlugin"; private string m_version = "0.0"; + private string m_openSimVersion; public string Version { @@ -89,6 +90,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController public void Initialise(OpenSimBase openSim) { + m_openSimVersion = openSim.GetVersionText(); + m_configSource = openSim.ConfigSource.Source; try { @@ -159,6 +162,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController // Misc availableMethods["admin_refresh_search"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRefreshSearch); + availableMethods["admin_get_opensim_version"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetOpenSimVersion); // Either enable full remote functionality or just selected features string enabledMethods = m_config.GetString("enabled_methods", "all"); @@ -1977,6 +1981,18 @@ namespace OpenSim.ApplicationPlugins.RemoteController m_log.Info("[RADMIN]: Refresh Search Request complete"); } + private void XmlRpcGetOpenSimVersion(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + { + m_log.Info("[RADMIN]: Received Get OpenSim Version Request"); + + Hashtable responseData = (Hashtable)response.Value; + + responseData["version"] = m_openSimVersion; + responseData["success"] = true; + + m_log.Info("[RADMIN]: Get OpenSim Version Request complete"); + } + /// /// Parse a float with the given parameter name from a request data hash table. /// -- cgit v1.1 From c341664c1b8ccf3bd7b81795b900b971a15ff318 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 24 Mar 2013 18:56:28 +0100 Subject: Phase 1 of implementing a transfer permission. Overwrite libOMV's PermissionMask with our own and add export permissions as well as a new definition for "All" as meaning "all conventional permissions" rather than "all possible permissions" --- OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 49fc566..f19e391 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -50,6 +50,7 @@ using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; using GridRegion = OpenSim.Services.Interfaces.GridRegion; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.ApplicationPlugins.RemoteController { -- cgit v1.1 From 01780d4dc6b3dc266b8fbf22f779ced5bd002743 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 5 Aug 2014 19:59:21 +0100 Subject: put back a check for null foldedperms --- OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index cf2e037..eb5d784 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -2942,7 +2942,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController /// private void ApplyNextOwnerPermissions(InventoryItemBase item) { - if (item.InvType == (int)InventoryType.Object) + if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) { uint perms = item.CurrentPermissions; PermissionsUtil.ApplyFoldedPermissions(item.CurrentPermissions, ref perms); -- cgit v1.1 From 1fc5dadc604daebd4aeaf6954ac64f45fdfc7a2f Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 23 Aug 2014 19:38:08 +0200 Subject: Add an admin message to refesh a region's map tile. Will be used to periodically rebuild the world map to clean out unused tiles. --- .../RemoteController/RemoteAdminPlugin.cs | 27 ++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index e50dac6..d2a5c43 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -164,6 +164,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController // Misc availableMethods["admin_refresh_search"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRefreshSearch); + availableMethods["admin_refresh_map"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRefreshMap); availableMethods["admin_get_opensim_version"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetOpenSimVersion); // Either enable full remote functionality or just selected features @@ -2048,6 +2049,32 @@ namespace OpenSim.ApplicationPlugins.RemoteController m_log.Info("[RADMIN]: Refresh Search Request complete"); } + private void XmlRpcRefreshMap(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + { + m_log.Info("[RADMIN]: Received Refresh Map Request"); + + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; + + CheckRegionParams(requestData, responseData); + + Scene scene = null; + GetSceneFromRegionParams(requestData, responseData, out scene); + + IMapTileModule mapTileModule = scene.RequestModuleInterface(); + if (mapTileModule != null) + { + mapTileModule.UploadMapTile(scene); + responseData["success"] = true; + } + else + { + responseData["success"] = false; + } + + m_log.Info("[RADMIN]: Refresh Map Request complete"); + } + private void XmlRpcGetOpenSimVersion(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { m_log.Info("[RADMIN]: Received Get OpenSim Version Request"); -- cgit v1.1 From 6a849e8cdfaa881cea18d10bcffc89bbe4414f74 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 21 Nov 2014 04:41:45 +0100 Subject: Add an XmlRpc method to get a region's root agent count. This is intended to let us restart grid regions when the last agent leaves. --- .../RemoteController/RemoteAdminPlugin.cs | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 4c05ec8..eba6a9c 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -170,6 +170,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController availableMethods["admin_refresh_search"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRefreshSearch); availableMethods["admin_refresh_map"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRefreshMap); availableMethods["admin_get_opensim_version"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetOpenSimVersion); + availableMethods["admin_get_agent_count"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetAgentCount); // Either enable full remote functionality or just selected features string enabledMethods = m_config.GetString("enabled_methods", "all"); @@ -2266,6 +2267,31 @@ namespace OpenSim.ApplicationPlugins.RemoteController m_log.Info("[RADMIN]: Get OpenSim Version Request complete"); } + private void XmlRpcGetAgentCount(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + { + m_log.Info("[RADMIN]: Received Get Agent Count Request"); + + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; + + CheckRegionParams(requestData, responseData); + + Scene scene = null; + GetSceneFromRegionParams(requestData, responseData, out scene); + + if (scene == null) + { + responseData["success"] = false; + } + else + { + responseData["count"] = scene.GetRootAgentCount(); + responseData["success"] = true; + } + + m_log.Info("[RADMIN]: Get Agent Count Request complete"); + } + /// /// Parse a float with the given parameter name from a request data hash table. /// -- cgit v1.1 From 7caff514812d585a52f4832b4976cb272b2750b5 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 7 Mar 2015 01:15:48 +0100 Subject: Make the maptile uploader in remote admin fire and forget so the controlling host gets a timely reply. --- OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index eba6a9c..2120116 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -2244,7 +2244,10 @@ namespace OpenSim.ApplicationPlugins.RemoteController IMapTileModule mapTileModule = scene.RequestModuleInterface(); if (mapTileModule != null) { - mapTileModule.UploadMapTile(scene); + Util.FireAndForget((x) => + { + mapTileModule.UploadMapTile(scene); + }); responseData["success"] = true; } else -- cgit v1.1 From 5cb8127e8745d6d89f9b748fecefbeb8a43da60e Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 23 Mar 2015 22:16:49 +0100 Subject: Make log output of remote admin's restart region call reflect restart cancellations properly. --- OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 2120116..e71e81c 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -271,8 +271,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController try { - m_log.Info("[RADMIN]: Request to restart Region."); - Scene rebootedScene = null; bool restartAll = false; @@ -307,6 +305,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController string[] alertTimes = requestData["alerts"].ToString().Split( new char[] {','}); if (alertTimes.Length == 1 && Convert.ToInt32(alertTimes[0]) == -1) { + m_log.Info("[RADMIN]: Request to cancel restart."); + if (restartModule != null) { message = "Restart has been cancelled"; @@ -342,6 +342,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController } } + m_log.Info("[RADMIN]: Request to restart Region."); + message = "Region is restarting in {0}. Please save what you are doing and log out."; if (requestData.ContainsKey("message")) -- cgit v1.1 From 08c72a8dc1e54114559521a6c2952905ecf6f105 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 28 Mar 2015 07:50:04 -0700 Subject: varregion: remove use of Constants.RegionSize is various places. More use of the Util routines for conversion of region handles into addresses. --- OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 2120116..cb96a55 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -1155,7 +1155,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController // Set home position GridRegion home = scene.GridService.GetRegionByPosition(scopeID, - (int)(regionXLocation * Constants.RegionSize), (int)(regionYLocation * Constants.RegionSize)); + (int)Util.RegionToWorldLoc(regionXLocation), (int)Util.RegionToWorldLoc(regionYLocation)); if (null == home) { m_log.WarnFormat("[RADMIN]: Unable to set home region for newly created user account {0} {1}", firstName, lastName); @@ -1385,7 +1385,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController if ((null != regionXLocation) && (null != regionYLocation)) { GridRegion home = scene.GridService.GetRegionByPosition(scopeID, - (int)(regionXLocation * Constants.RegionSize), (int)(regionYLocation * Constants.RegionSize)); + (int)Util.RegionToWorldLoc((uint)regionXLocation), (int)Util.RegionToWorldLoc((uint)regionYLocation)); if (null == home) { m_log.WarnFormat("[RADMIN]: Unable to set home region for updated user account {0} {1}", firstName, lastName); } else { @@ -3116,7 +3116,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController // Set home position GridRegion home = scene.GridService.GetRegionByPosition(scopeID, - (int)(regionXLocation * Constants.RegionSize), (int)(regionYLocation * Constants.RegionSize)); + (int)Util.RegionToWorldLoc(regionXLocation), (int)Util.RegionToWorldLoc(regionYLocation)); if (null == home) { m_log.WarnFormat("[RADMIN]: Unable to set home region for newly created user account {0} {1}", names[0], names[1]); } else { -- cgit v1.1 From cbc569a1e0cd26b991bed27245f07946cdbec4b7 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 24 Aug 2015 11:06:12 +0100 Subject: rename ImapTileModule as IMAPImageUploadModule to match core --- OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 2e128a7..c416e88 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -2243,7 +2243,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController Scene scene = null; GetSceneFromRegionParams(requestData, responseData, out scene); - IMapTileModule mapTileModule = scene.RequestModuleInterface(); + IMapImageUploadModule mapTileModule = scene.RequestModuleInterface(); if (mapTileModule != null) { Util.FireAndForget((x) => -- cgit v1.1 From 3829df10595911de9ed1ce2f7b6cdd205828f8d0 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 24 Aug 2015 17:05:16 +0100 Subject: try to implement core load oar options --- OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index c416e88..589307a 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -1619,8 +1619,11 @@ namespace OpenSim.ApplicationPlugins.RemoteController } IRegionArchiverModule archiver = scene.RequestModuleInterface(); + Dictionary archiveOptions = new Dictionary(); + if (mergeOar) archiveOptions.Add("merge", null); + if (skipAssets) archiveOptions.Add("skipAssets", null); if (archiver != null) - archiver.DearchiveRegion(filename, mergeOar, skipAssets, Guid.Empty); + archiver.DearchiveRegion(filename, Guid.Empty, archiveOptions); else throw new Exception("Archiver module not present for scene"); -- cgit v1.1