From: Dr Scofield <hud@zurich.ibm.com>

the attached patch set is centered around RemoteAdminPlugin and focuses
mainly on making it more robust (i.e. more parameter checking and better
error reporting) but also we've re-implemented the LoadTerrain stuff that
got disabled during the terrain code reworking:

   * missing PostInitialize() calls on region modules that were loaded
     for regions created via RemoteAdmin's CreateRegion XmlRpc call
   * re-implements RemoteAdmin's LoadTerrain XmlRpc call (probably lost
     during the TerrainModule rework)
   * adds lots more parameter checking and error reporting to RemoteAdmin
   * adds a read-only property to RegionApplicationBase so that we can
     access the CommsManager
   * adds Exceptions to TerrainModule so that we get better error case
     feedback (and can report more meaningful errors in turn)
   * adds a CheckForTerrainUpdate() call to
     TerrainModule.LoadFromFile() to make terrain changes effective
   * adds TryGetCurrentScene(LLUUID) to SceneManager so that we can
     retrieve Scenes not only by name but also by LLUUID


   cheers,
   dr scofield
0.6.0-stable
Sean Dague 2008-04-21 12:42:56 +00:00
parent a0b8c46ef3
commit bf1580fba4
8 changed files with 170 additions and 68 deletions

View File

@ -38,6 +38,7 @@ using Nwc.XmlRpc;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Servers; using OpenSim.Framework.Servers;
using OpenSim.Region.Environment.Scenes; using OpenSim.Region.Environment.Scenes;
using OpenSim.Region.Environment.Modules.Terrain;
[assembly : Addin] [assembly : Addin]
[assembly : AddinDependency("OpenSim", "0.5")] [assembly : AddinDependency("OpenSim", "0.5")]
@ -88,6 +89,9 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
LLUUID regionID = new LLUUID((string) requestData["regionID"]); LLUUID regionID = new LLUUID((string) requestData["regionID"]);
Hashtable responseData = new Hashtable(); Hashtable responseData = new Hashtable();
m_log.Info("[RADMIN]: Request to restart Region.");
if (requiredPassword != String.Empty && if (requiredPassword != String.Empty &&
(!requestData.Contains("password") || (string) requestData["password"] != requiredPassword)) (!requestData.Contains("password") || (string) requestData["password"] != requiredPassword))
{ {
@ -119,24 +123,30 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
{ {
XmlRpcResponse response = new XmlRpcResponse(); XmlRpcResponse response = new XmlRpcResponse();
Hashtable requestData = (Hashtable) request.Params[0]; Hashtable requestData = (Hashtable) request.Params[0];
Hashtable responseData = new Hashtable(); Hashtable responseData = new Hashtable();
try {
checkStringParameters(request, new string[] { "password", "message" });
if (requiredPassword != String.Empty && if (requiredPassword != String.Empty &&
(!requestData.Contains("password") || (string) requestData["password"] != requiredPassword)) (!requestData.Contains("password") || (string) requestData["password"] != requiredPassword))
{ throw new Exception("wrong password");
responseData["accepted"] = "false";
response.Value = responseData;
}
else
{
string message = (string) requestData["message"]; string message = (string) requestData["message"];
m_log.Info("[RADMIN]: Broadcasting: " + message); m_log.InfoFormat("[RADMIN]: Broadcasting: {0}", message);
responseData["accepted"] = "true"; responseData["accepted"] = "true";
response.Value = responseData; response.Value = responseData;
m_app.SceneManager.SendGeneralMessage(message); m_app.SceneManager.SendGeneralMessage(message);
} }
catch(Exception e)
{
m_log.ErrorFormat("[RADMIN]: Broadcasting: failed: {0}", e.Message);
m_log.DebugFormat("[RADMIN]: Broadcasting: failed: {0}", e.ToString());
responseData["accepted"] = "false";
response.Value = responseData;
}
return response; return response;
} }
@ -146,35 +156,48 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
XmlRpcResponse response = new XmlRpcResponse(); XmlRpcResponse response = new XmlRpcResponse();
Hashtable requestData = (Hashtable)request.Params[0]; Hashtable requestData = (Hashtable)request.Params[0];
m_log.DebugFormat("[RADMIN]: Load Terrain: XmlRpc {0}", request.ToString());
foreach (string k in requestData.Keys)
{
m_log.DebugFormat("[RADMIN]: Load Terrain: XmlRpc {0}: >{1}< {2}",
k, (string)requestData[k], ((string)requestData[k]).Length);
}
Hashtable responseData = new Hashtable(); Hashtable responseData = new Hashtable();
try {
checkStringParameters(request, new string[] { "password", "filename", "regionid"});
if (requiredPassword != String.Empty && if (requiredPassword != String.Empty &&
(!requestData.Contains("password") || (string)requestData["password"] != requiredPassword)) (!requestData.Contains("password") || (string)requestData["password"] != requiredPassword))
{ throw new Exception("wrong password");
responseData["accepted"] = "false";
response.Value = responseData;
}
else
{
string file = (string)requestData["filename"]; string file = (string)requestData["filename"];
LLUUID regionID = LLUUID.Parse((string)requestData["regionid"]); LLUUID regionID = (string) requestData["regionid"];
m_log.Info("[RADMIN]: Terrain Loading: " + file); m_log.InfoFormat("[RADMIN]: Terrain Loading: {0}", file);
responseData["accepted"] = "true"; responseData["accepted"] = "true";
Scene region = null; Scene region = null;
if (m_app.SceneManager.TryGetScene(regionID, out region)) if (!m_app.SceneManager.TryGetScene(regionID, out region))
{ throw new Exception("1: unable to get a scene with that name");
//region.LoadWorldMap(file);
ITerrainModule terrainModule = region.RequestModuleInterface<ITerrainModule>();
if (null == terrainModule) throw new Exception("terrain module not available");
terrainModule.LoadFromFile(file);
responseData["success"] = "true"; responseData["success"] = "true";
}
else
{
responseData["success"] = "false";
responseData["error"] = "1: Unable to get a scene with that name.";
}
response.Value = responseData; response.Value = responseData;
} }
catch (Exception e)
{
m_log.ErrorFormat("[RADMIN] Terrain Loading: failed: {0}", e.Message);
m_log.DebugFormat("[RADMIN] Terrain Loading: failed: {0}", e.ToString());
responseData["success"] = "false";
responseData["error"] = e.Message;
}
return response; return response;
} }
@ -185,21 +208,21 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
XmlRpcResponse response = new XmlRpcResponse(); XmlRpcResponse response = new XmlRpcResponse();
Hashtable requestData = (Hashtable) request.Params[0]; Hashtable requestData = (Hashtable) request.Params[0];
Hashtable responseData = new Hashtable(); Hashtable responseData = new Hashtable();
try {
checkStringParameters(request, new string[] { "password", "shutdown" });
checkIntegerParams(request, new string[] { "milliseconds"});
if (requiredPassword != String.Empty && if (requiredPassword != String.Empty &&
(!requestData.Contains("password") || (string) requestData["password"] != requiredPassword)) (!requestData.Contains("password") || (string) requestData["password"] != requiredPassword))
{ throw new Exception("wrong password");
responseData["accepted"] = "false";
response.Value = responseData;
}
else
{
if ((string) requestData["shutdown"] == "delayed")
{
int timeout = (Int32) requestData["milliseconds"];
responseData["accepted"] = "true"; responseData["accepted"] = "true";
response.Value = responseData; response.Value = responseData;
if ((string) requestData["shutdown"] == "delayed")
{
int timeout = (Int32) requestData["milliseconds"];
m_app.SceneManager.SendGeneralMessage("Region is going down in " + ((int) (timeout/1000)).ToString() + m_app.SceneManager.SendGeneralMessage("Region is going down in " + ((int) (timeout/1000)).ToString() +
" second(s). Please save what you are doing and log out."); " second(s). Please save what you are doing and log out.");
@ -208,14 +231,9 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
shutdownTimer.AutoReset = false; shutdownTimer.AutoReset = false;
shutdownTimer.Elapsed += new ElapsedEventHandler(shutdownTimer_Elapsed); shutdownTimer.Elapsed += new ElapsedEventHandler(shutdownTimer_Elapsed);
shutdownTimer.Start(); shutdownTimer.Start();
return response;
} }
else else
{ {
responseData["accepted"] = "true";
response.Value = responseData;
m_app.SceneManager.SendGeneralMessage("Region is going down now."); m_app.SceneManager.SendGeneralMessage("Region is going down now.");
// Perform shutdown // Perform shutdown
@ -223,10 +241,18 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
shutdownTimer.AutoReset = false; shutdownTimer.AutoReset = false;
shutdownTimer.Elapsed += new ElapsedEventHandler(shutdownTimer_Elapsed); shutdownTimer.Elapsed += new ElapsedEventHandler(shutdownTimer_Elapsed);
shutdownTimer.Start(); shutdownTimer.Start();
return response;
} }
} }
catch (Exception e)
{
m_log.ErrorFormat("[RADMIN] Shutdown: failed: {0}", e.Message);
m_log.DebugFormat("[RADMIN] Shutdown: failed: {0}", e.ToString());
responseData["accepted"] = "false";
responseData["error"] = e.Message;
response.Value = responseData;
}
return response; return response;
} }
@ -401,7 +427,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
region.SaveRegionToFile("dynamic region", regionConfigPath); region.SaveRegionToFile("dynamic region", regionConfigPath);
} }
m_app.CreateRegion(region, true); m_app.CreateRegion(region);
responseData["success"] = "true"; responseData["success"] = "true";
responseData["region_name"] = region.RegionName; responseData["region_name"] = region.RegionName;
@ -484,8 +510,10 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
uint regX = Convert.ToUInt32((Int32)requestData["start_region_x"]); uint regX = Convert.ToUInt32((Int32)requestData["start_region_x"]);
uint regY = Convert.ToUInt32((Int32)requestData["start_region_y"]); uint regY = Convert.ToUInt32((Int32)requestData["start_region_y"]);
// FIXME: need to check whether "firstname lastname" UserProfileData userProfile = m_app.CommunicationsManager.UserService.GetUserProfile(firstname, lastname);
// already exists! if (null != userProfile)
throw new Exception(String.Format("avatar {0} {1} already exists", firstname, lastname));
LLUUID userID = m_app.CreateUser(firstname, lastname, passwd, regX, regY); LLUUID userID = m_app.CreateUser(firstname, lastname, passwd, regX, regY);
if (userID == LLUUID.Zero) throw new Exception(String.Format("failed to create new user {0} {1}", if (userID == LLUUID.Zero) throw new Exception(String.Format("failed to create new user {0} {1}",
@ -523,22 +551,34 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
try try
{ {
// check completeness // check completeness
foreach (string p in new string[] { "password", "region_name", "filename" }) foreach (string p in new string[] { "password", "filename" })
{ {
if (!requestData.Contains(p)) if (!requestData.Contains(p))
throw new Exception(String.Format("missing parameter {0}", p)); throw new Exception(String.Format("missing parameter {0}", p));
if (String.IsNullOrEmpty((string)requestData[p]))
throw new Exception(String.Format("parameter {0} is empty"));
} }
// check password // check password
if (!String.IsNullOrEmpty(requiredPassword) && if (!String.IsNullOrEmpty(requiredPassword) &&
(string)requestData["password"] != requiredPassword) throw new Exception("wrong password"); (string)requestData["password"] != requiredPassword) throw new Exception("wrong password");
string region_name = (string)requestData["region_name"];
string filename = (string)requestData["filename"]; string filename = (string)requestData["filename"];
if (requestData.Contains("region_uuid"))
{
LLUUID region_uuid = (string)requestData["region_uuid"];
if (!m_app.SceneManager.TrySetCurrentScene(region_uuid))
throw new Exception(String.Format("failed to switch to region {0}", region_uuid.ToString()));
m_log.InfoFormat("[RADMIN] Switched to region {0}", region_uuid.ToString());
}
else if (requestData.Contains("region_name"))
{
string region_name = (string)requestData["region_name"];
if (!m_app.SceneManager.TrySetCurrentScene(region_name)) if (!m_app.SceneManager.TrySetCurrentScene(region_name))
throw new Exception(String.Format("failed to switch to region {0}", region_name)); throw new Exception(String.Format("failed to switch to region {0}", region_name));
m_log.InfoFormat("[RADMIN] Switched to region {0}"); m_log.InfoFormat("[RADMIN] Switched to region {0}", region_name);
}
else throw new Exception("neither region_name nor region_uuid given");
responseData["switched"] = "true"; responseData["switched"] = "true";
@ -550,7 +590,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
catch (Exception e) catch (Exception e)
{ {
m_log.InfoFormat("[RADMIN] LoadXml: {0}", e.Message); m_log.InfoFormat("[RADMIN] LoadXml: {0}", e.Message);
m_log.DebugFormat("[RADMIN] LoadXML {0}: {1}", e.ToString()); m_log.DebugFormat("[RADMIN] LoadXml: {0}", e.ToString());
responseData["loaded"] = "false"; responseData["loaded"] = "false";
responseData["switched"] = "false"; responseData["switched"] = "false";

View File

@ -44,6 +44,10 @@ namespace OpenSim.Region.Capabilities
private uint m_httpListenerPort; private uint m_httpListenerPort;
/// <summary></summary> /// <summary></summary>
/// CapsHandlers is a cap handler container but also takes
/// care of adding and removing cap handlers to and from the
/// supplied BaseHttpServer.
/// </summary>
/// <param name="httpListener">base HTTP server</param> /// <param name="httpListener">base HTTP server</param>
/// <param name="httpListenerHostname">host name of the HTTP /// <param name="httpListenerHostname">host name of the HTTP
/// server</param> /// server</param>

View File

@ -462,7 +462,28 @@ namespace OpenSim
/// <param name="regionInfo"></param> /// <param name="regionInfo"></param>
/// <param name="portadd_flag"></param> /// <param name="portadd_flag"></param>
/// <returns></returns> /// <returns></returns>
public UDPServer CreateRegion(RegionInfo regionInfo, bool portadd_flag) public UDPServer CreateRegion(RegionInfo regionInfo, bool portadd_flag) {
return CreateRegion(regionInfo, portadd_flag, false);
}
/// <summary>
/// Execute the region creation process. This includes setting up scene infrastructure.
/// </summary>
/// <param name="regionInfo"></param>
/// <param name="portadd_flag"></param>
/// <returns></returns>
public UDPServer CreateRegion(RegionInfo regionInfo) {
return CreateRegion(regionInfo, false, true);
}
/// <summary>
/// Execute the region creation process. This includes setting up scene infrastructure.
/// </summary>
/// <param name="regionInfo"></param>
/// <param name="portadd_flag"></param>
/// <param name="do_post_init"></param>
/// <returns></returns>
public UDPServer CreateRegion(RegionInfo regionInfo, bool portadd_flag, bool do_post_init)
{ {
int port = regionInfo.InternalEndPoint.Port; int port = regionInfo.InternalEndPoint.Port;
@ -487,7 +508,7 @@ namespace OpenSim
m_log.Info("[MODULES]: Loading Region's modules"); m_log.Info("[MODULES]: Loading Region's modules");
m_moduleLoader.PickupModules(scene, "."); List<IRegionModule> modules = m_moduleLoader.PickupModules(scene, ".");
//m_moduleLoader.PickupModules(scene, "ScriptEngines"); //m_moduleLoader.PickupModules(scene, "ScriptEngines");
//m_moduleLoader.LoadRegionModules(Path.Combine("ScriptEngines", m_scriptEngine), scene); //m_moduleLoader.LoadRegionModules(Path.Combine("ScriptEngines", m_scriptEngine), scene);
@ -536,6 +557,14 @@ namespace OpenSim
m_regionData.Add(regionInfo); m_regionData.Add(regionInfo);
udpServer.ServerListener(); udpServer.ServerListener();
if (do_post_init)
{
foreach (IRegionModule module in modules)
{
module.PostInitialise();
}
}
return udpServer; return udpServer;
} }

View File

@ -54,6 +54,9 @@ namespace OpenSim.Region.ClientStack
protected uint m_httpServerPort; protected uint m_httpServerPort;
protected CommunicationsManager m_commsManager; protected CommunicationsManager m_commsManager;
public CommunicationsManager CommunicationsManager {
get { return m_commsManager; }
}
protected SceneManager m_sceneManager = new SceneManager(); protected SceneManager m_sceneManager = new SceneManager();

View File

@ -62,14 +62,16 @@ namespace OpenSim.Region.Environment
} }
} }
public void PickupModules(Scene scene, string moduleDir) public List<IRegionModule> PickupModules(Scene scene, string moduleDir)
{ {
DirectoryInfo dir = new DirectoryInfo(moduleDir); DirectoryInfo dir = new DirectoryInfo(moduleDir);
List<IRegionModule> modules = new List<IRegionModule>();
foreach (FileInfo fileInfo in dir.GetFiles("*.dll")) foreach (FileInfo fileInfo in dir.GetFiles("*.dll"))
{ {
LoadRegionModules(fileInfo.FullName, scene); modules.AddRange(LoadRegionModules(fileInfo.FullName, scene));
} }
return modules;
} }
public void LoadDefaultSharedModules() public void LoadDefaultSharedModules()
@ -190,9 +192,10 @@ namespace OpenSim.Region.Environment
} }
} }
public void LoadRegionModules(string dllName, Scene scene) public List<IRegionModule> LoadRegionModules(string dllName, Scene scene)
{ {
IRegionModule[] modules = LoadModules(dllName); IRegionModule[] modules = LoadModules(dllName);
List<IRegionModule> initializedModules = new List<IRegionModule>();
if (modules.Length > 0) if (modules.Length > 0)
{ {
@ -203,6 +206,7 @@ namespace OpenSim.Region.Environment
{ {
m_log.InfoFormat("[MODULES]: [{0}]: Initializing.", module.Name); m_log.InfoFormat("[MODULES]: [{0}]: Initializing.", module.Name);
InitializeModule(module, scene); InitializeModule(module, scene);
initializedModules.Add(module);
} }
else else
{ {
@ -211,6 +215,7 @@ namespace OpenSim.Region.Environment
} }
} }
} }
return initializedModules;
} }
public void LoadRegionModule(string dllName, string moduleName, Scene scene) public void LoadRegionModule(string dllName, string moduleName, Scene scene)

