From e61f42ad3a4a315d4eb56107bb6ead7092035bff Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 21 Jan 2010 23:59:04 -0800 Subject: [PATCH 01/11] add a target position to agent updates to ScenePresence to support alternative client protocols --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 39a2c656cf..1c183f3310 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1276,6 +1276,12 @@ namespace OpenSim.Region.Framework.Scenes if (m_allowMovement) { + if (agentData.UseClientAgentPosition) + { + m_moveToPositionInProgress = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f; + m_moveToPositionTarget = agentData.ClientAgentPosition; + } + int i = 0; bool update_rotation = false; @@ -1382,7 +1388,7 @@ namespace OpenSim.Region.Framework.Scenes if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving)) { //Check the error term of the current position in relation to the target position - if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 1.5f) + if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f) { // we are close enough to the target m_moveToPositionTarget = Vector3.Zero; From 5f5fdc36248788b97c1283f65e2188fa1d60a361 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 22 Jan 2010 16:22:23 +0000 Subject: [PATCH 02/11] Allow oar loading to work even if an estate module is not present Write bare bones unit test for region setting loads --- .../World/Archiver/ArchiveReadRequest.cs | 6 +- .../World/Archiver/Tests/ArchiverTests.cs | 70 +++++++++++++++++++ 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index 52add238c6..8ed1913c30 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -423,9 +423,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver currentRegionSettings.TerrainTexture4 = loadedRegionSettings.TerrainTexture4; currentRegionSettings.UseEstateSun = loadedRegionSettings.UseEstateSun; currentRegionSettings.WaterHeight = loadedRegionSettings.WaterHeight; - + IEstateModule estateModule = m_scene.RequestModuleInterface(); - estateModule.sendRegionHandshakeToAll(); + + if (estateModule != null) + estateModule.sendRegionHandshakeToAll(); return true; } diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index edac4a4e8b..4f7a1372ac 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs @@ -36,6 +36,7 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Communications.Cache; using OpenSim.Framework.Serialization; +using OpenSim.Framework.Serialization.External; using OpenSim.Region.CoreModules.World.Serialiser; using OpenSim.Region.CoreModules.World.Terrain; using OpenSim.Region.Framework.Scenes; @@ -269,6 +270,75 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests Console.WriteLine("Successfully completed {0}", MethodBase.GetCurrentMethod()); } + /// + /// Test loading the region settings of a V0.2 OpenSim Region Archive. + /// + [Test] + public void TestLoadOarV0_2RegionSettings() + { + TestHelper.InMethod(); + //log4net.Config.XmlConfigurator.Configure(); + + SerialiserModule serialiserModule = new SerialiserModule(); + ArchiverModule archiverModule = new ArchiverModule(); + Scene scene = SceneSetupHelpers.SetupScene(); + SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); + + MemoryStream archiveWriteStream = new MemoryStream(); + TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream); + + tar.WriteDir(ArchiveConstants.TERRAINS_PATH); + tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestExecution.Create0p2ControlFile()); + + RegionSettings rs = new RegionSettings(); + rs.AgentLimit = 17; + rs.AllowDamage = true; + rs.AllowLandJoinDivide = true; + rs.AllowLandResell = true; + rs.BlockFly = true; + rs.BlockShowInSearch = true; + rs.BlockTerraform = true; + rs.DisableCollisions = true; + rs.DisablePhysics = true; + rs.DisableScripts = true; + rs.Elevation1NW = 15.9; + rs.Elevation1NE = 45.3; + rs.Elevation1SE = 49; + rs.Elevation1SW = 1.9; + rs.Elevation2NW = 4.5; + rs.Elevation2NE = 19.2; + rs.Elevation2SE = 9.2; + rs.Elevation2SW = 2.1; + rs.FixedSun = true; + rs.ObjectBonus = 1.4; + rs.RestrictPushing = true; + rs.TerrainLowerLimit = 0.4; + rs.TerrainRaiseLimit = 17.9; + rs.TerrainTexture1 = UUID.Parse("00000000-0000-0000-0000-000000000020"); + rs.TerrainTexture2 = UUID.Parse("00000000-0000-0000-0000-000000000040"); + rs.TerrainTexture3 = UUID.Parse("00000000-0000-0000-0000-000000000060"); + rs.TerrainTexture4 = UUID.Parse("00000000-0000-0000-0000-000000000080"); + rs.UseEstateSun = true; + rs.WaterHeight = 23; + + tar.WriteFile(ArchiveConstants.SETTINGS_PATH + "region1.xml", RegionSettingsSerializer.Serialize(rs)); + + tar.Close(); + + MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); + + lock (this) + { + scene.EventManager.OnOarFileLoaded += LoadCompleted; + archiverModule.DearchiveRegion(archiveReadStream); + } + + Assert.That(m_lastErrorMessage, Is.Null); + RegionSettings loadedRs = scene.RegionInfo.RegionSettings; + + Assert.That(loadedRs.AgentLimit, Is.EqualTo(17)); + } + /// /// Test merging a V0.2 OpenSim Region Archive into an existing scene /// From 2308b375a773d3c00d85f49e78ef7691720d002a Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 22 Jan 2010 16:26:42 +0000 Subject: [PATCH 03/11] minor: remove warning from LLClientView --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 515d0ea1c2..4b5e4c4d5c 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -9091,8 +9091,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP private bool HandleSendPostcard(IClientAPI client, Packet packet) { - SendPostcardPacket SendPostcard = - (SendPostcardPacket)packet; +// SendPostcardPacket SendPostcard = +// (SendPostcardPacket)packet; SendPostcard handlerSendPostcard = OnSendPostcard; if (handlerSendPostcard != null) { From a0e4665077748430ebcb7c02917036fc59794975 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 22 Jan 2010 17:17:25 +0000 Subject: [PATCH 04/11] complete assertion checks of all other oar loaded region settings --- .../World/Archiver/Tests/ArchiverTests.cs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index 4f7a1372ac..9e9ceddf42 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs @@ -337,6 +337,34 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests RegionSettings loadedRs = scene.RegionInfo.RegionSettings; Assert.That(loadedRs.AgentLimit, Is.EqualTo(17)); + Assert.That(loadedRs.AllowDamage, Is.True); + Assert.That(loadedRs.AllowLandJoinDivide, Is.True); + Assert.That(loadedRs.AllowLandResell, Is.True); + Assert.That(loadedRs.BlockFly, Is.True); + Assert.That(loadedRs.BlockShowInSearch, Is.True); + Assert.That(loadedRs.BlockTerraform, Is.True); + Assert.That(loadedRs.DisableCollisions, Is.True); + Assert.That(loadedRs.DisablePhysics, Is.True); + Assert.That(loadedRs.DisableScripts, Is.True); + Assert.That(loadedRs.Elevation1NW, Is.EqualTo(15.9)); + Assert.That(loadedRs.Elevation1NE, Is.EqualTo(45.3)); + Assert.That(loadedRs.Elevation1SE, Is.EqualTo(49)); + Assert.That(loadedRs.Elevation1SW, Is.EqualTo(1.9)); + Assert.That(loadedRs.Elevation2NW, Is.EqualTo(4.5)); + Assert.That(loadedRs.Elevation2NE, Is.EqualTo(19.2)); + Assert.That(loadedRs.Elevation2SE, Is.EqualTo(9.2)); + Assert.That(loadedRs.Elevation2SW, Is.EqualTo(2.1)); + Assert.That(loadedRs.FixedSun, Is.True); + Assert.That(loadedRs.ObjectBonus, Is.EqualTo(1.4)); + Assert.That(loadedRs.RestrictPushing, Is.True); + Assert.That(loadedRs.TerrainLowerLimit, Is.EqualTo(0.4)); + Assert.That(loadedRs.TerrainRaiseLimit, Is.EqualTo(17.9)); + Assert.That(loadedRs.TerrainTexture1, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000020"))); + Assert.That(loadedRs.TerrainTexture2, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000040"))); + Assert.That(loadedRs.TerrainTexture3, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000060"))); + Assert.That(loadedRs.TerrainTexture4, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000080"))); + Assert.That(loadedRs.UseEstateSun, Is.True); + Assert.That(loadedRs.WaterHeight, Is.EqualTo(23)); } /// From 1df69be9a6d7a1c7c0a5446c11fe9fde2c2b88f7 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 22 Jan 2010 20:32:34 +0000 Subject: [PATCH 05/11] Add first part of test for checking restore of task inventory items on oar load Passes but not yet complete --- .../World/Archiver/Tests/ArchiverTests.cs | 50 +++++++++++++++++- .../Archiver/Tests/Resources/test-sound.wav | Bin 0 -> 211648 bytes prebuild.xml | 1 + 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100755 OpenSim/Region/CoreModules/World/Archiver/Tests/Resources/test-sound.wav diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index 9e9ceddf42..1200105817 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs @@ -215,7 +215,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests // Also check that direct entries which will also have a file entry containing that directory doesn't // upset load tar.WriteDir(ArchiveConstants.TERRAINS_PATH); - + tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestExecution.Create0p2ControlFile()); string part1Name = "object1"; @@ -235,6 +235,45 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests UUID.Zero, shape, groupPosition, rotationOffset, offsetPosition); part1.Name = part1Name; SceneObjectGroup object1 = new SceneObjectGroup(part1); + + // Let's put some inventory items into our object + UUID soundItemUuid = UUID.Parse("00000000-0000-0000-0000-000000000002"); + Type type = GetType(); + Assembly assembly = type.Assembly; + string soundDataResourceName = null; + string[] names = assembly.GetManifestResourceNames(); + foreach (string name in names) + { + if (name.EndsWith(".Resources.test-sound.wav")) + soundDataResourceName = name; + } + Assert.That(soundDataResourceName, Is.Not.Null); + + byte[] soundData; + Console.WriteLine("Loading " + soundDataResourceName); + using (Stream resource = assembly.GetManifestResourceStream(soundDataResourceName)) + { + using (BinaryReader br = new BinaryReader(resource)) + { + // FIXME: Use the inspector insteadthere are so many forums and lists already, though admittedly none of them are suitable for cross virtual-enivornemnt discussion + soundData = br.ReadBytes(99999999); + UUID soundUuid = UUID.Parse("00000000-0000-0000-0000-000000000001"); + string soundAssetFileName + = ArchiveConstants.ASSETS_PATH + soundUuid + + ArchiveConstants.ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.SoundWAV]; + tar.WriteFile(soundAssetFileName, soundData); + + /* + AssetBase soundAsset = AssetHelpers.CreateAsset(soundUuid, soundData); + scene.AssetService.Store(soundAsset); + asset1FileName = ArchiveConstants.ASSETS_PATH + soundUuid + ".wav"; + */ + + TaskInventoryItem item1 = new TaskInventoryItem { AssetID = soundUuid, ItemID = soundItemUuid }; + part1.Inventory.AddInventoryItem(item1, true); + } + } + scene.AddNewSceneObject(object1, false); string object1FileName = string.Format( @@ -266,6 +305,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests Assert.That( object1PartLoaded.OffsetPosition, Is.EqualTo(offsetPosition), "object1 offset position not equal"); + // Need to implement a method to get the task inventory item by name (since the uuid will have changed on load) + /* + TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItem(soundItemUuid); + Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null"); + AssetBase loadedSoundAsset = scene.AssetService.Get(loadedSoundItem.AssetID.ToString()); + Assert.That(loadedSoundAsset, Is.Not.Null, "loaded sound asset was null"); + Assert.That(loadedSoundAsset.Data, Is.EqualTo(soundData), "saved and loaded sound data do not match"); + */ + // Temporary Console.WriteLine("Successfully completed {0}", MethodBase.GetCurrentMethod()); } diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/Resources/test-sound.wav b/OpenSim/Region/CoreModules/World/Archiver/Tests/Resources/test-sound.wav new file mode 100755 index 0000000000000000000000000000000000000000..b45ee54d354c075cec2c681e057265bee4c8ccef GIT binary patch literal 211648 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 literal 0 HcmV?d00001 diff --git a/prebuild.xml b/prebuild.xml index 7881cd7ebf..0ab7414f4c 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -3271,6 +3271,7 @@ + From ec3c31e61e5e540f822891110df9bc978655bbaf Mon Sep 17 00:00:00 2001 From: Revolution Date: Fri, 22 Jan 2010 18:09:33 -0600 Subject: [PATCH 06/11] Updates all IRegionModules to the new style region modules. Signed-off-by: Melanie --- .../LoadRegions/LoadRegionsPlugin.cs | 4 +- OpenSim/Client/MXP/MXPModule.cs | 38 ++- .../AssetTransactionModule.cs | 35 ++- .../Agent/Capabilities/CapabilitiesModule.cs | 2 +- .../CoreModules/Agent/IPBan/IPBanModule.cs | 40 ++- .../TextureDownload/TextureDownloadModule.cs | 33 ++- .../Agent/TextureSender/J2KDecoderModule.cs | 33 ++- .../CoreModules/Agent/Xfer/XferModule.cs | 30 +- .../AvatarFactory/AvatarFactoryModule.cs | 31 ++- .../CoreModules/Avatar/Combat/CombatModule.cs | 32 ++- .../CoreModules/Avatar/Dialog/DialogModule.cs | 32 ++- .../Avatar/Friends/FriendsModule.cs | 54 +++- .../Avatar/Gestures/GesturesModule.cs | 30 +- .../CoreModules/Avatar/Gods/GodsModule.cs | 28 +- .../CoreModules/Avatar/Groups/GroupsModule.cs | 35 ++- .../InstantMessage/InstantMessageModule.cs | 53 ++-- .../InstantMessage/MessageTransferModule.cs | 54 ++-- .../Avatar/InstantMessage/MuteListModule.cs | 48 ++-- .../InstantMessage/OfflineMessageModule.cs | 76 ++++-- .../Avatar/InstantMessage/PresenceModule.cs | 65 +++-- .../Archiver/InventoryArchiverModule.cs | 35 ++- .../Transfer/InventoryTransferModule.cs | 65 +++-- .../CoreModules/Avatar/Lure/LureModule.cs | 61 ++++- .../Avatar/ObjectCaps/ObjectAdd.cs | 55 ++-- .../Avatar/Profiles/AvatarProfilesModule.cs | 32 ++- .../EventQueue/EventQueueGetModule.cs | 42 +-- .../Framework/Monitoring/MonitorModule.cs | 103 ++++--- .../Hypergrid/HGStandaloneLoginModule.cs | 83 +++--- .../Region/CoreModules/InterGrid/OGSRadmin.cs | 31 +-- .../InterGrid/OpenGridProtocolModule.cs | 104 ++++--- .../DynamicTexture/DynamicTextureModule.cs | 60 ++-- .../Scripting/EMailModules/EmailModule.cs | 32 ++- .../HttpRequest/ScriptsHttpRequests.cs | 36 ++- .../Scripting/LSLHttp/UrlModule.cs | 2 + .../LoadImageURL/LoadImageURLModule.cs | 37 ++- .../VectorRender/VectorRenderModule.cs | 41 ++- .../Scripting/WorldComm/WorldCommModule.cs | 39 ++- .../Scripting/XMLRPC/XMLRPCModule.cs | 51 +++- .../Asset/AssetServiceInConnectorModule.cs | 2 +- .../Grid/HypergridServiceInConnectorModule.cs | 2 +- .../InventoryServiceInConnectorModule.cs | 2 +- .../Land/LandServiceInConnectorModule.cs | 2 +- .../NeighbourServiceInConnectorModule.cs | 2 +- .../SimulationServiceInConnectorModule.cs | 2 +- .../Interregion/LocalInterregionComms.cs | 4 +- .../Interregion/RESTInterregionComms.cs | 16 +- .../World/Archiver/ArchiverModule.cs | 1 + .../CoreModules/World/Cloud/CloudModule.cs | 30 +- .../World/Estate/EstateManagementModule.cs | 58 ++-- .../World/Permissions/PermissionsModule.cs | 256 +++++++++++------- .../CoreModules/World/Sound/SoundModule.cs | 33 ++- .../Region/CoreModules/World/Sun/SunModule.cs | 150 +++++----- .../World/Vegetation/VegetationModule.cs | 27 +- .../CoreModules/World/Wind/WindModule.cs | 47 ++-- .../World/WorldMap/MapImageModule.cs | 30 +- .../World/WorldMap/MapSearchModule.cs | 35 ++- .../DataSnapshot/DataSnapshotManager.cs | 59 ++-- .../Framework/Interfaces/ICloudModule.cs | 2 +- .../Framework/Interfaces/IEmailModule.cs | 2 +- .../Framework/Interfaces/IEstateModule.cs | 2 +- .../Region/Framework/Interfaces/ISunModule.cs | 2 +- .../Framework/Interfaces/IWindModule.cs | 2 +- .../InternetRelayClientView/IRCStackModule.cs | 32 ++- .../FreeSwitchVoice/FreeSwitchVoiceModule.cs | 72 +++-- .../ContentManagementModule.cs | 47 ++-- .../Scripting/Minimodule/MRMModule.cs | 64 +++-- .../RegionReadyModule/RegionReadyModule.cs | 6 +- .../ScriptModuleCommsModule.cs | 1 + .../XmlRpcGridRouterModule.cs | 28 +- .../XmlRpcRouterModule/XmlRpcRouterModule.cs | 32 ++- .../FreeswitchServiceInConnectorModule.cs | 2 +- .../SvnSerialiser/SvnBackupModule.cs | 28 +- .../OptionalModules/World/NPC/NPCModule.cs | 28 +- .../TreePopulator/TreePopulatorModule.cs | 41 +-- .../Region/UserStatistics/WebStatsModule.cs | 33 ++- .../Tests/Common/Setup/SceneSetupHelpers.cs | 9 +- 76 files changed, 1899 insertions(+), 954 deletions(-) diff --git a/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs b/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs index 6fd3d301a5..64863c5176 100644 --- a/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs +++ b/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs @@ -99,7 +99,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions regionLoader.SetIniConfigSource(m_openSim.ConfigSource.Source); RegionInfo[] regionsToLoad = regionLoader.LoadRegions(); - m_log.Info("[LOADREGIONSPLUGIN]: Loading specific shared modules..."); + /*m_log.Info("[LOADREGIONSPLUGIN]: Loading specific shared modules..."); m_log.Info("[LOADREGIONSPLUGIN]: DynamicTextureModule..."); m_openSim.ModuleLoader.LoadDefaultSharedModule(new DynamicTextureModule()); m_log.Info("[LOADREGIONSPLUGIN]: InstantMessageModule..."); @@ -111,7 +111,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions m_log.Info("[LOADREGIONSPLUGIN]: AssetTransactionModule..."); m_openSim.ModuleLoader.LoadDefaultSharedModule(new AssetTransactionModule()); m_log.Info("[LOADREGIONSPLUGIN]: Done."); - + */ if (!CheckRegionsForSanity(regionsToLoad)) { m_log.Error("[LOADREGIONS]: Halting startup due to conflicts in region configurations"); diff --git a/OpenSim/Client/MXP/MXPModule.cs b/OpenSim/Client/MXP/MXPModule.cs index 0b442cca15..47417ab477 100644 --- a/OpenSim/Client/MXP/MXPModule.cs +++ b/OpenSim/Client/MXP/MXPModule.cs @@ -31,6 +31,7 @@ using System.Reflection; using System.Text; using System.Timers; using log4net; +using Mono.Addins; using MXP; using Nini.Config; using OpenMetaverse; @@ -44,7 +45,8 @@ namespace OpenSim.Client.MXP /** * MXP Client Module which adds MXP support to client / region communication. */ - public class MXPModule : IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class MXPModule : ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -57,15 +59,23 @@ namespace OpenSim.Client.MXP private readonly Dictionary m_scenes = new Dictionary(); private bool m_shutdown; - public void Initialise(Scene scene, IConfigSource source) + public void Initialise(IConfigSource source) { - if (!m_scenes.ContainsKey(scene.RegionInfo.RegionID)) - m_scenes.Add(scene.RegionInfo.RegionID, scene); - m_config = source; } - public void PostInitialise() + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) + { + if (!m_scenes.ContainsKey(scene.RegionInfo.RegionID)) + m_scenes.Add(scene.RegionInfo.RegionID, scene); + } + + public void RegionLoaded(Scene scene) { if (m_config.Configs["MXP"] != null) { @@ -76,7 +86,7 @@ namespace OpenSim.Client.MXP m_port = con.GetInt("Port", m_port); - m_server = new MXPPacketServer(m_port, m_scenes,m_config.Configs["StandAlone"].GetBoolean("accounts_authenticate",true)); + m_server = new MXPPacketServer(m_port, m_scenes, m_config.Configs["StandAlone"].GetBoolean("accounts_authenticate", true)); m_ticker = new Timer(100); m_ticker.AutoReset = false; @@ -89,6 +99,14 @@ namespace OpenSim.Client.MXP } } + public void RemoveRegion(Scene scene) + { + } + + public void PostInitialise() + { + } + void ticker_Elapsed(object sender, ElapsedEventArgs e) { try @@ -121,11 +139,5 @@ namespace OpenSim.Client.MXP { get { return "MXP ClientStack Module"; } } - - public bool IsSharedModule - { - get { return true; } - } - } } diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs index 1077f4a22f..7012037834 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -35,7 +36,8 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Agent.AssetTransaction { - public class AssetTransactionModule : IRegionModule, IAgentAssetTransactions + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class AssetTransactionModule : ISharedRegionModule, IAgentAssetTransactions { private readonly Dictionary RegisteredScenes = new Dictionary(); private bool m_dumpAssetsToFile = false; @@ -59,9 +61,14 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction //m_log.Debug("creating AgentAssetTransactionModule"); } - #region IRegionModule Members + #region ISharedRegionModule Members - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) + { + + } + + public void AddRegion(Scene scene) { if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) { @@ -79,6 +86,23 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction m_scene = scene; } + public Type ReplaceableInterface + { + get { return null; } + } + + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + if (RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) + RegisteredScenes.Remove(scene.RegionInfo.RegionID); + scene.UnregisterModuleInterface(this); + scene.EventManager.OnNewClient -= NewClient; + } + public void PostInitialise() { } @@ -92,11 +116,6 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction get { return "AgentTransactionModule"; } } - public bool IsSharedModule - { - get { return true; } - } - #endregion public void NewClient(IClientAPI client) diff --git a/OpenSim/Region/CoreModules/Agent/Capabilities/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Agent/Capabilities/CapabilitiesModule.cs index 2a1355b9ef..886173fb45 100644 --- a/OpenSim/Region/CoreModules/Agent/Capabilities/CapabilitiesModule.cs +++ b/OpenSim/Region/CoreModules/Agent/Capabilities/CapabilitiesModule.cs @@ -69,7 +69,7 @@ namespace OpenSim.Region.CoreModules.Agent.Capabilities public void RemoveRegion(Scene scene) { - m_scene.UnregisterModuleInterface(this); + scene.UnregisterModuleInterface(this); } public void PostInitialise() {} diff --git a/OpenSim/Region/CoreModules/Agent/IPBan/IPBanModule.cs b/OpenSim/Region/CoreModules/Agent/IPBan/IPBanModule.cs index bfe2a716af..f7f2eff487 100644 --- a/OpenSim/Region/CoreModules/Agent/IPBan/IPBanModule.cs +++ b/OpenSim/Region/CoreModules/Agent/IPBan/IPBanModule.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Text; +using Mono.Addins; using Nini.Config; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; @@ -36,21 +37,27 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Agent.IPBan { - public class IPBanModule : IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class IPBanModule : ISharedRegionModule { - #region Implementation of IRegionModule + #region Implementation of ISharedRegionModule private List m_bans = new List(); + private Dictionary SceneBanners = new Dictionary(); - public void Initialise(Scene scene, IConfigSource source) + public void Initialise(IConfigSource source) { - new SceneBanner(scene, m_bans); + } + + public void AddRegion(Scene scene) + { + SceneBanners.Add(scene, new SceneBanner(scene, m_bans)); lock (m_bans) { foreach (EstateBan ban in scene.RegionInfo.EstateSettings.EstateBans) { - if (!String.IsNullOrEmpty(ban.BannedHostIPMask)) + if (!String.IsNullOrEmpty(ban.BannedHostIPMask)) m_bans.Add(ban.BannedHostIPMask); if (!String.IsNullOrEmpty(ban.BannedHostNameMask)) m_bans.Add(ban.BannedHostNameMask); @@ -58,7 +65,12 @@ namespace OpenSim.Region.CoreModules.Agent.IPBan } } - public void PostInitialise() + public Type ReplaceableInterface + { + get { return null; } + } + + public void RegionLoaded(Scene scene) { if (File.Exists("bans.txt")) { @@ -70,9 +82,18 @@ namespace OpenSim.Region.CoreModules.Agent.IPBan } } + public void RemoveRegion(Scene scene) + { + if(SceneBanners.ContainsKey(scene)) + SceneBanners.Remove(scene); + } + + public void PostInitialise() + { + } + public void Close() { - } public string Name @@ -80,11 +101,6 @@ namespace OpenSim.Region.CoreModules.Agent.IPBan get { return "IPBanModule"; } } - public bool IsSharedModule - { - get { return true; } - } - #endregion /// diff --git a/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureDownloadModule.cs b/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureDownloadModule.cs index 71ff28c8b5..c4d84cb51a 100644 --- a/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureDownloadModule.cs +++ b/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureDownloadModule.cs @@ -30,6 +30,7 @@ using System.Collections.Generic; using System.Reflection; using System.Threading; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -41,7 +42,8 @@ using OpenSim.Services.Interfaces; namespace OpenSim.Region.CoreModules.Agent.TextureDownload { - public class TextureDownloadModule : IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class TextureDownloadModule : INonSharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -65,11 +67,14 @@ namespace OpenSim.Region.CoreModules.Agent.TextureDownload { } - #region IRegionModule Members + #region INonSharedRegionModule Members - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) + { + } + + public void AddRegion(Scene scene) { - if (m_scene == null) { //m_log.Debug("Creating Texture download module"); @@ -90,8 +95,21 @@ namespace OpenSim.Region.CoreModules.Agent.TextureDownload } } - public void PostInitialise() + public Type ReplaceableInterface { + get { return null; } + } + + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + if(m_scenes.Contains(scene)) + m_scenes.Remove(scene); + scene.EventManager.OnNewClient -= NewClient; + scene.EventManager.OnRemovePresence -= EventManager_OnRemovePresence; } public void Close() @@ -103,11 +121,6 @@ namespace OpenSim.Region.CoreModules.Agent.TextureDownload get { return "TextureDownloadModule"; } } - public bool IsSharedModule - { - get { return false; } - } - #endregion /// diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs index 7ac8bed012..ff87493831 100644 --- a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs +++ b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs @@ -32,6 +32,7 @@ using System.Reflection; using System.Text; using System.Threading; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenMetaverse.Imaging; @@ -45,7 +46,8 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender { public delegate void J2KDecodeDelegate(UUID assetID); - public class J2KDecoderModule : IRegionModule, IJ2KDecoder + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class J2KDecoderModule : ISharedRegionModule, IJ2KDecoder { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -58,16 +60,19 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender /// Reference to a scene (doesn't matter which one as long as it can load the cache module) private Scene m_scene; - #region IRegionModule + #region ISharedRegionModule public string Name { get { return "J2KDecoderModule"; } } - public bool IsSharedModule { get { return true; } } - + public J2KDecoderModule() { } - public void Initialise(Scene scene, IConfigSource source) + public void Initialise(IConfigSource source) + { + } + + public void AddRegion(Scene scene) { if (m_scene == null) m_scene = scene; @@ -75,16 +80,30 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender scene.RegisterModuleInterface(this); } - public void PostInitialise() + public Type ReplaceableInterface + { + get { return null; } + } + + public void RegionLoaded(Scene scene) { m_cache = m_scene.RequestModuleInterface(); } + public void RemoveRegion(Scene scene) + { + scene.UnregisterModuleInterface(this); + } + + public void PostInitialise() + { + } + public void Close() { } - #endregion IRegionModule + #endregion #region IJ2KDecoder diff --git a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs index ef7dce812e..d062361b99 100644 --- a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs +++ b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -35,7 +36,8 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Agent.Xfer { - public class XferModule : IRegionModule, IXfer + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class XferModule : INonSharedRegionModule, IXfer { private Scene m_scene; private Dictionary Requests = new Dictionary(); @@ -52,9 +54,13 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer public DateTime timeStamp; } - #region IRegionModule Members + #region INonSharedRegionModule Members - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) + { + } + + public void AddRegion(Scene scene) { m_scene = scene; m_scene.EventManager.OnNewClient += NewClient; @@ -62,8 +68,19 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer m_scene.RegisterModuleInterface(this); } - public void PostInitialise() + public Type ReplaceableInterface { + get { return null; } + } + + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + scene.EventManager.OnNewClient -= NewClient; + scene.UnregisterModuleInterface(this); } public void Close() @@ -75,11 +92,6 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer get { return "XferModule"; } } - public bool IsSharedModule - { - get { return false; } - } - #endregion #region IXfer Members diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 35c59aa6d7..6bbbd56569 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -28,6 +28,7 @@ using System; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -38,7 +39,8 @@ using OpenSim.Services.Interfaces; namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory { - public class AvatarFactoryModule : IAvatarFactory, IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class AvatarFactoryModule : IAvatarFactory, ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene = null; @@ -75,7 +77,16 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory return appearance; } - public void Initialise(Scene scene, IConfigSource source) + public void Initialise(IConfigSource source) + { + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) { scene.RegisterModuleInterface(this); scene.EventManager.OnNewClient += NewClient; @@ -84,9 +95,18 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory { m_scene = scene; } - } + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + scene.UnregisterModuleInterface(this); + scene.EventManager.OnNewClient -= NewClient; + } + public void PostInitialise() { } @@ -100,11 +120,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory get { return "Default Avatar Factory"; } } - public bool IsSharedModule - { - get { return false; } - } - public void NewClient(IClientAPI client) { client.OnAvatarNowWearing += AvatarIsWearing; diff --git a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs index 61b6d65cc7..b7d12aa7e7 100644 --- a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using Mono.Addins; using Nini.Config; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -34,7 +35,8 @@ using OpenMetaverse; namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule { - public class CombatModule : IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class CombatModule : ISharedRegionModule { //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -53,7 +55,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule /// /// /// - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) + { + + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) { lock (m_scenel) { @@ -71,6 +83,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; } + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + scene.EventManager.OnAvatarKilled -= KillAvatar; + scene.EventManager.OnAvatarEnteringNewParcel -= AvatarEnteringParcel; + m_scenel.Remove(scene.RegionInfo.RegionHandle); + } + public void PostInitialise() { } @@ -84,11 +107,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule get { return "CombatModule"; } } - public bool IsSharedModule - { - get { return true; } - } - private void KillAvatar(uint killerObjectLocalID, ScenePresence DeadAvatar) { if (killerObjectLocalID == 0) diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs index 72ec869c48..ecffc7ab66 100644 --- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs @@ -25,9 +25,11 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; using System.Collections.Generic; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -37,28 +39,46 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Avatar.Dialog { - public class DialogModule : IRegionModule, IDialogModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class DialogModule : ISharedRegionModule, IDialogModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected Scene m_scene; - public void Initialise(Scene scene, IConfigSource source) + public void Initialise(IConfigSource source) + { + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) { m_scene = scene; m_scene.RegisterModuleInterface(this); - + m_scene.AddCommand( this, "alert", "alert ", "Send an alert to a user", HandleAlertConsoleCommand); m_scene.AddCommand( this, "alert general", "alert general ", "Send an alert to everyone", HandleAlertConsoleCommand); } - - public void PostInitialise() {} + + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + scene.UnregisterModuleInterface(this); + } + + public void PostInitialise() { } public void Close() {} public string Name { get { return "Dialog Module"; } } - public bool IsSharedModule { get { return false; } } public void SendAlertToUser(IClientAPI client, string message) { diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 086d4fe69a..7254180ab9 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -31,6 +31,7 @@ using System.Collections.Generic; using System.Net; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using Nwc.XmlRpc; using OpenMetaverse; @@ -81,7 +82,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends - Terminate Friendship messages (single) */ - public class FriendsModule : IRegionModule, IFriendsModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class FriendsModule : ISharedRegionModule, IFriendsModule { private class Transaction { @@ -111,9 +113,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends private IGridService m_gridServices = null; - #region IRegionModule Members + #region ISharedRegionModule Members - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) + { + + } + + public void PostInitialise() + { + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) { lock (m_scenes) { @@ -128,9 +144,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (!m_scenes.ContainsKey(scene.RegionInfo.RegionHandle)) m_scenes[scene.RegionInfo.RegionHandle] = scene; } - + scene.RegisterModuleInterface(this); - + scene.EventManager.OnNewClient += OnNewClient; scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; @@ -138,17 +154,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends scene.EventManager.OnClientClosed += ClientClosed; } - public void PostInitialise() + public void RegionLoaded(Scene scene) { if (m_scenes.Count > 0) { - m_TransferModule = m_initialScene.RequestModuleInterface(); - m_gridServices = m_initialScene.GridService; + m_TransferModule = scene.RequestModuleInterface(); + m_gridServices = scene.GridService; } if (m_TransferModule == null) m_log.Error("[FRIENDS]: Unable to find a message transfer module, friendship offers will not work"); } + public void RemoveRegion(Scene scene) + { + MainServer.Instance.RemoveXmlRPCHandler("presence_update_bulk"); + MainServer.Instance.RemoveXmlRPCHandler("terminate_friend"); + + if (m_scenes.ContainsKey(scene.RegionInfo.RegionHandle)) + m_scenes.Remove(scene.RegionInfo.RegionHandle); + + scene.UnregisterModuleInterface(this); + + scene.EventManager.OnNewClient -= OnNewClient; + scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; + scene.EventManager.OnAvatarEnteringNewParcel -= AvatarEnteringParcel; + scene.EventManager.OnMakeChildAgent -= MakeChildAgent; + scene.EventManager.OnClientClosed -= ClientClosed; + } + public void Close() { } @@ -158,11 +191,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends get { return "FriendsModule"; } } - public bool IsSharedModule - { - get { return true; } - } - #endregion #region IInterregionFriendsComms diff --git a/OpenSim/Region/CoreModules/Avatar/Gestures/GesturesModule.cs b/OpenSim/Region/CoreModules/Avatar/Gestures/GesturesModule.cs index 8ce509239d..c306f94e06 100644 --- a/OpenSim/Region/CoreModules/Avatar/Gestures/GesturesModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Gestures/GesturesModule.cs @@ -25,8 +25,10 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -37,23 +39,41 @@ using OpenSim.Services.Interfaces; namespace OpenSim.Region.CoreModules.Avatar.Gestures { - public class GesturesModule : IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class GesturesModule : INonSharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected Scene m_scene; - public void Initialise(Scene scene, IConfigSource source) + public void Initialise(IConfigSource source) + { + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) { m_scene = scene; - m_scene.EventManager.OnNewClient += OnNewClient; } + + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + if(m_scene == scene) + m_scene = null; + scene.EventManager.OnNewClient -= OnNewClient; + } - public void PostInitialise() {} public void Close() {} public string Name { get { return "Gestures Module"; } } - public bool IsSharedModule { get { return false; } } private void OnNewClient(IClientAPI client) { diff --git a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs index 50171a391e..3914f2efd1 100644 --- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs @@ -25,7 +25,9 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; using System.Collections.Generic; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -34,7 +36,8 @@ using OpenSim.Region.Framework.Interfaces; namespace OpenSim.Region.CoreModules.Avatar.Gods { - public class GodsModule : IRegionModule, IGodsModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class GodsModule : INonSharedRegionModule, IGodsModule { /// Special UUID for actions that apply to all agents private static readonly UUID ALL_AGENTS = new UUID("44e87126-e794-4ded-05b3-7c42da3d5cdb"); @@ -42,17 +45,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods protected Scene m_scene; protected IDialogModule m_dialogModule; - public void Initialise(Scene scene, IConfigSource source) + public void Initialise(IConfigSource source) + { + + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) { m_scene = scene; m_dialogModule = m_scene.RequestModuleInterface(); m_scene.RegisterModuleInterface(this); } + + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + scene.UnregisterModuleInterface(this); + } - public void PostInitialise() {} public void Close() {} public string Name { get { return "Gods Module"; } } - public bool IsSharedModule { get { return false; } } public void RequestGodlikePowers( UUID agentID, UUID sessionID, UUID token, bool godLike, IClientAPI controllingClient) diff --git a/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs b/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs index 31363e5705..7ff8d3000d 100644 --- a/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs @@ -25,9 +25,11 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; using System.Collections.Generic; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -36,7 +38,8 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Avatar.Groups { - public class GroupsModule : IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class GroupsModule : ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -55,9 +58,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups private static GroupMembershipData osGroup = new GroupMembershipData(); - #region IRegionModule Members + #region ISharedRegionModule Members - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { IConfig groupsConfig = config.Configs["Groups"]; @@ -76,7 +79,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups if (groupsConfig.GetString("Module", "Default") != "Default") return; } + } + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) + { lock (m_SceneList) { if (!m_SceneList.Contains(scene)) @@ -99,6 +110,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; } + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + if (m_SceneList.Contains(scene)) + m_SceneList.Remove(scene); + scene.EventManager.OnNewClient -= OnNewClient; + scene.EventManager.OnClientClosed -= OnClientClosed; + scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; + } + public void PostInitialise() { } @@ -123,11 +147,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups get { return "GroupsModule"; } } - public bool IsSharedModule - { - get { return true; } - } - #endregion private void OnNewClient(IClientAPI client) diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs index 9a6874909b..e1bde4b3b6 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs @@ -24,9 +24,12 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +using System; using System.Collections.Generic; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -36,7 +39,8 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Avatar.InstantMessage { - public class InstantMessageModule : IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class InstantMessageModule : ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -47,11 +51,11 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage private readonly List m_scenes = new List(); - #region IRegionModule Members + #region ISharedRegionModule Members private IMessageTransferModule m_TransferModule = null; - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { if (config.Configs["Messaging"] != null) { @@ -62,7 +66,15 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage } m_enabled = true; + } + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) + { lock (m_scenes) { if (!m_scenes.Contains(scene)) @@ -74,6 +86,27 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage } } + public void RegionLoaded(Scene scene) + { + if (!m_enabled) + return; + + m_TransferModule = + m_scenes[0].RequestModuleInterface(); + + if (m_TransferModule == null) + m_log.Error("[INSTANT MESSAGE]: No message transfer module, " + + "IM will not work!"); + } + + public void RemoveRegion(Scene scene) + { + if (m_scenes.Contains(scene)) + m_scenes.Remove(scene); + scene.EventManager.OnClientConnect -= OnClientConnect; + scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; + } + void OnClientConnect(IClientCore client) { IClientIM clientIM; @@ -85,15 +118,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage public void PostInitialise() { - if (!m_enabled) - return; - - m_TransferModule = - m_scenes[0].RequestModuleInterface(); - - if (m_TransferModule == null) - m_log.Error("[INSTANT MESSAGE]: No message transfer module, "+ - "IM will not work!"); } public void Close() @@ -105,11 +129,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage get { return "InstantMessageModule"; } } - public bool IsSharedModule - { - get { return true; } - } - #endregion public void OnInstantMessage(IClientAPI client, GridInstantMessage im) diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs index e5159b3817..16bdfddea7 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs @@ -30,6 +30,7 @@ using System.Collections.Generic; using System.Net; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using Nwc.XmlRpc; using OpenMetaverse; @@ -40,7 +41,8 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion; namespace OpenSim.Region.CoreModules.Avatar.InstantMessage { - public class MessageTransferModule : IRegionModule, IMessageTransferModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class MessageTransferModule : ISharedRegionModule, IMessageTransferModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -50,8 +52,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage protected Dictionary m_UserRegionMap = new Dictionary(); public event UndeliveredMessage OnUndeliveredMessage; + private bool m_enabled = true; - public virtual void Initialise(Scene scene, IConfigSource config) + public virtual void Initialise(IConfigSource config) { IConfig cnf = config.Configs["Messaging"]; if (cnf != null && cnf.GetString( @@ -59,29 +62,51 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage "MessageTransferModule") { m_log.Debug("[MESSAGE TRANSFER]: Disabled by configuration"); - return; + m_enabled = false; } cnf = config.Configs["Startup"]; if (cnf != null) m_Gridmode = cnf.GetBoolean("gridmode", false); + } - // m_Enabled = true; + public Type ReplaceableInterface + { + get { return null; } + } - lock (m_Scenes) + public void AddRegion(Scene scene) + { + if (m_enabled) { - if (m_Scenes.Count == 0) + lock (m_Scenes) { - MainServer.Instance.AddXmlRPCHandler( - "grid_instant_message", processXMLRPCGridInstantMessage); - } + if (m_Scenes.Count == 0) + { + MainServer.Instance.AddXmlRPCHandler( + "grid_instant_message", processXMLRPCGridInstantMessage); + } - m_log.Debug("[MESSAGE TRANSFER]: Message transfer module active"); - scene.RegisterModuleInterface(this); - m_Scenes.Add(scene); + m_log.Debug("[MESSAGE TRANSFER]: Message transfer module active"); + scene.RegisterModuleInterface(this); + m_Scenes.Add(scene); + } } } + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + if (m_Scenes.Contains(scene)) + m_Scenes.Remove(scene); + MainServer.Instance.RemoveXmlRPCHandler( + "grid_instant_message"); + scene.UnregisterModuleInterface(this); + } + public virtual void PostInitialise() { } @@ -95,11 +120,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage get { return "MessageTransferModule"; } } - public virtual bool IsSharedModule - { - get { return true; } - } - public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result) { UUID toAgentID = new UUID(im.toAgentID); diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs index 2d4a635056..3570495796 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs @@ -28,6 +28,7 @@ using System; using System.Collections.Generic; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -39,7 +40,8 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Avatar.MuteList { - public class MuteListModule : IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class MuteListModule : ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -47,7 +49,7 @@ namespace OpenSim.Region.CoreModules.Avatar.MuteList private List m_SceneList = new List(); private string m_RestURL = String.Empty; - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { if (!enabled) return; @@ -66,19 +68,24 @@ namespace OpenSim.Region.CoreModules.Avatar.MuteList enabled = false; return; } + m_RestURL = cnf.GetString("MuteListURL", ""); + if (m_RestURL == "") + { + m_log.Error("[MUTE LIST] Module was enabled, but no URL is given, disabling"); + enabled = false; + return; + } + } + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) + { lock (m_SceneList) { - if (m_SceneList.Count == 0) - { - m_RestURL = cnf.GetString("MuteListURL", ""); - if (m_RestURL == "") - { - m_log.Error("[MUTE LIST] Module was enabled, but no URL is given, disabling"); - enabled = false; - return; - } - } if (!m_SceneList.Contains(scene)) m_SceneList.Add(scene); @@ -86,6 +93,18 @@ namespace OpenSim.Region.CoreModules.Avatar.MuteList } } + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + if (m_SceneList.Contains(scene)) + m_SceneList.Remove(scene); + + scene.EventManager.OnNewClient -= OnNewClient; + } + public void PostInitialise() { if (!enabled) @@ -102,11 +121,6 @@ namespace OpenSim.Region.CoreModules.Avatar.MuteList get { return "MuteListModule"; } } - public bool IsSharedModule - { - get { return true; } - } - public void Close() { } diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs index 450897c77e..6c4d0bfcf4 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs @@ -28,6 +28,7 @@ using System; using System.Collections.Generic; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -40,7 +41,8 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Avatar.InstantMessage { - public class OfflineMessageModule : IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class OfflineMessageModule : ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -49,7 +51,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage private string m_RestURL = String.Empty; private bool m_ForwardOfflineGroupMessages = true; - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { if (!enabled) return; @@ -83,14 +85,23 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage return; } } - if (!m_SceneList.Contains(scene)) - m_SceneList.Add(scene); - - scene.EventManager.OnNewClient += OnNewClient; } } - public void PostInitialise() + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) + { + if (!m_SceneList.Contains(scene)) + m_SceneList.Add(scene); + + scene.EventManager.OnNewClient += OnNewClient; + } + + public void RegionLoaded(Scene scene) { if (!enabled) return; @@ -120,16 +131,22 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage m_log.Debug("[OFFLINE MESSAGING] Offline messages enabled"); } + public void RemoveRegion(Scene scene) + { + if (m_SceneList.Contains(scene)) + m_SceneList.Remove(scene); + scene.EventManager.OnNewClient -= OnNewClient; + } + + public void PostInitialise() + { + } + public string Name { get { return "OfflineMessageModule"; } } - public bool IsSharedModule - { - get { return true; } - } - public void Close() { } @@ -163,24 +180,27 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage private void RetrieveInstantMessages(IClientAPI client) { - m_log.DebugFormat("[OFFLINE MESSAGING] Retrieving stored messages for {0}", client.AgentId); - - Listmsglist = SynchronousRestObjectPoster.BeginPostObject>( - "POST", m_RestURL+"/RetrieveMessages/", client.AgentId); - - foreach (GridInstantMessage im in msglist) + if (m_RestURL != "") { - // client.SendInstantMessage(im); + m_log.DebugFormat("[OFFLINE MESSAGING] Retrieving stored messages for {0}", client.AgentId); - // Send through scene event manager so all modules get a chance - // to look at this message before it gets delivered. - // - // Needed for proper state management for stored group - // invitations - // - Scene s = FindScene(client.AgentId); - if (s != null) - s.EventManager.TriggerIncomingInstantMessage(im); + List msglist = SynchronousRestObjectPoster.BeginPostObject>( + "POST", m_RestURL + "/RetrieveMessages/", client.AgentId); + + foreach (GridInstantMessage im in msglist) + { + // client.SendInstantMessage(im); + + // Send through scene event manager so all modules get a chance + // to look at this message before it gets delivered. + // + // Needed for proper state management for stored group + // invitations + // + Scene s = FindScene(client.AgentId); + if (s != null) + s.EventManager.TriggerIncomingInstantMessage(im); + } } } diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs index f5ab45466c..f5498f42e1 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs @@ -24,11 +24,14 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +using System; using System.Collections; using System.Collections.Generic; using System.Net; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using Nwc.XmlRpc; using OpenMetaverse; @@ -39,7 +42,8 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion; namespace OpenSim.Region.CoreModules.Avatar.InstantMessage { - public class PresenceModule : IRegionModule, IPresenceModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class PresenceModule : ISharedRegionModule, IPresenceModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -59,7 +63,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage public event PresenceChange OnPresenceChange; public event BulkPresenceData OnBulkPresenceData; - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { lock (m_Scenes) { @@ -78,28 +82,38 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage m_Gridmode = cnf.GetBoolean("gridmode", false); m_Enabled = true; - - m_initialScene = scene; } + } + } + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) + { + if (m_Enabled) + { + m_initialScene = scene; if (m_Gridmode) NotifyMessageServerOfStartup(scene); m_Scenes.Add(scene); + + scene.RegisterModuleInterface(this); + + scene.EventManager.OnNewClient += OnNewClient; + scene.EventManager.OnSetRootAgentScene += OnSetRootAgentScene; + scene.EventManager.OnMakeChildAgent += OnMakeChildAgent; } - - scene.RegisterModuleInterface(this); - - scene.EventManager.OnNewClient += OnNewClient; - scene.EventManager.OnSetRootAgentScene += OnSetRootAgentScene; - scene.EventManager.OnMakeChildAgent += OnMakeChildAgent; } - public void PostInitialise() + public void RegionLoaded(Scene scene) { } - public void Close() + public void RemoveRegion(Scene scene) { if (!m_Gridmode || !m_Enabled) return; @@ -116,11 +130,23 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage } } - lock (m_Scenes) - { - foreach (Scene scene in m_Scenes) - NotifyMessageServerOfShutdown(scene); - } + NotifyMessageServerOfShutdown(scene); + if(m_Scenes.Contains(scene)) + m_Scenes.Remove(scene); + + scene.UnregisterModuleInterface(this); + + scene.EventManager.OnNewClient -= OnNewClient; + scene.EventManager.OnSetRootAgentScene -= OnSetRootAgentScene; + scene.EventManager.OnMakeChildAgent -= OnMakeChildAgent; + } + + public void PostInitialise() + { + } + + public void Close() + { } public string Name @@ -128,11 +154,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage get { return "PresenceModule"; } } - public bool IsSharedModule - { - get { return true; } - } - public void RequestBulkPresenceData(UUID[] users) { if (OnBulkPresenceData != null) diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs index ecd60bdaad..a04ab22588 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs @@ -30,6 +30,7 @@ using System.Collections.Generic; using System.IO; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -41,10 +42,11 @@ using OpenSim.Services.Interfaces; namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver { + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] /// /// This module loads and saves OpenSimulator inventory archives /// - public class InventoryArchiverModule : IRegionModule, IInventoryArchiverModule + public class InventoryArchiverModule : ISharedRegionModule, IInventoryArchiverModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -82,18 +84,28 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver DisablePresenceChecks = disablePresenceChecks; } - public void Initialise(Scene scene, IConfigSource source) + public void Initialise(IConfigSource source) + { + + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) { if (m_scenes.Count == 0) { scene.RegisterModuleInterface(this); OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted; - + scene.AddCommand( this, "load iar", "load iar []", - "Load user inventory archive.", HandleLoadInvConsoleCommand); - + "Load user inventory archive.", HandleLoadInvConsoleCommand); + scene.AddCommand( this, "save iar", "save iar []", @@ -101,10 +113,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver m_aScene = scene; } - + m_scenes[scene.RegionInfo.RegionID] = scene; } + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + scene.UnregisterModuleInterface(this); + if(m_scenes.ContainsKey(scene.RegionInfo.RegionID)) + m_scenes.Remove(scene.RegionInfo.RegionID); + } + public void PostInitialise() {} public void Close() {} diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index d9a021fc02..44906b4afa 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -39,7 +40,8 @@ using OpenSim.Services.Interfaces; namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer { - public class InventoryTransferModule : IInventoryTransferModule, IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class InventoryTransferModule : IInventoryTransferModule, ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -50,10 +52,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer new Dictionary(); private IMessageTransferModule m_TransferModule = null; + private bool m_enabled = true; - #region IRegionModule Members + #region ISharedRegionModule Members - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { if (config.Configs["Messaging"] != null) { @@ -62,29 +65,59 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer if (config.Configs["Messaging"].GetString( "InventoryTransferModule", "InventoryTransferModule") != "InventoryTransferModule") - return; + m_enabled = false; } + } - if (!m_Scenelist.Contains(scene)) + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) + { + if (m_enabled) { - m_Scenelist.Add(scene); + if (!m_Scenelist.Contains(scene)) + { + m_Scenelist.Add(scene); - scene.RegisterModuleInterface(this); + scene.RegisterModuleInterface(this); - scene.EventManager.OnNewClient += OnNewClient; - scene.EventManager.OnClientClosed += ClientLoggedOut; - scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; + scene.EventManager.OnNewClient += OnNewClient; + scene.EventManager.OnClientClosed += ClientLoggedOut; + scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; + } } } + public void RegionLoaded(Scene scene) + { + if (m_enabled) + { + if (m_Scenelist.Count > 0) + { + m_TransferModule = m_Scenelist[0].RequestModuleInterface(); + if (m_TransferModule == null) + m_log.Error("[INVENTORY TRANSFER] No Message transfer module found, transfers will be local only"); + } + } + } + + public void RemoveRegion(Scene scene) + { + if (m_Scenelist.Contains(scene)) + m_Scenelist.Remove(scene); + + scene.UnregisterModuleInterface(this); + + scene.EventManager.OnNewClient -= OnNewClient; + scene.EventManager.OnClientClosed -= ClientLoggedOut; + scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; + } + public void PostInitialise() { - if (m_Scenelist.Count > 0) - { - m_TransferModule = m_Scenelist[0].RequestModuleInterface(); - if (m_TransferModule == null) - m_log.Error("[INVENTORY TRANSFER] No Message transfer module found, transfers will be local only"); - } } public void Close() diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs index 261bd6c609..973d27fd24 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -37,36 +38,72 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Avatar.Lure { - public class LureModule : IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class LureModule : ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private readonly List m_scenes = new List(); + private bool m_enabled = true; + private IMessageTransferModule m_TransferModule = null; - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { if (config.Configs["Messaging"] != null) { if (config.Configs["Messaging"].GetString( "LureModule", "LureModule") != "LureModule") - return; + m_enabled = false; } + } - lock (m_scenes) + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) + { + if (m_enabled) { - if (!m_scenes.Contains(scene)) + lock (m_scenes) { - m_scenes.Add(scene); - scene.EventManager.OnNewClient += OnNewClient; - scene.EventManager.OnIncomingInstantMessage += - OnGridInstantMessage; + if (!m_scenes.Contains(scene)) + { + m_scenes.Add(scene); + scene.EventManager.OnNewClient += OnNewClient; + scene.EventManager.OnIncomingInstantMessage += + OnGridInstantMessage; + } } } } + public void RegionLoaded(Scene scene) + { + if (m_enabled) + { + m_TransferModule = + m_scenes[0].RequestModuleInterface(); + + if (m_TransferModule == null) + m_log.Error("[INSTANT MESSAGE]: No message transfer module, " + + "lures will not work!"); + } + } + + public void RemoveRegion(Scene scene) + { + if (m_scenes.Contains(scene)) + m_scenes.Remove(scene); + scene.EventManager.OnNewClient -= OnNewClient; + scene.EventManager.OnIncomingInstantMessage -= + OnGridInstantMessage; + } + void OnNewClient(IClientAPI client) { client.OnInstantMessage += OnInstantMessage; @@ -76,12 +113,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure public void PostInitialise() { - m_TransferModule = - m_scenes[0].RequestModuleInterface(); - - if (m_TransferModule == null) - m_log.Error("[INSTANT MESSAGE]: No message transfer module, "+ - "lures will not work!"); } public void Close() diff --git a/OpenSim/Region/CoreModules/Avatar/ObjectCaps/ObjectAdd.cs b/OpenSim/Region/CoreModules/Avatar/ObjectCaps/ObjectAdd.cs index 63a93aa026..748b42c5f3 100644 --- a/OpenSim/Region/CoreModules/Avatar/ObjectCaps/ObjectAdd.cs +++ b/OpenSim/Region/CoreModules/Avatar/ObjectCaps/ObjectAdd.cs @@ -29,6 +29,7 @@ using System; using System.Collections; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenMetaverse.StructuredData; @@ -41,24 +42,54 @@ using Caps=OpenSim.Framework.Capabilities.Caps; namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps { - public class ObjectAdd : IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class ObjectAdd : ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; - #region IRegionModule Members + #region ISharedRegionModule Members - public void Initialise(Scene pScene, IConfigSource pSource) + public void Initialise(IConfigSource pSource) { - m_scene = pScene; + + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) + { + m_scene = scene; m_scene.EventManager.OnRegisterCaps += RegisterCaps; } + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + scene.EventManager.OnRegisterCaps -= RegisterCaps; + } + public void PostInitialise() { } + public void Close() + { + + } + + public string Name + { + get { return "ObjectAddModule"; } + } + public void RegisterCaps(UUID agentID, Caps caps) { UUID capuuid = UUID.Random(); @@ -348,22 +379,6 @@ namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps Array.Reverse(resultbytes); return String.Format("{0}",Convert.ToBase64String(resultbytes)); } - - public void Close() - { - - } - - public string Name - { - get { return "ObjectAddModule"; } - } - - public bool IsSharedModule - { - get { return false; } - } - #endregion } } diff --git a/OpenSim/Region/CoreModules/Avatar/Profiles/AvatarProfilesModule.cs b/OpenSim/Region/CoreModules/Avatar/Profiles/AvatarProfilesModule.cs index 8cf58c6df0..7fcb0e13cf 100644 --- a/OpenSim/Region/CoreModules/Avatar/Profiles/AvatarProfilesModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Profiles/AvatarProfilesModule.cs @@ -30,6 +30,7 @@ using System.Collections; using System.Globalization; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -38,20 +39,17 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Avatar.Profiles { - public class AvatarProfilesModule : IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class AvatarProfilesModule : INonSharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; private IProfileModule m_profileModule = null; private bool m_enabled = true; - public AvatarProfilesModule() - { - } + #region INonSharedRegionModule Members - #region IRegionModule Members - - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { IConfig profileConfig = config.Configs["Profile"]; if (profileConfig != null) @@ -62,18 +60,31 @@ namespace OpenSim.Region.CoreModules.Avatar.Profiles return; } } + } + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) + { m_scene = scene; m_scene.EventManager.OnNewClient += NewClient; } - public void PostInitialise() + public void RegionLoaded(Scene scene) { if (!m_enabled) return; m_profileModule = m_scene.RequestModuleInterface(); } + public void RemoveRegion(Scene scene) + { + scene.EventManager.OnNewClient -= NewClient; + } + public void Close() { } @@ -83,11 +94,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Profiles get { return "AvatarProfilesModule"; } } - public bool IsSharedModule - { - get { return false; } - } - #endregion public void NewClient(IClientAPI client) diff --git a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs index 0c6cb1bdfa..1ee6f0d322 100644 --- a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs @@ -32,6 +32,7 @@ using System.Net; using System.Reflection; using System.Threading; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenMetaverse.Packets; @@ -52,11 +53,13 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue public OSDMap body; } - public class EventQueueGetModule : IEventQueue, IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class EventQueueGetModule : IEventQueue, INonSharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected Scene m_scene = null; private IConfigSource m_gConfig; + private IConfig m_startupConfig; bool enabledYN = false; private Dictionary m_ids = new Dictionary(); @@ -65,23 +68,31 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue private Dictionary m_QueueUUIDAvatarMapping = new Dictionary(); private Dictionary m_AvatarQueueUUIDMapping = new Dictionary(); - #region IRegionModule methods - public virtual void Initialise(Scene scene, IConfigSource config) + #region INonSharedRegionModule methods + public virtual void Initialise(IConfigSource config) { m_gConfig = config; - IConfig startupConfig = m_gConfig.Configs["Startup"]; + m_startupConfig = m_gConfig.Configs["Startup"]; + } - ReadConfigAndPopulate(scene, startupConfig, "Startup"); + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) + { + ReadConfigAndPopulate(scene, m_startupConfig, "Startup"); if (enabledYN) { m_scene = scene; scene.RegisterModuleInterface(this); - + // Register fallback handler // Why does EQG Fail on region crossings! - + //scene.CommsManager.HttpServer.AddLLSDHandler("/CAPS/EQG/", EventQueueFallBack); scene.EventManager.OnNewClient += OnNewClient; @@ -99,7 +110,14 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue { m_gConfig = null; } - + } + + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { } private void ReadConfigAndPopulate(Scene scene, IConfig startupConfig, string p) @@ -107,10 +125,6 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue enabledYN = startupConfig.GetBoolean("EventQueue", true); } - public void PostInitialise() - { - } - public virtual void Close() { } @@ -120,10 +134,6 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue get { return "EventQueueGetModule"; } } - public bool IsSharedModule - { - get { return false; } - } #endregion /// diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs index f15f8f6de1..0135d3359b 100644 --- a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs @@ -25,10 +25,12 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; using System.Collections; using System.Collections.Generic; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -39,7 +41,8 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Framework.Monitoring { - public class MonitorModule : IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class MonitorModule : INonSharedRegionModule { private Scene m_scene; private readonly List m_monitors = new List(); @@ -62,9 +65,19 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring } } - #region Implementation of IRegionModule + #region Implementation of INonSharedRegionModule - public void Initialise(Scene scene, IConfigSource source) + public void Initialise(IConfigSource source) + { + + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) { m_scene = scene; @@ -77,6 +90,51 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring MainServer.Instance.AddHTTPHandler("/monitorstats/" + m_scene.RegionInfo.RegionID + "/", StatsPage); } + public void RegionLoaded(Scene scene) + { + m_monitors.Add(new AgentCountMonitor(m_scene)); + m_monitors.Add(new ChildAgentCountMonitor(m_scene)); + m_monitors.Add(new GCMemoryMonitor()); + m_monitors.Add(new ObjectCountMonitor(m_scene)); + m_monitors.Add(new PhysicsFrameMonitor(m_scene)); + m_monitors.Add(new PhysicsUpdateFrameMonitor(m_scene)); + m_monitors.Add(new PWSMemoryMonitor()); + m_monitors.Add(new ThreadCountMonitor()); + m_monitors.Add(new TotalFrameMonitor(m_scene)); + m_monitors.Add(new EventFrameMonitor(m_scene)); + m_monitors.Add(new LandFrameMonitor(m_scene)); + m_monitors.Add(new LastFrameTimeMonitor(m_scene)); + + m_alerts.Add(new DeadlockAlert(m_monitors.Find(x => x is LastFrameTimeMonitor) as LastFrameTimeMonitor)); + + foreach (IAlert alert in m_alerts) + { + alert.OnTriggerAlert += OnTriggerAlert; + } + } + + public void RemoveRegion(Scene scene) + { + MainServer.Instance.RemoveHTTPHandler("", "/monitorstats/" + m_scene.RegionInfo.RegionID + "/"); + m_monitors.Clear(); + + foreach (IAlert alert in m_alerts) + { + alert.OnTriggerAlert -= OnTriggerAlert; + } + m_alerts.Clear(); + } + + public void Close() + { + + } + + public string Name + { + get { return "Region Health Monitoring Module"; } + } + public Hashtable StatsPage(Hashtable request) { // If request was for a specific monitor @@ -132,49 +190,10 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring return ereply; } - public void PostInitialise() - { - m_monitors.Add(new AgentCountMonitor(m_scene)); - m_monitors.Add(new ChildAgentCountMonitor(m_scene)); - m_monitors.Add(new GCMemoryMonitor()); - m_monitors.Add(new ObjectCountMonitor(m_scene)); - m_monitors.Add(new PhysicsFrameMonitor(m_scene)); - m_monitors.Add(new PhysicsUpdateFrameMonitor(m_scene)); - m_monitors.Add(new PWSMemoryMonitor()); - m_monitors.Add(new ThreadCountMonitor()); - m_monitors.Add(new TotalFrameMonitor(m_scene)); - m_monitors.Add(new EventFrameMonitor(m_scene)); - m_monitors.Add(new LandFrameMonitor(m_scene)); - m_monitors.Add(new LastFrameTimeMonitor(m_scene)); - - m_alerts.Add(new DeadlockAlert(m_monitors.Find(x => x is LastFrameTimeMonitor) as LastFrameTimeMonitor)); - - foreach (IAlert alert in m_alerts) - { - alert.OnTriggerAlert += OnTriggerAlert; - } - } - void OnTriggerAlert(System.Type reporter, string reason, bool fatal) { m_log.Error("[Monitor] " + reporter.Name + " for " + m_scene.RegionInfo.RegionName + " reports " + reason + " (Fatal: " + fatal + ")"); } - - public void Close() - { - - } - - public string Name - { - get { return "Region Health Monitoring Module"; } - } - - public bool IsSharedModule - { - get { return false; } - } - #endregion } } diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs index 0b54746f19..f9c594b800 100644 --- a/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs +++ b/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -32,6 +32,7 @@ using System.Net; using System.Reflection; using System.Text.RegularExpressions; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using Nwc.XmlRpc; @@ -46,7 +47,8 @@ using OpenSim.Region.Framework.Interfaces; namespace OpenSim.Region.CoreModules.Hypergrid { - public class HGStandaloneLoginModule : IRegionModule, ILoginServiceToRegionsConnector + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class HGStandaloneLoginModule : ISharedRegionModule, ILoginServiceToRegionsConnector { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -56,47 +58,58 @@ namespace OpenSim.Region.CoreModules.Hypergrid protected bool m_enabled = false; // Module is only enabled if running in standalone mode protected HGLoginAuthService m_loginService; + private bool authenticate = true; + private string welcomeMessage = "Welcome to OpenSim"; + private IConfig startupConfig; + private IConfig standaloneConfig; + + #region ISharedRegionModule Members - #region IRegionModule Members + public void Initialise(IConfigSource source) + { + startupConfig = source.Configs["Startup"]; + standaloneConfig = source.Configs["StandAlone"]; + if (standaloneConfig != null) + { + authenticate = standaloneConfig.GetBoolean("accounts_authenticate", true); + welcomeMessage = standaloneConfig.GetString("welcome_message"); + } + m_enabled = !startupConfig.GetBoolean("gridmode", false); + } - public void Initialise(Scene scene, IConfigSource source) + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) + { + } + + public void RegionLoaded(Scene scene) { if (m_firstScene == null) { m_firstScene = scene; - IConfig startupConfig = source.Configs["Startup"]; - if (startupConfig != null) - { - m_enabled = !startupConfig.GetBoolean("gridmode", false); - } - if (m_enabled) { m_log.Debug("[HGLogin]: HGlogin module enabled"); - bool authenticate = true; - string welcomeMessage = "Welcome to OpenSim"; - IConfig standaloneConfig = source.Configs["StandAlone"]; - if (standaloneConfig != null) - { - authenticate = standaloneConfig.GetBoolean("accounts_authenticate", true); - welcomeMessage = standaloneConfig.GetString("welcome_message"); - } //TODO: fix casting. LibraryRootFolder rootFolder = m_firstScene.CommsManager.UserProfileCacheService.LibraryRoot as LibraryRootFolder; - + IHttpServer httpServer = MainServer.Instance; //TODO: fix the casting of the user service, maybe by registering the userManagerBase with scenes, or refactoring so we just need a IUserService reference - m_loginService + m_loginService = new HGLoginAuthService( - (UserManagerBase)m_firstScene.CommsManager.UserAdminService, - welcomeMessage, - m_firstScene.CommsManager.InterServiceInventoryService, - m_firstScene.CommsManager.NetworkServersInfo, - authenticate, - rootFolder, + (UserManagerBase)m_firstScene.CommsManager.UserAdminService, + welcomeMessage, + m_firstScene.CommsManager.InterServiceInventoryService, + m_firstScene.CommsManager.NetworkServersInfo, + authenticate, + rootFolder, this); httpServer.AddXmlRPCHandler("hg_login", m_loginService.XmlRpcLoginMethod); @@ -113,6 +126,19 @@ namespace OpenSim.Region.CoreModules.Hypergrid } } + public void RemoveRegion(Scene scene) + { + if (scene == m_firstScene) + { + IHttpServer httpServer = MainServer.Instance; + httpServer.RemoveXmlRPCHandler("hg_login"); + httpServer.RemoveXmlRPCHandler("check_auth_session"); + httpServer.RemoveXmlRPCHandler("get_avatar_appearance"); + httpServer.RemoveXmlRPCHandler("update_avatar_appearance"); + } + m_scenes.Remove(scene); + } + public void PostInitialise() { @@ -128,11 +154,6 @@ namespace OpenSim.Region.CoreModules.Hypergrid get { return "HGStandaloneLoginModule"; } } - public bool IsSharedModule - { - get { return true; } - } - #endregion protected void AddScene(Scene scene) diff --git a/OpenSim/Region/CoreModules/InterGrid/OGSRadmin.cs b/OpenSim/Region/CoreModules/InterGrid/OGSRadmin.cs index 0f2ba324e0..45340241cb 100644 --- a/OpenSim/Region/CoreModules/InterGrid/OGSRadmin.cs +++ b/OpenSim/Region/CoreModules/InterGrid/OGSRadmin.cs @@ -32,6 +32,7 @@ using System.Net; using System.Reflection; using System.Text; using log4net; +using Mono.Addins; using Nini.Config; using Nwc.XmlRpc; using OpenMetaverse; @@ -42,7 +43,8 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.InterGrid { - public class OGSRadmin : IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class OGSRadmin : ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private readonly List m_scenes = new List(); @@ -56,7 +58,6 @@ namespace OpenSim.Region.CoreModules.InterGrid get { return "OGS Supporting RAdmin"; } } - public void Initialise(IConfigSource source) { m_settings = source; @@ -67,6 +68,11 @@ namespace OpenSim.Region.CoreModules.InterGrid } + public Type ReplaceableInterface + { + get { return null; } + } + public void AddRegion(Scene scene) { lock (m_scenes) @@ -77,14 +83,10 @@ namespace OpenSim.Region.CoreModules.InterGrid { lock (m_scenes) m_scenes.Remove(scene); + MainServer.Instance.RemoveXmlRPCHandler("grid_message"); } public void RegionLoaded(Scene scene) - { - - } - - public void PostInitialise() { if (m_settings.Configs["Startup"].GetBoolean("gridmode", false)) { @@ -93,21 +95,8 @@ namespace OpenSim.Region.CoreModules.InterGrid } } - #endregion - - #region IRegionModule - - public void Initialise(Scene scene, IConfigSource source) + public void PostInitialise() { - m_settings = source; - - lock (m_scenes) - m_scenes.Add(scene); - } - - public bool IsSharedModule - { - get { return true; } } #endregion diff --git a/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs b/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs index 10a3232019..8bb0fa9bd2 100644 --- a/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs +++ b/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs @@ -35,6 +35,7 @@ using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Web; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenMetaverse.StructuredData; @@ -75,8 +76,9 @@ namespace OpenSim.Region.CoreModules.InterGrid public bool visible_to_parent; public string teleported_into_region; } - - public class OpenGridProtocolModule : IRegionModule + + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class OpenGridProtocolModule : ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private List m_scene = new List(); @@ -92,21 +94,22 @@ namespace OpenSim.Region.CoreModules.InterGrid private bool httpSSL = false; private uint httpsslport = 0; private bool GridMode = false; + private bool m_enabled = false; + private IConfig cfg = null; + private IConfig httpcfg = null; + private IConfig startupcfg = null; + + #region ISharedRegionModule Members - #region IRegionModule Members - - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { - bool enabled = false; - IConfig cfg = null; - IConfig httpcfg = null; - IConfig startupcfg = null; try { cfg = config.Configs["OpenGridProtocol"]; - } catch (NullReferenceException) + } + catch (NullReferenceException) { - enabled = false; + m_enabled = false; } try @@ -128,15 +131,15 @@ namespace OpenSim.Region.CoreModules.InterGrid if (startupcfg != null) { - GridMode = enabled = startupcfg.GetBoolean("gridmode", false); + GridMode = m_enabled = startupcfg.GetBoolean("gridmode", false); } if (cfg != null) { - enabled = cfg.GetBoolean("ogp_enabled", false); + m_enabled = cfg.GetBoolean("ogp_enabled", false); LastNameSuffix = cfg.GetString("ogp_lastname_suffix", "_EXTERNAL"); FirstNamePrefix = cfg.GetString("ogp_firstname_prefix", ""); - if (enabled) + if (m_enabled) { m_log.Warn("[OGP]: Open Grid Protocol is on, Listening for Clients on /agent/"); lock (m_scene) @@ -165,35 +168,61 @@ namespace OpenSim.Region.CoreModules.InterGrid } } - // can't pick the region 'agent' because it would conflict with our agent domain handler - // a zero length region name would conflict with are base region seed cap - if (!SceneListDuplicateCheck(scene.RegionInfo.RegionName) && scene.RegionInfo.RegionName.ToLower() != "agent" && scene.RegionInfo.RegionName.Length > 0) - { - MainServer.Instance.AddLLSDHandler( - "/" + HttpUtility.UrlPathEncode(scene.RegionInfo.RegionName.ToLower()), - ProcessRegionDomainSeed); - } + } + } + } + } - if (!m_scene.Contains(scene)) - m_scene.Add(scene); - } - } - } - lock (m_scene) + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) + { + if (m_enabled) { - if (m_scene.Count == 1) + lock (m_scene) { - if (httpcfg != null) + if (m_scene.Count == 1) { - httpSSL = httpcfg.GetBoolean("http_listener_ssl", false); - httpsCN = httpcfg.GetString("http_listener_cn", scene.RegionInfo.ExternalHostName); - if (httpsCN.Length == 0) - httpsCN = scene.RegionInfo.ExternalHostName; - httpsslport = (uint)httpcfg.GetInt("http_listener_sslport",((int)scene.RegionInfo.HttpPort + 1)); + if (httpcfg != null) + { + httpSSL = httpcfg.GetBoolean("http_listener_ssl", false); + httpsCN = httpcfg.GetString("http_listener_cn", scene.RegionInfo.ExternalHostName); + if (httpsCN.Length == 0) + httpsCN = scene.RegionInfo.ExternalHostName; + httpsslport = (uint)httpcfg.GetInt("http_listener_sslport", ((int)scene.RegionInfo.HttpPort + 1)); + } } } + // can't pick the region 'agent' because it would conflict with our agent domain handler + // a zero length region name would conflict with are base region seed cap + if (!SceneListDuplicateCheck(scene.RegionInfo.RegionName) && scene.RegionInfo.RegionName.ToLower() != "agent" && scene.RegionInfo.RegionName.Length > 0) + { + MainServer.Instance.AddLLSDHandler( + "/" + HttpUtility.UrlPathEncode(scene.RegionInfo.RegionName.ToLower()), + ProcessRegionDomainSeed); + } + + if (!m_scene.Contains(scene)) + m_scene.Add(scene); } } + + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + MainServer.Instance.RemoveLLSDHandler( + "/" + HttpUtility.UrlPathEncode(scene.RegionInfo.RegionName.ToLower()), + ProcessRegionDomainSeed); + + if (m_scene.Contains(scene)) + m_scene.Remove(scene); + } public void PostInitialise() { @@ -209,11 +238,6 @@ namespace OpenSim.Region.CoreModules.InterGrid get { return "OpenGridProtocolModule"; } } - public bool IsSharedModule - { - get { return true; } - } - #endregion public OSD ProcessRegionDomainSeed(string path, OSD request, string endpoint) diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index 679c871441..40b715955a 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenMetaverse.Imaging; @@ -40,7 +41,8 @@ using System.Reflection; namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture { - public class DynamicTextureModule : IRegionModule, IDynamicTextureManager + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class DynamicTextureModule : ISharedRegionModule, IDynamicTextureManager { //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -210,9 +212,14 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture #endregion - #region IRegionModule Members + #region ISharedRegionModule Members - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) + { + + } + + public void AddRegion(Scene scene) { if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) { @@ -221,6 +228,24 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture } } + public Type ReplaceableInterface + { + get { return null; } + } + + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) + { + RegisteredScenes.Remove(scene.RegionInfo.RegionID); + scene.UnregisterModuleInterface(this); + } + } + public void PostInitialise() { } @@ -234,11 +259,6 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture get { return "DynamicTextureModule"; } } - public bool IsSharedModule - { - get { return true; } - } - #endregion #region Nested type: DynamicTextureUpdater @@ -358,18 +378,18 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture // tmptex.DefaultTexture.Fullbright = true; part.UpdateTexture(tmptex); - } - - if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0)) - { - if (oldAsset == null) oldAsset = scene.AssetService.Get(oldID.ToString()); - if (oldAsset != null) - { - if (oldAsset.Temporary == true) - { - scene.AssetService.Delete(oldID.ToString()); - } - } + } + + if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0)) + { + if (oldAsset == null) oldAsset = scene.AssetService.Get(oldID.ToString()); + if (oldAsset != null) + { + if (oldAsset.Temporary == true) + { + scene.AssetService.Delete(oldID.ToString()); + } + } } } diff --git a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs index 83f004dc60..d6ed468814 100644 --- a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs @@ -32,6 +32,7 @@ using System.Text.RegularExpressions; using DotNetOpenMail; using DotNetOpenMail.SmtpAuth; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -40,6 +41,7 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Scripting.EmailModules { + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class EmailModule : IEmailModule { // @@ -94,7 +96,7 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules } } - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { m_Config = config; IConfig SMTPConfig; @@ -136,7 +138,16 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules m_Enabled = false; return; } + m_log.Info("[EMAIL] Activated DefaultEmailModule"); + } + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) + { // It's a go! if (m_Enabled) { @@ -155,8 +166,20 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules m_Scenes.Add(scene.RegionInfo.RegionHandle, scene); } } + } + } - m_log.Info("[EMAIL] Activated DefaultEmailModule"); + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + scene.UnregisterModuleInterface(this); + + if (m_Scenes.ContainsKey(scene.RegionInfo.RegionHandle)) + { + m_Scenes.Remove(scene.RegionInfo.RegionHandle); } } @@ -173,11 +196,6 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules get { return "DefaultEmailModule"; } } - public bool IsSharedModule - { - get { return true; } - } - /// /// Delay function using thread in seconds /// diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index d78931a524..e331b8d3e8 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs @@ -31,6 +31,7 @@ using System.IO; using System.Net; using System.Text; using System.Threading; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -84,7 +85,8 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Scripting.HttpRequest { - public class HttpRequestModule : IRegionModule, IHttpRequestModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class HttpRequestModule : ISharedRegionModule, IHttpRequestModule { private object HttpListLock = new object(); private int httpTimeout = 30000; @@ -229,18 +231,35 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest #endregion - #region IRegionModule Members + #region ISharedRegionModule Members - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) + { + m_proxyurl = config.Configs["Startup"].GetString("HttpProxy"); + m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions"); + + m_pendingRequests = new Dictionary(); + } + + public void AddRegion(Scene scene) { m_scene = scene; m_scene.RegisterModuleInterface(this); + } - m_proxyurl = config.Configs["Startup"].GetString("HttpProxy"); - m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions"); + public Type ReplaceableInterface + { + get { return null; } + } - m_pendingRequests = new Dictionary(); + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + scene.UnregisterModuleInterface(this); } public void PostInitialise() @@ -256,11 +275,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest get { return m_name; } } - public bool IsSharedModule - { - get { return true; } - } - #endregion } diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index 9b565ed85b..6ce55a90c6 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -126,6 +126,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp public void RemoveRegion(Scene scene) { + scene.UnregisterModuleInterface(this); + scene.EventManager.OnScriptReset -= OnScriptReset; } public void Close() diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs index c23cea539a..35ce2cbf2c 100644 --- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs @@ -29,6 +29,7 @@ using System; using System.Drawing; using System.IO; using System.Net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenMetaverse.Imaging; @@ -39,7 +40,8 @@ using System.Reflection; namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL { - public class LoadImageURLModule : IRegionModule, IDynamicTextureRender + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class LoadImageURLModule : ISharedRegionModule, IDynamicTextureRender { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -97,20 +99,28 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL #endregion - #region IRegionModule Members + #region ISharedRegionModule Members - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) + { + m_proxyurl = config.Configs["Startup"].GetString("HttpProxy"); + m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions"); + } + + public void AddRegion(Scene scene) { if (m_scene == null) { m_scene = scene; } - - m_proxyurl = config.Configs["Startup"].GetString("HttpProxy"); - m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions"); } - public void PostInitialise() + public Type ReplaceableInterface + { + get { return null; } + } + + public void RegionLoaded(Scene scene) { m_textureManager = m_scene.RequestModuleInterface(); if (m_textureManager != null) @@ -119,6 +129,14 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL } } + public void RemoveRegion(Scene scene) + { + } + + public void PostInitialise() + { + } + public void Close() { } @@ -128,11 +146,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL get { return m_name; } } - public bool IsSharedModule - { - get { return true; } - } - #endregion private void MakeHttpRequest(string url, UUID requestID) diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index d57a8e5979..71b01a16bc 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs @@ -31,6 +31,7 @@ using System.Drawing.Imaging; using System.Globalization; using System.IO; using System.Net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenMetaverse.Imaging; @@ -43,7 +44,8 @@ using System.Reflection; namespace OpenSim.Region.CoreModules.Scripting.VectorRender { - public class VectorRenderModule : IRegionModule, IDynamicTextureRender + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class VectorRenderModule : ISharedRegionModule, IDynamicTextureRender { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -110,15 +112,10 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender #endregion - #region IRegionModule Members + #region ISharedRegionModule Members - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { - if (m_scene == null) - { - m_scene = scene; - } - if (m_graph == null) { Bitmap bitmap = new Bitmap(1024, 1024, PixelFormat.Format32bppArgb); @@ -133,7 +130,20 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender m_log.DebugFormat("[VECTORRENDERMODULE]: using font \"{0}\" for text rendering.", m_fontName); } - public void PostInitialise() + public void AddRegion(Scene scene) + { + if (m_scene == null) + { + m_scene = scene; + } + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void RegionLoaded(Scene scene) { m_textureManager = m_scene.RequestModuleInterface(); if (m_textureManager != null) @@ -142,6 +152,14 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender } } + public void RemoveRegion(Scene scene) + { + } + + public void PostInitialise() + { + } + public void Close() { } @@ -151,11 +169,6 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender get { return m_name; } } - public bool IsSharedModule - { - get { return true; } - } - #endregion private void Draw(string data, UUID id, string extraParams) diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs index 60df2e7273..acd8dbf0f0 100644 --- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs @@ -28,6 +28,7 @@ using System; using System.Collections; using System.Collections.Generic; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -85,7 +86,8 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Scripting.WorldComm { - public class WorldCommModule : IRegionModule, IWorldComm + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class WorldCommModule : INonSharedRegionModule, IWorldComm { // private static readonly ILog m_log = // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -98,9 +100,9 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm private int m_saydistance = 30; private int m_shoutdistance = 100; - #region IRegionModule Members + #region ISharedRegionModule Members - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { // wrap this in a try block so that defaults will work if // the config file doesn't specify otherwise. @@ -120,17 +122,33 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm if (maxlisteners < 1) maxlisteners = int.MaxValue; if (maxhandles < 1) maxhandles = int.MaxValue; - m_scene = scene; - m_scene.RegisterModuleInterface(this); m_listenerManager = new ListenerManager(maxlisteners, maxhandles); - m_scene.EventManager.OnChatFromClient += DeliverClientMessage; - m_scene.EventManager.OnChatBroadcast += DeliverClientMessage; m_pendingQ = new Queue(); m_pending = Queue.Synchronized(m_pendingQ); } - public void PostInitialise() + public void AddRegion(Scene scene) { + m_scene = scene; + m_scene.RegisterModuleInterface(this); + m_scene.EventManager.OnChatFromClient += DeliverClientMessage; + m_scene.EventManager.OnChatBroadcast += DeliverClientMessage; + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + scene.UnregisterModuleInterface(this); + scene.EventManager.OnChatFromClient -= DeliverClientMessage; + scene.EventManager.OnChatBroadcast -= DeliverClientMessage; } public void Close() @@ -142,11 +160,6 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm get { return "WorldCommModule"; } } - public bool IsSharedModule - { - get { return false; } - } - #endregion #region IWorldComm Members diff --git a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs index 27b64bffc0..a9147fb601 100644 --- a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs @@ -32,6 +32,7 @@ using System.Net; using System.Reflection; using System.Threading; using log4net; +using Mono.Addins; using Nini.Config; using Nwc.XmlRpc; using OpenMetaverse; @@ -76,7 +77,8 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Scripting.XMLRPC { - public class XMLRPCModule : IRegionModule, IXMLRPC + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class XMLRPCModule : ISharedRegionModule, IXMLRPC { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -94,9 +96,9 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC private int RemoteReplyScriptWait = 300; private object XMLRPCListLock = new object(); - #region IRegionModule Members + #region ISharedRegionModule Members - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { // We need to create these early because the scripts might be calling // But since this gets called for every region, we need to make sure they @@ -116,7 +118,14 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC { } } + } + public void PostInitialise() + { + } + + public void AddRegion(Scene scene) + { if (!m_scenes.Contains(scene)) { m_scenes.Add(scene); @@ -125,7 +134,12 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC } } - public void PostInitialise() + public Type ReplaceableInterface + { + get { return null; } + } + private Dictionary m_HttpServers = new Dictionary(); + public void RegionLoaded(Scene scene) { if (IsEnabled()) { @@ -133,9 +147,31 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC // Attach xmlrpc handlers m_log.Info("[REMOTE_DATA]: " + "Starting XMLRPC Server on port " + m_remoteDataPort + " for llRemoteData commands."); - BaseHttpServer httpServer = new BaseHttpServer((uint) m_remoteDataPort); + BaseHttpServer httpServer = new BaseHttpServer((uint)m_remoteDataPort); httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData); httpServer.Start(); + m_HttpServers.Add(scene, httpServer); + } + } + + public void RemoveRegion(Scene scene) + { + if (m_scenes.Contains(scene)) + m_scenes.Remove(scene); + scene.UnregisterModuleInterface(this); + if (IsEnabled()) + { + // Start http server + // Attach xmlrpc handlers + if (m_HttpServers.ContainsKey(scene)) + { + BaseHttpServer httpServer; + m_HttpServers.TryGetValue(scene, out httpServer); + m_log.Info("[REMOTE_DATA]: " + + "Stopping XMLRPC Server on port " + m_remoteDataPort + " for llRemoteData commands."); + httpServer.RemoveXmlRPCHandler("llRemoteData"); + httpServer.Stop(); + } } } @@ -148,11 +184,6 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC get { return m_name; } } - public bool IsSharedModule - { - get { return true; } - } - public int Port { get { return m_remoteDataPort; } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs index 879cc70903..d3e2db7cde 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs @@ -47,7 +47,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Asset private IConfigSource m_Config; bool m_Registered = false; - #region IRegionModule interface + #region ISharedRegionModule interface public void Initialise(IConfigSource config) { diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/HypergridServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/HypergridServiceInConnectorModule.cs index b12d778f87..a895a3fa0b 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/HypergridServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/HypergridServiceInConnectorModule.cs @@ -51,7 +51,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Grid bool m_Registered = false; HypergridServiceInConnector m_HypergridHandler; - #region IRegionModule interface + #region ISharedRegionModule interface public void Initialise(IConfigSource config) { diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Inventory/InventoryServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Inventory/InventoryServiceInConnectorModule.cs index 54c6d89073..4c74725ed9 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Inventory/InventoryServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Inventory/InventoryServiceInConnectorModule.cs @@ -47,7 +47,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Inventory private IConfigSource m_Config; bool m_Registered = false; - #region IRegionModule interface + #region ISharedRegionModule interface public void Initialise(IConfigSource config) { diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs index bce160a92a..dcc6decc3c 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs @@ -50,7 +50,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Land private IConfigSource m_Config; private List m_Scenes = new List(); - #region IRegionModule interface + #region ISharedRegionModule interface public void Initialise(IConfigSource config) { diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs index 8a903701fa..a5c5ef637f 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs @@ -50,7 +50,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Neighbour private IConfigSource m_Config; private List m_Scenes = new List(); - #region IRegionModule interface + #region ISharedRegionModule interface public void Initialise(IConfigSource config) { diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Simulation/SimulationServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Simulation/SimulationServiceInConnectorModule.cs index f28a31849a..c2cea1640e 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Simulation/SimulationServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Simulation/SimulationServiceInConnectorModule.cs @@ -49,7 +49,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Simulation private IConfigSource m_Config; bool m_Registered = false; - #region IRegionModule interface + #region ISharedRegionModule interface public void Initialise(IConfigSource config) { diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs index d68c683143..71d7993ab4 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs @@ -48,7 +48,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Interregion #endregion /* Events */ - #region IRegionModule + #region ISharedRegionModule public void Initialise(IConfigSource config) { @@ -136,7 +136,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Interregion } } - #endregion /* IRegionModule */ + #endregion #region IInterregionComms diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/RESTInterregionComms.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/RESTInterregionComms.cs index 44458d175f..24d35e10cc 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/RESTInterregionComms.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/RESTInterregionComms.cs @@ -66,7 +66,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Interregion protected bool m_safemode; protected IPAddress m_thisIP; - #region IRegionModule + #region ISharedRegionModule public virtual void Initialise(IConfigSource config) { @@ -149,7 +149,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Interregion MainServer.Instance.AddHTTPHandler("/object/", ObjectHandler); } - #endregion /* IRegionModule */ + #endregion #region IInterregionComms @@ -436,12 +436,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Interregion } OSDMap resp = new OSDMap(2); - string reason = String.Empty; - uint teleportFlags = 0; - if (args.ContainsKey("teleport_flags")) - { - teleportFlags = args["teleport_flags"].AsUInteger(); - } + string reason = String.Empty; + uint teleportFlags = 0; + if (args.ContainsKey("teleport_flags")) + { + teleportFlags = args["teleport_flags"].AsUInteger(); + } // This is the meaning of POST agent m_regionClient.AdjustUserInformation(aCircuit); diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs index fc8d4e1d04..c738b65773 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs @@ -81,6 +81,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver public void RemoveRegion(Scene scene) { + scene.UnregisterModuleInterface(this); } public void Close() diff --git a/OpenSim/Region/CoreModules/World/Cloud/CloudModule.cs b/OpenSim/Region/CoreModules/World/Cloud/CloudModule.cs index 5fa3dc2191..a2cfce6d38 100644 --- a/OpenSim/Region/CoreModules/World/Cloud/CloudModule.cs +++ b/OpenSim/Region/CoreModules/World/Cloud/CloudModule.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -35,6 +36,7 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules { + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class CloudModule : ICloudModule { // private static readonly log4net.ILog m_log @@ -48,7 +50,7 @@ namespace OpenSim.Region.CoreModules private float m_cloudDensity = 1.0F; private float[] cloudCover = new float[16 * 16]; - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { IConfig cloudConfig = config.Configs["Cloud"]; @@ -58,10 +60,17 @@ namespace OpenSim.Region.CoreModules m_cloudDensity = cloudConfig.GetFloat("density", 0.5F); m_frameUpdateRate = cloudConfig.GetInt("cloud_update_rate", 1000); } + } + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) + { if (m_enabled) { - m_scene = scene; scene.EventManager.OnNewClient += CloudsToClient; @@ -71,9 +80,18 @@ namespace OpenSim.Region.CoreModules GenerateCloudCover(); m_ready = true; - } + } + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + scene.EventManager.OnNewClient -= CloudsToClient; + scene.UnregisterModuleInterface(this); + scene.EventManager.OnFrame -= CloudUpdate; } public void PostInitialise() @@ -96,12 +114,6 @@ namespace OpenSim.Region.CoreModules get { return "CloudModule"; } } - public bool IsSharedModule - { - get { return false; } - } - - public float CloudCover(int x, int y, int z) { float cover = 0f; diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 695cced293..39836aeeee 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -30,6 +30,7 @@ using System.IO; using System.Reflection; using System.Security; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -38,6 +39,7 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.World.Estate { + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class EstateManagementModule : IEstateModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -898,7 +900,16 @@ namespace OpenSim.Region.CoreModules.World.Estate #region IRegionModule Members - public void Initialise(Scene scene, IConfigSource source) + public void Initialise(IConfigSource source) + { + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) { m_scene = scene; m_scene.RegisterModuleInterface(this); @@ -920,6 +931,29 @@ namespace OpenSim.Region.CoreModules.World.Estate consoleSetTerrainHeights); } + public void RegionLoaded(Scene scene) + { + // Sets up the sun module based on the saved Estate and Region Settings + // DO NOT REMOVE or the sun will stop working + TriggerEstateToolsSunUpdate(); + } + + public void RemoveRegion(Scene scene) + { + scene.UnregisterModuleInterface(this); + scene.EventManager.OnNewClient -= EventManager_OnNewClient; + scene.EventManager.OnRequestChangeWaterHeight -= changeWaterHeight; + } + + public void Close() + { + } + + public string Name + { + get { return "EstateManagementModule"; } + } + #region Console Commands public void consoleSetTerrainTexture(string module, string[] args) @@ -1006,28 +1040,6 @@ namespace OpenSim.Region.CoreModules.World.Estate } #endregion - - public void PostInitialise() - { - // Sets up the sun module based no the saved Estate and Region Settings - // DO NOT REMOVE or the sun will stop working - TriggerEstateToolsSunUpdate(); - } - - public void Close() - { - } - - public string Name - { - get { return "EstateManagementModule"; } - } - - public bool IsSharedModule - { - get { return false; } - } - #endregion #region Other Functions diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index f66f01f0d3..68e8485daf 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -89,7 +90,8 @@ enum GroupPowers : long namespace OpenSim.Region.CoreModules.World.Permissions { - public class PermissionsModule : IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class PermissionsModule : INonSharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -148,12 +150,10 @@ namespace OpenSim.Region.CoreModules.World.Permissions #endregion - #region IRegionModule Members + #region INonSharedRegionModule Members - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { - m_scene = scene; - IConfig myConfig = config.Configs["Startup"]; string permissionModules = myConfig.GetString("permissionmodules", "DefaultPermissionsModule"); @@ -177,74 +177,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions if (m_bypassPermissions) m_log.Info("[PERMISSIONS]: serviceside_object_permissions = false in ini file so disabling all region service permission checks"); else - m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks"); - - //Register functions with Scene External Checks! - m_scene.Permissions.OnBypassPermissions += BypassPermissions; - m_scene.Permissions.OnSetBypassPermissions += SetBypassPermissions; - m_scene.Permissions.OnPropagatePermissions += PropagatePermissions; - m_scene.Permissions.OnGenerateClientFlags += GenerateClientFlags; - m_scene.Permissions.OnAbandonParcel += CanAbandonParcel; - m_scene.Permissions.OnReclaimParcel += CanReclaimParcel; - m_scene.Permissions.OnDeedParcel += CanDeedParcel; - m_scene.Permissions.OnDeedObject += CanDeedObject; - m_scene.Permissions.OnIsGod += IsGod; - m_scene.Permissions.OnDuplicateObject += CanDuplicateObject; - m_scene.Permissions.OnDeleteObject += CanDeleteObject; //MAYBE FULLY IMPLEMENTED - m_scene.Permissions.OnEditObject += CanEditObject; //MAYBE FULLY IMPLEMENTED - m_scene.Permissions.OnEditParcel += CanEditParcel; //MAYBE FULLY IMPLEMENTED - m_scene.Permissions.OnInstantMessage += CanInstantMessage; - m_scene.Permissions.OnInventoryTransfer += CanInventoryTransfer; //NOT YET IMPLEMENTED - m_scene.Permissions.OnIssueEstateCommand += CanIssueEstateCommand; //FULLY IMPLEMENTED - m_scene.Permissions.OnMoveObject += CanMoveObject; //MAYBE FULLY IMPLEMENTED - m_scene.Permissions.OnObjectEntry += CanObjectEntry; - m_scene.Permissions.OnReturnObject += CanReturnObject; //NOT YET IMPLEMENTED - m_scene.Permissions.OnRezObject += CanRezObject; //MAYBE FULLY IMPLEMENTED - m_scene.Permissions.OnRunConsoleCommand += CanRunConsoleCommand; - m_scene.Permissions.OnRunScript += CanRunScript; //NOT YET IMPLEMENTED - m_scene.Permissions.OnCompileScript += CanCompileScript; - m_scene.Permissions.OnSellParcel += CanSellParcel; - m_scene.Permissions.OnTakeObject += CanTakeObject; - m_scene.Permissions.OnTakeCopyObject += CanTakeCopyObject; - m_scene.Permissions.OnTerraformLand += CanTerraformLand; - m_scene.Permissions.OnLinkObject += CanLinkObject; //NOT YET IMPLEMENTED - m_scene.Permissions.OnDelinkObject += CanDelinkObject; //NOT YET IMPLEMENTED - m_scene.Permissions.OnBuyLand += CanBuyLand; //NOT YET IMPLEMENTED - - m_scene.Permissions.OnViewNotecard += CanViewNotecard; //NOT YET IMPLEMENTED - m_scene.Permissions.OnViewScript += CanViewScript; //NOT YET IMPLEMENTED - m_scene.Permissions.OnEditNotecard += CanEditNotecard; //NOT YET IMPLEMENTED - m_scene.Permissions.OnEditScript += CanEditScript; //NOT YET IMPLEMENTED - - m_scene.Permissions.OnCreateObjectInventory += CanCreateObjectInventory; //NOT IMPLEMENTED HERE - m_scene.Permissions.OnEditObjectInventory += CanEditObjectInventory;//MAYBE FULLY IMPLEMENTED - m_scene.Permissions.OnCopyObjectInventory += CanCopyObjectInventory; //NOT YET IMPLEMENTED - m_scene.Permissions.OnDeleteObjectInventory += CanDeleteObjectInventory; //NOT YET IMPLEMENTED - m_scene.Permissions.OnResetScript += CanResetScript; - - m_scene.Permissions.OnCreateUserInventory += CanCreateUserInventory; //NOT YET IMPLEMENTED - m_scene.Permissions.OnCopyUserInventory += CanCopyUserInventory; //NOT YET IMPLEMENTED - m_scene.Permissions.OnEditUserInventory += CanEditUserInventory; //NOT YET IMPLEMENTED - m_scene.Permissions.OnDeleteUserInventory += CanDeleteUserInventory; //NOT YET IMPLEMENTED - - m_scene.Permissions.OnTeleport += CanTeleport; //NOT YET IMPLEMENTED - m_scene.Permissions.OnUseObjectReturn += CanUseObjectReturn; //NOT YET IMPLEMENTED - - m_scene.AddCommand(this, "bypass permissions", - "bypass permissions ", - "Bypass permission checks", - HandleBypassPermissions); - - m_scene.AddCommand(this, "force permissions", - "force permissions ", - "Force permissions on or off", - HandleForcePermissions); - - m_scene.AddCommand(this, "debug permissions", - "debug permissions ", - "Enable permissions debugging", - HandleDebugPermissions); - + m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks"); string grant = myConfig.GetString("GrantLSL",""); if (grant.Length > 0) { @@ -292,6 +225,158 @@ namespace OpenSim.Region.CoreModules.World.Permissions } + public void AddRegion(Scene scene) + { + m_scene = scene; + + //Register functions with Scene External Checks! + m_scene.Permissions.OnBypassPermissions += BypassPermissions; + m_scene.Permissions.OnSetBypassPermissions += SetBypassPermissions; + m_scene.Permissions.OnPropagatePermissions += PropagatePermissions; + m_scene.Permissions.OnGenerateClientFlags += GenerateClientFlags; + m_scene.Permissions.OnAbandonParcel += CanAbandonParcel; + m_scene.Permissions.OnReclaimParcel += CanReclaimParcel; + m_scene.Permissions.OnDeedParcel += CanDeedParcel; + m_scene.Permissions.OnDeedObject += CanDeedObject; + m_scene.Permissions.OnIsGod += IsGod; + m_scene.Permissions.OnDuplicateObject += CanDuplicateObject; + m_scene.Permissions.OnDeleteObject += CanDeleteObject; //MAYBE FULLY IMPLEMENTED + m_scene.Permissions.OnEditObject += CanEditObject; //MAYBE FULLY IMPLEMENTED + m_scene.Permissions.OnEditParcel += CanEditParcel; //MAYBE FULLY IMPLEMENTED + m_scene.Permissions.OnInstantMessage += CanInstantMessage; + m_scene.Permissions.OnInventoryTransfer += CanInventoryTransfer; //NOT YET IMPLEMENTED + m_scene.Permissions.OnIssueEstateCommand += CanIssueEstateCommand; //FULLY IMPLEMENTED + m_scene.Permissions.OnMoveObject += CanMoveObject; //MAYBE FULLY IMPLEMENTED + m_scene.Permissions.OnObjectEntry += CanObjectEntry; + m_scene.Permissions.OnReturnObject += CanReturnObject; //NOT YET IMPLEMENTED + m_scene.Permissions.OnRezObject += CanRezObject; //MAYBE FULLY IMPLEMENTED + m_scene.Permissions.OnRunConsoleCommand += CanRunConsoleCommand; + m_scene.Permissions.OnRunScript += CanRunScript; //NOT YET IMPLEMENTED + m_scene.Permissions.OnCompileScript += CanCompileScript; + m_scene.Permissions.OnSellParcel += CanSellParcel; + m_scene.Permissions.OnTakeObject += CanTakeObject; + m_scene.Permissions.OnTakeCopyObject += CanTakeCopyObject; + m_scene.Permissions.OnTerraformLand += CanTerraformLand; + m_scene.Permissions.OnLinkObject += CanLinkObject; //NOT YET IMPLEMENTED + m_scene.Permissions.OnDelinkObject += CanDelinkObject; //NOT YET IMPLEMENTED + m_scene.Permissions.OnBuyLand += CanBuyLand; //NOT YET IMPLEMENTED + + m_scene.Permissions.OnViewNotecard += CanViewNotecard; //NOT YET IMPLEMENTED + m_scene.Permissions.OnViewScript += CanViewScript; //NOT YET IMPLEMENTED + m_scene.Permissions.OnEditNotecard += CanEditNotecard; //NOT YET IMPLEMENTED + m_scene.Permissions.OnEditScript += CanEditScript; //NOT YET IMPLEMENTED + + m_scene.Permissions.OnCreateObjectInventory += CanCreateObjectInventory; //NOT IMPLEMENTED HERE + m_scene.Permissions.OnEditObjectInventory += CanEditObjectInventory;//MAYBE FULLY IMPLEMENTED + m_scene.Permissions.OnCopyObjectInventory += CanCopyObjectInventory; //NOT YET IMPLEMENTED + m_scene.Permissions.OnDeleteObjectInventory += CanDeleteObjectInventory; //NOT YET IMPLEMENTED + m_scene.Permissions.OnResetScript += CanResetScript; + + m_scene.Permissions.OnCreateUserInventory += CanCreateUserInventory; //NOT YET IMPLEMENTED + m_scene.Permissions.OnCopyUserInventory += CanCopyUserInventory; //NOT YET IMPLEMENTED + m_scene.Permissions.OnEditUserInventory += CanEditUserInventory; //NOT YET IMPLEMENTED + m_scene.Permissions.OnDeleteUserInventory += CanDeleteUserInventory; //NOT YET IMPLEMENTED + + m_scene.Permissions.OnTeleport += CanTeleport; //NOT YET IMPLEMENTED + m_scene.Permissions.OnUseObjectReturn += CanUseObjectReturn; //NOT YET IMPLEMENTED + + m_scene.AddCommand(this, "bypass permissions", + "bypass permissions ", + "Bypass permission checks", + HandleBypassPermissions); + + m_scene.AddCommand(this, "force permissions", + "force permissions ", + "Force permissions on or off", + HandleForcePermissions); + + m_scene.AddCommand(this, "debug permissions", + "debug permissions ", + "Enable permissions debugging", + HandleDebugPermissions); + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void RegionLoaded(Scene scene) + { + m_friendsModule = m_scene.RequestModuleInterface(); + + if (m_friendsModule == null) + m_log.Error("[PERMISSIONS]: Friends module not found, friend permissions will not work"); + else + m_log.Info("[PERMISSIONS]: Friends module found, friend permissions enabled"); + } + + public void RemoveRegion(Scene scene) + { + scene.Permissions.OnBypassPermissions -= BypassPermissions; + scene.Permissions.OnSetBypassPermissions -= SetBypassPermissions; + scene.Permissions.OnPropagatePermissions -= PropagatePermissions; + scene.Permissions.OnGenerateClientFlags -= GenerateClientFlags; + scene.Permissions.OnAbandonParcel -= CanAbandonParcel; + scene.Permissions.OnReclaimParcel -= CanReclaimParcel; + scene.Permissions.OnDeedParcel -= CanDeedParcel; + scene.Permissions.OnDeedObject -= CanDeedObject; + scene.Permissions.OnIsGod -= IsGod; + scene.Permissions.OnDuplicateObject -= CanDuplicateObject; + scene.Permissions.OnDeleteObject -= CanDeleteObject; //MAYBE FULLY IMPLEMENTED + scene.Permissions.OnEditObject -= CanEditObject; //MAYBE FULLY IMPLEMENTED + scene.Permissions.OnEditParcel -= CanEditParcel; //MAYBE FULLY IMPLEMENTED + scene.Permissions.OnInstantMessage -= CanInstantMessage; + scene.Permissions.OnInventoryTransfer -= CanInventoryTransfer; //NOT YET IMPLEMENTED + scene.Permissions.OnIssueEstateCommand -= CanIssueEstateCommand; //FULLY IMPLEMENTED + scene.Permissions.OnMoveObject -= CanMoveObject; //MAYBE FULLY IMPLEMENTED + scene.Permissions.OnObjectEntry -= CanObjectEntry; + scene.Permissions.OnReturnObject -= CanReturnObject; //NOT YET IMPLEMENTED + scene.Permissions.OnRezObject -= CanRezObject; //MAYBE FULLY IMPLEMENTED + scene.Permissions.OnRunConsoleCommand -= CanRunConsoleCommand; + scene.Permissions.OnRunScript -= CanRunScript; //NOT YET IMPLEMENTED + scene.Permissions.OnCompileScript -= CanCompileScript; + scene.Permissions.OnSellParcel -= CanSellParcel; + scene.Permissions.OnTakeObject -= CanTakeObject; + scene.Permissions.OnTakeCopyObject -= CanTakeCopyObject; + scene.Permissions.OnTerraformLand -= CanTerraformLand; + scene.Permissions.OnLinkObject -= CanLinkObject; //NOT YET IMPLEMENTED + scene.Permissions.OnDelinkObject -= CanDelinkObject; //NOT YET IMPLEMENTED + scene.Permissions.OnBuyLand -= CanBuyLand; //NOT YET IMPLEMENTED + + scene.Permissions.OnViewNotecard -= CanViewNotecard; //NOT YET IMPLEMENTED + scene.Permissions.OnViewScript -= CanViewScript; //NOT YET IMPLEMENTED + scene.Permissions.OnEditNotecard -= CanEditNotecard; //NOT YET IMPLEMENTED + scene.Permissions.OnEditScript -= CanEditScript; //NOT YET IMPLEMENTED + + scene.Permissions.OnCreateObjectInventory -= CanCreateObjectInventory; //NOT IMPLEMENTED HERE + scene.Permissions.OnEditObjectInventory -= CanEditObjectInventory;//MAYBE FULLY IMPLEMENTED + scene.Permissions.OnCopyObjectInventory -= CanCopyObjectInventory; //NOT YET IMPLEMENTED + scene.Permissions.OnDeleteObjectInventory -= CanDeleteObjectInventory; //NOT YET IMPLEMENTED + scene.Permissions.OnResetScript -= CanResetScript; + + scene.Permissions.OnCreateUserInventory -= CanCreateUserInventory; //NOT YET IMPLEMENTED + scene.Permissions.OnCopyUserInventory -= CanCopyUserInventory; //NOT YET IMPLEMENTED + scene.Permissions.OnEditUserInventory -= CanEditUserInventory; //NOT YET IMPLEMENTED + scene.Permissions.OnDeleteUserInventory -= CanDeleteUserInventory; //NOT YET IMPLEMENTED + + scene.Permissions.OnTeleport -= CanTeleport; //NOT YET IMPLEMENTED + scene.Permissions.OnUseObjectReturn -= CanUseObjectReturn; //NOT YET IMPLEMENTED + } + + public void PostInitialise() + { + } + + public void Close() + { + } + + public string Name + { + get { return "PermissionsModule"; } + } + public void HandleBypassPermissions(string module, string[] args) { if (m_scene.ConsoleScene() != null && @@ -362,31 +447,6 @@ namespace OpenSim.Region.CoreModules.World.Permissions m_log.InfoFormat("[PERMISSIONS] Set permissions debugging to {0} in {1}", m_debugPermissions, m_scene.RegionInfo.RegionName); } } - - public void PostInitialise() - { - m_friendsModule = m_scene.RequestModuleInterface(); - - if (m_friendsModule == null) - m_log.Error("[PERMISSIONS]: Friends module not found, friend permissions will not work"); - else - m_log.Info("[PERMISSIONS]: Friends module found, friend permissions enabled"); - } - - public void Close() - { - } - - public string Name - { - get { return "PermissionsModule"; } - } - - public bool IsSharedModule - { - get { return false; } - } - #endregion #region Helper Functions diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs index 37f1f2eb9f..ed7bfe1a01 100644 --- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs +++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs @@ -26,6 +26,7 @@ */ using System; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -34,26 +35,44 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.World.Sound { - public class SoundModule : IRegionModule, ISoundModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class SoundModule : INonSharedRegionModule, ISoundModule { //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected Scene m_scene; - public void Initialise(Scene scene, IConfigSource source) + public void Initialise(IConfigSource source) + { + } + + public void AddRegion(Scene scene) { m_scene = scene; - + m_scene.EventManager.OnNewClient += OnNewClient; - + m_scene.RegisterModuleInterface(this); } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + scene.EventManager.OnNewClient -= OnNewClient; + scene.UnregisterModuleInterface(this); + } - public void PostInitialise() {} public void Close() {} public string Name { get { return "Sound Module"; } } - public bool IsSharedModule { get { return false; } } - + private void OnNewClient(IClientAPI client) { client.OnSoundTrigger += TriggerSound; diff --git a/OpenSim/Region/CoreModules/World/Sun/SunModule.cs b/OpenSim/Region/CoreModules/World/Sun/SunModule.cs index 0712a7fabc..948c47ce10 100644 --- a/OpenSim/Region/CoreModules/World/Sun/SunModule.cs +++ b/OpenSim/Region/CoreModules/World/Sun/SunModule.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -37,6 +38,7 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules { + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class SunModule : ISunModule { /// @@ -278,27 +280,12 @@ namespace OpenSim.Region.CoreModules return GetCurrentSunHour() + 6.0f; } - #region IRegion Methods + #region INonSharedRegionModule Methods // Called immediately after the module is loaded for a given region // i.e. Immediately after instance creation. - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { - m_scene = scene; - m_frame = 0; - - // This one puts an entry in the main help screen - m_scene.AddCommand(this, String.Empty, "sun", "Usage: sun [param] [value] - Get or Update Sun module paramater", null); - - // This one enables the ability to type just "sun" without any parameters - m_scene.AddCommand(this, "sun", "", "", HandleSunConsoleCommand); - foreach (KeyValuePair kvp in GetParamList()) - { - m_scene.AddCommand(this, String.Format("sun {0}", kvp.Key), String.Format("{0} - {1}", kvp.Key, kvp.Value), "", HandleSunConsoleCommand); - } - - - TimeZone local = TimeZone.CurrentTimeZone; TicksUTCOffset = local.GetUtcOffset(local.ToLocalTime(DateTime.Now)).Ticks; m_log.Debug("[SUN]: localtime offset is " + TicksUTCOffset); @@ -346,57 +333,6 @@ namespace OpenSim.Region.CoreModules // m_latitude = d_latitude; // m_longitude = d_longitude; } - - switch (m_RegionMode) - { - case "T1": - default: - case "SL": - // Time taken to complete a cycle (day and season) - - SecondsPerSunCycle = (uint) (m_DayLengthHours * 60 * 60); - SecondsPerYear = (uint) (SecondsPerSunCycle*m_YearLengthDays); - - // Ration of real-to-virtual time - - // VWTimeRatio = 24/m_day_length; - - // Speed of rotation needed to complete a cycle in the - // designated period (day and season) - - SunSpeed = m_SunCycle/SecondsPerSunCycle; - SeasonSpeed = m_SeasonalCycle/SecondsPerYear; - - // Horizon translation - - HorizonShift = m_HorizonShift; // Z axis translation - // HoursToRadians = (SunCycle/24)*VWTimeRatio; - - // Insert our event handling hooks - - scene.EventManager.OnFrame += SunUpdate; - scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; - scene.EventManager.OnEstateToolsSunUpdate += EstateToolsSunUpdate; - scene.EventManager.OnGetCurrentTimeAsLindenSunHour += GetCurrentTimeAsLindenSunHour; - - ready = true; - - m_log.Debug("[SUN]: Mode is " + m_RegionMode); - m_log.Debug("[SUN]: Initialization completed. Day is " + SecondsPerSunCycle + " seconds, and year is " + m_YearLengthDays + " days"); - m_log.Debug("[SUN]: Axis offset is " + m_HorizonShift); - m_log.Debug("[SUN]: Percentage of time for daylight " + m_DayTimeSunHourScale); - m_log.Debug("[SUN]: Positional data updated every " + m_UpdateInterval + " frames"); - - break; - } - - scene.RegisterModuleInterface(this); - - } - - - public void PostInitialise() - { } public void Close() @@ -415,10 +351,84 @@ namespace OpenSim.Region.CoreModules get { return "SunModule"; } } - public bool IsSharedModule + public Type ReplaceableInterface { - get { return false; } + get { return null; } } + + public void AddRegion(Scene scene) + { + m_scene = scene; + m_frame = 0; + + // This one puts an entry in the main help screen + m_scene.AddCommand(this, String.Empty, "sun", "Usage: sun [param] [value] - Get or Update Sun module paramater", null); + + // This one enables the ability to type just "sun" without any parameters + m_scene.AddCommand(this, "sun", "", "", HandleSunConsoleCommand); + foreach (KeyValuePair kvp in GetParamList()) + { + m_scene.AddCommand(this, String.Format("sun {0}", kvp.Key), String.Format("{0} - {1}", kvp.Key, kvp.Value), "", HandleSunConsoleCommand); + } + switch (m_RegionMode) + { + case "T1": + default: + case "SL": + // Time taken to complete a cycle (day and season) + + SecondsPerSunCycle = (uint)(m_DayLengthHours * 60 * 60); + SecondsPerYear = (uint)(SecondsPerSunCycle * m_YearLengthDays); + + // Ration of real-to-virtual time + + // VWTimeRatio = 24/m_day_length; + + // Speed of rotation needed to complete a cycle in the + // designated period (day and season) + + SunSpeed = m_SunCycle / SecondsPerSunCycle; + SeasonSpeed = m_SeasonalCycle / SecondsPerYear; + + // Horizon translation + + HorizonShift = m_HorizonShift; // Z axis translation + // HoursToRadians = (SunCycle/24)*VWTimeRatio; + + // Insert our event handling hooks + + scene.EventManager.OnFrame += SunUpdate; + scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; + scene.EventManager.OnEstateToolsSunUpdate += EstateToolsSunUpdate; + scene.EventManager.OnGetCurrentTimeAsLindenSunHour += GetCurrentTimeAsLindenSunHour; + + ready = true; + + m_log.Debug("[SUN]: Mode is " + m_RegionMode); + m_log.Debug("[SUN]: Initialization completed. Day is " + SecondsPerSunCycle + " seconds, and year is " + m_YearLengthDays + " days"); + m_log.Debug("[SUN]: Axis offset is " + m_HorizonShift); + m_log.Debug("[SUN]: Percentage of time for daylight " + m_DayTimeSunHourScale); + m_log.Debug("[SUN]: Positional data updated every " + m_UpdateInterval + " frames"); + + break; + } + + scene.RegisterModuleInterface(this); + } + + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + scene.RegisterModuleInterface(this); + scene.EventManager.OnFrame -= SunUpdate; + scene.EventManager.OnAvatarEnteringNewParcel -= AvatarEnteringParcel; + scene.EventManager.OnEstateToolsSunUpdate -= EstateToolsSunUpdate; + scene.EventManager.OnGetCurrentTimeAsLindenSunHour -= GetCurrentTimeAsLindenSunHour; + } + #endregion #region EventManager Events diff --git a/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs b/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs index c2ad7b8c38..0b487ed442 100644 --- a/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs +++ b/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs @@ -28,6 +28,7 @@ using System; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -36,7 +37,8 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Avatar.Vegetation { - public class VegetationModule : IRegionModule, IVegetationModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class VegetationModule : INonSharedRegionModule, IVegetationModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -45,17 +47,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Vegetation protected static readonly PCode[] creationCapabilities = new PCode[] { PCode.Grass, PCode.NewTree, PCode.Tree }; public PCode[] CreationCapabilities { get { return creationCapabilities; } } - public void Initialise(Scene scene, IConfigSource source) + public void Initialise(IConfigSource source) + { + } + + public void AddRegion(Scene scene) { m_scene = scene; m_scene.RegisterModuleInterface(this); } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + scene.UnregisterModuleInterface(this); + } public void PostInitialise() {} public void Close() {} public string Name { get { return "Vegetation Module"; } } - public bool IsSharedModule { get { return false; } } - + public SceneObjectGroup AddTree( UUID uuid, UUID groupID, Vector3 scale, Quaternion rotation, Vector3 position, Tree treeType, bool newTree) { diff --git a/OpenSim/Region/CoreModules/World/Wind/WindModule.cs b/OpenSim/Region/CoreModules/World/Wind/WindModule.cs index 3283c1ffa7..cd3706d7b3 100644 --- a/OpenSim/Region/CoreModules/World/Wind/WindModule.cs +++ b/OpenSim/Region/CoreModules/World/Wind/WindModule.cs @@ -55,17 +55,19 @@ namespace OpenSim.Region.CoreModules private IWindModelPlugin m_activeWindPlugin = null; private const string m_dWindPluginName = "SimpleRandomWind"; + private string m_desiredWindPlugin = "SimpleRandomWind"; private Dictionary m_availableWindPlugins = new Dictionary(); // Simplified windSpeeds based on the fact that the client protocal tracks at a resolution of 16m private Vector2[] windSpeeds = new Vector2[16 * 16]; + private IConfig windConfig; #region IRegion Methods - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { - IConfig windConfig = config.Configs["Wind"]; - string desiredWindPlugin = m_dWindPluginName; + windConfig = config.Configs["Wind"]; + m_desiredWindPlugin = m_dWindPluginName; if (windConfig != null) { @@ -76,10 +78,18 @@ namespace OpenSim.Region.CoreModules // Determine which wind model plugin is desired if (windConfig.Contains("wind_plugin")) { - desiredWindPlugin = windConfig.GetString("wind_plugin"); + m_desiredWindPlugin = windConfig.GetString("wind_plugin"); } } + } + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) + { if (m_enabled) { m_log.InfoFormat("[WIND] Enabled with an update rate of {0} frames.", m_frameUpdateRate); @@ -95,30 +105,30 @@ namespace OpenSim.Region.CoreModules } // Check for desired plugin - if (m_availableWindPlugins.ContainsKey(desiredWindPlugin)) + if (m_availableWindPlugins.ContainsKey(m_desiredWindPlugin)) { - m_activeWindPlugin = m_availableWindPlugins[desiredWindPlugin]; + m_activeWindPlugin = m_availableWindPlugins[m_desiredWindPlugin]; - m_log.InfoFormat("[WIND] {0} plugin found, initializing.", desiredWindPlugin); + m_log.InfoFormat("[WIND] {0} plugin found, initializing.", m_desiredWindPlugin); if (windConfig != null) { m_activeWindPlugin.Initialise(); m_activeWindPlugin.WindConfig(m_scene, windConfig); } - } + } // if the plug-in wasn't found, default to no wind. if (m_activeWindPlugin == null) { - m_log.ErrorFormat("[WIND] Could not find specified wind plug-in: {0}", desiredWindPlugin); + m_log.ErrorFormat("[WIND] Could not find specified wind plug-in: {0}", m_desiredWindPlugin); m_log.ErrorFormat("[WIND] Defaulting to no wind."); } // This one puts an entry in the main help screen m_scene.AddCommand(this, String.Empty, "wind", "Usage: wind [value] - Get or Update Wind paramaters", null); - + // This one enables the ability to type just the base command without any parameters m_scene.AddCommand(this, "wind", "", "", HandleConsoleCommand); @@ -127,7 +137,7 @@ namespace OpenSim.Region.CoreModules { m_scene.AddCommand(this, String.Format("wind base wind_plugin {0}", windPlugin.Name), String.Format("{0} - {1}", windPlugin.Name, windPlugin.Description), "", HandleConsoleBaseCommand); m_scene.AddCommand(this, String.Format("wind base wind_update_rate"), "Change the wind update rate.", "", HandleConsoleBaseCommand); - + foreach (KeyValuePair kvp in windPlugin.WindParams()) { m_scene.AddCommand(this, String.Format("wind {0} {1}", windPlugin.Name, kvp.Key), String.Format("{0} : {1} - {2}", windPlugin.Name, kvp.Key, kvp.Value), "", HandleConsoleParamCommand); @@ -149,13 +159,19 @@ namespace OpenSim.Region.CoreModules m_ready = true; } - } - public void PostInitialise() + public void RegionLoaded(Scene scene) { } + public void RemoveRegion(Scene scene) + { + scene.EventManager.OnFrame -= WindUpdate; + scene.EventManager.OnMakeRootAgent -= OnAgentEnteredRegion; + scene.UnregisterModuleInterface(this); + } + public void Close() { if (m_enabled) @@ -182,11 +198,6 @@ namespace OpenSim.Region.CoreModules get { return "WindModule"; } } - public bool IsSharedModule - { - get { return false; } - } - #endregion diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs index 285d36a3d6..6bda1e9e6d 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs @@ -30,6 +30,7 @@ using System.Collections.Generic; using System.Drawing; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenMetaverse.Imaging; @@ -59,7 +60,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap public face[] trns; } - public class MapImageModule : IMapImageGenerator, IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class MapImageModule : IMapImageGenerator, INonSharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -128,23 +130,36 @@ namespace OpenSim.Region.CoreModules.World.WorldMap #endregion - #region IRegionModule Members + #region INonSharedRegionModule Members - public void Initialise(Scene scene, IConfigSource source) + public void Initialise(IConfigSource source) { - m_scene = scene; m_config = source; IConfig startupConfig = m_config.Configs["Startup"]; if (startupConfig.GetString("MapImageModule", "MapImageModule") != "MapImageModule") return; + } + public void AddRegion(Scene scene) + { + m_scene = scene; m_scene.RegisterModuleInterface(this); } - public void PostInitialise() + public Type ReplaceableInterface { + get { return null; } + } + + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + scene.UnregisterModuleInterface(this); } public void Close() @@ -156,11 +171,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap get { return "MapImageModule"; } } - public bool IsSharedModule - { - get { return false; } - } - #endregion // TODO: unused: diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs index be46fa55b2..dd336735a3 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs @@ -24,9 +24,12 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +using System; using System.Collections.Generic; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -38,7 +41,8 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion; namespace OpenSim.Region.CoreModules.World.WorldMap { - public class MapSearchModule : IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class MapSearchModule : ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -46,8 +50,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap Scene m_scene = null; // only need one for communication with GridService List m_scenes = new List(); - #region IRegionModule Members - public void Initialise(Scene scene, IConfigSource source) + #region ISharedRegionModule Members + public void Initialise(IConfigSource source) + { + } + + public void AddRegion(Scene scene) { if (m_scene == null) { @@ -58,6 +66,22 @@ namespace OpenSim.Region.CoreModules.World.WorldMap scene.EventManager.OnNewClient += OnNewClient; } + public Type ReplaceableInterface + { + get { return null; } + } + + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + if(m_scenes.Contains(scene)) + m_scenes.Remove(scene); + scene.EventManager.OnNewClient -= OnNewClient; + } + public void PostInitialise() { } @@ -73,11 +97,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap get { return "MapSearchModule"; } } - public bool IsSharedModule - { - get { return true; } - } - #endregion private void OnNewClient(IClientAPI client) diff --git a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs index 4df9094644..b0cefc3047 100644 --- a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs +++ b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs @@ -33,6 +33,7 @@ using System.Net; using System.Reflection; using System.Xml; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -43,7 +44,8 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.DataSnapshot { - public class DataSnapshotManager : IRegionModule, IDataSnapshot + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class DataSnapshotManager : ISharedRegionModule, IDataSnapshot { #region Class members //Information from config @@ -89,7 +91,7 @@ namespace OpenSim.Region.DataSnapshot #region IRegionModule - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { if (!m_configLoaded) { @@ -140,24 +142,29 @@ namespace OpenSim.Region.DataSnapshot return; } } - - if (m_enabled) - { - //Hand it the first scene, assuming that all scenes have the same BaseHTTPServer - new DataRequestHandler(scene, this); - - m_hostname = scene.RegionInfo.ExternalHostName; - m_snapStore = new SnapshotStore(m_snapsDir, m_gridinfo, m_listener_port, m_hostname); - - MakeEverythingStale(); - - if (m_dataServices != "" && m_dataServices != "noservices") - NotifyDataServices(m_dataServices, "online"); - } } + } + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) + { if (m_enabled) { + //Hand it the first scene, assuming that all scenes have the same BaseHTTPServer + new DataRequestHandler(scene, this); + + m_hostname = scene.RegionInfo.ExternalHostName; + m_snapStore = new SnapshotStore(m_snapsDir, m_gridinfo, m_listener_port, m_hostname); + + MakeEverythingStale(); + + if (m_dataServices != "" && m_dataServices != "noservices") + NotifyDataServices(m_dataServices, "online"); + m_log.Info("[DATASNAPSHOT]: Scene added to module."); m_snapStore.AddScene(scene); @@ -191,22 +198,27 @@ namespace OpenSim.Region.DataSnapshot } else { - m_log.Warn("[DATASNAPSHOT]: Data snapshot disabled, not adding scene to module (or anything else)."); + m_log.Info("[DATASNAPSHOT]: Data snapshot disabled, not adding scene to module (or anything else)."); } } + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + if (m_scenes.Contains(scene)) + m_scenes.Remove(scene); + m_snapStore.RemoveScene(scene); + } + public void Close() { if (m_enabled && m_dataServices != "" && m_dataServices != "noservices") NotifyDataServices(m_dataServices, "offline"); } - - public bool IsSharedModule - { - get { return true; } - } - public string Name { get { return "External Data Generator"; } @@ -214,7 +226,6 @@ namespace OpenSim.Region.DataSnapshot public void PostInitialise() { - } #endregion diff --git a/OpenSim/Region/Framework/Interfaces/ICloudModule.cs b/OpenSim/Region/Framework/Interfaces/ICloudModule.cs index f8a5bad347..879114b18c 100644 --- a/OpenSim/Region/Framework/Interfaces/ICloudModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ICloudModule.cs @@ -28,7 +28,7 @@ namespace OpenSim.Region.Framework.Interfaces { - public interface ICloudModule : IRegionModule + public interface ICloudModule : INonSharedRegionModule { /// /// Retrieves the cloud density at the given region coordinates diff --git a/OpenSim/Region/Framework/Interfaces/IEmailModule.cs b/OpenSim/Region/Framework/Interfaces/IEmailModule.cs index 3a2c4231cf..bdad0b4061 100644 --- a/OpenSim/Region/Framework/Interfaces/IEmailModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEmailModule.cs @@ -38,7 +38,7 @@ namespace OpenSim.Region.Framework.Interfaces public int numLeft; } - public interface IEmailModule : IRegionModule + public interface IEmailModule : ISharedRegionModule { void SendEmail(UUID objectID, string address, string subject, string body); Email GetNextEmail(UUID objectID, string sender, string subject); diff --git a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs index 890fa31df0..347818cf42 100644 --- a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs @@ -29,7 +29,7 @@ using OpenMetaverse; namespace OpenSim.Region.Framework.Interfaces { - public interface IEstateModule : IRegionModule + public interface IEstateModule : INonSharedRegionModule { uint GetRegionFlags(); bool IsManager(UUID avatarID); diff --git a/OpenSim/Region/Framework/Interfaces/ISunModule.cs b/OpenSim/Region/Framework/Interfaces/ISunModule.cs index 819ae11d3c..8231716f2e 100644 --- a/OpenSim/Region/Framework/Interfaces/ISunModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ISunModule.cs @@ -29,7 +29,7 @@ using OpenMetaverse; namespace OpenSim.Region.Framework.Interfaces { - public interface ISunModule : IRegionModule + public interface ISunModule : INonSharedRegionModule { double GetSunParameter(string param); diff --git a/OpenSim/Region/Framework/Interfaces/IWindModule.cs b/OpenSim/Region/Framework/Interfaces/IWindModule.cs index 10ecc325c8..4a26a717db 100644 --- a/OpenSim/Region/Framework/Interfaces/IWindModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IWindModule.cs @@ -29,7 +29,7 @@ using OpenMetaverse; namespace OpenSim.Region.Framework.Interfaces { - public interface IWindModule : IRegionModule + public interface IWindModule : INonSharedRegionModule { /// diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs index cfe1278786..ec040dbbf2 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs @@ -25,9 +25,11 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; using System.Net; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -35,24 +37,23 @@ using OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server; namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView { - public class IRCStackModule : IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class IRCStackModule : INonSharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private IRCServer m_server; // private Scene m_scene; + private int portNo; - #region Implementation of IRegionModule + #region Implementation of ISharedRegionModule - public void Initialise(Scene scene, IConfigSource source) + public void Initialise(IConfigSource source) { if (null != source.Configs["IRCd"] && source.Configs["IRCd"].GetBoolean("Enabled",false)) { - int portNo = source.Configs["IRCd"].GetInt("Port",6666); -// m_scene = scene; - m_server = new IRCServer(IPAddress.Parse("0.0.0.0"), portNo, scene); - m_server.OnNewIRCClient += m_server_OnNewIRCClient; + portNo = source.Configs["IRCd"].GetInt("Port",6666); } } @@ -68,9 +69,20 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView m_log.Info("[IRCd] Added user to Scene"); } - public void PostInitialise() + public void AddRegion(Scene scene) { + if (portNo != null) + { + m_server = new IRCServer(IPAddress.Parse("0.0.0.0"), portNo, scene); + m_server.OnNewIRCClient += m_server_OnNewIRCClient; + } + } + public void RegionLoaded(Scene scene) + { + } + public void RemoveRegion(Scene scene) + { } public void Close() @@ -83,9 +95,9 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView get { return "IRCClientStackModule"; } } - public bool IsSharedModule + public Type ReplaceableInterface { - get { return false; } + get { return null; } } #endregion diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index b04b076629..23ae307910 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -38,6 +38,7 @@ using System.Collections.Generic; using System.Reflection; using OpenMetaverse; using log4net; +using Mono.Addins; using Nini.Config; using Nwc.XmlRpc; using OpenSim.Framework; @@ -53,7 +54,8 @@ using System.Text.RegularExpressions; namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { - public class FreeSwitchVoiceModule : IRegionModule, IVoiceModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class FreeSwitchVoiceModule : ISharedRegionModule, IVoiceModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -108,9 +110,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private IConfig m_config; - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { - m_scene = scene; m_config = config.Configs["FreeSwitchVoice"]; if (null == m_config) @@ -224,17 +225,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice return; } } + } - if (m_pluginEnabled) + public void AddRegion(Scene scene) + { + m_scene = scene; + if (m_pluginEnabled) { // we need to capture scene in an anonymous method // here as we need it later in the callbacks scene.EventManager.OnRegisterCaps += delegate(UUID agentID, Caps caps) - { - OnRegisterCaps(scene, agentID, caps); - }; - - + { + OnRegisterCaps(scene, agentID, caps); + }; + + try { @@ -254,21 +259,53 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_log.Error("[FreeSwitchVoice]: Certificate validation handler change not supported. You may get ssl certificate validation errors teleporting from your region to some SSL regions."); } } - + } - } - - public void PostInitialise() - { if (m_pluginEnabled) { m_log.Info("[FreeSwitchVoice] registering IVoiceModule with the scene"); - + // register the voice interface for this module, so the script engine can call us m_scene.RegisterModuleInterface(this); } } + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + if (UseProxy) + { + MainServer.Instance.RemoveHTTPHandler("", String.Format("{0}/", m_freeSwitchAPIPrefix)); + } + else + { + MainServer.Instance.RemoveHTTPHandler("", String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix)); + + MainServer.Instance.RemoveHTTPHandler("", String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix)); + + MainServer.Instance.RemoveHTTPHandler("", String.Format("{0}/freeswitch-config", m_freeSwitchAPIPrefix)); + + MainServer.Instance.RemoveHTTPHandler("", String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix)); + } + scene.EventManager.OnRegisterCaps -= delegate(UUID agentID, Caps caps) + { + OnRegisterCaps(scene, agentID, caps); + }; + scene.UnregisterModuleInterface(this); + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void PostInitialise() + { + } + public void Close() { } @@ -277,11 +314,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { get { return "FreeSwitchVoiceModule"; } } - - public bool IsSharedModule - { - get { return true; } - } // // implementation of IVoiceModule, called by osSetParcelSIPAddress script function diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementModule.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementModule.cs index 3d1c346dc8..6769d59bc6 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementModule.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementModule.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -38,6 +38,7 @@ using System.Threading; using OpenMetaverse; +using Mono.Addins; using Nini.Config; using OpenSim; @@ -50,7 +51,8 @@ using log4net; namespace OpenSim.Region.OptionalModules.ContentManagement { - public class ContentManagementModule : IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class ContentManagementModule : ISharedRegionModule { #region Static Fields @@ -60,22 +62,20 @@ namespace OpenSim.Region.OptionalModules.ContentManagement #region Fields - bool initialised = false; - CMController m_control = null; - bool m_enabled = false; - CMModel m_model = null; - bool m_posted = false; - CMView m_view = null; + private bool initialised = false; + private CMController m_control = null; + private bool m_enabled = false; + private CMModel m_model = null; + private bool m_posted = false; + private CMView m_view = null; + private string databaseDir = "./"; + private string database = "FileSystemDatabase"; + private int channel = 345; #endregion Fields #region Public Properties - public bool IsSharedModule - { - get { return true; } - } - public string Name { get { return "ContentManagementModule"; } @@ -89,11 +89,8 @@ namespace OpenSim.Region.OptionalModules.ContentManagement { } - public void Initialise(Scene scene, IConfigSource source) + public void Initialise(IConfigSource source) { - string databaseDir = "./"; - string database = "FileSystemDatabase"; - int channel = 345; try { if (source.Configs["CMS"] == null) @@ -115,13 +112,15 @@ namespace OpenSim.Region.OptionalModules.ContentManagement m_log.ErrorFormat("[Content Management]: Exception thrown while reading parameters from configuration file. Message: " + e); m_enabled = false; } + } + public void AddRegion(Scene scene) + { if (!m_enabled) { m_log.Info("[Content Management]: Content Management System is not Enabled."); return; } - lock (this) { if (!initialised) //only init once @@ -142,6 +141,18 @@ namespace OpenSim.Region.OptionalModules.ContentManagement } } } + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + } + + public Type ReplaceableInterface + { + get { return null; } + } public void PostInitialise() { diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs index 4521f8ef6a..f24bcdc1e7 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs @@ -38,6 +38,7 @@ using System.Security.Policy; using System.Text; using log4net; using Microsoft.CSharp; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -46,7 +47,8 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.OptionalModules.Scripting.Minimodule { - public class MRMModule : IRegionModule, IMRMModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class MRMModule : INonSharedRegionModule, IMRMModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; @@ -62,12 +64,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule private IConfig m_config; + private bool m_hidden = true; + public void RegisterExtension(T instance) { m_extensions[typeof (T)] = instance; } - public void Initialise(Scene scene, IConfigSource source) + public void Initialise(IConfigSource source) { if (source.Configs["MRM"] != null) { @@ -76,19 +80,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule if (source.Configs["MRM"].GetBoolean("Enabled", false)) { m_log.Info("[MRM] Enabling MRM Module"); - m_scene = scene; - + // when hidden, we don't listen for client initiated script events // only making the MRM engine available for region modules - if (!source.Configs["MRM"].GetBoolean("Hidden", false)) - { - scene.EventManager.OnRezScript += EventManager_OnRezScript; - scene.EventManager.OnStopScript += EventManager_OnStopScript; - } - - scene.EventManager.OnFrame += EventManager_OnFrame; - - scene.RegisterModuleInterface(this); + m_hidden = source.Configs["MRM"].GetBoolean("Hidden", false); } else { @@ -101,6 +96,39 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule } } + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) + { + m_scene = scene; + if (!m_hidden) + { + scene.EventManager.OnRezScript += EventManager_OnRezScript; + scene.EventManager.OnStopScript += EventManager_OnStopScript; + } + scene.EventManager.OnFrame += EventManager_OnFrame; + + scene.RegisterModuleInterface(this); + } + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + if (!m_hidden) + { + scene.EventManager.OnRezScript -= EventManager_OnRezScript; + scene.EventManager.OnStopScript -= EventManager_OnStopScript; + } + scene.EventManager.OnFrame -= EventManager_OnFrame; + + scene.UnregisterModuleInterface(this); + } + void EventManager_OnStopScript(uint localID, UUID itemID) { if (m_scripts.ContainsKey(itemID)) @@ -302,11 +330,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule mmb.InitMiniModule(world, host, itemID); } - public void PostInitialise() - { - - } - public void Close() { foreach (KeyValuePair pair in m_scripts) @@ -320,11 +343,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule get { return "MiniRegionModule"; } } - public bool IsSharedModule - { - get { return false; } - } - /// /// Stolen from ScriptEngine Common /// diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs index c653e98401..999756a93f 100644 --- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs @@ -100,10 +100,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady if (!m_enabled) return; - m_scene.EventManager.OnEmptyScriptCompileQueue -= OnEmptyScriptCompileQueue; - m_scene.EventManager.OnOarFileLoaded -= OnOarFileLoaded; + scene.EventManager.OnEmptyScriptCompileQueue -= OnEmptyScriptCompileQueue; + scene.EventManager.OnOarFileLoaded -= OnOarFileLoaded; - m_scene = null; + scene = null; } public void Close() diff --git a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs index 44c9ada221..df01938d5f 100644 --- a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs @@ -58,6 +58,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms public void RemoveRegion(Scene scene) { + scene.UnregisterModuleInterface(this); } public void RegionLoaded(Scene scene) diff --git a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs index d18ac0a90c..f2a0e53558 100644 --- a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs @@ -30,6 +30,7 @@ using System.Collections.Generic; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; @@ -49,7 +50,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule public string uri; } - public class XmlRpcGridRouter : IRegionModule, IXmlRpcRouter + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class XmlRpcGridRouter : INonSharedRegionModule, IXmlRpcRouter { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -59,7 +61,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule private bool m_Enabled = false; private string m_ServerURI = String.Empty; - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { IConfig startupConfig = config.Configs["Startup"]; if (startupConfig == null) @@ -75,13 +77,26 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule return; } - scene.RegisterModuleInterface(this); m_Enabled = true; } } - public void PostInitialise() + public void AddRegion(Scene scene) { + scene.RegisterModuleInterface(this); + } + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + scene.UnregisterModuleInterface(this); + } + + public Type ReplaceableInterface + { + get { return null; } } public void Close() @@ -93,11 +108,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule get { return "XmlRpcGridRouterModule"; } } - public bool IsSharedModule - { - get { return false; } - } - public void RegisterNewReceiver(IScriptModule scriptEngine, UUID channel, UUID objectID, UUID itemID, string uri) { if (!m_Channels.ContainsKey(itemID)) diff --git a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs index 32659c8e5d..4d39345302 100644 --- a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs @@ -29,6 +29,7 @@ using System; using System.Reflection; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; @@ -39,11 +40,12 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcRouterModule { - public class XmlRpcRouter : IRegionModule, IXmlRpcRouter + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class XmlRpcRouter : INonSharedRegionModule, IXmlRpcRouter { //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - public void Initialise(Scene scene, IConfigSource config) + private bool m_enabled = false; + public void Initialise(IConfigSource config) { IConfig startupConfig = config.Configs["Startup"]; if (startupConfig == null) @@ -52,12 +54,25 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcRouterModule if (startupConfig.GetString("XmlRpcRouterModule", "XmlRpcRouterModule") == "XmlRpcRouterModule") { - scene.RegisterModuleInterface(this); + m_enabled = true; } } - - public void PostInitialise() + public void AddRegion(Scene scene) { + scene.RegisterModuleInterface(this); + } + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + scene.UnregisterModuleInterface(this); + } + + public Type ReplaceableInterface + { + get { return null; } } public void Close() @@ -69,11 +84,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcRouterModule get { return "XmlRpcRouterModule"; } } - public bool IsSharedModule - { - get { return false; } - } - public void RegisterNewReceiver(IScriptModule scriptEngine, UUID channel, UUID objectID, UUID itemID, string uri) { scriptEngine.PostScriptEvent(itemID, "xmlrpc_uri", new Object[] {uri}); diff --git a/OpenSim/Region/OptionalModules/ServiceConnectorsIn/Freeswitch/FreeswitchServiceInConnectorModule.cs b/OpenSim/Region/OptionalModules/ServiceConnectorsIn/Freeswitch/FreeswitchServiceInConnectorModule.cs index 97fa63cb45..801f1f8f50 100644 --- a/OpenSim/Region/OptionalModules/ServiceConnectorsIn/Freeswitch/FreeswitchServiceInConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/ServiceConnectorsIn/Freeswitch/FreeswitchServiceInConnectorModule.cs @@ -47,7 +47,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Freeswitch private IConfigSource m_Config; bool m_Registered = false; - #region IRegionModule interface + #region ISharedRegionModule interface public void Initialise(IConfigSource config) { diff --git a/OpenSim/Region/OptionalModules/SvnSerialiser/SvnBackupModule.cs b/OpenSim/Region/OptionalModules/SvnSerialiser/SvnBackupModule.cs index 3490a8baef..fa5878d5c5 100644 --- a/OpenSim/Region/OptionalModules/SvnSerialiser/SvnBackupModule.cs +++ b/OpenSim/Region/OptionalModules/SvnSerialiser/SvnBackupModule.cs @@ -31,6 +31,7 @@ using System.IO; using System.Reflection; using System.Timers; using log4net; +using Mono.Addins; using Nini.Config; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.CoreModules.World.Serialiser; @@ -42,7 +43,8 @@ using Slash = System.IO.Path; namespace OpenSim.Region.Modules.SvnSerialiser { - public class SvnBackupModule : IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class SvnBackupModule : ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -200,9 +202,9 @@ namespace OpenSim.Region.Modules.SvnSerialiser #endregion - #region IRegionModule Members + #region ISharedRegionModule Members - public void Initialise(Scene scene, IConfigSource source) + public void Initialise(IConfigSource source) { m_scenes = new List(); m_timer = new Timer(); @@ -225,7 +227,10 @@ namespace OpenSim.Region.Modules.SvnSerialiser catch (Exception) { } + } + public void AddRegion(Scene scene) + { lock (m_scenes) { m_scenes.Add(scene); @@ -236,6 +241,18 @@ namespace OpenSim.Region.Modules.SvnSerialiser scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; } } + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + } + + public Type ReplaceableInterface + { + get { return null; } + } public void PostInitialise() { @@ -277,11 +294,6 @@ namespace OpenSim.Region.Modules.SvnSerialiser get { return "SvnBackupModule"; } } - public bool IsSharedModule - { - get { return true; } - } - #endregion private void EventManager_OnPluginConsole(string[] args) diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index ac39a532ae..521d01a7d4 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -25,9 +25,11 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; using System.Collections.Generic; using System.Threading; using OpenMetaverse; +using Mono.Addins; using Nini.Config; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -37,7 +39,8 @@ using Timer=System.Timers.Timer; namespace OpenSim.Region.OptionalModules.World.NPC { - public class NPCModule : IRegionModule, INPCModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class NPCModule : ISharedRegionModule, INPCModule { // private const bool m_enabled = false; @@ -134,15 +137,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC } - public void Initialise(Scene scene, IConfigSource source) + public void Initialise(IConfigSource source) { m_createMutex = new Mutex(false); m_timer = new Timer(500); m_timer.Elapsed += m_timer_Elapsed; m_timer.Start(); - - scene.RegisterModuleInterface(this); } void m_timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) @@ -173,6 +174,19 @@ namespace OpenSim.Region.OptionalModules.World.NPC } } + public void AddRegion(Scene scene) + { + scene.RegisterModuleInterface(this); + } + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + scene.UnregisterModuleInterface(this); + } + public void PostInitialise() { } @@ -186,9 +200,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC get { return "NPCModule"; } } - public bool IsSharedModule + public Type ReplaceableInterface { - get { return true; } - } + get { return null; } + } } } diff --git a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs index e3fbb6ee09..b59d07adde 100644 --- a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs +++ b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs @@ -31,6 +31,7 @@ using System.Reflection; using System.Timers; using OpenMetaverse; using log4net; +using Mono.Addins; using Nini.Config; using OpenSim.Framework; using OpenSim.Region.CoreModules.Framework.InterfaceCommander; @@ -46,7 +47,8 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator /// /// Version 2.02 - Still hacky /// - public class TreePopulatorModule : IRegionModule, ICommandableModule, IVegetationModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class TreePopulatorModule : INonSharedRegionModule, ICommandableModule, IVegetationModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private readonly Commander m_commander = new Commander("tree"); @@ -168,15 +170,10 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator #endregion - #region IRegionModule Members + #region ISharedRegionModule Members - public void Initialise(Scene scene, IConfigSource config) + public void Initialise(IConfigSource config) { - - m_scene = scene; - m_scene.RegisterModuleInterface(this); - m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; - // ini file settings try { @@ -196,12 +193,18 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator m_log.Debug("[TREES]: ini failure for update_rate - using default"); } - InstallCommands(); - m_log.Debug("[TREES]: Initialised tree module"); } - public void PostInitialise() + public void AddRegion(Scene scene) + { + m_scene = scene; + m_scene.RegisterModuleInterface(this); + m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; + InstallCommands(); + } + + public void RegionLoaded(Scene scene) { ReloadCopse(); if (m_copse.Count > 0) @@ -211,6 +214,17 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator activeizeTreeze(true); } + public void RemoveRegion(Scene scene) + { + scene.UnregisterModuleInterface(this); + scene.EventManager.OnPluginConsole -= EventManager_OnPluginConsole; + } + + public Type ReplaceableInterface + { + get { return null; } + } + public void Close() { } @@ -220,11 +234,6 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator get { return "TreePopulatorModule"; } } - public bool IsSharedModule - { - get { return false; } - } - #endregion //-------------------------------------------------------------- diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs index a03cc4cf50..9b53d06bb9 100644 --- a/OpenSim/Region/UserStatistics/WebStatsModule.cs +++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs @@ -34,6 +34,7 @@ using System.Reflection; using System.Text; using System.Threading; using log4net; +using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenMetaverse.StructuredData; @@ -52,7 +53,8 @@ using OSDMap = OpenMetaverse.StructuredData.OSDMap; namespace OpenSim.Region.UserStatistics { - public class WebStatsModule : IRegionModule + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class WebStatsModule : ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -70,7 +72,7 @@ namespace OpenSim.Region.UserStatistics private string m_loglines = String.Empty; private volatile int lastHit = 12000; - public virtual void Initialise(Scene scene, IConfigSource config) + public virtual void Initialise(IConfigSource config) { IConfig cnfg; try @@ -82,11 +84,17 @@ namespace OpenSim.Region.UserStatistics { enabled = false; } - + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) + { if (!enabled) - { return; - } lock (m_scene) { @@ -130,7 +138,7 @@ namespace OpenSim.Region.UserStatistics MainServer.Instance.AddHTTPHandler("/SStats/", HandleStatsRequest); MainServer.Instance.AddHTTPHandler("/CAPS/VS/", HandleUnknownCAPSRequest); } - + m_scene.Add(scene); if (m_simstatsCounters.ContainsKey(scene.RegionInfo.RegionID)) m_simstatsCounters.Remove(scene.RegionInfo.RegionID); @@ -140,6 +148,14 @@ namespace OpenSim.Region.UserStatistics } } + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + } + public void ReceiveClassicSimStatsPacket(SimStats stats) { if (!enabled) @@ -308,11 +324,6 @@ namespace OpenSim.Region.UserStatistics get { return "ViewerStatsModule"; } } - public bool IsSharedModule - { - get { return true; } - } - public void OnRegisterCaps(UUID agentID, Caps caps) { m_log.DebugFormat("[VC]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps); diff --git a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs index b13e8dd208..20f2bca301 100644 --- a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs +++ b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs @@ -161,10 +161,11 @@ namespace OpenSim.Tests.Common.Setup capsModule.Initialise(new IniConfigSource()); testScene.AddRegionModule(capsModule.Name, capsModule); capsModule.AddRegion(testScene); - - IRegionModule godsModule = new GodsModule(); - godsModule.Initialise(testScene, new IniConfigSource()); - testScene.AddModule(godsModule.Name, godsModule); + + INonSharedRegionModule godsModule = new GodsModule(); + godsModule.Initialise(new IniConfigSource()); + testScene.AddRegionModule(godsModule.Name, godsModule); + godsModule.AddRegion(testScene); realServices = realServices.ToLower(); // IConfigSource config = new IniConfigSource(); From 316503c3984ea5333e6d13fb3d4d2f308a618424 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 23 Jan 2010 15:40:34 +0000 Subject: [PATCH 07/11] Added some prebuild refs needed for mono building --- prebuild.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/prebuild.xml b/prebuild.xml index 0ab7414f4c..46a10578de 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -2242,6 +2242,7 @@ + @@ -2302,6 +2303,7 @@ + @@ -2812,6 +2814,7 @@ + From fe06f0dd05fa783a6d3d7e7aa2b5614c9825e8fe Mon Sep 17 00:00:00 2001 From: Revolution Date: Sat, 23 Jan 2010 20:29:02 -0600 Subject: [PATCH 08/11] Fixes Region Crossings on a prim. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 1c183f3310..5562e51ee4 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2779,7 +2779,15 @@ namespace OpenSim.Region.Framework.Scenes protected void CrossToNewRegion() { InTransit(); - m_scene.CrossAgentToNewRegion(this, m_physicsActor.Flying); + try + { + m_scene.CrossAgentToNewRegion(this, m_physicsActor.Flying); + } + catch(Exception ex) + { + m_scene.CrossAgentToNewRegion(this, false); + } + } public void InTransit() From 19d4867af7ee6c8f3005b116a545319cda8e1b25 Mon Sep 17 00:00:00 2001 From: Adam Frisby Date: Tue, 26 Jan 2010 07:40:33 +1100 Subject: [PATCH 09/11] * Quick fix to Remote Console session ID handling. --- OpenSim/Framework/Console/RemoteConsole.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OpenSim/Framework/Console/RemoteConsole.cs b/OpenSim/Framework/Console/RemoteConsole.cs index c27072c2c4..9fdd1b8a14 100644 --- a/OpenSim/Framework/Console/RemoteConsole.cs +++ b/OpenSim/Framework/Console/RemoteConsole.cs @@ -302,6 +302,12 @@ namespace OpenSim.Framework.Console if (!UUID.TryParse(post["ID"].ToString(), out id)) return reply; + lock(m_Connections) + { + if(!m_Connections.ContainsKey(id)) + return reply; + } + if (post["COMMAND"] == null || post["COMMAND"].ToString() == String.Empty) return reply; From 38cfc9366ce264d2aeb6409df48be7cecc348952 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 25 Jan 2010 21:51:58 +0000 Subject: [PATCH 10/11] Fix a problem where llDie() calls were sometimes leaving dead objects behind. When an object was deleted, the remove script instance call was aggregating the scripting events as normal. This would queue a full update of the prim before the viewer was notifed of the deletion of that prim (QuitPacket) On some occasions, the QuitPacket would be sent before the full update was dequeued and sent. In principle, you would think that a viewer would ignore updates for deleted prims. But it appears that in the Linden viewer (1.23.5), a prim update that arrives after the prim was deleted instead makes the deleted prim persist in the viewer. Such prims have no properties and cannot be removed from the viewer except by a relog. This change stops the prim event aggregation call if it's being deleted anyway, hence removing the spurious viewer-confusing update. --- .../ClientStack/LindenUDP/LLClientView.cs | 18 ++++++++++++++++ .../Framework/Interfaces/IEntityInventory.cs | 12 +++++++++-- .../Framework/Scenes/Scene.Inventory.cs | 4 +++- OpenSim/Region/Framework/Scenes/Scene.cs | 8 +++++-- .../Scenes/SceneObjectGroup.Inventory.cs | 8 +++++-- .../Framework/Scenes/SceneObjectPart.cs | 12 ++++++++++- .../Scenes/SceneObjectPartInventory.cs | 21 ++++++++++++++----- .../Region/ScriptEngine/XEngine/XEngine.cs | 9 +++----- 8 files changed, 73 insertions(+), 19 deletions(-) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 4b5e4c4d5c..1d364d4178 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -1465,6 +1465,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void SendKillObject(ulong regionHandle, uint localID) { +// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); + KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); // TODO: don't create new blocks if recycling an old packet kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; @@ -3472,6 +3474,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void SendPrimitiveToClient(SendPrimitiveData data) { +// string text = data.text; +// if (text.IndexOf("\n") >= 0) +// text = text.Remove(text.IndexOf("\n")); +// m_log.DebugFormat( +// "[CLIENT]: Placing request to send full info about prim {0} text {1} to client {2}", +// data.localID, text, Name); + if (data.priority == double.NaN) { m_log.Error("[LLClientView] SendPrimitiveToClient received a NaN priority, dropping update"); @@ -3509,7 +3518,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[count]; for (int i = 0; i < count; i++) + { outPacket.ObjectData[i] = m_primFullUpdates.Dequeue(); + +// string text = Util.FieldToString(outPacket.ObjectData[i].Text); +// if (text.IndexOf("\n") >= 0) +// text = text.Remove(text.IndexOf("\n")); +// m_log.DebugFormat( +// "[CLIENT]: Sending full info about prim {0} text {1} to client {2}", +// outPacket.ObjectData[i].ID, text, Name); + } } OutPacket(outPacket, ThrottleOutPacketType.State); diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index 67395fa23d..eeb51024e9 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs @@ -77,7 +77,11 @@ namespace OpenSim.Region.Framework.Interfaces /// /// Stop all the scripts in this entity. /// - void RemoveScriptInstances(); + /// + /// Should be true if these scripts are being removed because the scene + /// object is being deleted. This will prevent spurious updates to the client. + /// + void RemoveScriptInstances(bool sceneObjectBeingDeleted); /// /// Start a script which is in this entity's inventory. @@ -103,7 +107,11 @@ namespace OpenSim.Region.Framework.Interfaces /// Stop a script which is in this prim's inventory. /// /// - void RemoveScriptInstance(UUID itemId); + /// + /// Should be true if these scripts are being removed because the scene + /// object is being deleted. This will prevent spurious updates to the client. + /// + void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted); /// /// Add an item to this entity's inventory. If an item with the same name already exists, then an alternative diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 30440172bd..11754eaca8 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -256,7 +256,7 @@ namespace OpenSim.Region.Framework.Scenes if (isScriptRunning) { - part.Inventory.RemoveScriptInstance(item.ItemID); + part.Inventory.RemoveScriptInstance(item.ItemID, false); } // Update item with new asset @@ -855,8 +855,10 @@ namespace OpenSim.Region.Framework.Scenes if (item.Type == 10) { + part.RemoveScriptEvents(itemID); EventManager.TriggerRemoveScript(localID, itemID); } + group.RemoveInventoryItem(localID, itemID); part.GetProperties(remoteClient); } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 234554ee4d..4da05cf3c1 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1009,7 +1009,7 @@ namespace OpenSim.Region.Framework.Scenes { if (ent is SceneObjectGroup) { - ((SceneObjectGroup) ent).RemoveScriptInstances(); + ((SceneObjectGroup) ent).RemoveScriptInstances(false); } } } @@ -1884,13 +1884,15 @@ namespace OpenSim.Region.Framework.Scenes /// Suppress broadcasting changes to other clients. public void DeleteSceneObject(SceneObjectGroup group, bool silent) { +// m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID); + //SceneObjectPart rootPart = group.GetChildPart(group.UUID); // Serialise calls to RemoveScriptInstances to avoid // deadlocking on m_parts inside SceneObjectGroup lock (m_deleting_scene_object) { - group.RemoveScriptInstances(); + group.RemoveScriptInstances(true); } foreach (SceneObjectPart part in group.Children.Values) @@ -1918,6 +1920,8 @@ namespace OpenSim.Region.Framework.Scenes } group.DeleteGroup(silent); + +// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); } /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index 5a06bdb7b9..71354b4eac 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs @@ -74,13 +74,17 @@ namespace OpenSim.Region.Framework.Scenes /// /// Stop the scripts contained in all the prims in this group /// - public void RemoveScriptInstances() + /// + /// Should be true if these scripts are being removed because the scene + /// object is being deleted. This will prevent spurious updates to the client. + /// + public void RemoveScriptInstances(bool sceneObjectBeingDeleted) { lock (m_parts) { foreach (SceneObjectPart part in m_parts.Values) { - part.Inventory.RemoveScriptInstances(); + part.Inventory.RemoveScriptInstances(sceneObjectBeingDeleted); } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 56b2f13f3d..a5296eb1fd 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2479,7 +2479,7 @@ namespace OpenSim.Region.Framework.Scenes //m_log.Debug("prev: " + prevflag.ToString() + " curr: " + Flags.ToString()); //ScheduleFullUpdate(); } - + public void RemoveScriptEvents(UUID scriptid) { lock (m_scriptEvents) @@ -2533,6 +2533,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void ScheduleFullUpdate() { +// m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId); + if (m_parentGroup != null) { m_parentGroup.QueueForUpdateCheck(); @@ -4042,6 +4044,8 @@ namespace OpenSim.Region.Framework.Scenes if (m_parentGroup == null) { +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Scheduling part {0} {1} for full update in aggregateScriptEvents() since m_parentGroup == null", Name, LocalId); ScheduleFullUpdate(); return; } @@ -4058,9 +4062,15 @@ namespace OpenSim.Region.Framework.Scenes LocalFlags=(PrimFlags)objectflagupdate; if (m_parentGroup != null && m_parentGroup.RootPart == this) + { m_parentGroup.aggregateScriptEvents(); + } else + { +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Scheduling part {0} {1} for full update in aggregateScriptEvents()", Name, LocalId); ScheduleFullUpdate(); + } } public int registerTargetWaypoint(Vector3 target, float tolerance) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index eb7f5ffc9f..5f132788e1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -230,7 +230,11 @@ namespace OpenSim.Region.Framework.Scenes /// /// Stop all the scripts in this prim. /// - public void RemoveScriptInstances() + /// + /// Should be true if these scripts are being removed because the scene + /// object is being deleted. This will prevent spurious updates to the client. + /// + public void RemoveScriptInstances(bool sceneObjectBeingDeleted) { lock (Items) { @@ -238,8 +242,7 @@ namespace OpenSim.Region.Framework.Scenes { if ((int)InventoryType.LSL == item.InvType) { - RemoveScriptInstance(item.ItemID); - m_part.RemoveScriptEvents(item.ItemID); + RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); } } } @@ -388,10 +391,17 @@ namespace OpenSim.Region.Framework.Scenes /// Stop a script which is in this prim's inventory. /// /// - public void RemoveScriptInstance(UUID itemId) + /// + /// Should be true if this script is being removed because the scene + /// object is being deleted. This will prevent spurious updates to the client. + /// + public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) { if (m_items.ContainsKey(itemId)) { + if (!sceneObjectBeingDeleted) + m_part.RemoveScriptEvents(itemId); + m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemId); m_part.ParentGroup.AddActiveScriptCount(-1); } @@ -465,7 +475,7 @@ namespace OpenSim.Region.Framework.Scenes if (i.Name == item.Name) { if (i.InvType == (int)InventoryType.LSL) - RemoveScriptInstance(i.ItemID); + RemoveScriptInstance(i.ItemID, false); RemoveInventoryItem(i.ItemID); break; @@ -613,6 +623,7 @@ namespace OpenSim.Region.Framework.Scenes int type = m_items[itemID].InvType; if (type == 10) // Script { + m_part.RemoveScriptEvents(itemID); m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); } m_items.Remove(itemID); diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 6dd94bb042..c552b92a26 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -806,12 +806,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine instance.ClearQueue(); instance.Stop(0); - SceneObjectPart part = - m_Scene.GetSceneObjectPart(localID); - - if (part != null) - part.RemoveScriptEvents(itemID); - // bool objectRemoved = false; lock (m_PrimObjects) @@ -846,7 +840,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine ObjectRemoved handlerObjectRemoved = OnObjectRemoved; if (handlerObjectRemoved != null) + { + SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); handlerObjectRemoved(part.UUID); + } CleanAssemblies(); } From 72dd680dd3808f0222bb4cba0c9989c5bbb00287 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 26 Jan 2010 14:46:53 +0000 Subject: [PATCH 11/11] Replace dome tabs with spaces --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 5562e51ee4..e26283dea0 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2781,11 +2781,11 @@ namespace OpenSim.Region.Framework.Scenes InTransit(); try { - m_scene.CrossAgentToNewRegion(this, m_physicsActor.Flying); + m_scene.CrossAgentToNewRegion(this, m_physicsActor.Flying); } catch(Exception ex) { - m_scene.CrossAgentToNewRegion(this, false); + m_scene.CrossAgentToNewRegion(this, false); } } @@ -3860,4 +3860,4 @@ namespace OpenSim.Region.Framework.Scenes } } } -} \ No newline at end of file +}