Some work on Module loading/management.

Some more modules templates classes (hoping that someone will pick some of these and work on implementing them).
Early version of the "Dynamic Texture Module", although currently there are no render modules included (so not really functional without them). 
Added osSetDynamicTextureURL script function, for attaching a dynamic texture to a prim. 
Some work on the console command handling. Added "change-region <regionname>" and "exit-region" so that after the use of change-region, the commands entered will apply to that region only. Then use exit-region to return to the top level (so commands then function as they did before and either apply to all regions or to the first region) (Note: this hasn't been tested very much)
This commit is contained in:
MW
2007-09-04 13:43:56 +00:00
parent 94b1d3c128
commit bfd36e2e83
28 changed files with 661 additions and 228 deletions

View File

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using libsecondlife;
namespace OpenSim.Region.Environment.Interfaces
{
public interface IDynamicTextureManager
{
void RegisterRender(string handleType, IDynamicTextureRender render);
void ReturnData(LLUUID id, byte[] data);
LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url, string extraParams, int updateTimer);
}
public interface IDynamicTextureRender
{
string GetName();
string GetContentType();
bool SupportsAsynchronous();
byte[] ConvertUrl(string url, string extraParams);
byte[] ConvertStream(Stream data, string extraParams);
bool AsyncConvertUrl(LLUUID id, string url, string extraParams);
bool AsyncConvertStream(LLUUID id, Stream data, string extraParams);
}
}

View File

@@ -10,5 +10,6 @@ namespace OpenSim.Region.Environment.Interfaces
void PostInitialise();
void CloseDown();
string GetName();
bool IsSharedModule();
}
}

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
using libsecondlife;
namespace OpenSim.Region.Environment.Interfaces
{
public interface ISimChat
{
void SimChat(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID);
}
}

View File

@@ -14,37 +14,51 @@ namespace OpenSim.Region.Environment
public Dictionary<string, Assembly> LoadedAssemblys = new Dictionary<string, Assembly>();
public List<IRegionModule> LoadedModules = new List<IRegionModule>();
public Dictionary<string, IRegionModule> LoadedSharedModules = new Dictionary<string, IRegionModule>();
public ModuleLoader()
{
}
/// <summary>
/// Really just a test method for loading a set of currently internal modules
/// Should have a module factory?
/// </summary>
/// <param name="scene"></param>
public void CreateDefaultModules(Scene scene)
public void CreateDefaultModules(Scene scene, string exceptModules)
{
//Testing IRegionModule ideas
XferModule xferManager = new XferModule();
xferManager.Initialise(scene);
scene.AddModule(xferManager.GetName(), xferManager);
LoadedModules.Add(xferManager);
ChatModule chatModule = new ChatModule();
chatModule.Initialise(scene);
scene.AddModule(chatModule.GetName(), chatModule);
LoadedModules.Add(chatModule);
AvatarProfilesModule avatarProfiles = new AvatarProfilesModule();
avatarProfiles.Initialise(scene);
scene.AddModule(avatarProfiles.GetName(), avatarProfiles);
LoadedModules.Add(avatarProfiles);
this.LoadModule("OpenSim.Region.ExtensionsScriptModule.dll", "ExtensionsScriptingModule", scene);
this.LoadRegionModule("OpenSim.Region.ExtensionsScriptModule.dll", "ExtensionsScriptingModule", scene);
}
// Post Initialise Modules, which most likely shouldn't be here
// but should rather be in a separate method that is called after all modules are loaded/created/intialised
xferManager.PostInitialise();
// chatModule.PostInitialise(); //for now leave this disabled as it would start up a partially working irc bot
avatarProfiles.PostInitialise();
public void LoadDefaultSharedModules(string exceptModules)
{
DynamicTextureModule dynamicModule = new DynamicTextureModule();
this.LoadedSharedModules.Add(dynamicModule.GetName(), dynamicModule);
}
public void InitialiseSharedModules(Scene scene)
{
foreach (IRegionModule module in this.LoadedSharedModules.Values)
{
module.Initialise(scene);
scene.AddModule(module.GetName(), module); //should be doing this?
}
}
/// <summary>
@@ -53,18 +67,33 @@ namespace OpenSim.Region.Environment
/// <param name="dllName"></param>
/// <param name="moduleName"></param>
/// <param name="scene"></param>
public void LoadSharedModule(string dllName, string moduleName, Scene scene)
public void LoadSharedModule(string dllName, string moduleName)
{
IRegionModule module = this.LoadModule(dllName, moduleName);
if (module != null)
{
this.LoadedSharedModules.Add(module.GetName(), module);
}
}
public void LoadRegionModule(string dllName, string moduleName, Scene scene)
{
IRegionModule module = this.LoadModule(dllName, moduleName);
if (module != null)
{
module.Initialise(scene);
scene.AddModule(module.GetName(), module);
LoadedModules.Add(module);
}
}
/// <summary>
/// Loads a external Module (if not already loaded) and creates a new instance of it for the passed Scene.
/// Loads a external Module (if not already loaded) and creates a new instance of it.
/// </summary>
/// <param name="dllName"></param>
/// <param name="moduleName"></param>
/// <param name="scene"></param>
public void LoadModule(string dllName, string moduleName, Scene scene)
public IRegionModule LoadModule(string dllName, string moduleName)
{
Assembly pluginAssembly = null;
if (LoadedAssemblys.ContainsKey(dllName))
@@ -97,13 +126,26 @@ namespace OpenSim.Region.Environment
}
pluginAssembly = null;
if (module.GetName() == moduleName)
if ((module != null ) || (module.GetName() == moduleName))
{
module.Initialise(scene);
scene.AddModule(moduleName, module);
module.PostInitialise(); //shouldn't be done here
return module;
}
return null;
}
public void PostInitialise()
{
foreach (IRegionModule module in this.LoadedSharedModules.Values)
{
module.PostInitialise();
}
foreach (IRegionModule module in this.LoadedModules)
{
module.PostInitialise();
}
}
public void ClearCache()

