Anonymous | Login | Signup for a new account | 2021-01-28 05:08 PST | ![]() |
Main | My View | View Issues | Change Log | Roadmap | Summary | My Account |
View Issue Details [ Jump to Notes ] | [ Issue History ] [ Print ] | |||||||||
ID | Project | Category | View Status | Date Submitted | Last Update | |||||
0005824 | opensim | [REGION] Specific OpenSim Module | public | 2011-12-15 06:37 | 2012-01-06 15:05 | |||||
Reporter | Michelle Argus | |||||||||
Assigned To | ||||||||||
Priority | none | Severity | feature | Reproducibility | N/A | |||||
Status | patch feedback | Resolution | open | |||||||
Platform | Operating System | Operating System Version | ||||||||
Product Version | ||||||||||
Target Version | Fixed in Version | |||||||||
Summary | 0005824: [Patch] Reorganised RemoteAdmin Module | |||||||||
Description | Added a Patch as Proposal to reorganise RemoteAdmin. The Patch groups RAdmin commands by command type. The c# function are now grouped using #region for easy easely navigation. As I am planing on adding many new commands, I feel it would be good to reorganise RAdmin prior to implementing new commands. Over time the commands have become mixed a bit. This is just a proposal. No functions or commands have been changed, only the sort order in which the functions are listed in the code have changed. | |||||||||
Additional Information | This Patch requires the Patch in http://opensimulator.org/mantis/view.php?id=5814 [^] to be implemented first... | |||||||||
Tags | No tags attached. | |||||||||
Git Revision or version number | 63fe673af1974e265c5d18dc95f963fd968afd26 | |||||||||
Run Mode | Standalone (1 Region) , Standalone (Multiple Regions) , Grid (1 Region per Sim) , Grid (Multiple Regions per Sim) | |||||||||
Physics Engine | BasicPhysics | |||||||||
Script Engine | ||||||||||
Environment | Unknown | |||||||||
Mono Version | None | |||||||||
Viewer | ||||||||||
Attached Files | ![]() From 63fe673af1974e265c5d18dc95f963fd968afd26 2011-12-08 23:45:53 +0000 From: Michelle Argus <info@marentals.de> Date: Wed, 14 Dec 2011 02:10:10 +0200 Subject: [PATCH] RemoteAdmin - Proposal to reorganise commands and function in the code and added #regions to make future navigation easier. diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs old mode 100755 new mode 100644 index 8ea5034..5ac6d54 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -124,16 +124,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController m_httpServer = MainServer.GetHttpServer((uint)port,ipaddr); Dictionary<string, XmlRpcMethod> availableMethods = new Dictionary<string, XmlRpcMethod>(); - 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_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"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcTeleportAgentMethod); @@ -142,15 +132,33 @@ namespace OpenSim.ApplicationPlugins.RemoteController 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); + availableMethods["admin_update_user"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcUpdateUserAccountMethod); + + // Group management + + // Object management + + // Parcel management + + // Region management + 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_restart"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRestartMethod); - // Region state management + // Region file management 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); + availableMethods["admin_load_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcLoadHeightmapMethod); + availableMethods["admin_save_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcSaveHeightmapMethod); - // Estate access list management + // Estate management 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); @@ -198,6 +206,10 @@ namespace OpenSim.ApplicationPlugins.RemoteController } } + public void Dispose() + { + } + /// <summary> /// Invoke an XmlRpc method with the standard actions (password check, etc.) /// </summary> @@ -245,9 +257,1285 @@ namespace OpenSim.ApplicationPlugins.RemoteController m_log.WarnFormat("[RADMIN]: Wrong password, blocked access from IP {0}", check_ip_address); responseData["accepted"] = false; throw new Exception("wrong password"); + } + } + +#region Agent Management + + private void XmlRpcTeleportAgentMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + { + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; + + UUID agentId; + string regionName = null; + Vector3 pos, lookAt; + ScenePresence sp = null; + + 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); + + 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"]; + + if (!UUID.TryParse(rawAgentId, out agentId)) + throw new Exception(string.Format("agent_id {0} does not have the correct id format", rawAgentId)); + + m_application.SceneManager.TryGetRootScenePresence(agentId, out sp); + + 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"); + } + + 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); + + // We have no way of telling the failure of the actual teleport + responseData["success"] = true; + } + +#endregion + +#region User Management + + /// <summary> + /// Create a new user account. + /// <summary> + /// <param name="request">incoming XML RPC request</param> + /// <remarks> + /// XmlRpcCreateUserMethod takes the following XMLRPC + /// parameters + /// <list type="table"> + /// <listheader><term>parameter name</term><description>description</description></listheader> + /// <item><term>password</term> + /// <description>admin password as set in OpenSim.ini</description></item> + /// <item><term>user_firstname</term> + /// <description>avatar's first name</description></item> + /// <item><term>user_lastname</term> + /// <description>avatar's last name</description></item> + /// <item><term>user_password</term> + /// <description>avatar's password</description></item> + /// <item><term>user_email</term> + /// <description>email of the avatar's owner (optional)</description></item> + /// <item><term>start_region_x</term> + /// <description>avatar's start region coordinates, X value</description></item> + /// <item><term>start_region_y</term> + /// <description>avatar's start region coordinates, Y value</description></item> + /// </list> + /// + /// XmlRpcCreateUserMethod returns + /// <list type="table"> + /// <listheader><term>name</term><description>description</description></listheader> + /// <item><term>success</term> + /// <description>true or false</description></item> + /// <item><term>error</term> + /// <description>error message if success is false</description></item> + /// <item><term>avatar_uuid</term> + /// <description>UUID of the newly created avatar + /// account; UUID.Zero if failed. + /// </description></item> + /// </list> + /// </remarks> + private void XmlRpcCreateUserMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + { + m_log.Info("[RADMIN]: CreateUser: new request"); + + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; + + lock (m_requestLock) + { + try + { + // check completeness + CheckStringParameters(requestData, responseData, new string[] + { + "user_firstname", + "user_lastname", "user_password", + }); + CheckIntegerParams(requestData, responseData, new string[] {"start_region_x", "start_region_y"}); + + // do the job + string firstName = (string) requestData["user_firstname"]; + string lastName = (string) requestData["user_lastname"]; + string password = (string) requestData["user_password"]; + + uint regionXLocation = Convert.ToUInt32((Int32) requestData["start_region_x"]); + uint regionYLocation = Convert.ToUInt32((Int32) requestData["start_region_y"]); + + string email = ""; // empty string for email + if (requestData.Contains("user_email")) + email = (string)requestData["user_email"]; + + Scene scene = m_application.SceneManager.CurrentOrFirstScene; + UUID scopeID = scene.RegionInfo.ScopeID; + + UserAccount account = CreateUser(scopeID, firstName, lastName, password, email); + + if (null == account) + throw new Exception(String.Format("failed to create new user {0} {1}", + firstName, lastName)); + + // Set home position + + 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}", firstName, lastName); + } + 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); + } + + // Establish the avatar's initial appearance + + UpdateUserAppearance(responseData, requestData, account.PrincipalID); + + responseData["success"] = true; + responseData["avatar_uuid"] = account.PrincipalID.ToString(); + + m_log.InfoFormat("[RADMIN]: CreateUser: User {0} {1} created, UUID {2}", firstName, lastName, account.PrincipalID); + } + catch (Exception e) + { + responseData["avatar_uuid"] = UUID.Zero.ToString(); + + throw e; + } + + m_log.Info("[RADMIN]: CreateUser: request complete"); + } + } + + /// <summary> + /// Check whether a certain user account exists. + /// <summary> + /// <param name="request">incoming XML RPC request</param> + /// <remarks> + /// XmlRpcUserExistsMethod takes the following XMLRPC + /// parameters + /// <list type="table"> + /// <listheader><term>parameter name</term><description>description</description></listheader> + /// <item><term>password</term> + /// <description>admin password as set in OpenSim.ini</description></item> + /// <item><term>user_firstname</term> + /// <description>avatar's first name</description></item> + /// <item><term>user_lastname</term> + /// <description>avatar's last name</description></item> + /// </list> + /// + /// XmlRpcCreateUserMethod returns + /// <list type="table"> + /// <listheader><term>name</term><description>description</description></listheader> + /// <item><term>user_firstname</term> + /// <description>avatar's first name</description></item> + /// <item><term>user_lastname</term> + /// <description>avatar's last name</description></item> + /// <item><term>user_lastlogin</term> + /// <description>avatar's last login time (secs since UNIX epoch)</description></item> + /// <item><term>success</term> + /// <description>true or false</description></item> + /// <item><term>error</term> + /// <description>error message if success is false</description></item> + /// </list> + /// </remarks> + private void XmlRpcUserExistsMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + { + m_log.Info("[RADMIN]: UserExists: new request"); + + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; + + // check completeness + CheckStringParameters(requestData, responseData, new string[] {"user_firstname", "user_lastname"}); + + string firstName = (string) requestData["user_firstname"]; + string lastName = (string) requestData["user_lastname"]; + + responseData["user_firstname"] = firstName; + responseData["user_lastname"] = lastName; + + UUID scopeID = m_application.SceneManager.CurrentOrFirstScene.RegionInfo.ScopeID; + + UserAccount account = m_application.SceneManager.CurrentOrFirstScene.UserAccountService.GetUserAccount(scopeID, firstName, 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; + + responseData["success"] = true; + } + + m_log.Info("[RADMIN]: UserExists: request complete"); + } + + /// <summary> + /// Update a user account. + /// <summary> + /// <param name="request">incoming XML RPC request</param> + /// <remarks> + /// XmlRpcUpdateUserAccountMethod takes the following XMLRPC + /// parameters (changeable ones are optional) + /// <list type="table"> + /// <listheader><term>parameter name</term><description>description</description></listheader> + /// <item><term>password</term> + /// <description>admin password as set in OpenSim.ini</description></item> + /// <item><term>user_firstname</term> + /// <description>avatar's first name (cannot be changed)</description></item> + /// <item><term>user_lastname</term> + /// <description>avatar's last name (cannot be changed)</description></item> + /// <item><term>user_password</term> + /// <description>avatar's password (changeable)</description></item> + /// <item><term>start_region_x</term> + /// <description>avatar's start region coordinates, X + /// value (changeable)</description></item> + /// <item><term>start_region_y</term> + /// <description>avatar's start region coordinates, Y + /// value (changeable)</description></item> + /// <item><term>about_real_world (not implemented yet)</term> + /// <description>"about" text of avatar owner (changeable)</description></item> + /// <item><term>about_virtual_world (not implemented yet)</term> + /// <description>"about" text of avatar (changeable)</description></item> + /// </list> + /// + /// XmlRpcCreateUserMethod returns + /// <list type="table"> + /// <listheader><term>name</term><description>description</description></listheader> + /// <item><term>success</term> + /// <description>true or false</description></item> + /// <item><term>error</term> + /// <description>error message if success is false</description></item> + /// <item><term>avatar_uuid</term> + /// <description>UUID of the updated avatar + /// account; UUID.Zero if failed. + /// </description></item> + /// </list> + /// </remarks> + 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"); + + Hashtable responseData = (Hashtable)response.Value; + Hashtable requestData = (Hashtable)request.Params[0]; + + lock (m_requestLock) + { + try + { + // check completeness + CheckStringParameters(requestData, responseData, new string[] { + "user_firstname", + "user_lastname"}); + + // do the job + string firstName = (string) requestData["user_firstname"]; + string lastName = (string) requestData["user_lastname"]; + + string password = String.Empty; + uint? regionXLocation = null; + uint? regionYLocation = null; + // uint? ulaX = null; + // uint? ulaY = null; + // uint? ulaZ = null; + // uint? usaX = null; + // uint? usaY = null; + // uint? usaZ = null; + // string aboutFirstLive = String.Empty; + // string aboutAvatar = String.Empty; + + if (requestData.ContainsKey("user_password")) password = (string) requestData["user_password"]; + if (requestData.ContainsKey("start_region_x")) + regionXLocation = Convert.ToUInt32((Int32) requestData["start_region_x"]); + if (requestData.ContainsKey("start_region_y")) + regionYLocation = Convert.ToUInt32((Int32) requestData["start_region_y"]); + + // if (requestData.ContainsKey("start_lookat_x")) + // ulaX = Convert.ToUInt32((Int32) requestData["start_lookat_x"]); + // if (requestData.ContainsKey("start_lookat_y")) + // ulaY = Convert.ToUInt32((Int32) requestData["start_lookat_y"]); + // if (requestData.ContainsKey("start_lookat_z")) + // ulaZ = Convert.ToUInt32((Int32) requestData["start_lookat_z"]); + + // if (requestData.ContainsKey("start_standat_x")) + // usaX = Convert.ToUInt32((Int32) requestData["start_standat_x"]); + // if (requestData.ContainsKey("start_standat_y")) + // usaY = Convert.ToUInt32((Int32) requestData["start_standat_y"]); + // if (requestData.ContainsKey("start_standat_z")) + // usaZ = Convert.ToUInt32((Int32) requestData["start_standat_z"]); + // if (requestData.ContainsKey("about_real_world")) + // aboutFirstLive = (string)requestData["about_real_world"]; + // if (requestData.ContainsKey("about_virtual_world")) + // aboutAvatar = (string)requestData["about_virtual_world"]; + + Scene scene = m_application.SceneManager.CurrentOrFirstScene; + UUID scopeID = scene.RegionInfo.ScopeID; + UserAccount account = scene.UserAccountService.GetUserAccount(scopeID, firstName, lastName); + + if (null == account) + throw new Exception(String.Format("avatar {0} {1} does not exist", firstName, lastName)); + + if (!String.IsNullOrEmpty(password)) + { + m_log.DebugFormat("[RADMIN]: UpdateUserAccount: updating password for avatar {0} {1}", firstName, lastName); + ChangeUserPassword(firstName, lastName, password); + } + + // if (null != usaX) userProfile.HomeLocationX = (uint) usaX; + // if (null != usaY) userProfile.HomeLocationY = (uint) usaY; + // if (null != usaZ) userProfile.HomeLocationZ = (uint) usaZ; + + // if (null != ulaX) userProfile.HomeLookAtX = (uint) ulaX; + // if (null != ulaY) userProfile.HomeLookAtY = (uint) ulaY; + // if (null != ulaZ) userProfile.HomeLookAtZ = (uint) ulaZ; + + // if (String.Empty != aboutFirstLive) userProfile.FirstLifeAboutText = aboutFirstLive; + // if (String.Empty != aboutAvatar) userProfile.AboutText = aboutAvatar; + + // Set home position + + if ((null != regionXLocation) && (null != regionYLocation)) + { + 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 updated user account {0} {1}", firstName, lastName); + } 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); + } + } + + // User has been created. Now establish gender and appearance. + + UpdateUserAppearance(responseData, requestData, account.PrincipalID); + + responseData["success"] = true; + responseData["avatar_uuid"] = account.PrincipalID.ToString(); + + m_log.InfoFormat("[RADMIN]: UpdateUserAccount: account for user {0} {1} updated, UUID {2}", + firstName, lastName, + account.PrincipalID); + } + catch (Exception e) + { + responseData["avatar_uuid"] = UUID.Zero.ToString(); + + throw e; + } + + m_log.Info("[RADMIN]: UpdateUserAccount: request complete"); + } + } + + /// <summary> + /// Create a user + /// </summary> + /// <param name="scopeID"></param> + /// <param name="firstName"></param> + /// <param name="lastName"></param> + /// <param name="password"></param> + /// <param name="email"></param> + 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; + + 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<string, object>(); + account.ServiceURLs["HomeURI"] = string.Empty; + account.ServiceURLs["GatekeeperURI"] = string.Empty; + account.ServiceURLs["InventoryServerURI"] = string.Empty; + account.ServiceURLs["AssetServerURI"] = string.Empty; + } + + if (userAccountService.StoreUserAccount(account)) + { + bool success; + if (authenticationService != null) + { + success = authenticationService.SetPassword(account.PrincipalID, password); + if (!success) + m_log.WarnFormat("[RADMIN]: Unable to set password for account {0} {1}.", + firstName, lastName); + } + + GridRegion home = null; + if (gridService != null) + { + List<GridRegion> defaultRegions = gridService.GetDefaultRegions(UUID.Zero); + if (defaultRegions != null && defaultRegions.Count >= 1) + home = defaultRegions[0]; + + 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); + + if (inventoryService != null) + { + success = inventoryService.CreateUserInventory(account.PrincipalID); + if (!success) + m_log.WarnFormat("[RADMIN]: Unable to create inventory for account {0} {1}.", + firstName, lastName); + } + + 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; + } + + /// <summary> + /// Change password + /// </summary> + /// <param name="firstName"></param> + /// <param name="lastName"></param> + /// <param name="password"></param> + private bool ChangeUserPassword(string firstName, string lastName, string password) + { + Scene scene = m_application.SceneManager.CurrentOrFirstScene; + IUserAccountService userAccountService = scene.UserAccountService; + IAuthenticationService authenticationService = scene.AuthenticationService; + + UserAccount account = userAccountService.GetUserAccount(UUID.Zero, firstName, lastName); + if (null != account) + { + bool success = false; + if (authenticationService != null) + success = authenticationService.SetPassword(account.PrincipalID, password); + + 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; + } + } + + + /// <summary> + /// 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. + /// </summary> + private void UpdateUserAppearance(Hashtable responseData, Hashtable requestData, UUID userid) + { + 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; + + // Has a gender preference been supplied? + + if (requestData.Contains("gender")) + { + switch ((string)requestData["gender"]) + { + case "m" : + case "male" : + model = defaultMale; + break; + case "f" : + case "female" : + model = defaultFemale; + break; + case "n" : + case "neutral" : + default : + model = defaultNeutral; + break; + } + } + + // Has an explicit model been specified? + + if (requestData.Contains("model") && (String.IsNullOrEmpty((string)requestData["gender"]))) + { + model = (string)requestData["model"]; + } + + // No appearance attributes were set + + if (String.IsNullOrEmpty(model)) + { + m_log.DebugFormat("[RADMIN]: Appearance update not requested"); + return; + } + + m_log.DebugFormat("[RADMIN]: Setting appearance for avatar {0}, using model <{1}>", userid, model); + + 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; + } + + // 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); + } + + /// <summary> + /// 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. + /// </summary> + private void EstablishAppearance(UUID destination, UUID source) + { + 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; + + // Simple appearance copy or copy Clothing and Bodyparts folders? + bool copyFolders = m_config.GetBoolean("copy_folders", false); + + if (!copyFolders) + { + // Simple copy of wearables and appearance update + try + { + CopyWearablesAndAttachments(destination, source, avatarAppearance); + + scene.AvatarService.SetAppearance(destination, avatarAppearance); + } + catch (Exception e) + { + m_log.WarnFormat("[RADMIN]: Error transferring appearance for {0} : {1}", + destination, e.Message); + } + + return; + } + + // Copy Clothing and Bodypart folders and appearance update + try + { + Dictionary<UUID,UUID> inventoryMap = new Dictionary<UUID,UUID>(); + CopyInventoryFolders(destination, source, AssetType.Clothing, inventoryMap, avatarAppearance); + CopyInventoryFolders(destination, source, AssetType.Bodypart, inventoryMap, avatarAppearance); + + AvatarWearable[] wearables = avatarAppearance.Wearables; + + for (int i=0; i<wearables.Length; i++) + { + if (inventoryMap.ContainsKey(wearables[i][0].ItemID)) + { + AvatarWearable wearable = new AvatarWearable(); + wearable.Wear(inventoryMap[wearables[i][0].ItemID], + wearables[i][0].AssetID); + avatarAppearance.SetWearable(i, wearable); + } + } + + scene.AvatarService.SetAppearance(destination, avatarAppearance); } + catch (Exception e) + { + m_log.WarnFormat("[RADMIN]: Error transferring appearance for {0} : {1}", + destination, e.Message); + } + + return; } + /// <summary> + /// 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. + /// </summary> + private void CopyWearablesAndAttachments(UUID destination, UUID source, AvatarAppearance avatarAppearance) + { + 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)"); + + // 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); + } + + // Wearables + AvatarWearable[] wearables = avatarAppearance.Wearables; + AvatarWearable wearable; + + for (int i = 0; i<wearables.Length; i++) + { + wearable = wearables[i]; + if (wearable[0].ItemID != UUID.Zero) + { + // Get inventory item and copy it + InventoryItemBase item = new InventoryItemBase(wearable[0].ItemID, source); + item = inventoryService.GetItem(item); + + if (item != null) + { + 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); + } + else + { + m_log.WarnFormat("[RADMIN]: Error transferring {0} to folder {1}", wearable[0].ItemID, destinationFolder.ID); + } + } + } + + // Attachments + List<AvatarAttachment> attachments = avatarAppearance.GetAttachments(); + + foreach (AvatarAttachment attachment in attachments) + { + int attachpoint = attachment.AttachPoint; + UUID itemID = attachment.ItemID; + + if (itemID != UUID.Zero) + { + // Get inventory item and copy it + InventoryItemBase item = new InventoryItemBase(itemID, source); + item = inventoryService.GetItem(item); + + if (item != null) + { + 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); + } + else + { + m_log.WarnFormat("[RADMIN]: Error transferring {0} to folder {1}", itemID, destinationFolder.ID); + } + } + } + } + + /// <summary> + /// This method is called by establishAppearance to copy inventory folders to make + /// copies of Clothing and Bodyparts inventory folders and attaches worn attachments + /// </summary> + private void CopyInventoryFolders(UUID destination, UUID source, AssetType assetType, Dictionary<UUID,UUID> inventoryMap, + AvatarAppearance avatarAppearance) + { + IInventoryService inventoryService = m_application.SceneManager.CurrentOrFirstScene.InventoryService; + + InventoryFolderBase sourceFolder = inventoryService.GetFolderForType(source, assetType); + InventoryFolderBase destinationFolder = inventoryService.GetFolderForType(destination, assetType); + + if (sourceFolder == null || destinationFolder == null) + throw new Exception("Cannot locate folder(s)"); + + // 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"; + } + 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) + { + destinationFolder.Name = "Clothing"; + } + else + { + destinationFolder.Name = "Body Parts"; + } + 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<InventoryFolderBase> 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); + + m_log.DebugFormat("[RADMIN]: Added folder {0} to folder {1}", extraFolder.ID, sourceFolder.ID); + + List<InventoryItemBase> items = inventoryService.GetFolderContent(source, folder.ID).Items; + + foreach (InventoryItemBase item in items) + { + 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.CurrentOrFirstScene.AddInventoryItem(destinationItem); + inventoryMap.Add(item.ID, destinationItem.ID); + m_log.DebugFormat("[RADMIN]: Added item {0} to folder {1}", destinationItem.ID, extraFolder.ID); + + // 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); + } + } + } + } + + /// <summary> + /// Apply next owner permissions. + /// </summary> + private void ApplyNextOwnerPermissions(InventoryItemBase item) + { + if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) + { + 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; + } + + /// <summary> + /// 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. + /// </summary> + private bool CreateDefaultAvatars() + { + // Only load once + if (m_defaultAvatarsLoaded) + { + return false; + } + + m_log.DebugFormat("[RADMIN]: Creating default avatar entries"); + + m_defaultAvatarsLoaded = true; + + // Load processing starts here... + + try + { + string defaultAppearanceFileName = null; + + //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"); + } + + 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; + + Scene scene = m_application.SceneManager.CurrentOrFirstScene; + IInventoryService inventoryService = scene.InventoryService; + IAssetService assetService = scene.AssetService; + + doc.LoadXml(File.ReadAllText(defaultAppearanceFileName)); + + // 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); + } + + avatars = doc.GetElementsByTagName("Avatar"); + + // The document may contain multiple avatars + + foreach (XmlElement avatar in avatars) + { + m_log.DebugFormat("[RADMIN]: Loading appearance for {0}, gender = {1}", + GetStringAttribute(avatar,"name","?"), GetStringAttribute(avatar,"gender","?")); + + // Create the user identified by the avatar entry + + 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); + + 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; + } + } + + // Set home position + + 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]); + } + + ID = account.PrincipalID; + + 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; + } + + // 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 (include) + { + // Setup for appearance processing + avatarAppearance = scene.AvatarService.GetAppearance(ID); + if (avatarAppearance == null) + avatarAppearance = new AvatarAppearance(); + + AvatarWearable[] wearables = avatarAppearance.Wearables; + for (int i=0; i<wearables.Length; i++) + { + wearables[i] = new AvatarWearable(); + } + + 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<InventoryFolderBase> 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<InventoryItemBase> 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 + { + 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; + } + + return true; + } + + #endregion + +#region Group management +#endregion + +#region Object management +#endregion + +#region Parcel management +#endregion + +#region Region management + private void XmlRpcRestartMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { Hashtable responseData = (Hashtable)response.Value; @@ -316,84 +1604,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController m_log.Info("[RADMIN]: Alert request complete"); } - private void XmlRpcLoadHeightmapMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) - { - m_log.Info("[RADMIN]: Load height maps request started"); - - Hashtable responseData = (Hashtable)response.Value; - 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); - // } - - CheckStringParameters(requestData, responseData, new string[] {"filename"}); - - Scene scene = null; - string error_message = String.Empty; - responseData["success"] = false; - - CheckRegionParamsInScene(requestData, out scene, out error_message); - - if (scene == null) - { - responseData["error"] = error_message; - throw new Exception(error_message); - } - - string file = (string) requestData["filename"]; - m_log.InfoFormat("[RADMIN]: Terrain Loading: {0}", file); - - responseData["accepted"] = true; - - LoadHeightmap(file, scene.RegionInfo.RegionID); - - responseData["success"] = true; - - m_log.Info("[RADMIN]: Load height maps request complete"); - } - - private void XmlRpcSaveHeightmapMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) - { - m_log.Info("[RADMIN]: Save height maps request started"); - - Hashtable responseData = (Hashtable)response.Value; - Hashtable requestData = (Hashtable)request.Params[0]; - -// m_log.DebugFormat("[RADMIN]: Save Terrain: XmlRpc {0}", request.ToString()); - - CheckStringParameters(requestData, responseData, new string[] { "filename" }); - - Scene scene = null; - string error_message = String.Empty; - responseData["success"] = false; - - CheckRegionParamsInScene(requestData, out scene, out error_message); - - if (scene == null) - { - responseData["error"] = error_message; - throw new Exception(error_message); - } - - string file = (string)requestData["filename"]; - m_log.InfoFormat("[RADMIN]: Terrain Saving: {0}", file); - - responseData["accepted"] = true; - - ITerrainModule terrainModule = scene.RequestModuleInterface<ITerrainModule>(); - if (null == terrainModule) throw new Exception("terrain module not available"); - - terrainModule.SaveToFile(file); - - responseData["success"] = true; - - m_log.Info("[RADMIN]: Save height maps request complete"); - } - private void XmlRpcShutdownMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { m_log.Info("[RADMIN]: Received Shutdown Administrator Request"); @@ -960,351 +2170,12 @@ namespace OpenSim.ApplicationPlugins.RemoteController responseData["region_name"] = scene.RegionInfo.RegionName; m_log.Info("[RADMIN]: ModifyRegion: request complete"); - } - } - - /// <summary> - /// Create a new user account. - /// <summary> - /// <param name="request">incoming XML RPC request</param> - /// <remarks> - /// XmlRpcCreateUserMethod takes the following XMLRPC - /// parameters - /// <list type="table"> - /// <listheader><term>parameter name</term><description>description</description></listheader> - /// <item><term>password</term> - /// <description>admin password as set in OpenSim.ini</description></item> - /// <item><term>user_firstname</term> - /// <description>avatar's first name</description></item> - /// <item><term>user_lastname</term> - /// <description>avatar's last name</description></item> - /// <item><term>user_password</term> - /// <description>avatar's password</description></item> - /// <item><term>user_email</term> - /// <description>email of the avatar's owner (optional)</description></item> - /// <item><term>start_region_x</term> - /// <description>avatar's start region coordinates, X value</description></item> - /// <item><term>start_region_y</term> - /// <description>avatar's start region coordinates, Y value</description></item> - /// </list> - /// - /// XmlRpcCreateUserMethod returns - /// <list type="table"> - /// <listheader><term>name</term><description>description</description></listheader> - /// <item><term>success</term> - /// <description>true or false</description></item> - /// <item><term>error</term> - /// <description>error message if success is false</description></item> - /// <item><term>avatar_uuid</term> - /// <description>UUID of the newly created avatar - /// account; UUID.Zero if failed. - /// </description></item> - /// </list> - /// </remarks> - private void XmlRpcCreateUserMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) - { - m_log.Info("[RADMIN]: CreateUser: new request"); - - Hashtable responseData = (Hashtable)response.Value; - Hashtable requestData = (Hashtable)request.Params[0]; - - lock (m_requestLock) - { - try - { - // check completeness - CheckStringParameters(requestData, responseData, new string[] - { - "user_firstname", - "user_lastname", "user_password", - }); - CheckIntegerParams(requestData, responseData, new string[] {"start_region_x", "start_region_y"}); - - // do the job - string firstName = (string) requestData["user_firstname"]; - string lastName = (string) requestData["user_lastname"]; - string password = (string) requestData["user_password"]; - - uint regionXLocation = Convert.ToUInt32((Int32) requestData["start_region_x"]); - uint regionYLocation = Convert.ToUInt32((Int32) requestData["start_region_y"]); - - string email = ""; // empty string for email - if (requestData.Contains("user_email")) - email = (string)requestData["user_email"]; - - Scene scene = m_application.SceneManager.CurrentOrFirstScene; - UUID scopeID = scene.RegionInfo.ScopeID; - - UserAccount account = CreateUser(scopeID, firstName, lastName, password, email); - - if (null == account) - throw new Exception(String.Format("failed to create new user {0} {1}", - firstName, lastName)); - - // Set home position - - 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}", firstName, lastName); - } - 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); - } - - // Establish the avatar's initial appearance - - UpdateUserAppearance(responseData, requestData, account.PrincipalID); - - responseData["success"] = true; - responseData["avatar_uuid"] = account.PrincipalID.ToString(); - - m_log.InfoFormat("[RADMIN]: CreateUser: User {0} {1} created, UUID {2}", firstName, lastName, account.PrincipalID); - } - catch (Exception e) - { - responseData["avatar_uuid"] = UUID.Zero.ToString(); - - throw e; - } - - m_log.Info("[RADMIN]: CreateUser: request complete"); - } - } - - /// <summary> - /// Check whether a certain user account exists. - /// <summary> - /// <param name="request">incoming XML RPC request</param> - /// <remarks> - /// XmlRpcUserExistsMethod takes the following XMLRPC - /// parameters - /// <list type="table"> - /// <listheader><term>parameter name</term><description>description</description></listheader> - /// <item><term>password</term> - /// <description>admin password as set in OpenSim.ini</description></item> - /// <item><term>user_firstname</term> - /// <description>avatar's first name</description></item> - /// <item><term>user_lastname</term> - /// <description>avatar's last name</description></item> - /// </list> - /// - /// XmlRpcCreateUserMethod returns - /// <list type="table"> - /// <listheader><term>name</term><description>description</description></listheader> - /// <item><term>user_firstname</term> - /// <description>avatar's first name</description></item> - /// <item><term>user_lastname</term> - /// <description>avatar's last name</description></item> - /// <item><term>user_lastlogin</term> - /// <description>avatar's last login time (secs since UNIX epoch)</description></item> - /// <item><term>success</term> - /// <description>true or false</description></item> - /// <item><term>error</term> - /// <description>error message if success is false</description></item> - /// </list> - /// </remarks> - private void XmlRpcUserExistsMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) - { - m_log.Info("[RADMIN]: UserExists: new request"); - - Hashtable responseData = (Hashtable)response.Value; - Hashtable requestData = (Hashtable)request.Params[0]; - - // check completeness - CheckStringParameters(requestData, responseData, new string[] {"user_firstname", "user_lastname"}); - - string firstName = (string) requestData["user_firstname"]; - string lastName = (string) requestData["user_lastname"]; - - responseData["user_firstname"] = firstName; - responseData["user_lastname"] = lastName; - - UUID scopeID = m_application.SceneManager.CurrentOrFirstScene.RegionInfo.ScopeID; - - UserAccount account = m_application.SceneManager.CurrentOrFirstScene.UserAccountService.GetUserAccount(scopeID, firstName, 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; - - responseData["success"] = true; - } - - m_log.Info("[RADMIN]: UserExists: request complete"); - } - - /// <summary> - /// Update a user account. - /// <summary> - /// <param name="request">incoming XML RPC request</param> - /// <remarks> - /// XmlRpcUpdateUserAccountMethod takes the following XMLRPC - /// parameters (changeable ones are optional) - /// <list type="table"> - /// <listheader><term>parameter name</term><description>description</description></listheader> - /// <item><term>password</term> - /// <description>admin password as set in OpenSim.ini</description></item> - /// <item><term>user_firstname</term> - /// <description>avatar's first name (cannot be changed)</description></item> - /// <item><term>user_lastname</term> - /// <description>avatar's last name (cannot be changed)</description></item> - /// <item><term>user_password</term> - /// <description>avatar's password (changeable)</description></item> - /// <item><term>start_region_x</term> - /// <description>avatar's start region coordinates, X - /// value (changeable)</description></item> - /// <item><term>start_region_y</term> - /// <description>avatar's start region coordinates, Y - /// value (changeable)</description></item> - /// <item><term>about_real_world (not implemented yet)</term> - /// <description>"about" text of avatar owner (changeable)</description></item> - /// <item><term>about_virtual_world (not implemented yet)</term> - /// <description>"about" text of avatar (changeable)</description></item> - /// </list> - /// - /// XmlRpcCreateUserMethod returns - /// <list type="table"> - /// <listheader><term>name</term><description>description</description></listheader> - /// <item><term>success</term> - /// <description>true or false</description></item> - /// <item><term>error</term> - /// <description>error message if success is false</description></item> - /// <item><term>avatar_uuid</term> - /// <description>UUID of the updated avatar - /// account; UUID.Zero if failed. - /// </description></item> - /// </list> - /// </remarks> - 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"); - - Hashtable responseData = (Hashtable)response.Value; - Hashtable requestData = (Hashtable)request.Params[0]; - - lock (m_requestLock) - { - try - { - // check completeness - CheckStringParameters(requestData, responseData, new string[] { - "user_firstname", - "user_lastname"}); - - // do the job - string firstName = (string) requestData["user_firstname"]; - string lastName = (string) requestData["user_lastname"]; - - string password = String.Empty; - uint? regionXLocation = null; - uint? regionYLocation = null; - // uint? ulaX = null; - // uint? ulaY = null; - // uint? ulaZ = null; - // uint? usaX = null; - // uint? usaY = null; - // uint? usaZ = null; - // string aboutFirstLive = String.Empty; - // string aboutAvatar = String.Empty; - - if (requestData.ContainsKey("user_password")) password = (string) requestData["user_password"]; - if (requestData.ContainsKey("start_region_x")) - regionXLocation = Convert.ToUInt32((Int32) requestData["start_region_x"]); - if (requestData.ContainsKey("start_region_y")) - regionYLocation = Convert.ToUInt32((Int32) requestData["start_region_y"]); - - // if (requestData.ContainsKey("start_lookat_x")) - // ulaX = Convert.ToUInt32((Int32) requestData["start_lookat_x"]); - // if (requestData.ContainsKey("start_lookat_y")) - // ulaY = Convert.ToUInt32((Int32) requestData["start_lookat_y"]); - // if (requestData.ContainsKey("start_lookat_z")) - // ulaZ = Convert.ToUInt32((Int32) requestData["start_lookat_z"]); - - // if (requestData.ContainsKey("start_standat_x")) - // usaX = Convert.ToUInt32((Int32) requestData["start_standat_x"]); - // if (requestData.ContainsKey("start_standat_y")) - // usaY = Convert.ToUInt32((Int32) requestData["start_standat_y"]); - // if (requestData.ContainsKey("start_standat_z")) - // usaZ = Convert.ToUInt32((Int32) requestData["start_standat_z"]); - // if (requestData.ContainsKey("about_real_world")) - // aboutFirstLive = (string)requestData["about_real_world"]; - // if (requestData.ContainsKey("about_virtual_world")) - // aboutAvatar = (string)requestData["about_virtual_world"]; - - Scene scene = m_application.SceneManager.CurrentOrFirstScene; - UUID scopeID = scene.RegionInfo.ScopeID; - UserAccount account = scene.UserAccountService.GetUserAccount(scopeID, firstName, lastName); - - if (null == account) - throw new Exception(String.Format("avatar {0} {1} does not exist", firstName, lastName)); - - if (!String.IsNullOrEmpty(password)) - { - m_log.DebugFormat("[RADMIN]: UpdateUserAccount: updating password for avatar {0} {1}", firstName, lastName); - ChangeUserPassword(firstName, lastName, password); - } - - // if (null != usaX) userProfile.HomeLocationX = (uint) usaX; - // if (null != usaY) userProfile.HomeLocationY = (uint) usaY; - // if (null != usaZ) userProfile.HomeLocationZ = (uint) usaZ; - - // if (null != ulaX) userProfile.HomeLookAtX = (uint) ulaX; - // if (null != ulaY) userProfile.HomeLookAtY = (uint) ulaY; - // if (null != ulaZ) userProfile.HomeLookAtZ = (uint) ulaZ; - - // if (String.Empty != aboutFirstLive) userProfile.FirstLifeAboutText = aboutFirstLive; - // if (String.Empty != aboutAvatar) userProfile.AboutText = aboutAvatar; - - // Set home position - - if ((null != regionXLocation) && (null != regionYLocation)) - { - 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 updated user account {0} {1}", firstName, lastName); - } 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); - } - } - - // User has been created. Now establish gender and appearance. - - UpdateUserAppearance(responseData, requestData, account.PrincipalID); - - responseData["success"] = true; - responseData["avatar_uuid"] = account.PrincipalID.ToString(); - - m_log.InfoFormat("[RADMIN]: UpdateUserAccount: account for user {0} {1} updated, UUID {2}", - firstName, lastName, - account.PrincipalID); - } - catch (Exception e) - { - responseData["avatar_uuid"] = UUID.Zero.ToString(); - - throw e; - } - - m_log.Info("[RADMIN]: UpdateUserAccount: request complete"); - } - } - + } + } + +#endregion + +#region Region file management /// <summary> /// Load an OAR file into a region.. /// <summary> @@ -1667,23 +2538,91 @@ namespace OpenSim.ApplicationPlugins.RemoteController int health = scene.GetHealth(); responseData["health"] = health; - m_log.Info("[RADMIN]: Query XML Administrator Request complete"); + m_log.Info("[RADMIN]: Query XML Administrator Request complete"); + } + + private void XmlRpcLoadHeightmapMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + { + m_log.Info("[RADMIN]: Load height maps request started"); + + Hashtable responseData = (Hashtable)response.Value; + 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); + // } + + CheckStringParameters(requestData, responseData, new string[] {"filename"}); + + Scene scene = null; + string error_message = String.Empty; + responseData["success"] = false; + + CheckRegionParamsInScene(requestData, out scene, out error_message); + + if (scene == null) + { + responseData["error"] = error_message; + throw new Exception(error_message); + } + + string file = (string) requestData["filename"]; + m_log.InfoFormat("[RADMIN]: Terrain Loading: {0}", file); + + responseData["accepted"] = true; + + LoadHeightmap(file, scene.RegionInfo.RegionID); + + responseData["success"] = true; + + m_log.Info("[RADMIN]: Load height maps request complete"); } - private void XmlRpcConsoleCommandMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + private void XmlRpcSaveHeightmapMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { - m_log.Info("[RADMIN]: Received Command XML Administrator Request"); + m_log.Info("[RADMIN]: Save height maps request started"); Hashtable responseData = (Hashtable)response.Value; Hashtable requestData = (Hashtable)request.Params[0]; - CheckStringParameters(requestData, responseData, new string[] {"command"}); +// m_log.DebugFormat("[RADMIN]: Save Terrain: XmlRpc {0}", request.ToString()); - MainConsole.Instance.RunCommand(requestData["command"].ToString()); + CheckStringParameters(requestData, responseData, new string[] { "filename" }); + + Scene scene = null; + string error_message = String.Empty; + responseData["success"] = false; + + CheckRegionParamsInScene(requestData, out scene, out error_message); + + if (scene == null) + { + responseData["error"] = error_message; + throw new Exception(error_message); + } + + string file = (string)requestData["filename"]; + m_log.InfoFormat("[RADMIN]: Terrain Saving: {0}", file); - m_log.Info("[RADMIN]: Command XML Administrator Request complete"); + responseData["accepted"] = true; + + ITerrainModule terrainModule = scene.RequestModuleInterface<ITerrainModule>(); + if (null == terrainModule) throw new Exception("terrain module not available"); + + terrainModule.SaveToFile(file); + + responseData["success"] = true; + + m_log.Info("[RADMIN]: Save height maps request complete"); } +#endregion + +#region Estate management + private void XmlRpcAccessListClear(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { m_log.Info("[RADMIN]: Received Access List Clear Request"); @@ -1860,64 +2799,31 @@ namespace OpenSim.ApplicationPlugins.RemoteController responseData["users"] = users; responseData["success"] = true; - m_log.Info("[RADMIN]: Access List List Request complete"); - } - - private void XmlRpcTeleportAgentMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) + m_log.Info("[RADMIN]: Access List List Request complete"); + } + +#endregion + +#region Administration + + private void XmlRpcConsoleCommandMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient) { + m_log.Info("[RADMIN]: Received Command XML Administrator Request"); + Hashtable responseData = (Hashtable)response.Value; Hashtable requestData = (Hashtable)request.Params[0]; - UUID agentId; - string regionName = null; - Vector3 pos, lookAt; - ScenePresence sp = null; - - 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); - - 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"]; - - if (!UUID.TryParse(rawAgentId, out agentId)) - throw new Exception(string.Format("agent_id {0} does not have the correct id format", rawAgentId)); - - m_application.SceneManager.TryGetRootScenePresence(agentId, out sp); - - 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"); - } - - 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); + CheckStringParameters(requestData, responseData, new string[] {"command"}); - // We have no way of telling the failure of the actual teleport - responseData["success"] = true; - } + MainConsole.Instance.RunCommand(requestData["command"].ToString()); + m_log.Info("[RADMIN]: Command XML Administrator Request complete"); + } + +#endregion + +#region Parameter functions + /// <summary> /// Parse a float with the given parameter name from a request data hash table. /// </summary> @@ -2082,125 +2988,13 @@ namespace OpenSim.ApplicationPlugins.RemoteController private string GetStringAttribute(XmlNode node, string attribute, string defaultValue) { try { return node.Attributes[attribute].Value; } catch{} - return defaultValue; - } - - public void Dispose() - { - } - - /// <summary> - /// Create a user - /// </summary> - /// <param name="scopeID"></param> - /// <param name="firstName"></param> - /// <param name="lastName"></param> - /// <param name="password"></param> - /// <param name="email"></param> - 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; - - 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<string, object>(); - account.ServiceURLs["HomeURI"] = string.Empty; - account.ServiceURLs["GatekeeperURI"] = string.Empty; - account.ServiceURLs["InventoryServerURI"] = string.Empty; - account.ServiceURLs["AssetServerURI"] = string.Empty; - } - - if (userAccountService.StoreUserAccount(account)) - { - bool success; - if (authenticationService != null) - { - success = authenticationService.SetPassword(account.PrincipalID, password); - if (!success) - m_log.WarnFormat("[RADMIN]: Unable to set password for account {0} {1}.", - firstName, lastName); - } - - GridRegion home = null; - if (gridService != null) - { - List<GridRegion> defaultRegions = gridService.GetDefaultRegions(UUID.Zero); - if (defaultRegions != null && defaultRegions.Count >= 1) - home = defaultRegions[0]; - - 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); - - if (inventoryService != null) - { - success = inventoryService.CreateUserInventory(account.PrincipalID); - if (!success) - m_log.WarnFormat("[RADMIN]: Unable to create inventory for account {0} {1}.", - firstName, lastName); - } - - 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; - } - - /// <summary> - /// Change password - /// </summary> - /// <param name="firstName"></param> - /// <param name="lastName"></param> - /// <param name="password"></param> - private bool ChangeUserPassword(string firstName, string lastName, string password) - { - Scene scene = m_application.SceneManager.CurrentOrFirstScene; - IUserAccountService userAccountService = scene.UserAccountService; - IAuthenticationService authenticationService = scene.AuthenticationService; - - UserAccount account = userAccountService.GetUserAccount(UUID.Zero, firstName, lastName); - if (null != account) - { - bool success = false; - if (authenticationService != null) - success = authenticationService.SetPassword(account.PrincipalID, password); - - 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; - } - } + return defaultValue; + } + +#endregion + +#region General function used in multiple command groups + //Here all functions get listed which are used in multiple command groups private bool LoadHeightmap(string file, UUID regionID) { @@ -2236,752 +3030,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController return true; } - - - /// <summary> - /// 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. - /// </summary> - private void UpdateUserAppearance(Hashtable responseData, Hashtable requestData, UUID userid) - { - 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; - - // Has a gender preference been supplied? - - if (requestData.Contains("gender")) - { - switch ((string)requestData["gender"]) - { - case "m" : - case "male" : - model = defaultMale; - break; - case "f" : - case "female" : - model = defaultFemale; - break; - case "n" : - case "neutral" : - default : - model = defaultNeutral; - break; - } - } - - // Has an explicit model been specified? - - if (requestData.Contains("model") && (String.IsNullOrEmpty((string)requestData["gender"]))) - { - model = (string)requestData["model"]; - } - - // No appearance attributes were set - - if (String.IsNullOrEmpty(model)) - { - m_log.DebugFormat("[RADMIN]: Appearance update not requested"); - return; - } - - m_log.DebugFormat("[RADMIN]: Setting appearance for avatar {0}, using model <{1}>", userid, model); - - 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; - } - - // 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); - } - - /// <summary> - /// 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. - /// </summary> - private void EstablishAppearance(UUID destination, UUID source) - { - 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; - - // Simple appearance copy or copy Clothing and Bodyparts folders? - bool copyFolders = m_config.GetBoolean("copy_folders", false); - - if (!copyFolders) - { - // Simple copy of wearables and appearance update - try - { - CopyWearablesAndAttachments(destination, source, avatarAppearance); - - scene.AvatarService.SetAppearance(destination, avatarAppearance); - } - catch (Exception e) - { - m_log.WarnFormat("[RADMIN]: Error transferring appearance for {0} : {1}", - destination, e.Message); - } - - return; - } - - // Copy Clothing and Bodypart folders and appearance update - try - { - Dictionary<UUID,UUID> inventoryMap = new Dictionary<UUID,UUID>(); - CopyInventoryFolders(destination, source, AssetType.Clothing, inventoryMap, avatarAppearance); - CopyInventoryFolders(destination, source, AssetType.Bodypart, inventoryMap, avatarAppearance); - - AvatarWearable[] wearables = avatarAppearance.Wearables; - - for (int i=0; i<wearables.Length; i++) - { - if (inventoryMap.ContainsKey(wearables[i][0].ItemID)) - { - AvatarWearable wearable = new AvatarWearable(); - wearable.Wear(inventoryMap[wearables[i][0].ItemID], - wearables[i][0].AssetID); - avatarAppearance.SetWearable(i, wearable); - } - } - - scene.AvatarService.SetAppearance(destination, avatarAppearance); - } - catch (Exception e) - { - m_log.WarnFormat("[RADMIN]: Error transferring appearance for {0} : {1}", - destination, e.Message); - } - - return; - } - - /// <summary> - /// 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. - /// </summary> - private void CopyWearablesAndAttachments(UUID destination, UUID source, AvatarAppearance avatarAppearance) - { - 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)"); - - // 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); - } - - // Wearables - AvatarWearable[] wearables = avatarAppearance.Wearables; - AvatarWearable wearable; - - for (int i = 0; i<wearables.Length; i++) - { - wearable = wearables[i]; - if (wearable[0].ItemID != UUID.Zero) - { - // Get inventory item and copy it - InventoryItemBase item = new InventoryItemBase(wearable[0].ItemID, source); - item = inventoryService.GetItem(item); - - if (item != null) - { - 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); - } - else - { - m_log.WarnFormat("[RADMIN]: Error transferring {0} to folder {1}", wearable[0].ItemID, destinationFolder.ID); - } - } - } - - // Attachments - List<AvatarAttachment> attachments = avatarAppearance.GetAttachments(); - - foreach (AvatarAttachment attachment in attachments) - { - int attachpoint = attachment.AttachPoint; - UUID itemID = attachment.ItemID; - - if (itemID != UUID.Zero) - { - // Get inventory item and copy it - InventoryItemBase item = new InventoryItemBase(itemID, source); - item = inventoryService.GetItem(item); - - if (item != null) - { - 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); - } - else - { - m_log.WarnFormat("[RADMIN]: Error transferring {0} to folder {1}", itemID, destinationFolder.ID); - } - } - } - } - - /// <summary> - /// This method is called by establishAppearance to copy inventory folders to make - /// copies of Clothing and Bodyparts inventory folders and attaches worn attachments - /// </summary> - private void CopyInventoryFolders(UUID destination, UUID source, AssetType assetType, Dictionary<UUID,UUID> inventoryMap, - AvatarAppearance avatarAppearance) - { - IInventoryService inventoryService = m_application.SceneManager.CurrentOrFirstScene.InventoryService; - - InventoryFolderBase sourceFolder = inventoryService.GetFolderForType(source, assetType); - InventoryFolderBase destinationFolder = inventoryService.GetFolderForType(destination, assetType); - - if (sourceFolder == null || destinationFolder == null) - throw new Exception("Cannot locate folder(s)"); - - // 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"; - } - 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) - { - destinationFolder.Name = "Clothing"; - } - else - { - destinationFolder.Name = "Body Parts"; - } - 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<InventoryFolderBase> 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); - - m_log.DebugFormat("[RADMIN]: Added folder {0} to folder {1}", extraFolder.ID, sourceFolder.ID); - - List<InventoryItemBase> items = inventoryService.GetFolderContent(source, folder.ID).Items; - - foreach (InventoryItemBase item in items) - { - 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.CurrentOrFirstScene.AddInventoryItem(destinationItem); - inventoryMap.Add(item.ID, destinationItem.ID); - m_log.DebugFormat("[RADMIN]: Added item {0} to folder {1}", destinationItem.ID, extraFolder.ID); - - // 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); - } - } - } - } - - /// <summary> - /// Apply next owner permissions. - /// </summary> - private void ApplyNextOwnerPermissions(InventoryItemBase item) - { - if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) - { - 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; - } - - /// <summary> - /// 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. - /// </summary> - private bool CreateDefaultAvatars() - { - // Only load once - if (m_defaultAvatarsLoaded) - { - return false; - } - - m_log.DebugFormat("[RADMIN]: Creating default avatar entries"); - - m_defaultAvatarsLoaded = true; - - // Load processing starts here... - - try - { - string defaultAppearanceFileName = null; - - //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"); - } - - 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; - - Scene scene = m_application.SceneManager.CurrentOrFirstScene; - IInventoryService inventoryService = scene.InventoryService; - IAssetService assetService = scene.AssetService; - - doc.LoadXml(File.ReadAllText(defaultAppearanceFileName)); - - // 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); - } - - avatars = doc.GetElementsByTagName("Avatar"); - - // The document may contain multiple avatars - - foreach (XmlElement avatar in avatars) - { - m_log.DebugFormat("[RADMIN]: Loading appearance for {0}, gender = {1}", - GetStringAttribute(avatar,"name","?"), GetStringAttribute(avatar,"gender","?")); - - // Create the user identified by the avatar entry - - 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); - - 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; - } - } - - // Set home position - - 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]); - } - - ID = account.PrincipalID; - - 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; - } - - // 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 (include) - { - // Setup for appearance processing - avatarAppearance = scene.AvatarService.GetAppearance(ID); - if (avatarAppearance == null) - avatarAppearance = new AvatarAppearance(); - - AvatarWearable[] wearables = avatarAppearance.Wearables; - for (int i=0; i<wearables.Length; i++) - { - wearables[i] = new AvatarWearable(); - } - - 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<InventoryFolderBase> 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<InventoryItemBase> 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 - { - 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; - } - - return true; - } + +#endregion } } | |||||||||
![]() |
|
(0020559) justincc (administrator) 2011-12-16 16:48 |
Looks fine to me, though I think in OpenSim we usually indent #region directives to the same level as the class. I'm assuming this relies on the application of http://opensimulator.org/mantis/view.php?id=5814 [^] |
(0020560) Michelle Argus (reporter) 2011-12-16 17:34 |
yes, it relies on the other mantis. i can change the #region to the same level... i chose it diffrently because its easier when scrolling through the code. But if its standard in OS, then i will change it when i update the patch... |
(0020635) justincc (administrator) 2012-01-06 15:05 |
Current patch no longer applies due to other changes. |
![]() |
|||
Date Modified | Username | Field | Change |
2011-12-15 06:37 | Michelle Argus | New Issue | |
2011-12-15 06:37 | Michelle Argus | File Added: 001-[Patch] RemoteAdmin-Proposal-to.reorganise-commands-and-functions.patch | |
2011-12-15 06:38 | Michelle Argus | Status | new => patch feedback |
2011-12-16 16:48 | justincc | Note Added: 0020559 | |
2011-12-16 17:34 | Michelle Argus | Note Added: 0020560 | |
2012-01-06 15:05 | justincc | Note Added: 0020635 |
Copyright © 2000 - 2012 MantisBT Group |