diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 2c1568690c..3f2a052e7c 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -134,16 +134,22 @@ namespace OpenSim.ApplicationPlugins.RemoteController availableMethods["admin_restart"] = XmlRpcRestartMethod; availableMethods["admin_load_heightmap"] = XmlRpcLoadHeightmapMethod; availableMethods["admin_save_heightmap"] = XmlRpcSaveHeightmapMethod; + + // Agent management + availableMethods["admin_teleport_agent"] = XmlRpcTeleportAgentMethod; + // User management availableMethods["admin_create_user"] = XmlRpcCreateUserMethod; availableMethods["admin_create_user_email"] = XmlRpcCreateUserMethod; availableMethods["admin_exists_user"] = XmlRpcUserExistsMethod; availableMethods["admin_update_user"] = XmlRpcUpdateUserAccountMethod; + // Region state management availableMethods["admin_load_xml"] = XmlRpcLoadXMLMethod; availableMethods["admin_save_xml"] = XmlRpcSaveXMLMethod; availableMethods["admin_load_oar"] = XmlRpcLoadOARMethod; availableMethods["admin_save_oar"] = XmlRpcSaveOARMethod; + // Estate access list management availableMethods["admin_acl_clear"] = XmlRpcAccessListClear; availableMethods["admin_acl_add"] = XmlRpcAccessListAdd; @@ -2965,6 +2971,112 @@ namespace OpenSim.ApplicationPlugins.RemoteController return response; } + public XmlRpcResponse XmlRpcTeleportAgentMethod(XmlRpcRequest request, IPEndPoint remoteClient) + { + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable responseData = new Hashtable(); + + try + { + responseData["success"] = true; + + Hashtable requestData = (Hashtable)request.Params[0]; + + CheckStringParameters(request, new string[] {"password"}); + + FailIfRemoteAdminNotAllowed((string)requestData["password"], remoteClient.Address.ToString()); + + UUID agentId; + string regionName = null; + Vector3 pos, lookAt; + bool agentSpecified = false; + 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); + } + catch (Exception e) + { + m_log.ErrorFormat("[RADMIN]: admin_teleport_agent exception: {0}{1}", e.Message, e.StackTrace); + + responseData["success"] = false; + responseData["error"] = e.Message; + } + finally + { + response.Value = responseData; + } + + return response; + } + + /// + /// Parse a float with the given parameter name from a request data hash table. + /// + /// + /// Will throw an exception if parameter is not a float. + /// Will not throw if parameter is not found, passes back default value instead. + /// + /// + /// + /// + /// + private static float ParseFloat(Hashtable requestData, string paramName, float defaultVal) + { + if (requestData.Contains(paramName)) + { + string rawVal = (string)requestData[paramName]; + float val; + + if (!float.TryParse(rawVal, out val)) + throw new Exception(string.Format("{0} {1} is not a valid float", paramName, rawVal)); + else + return val; + } + else + { + return defaultVal; + } + } + private static void CheckStringParameters(XmlRpcRequest request, string[] param) { Hashtable requestData = (Hashtable) request.Params[0]; @@ -3144,6 +3256,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController return false; } } + private bool LoadHeightmap(string file, UUID regionID) { m_log.InfoFormat("[RADMIN]: Terrain Loading: {0}", file); diff --git a/OpenSim/Framework/IScene.cs b/OpenSim/Framework/IScene.cs index 76b731f0f3..7b0fe374c7 100644 --- a/OpenSim/Framework/IScene.cs +++ b/OpenSim/Framework/IScene.cs @@ -90,9 +90,9 @@ namespace OpenSim.Framework /// /// Is the agent denoted by the given agentID a child presence in this scene? /// - /// + /// /// Used by ClientView when a 'kick everyone' or 'estate message' occurs - /// + /// /// AvatarID to lookup /// true if the presence is a child agent, false if the presence is a root exception /// diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 04eca3302f..17aca6592f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -4208,7 +4208,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void ForEachRootScenePresence(Action action) { - if(m_sceneGraph != null) + if (m_sceneGraph != null) { m_sceneGraph.ForEachRootScenePresence(action); } @@ -4307,9 +4307,9 @@ namespace OpenSim.Region.Framework.Scenes return m_sceneGraph.GetGroupByPrim(localID); } - public override bool TryGetScenePresence(UUID avatarId, out ScenePresence avatar) + public override bool TryGetScenePresence(UUID agentID, out ScenePresence sp) { - return m_sceneGraph.TryGetScenePresence(avatarId, out avatar); + return m_sceneGraph.TryGetScenePresence(agentID, out sp); } public bool TryGetAvatarByName(string avatarName, out ScenePresence avatar) diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs index c5ec169cb1..5f934201f6 100644 --- a/OpenSim/Region/Framework/Scenes/SceneBase.cs +++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs @@ -191,6 +191,12 @@ namespace OpenSim.Region.Framework.Scenes return false; } + /// + /// Try to get a scene presence from the scene + /// + /// + /// null if there is no scene presence with the given agent id + /// true if there was a scene presence with the given id, false otherwise. public abstract bool TryGetScenePresence(UUID agentID, out ScenePresence scenePresence); #endregion diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs index 82458e2acf..04912056d9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneManager.cs +++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs @@ -545,6 +545,23 @@ namespace OpenSim.Region.Framework.Scenes return false; } + public bool TryGetRootScenePresence(UUID avatarId, out ScenePresence avatar) + { + lock (m_localScenes) + { + foreach (Scene scene in m_localScenes) + { + avatar = scene.GetScenePresence(avatarId); + + if (avatar != null && !avatar.IsChildAgent) + return true; + } + } + + avatar = null; + return false; + } + public bool TryGetAvatarsScene(UUID avatarId, out Scene scene) { ScenePresence avatar = null; @@ -590,6 +607,22 @@ namespace OpenSim.Region.Framework.Scenes return false; } + public bool TryGetRootScenePresenceByName(string firstName, string lastName, out ScenePresence sp) + { + lock (m_localScenes) + { + foreach (Scene scene in m_localScenes) + { + sp = scene.GetScenePresence(firstName, lastName); + if (sp != null && !sp.IsChildAgent) + return true; + } + } + + sp = null; + return false; + } + public void ForEachScene(Action action) { lock (m_localScenes)