View File

@@ -38,6 +38,11 @@ namespace OpenSim.Region.Environment.Modules
return "AssetDownloadModule";
}
public bool IsSharedModule()
{
return false;
}
public void NewClient(IClientAPI client)
{
}

View File

@@ -39,11 +39,21 @@ namespace OpenSim.Region.Environment.Modules
return "AvatarProfilesModule";
}
public bool IsSharedModule()
{
return false;
}
public void NewClient(IClientAPI client)
{
client.OnRequestAvatarProperties += RequestAvatarProperty;
}
public void RemoveClient(IClientAPI client)
{
client.OnRequestAvatarProperties -= RequestAvatarProperty;
}
/// <summary>
///
/// </summary>

View File

@@ -14,7 +14,7 @@ using OpenSim.Framework.Console;
namespace OpenSim.Region.Environment.Modules
{
public class ChatModule : IRegionModule
public class ChatModule : IRegionModule, ISimChat
{
private Scene m_scene;
@@ -45,11 +45,12 @@ namespace OpenSim.Region.Environment.Modules
m_scene = scene;
m_scene.EventManager.OnNewClient += NewClient;
//should register a optional API Method, so other modules can send chat messages using this module
m_scene.RegisterModuleInterface<ISimChat>(this);
}
public void PostInitialise()
{
/*
try
{
m_irc = new TcpClient(m_server, m_port);
@@ -75,6 +76,7 @@ namespace OpenSim.Region.Environment.Modules
{
Console.WriteLine(e.ToString());
}
*/
}
public void CloseDown()
@@ -89,6 +91,11 @@ namespace OpenSim.Region.Environment.Modules
return "ChatModule";
}
public bool IsSharedModule()
{
return false;
}
public void NewClient(IClientAPI client)
{
client.OnChatFromViewer += SimChat;

View File

@@ -0,0 +1,136 @@
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Collections.Generic;
using libsecondlife;
using OpenJPEGNet;
using OpenSim.Region.Environment.Scenes;
using OpenSim.Region.Environment.Interfaces;
using OpenSim.Framework.Interfaces;
using OpenSim.Framework.Utilities;
using OpenSim.Framework.Console;
using OpenSim.Framework.Types;
namespace OpenSim.Region.Environment.Modules
{
public class DynamicTextureModule :IRegionModule, IDynamicTextureManager
{
private Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>();
private Dictionary<string, IDynamicTextureRender> RenderPlugins= new Dictionary<string, IDynamicTextureRender>();
private Dictionary<LLUUID, DynamicTextureUpdater> Updaters = new Dictionary<LLUUID, DynamicTextureUpdater>();
public void Initialise(Scene scene)
{
if (!RegisteredScenes.ContainsKey(scene.RegionInfo.SimUUID))
{
RegisteredScenes.Add(scene.RegionInfo.SimUUID, scene);
scene.RegisterModuleInterface<IDynamicTextureManager>(this);
}
}
public void PostInitialise()
{
}
public void CloseDown()
{
}
public string GetName()
{
return "DynamicTextureModule";
}
public bool IsSharedModule()
{
return true;
}
public void RegisterRender(string handleType, IDynamicTextureRender render)
{
if (!RenderPlugins.ContainsKey(handleType))
{
RenderPlugins.Add(handleType, render);
}
}
public void ReturnData(LLUUID id, byte[] data)
{
if (Updaters.ContainsKey(id))
{
DynamicTextureUpdater updater = Updaters[id];
if (RegisteredScenes.ContainsKey(updater.SimUUID))
{
Scene scene = RegisteredScenes[updater.SimUUID];
updater.DataReceived(data, scene);
}
}
}
public LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url, string extraParams, int updateTimer)
{
System.Console.WriteLine("dynamic texture being created " + url + " of type " + contentType);
if (this.RenderPlugins.ContainsKey(contentType))
{
DynamicTextureUpdater updater = new DynamicTextureUpdater();
updater.SimUUID = simID;
updater.PrimID = primID;
updater.ContentType = contentType;
updater.Url = url;
updater.UpdateTimer = updateTimer;
updater.UpdaterID = LLUUID.Random();
updater.Params = extraParams;
if (!this.Updaters.ContainsKey(updater.UpdaterID))
{
Updaters.Add(updater.UpdaterID, updater);
}
RenderPlugins[contentType].AsyncConvertUrl(updater.UpdaterID, url, extraParams);
return updater.UpdaterID;
}
return LLUUID.Zero;
}
public class DynamicTextureUpdater
{
public LLUUID SimUUID;
public LLUUID UpdaterID;
public string ContentType;
public string Url;
public Stream StreamData;
public LLUUID PrimID;
public int UpdateTimer;
public LLUUID LastAssetID;
public string Params;
public DynamicTextureUpdater()
{
LastAssetID = LLUUID.Zero;
UpdateTimer = 0;
StreamData = null;
}
public void DataReceived(byte[] data, Scene scene)
{
//TODO delete the last asset(data), if it was a dynamic texture
AssetBase asset = new AssetBase();
asset.FullID = LLUUID.Random();
asset.Data = data;
asset.Name = "DynamicImage" + Util.RandomClass.Next(1, 10000);
asset.Type = 0;
scene.commsManager.AssetCache.AddAsset(asset);
this.LastAssetID = asset.FullID;
SceneObjectPart part = scene.GetSceneObjectPart(PrimID);
part.Shape.TextureEntry = new LLObject.TextureEntry(asset.FullID).ToBytes();
part.ScheduleFullUpdate();
}
}
}
}

