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)