View File

@ -178,20 +178,24 @@ namespace OpenSim.Region.Environment.Modules.Terrain
{ {
m_log.Error("[TERRAIN]: Unable to load heightmap, the " + loader.Value + m_log.Error("[TERRAIN]: Unable to load heightmap, the " + loader.Value +
" parser does not support file loading. (May be save only)"); " parser does not support file loading. (May be save only)");
return; throw new Exception(String.Format("unable to load heightmap: parser {0} does not support loading", loader.Value));
} }
catch (FileNotFoundException) catch (FileNotFoundException)
{ {
m_log.Error( m_log.Error(
"[TERRAIN]: Unable to load heightmap, file not found. (A directory permissions error may also cause this)"); "[TERRAIN]: Unable to load heightmap, file not found. (A directory permissions error may also cause this)");
return; throw new Exception(String.Format("unable to load heightmap: file {0} not found (or permissions do not allow access",
filename));
} }
} }
CheckForTerrainUpdates();
m_log.Info("[TERRAIN]: File (" + filename + ") loaded successfully"); m_log.Info("[TERRAIN]: File (" + filename + ") loaded successfully");
return; return;
} }
} }
m_log.Error("[TERRAIN]: Unable to load heightmap, no file loader availible for that format."); m_log.Error("[TERRAIN]: Unable to load heightmap, no file loader availible for that format.");
throw new Exception(String.Format("unable to load heightmap from file {0}: no loader available for that format",
filename));
} }
/// <summary> /// <summary>
@ -214,6 +218,7 @@ namespace OpenSim.Region.Environment.Modules.Terrain
catch (NotImplementedException) catch (NotImplementedException)
{ {
m_log.Error("Unable to save to " + filename + ", saving of this file format has not been implemented."); m_log.Error("Unable to save to " + filename + ", saving of this file format has not been implemented.");
throw new Exception(String.Format("unable to save heightmap: {0}: saving of this file format not implemented"));
} }
} }

View File

@ -250,6 +250,22 @@ namespace OpenSim.Region.Environment.Scenes
} }
} }
public bool TrySetCurrentScene(LLUUID regionID)
{
Console.WriteLine("Searching for Region: '{0}'", regionID.ToString());
foreach (Scene scene in m_localScenes)
{
if (scene.RegionInfo.RegionID == regionID)
{
m_currentScene = scene;
return true;
}
}
return false;
}
public bool TryGetScene(string regionName, out Scene scene) public bool TryGetScene(string regionName, out Scene scene)
{ {
foreach (Scene mscene in m_localScenes) foreach (Scene mscene in m_localScenes)