View File

@@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenSim.Region.Environment.Modules
{
class EmailModule
{
}
}

View File

@@ -31,5 +31,10 @@ namespace OpenSim.Region.Environment.Modules
{
return "FriendsModule";
}
public bool IsSharedModule()
{
return false;
}
}
}

View File

@@ -30,6 +30,11 @@ namespace OpenSim.Region.Environment.Modules
{
return "GroupsModule";
}
public bool IsSharedModule()
{
return false;
}
}
}

View File

@@ -31,5 +31,10 @@ namespace OpenSim.Region.Environment.Modules
{
return "InstantMessageModule";
}
public bool IsSharedModule()
{
return false;
}
}
}

View File

@@ -31,5 +31,10 @@ namespace OpenSim.Region.Environment.Modules
{
return "InventoryModule";
}
public bool IsSharedModule()
{
return false;
}
}
}

View File

@@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenSim.Region.Environment.Modules
{
class ScriptsHttpRequests
{
}
}

View File

@@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenSim.Region.Environment.Modules
{
class TeleportModule
{
}
}

View File

@@ -37,6 +37,11 @@ namespace OpenSim.Region.Environment.Modules
return "TextureDownloadModule";
}
public bool IsSharedModule()
{
return false;
}
public void NewClient(IClientAPI client)
{
}

View File

@@ -45,6 +45,11 @@ namespace OpenSim.Region.Environment.Modules
return "XferModule";
}
public bool IsSharedModule()
{
return false;
}
public void NewClient(IClientAPI client)
{
client.OnRequestXfer += RequestXfer;

View File

@@ -35,6 +35,7 @@ using OpenSim.Framework.Types;
using OpenSim.Framework.Communications.Caches;
using OpenSim.Framework.Data;
using OpenSim.Framework.Utilities;
using OpenSim.Region.Environment.Interfaces;
namespace OpenSim.Region.Environment.Scenes
{
@@ -94,7 +95,7 @@ namespace OpenSim.Region.Environment.Scenes
}
/// <summary>
/// Should be removed soon as the Chat modules should take over this function
///
/// </summary>
/// <param name="message"></param>
/// <param name="type"></param>
@@ -103,56 +104,10 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="fromAgentID"></param>
public void SimChat(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID)
{
ScenePresence avatar = null;
if (this.Avatars.ContainsKey(fromAgentID))
if (m_simChatModule != null)
{
avatar = this.Avatars[fromAgentID];
fromPos = avatar.AbsolutePosition;
fromName = avatar.Firstname + " " + avatar.Lastname;
avatar = null;
m_simChatModule.SimChat(message, type, fromPos, fromName, fromAgentID);
}
this.ForEachScenePresence(delegate(ScenePresence presence)
{
int dis = -1000;
if (this.Avatars.ContainsKey(presence.ControllingClient.AgentId))
{
avatar = this.Avatars[presence.ControllingClient.AgentId];
dis = (int)avatar.AbsolutePosition.GetDistanceTo(fromPos);
}
switch (type)
{
case 0: // Whisper
if ((dis < 10) && (dis > -10))
{
//should change so the message is sent through the avatar rather than direct to the ClientView
presence.ControllingClient.SendChatMessage(message, type, fromPos, fromName,
fromAgentID);
}
break;
case 1: // Say
if ((dis < 30) && (dis > -30))
{
//Console.WriteLine("sending chat");
presence.ControllingClient.SendChatMessage(message, type, fromPos, fromName,
fromAgentID);
}
break;
case 2: // Shout
if ((dis < 100) && (dis > -100))
{
presence.ControllingClient.SendChatMessage(message, type, fromPos, fromName,
fromAgentID);
}
break;
case 0xff: // Broadcast
presence.ControllingClient.SendChatMessage(message, type, fromPos, fromName,
fromAgentID);
break;
}
});
}
/// <summary>

View File

@@ -78,20 +78,23 @@ namespace OpenSim.Region.Environment.Scenes
protected StorageManager storageManager;
protected AgentCircuitManager authenticateHandler;
protected RegionCommsListener regionCommsHost;
protected CommunicationsManager commsManager;
// protected XferManager xferManager;
public CommunicationsManager commsManager;
// protected XferManager xferManager;
protected Dictionary<LLUUID, Caps> capsHandlers = new Dictionary<LLUUID, Caps>();
protected BaseHttpServer httpListener;
protected Dictionary<string, IRegionModule> Modules = new Dictionary<string, IRegionModule>();
protected Dictionary<string, object> APIMethods = new Dictionary<string, object>();
public Dictionary<Type, object> ModuleInterfaces = new Dictionary<Type, object>();
protected Dictionary<string, object> ModuleAPIMethods = new Dictionary<string, object>();
//API method Delegates
//API method Delegates and interfaces
// this most likely shouldn't be handled as a API method like this, but doing it for testing purposes
public ModuleAPIMethod2<bool, string, byte[]>AddXferFile = null;
public ModuleAPIMethod2<bool, string, byte[]> AddXferFile = null;
private ISimChat m_simChatModule = null;
#region Properties
public AgentCircuitManager AuthenticateHandler
@@ -152,7 +155,7 @@ namespace OpenSim.Region.Environment.Scenes
AssetCache assetCach, StorageManager storeManager, BaseHttpServer httpServer, ModuleLoader moduleLoader)
{
updateLock = new Mutex(false);
m_moduleLoader = moduleLoader;
authenticateHandler = authen;
commsManager = commsMan;
@@ -169,9 +172,6 @@ namespace OpenSim.Region.Environment.Scenes
m_eventManager = new EventManager();
m_permissionManager = new PermissionManager(this);
MainLog.Instance.Verbose("Loading Region Modules");
m_moduleLoader.CreateDefaultModules(this);
m_eventManager.OnParcelPrimCountAdd +=
m_LandManager.addPrimToLandPrimCounts;
@@ -189,13 +189,15 @@ namespace OpenSim.Region.Environment.Scenes
httpListener = httpServer;
SetMethodDelegates();
}
#endregion
private void SetMethodDelegates()
public void SetModuleInterfaces()
{
m_simChatModule = this.RequestModuleInterface<ISimChat>();
//should change so it uses the module interface functions
AddXferFile = (ModuleAPIMethod2<bool, string, byte[]>)this.RequestAPIMethod("API_AddXferFile");
}
@@ -526,7 +528,7 @@ namespace OpenSim.Region.Environment.Scenes
MainLog.Instance.Verbose("Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)");
}
/// <summary>
/// Returns a new unallocated primitive ID
@@ -635,12 +637,12 @@ namespace OpenSim.Region.Environment.Scenes
//obj.RegenerateFullIDs();
AddEntity(obj);
SceneObjectPart rootPart = obj.GetChildPart(obj.UUID);
rootPart.PhysActor = phyScene.AddPrim(
new PhysicsVector(rootPart.AbsolutePosition.X, rootPart.AbsolutePosition.Y, rootPart.AbsolutePosition.Z),
new PhysicsVector(rootPart.Scale.X, rootPart.Scale.Y, rootPart.Scale.Z),
new Axiom.Math.Quaternion(rootPart.RotationOffset.W, rootPart.RotationOffset.X,
rootPart.RotationOffset.Y, rootPart.RotationOffset.Z));
SceneObjectPart rootPart = obj.GetChildPart(obj.UUID);
rootPart.PhysActor = phyScene.AddPrim(
new PhysicsVector(rootPart.AbsolutePosition.X, rootPart.AbsolutePosition.Y, rootPart.AbsolutePosition.Z),
new PhysicsVector(rootPart.Scale.X, rootPart.Scale.Y, rootPart.Scale.Z),
new Axiom.Math.Quaternion(rootPart.RotationOffset.W, rootPart.RotationOffset.X,
rootPart.RotationOffset.Y, rootPart.RotationOffset.Z));
primCount++;
}
}
@@ -692,7 +694,7 @@ namespace OpenSim.Region.Environment.Scenes
protected virtual void SubscribeToClientEvents(IClientAPI client)
{
// client.OnStartAnim += StartAnimation;
// client.OnStartAnim += StartAnimation;
client.OnRegionHandShakeReply += SendLayerData;
//remoteClient.OnRequestWearables += new GenericCall(this.GetInitialPrims);
client.OnModifyTerrain += ModifyTerrain;
@@ -742,7 +744,7 @@ namespace OpenSim.Region.Environment.Scenes
client.OnRezScript += RezScript;
client.OnRemoveTaskItem += RemoveTaskInventory;
// client.OnRequestAvatarProperties += RequestAvatarProperty;
// client.OnRequestAvatarProperties += RequestAvatarProperty;
client.OnGrabObject += ProcessObjectGrab;
@@ -1071,13 +1073,12 @@ namespace OpenSim.Region.Environment.Scenes
AgentCircuitData agent = remoteClient.RequestClientInfo();
agent.BaseFolder = LLUUID.Zero;
agent.InventoryFolder = LLUUID.Zero;
// agent.startpos = new LLVector3(128, 128, 70);
// agent.startpos = new LLVector3(128, 128, 70);
agent.startpos = position;
agent.child = true;
commsManager.InterRegion.InformRegionOfChildAgent(regionHandle, agent);
commsManager.InterRegion.ExpectAvatarCrossing(regionHandle, remoteClient.AgentId, position, false);
//TODO: following line is hard coded to port 9000, really need to change this as soon as possible
AgentCircuitData circuitdata = remoteClient.RequestClientInfo();
string capsPath = Util.GetCapsURL(remoteClient.AgentId);
remoteClient.SendRegionTeleport(regionHandle, 13, reg.ExternalEndPoint, 4, (1 << 4), capsPath);
@@ -1114,23 +1115,45 @@ namespace OpenSim.Region.Environment.Scenes
}
}
//following delegate methods will be removed, so use the interface methods (below these)
public void RegisterAPIMethod(string name, object method)
{
if (!this.APIMethods.ContainsKey(name))
if (!this.ModuleAPIMethods.ContainsKey(name))
{
this.APIMethods.Add(name, method);
this.ModuleAPIMethods.Add(name, method);
}
}
public object RequestAPIMethod(string name)
{
if (this.APIMethods.ContainsKey(name))
if (this.ModuleAPIMethods.ContainsKey(name))
{
return APIMethods[name];
return ModuleAPIMethods[name];
}
return false;
}
public void RegisterModuleInterface<M>( M mod)
{
//Console.WriteLine("registering module interface " + typeof(M));
if (!this.ModuleInterfaces.ContainsKey(typeof(M)))
{
ModuleInterfaces.Add(typeof(M), mod);
}
}
public T RequestModuleInterface<T>()
{
if (ModuleInterfaces.ContainsKey(typeof(T)))
{
return (T)ModuleInterfaces[typeof(T)];
}
else
{
return default(T);
}
}
public void SetTimePhase(int phase)
{
m_timePhase = phase;
@@ -1205,6 +1228,49 @@ namespace OpenSim.Region.Environment.Scenes
}
#endregion
public void ProcessConsoleCmd(string command, string[] cmdparams)
{
switch (command)
{
case "save-xml":
if (cmdparams.Length > 0)
{
SavePrimsToXml(cmdparams[0]);
}
else
{
SavePrimsToXml("test.xml");
}
break;
case "load-xml":
if (cmdparams.Length > 0)
{
LoadPrimsFromXml(cmdparams[0]);
}
else
{
LoadPrimsFromXml("test.xml");
}
break;
case "set-time":
break;
case "backup":
Backup();
break;
case "alert":
HandleAlertCommand(cmdparams);
break;
default:
MainLog.Instance.Error("Unknown command: " + command);
break;
}
}
#region Script Engine
private List<OpenSim.Region.Environment.Scenes.Scripting.ScriptEngineInterface> ScriptEngines = new List<OpenSim.Region.Environment.Scenes.Scripting.ScriptEngineInterface>();
public void AddScriptEngine(OpenSim.Region.Environment.Scenes.Scripting.ScriptEngineInterface ScriptEngine, LogBase m_logger)
@@ -1248,5 +1314,22 @@ namespace OpenSim.Region.Environment.Scenes
}
return null;
}
public SceneObjectPart GetSceneObjectPart(LLUUID fullID)
{
bool hasPrim = false;
foreach (EntityBase ent in Entities.Values)
{
if (ent is SceneObjectGroup)
{
hasPrim = ((SceneObjectGroup)ent).HasChildPrim(fullID);
if (hasPrim != false)
{
return ((SceneObjectGroup)ent).GetChildPart(fullID);
}
}
}
return null;
}
}
}