aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules
diff options
context:
space:
mode:
authorubit2012-12-03 21:26:36 +0100
committerubit2012-12-03 21:26:36 +0100
commit5d4b7d537d872d27c394402d3483c2a9bd2153f0 (patch)
tree39aae50386555bf024700314fb7bee5121a9d683 /OpenSim/Region/CoreModules
parentMerge branch 'ubitwork' of ssh://3dhosting.de/var/git/careminster into ubitwork (diff)
parentMerge branch 'avination' into ubitwork (diff)
downloadopensim-SC-5d4b7d537d872d27c394402d3483c2a9bd2153f0.zip
opensim-SC-5d4b7d537d872d27c394402d3483c2a9bd2153f0.tar.gz
opensim-SC-5d4b7d537d872d27c394402d3483c2a9bd2153f0.tar.bz2
opensim-SC-5d4b7d537d872d27c394402d3483c2a9bd2153f0.tar.xz
Merge branch 'ubitwork' of ssh://3dhosting.de/var/git/careminster into ubitwork
Diffstat (limited to 'OpenSim/Region/CoreModules')
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs138
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs13
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs253
-rw-r--r--OpenSim/Region/CoreModules/Agent/IPBan/IPBanModule.cs26
-rw-r--r--OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs71
-rw-r--r--OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs33
-rw-r--r--OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs2
-rw-r--r--OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs2
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs51
-rw-r--r--OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs2
-rw-r--r--OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs1
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs36
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs76
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs40
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs38
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs29
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs144
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs61
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs1
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Gestures/GesturesModule.cs33
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs52
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs50
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs5
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs15
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs43
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs30
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs68
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs290
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs78
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs226
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs79
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs17
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs211
-rwxr-xr-xOpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs331
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs5
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs10
-rw-r--r--OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/InterGrid/OGSRadmin.cs150
-rw-r--r--OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs1297
-rw-r--r--OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs38
-rw-r--r--OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml90
-rw-r--r--OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs (renamed from OpenSim/Region/CoreModules/Framework/InventoryAccess/HGUuidGatherer.cs)42
-rw-r--r--OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs315
-rw-r--r--OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs110
-rw-r--r--OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs34
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs22
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs87
-rw-r--r--OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs383
-rw-r--r--OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs281
-rw-r--r--OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs213
-rw-r--r--OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs375
-rw-r--r--OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs82
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/Authentication/AuthenticationServiceInConnectorModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/GridInfoServiceInConnectorModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/Inventory/InventoryServiceInConnectorModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/Login/LLLoginServiceInConnectorModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/Simulation/SimulationServiceInConnectorModule.cs5
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs28
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs9
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/RemoteAssetServiceConnector.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/Tests/AssetConnectorTests.cs136
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Authentication/LocalAuthenticationServiceConnector.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Authentication/RemoteAuthenticationServiceConnector.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Avatar/LocalAvatarServiceConnector.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Avatar/RemoteAvatarServiceConnector.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs10
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs19
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/LocalGridUserServiceConnector.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/RemoteGridUserServiceConnector.cs48
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/LocalLandServiceConnector.cs5
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/RemoteLandServiceConnector.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/LocalNeighbourServiceConnector.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/RemoteNeighourServiceConnector.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/BasePresenceServiceConnector.cs137
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/LocalPresenceServiceConnector.cs113
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/RemotePresenceServiceConnector.cs91
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs3
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs12
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs8
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Access/AccessModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs434
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveScenesGroup.cs176
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs634
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs153
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs438
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs27
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs10
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs232
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs404
-rw-r--r--OpenSim/Region/CoreModules/World/Cloud/CloudModule.cs57
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs28
-rw-r--r--OpenSim/Region/CoreModules/World/Land/DwellModule.cs112
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs3
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs1
-rw-r--r--OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs (renamed from OpenSim/Region/CoreModules/LightShare/EnvironmentModule.cs)20
-rw-r--r--OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs (renamed from OpenSim/Region/CoreModules/LightShare/LightShareModule.cs)125
-rw-r--r--OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs522
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs267
-rw-r--r--OpenSim/Region/CoreModules/World/Region/RestartModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Serialiser/SerialiserModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Sound/SoundModule.cs313
-rw-r--r--OpenSim/Region/CoreModules/World/Sun/SunModule.cs64
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs63
-rw-r--r--OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs30
-rw-r--r--OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs11
-rw-r--r--OpenSim/Region/CoreModules/World/Wind/Plugins/ConfigurableWind.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Wind/Plugins/SimpleRandomWind.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Wind/WindModule.cs183
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs68
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs2
140 files changed, 6886 insertions, 4326 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
index 8a4fd8f..da1ff2e 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs
@@ -57,39 +57,36 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
57 } 57 }
58 58
59 /// <summary> 59 /// <summary>
60 /// Return a xfer uploader if one does not already exist. 60 /// Return the xfer uploader for the given transaction.
61 /// </summary> 61 /// </summary>
62 /// <remarks>
63 /// If an uploader does not already exist for this transaction then it is created, otherwise the existing
64 /// uploader is returned.
65 /// </remarks>
62 /// <param name="transactionID"></param> 66 /// <param name="transactionID"></param>
63 /// <param name="assetID"> 67 /// <returns>The asset xfer uploader</returns>
64 /// We must transfer the new asset ID into the uploader on creation, otherwise 68 public AssetXferUploader RequestXferUploader(UUID transactionID)
65 /// we can see race conditions with other threads which can retrieve an item before it is updated with the new
66 /// asset id.
67 /// </param>
68 /// <returns>
69 /// The xfer uploader requested. Null if one is already in existence.
70 /// FIXME: This is a bizarre thing to do, and is probably meant to signal an error condition if multiple
71 /// transfers are made. Needs to be corrected.
72 /// </returns>
73 public AssetXferUploader RequestXferUploader(UUID transactionID, UUID assetID)
74 { 69 {
70 AssetXferUploader uploader;
71
75 lock (XferUploaders) 72 lock (XferUploaders)
76 { 73 {
77 if (!XferUploaders.ContainsKey(transactionID)) 74 if (!XferUploaders.ContainsKey(transactionID))
78 { 75 {
79 AssetXferUploader uploader = new AssetXferUploader(this, m_Scene, assetID, m_dumpAssetsToFile); 76 uploader = new AssetXferUploader(this, m_Scene, transactionID, m_dumpAssetsToFile);
80 77
81// m_log.DebugFormat( 78// m_log.DebugFormat(
82// "[AGENT ASSETS TRANSACTIONS]: Adding asset xfer uploader {0} since it didn't previously exist", transactionID); 79// "[AGENT ASSETS TRANSACTIONS]: Adding asset xfer uploader {0} since it didn't previously exist", transactionID);
83 80
84 XferUploaders.Add(transactionID, uploader); 81 XferUploaders.Add(transactionID, uploader);
85 82 }
86 return uploader; 83 else
84 {
85 uploader = XferUploaders[transactionID];
87 } 86 }
88 } 87 }
89 88
90 m_log.WarnFormat("[AGENT ASSETS TRANSACTIONS]: Ignoring request for asset xfer uploader {0} since it already exists", transactionID); 89 return uploader;
91
92 return null;
93 } 90 }
94 91
95 public void HandleXfer(ulong xferID, uint packetID, byte[] data) 92 public void HandleXfer(ulong xferID, uint packetID, byte[] data)
@@ -151,117 +148,30 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
151 string description, string name, sbyte invType, 148 string description, string name, sbyte invType,
152 sbyte type, byte wearableType, uint nextOwnerMask) 149 sbyte type, byte wearableType, uint nextOwnerMask)
153 { 150 {
154 AssetXferUploader uploader = null; 151 AssetXferUploader uploader = RequestXferUploader(transactionID);
155
156 lock (XferUploaders)
157 {
158 if (XferUploaders.ContainsKey(transactionID))
159 uploader = XferUploaders[transactionID];
160 }
161 152
162 if (uploader != null) 153 uploader.RequestCreateInventoryItem(
163 { 154 remoteClient, folderID, callbackID,
164 uploader.RequestCreateInventoryItem( 155 description, name, invType, type, wearableType, nextOwnerMask);
165 remoteClient, transactionID, folderID,
166 callbackID, description, name, invType, type,
167 wearableType, nextOwnerMask);
168 156
169 return true; 157 return true;
170 }
171
172 return false;
173 }
174
175 /// <summary>
176 /// Get an uploaded asset. If the data is successfully retrieved,
177 /// the transaction will be removed.
178 /// </summary>
179 /// <param name="transactionID"></param>
180 /// <returns>The asset if the upload has completed, null if it has not.</returns>
181 private AssetBase GetTransactionAsset(UUID transactionID)
182 {
183 lock (XferUploaders)
184 {
185 if (XferUploaders.ContainsKey(transactionID))
186 {
187 AssetXferUploader uploader = XferUploaders[transactionID];
188 AssetBase asset = uploader.GetAssetData();
189 RemoveXferUploader(transactionID);
190
191 return asset;
192 }
193 }
194
195 return null;
196 } 158 }
197 159
198 public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient, 160 public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient,
199 SceneObjectPart part, UUID transactionID, 161 SceneObjectPart part, UUID transactionID,
200 TaskInventoryItem item) 162 TaskInventoryItem item)
201 { 163 {
202 AssetXferUploader uploader = null; 164 AssetXferUploader uploader = RequestXferUploader(transactionID);
203
204 lock (XferUploaders)
205 {
206 if (XferUploaders.ContainsKey(transactionID))
207 uploader = XferUploaders[transactionID];
208 }
209
210 if (uploader != null)
211 {
212 AssetBase asset = GetTransactionAsset(transactionID);
213
214 // Only legacy viewers use this, and they prefer CAPS, which
215 // we have, so this really never runs.
216 // Allow it, but only for "safe" types.
217 if ((InventoryType)item.InvType != InventoryType.Notecard &&
218 (InventoryType)item.InvType != InventoryType.LSL)
219 return;
220 165
221 if (asset != null) 166 uploader.RequestUpdateTaskInventoryItem(remoteClient, item);
222 {
223// m_log.DebugFormat(
224// "[AGENT ASSETS TRANSACTIONS]: Updating item {0} in {1} for transaction {2}",
225// item.Name, part.Name, transactionID);
226
227 asset.FullID = UUID.Random();
228 asset.Name = item.Name;
229 asset.Description = item.Description;
230 asset.Type = (sbyte)item.Type;
231 item.AssetID = asset.FullID;
232
233 m_Scene.AssetService.Store(asset);
234 }
235 }
236 else
237 {
238 m_log.ErrorFormat(
239 "[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to update task inventory item {1} in {2}",
240 transactionID, item.Name, part.Name);
241 }
242 } 167 }
243 168
244 public void RequestUpdateInventoryItem(IClientAPI remoteClient, 169 public void RequestUpdateInventoryItem(IClientAPI remoteClient,
245 UUID transactionID, InventoryItemBase item) 170 UUID transactionID, InventoryItemBase item)
246 { 171 {
247 AssetXferUploader uploader = null; 172 AssetXferUploader uploader = RequestXferUploader(transactionID);
248
249 lock (XferUploaders)
250 {
251 if (XferUploaders.ContainsKey(transactionID))
252 uploader = XferUploaders[transactionID];
253 }
254 173
255 if (uploader != null) 174 uploader.RequestUpdateInventoryItem(remoteClient, item);
256 {
257 uploader.RequestUpdateInventoryItem(remoteClient, transactionID, item);
258 }
259 else
260 {
261 m_log.ErrorFormat(
262 "[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to update inventory item {1} for {2}",
263 transactionID, item.Name, remoteClient.Name);
264 }
265 } 175 }
266 } 176 }
267} 177}
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
index 441c4ff..7332415 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
@@ -54,7 +54,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
54 private Dictionary<UUID, AgentAssetTransactions> AgentTransactions = 54 private Dictionary<UUID, AgentAssetTransactions> AgentTransactions =
55 new Dictionary<UUID, AgentAssetTransactions>(); 55 new Dictionary<UUID, AgentAssetTransactions>();
56 56
57 #region IRegionModule Members 57 #region Region Module interface
58 58
59 public void Initialise(IConfigSource source) 59 public void Initialise(IConfigSource source)
60 { 60 {
@@ -215,7 +215,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
215 IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item) 215 IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item)
216 { 216 {
217 m_log.DebugFormat( 217 m_log.DebugFormat(
218 "[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0} in {1} for {2} in {3}", 218 "[ASSET TRANSACTION MODULE] Called HandleTaskItemUpdateFromTransaction with item {0} in {1} for {2} in {3}",
219 item.Name, part.Name, remoteClient.Name, m_Scene.RegionInfo.RegionName); 219 item.Name, part.Name, remoteClient.Name, m_Scene.RegionInfo.RegionName);
220 220
221 AgentAssetTransactions transactions = 221 AgentAssetTransactions transactions =
@@ -274,13 +274,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
274 } 274 }
275 275
276 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 276 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
277 AssetXferUploader uploader = transactions.RequestXferUploader(transaction, assetID); 277 AssetXferUploader uploader = transactions.RequestXferUploader(transaction);
278 278 uploader.StartUpload(remoteClient, assetID, transaction, type, data, storeLocal, tempFile);
279 if (uploader != null)
280 {
281 uploader.Initialise(remoteClient, assetID, transaction, type,
282 data, storeLocal, tempFile);
283 }
284 } 279 }
285 280
286 /// <summary> 281 /// <summary>
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
index 4cedfe6..0aa4693 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
@@ -49,39 +49,75 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 50
51 /// <summary> 51 /// <summary>
52 /// Upload state.
53 /// </summary>
54 /// <remarks>
55 /// New -> Uploading -> Complete
56 /// </remarks>
57 private enum UploadState
58 {
59 New,
60 Uploading,
61 Complete
62 }
63
64 /// <summary>
52 /// Reference to the object that holds this uploader. Used to remove ourselves from it's list if we 65 /// Reference to the object that holds this uploader. Used to remove ourselves from it's list if we
53 /// are performing a delayed update. 66 /// are performing a delayed update.
54 /// </summary> 67 /// </summary>
55 AgentAssetTransactions m_transactions; 68 AgentAssetTransactions m_transactions;
56 69
70 private UploadState m_uploadState = UploadState.New;
71
57 private AssetBase m_asset; 72 private AssetBase m_asset;
58 private UUID InventFolder = UUID.Zero; 73 private UUID InventFolder = UUID.Zero;
59 private sbyte invType = 0; 74 private sbyte invType = 0;
60 75
61 private bool m_createItem = false; 76 private bool m_createItem;
62 private uint m_createItemCallback = 0; 77 private uint m_createItemCallback;
63 private bool m_updateItem = false; 78
79 private bool m_updateItem;
64 private InventoryItemBase m_updateItemData; 80 private InventoryItemBase m_updateItemData;
65 81
82 private bool m_updateTaskItem;
83 private TaskInventoryItem m_updateTaskItemData;
84
66 private string m_description = String.Empty; 85 private string m_description = String.Empty;
67 private bool m_dumpAssetToFile; 86 private bool m_dumpAssetToFile;
68 private bool m_finished = false;
69 private string m_name = String.Empty; 87 private string m_name = String.Empty;
70 private bool m_storeLocal; 88// private bool m_storeLocal;
71 private uint nextPerm = 0; 89 private uint nextPerm = 0;
72 private IClientAPI ourClient; 90 private IClientAPI ourClient;
73 private UUID TransactionID = UUID.Zero; 91
92 private UUID m_transactionID;
93
74 private sbyte type = 0; 94 private sbyte type = 0;
75 private byte wearableType = 0; 95 private byte wearableType = 0;
76 private byte[] m_oldData = null; 96 private byte[] m_oldData = null;
77 public ulong XferID; 97 public ulong XferID;
78 private Scene m_Scene; 98 private Scene m_Scene;
79 99
80 public AssetXferUploader(AgentAssetTransactions transactions, Scene scene, UUID assetID, bool dumpAssetToFile) 100 /// <summary>
101 /// AssetXferUploader constructor
102 /// </summary>
103 /// <param name='transactions'>/param>
104 /// <param name='scene'></param>
105 /// <param name='transactionID'></param>
106 /// <param name='dumpAssetToFile'>
107 /// If true then when the asset is uploaded it is dumped to a file with the format
108 /// String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat",
109 /// now.Year, now.Month, now.Day, now.Hour, now.Minute,
110 /// now.Second, m_asset.Name, m_asset.Type);
111 /// for debugging purposes.
112 /// </param>
113 public AssetXferUploader(
114 AgentAssetTransactions transactions, Scene scene, UUID transactionID, bool dumpAssetToFile)
81 { 115 {
116 m_asset = new AssetBase();
117
82 m_transactions = transactions; 118 m_transactions = transactions;
119 m_transactionID = transactionID;
83 m_Scene = scene; 120 m_Scene = scene;
84 m_asset = new AssetBase() { FullID = assetID };
85 m_dumpAssetToFile = dumpAssetToFile; 121 m_dumpAssetToFile = dumpAssetToFile;
86 } 122 }
87 123
@@ -100,18 +136,27 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
100 136
101 if (XferID == xferID) 137 if (XferID == xferID)
102 { 138 {
103 if (m_asset.Data.Length > 1) 139 lock (this)
104 {
105 byte[] destinationArray = new byte[m_asset.Data.Length + data.Length];
106 Array.Copy(m_asset.Data, 0, destinationArray, 0, m_asset.Data.Length);
107 Array.Copy(data, 0, destinationArray, m_asset.Data.Length, data.Length);
108 m_asset.Data = destinationArray;
109 }
110 else
111 { 140 {
112 byte[] buffer2 = new byte[data.Length - 4]; 141 int assetLength = m_asset.Data.Length;
113 Array.Copy(data, 4, buffer2, 0, data.Length - 4); 142 int dataLength = data.Length;
114 m_asset.Data = buffer2; 143
144 if (m_asset.Data.Length > 1)
145 {
146 byte[] destinationArray = new byte[assetLength + dataLength];
147 Array.Copy(m_asset.Data, 0, destinationArray, 0, assetLength);
148 Array.Copy(data, 0, destinationArray, assetLength, dataLength);
149 m_asset.Data = destinationArray;
150 }
151 else
152 {
153 if (dataLength > 4)
154 {
155 byte[] buffer2 = new byte[dataLength - 4];
156 Array.Copy(data, 4, buffer2, 0, dataLength - 4);
157 m_asset.Data = buffer2;
158 }
159 }
115 } 160 }
116 161
117 ourClient.SendConfirmXfer(xferID, packetID); 162 ourClient.SendConfirmXfer(xferID, packetID);
@@ -127,30 +172,50 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
127 } 172 }
128 173
129 /// <summary> 174 /// <summary>
130 /// Initialise asset transfer from the client 175 /// Start asset transfer from the client
131 /// </summary> 176 /// </summary>
132 /// <param name="xferID"></param> 177 /// <param name="remoteClient"></param>
133 /// <param name="packetID"></param> 178 /// <param name="assetID"></param>
134 /// <param name="data"></param> 179 /// <param name="transaction"></param>
135 public void Initialise(IClientAPI remoteClient, UUID assetID, 180 /// <param name="type"></param>
136 UUID transaction, sbyte type, byte[] data, bool storeLocal, 181 /// <param name="data">
137 bool tempFile) 182 /// Optional data. If present then the asset is created immediately with this data
183 /// rather than requesting an upload from the client. The data must be longer than 2 bytes.
184 /// </param>
185 /// <param name="storeLocal"></param>
186 /// <param name="tempFile"></param>
187 public void StartUpload(
188 IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type, byte[] data, bool storeLocal,
189 bool tempFile)
138 { 190 {
139// m_log.DebugFormat( 191// m_log.DebugFormat(
140// "[ASSET XFER UPLOADER]: Initialised xfer from {0}, asset {1}, transaction {2}, type {3}, storeLocal {4}, tempFile {5}, already received data length {6}", 192// "[ASSET XFER UPLOADER]: Initialised xfer from {0}, asset {1}, transaction {2}, type {3}, storeLocal {4}, tempFile {5}, already received data length {6}",
141// remoteClient.Name, assetID, transaction, type, storeLocal, tempFile, data.Length); 193// remoteClient.Name, assetID, transaction, type, storeLocal, tempFile, data.Length);
142 194
195 lock (this)
196 {
197 if (m_uploadState != UploadState.New)
198 {
199 m_log.WarnFormat(
200 "[ASSET XFER UPLOADER]: Tried to start upload of asset {0}, transaction {1} for {2} but this is already in state {3}. Aborting.",
201 assetID, transaction, remoteClient.Name, m_uploadState);
202
203 return;
204 }
205
206 m_uploadState = UploadState.Uploading;
207 }
208
143 ourClient = remoteClient; 209 ourClient = remoteClient;
144 m_asset.Name = "blank"; 210
145 m_asset.Description = "empty"; 211 m_asset.FullID = assetID;
146 m_asset.Type = type; 212 m_asset.Type = type;
147 m_asset.CreatorID = remoteClient.AgentId.ToString(); 213 m_asset.CreatorID = remoteClient.AgentId.ToString();
148 m_asset.Data = data; 214 m_asset.Data = data;
149 m_asset.Local = storeLocal; 215 m_asset.Local = storeLocal;
150 m_asset.Temporary = tempFile; 216 m_asset.Temporary = tempFile;
151 217
152 TransactionID = transaction; 218// m_storeLocal = storeLocal;
153 m_storeLocal = storeLocal;
154 219
155 if (m_asset.Data.Length > 2) 220 if (m_asset.Data.Length > 2)
156 { 221 {
@@ -175,36 +240,35 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
175 240
176 protected void SendCompleteMessage() 241 protected void SendCompleteMessage()
177 { 242 {
178 ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true,
179 m_asset.FullID);
180
181 // We must lock in order to avoid a race with a separate thread dealing with an inventory item or create 243 // We must lock in order to avoid a race with a separate thread dealing with an inventory item or create
182 // message from other client UDP. 244 // message from other client UDP.
183 lock (this) 245 lock (this)
184 { 246 {
185 m_finished = true; 247 m_uploadState = UploadState.Complete;
248
249 ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, m_asset.FullID);
250
186 if (m_createItem) 251 if (m_createItem)
187 { 252 {
188 DoCreateItem(m_createItemCallback); 253 CompleteCreateItem(m_createItemCallback);
189 } 254 }
190 else if (m_updateItem) 255 else if (m_updateItem)
191 { 256 {
192 StoreAssetForItemUpdate(m_updateItemData); 257 CompleteItemUpdate(m_updateItemData);
193
194 // Remove ourselves from the list of transactions if completion was delayed until the transaction
195 // was complete.
196 // TODO: Should probably do the same for create item.
197 m_transactions.RemoveXferUploader(TransactionID);
198 } 258 }
199 else if (m_storeLocal) 259 else if (m_updateTaskItem)
200 { 260 {
201 m_Scene.AssetService.Store(m_asset); 261 CompleteTaskItemUpdate(m_updateTaskItemData);
202 } 262 }
263// else if (m_storeLocal)
264// {
265// m_Scene.AssetService.Store(m_asset);
266// }
203 } 267 }
204 268
205 m_log.DebugFormat( 269 m_log.DebugFormat(
206 "[ASSET XFER UPLOADER]: Uploaded asset {0} for transaction {1}", 270 "[ASSET XFER UPLOADER]: Uploaded asset {0} for transaction {1}",
207 m_asset.FullID, TransactionID); 271 m_asset.FullID, m_transactionID);
208 272
209 if (m_dumpAssetToFile) 273 if (m_dumpAssetToFile)
210 { 274 {
@@ -232,40 +296,37 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
232 } 296 }
233 297
234 public void RequestCreateInventoryItem(IClientAPI remoteClient, 298 public void RequestCreateInventoryItem(IClientAPI remoteClient,
235 UUID transactionID, UUID folderID, uint callbackID, 299 UUID folderID, uint callbackID,
236 string description, string name, sbyte invType, 300 string description, string name, sbyte invType,
237 sbyte type, byte wearableType, uint nextOwnerMask) 301 sbyte type, byte wearableType, uint nextOwnerMask)
238 { 302 {
239 if (TransactionID == transactionID) 303 InventFolder = folderID;
304 m_name = name;
305 m_description = description;
306 this.type = type;
307 this.invType = invType;
308 this.wearableType = wearableType;
309 nextPerm = nextOwnerMask;
310 m_asset.Name = name;
311 m_asset.Description = description;
312 m_asset.Type = type;
313
314 // We must lock to avoid a race with a separate thread uploading the asset.
315 lock (this)
240 { 316 {
241 InventFolder = folderID; 317 if (m_uploadState == UploadState.Complete)
242 m_name = name;
243 m_description = description;
244 this.type = type;
245 this.invType = invType;
246 this.wearableType = wearableType;
247 nextPerm = nextOwnerMask;
248 m_asset.Name = name;
249 m_asset.Description = description;
250 m_asset.Type = type;
251
252 // We must lock to avoid a race with a separate thread uploading the asset.
253 lock (this)
254 { 318 {
255 if (m_finished) 319 CompleteCreateItem(callbackID);
256 { 320 }
257 DoCreateItem(callbackID); 321 else
258 } 322 {
259 else 323 m_createItem = true; //set flag so the inventory item is created when upload is complete
260 { 324 m_createItemCallback = callbackID;
261 m_createItem = true; //set flag so the inventory item is created when upload is complete
262 m_createItemCallback = callbackID;
263 }
264 } 325 }
265 } 326 }
266 } 327 }
267 328
268 public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, InventoryItemBase item) 329 public void RequestUpdateInventoryItem(IClientAPI remoteClient, InventoryItemBase item)
269 { 330 {
270 // We must lock to avoid a race with a separate thread uploading the asset. 331 // We must lock to avoid a race with a separate thread uploading the asset.
271 lock (this) 332 lock (this)
@@ -280,9 +341,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
280 item.AssetID = m_asset.FullID; 341 item.AssetID = m_asset.FullID;
281 m_Scene.InventoryService.UpdateItem(item); 342 m_Scene.InventoryService.UpdateItem(item);
282 343
283 if (m_finished) 344 if (m_uploadState == UploadState.Complete)
284 { 345 {
285 StoreAssetForItemUpdate(item); 346 CompleteItemUpdate(item);
286 } 347 }
287 else 348 else
288 { 349 {
@@ -296,20 +357,59 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
296 } 357 }
297 } 358 }
298 359
360 public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient, TaskInventoryItem taskItem)
361 {
362 // We must lock to avoid a race with a separate thread uploading the asset.
363 lock (this)
364 {
365 m_asset.Name = taskItem.Name;
366 m_asset.Description = taskItem.Description;
367 m_asset.Type = (sbyte)taskItem.Type;
368 taskItem.AssetID = m_asset.FullID;
369
370 if (m_uploadState == UploadState.Complete)
371 {
372 CompleteTaskItemUpdate(taskItem);
373 }
374 else
375 {
376 m_updateTaskItem = true;
377 m_updateTaskItemData = taskItem;
378 }
379 }
380 }
381
299 /// <summary> 382 /// <summary>
300 /// Store the asset for the given item. 383 /// Store the asset for the given item when it has been uploaded.
301 /// </summary> 384 /// </summary>
302 /// <param name="item"></param> 385 /// <param name="item"></param>
303 private void StoreAssetForItemUpdate(InventoryItemBase item) 386 private void CompleteItemUpdate(InventoryItemBase item)
304 { 387 {
305// m_log.DebugFormat( 388// m_log.DebugFormat(
306// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}", 389// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}",
307// m_asset.FullID, item.Name, ourClient.Name); 390// m_asset.FullID, item.Name, ourClient.Name);
308 391
309 m_Scene.AssetService.Store(m_asset); 392 m_Scene.AssetService.Store(m_asset);
393
394 m_transactions.RemoveXferUploader(m_transactionID);
310 } 395 }
311 396
312 private void DoCreateItem(uint callbackID) 397 /// <summary>
398 /// Store the asset for the given task item when it has been uploaded.
399 /// </summary>
400 /// <param name="taskItem"></param>
401 private void CompleteTaskItemUpdate(TaskInventoryItem taskItem)
402 {
403// m_log.DebugFormat(
404// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier task item update for {1} for {2}",
405// m_asset.FullID, taskItem.Name, ourClient.Name);
406
407 m_Scene.AssetService.Store(m_asset);
408
409 m_transactions.RemoveXferUploader(m_transactionID);
410 }
411
412 private void CompleteCreateItem(uint callbackID)
313 { 413 {
314 ValidateAssets(); 414 ValidateAssets();
315 m_Scene.AssetService.Store(m_asset); 415 m_Scene.AssetService.Store(m_asset);
@@ -339,6 +439,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
339 ourClient.SendInventoryItemCreateUpdate(item, callbackID); 439 ourClient.SendInventoryItemCreateUpdate(item, callbackID);
340 else 440 else
341 ourClient.SendAlertMessage("Unable to create inventory item"); 441 ourClient.SendAlertMessage("Unable to create inventory item");
442
443 m_transactions.RemoveXferUploader(m_transactionID);
342 } 444 }
343 445
344 private void ValidateAssets() 446 private void ValidateAssets()
@@ -416,7 +518,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
416 /// <returns>null if the asset has not finished uploading</returns> 518 /// <returns>null if the asset has not finished uploading</returns>
417 public AssetBase GetAssetData() 519 public AssetBase GetAssetData()
418 { 520 {
419 if (m_finished) 521 if (m_uploadState == UploadState.Complete)
420 { 522 {
421 ValidateAssets(); 523 ValidateAssets();
422 return m_asset; 524 return m_asset;
@@ -469,4 +571,3 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
469 } 571 }
470 } 572 }
471} 573}
472
diff --git a/OpenSim/Region/CoreModules/Agent/IPBan/IPBanModule.cs b/OpenSim/Region/CoreModules/Agent/IPBan/IPBanModule.cs
index bfe2a71..4b457b1 100644
--- a/OpenSim/Region/CoreModules/Agent/IPBan/IPBanModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/IPBan/IPBanModule.cs
@@ -29,6 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO; 30using System.IO;
31using System.Text; 31using System.Text;
32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Region.Framework.Interfaces; 35using OpenSim.Region.Framework.Interfaces;
@@ -36,13 +37,18 @@ using OpenSim.Region.Framework.Scenes;
36 37
37namespace OpenSim.Region.CoreModules.Agent.IPBan 38namespace OpenSim.Region.CoreModules.Agent.IPBan
38{ 39{
39 public class IPBanModule : IRegionModule 40 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "IPBanModule")]
41 public class IPBanModule : ISharedRegionModule
40 { 42 {
41 #region Implementation of IRegionModule 43 #region Implementation of ISharedRegionModule
42 44
43 private List<string> m_bans = new List<string>(); 45 private List<string> m_bans = new List<string>();
44 46
45 public void Initialise(Scene scene, IConfigSource source) 47 public void Initialise(IConfigSource source)
48 {
49 }
50
51 public void AddRegion(Scene scene)
46 { 52 {
47 new SceneBanner(scene, m_bans); 53 new SceneBanner(scene, m_bans);
48 54
@@ -50,7 +56,7 @@ namespace OpenSim.Region.CoreModules.Agent.IPBan
50 { 56 {
51 foreach (EstateBan ban in scene.RegionInfo.EstateSettings.EstateBans) 57 foreach (EstateBan ban in scene.RegionInfo.EstateSettings.EstateBans)
52 { 58 {
53 if (!String.IsNullOrEmpty(ban.BannedHostIPMask)) 59 if (!String.IsNullOrEmpty(ban.BannedHostIPMask))
54 m_bans.Add(ban.BannedHostIPMask); 60 m_bans.Add(ban.BannedHostIPMask);
55 if (!String.IsNullOrEmpty(ban.BannedHostNameMask)) 61 if (!String.IsNullOrEmpty(ban.BannedHostNameMask))
56 m_bans.Add(ban.BannedHostNameMask); 62 m_bans.Add(ban.BannedHostNameMask);
@@ -58,6 +64,14 @@ namespace OpenSim.Region.CoreModules.Agent.IPBan
58 } 64 }
59 } 65 }
60 66
67 public void RemoveRegion(Scene scene)
68 {
69 }
70
71 public void RegionLoaded(Scene scene)
72 {
73 }
74
61 public void PostInitialise() 75 public void PostInitialise()
62 { 76 {
63 if (File.Exists("bans.txt")) 77 if (File.Exists("bans.txt"))
@@ -80,9 +94,9 @@ namespace OpenSim.Region.CoreModules.Agent.IPBan
80 get { return "IPBanModule"; } 94 get { return "IPBanModule"; }
81 } 95 }
82 96
83 public bool IsSharedModule 97 public Type ReplaceableInterface
84 { 98 {
85 get { return true; } 99 get { return null; }
86 } 100 }
87 101
88 #endregion 102 #endregion
diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
index a1a2501..3764685 100644
--- a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
@@ -32,6 +32,7 @@ using System.Reflection;
32using System.Text; 32using System.Text;
33using System.Threading; 33using System.Threading;
34using log4net; 34using log4net;
35using Mono.Addins;
35using Nini.Config; 36using Nini.Config;
36using OpenMetaverse; 37using OpenMetaverse;
37using OpenMetaverse.Imaging; 38using OpenMetaverse.Imaging;
@@ -45,7 +46,8 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
45{ 46{
46 public delegate void J2KDecodeDelegate(UUID assetID); 47 public delegate void J2KDecodeDelegate(UUID assetID);
47 48
48 public class J2KDecoderModule : IRegionModule, IJ2KDecoder 49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "J2KDecoderModule")]
50 public class J2KDecoderModule : ISharedRegionModule, IJ2KDecoder
49 { 51 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 53
@@ -55,27 +57,32 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
55 private readonly Dictionary<UUID, List<DecodedCallback>> m_notifyList = new Dictionary<UUID, List<DecodedCallback>>(); 57 private readonly Dictionary<UUID, List<DecodedCallback>> m_notifyList = new Dictionary<UUID, List<DecodedCallback>>();
56 /// <summary>Cache that will store decoded JPEG2000 layer boundary data</summary> 58 /// <summary>Cache that will store decoded JPEG2000 layer boundary data</summary>
57 private IImprovedAssetCache m_cache; 59 private IImprovedAssetCache m_cache;
60 private IImprovedAssetCache Cache
61 {
62 get
63 {
64 if (m_cache == null)
65 m_cache = m_scene.RequestModuleInterface<IImprovedAssetCache>();
66
67 return m_cache;
68 }
69 }
58 /// <summary>Reference to a scene (doesn't matter which one as long as it can load the cache module)</summary> 70 /// <summary>Reference to a scene (doesn't matter which one as long as it can load the cache module)</summary>
71 private UUID m_CreatorID = UUID.Zero;
59 private Scene m_scene; 72 private Scene m_scene;
60 73
61 #region IRegionModule 74 #region ISharedRegionModule
62 75
63 private bool m_useCSJ2K = true; 76 private bool m_useCSJ2K = true;
64 77
65 public string Name { get { return "J2KDecoderModule"; } } 78 public string Name { get { return "J2KDecoderModule"; } }
66 public bool IsSharedModule { get { return true; } }
67 79
68 public J2KDecoderModule() 80 public J2KDecoderModule()
69 { 81 {
70 } 82 }
71 83
72 public void Initialise(Scene scene, IConfigSource source) 84 public void Initialise(IConfigSource source)
73 { 85 {
74 if (m_scene == null)
75 m_scene = scene;
76
77 scene.RegisterModuleInterface<IJ2KDecoder>(this);
78
79 IConfig startupConfig = source.Configs["Startup"]; 86 IConfig startupConfig = source.Configs["Startup"];
80 if (startupConfig != null) 87 if (startupConfig != null)
81 { 88 {
@@ -83,16 +90,42 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
83 } 90 }
84 } 91 }
85 92
93 public void AddRegion(Scene scene)
94 {
95 if (m_scene == null)
96 {
97 m_scene = scene;
98 m_CreatorID = scene.RegionInfo.RegionID;
99 }
100
101 scene.RegisterModuleInterface<IJ2KDecoder>(this);
102
103 }
104
105 public void RemoveRegion(Scene scene)
106 {
107 if (m_scene == scene)
108 m_scene = null;
109 }
110
86 public void PostInitialise() 111 public void PostInitialise()
87 { 112 {
88 m_cache = m_scene.RequestModuleInterface<IImprovedAssetCache>();
89 } 113 }
90 114
91 public void Close() 115 public void Close()
92 { 116 {
93 } 117 }
94 118
95 #endregion IRegionModule 119 public void RegionLoaded(Scene scene)
120 {
121 }
122
123 public Type ReplaceableInterface
124 {
125 get { return null; }
126 }
127
128 #endregion Region Module interface
96 129
97 #region IJ2KDecoder 130 #region IJ2KDecoder
98 131
@@ -275,11 +308,11 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
275 { 308 {
276 m_decodedCache.AddOrUpdate(AssetId, Layers, TimeSpan.FromMinutes(10)); 309 m_decodedCache.AddOrUpdate(AssetId, Layers, TimeSpan.FromMinutes(10));
277 310
278 if (m_cache != null) 311 if (Cache != null)
279 { 312 {
280 string assetID = "j2kCache_" + AssetId.ToString(); 313 string assetID = "j2kCache_" + AssetId.ToString();
281 314
282 AssetBase layerDecodeAsset = new AssetBase(assetID, assetID, (sbyte)AssetType.Notecard, m_scene.RegionInfo.RegionID.ToString()); 315 AssetBase layerDecodeAsset = new AssetBase(assetID, assetID, (sbyte)AssetType.Notecard, m_CreatorID.ToString());
283 layerDecodeAsset.Local = true; 316 layerDecodeAsset.Local = true;
284 layerDecodeAsset.Temporary = true; 317 layerDecodeAsset.Temporary = true;
285 318
@@ -299,7 +332,7 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
299 332
300 #endregion Serialize Layer Data 333 #endregion Serialize Layer Data
301 334
302 m_cache.Cache(layerDecodeAsset); 335 Cache.Cache(layerDecodeAsset);
303 } 336 }
304 } 337 }
305 338
@@ -309,10 +342,10 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
309 { 342 {
310 return true; 343 return true;
311 } 344 }
312 else if (m_cache != null) 345 else if (Cache != null)
313 { 346 {
314 string assetName = "j2kCache_" + AssetId.ToString(); 347 string assetName = "j2kCache_" + AssetId.ToString();
315 AssetBase layerDecodeAsset = m_cache.Get(assetName); 348 AssetBase layerDecodeAsset = Cache.Get(assetName);
316 349
317 if (layerDecodeAsset != null) 350 if (layerDecodeAsset != null)
318 { 351 {
@@ -324,7 +357,7 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
324 if (lines.Length == 0) 357 if (lines.Length == 0)
325 { 358 {
326 m_log.Warn("[J2KDecodeCache]: Expiring corrupted layer data (empty) " + assetName); 359 m_log.Warn("[J2KDecodeCache]: Expiring corrupted layer data (empty) " + assetName);
327 m_cache.Expire(assetName); 360 Cache.Expire(assetName);
328 return false; 361 return false;
329 } 362 }
330 363
@@ -345,7 +378,7 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
345 catch (FormatException) 378 catch (FormatException)
346 { 379 {
347 m_log.Warn("[J2KDecodeCache]: Expiring corrupted layer data (format) " + assetName); 380 m_log.Warn("[J2KDecodeCache]: Expiring corrupted layer data (format) " + assetName);
348 m_cache.Expire(assetName); 381 Cache.Expire(assetName);
349 return false; 382 return false;
350 } 383 }
351 384
@@ -356,7 +389,7 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
356 else 389 else
357 { 390 {
358 m_log.Warn("[J2KDecodeCache]: Expiring corrupted layer data (layout) " + assetName); 391 m_log.Warn("[J2KDecodeCache]: Expiring corrupted layer data (layout) " + assetName);
359 m_cache.Expire(assetName); 392 Cache.Expire(assetName);
360 return false; 393 return false;
361 } 394 }
362 } 395 }
diff --git a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs
index 78d597d..7113f4f 100644
--- a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs
@@ -35,9 +35,12 @@ using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces; 35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
37 37
38using Mono.Addins;
39
38namespace OpenSim.Region.CoreModules.Agent.Xfer 40namespace OpenSim.Region.CoreModules.Agent.Xfer
39{ 41{
40 public class XferModule : IRegionModule, IXfer 42 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "XferModule")]
43 public class XferModule : INonSharedRegionModule, IXfer
41 { 44 {
42 private Scene m_scene; 45 private Scene m_scene;
43 private Dictionary<string, FileData> NewFiles = new Dictionary<string, FileData>(); 46 private Dictionary<string, FileData> NewFiles = new Dictionary<string, FileData>();
@@ -59,9 +62,13 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
59 public int Count; 62 public int Count;
60 } 63 }
61 64
62 #region IRegionModule Members 65 #region INonSharedRegionModule Members
66
67 public void Initialise(IConfigSource config)
68 {
69 }
63 70
64 public void Initialise(Scene scene, IConfigSource config) 71 public void AddRegion(Scene scene)
65 { 72 {
66 m_scene = scene; 73 m_scene = scene;
67 m_scene.EventManager.OnNewClient += NewClient; 74 m_scene.EventManager.OnNewClient += NewClient;
@@ -69,22 +76,30 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
69 m_scene.RegisterModuleInterface<IXfer>(this); 76 m_scene.RegisterModuleInterface<IXfer>(this);
70 } 77 }
71 78
72 public void PostInitialise() 79 public void RemoveRegion(Scene scene)
73 { 80 {
81 m_scene.EventManager.OnNewClient -= NewClient;
82
83 m_scene.UnregisterModuleInterface<IXfer>(this);
84 m_scene = null;
74 } 85 }
75 86
76 public void Close() 87 public void RegionLoaded(Scene scene)
77 { 88 {
78 } 89 }
79 90
80 public string Name 91 public Type ReplaceableInterface
81 { 92 {
82 get { return "XferModule"; } 93 get { return null; }
83 } 94 }
84 95
85 public bool IsSharedModule 96 public void Close()
86 { 97 {
87 get { return false; } 98 }
99
100 public string Name
101 {
102 get { return "XferModule"; }
88 } 103 }
89 104
90 #endregion 105 #endregion
diff --git a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs
index b1b7b27..e40caec 100644
--- a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Reflection; 29using System.Reflection;
30using log4net; 30using log4net;
31using Mono.Addins;
31using Nini.Config; 32using Nini.Config;
32using OpenSim.Framework; 33using OpenSim.Framework;
33using OpenSim.Region.Framework.Interfaces; 34using OpenSim.Region.Framework.Interfaces;
@@ -89,6 +90,7 @@ namespace OpenSim.Region.CoreModules.Asset
89 /// ExpirationTime = 60 90 /// ExpirationTime = 60
90 /// </code> 91 /// </code>
91 /// </example> 92 /// </example>
93 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "CenomeMemoryAssetCache")]
92 public class CenomeMemoryAssetCache : IImprovedAssetCache, ISharedRegionModule 94 public class CenomeMemoryAssetCache : IImprovedAssetCache, ISharedRegionModule
93 { 95 {
94 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 96 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
diff --git a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs
index 7da5e7a..9742a5c 100644
--- a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs
@@ -30,6 +30,7 @@ using System;
30using System.IO; 30using System.IO;
31using System.Collections.Generic; 31using System.Collections.Generic;
32using System.Reflection; 32using System.Reflection;
33using Mono.Addins;
33using Nini.Config; 34using Nini.Config;
34using OpenSim.Framework; 35using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces; 36using OpenSim.Region.Framework.Interfaces;
@@ -38,6 +39,7 @@ using OpenSim.Services.Interfaces;
38 39
39namespace OpenSim.Region.CoreModules.Asset 40namespace OpenSim.Region.CoreModules.Asset
40{ 41{
42 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "CoreAssetCache")]
41 public class CoreAssetCache : ISharedRegionModule, IImprovedAssetCache 43 public class CoreAssetCache : ISharedRegionModule, IImprovedAssetCache
42 { 44 {
43 private static readonly ILog m_log = 45 private static readonly ILog m_log =
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index 7d7176f..b1bb56b 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -49,12 +49,12 @@ using OpenSim.Region.Framework.Scenes;
49using OpenSim.Services.Interfaces; 49using OpenSim.Services.Interfaces;
50 50
51 51
52[assembly: Addin("FlotsamAssetCache", "1.1")] 52//[assembly: Addin("FlotsamAssetCache", "1.1")]
53[assembly: AddinDependency("OpenSim", "0.5")] 53//[assembly: AddinDependency("OpenSim", "0.5")]
54 54
55namespace Flotsam.RegionModules.AssetCache 55namespace OpenSim.Region.CoreModules.Asset
56{ 56{
57 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 57 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "FlotsamAssetCache")]
58 public class FlotsamAssetCache : ISharedRegionModule, IImprovedAssetCache, IAssetService 58 public class FlotsamAssetCache : ISharedRegionModule, IImprovedAssetCache, IAssetService
59 { 59 {
60 private static readonly ILog m_log = 60 private static readonly ILog m_log =
@@ -107,8 +107,6 @@ namespace Flotsam.RegionModules.AssetCache
107 private IAssetService m_AssetService; 107 private IAssetService m_AssetService;
108 private List<Scene> m_Scenes = new List<Scene>(); 108 private List<Scene> m_Scenes = new List<Scene>();
109 109
110 private bool m_DeepScanBeforePurge;
111
112 public FlotsamAssetCache() 110 public FlotsamAssetCache()
113 { 111 {
114 m_InvalidChars.AddRange(Path.GetInvalidPathChars()); 112 m_InvalidChars.AddRange(Path.GetInvalidPathChars());
@@ -170,8 +168,6 @@ namespace Flotsam.RegionModules.AssetCache
170 m_CacheDirectoryTierLen = assetConfig.GetInt("CacheDirectoryTierLength", m_CacheDirectoryTierLen); 168 m_CacheDirectoryTierLen = assetConfig.GetInt("CacheDirectoryTierLength", m_CacheDirectoryTierLen);
171 169
172 m_CacheWarnAt = assetConfig.GetInt("CacheWarnAt", m_CacheWarnAt); 170 m_CacheWarnAt = assetConfig.GetInt("CacheWarnAt", m_CacheWarnAt);
173
174 m_DeepScanBeforePurge = assetConfig.GetBoolean("DeepScanBeforePurge", m_DeepScanBeforePurge);
175 } 171 }
176 172
177 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory {0}", m_CacheDirectory); 173 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory {0}", m_CacheDirectory);
@@ -226,10 +222,6 @@ namespace Flotsam.RegionModules.AssetCache
226 scene.RegisterModuleInterface<IImprovedAssetCache>(this); 222 scene.RegisterModuleInterface<IImprovedAssetCache>(this);
227 m_Scenes.Add(scene); 223 m_Scenes.Add(scene);
228 224
229 if (m_AssetService == null)
230 {
231 m_AssetService = scene.RequestModuleInterface<IAssetService>();
232 }
233 } 225 }
234 } 226 }
235 227
@@ -244,6 +236,8 @@ namespace Flotsam.RegionModules.AssetCache
244 236
245 public void RegionLoaded(Scene scene) 237 public void RegionLoaded(Scene scene)
246 { 238 {
239 if (m_Enabled && m_AssetService == null)
240 m_AssetService = scene.RequestModuleInterface<IAssetService>();
247 } 241 }
248 242
249 //////////////////////////////////////////////////////////// 243 ////////////////////////////////////////////////////////////
@@ -519,13 +513,10 @@ namespace Flotsam.RegionModules.AssetCache
519 // Purge all files last accessed prior to this point 513 // Purge all files last accessed prior to this point
520 DateTime purgeLine = DateTime.Now - m_FileExpiration; 514 DateTime purgeLine = DateTime.Now - m_FileExpiration;
521 515
522 // An optional deep scan at this point will ensure assets present in scenes, 516 // An asset cache may contain local non-temporary assets that are not in the asset service. Therefore,
523 // or referenced by objects in the scene, but not recently accessed 517 // before cleaning up expired files we must scan the objects in the scene to make sure that we retain
524 // are not purged. 518 // such local assets if they have not been recently accessed.
525 if (m_DeepScanBeforePurge) 519 TouchAllSceneAssets(false);
526 {
527 CacheScenes();
528 }
529 520
530 foreach (string dir in Directory.GetDirectories(m_CacheDirectory)) 521 foreach (string dir in Directory.GetDirectories(m_CacheDirectory))
531 { 522 {
@@ -718,11 +709,14 @@ namespace Flotsam.RegionModules.AssetCache
718 709
719 /// <summary> 710 /// <summary>
720 /// Iterates through all Scenes, doing a deep scan through assets 711 /// Iterates through all Scenes, doing a deep scan through assets
721 /// to cache all assets present in the scene or referenced by assets 712 /// to update the access time of all assets present in the scene or referenced by assets
722 /// in the scene 713 /// in the scene.
723 /// </summary> 714 /// </summary>
724 /// <returns></returns> 715 /// <param name="storeUncached">
725 private int CacheScenes() 716 /// If true, then assets scanned which are not found in cache are added to the cache.
717 /// </param>
718 /// <returns>Number of distinct asset references found in the scene.</returns>
719 private int TouchAllSceneAssets(bool storeUncached)
726 { 720 {
727 UuidGatherer gatherer = new UuidGatherer(m_AssetService); 721 UuidGatherer gatherer = new UuidGatherer(m_AssetService);
728 722
@@ -745,7 +739,7 @@ namespace Flotsam.RegionModules.AssetCache
745 { 739 {
746 File.SetLastAccessTime(filename, DateTime.Now); 740 File.SetLastAccessTime(filename, DateTime.Now);
747 } 741 }
748 else 742 else if (storeUncached)
749 { 743 {
750 m_AssetService.Get(assetID.ToString()); 744 m_AssetService.Get(assetID.ToString());
751 } 745 }
@@ -873,13 +867,14 @@ namespace Flotsam.RegionModules.AssetCache
873 867
874 break; 868 break;
875 869
876
877 case "assets": 870 case "assets":
878 m_log.Info("[FLOTSAM ASSET CACHE]: Caching all assets, in all scenes."); 871 m_log.Info("[FLOTSAM ASSET CACHE]: Ensuring assets are cached for all scenes.");
879 872
880 Util.FireAndForget(delegate { 873 Util.FireAndForget(delegate {
881 int assetsCached = CacheScenes(); 874 int assetReferenceTotal = TouchAllSceneAssets(true);
882 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Completed Scene Caching, {0} assets found.", assetsCached); 875 m_log.InfoFormat(
876 "[FLOTSAM ASSET CACHE]: Completed check with {0} assets.",
877 assetReferenceTotal);
883 }); 878 });
884 879
885 break; 880 break;
diff --git a/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs b/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs
index 1365e69..9592ca0 100644
--- a/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs
@@ -31,6 +31,7 @@ using System.IO;
31using System.Collections.Generic; 31using System.Collections.Generic;
32using System.Reflection; 32using System.Reflection;
33using GlynnTucker.Cache; 33using GlynnTucker.Cache;
34using Mono.Addins;
34using Nini.Config; 35using Nini.Config;
35using OpenSim.Framework; 36using OpenSim.Framework;
36using OpenSim.Region.Framework.Interfaces; 37using OpenSim.Region.Framework.Interfaces;
@@ -39,6 +40,7 @@ using OpenSim.Services.Interfaces;
39 40
40namespace OpenSim.Region.CoreModules.Asset 41namespace OpenSim.Region.CoreModules.Asset
41{ 42{
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GlynnTuckerAssetCache")]
42 public class GlynnTuckerAssetCache : ISharedRegionModule, IImprovedAssetCache 44 public class GlynnTuckerAssetCache : ISharedRegionModule, IImprovedAssetCache
43 { 45 {
44 private static readonly ILog m_log = 46 private static readonly ILog m_log =
diff --git a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs
index c91b25f..1c2bfd0 100644
--- a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs
+++ b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs
@@ -35,7 +35,6 @@ using Nini.Config;
35using NUnit.Framework; 35using NUnit.Framework;
36using OpenMetaverse; 36using OpenMetaverse;
37using OpenMetaverse.Assets; 37using OpenMetaverse.Assets;
38using Flotsam.RegionModules.AssetCache;
39using OpenSim.Framework; 38using OpenSim.Framework;
40using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
41using OpenSim.Region.Framework.Scenes.Serialization; 40using OpenSim.Region.Framework.Scenes.Serialization;
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 951afd7..acd156e 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -286,6 +286,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
286 286
287 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp) 287 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp)
288 { 288 {
289 if (!Enabled)
290 return false;
291
292 if (AttachObjectInternal(sp, group, attachmentPt, silent, useAttachData, temp))
293 {
294 m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID);
295 return true;
296 }
297
298 return false;
299 }
300
301 private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp)
302 {
289 lock (sp.AttachmentsSyncLock) 303 lock (sp.AttachmentsSyncLock)
290 { 304 {
291// m_log.DebugFormat( 305// m_log.DebugFormat(
@@ -461,6 +475,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
461 475
462 public void DetachSingleAttachmentToGround(IScenePresence sp, uint soLocalId) 476 public void DetachSingleAttachmentToGround(IScenePresence sp, uint soLocalId)
463 { 477 {
478 DetachSingleAttachmentToGround(sp, soLocalId, sp.AbsolutePosition, Quaternion.Identity);
479 }
480
481 public void DetachSingleAttachmentToGround(IScenePresence sp, uint soLocalId, Vector3 absolutePos, Quaternion absoluteRot)
482 {
464 if (!Enabled) 483 if (!Enabled)
465 return; 484 return;
466 485
@@ -502,7 +521,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
502 so.FromItemID = UUID.Zero; 521 so.FromItemID = UUID.Zero;
503 522
504 SceneObjectPart rootPart = so.RootPart; 523 SceneObjectPart rootPart = so.RootPart;
505 so.AbsolutePosition = sp.AbsolutePosition; 524 so.AbsolutePosition = absolutePos;
525 if (absoluteRot != Quaternion.Identity)
526 {
527 so.UpdateGroupRotationR(absoluteRot);
528 }
506 so.AttachedAvatar = UUID.Zero; 529 so.AttachedAvatar = UUID.Zero;
507 rootPart.SetParentLocalId(0); 530 rootPart.SetParentLocalId(0);
508 so.ClearPartAttachmentData(); 531 so.ClearPartAttachmentData();
@@ -616,9 +639,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
616 639
617 if (grp.HasGroupChanged) 640 if (grp.HasGroupChanged)
618 { 641 {
619// m_log.DebugFormat( 642 m_log.DebugFormat(
620// "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", 643 "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
621// grp.UUID, grp.AttachmentPoint); 644 grp.UUID, grp.AttachmentPoint);
622 645
623 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, scriptedState); 646 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, scriptedState);
624 647
@@ -862,7 +885,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
862 // This will throw if the attachment fails 885 // This will throw if the attachment fails
863 try 886 try
864 { 887 {
865 AttachObject(sp, objatt, attachmentPt, false, false, false); 888 AttachObjectInternal(sp, objatt, attachmentPt, false, false, false);
866 } 889 }
867 catch (Exception e) 890 catch (Exception e)
868 { 891 {
@@ -933,6 +956,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
933 956
934 InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID); 957 InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID);
935 item = m_scene.InventoryService.GetItem(item); 958 item = m_scene.InventoryService.GetItem(item);
959 if (item == null)
960 return;
961
936 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); 962 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID);
937 if (changed && m_scene.AvatarFactory != null) 963 if (changed && m_scene.AvatarFactory != null)
938 { 964 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index d9a619d..4e9d3f9 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -62,7 +62,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
62 public class AttachmentsModuleTests : OpenSimTestCase 62 public class AttachmentsModuleTests : OpenSimTestCase
63 { 63 {
64 private AutoResetEvent m_chatEvent = new AutoResetEvent(false); 64 private AutoResetEvent m_chatEvent = new AutoResetEvent(false);
65 private OSChatMessage m_osChatMessageReceived; 65// private OSChatMessage m_osChatMessageReceived;
66
67 // Used to test whether the operations have fired the attach event. Must be reset after each test.
68 private int m_numberOfAttachEventsFired;
66 69
67 [TestFixtureSetUp] 70 [TestFixtureSetUp]
68 public void FixtureInit() 71 public void FixtureInit()
@@ -83,7 +86,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
83 { 86 {
84// Console.WriteLine("Got chat [{0}]", oscm.Message); 87// Console.WriteLine("Got chat [{0}]", oscm.Message);
85 88
86 m_osChatMessageReceived = oscm; 89// m_osChatMessageReceived = oscm;
87 m_chatEvent.Set(); 90 m_chatEvent.Set();
88 } 91 }
89 92
@@ -99,6 +102,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
99 "attachments-test-scene", TestHelpers.ParseTail(999), 1000, 1000, config); 102 "attachments-test-scene", TestHelpers.ParseTail(999), 1000, 1000, config);
100 SceneHelpers.SetupSceneModules(scene, config, modules.ToArray()); 103 SceneHelpers.SetupSceneModules(scene, config, modules.ToArray());
101 104
105 scene.EventManager.OnAttach += (localID, itemID, avatarID) => m_numberOfAttachEventsFired++;
106
102 return scene; 107 return scene;
103 } 108 }
104 109
@@ -181,6 +186,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
181 TestHelpers.InMethod(); 186 TestHelpers.InMethod();
182// TestHelpers.EnableLogging(); 187// TestHelpers.EnableLogging();
183 188
189 m_numberOfAttachEventsFired = 0;
190
184 Scene scene = CreateTestScene(); 191 Scene scene = CreateTestScene();
185 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); 192 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
186 ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); 193 ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
@@ -189,6 +196,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
189 196
190 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID); 197 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
191 198
199 m_numberOfAttachEventsFired = 0;
192 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false); 200 scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false);
193 201
194 // Check status on scene presence 202 // Check status on scene presence
@@ -216,7 +224,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
216 224
217 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); 225 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
218 226
219// TestHelpers.DisableLogging(); 227 // Check events
228 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
220 } 229 }
221 230
222 /// <summary> 231 /// <summary>
@@ -228,6 +237,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
228 TestHelpers.InMethod(); 237 TestHelpers.InMethod();
229// TestHelpers.EnableLogging(); 238// TestHelpers.EnableLogging();
230 239
240 m_numberOfAttachEventsFired = 0;
241
231 Scene scene = CreateTestScene(); 242 Scene scene = CreateTestScene();
232 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); 243 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
233 ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); 244 ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
@@ -247,6 +258,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
247 258
248 Assert.That(sp.HasAttachments(), Is.False); 259 Assert.That(sp.HasAttachments(), Is.False);
249 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); 260 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
261
262 // Check events
263 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0));
250 } 264 }
251 265
252 [Test] 266 [Test]
@@ -261,6 +275,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
261 275
262 InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); 276 InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
263 277
278 m_numberOfAttachEventsFired = 0;
264 scene.AttachmentsModule.RezSingleAttachmentFromInventory( 279 scene.AttachmentsModule.RezSingleAttachmentFromInventory(
265 sp, attItem.ID, (uint)AttachmentPoint.Chest); 280 sp, attItem.ID, (uint)AttachmentPoint.Chest);
266 281
@@ -280,6 +295,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
280 Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); 295 Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
281 296
282 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); 297 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
298
299 // Check events
300 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
283 } 301 }
284 302
285 /// <summary> 303 /// <summary>
@@ -338,6 +356,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
338 ISceneEntity so 356 ISceneEntity so
339 = scene.AttachmentsModule.RezSingleAttachmentFromInventory( 357 = scene.AttachmentsModule.RezSingleAttachmentFromInventory(
340 sp, attItem.ID, (uint)AttachmentPoint.Chest); 358 sp, attItem.ID, (uint)AttachmentPoint.Chest);
359
360 m_numberOfAttachEventsFired = 0;
341 scene.AttachmentsModule.DetachSingleAttachmentToGround(sp, so.LocalId); 361 scene.AttachmentsModule.DetachSingleAttachmentToGround(sp, so.LocalId);
342 362
343 // Check scene presence status 363 // Check scene presence status
@@ -353,6 +373,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
353 373
354 // Check object in scene 374 // Check object in scene
355 Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null); 375 Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null);
376
377 // Check events
378 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
356 } 379 }
357 380
358 [Test] 381 [Test]
@@ -369,6 +392,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
369 SceneObjectGroup so 392 SceneObjectGroup so
370 = (SceneObjectGroup)scene.AttachmentsModule.RezSingleAttachmentFromInventory( 393 = (SceneObjectGroup)scene.AttachmentsModule.RezSingleAttachmentFromInventory(
371 sp, attItem.ID, (uint)AttachmentPoint.Chest); 394 sp, attItem.ID, (uint)AttachmentPoint.Chest);
395
396 m_numberOfAttachEventsFired = 0;
372 scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, so); 397 scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, so);
373 398
374 // Check status on scene presence 399 // Check status on scene presence
@@ -380,6 +405,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
380 Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo(0)); 405 Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo(0));
381 406
382 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(0)); 407 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(0));
408
409 // Check events
410 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
383 } 411 }
384 412
385 /// <summary> 413 /// <summary>
@@ -461,10 +489,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
461 489
462 SceneObjectGroup rezzedAtt = presence.GetAttachments()[0]; 490 SceneObjectGroup rezzedAtt = presence.GetAttachments()[0];
463 491
464 scene.IncomingCloseAgent(presence.UUID); 492 m_numberOfAttachEventsFired = 0;
493 scene.IncomingCloseAgent(presence.UUID, false);
465 494
466 // Check that we can't retrieve this attachment from the scene. 495 // Check that we can't retrieve this attachment from the scene.
467 Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null); 496 Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null);
497
498 // Check events
499 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0));
468 } 500 }
469 501
470 [Test] 502 [Test]
@@ -480,6 +512,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
480 AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); 512 AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID);
481 acd.Appearance = new AvatarAppearance(); 513 acd.Appearance = new AvatarAppearance();
482 acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); 514 acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
515
516 m_numberOfAttachEventsFired = 0;
483 ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd); 517 ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd);
484 518
485 Assert.That(presence.HasAttachments(), Is.True); 519 Assert.That(presence.HasAttachments(), Is.True);
@@ -502,6 +536,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
502 Assert.That(presence.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); 536 Assert.That(presence.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
503 537
504 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); 538 Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
539
540 // Check events. We expect OnAttach to fire on login.
541 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1));
505 } 542 }
506 543
507 [Test] 544 [Test]
@@ -522,10 +559,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
522 559
523 Vector3 newPosition = new Vector3(1, 2, 4); 560 Vector3 newPosition = new Vector3(1, 2, 4);
524 561
562 m_numberOfAttachEventsFired = 0;
525 scene.SceneGraph.UpdatePrimGroupPosition(attSo.LocalId, newPosition, sp.ControllingClient); 563 scene.SceneGraph.UpdatePrimGroupPosition(attSo.LocalId, newPosition, sp.ControllingClient);
526 564
527 Assert.That(attSo.AbsolutePosition, Is.EqualTo(sp.AbsolutePosition)); 565 Assert.That(attSo.AbsolutePosition, Is.EqualTo(sp.AbsolutePosition));
528 Assert.That(attSo.RootPart.AttachedPos, Is.EqualTo(newPosition)); 566 Assert.That(attSo.RootPart.AttachedPos, Is.EqualTo(newPosition));
567
568 // Check events
569 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0));
529 } 570 }
530 571
531 [Test] 572 [Test]
@@ -574,6 +615,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
574 Vector3 teleportPosition = new Vector3(10, 11, 12); 615 Vector3 teleportPosition = new Vector3(10, 11, 12);
575 Vector3 teleportLookAt = new Vector3(20, 21, 22); 616 Vector3 teleportLookAt = new Vector3(20, 21, 22);
576 617
618 m_numberOfAttachEventsFired = 0;
577 sceneA.RequestTeleportLocation( 619 sceneA.RequestTeleportLocation(
578 beforeTeleportSp.ControllingClient, 620 beforeTeleportSp.ControllingClient,
579 sceneB.RegionInfo.RegionHandle, 621 sceneB.RegionInfo.RegionHandle,
@@ -616,29 +658,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
616 Assert.That(actualSceneAAttachments.Count, Is.EqualTo(0)); 658 Assert.That(actualSceneAAttachments.Count, Is.EqualTo(0));
617 659
618 Assert.That(sceneA.GetSceneObjectGroups().Count, Is.EqualTo(0)); 660 Assert.That(sceneA.GetSceneObjectGroups().Count, Is.EqualTo(0));
619 }
620 661
621 // I'm commenting this test because scene setup NEEDS InventoryService to 662 // Check events
622 // be non-null 663 Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0));
623 //[Test] 664 }
624// public void T032_CrossAttachments()
625// {
626// TestHelpers.InMethod();
627//
628// ScenePresence presence = scene.GetScenePresence(agent1);
629// ScenePresence presence2 = scene2.GetScenePresence(agent1);
630// presence2.AddAttachment(sog1);
631// presence2.AddAttachment(sog2);
632//
633// ISharedRegionModule serialiser = new SerialiserModule();
634// SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), serialiser);
635// SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), serialiser);
636//
637// Assert.That(presence.HasAttachments(), Is.False, "Presence has attachments before cross");
638//
639// //Assert.That(presence2.CrossAttachmentsIntoNewRegion(region1, true), Is.True, "Cross was not successful");
640// Assert.That(presence2.HasAttachments(), Is.False, "Presence2 objects were not deleted");
641// Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects");
642// }
643 } 665 }
644} 666}
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index 4cb4370..8496005 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -39,9 +39,12 @@ using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces; 40using OpenSim.Services.Interfaces;
41 41
42using Mono.Addins;
43
42namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory 44namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
43{ 45{
44 public class AvatarFactoryModule : IAvatarFactoryModule, IRegionModule 46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AvatarFactoryModule")]
47 public class AvatarFactoryModule : IAvatarFactoryModule, INonSharedRegionModule
45 { 48 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47 50
@@ -59,12 +62,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
59 62
60 private object m_setAppearanceLock = new object(); 63 private object m_setAppearanceLock = new object();
61 64
62 #region IRegionModule 65 #region Region Module interface
63 66
64 public void Initialise(Scene scene, IConfigSource config) 67 public void Initialise(IConfigSource config)
65 { 68 {
66 scene.RegisterModuleInterface<IAvatarFactoryModule>(this);
67 scene.EventManager.OnNewClient += SubscribeToClientEvents;
68 69
69 IConfig appearanceConfig = config.Configs["Appearance"]; 70 IConfig appearanceConfig = config.Configs["Appearance"];
70 if (appearanceConfig != null) 71 if (appearanceConfig != null)
@@ -74,11 +75,29 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
74 // m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime); 75 // m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime);
75 } 76 }
76 77
78 }
79
80 public void AddRegion(Scene scene)
81 {
77 if (m_scene == null) 82 if (m_scene == null)
78 m_scene = scene; 83 m_scene = scene;
84
85 scene.RegisterModuleInterface<IAvatarFactoryModule>(this);
86 scene.EventManager.OnNewClient += SubscribeToClientEvents;
87 }
88
89 public void RemoveRegion(Scene scene)
90 {
91 if (scene == m_scene)
92 {
93 scene.UnregisterModuleInterface<IAvatarFactoryModule>(this);
94 scene.EventManager.OnNewClient -= SubscribeToClientEvents;
95 }
96
97 m_scene = null;
79 } 98 }
80 99
81 public void PostInitialise() 100 public void RegionLoaded(Scene scene)
82 { 101 {
83 m_updateTimer.Enabled = false; 102 m_updateTimer.Enabled = false;
84 m_updateTimer.AutoReset = true; 103 m_updateTimer.AutoReset = true;
@@ -100,6 +119,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
100 get { return false; } 119 get { return false; }
101 } 120 }
102 121
122 public Type ReplaceableInterface
123 {
124 get { return null; }
125 }
126
127
103 private void SubscribeToClientEvents(IClientAPI client) 128 private void SubscribeToClientEvents(IClientAPI client)
104 { 129 {
105 client.OnRequestWearables += Client_OnRequestWearables; 130 client.OnRequestWearables += Client_OnRequestWearables;
@@ -533,6 +558,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
533 // Ignore ruth's assets 558 // Ignore ruth's assets
534 if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID) 559 if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
535 continue; 560 continue;
561
536 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); 562 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
537 baseItem = invService.GetItem(baseItem); 563 baseItem = invService.GetItem(baseItem);
538 564
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
index dbbb0ae..4c3f1cc 100644
--- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs
@@ -30,6 +30,7 @@ using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using log4net; 31using log4net;
32using Nini.Config; 32using Nini.Config;
33using Mono.Addins;
33using OpenMetaverse; 34using OpenMetaverse;
34using OpenSim.Framework; 35using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces; 36using OpenSim.Region.Framework.Interfaces;
@@ -37,6 +38,7 @@ using OpenSim.Region.Framework.Scenes;
37 38
38namespace OpenSim.Region.CoreModules.Avatar.Chat 39namespace OpenSim.Region.CoreModules.Avatar.Chat
39{ 40{
41 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ChatModule")]
40 public class ChatModule : ISharedRegionModule 42 public class ChatModule : ISharedRegionModule
41 { 43 {
42 private static readonly ILog m_log = 44 private static readonly ILog m_log =
@@ -197,6 +199,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
197 string fromName = c.From; 199 string fromName = c.From;
198 string fromNamePrefix = ""; 200 string fromNamePrefix = "";
199 UUID fromID = UUID.Zero; 201 UUID fromID = UUID.Zero;
202 UUID ownerID = UUID.Zero;
200 string message = c.Message; 203 string message = c.Message;
201 IScene scene = c.Scene; 204 IScene scene = c.Scene;
202 UUID destination = c.Destination; 205 UUID destination = c.Destination;
@@ -224,11 +227,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
224 fromNamePrefix = m_adminPrefix; 227 fromNamePrefix = m_adminPrefix;
225 } 228 }
226 destination = UUID.Zero; // Avatars cant "SayTo" 229 destination = UUID.Zero; // Avatars cant "SayTo"
230 ownerID = c.Sender.AgentId;
231
227 break; 232 break;
228 233
229 case ChatSourceType.Object: 234 case ChatSourceType.Object:
230 fromID = c.SenderUUID; 235 fromID = c.SenderUUID;
231 236
237 if (c.SenderObject != null && c.SenderObject is SceneObjectPart)
238 ownerID = ((SceneObjectPart)c.SenderObject).OwnerID;
239
232 break; 240 break;
233 } 241 }
234 242
@@ -262,8 +270,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
262 // objects on a parcel with access restrictions 270 // objects on a parcel with access restrictions
263 if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true) 271 if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true)
264 { 272 {
265 if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromNamePrefix + fromName, c.Type, message, sourceType)) 273 if (destination != UUID.Zero)
266 receiverIDs.Add(presence.UUID); 274 {
275 if (TrySendChatMessage(presence, fromPos, regionPos, fromID, ownerID, fromNamePrefix + fromName, c.Type, message, sourceType, true))
276 receiverIDs.Add(presence.UUID);
277 }
278 else
279 {
280 if (TrySendChatMessage(presence, fromPos, regionPos, fromID, ownerID, fromNamePrefix + fromName, c.Type, message, sourceType, false))
281 receiverIDs.Add(presence.UUID);
282 }
267 } 283 }
268 } 284 }
269 } 285 }
@@ -324,7 +340,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
324 (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId)) 340 (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId))
325 return; 341 return;
326 342
327 client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID, 343 client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID, fromID,
328 (byte)sourceType, (byte)ChatAudibleLevel.Fully); 344 (byte)sourceType, (byte)ChatAudibleLevel.Fully);
329 receiverIDs.Add(client.AgentId); 345 receiverIDs.Add(client.AgentId);
330 } 346 }
@@ -341,15 +357,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
341 /// <param name="fromPos"></param> 357 /// <param name="fromPos"></param>
342 /// <param name="regionPos">/param> 358 /// <param name="regionPos">/param>
343 /// <param name="fromAgentID"></param> 359 /// <param name="fromAgentID"></param>
360 /// <param name='ownerID'>
361 /// Owner of the message. For at least some messages from objects, this has to be correctly filled with the owner's UUID.
362 /// This is the case for script error messages in viewer 3 since LLViewer change EXT-7762
363 /// </param>
344 /// <param name="fromName"></param> 364 /// <param name="fromName"></param>
345 /// <param name="type"></param> 365 /// <param name="type"></param>
346 /// <param name="message"></param> 366 /// <param name="message"></param>
347 /// <param name="src"></param> 367 /// <param name="src"></param>
348 /// <returns>true if the message was sent to the receiver, false if it was not sent due to failing a 368 /// <returns>true if the message was sent to the receiver, false if it was not sent due to failing a
349 /// precondition</returns> 369 /// precondition</returns>
350 protected virtual bool TrySendChatMessage(ScenePresence presence, Vector3 fromPos, Vector3 regionPos, 370 protected virtual bool TrySendChatMessage(
351 UUID fromAgentID, string fromName, ChatTypeEnum type, 371 ScenePresence presence, Vector3 fromPos, Vector3 regionPos,
352 string message, ChatSourceType src) 372 UUID fromAgentID, UUID ownerID, string fromName, ChatTypeEnum type,
373 string message, ChatSourceType src, bool ignoreDistance)
353 { 374 {
354 // don't send chat to child agents 375 // don't send chat to child agents
355 if (presence.IsChildAgent) return false; 376 if (presence.IsChildAgent) return false;
@@ -369,8 +390,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
369 } 390 }
370 391
371 // TODO: should change so the message is sent through the avatar rather than direct to the ClientView 392 // TODO: should change so the message is sent through the avatar rather than direct to the ClientView
372 presence.ControllingClient.SendChatMessage(message, (byte) type, fromPos, fromName, 393 presence.ControllingClient.SendChatMessage(
373 fromAgentID, (byte)src, (byte)ChatAudibleLevel.Fully); 394 message, (byte) type, fromPos, fromName,
395 fromAgentID, ownerID, (byte)src, (byte)ChatAudibleLevel.Fully);
374 396
375 return true; 397 return true;
376 } 398 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs
index 3a91465..343cdb5 100644
--- a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs
@@ -33,9 +33,12 @@ using OpenSim.Region.Framework.Interfaces;
33using OpenSim.Region.Framework.Scenes; 33using OpenSim.Region.Framework.Scenes;
34using OpenMetaverse; 34using OpenMetaverse;
35 35
36using Mono.Addins;
37
36namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule 38namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
37{ 39{
38 public class CombatModule : IRegionModule 40 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "CombatModule")]
41 public class CombatModule : ISharedRegionModule
39 { 42 {
40 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 43 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41 44
@@ -54,7 +57,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
54 /// </summary> 57 /// </summary>
55 /// <param name="scene"></param> 58 /// <param name="scene"></param>
56 /// <param name="config"></param> 59 /// <param name="config"></param>
57 public void Initialise(Scene scene, IConfigSource config) 60 public void Initialise(IConfigSource config)
61 {
62 }
63
64 public void AddRegion(Scene scene)
58 { 65 {
59 lock (m_scenel) 66 lock (m_scenel)
60 { 67 {
@@ -72,6 +79,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
72 scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; 79 scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel;
73 } 80 }
74 81
82 public void RemoveRegion(Scene scene)
83 {
84 if (m_scenel.ContainsKey(scene.RegionInfo.RegionHandle))
85 m_scenel.Remove(scene.RegionInfo.RegionHandle);
86
87 scene.EventManager.OnAvatarKilled -= KillAvatar;
88 scene.EventManager.OnAvatarEnteringNewParcel -= AvatarEnteringParcel;
89 }
90
91 public void RegionLoaded(Scene scene)
92 {
93 }
94
75 public void PostInitialise() 95 public void PostInitialise()
76 { 96 {
77 } 97 }
@@ -85,11 +105,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule
85 get { return "CombatModule"; } 105 get { return "CombatModule"; }
86 } 106 }
87 107
88 public bool IsSharedModule 108 public Type ReplaceableInterface
89 { 109 {
90 get { return true; } 110 get { return null; }
91 } 111 }
92 112
113
93 private void KillAvatar(uint killerObjectLocalID, ScenePresence deadAvatar) 114 private void KillAvatar(uint killerObjectLocalID, ScenePresence deadAvatar)
94 { 115 {
95 string deadAvatarMessage; 116 string deadAvatarMessage;
diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
index 3c294bb..0e7ab7e 100644
--- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs
@@ -32,6 +32,7 @@ using log4net;
32using Nini.Config; 32using Nini.Config;
33using OpenMetaverse; 33using OpenMetaverse;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using Mono.Addins;
35 36
36using OpenSim.Region.Framework.Interfaces; 37using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes; 38using OpenSim.Region.Framework.Scenes;
@@ -39,16 +40,27 @@ using OpenSim.Services.Interfaces;
39 40
40namespace OpenSim.Region.CoreModules.Avatar.Dialog 41namespace OpenSim.Region.CoreModules.Avatar.Dialog
41{ 42{
42 public class DialogModule : IRegionModule, IDialogModule 43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DialogModule")]
43 { 44 public class DialogModule : IDialogModule, INonSharedRegionModule
45 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 47
46 protected Scene m_scene; 48 protected Scene m_scene;
47 49
48 public void Initialise(Scene scene, IConfigSource source) 50 public void Initialise(IConfigSource source) { }
51
52 public Type ReplaceableInterface { get { return null; } }
53
54 public void AddRegion(Scene scene)
49 { 55 {
50 m_scene = scene; 56 m_scene = scene;
51 m_scene.RegisterModuleInterface<IDialogModule>(this); 57 m_scene.RegisterModuleInterface<IDialogModule>(this);
58 }
59
60 public void RegionLoaded(Scene scene)
61 {
62 if (scene != m_scene)
63 return;
52 64
53 m_scene.AddCommand( 65 m_scene.AddCommand(
54 "Users", this, "alert", "alert <message>", 66 "Users", this, "alert", "alert <message>",
@@ -56,46 +68,59 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
56 HandleAlertConsoleCommand); 68 HandleAlertConsoleCommand);
57 69
58 m_scene.AddCommand( 70 m_scene.AddCommand(
59 "Users", this, "alert-user", "alert-user <first> <last> <message>", 71 "Users", this, "alert-user",
72 "alert-user <first> <last> <message>",
60 "Send an alert to a user", 73 "Send an alert to a user",
61 HandleAlertConsoleCommand); 74 HandleAlertConsoleCommand);
62 } 75 }
63 76
64 public void PostInitialise() {} 77 public void RemoveRegion(Scene scene)
65 public void Close() {} 78 {
79 if (scene != m_scene)
80 return;
81
82 m_scene.UnregisterModuleInterface<IDialogModule>(this);
83 }
84
85 public void Close() { }
66 public string Name { get { return "Dialog Module"; } } 86 public string Name { get { return "Dialog Module"; } }
67 public bool IsSharedModule { get { return false; } } 87
68
69 public void SendAlertToUser(IClientAPI client, string message) 88 public void SendAlertToUser(IClientAPI client, string message)
70 { 89 {
71 SendAlertToUser(client, message, false); 90 SendAlertToUser(client, message, false);
72 } 91 }
73 92
74 public void SendAlertToUser(IClientAPI client, string message, bool modal) 93 public void SendAlertToUser(IClientAPI client, string message,
94 bool modal)
75 { 95 {
76 client.SendAgentAlertMessage(message, modal); 96 client.SendAgentAlertMessage(message, modal);
77 } 97 }
78 98
79 public void SendAlertToUser(UUID agentID, string message) 99 public void SendAlertToUser(UUID agentID, string message)
80 { 100 {
81 SendAlertToUser(agentID, message, false); 101 SendAlertToUser(agentID, message, false);
82 } 102 }
83 103
84 public void SendAlertToUser(UUID agentID, string message, bool modal) 104 public void SendAlertToUser(UUID agentID, string message, bool modal)
85 { 105 {
86 ScenePresence sp = m_scene.GetScenePresence(agentID); 106 ScenePresence sp = m_scene.GetScenePresence(agentID);
87 107
88 if (sp != null) 108 if (sp != null)
89 sp.ControllingClient.SendAgentAlertMessage(message, modal); 109 sp.ControllingClient.SendAgentAlertMessage(message, modal);
90 } 110 }
91 111
92 public void SendAlertToUser(string firstName, string lastName, string message, bool modal) 112 public void SendAlertToUser(string firstName, string lastName,
113 string message, bool modal)
93 { 114 {
94 ScenePresence presence = m_scene.GetScenePresence(firstName, lastName); 115 ScenePresence presence = m_scene.GetScenePresence(firstName,
116 lastName);
95 if (presence != null) 117 if (presence != null)
96 presence.ControllingClient.SendAgentAlertMessage(message, modal); 118 {
119 presence.ControllingClient.SendAgentAlertMessage(message,
120 modal);
121 }
97 } 122 }
98 123
99 public void SendGeneralAlert(string message) 124 public void SendGeneralAlert(string message)
100 { 125 {
101 m_scene.ForEachRootClient(delegate(IClientAPI client) 126 m_scene.ForEachRootClient(delegate(IClientAPI client)
@@ -104,11 +129,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
104 }); 129 });
105 } 130 }
106 131
107 public void SendDialogToUser( 132 public void SendDialogToUser(UUID avatarID, string objectName,
108 UUID avatarID, string objectName, UUID objectID, UUID ownerID, 133 UUID objectID, UUID ownerID, string message, UUID textureID,
109 string message, UUID textureID, int ch, string[] buttonlabels) 134 int ch, string[] buttonlabels)
110 { 135 {
111 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, ownerID); 136 UserAccount account = m_scene.UserAccountService.GetUserAccount(
137 m_scene.RegionInfo.ScopeID, ownerID);
112 string ownerFirstName, ownerLastName; 138 string ownerFirstName, ownerLastName;
113 if (account != null) 139 if (account != null)
114 { 140 {
@@ -123,29 +149,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
123 149
124 ScenePresence sp = m_scene.GetScenePresence(avatarID); 150 ScenePresence sp = m_scene.GetScenePresence(avatarID);
125 if (sp != null) 151 if (sp != null)
126 sp.ControllingClient.SendDialog( 152 {
127 objectName, objectID, ownerID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels); 153 sp.ControllingClient.SendDialog(objectName, objectID, ownerID,
154 ownerFirstName, ownerLastName, message, textureID, ch,
155 buttonlabels);
156 }
128 } 157 }
129 158
130 public void SendUrlToUser( 159 public void SendUrlToUser(UUID avatarID, string objectName,
131 UUID avatarID, string objectName, UUID objectID, UUID ownerID, bool groupOwned, string message, string url) 160 UUID objectID, UUID ownerID, bool groupOwned, string message,
161 string url)
132 { 162 {
133 ScenePresence sp = m_scene.GetScenePresence(avatarID); 163 ScenePresence sp = m_scene.GetScenePresence(avatarID);
134 164
135 if (sp != null) 165 if (sp != null)
136 sp.ControllingClient.SendLoadURL(objectName, objectID, ownerID, groupOwned, message, url); 166 {
167 sp.ControllingClient.SendLoadURL(objectName, objectID,
168 ownerID, groupOwned, message, url);
169 }
137 } 170 }
138 171
139 public void SendTextBoxToUser(UUID avatarid, string message, int chatChannel, string name, UUID objectid, UUID ownerid) 172 public void SendTextBoxToUser(UUID avatarid, string message,
173 int chatChannel, string name, UUID objectid, UUID ownerid)
140 { 174 {
141 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, ownerid); 175 UserAccount account = m_scene.UserAccountService.GetUserAccount(
176 m_scene.RegionInfo.ScopeID, ownerid);
142 string ownerFirstName, ownerLastName; 177 string ownerFirstName, ownerLastName;
143 UUID ownerID = UUID.Zero; 178 UUID ownerID = UUID.Zero;
144 if (account != null) 179 if (account != null)
145 { 180 {
146 ownerFirstName = account.FirstName; 181 ownerFirstName = account.FirstName;
147 ownerLastName = account.LastName; 182 ownerLastName = account.LastName;
148 ownerID = account.PrincipalID; 183 ownerID = account.PrincipalID;
149 } 184 }
150 else 185 else
151 { 186 {
@@ -154,29 +189,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
154 } 189 }
155 190
156 ScenePresence sp = m_scene.GetScenePresence(avatarid); 191 ScenePresence sp = m_scene.GetScenePresence(avatarid);
157 192
158 if (sp != null) 193 if (sp != null)
159 sp.ControllingClient.SendTextBoxRequest(message, chatChannel, name, ownerID, ownerFirstName, ownerLastName, objectid); 194 {
195 sp.ControllingClient.SendTextBoxRequest(message, chatChannel,
196 name, ownerID, ownerFirstName, ownerLastName,
197 objectid);
198 }
160 } 199 }
161 200
162 public void SendNotificationToUsersInRegion( 201 public void SendNotificationToUsersInRegion(UUID fromAvatarID,
163 UUID fromAvatarID, string fromAvatarName, string message) 202 string fromAvatarName, string message)
164 { 203 {
165 m_scene.ForEachRootClient(delegate(IClientAPI client) 204 m_scene.ForEachRootClient(delegate(IClientAPI client)
166 { 205 {
167 client.SendBlueBoxMessage(fromAvatarID, fromAvatarName, message); 206 client.SendBlueBoxMessage(fromAvatarID, fromAvatarName,
207 message);
168 }); 208 });
169 } 209 }
170 210
171 /// <summary> 211 /// <summary>
172 /// Handle an alert command from the console. 212 /// Handle an alert command from the console.
173 /// </summary> 213 /// </summary>
174 /// <param name="module"></param> 214 /// <param name="module"></param>
175 /// <param name="cmdparams"></param> 215 /// <param name="cmdparams"></param>
176 public void HandleAlertConsoleCommand(string module, string[] cmdparams) 216 public void HandleAlertConsoleCommand(string module,
217 string[] cmdparams)
177 { 218 {
178 if (m_scene.ConsoleScene() != null && m_scene.ConsoleScene() != m_scene) 219 if (m_scene.ConsoleScene() != null &&
220 m_scene.ConsoleScene() != m_scene)
221 {
179 return; 222 return;
223 }
180 224
181 string message = string.Empty; 225 string message = string.Empty;
182 226
@@ -184,7 +228,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
184 { 228 {
185 message = CombineParams(cmdparams, 1); 229 message = CombineParams(cmdparams, 1);
186 m_log.InfoFormat("[DIALOG]: Sending general alert in region {0} with message {1}", 230 m_log.InfoFormat("[DIALOG]: Sending general alert in region {0} with message {1}",
187 m_scene.RegionInfo.RegionName, message); 231 m_scene.RegionInfo.RegionName, message);
188 SendGeneralAlert(message); 232 SendGeneralAlert(message);
189 } 233 }
190 else if (cmdparams.Length > 3) 234 else if (cmdparams.Length > 3)
@@ -192,9 +236,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
192 string firstName = cmdparams[1]; 236 string firstName = cmdparams[1];
193 string lastName = cmdparams[2]; 237 string lastName = cmdparams[2];
194 message = CombineParams(cmdparams, 3); 238 message = CombineParams(cmdparams, 3);
195 m_log.InfoFormat( 239 m_log.InfoFormat("[DIALOG]: Sending alert in region {0} to {1} {2} with message {3}",
196 "[DIALOG]: Sending alert in region {0} to {1} {2} with message {3}", 240 m_scene.RegionInfo.RegionName, firstName, lastName,
197 m_scene.RegionInfo.RegionName, firstName, lastName, message); 241 message);
198 SendAlertToUser(firstName, lastName, message, false); 242 SendAlertToUser(firstName, lastName, message, false);
199 } 243 }
200 else 244 else
@@ -212,7 +256,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
212 { 256 {
213 result += commandParams[i] + " "; 257 result += commandParams[i] + " ";
214 } 258 }
215 259
216 return result; 260 return result;
217 } 261 }
218 } 262 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs
index d942e87..5ec0ea9 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs
@@ -141,7 +141,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
141 client.FirstName+" "+client.LastName, 141 client.FirstName+" "+client.LastName,
142 destID, (byte)211, false, 142 destID, (byte)211, false,
143 String.Empty, 143 String.Empty,
144 transactionID, false, new Vector3(), new byte[0]), 144 transactionID, false, new Vector3(), new byte[0], true),
145 delegate(bool success) {} ); 145 delegate(bool success) {} );
146 } 146 }
147 } 147 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index 24ec435..8056030 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -28,12 +28,14 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Linq;
31using System.Reflection; 32using System.Reflection;
32using System.Threading; 33using System.Threading;
33using log4net; 34using log4net;
34using Nini.Config; 35using Nini.Config;
35using Nwc.XmlRpc; 36using Nwc.XmlRpc;
36using OpenMetaverse; 37using OpenMetaverse;
38using Mono.Addins;
37using OpenSim.Framework; 39using OpenSim.Framework;
38using OpenSim.Framework.Servers.HttpServer; 40using OpenSim.Framework.Servers.HttpServer;
39using OpenSim.Framework.Communications; 41using OpenSim.Framework.Communications;
@@ -49,6 +51,7 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
49 51
50namespace OpenSim.Region.CoreModules.Avatar.Friends 52namespace OpenSim.Region.CoreModules.Avatar.Friends
51{ 53{
54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "FriendsModule")]
52 public class FriendsModule : ISharedRegionModule, IFriendsModule 55 public class FriendsModule : ISharedRegionModule, IFriendsModule
53 { 56 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 57 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -482,9 +485,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
482 Util.FireAndForget( 485 Util.FireAndForget(
483 delegate 486 delegate
484 { 487 {
485 m_log.DebugFormat( 488// m_log.DebugFormat(
486 "[FRIENDS MODULE]: Notifying {0} friends of {1} of online status {2}", 489// "[FRIENDS MODULE]: Notifying {0} friends of {1} of online status {2}",
487 friendList.Count, agentID, online); 490// friendList.Count, agentID, online);
488 491
489 // Notify about this user status 492 // Notify about this user status
490 StatusNotify(friendList, agentID, online); 493 StatusNotify(friendList, agentID, online);
@@ -495,42 +498,36 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
495 498
496 protected virtual void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online) 499 protected virtual void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
497 { 500 {
498 foreach (FriendInfo friend in friendList) 501 List<string> friendStringIds = friendList.ConvertAll<string>(friend => friend.Friend);
502 List<string> remoteFriendStringIds = new List<string>();
503 foreach (string friendStringId in friendStringIds)
499 { 504 {
500 UUID friendID; 505 UUID friendUuid;
501 if (UUID.TryParse(friend.Friend, out friendID)) 506 if (UUID.TryParse(friendStringId, out friendUuid))
502 { 507 {
503 // Try local 508 if (LocalStatusNotification(userID, friendUuid, online))
504 if (LocalStatusNotification(userID, friendID, online))
505 continue; 509 continue;
506 510
507 // The friend is not here [as root]. Let's forward. 511 remoteFriendStringIds.Add(friendStringId);
508 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
509 if (friendSessions != null && friendSessions.Length > 0)
510 {
511 PresenceInfo friendSession = null;
512 foreach (PresenceInfo pinfo in friendSessions)
513 {
514 if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad
515 {
516 friendSession = pinfo;
517 break;
518 }
519 }
520
521 if (friendSession != null)
522 {
523 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
524 //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
525 m_FriendsSimConnector.StatusNotify(region, userID, friendID, online);
526 }
527 }
528
529 // Friend is not online. Ignore.
530 } 512 }
531 else 513 else
532 { 514 {
533 m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend); 515 m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friendStringId);
516 }
517 }
518
519 // We do this regrouping so that we can efficiently send a single request rather than one for each
520 // friend in what may be a very large friends list.
521 PresenceInfo[] friendSessions = PresenceService.GetAgents(remoteFriendStringIds.ToArray());
522
523 foreach (PresenceInfo friendSession in friendSessions)
524 {
525 // let's guard against sessions-gone-bad
526 if (friendSession.RegionID != UUID.Zero)
527 {
528 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
529 //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
530 m_FriendsSimConnector.StatusNotify(region, userID, friendSession.UserID, online);
534 } 531 }
535 } 532 }
536 } 533 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
index 06f27e2..bf5c0bb 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
@@ -46,6 +46,7 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
46 46
47namespace OpenSim.Region.CoreModules.Avatar.Friends 47namespace OpenSim.Region.CoreModules.Avatar.Friends
48{ 48{
49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "HGFriendsModule")]
49 public class HGFriendsModule : FriendsModule, ISharedRegionModule, IFriendsModule, IFriendsSimConnector 50 public class HGFriendsModule : FriendsModule, ISharedRegionModule, IFriendsModule, IFriendsSimConnector
50 { 51 {
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
diff --git a/OpenSim/Region/CoreModules/Avatar/Gestures/GesturesModule.cs b/OpenSim/Region/CoreModules/Avatar/Gestures/GesturesModule.cs
index 7df2beb..095c57b 100644
--- a/OpenSim/Region/CoreModules/Avatar/Gestures/GesturesModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Gestures/GesturesModule.cs
@@ -25,6 +25,7 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System;
28using System.Reflection; 29using System.Reflection;
29using log4net; 30using log4net;
30using Nini.Config; 31using Nini.Config;
@@ -35,26 +36,46 @@ using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
36using OpenSim.Services.Interfaces; 37using OpenSim.Services.Interfaces;
37 38
39using Mono.Addins;
40
38namespace OpenSim.Region.CoreModules.Avatar.Gestures 41namespace OpenSim.Region.CoreModules.Avatar.Gestures
39{ 42{
40 public class GesturesModule : IRegionModule 43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GesturesModule")]
44 public class GesturesModule : INonSharedRegionModule
41 { 45 {
42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43 47
44 protected Scene m_scene; 48 protected Scene m_scene;
45 49
46 public void Initialise(Scene scene, IConfigSource source) 50 public void Initialise(IConfigSource source)
51 {
52 }
53
54 public void AddRegion(Scene scene)
47 { 55 {
48 m_scene = scene; 56 m_scene = scene;
49 57
50 m_scene.EventManager.OnNewClient += OnNewClient; 58 m_scene.EventManager.OnNewClient += OnNewClient;
51 } 59 }
60
61 public void RegionLoaded(Scene scene)
62 {
63 }
64
65 public void RemoveRegion(Scene scene)
66 {
67 m_scene.EventManager.OnNewClient -= OnNewClient;
68 m_scene = null;
69 }
52 70
53 public void PostInitialise() {}
54 public void Close() {} 71 public void Close() {}
55 public string Name { get { return "Gestures Module"; } } 72 public string Name { get { return "Gestures Module"; } }
56 public bool IsSharedModule { get { return false; } } 73
57 74 public Type ReplaceableInterface
75 {
76 get { return null; }
77 }
78
58 private void OnNewClient(IClientAPI client) 79 private void OnNewClient(IClientAPI client)
59 { 80 {
60 client.OnActivateGesture += ActivateGesture; 81 client.OnActivateGesture += ActivateGesture;
diff --git a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
index 716cc69..9fa9be1 100644
--- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs
@@ -25,6 +25,7 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System;
28using System.Collections.Generic; 29using System.Collections.Generic;
29using Nini.Config; 30using Nini.Config;
30using OpenMetaverse; 31using OpenMetaverse;
@@ -50,9 +51,12 @@ using Caps = OpenSim.Framework.Capabilities.Caps;
50using OSDArray = OpenMetaverse.StructuredData.OSDArray; 51using OSDArray = OpenMetaverse.StructuredData.OSDArray;
51using OSDMap = OpenMetaverse.StructuredData.OSDMap; 52using OSDMap = OpenMetaverse.StructuredData.OSDMap;
52 53
54using Mono.Addins;
55
53namespace OpenSim.Region.CoreModules.Avatar.Gods 56namespace OpenSim.Region.CoreModules.Avatar.Gods
54{ 57{
55 public class GodsModule : IRegionModule, IGodsModule 58 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GodsModule")]
59 public class GodsModule : INonSharedRegionModule, IGodsModule
56 { 60 {
57 private static readonly ILog m_log = 61 private static readonly ILog m_log =
58 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 62 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -66,10 +70,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
66 protected Dictionary<UUID, string> m_capsDict = 70 protected Dictionary<UUID, string> m_capsDict =
67 new Dictionary<UUID, string>(); 71 new Dictionary<UUID, string>();
68 72
69 public void Initialise(Scene scene, IConfigSource source) 73 protected IDialogModule DialogModule
74 {
75 get
76 {
77 if (m_dialogModule == null)
78 m_dialogModule = m_scene.RequestModuleInterface<IDialogModule>();
79
80 return m_dialogModule;
81 }
82 }
83
84 public void Initialise(IConfigSource source)
85 {
86 }
87
88 public void AddRegion(Scene scene)
70 { 89 {
71 m_scene = scene; 90 m_scene = scene;
72 m_dialogModule = m_scene.RequestModuleInterface<IDialogModule>();
73 m_scene.RegisterModuleInterface<IGodsModule>(this); 91 m_scene.RegisterModuleInterface<IGodsModule>(this);
74 m_scene.EventManager.OnNewClient += SubscribeToClientEvents; 92 m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
75 m_scene.EventManager.OnRegisterCaps += OnRegisterCaps; 93 m_scene.EventManager.OnRegisterCaps += OnRegisterCaps;
@@ -77,12 +95,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
77 scene.EventManager.OnIncomingInstantMessage += 95 scene.EventManager.OnIncomingInstantMessage +=
78 OnIncomingInstantMessage; 96 OnIncomingInstantMessage;
79 } 97 }
80 98
81 public void PostInitialise() {} 99 public void RemoveRegion(Scene scene)
100 {
101 m_scene.UnregisterModuleInterface<IGodsModule>(this);
102 m_scene.EventManager.OnNewClient -= SubscribeToClientEvents;
103 m_scene = null;
104 }
105
106 public void RegionLoaded(Scene scene)
107 {
108 }
109
82 public void Close() {} 110 public void Close() {}
83 public string Name { get { return "Gods Module"; } } 111 public string Name { get { return "Gods Module"; } }
84 public bool IsSharedModule { get { return false; } } 112
85 113 public Type ReplaceableInterface
114 {
115 get { return null; }
116 }
117
86 public void SubscribeToClientEvents(IClientAPI client) 118 public void SubscribeToClientEvents(IClientAPI client)
87 { 119 {
88 client.OnGodKickUser += KickUser; 120 client.OnGodKickUser += KickUser;
@@ -172,8 +204,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
172 } 204 }
173 else 205 else
174 { 206 {
175 if (m_dialogModule != null) 207 if (DialogModule != null)
176 m_dialogModule.SendAlertToUser(agentID, "Request for god powers denied"); 208 DialogModule.SendAlertToUser(agentID, "Request for god powers denied");
177 } 209 }
178 } 210 }
179 } 211 }
@@ -206,7 +238,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
206 transferModule.SendInstantMessage(new GridInstantMessage( 238 transferModule.SendInstantMessage(new GridInstantMessage(
207 m_scene, godID, "God", agentID, (byte)250, false, 239 m_scene, godID, "God", agentID, (byte)250, false,
208 Utils.BytesToString(reason), UUID.Zero, true, 240 Utils.BytesToString(reason), UUID.Zero, true,
209 new Vector3(), new byte[] {(byte)kickflags}), 241 new Vector3(), new byte[] {(byte)kickflags}, true),
210 delegate(bool success) {} ); 242 delegate(bool success) {} );
211 } 243 }
212 return; 244 return;
diff --git a/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs b/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs
index b258e13..af54c1a 100644
--- a/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs
@@ -25,6 +25,7 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System;
28using System.Collections.Generic; 29using System.Collections.Generic;
29using System.Reflection; 30using System.Reflection;
30using log4net; 31using log4net;
@@ -34,9 +35,12 @@ using OpenSim.Framework;
34using OpenSim.Region.Framework.Interfaces; 35using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
36 37
38using Mono.Addins;
39
37namespace OpenSim.Region.CoreModules.Avatar.Groups 40namespace OpenSim.Region.CoreModules.Avatar.Groups
38{ 41{
39 public class GroupsModule : IRegionModule 42 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsModule")]
43 public class GroupsModule : ISharedRegionModule
40 { 44 {
41 private static readonly ILog m_log = 45 private static readonly ILog m_log =
42 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -55,9 +59,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups
55 private static GroupMembershipData osGroup = 59 private static GroupMembershipData osGroup =
56 new GroupMembershipData(); 60 new GroupMembershipData();
57 61
58 #region IRegionModule Members 62 private bool m_Enabled = false;
63
64 #region ISharedRegionModule Members
59 65
60 public void Initialise(Scene scene, IConfigSource config) 66 public void Initialise(IConfigSource config)
61 { 67 {
62 IConfig groupsConfig = config.Configs["Groups"]; 68 IConfig groupsConfig = config.Configs["Groups"];
63 69
@@ -67,7 +73,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups
67 } 73 }
68 else 74 else
69 { 75 {
70 if (!groupsConfig.GetBoolean("Enabled", false)) 76 m_Enabled = groupsConfig.GetBoolean("Enabled", false);
77 if (!m_Enabled)
71 { 78 {
72 m_log.Info("[GROUPS]: Groups disabled in configuration"); 79 m_log.Info("[GROUPS]: Groups disabled in configuration");
73 return; 80 return;
@@ -77,6 +84,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups
77 return; 84 return;
78 } 85 }
79 86
87 }
88
89 public void AddRegion(Scene scene)
90 {
91 if (!m_Enabled)
92 return;
93
80 lock (m_SceneList) 94 lock (m_SceneList)
81 { 95 {
82 if (!m_SceneList.Contains(scene)) 96 if (!m_SceneList.Contains(scene))
@@ -96,7 +110,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups
96 110
97 scene.EventManager.OnNewClient += OnNewClient; 111 scene.EventManager.OnNewClient += OnNewClient;
98 scene.EventManager.OnClientClosed += OnClientClosed; 112 scene.EventManager.OnClientClosed += OnClientClosed;
99// scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; 113 // scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
114 }
115
116 public void RemoveRegion(Scene scene)
117 {
118 if (!m_Enabled)
119 return;
120
121 lock (m_SceneList)
122 {
123 if (m_SceneList.Contains(scene))
124 m_SceneList.Remove(scene);
125 }
126
127 scene.EventManager.OnNewClient -= OnNewClient;
128 scene.EventManager.OnClientClosed -= OnClientClosed;
129 }
130
131 public void RegionLoaded(Scene scene)
132 {
100 } 133 }
101 134
102 public void PostInitialise() 135 public void PostInitialise()
@@ -105,6 +138,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups
105 138
106 public void Close() 139 public void Close()
107 { 140 {
141 if (!m_Enabled)
142 return;
143
108// m_log.Debug("[GROUPS]: Shutting down group module."); 144// m_log.Debug("[GROUPS]: Shutting down group module.");
109 145
110 lock (m_ClientMap) 146 lock (m_ClientMap)
@@ -123,9 +159,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups
123 get { return "GroupsModule"; } 159 get { return "GroupsModule"; }
124 } 160 }
125 161
126 public bool IsSharedModule 162 public Type ReplaceableInterface
127 { 163 {
128 get { return true; } 164 get { return null; }
129 } 165 }
130 166
131 #endregion 167 #endregion
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs
index bf1d787..7bf19c2 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs
@@ -48,7 +48,7 @@ using OpenSim.Server.Handlers.Hypergrid;
48 48
49namespace OpenSim.Region.CoreModules.Avatar.InstantMessage 49namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
50{ 50{
51 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 51 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "HGMessageTransferModule")]
52 public class HGMessageTransferModule : ISharedRegionModule, IMessageTransferModule, IInstantMessageSimConnector 52 public class HGMessageTransferModule : ISharedRegionModule, IMessageTransferModule, IInstantMessageSimConnector
53 { 53 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs
index 727f1c9..55e30a0 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs
@@ -29,6 +29,7 @@ using System.Collections.Generic;
29using System.Reflection; 29using System.Reflection;
30using System.Timers; 30using System.Timers;
31using log4net; 31using log4net;
32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
33using OpenMetaverse; 34using OpenMetaverse;
34using OpenSim.Framework; 35using OpenSim.Framework;
@@ -38,6 +39,7 @@ using OpenSim.Region.Framework.Scenes;
38 39
39namespace OpenSim.Region.CoreModules.Avatar.InstantMessage 40namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
40{ 41{
42 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "InstantMessageModule")]
41 public class InstantMessageModule : ISharedRegionModule 43 public class InstantMessageModule : ISharedRegionModule
42 { 44 {
43 private static readonly ILog m_log = LogManager.GetLogger( 45 private static readonly ILog m_log = LogManager.GetLogger(
@@ -54,7 +56,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
54 56
55 private readonly List<Scene> m_scenes = new List<Scene>(); 57 private readonly List<Scene> m_scenes = new List<Scene>();
56 58
57 #region IRegionModule Members 59 #region Region Module interface
58 60
59 private IMessageTransferModule m_TransferModule = null; 61 private IMessageTransferModule m_TransferModule = null;
60 62
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
index edd9707..cc266df 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;
30using System.Net; 30using System.Net;
31using System.Reflection; 31using System.Reflection;
32using log4net; 32using log4net;
33using Mono.Addins;
33using Nini.Config; 34using Nini.Config;
34using Nwc.XmlRpc; 35using Nwc.XmlRpc;
35using OpenMetaverse; 36using OpenMetaverse;
@@ -43,6 +44,7 @@ using OpenSim.Services.Interfaces;
43 44
44namespace OpenSim.Region.CoreModules.Avatar.InstantMessage 45namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
45{ 46{
47 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MessageTransferModule")]
46 public class MessageTransferModule : ISharedRegionModule, IMessageTransferModule 48 public class MessageTransferModule : ISharedRegionModule, IMessageTransferModule
47 { 49 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs
index 24cbaeb..7ce2813 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs
@@ -29,6 +29,7 @@ using System.Collections.Generic;
29using System.Reflection; 29using System.Reflection;
30using log4net; 30using log4net;
31using Nini.Config; 31using Nini.Config;
32using Mono.Addins;
32using OpenMetaverse; 33using OpenMetaverse;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Framework.Communications; 35using OpenSim.Framework.Communications;
@@ -39,6 +40,7 @@ using OpenSim.Region.Framework.Scenes;
39 40
40namespace OpenSim.Region.CoreModules.Avatar.InstantMessage 41namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
41{ 42{
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MuteListModule")]
42 public class MuteListModule : ISharedRegionModule 44 public class MuteListModule : ISharedRegionModule
43 { 45 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
index b27b07d..3a44cc5 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
@@ -28,6 +28,7 @@ using System;
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.Reflection; 29using System.Reflection;
30using log4net; 30using log4net;
31using Mono.Addins;
31using Nini.Config; 32using Nini.Config;
32using OpenMetaverse; 33using OpenMetaverse;
33using OpenSim.Framework; 34using OpenSim.Framework;
@@ -39,6 +40,7 @@ using OpenSim.Region.Framework.Scenes;
39 40
40namespace OpenSim.Region.CoreModules.Avatar.InstantMessage 41namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
41{ 42{
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "OfflineMessageModule")]
42 public class OfflineMessageModule : ISharedRegionModule 44 public class OfflineMessageModule : ISharedRegionModule
43 { 45 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs
index dd17f3c..4c678c2 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs
@@ -33,6 +33,7 @@ using log4net;
33using Nini.Config; 33using Nini.Config;
34using Nwc.XmlRpc; 34using Nwc.XmlRpc;
35using OpenMetaverse; 35using OpenMetaverse;
36using Mono.Addins;
36using OpenSim.Framework; 37using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces; 38using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
@@ -42,6 +43,7 @@ using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
42 43
43namespace OpenSim.Region.CoreModules.Avatar.InstantMessage 44namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
44{ 45{
46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "PresenceModule")]
45 public class PresenceModule : ISharedRegionModule, IPresenceModule 47 public class PresenceModule : ISharedRegionModule, IPresenceModule
46 { 48 {
47 private static readonly ILog m_log = LogManager.GetLogger( 49 private static readonly ILog m_log = LogManager.GetLogger(
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
index 0833154..dc2b0e0 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -411,18 +411,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
411 { 411 {
412// m_log.DebugFormat("[INVENTORY ARCHIVER]: Found creator {0} via OSPA resolution", ospResolvedId); 412// m_log.DebugFormat("[INVENTORY ARCHIVER]: Found creator {0} via OSPA resolution", ospResolvedId);
413 413
414 item.CreatorIdAsUuid = ospResolvedId; 414// item.CreatorIdAsUuid = ospResolvedId;
415 415
416 // Don't preserve the OSPA in the creator id (which actually gets persisted to the 416 // Don't preserve the OSPA in the creator id (which actually gets persisted to the
417 // database). Instead, replace with the UUID that we found. 417 // database). Instead, replace with the UUID that we found.
418 item.CreatorId = ospResolvedId.ToString(); 418 item.CreatorId = ospResolvedId.ToString();
419
420 item.CreatorData = string.Empty; 419 item.CreatorData = string.Empty;
421 } 420 }
422 else if (item.CreatorData == null || item.CreatorData == String.Empty) 421 else if (item.CreatorData == null || item.CreatorData == String.Empty)
423 { 422 {
424 item.CreatorId = m_userInfo.PrincipalID.ToString(); 423 item.CreatorId = m_userInfo.PrincipalID.ToString();
425 item.CreatorIdAsUuid = new UUID(item.CreatorId); 424// item.CreatorIdAsUuid = new UUID(item.CreatorId);
426 } 425 }
427 426
428 item.Owner = m_userInfo.PrincipalID; 427 item.Owner = m_userInfo.PrincipalID;
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index 6587ead..d0e88f6 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -166,7 +166,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
166 166
167 if (options.ContainsKey("verbose")) 167 if (options.ContainsKey("verbose"))
168 m_log.InfoFormat( 168 m_log.InfoFormat(
169 "[INVENTORY ARCHIVER]: Saving item {0} {1} with asset {2}", 169 "[INVENTORY ARCHIVER]: Saving item {0} {1} (asset UUID {2})",
170 inventoryItem.ID, inventoryItem.Name, inventoryItem.AssetID); 170 inventoryItem.ID, inventoryItem.Name, inventoryItem.AssetID);
171 171
172 string filename = path + CreateArchiveItemName(inventoryItem); 172 string filename = path + CreateArchiveItemName(inventoryItem);
@@ -337,11 +337,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
337 { 337 {
338 m_log.DebugFormat("[INVENTORY ARCHIVER]: Saving {0} assets for items", m_assetUuids.Count); 338 m_log.DebugFormat("[INVENTORY ARCHIVER]: Saving {0} assets for items", m_assetUuids.Count);
339 339
340 new AssetsRequest( 340 AssetsRequest ar
341 new AssetsArchiver(m_archiveWriter), 341 = new AssetsRequest(
342 m_assetUuids, m_scene.AssetService, 342 new AssetsArchiver(m_archiveWriter),
343 m_scene.UserAccountService, m_scene.RegionInfo.ScopeID, 343 m_assetUuids, m_scene.AssetService,
344 options, ReceivedAllAssets).Execute(); 344 m_scene.UserAccountService, m_scene.RegionInfo.ScopeID,
345 options, ReceivedAllAssets);
346
347 Util.FireAndForget(o => ar.Execute());
345 } 348 }
346 else 349 else
347 { 350 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
index 7d1fe68..f4f9e2d 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
@@ -35,23 +35,22 @@ using Nini.Config;
35using OpenMetaverse; 35using OpenMetaverse;
36using OpenSim.Framework; 36using OpenSim.Framework;
37using OpenSim.Framework.Communications; 37using OpenSim.Framework.Communications;
38using OpenSim.Framework.Console;
38using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces; 41using OpenSim.Services.Interfaces;
42using Mono.Addins;
41 43
42namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver 44namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
43{ 45{
44 /// <summary> 46 /// <summary>
45 /// This module loads and saves OpenSimulator inventory archives 47 /// This module loads and saves OpenSimulator inventory archives
46 /// </summary> 48 /// </summary>
47 public class InventoryArchiverModule : IRegionModule, IInventoryArchiverModule 49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "InventoryArchiverModule")]
50 public class InventoryArchiverModule : ISharedRegionModule, IInventoryArchiverModule
48 { 51 {
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 53
51 public string Name { get { return "Inventory Archiver Module"; } }
52
53 public bool IsSharedModule { get { return true; } }
54
55 /// <value> 54 /// <value>
56 /// Enable or disable checking whether the iar user is actually logged in 55 /// Enable or disable checking whether the iar user is actually logged in
57 /// </value> 56 /// </value>
@@ -98,9 +97,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
98// public InventoryArchiverModule(bool disablePresenceChecks) 97// public InventoryArchiverModule(bool disablePresenceChecks)
99// { 98// {
100// DisablePresenceChecks = disablePresenceChecks; 99// DisablePresenceChecks = disablePresenceChecks;
101// } 100 // }
101
102 #region ISharedRegionModule
103
104 public void Initialise(IConfigSource source)
105 {
106 }
102 107
103 public void Initialise(Scene scene, IConfigSource source) 108 public void AddRegion(Scene scene)
104 { 109 {
105 if (m_scenes.Count == 0) 110 if (m_scenes.Count == 0)
106 { 111 {
@@ -143,10 +148,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
143 m_scenes[scene.RegionInfo.RegionID] = scene; 148 m_scenes[scene.RegionInfo.RegionID] = scene;
144 } 149 }
145 150
146 public void PostInitialise() {} 151 public void RemoveRegion(Scene scene)
152 {
153 }
147 154
148 public void Close() {} 155 public void Close() {}
149 156
157 public void RegionLoaded(Scene scene)
158 {
159 }
160
161 public void PostInitialise()
162 {
163 }
164
165 public Type ReplaceableInterface
166 {
167 get { return null; }
168 }
169
170 public string Name { get { return "Inventory Archiver Module"; } }
171
172 #endregion
173
150 /// <summary> 174 /// <summary>
151 /// Trigger the inventory archive saved event. 175 /// Trigger the inventory archive saved event.
152 /// </summary> 176 /// </summary>
@@ -209,6 +233,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
209 Guid id, string firstName, string lastName, string invPath, string pass, string savePath, 233 Guid id, string firstName, string lastName, string invPath, string pass, string savePath,
210 Dictionary<string, object> options) 234 Dictionary<string, object> options)
211 { 235 {
236// if (!ConsoleUtil.CheckFileDoesNotExist(MainConsole.Instance, savePath))
237// return false;
238
212 if (m_scenes.Count > 0) 239 if (m_scenes.Count > 0)
213 { 240 {
214 UserAccount userInfo = GetUserInfo(firstName, lastName, pass); 241 UserAccount userInfo = GetUserInfo(firstName, lastName, pass);
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs
index 1056865..db78da9 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs
@@ -82,7 +82,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
82 82
83 protected string m_item1Name = "Ray Gun Item"; 83 protected string m_item1Name = "Ray Gun Item";
84 protected string m_coaItemName = "Coalesced Item"; 84 protected string m_coaItemName = "Coalesced Item";
85 85
86 [TestFixtureSetUp]
87 public void FixtureSetup()
88 {
89 // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
90 Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
91
92 ConstructDefaultIarBytesForTestLoad();
93 }
94
95 [TestFixtureTearDown]
96 public void TearDown()
97 {
98 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
99 // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
100 // tests really shouldn't).
101 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
102 }
103
86 [SetUp] 104 [SetUp]
87 public override void SetUp() 105 public override void SetUp()
88 { 106 {
@@ -90,12 +108,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
90 m_iarStream = new MemoryStream(m_iarStreamBytes); 108 m_iarStream = new MemoryStream(m_iarStreamBytes);
91 } 109 }
92 110
93 [TestFixtureSetUp]
94 public void FixtureSetup()
95 {
96 ConstructDefaultIarBytesForTestLoad();
97 }
98
99 protected void ConstructDefaultIarBytesForTestLoad() 111 protected void ConstructDefaultIarBytesForTestLoad()
100 { 112 {
101// log4net.Config.XmlConfigurator.Configure(); 113// log4net.Config.XmlConfigurator.Configure();
@@ -122,7 +134,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
122 item1.ID = UUID.Parse("00000000-0000-0000-0000-000000000020"); 134 item1.ID = UUID.Parse("00000000-0000-0000-0000-000000000020");
123 item1.AssetID = asset1.FullID; 135 item1.AssetID = asset1.FullID;
124 item1.GroupID = UUID.Random(); 136 item1.GroupID = UUID.Random();
125 item1.CreatorIdAsUuid = m_uaLL1.PrincipalID; 137 item1.CreatorId = m_uaLL1.PrincipalID.ToString();
126 item1.Owner = m_uaLL1.PrincipalID; 138 item1.Owner = m_uaLL1.PrincipalID;
127 item1.Folder = scene.InventoryService.GetRootFolder(m_uaLL1.PrincipalID).ID; 139 item1.Folder = scene.InventoryService.GetRootFolder(m_uaLL1.PrincipalID).ID;
128 scene.AddInventoryItem(item1); 140 scene.AddInventoryItem(item1);
@@ -145,7 +157,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
145 coaItem.ID = UUID.Parse("00000000-0000-0000-0000-000000000180"); 157 coaItem.ID = UUID.Parse("00000000-0000-0000-0000-000000000180");
146 coaItem.AssetID = coaAsset.FullID; 158 coaItem.AssetID = coaAsset.FullID;
147 coaItem.GroupID = UUID.Random(); 159 coaItem.GroupID = UUID.Random();
148 coaItem.CreatorIdAsUuid = m_uaLL1.PrincipalID; 160 coaItem.CreatorId = m_uaLL1.PrincipalID.ToString();
149 coaItem.Owner = m_uaLL1.PrincipalID; 161 coaItem.Owner = m_uaLL1.PrincipalID;
150 coaItem.Folder = scene.InventoryService.GetRootFolder(m_uaLL1.PrincipalID).ID; 162 coaItem.Folder = scene.InventoryService.GetRootFolder(m_uaLL1.PrincipalID).ID;
151 scene.AddInventoryItem(coaItem); 163 scene.AddInventoryItem(coaItem);
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index b112b6d..06f6e49 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -49,7 +49,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
49{ 49{
50 [TestFixture] 50 [TestFixture]
51 public class InventoryArchiverTests : InventoryArchiveTestCase 51 public class InventoryArchiverTests : InventoryArchiveTestCase
52 { 52 {
53 protected TestScene m_scene; 53 protected TestScene m_scene;
54 protected InventoryArchiverModule m_archiverModule; 54 protected InventoryArchiverModule m_archiverModule;
55 55
@@ -69,7 +69,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
69 public void TestLoadCoalesecedItem() 69 public void TestLoadCoalesecedItem()
70 { 70 {
71 TestHelpers.InMethod(); 71 TestHelpers.InMethod();
72// log4net.Config.XmlConfigurator.Configure(); 72// TestHelpers.EnableLogging();
73 73
74 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password"); 74 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password");
75 m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "password", m_iarStream); 75 m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "password", m_iarStream);
@@ -350,38 +350,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
350 Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL1.PrincipalID)); 350 Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL1.PrincipalID));
351 } 351 }
352 352
353 /// <summary> 353// /// <summary>
354 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where 354// /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
355 /// an account exists with the same name as the creator, though not the same id. 355// /// an account exists with the same name as the creator, though not the same id.
356 /// </summary> 356// /// </summary>
357 [Test] 357// [Test]
358 public void TestLoadIarV0_1SameNameCreator() 358// public void TestLoadIarV0_1SameNameCreator()
359 { 359// {
360 TestHelpers.InMethod(); 360// TestHelpers.InMethod();
361// log4net.Config.XmlConfigurator.Configure(); 361// TestHelpers.EnableLogging();
362 362//
363 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood"); 363// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood");
364 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire"); 364// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire");
365 365//
366 m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream); 366// m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream);
367 InventoryItemBase foundItem1 367// InventoryItemBase foundItem1
368 = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); 368// = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name);
369 369//
370 Assert.That( 370// Assert.That(
371 foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()), 371// foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()),
372 "Loaded item non-uuid creator doesn't match original"); 372// "Loaded item non-uuid creator doesn't match original");
373 Assert.That( 373// Assert.That(
374 foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID), 374// foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID),
375 "Loaded item uuid creator doesn't match original"); 375// "Loaded item uuid creator doesn't match original");
376 Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID), 376// Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID),
377 "Loaded item owner doesn't match inventory reciever"); 377// "Loaded item owner doesn't match inventory reciever");
378 378//
379 AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); 379// AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString());
380 string xmlData = Utils.BytesToString(asset1.Data); 380// string xmlData = Utils.BytesToString(asset1.Data);
381 SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); 381// SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
382 382//
383 Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID)); 383// Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID));
384 } 384// }
385 385
386 /// <summary> 386 /// <summary>
387 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where 387 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
index c14cb17..4cfa33d 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;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using log4net; 31using log4net;
32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
33using OpenMetaverse; 34using OpenMetaverse;
34using OpenSim.Framework; 35using OpenSim.Framework;
@@ -38,20 +39,21 @@ using OpenSim.Services.Interfaces;
38 39
39namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer 40namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
40{ 41{
41 public class InventoryTransferModule : IInventoryTransferModule, ISharedRegionModule 42 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "InventoryTransferModule")]
43 public class InventoryTransferModule : ISharedRegionModule
42 { 44 {
43 private static readonly ILog m_log 45 private static readonly ILog m_log
44 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 47
46 /// <summary> 48 /// <summary>
47 private List<Scene> m_Scenelist = new List<Scene>(); 49 private List<Scene> m_Scenelist = new List<Scene>();
48 private Dictionary<UUID, Scene> m_AgentRegions = 50// private Dictionary<UUID, Scene> m_AgentRegions =
49 new Dictionary<UUID, Scene>(); 51// new Dictionary<UUID, Scene>();
50 52
51 private IMessageTransferModule m_TransferModule = null; 53 private IMessageTransferModule m_TransferModule = null;
52 private bool m_Enabled = true; 54 private bool m_Enabled = true;
53 55
54 #region IRegionModule Members 56 #region Region Module interface
55 57
56 public void Initialise(IConfigSource config) 58 public void Initialise(IConfigSource config)
57 { 59 {
@@ -76,12 +78,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
76 78
77 m_Scenelist.Add(scene); 79 m_Scenelist.Add(scene);
78 80
79 scene.RegisterModuleInterface<IInventoryTransferModule>(this); 81// scene.RegisterModuleInterface<IInventoryTransferModule>(this);
80 82
81 scene.EventManager.OnNewClient += OnNewClient; 83 scene.EventManager.OnNewClient += OnNewClient;
82 scene.EventManager.OnClientClosed += ClientLoggedOut; 84// scene.EventManager.OnClientClosed += ClientLoggedOut;
83 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; 85 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
84 scene.EventManager.OnSetRootAgentScene += OnSetRootAgentScene; 86// scene.EventManager.OnSetRootAgentScene += OnSetRootAgentScene;
85 } 87 }
86 88
87 public void RegionLoaded(Scene scene) 89 public void RegionLoaded(Scene scene)
@@ -96,9 +98,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
96 98
97 m_Scenelist.Clear(); 99 m_Scenelist.Clear();
98 scene.EventManager.OnNewClient -= OnNewClient; 100 scene.EventManager.OnNewClient -= OnNewClient;
99 scene.EventManager.OnClientClosed -= ClientLoggedOut; 101// scene.EventManager.OnClientClosed -= ClientLoggedOut;
100 scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; 102 scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage;
101 scene.EventManager.OnSetRootAgentScene -= OnSetRootAgentScene; 103// scene.EventManager.OnSetRootAgentScene -= OnSetRootAgentScene;
102 } 104 }
103 } 105 }
104 } 106 }
@@ -106,9 +108,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
106 public void RemoveRegion(Scene scene) 108 public void RemoveRegion(Scene scene)
107 { 109 {
108 scene.EventManager.OnNewClient -= OnNewClient; 110 scene.EventManager.OnNewClient -= OnNewClient;
109 scene.EventManager.OnClientClosed -= ClientLoggedOut; 111// scene.EventManager.OnClientClosed -= ClientLoggedOut;
110 scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; 112 scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage;
111 scene.EventManager.OnSetRootAgentScene -= OnSetRootAgentScene; 113// scene.EventManager.OnSetRootAgentScene -= OnSetRootAgentScene;
112 m_Scenelist.Remove(scene); 114 m_Scenelist.Remove(scene);
113 } 115 }
114 116
@@ -138,10 +140,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
138 client.OnInstantMessage += OnInstantMessage; 140 client.OnInstantMessage += OnInstantMessage;
139 } 141 }
140 142
141 protected void OnSetRootAgentScene(UUID id, Scene scene) 143// protected void OnSetRootAgentScene(UUID id, Scene scene)
142 { 144// {
143 m_AgentRegions[id] = scene; 145// m_AgentRegions[id] = scene;
144 } 146// }
145 147
146 private Scene FindClientScene(UUID agentId) 148 private Scene FindClientScene(UUID agentId)
147 { 149 {
@@ -313,45 +315,77 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
313 m_TransferModule.SendInstantMessage(im, delegate(bool success) {}); 315 m_TransferModule.SendInstantMessage(im, delegate(bool success) {});
314 } 316 }
315 } 317 }
316 else if (im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
317 {
318 UUID destinationFolderID = UUID.Zero;
319
320 if (im.binaryBucket != null && im.binaryBucket.Length >= 16)
321 {
322 destinationFolderID = new UUID(im.binaryBucket, 0);
323 }
324
325 if (destinationFolderID != UUID.Zero)
326 {
327 IInventoryService invService = scene.InventoryService;
328
329 UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip
330 318
331 InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId); 319 // Disabled for now as it looks like http://opensimulator.org/mantis/view.php?id=6311 was fixed by fixes
332 item = invService.GetItem(item); 320 // to inventory folder versioning allowing the viewer to move the received folder itself as happens on the
333 InventoryFolderBase folder = null; 321 // LL grid. Doing it again server-side then wrongly does a second create and move
334 322// // XXX: This code was placed here to try and accomdate RLV which moves given folders named #RLV/~<name>
335 if (item != null) // It's an item 323// // to a folder called name in #RLV. However, this approach may not be ultimately correct - from analysis
336 { 324// // of Firestorm 4.2.2 on sending an InventoryOffered instead of TaskInventoryOffered (as was previously
337 item.Folder = destinationFolderID; 325// // done), the viewer itself would appear to move and rename the folder, rather than the simulator doing it here.
338 326// else if (im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted)
339 invService.DeleteItems(item.Owner, new List<UUID>() { item.ID }); 327// {
340 scene.AddInventoryItem(client, item); 328// UUID destinationFolderID = UUID.Zero;
341 } 329//
342 else 330// if (im.binaryBucket != null && im.binaryBucket.Length >= 16)
343 { 331// {
344 folder = new InventoryFolderBase(inventoryID, client.AgentId); 332// destinationFolderID = new UUID(im.binaryBucket, 0);
345 folder = invService.GetFolder(folder); 333// }
346 334//
347 if (folder != null) // It's a folder 335// if (destinationFolderID != UUID.Zero)
348 { 336// {
349 folder.ParentID = destinationFolderID; 337// InventoryFolderBase destinationFolder = new InventoryFolderBase(destinationFolderID, client.AgentId);
350 invService.MoveFolder(folder); 338// if (destinationFolder == null)
351 } 339// {
352 } 340// m_log.WarnFormat(
353 } 341// "[INVENTORY TRANSFER]: TaskInventoryAccepted message from {0} in {1} specified folder {2} which does not exist",
354 } 342// client.Name, scene.Name, destinationFolderID);
343//
344// return;
345// }
346//
347// IInventoryService invService = scene.InventoryService;
348//
349// UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip
350//
351// InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId);
352// item = invService.GetItem(item);
353// InventoryFolderBase folder = null;
354// UUID? previousParentFolderID = null;
355//
356// if (item != null) // It's an item
357// {
358// previousParentFolderID = item.Folder;
359// item.Folder = destinationFolderID;
360//
361// invService.DeleteItems(item.Owner, new List<UUID>() { item.ID });
362// scene.AddInventoryItem(client, item);
363// }
364// else
365// {
366// folder = new InventoryFolderBase(inventoryID, client.AgentId);
367// folder = invService.GetFolder(folder);
368//
369// if (folder != null) // It's a folder
370// {
371// previousParentFolderID = folder.ParentID;
372// folder.ParentID = destinationFolderID;
373// invService.MoveFolder(folder);
374// }
375// }
376//
377// // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code).
378// if (previousParentFolderID != null)
379// {
380// InventoryFolderBase previousParentFolder
381// = new InventoryFolderBase((UUID)previousParentFolderID, client.AgentId);
382// previousParentFolder = invService.GetFolder(previousParentFolder);
383// scene.SendInventoryUpdate(client, previousParentFolder, true, true);
384//
385// scene.SendInventoryUpdate(client, destinationFolder, true, true);
386// }
387// }
388// }
355 else if ( 389 else if (
356 im.dialog == (byte)InstantMessageDialog.InventoryDeclined 390 im.dialog == (byte)InstantMessageDialog.InventoryDeclined
357 || im.dialog == (byte)InstantMessageDialog.TaskInventoryDeclined) 391 || im.dialog == (byte)InstantMessageDialog.TaskInventoryDeclined)
@@ -370,9 +404,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
370 InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId); 404 InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId);
371 item = invService.GetItem(item); 405 item = invService.GetItem(item);
372 InventoryFolderBase folder = null; 406 InventoryFolderBase folder = null;
407 UUID? previousParentFolderID = null;
373 408
374 if (item != null && trashFolder != null) 409 if (item != null && trashFolder != null)
375 { 410 {
411 previousParentFolderID = item.Folder;
376 item.Folder = trashFolder.ID; 412 item.Folder = trashFolder.ID;
377 413
378 // Diva comment: can't we just update this item??? 414 // Diva comment: can't we just update this item???
@@ -388,6 +424,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
388 424
389 if (folder != null & trashFolder != null) 425 if (folder != null & trashFolder != null)
390 { 426 {
427 previousParentFolderID = folder.ParentID;
391 folder.ParentID = trashFolder.ID; 428 folder.ParentID = trashFolder.ID;
392 invService.MoveFolder(folder); 429 invService.MoveFolder(folder);
393 client.SendBulkUpdateInventory(folder); 430 client.SendBulkUpdateInventory(folder);
@@ -408,84 +445,97 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
408 client.SendAgentAlertMessage("Unable to delete "+ 445 client.SendAgentAlertMessage("Unable to delete "+
409 "received inventory" + reason, false); 446 "received inventory" + reason, false);
410 } 447 }
411 448 // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code).
412 ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); 449 else if (previousParentFolderID != null)
413
414 if (user != null) // Local
415 { 450 {
416 user.ControllingClient.SendInstantMessage(im); 451 InventoryFolderBase previousParentFolder
417 } 452 = new InventoryFolderBase((UUID)previousParentFolderID, client.AgentId);
418 else 453 previousParentFolder = invService.GetFolder(previousParentFolder);
419 { 454 scene.SendInventoryUpdate(client, previousParentFolder, true, true);
420 if (m_TransferModule != null)
421 m_TransferModule.SendInstantMessage(im, delegate(bool success) {});
422 }
423 }
424 }
425 455
426 public bool NeedSceneCacheClear(UUID agentID, Scene scene) 456 scene.SendInventoryUpdate(client, trashFolder, true, true);
427 { 457 }
428 if (!m_AgentRegions.ContainsKey(agentID))
429 {
430 // Since we can get here two ways, we need to scan
431 // the scenes here. This is somewhat more expensive
432 // but helps avoid a nasty bug
433 //
434 458
435 foreach (Scene s in m_Scenelist) 459 if (im.dialog == (byte)InstantMessageDialog.InventoryDeclined)
436 { 460 {
437 ScenePresence presence; 461 ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID));
438 462
439 if (s.TryGetScenePresence(agentID, out presence)) 463 if (user != null) // Local
440 { 464 {
441 // If the agent is in this scene, then we 465 user.ControllingClient.SendInstantMessage(im);
442 // are being called twice in a single 466 }
443 // teleport. This is wasteful of cycles 467 else
444 // but harmless due to this 2nd level check 468 {
445 // 469 if (m_TransferModule != null)
446 // If the agent is found in another scene 470 m_TransferModule.SendInstantMessage(im, delegate(bool success) { });
447 // then the list wasn't current
448 //
449 // If the agent is totally unknown, then what
450 // are we even doing here??
451 //
452 if (s == scene)
453 {
454 //m_log.Debug("[INVTRANSFERMOD]: s == scene. Returning true in " + scene.RegionInfo.RegionName);
455 return true;
456 }
457 else
458 {
459 //m_log.Debug("[INVTRANSFERMOD]: s != scene. Returning false in " + scene.RegionInfo.RegionName);
460 return false;
461 }
462 } 471 }
463 } 472 }
464 //m_log.Debug("[INVTRANSFERMOD]: agent not in scene. Returning true in " + scene.RegionInfo.RegionName);
465 return true;
466 } 473 }
467
468 // The agent is left in current Scene, so we must be
469 // going to another instance
470 //
471 if (m_AgentRegions[agentID] == scene)
472 {
473 //m_log.Debug("[INVTRANSFERMOD]: m_AgentRegions[agentID] == scene. Returning true in " + scene.RegionInfo.RegionName);
474 m_AgentRegions.Remove(agentID);
475 return true;
476 }
477
478 // Another region has claimed the agent
479 //
480 //m_log.Debug("[INVTRANSFERMOD]: last resort. Returning false in " + scene.RegionInfo.RegionName);
481 return false;
482 } 474 }
483 475
484 public void ClientLoggedOut(UUID agentID, Scene scene) 476// public bool NeedSceneCacheClear(UUID agentID, Scene scene)
485 { 477// {
486 if (m_AgentRegions.ContainsKey(agentID)) 478// if (!m_AgentRegions.ContainsKey(agentID))
487 m_AgentRegions.Remove(agentID); 479// {
488 } 480// // Since we can get here two ways, we need to scan
481// // the scenes here. This is somewhat more expensive
482// // but helps avoid a nasty bug
483// //
484//
485// foreach (Scene s in m_Scenelist)
486// {
487// ScenePresence presence;
488//
489// if (s.TryGetScenePresence(agentID, out presence))
490// {
491// // If the agent is in this scene, then we
492// // are being called twice in a single
493// // teleport. This is wasteful of cycles
494// // but harmless due to this 2nd level check
495// //
496// // If the agent is found in another scene
497// // then the list wasn't current
498// //
499// // If the agent is totally unknown, then what
500// // are we even doing here??
501// //
502// if (s == scene)
503// {
504// //m_log.Debug("[INVTRANSFERMOD]: s == scene. Returning true in " + scene.RegionInfo.RegionName);
505// return true;
506// }
507// else
508// {
509// //m_log.Debug("[INVTRANSFERMOD]: s != scene. Returning false in " + scene.RegionInfo.RegionName);
510// return false;
511// }
512// }
513// }
514// //m_log.Debug("[INVTRANSFERMOD]: agent not in scene. Returning true in " + scene.RegionInfo.RegionName);
515// return true;
516// }
517//
518// // The agent is left in current Scene, so we must be
519// // going to another instance
520// //
521// if (m_AgentRegions[agentID] == scene)
522// {
523// //m_log.Debug("[INVTRANSFERMOD]: m_AgentRegions[agentID] == scene. Returning true in " + scene.RegionInfo.RegionName);
524// m_AgentRegions.Remove(agentID);
525// return true;
526// }
527//
528// // Another region has claimed the agent
529// //
530// //m_log.Debug("[INVTRANSFERMOD]: last resort. Returning false in " + scene.RegionInfo.RegionName);
531// return false;
532// }
533//
534// public void ClientLoggedOut(UUID agentID, Scene scene)
535// {
536// if (m_AgentRegions.ContainsKey(agentID))
537// m_AgentRegions.Remove(agentID);
538// }
489 539
490 /// <summary> 540 /// <summary>
491 /// 541 ///
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
index 92cf9d1..232a4fe 100644
--- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
@@ -42,7 +42,7 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
42 42
43namespace OpenSim.Region.CoreModules.Avatar.Lure 43namespace OpenSim.Region.CoreModules.Avatar.Lure
44{ 44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "HGLureModule")]
46 public class HGLureModule : ISharedRegionModule 46 public class HGLureModule : ISharedRegionModule
47 { 47 {
48 private static readonly ILog m_log = LogManager.GetLogger( 48 private static readonly ILog m_log = LogManager.GetLogger(
@@ -186,7 +186,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
186 client.FirstName+" "+client.LastName, targetid, 186 client.FirstName+" "+client.LastName, targetid,
187 (byte)InstantMessageDialog.RequestTeleport, false, 187 (byte)InstantMessageDialog.RequestTeleport, false,
188 message, sessionID, false, presence.AbsolutePosition, 188 message, sessionID, false, presence.AbsolutePosition,
189 new Byte[0]); 189 new Byte[0], true);
190 m.RegionID = client.Scene.RegionInfo.RegionID.Guid; 190 m.RegionID = client.Scene.RegionInfo.RegionID.Guid;
191 191
192 m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", m.imSessionID, m.RegionID, m.message); 192 m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", m.imSessionID, m.RegionID, m.message);
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
index a889984..f3adb95 100644
--- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs
@@ -29,6 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using log4net; 31using log4net;
32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
33using OpenMetaverse; 34using OpenMetaverse;
34using OpenSim.Framework; 35using OpenSim.Framework;
@@ -37,6 +38,7 @@ using OpenSim.Region.Framework.Scenes;
37 38
38namespace OpenSim.Region.CoreModules.Avatar.Lure 39namespace OpenSim.Region.CoreModules.Avatar.Lure
39{ 40{
41 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LureModule")]
40 public class LureModule : ISharedRegionModule 42 public class LureModule : ISharedRegionModule
41 { 43 {
42 private static readonly ILog m_log = LogManager.GetLogger( 44 private static readonly ILog m_log = LogManager.GetLogger(
@@ -173,7 +175,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
173 client.FirstName+" "+client.LastName, targetid, 175 client.FirstName+" "+client.LastName, targetid,
174 (byte)InstantMessageDialog.GodLikeRequestTeleport, false, 176 (byte)InstantMessageDialog.GodLikeRequestTeleport, false,
175 message, dest, false, presence.AbsolutePosition, 177 message, dest, false, presence.AbsolutePosition,
176 new Byte[0]); 178 new Byte[0], true);
177 } 179 }
178 else 180 else
179 { 181 {
@@ -181,7 +183,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
181 client.FirstName+" "+client.LastName, targetid, 183 client.FirstName+" "+client.LastName, targetid,
182 (byte)InstantMessageDialog.RequestTeleport, false, 184 (byte)InstantMessageDialog.RequestTeleport, false,
183 message, dest, false, presence.AbsolutePosition, 185 message, dest, false, presence.AbsolutePosition,
184 new Byte[0]); 186 new Byte[0], true);
185 } 187 }
186 188
187 if (m_TransferModule != null) 189 if (m_TransferModule != null)
diff --git a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
index 87ca327..bf24030 100644
--- a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
@@ -42,7 +42,7 @@ using OpenSim.Services.Interfaces;
42 42
43namespace OpenSim.Region.CoreModules.Avatar.Profile 43namespace OpenSim.Region.CoreModules.Avatar.Profile
44{ 44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "BasicProfileModule")]
46 public class BasicProfileModule : IProfileModule, ISharedRegionModule 46 public class BasicProfileModule : IProfileModule, ISharedRegionModule
47 { 47 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
index dbe75b5..7f30e5a 100644
--- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
@@ -43,7 +43,7 @@ using Caps=OpenSim.Framework.Capabilities.Caps;
43 43
44namespace OpenSim.Region.CoreModules.Framework 44namespace OpenSim.Region.CoreModules.Framework
45{ 45{
46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "CapabilitiesModule")]
47 public class CapabilitiesModule : INonSharedRegionModule, ICapabilitiesModule 47 public class CapabilitiesModule : INonSharedRegionModule, ICapabilitiesModule
48 { 48 {
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 880b2cc..7e72d47 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -43,9 +43,11 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
43using OpenMetaverse; 43using OpenMetaverse;
44using log4net; 44using log4net;
45using Nini.Config; 45using Nini.Config;
46using Mono.Addins;
46 47
47namespace OpenSim.Region.CoreModules.Framework.EntityTransfer 48namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
48{ 49{
50 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EntityTransferModule")]
49 public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule 51 public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule
50 { 52 {
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 53 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -327,6 +329,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
327 return; 329 return;
328 } 330 }
329 331
332 // Validate assorted conditions
333 string reason = string.Empty;
334 if (!ValidateGenericConditions(sp, reg, finalDestination, teleportFlags, out reason))
335 {
336 sp.ControllingClient.SendTeleportFailed(reason);
337 return;
338 }
339
330 // 340 //
331 // This is it 341 // This is it
332 // 342 //
@@ -358,6 +368,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
358 } 368 }
359 } 369 }
360 370
371 // Nothing to validate here
372 protected virtual bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason)
373 {
374 reason = String.Empty;
375 return true;
376 }
377
361 /// <summary> 378 /// <summary>
362 /// Determines whether this instance is within the max transfer distance. 379 /// Determines whether this instance is within the max transfer distance.
363 /// </summary> 380 /// </summary>
@@ -473,10 +490,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
473 // both regions 490 // both regions
474 if (sp.ParentID != (uint)0) 491 if (sp.ParentID != (uint)0)
475 sp.StandUp(); 492 sp.StandUp();
476
477 else if (sp.Flying) 493 else if (sp.Flying)
478 teleportFlags |= (uint)TeleportFlags.IsFlying; 494 teleportFlags |= (uint)TeleportFlags.IsFlying;
479 495
496 // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to
497 // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested).
480 sp.ControllingClient.SendTeleportStart(teleportFlags); 498 sp.ControllingClient.SendTeleportStart(teleportFlags);
481 499
482 // the avatar.Close below will clear the child region list. We need this below for (possibly) 500 // the avatar.Close below will clear the child region list. We need this below for (possibly)
@@ -552,8 +570,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
552 // So let's wait 570 // So let's wait
553 Thread.Sleep(200); 571 Thread.Sleep(200);
554 572
573 // At least on LL 3.3.4 for teleports between different regions on the same simulator this appears
574 // unnecessary - teleport will succeed and SEED caps will be requested without it (though possibly
575 // only on TeleportFinish). This is untested for region teleport between different simulators
576 // though this probably also works.
555 m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); 577 m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath);
556
557 } 578 }
558 else 579 else
559 { 580 {
@@ -574,7 +595,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
574 595
575 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); 596 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent...");
576 597
577 if (!UpdateAgent(reg, finalDestination, agent)) 598 if (!UpdateAgent(reg, finalDestination, agent, sp))
578 { 599 {
579 // Region doesn't take it 600 // Region doesn't take it
580 m_log.WarnFormat( 601 m_log.WarnFormat(
@@ -650,7 +671,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
650 // an agent cannot teleport back to this region if it has teleported away. 671 // an agent cannot teleport back to this region if it has teleported away.
651 Thread.Sleep(3000); 672 Thread.Sleep(3000);
652 673
653 sp.Scene.IncomingCloseAgent(sp.UUID); 674 sp.Scene.IncomingCloseAgent(sp.UUID, false);
654 } 675 }
655 else 676 else
656 { 677 {
@@ -658,13 +679,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
658 sp.Reset(); 679 sp.Reset();
659 } 680 }
660 681
661 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! 682 // Commented pending deletion since this method no longer appears to do anything at all
662 if (sp.Scene.NeedSceneCacheClear(sp.UUID)) 683// // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
663 { 684// if (sp.Scene.NeedSceneCacheClear(sp.UUID))
664 m_log.DebugFormat( 685// {
665 "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", 686// m_log.DebugFormat(
666 sp.UUID); 687// "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed",
667 } 688// sp.UUID);
689// }
668 690
669 m_entityTransferStateMachine.ResetFromTransit(sp.UUID); 691 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
670 } 692 }
@@ -701,7 +723,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
701 return success; 723 return success;
702 } 724 }
703 725
704 protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent) 726 protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent, ScenePresence sp)
705 { 727 {
706 return Scene.SimulationService.UpdateAgent(finalDestination, agent); 728 return Scene.SimulationService.UpdateAgent(finalDestination, agent);
707 } 729 }
@@ -1013,6 +1035,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1013 Scene initiatingScene) 1035 Scene initiatingScene)
1014 { 1036 {
1015 Thread.Sleep(10000); 1037 Thread.Sleep(10000);
1038
1016 IMessageTransferModule im = initiatingScene.RequestModuleInterface<IMessageTransferModule>(); 1039 IMessageTransferModule im = initiatingScene.RequestModuleInterface<IMessageTransferModule>();
1017 if (im != null) 1040 if (im != null)
1018 { 1041 {
@@ -1025,11 +1048,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1025 (uint)(int)position.X, 1048 (uint)(int)position.X,
1026 (uint)(int)position.Y, 1049 (uint)(int)position.Y,
1027 (uint)(int)position.Z); 1050 (uint)(int)position.Z);
1028 GridInstantMessage m = new GridInstantMessage(initiatingScene, UUID.Zero, 1051
1029 "Region", agent.UUID, 1052 GridInstantMessage m
1030 (byte)InstantMessageDialog.GodLikeRequestTeleport, false, 1053 = new GridInstantMessage(
1031 "", gotoLocation, false, new Vector3(127, 0, 0), 1054 initiatingScene,
1032 new Byte[0]); 1055 UUID.Zero,
1056 "Region",
1057 agent.UUID,
1058 (byte)InstantMessageDialog.GodLikeRequestTeleport,
1059 false,
1060 "",
1061 gotoLocation,
1062 false,
1063 new Vector3(127, 0, 0),
1064 new Byte[0],
1065 false);
1066
1033 im.SendInstantMessage(m, delegate(bool success) 1067 im.SendInstantMessage(m, delegate(bool success)
1034 { 1068 {
1035 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Client Initiating Teleport sending IM success = {0}", success); 1069 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Client Initiating Teleport sending IM success = {0}", success);
@@ -1191,11 +1225,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1191 // the user may change their profile information in other region, 1225 // the user may change their profile information in other region,
1192 // so the userinfo in UserProfileCache is not reliable any more, delete it 1226 // so the userinfo in UserProfileCache is not reliable any more, delete it
1193 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! 1227 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
1194 if (agent.Scene.NeedSceneCacheClear(agent.UUID)) 1228// if (agent.Scene.NeedSceneCacheClear(agent.UUID))
1195 { 1229// {
1196 m_log.DebugFormat( 1230// m_log.DebugFormat(
1197 "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); 1231// "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
1198 } 1232// }
1199 1233
1200 //m_log.Debug("AFTER CROSS"); 1234 //m_log.Debug("AFTER CROSS");
1201 //Scene.DumpChildrenSeeds(UUID); 1235 //Scene.DumpChildrenSeeds(UUID);
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index 3010b59..f3a0b01 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -42,9 +42,11 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
42using OpenMetaverse; 42using OpenMetaverse;
43using log4net; 43using log4net;
44using Nini.Config; 44using Nini.Config;
45using Mono.Addins;
45 46
46namespace OpenSim.Region.CoreModules.Framework.EntityTransfer 47namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
47{ 48{
49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "HGEntityTransferModule")]
48 public class HGEntityTransferModule 50 public class HGEntityTransferModule
49 : EntityTransferModule, INonSharedRegionModule, IEntityTransferModule, IUserAgentVerificationModule 51 : EntityTransferModule, INonSharedRegionModule, IEntityTransferModule, IUserAgentVerificationModule
50 { 52 {
@@ -54,6 +56,59 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
54 56
55 private GatekeeperServiceConnector m_GatekeeperConnector; 57 private GatekeeperServiceConnector m_GatekeeperConnector;
56 58
59 protected bool m_RestrictAppearanceAbroad;
60 protected string m_AccountName;
61 protected List<AvatarAppearance> m_ExportedAppearances;
62 protected List<AvatarAttachment> m_Attachs;
63
64 protected List<AvatarAppearance> ExportedAppearance
65 {
66 get
67 {
68 if (m_ExportedAppearances != null)
69 return m_ExportedAppearances;
70
71 m_ExportedAppearances = new List<AvatarAppearance>();
72 m_Attachs = new List<AvatarAttachment>();
73
74 string[] names = m_AccountName.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
75
76 foreach (string name in names)
77 {
78 string[] parts = name.Trim().Split();
79 if (parts.Length != 2)
80 {
81 m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Wrong user account name format {0}. Specify 'First Last'", name);
82 return null;
83 }
84 UserAccount account = Scene.UserAccountService.GetUserAccount(UUID.Zero, parts[0], parts[1]);
85 if (account == null)
86 {
87 m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unknown account {0}", m_AccountName);
88 return null;
89 }
90 AvatarAppearance a = Scene.AvatarService.GetAppearance(account.PrincipalID);
91 if (a != null)
92 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Successfully retrieved appearance for {0}", name);
93
94 foreach (AvatarAttachment att in a.GetAttachments())
95 {
96 InventoryItemBase item = new InventoryItemBase(att.ItemID, account.PrincipalID);
97 item = Scene.InventoryService.GetItem(item);
98 if (item != null)
99 a.SetAttachment(att.AttachPoint, att.ItemID, item.AssetID);
100 else
101 m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unable to retrieve item {0} from inventory {1}", att.ItemID, name);
102 }
103
104 m_ExportedAppearances.Add(a);
105 m_Attachs.AddRange(a.GetAttachments());
106 }
107
108 return m_ExportedAppearances;
109 }
110 }
111
57 #region ISharedRegionModule 112 #region ISharedRegionModule
58 113
59 public override string Name 114 public override string Name
@@ -72,8 +127,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
72 { 127 {
73 IConfig transferConfig = source.Configs["EntityTransfer"]; 128 IConfig transferConfig = source.Configs["EntityTransfer"];
74 if (transferConfig != null) 129 if (transferConfig != null)
130 {
75 m_levelHGTeleport = transferConfig.GetInt("LevelHGTeleport", 0); 131 m_levelHGTeleport = transferConfig.GetInt("LevelHGTeleport", 0);
76 132
133 m_RestrictAppearanceAbroad = transferConfig.GetBoolean("RestrictAppearanceAbroad", false);
134 if (m_RestrictAppearanceAbroad)
135 {
136 m_AccountName = transferConfig.GetString("AccountForAppearance", string.Empty);
137 if (m_AccountName == string.Empty)
138 m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is on, but no account has been given for avatar appearance!");
139 }
140 }
141
77 InitialiseCommon(source); 142 InitialiseCommon(source);
78 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); 143 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name);
79 } 144 }
@@ -85,7 +150,36 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
85 base.AddRegion(scene); 150 base.AddRegion(scene);
86 151
87 if (m_Enabled) 152 if (m_Enabled)
153 {
88 scene.RegisterModuleInterface<IUserAgentVerificationModule>(this); 154 scene.RegisterModuleInterface<IUserAgentVerificationModule>(this);
155 scene.EventManager.OnIncomingSceneObject += OnIncomingSceneObject;
156 }
157 }
158
159 void OnIncomingSceneObject(SceneObjectGroup so)
160 {
161 if (!so.IsAttachment)
162 return;
163
164 if (so.Scene.UserManagementModule.IsLocalGridUser(so.AttachedAvatar))
165 return;
166
167 // foreign user
168 AgentCircuitData aCircuit = so.Scene.AuthenticateHandler.GetAgentCircuitData(so.AttachedAvatar);
169 if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
170 {
171 if (aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
172 {
173 string url = aCircuit.ServiceURLs["AssetServerURI"].ToString();
174 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Incoming attachement {0} for HG user {1} with asset server {2}", so.Name, so.AttachedAvatar, url);
175 Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>();
176 HGUuidGatherer uuidGatherer = new HGUuidGatherer(so.Scene.AssetService, url);
177 uuidGatherer.GatherAssetUuids(so, ids);
178
179 foreach (KeyValuePair<UUID, AssetType> kvp in ids)
180 uuidGatherer.FetchAsset(kvp.Key);
181 }
182 }
89 } 183 }
90 184
91 protected override void OnNewClient(IClientAPI client) 185 protected override void OnNewClient(IClientAPI client)
@@ -120,7 +214,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
120 int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, region.RegionID); 214 int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, region.RegionID);
121 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionID, flags); 215 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionID, flags);
122 216
123 if ((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) 217 if ((flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0)
124 { 218 {
125 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region {0} is hyperlink", region.RegionID); 219 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region {0} is hyperlink", region.RegionID);
126 GridRegion real_destination = m_GatekeeperConnector.GetHyperlinkRegion(region, region.RegionID); 220 GridRegion real_destination = m_GatekeeperConnector.GetHyperlinkRegion(region, region.RegionID);
@@ -140,7 +234,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
140 return true; 234 return true;
141 235
142 int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID); 236 int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID);
143 if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) 237 if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0)
144 return true; 238 return true;
145 239
146 return false; 240 return false;
@@ -153,6 +247,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
153 { 247 {
154 // Log them out of this grid 248 // Log them out of this grid
155 Scene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId); 249 Scene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
250 string userId = Scene.UserManagementModule.GetUserUUI(sp.UUID);
251 Scene.GridUserService.LoggedOut(userId, UUID.Zero, Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
156 } 252 }
157 } 253 }
158 254
@@ -162,11 +258,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
162 reason = string.Empty; 258 reason = string.Empty;
163 logout = false; 259 logout = false;
164 int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID); 260 int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID);
165 if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) 261 if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0)
166 { 262 {
167 // this user is going to another grid 263 // this user is going to another grid
168 // check if HyperGrid teleport is allowed, based on user level 264 // for local users, check if HyperGrid teleport is allowed, based on user level
169 if (sp.UserLevel < m_levelHGTeleport) 265 if (Scene.UserManagementModule.IsLocalGridUser(sp.UUID) && sp.UserLevel < m_levelHGTeleport)
170 { 266 {
171 m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unable to HG teleport agent due to insufficient UserLevel."); 267 m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unable to HG teleport agent due to insufficient UserLevel.");
172 reason = "Hypergrid teleport not allowed"; 268 reason = "Hypergrid teleport not allowed";
@@ -200,6 +296,124 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
200 TeleportHome(id, client); 296 TeleportHome(id, client);
201 } 297 }
202 298
299 protected override bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason)
300 {
301 reason = "Please wear your grid's allowed appearance before teleporting to another grid";
302 if (!m_RestrictAppearanceAbroad)
303 return true;
304
305 // The rest is only needed for controlling appearance
306
307 int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID);
308 if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0)
309 {
310 // this user is going to another grid
311 if (Scene.UserManagementModule.IsLocalGridUser(sp.UUID))
312 {
313 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is ON. Checking generic appearance");
314
315 // Check wearables
316 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
317 {
318 for (int j = 0; j < sp.Appearance.Wearables[i].Count; j++)
319 {
320 if (sp.Appearance.Wearables[i] == null)
321 continue;
322
323 bool found = false;
324 foreach (AvatarAppearance a in ExportedAppearance)
325 if (a.Wearables[i] != null)
326 {
327 found = true;
328 break;
329 }
330
331 if (!found)
332 {
333 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Wearable not allowed to go outside {0}", i);
334 return false;
335 }
336
337 found = false;
338 foreach (AvatarAppearance a in ExportedAppearance)
339 if (sp.Appearance.Wearables[i][j].AssetID == a.Wearables[i][j].AssetID)
340 {
341 found = true;
342 break;
343 }
344
345 if (!found)
346 {
347 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Wearable not allowed to go outside {0}", i);
348 return false;
349 }
350 }
351 }
352
353 // Check attachments
354 foreach (AvatarAttachment att in sp.Appearance.GetAttachments())
355 {
356 bool found = false;
357 foreach (AvatarAttachment att2 in m_Attachs)
358 {
359 if (att2.AssetID == att.AssetID)
360 {
361 found = true;
362 break;
363 }
364 }
365 if (!found)
366 {
367 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Attachment not allowed to go outside {0}", att.AttachPoint);
368 return false;
369 }
370 }
371 }
372 }
373
374 reason = string.Empty;
375 return true;
376 }
377
378
379 //protected override bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agentData, ScenePresence sp)
380 //{
381 // int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID);
382 // if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0)
383 // {
384 // // this user is going to another grid
385 // if (m_RestrictAppearanceAbroad && Scene.UserManagementModule.IsLocalGridUser(agentData.AgentID))
386 // {
387 // // We need to strip the agent off its appearance
388 // m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is ON. Sending generic appearance");
389
390 // // Delete existing npc attachments
391 // Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, false);
392
393 // // XXX: We can't just use IAvatarFactoryModule.SetAppearance() yet since it doesn't transfer attachments
394 // AvatarAppearance newAppearance = new AvatarAppearance(ExportedAppearance, true);
395 // sp.Appearance = newAppearance;
396
397 // // Rez needed npc attachments
398 // Scene.AttachmentsModule.RezAttachments(sp);
399
400
401 // IAvatarFactoryModule module = Scene.RequestModuleInterface<IAvatarFactoryModule>();
402 // //module.SendAppearance(sp.UUID);
403 // module.RequestRebake(sp, false);
404
405 // Scene.AttachmentsModule.CopyAttachments(sp, agentData);
406 // agentData.Appearance = sp.Appearance;
407 // }
408 // }
409
410 // foreach (AvatarAttachment a in agentData.Appearance.GetAttachments())
411 // m_log.DebugFormat("[XXX]: {0}-{1}", a.ItemID, a.AssetID);
412
413
414 // return base.UpdateAgent(reg, finalDestination, agentData, sp);
415 //}
416
203 public override bool TeleportHome(UUID id, IClientAPI client) 417 public override bool TeleportHome(UUID id, IClientAPI client)
204 { 418 {
205 m_log.DebugFormat( 419 m_log.DebugFormat(
@@ -375,4 +589,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
375 return region; 589 return region;
376 } 590 }
377 } 591 }
378} \ No newline at end of file 592}
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
index eaadc1b..f8ec6de 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
@@ -71,19 +71,19 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
71 71
72 #region Internal functions 72 #region Internal functions
73 73
74 public AssetBase FetchAsset(string url, UUID assetID) 74 public AssetMetadata FetchMetadata(string url, UUID assetID)
75 { 75 {
76 if (!url.EndsWith("/") && !url.EndsWith("=")) 76 if (!url.EndsWith("/") && !url.EndsWith("="))
77 url = url + "/"; 77 url = url + "/";
78 78
79 AssetBase asset = m_scene.AssetService.Get(url + assetID.ToString()); 79 AssetMetadata meta = m_scene.AssetService.GetMetadata(url + assetID.ToString());
80 80
81 if (asset != null) 81 if (meta != null)
82 { 82 m_log.DebugFormat("[HG ASSET MAPPER]: Fetched metadata for asset {0} of type {1} from {2} ", assetID, meta.Type, url);
83 m_log.DebugFormat("[HG ASSET MAPPER]: Copied asset {0} from {1} to local asset server. ", asset.ID, url); 83 else
84 return asset; 84 m_log.DebugFormat("[HG ASSET MAPPER]: Unable to fetched metadata for asset {0} from {1} ", assetID, url);
85 } 85
86 return null; 86 return meta;
87 } 87 }
88 88
89 public bool PostAsset(string url, AssetBase asset) 89 public bool PostAsset(string url, AssetBase asset)
@@ -93,6 +93,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
93 if (!url.EndsWith("/") && !url.EndsWith("=")) 93 if (!url.EndsWith("/") && !url.EndsWith("="))
94 url = url + "/"; 94 url = url + "/";
95 95
96 bool success = true;
96 // See long comment in AssetCache.AddAsset 97 // See long comment in AssetCache.AddAsset
97 if (!asset.Temporary || asset.Local) 98 if (!asset.Temporary || asset.Local)
98 { 99 {
@@ -103,14 +104,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
103 // not having a global naming infrastructure 104 // not having a global naming infrastructure
104 AssetBase asset1 = new AssetBase(asset.FullID, asset.Name, asset.Type, asset.Metadata.CreatorID); 105 AssetBase asset1 = new AssetBase(asset.FullID, asset.Name, asset.Type, asset.Metadata.CreatorID);
105 Copy(asset, asset1); 106 Copy(asset, asset1);
106 try 107 asset1.ID = url + asset.ID;
107 {
108 asset1.ID = url + asset.ID;
109 }
110 catch
111 {
112 m_log.Warn("[HG ASSET MAPPER]: Oops.");
113 }
114 108
115 AdjustIdentifiers(asset1.Metadata); 109 AdjustIdentifiers(asset1.Metadata);
116 if (asset1.Metadata.Type == (sbyte)AssetType.Object) 110 if (asset1.Metadata.Type == (sbyte)AssetType.Object)
@@ -118,11 +112,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
118 else 112 else
119 asset1.Data = asset.Data; 113 asset1.Data = asset.Data;
120 114
121 m_scene.AssetService.Store(asset1); 115 string id = m_scene.AssetService.Store(asset1);
122 m_log.DebugFormat("[HG ASSET MAPPER]: Posted copy of asset {0} from local asset server to {1}", asset1.ID, url); 116 if (id == string.Empty)
117 {
118 m_log.DebugFormat("[HG ASSET MAPPER]: Asset server {0} did not accept {1}", url, asset.ID);
119 success = false;
120 }
121 else
122 m_log.DebugFormat("[HG ASSET MAPPER]: Posted copy of asset {0} from local asset server to {1}", asset1.ID, url);
123 } 123 }
124 return true; 124 return success;
125 } 125 }
126 else 126 else
127 m_log.Warn("[HG ASSET MAPPER]: Tried to post asset to remote server, but asset not in local cache."); 127 m_log.Warn("[HG ASSET MAPPER]: Tried to post asset to remote server, but asset not in local cache.");
128 128
@@ -222,28 +222,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
222 222
223 public void Get(UUID assetID, UUID ownerID, string userAssetURL) 223 public void Get(UUID assetID, UUID ownerID, string userAssetURL)
224 { 224 {
225 // Get the item from the remote asset server onto the local AssetCache 225 // Get the item from the remote asset server onto the local AssetService
226 // and place an entry in m_assetMap
227
228 m_log.Debug("[HG ASSET MAPPER]: Fetching object " + assetID + " from asset server " + userAssetURL);
229 AssetBase asset = FetchAsset(userAssetURL, assetID);
230 226
231 if (asset != null) 227 AssetMetadata meta = FetchMetadata(userAssetURL, assetID);
232 { 228 if (meta == null)
233 // OK, now fetch the inside. 229 return;
234 Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>();
235 HGUuidGatherer uuidGatherer = new HGUuidGatherer(this, m_scene.AssetService, userAssetURL);
236 uuidGatherer.GatherAssetUuids(asset.FullID, (AssetType)asset.Type, ids);
237 if (ids.ContainsKey(assetID))
238 ids.Remove(assetID);
239 foreach (UUID uuid in ids.Keys)
240 FetchAsset(userAssetURL, uuid);
241 230
242 m_log.DebugFormat("[HG ASSET MAPPER]: Successfully fetched asset {0} from asset server {1}", asset.ID, userAssetURL); 231 // The act of gathering UUIDs downloads the assets from the remote server
232 Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>();
233 HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, userAssetURL);
234 uuidGatherer.GatherAssetUuids(assetID, (AssetType)meta.Type, ids);
243 235
244 }
245 else
246 m_log.Warn("[HG ASSET MAPPER]: Could not fetch asset from remote asset server " + userAssetURL);
247 } 236 }
248 237
249 238
@@ -257,19 +246,23 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
257 if (asset != null) 246 if (asset != null)
258 { 247 {
259 Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>(); 248 Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>();
260 HGUuidGatherer uuidGatherer = new HGUuidGatherer(this, m_scene.AssetService, string.Empty); 249 HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, string.Empty);
261 uuidGatherer.GatherAssetUuids(asset.FullID, (AssetType)asset.Type, ids); 250 uuidGatherer.GatherAssetUuids(asset.FullID, (AssetType)asset.Type, ids);
251 bool success = false;
262 foreach (UUID uuid in ids.Keys) 252 foreach (UUID uuid in ids.Keys)
263 { 253 {
264 asset = m_scene.AssetService.Get(uuid.ToString()); 254 asset = m_scene.AssetService.Get(uuid.ToString());
265 if (asset == null) 255 if (asset == null)
266 m_log.DebugFormat("[HG ASSET MAPPER]: Could not find asset {0}", uuid); 256 m_log.DebugFormat("[HG ASSET MAPPER]: Could not find asset {0}", uuid);
267 else 257 else
268 PostAsset(userAssetURL, asset); 258 success = PostAsset(userAssetURL, asset);
269 } 259 }
270 260
271 // maybe all pieces got there... 261 // maybe all pieces got there...
272 m_log.DebugFormat("[HG ASSET MAPPER]: Successfully posted item {0} to asset server {1}", assetID, userAssetURL); 262 if (!success)
263 m_log.DebugFormat("[HG ASSET MAPPER]: Problems posting item {0} to asset server {1}", assetID, userAssetURL);
264 else
265 m_log.DebugFormat("[HG ASSET MAPPER]: Successfully posted item {0} to asset server {1}", assetID, userAssetURL);
273 266
274 } 267 }
275 else 268 else
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
index cf72b58..964efda 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
@@ -42,9 +42,11 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
42using OpenMetaverse; 42using OpenMetaverse;
43using log4net; 43using log4net;
44using Nini.Config; 44using Nini.Config;
45using Mono.Addins;
45 46
46namespace OpenSim.Region.CoreModules.Framework.InventoryAccess 47namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
47{ 48{
49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "HGInventoryAccessModule")]
48 public class HGInventoryAccessModule : BasicInventoryAccessModule, INonSharedRegionModule, IInventoryAccessModule 50 public class HGInventoryAccessModule : BasicInventoryAccessModule, INonSharedRegionModule, IInventoryAccessModule
49 { 51 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -92,7 +94,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
92 m_HomeURI = thisModuleConfig.GetString("HomeURI", m_HomeURI); 94 m_HomeURI = thisModuleConfig.GetString("HomeURI", m_HomeURI);
93 m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true); 95 m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true);
94 m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty); 96 m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty);
95 m_RestrictInventoryAccessAbroad = thisModuleConfig.GetBoolean("RestrictInventoryAccessAbroad", false); 97 m_RestrictInventoryAccessAbroad = thisModuleConfig.GetBoolean("RestrictInventoryAccessAbroad", true);
96 } 98 }
97 else 99 else
98 m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!"); 100 m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!");
@@ -263,8 +265,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
263 //} 265 //}
264 266
265 // OK, we're done fetching. Pass it up to the default RezObject 267 // OK, we're done fetching. Pass it up to the default RezObject
266 return base.RezObject(remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection, 268 SceneObjectGroup sog = base.RezObject(remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection,
267 RezSelected, RemoveItem, fromTaskID, attachment); 269 RezSelected, RemoveItem, fromTaskID, attachment);
270
271 if (sog == null)
272 remoteClient.SendAgentAlertMessage("Unable to rez: problem accessing inventory or locating assets", false);
273
274 return sog;
268 275
269 } 276 }
270 277
@@ -308,6 +315,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
308 protected override InventoryItemBase GetItem(UUID agentID, UUID itemID) 315 protected override InventoryItemBase GetItem(UUID agentID, UUID itemID)
309 { 316 {
310 InventoryItemBase item = base.GetItem(agentID, itemID); 317 InventoryItemBase item = base.GetItem(agentID, itemID);
318 if (item == null)
319 return null;
311 320
312 string userAssetServer = string.Empty; 321 string userAssetServer = string.Empty;
313 if (IsForeignUser(agentID, out userAssetServer)) 322 if (IsForeignUser(agentID, out userAssetServer))
@@ -344,6 +353,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
344 353
345 private void ProcessInventoryForArriving(IClientAPI client) 354 private void ProcessInventoryForArriving(IClientAPI client)
346 { 355 {
356 // No-op for now, but we may need to do something for freign users inventory
347 } 357 }
348 358
349 // 359 //
@@ -390,6 +400,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
390 400
391 private void ProcessInventoryForLeaving(IClientAPI client) 401 private void ProcessInventoryForLeaving(IClientAPI client)
392 { 402 {
403 // No-op for now
393 } 404 }
394 405
395 #endregion 406 #endregion
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 50f5f68..6e5a4a5 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -46,9 +46,11 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
46using OpenMetaverse; 46using OpenMetaverse;
47using log4net; 47using log4net;
48using Nini.Config; 48using Nini.Config;
49using Mono.Addins;
49 50
50namespace OpenSim.Region.CoreModules.Framework.InventoryAccess 51namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
51{ 52{
53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "BasicInventoryAccessModule")]
52 public class BasicInventoryAccessModule : INonSharedRegionModule, IInventoryAccessModule 54 public class BasicInventoryAccessModule : INonSharedRegionModule, IInventoryAccessModule
53 { 55 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 56 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
index 3155ce7..ec22146 100644
--- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
@@ -41,10 +41,12 @@ using OpenSim.Server.Base;
41 41
42using OpenMetaverse; 42using OpenMetaverse;
43using log4net; 43using log4net;
44using Mono.Addins;
44using Nini.Config; 45using Nini.Config;
45 46
46namespace OpenSim.Region.CoreModules.Framework.Library 47namespace OpenSim.Region.CoreModules.Framework.Library
47{ 48{
49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LibraryModule")]
48 public class LibraryModule : ISharedRegionModule 50 public class LibraryModule : ISharedRegionModule
49 { 51 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
index e135c21..d84460a 100644
--- a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
@@ -38,10 +38,12 @@ using OpenSim.Region.CoreModules.Framework.Monitoring.Alerts;
38using OpenSim.Region.CoreModules.Framework.Monitoring.Monitors; 38using OpenSim.Region.CoreModules.Framework.Monitoring.Monitors;
39using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
41using Mono.Addins;
41 42
42namespace OpenSim.Region.CoreModules.Framework.Monitoring 43namespace OpenSim.Region.CoreModules.Framework.Monitoring
43{ 44{
44 public class MonitorModule : IRegionModule 45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MonitorModule")]
46 public class MonitorModule : INonSharedRegionModule
45 { 47 {
46 /// <summary> 48 /// <summary>
47 /// Is this module enabled? 49 /// Is this module enabled?
@@ -62,14 +64,14 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
62 private readonly List<IAlert> m_alerts = new List<IAlert>(); 64 private readonly List<IAlert> m_alerts = new List<IAlert>();
63 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 65 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
64 66
65 #region Implementation of IRegionModule
66
67 public MonitorModule() 67 public MonitorModule()
68 { 68 {
69 Enabled = true; 69 Enabled = true;
70 } 70 }
71 71
72 public void Initialise(Scene scene, IConfigSource source) 72 #region Implementation of INonSharedRegionModule
73
74 public void Initialise(IConfigSource source)
73 { 75 {
74 IConfig cnfg = source.Configs["Monitoring"]; 76 IConfig cnfg = source.Configs["Monitoring"];
75 77
@@ -79,6 +81,13 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
79 if (!Enabled) 81 if (!Enabled)
80 return; 82 return;
81 83
84 }
85
86 public void AddRegion(Scene scene)
87 {
88 if (!Enabled)
89 return;
90
82 m_scene = scene; 91 m_scene = scene;
83 92
84 m_scene.AddCommand("General", this, "monitor report", 93 m_scene.AddCommand("General", this, "monitor report",
@@ -89,101 +98,42 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
89 MainServer.Instance.AddHTTPHandler("/monitorstats/" + m_scene.RegionInfo.RegionID, StatsPage); 98 MainServer.Instance.AddHTTPHandler("/monitorstats/" + m_scene.RegionInfo.RegionID, StatsPage);
90 MainServer.Instance.AddHTTPHandler( 99 MainServer.Instance.AddHTTPHandler(
91 "/monitorstats/" + Uri.EscapeDataString(m_scene.RegionInfo.RegionName), StatsPage); 100 "/monitorstats/" + Uri.EscapeDataString(m_scene.RegionInfo.RegionName), StatsPage);
101
102 AddMonitors();
92 } 103 }
93 104
94 public void DebugMonitors(string module, string[] args) 105 public void RemoveRegion(Scene scene)
95 { 106 {
96 foreach (IMonitor monitor in m_staticMonitors) 107 if (!Enabled)
97 { 108 return;
98 m_log.InfoFormat(
99 "[MONITOR MODULE]: {0} reports {1} = {2}",
100 m_scene.RegionInfo.RegionName, monitor.GetFriendlyName(), monitor.GetFriendlyValue());
101 }
102 109
103 foreach (KeyValuePair<string, float> tuple in m_scene.StatsReporter.GetExtraSimStats()) 110 MainServer.Instance.RemoveHTTPHandler("GET", "/monitorstats/" + m_scene.RegionInfo.RegionID);
104 { 111 MainServer.Instance.RemoveHTTPHandler("GET", "/monitorstats/" + Uri.EscapeDataString(m_scene.RegionInfo.RegionName));
105 m_log.InfoFormat( 112 m_scene = null;
106 "[MONITOR MODULE]: {0} reports {1} = {2}",
107 m_scene.RegionInfo.RegionName, tuple.Key, tuple.Value);
108 }
109 } 113 }
110 114
111 public void TestAlerts() 115 public void Close()
112 { 116 {
113 foreach (IAlert alert in m_alerts)
114 {
115 alert.Test();
116 }
117 } 117 }
118 118
119 public Hashtable StatsPage(Hashtable request) 119 public string Name
120 { 120 {
121 // If request was for a specific monitor 121 get { return "Region Health Monitoring Module"; }
122 // eg url/?monitor=Monitor.Name 122 }
123 if (request.ContainsKey("monitor"))
124 {
125 string monID = (string) request["monitor"];
126
127 foreach (IMonitor monitor in m_staticMonitors)
128 {
129 string elemName = monitor.ToString();
130 if (elemName.StartsWith(monitor.GetType().Namespace))
131 elemName = elemName.Substring(monitor.GetType().Namespace.Length + 1);
132
133 if (elemName == monID || monitor.ToString() == monID)
134 {
135 Hashtable ereply3 = new Hashtable();
136
137 ereply3["int_response_code"] = 404; // 200 OK
138 ereply3["str_response_string"] = monitor.GetValue().ToString();
139 ereply3["content_type"] = "text/plain";
140
141 return ereply3;
142 }
143 }
144
145 // FIXME: Arguably this should also be done with dynamic monitors but I'm not sure what the above code
146 // is even doing. Why are we inspecting the type of the monitor???
147
148 // No monitor with that name
149 Hashtable ereply2 = new Hashtable();
150
151 ereply2["int_response_code"] = 404; // 200 OK
152 ereply2["str_response_string"] = "No such monitor";
153 ereply2["content_type"] = "text/plain";
154
155 return ereply2;
156 }
157
158 string xml = "<data>";
159 foreach (IMonitor monitor in m_staticMonitors)
160 {
161 string elemName = monitor.GetName();
162 xml += "<" + elemName + ">" + monitor.GetValue().ToString() + "</" + elemName + ">";
163// m_log.DebugFormat("[MONITOR MODULE]: {0} = {1}", elemName, monitor.GetValue());
164 }
165
166 foreach (KeyValuePair<string, float> tuple in m_scene.StatsReporter.GetExtraSimStats())
167 {
168 xml += "<" + tuple.Key + ">" + tuple.Value + "</" + tuple.Key + ">";
169 }
170
171 xml += "</data>";
172
173 Hashtable ereply = new Hashtable();
174
175 ereply["int_response_code"] = 200; // 200 OK
176 ereply["str_response_string"] = xml;
177 ereply["content_type"] = "text/xml";
178 123
179 return ereply; 124 public void RegionLoaded(Scene scene)
125 {
180 } 126 }
181 127
182 public void PostInitialise() 128 public Type ReplaceableInterface
183 { 129 {
184 if (!Enabled) 130 get { return null; }
185 return; 131 }
132
133 #endregion
186 134
135 public void AddMonitors()
136 {
187 m_staticMonitors.Add(new AgentCountMonitor(m_scene)); 137 m_staticMonitors.Add(new AgentCountMonitor(m_scene));
188 m_staticMonitors.Add(new ChildAgentCountMonitor(m_scene)); 138 m_staticMonitors.Add(new ChildAgentCountMonitor(m_scene));
189 m_staticMonitors.Add(new GCMemoryMonitor()); 139 m_staticMonitors.Add(new GCMemoryMonitor());
@@ -196,7 +146,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
196 m_staticMonitors.Add(new EventFrameMonitor(m_scene)); 146 m_staticMonitors.Add(new EventFrameMonitor(m_scene));
197 m_staticMonitors.Add(new LandFrameMonitor(m_scene)); 147 m_staticMonitors.Add(new LandFrameMonitor(m_scene));
198 m_staticMonitors.Add(new LastFrameTimeMonitor(m_scene)); 148 m_staticMonitors.Add(new LastFrameTimeMonitor(m_scene));
199 149
200 m_staticMonitors.Add( 150 m_staticMonitors.Add(
201 new GenericMonitor( 151 new GenericMonitor(
202 m_scene, 152 m_scene,
@@ -357,25 +307,98 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
357 } 307 }
358 } 308 }
359 309
360 void OnTriggerAlert(System.Type reporter, string reason, bool fatal) 310 public void DebugMonitors(string module, string[] args)
361 { 311 {
362 m_log.Error("[Monitor] " + reporter.Name + " for " + m_scene.RegionInfo.RegionName + " reports " + reason + " (Fatal: " + fatal + ")"); 312 foreach (IMonitor monitor in m_staticMonitors)
313 {
314 MainConsole.Instance.OutputFormat(
315 "[MONITOR MODULE]: {0} reports {1} = {2}",
316 m_scene.RegionInfo.RegionName, monitor.GetFriendlyName(), monitor.GetFriendlyValue());
317 }
318
319 foreach (KeyValuePair<string, float> tuple in m_scene.StatsReporter.GetExtraSimStats())
320 {
321 MainConsole.Instance.OutputFormat(
322 "[MONITOR MODULE]: {0} reports {1} = {2}",
323 m_scene.RegionInfo.RegionName, tuple.Key, tuple.Value);
324 }
363 } 325 }
364 326
365 public void Close() 327 public void TestAlerts()
366 { 328 {
329 foreach (IAlert alert in m_alerts)
330 {
331 alert.Test();
332 }
367 } 333 }
368 334
369 public string Name 335 public Hashtable StatsPage(Hashtable request)
370 { 336 {
371 get { return "Region Health Monitoring Module"; } 337 // If request was for a specific monitor
338 // eg url/?monitor=Monitor.Name
339 if (request.ContainsKey("monitor"))
340 {
341 string monID = (string) request["monitor"];
342
343 foreach (IMonitor monitor in m_staticMonitors)
344 {
345 string elemName = monitor.ToString();
346 if (elemName.StartsWith(monitor.GetType().Namespace))
347 elemName = elemName.Substring(monitor.GetType().Namespace.Length + 1);
348
349 if (elemName == monID || monitor.ToString() == monID)
350 {
351 Hashtable ereply3 = new Hashtable();
352
353 ereply3["int_response_code"] = 404; // 200 OK
354 ereply3["str_response_string"] = monitor.GetValue().ToString();
355 ereply3["content_type"] = "text/plain";
356
357 return ereply3;
358 }
359 }
360
361 // FIXME: Arguably this should also be done with dynamic monitors but I'm not sure what the above code
362 // is even doing. Why are we inspecting the type of the monitor???
363
364 // No monitor with that name
365 Hashtable ereply2 = new Hashtable();
366
367 ereply2["int_response_code"] = 404; // 200 OK
368 ereply2["str_response_string"] = "No such monitor";
369 ereply2["content_type"] = "text/plain";
370
371 return ereply2;
372 }
373
374 string xml = "<data>";
375 foreach (IMonitor monitor in m_staticMonitors)
376 {
377 string elemName = monitor.GetName();
378 xml += "<" + elemName + ">" + monitor.GetValue().ToString() + "</" + elemName + ">";
379// m_log.DebugFormat("[MONITOR MODULE]: {0} = {1}", elemName, monitor.GetValue());
380 }
381
382 foreach (KeyValuePair<string, float> tuple in m_scene.StatsReporter.GetExtraSimStats())
383 {
384 xml += "<" + tuple.Key + ">" + tuple.Value + "</" + tuple.Key + ">";
385 }
386
387 xml += "</data>";
388
389 Hashtable ereply = new Hashtable();
390
391 ereply["int_response_code"] = 200; // 200 OK
392 ereply["str_response_string"] = xml;
393 ereply["content_type"] = "text/xml";
394
395 return ereply;
372 } 396 }
373 397
374 public bool IsSharedModule 398 void OnTriggerAlert(System.Type reporter, string reason, bool fatal)
375 { 399 {
376 get { return false; } 400 m_log.Error("[Monitor] " + reporter.Name + " for " + m_scene.RegionInfo.RegionName + " reports " + reason + " (Fatal: " + fatal + ")");
377 } 401 }
378 402
379 #endregion
380 } 403 }
381} 404}
diff --git a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs
index 65e4c90..fd8d5e3 100755
--- a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs
+++ b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs
@@ -1,161 +1,170 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the 12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Text; 30using System.Text;
31using log4net; 31using log4net;
32 32
33namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging 33namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
34{ 34{
35 /// <summary> 35 /// <summary>
36 /// Class for writing a high performance, high volume log file. 36 /// Class for writing a high performance, high volume log file.
37 /// Sometimes, to debug, one has a high volume logging to do and the regular 37 /// Sometimes, to debug, one has a high volume logging to do and the regular
38 /// log file output is not appropriate. 38 /// log file output is not appropriate.
39 /// Create a new instance with the parameters needed and 39 /// Create a new instance with the parameters needed and
40 /// call Write() to output a line. Call Close() when finished. 40 /// call Write() to output a line. Call Close() when finished.
41 /// If created with no parameters, it will not log anything. 41 /// If created with no parameters, it will not log anything.
42 /// </summary> 42 /// </summary>
43 public class LogWriter : IDisposable 43 public class LogWriter : IDisposable
44 { 44 {
45 public bool Enabled { get; private set; } 45 public bool Enabled { get; private set; }
46 46
47 private string m_logDirectory = "."; 47 private string m_logDirectory = ".";
48 private int m_logMaxFileTimeMin = 5; // 5 minutes 48 private int m_logMaxFileTimeMin = 5; // 5 minutes
49 public String LogFileHeader { get; set; } 49 public String LogFileHeader { get; set; }
50 50
51 private StreamWriter m_logFile = null; 51 private StreamWriter m_logFile = null;
52 private TimeSpan m_logFileLife; 52 private TimeSpan m_logFileLife;
53 private DateTime m_logFileEndTime; 53 private DateTime m_logFileEndTime;
54 private Object m_logFileWriteLock = new Object(); 54 private Object m_logFileWriteLock = new Object();
55 55
56 // set externally when debugging. If let 'null', this does not write any error messages. 56 // set externally when debugging. If let 'null', this does not write any error messages.
57 public ILog ErrorLogger = null; 57 public ILog ErrorLogger = null;
58 private string LogHeader = "[LOG WRITER]"; 58 private string LogHeader = "[LOG WRITER]";
59 59
60 /// <summary> 60 /// <summary>
61 /// Create a log writer that will not write anything. Good for when not enabled 61 /// Create a log writer that will not write anything. Good for when not enabled
62 /// but the write statements are still in the code. 62 /// but the write statements are still in the code.
63 /// </summary> 63 /// </summary>
64 public LogWriter() 64 public LogWriter()
65 { 65 {
66 Enabled = false; 66 Enabled = false;
67 m_logFile = null; 67 m_logFile = null;
68 } 68 }
69 69
70 /// <summary> 70 /// <summary>
71 /// Create a log writer instance. 71 /// Create a log writer instance.
72 /// </summary> 72 /// </summary>
73 /// <param name="dir">The directory to create the log file in. May be 'null' for default.</param> 73 /// <param name="dir">The directory to create the log file in. May be 'null' for default.</param>
74 /// <param name="headr">The characters that begin the log file name. May be 'null' for default.</param> 74 /// <param name="headr">The characters that begin the log file name. May be 'null' for default.</param>
75 /// <param name="maxFileTime">Maximum age of a log file in minutes. If zero, will set default.</param> 75 /// <param name="maxFileTime">Maximum age of a log file in minutes. If zero, will set default.</param>
76 public LogWriter(string dir, string headr, int maxFileTime) 76 public LogWriter(string dir, string headr, int maxFileTime)
77 { 77 {
78 m_logDirectory = dir == null ? "." : dir; 78 m_logDirectory = dir == null ? "." : dir;
79 79
80 LogFileHeader = headr == null ? "log-" : headr; 80 LogFileHeader = headr == null ? "log-" : headr;
81 81
82 m_logMaxFileTimeMin = maxFileTime; 82 m_logMaxFileTimeMin = maxFileTime;
83 if (m_logMaxFileTimeMin < 1) 83 if (m_logMaxFileTimeMin < 1)
84 m_logMaxFileTimeMin = 5; 84 m_logMaxFileTimeMin = 5;
85 85
86 m_logFileLife = new TimeSpan(0, m_logMaxFileTimeMin, 0); 86 m_logFileLife = new TimeSpan(0, m_logMaxFileTimeMin, 0);
87 m_logFileEndTime = DateTime.Now + m_logFileLife; 87 m_logFileEndTime = DateTime.Now + m_logFileLife;
88 88
89 Enabled = true; 89 Enabled = true;
90 } 90 }
91 91
92 public void Dispose() 92 public void Dispose()
93 { 93 {
94 this.Close(); 94 this.Close();
95 } 95 }
96 96
97 public void Close() 97 public void Close()
98 { 98 {
99 Enabled = false; 99 Enabled = false;
100 if (m_logFile != null) 100 if (m_logFile != null)
101 { 101 {
102 m_logFile.Close(); 102 m_logFile.Close();
103 m_logFile.Dispose(); 103 m_logFile.Dispose();
104 m_logFile = null; 104 m_logFile = null;
105 } 105 }
106 } 106 }
107 107
108 public void Write(string line, params object[] args) 108 public void Write(string line, params object[] args)
109 { 109 {
110 if (!Enabled) return; 110 if (!Enabled) return;
111 Write(String.Format(line, args)); 111 Write(String.Format(line, args));
112 } 112 }
113 113
114 public void Write(string line) 114 public void Flush()
115 { 115 {
116 if (!Enabled) return; 116 if (!Enabled) return;
117 try 117 if (m_logFile != null)
118 { 118 {
119 lock (m_logFileWriteLock) 119 m_logFile.Flush();
120 { 120 }
121 DateTime now = DateTime.Now; 121 }
122 if (m_logFile == null || now > m_logFileEndTime) 122
123 { 123 public void Write(string line)
124 if (m_logFile != null) 124 {
125 { 125 if (!Enabled) return;
126 m_logFile.Close(); 126 try
127 m_logFile.Dispose(); 127 {
128 m_logFile = null; 128 lock (m_logFileWriteLock)
129 } 129 {
130 130 DateTime now = DateTime.Now;
131 // First log file or time has expired, start writing to a new log file 131 if (m_logFile == null || now > m_logFileEndTime)
132 m_logFileEndTime = now + m_logFileLife; 132 {
133 string path = (m_logDirectory.Length > 0 ? m_logDirectory 133 if (m_logFile != null)
134 + System.IO.Path.DirectorySeparatorChar.ToString() : "") 134 {
135 + String.Format("{0}{1}.log", LogFileHeader, now.ToString("yyyyMMddHHmmss")); 135 m_logFile.Close();
136 m_logFile = new StreamWriter(File.Open(path, FileMode.Append, FileAccess.Write)); 136 m_logFile.Dispose();
137 } 137 m_logFile = null;
138 if (m_logFile != null) 138 }
139 { 139
140 StringBuilder buff = new StringBuilder(line.Length + 25); 140 // First log file or time has expired, start writing to a new log file
141 buff.Append(now.ToString("yyyyMMddHHmmssfff")); 141 m_logFileEndTime = now + m_logFileLife;
142 // buff.Append(now.ToString("yyyyMMddHHmmss")); 142 string path = (m_logDirectory.Length > 0 ? m_logDirectory
143 buff.Append(","); 143 + System.IO.Path.DirectorySeparatorChar.ToString() : "")
144 buff.Append(line); 144 + String.Format("{0}{1}.log", LogFileHeader, now.ToString("yyyyMMddHHmmss"));
145 buff.Append("\r\n"); 145 m_logFile = new StreamWriter(File.Open(path, FileMode.Append, FileAccess.Write));
146 m_logFile.Write(buff.ToString()); 146 }
147 } 147 if (m_logFile != null)
148 } 148 {
149 } 149 StringBuilder buff = new StringBuilder(line.Length + 25);
150 catch (Exception e) 150 buff.Append(now.ToString("yyyyMMddHHmmssfff"));
151 { 151 // buff.Append(now.ToString("yyyyMMddHHmmss"));
152 if (ErrorLogger != null) 152 buff.Append(",");
153 { 153 buff.Append(line);
154 ErrorLogger.ErrorFormat("{0}: FAILURE WRITING TO LOGFILE: {1}", LogHeader, e); 154 buff.Append("\r\n");
155 } 155 m_logFile.Write(buff.ToString());
156 Enabled = false; 156 }
157 } 157 }
158 return; 158 }
159 } 159 catch (Exception e)
160 } 160 {
161} \ No newline at end of file 161 if (ErrorLogger != null)
162 {
163 ErrorLogger.ErrorFormat("{0}: FAILURE WRITING TO LOGFILE: {1}", LogHeader, e);
164 }
165 Enabled = false;
166 }
167 return;
168 }
169 }
170}
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
index 4eecaa2..4ef57fe 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
@@ -41,9 +41,11 @@ using OpenMetaverse;
41using OpenMetaverse.Packets; 41using OpenMetaverse.Packets;
42using log4net; 42using log4net;
43using Nini.Config; 43using Nini.Config;
44using Mono.Addins;
44 45
45namespace OpenSim.Region.CoreModules.Framework.UserManagement 46namespace OpenSim.Region.CoreModules.Framework.UserManagement
46{ 47{
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "HGUserManagementModule")]
47 public class HGUserManagementModule : UserManagementModule, ISharedRegionModule, IUserManagement 49 public class HGUserManagementModule : UserManagementModule, ISharedRegionModule, IUserManagement
48 { 50 {
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -137,6 +139,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
137 ud.FirstName = words[0]; 139 ud.FirstName = words[0];
138 ud.LastName = "@" + words[1]; 140 ud.LastName = "@" + words[1];
139 users.Add(ud); 141 users.Add(ud);
142 // WARNING! that uriStr is not quite right... it may be missing the / at the end,
143 // which will cause trouble (duplicate entries on some tables). We should
144 // get the UUI instead from the UAS. TO BE FIXED.
140 AddUser(userID, names[0], names[1], uriStr); 145 AddUser(userID, names[0], names[1], uriStr);
141 m_log.DebugFormat("[USER MANAGEMENT MODULE]: User {0}@{1} found", words[0], words[1]); 146 m_log.DebugFormat("[USER MANAGEMENT MODULE]: User {0}@{1} found", words[0], words[1]);
142 } 147 }
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index f4ed67b..86e7004 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -31,6 +31,7 @@ using System.Reflection;
31 31
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Framework.Console; 33using OpenSim.Framework.Console;
34using OpenSim.Region.ClientStack.LindenUDP;
34using OpenSim.Region.Framework; 35using OpenSim.Region.Framework;
35using OpenSim.Region.Framework.Interfaces; 36using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
@@ -41,6 +42,7 @@ using OpenMetaverse;
41using OpenMetaverse.Packets; 42using OpenMetaverse.Packets;
42using log4net; 43using log4net;
43using Nini.Config; 44using Nini.Config;
45using Mono.Addins;
44 46
45namespace OpenSim.Region.CoreModules.Framework.UserManagement 47namespace OpenSim.Region.CoreModules.Framework.UserManagement
46{ 48{
@@ -53,6 +55,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
53 public Dictionary<string, object> ServerURLs { get; set; } 55 public Dictionary<string, object> ServerURLs { get; set; }
54 } 56 }
55 57
58 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserManagementModule")]
56 public class UserManagementModule : ISharedRegionModule, IUserManagement 59 public class UserManagementModule : ISharedRegionModule, IUserManagement
57 { 60 {
58 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 61 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -429,8 +432,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
429 432
430 public void AddUser(UUID uuid, string first, string last, string homeURL) 433 public void AddUser(UUID uuid, string first, string last, string homeURL)
431 { 434 {
432 // m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, first {1}, last {2}, url {3}", uuid, first, last, homeURL); 435 //m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, first {1}, last {2}, url {3}", uuid, first, last, homeURL);
433
434 AddUser(uuid, homeURL + ";" + first + " " + last); 436 AddUser(uuid, homeURL + ";" + first + " " + last);
435 } 437 }
436 438
@@ -553,8 +555,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
553 MainConsole.Instance.Output("-----------------------------------------------------------------------------"); 555 MainConsole.Instance.Output("-----------------------------------------------------------------------------");
554 foreach (KeyValuePair<UUID, UserData> kvp in m_UserCache) 556 foreach (KeyValuePair<UUID, UserData> kvp in m_UserCache)
555 { 557 {
556 MainConsole.Instance.Output(String.Format("{0} {1} {2}", 558 MainConsole.Instance.Output(String.Format("{0} {1} {2} ({3})",
557 kvp.Key, kvp.Value.FirstName, kvp.Value.LastName)); 559 kvp.Key, kvp.Value.FirstName, kvp.Value.LastName, kvp.Value.HomeURL));
558 } 560 }
559 561
560 return; 562 return;
diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
index 4f18b53..ec94420 100644
--- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs
@@ -31,6 +31,7 @@ using System.Reflection;
31using log4net; 31using log4net;
32using Nini.Config; 32using Nini.Config;
33using OpenMetaverse; 33using OpenMetaverse;
34using Mono.Addins;
34using OpenSim.Framework; 35using OpenSim.Framework;
35using OpenSim.Region.CoreModules.World.WorldMap; 36using OpenSim.Region.CoreModules.World.WorldMap;
36using OpenSim.Region.Framework.Interfaces; 37using OpenSim.Region.Framework.Interfaces;
@@ -39,6 +40,7 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
39 40
40namespace OpenSim.Region.CoreModules.Hypergrid 41namespace OpenSim.Region.CoreModules.Hypergrid
41{ 42{
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "HGWorldMapModule")]
42 public class HGWorldMapModule : WorldMapModule 44 public class HGWorldMapModule : WorldMapModule
43 { 45 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
diff --git a/OpenSim/Region/CoreModules/InterGrid/OGSRadmin.cs b/OpenSim/Region/CoreModules/InterGrid/OGSRadmin.cs
deleted file mode 100644
index 2cc0a07..0000000
--- a/OpenSim/Region/CoreModules/InterGrid/OGSRadmin.cs
+++ /dev/null
@@ -1,150 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Net;
32using System.Reflection;
33using System.Text;
34using log4net;
35using Nini.Config;
36using Nwc.XmlRpc;
37using OpenMetaverse;
38using OpenSim.Framework;
39using OpenSim.Framework.Communications;
40using OpenSim.Framework.Servers;
41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.Framework.Scenes;
43
44namespace OpenSim.Region.CoreModules.InterGrid
45{
46 public class OGSRadmin : IRegionModule
47 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 private readonly List<Scene> m_scenes = new List<Scene>();
50 private IConfigSource m_settings;
51
52 #region Implementation of IRegionModuleBase
53
54 public string Name
55 {
56 get { return "OGS Supporting RAdmin"; }
57 }
58
59
60 public void Initialise(IConfigSource source)
61 {
62 m_settings = source;
63 }
64
65 public void Close()
66 {
67
68 }
69
70 public void AddRegion(Scene scene)
71 {
72 lock (m_scenes)
73 m_scenes.Add(scene);
74 }
75
76 public void RemoveRegion(Scene scene)
77 {
78 lock (m_scenes)
79 m_scenes.Remove(scene);
80 }
81
82 public void RegionLoaded(Scene scene)
83 {
84
85 }
86
87 public void PostInitialise()
88 {
89 if (m_settings.Configs["Startup"].GetBoolean("gridmode", false))
90 {
91 MainServer.Instance.AddXmlRPCHandler("grid_message", GridWideMessage);
92 }
93 }
94
95 #endregion
96
97 #region IRegionModule
98
99 public void Initialise(Scene scene, IConfigSource source)
100 {
101 m_settings = source;
102
103 lock (m_scenes)
104 m_scenes.Add(scene);
105 }
106
107 public bool IsSharedModule
108 {
109 get { return true; }
110 }
111
112 #endregion
113
114 public XmlRpcResponse GridWideMessage(XmlRpcRequest req, IPEndPoint remoteClient)
115 {
116 XmlRpcResponse response = new XmlRpcResponse();
117 Hashtable responseData = new Hashtable();
118
119 Hashtable requestData = (Hashtable)req.Params[0];
120
121 // REFACTORING PROBLEM. This authorization needs to be replaced with some other
122 //if ((!requestData.Contains("password") || (string)requestData["password"] != m_com.NetworkServersInfo.GridRecvKey))
123 //{
124 // responseData["accepted"] = false;
125 // responseData["success"] = false;
126 // responseData["error"] = "Invalid Key";
127 // response.Value = responseData;
128 // return response;
129 //}
130
131 string message = (string)requestData["message"];
132 string user = (string)requestData["user"];
133 m_log.InfoFormat("[RADMIN]: Broadcasting: {0}", message);
134
135 lock (m_scenes)
136 foreach (Scene scene in m_scenes)
137 {
138 IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
139 if (dialogModule != null)
140 dialogModule.SendNotificationToUsersInRegion(UUID.Random(), user, message);
141 }
142
143 responseData["accepted"] = true;
144 responseData["success"] = true;
145 response.Value = responseData;
146
147 return response;
148 }
149 }
150}
diff --git a/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs b/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs
deleted file mode 100644
index 4a76b00..0000000
--- a/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs
+++ /dev/null
@@ -1,1297 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Net;
32using System.Net.Security;
33using System.Reflection;
34using System.Security.Cryptography.X509Certificates;
35using System.Threading;
36using System.Web;
37using log4net;
38using Nini.Config;
39using OpenMetaverse;
40using OpenMetaverse.StructuredData;
41using OpenSim.Framework;
42using OpenSim.Framework.Capabilities;
43using OpenSim.Framework.Monitoring;
44using OpenSim.Framework.Servers;
45using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes;
47using Caps=OpenSim.Framework.Capabilities.Caps;
48using OSDArray=OpenMetaverse.StructuredData.OSDArray;
49using OSDMap=OpenMetaverse.StructuredData.OSDMap;
50
51namespace OpenSim.Region.CoreModules.InterGrid
52{
53 public struct OGPState
54 {
55 public string first_name;
56 public string last_name;
57 public UUID agent_id;
58 public UUID local_agent_id;
59 public UUID region_id;
60 public uint circuit_code;
61 public UUID secure_session_id;
62 public UUID session_id;
63 public bool agent_access;
64 public string sim_access;
65 public uint god_level;
66 public bool god_overide;
67 public bool identified;
68 public bool transacted;
69 public bool age_verified;
70 public bool allow_redirect;
71 public int limited_to_estate;
72 public string inventory_host;
73 public bool src_can_see_mainland;
74 public int src_estate_id;
75 public int src_version;
76 public int src_parent_estate_id;
77 public bool visible_to_parent;
78 public string teleported_into_region;
79 }
80
81 public class OpenGridProtocolModule : IRegionModule
82 {
83 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
84 private List<Scene> m_scene = new List<Scene>();
85
86 private Dictionary<string, AgentCircuitData> CapsLoginID = new Dictionary<string, AgentCircuitData>();
87 private Dictionary<UUID, OGPState> m_OGPState = new Dictionary<UUID, OGPState>();
88 private Dictionary<string, string> m_loginToRegionState = new Dictionary<string, string>();
89
90
91 private string LastNameSuffix = "_EXTERNAL";
92 private string FirstNamePrefix = "";
93 private string httpsCN = "";
94 private bool httpSSL = false;
95 private uint httpsslport = 0;
96// private bool GridMode = false;
97
98 #region IRegionModule Members
99
100 public void Initialise(Scene scene, IConfigSource config)
101 {
102 bool enabled = false;
103 IConfig cfg = null;
104 IConfig httpcfg = null;
105// IConfig startupcfg = null;
106 try
107 {
108 cfg = config.Configs["OpenGridProtocol"];
109 } catch (NullReferenceException)
110 {
111 enabled = false;
112 }
113
114 try
115 {
116 httpcfg = config.Configs["Network"];
117 }
118 catch (NullReferenceException)
119 {
120
121 }
122// try
123// {
124// startupcfg = config.Configs["Startup"];
125// }
126// catch (NullReferenceException)
127// {
128//
129// }
130
131// if (startupcfg != null)
132// {
133// GridMode = enabled = startupcfg.GetBoolean("gridmode", false);
134// }
135
136 if (cfg != null)
137 {
138 enabled = cfg.GetBoolean("ogp_enabled", false);
139 LastNameSuffix = cfg.GetString("ogp_lastname_suffix", "_EXTERNAL");
140 FirstNamePrefix = cfg.GetString("ogp_firstname_prefix", "");
141 if (enabled)
142 {
143 m_log.Warn("[OGP]: Open Grid Protocol is on, Listening for Clients on /agent/");
144 lock (m_scene)
145 {
146 if (m_scene.Count == 0)
147 {
148 MainServer.Instance.AddLLSDHandler("/agent/", ProcessAgentDomainMessage);
149 MainServer.Instance.AddLLSDHandler("/", ProcessRegionDomainSeed);
150 try
151 {
152 ServicePointManager.ServerCertificateValidationCallback += customXertificateValidation;
153 }
154 catch (NotImplementedException)
155 {
156 try
157 {
158#pragma warning disable 0612, 0618
159 // Mono does not implement the ServicePointManager.ServerCertificateValidationCallback yet! Don't remove this!
160 ServicePointManager.CertificatePolicy = new MonoCert();
161#pragma warning restore 0612, 0618
162 }
163 catch (Exception)
164 {
165 m_log.Error("[OGP]: Certificate validation handler change not supported. You may get ssl certificate validation errors teleporting from your region to some SSL regions.");
166 }
167 }
168
169 }
170 // can't pick the region 'agent' because it would conflict with our agent domain handler
171 // a zero length region name would conflict with are base region seed cap
172 if (!SceneListDuplicateCheck(scene.RegionInfo.RegionName) && scene.RegionInfo.RegionName.ToLower() != "agent" && scene.RegionInfo.RegionName.Length > 0)
173 {
174 MainServer.Instance.AddLLSDHandler(
175 "/" + HttpUtility.UrlPathEncode(scene.RegionInfo.RegionName.ToLower()),
176 ProcessRegionDomainSeed);
177 }
178
179 if (!m_scene.Contains(scene))
180 m_scene.Add(scene);
181 }
182 }
183 }
184 lock (m_scene)
185 {
186 if (m_scene.Count == 1)
187 {
188 if (httpcfg != null)
189 {
190 httpSSL = httpcfg.GetBoolean("http_listener_ssl", false);
191 httpsCN = httpcfg.GetString("http_listener_cn", scene.RegionInfo.ExternalHostName);
192 if (httpsCN.Length == 0)
193 httpsCN = scene.RegionInfo.ExternalHostName;
194 httpsslport = (uint)httpcfg.GetInt("http_listener_sslport",((int)scene.RegionInfo.HttpPort + 1));
195 }
196 }
197 }
198 }
199
200 public void PostInitialise()
201 {
202 }
203
204 public void Close()
205 {
206 //scene.EventManager.OnAvatarEnteringNewParcel -= AvatarEnteringParcel;
207 }
208
209 public string Name
210 {
211 get { return "OpenGridProtocolModule"; }
212 }
213
214 public bool IsSharedModule
215 {
216 get { return true; }
217 }
218
219 #endregion
220
221 public OSD ProcessRegionDomainSeed(string path, OSD request, string endpoint)
222 {
223 string[] pathSegments = path.Split('/');
224
225 if (pathSegments.Length <= 1)
226 {
227 return GenerateNoHandlerMessage();
228
229 }
230
231 return GenerateRezAvatarRequestMessage(pathSegments[1]);
232
233
234
235 //m_log.InfoFormat("[OGP]: path {0}, segments {1} segment[1] {2} Last segment {3}",
236 // path, pathSegments.Length, pathSegments[1], pathSegments[pathSegments.Length - 1]);
237 //return new OSDMap();
238
239 }
240
241 public OSD ProcessAgentDomainMessage(string path, OSD request, string endpoint)
242 {
243 // /agent/*
244
245 string[] pathSegments = path.Split('/');
246 if (pathSegments.Length <= 1)
247 {
248 return GenerateNoHandlerMessage();
249
250 }
251 if (pathSegments[0].Length == 0 && pathSegments[1].Length == 0)
252 {
253 return GenerateRezAvatarRequestMessage("");
254 }
255 m_log.InfoFormat("[OGP]: path {0}, segments {1} segment[1] {2} Last segment {3}",
256 path, pathSegments.Length, pathSegments[1], pathSegments[pathSegments.Length - 1]);
257
258 switch (pathSegments[pathSegments.Length - 1])
259 {
260 case "rez_avatar":
261 return RezAvatarMethod(path, request);
262 //break;
263 case "derez_avatar":
264 return DerezAvatarMethod(path, request);
265 //break;
266
267 }
268 if (path.Length < 2)
269 {
270 return GenerateNoHandlerMessage();
271 }
272
273 switch (pathSegments[pathSegments.Length - 2] + "/" + pathSegments[pathSegments.Length - 1])
274 {
275 case "rez_avatar/rez":
276 return RezAvatarMethod(path, request);
277 //break;
278 case "rez_avatar/request":
279 return RequestRezAvatarMethod(path, request);
280 case "rez_avatar/place":
281 return RequestRezAvatarMethod(path, request);
282 case "rez_avatar/derez":
283 return DerezAvatarMethod(path, request);
284 //break;
285 default:
286 return GenerateNoHandlerMessage();
287 }
288 //return null;
289 }
290
291 private OSD GenerateRezAvatarRequestMessage(string regionname)
292 {
293 Scene region = null;
294 bool usedroot = false;
295
296 if (regionname.Length == 0)
297 {
298 region = GetRootScene();
299 usedroot = true;
300 }
301 else
302 {
303 region = GetScene(HttpUtility.UrlDecode(regionname).ToLower());
304 }
305
306 // this shouldn't happen since we don't listen for a region that is down.. but
307 // it might if the region was taken down or is in the middle of restarting
308
309 if (region == null)
310 {
311 region = GetRootScene();
312 usedroot = true;
313 }
314
315 UUID statekeeper = UUID.Random();
316
317
318
319
320 RegionInfo reg = region.RegionInfo;
321
322 OSDMap responseMap = new OSDMap();
323 string rezHttpProtocol = "http://";
324 //string regionCapsHttpProtocol = "http://";
325 string httpaddr = reg.ExternalHostName;
326 string urlport = reg.HttpPort.ToString();
327 string requestpath = "/agent/" + statekeeper + "/rez_avatar/request";
328
329 if (!usedroot)
330 {
331 lock (m_loginToRegionState)
332 {
333 if (!m_loginToRegionState.ContainsKey(requestpath))
334 {
335 m_loginToRegionState.Add(requestpath, region.RegionInfo.RegionName.ToLower());
336 }
337 }
338 }
339
340 if (httpSSL)
341 {
342 rezHttpProtocol = "https://";
343 //regionCapsHttpProtocol = "https://";
344 urlport = httpsslport.ToString();
345
346 if (httpsCN.Length > 0)
347 httpaddr = httpsCN;
348 }
349
350 responseMap["connect"] = OSD.FromBoolean(true);
351 OSDMap capabilitiesMap = new OSDMap();
352 capabilitiesMap["rez_avatar/request"] = OSD.FromString(rezHttpProtocol + httpaddr + ":" + urlport + requestpath);
353 responseMap["capabilities"] = capabilitiesMap;
354
355 return responseMap;
356 }
357
358 // Using OpenSim.Framework.Capabilities.Caps here one time..
359 // so the long name is probably better then a using statement
360 public void OnRegisterCaps(UUID agentID, Caps caps)
361 {
362 /* If we ever want to register our own caps here....
363 *
364 string capsBase = "/CAPS/" + caps.CapsObjectPath;
365 caps.RegisterHandler("CAPNAME",
366 new RestStreamHandler("POST", capsBase + CAPSPOSTFIX!,
367 delegate(string request, string path, string param,
368 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
369 {
370 return METHODHANDLER(request, path, param,
371 agentID, caps);
372 }));
373
374 *
375 */
376 }
377
378 public OSD RequestRezAvatarMethod(string path, OSD request)
379 {
380 //m_log.Debug("[REQUESTREZAVATAR]: " + request.ToString());
381
382 OSDMap requestMap = (OSDMap)request;
383
384
385 Scene homeScene = null;
386
387 lock (m_loginToRegionState)
388 {
389 if (m_loginToRegionState.ContainsKey(path))
390 {
391 homeScene = GetScene(m_loginToRegionState[path]);
392 m_loginToRegionState.Remove(path);
393
394 if (homeScene == null)
395 homeScene = GetRootScene();
396 }
397 else
398 {
399 homeScene = GetRootScene();
400 }
401 }
402
403 // Homescene is still null, we must have no regions that are up
404 if (homeScene == null)
405 return GenerateNoHandlerMessage();
406
407 RegionInfo reg = homeScene.RegionInfo;
408 ulong regionhandle = GetOSCompatibleRegionHandle(reg);
409 //string RegionURI = reg.ServerURI;
410 //int RegionPort = (int)reg.HttpPort;
411
412 UUID RemoteAgentID = requestMap["agent_id"].AsUUID();
413
414 // will be used in the future. The client always connects with the aditi agentid currently
415 UUID LocalAgentID = RemoteAgentID;
416
417 string FirstName = requestMap["first_name"].AsString();
418 string LastName = requestMap["last_name"].AsString();
419
420 FirstName = FirstNamePrefix + FirstName;
421 LastName = LastName + LastNameSuffix;
422
423 OGPState userState = GetOGPState(LocalAgentID);
424
425 userState.first_name = requestMap["first_name"].AsString();
426 userState.last_name = requestMap["last_name"].AsString();
427 userState.age_verified = requestMap["age_verified"].AsBoolean();
428 userState.transacted = requestMap["transacted"].AsBoolean();
429 userState.agent_access = requestMap["agent_access"].AsBoolean();
430 userState.allow_redirect = requestMap["allow_redirect"].AsBoolean();
431 userState.identified = requestMap["identified"].AsBoolean();
432 userState.god_level = (uint)requestMap["god_level"].AsInteger();
433 userState.sim_access = requestMap["sim_access"].AsString();
434 userState.agent_id = RemoteAgentID;
435 userState.limited_to_estate = requestMap["limited_to_estate"].AsInteger();
436 userState.src_can_see_mainland = requestMap["src_can_see_mainland"].AsBoolean();
437 userState.src_estate_id = requestMap["src_estate_id"].AsInteger();
438 userState.local_agent_id = LocalAgentID;
439 userState.teleported_into_region = reg.RegionName.ToLower();
440
441 UpdateOGPState(LocalAgentID, userState);
442
443 OSDMap responseMap = new OSDMap();
444
445 if (RemoteAgentID == UUID.Zero)
446 {
447 responseMap["connect"] = OSD.FromBoolean(false);
448 responseMap["message"] = OSD.FromString("No agent ID was specified in rez_avatar/request");
449 m_log.Error("[OGP]: rez_avatar/request failed because no avatar UUID was provided in the request body");
450 return responseMap;
451 }
452
453 responseMap["sim_host"] = OSD.FromString(reg.ExternalHostName);
454
455 // DEPRECATED
456 responseMap["sim_ip"] = OSD.FromString(Util.GetHostFromDNS(reg.ExternalHostName).ToString());
457
458 responseMap["connect"] = OSD.FromBoolean(true);
459 responseMap["sim_port"] = OSD.FromInteger(reg.InternalEndPoint.Port);
460 responseMap["region_x"] = OSD.FromInteger(reg.RegionLocX * (uint)Constants.RegionSize); // LLX
461 responseMap["region_y"] = OSD.FromInteger(reg.RegionLocY * (uint)Constants.RegionSize); // LLY
462 responseMap["region_id"] = OSD.FromUUID(reg.originRegionID);
463
464 if (reg.RegionSettings.Maturity == 1)
465 {
466 responseMap["sim_access"] = OSD.FromString("Mature");
467 }
468 else if (reg.RegionSettings.Maturity == 2)
469 {
470 responseMap["sim_access"] = OSD.FromString("Adult");
471 }
472 else
473 {
474 responseMap["sim_access"] = OSD.FromString("PG");
475 }
476
477 // Generate a dummy agent for the user so we can get back a CAPS path
478 AgentCircuitData agentData = new AgentCircuitData();
479 agentData.AgentID = LocalAgentID;
480 agentData.BaseFolder = UUID.Zero;
481 agentData.CapsPath = CapsUtil.GetRandomCapsObjectPath();
482 agentData.child = false;
483 agentData.circuitcode = (uint)(Util.RandomClass.Next());
484 agentData.firstname = FirstName;
485 agentData.lastname = LastName;
486 agentData.SecureSessionID = UUID.Random();
487 agentData.SessionID = UUID.Random();
488 agentData.startpos = new Vector3(128f, 128f, 100f);
489
490 // Pre-Fill our region cache with information on the agent.
491 UserAgentData useragent = new UserAgentData();
492 useragent.AgentIP = "unknown";
493 useragent.AgentOnline = true;
494 useragent.AgentPort = (uint)0;
495 useragent.Handle = regionhandle;
496 useragent.InitialRegion = reg.originRegionID;
497 useragent.LoginTime = Util.UnixTimeSinceEpoch();
498 useragent.LogoutTime = 0;
499 useragent.Position = agentData.startpos;
500 useragent.Region = reg.originRegionID;
501 useragent.SecureSessionID = agentData.SecureSessionID;
502 useragent.SessionID = agentData.SessionID;
503
504 UserProfileData userProfile = new UserProfileData();
505 userProfile.AboutText = "OGP User";
506 userProfile.CanDoMask = (uint)0;
507 userProfile.Created = Util.UnixTimeSinceEpoch();
508 userProfile.CurrentAgent = useragent;
509 userProfile.CustomType = "OGP";
510 userProfile.FirstLifeAboutText = "I'm testing OpenGrid Protocol";
511 userProfile.FirstLifeImage = UUID.Zero;
512 userProfile.FirstName = agentData.firstname;
513 userProfile.GodLevel = 0;
514 userProfile.HomeLocation = agentData.startpos;
515 userProfile.HomeLocationX = agentData.startpos.X;
516 userProfile.HomeLocationY = agentData.startpos.Y;
517 userProfile.HomeLocationZ = agentData.startpos.Z;
518 userProfile.HomeLookAt = Vector3.Zero;
519 userProfile.HomeLookAtX = userProfile.HomeLookAt.X;
520 userProfile.HomeLookAtY = userProfile.HomeLookAt.Y;
521 userProfile.HomeLookAtZ = userProfile.HomeLookAt.Z;
522 userProfile.HomeRegion = reg.RegionHandle;
523 userProfile.HomeRegionID = reg.originRegionID;
524 userProfile.HomeRegionX = reg.RegionLocX;
525 userProfile.HomeRegionY = reg.RegionLocY;
526 userProfile.ID = agentData.AgentID;
527 userProfile.Image = UUID.Zero;
528 userProfile.LastLogin = Util.UnixTimeSinceEpoch();
529 userProfile.Partner = UUID.Zero;
530 userProfile.PasswordHash = "$1$";
531 userProfile.PasswordSalt = "";
532 userProfile.SurName = agentData.lastname;
533 //userProfile.UserAssetURI = homeScene.CommsManager.NetworkServersInfo.AssetURL;
534 userProfile.UserFlags = 0;
535 //userProfile.UserInventoryURI = homeScene.CommsManager.NetworkServersInfo.InventoryURL;
536 userProfile.WantDoMask = 0;
537 userProfile.WebLoginKey = UUID.Random();
538
539 // !!! REFACTORING PROBLEM. This needs to be changed for 0.7
540 //
541 //// Do caps registration
542 //// get seed capagentData.firstname = FirstName;agentData.lastname = LastName;
543 //if (homeScene.CommsManager.UserService.GetUserProfile(agentData.AgentID) == null && !GridMode)
544 //{
545 // homeScene.CommsManager.UserAdminService.AddUser(
546 // agentData.firstname, agentData.lastname, CreateRandomStr(7), "",
547 // homeScene.RegionInfo.RegionLocX, homeScene.RegionInfo.RegionLocY, agentData.AgentID);
548
549 // UserProfileData userProfile2 = homeScene.CommsManager.UserService.GetUserProfile(agentData.AgentID);
550 // if (userProfile2 != null)
551 // {
552 // userProfile = userProfile2;
553 // userProfile.AboutText = "OGP USER";
554 // userProfile.FirstLifeAboutText = "OGP USER";
555 // homeScene.CommsManager.UserService.UpdateUserProfile(userProfile);
556 // }
557 //}
558
559 //// Stick our data in the cache so the region will know something about us
560 //homeScene.CommsManager.UserProfileCacheService.PreloadUserCache(userProfile);
561
562 // Call 'new user' event handler
563 string reason;
564 if (!homeScene.NewUserConnection(agentData, (uint)TeleportFlags.ViaLogin, out reason))
565 {
566 responseMap["connect"] = OSD.FromBoolean(false);
567 responseMap["message"] = OSD.FromString(String.Format("Connection refused: {0}", reason));
568 m_log.ErrorFormat("[OGP]: rez_avatar/request failed: {0}", reason);
569 return responseMap;
570 }
571
572
573 //string raCap = string.Empty;
574
575 UUID AvatarRezCapUUID = LocalAgentID;
576 string rezAvatarPath = "/agent/" + AvatarRezCapUUID + "/rez_avatar/rez";
577 string derezAvatarPath = "/agent/" + AvatarRezCapUUID + "/rez_avatar/derez";
578 // Get a reference to the user's cap so we can pull out the Caps Object Path
579 Caps userCap
580 = homeScene.CapsModule.GetCapsForUser(agentData.AgentID);
581
582 string rezHttpProtocol = "http://";
583 string regionCapsHttpProtocol = "http://";
584 string httpaddr = reg.ExternalHostName;
585 string urlport = reg.HttpPort.ToString();
586
587 if (httpSSL)
588 {
589 rezHttpProtocol = "https://";
590 regionCapsHttpProtocol = "https://";
591 urlport = httpsslport.ToString();
592
593 if (httpsCN.Length > 0)
594 httpaddr = httpsCN;
595 }
596
597 // DEPRECATED
598 responseMap["seed_capability"]
599 = OSD.FromString(
600 regionCapsHttpProtocol + httpaddr + ":" + reg.HttpPort + "/" + CapsUtil.GetCapsSeedPath(userCap.CapsObjectPath));
601
602 // REPLACEMENT
603 responseMap["region_seed_capability"]
604 = OSD.FromString(
605 regionCapsHttpProtocol + httpaddr + ":" + reg.HttpPort + "/" + CapsUtil.GetCapsSeedPath(userCap.CapsObjectPath));
606
607 responseMap["rez_avatar"] = OSD.FromString(rezHttpProtocol + httpaddr + ":" + urlport + rezAvatarPath);
608 responseMap["rez_avatar/rez"] = OSD.FromString(rezHttpProtocol + httpaddr + ":" + urlport + rezAvatarPath);
609 responseMap["rez_avatar/derez"] = OSD.FromString(rezHttpProtocol + httpaddr + ":" + urlport + derezAvatarPath);
610
611 // Add the user to the list of CAPS that are outstanding.
612 // well allow the caps hosts in this dictionary
613 lock (CapsLoginID)
614 {
615 if (CapsLoginID.ContainsKey(rezAvatarPath))
616 {
617 CapsLoginID[rezAvatarPath] = agentData;
618
619 // This is a joke, if you didn't notice... It's so unlikely to happen, that I'll print this message if it does occur!
620 m_log.Error("[OGP]: Holy anomoly batman! Caps path already existed! All the UUID Duplication worries were founded!");
621 }
622 else
623 {
624 CapsLoginID.Add(rezAvatarPath, agentData);
625 }
626 }
627
628 //m_log.Debug("Response:" + responseMap.ToString());
629 return responseMap;
630 }
631
632 public OSD RezAvatarMethod(string path, OSD request)
633 {
634 m_log.WarnFormat("[REZAVATAR]: {0}", request.ToString());
635
636 OSDMap responseMap = new OSDMap();
637
638 AgentCircuitData userData = null;
639
640 // Only people we've issued a cap can go further
641 if (TryGetAgentCircuitData(path,out userData))
642 {
643 OSDMap requestMap = (OSDMap)request;
644
645 // take these values to start. There's a few more
646 UUID SecureSessionID=requestMap["secure_session_id"].AsUUID();
647 UUID SessionID = requestMap["session_id"].AsUUID();
648 int circuitcode = requestMap["circuit_code"].AsInteger();
649 OSDArray Parameter = new OSDArray();
650 if (requestMap.ContainsKey("parameter"))
651 {
652 Parameter = (OSDArray)requestMap["parameter"];
653 }
654
655 //int version = 1;
656 int estateID = 1;
657 int parentEstateID = 1;
658 UUID regionID = UUID.Zero;
659 bool visibleToParent = true;
660
661 for (int i = 0; i < Parameter.Count; i++)
662 {
663 OSDMap item = (OSDMap)Parameter[i];
664// if (item.ContainsKey("version"))
665// {
666// version = item["version"].AsInteger();
667// }
668 if (item.ContainsKey("estate_id"))
669 {
670 estateID = item["estate_id"].AsInteger();
671 }
672 if (item.ContainsKey("parent_estate_id"))
673 {
674 parentEstateID = item["parent_estate_id"].AsInteger();
675
676 }
677 if (item.ContainsKey("region_id"))
678 {
679 regionID = item["region_id"].AsUUID();
680
681 }
682 if (item.ContainsKey("visible_to_parent"))
683 {
684 visibleToParent = item["visible_to_parent"].AsBoolean();
685 }
686 }
687 //Update our Circuit data with the real values
688 userData.SecureSessionID = SecureSessionID;
689 userData.SessionID = SessionID;
690
691 OGPState userState = GetOGPState(userData.AgentID);
692
693 // Locate a home scene suitable for the user.
694 Scene homeScene = null;
695
696 homeScene = GetScene(userState.teleported_into_region);
697
698 if (homeScene == null)
699 homeScene = GetRootScene();
700
701 if (homeScene != null)
702 {
703 // Get a referenceokay - to their Cap object so we can pull out the capobjectroot
704 Caps userCap
705 = homeScene.CapsModule.GetCapsForUser(userData.AgentID);
706
707 //Update the circuit data in the region so this user is authorized
708 homeScene.UpdateCircuitData(userData);
709 homeScene.ChangeCircuitCode(userData.circuitcode,(uint)circuitcode);
710
711 // Load state
712
713
714 // Keep state changes
715 userState.first_name = requestMap["first_name"].AsString();
716 userState.secure_session_id = requestMap["secure_session_id"].AsUUID();
717 userState.age_verified = requestMap["age_verified"].AsBoolean();
718 userState.region_id = homeScene.RegionInfo.originRegionID; // replace 0000000 with our regionid
719 userState.transacted = requestMap["transacted"].AsBoolean();
720 userState.agent_access = requestMap["agent_access"].AsBoolean();
721 userState.inventory_host = requestMap["inventory_host"].AsString();
722 userState.identified = requestMap["identified"].AsBoolean();
723 userState.session_id = requestMap["session_id"].AsUUID();
724 userState.god_level = (uint)requestMap["god_level"].AsInteger();
725 userState.last_name = requestMap["last_name"].AsString();
726 userState.god_overide = requestMap["god_override"].AsBoolean();
727 userState.circuit_code = (uint)requestMap["circuit_code"].AsInteger();
728 userState.limited_to_estate = requestMap["limited_to_estate"].AsInteger();
729 userState.src_estate_id = estateID;
730 userState.region_id = regionID;
731 userState.src_parent_estate_id = parentEstateID;
732 userState.visible_to_parent = visibleToParent;
733
734 // Save state changes
735 UpdateOGPState(userData.AgentID, userState);
736
737 // Get the region information for the home region.
738 RegionInfo reg = homeScene.RegionInfo;
739
740 // Dummy positional and look at info.. we don't have it.
741 OSDArray PositionArray = new OSDArray();
742 PositionArray.Add(OSD.FromInteger(128));
743 PositionArray.Add(OSD.FromInteger(128));
744 PositionArray.Add(OSD.FromInteger(40));
745
746 OSDArray LookAtArray = new OSDArray();
747 LookAtArray.Add(OSD.FromInteger(1));
748 LookAtArray.Add(OSD.FromInteger(1));
749 LookAtArray.Add(OSD.FromInteger(1));
750
751 // Our region's X and Y position in OpenSimulator space.
752 uint fooX = reg.RegionLocX;
753 uint fooY = reg.RegionLocY;
754 m_log.InfoFormat("[OGP]: region x({0}) region y({1})", fooX, fooY);
755 m_log.InfoFormat("[OGP]: region http {0} {1}", reg.ServerURI, reg.HttpPort);
756 m_log.InfoFormat("[OGO]: region UUID {0} ", reg.RegionID);
757
758 // Convert the X and Y position to LL space
759 responseMap["region_x"] = OSD.FromInteger(fooX * (uint)Constants.RegionSize); // convert it to LL X
760 responseMap["region_y"] = OSD.FromInteger(fooY * (uint)Constants.RegionSize); // convert it to LL Y
761
762 // Give em a new seed capability
763 responseMap["seed_capability"] = OSD.FromString("http://" + reg.ExternalHostName + ":" + reg.HttpPort + "/CAPS/" + userCap.CapsObjectPath + "0000/");
764 responseMap["region"] = OSD.FromUUID(reg.originRegionID);
765 responseMap["look_at"] = LookAtArray;
766
767 responseMap["sim_port"] = OSD.FromInteger(reg.InternalEndPoint.Port);
768 responseMap["sim_host"] = OSD.FromString(reg.ExternalHostName);// + ":" + reg.InternalEndPoint.Port.ToString());
769
770 // DEPRECATED
771 responseMap["sim_ip"] = OSD.FromString(Util.GetHostFromDNS(reg.ExternalHostName).ToString());
772
773 responseMap["session_id"] = OSD.FromUUID(SessionID);
774 responseMap["secure_session_id"] = OSD.FromUUID(SecureSessionID);
775 responseMap["circuit_code"] = OSD.FromInteger(circuitcode);
776
777 responseMap["position"] = PositionArray;
778
779 responseMap["region_id"] = OSD.FromUUID(reg.originRegionID);
780
781 responseMap["sim_access"] = OSD.FromString("Mature");
782
783 responseMap["connect"] = OSD.FromBoolean(true);
784
785
786
787 m_log.InfoFormat("[OGP]: host: {0}, IP {1}", responseMap["sim_host"].ToString(), responseMap["sim_ip"].ToString());
788 }
789 }
790
791 return responseMap;
792 }
793
794 public OSD DerezAvatarMethod(string path, OSD request)
795 {
796 m_log.ErrorFormat("DerezPath: {0}, Request: {1}", path, request.ToString());
797
798 //LLSD llsdResponse = null;
799 OSDMap responseMap = new OSDMap();
800
801 string[] PathArray = path.Split('/');
802 m_log.InfoFormat("[OGP]: prefix {0}, uuid {1}, suffix {2}", PathArray[1], PathArray[2], PathArray[3]);
803 string uuidString = PathArray[2];
804 m_log.InfoFormat("[OGP]: Request to Derez avatar with UUID {0}", uuidString);
805 UUID userUUID = UUID.Zero;
806 if (UUID.TryParse(uuidString, out userUUID))
807 {
808 UUID RemoteID = (UUID)uuidString;
809 UUID LocalID = RemoteID;
810 // FIXME: TODO: Routine to map RemoteUUIDs to LocalUUIds
811 // would be done already.. but the client connects with the Aditi UUID
812 // regardless over the UDP stack
813
814 OGPState userState = GetOGPState(LocalID);
815 if (userState.agent_id != UUID.Zero)
816 {
817 //OSDMap outboundRequestMap = new OSDMap();
818 OSDMap inboundRequestMap = (OSDMap)request;
819 string rezAvatarString = inboundRequestMap["rez_avatar"].AsString();
820 if (rezAvatarString.Length == 0)
821 {
822 rezAvatarString = inboundRequestMap["rez_avatar/rez"].AsString();
823 }
824 OSDArray LookAtArray = new OSDArray();
825 LookAtArray.Add(OSD.FromInteger(1));
826 LookAtArray.Add(OSD.FromInteger(1));
827 LookAtArray.Add(OSD.FromInteger(1));
828
829 OSDArray PositionArray = new OSDArray();
830 PositionArray.Add(OSD.FromInteger(128));
831 PositionArray.Add(OSD.FromInteger(128));
832 PositionArray.Add(OSD.FromInteger(40));
833
834 OSDArray lookArray = new OSDArray();
835 lookArray.Add(OSD.FromInteger(128));
836 lookArray.Add(OSD.FromInteger(128));
837 lookArray.Add(OSD.FromInteger(40));
838
839 responseMap["connect"] = OSD.FromBoolean(true);// it's okay to give this user up
840 responseMap["look_at"] = LookAtArray;
841
842 m_log.WarnFormat("[OGP]: Invoking rez_avatar on host:{0} for avatar: {1} {2}", rezAvatarString, userState.first_name, userState.last_name);
843
844 OSDMap rezResponseMap = invokeRezAvatarCap(responseMap, rezAvatarString,userState);
845
846 // If invoking it returned an error, parse and end
847 if (rezResponseMap.ContainsKey("connect"))
848 {
849 if (rezResponseMap["connect"].AsBoolean() == false)
850 {
851 return responseMap;
852 }
853 }
854
855 string rezRespSeedCap = "";
856
857 // DEPRECATED
858 if (rezResponseMap.ContainsKey("seed_capability"))
859 rezRespSeedCap = rezResponseMap["seed_capability"].AsString();
860
861 // REPLACEMENT
862 if (rezResponseMap.ContainsKey("region_seed_capability"))
863 rezRespSeedCap = rezResponseMap["region_seed_capability"].AsString();
864
865 // REPLACEMENT
866 if (rezResponseMap.ContainsKey("rez_avatar/rez"))
867 rezRespSeedCap = rezResponseMap["rez_avatar/rez"].AsString();
868
869 // DEPRECATED
870 string rezRespSim_ip = rezResponseMap["sim_ip"].AsString();
871
872 string rezRespSim_host = rezResponseMap["sim_host"].AsString();
873
874 int rrPort = rezResponseMap["sim_port"].AsInteger();
875 int rrX = rezResponseMap["region_x"].AsInteger();
876 int rrY = rezResponseMap["region_y"].AsInteger();
877 m_log.ErrorFormat("X:{0}, Y:{1}", rrX, rrY);
878 UUID rrRID = rezResponseMap["region_id"].AsUUID();
879 OSDArray RezResponsePositionArray = null;
880 string rrAccess = rezResponseMap["sim_access"].AsString();
881 if (rezResponseMap.ContainsKey("position"))
882 {
883 RezResponsePositionArray = (OSDArray)rezResponseMap["position"];
884 }
885 // DEPRECATED
886 responseMap["seed_capability"] = OSD.FromString(rezRespSeedCap);
887
888 // REPLACEMENT r3
889 responseMap["region_seed_capability"] = OSD.FromString(rezRespSeedCap);
890
891 // DEPRECATED
892 responseMap["sim_ip"] = OSD.FromString(Util.GetHostFromDNS(rezRespSim_ip).ToString());
893
894 responseMap["sim_host"] = OSD.FromString(rezRespSim_host);
895 responseMap["sim_port"] = OSD.FromInteger(rrPort);
896 responseMap["region_x"] = OSD.FromInteger(rrX);
897 responseMap["region_y"] = OSD.FromInteger(rrY);
898 responseMap["region_id"] = OSD.FromUUID(rrRID);
899 responseMap["sim_access"] = OSD.FromString(rrAccess);
900
901 if (RezResponsePositionArray != null)
902 {
903 responseMap["position"] = RezResponsePositionArray;
904 }
905 responseMap["look_at"] = lookArray;
906 responseMap["connect"] = OSD.FromBoolean(true);
907
908 ShutdownConnection(LocalID,this);
909 // PLEASE STOP CHANGING THIS TO an M_LOG, M_LOG DOESN'T WORK ON MULTILINE .TOSTRINGS
910 Console.WriteLine("RESPONSEDEREZ: " + responseMap.ToString());
911 return responseMap;
912 }
913 else
914 {
915 return GenerateNoStateMessage(LocalID);
916 }
917 }
918 else
919 {
920 return GenerateNoHandlerMessage();
921 }
922
923 //return responseMap;
924 }
925
926 private OSDMap invokeRezAvatarCap(OSDMap responseMap, string CapAddress, OGPState userState)
927 {
928 Scene reg = GetRootScene();
929
930 WebRequest DeRezRequest = WebRequest.Create(CapAddress);
931 DeRezRequest.Method = "POST";
932 DeRezRequest.ContentType = "application/xml+llsd";
933
934 OSDMap RAMap = new OSDMap();
935 OSDMap AgentParms = new OSDMap();
936 OSDMap RegionParms = new OSDMap();
937
938 OSDArray Parameter = new OSDArray(2);
939
940 OSDMap version = new OSDMap();
941 version["version"] = OSD.FromInteger(userState.src_version);
942 Parameter.Add(version);
943
944 OSDMap SrcData = new OSDMap();
945 SrcData["estate_id"] = OSD.FromInteger(reg.RegionInfo.EstateSettings.EstateID);
946 SrcData["parent_estate_id"] = OSD.FromInteger((reg.RegionInfo.EstateSettings.ParentEstateID == 100 ? 1 : reg.RegionInfo.EstateSettings.ParentEstateID));
947 SrcData["region_id"] = OSD.FromUUID(reg.RegionInfo.originRegionID);
948 SrcData["visible_to_parent"] = OSD.FromBoolean(userState.visible_to_parent);
949 Parameter.Add(SrcData);
950
951 AgentParms["first_name"] = OSD.FromString(userState.first_name);
952 AgentParms["last_name"] = OSD.FromString(userState.last_name);
953 AgentParms["agent_id"] = OSD.FromUUID(userState.agent_id);
954 RegionParms["region_id"] = OSD.FromUUID(userState.region_id);
955 AgentParms["circuit_code"] = OSD.FromInteger(userState.circuit_code);
956 AgentParms["secure_session_id"] = OSD.FromUUID(userState.secure_session_id);
957 AgentParms["session_id"] = OSD.FromUUID(userState.session_id);
958 AgentParms["agent_access"] = OSD.FromBoolean(userState.agent_access);
959 AgentParms["god_level"] = OSD.FromInteger(userState.god_level);
960 AgentParms["god_overide"] = OSD.FromBoolean(userState.god_overide);
961 AgentParms["identified"] = OSD.FromBoolean(userState.identified);
962 AgentParms["transacted"] = OSD.FromBoolean(userState.transacted);
963 AgentParms["age_verified"] = OSD.FromBoolean(userState.age_verified);
964 AgentParms["limited_to_estate"] = OSD.FromInteger(userState.limited_to_estate);
965 AgentParms["inventory_host"] = OSD.FromString(userState.inventory_host);
966
967 // version 1
968 RAMap = AgentParms;
969
970 // Planned for version 2
971 // RAMap["agent_params"] = AgentParms;
972
973 RAMap["region_params"] = RegionParms;
974 RAMap["parameter"] = Parameter;
975
976 string RAMapString = RAMap.ToString();
977 m_log.InfoFormat("[OGP] RAMap string {0}", RAMapString);
978 OSD LLSDofRAMap = RAMap; // RENAME if this works
979
980 m_log.InfoFormat("[OGP]: LLSD of map as string was {0}", LLSDofRAMap.ToString());
981 //m_log.InfoFormat("[OGP]: LLSD+XML: {0}", LLSDParser.SerializeXmlString(LLSDofRAMap));
982 byte[] buffer = OSDParser.SerializeLLSDXmlBytes(LLSDofRAMap);
983
984 //string bufferDump = System.Text.Encoding.ASCII.GetString(buffer);
985 //m_log.InfoFormat("[OGP]: buffer form is {0}",bufferDump);
986 //m_log.InfoFormat("[OGP]: LLSD of map was {0}",buffer.Length);
987
988 Stream os = null;
989 try
990 { // send the Post
991 DeRezRequest.ContentLength = buffer.Length; //Count bytes to send
992 os = DeRezRequest.GetRequestStream();
993 os.Write(buffer, 0, buffer.Length); //Send it
994 os.Close();
995 m_log.InfoFormat("[OGP]: Derez Avatar Posted Rez Avatar request to remote sim {0}", CapAddress);
996 }
997 catch (WebException ex)
998 {
999 m_log.InfoFormat("[OGP] Bad send on de_rez_avatar {0}", ex.Message);
1000 responseMap["connect"] = OSD.FromBoolean(false);
1001
1002 return responseMap;
1003 }
1004
1005 m_log.Info("[OGP] waiting for a reply after rez avatar send");
1006 string rez_avatar_reply = null;
1007 { // get the response
1008 try
1009 {
1010 WebResponse webResponse = DeRezRequest.GetResponse();
1011 if (webResponse == null)
1012 {
1013 m_log.Info("[OGP:] Null reply on rez_avatar post");
1014 }
1015
1016 StreamReader sr = new StreamReader(webResponse.GetResponseStream());
1017 rez_avatar_reply = sr.ReadToEnd().Trim();
1018 m_log.InfoFormat("[OGP]: rez_avatar reply was {0} ", rez_avatar_reply);
1019
1020 }
1021 catch (WebException ex)
1022 {
1023 m_log.InfoFormat("[OGP]: exception on read after send of rez avatar {0}", ex.Message);
1024 responseMap["connect"] = OSD.FromBoolean(false);
1025
1026 return responseMap;
1027 }
1028 OSD rezResponse = null;
1029 try
1030 {
1031 rezResponse = OSDParser.DeserializeLLSDXml(rez_avatar_reply);
1032
1033 responseMap = (OSDMap)rezResponse;
1034 }
1035 catch (Exception ex)
1036 {
1037 m_log.InfoFormat("[OGP]: exception on parse of rez reply {0}", ex.Message);
1038 responseMap["connect"] = OSD.FromBoolean(false);
1039
1040 return responseMap;
1041 }
1042 }
1043 return responseMap;
1044 }
1045
1046 public OSD GenerateNoHandlerMessage()
1047 {
1048 OSDMap map = new OSDMap();
1049 map["reason"] = OSD.FromString("LLSDRequest");
1050 map["message"] = OSD.FromString("No handler registered for LLSD Requests");
1051 map["login"] = OSD.FromString("false");
1052 map["connect"] = OSD.FromString("false");
1053 return map;
1054 }
1055 public OSD GenerateNoStateMessage(UUID passedAvatar)
1056 {
1057 OSDMap map = new OSDMap();
1058 map["reason"] = OSD.FromString("derez failed");
1059 map["message"] = OSD.FromString("Unable to locate OGP state for avatar " + passedAvatar.ToString());
1060 map["login"] = OSD.FromString("false");
1061 map["connect"] = OSD.FromString("false");
1062 return map;
1063 }
1064 private bool TryGetAgentCircuitData(string path, out AgentCircuitData userdata)
1065 {
1066 userdata = null;
1067 lock (CapsLoginID)
1068 {
1069 if (CapsLoginID.ContainsKey(path))
1070 {
1071 userdata = CapsLoginID[path];
1072 DiscardUsedCap(path);
1073 return true;
1074 }
1075 }
1076 return false;
1077 }
1078
1079 private void DiscardUsedCap(string path)
1080 {
1081 CapsLoginID.Remove(path);
1082 }
1083
1084 private Scene GetRootScene()
1085 {
1086 Scene ReturnScene = null;
1087 lock (m_scene)
1088 {
1089 if (m_scene.Count > 0)
1090 {
1091 ReturnScene = m_scene[0];
1092 }
1093 }
1094
1095 return ReturnScene;
1096 }
1097
1098 private Scene GetScene(string scenename)
1099 {
1100 Scene ReturnScene = null;
1101 lock (m_scene)
1102 {
1103 foreach (Scene s in m_scene)
1104 {
1105 if (s.RegionInfo.RegionName.ToLower() == scenename)
1106 {
1107 ReturnScene = s;
1108 break;
1109 }
1110 }
1111 }
1112
1113 return ReturnScene;
1114 }
1115
1116 private ulong GetOSCompatibleRegionHandle(RegionInfo reg)
1117 {
1118 return Util.UIntsToLong(reg.RegionLocX, reg.RegionLocY);
1119 }
1120
1121 private OGPState InitializeNewState()
1122 {
1123 OGPState returnState = new OGPState();
1124 returnState.first_name = "";
1125 returnState.last_name = "";
1126 returnState.agent_id = UUID.Zero;
1127 returnState.local_agent_id = UUID.Zero;
1128 returnState.region_id = UUID.Zero;
1129 returnState.circuit_code = 0;
1130 returnState.secure_session_id = UUID.Zero;
1131 returnState.session_id = UUID.Zero;
1132 returnState.agent_access = true;
1133 returnState.god_level = 0;
1134 returnState.god_overide = false;
1135 returnState.identified = false;
1136 returnState.transacted = false;
1137 returnState.age_verified = false;
1138 returnState.limited_to_estate = 1;
1139 returnState.inventory_host = "http://inv4.mysql.aditi.lindenlab.com";
1140 returnState.allow_redirect = true;
1141 returnState.sim_access = "";
1142 returnState.src_can_see_mainland = true;
1143 returnState.src_estate_id = 1;
1144 returnState.src_version = 1;
1145 returnState.src_parent_estate_id = 1;
1146 returnState.visible_to_parent = true;
1147 returnState.teleported_into_region = "";
1148
1149 return returnState;
1150 }
1151
1152 private OGPState GetOGPState(UUID agentId)
1153 {
1154 lock (m_OGPState)
1155 {
1156 if (m_OGPState.ContainsKey(agentId))
1157 {
1158 return m_OGPState[agentId];
1159 }
1160 else
1161 {
1162 return InitializeNewState();
1163 }
1164 }
1165 }
1166
1167 public void DeleteOGPState(UUID agentId)
1168 {
1169 lock (m_OGPState)
1170 {
1171 if (m_OGPState.ContainsKey(agentId))
1172 m_OGPState.Remove(agentId);
1173 }
1174 }
1175
1176 private void UpdateOGPState(UUID agentId, OGPState state)
1177 {
1178 lock (m_OGPState)
1179 {
1180 if (m_OGPState.ContainsKey(agentId))
1181 {
1182 m_OGPState[agentId] = state;
1183 }
1184 else
1185 {
1186 m_OGPState.Add(agentId,state);
1187 }
1188 }
1189 }
1190 private bool SceneListDuplicateCheck(string str)
1191 {
1192 // no lock, called from locked space!
1193 bool found = false;
1194
1195 foreach (Scene s in m_scene)
1196 {
1197 if (s.RegionInfo.RegionName == str)
1198 {
1199 found = true;
1200 break;
1201 }
1202 }
1203
1204 return found;
1205 }
1206
1207 public void ShutdownConnection(UUID avatarId, OpenGridProtocolModule mod)
1208 {
1209 Scene homeScene = GetRootScene();
1210 ScenePresence avatar = null;
1211 if (homeScene.TryGetScenePresence(avatarId,out avatar))
1212 {
1213 KillAUser ku = new KillAUser(avatar,mod);
1214 Watchdog.StartThread(ku.ShutdownNoLogout, "OGPShutdown", ThreadPriority.Normal, true, true);
1215 }
1216 }
1217
1218// private string CreateRandomStr(int len)
1219// {
1220// Random rnd = new Random(Environment.TickCount);
1221// string returnstring = "";
1222// string chars = "abcdefghijklmnopqrstuvwxyz0123456789";
1223//
1224// for (int i = 0; i < len; i++)
1225// {
1226// returnstring += chars.Substring(rnd.Next(chars.Length), 1);
1227// }
1228// return returnstring;
1229// }
1230
1231 // Temporary hack to allow teleporting to and from Vaak
1232 private static bool customXertificateValidation(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
1233 {
1234 //if (cert.Subject == "E=root@lindenlab.com, CN=*.vaak.lindenlab.com, O=\"Linden Lab, Inc.\", L=San Francisco, S=California, C=US")
1235 //{
1236 return true;
1237 //}
1238
1239 //return false;
1240 }
1241 }
1242
1243 public class KillAUser
1244 {
1245 private ScenePresence avToBeKilled = null;
1246 private OpenGridProtocolModule m_mod = null;
1247
1248 public KillAUser(ScenePresence avatar, OpenGridProtocolModule mod)
1249 {
1250 avToBeKilled = avatar;
1251 m_mod = mod;
1252 }
1253
1254 public void ShutdownNoLogout()
1255 {
1256 UUID avUUID = UUID.Zero;
1257
1258 if (avToBeKilled != null)
1259 {
1260 avUUID = avToBeKilled.UUID;
1261 avToBeKilled.MakeChildAgent();
1262
1263 avToBeKilled.ControllingClient.SendLogoutPacketWhenClosing = false;
1264
1265 int sleepMS = 30000;
1266 while (sleepMS > 0)
1267 {
1268 Watchdog.UpdateThread();
1269 Thread.Sleep(1000);
1270 sleepMS -= 1000;
1271 }
1272
1273 // test for child agent because they might have come back
1274 if (avToBeKilled.IsChildAgent)
1275 {
1276 m_mod.DeleteOGPState(avUUID);
1277 avToBeKilled.ControllingClient.Close();
1278 }
1279 }
1280
1281 Watchdog.RemoveThread();
1282 }
1283
1284 }
1285
1286 public class MonoCert : ICertificatePolicy
1287 {
1288 #region ICertificatePolicy Members
1289
1290 public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem)
1291 {
1292 return true;
1293 }
1294
1295 #endregion
1296 }
1297}
diff --git a/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs b/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..5a8c4a2
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs
@@ -0,0 +1,38 @@
1using System.Reflection;
2using System.Runtime.CompilerServices;
3using System.Runtime.InteropServices;
4using Mono.Addins;
5
6// General Information about an assembly is controlled through the following
7// set of attributes. Change these attribute values to modify the information
8// associated with an assembly.
9[assembly: AssemblyTitle("OpenSim.Region.CoreModules")]
10[assembly: AssemblyDescription("Core modules for OpenSim")]
11[assembly: AssemblyConfiguration("")]
12[assembly: AssemblyCompany("")]
13[assembly: AssemblyProduct("OpenSim.Region.CoreModules.Properties")]
14[assembly: AssemblyCopyright("Copyright © 2012")]
15[assembly: AssemblyTrademark("")]
16[assembly: AssemblyCulture("")]
17
18// Setting ComVisible to false makes the types in this assembly not visible
19// to COM components. If you need to access a type in this assembly from
20// COM, set the ComVisible attribute to true on that type.
21[assembly: ComVisible(false)]
22
23// The following GUID is for the ID of the typelib if this project is exposed to COM
24[assembly: Guid("94f62dd1-bcf3-4218-9844-9a3996286e3e")]
25
26// Version information for an assembly consists of the following four values:
27//
28// Major Version
29// Minor Version
30// Build Number
31// Revision
32//
33[assembly: AssemblyVersion("0.7.5.*")]
34[assembly: AssemblyFileVersion("1.0.0.0")]
35
36[assembly: Addin("OpenSim.Region.CoreModules", "0.1")]
37[assembly: AddinDependency("OpenSim", "0.5")]
38
diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
deleted file mode 100644
index 424e0ab..0000000
--- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
+++ /dev/null
@@ -1,90 +0,0 @@
1<Addin id="OpenSim.Region.CoreModules" version="0.3">
2 <Runtime>
3 <Import assembly="OpenSim.Region.CoreModules.dll"/>
4 </Runtime>
5
6 <Dependencies>
7 <Addin id="OpenSim" version="0.5" />
8 </Dependencies>
9
10 <Extension path = "/OpenSim/RegionModules">
11 <RegionModule id="UserManagementModule" type="OpenSim.Region.CoreModules.Framework.UserManagement.UserManagementModule" />
12 <RegionModule id="HGUserManagementModule" type="OpenSim.Region.CoreModules.Framework.UserManagement.HGUserManagementModule" />
13 <RegionModule id="EntityTransferModule" type="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule" />
14 <RegionModule id="HGEntityTransferModule" type="OpenSim.Region.CoreModules.Framework.EntityTransfer.HGEntityTransferModule" />
15 <RegionModule id="InventoryAccessModule" type="OpenSim.Region.CoreModules.Framework.InventoryAccess.BasicInventoryAccessModule" />
16 <RegionModule id="HGInventoryAccessModule" type="OpenSim.Region.CoreModules.Framework.InventoryAccess.HGInventoryAccessModule" />
17 <RegionModule id="LandManagementModule" type="OpenSim.Region.CoreModules.World.Land.LandManagementModule" />
18 <RegionModule id="PrimCountModule" type="OpenSim.Region.CoreModules.World.Land.PrimCountModule" />
19 <RegionModule id="ExportSerialisationModule" type="OpenSim.Region.CoreModules.World.Serialiser.SerialiserModule" />
20 <RegionModule id="ArchiverModule" type="OpenSim.Region.CoreModules.World.Archiver.ArchiverModule" />
21 <RegionModule id="TerrainModule" type="OpenSim.Region.CoreModules.World.Terrain.TerrainModule" />
22 <RegionModule id="WorldMapModule" type="OpenSim.Region.CoreModules.World.WorldMap.WorldMapModule" />
23 <RegionModule id="Warp3DImageModule" type="OpenSim.Region.CoreModules.World.Warp3DMap.Warp3DImageModule" />
24 <RegionModule id="HGWorldMapModule" type="OpenSim.Region.CoreModules.Hypergrid.HGWorldMapModule" />
25 <RegionModule id="UrlModule" type="OpenSim.Region.CoreModules.Scripting.LSLHttp.UrlModule" />
26 <RegionModule id="Chat" type="OpenSim.Region.CoreModules.Avatar.Chat.ChatModule" />
27 <RegionModule id="FriendsModule" type="OpenSim.Region.CoreModules.Avatar.Friends.FriendsModule" />
28 <RegionModule id="HGFriendsModule" type="OpenSim.Region.CoreModules.Avatar.Friends.HGFriendsModule" />
29 <RegionModule id="PresenceModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.PresenceModule" />
30 <RegionModule id="MuteListModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.MuteListModule" />
31 <RegionModule id="OfflineMessageModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.OfflineMessageModule" />
32 <RegionModule id="InstantMessageModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.InstantMessageModule" />
33 <RegionModule id="MessageTransferModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.MessageTransferModule" />
34 <RegionModule id="LureModule" type="OpenSim.Region.CoreModules.Avatar.Lure.LureModule" />
35 <RegionModule id="InventoryTransferModule" type="OpenSim.Region.CoreModules.Avatar.Inventory.Transfer.InventoryTransferModule" />
36 <RegionModule id="CoreAssetCache" type="OpenSim.Region.CoreModules.Asset.CoreAssetCache" />
37 <RegionModule id="GlynnTuckerAssetCache" type="OpenSim.Region.CoreModules.Asset.GlynnTuckerAssetCache" />
38 <RegionModule id="CenomeMemoryAssetCache" type="OpenSim.Region.CoreModules.Asset.CenomeMemoryAssetCache"/>
39 <RegionModule id="LibraryModule" type="OpenSim.Region.CoreModules.Framework.Library.LibraryModule"/>
40 <!-- Service connectors OUT modules -->
41 <RegionModule id="LocalAssetServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset.LocalAssetServicesConnector" />
42 <RegionModule id="RemoteAssetServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset.RemoteAssetServicesConnector" />
43 <RegionModule id="LocalAvatarServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar.LocalAvatarServicesConnector" />
44 <RegionModule id="RemoteAvatarServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar.RemoteAvatarServicesConnector" />
45 <RegionModule id="LocalAuthenticationServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Authentication.LocalAuthenticationServicesConnector" />
46 <RegionModule id="RemoteAuthenticationServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Authentication.RemoteAuthenticationServicesConnector" />
47 <RegionModule id="LocalAuthorizationServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization.LocalAuthorizationServicesConnector" />
48 <RegionModule id="RemoteAuthorizationServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization.RemoteAuthorizationServicesConnector" />
49 <RegionModule id="HGAssetBroker" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset.HGAssetBroker" />
50 <RegionModule id="LocalInventoryServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.LocalInventoryServicesConnector" />
51 <RegionModule id="RemoteXInventoryServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.RemoteXInventoryServicesConnector" />
52 <RegionModule id="HGInventoryBroker" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.HGInventoryBroker" />
53 <RegionModule id="LocalNeighbourServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour.LocalNeighbourServicesConnector" />
54 <RegionModule id="RemoteNeighbourServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour.RemoteNeighbourServicesConnector" />
55 <RegionModule id="LocalLandServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Land.LocalLandServicesConnector" />
56 <RegionModule id="RemoteLandServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Land.RemoteLandServicesConnector" />
57 <RegionModule id="LocalGridServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.LocalGridServicesConnector" />
58 <RegionModule id="RemoteGridServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.RemoteGridServicesConnector" />
59 <RegionModule id="LocalPresenceServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence.LocalPresenceServicesConnector" />
60 <RegionModule id="RemotePresenceServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence.RemotePresenceServicesConnector" />
61 <RegionModule id="LocalUserAccountServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts.LocalUserAccountServicesConnector" />
62 <RegionModule id="RemoteUserAccountServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts.RemoteUserAccountServicesConnector" />
63
64 <RegionModule id="LocalGridUserServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser.LocalGridUserServicesConnector" />
65 <RegionModule id="RemoteGridUserServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser.RemoteGridUserServicesConnector" />
66
67 <RegionModule id="LocalSimulationConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation.LocalSimulationConnectorModule" />
68 <RegionModule id="RemoteSimulationConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation.RemoteSimulationConnectorModule" />
69
70 <!-- Service connectors IN modules -->
71 <RegionModule id="AssetServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Asset.AssetServiceInConnectorModule" />
72 <RegionModule id="InventoryServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Inventory.InventoryServiceInConnectorModule" />
73 <RegionModule id="LandServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Land.LandServiceInConnectorModule" />
74 <RegionModule id="NeighbourServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Neighbour.NeighbourServiceInConnectorModule" /> \
75 <RegionModule id="HypergridServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid.HypergridServiceInConnectorModule" /> \
76 <RegionModule id="LLLoginServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Login.LLLoginServiceInConnectorModule" /> \
77 <RegionModule id="SimulationServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Simulation.SimulationServiceInConnectorModule" /> \
78 <RegionModule id="GridInfoServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Grid.GridInfoServiceInConnectorModule" /> \
79 <RegionModule id="AuthenticationServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Authentication.AuthenticationServiceInConnectorModule" />
80 <RegionModule id="AccessModule" type="OpenSim.Region.CoreModules.World.AccessModule" /> \
81 <RegionModule id="MapImageModule" type="OpenSim.Region.CoreModules.World.LegacyMap.MapImageModule" /> \
82
83 </Extension>
84
85 <Extension path = "/OpenSim/WindModule">
86 <WindModel id="ConfigurableWind" type="OpenSim.Region.CoreModules.World.Wind.Plugins.ConfigurableWind" />
87 <WindModel id="SimpleRandomWind" type="OpenSim.Region.CoreModules.World.Wind.Plugins.SimpleRandomWind" />
88 </Extension>
89
90</Addin>
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGUuidGatherer.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs
index fcb544f..fce9490 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGUuidGatherer.cs
+++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs
@@ -26,32 +26,36 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Drawing;
30using OpenSim.Region.Framework.Interfaces;
30 31
31using OpenSim.Framework; 32namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
32using OpenSim.Region.Framework.Scenes;
33using OpenSim.Services.Interfaces;
34using OpenMetaverse;
35
36namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
37{ 33{
38 public class HGUuidGatherer : UuidGatherer 34 public class DynamicTexture : IDynamicTexture
39 { 35 {
40 protected string m_assetServerURL; 36 public string InputCommands { get; private set; }
41 protected HGAssetMapper m_assetMapper; 37 public Uri InputUri { get; private set; }
38 public string InputParams { get; private set; }
39 public byte[] Data { get; private set; }
40 public Size Size { get; private set; }
41 public bool IsReuseable { get; private set; }
42 42
43 public HGUuidGatherer(HGAssetMapper assMap, IAssetService assetCache, string assetServerURL) : base(assetCache) 43 public DynamicTexture(string inputCommands, string inputParams, byte[] data, Size size, bool isReuseable)
44 { 44 {
45 m_assetMapper = assMap; 45 InputCommands = inputCommands;
46 m_assetServerURL = assetServerURL; 46 InputParams = inputParams;
47 Data = data;
48 Size = size;
49 IsReuseable = isReuseable;
47 } 50 }
48 51
49 protected override AssetBase GetAsset(UUID uuid) 52 public DynamicTexture(Uri inputUri, string inputParams, byte[] data, Size size, bool isReuseable)
50 { 53 {
51 if (string.Empty == m_assetServerURL) 54 InputUri = inputUri;
52 return m_assetCache.Get(uuid.ToString()); 55 InputParams = inputParams;
53 else 56 Data = data;
54 return m_assetMapper.FetchAsset(m_assetServerURL, uuid); 57 Size = size;
58 IsReuseable = isReuseable;
55 } 59 }
56 } 60 }
57} 61} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
index 18bd018..9d77b19 100644
--- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
@@ -37,18 +37,36 @@ using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using log4net; 38using log4net;
39using System.Reflection; 39using System.Reflection;
40using Mono.Addins;
40 41
41namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture 42namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
42{ 43{
43 public class DynamicTextureModule : IRegionModule, IDynamicTextureManager 44 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DynamicTextureModule")]
45 public class DynamicTextureModule : ISharedRegionModule, IDynamicTextureManager
44 { 46 {
45 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 48
47 private const int ALL_SIDES = -1; 49 private const int ALL_SIDES = -1;
48 50
49 public const int DISP_EXPIRE = 1; 51 public const int DISP_EXPIRE = 1;
50 public const int DISP_TEMP = 2; 52 public const int DISP_TEMP = 2;
51 53
54 /// <summary>
55 /// If true then where possible dynamic textures are reused.
56 /// </summary>
57 public bool ReuseTextures { get; set; }
58
59 /// <summary>
60 /// If false, then textures which have a low data size are not reused when ReuseTextures = true.
61 /// </summary>
62 /// <remarks>
63 /// LL viewers 3.3.4 and before appear to not fully render textures pulled from the viewer cache if those
64 /// textures have a relatively high pixel surface but a small data size. Typically, this appears to happen
65 /// if the data size is smaller than the viewer's discard level 2 size estimate. So if this is setting is
66 /// false, textures smaller than the calculation in IsSizeReuseable are always regenerated rather than reused
67 /// to work around this problem.</remarks>
68 public bool ReuseLowDataTextures { get; set; }
69
52 private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>(); 70 private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>();
53 71
54 private Dictionary<string, IDynamicTextureRender> RenderPlugins = 72 private Dictionary<string, IDynamicTextureRender> RenderPlugins =
@@ -56,6 +74,25 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
56 74
57 private Dictionary<UUID, DynamicTextureUpdater> Updaters = new Dictionary<UUID, DynamicTextureUpdater>(); 75 private Dictionary<UUID, DynamicTextureUpdater> Updaters = new Dictionary<UUID, DynamicTextureUpdater>();
58 76
77 /// <summary>
78 /// Record dynamic textures that we can reuse for a given data and parameter combination rather than
79 /// regenerate.
80 /// </summary>
81 /// <remarks>
82 /// Key is string.Format("{0}{1}", data
83 /// </remarks>
84 private Cache m_reuseableDynamicTextures;
85
86 /// <summary>
87 /// This constructor is only here because of the Unit Tests...
88 /// Don't use it.
89 /// </summary>
90 public DynamicTextureModule()
91 {
92 m_reuseableDynamicTextures = new Cache(CacheMedium.Memory, CacheStrategy.Conservative);
93 m_reuseableDynamicTextures.DefaultTTL = new TimeSpan(24, 0, 0);
94 }
95
59 #region IDynamicTextureManager Members 96 #region IDynamicTextureManager Members
60 97
61 public void RegisterRender(string handleType, IDynamicTextureRender render) 98 public void RegisterRender(string handleType, IDynamicTextureRender render)
@@ -69,17 +106,17 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
69 /// <summary> 106 /// <summary>
70 /// Called by code which actually renders the dynamic texture to supply texture data. 107 /// Called by code which actually renders the dynamic texture to supply texture data.
71 /// </summary> 108 /// </summary>
72 /// <param name="id"></param> 109 /// <param name="updaterId"></param>
73 /// <param name="data"></param> 110 /// <param name="texture"></param>
74 public void ReturnData(UUID id, byte[] data) 111 public void ReturnData(UUID updaterId, IDynamicTexture texture)
75 { 112 {
76 DynamicTextureUpdater updater = null; 113 DynamicTextureUpdater updater = null;
77 114
78 lock (Updaters) 115 lock (Updaters)
79 { 116 {
80 if (Updaters.ContainsKey(id)) 117 if (Updaters.ContainsKey(updaterId))
81 { 118 {
82 updater = Updaters[id]; 119 updater = Updaters[updaterId];
83 } 120 }
84 } 121 }
85 122
@@ -88,7 +125,16 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
88 if (RegisteredScenes.ContainsKey(updater.SimUUID)) 125 if (RegisteredScenes.ContainsKey(updater.SimUUID))
89 { 126 {
90 Scene scene = RegisteredScenes[updater.SimUUID]; 127 Scene scene = RegisteredScenes[updater.SimUUID];
91 updater.DataReceived(data, scene); 128 UUID newTextureID = updater.DataReceived(texture.Data, scene);
129
130 if (ReuseTextures
131 && !updater.BlendWithOldTexture
132 && texture.IsReuseable
133 && (ReuseLowDataTextures || IsDataSizeReuseable(texture)))
134 {
135 m_reuseableDynamicTextures.Store(
136 GenerateReusableTextureKey(texture.InputCommands, texture.InputParams), newTextureID);
137 }
92 } 138 }
93 } 139 }
94 140
@@ -104,6 +150,27 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
104 } 150 }
105 } 151 }
106 152
153 /// <summary>
154 /// Determines whether the texture is reuseable based on its data size.
155 /// </summary>
156 /// <remarks>
157 /// This is a workaround for a viewer bug where very small data size textures relative to their pixel size
158 /// are not redisplayed properly when pulled from cache. The calculation here is based on the typical discard
159 /// level of 2, a 'rate' of 0.125 and 4 components (which makes for a factor of 0.5).
160 /// </remarks>
161 /// <returns></returns>
162 private bool IsDataSizeReuseable(IDynamicTexture texture)
163 {
164// Console.WriteLine("{0} {1}", texture.Size.Width, texture.Size.Height);
165 int discardLevel2DataThreshold = (int)Math.Ceiling((texture.Size.Width >> 2) * (texture.Size.Height >> 2) * 0.5);
166
167// m_log.DebugFormat(
168// "[DYNAMIC TEXTURE MODULE]: Discard level 2 threshold {0}, texture data length {1}",
169// discardLevel2DataThreshold, texture.Data.Length);
170
171 return discardLevel2DataThreshold < texture.Data.Length;
172 }
173
107 public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, 174 public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url,
108 string extraParams, int updateTimer) 175 string extraParams, int updateTimer)
109 { 176 {
@@ -167,22 +234,61 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
167 public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, 234 public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data,
168 string extraParams, int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face) 235 string extraParams, int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face)
169 { 236 {
170 if (RenderPlugins.ContainsKey(contentType)) 237 if (!RenderPlugins.ContainsKey(contentType))
238 return UUID.Zero;
239
240 Scene scene;
241 RegisteredScenes.TryGetValue(simID, out scene);
242
243 if (scene == null)
244 return UUID.Zero;
245
246 SceneObjectPart part = scene.GetSceneObjectPart(primID);
247
248 if (part == null)
249 return UUID.Zero;
250
251 // If we want to reuse dynamic textures then we have to ignore any request from the caller to expire
252 // them.
253 if (ReuseTextures)
254 disp = disp & ~DISP_EXPIRE;
255
256 DynamicTextureUpdater updater = new DynamicTextureUpdater();
257 updater.SimUUID = simID;
258 updater.PrimID = primID;
259 updater.ContentType = contentType;
260 updater.BodyData = data;
261 updater.UpdateTimer = updateTimer;
262 updater.UpdaterID = UUID.Random();
263 updater.Params = extraParams;
264 updater.BlendWithOldTexture = SetBlending;
265 updater.FrontAlpha = AlphaValue;
266 updater.Face = face;
267 updater.Url = "Local image";
268 updater.Disp = disp;
269
270 object objReusableTextureUUID = null;
271
272 if (ReuseTextures && !updater.BlendWithOldTexture)
171 { 273 {
172 DynamicTextureUpdater updater = new DynamicTextureUpdater(); 274 string reuseableTextureKey = GenerateReusableTextureKey(data, extraParams);
173 updater.SimUUID = simID; 275 objReusableTextureUUID = m_reuseableDynamicTextures.Get(reuseableTextureKey);
174 updater.PrimID = primID;
175 updater.ContentType = contentType;
176 updater.BodyData = data;
177 updater.UpdateTimer = updateTimer;
178 updater.UpdaterID = UUID.Random();
179 updater.Params = extraParams;
180 updater.BlendWithOldTexture = SetBlending;
181 updater.FrontAlpha = AlphaValue;
182 updater.Face = face;
183 updater.Url = "Local image";
184 updater.Disp = disp;
185 276
277 if (objReusableTextureUUID != null)
278 {
279 // If something else has removed this temporary asset from the cache, detect and invalidate
280 // our cached uuid.
281 if (scene.AssetService.GetMetadata(objReusableTextureUUID.ToString()) == null)
282 {
283 m_reuseableDynamicTextures.Invalidate(reuseableTextureKey);
284 objReusableTextureUUID = null;
285 }
286 }
287 }
288
289 // We cannot reuse a dynamic texture if the data is going to be blended with something already there.
290 if (objReusableTextureUUID == null)
291 {
186 lock (Updaters) 292 lock (Updaters)
187 { 293 {
188 if (!Updaters.ContainsKey(updater.UpdaterID)) 294 if (!Updaters.ContainsKey(updater.UpdaterID))
@@ -191,11 +297,29 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
191 } 297 }
192 } 298 }
193 299
300// m_log.DebugFormat(
301// "[DYNAMIC TEXTURE MODULE]: Requesting generation of new dynamic texture for {0} in {1}",
302// part.Name, part.ParentGroup.Scene.Name);
303
194 RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams); 304 RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams);
195 return updater.UpdaterID;
196 } 305 }
197 306 else
198 return UUID.Zero; 307 {
308// m_log.DebugFormat(
309// "[DYNAMIC TEXTURE MODULE]: Reusing cached texture {0} for {1} in {2}",
310// objReusableTextureUUID, part.Name, part.ParentGroup.Scene.Name);
311
312 // No need to add to updaters as the texture is always the same. Not that this functionality
313 // apppears to be implemented anyway.
314 updater.UpdatePart(part, (UUID)objReusableTextureUUID);
315 }
316
317 return updater.UpdaterID;
318 }
319
320 private string GenerateReusableTextureKey(string data, string extraParams)
321 {
322 return string.Format("{0}{1}", data, extraParams);
199 } 323 }
200 324
201 public void GetDrawStringSize(string contentType, string text, string fontName, int fontSize, 325 public void GetDrawStringSize(string contentType, string text, string fontName, int fontSize,
@@ -211,9 +335,29 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
211 335
212 #endregion 336 #endregion
213 337
214 #region IRegionModule Members 338 #region ISharedRegionModule Members
215 339
216 public void Initialise(Scene scene, IConfigSource config) 340 public void Initialise(IConfigSource config)
341 {
342 IConfig texturesConfig = config.Configs["Textures"];
343 if (texturesConfig != null)
344 {
345 ReuseTextures = texturesConfig.GetBoolean("ReuseDynamicTextures", false);
346 ReuseLowDataTextures = texturesConfig.GetBoolean("ReuseDynamicLowDataTextures", false);
347
348 if (ReuseTextures)
349 {
350 m_reuseableDynamicTextures = new Cache(CacheMedium.Memory, CacheStrategy.Conservative);
351 m_reuseableDynamicTextures.DefaultTTL = new TimeSpan(24, 0, 0);
352 }
353 }
354 }
355
356 public void PostInitialise()
357 {
358 }
359
360 public void AddRegion(Scene scene)
217 { 361 {
218 if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) 362 if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
219 { 363 {
@@ -222,8 +366,14 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
222 } 366 }
223 } 367 }
224 368
225 public void PostInitialise() 369 public void RegionLoaded(Scene scene)
370 {
371 }
372
373 public void RemoveRegion(Scene scene)
226 { 374 {
375 if (RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
376 RegisteredScenes.Remove(scene.RegionInfo.RegionID);
227 } 377 }
228 378
229 public void Close() 379 public void Close()
@@ -235,9 +385,9 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
235 get { return "DynamicTextureModule"; } 385 get { return "DynamicTextureModule"; }
236 } 386 }
237 387
238 public bool IsSharedModule 388 public Type ReplaceableInterface
239 { 389 {
240 get { return true; } 390 get { return null; }
241 } 391 }
242 392
243 #endregion 393 #endregion
@@ -269,9 +419,60 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
269 } 419 }
270 420
271 /// <summary> 421 /// <summary>
422 /// Update the given part with the new texture.
423 /// </summary>
424 /// <returns>
425 /// The old texture UUID.
426 /// </returns>
427 public UUID UpdatePart(SceneObjectPart part, UUID textureID)
428 {
429 UUID oldID;
430
431 lock (part)
432 {
433 // mostly keep the values from before
434 Primitive.TextureEntry tmptex = part.Shape.Textures;
435
436 // FIXME: Need to return the appropriate ID if only a single face is replaced.
437 oldID = tmptex.DefaultTexture.TextureID;
438
439 if (Face == ALL_SIDES)
440 {
441 oldID = tmptex.DefaultTexture.TextureID;
442 tmptex.DefaultTexture.TextureID = textureID;
443 }
444 else
445 {
446 try
447 {
448 Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face);
449 texface.TextureID = textureID;
450 tmptex.FaceTextures[Face] = texface;
451 }
452 catch (Exception)
453 {
454 tmptex.DefaultTexture.TextureID = textureID;
455 }
456 }
457
458 // I'm pretty sure we always want to force this to true
459 // I'm pretty sure noone whats to set fullbright true if it wasn't true before.
460 // tmptex.DefaultTexture.Fullbright = true;
461
462 part.UpdateTextureEntry(tmptex.GetBytes());
463 }
464
465 return oldID;
466 }
467
468 /// <summary>
272 /// Called once new texture data has been received for this updater. 469 /// Called once new texture data has been received for this updater.
273 /// </summary> 470 /// </summary>
274 public void DataReceived(byte[] data, Scene scene) 471 /// <param name="data"></param>
472 /// <param name="scene"></param>
473 /// <param name="isReuseable">True if the data given is reuseable.</param>
474 /// <returns>The asset UUID given to the incoming data.</returns>
475 public UUID DataReceived(byte[] data, Scene scene)
275 { 476 {
276 SceneObjectPart part = scene.GetSceneObjectPart(PrimID); 477 SceneObjectPart part = scene.GetSceneObjectPart(PrimID);
277 478
@@ -281,7 +482,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
281 String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url); 482 String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url);
282 scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say, 483 scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say,
283 0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false); 484 0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false);
284 return; 485
486 return UUID.Zero;
285 } 487 }
286 488
287 byte[] assetData = null; 489 byte[] assetData = null;
@@ -319,56 +521,29 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
319 IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface<IJ2KDecoder>(); 521 IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface<IJ2KDecoder>();
320 if (cacheLayerDecode != null) 522 if (cacheLayerDecode != null)
321 { 523 {
322 cacheLayerDecode.Decode(asset.FullID, asset.Data); 524 if (!cacheLayerDecode.Decode(asset.FullID, asset.Data))
323 cacheLayerDecode = null; 525 m_log.WarnFormat(
526 "[DYNAMIC TEXTURE MODULE]: Decoding of dynamically generated asset {0} for {1} in {2} failed",
527 asset.ID, part.Name, part.ParentGroup.Scene.Name);
324 } 528 }
325 529
326 UUID oldID = UUID.Zero; 530 UUID oldID = UpdatePart(part, asset.FullID);
327
328 lock (part)
329 {
330 // mostly keep the values from before
331 Primitive.TextureEntry tmptex = part.Shape.Textures;
332
333 // remove the old asset from the cache
334 oldID = tmptex.DefaultTexture.TextureID;
335
336 if (Face == ALL_SIDES)
337 {
338 tmptex.DefaultTexture.TextureID = asset.FullID;
339 }
340 else
341 {
342 try
343 {
344 Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face);
345 texface.TextureID = asset.FullID;
346 tmptex.FaceTextures[Face] = texface;
347 }
348 catch (Exception)
349 {
350 tmptex.DefaultTexture.TextureID = asset.FullID;
351 }
352 }
353
354 // I'm pretty sure we always want to force this to true
355 // I'm pretty sure noone whats to set fullbright true if it wasn't true before.
356 // tmptex.DefaultTexture.Fullbright = true;
357
358 part.UpdateTextureEntry(tmptex.GetBytes());
359 }
360 531
361 if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0)) 532 if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0))
362 { 533 {
363 if (oldAsset == null) oldAsset = scene.AssetService.Get(oldID.ToString()); 534 if (oldAsset == null)
535 oldAsset = scene.AssetService.Get(oldID.ToString());
536
364 if (oldAsset != null) 537 if (oldAsset != null)
365 { 538 {
366 if (oldAsset.Temporary == true) 539 if (oldAsset.Temporary)
367 { 540 {
368 scene.AssetService.Delete(oldID.ToString()); 541 scene.AssetService.Delete(oldID.ToString());
369 } 542 }
370 } 543 }
371 } 544 }
545
546 return asset.FullID;
372 } 547 }
373 548
374 private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha) 549 private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha)
diff --git a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs
index e91e8b9..d943b20 100644
--- a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs
@@ -37,10 +37,12 @@ using OpenMetaverse;
37using OpenSim.Framework; 37using OpenSim.Framework;
38using OpenSim.Region.Framework.Interfaces; 38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
40using Mono.Addins;
40 41
41namespace OpenSim.Region.CoreModules.Scripting.EmailModules 42namespace OpenSim.Region.CoreModules.Scripting.EmailModules
42{ 43{
43 public class EmailModule : IRegionModule, IEmailModule 44 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EmailModule")]
45 public class EmailModule : ISharedRegionModule, IEmailModule
44 { 46 {
45 // 47 //
46 // Log 48 // Log
@@ -72,31 +74,9 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
72 74
73 private bool m_Enabled = false; 75 private bool m_Enabled = false;
74 76
75 public void InsertEmail(UUID to, Email email) 77 #region ISharedRegionModule
76 {
77 // It's tempting to create the queue here. Don't; objects which have
78 // not yet called GetNextEmail should have no queue, and emails to them
79 // should be silently dropped.
80
81 lock (m_MailQueues)
82 {
83 if (m_MailQueues.ContainsKey(to))
84 {
85 if (m_MailQueues[to].Count >= m_MaxQueueSize)
86 {
87 // fail silently
88 return;
89 }
90
91 lock (m_MailQueues[to])
92 {
93 m_MailQueues[to].Add(email);
94 }
95 }
96 }
97 }
98 78
99 public void Initialise(Scene scene, IConfigSource config) 79 public void Initialise(IConfigSource config)
100 { 80 {
101 m_Config = config; 81 m_Config = config;
102 IConfig SMTPConfig; 82 IConfig SMTPConfig;
@@ -129,36 +109,44 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
129 SMTP_SERVER_PORT = SMTPConfig.GetInt("SMTP_SERVER_PORT", SMTP_SERVER_PORT); 109 SMTP_SERVER_PORT = SMTPConfig.GetInt("SMTP_SERVER_PORT", SMTP_SERVER_PORT);
130 SMTP_SERVER_LOGIN = SMTPConfig.GetString("SMTP_SERVER_LOGIN", SMTP_SERVER_LOGIN); 110 SMTP_SERVER_LOGIN = SMTPConfig.GetString("SMTP_SERVER_LOGIN", SMTP_SERVER_LOGIN);
131 SMTP_SERVER_PASSWORD = SMTPConfig.GetString("SMTP_SERVER_PASSWORD", SMTP_SERVER_PASSWORD); 111 SMTP_SERVER_PASSWORD = SMTPConfig.GetString("SMTP_SERVER_PASSWORD", SMTP_SERVER_PASSWORD);
132 m_MaxEmailSize = SMTPConfig.GetInt("email_max_size", m_MaxEmailSize); 112 m_MaxEmailSize = SMTPConfig.GetInt("email_max_size", m_MaxEmailSize);
133 } 113 }
134 catch (Exception e) 114 catch (Exception e)
135 { 115 {
136 m_log.Error("[EMAIL] DefaultEmailModule not configured: "+ e.Message); 116 m_log.Error("[EMAIL] DefaultEmailModule not configured: " + e.Message);
137 m_Enabled = false; 117 m_Enabled = false;
138 return; 118 return;
139 } 119 }
140 120
141 // It's a go! 121 }
142 if (m_Enabled) 122
123 public void AddRegion(Scene scene)
124 {
125 if (!m_Enabled)
126 return;
127
128 // It's a go!
129 lock (m_Scenes)
143 { 130 {
144 lock (m_Scenes) 131 // Claim the interface slot
145 { 132 scene.RegisterModuleInterface<IEmailModule>(this);
146 // Claim the interface slot
147 scene.RegisterModuleInterface<IEmailModule>(this);
148 133
149 // Add to scene list 134 // Add to scene list
150 if (m_Scenes.ContainsKey(scene.RegionInfo.RegionHandle)) 135 if (m_Scenes.ContainsKey(scene.RegionInfo.RegionHandle))
151 { 136 {
152 m_Scenes[scene.RegionInfo.RegionHandle] = scene; 137 m_Scenes[scene.RegionInfo.RegionHandle] = scene;
153 } 138 }
154 else 139 else
155 { 140 {
156 m_Scenes.Add(scene.RegionInfo.RegionHandle, scene); 141 m_Scenes.Add(scene.RegionInfo.RegionHandle, scene);
157 }
158 } 142 }
159
160 m_log.Info("[EMAIL] Activated DefaultEmailModule");
161 } 143 }
144
145 m_log.Info("[EMAIL] Activated DefaultEmailModule");
146 }
147
148 public void RemoveRegion(Scene scene)
149 {
162 } 150 }
163 151
164 public void PostInitialise() 152 public void PostInitialise()
@@ -174,9 +162,39 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules
174 get { return "DefaultEmailModule"; } 162 get { return "DefaultEmailModule"; }
175 } 163 }
176 164
177 public bool IsSharedModule 165 public Type ReplaceableInterface
166 {
167 get { return null; }
168 }
169
170 public void RegionLoaded(Scene scene)
178 { 171 {
179 get { return true; } 172 }
173
174 #endregion
175
176 public void InsertEmail(UUID to, Email email)
177 {
178 // It's tempting to create the queue here. Don't; objects which have
179 // not yet called GetNextEmail should have no queue, and emails to them
180 // should be silently dropped.
181
182 lock (m_MailQueues)
183 {
184 if (m_MailQueues.ContainsKey(to))
185 {
186 if (m_MailQueues[to].Count >= m_MaxQueueSize)
187 {
188 // fail silently
189 return;
190 }
191
192 lock (m_MailQueues[to])
193 {
194 m_MailQueues[to].Add(email);
195 }
196 }
197 }
180 } 198 }
181 199
182 private bool IsLocal(UUID objectID) 200 private bool IsLocal(UUID objectID)
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
index 9dac6b9..a0ae203 100644
--- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
@@ -41,6 +41,7 @@ using OpenSim.Framework.Servers;
41using OpenSim.Framework.Servers.HttpServer; 41using OpenSim.Framework.Servers.HttpServer;
42using OpenSim.Region.Framework.Interfaces; 42using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.Framework.Scenes; 43using OpenSim.Region.Framework.Scenes;
44using Mono.Addins;
44 45
45/***************************************************** 46/*****************************************************
46 * 47 *
@@ -87,7 +88,8 @@ using OpenSim.Region.Framework.Scenes;
87 88
88namespace OpenSim.Region.CoreModules.Scripting.HttpRequest 89namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
89{ 90{
90 public class HttpRequestModule : IRegionModule, IHttpRequestModule 91 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "HttpRequestModule")]
92 public class HttpRequestModule : ISharedRegionModule, IHttpRequestModule
91 { 93 {
92 private object HttpListLock = new object(); 94 private object HttpListLock = new object();
93 private int httpTimeout = 30000; 95 private int httpTimeout = 30000;
@@ -270,24 +272,38 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
270 272
271 #endregion 273 #endregion
272 274
273 #region IRegionModule Members 275 #region ISharedRegionModule Members
274 276
275 public void Initialise(Scene scene, IConfigSource config) 277 public void Initialise(IConfigSource config)
276 { 278 {
277 m_scene = scene;
278
279 m_scene.RegisterModuleInterface<IHttpRequestModule>(this);
280
281 m_proxyurl = config.Configs["Startup"].GetString("HttpProxy"); 279 m_proxyurl = config.Configs["Startup"].GetString("HttpProxy");
282 m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions"); 280 m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions");
283 281
284 m_pendingRequests = new Dictionary<UUID, HttpRequestClass>(); 282 m_pendingRequests = new Dictionary<UUID, HttpRequestClass>();
285 } 283 }
286 284
285 public void AddRegion(Scene scene)
286 {
287 m_scene = scene;
288
289 m_scene.RegisterModuleInterface<IHttpRequestModule>(this);
290 }
291
292 public void RemoveRegion(Scene scene)
293 {
294 scene.UnregisterModuleInterface<IHttpRequestModule>(this);
295 if (scene == m_scene)
296 m_scene = null;
297 }
298
287 public void PostInitialise() 299 public void PostInitialise()
288 { 300 {
289 } 301 }
290 302
303 public void RegionLoaded(Scene scene)
304 {
305 }
306
291 public void Close() 307 public void Close()
292 { 308 {
293 } 309 }
@@ -297,9 +313,9 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
297 get { return m_name; } 313 get { return m_name; }
298 } 314 }
299 315
300 public bool IsSharedModule 316 public Type ReplaceableInterface
301 { 317 {
302 get { return true; } 318 get { return null; }
303 } 319 }
304 320
305 #endregion 321 #endregion
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
index 56221aa..da59eab 100644
--- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
@@ -31,6 +31,7 @@ using System.Collections.Generic;
31using System.Collections; 31using System.Collections;
32using System.Reflection; 32using System.Reflection;
33using log4net; 33using log4net;
34using Mono.Addins;
34using Nini.Config; 35using Nini.Config;
35using OpenMetaverse; 36using OpenMetaverse;
36using OpenSim.Framework; 37using OpenSim.Framework;
@@ -58,6 +59,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
58 public string body; 59 public string body;
59 public int responseCode; 60 public int responseCode;
60 public string responseBody; 61 public string responseBody;
62 public string responseType = "text/plain";
61 //public ManualResetEvent ev; 63 //public ManualResetEvent ev;
62 public bool requestDone; 64 public bool requestDone;
63 public int startTime; 65 public int startTime;
@@ -65,6 +67,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
65 public string uri; 67 public string uri;
66 } 68 }
67 69
70 /// <summary>
71 /// This module provides external URLs for in-world scripts.
72 /// </summary>
73 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UrlModule")]
68 public class UrlModule : ISharedRegionModule, IUrlModule 74 public class UrlModule : ISharedRegionModule, IUrlModule
69 { 75 {
70 private static readonly ILog m_log = 76 private static readonly ILog m_log =
@@ -270,6 +276,22 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
270 } 276 }
271 } 277 }
272 278
279 public void HttpContentType(UUID request, string type)
280 {
281 lock (m_UrlMap)
282 {
283 if (m_RequestMap.ContainsKey(request))
284 {
285 UrlData urlData = m_RequestMap[request];
286 urlData.requests[request].responseType = type;
287 }
288 else
289 {
290 m_log.Info("[HttpRequestHandler] There is no http-in request with id " + request.ToString());
291 }
292 }
293 }
294
273 public void HttpResponse(UUID request, int status, string body) 295 public void HttpResponse(UUID request, int status, string body)
274 { 296 {
275 lock (m_RequestMap) 297 lock (m_RequestMap)
diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
index 6f83948..65737fa 100644
--- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
@@ -32,14 +32,17 @@ using System.Net;
32using Nini.Config; 32using Nini.Config;
33using OpenMetaverse; 33using OpenMetaverse;
34using OpenMetaverse.Imaging; 34using OpenMetaverse.Imaging;
35using OpenSim.Region.CoreModules.Scripting.DynamicTexture;
35using OpenSim.Region.Framework.Interfaces; 36using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
37using log4net; 38using log4net;
38using System.Reflection; 39using System.Reflection;
40using Mono.Addins;
39 41
40namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL 42namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
41{ 43{
42 public class LoadImageURLModule : IRegionModule, IDynamicTextureRender 44 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LoadImageURLModule")]
45 public class LoadImageURLModule : ISharedRegionModule, IDynamicTextureRender
43 { 46 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 48
@@ -67,12 +70,18 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
67 return true; 70 return true;
68 } 71 }
69 72
70 public byte[] ConvertUrl(string url, string extraParams) 73// public bool AlwaysIdenticalConversion(string bodyData, string extraParams)
74// {
75// // We don't support conversion of body data.
76// return false;
77// }
78
79 public IDynamicTexture ConvertUrl(string url, string extraParams)
71 { 80 {
72 return null; 81 return null;
73 } 82 }
74 83
75 public byte[] ConvertStream(Stream data, string extraParams) 84 public IDynamicTexture ConvertData(string bodyData, string extraParams)
76 { 85 {
77 return null; 86 return null;
78 } 87 }
@@ -97,22 +106,32 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
97 106
98 #endregion 107 #endregion
99 108
100 #region IRegionModule Members 109 #region ISharedRegionModule Members
101 110
102 public void Initialise(Scene scene, IConfigSource config) 111 public void Initialise(IConfigSource config)
103 { 112 {
104 if (m_scene == null)
105 {
106 m_scene = scene;
107 }
108
109 m_proxyurl = config.Configs["Startup"].GetString("HttpProxy"); 113 m_proxyurl = config.Configs["Startup"].GetString("HttpProxy");
110 m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions"); 114 m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions");
111 } 115 }
112 116
113 public void PostInitialise() 117 public void PostInitialise()
114 { 118 {
115 if (m_scene != null) 119 }
120
121 public void AddRegion(Scene scene)
122 {
123 if (m_scene == null)
124 m_scene = scene;
125
126 }
127
128 public void RemoveRegion(Scene scene)
129 {
130 }
131
132 public void RegionLoaded(Scene scene)
133 {
134 if (m_textureManager == null && m_scene == scene)
116 { 135 {
117 m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>(); 136 m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>();
118 if (m_textureManager != null) 137 if (m_textureManager != null)
@@ -131,9 +150,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
131 get { return m_name; } 150 get { return m_name; }
132 } 151 }
133 152
134 public bool IsSharedModule 153 public Type ReplaceableInterface
135 { 154 {
136 get { return true; } 155 get { return null; }
137 } 156 }
138 157
139 #endregion 158 #endregion
@@ -165,11 +184,17 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
165 184
166 private void HttpRequestReturn(IAsyncResult result) 185 private void HttpRequestReturn(IAsyncResult result)
167 { 186 {
187 if (m_textureManager == null)
188 {
189 m_log.WarnFormat("[LOADIMAGEURLMODULE]: No texture manager. Can't function.");
190 return;
191 }
168 192
169 RequestState state = (RequestState) result.AsyncState; 193 RequestState state = (RequestState) result.AsyncState;
170 WebRequest request = (WebRequest) state.Request; 194 WebRequest request = (WebRequest) state.Request;
171 Stream stream = null; 195 Stream stream = null;
172 byte[] imageJ2000 = new byte[0]; 196 byte[] imageJ2000 = new byte[0];
197 Size newSize = new Size(0, 0);
173 198
174 try 199 try
175 { 200 {
@@ -182,37 +207,43 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
182 try 207 try
183 { 208 {
184 Bitmap image = new Bitmap(stream); 209 Bitmap image = new Bitmap(stream);
185 Size newsize;
186 210
187 // TODO: make this a bit less hard coded 211 // TODO: make this a bit less hard coded
188 if ((image.Height < 64) && (image.Width < 64)) 212 if ((image.Height < 64) && (image.Width < 64))
189 { 213 {
190 newsize = new Size(32, 32); 214 newSize.Width = 32;
215 newSize.Height = 32;
191 } 216 }
192 else if ((image.Height < 128) && (image.Width < 128)) 217 else if ((image.Height < 128) && (image.Width < 128))
193 { 218 {
194 newsize = new Size(64, 64); 219 newSize.Width = 64;
220 newSize.Height = 64;
195 } 221 }
196 else if ((image.Height < 256) && (image.Width < 256)) 222 else if ((image.Height < 256) && (image.Width < 256))
197 { 223 {
198 newsize = new Size(128, 128); 224 newSize.Width = 128;
225 newSize.Height = 128;
199 } 226 }
200 else if ((image.Height < 512 && image.Width < 512)) 227 else if ((image.Height < 512 && image.Width < 512))
201 { 228 {
202 newsize = new Size(256, 256); 229 newSize.Width = 256;
230 newSize.Height = 256;
203 } 231 }
204 else if ((image.Height < 1024 && image.Width < 1024)) 232 else if ((image.Height < 1024 && image.Width < 1024))
205 { 233 {
206 newsize = new Size(512, 512); 234 newSize.Width = 512;
235 newSize.Height = 512;
207 } 236 }
208 else 237 else
209 { 238 {
210 newsize = new Size(1024, 1024); 239 newSize.Width = 1024;
240 newSize.Height = 1024;
211 } 241 }
212 242
213 Bitmap resize = new Bitmap(image, newsize); 243 using (Bitmap resize = new Bitmap(image, newSize))
214 244 {
215 imageJ2000 = OpenJPEG.EncodeFromImage(resize, true); 245 imageJ2000 = OpenJPEG.EncodeFromImage(resize, true);
246 }
216 } 247 }
217 catch (Exception) 248 catch (Exception)
218 { 249 {
@@ -227,7 +258,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
227 } 258 }
228 catch (WebException) 259 catch (WebException)
229 { 260 {
230
231 } 261 }
232 finally 262 finally
233 { 263 {
@@ -236,9 +266,14 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
236 stream.Close(); 266 stream.Close();
237 } 267 }
238 } 268 }
239 m_log.DebugFormat("[LOADIMAGEURLMODULE] Returning {0} bytes of image data for request {1}", 269
270 m_log.DebugFormat("[LOADIMAGEURLMODULE]: Returning {0} bytes of image data for request {1}",
240 imageJ2000.Length, state.RequestID); 271 imageJ2000.Length, state.RequestID);
241 m_textureManager.ReturnData(state.RequestID, imageJ2000); 272
273 m_textureManager.ReturnData(
274 state.RequestID,
275 new OpenSim.Region.CoreModules.Scripting.DynamicTexture.DynamicTexture(
276 request.RequestUri, null, imageJ2000, newSize, false));
242 } 277 }
243 278
244 #region Nested type: RequestState 279 #region Nested type: RequestState
diff --git a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
new file mode 100644
index 0000000..f6e1d39
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
@@ -0,0 +1,383 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using System.Collections.Generic;
31using Nini.Config;
32using log4net;
33using OpenSim.Framework;
34using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Region.Framework.Scenes;
36using Mono.Addins;
37using OpenMetaverse;
38using System.Linq;
39using System.Linq.Expressions;
40
41namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms
42{
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ScriptModuleCommsModule")]
44 class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms
45 {
46 private static readonly ILog m_log =
47 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48
49 private Dictionary<string,object> m_constants = new Dictionary<string,object>();
50
51#region ScriptInvocation
52 protected class ScriptInvocationData
53 {
54 public Delegate ScriptInvocationDelegate { get; private set; }
55 public string FunctionName { get; private set; }
56 public Type[] TypeSignature { get; private set; }
57 public Type ReturnType { get; private set; }
58
59 public ScriptInvocationData(string fname, Delegate fn, Type[] callsig, Type returnsig)
60 {
61 FunctionName = fname;
62 ScriptInvocationDelegate = fn;
63 TypeSignature = callsig;
64 ReturnType = returnsig;
65 }
66 }
67
68 private Dictionary<string,ScriptInvocationData> m_scriptInvocation = new Dictionary<string,ScriptInvocationData>();
69#endregion
70
71 private IScriptModule m_scriptModule = null;
72 public event ScriptCommand OnScriptCommand;
73
74#region RegionModuleInterface
75 public void Initialise(IConfigSource config)
76 {
77 }
78
79 public void AddRegion(Scene scene)
80 {
81 scene.RegisterModuleInterface<IScriptModuleComms>(this);
82 }
83
84 public void RemoveRegion(Scene scene)
85 {
86 }
87
88 public void RegionLoaded(Scene scene)
89 {
90 m_scriptModule = scene.RequestModuleInterface<IScriptModule>();
91
92 if (m_scriptModule != null)
93 m_log.Info("[MODULE COMMANDS]: Script engine found, module active");
94 }
95
96 public string Name
97 {
98 get { return "ScriptModuleCommsModule"; }
99 }
100
101 public Type ReplaceableInterface
102 {
103 get { return null; }
104 }
105
106 public void Close()
107 {
108 }
109#endregion
110
111#region ScriptModuleComms
112
113 public void RaiseEvent(UUID script, string id, string module, string command, string k)
114 {
115 ScriptCommand c = OnScriptCommand;
116
117 if (c == null)
118 return;
119
120 c(script, id, module, command, k);
121 }
122
123 public void DispatchReply(UUID script, int code, string text, string k)
124 {
125 if (m_scriptModule == null)
126 return;
127
128 Object[] args = new Object[] {-1, code, text, k};
129
130 m_scriptModule.PostScriptEvent(script, "link_message", args);
131 }
132
133 private static MethodInfo GetMethodInfoFromType(Type target, string meth, bool searchInstanceMethods)
134 {
135 BindingFlags getMethodFlags =
136 BindingFlags.NonPublic | BindingFlags.Public;
137
138 if (searchInstanceMethods)
139 getMethodFlags |= BindingFlags.Instance;
140 else
141 getMethodFlags |= BindingFlags.Static;
142
143 return target.GetMethod(meth, getMethodFlags);
144 }
145
146 public void RegisterScriptInvocation(object target, string meth)
147 {
148 MethodInfo mi = GetMethodInfoFromType(target.GetType(), meth, true);
149 if (mi == null)
150 {
151 m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}", meth);
152 return;
153 }
154
155 RegisterScriptInvocation(target, mi);
156 }
157
158 public void RegisterScriptInvocation(object target, string[] meth)
159 {
160 foreach (string m in meth)
161 RegisterScriptInvocation(target, m);
162 }
163
164 public void RegisterScriptInvocation(object target, MethodInfo mi)
165 {
166 m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, (target is Type) ? ((Type)target).Name : target.GetType().Name);
167
168 Type delegateType;
169 List<Type> typeArgs = mi.GetParameters()
170 .Select(p => p.ParameterType)
171 .ToList();
172
173 if (mi.ReturnType == typeof(void))
174 {
175 delegateType = Expression.GetActionType(typeArgs.ToArray());
176 }
177 else
178 {
179 typeArgs.Add(mi.ReturnType);
180 delegateType = Expression.GetFuncType(typeArgs.ToArray());
181 }
182
183 Delegate fcall;
184 if (!(target is Type))
185 fcall = Delegate.CreateDelegate(delegateType, target, mi);
186 else
187 fcall = Delegate.CreateDelegate(delegateType, (Type)target, mi.Name);
188
189 lock (m_scriptInvocation)
190 {
191 ParameterInfo[] parameters = fcall.Method.GetParameters();
192 if (parameters.Length < 2) // Must have two UUID params
193 return;
194
195 // Hide the first two parameters
196 Type[] parmTypes = new Type[parameters.Length - 2];
197 for (int i = 2; i < parameters.Length; i++)
198 parmTypes[i - 2] = parameters[i].ParameterType;
199 m_scriptInvocation[fcall.Method.Name] = new ScriptInvocationData(fcall.Method.Name, fcall, parmTypes, fcall.Method.ReturnType);
200 }
201 }
202
203 public void RegisterScriptInvocation(Type target, string[] methods)
204 {
205 foreach (string method in methods)
206 {
207 MethodInfo mi = GetMethodInfoFromType(target, method, false);
208 if (mi == null)
209 m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}", method);
210 else
211 RegisterScriptInvocation(target, mi);
212 }
213 }
214
215 public void RegisterScriptInvocations(IRegionModuleBase target)
216 {
217 foreach(MethodInfo method in target.GetType().GetMethods(
218 BindingFlags.Public | BindingFlags.Instance |
219 BindingFlags.Static))
220 {
221 if(method.GetCustomAttributes(
222 typeof(ScriptInvocationAttribute), true).Any())
223 {
224 if(method.IsStatic)
225 RegisterScriptInvocation(target.GetType(), method);
226 else
227 RegisterScriptInvocation(target, method);
228 }
229 }
230 }
231
232 public Delegate[] GetScriptInvocationList()
233 {
234 List<Delegate> ret = new List<Delegate>();
235
236 lock (m_scriptInvocation)
237 {
238 foreach (ScriptInvocationData d in m_scriptInvocation.Values)
239 ret.Add(d.ScriptInvocationDelegate);
240 }
241 return ret.ToArray();
242 }
243
244 public string LookupModInvocation(string fname)
245 {
246 lock (m_scriptInvocation)
247 {
248 ScriptInvocationData sid;
249 if (m_scriptInvocation.TryGetValue(fname,out sid))
250 {
251 if (sid.ReturnType == typeof(string))
252 return "modInvokeS";
253 else if (sid.ReturnType == typeof(int))
254 return "modInvokeI";
255 else if (sid.ReturnType == typeof(float))
256 return "modInvokeF";
257 else if (sid.ReturnType == typeof(UUID))
258 return "modInvokeK";
259 else if (sid.ReturnType == typeof(OpenMetaverse.Vector3))
260 return "modInvokeV";
261 else if (sid.ReturnType == typeof(OpenMetaverse.Quaternion))
262 return "modInvokeR";
263 else if (sid.ReturnType == typeof(object[]))
264 return "modInvokeL";
265
266 m_log.WarnFormat("[MODULE COMMANDS] failed to find match for {0} with return type {1}",fname,sid.ReturnType.Name);
267 }
268 }
269
270 return null;
271 }
272
273 public Delegate LookupScriptInvocation(string fname)
274 {
275 lock (m_scriptInvocation)
276 {
277 ScriptInvocationData sid;
278 if (m_scriptInvocation.TryGetValue(fname,out sid))
279 return sid.ScriptInvocationDelegate;
280 }
281
282 return null;
283 }
284
285 public Type[] LookupTypeSignature(string fname)
286 {
287 lock (m_scriptInvocation)
288 {
289 ScriptInvocationData sid;
290 if (m_scriptInvocation.TryGetValue(fname,out sid))
291 return sid.TypeSignature;
292 }
293
294 return null;
295 }
296
297 public Type LookupReturnType(string fname)
298 {
299 lock (m_scriptInvocation)
300 {
301 ScriptInvocationData sid;
302 if (m_scriptInvocation.TryGetValue(fname,out sid))
303 return sid.ReturnType;
304 }
305
306 return null;
307 }
308
309 public object InvokeOperation(UUID hostid, UUID scriptid, string fname, params object[] parms)
310 {
311 List<object> olist = new List<object>();
312 olist.Add(hostid);
313 olist.Add(scriptid);
314 foreach (object o in parms)
315 olist.Add(o);
316 Delegate fn = LookupScriptInvocation(fname);
317 return fn.DynamicInvoke(olist.ToArray());
318 }
319
320 /// <summary>
321 /// Operation to for a region module to register a constant to be used
322 /// by the script engine
323 /// </summary>
324 public void RegisterConstant(string cname, object value)
325 {
326 m_log.DebugFormat("[MODULE COMMANDS] register constant <{0}> with value {1}",cname,value.ToString());
327 lock (m_constants)
328 {
329 m_constants.Add(cname,value);
330 }
331 }
332
333 public void RegisterConstants(IRegionModuleBase target)
334 {
335 foreach (FieldInfo field in target.GetType().GetFields(
336 BindingFlags.Public | BindingFlags.Static |
337 BindingFlags.Instance))
338 {
339 if (field.GetCustomAttributes(
340 typeof(ScriptConstantAttribute), true).Any())
341 {
342 RegisterConstant(field.Name, field.GetValue(target));
343 }
344 }
345 }
346
347 /// <summary>
348 /// Operation to check for a registered constant
349 /// </summary>
350 public object LookupModConstant(string cname)
351 {
352 // m_log.DebugFormat("[MODULE COMMANDS] lookup constant <{0}>",cname);
353
354 lock (m_constants)
355 {
356 object value = null;
357 if (m_constants.TryGetValue(cname,out value))
358 return value;
359 }
360
361 return null;
362 }
363
364 /// <summary>
365 /// Get all registered constants
366 /// </summary>
367 public Dictionary<string, object> GetConstants()
368 {
369 Dictionary<string, object> ret = new Dictionary<string, object>();
370
371 lock (m_constants)
372 {
373 foreach (KeyValuePair<string, object> kvp in m_constants)
374 ret[kvp.Key] = kvp.Value;
375 }
376
377 return ret;
378 }
379
380#endregion
381
382 }
383}
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
index 9787c8c..41baccc 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
@@ -45,31 +45,292 @@ using OpenSim.Tests.Common.Mock;
45namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests 45namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
46{ 46{
47 [TestFixture] 47 [TestFixture]
48 public class VectorRenderModuleTests 48 public class VectorRenderModuleTests : OpenSimTestCase
49 { 49 {
50 Scene m_scene;
51 DynamicTextureModule m_dtm;
52 VectorRenderModule m_vrm;
53
54 private void SetupScene(bool reuseTextures)
55 {
56 m_scene = new SceneHelpers().SetupScene();
57
58 m_dtm = new DynamicTextureModule();
59 m_dtm.ReuseTextures = reuseTextures;
60// m_dtm.ReuseLowDataTextures = reuseTextures;
61
62 m_vrm = new VectorRenderModule();
63
64 SceneHelpers.SetupSceneModules(m_scene, m_dtm, m_vrm);
65 }
66
50 [Test] 67 [Test]
51 public void TestDraw() 68 public void TestDraw()
52 { 69 {
53 TestHelpers.InMethod(); 70 TestHelpers.InMethod();
54 71
55 Scene scene = new SceneHelpers().SetupScene(); 72 SetupScene(false);
56 DynamicTextureModule dtm = new DynamicTextureModule(); 73 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
57 VectorRenderModule vrm = new VectorRenderModule();
58 SceneHelpers.SetupSceneModules(scene, dtm, vrm);
59
60 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene);
61 UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; 74 UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
62 75
63 dtm.AddDynamicTextureData( 76 m_dtm.AddDynamicTextureData(
64 scene.RegionInfo.RegionID, 77 m_scene.RegionInfo.RegionID,
65 so.UUID, 78 so.UUID,
66 vrm.GetContentType(), 79 m_vrm.GetContentType(),
67 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;", 80 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;",
68 "", 81 "",
69 0); 82 0);
70 83
84 Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
85 }
86
87 [Test]
88 public void TestRepeatSameDraw()
89 {
90 TestHelpers.InMethod();
91
92 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
93
94 SetupScene(false);
95 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
96
97 m_dtm.AddDynamicTextureData(
98 m_scene.RegionInfo.RegionID,
99 so.UUID,
100 m_vrm.GetContentType(),
101 dtText,
102 "",
103 0);
104
105 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
106
107 m_dtm.AddDynamicTextureData(
108 m_scene.RegionInfo.RegionID,
109 so.UUID,
110 m_vrm.GetContentType(),
111 dtText,
112 "",
113 0);
114
115 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
116 }
117
118 [Test]
119 public void TestRepeatSameDrawDifferentExtraParams()
120 {
121 TestHelpers.InMethod();
122
123 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
124
125 SetupScene(false);
126 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
127
128 m_dtm.AddDynamicTextureData(
129 m_scene.RegionInfo.RegionID,
130 so.UUID,
131 m_vrm.GetContentType(),
132 dtText,
133 "",
134 0);
135
136 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
137
138 m_dtm.AddDynamicTextureData(
139 m_scene.RegionInfo.RegionID,
140 so.UUID,
141 m_vrm.GetContentType(),
142 dtText,
143 "alpha:250",
144 0);
145
146 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
147 }
148
149 [Test]
150 public void TestRepeatSameDrawContainingImage()
151 {
152 TestHelpers.InMethod();
153
154 string dtText
155 = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png";
156
157 SetupScene(false);
158 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
159
160 m_dtm.AddDynamicTextureData(
161 m_scene.RegionInfo.RegionID,
162 so.UUID,
163 m_vrm.GetContentType(),
164 dtText,
165 "",
166 0);
167
168 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
169
170 m_dtm.AddDynamicTextureData(
171 m_scene.RegionInfo.RegionID,
172 so.UUID,
173 m_vrm.GetContentType(),
174 dtText,
175 "",
176 0);
177
178 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
179 }
180
181 [Test]
182 public void TestDrawReusingTexture()
183 {
184 TestHelpers.InMethod();
185
186 SetupScene(true);
187 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
188 UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
189
190 m_dtm.AddDynamicTextureData(
191 m_scene.RegionInfo.RegionID,
192 so.UUID,
193 m_vrm.GetContentType(),
194 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;",
195 "",
196 0);
71 197
72 Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); 198 Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
73 } 199 }
200
201 [Test]
202 public void TestRepeatSameDrawReusingTexture()
203 {
204 TestHelpers.InMethod();
205// TestHelpers.EnableLogging();
206
207 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
208
209 SetupScene(true);
210 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
211
212 m_dtm.AddDynamicTextureData(
213 m_scene.RegionInfo.RegionID,
214 so.UUID,
215 m_vrm.GetContentType(),
216 dtText,
217 "",
218 0);
219
220 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
221
222 m_dtm.AddDynamicTextureData(
223 m_scene.RegionInfo.RegionID,
224 so.UUID,
225 m_vrm.GetContentType(),
226 dtText,
227 "",
228 0);
229
230 Assert.That(firstDynamicTextureID, Is.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
231 }
232
233 /// <summary>
234 /// Test a low data dynamically generated texture such that it is treated as a low data texture that causes
235 /// problems for current viewers.
236 /// </summary>
237 /// <remarks>
238 /// As we do not set DynamicTextureModule.ReuseLowDataTextures = true in this test, it should not reuse the
239 /// texture
240 /// </remarks>
241 [Test]
242 public void TestRepeatSameDrawLowDataTexture()
243 {
244 TestHelpers.InMethod();
245// TestHelpers.EnableLogging();
246
247 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
248
249 SetupScene(true);
250 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
251
252 m_dtm.AddDynamicTextureData(
253 m_scene.RegionInfo.RegionID,
254 so.UUID,
255 m_vrm.GetContentType(),
256 dtText,
257 "1024",
258 0);
259
260 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
261
262 m_dtm.AddDynamicTextureData(
263 m_scene.RegionInfo.RegionID,
264 so.UUID,
265 m_vrm.GetContentType(),
266 dtText,
267 "1024",
268 0);
269
270 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
271 }
272
273 [Test]
274 public void TestRepeatSameDrawDifferentExtraParamsReusingTexture()
275 {
276 TestHelpers.InMethod();
277
278 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
279
280 SetupScene(true);
281 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
282
283 m_dtm.AddDynamicTextureData(
284 m_scene.RegionInfo.RegionID,
285 so.UUID,
286 m_vrm.GetContentType(),
287 dtText,
288 "",
289 0);
290
291 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
292
293 m_dtm.AddDynamicTextureData(
294 m_scene.RegionInfo.RegionID,
295 so.UUID,
296 m_vrm.GetContentType(),
297 dtText,
298 "alpha:250",
299 0);
300
301 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
302 }
303
304 [Test]
305 public void TestRepeatSameDrawContainingImageReusingTexture()
306 {
307 TestHelpers.InMethod();
308
309 string dtText
310 = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png";
311
312 SetupScene(true);
313 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
314
315 m_dtm.AddDynamicTextureData(
316 m_scene.RegionInfo.RegionID,
317 so.UUID,
318 m_vrm.GetContentType(),
319 dtText,
320 "",
321 0);
322
323 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
324
325 m_dtm.AddDynamicTextureData(
326 m_scene.RegionInfo.RegionID,
327 so.UUID,
328 m_vrm.GetContentType(),
329 dtText,
330 "",
331 0);
332
333 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
334 }
74 } 335 }
75} \ No newline at end of file 336} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
index 8b2f2f8..f395441 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
@@ -30,26 +30,35 @@ using System.Drawing;
30using System.Drawing.Imaging; 30using System.Drawing.Imaging;
31using System.Globalization; 31using System.Globalization;
32using System.IO; 32using System.IO;
33using System.Linq;
33using System.Net; 34using System.Net;
34using Nini.Config; 35using Nini.Config;
35using OpenMetaverse; 36using OpenMetaverse;
36using OpenMetaverse.Imaging; 37using OpenMetaverse.Imaging;
38using OpenSim.Region.CoreModules.Scripting.DynamicTexture;
37using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
39using log4net; 41using log4net;
40using System.Reflection; 42using System.Reflection;
43using Mono.Addins;
41 44
42//using Cairo; 45//using Cairo;
43 46
44namespace OpenSim.Region.CoreModules.Scripting.VectorRender 47namespace OpenSim.Region.CoreModules.Scripting.VectorRender
45{ 48{
46 public class VectorRenderModule : IRegionModule, IDynamicTextureRender 49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "VectorRenderModule")]
50 public class VectorRenderModule : ISharedRegionModule, IDynamicTextureRender
47 { 51 {
52 // These fields exist for testing purposes, please do not remove.
53// private static bool s_flipper;
54// private static byte[] s_asset1Data;
55// private static byte[] s_asset2Data;
56
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 57 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 58
50 private string m_name = "VectorRenderModule";
51 private Scene m_scene; 59 private Scene m_scene;
52 private IDynamicTextureManager m_textureManager; 60 private IDynamicTextureManager m_textureManager;
61
53 private Graphics m_graph; 62 private Graphics m_graph;
54 private string m_fontName = "Arial"; 63 private string m_fontName = "Arial";
55 64
@@ -61,12 +70,12 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
61 70
62 public string GetContentType() 71 public string GetContentType()
63 { 72 {
64 return ("vector"); 73 return "vector";
65 } 74 }
66 75
67 public string GetName() 76 public string GetName()
68 { 77 {
69 return m_name; 78 return Name;
70 } 79 }
71 80
72 public bool SupportsAsynchronous() 81 public bool SupportsAsynchronous()
@@ -74,14 +83,20 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
74 return true; 83 return true;
75 } 84 }
76 85
77 public byte[] ConvertUrl(string url, string extraParams) 86// public bool AlwaysIdenticalConversion(string bodyData, string extraParams)
87// {
88// string[] lines = GetLines(bodyData);
89// return lines.Any((str, r) => str.StartsWith("Image"));
90// }
91
92 public IDynamicTexture ConvertUrl(string url, string extraParams)
78 { 93 {
79 return null; 94 return null;
80 } 95 }
81 96
82 public byte[] ConvertStream(Stream data, string extraParams) 97 public IDynamicTexture ConvertData(string bodyData, string extraParams)
83 { 98 {
84 return null; 99 return Draw(bodyData, extraParams);
85 } 100 }
86 101
87 public bool AsyncConvertUrl(UUID id, string url, string extraParams) 102 public bool AsyncConvertUrl(UUID id, string url, string extraParams)
@@ -91,78 +106,101 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
91 106
92 public bool AsyncConvertData(UUID id, string bodyData, string extraParams) 107 public bool AsyncConvertData(UUID id, string bodyData, string extraParams)
93 { 108 {
94 Draw(bodyData, id, extraParams); 109 if (m_textureManager == null)
110 {
111 m_log.Warn("[VECTORRENDERMODULE]: No texture manager. Can't function");
112 return false;
113 }
114 // XXX: This isn't actually being done asynchronously!
115 m_textureManager.ReturnData(id, ConvertData(bodyData, extraParams));
116
95 return true; 117 return true;
96 } 118 }
97 119
98 public void GetDrawStringSize(string text, string fontName, int fontSize, 120 public void GetDrawStringSize(string text, string fontName, int fontSize,
99 out double xSize, out double ySize) 121 out double xSize, out double ySize)
100 { 122 {
101 using (Font myFont = new Font(fontName, fontSize)) 123 lock (this)
102 { 124 {
103 SizeF stringSize = new SizeF(); 125 using (Font myFont = new Font(fontName, fontSize))
104 lock (m_graph)
105 { 126 {
106 stringSize = m_graph.MeasureString(text, myFont); 127 SizeF stringSize = new SizeF();
107 xSize = stringSize.Width; 128
108 ySize = stringSize.Height; 129 // XXX: This lock may be unnecessary.
130 lock (m_graph)
131 {
132 stringSize = m_graph.MeasureString(text, myFont);
133 xSize = stringSize.Width;
134 ySize = stringSize.Height;
135 }
109 } 136 }
110 } 137 }
111 } 138 }
112 139
113 #endregion 140 #endregion
114 141
115 #region IRegionModule Members 142 #region ISharedRegionModule Members
116 143
117 public void Initialise(Scene scene, IConfigSource config) 144 public void Initialise(IConfigSource config)
118 { 145 {
119 if (m_scene == null)
120 {
121 m_scene = scene;
122 }
123
124 if (m_graph == null)
125 {
126 // We won't dispose of these explicitly since this module is only removed when the entire simulator
127 // is shut down.
128 Bitmap bitmap = new Bitmap(1024, 1024, PixelFormat.Format32bppArgb);
129 m_graph = Graphics.FromImage(bitmap);
130 }
131
132 IConfig cfg = config.Configs["VectorRender"]; 146 IConfig cfg = config.Configs["VectorRender"];
133 if (null != cfg) 147 if (null != cfg)
134 { 148 {
135 m_fontName = cfg.GetString("font_name", m_fontName); 149 m_fontName = cfg.GetString("font_name", m_fontName);
136 } 150 }
137 m_log.DebugFormat("[VECTORRENDERMODULE]: using font \"{0}\" for text rendering.", m_fontName); 151 m_log.DebugFormat("[VECTORRENDERMODULE]: using font \"{0}\" for text rendering.", m_fontName);
152
153 // We won't dispose of these explicitly since this module is only removed when the entire simulator
154 // is shut down.
155 Bitmap bitmap = new Bitmap(1024, 1024, PixelFormat.Format32bppArgb);
156 m_graph = Graphics.FromImage(bitmap);
138 } 157 }
139 158
140 public void PostInitialise() 159 public void PostInitialise()
141 { 160 {
142 m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>(); 161 }
143 if (m_textureManager != null) 162
163 public void AddRegion(Scene scene)
164 {
165 if (m_scene == null)
144 { 166 {
145 m_textureManager.RegisterRender(GetContentType(), this); 167 m_scene = scene;
146 } 168 }
147 } 169 }
148 170
171 public void RegionLoaded(Scene scene)
172 {
173 if (m_textureManager == null && m_scene == scene)
174 {
175 m_textureManager = m_scene.RequestModuleInterface<IDynamicTextureManager>();
176 if (m_textureManager != null)
177 {
178 m_textureManager.RegisterRender(GetContentType(), this);
179 }
180 }
181 }
182
183 public void RemoveRegion(Scene scene)
184 {
185 }
186
149 public void Close() 187 public void Close()
150 { 188 {
151 } 189 }
152 190
153 public string Name 191 public string Name
154 { 192 {
155 get { return m_name; } 193 get { return "VectorRenderModule"; }
156 } 194 }
157 195
158 public bool IsSharedModule 196 public Type ReplaceableInterface
159 { 197 {
160 get { return true; } 198 get { return null; }
161 } 199 }
162 200
163 #endregion 201 #endregion
164 202
165 private void Draw(string data, UUID id, string extraParams) 203 private IDynamicTexture Draw(string data, string extraParams)
166 { 204 {
167 // We need to cater for old scripts that didnt use extraParams neatly, they use either an integer size which represents both width and height, or setalpha 205 // We need to cater for old scripts that didnt use extraParams neatly, they use either an integer size which represents both width and height, or setalpha
168 // we will now support multiple comma seperated params in the form width:256,height:512,alpha:255 206 // we will now support multiple comma seperated params in the form width:256,height:512,alpha:255
@@ -305,40 +343,57 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
305 343
306 Bitmap bitmap = null; 344 Bitmap bitmap = null;
307 Graphics graph = null; 345 Graphics graph = null;
346 bool reuseable = false;
308 347
309 try 348 try
310 { 349 {
311 if (alpha == 256) 350 // XXX: In testing, it appears that if multiple threads dispose of separate GDI+ objects simultaneously,
312 bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb); 351 // the native malloc heap can become corrupted, possibly due to a double free(). This may be due to
313 else 352 // bugs in the underlying libcairo used by mono's libgdiplus.dll on Linux/OSX. These problems were
314 bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb); 353 // seen with both libcario 1.10.2-6.1ubuntu3 and 1.8.10-2ubuntu1. They go away if disposal is perfomed
315 354 // under lock.
316 graph = Graphics.FromImage(bitmap); 355 lock (this)
317
318 // this is really just to save people filling the
319 // background color in their scripts, only do when fully opaque
320 if (alpha >= 255)
321 { 356 {
322 using (SolidBrush bgFillBrush = new SolidBrush(bgColor)) 357 if (alpha == 256)
358 bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
359 else
360 bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
361
362 graph = Graphics.FromImage(bitmap);
363
364 // this is really just to save people filling the
365 // background color in their scripts, only do when fully opaque
366 if (alpha >= 255)
323 { 367 {
324 graph.FillRectangle(bgFillBrush, 0, 0, width, height); 368 using (SolidBrush bgFillBrush = new SolidBrush(bgColor))
369 {
370 graph.FillRectangle(bgFillBrush, 0, 0, width, height);
371 }
325 } 372 }
326 } 373
327 374 for (int w = 0; w < bitmap.Width; w++)
328 for (int w = 0; w < bitmap.Width; w++)
329 {
330 if (alpha <= 255)
331 { 375 {
332 for (int h = 0; h < bitmap.Height; h++) 376 if (alpha <= 255)
333 { 377 {
334 bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h))); 378 for (int h = 0; h < bitmap.Height; h++)
379 {
380 bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h)));
381 }
335 } 382 }
336 } 383 }
384
385 GDIDraw(data, graph, altDataDelim, out reuseable);
337 } 386 }
338 387
339 GDIDraw(data, graph, altDataDelim);
340
341 byte[] imageJ2000 = new byte[0]; 388 byte[] imageJ2000 = new byte[0];
389
390 // This code exists for testing purposes, please do not remove.
391// if (s_flipper)
392// imageJ2000 = s_asset1Data;
393// else
394// imageJ2000 = s_asset2Data;
395//
396// s_flipper = !s_flipper;
342 397
343 try 398 try
344 { 399 {
@@ -351,15 +406,24 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
351 e.Message, e.StackTrace); 406 e.Message, e.StackTrace);
352 } 407 }
353 408
354 m_textureManager.ReturnData(id, imageJ2000); 409 return new OpenSim.Region.CoreModules.Scripting.DynamicTexture.DynamicTexture(
410 data, extraParams, imageJ2000, new Size(width, height), reuseable);
355 } 411 }
356 finally 412 finally
357 { 413 {
358 if (graph != null) 414 // XXX: In testing, it appears that if multiple threads dispose of separate GDI+ objects simultaneously,
359 graph.Dispose(); 415 // the native malloc heap can become corrupted, possibly due to a double free(). This may be due to
360 416 // bugs in the underlying libcairo used by mono's libgdiplus.dll on Linux/OSX. These problems were
361 if (bitmap != null) 417 // seen with both libcario 1.10.2-6.1ubuntu3 and 1.8.10-2ubuntu1. They go away if disposal is perfomed
362 bitmap.Dispose(); 418 // under lock.
419 lock (this)
420 {
421 if (graph != null)
422 graph.Dispose();
423
424 if (bitmap != null)
425 bitmap.Dispose();
426 }
363 } 427 }
364 } 428 }
365 429
@@ -418,8 +482,21 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
418 } 482 }
419*/ 483*/
420 484
421 private void GDIDraw(string data, Graphics graph, char dataDelim) 485 /// <summary>
486 /// Split input data into discrete command lines.
487 /// </summary>
488 /// <returns></returns>
489 /// <param name='data'></param>
490 /// <param name='dataDelim'></param>
491 private string[] GetLines(string data, char dataDelim)
492 {
493 char[] lineDelimiter = { dataDelim };
494 return data.Split(lineDelimiter);
495 }
496
497 private void GDIDraw(string data, Graphics graph, char dataDelim, out bool reuseable)
422 { 498 {
499 reuseable = true;
423 Point startPoint = new Point(0, 0); 500 Point startPoint = new Point(0, 0);
424 Point endPoint = new Point(0, 0); 501 Point endPoint = new Point(0, 0);
425 Pen drawPen = null; 502 Pen drawPen = null;
@@ -434,11 +511,9 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
434 myFont = new Font(fontName, fontSize); 511 myFont = new Font(fontName, fontSize);
435 myBrush = new SolidBrush(Color.Black); 512 myBrush = new SolidBrush(Color.Black);
436 513
437 char[] lineDelimiter = {dataDelim};
438 char[] partsDelimiter = {','}; 514 char[] partsDelimiter = {','};
439 string[] lines = data.Split(lineDelimiter);
440 515
441 foreach (string line in lines) 516 foreach (string line in GetLines(data, dataDelim))
442 { 517 {
443 string nextLine = line.Trim(); 518 string nextLine = line.Trim();
444 //replace with switch, or even better, do some proper parsing 519 //replace with switch, or even better, do some proper parsing
@@ -469,6 +544,10 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
469 } 544 }
470 else if (nextLine.StartsWith("Image")) 545 else if (nextLine.StartsWith("Image"))
471 { 546 {
547 // We cannot reuse any generated texture involving fetching an image via HTTP since that image
548 // can change.
549 reuseable = false;
550
472 float x = 0; 551 float x = 0;
473 float y = 0; 552 float y = 0;
474 GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y); 553 GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y);
diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
index 07bb291..87a0537 100644
--- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
@@ -28,8 +28,13 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Text.RegularExpressions;
32
31using Nini.Config; 33using Nini.Config;
34using Mono.Addins;
35
32using OpenMetaverse; 36using OpenMetaverse;
37
33using OpenSim.Framework; 38using OpenSim.Framework;
34using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
@@ -85,7 +90,8 @@ using OpenSim.Region.Framework.Scenes;
85 90
86namespace OpenSim.Region.CoreModules.Scripting.WorldComm 91namespace OpenSim.Region.CoreModules.Scripting.WorldComm
87{ 92{
88 public class WorldCommModule : IRegionModule, IWorldComm 93 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WorldCommModule")]
94 public class WorldCommModule : IWorldComm, INonSharedRegionModule
89 { 95 {
90 // private static readonly ILog m_log = 96 // private static readonly ILog m_log =
91 // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 97 // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -100,9 +106,9 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
100 private int m_saydistance = 20; 106 private int m_saydistance = 20;
101 private int m_shoutdistance = 100; 107 private int m_shoutdistance = 100;
102 108
103 #region IRegionModule Members 109 #region INonSharedRegionModule Members
104 110
105 public void Initialise(Scene scene, IConfigSource config) 111 public void Initialise(IConfigSource config)
106 { 112 {
107 // wrap this in a try block so that defaults will work if 113 // wrap this in a try block so that defaults will work if
108 // the config file doesn't specify otherwise. 114 // the config file doesn't specify otherwise.
@@ -110,29 +116,49 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
110 int maxhandles = 64; 116 int maxhandles = 64;
111 try 117 try
112 { 118 {
113 m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance); 119 m_whisperdistance = config.Configs["Chat"].GetInt(
114 m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance); 120 "whisper_distance", m_whisperdistance);
115 m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance); 121 m_saydistance = config.Configs["Chat"].GetInt(
116 maxlisteners = config.Configs["LL-Functions"].GetInt("max_listens_per_region", maxlisteners); 122 "say_distance", m_saydistance);
117 maxhandles = config.Configs["LL-Functions"].GetInt("max_listens_per_script", maxhandles); 123 m_shoutdistance = config.Configs["Chat"].GetInt(
124 "shout_distance", m_shoutdistance);
125 maxlisteners = config.Configs["LL-Functions"].GetInt(
126 "max_listens_per_region", maxlisteners);
127 maxhandles = config.Configs["LL-Functions"].GetInt(
128 "max_listens_per_script", maxhandles);
118 } 129 }
119 catch (Exception) 130 catch (Exception)
120 { 131 {
121 } 132 }
122 if (maxlisteners < 1) maxlisteners = int.MaxValue; 133 if (maxlisteners < 1) maxlisteners = int.MaxValue;
123 if (maxhandles < 1) maxhandles = int.MaxValue; 134 if (maxhandles < 1) maxhandles = int.MaxValue;
135 m_listenerManager = new ListenerManager(maxlisteners, maxhandles);
136 m_pendingQ = new Queue();
137 m_pending = Queue.Synchronized(m_pendingQ);
138 }
124 139
140 public void PostInitialise()
141 {
142 }
143
144 public void AddRegion(Scene scene)
145 {
125 m_scene = scene; 146 m_scene = scene;
126 m_scene.RegisterModuleInterface<IWorldComm>(this); 147 m_scene.RegisterModuleInterface<IWorldComm>(this);
127 m_listenerManager = new ListenerManager(maxlisteners, maxhandles);
128 m_scene.EventManager.OnChatFromClient += DeliverClientMessage; 148 m_scene.EventManager.OnChatFromClient += DeliverClientMessage;
129 m_scene.EventManager.OnChatBroadcast += DeliverClientMessage; 149 m_scene.EventManager.OnChatBroadcast += DeliverClientMessage;
130 m_pendingQ = new Queue();
131 m_pending = Queue.Synchronized(m_pendingQ);
132 } 150 }
133 151
134 public void PostInitialise() 152 public void RegionLoaded(Scene scene) { }
153
154 public void RemoveRegion(Scene scene)
135 { 155 {
156 if (scene != m_scene)
157 return;
158
159 m_scene.UnregisterModuleInterface<IWorldComm>(this);
160 m_scene.EventManager.OnChatBroadcast -= DeliverClientMessage;
161 m_scene.EventManager.OnChatBroadcast -= DeliverClientMessage;
136 } 162 }
137 163
138 public void Close() 164 public void Close()
@@ -144,10 +170,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
144 get { return "WorldCommModule"; } 170 get { return "WorldCommModule"; }
145 } 171 }
146 172
147 public bool IsSharedModule 173 public Type ReplaceableInterface { get { return null; } }
148 {
149 get { return false; }
150 }
151 174
152 #endregion 175 #endregion
153 176
@@ -172,12 +195,42 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
172 /// <param name="hostID">UUID of the SceneObjectPart</param> 195 /// <param name="hostID">UUID of the SceneObjectPart</param>
173 /// <param name="channel">channel to listen on</param> 196 /// <param name="channel">channel to listen on</param>
174 /// <param name="name">name to filter on</param> 197 /// <param name="name">name to filter on</param>
175 /// <param name="id">key to filter on (user given, could be totally faked)</param> 198 /// <param name="id">
199 /// key to filter on (user given, could be totally faked)
200 /// </param>
201 /// <param name="msg">msg to filter on</param>
202 /// <returns>number of the scripts handle</returns>
203 public int Listen(uint localID, UUID itemID, UUID hostID, int channel,
204 string name, UUID id, string msg)
205 {
206 return m_listenerManager.AddListener(localID, itemID, hostID,
207 channel, name, id, msg);
208 }
209
210 /// <summary>
211 /// Create a listen event callback with the specified filters.
212 /// The parameters localID,itemID are needed to uniquely identify
213 /// the script during 'peek' time. Parameter hostID is needed to
214 /// determine the position of the script.
215 /// </summary>
216 /// <param name="localID">localID of the script engine</param>
217 /// <param name="itemID">UUID of the script engine</param>
218 /// <param name="hostID">UUID of the SceneObjectPart</param>
219 /// <param name="channel">channel to listen on</param>
220 /// <param name="name">name to filter on</param>
221 /// <param name="id">
222 /// key to filter on (user given, could be totally faked)
223 /// </param>
176 /// <param name="msg">msg to filter on</param> 224 /// <param name="msg">msg to filter on</param>
225 /// <param name="regexBitfield">
226 /// Bitfield indicating which strings should be processed as regex.
227 /// </param>
177 /// <returns>number of the scripts handle</returns> 228 /// <returns>number of the scripts handle</returns>
178 public int Listen(uint localID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg) 229 public int Listen(uint localID, UUID itemID, UUID hostID, int channel,
230 string name, UUID id, string msg, int regexBitfield)
179 { 231 {
180 return m_listenerManager.AddListener(localID, itemID, hostID, channel, name, id, msg); 232 return m_listenerManager.AddListener(localID, itemID, hostID,
233 channel, name, id, msg, regexBitfield);
181 } 234 }
182 235
183 /// <summary> 236 /// <summary>
@@ -226,7 +279,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
226 279
227 if ((source = m_scene.GetSceneObjectPart(id)) != null) 280 if ((source = m_scene.GetSceneObjectPart(id)) != null)
228 position = source.AbsolutePosition; 281 position = source.AbsolutePosition;
229 else if ((avatar = m_scene.GetScenePresence(id)) != null) 282 else if ((avatar = m_scene.GetScenePresence(id)) != null)
230 position = avatar.AbsolutePosition; 283 position = avatar.AbsolutePosition;
231 else if (ChatTypeEnum.Region == type) 284 else if (ChatTypeEnum.Region == type)
232 position = CenterOfRegion; 285 position = CenterOfRegion;
@@ -249,7 +302,8 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
249 /// <param name="name">name of sender (object or avatar)</param> 302 /// <param name="name">name of sender (object or avatar)</param>
250 /// <param name="id">key of sender (object or avatar)</param> 303 /// <param name="id">key of sender (object or avatar)</param>
251 /// <param name="msg">msg to sent</param> 304 /// <param name="msg">msg to sent</param>
252 public void DeliverMessage(ChatTypeEnum type, int channel, string name, UUID id, string msg, Vector3 position) 305 public void DeliverMessage(ChatTypeEnum type, int channel,
306 string name, UUID id, string msg, Vector3 position)
253 { 307 {
254 // m_log.DebugFormat("[WorldComm] got[2] type {0}, channel {1}, name {2}, id {3}, msg {4}", 308 // m_log.DebugFormat("[WorldComm] got[2] type {0}, channel {1}, name {2}, id {3}, msg {4}",
255 // type, channel, name, id, msg); 309 // type, channel, name, id, msg);
@@ -257,17 +311,21 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
257 // Determine which listen event filters match the given set of arguments, this results 311 // Determine which listen event filters match the given set of arguments, this results
258 // in a limited set of listeners, each belonging a host. If the host is in range, add them 312 // in a limited set of listeners, each belonging a host. If the host is in range, add them
259 // to the pending queue. 313 // to the pending queue.
260 foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) 314 foreach (ListenerInfo li
315 in m_listenerManager.GetListeners(UUID.Zero, channel,
316 name, id, msg))
261 { 317 {
262 // Dont process if this message is from yourself! 318 // Dont process if this message is from yourself!
263 if (li.GetHostID().Equals(id)) 319 if (li.GetHostID().Equals(id))
264 continue; 320 continue;
265 321
266 SceneObjectPart sPart = m_scene.GetSceneObjectPart(li.GetHostID()); 322 SceneObjectPart sPart = m_scene.GetSceneObjectPart(
323 li.GetHostID());
267 if (sPart == null) 324 if (sPart == null)
268 continue; 325 continue;
269 326
270 double dis = Util.GetDistanceTo(sPart.AbsolutePosition, position); 327 double dis = Util.GetDistanceTo(sPart.AbsolutePosition,
328 position);
271 switch (type) 329 switch (type)
272 { 330 {
273 case ChatTypeEnum.Whisper: 331 case ChatTypeEnum.Whisper:
@@ -326,7 +384,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
326 if (channel == 0) 384 if (channel == 0)
327 { 385 {
328 // Channel 0 goes to viewer ONLY 386 // Channel 0 goes to viewer ONLY
329 m_scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Broadcast, 0, pos, name, id, false, false, target); 387 m_scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Broadcast, 0, pos, name, id, target, false, false);
330 return true; 388 return true;
331 } 389 }
332 390
@@ -369,11 +427,12 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
369 if (li.GetHostID().Equals(id)) 427 if (li.GetHostID().Equals(id))
370 continue; 428 continue;
371 429
372 SceneObjectPart sPart = m_scene.GetSceneObjectPart(li.GetHostID()); 430 SceneObjectPart sPart = m_scene.GetSceneObjectPart(
431 li.GetHostID());
373 if (sPart == null) 432 if (sPart == null)
374 continue; 433 continue;
375 434
376 if ( li.GetHostID().Equals(target)) 435 if (li.GetHostID().Equals(target))
377 { 436 {
378 QueueMessage(new ListenerInfo(li, name, id, msg)); 437 QueueMessage(new ListenerInfo(li, name, id, msg));
379 break; 438 break;
@@ -427,9 +486,15 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
427 private void DeliverClientMessage(Object sender, OSChatMessage e) 486 private void DeliverClientMessage(Object sender, OSChatMessage e)
428 { 487 {
429 if (null != e.Sender) 488 if (null != e.Sender)
430 DeliverMessage(e.Type, e.Channel, e.Sender.Name, e.Sender.AgentId, e.Message, e.Position); 489 {
490 DeliverMessage(e.Type, e.Channel, e.Sender.Name,
491 e.Sender.AgentId, e.Message, e.Position);
492 }
431 else 493 else
432 DeliverMessage(e.Type, e.Channel, e.From, UUID.Zero, e.Message, e.Position); 494 {
495 DeliverMessage(e.Type, e.Channel, e.From, UUID.Zero,
496 e.Message, e.Position);
497 }
433 } 498 }
434 499
435 public Object[] GetSerializationData(UUID itemID) 500 public Object[] GetSerializationData(UUID itemID)
@@ -446,7 +511,8 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
446 511
447 public class ListenerManager 512 public class ListenerManager
448 { 513 {
449 private Dictionary<int, List<ListenerInfo>> m_listeners = new Dictionary<int, List<ListenerInfo>>(); 514 private Dictionary<int, List<ListenerInfo>> m_listeners =
515 new Dictionary<int, List<ListenerInfo>>();
450 private int m_maxlisteners; 516 private int m_maxlisteners;
451 private int m_maxhandles; 517 private int m_maxhandles;
452 private int m_curlisteners; 518 private int m_curlisteners;
@@ -470,15 +536,25 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
470 m_curlisteners = 0; 536 m_curlisteners = 0;
471 } 537 }
472 538
473 public int AddListener(uint localID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg) 539 public int AddListener(uint localID, UUID itemID, UUID hostID,
540 int channel, string name, UUID id, string msg)
541 {
542 return AddListener(localID, itemID, hostID, channel, name, id,
543 msg, 0);
544 }
545
546 public int AddListener(uint localID, UUID itemID, UUID hostID,
547 int channel, string name, UUID id, string msg,
548 int regexBitfield)
474 { 549 {
475 // do we already have a match on this particular filter event? 550 // do we already have a match on this particular filter event?
476 List<ListenerInfo> coll = GetListeners(itemID, channel, name, id, msg); 551 List<ListenerInfo> coll = GetListeners(itemID, channel, name, id,
552 msg);
477 553
478 if (coll.Count > 0) 554 if (coll.Count > 0)
479 { 555 {
480 // special case, called with same filter settings, return same handle 556 // special case, called with same filter settings, return same
481 // (2008-05-02, tested on 1.21.1 server, still holds) 557 // handle (2008-05-02, tested on 1.21.1 server, still holds)
482 return coll[0].GetHandle(); 558 return coll[0].GetHandle();
483 } 559 }
484 560
@@ -490,16 +566,19 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
490 566
491 if (newHandle > 0) 567 if (newHandle > 0)
492 { 568 {
493 ListenerInfo li = new ListenerInfo(newHandle, localID, itemID, hostID, channel, name, id, msg); 569 ListenerInfo li = new ListenerInfo(newHandle, localID,
570 itemID, hostID, channel, name, id, msg,
571 regexBitfield);
494 572
495 List<ListenerInfo> listeners; 573 List<ListenerInfo> listeners;
496 if (!m_listeners.TryGetValue(channel,out listeners)) 574 if (!m_listeners.TryGetValue(
497 { 575 channel, out listeners))
498 listeners = new List<ListenerInfo>(); 576 {
499 m_listeners.Add(channel, listeners); 577 listeners = new List<ListenerInfo>();
500 } 578 m_listeners.Add(channel, listeners);
501 listeners.Add(li); 579 }
502 m_curlisteners++; 580 listeners.Add(li);
581 m_curlisteners++;
503 582
504 return newHandle; 583 return newHandle;
505 } 584 }
@@ -512,11 +591,13 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
512 { 591 {
513 lock (m_listeners) 592 lock (m_listeners)
514 { 593 {
515 foreach (KeyValuePair<int,List<ListenerInfo>> lis in m_listeners) 594 foreach (KeyValuePair<int, List<ListenerInfo>> lis
595 in m_listeners)
516 { 596 {
517 foreach (ListenerInfo li in lis.Value) 597 foreach (ListenerInfo li in lis.Value)
518 { 598 {
519 if (li.GetItemID().Equals(itemID) && li.GetHandle().Equals(handle)) 599 if (li.GetItemID().Equals(itemID) &&
600 li.GetHandle().Equals(handle))
520 { 601 {
521 lis.Value.Remove(li); 602 lis.Value.Remove(li);
522 if (lis.Value.Count == 0) 603 if (lis.Value.Count == 0)
@@ -539,13 +620,15 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
539 620
540 lock (m_listeners) 621 lock (m_listeners)
541 { 622 {
542 foreach (KeyValuePair<int,List<ListenerInfo>> lis in m_listeners) 623 foreach (KeyValuePair<int, List<ListenerInfo>> lis
624 in m_listeners)
543 { 625 {
544 foreach (ListenerInfo li in lis.Value) 626 foreach (ListenerInfo li in lis.Value)
545 { 627 {
546 if (li.GetItemID().Equals(itemID)) 628 if (li.GetItemID().Equals(itemID))
547 { 629 {
548 // store them first, else the enumerated bails on us 630 // store them first, else the enumerated bails on
631 // us
549 removedListeners.Add(li); 632 removedListeners.Add(li);
550 } 633 }
551 } 634 }
@@ -572,11 +655,13 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
572 { 655 {
573 lock (m_listeners) 656 lock (m_listeners)
574 { 657 {
575 foreach (KeyValuePair<int,List<ListenerInfo>> lis in m_listeners) 658 foreach (KeyValuePair<int, List<ListenerInfo>> lis
659 in m_listeners)
576 { 660 {
577 foreach (ListenerInfo li in lis.Value) 661 foreach (ListenerInfo li in lis.Value)
578 { 662 {
579 if (li.GetItemID().Equals(itemID) && li.GetHandle() == handle) 663 if (li.GetItemID().Equals(itemID) &&
664 li.GetHandle() == handle)
580 { 665 {
581 li.Activate(); 666 li.Activate();
582 // only one, bail out 667 // only one, bail out
@@ -591,11 +676,13 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
591 { 676 {
592 lock (m_listeners) 677 lock (m_listeners)
593 { 678 {
594 foreach (KeyValuePair<int,List<ListenerInfo>> lis in m_listeners) 679 foreach (KeyValuePair<int, List<ListenerInfo>> lis
680 in m_listeners)
595 { 681 {
596 foreach (ListenerInfo li in lis.Value) 682 foreach (ListenerInfo li in lis.Value)
597 { 683 {
598 if (li.GetItemID().Equals(itemID) && li.GetHandle() == handle) 684 if (li.GetItemID().Equals(itemID) &&
685 li.GetHandle() == handle)
599 { 686 {
600 li.Deactivate(); 687 li.Deactivate();
601 // only one, bail out 688 // only one, bail out
@@ -606,19 +693,24 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
606 } 693 }
607 } 694 }
608 695
609 // non-locked access, since its always called in the context of the lock 696 /// <summary>
697 /// non-locked access, since its always called in the context of the
698 /// lock
699 /// </summary>
700 /// <param name="itemID"></param>
701 /// <returns></returns>
610 private int GetNewHandle(UUID itemID) 702 private int GetNewHandle(UUID itemID)
611 { 703 {
612 List<int> handles = new List<int>(); 704 List<int> handles = new List<int>();
613 705
614 // build a list of used keys for this specific itemID... 706 // build a list of used keys for this specific itemID...
615 foreach (KeyValuePair<int,List<ListenerInfo>> lis in m_listeners) 707 foreach (KeyValuePair<int, List<ListenerInfo>> lis in m_listeners)
616 { 708 {
617 foreach (ListenerInfo li in lis.Value) 709 foreach (ListenerInfo li in lis.Value)
618 { 710 {
619 if (li.GetItemID().Equals(itemID)) 711 if (li.GetItemID().Equals(itemID))
620 handles.Add(li.GetHandle()); 712 handles.Add(li.GetHandle());
621 } 713 }
622 } 714 }
623 715
624 // Note: 0 is NOT a valid handle for llListen() to return 716 // Note: 0 is NOT a valid handle for llListen() to return
@@ -631,17 +723,46 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
631 return -1; 723 return -1;
632 } 724 }
633 725
634 // Theres probably a more clever and efficient way to 726 /// These are duplicated from ScriptBaseClass
635 // do this, maybe with regex. 727 /// http://opensimulator.org/mantis/view.php?id=6106#c21945
636 // PM2008: Ha, one could even be smart and define a specialized Enumerator. 728 #region Constants for the bitfield parameter of osListenRegex
637 public List<ListenerInfo> GetListeners(UUID itemID, int channel, string name, UUID id, string msg) 729
730 /// <summary>
731 /// process name parameter as regex
732 /// </summary>
733 public const int OS_LISTEN_REGEX_NAME = 0x1;
734
735 /// <summary>
736 /// process message parameter as regex
737 /// </summary>
738 public const int OS_LISTEN_REGEX_MESSAGE = 0x2;
739
740 #endregion
741
742 /// <summary>
743 /// Get listeners matching the input parameters.
744 /// </summary>
745 /// <remarks>
746 /// Theres probably a more clever and efficient way to do this, maybe
747 /// with regex.
748 /// PM2008: Ha, one could even be smart and define a specialized
749 /// Enumerator.
750 /// </remarks>
751 /// <param name="itemID"></param>
752 /// <param name="channel"></param>
753 /// <param name="name"></param>
754 /// <param name="id"></param>
755 /// <param name="msg"></param>
756 /// <returns></returns>
757 public List<ListenerInfo> GetListeners(UUID itemID, int channel,
758 string name, UUID id, string msg)
638 { 759 {
639 List<ListenerInfo> collection = new List<ListenerInfo>(); 760 List<ListenerInfo> collection = new List<ListenerInfo>();
640 761
641 lock (m_listeners) 762 lock (m_listeners)
642 { 763 {
643 List<ListenerInfo> listeners; 764 List<ListenerInfo> listeners;
644 if (!m_listeners.TryGetValue(channel,out listeners)) 765 if (!m_listeners.TryGetValue(channel, out listeners))
645 { 766 {
646 return collection; 767 return collection;
647 } 768 }
@@ -652,11 +773,15 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
652 { 773 {
653 continue; 774 continue;
654 } 775 }
655 if (!itemID.Equals(UUID.Zero) && !li.GetItemID().Equals(itemID)) 776 if (!itemID.Equals(UUID.Zero) &&
777 !li.GetItemID().Equals(itemID))
656 { 778 {
657 continue; 779 continue;
658 } 780 }
659 if (li.GetName().Length > 0 && !li.GetName().Equals(name)) 781 if (li.GetName().Length > 0 && (
782 ((li.RegexBitfield & OS_LISTEN_REGEX_NAME) != OS_LISTEN_REGEX_NAME && !li.GetName().Equals(name)) ||
783 ((li.RegexBitfield & OS_LISTEN_REGEX_NAME) == OS_LISTEN_REGEX_NAME && !Regex.IsMatch(name, li.GetName()))
784 ))
660 { 785 {
661 continue; 786 continue;
662 } 787 }
@@ -664,7 +789,10 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
664 { 789 {
665 continue; 790 continue;
666 } 791 }
667 if (li.GetMessage().Length > 0 && !li.GetMessage().Equals(msg)) 792 if (li.GetMessage().Length > 0 && (
793 ((li.RegexBitfield & OS_LISTEN_REGEX_MESSAGE) != OS_LISTEN_REGEX_MESSAGE && !li.GetMessage().Equals(msg)) ||
794 ((li.RegexBitfield & OS_LISTEN_REGEX_MESSAGE) == OS_LISTEN_REGEX_MESSAGE && !Regex.IsMatch(msg, li.GetMessage()))
795 ))
668 { 796 {
669 continue; 797 continue;
670 } 798 }
@@ -697,10 +825,13 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
697 { 825 {
698 int idx = 0; 826 int idx = 0;
699 Object[] item = new Object[6]; 827 Object[] item = new Object[6];
828 int dataItemLength = 6;
700 829
701 while (idx < data.Length) 830 while (idx < data.Length)
702 { 831 {
703 Array.Copy(data, idx, item, 0, 6); 832 dataItemLength = (idx + 7 == data.Length || (idx + 7 < data.Length && data[idx + 7] is bool)) ? 7 : 6;
833 item = new Object[dataItemLength];
834 Array.Copy(data, idx, item, 0, dataItemLength);
704 835
705 ListenerInfo info = 836 ListenerInfo info =
706 ListenerInfo.FromData(localID, itemID, hostID, item); 837 ListenerInfo.FromData(localID, itemID, hostID, item);
@@ -708,39 +839,98 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
708 lock (m_listeners) 839 lock (m_listeners)
709 { 840 {
710 if (!m_listeners.ContainsKey((int)item[2])) 841 if (!m_listeners.ContainsKey((int)item[2]))
711 m_listeners.Add((int)item[2], new List<ListenerInfo>()); 842 {
843 m_listeners.Add((int)item[2],
844 new List<ListenerInfo>());
845 }
712 m_listeners[(int)item[2]].Add(info); 846 m_listeners[(int)item[2]].Add(info);
713 } 847 }
714 848
715 idx+=6; 849 idx += dataItemLength;
716 } 850 }
717 } 851 }
718 } 852 }
719 853
720 public class ListenerInfo: IWorldCommListenerInfo 854 public class ListenerInfo : IWorldCommListenerInfo
721 { 855 {
722 private bool m_active; // Listener is active or not 856 /// <summary>
723 private int m_handle; // Assigned handle of this listener 857 /// Listener is active or not
724 private uint m_localID; // Local ID from script engine 858 /// </summary>
725 private UUID m_itemID; // ID of the host script engine 859 private bool m_active;
726 private UUID m_hostID; // ID of the host/scene part 860
727 private int m_channel; // Channel 861 /// <summary>
728 private UUID m_id; // ID to filter messages from 862 /// Assigned handle of this listener
729 private string m_name; // Object name to filter messages from 863 /// </summary>
730 private string m_message; // The message 864 private int m_handle;
865
866 /// <summary>
867 /// Local ID from script engine
868 /// </summary>
869 private uint m_localID;
870
871 /// <summary>
872 /// ID of the host script engine
873 /// </summary>
874 private UUID m_itemID;
875
876 /// <summary>
877 /// ID of the host/scene part
878 /// </summary>
879 private UUID m_hostID;
880
881 /// <summary>
882 /// Channel
883 /// </summary>
884 private int m_channel;
885
886 /// <summary>
887 /// ID to filter messages from
888 /// </summary>
889 private UUID m_id;
890
891 /// <summary>
892 /// Object name to filter messages from
893 /// </summary>
894 private string m_name;
895
896 /// <summary>
897 /// The message
898 /// </summary>
899 private string m_message;
900
901 public ListenerInfo(int handle, uint localID, UUID ItemID,
902 UUID hostID, int channel, string name, UUID id,
903 string message)
904 {
905 Initialise(handle, localID, ItemID, hostID, channel, name, id,
906 message, 0);
907 }
731 908
732 public ListenerInfo(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, UUID id, string message) 909 public ListenerInfo(int handle, uint localID, UUID ItemID,
910 UUID hostID, int channel, string name, UUID id,
911 string message, int regexBitfield)
733 { 912 {
734 Initialise(handle, localID, ItemID, hostID, channel, name, id, message); 913 Initialise(handle, localID, ItemID, hostID, channel, name, id,
914 message, regexBitfield);
735 } 915 }
736 916
737 public ListenerInfo(ListenerInfo li, string name, UUID id, string message) 917 public ListenerInfo(ListenerInfo li, string name, UUID id,
918 string message)
738 { 919 {
739 Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID, li.m_channel, name, id, message); 920 Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID,
921 li.m_channel, name, id, message, 0);
740 } 922 }
741 923
742 private void Initialise(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, 924 public ListenerInfo(ListenerInfo li, string name, UUID id,
743 UUID id, string message) 925 string message, int regexBitfield)
926 {
927 Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID,
928 li.m_channel, name, id, message, regexBitfield);
929 }
930
931 private void Initialise(int handle, uint localID, UUID ItemID,
932 UUID hostID, int channel, string name, UUID id,
933 string message, int regexBitfield)
744 { 934 {
745 m_active = true; 935 m_active = true;
746 m_handle = handle; 936 m_handle = handle;
@@ -751,11 +941,12 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
751 m_name = name; 941 m_name = name;
752 m_id = id; 942 m_id = id;
753 m_message = message; 943 m_message = message;
944 RegexBitfield = regexBitfield;
754 } 945 }
755 946
756 public Object[] GetSerializationData() 947 public Object[] GetSerializationData()
757 { 948 {
758 Object[] data = new Object[6]; 949 Object[] data = new Object[7];
759 950
760 data[0] = m_active; 951 data[0] = m_active;
761 data[1] = m_handle; 952 data[1] = m_handle;
@@ -763,16 +954,22 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
763 data[3] = m_name; 954 data[3] = m_name;
764 data[4] = m_id; 955 data[4] = m_id;
765 data[5] = m_message; 956 data[5] = m_message;
957 data[6] = RegexBitfield;
766 958
767 return data; 959 return data;
768 } 960 }
769 961
770 public static ListenerInfo FromData(uint localID, UUID ItemID, UUID hostID, Object[] data) 962 public static ListenerInfo FromData(uint localID, UUID ItemID,
963 UUID hostID, Object[] data)
771 { 964 {
772 ListenerInfo linfo = new ListenerInfo((int)data[1], localID, 965 ListenerInfo linfo = new ListenerInfo((int)data[1], localID,
773 ItemID, hostID, (int)data[2], (string)data[3], 966 ItemID, hostID, (int)data[2], (string)data[3],
774 (UUID)data[4], (string)data[5]); 967 (UUID)data[4], (string)data[5]);
775 linfo.m_active=(bool)data[0]; 968 linfo.m_active = (bool)data[0];
969 if (data.Length >= 7)
970 {
971 linfo.RegexBitfield = (int)data[6];
972 }
776 973
777 return linfo; 974 return linfo;
778 } 975 }
@@ -831,5 +1028,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
831 { 1028 {
832 return m_id; 1029 return m_id;
833 } 1030 }
1031
1032 public int RegexBitfield { get; private set; }
834 } 1033 }
835} 1034}
diff --git a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs
index 0003af2..385f5ad 100644
--- a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs
@@ -40,6 +40,7 @@ using OpenSim.Framework.Servers;
40using OpenSim.Framework.Servers.HttpServer; 40using OpenSim.Framework.Servers.HttpServer;
41using OpenSim.Region.Framework.Interfaces; 41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.Framework.Scenes; 42using OpenSim.Region.Framework.Scenes;
43using Mono.Addins;
43 44
44/***************************************************** 45/*****************************************************
45 * 46 *
@@ -76,7 +77,8 @@ using OpenSim.Region.Framework.Scenes;
76 77
77namespace OpenSim.Region.CoreModules.Scripting.XMLRPC 78namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
78{ 79{
79 public class XMLRPCModule : IRegionModule, IXMLRPC 80 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "XMLRPCModule")]
81 public class XMLRPCModule : ISharedRegionModule, IXMLRPC
80 { 82 {
81 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 83 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
82 84
@@ -86,6 +88,10 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
86 private Dictionary<UUID, RPCChannelInfo> m_openChannels; 88 private Dictionary<UUID, RPCChannelInfo> m_openChannels;
87 private Dictionary<UUID, SendRemoteDataRequest> m_pendingSRDResponses; 89 private Dictionary<UUID, SendRemoteDataRequest> m_pendingSRDResponses;
88 private int m_remoteDataPort = 0; 90 private int m_remoteDataPort = 0;
91 public int Port
92 {
93 get { return m_remoteDataPort; }
94 }
89 95
90 private Dictionary<UUID, RPCRequestInfo> m_rpcPending; 96 private Dictionary<UUID, RPCRequestInfo> m_rpcPending;
91 private Dictionary<UUID, RPCRequestInfo> m_rpcPendingResponses; 97 private Dictionary<UUID, RPCRequestInfo> m_rpcPendingResponses;
@@ -94,34 +100,24 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
94 private int RemoteReplyScriptWait = 300; 100 private int RemoteReplyScriptWait = 300;
95 private object XMLRPCListLock = new object(); 101 private object XMLRPCListLock = new object();
96 102
97 #region IRegionModule Members 103 #region ISharedRegionModule Members
98 104
99 public void Initialise(Scene scene, IConfigSource config) 105 public void Initialise(IConfigSource config)
100 { 106 {
101 // We need to create these early because the scripts might be calling 107 // We need to create these early because the scripts might be calling
102 // But since this gets called for every region, we need to make sure they 108 // But since this gets called for every region, we need to make sure they
103 // get called only one time (or we lose any open channels) 109 // get called only one time (or we lose any open channels)
104 if (null == m_openChannels) 110 m_openChannels = new Dictionary<UUID, RPCChannelInfo>();
105 { 111 m_rpcPending = new Dictionary<UUID, RPCRequestInfo>();
106 m_openChannels = new Dictionary<UUID, RPCChannelInfo>(); 112 m_rpcPendingResponses = new Dictionary<UUID, RPCRequestInfo>();
107 m_rpcPending = new Dictionary<UUID, RPCRequestInfo>(); 113 m_pendingSRDResponses = new Dictionary<UUID, SendRemoteDataRequest>();
108 m_rpcPendingResponses = new Dictionary<UUID, RPCRequestInfo>();
109 m_pendingSRDResponses = new Dictionary<UUID, SendRemoteDataRequest>();
110 114
111 try 115 try
112 { 116 {
113 m_remoteDataPort = config.Configs["XMLRPC"].GetInt("XmlRpcPort", m_remoteDataPort); 117 m_remoteDataPort = config.Configs["XMLRPC"].GetInt("XmlRpcPort", m_remoteDataPort);
114 }
115 catch (Exception)
116 {
117 }
118 } 118 }
119 119 catch (Exception)
120 if (!m_scenes.Contains(scene))
121 { 120 {
122 m_scenes.Add(scene);
123
124 scene.RegisterModuleInterface<IXMLRPC>(this);
125 } 121 }
126 } 122 }
127 123
@@ -131,32 +127,56 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
131 { 127 {
132 // Start http server 128 // Start http server
133 // Attach xmlrpc handlers 129 // Attach xmlrpc handlers
134// m_log.InfoFormat( 130 // m_log.InfoFormat(
135// "[XML RPC MODULE]: Starting up XMLRPC Server on port {0} for llRemoteData commands.", 131 // "[XML RPC MODULE]: Starting up XMLRPC Server on port {0} for llRemoteData commands.",
136// m_remoteDataPort); 132 // m_remoteDataPort);
137 133
138 IHttpServer httpServer = MainServer.GetHttpServer((uint)m_remoteDataPort); 134 IHttpServer httpServer = MainServer.GetHttpServer((uint)m_remoteDataPort);
139 httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData); 135 httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData);
140 } 136 }
141 } 137 }
142 138
143 public void Close() 139 public void AddRegion(Scene scene)
140 {
141 if (!IsEnabled())
142 return;
143
144 if (!m_scenes.Contains(scene))
145 {
146 m_scenes.Add(scene);
147
148 scene.RegisterModuleInterface<IXMLRPC>(this);
149 }
150 }
151
152 public void RegionLoaded(Scene scene)
144 { 153 {
145 } 154 }
146 155
147 public string Name 156 public void RemoveRegion(Scene scene)
148 { 157 {
149 get { return m_name; } 158 if (!IsEnabled())
159 return;
160
161 if (m_scenes.Contains(scene))
162 {
163 scene.UnregisterModuleInterface<IXMLRPC>(this);
164 m_scenes.Remove(scene);
165 }
150 } 166 }
151 167
152 public bool IsSharedModule 168 public void Close()
153 { 169 {
154 get { return true; }
155 } 170 }
156 171
157 public int Port 172 public string Name
158 { 173 {
159 get { return m_remoteDataPort; } 174 get { return m_name; }
175 }
176
177 public Type ReplaceableInterface
178 {
179 get { return null; }
160 } 180 }
161 181
162 #endregion 182 #endregion
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs
index 5541684..7b4668a 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs
@@ -29,6 +29,7 @@ using System;
29using System.Reflection; 29using System.Reflection;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using log4net; 31using log4net;
32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Framework.Servers; 35using OpenSim.Framework.Servers;
@@ -39,6 +40,7 @@ using OpenSim.Server.Handlers.Base;
39 40
40namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Asset 41namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Asset
41{ 42{
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AssetServiceInConnectorModule")]
42 public class AssetServiceInConnectorModule : ISharedRegionModule 44 public class AssetServiceInConnectorModule : ISharedRegionModule
43 { 45 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -47,7 +49,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Asset
47 private IConfigSource m_Config; 49 private IConfigSource m_Config;
48 bool m_Registered = false; 50 bool m_Registered = false;
49 51
50 #region IRegionModule interface 52 #region Region Module interface
51 53
52 public void Initialise(IConfigSource config) 54 public void Initialise(IConfigSource config)
53 { 55 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Authentication/AuthenticationServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Authentication/AuthenticationServiceInConnectorModule.cs
index ccf2275..2cdffe6 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Authentication/AuthenticationServiceInConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Authentication/AuthenticationServiceInConnectorModule.cs
@@ -29,6 +29,7 @@ using System;
29using System.Reflection; 29using System.Reflection;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using log4net; 31using log4net;
32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Framework.Servers; 35using OpenSim.Framework.Servers;
@@ -41,6 +42,7 @@ using OpenSim.Services.Interfaces;
41 42
42namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Authentication 43namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Authentication
43{ 44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AuthenticationServiceInConnectorModule")]
44 public class AuthenticationServiceInConnectorModule : ISharedRegionModule 46 public class AuthenticationServiceInConnectorModule : ISharedRegionModule
45 { 47 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -49,7 +51,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Authentication
49 private IConfigSource m_Config; 51 private IConfigSource m_Config;
50 bool m_Registered = false; 52 bool m_Registered = false;
51 53
52 #region IRegionModule interface 54 #region Region Module interface
53 55
54 public void Initialise(IConfigSource config) 56 public void Initialise(IConfigSource config)
55 { 57 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/GridInfoServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/GridInfoServiceInConnectorModule.cs
index 0e16e5a..22857d0 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/GridInfoServiceInConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/GridInfoServiceInConnectorModule.cs
@@ -29,6 +29,7 @@ using System;
29using System.Reflection; 29using System.Reflection;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using log4net; 31using log4net;
32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Framework.Servers; 35using OpenSim.Framework.Servers;
@@ -41,6 +42,7 @@ using OpenSim.Services.Interfaces;
41 42
42namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Grid 43namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Grid
43{ 44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GridInfoServiceInConnectorModule")]
44 public class GridInfoServiceInConnectorModule : ISharedRegionModule 46 public class GridInfoServiceInConnectorModule : ISharedRegionModule
45 { 47 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -49,7 +51,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Grid
49 private IConfigSource m_Config; 51 private IConfigSource m_Config;
50 bool m_Registered = false; 52 bool m_Registered = false;
51 53
52 #region IRegionModule interface 54 #region Region Module interface
53 55
54 public void Initialise(IConfigSource config) 56 public void Initialise(IConfigSource config)
55 { 57 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
index a7dd0dd..f749295 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
@@ -29,6 +29,7 @@ using System;
29using System.Reflection; 29using System.Reflection;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using log4net; 31using log4net;
32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Framework.Servers; 35using OpenSim.Framework.Servers;
@@ -42,6 +43,7 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
42 43
43namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid 44namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
44{ 45{
46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "HypergridServiceInConnectorModule")]
45 public class HypergridServiceInConnectorModule : ISharedRegionModule 47 public class HypergridServiceInConnectorModule : ISharedRegionModule
46 { 48 {
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -53,7 +55,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
53 private GatekeeperServiceInConnector m_HypergridHandler; 55 private GatekeeperServiceInConnector m_HypergridHandler;
54 private UserAgentServerConnector m_UASHandler; 56 private UserAgentServerConnector m_UASHandler;
55 57
56 #region IRegionModule interface 58 #region Region Module interface
57 59
58 public void Initialise(IConfigSource config) 60 public void Initialise(IConfigSource config)
59 { 61 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Inventory/InventoryServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Inventory/InventoryServiceInConnectorModule.cs
index 831ea27..0a4e736 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Inventory/InventoryServiceInConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Inventory/InventoryServiceInConnectorModule.cs
@@ -29,6 +29,7 @@ using System;
29using System.Reflection; 29using System.Reflection;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using log4net; 31using log4net;
32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Framework.Servers; 35using OpenSim.Framework.Servers;
@@ -39,6 +40,7 @@ using OpenSim.Server.Handlers.Base;
39 40
40namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Inventory 41namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Inventory
41{ 42{
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "InventoryServiceInConnectorModule")]
42 public class InventoryServiceInConnectorModule : ISharedRegionModule 44 public class InventoryServiceInConnectorModule : ISharedRegionModule
43 { 45 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -47,7 +49,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Inventory
47 private IConfigSource m_Config; 49 private IConfigSource m_Config;
48 bool m_Registered = false; 50 bool m_Registered = false;
49 51
50 #region IRegionModule interface 52 #region Region Module interface
51 53
52 public void Initialise(IConfigSource config) 54 public void Initialise(IConfigSource config)
53 { 55 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs
index 2f3c350..2fd21be 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs
@@ -29,6 +29,7 @@ using System;
29using System.Reflection; 29using System.Reflection;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using log4net; 31using log4net;
32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Framework.Servers; 35using OpenSim.Framework.Servers;
@@ -42,6 +43,7 @@ using OpenMetaverse;
42 43
43namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Land 44namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Land
44{ 45{
46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LandServiceInConnectorModule")]
45 public class LandServiceInConnectorModule : ISharedRegionModule, ILandService 47 public class LandServiceInConnectorModule : ISharedRegionModule, ILandService
46 { 48 {
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -51,7 +53,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Land
51 private IConfigSource m_Config; 53 private IConfigSource m_Config;
52 private List<Scene> m_Scenes = new List<Scene>(); 54 private List<Scene> m_Scenes = new List<Scene>();
53 55
54 #region IRegionModule interface 56 #region Region Module interface
55 57
56 public void Initialise(IConfigSource config) 58 public void Initialise(IConfigSource config)
57 { 59 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Login/LLLoginServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Login/LLLoginServiceInConnectorModule.cs
index ecdb380..425febd 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Login/LLLoginServiceInConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Login/LLLoginServiceInConnectorModule.cs
@@ -29,6 +29,7 @@ using System;
29using System.Reflection; 29using System.Reflection;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using log4net; 31using log4net;
32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Framework.Servers; 35using OpenSim.Framework.Servers;
@@ -42,6 +43,7 @@ using OpenSim.Services.Interfaces;
42 43
43namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Login 44namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Login
44{ 45{
46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LLLoginServiceInConnectorModule")]
45 public class LLLoginServiceInConnectorModule : ISharedRegionModule 47 public class LLLoginServiceInConnectorModule : ISharedRegionModule
46 { 48 {
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -51,7 +53,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Login
51 private IConfigSource m_Config; 53 private IConfigSource m_Config;
52 private List<Scene> m_Scenes = new List<Scene>(); 54 private List<Scene> m_Scenes = new List<Scene>();
53 55
54 #region IRegionModule interface 56 #region Region Module interface
55 57
56 public void Initialise(IConfigSource config) 58 public void Initialise(IConfigSource config)
57 { 59 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs
index d38af23..c14bce7 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/MapImage/MapImageServiceInConnectorModule.cs
@@ -42,7 +42,7 @@ using OpenSim.Services.Interfaces;
42 42
43namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.MapImage 43namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.MapImage
44{ 44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MapImageServiceInConnectorModule")]
46 public class MapImageServiceInConnectorModule : ISharedRegionModule 46 public class MapImageServiceInConnectorModule : ISharedRegionModule
47 { 47 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -50,7 +50,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.MapImage
50 50
51 private IConfigSource m_Config; 51 private IConfigSource m_Config;
52 52
53 #region IRegionModule interface 53 #region Region Module interface
54 54
55 public void Initialise(IConfigSource config) 55 public void Initialise(IConfigSource config)
56 { 56 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs
index b544ab3..6bf47cb 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs
@@ -29,6 +29,7 @@ using System;
29using System.Reflection; 29using System.Reflection;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using log4net; 31using log4net;
32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Framework.Servers; 35using OpenSim.Framework.Servers;
@@ -41,6 +42,7 @@ using OpenSim.Services.Interfaces;
41 42
42namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Neighbour 43namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Neighbour
43{ 44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "NeighbourServiceInConnectorModule")]
44 public class NeighbourServiceInConnectorModule : ISharedRegionModule, INeighbourService 46 public class NeighbourServiceInConnectorModule : ISharedRegionModule, INeighbourService
45 { 47 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -50,7 +52,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Neighbour
50 private IConfigSource m_Config; 52 private IConfigSource m_Config;
51 private List<Scene> m_Scenes = new List<Scene>(); 53 private List<Scene> m_Scenes = new List<Scene>();
52 54
53 #region IRegionModule interface 55 #region Region Module interface
54 56
55 public void Initialise(IConfigSource config) 57 public void Initialise(IConfigSource config)
56 { 58 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Simulation/SimulationServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Simulation/SimulationServiceInConnectorModule.cs
index 0a5275d..57d1132 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Simulation/SimulationServiceInConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Simulation/SimulationServiceInConnectorModule.cs
@@ -29,6 +29,7 @@ using System;
29using System.Reflection; 29using System.Reflection;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using log4net; 31using log4net;
32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Framework.Servers; 35using OpenSim.Framework.Servers;
@@ -40,7 +41,7 @@ using OpenSim.Server.Handlers.Base;
40 41
41namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Simulation 42namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Simulation
42{ 43{
43 // Under construction 44 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SimulationServiceInConnectorModule")]
44 public class SimulationServiceInConnectorModule : ISharedRegionModule 45 public class SimulationServiceInConnectorModule : ISharedRegionModule
45 { 46 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -49,7 +50,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Simulation
49 private IConfigSource m_Config; 50 private IConfigSource m_Config;
50 bool m_Registered = false; 51 bool m_Registered = false;
51 52
52 #region IRegionModule interface 53 #region Region Module interface
53 54
54 public void Initialise(IConfigSource config) 55 public void Initialise(IConfigSource config)
55 { 56 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs
index 008465f..d221d68 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using log4net; 28using log4net;
29using Mono.Addins;
29using Nini.Config; 30using Nini.Config;
30using System; 31using System;
31using System.Collections.Generic; 32using System.Collections.Generic;
@@ -40,8 +41,8 @@ using OpenMetaverse;
40 41
41namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset 42namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
42{ 43{
43 public class HGAssetBroker : 44 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "HGAssetBroker")]
44 ISharedRegionModule, IAssetService 45 public class HGAssetBroker : ISharedRegionModule, IAssetService
45 { 46 {
46 private static readonly ILog m_log = 47 private static readonly ILog m_log =
47 LogManager.GetLogger( 48 LogManager.GetLogger(
@@ -56,6 +57,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
56 57
57 private bool m_Enabled = false; 58 private bool m_Enabled = false;
58 59
60 private AssetPermissions m_AssetPerms;
61
59 public Type ReplaceableInterface 62 public Type ReplaceableInterface
60 { 63 {
61 get { return null; } 64 get { return null; }
@@ -128,6 +131,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
128 if (m_LocalAssetServiceURI != string.Empty) 131 if (m_LocalAssetServiceURI != string.Empty)
129 m_LocalAssetServiceURI = m_LocalAssetServiceURI.Trim('/'); 132 m_LocalAssetServiceURI = m_LocalAssetServiceURI.Trim('/');
130 133
134 IConfig hgConfig = source.Configs["HGAssetService"];
135 m_AssetPerms = new AssetPermissions(hgConfig); // it's ok if arg is null
136
131 m_Enabled = true; 137 m_Enabled = true;
132 m_log.Info("[HG ASSET CONNECTOR]: HG asset broker enabled"); 138 m_log.Info("[HG ASSET CONNECTOR]: HG asset broker enabled");
133 } 139 }
@@ -206,14 +212,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
206 asset = m_HGService.Get(id); 212 asset = m_HGService.Get(id);
207 if (asset != null) 213 if (asset != null)
208 { 214 {
209 // Now store it locally 215 // Now store it locally, if allowed
210 // For now, let me just do it for textures and scripts 216 if (m_AssetPerms.AllowedImport(asset.Type))
211 if (((AssetType)asset.Type == AssetType.Texture) ||
212 ((AssetType)asset.Type == AssetType.LSLBytecode) ||
213 ((AssetType)asset.Type == AssetType.LSLText))
214 {
215 m_GridService.Store(asset); 217 m_GridService.Store(asset);
216 } 218 else
219 return null;
217 } 220 }
218 } 221 }
219 else 222 else
@@ -328,7 +331,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
328 331
329 string id = string.Empty; 332 string id = string.Empty;
330 if (IsHG(asset.ID)) 333 if (IsHG(asset.ID))
331 id = m_HGService.Store(asset); 334 {
335 if (m_AssetPerms.AllowedExport(asset.Type))
336 id = m_HGService.Store(asset);
337 else
338 return String.Empty;
339 }
332 else 340 else
333 id = m_GridService.Store(asset); 341 id = m_GridService.Store(asset);
334 342
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs
index c78915f..480cd69 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using log4net; 28using log4net;
29using Mono.Addins;
29using Nini.Config; 30using Nini.Config;
30using System; 31using System;
31using System.Collections.Generic; 32using System.Collections.Generic;
@@ -38,6 +39,7 @@ using OpenSim.Services.Interfaces;
38 39
39namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset 40namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
40{ 41{
42 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LocalAssetServicesConnector")]
41 public class LocalAssetServicesConnector : ISharedRegionModule, IAssetService 43 public class LocalAssetServicesConnector : ISharedRegionModule, IAssetService
42 { 44 {
43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -204,8 +206,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
204 public byte[] GetData(string id) 206 public byte[] GetData(string id)
205 { 207 {
206// m_log.DebugFormat("[LOCAL ASSET SERVICES CONNECTOR]: Requesting data for asset {0}", id); 208// m_log.DebugFormat("[LOCAL ASSET SERVICES CONNECTOR]: Requesting data for asset {0}", id);
207 209
208 AssetBase asset = m_Cache.Get(id); 210 AssetBase asset = null;
211
212 if (m_Cache != null)
213 asset = m_Cache.Get(id);
209 214
210 if (asset != null) 215 if (asset != null)
211 return asset.Data; 216 return asset.Data;
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/RemoteAssetServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/RemoteAssetServiceConnector.cs
index 8a22cfc..e6eeacf 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/RemoteAssetServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/RemoteAssetServiceConnector.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using log4net; 28using log4net;
29using Mono.Addins;
29using System; 30using System;
30using System.Collections.Generic; 31using System.Collections.Generic;
31using System.Reflection; 32using System.Reflection;
@@ -38,6 +39,7 @@ using OpenSim.Services.Interfaces;
38 39
39namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset 40namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
40{ 41{
42 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemoteAssetServicesConnector")]
41 public class RemoteAssetServicesConnector : 43 public class RemoteAssetServicesConnector :
42 AssetServicesConnector, ISharedRegionModule, IAssetService 44 AssetServicesConnector, ISharedRegionModule, IAssetService
43 { 45 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/Tests/AssetConnectorTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/Tests/AssetConnectorTests.cs
new file mode 100644
index 0000000..1982473
--- /dev/null
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/Tests/AssetConnectorTests.cs
@@ -0,0 +1,136 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Reflection;
32using System.Threading;
33using log4net.Config;
34using Nini.Config;
35using NUnit.Framework;
36using OpenMetaverse;
37using OpenSim.Framework;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset;
40using OpenSim.Tests.Common;
41
42namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset.Tests
43{
44 [TestFixture]
45 public class AssetConnectorsTests : OpenSimTestCase
46 {
47 [Test]
48 public void TestAddAsset()
49 {
50 TestHelpers.InMethod();
51// TestHelpers.EnableLogging();
52
53 IConfigSource config = new IniConfigSource();
54 config.AddConfig("Modules");
55 config.Configs["Modules"].Set("AssetServices", "LocalAssetServicesConnector");
56 config.AddConfig("AssetService");
57 config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Services.AssetService.dll:AssetService");
58 config.Configs["AssetService"].Set("StorageProvider", "OpenSim.Tests.Common.dll");
59
60 LocalAssetServicesConnector lasc = new LocalAssetServicesConnector();
61 lasc.Initialise(config);
62
63 AssetBase a1 = AssetHelpers.CreateNotecardAsset();
64 lasc.Store(a1);
65
66 AssetBase retreivedA1 = lasc.Get(a1.ID);
67 Assert.That(retreivedA1.ID, Is.EqualTo(a1.ID));
68 Assert.That(retreivedA1.Metadata.ID, Is.EqualTo(a1.Metadata.ID));
69 Assert.That(retreivedA1.Data.Length, Is.EqualTo(a1.Data.Length));
70
71 AssetMetadata retrievedA1Metadata = lasc.GetMetadata(a1.ID);
72 Assert.That(retrievedA1Metadata.ID, Is.EqualTo(a1.ID));
73
74 byte[] retrievedA1Data = lasc.GetData(a1.ID);
75 Assert.That(retrievedA1Data.Length, Is.EqualTo(a1.Data.Length));
76
77 // TODO: Add cache and check that this does receive a copy of the asset
78 }
79
80 [Test]
81 public void TestAddTemporaryAsset()
82 {
83 TestHelpers.InMethod();
84// TestHelpers.EnableLogging();
85
86 IConfigSource config = new IniConfigSource();
87 config.AddConfig("Modules");
88 config.Configs["Modules"].Set("AssetServices", "LocalAssetServicesConnector");
89 config.AddConfig("AssetService");
90 config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Services.AssetService.dll:AssetService");
91 config.Configs["AssetService"].Set("StorageProvider", "OpenSim.Tests.Common.dll");
92
93 LocalAssetServicesConnector lasc = new LocalAssetServicesConnector();
94 lasc.Initialise(config);
95
96 AssetBase a1 = AssetHelpers.CreateNotecardAsset();
97 a1.Temporary = true;
98
99 lasc.Store(a1);
100
101 Assert.That(lasc.Get(a1.ID), Is.Null);
102 Assert.That(lasc.GetData(a1.ID), Is.Null);
103 Assert.That(lasc.GetMetadata(a1.ID), Is.Null);
104
105 // TODO: Add cache and check that this does receive a copy of the asset
106 }
107
108 [Test]
109 public void TestAddLocalAsset()
110 {
111 TestHelpers.InMethod();
112// TestHelpers.EnableLogging();
113
114 IConfigSource config = new IniConfigSource();
115 config.AddConfig("Modules");
116 config.Configs["Modules"].Set("AssetServices", "LocalAssetServicesConnector");
117 config.AddConfig("AssetService");
118 config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Services.AssetService.dll:AssetService");
119 config.Configs["AssetService"].Set("StorageProvider", "OpenSim.Tests.Common.dll");
120
121 LocalAssetServicesConnector lasc = new LocalAssetServicesConnector();
122 lasc.Initialise(config);
123
124 AssetBase a1 = AssetHelpers.CreateNotecardAsset();
125 a1.Local = true;
126
127 lasc.Store(a1);
128
129 Assert.That(lasc.Get(a1.ID), Is.Null);
130 Assert.That(lasc.GetData(a1.ID), Is.Null);
131 Assert.That(lasc.GetMetadata(a1.ID), Is.Null);
132
133 // TODO: Add cache and check that this does receive a copy of the asset
134 }
135 }
136} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authentication/LocalAuthenticationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authentication/LocalAuthenticationServiceConnector.cs
index d809ac2..f027810 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authentication/LocalAuthenticationServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authentication/LocalAuthenticationServiceConnector.cs
@@ -29,6 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using log4net; 31using log4net;
32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
33using OpenSim.Region.Framework.Interfaces; 34using OpenSim.Region.Framework.Interfaces;
34using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
@@ -39,6 +40,7 @@ using OpenMetaverse;
39 40
40namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authentication 41namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authentication
41{ 42{
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LocalAuthenticationServicesConnector")]
42 public class LocalAuthenticationServicesConnector : ISharedRegionModule, IAuthenticationService 44 public class LocalAuthenticationServicesConnector : ISharedRegionModule, IAuthenticationService
43 { 45 {
44 private static readonly ILog m_log = 46 private static readonly ILog m_log =
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authentication/RemoteAuthenticationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authentication/RemoteAuthenticationServiceConnector.cs
index a053bc2..7cb8b22 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authentication/RemoteAuthenticationServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authentication/RemoteAuthenticationServiceConnector.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using Nini.Config; 29using Nini.Config;
30using log4net; 30using log4net;
31using Mono.Addins;
31using System.Reflection; 32using System.Reflection;
32using OpenSim.Region.Framework.Interfaces; 33using OpenSim.Region.Framework.Interfaces;
33using OpenSim.Region.Framework.Scenes; 34using OpenSim.Region.Framework.Scenes;
@@ -36,6 +37,7 @@ using OpenSim.Services.Connectors;
36 37
37namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authentication 38namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authentication
38{ 39{
40 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemoteAuthenticationServicesConnector")]
39 public class RemoteAuthenticationServicesConnector : AuthenticationServicesConnector, 41 public class RemoteAuthenticationServicesConnector : AuthenticationServicesConnector,
40 ISharedRegionModule, IAuthenticationService 42 ISharedRegionModule, IAuthenticationService
41 { 43 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs
index 267fb9e..1acb695 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using log4net; 28using log4net;
29using Mono.Addins;
29using Nini.Config; 30using Nini.Config;
30using System; 31using System;
31using System.Collections.Generic; 32using System.Collections.Generic;
@@ -39,6 +40,7 @@ using OpenMetaverse;
39 40
40namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization 41namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
41{ 42{
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LocalAuthorizationServicesConnector")]
42 public class LocalAuthorizationServicesConnector : INonSharedRegionModule, IAuthorizationService 44 public class LocalAuthorizationServicesConnector : INonSharedRegionModule, IAuthorizationService
43 { 45 {
44 private static readonly ILog m_log = 46 private static readonly ILog m_log =
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs
index 86c0099..b8d409d 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using log4net; 28using log4net;
29using Mono.Addins;
29using System; 30using System;
30using System.Collections.Generic; 31using System.Collections.Generic;
31using System.Reflection; 32using System.Reflection;
@@ -39,6 +40,7 @@ using OpenMetaverse;
39 40
40namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization 41namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
41{ 42{
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemoteAuthorizationServicesConnector")]
42 public class RemoteAuthorizationServicesConnector : 44 public class RemoteAuthorizationServicesConnector :
43 AuthorizationServicesConnector, ISharedRegionModule, IAuthorizationService 45 AuthorizationServicesConnector, ISharedRegionModule, IAuthorizationService
44 { 46 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Avatar/LocalAvatarServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Avatar/LocalAvatarServiceConnector.cs
index 9ee19f8..c3ef588 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Avatar/LocalAvatarServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Avatar/LocalAvatarServiceConnector.cs
@@ -29,6 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using log4net; 31using log4net;
32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Region.Framework.Interfaces; 35using OpenSim.Region.Framework.Interfaces;
@@ -40,6 +41,7 @@ using OpenMetaverse;
40 41
41namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar 42namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar
42{ 43{
44 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LocalAvatarServicesConnector")]
43 public class LocalAvatarServicesConnector : ISharedRegionModule, IAvatarService 45 public class LocalAvatarServicesConnector : ISharedRegionModule, IAvatarService
44 { 46 {
45 private static readonly ILog m_log = 47 private static readonly ILog m_log =
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Avatar/RemoteAvatarServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Avatar/RemoteAvatarServiceConnector.cs
index d665a54..a087aea 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Avatar/RemoteAvatarServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Avatar/RemoteAvatarServiceConnector.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using Mono.Addins;
29using Nini.Config; 30using Nini.Config;
30using log4net; 31using log4net;
31using System.Reflection; 32using System.Reflection;
@@ -36,6 +37,7 @@ using OpenSim.Services.Connectors;
36 37
37namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar 38namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar
38{ 39{
40 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemoteAvatarServicesConnector")]
39 public class RemoteAvatarServicesConnector : AvatarServicesConnector, 41 public class RemoteAvatarServicesConnector : AvatarServicesConnector,
40 ISharedRegionModule, IAvatarService 42 ISharedRegionModule, IAvatarService
41 { 43 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
index 3c6e381..c0c2ca7 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using log4net; 28using log4net;
29using Mono.Addins;
29using Nini.Config; 30using Nini.Config;
30using System; 31using System;
31using System.Collections.Generic; 32using System.Collections.Generic;
@@ -41,6 +42,7 @@ using OpenMetaverse;
41 42
42namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid 43namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
43{ 44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LocalGridServicesConnector")]
44 public class LocalGridServicesConnector : ISharedRegionModule, IGridService 46 public class LocalGridServicesConnector : ISharedRegionModule, IGridService
45 { 47 {
46 private static readonly ILog m_log = 48 private static readonly ILog m_log =
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs
index e6c89d7..b2646ba 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using log4net; 28using log4net;
29using Mono.Addins;
29using System; 30using System;
30using System.Collections.Generic; 31using System.Collections.Generic;
31using System.Reflection; 32using System.Reflection;
@@ -42,6 +43,7 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
42 43
43namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid 44namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
44{ 45{
46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemoteGridServicesConnector")]
45 public class RemoteGridServicesConnector : ISharedRegionModule, IGridService 47 public class RemoteGridServicesConnector : ISharedRegionModule, IGridService
46 { 48 {
47 private static readonly ILog m_log = 49 private static readonly ILog m_log =
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs
index b286d17..4338133 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs
@@ -43,11 +43,15 @@ using OpenSim.Tests.Common;
43namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests 43namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests
44{ 44{
45 [TestFixture] 45 [TestFixture]
46 public class GridConnectorsTests 46 public class GridConnectorsTests : OpenSimTestCase
47 { 47 {
48 LocalGridServicesConnector m_LocalConnector; 48 LocalGridServicesConnector m_LocalConnector;
49 private void SetUp() 49
50 [SetUp]
51 public override void SetUp()
50 { 52 {
53 base.SetUp();
54
51 IConfigSource config = new IniConfigSource(); 55 IConfigSource config = new IniConfigSource();
52 config.AddConfig("Modules"); 56 config.AddConfig("Modules");
53 config.AddConfig("GridService"); 57 config.AddConfig("GridService");
@@ -71,8 +75,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests
71 TestHelpers.InMethod(); 75 TestHelpers.InMethod();
72// log4net.Config.XmlConfigurator.Configure(); 76// log4net.Config.XmlConfigurator.Configure();
73 77
74 SetUp();
75
76 // Create 4 regions 78 // Create 4 regions
77 GridRegion r1 = new GridRegion(); 79 GridRegion r1 = new GridRegion();
78 r1.RegionName = "Test Region 1"; 80 r1.RegionName = "Test Region 1";
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs
index b0edce7..221f815 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs
@@ -65,11 +65,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser
65 65
66 public void OnMakeRootAgent(ScenePresence sp) 66 public void OnMakeRootAgent(ScenePresence sp)
67 { 67 {
68// m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected root presence {0} in {1}", sp.UUID, sp.Scene.RegionInfo.RegionName);
69
70 if (sp.PresenceType != PresenceType.Npc) 68 if (sp.PresenceType != PresenceType.Npc)
69 {
70 string userid = sp.Scene.UserManagementModule.GetUserUUI(sp.UUID);
71 //m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected root presence {0} in {1}", userid, sp.Scene.RegionInfo.RegionName);
71 m_GridUserService.SetLastPosition( 72 m_GridUserService.SetLastPosition(
72 sp.UUID.ToString(), UUID.Zero, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); 73 userid, UUID.Zero, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
74 }
73 } 75 }
74 76
75 public void OnNewClient(IClientAPI client) 77 public void OnNewClient(IClientAPI client)
@@ -82,9 +84,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser
82 if (client.SceneAgent.IsChildAgent) 84 if (client.SceneAgent.IsChildAgent)
83 return; 85 return;
84 86
85// m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); 87 string userId = client.AgentId.ToString();
88 if (client.Scene is Scene)
89 {
90 Scene s = (Scene)client.Scene;
91 userId = s.UserManagementModule.GetUserUUI(client.AgentId);
92 }
93 //m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected client logout {0} in {1}", userId, client.Scene.RegionInfo.RegionName);
94
86 m_GridUserService.LoggedOut( 95 m_GridUserService.LoggedOut(
87 client.AgentId.ToString(), client.SessionId, client.Scene.RegionInfo.RegionID, 96 userId, client.SessionId, client.Scene.RegionInfo.RegionID,
88 client.SceneAgent.AbsolutePosition, client.SceneAgent.Lookat); 97 client.SceneAgent.AbsolutePosition, client.SceneAgent.Lookat);
89 } 98 }
90 } 99 }
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/LocalGridUserServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/LocalGridUserServiceConnector.cs
index 90fe69e..5734334 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/LocalGridUserServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/LocalGridUserServiceConnector.cs
@@ -29,6 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using log4net; 31using log4net;
32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
33using OpenSim.Region.Framework.Interfaces; 34using OpenSim.Region.Framework.Interfaces;
34using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
@@ -39,6 +40,7 @@ using OpenMetaverse;
39 40
40namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser 41namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser
41{ 42{
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LocalGridUserServicesConnector")]
42 public class LocalGridUserServicesConnector : ISharedRegionModule, IGridUserService 44 public class LocalGridUserServicesConnector : ISharedRegionModule, IGridUserService
43 { 45 {
44 private static readonly ILog m_log = 46 private static readonly ILog m_log =
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/RemoteGridUserServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/RemoteGridUserServiceConnector.cs
index badb552..f7e6eb8 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/RemoteGridUserServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/RemoteGridUserServiceConnector.cs
@@ -36,14 +36,19 @@ using OpenSim.Services.Connectors;
36 36
37using OpenMetaverse; 37using OpenMetaverse;
38using log4net; 38using log4net;
39using Mono.Addins;
39using Nini.Config; 40using Nini.Config;
40 41
41namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser 42namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser
42{ 43{
44 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemoteGridUserServicesConnector")]
43 public class RemoteGridUserServicesConnector : ISharedRegionModule, IGridUserService 45 public class RemoteGridUserServicesConnector : ISharedRegionModule, IGridUserService
44 { 46 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 48
49 private const int KEEPTIME = 30; // 30 secs
50 private ExpiringCache<string, GridUserInfo> m_Infos = new ExpiringCache<string, GridUserInfo>();
51
47 #region ISharedRegionModule 52 #region ISharedRegionModule
48 53
49 private bool m_Enabled = false; 54 private bool m_Enabled = false;
@@ -128,23 +133,60 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser
128 133
129 public bool LoggedOut(string userID, UUID sessionID, UUID region, Vector3 position, Vector3 lookat) 134 public bool LoggedOut(string userID, UUID sessionID, UUID region, Vector3 position, Vector3 lookat)
130 { 135 {
136 if (m_Infos.Contains(userID))
137 m_Infos.Remove(userID);
138
131 return m_RemoteConnector.LoggedOut(userID, sessionID, region, position, lookat); 139 return m_RemoteConnector.LoggedOut(userID, sessionID, region, position, lookat);
132 } 140 }
133 141
134 142
135 public bool SetHome(string userID, UUID regionID, Vector3 position, Vector3 lookAt) 143 public bool SetHome(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
136 { 144 {
137 return m_RemoteConnector.SetHome(userID, regionID, position, lookAt); 145 if (m_RemoteConnector.SetHome(userID, regionID, position, lookAt))
146 {
147 // Update the cache too
148 GridUserInfo info = null;
149 if (m_Infos.TryGetValue(userID, out info))
150 {
151 info.HomeRegionID = regionID;
152 info.HomePosition = position;
153 info.HomeLookAt = lookAt;
154 }
155 return true;
156 }
157
158 return false;
138 } 159 }
139 160
140 public bool SetLastPosition(string userID, UUID sessionID, UUID regionID, Vector3 position, Vector3 lookAt) 161 public bool SetLastPosition(string userID, UUID sessionID, UUID regionID, Vector3 position, Vector3 lookAt)
141 { 162 {
142 return m_RemoteConnector.SetLastPosition(userID, sessionID, regionID, position, lookAt); 163 if (m_RemoteConnector.SetLastPosition(userID, sessionID, regionID, position, lookAt))
164 {
165 // Update the cache too
166 GridUserInfo info = null;
167 if (m_Infos.TryGetValue(userID, out info))
168 {
169 info.LastRegionID = regionID;
170 info.LastPosition = position;
171 info.LastLookAt = lookAt;
172 }
173 return true;
174 }
175
176 return false;
143 } 177 }
144 178
145 public GridUserInfo GetGridUserInfo(string userID) 179 public GridUserInfo GetGridUserInfo(string userID)
146 { 180 {
147 return m_RemoteConnector.GetGridUserInfo(userID); 181 GridUserInfo info = null;
182 if (m_Infos.TryGetValue(userID, out info))
183 return info;
184
185 info = m_RemoteConnector.GetGridUserInfo(userID);
186
187 m_Infos.AddOrUpdate(userID, info, KEEPTIME);
188
189 return info;
148 } 190 }
149 191
150 public GridUserInfo[] GetGridUserInfo(string[] userID) 192 public GridUserInfo[] GetGridUserInfo(string[] userID)
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
index cf6d2f7..e474ef6 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using log4net; 28using log4net;
29using Mono.Addins;
29using Nini.Config; 30using Nini.Config;
30using System; 31using System;
31using System.Collections.Generic; 32using System.Collections.Generic;
@@ -42,6 +43,7 @@ using OpenMetaverse;
42 43
43namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory 44namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
44{ 45{
46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "HGInventoryBroker")]
45 public class HGInventoryBroker : ISharedRegionModule, IInventoryService 47 public class HGInventoryBroker : ISharedRegionModule, IInventoryService
46 { 48 {
47 private static readonly ILog m_log = 49 private static readonly ILog m_log =
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
index 097ff1a..ec5751d 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using log4net; 28using log4net;
29using Mono.Addins;
29using Nini.Config; 30using Nini.Config;
30 31
31using System; 32using System;
@@ -41,6 +42,7 @@ using OpenMetaverse;
41 42
42namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory 43namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
43{ 44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LocalInventoryServicesConnector")]
44 public class LocalInventoryServicesConnector : ISharedRegionModule, IInventoryService 46 public class LocalInventoryServicesConnector : ISharedRegionModule, IInventoryService
45 { 47 {
46 private static readonly ILog m_log = 48 private static readonly ILog m_log =
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
index 11e0150..2d3ba82 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
@@ -29,6 +29,7 @@ using log4net;
29using System; 29using System;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Reflection; 31using System.Reflection;
32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Framework.Monitoring; 35using OpenSim.Framework.Monitoring;
@@ -40,6 +41,7 @@ using OpenMetaverse;
40 41
41namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory 42namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
42{ 43{
44 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemoteXInventoryServicesConnector")]
43 public class RemoteXInventoryServicesConnector : ISharedRegionModule, IInventoryService 45 public class RemoteXInventoryServicesConnector : ISharedRegionModule, IInventoryService
44 { 46 {
45 private static readonly ILog m_log = 47 private static readonly ILog m_log =
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/LocalLandServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/LocalLandServiceConnector.cs
index 86c0b85..5329933 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/LocalLandServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/LocalLandServiceConnector.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using log4net; 28using log4net;
29using Mono.Addins;
29using Nini.Config; 30using Nini.Config;
30using System; 31using System;
31using System.Collections.Generic; 32using System.Collections.Generic;
@@ -39,8 +40,8 @@ using OpenMetaverse;
39 40
40namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Land 41namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Land
41{ 42{
42 public class LocalLandServicesConnector : 43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LocalLandServicesConnector")]
43 ISharedRegionModule, ILandService 44 public class LocalLandServicesConnector : ISharedRegionModule, ILandService
44 { 45 {
45 private static readonly ILog m_log = 46 private static readonly ILog m_log =
46 LogManager.GetLogger( 47 LogManager.GetLogger(
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/RemoteLandServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/RemoteLandServiceConnector.cs
index 766ef81..77dfa4a 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/RemoteLandServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/RemoteLandServiceConnector.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using log4net; 28using log4net;
29using Mono.Addins;
29using System; 30using System;
30using System.Collections.Generic; 31using System.Collections.Generic;
31using System.Reflection; 32using System.Reflection;
@@ -41,6 +42,7 @@ using OpenMetaverse;
41 42
42namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Land 43namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Land
43{ 44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemoteLandServicesConnector")]
44 public class RemoteLandServicesConnector : 46 public class RemoteLandServicesConnector :
45 LandServicesConnector, ISharedRegionModule, ILandService 47 LandServicesConnector, ISharedRegionModule, ILandService
46 { 48 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
index e4c6c1a..5836eb9 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs
@@ -52,7 +52,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage
52 /// <remarks> 52 /// <remarks>
53 /// </remarks> 53 /// </remarks>
54 54
55 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 55 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MapImageServiceModule")]
56 public class MapImageServiceModule : ISharedRegionModule 56 public class MapImageServiceModule : ISharedRegionModule
57 { 57 {
58 private static readonly ILog m_log = 58 private static readonly ILog m_log =
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/LocalNeighbourServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/LocalNeighbourServiceConnector.cs
index 7a90686..fd89428 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/LocalNeighbourServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/LocalNeighbourServiceConnector.cs
@@ -29,6 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using log4net; 31using log4net;
32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
33using OpenMetaverse; 34using OpenMetaverse;
34using OpenSim.Framework; 35using OpenSim.Framework;
@@ -39,6 +40,7 @@ using OpenSim.Services.Interfaces;
39 40
40namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour 41namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour
41{ 42{
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LocalNeighbourServicesConnector")]
42 public class LocalNeighbourServicesConnector : 44 public class LocalNeighbourServicesConnector :
43 ISharedRegionModule, INeighbourService 45 ISharedRegionModule, INeighbourService
44 { 46 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/RemoteNeighourServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/RemoteNeighourServiceConnector.cs
index c6fc2a1..e6772f3 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/RemoteNeighourServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/RemoteNeighourServiceConnector.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using log4net; 28using log4net;
29using Mono.Addins;
29using System; 30using System;
30using System.Collections.Generic; 31using System.Collections.Generic;
31using System.Reflection; 32using System.Reflection;
@@ -39,6 +40,7 @@ using OpenSim.Server.Base;
39 40
40namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour 41namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour
41{ 42{
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemoteNeighbourServicesConnector")]
42 public class RemoteNeighbourServicesConnector : 44 public class RemoteNeighbourServicesConnector :
43 NeighbourServicesConnector, ISharedRegionModule, INeighbourService 45 NeighbourServicesConnector, ISharedRegionModule, INeighbourService
44 { 46 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/BasePresenceServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/BasePresenceServiceConnector.cs
new file mode 100644
index 0000000..fdbe10a
--- /dev/null
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/BasePresenceServiceConnector.cs
@@ -0,0 +1,137 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using log4net;
32using Mono.Addins;
33using Nini.Config;
34using OpenMetaverse;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Server.Base;
38using OpenSim.Services.Interfaces;
39using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
40
41namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
42{
43 public class BasePresenceServiceConnector : IPresenceService
44 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46
47 protected bool m_Enabled;
48
49 protected PresenceDetector m_PresenceDetector;
50
51 /// <summary>
52 /// Underlying presence service. Do not use directly.
53 /// </summary>
54 public IPresenceService m_PresenceService;
55
56 public Type ReplaceableInterface
57 {
58 get { return null; }
59 }
60
61 public void AddRegion(Scene scene)
62 {
63 if (!m_Enabled)
64 return;
65
66 // m_log.DebugFormat(
67 // "[LOCAL PRESENCE CONNECTOR]: Registering IPresenceService to scene {0}", scene.RegionInfo.RegionName);
68
69 scene.RegisterModuleInterface<IPresenceService>(this);
70 m_PresenceDetector.AddRegion(scene);
71
72 m_log.InfoFormat("[BASE PRESENCE SERVICE CONNECTOR]: Enabled for region {0}", scene.Name);
73 }
74
75 public void RemoveRegion(Scene scene)
76 {
77 if (!m_Enabled)
78 return;
79
80 m_PresenceDetector.RemoveRegion(scene);
81 }
82
83 public void RegionLoaded(Scene scene)
84 {
85 if (!m_Enabled)
86 return;
87
88 }
89
90 public void PostInitialise()
91 {
92 }
93
94 public void Close()
95 {
96 }
97
98 #region IPresenceService
99
100 public bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID)
101 {
102 m_log.Warn("[BASE PRESENCE SERVICE CONNECTOR]: LoginAgent connector not implemented at the simulators");
103 return false;
104 }
105
106 public bool LogoutAgent(UUID sessionID)
107 {
108 return m_PresenceService.LogoutAgent(sessionID);
109 }
110
111 public bool LogoutRegionAgents(UUID regionID)
112 {
113 return m_PresenceService.LogoutRegionAgents(regionID);
114 }
115
116 public bool ReportAgent(UUID sessionID, UUID regionID)
117 {
118 return m_PresenceService.ReportAgent(sessionID, regionID);
119 }
120
121 public PresenceInfo GetAgent(UUID sessionID)
122 {
123 return m_PresenceService.GetAgent(sessionID);
124 }
125
126 public PresenceInfo[] GetAgents(string[] userIDs)
127 {
128 // Don't bother potentially making a useless network call if we not going to ask for any users anyway.
129 if (userIDs.Length == 0)
130 return new PresenceInfo[0];
131
132 return m_PresenceService.GetAgents(userIDs);
133 }
134
135 #endregion
136 }
137} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/LocalPresenceServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/LocalPresenceServiceConnector.cs
index 49dd633..db5c520 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/LocalPresenceServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/LocalPresenceServiceConnector.cs
@@ -24,51 +24,29 @@
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27
27using System; 28using System;
28using System.Collections.Generic; 29using System.Collections.Generic;
29using System.Reflection; 30using System.Reflection;
30 31using log4net;
32using Mono.Addins;
33using Nini.Config;
34using OpenMetaverse;
31using OpenSim.Region.Framework.Interfaces; 35using OpenSim.Region.Framework.Interfaces;
32using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
33using OpenSim.Server.Base; 37using OpenSim.Server.Base;
34using OpenSim.Services.Interfaces; 38using OpenSim.Services.Interfaces;
35using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; 39using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
36 40
37using OpenMetaverse;
38using log4net;
39using Nini.Config;
40
41namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence 41namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
42{ 42{
43 public class LocalPresenceServicesConnector : ISharedRegionModule, IPresenceService 43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LocalPresenceServicesConnector")]
44 public class LocalPresenceServicesConnector : BasePresenceServiceConnector, ISharedRegionModule, IPresenceService
44 { 45 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 47
47 private bool m_Enabled = false;
48
49 private PresenceDetector m_PresenceDetector;
50
51 /// <summary>
52 /// Underlying presence service. Do not use directly.
53 /// </summary>
54 public IPresenceService m_PresenceService;
55
56 public LocalPresenceServicesConnector()
57 {
58 }
59
60 public LocalPresenceServicesConnector(IConfigSource source)
61 {
62 Initialise(source);
63 }
64
65 #region ISharedRegionModule 48 #region ISharedRegionModule
66 49
67 public Type ReplaceableInterface
68 {
69 get { return null; }
70 }
71
72 public string Name 50 public string Name
73 { 51 {
74 get { return "LocalPresenceServicesConnector"; } 52 get { return "LocalPresenceServicesConnector"; }
@@ -119,81 +97,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
119 } 97 }
120 } 98 }
121 99
122 public void PostInitialise()
123 {
124 }
125
126 public void Close()
127 {
128 }
129
130 public void AddRegion(Scene scene)
131 {
132 if (!m_Enabled)
133 return;
134
135 // m_log.DebugFormat(
136 // "[LOCAL PRESENCE CONNECTOR]: Registering IPresenceService to scene {0}", scene.RegionInfo.RegionName);
137
138 scene.RegisterModuleInterface<IPresenceService>(this);
139 m_PresenceDetector.AddRegion(scene);
140
141 m_log.InfoFormat("[LOCAL PRESENCE CONNECTOR]: Enabled local presence for region {0}", scene.RegionInfo.RegionName);
142
143 }
144
145 public void RemoveRegion(Scene scene)
146 {
147 if (!m_Enabled)
148 return;
149
150 m_PresenceDetector.RemoveRegion(scene);
151 }
152
153 public void RegionLoaded(Scene scene)
154 {
155 if (!m_Enabled)
156 return;
157
158 }
159
160 #endregion
161
162 #region IPresenceService
163
164 public bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID)
165 {
166 m_log.Warn("[LOCAL PRESENCE CONNECTOR]: LoginAgent connector not implemented at the simulators");
167 return false;
168 }
169
170 public bool LogoutAgent(UUID sessionID)
171 {
172 return m_PresenceService.LogoutAgent(sessionID);
173 }
174
175
176 public bool LogoutRegionAgents(UUID regionID)
177 {
178 return m_PresenceService.LogoutRegionAgents(regionID);
179 }
180
181 public bool ReportAgent(UUID sessionID, UUID regionID)
182 {
183 return m_PresenceService.ReportAgent(sessionID, regionID);
184 }
185
186 public PresenceInfo GetAgent(UUID sessionID)
187 {
188 return m_PresenceService.GetAgent(sessionID);
189 }
190
191 public PresenceInfo[] GetAgents(string[] userIDs)
192 {
193 return m_PresenceService.GetAgents(userIDs);
194 }
195
196 #endregion 100 #endregion
197
198 } 101 }
199} 102} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/RemotePresenceServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/RemotePresenceServiceConnector.cs
index bf4e9ab..6ca5c28 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/RemotePresenceServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/RemotePresenceServiceConnector.cs
@@ -37,26 +37,18 @@ using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
37 37
38using OpenMetaverse; 38using OpenMetaverse;
39using log4net; 39using log4net;
40using Mono.Addins;
40using Nini.Config; 41using Nini.Config;
41 42
42namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence 43namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
43{ 44{
44 public class RemotePresenceServicesConnector : ISharedRegionModule, IPresenceService 45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemotePresenceServicesConnector")]
46 public class RemotePresenceServicesConnector : BasePresenceServiceConnector, ISharedRegionModule
45 { 47 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47 49
48 #region ISharedRegionModule 50 #region ISharedRegionModule
49 51
50 private bool m_Enabled = false;
51
52 private PresenceDetector m_PresenceDetector;
53 private IPresenceService m_RemoteConnector;
54
55 public Type ReplaceableInterface
56 {
57 get { return null; }
58 }
59
60 public string Name 52 public string Name
61 { 53 {
62 get { return "RemotePresenceServicesConnector"; } 54 get { return "RemotePresenceServicesConnector"; }
@@ -70,7 +62,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
70 string name = moduleConfig.GetString("PresenceServices", ""); 62 string name = moduleConfig.GetString("PresenceServices", "");
71 if (name == Name) 63 if (name == Name)
72 { 64 {
73 m_RemoteConnector = new PresenceServicesConnector(source); 65 m_PresenceService = new PresenceServicesConnector(source);
74 66
75 m_Enabled = true; 67 m_Enabled = true;
76 68
@@ -79,81 +71,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
79 m_log.Info("[REMOTE PRESENCE CONNECTOR]: Remote presence enabled"); 71 m_log.Info("[REMOTE PRESENCE CONNECTOR]: Remote presence enabled");
80 } 72 }
81 } 73 }
82
83 }
84
85 public void PostInitialise()
86 {
87 }
88
89 public void Close()
90 {
91 }
92
93 public void AddRegion(Scene scene)
94 {
95 if (!m_Enabled)
96 return;
97
98 scene.RegisterModuleInterface<IPresenceService>(this);
99 m_PresenceDetector.AddRegion(scene);
100
101 m_log.InfoFormat("[REMOTE PRESENCE CONNECTOR]: Enabled remote presence for region {0}", scene.RegionInfo.RegionName);
102
103 }
104
105 public void RemoveRegion(Scene scene)
106 {
107 if (!m_Enabled)
108 return;
109
110 m_PresenceDetector.RemoveRegion(scene);
111 }
112
113 public void RegionLoaded(Scene scene)
114 {
115 if (!m_Enabled)
116 return;
117
118 }
119
120 #endregion
121
122 #region IPresenceService
123
124 public bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID)
125 {
126 m_log.Warn("[REMOTE PRESENCE CONNECTOR]: LoginAgent connector not implemented at the simulators");
127 return false;
128 }
129
130 public bool LogoutAgent(UUID sessionID)
131 {
132 return m_RemoteConnector.LogoutAgent(sessionID);
133 }
134
135
136 public bool LogoutRegionAgents(UUID regionID)
137 {
138 return m_RemoteConnector.LogoutRegionAgents(regionID);
139 }
140
141 public bool ReportAgent(UUID sessionID, UUID regionID)
142 {
143 return m_RemoteConnector.ReportAgent(sessionID, regionID);
144 }
145
146 public PresenceInfo GetAgent(UUID sessionID)
147 {
148 return m_RemoteConnector.GetAgent(sessionID);
149 }
150
151 public PresenceInfo[] GetAgents(string[] userIDs)
152 {
153 return m_RemoteConnector.GetAgents(userIDs);
154 } 74 }
155 75
156 #endregion 76 #endregion
157
158 } 77 }
159} 78} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs
index 4556df3..32e47f9 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/Tests/PresenceConnectorsTests.cs
@@ -56,7 +56,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence.Tests
56 config.Configs["PresenceService"].Set("LocalServiceModule", "OpenSim.Services.PresenceService.dll:PresenceService"); 56 config.Configs["PresenceService"].Set("LocalServiceModule", "OpenSim.Services.PresenceService.dll:PresenceService");
57 config.Configs["PresenceService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); 57 config.Configs["PresenceService"].Set("StorageProvider", "OpenSim.Data.Null.dll");
58 58
59 m_LocalConnector = new LocalPresenceServicesConnector(config); 59 m_LocalConnector = new LocalPresenceServicesConnector();
60 m_LocalConnector.Initialise(config);
60 61
61 // Let's stick in a test presence 62 // Let's stick in a test presence
62 m_LocalConnector.m_PresenceService.LoginAgent(UUID.Zero.ToString(), UUID.Zero, UUID.Zero); 63 m_LocalConnector.m_PresenceService.LoginAgent(UUID.Zero.ToString(), UUID.Zero, UUID.Zero);
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
index 6eb99ea..b485194 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
@@ -29,6 +29,7 @@ using System.Collections.Generic;
29using System.Linq; 29using System.Linq;
30using System.Reflection; 30using System.Reflection;
31using log4net; 31using log4net;
32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
33using OpenMetaverse; 34using OpenMetaverse;
34using OpenSim.Framework; 35using OpenSim.Framework;
@@ -39,6 +40,7 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
39 40
40namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation 41namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
41{ 42{
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LocalSimulationConnectorModule")]
42 public class LocalSimulationConnectorModule : ISharedRegionModule, ISimulationService 44 public class LocalSimulationConnectorModule : ISharedRegionModule, ISimulationService
43 { 45 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -58,7 +60,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
58 /// </summary> 60 /// </summary>
59 private bool m_ModuleEnabled = false; 61 private bool m_ModuleEnabled = false;
60 62
61 #region IRegionModule 63 #region Region Module interface
62 64
63 public void Initialise(IConfigSource config) 65 public void Initialise(IConfigSource config)
64 { 66 {
@@ -156,7 +158,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
156 } 158 }
157 } 159 }
158 160
159 #endregion /* IRegionModule */ 161 #endregion
160 162
161 #region ISimulation 163 #region ISimulation
162 164
@@ -313,7 +315,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
313 315
314 if (m_scenes.ContainsKey(destination.RegionID)) 316 if (m_scenes.ContainsKey(destination.RegionID))
315 { 317 {
316 Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id); }); 318// m_log.DebugFormat(
319// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
320// s.RegionInfo.RegionName, destination.RegionHandle);
321
322 Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id, false); });
317 return true; 323 return true;
318 } 324 }
319 //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); 325 //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent");
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
index 68be552..c8698ca 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs
@@ -32,6 +32,7 @@ using System.Net;
32using System.Reflection; 32using System.Reflection;
33using System.Text; 33using System.Text;
34using log4net; 34using log4net;
35using Mono.Addins;
35using Nini.Config; 36using Nini.Config;
36using OpenMetaverse; 37using OpenMetaverse;
37using OpenMetaverse.StructuredData; 38using OpenMetaverse.StructuredData;
@@ -46,6 +47,7 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
46 47
47namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation 48namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
48{ 49{
50 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemoteSimulationConnectorModule")]
49 public class RemoteSimulationConnectorModule : ISharedRegionModule, ISimulationService 51 public class RemoteSimulationConnectorModule : ISharedRegionModule, ISimulationService
50 { 52 {
51 private bool initialized = false; 53 private bool initialized = false;
@@ -60,7 +62,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
60 protected bool m_safemode; 62 protected bool m_safemode;
61 protected IPAddress m_thisIP; 63 protected IPAddress m_thisIP;
62 64
63 #region IRegionModule 65 #region Region Module interface
64 66
65 public virtual void Initialise(IConfigSource config) 67 public virtual void Initialise(IConfigSource config)
66 { 68 {
@@ -147,7 +149,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
147 m_thisIP = Util.GetHostFromDNS(scene.RegionInfo.ExternalHostName); 149 m_thisIP = Util.GetHostFromDNS(scene.RegionInfo.ExternalHostName);
148 } 150 }
149 151
150 #endregion /* IRegionModule */ 152 #endregion
151 153
152 #region IInterregionComms 154 #region IInterregionComms
153 155
@@ -317,4 +319,4 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
317 319
318 #endregion /* IInterregionComms */ 320 #endregion /* IInterregionComms */
319 } 321 }
320} \ No newline at end of file 322}
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs
index 1ffd480..ea4ade5 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs
@@ -29,6 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using log4net; 31using log4net;
32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
33using OpenSim.Region.Framework.Interfaces; 34using OpenSim.Region.Framework.Interfaces;
34using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
@@ -39,6 +40,7 @@ using OpenMetaverse;
39 40
40namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts 41namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
41{ 42{
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LocalUserAccountServicesConnector")]
42 public class LocalUserAccountServicesConnector : ISharedRegionModule, IUserAccountService 44 public class LocalUserAccountServicesConnector : ISharedRegionModule, IUserAccountService
43 { 45 {
44 private static readonly ILog m_log = 46 private static readonly ILog m_log =
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs
index f6b6aeb..afbba30 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/RemoteUserAccountServiceConnector.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using Nini.Config; 29using Nini.Config;
30using log4net; 30using log4net;
31using Mono.Addins;
31using System.Reflection; 32using System.Reflection;
32using OpenSim.Region.Framework.Interfaces; 33using OpenSim.Region.Framework.Interfaces;
33using OpenSim.Region.Framework.Scenes; 34using OpenSim.Region.Framework.Scenes;
@@ -39,6 +40,7 @@ using OpenMetaverse;
39 40
40namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts 41namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
41{ 42{
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemoteUserAccountServicesConnector")]
42 public class RemoteUserAccountServicesConnector : UserAccountServicesConnector, 44 public class RemoteUserAccountServicesConnector : UserAccountServicesConnector,
43 ISharedRegionModule, IUserAccountService 45 ISharedRegionModule, IUserAccountService
44 { 46 {
diff --git a/OpenSim/Region/CoreModules/World/Access/AccessModule.cs b/OpenSim/Region/CoreModules/World/Access/AccessModule.cs
index e7b1454..1599f15 100644
--- a/OpenSim/Region/CoreModules/World/Access/AccessModule.cs
+++ b/OpenSim/Region/CoreModules/World/Access/AccessModule.cs
@@ -29,6 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using log4net; 31using log4net;
32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
33using OpenMetaverse; 34using OpenMetaverse;
34using OpenSim.Framework; 35using OpenSim.Framework;
@@ -39,6 +40,7 @@ using OpenSim.Services.Interfaces;
39 40
40namespace OpenSim.Region.CoreModules.World 41namespace OpenSim.Region.CoreModules.World
41{ 42{
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AccessModule")]
42 public class AccessModule : ISharedRegionModule 44 public class AccessModule : ISharedRegionModule
43 { 45 {
44// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index 619550c..ade5e76 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -43,6 +43,7 @@ using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.Framework.Scenes; 43using OpenSim.Region.Framework.Scenes;
44using OpenSim.Region.Framework.Scenes.Serialization; 44using OpenSim.Region.Framework.Scenes.Serialization;
45using OpenSim.Services.Interfaces; 45using OpenSim.Services.Interfaces;
46using System.Threading;
46 47
47namespace OpenSim.Region.CoreModules.World.Archiver 48namespace OpenSim.Region.CoreModules.World.Archiver
48{ 49{
@@ -52,7 +53,30 @@ namespace OpenSim.Region.CoreModules.World.Archiver
52 public class ArchiveReadRequest 53 public class ArchiveReadRequest
53 { 54 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 55 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56
57 /// <summary>
58 /// Contains data used while dearchiving a single scene.
59 /// </summary>
60 private class DearchiveContext
61 {
62 public Scene Scene { get; set; }
63
64 public List<string> SerialisedSceneObjects { get; set; }
65
66 public List<string> SerialisedParcels { get; set; }
67
68 public List<SceneObjectGroup> SceneObjects { get; set; }
69
70 public DearchiveContext(Scene scene)
71 {
72 Scene = scene;
73 SerialisedSceneObjects = new List<string>();
74 SerialisedParcels = new List<string>();
75 SceneObjects = new List<SceneObjectGroup>();
76 }
77 }
55 78
79
56 /// <summary> 80 /// <summary>
57 /// The maximum major version of OAR that we can read. Minor versions shouldn't need a max number since version 81 /// The maximum major version of OAR that we can read. Minor versions shouldn't need a max number since version
58 /// bumps here should be compatible. 82 /// bumps here should be compatible.
@@ -62,9 +86,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver
62 /// <summary> 86 /// <summary>
63 /// Has the control file been loaded for this archive? 87 /// Has the control file been loaded for this archive?
64 /// </summary> 88 /// </summary>
65 public bool ControlFileLoaded { get; private set; } 89 public bool ControlFileLoaded { get; private set; }
66 90
67 protected Scene m_scene; 91 protected string m_loadPath;
92 protected Scene m_rootScene;
68 protected Stream m_loadStream; 93 protected Stream m_loadStream;
69 protected Guid m_requestId; 94 protected Guid m_requestId;
70 protected string m_errorMessage; 95 protected string m_errorMessage;
@@ -91,16 +116,27 @@ namespace OpenSim.Region.CoreModules.World.Archiver
91 { 116 {
92 if (m_UserMan == null) 117 if (m_UserMan == null)
93 { 118 {
94 m_UserMan = m_scene.RequestModuleInterface<IUserManagement>(); 119 m_UserMan = m_rootScene.RequestModuleInterface<IUserManagement>();
95 } 120 }
96 return m_UserMan; 121 return m_UserMan;
97 } 122 }
98 } 123 }
99 124
125 /// <summary>
126 /// Used to cache lookups for valid groups.
127 /// </summary>
128 private IDictionary<UUID, bool> m_validGroupUuids = new Dictionary<UUID, bool>();
129
130 private IGroupsModule m_groupsModule;
131
132 private IAssetService m_assetService = null;
133
134
100 public ArchiveReadRequest(Scene scene, string loadPath, bool merge, bool skipAssets, Guid requestId) 135 public ArchiveReadRequest(Scene scene, string loadPath, bool merge, bool skipAssets, Guid requestId)
101 { 136 {
102 m_scene = scene; 137 m_rootScene = scene;
103 138
139 m_loadPath = loadPath;
104 try 140 try
105 { 141 {
106 m_loadStream = new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress); 142 m_loadStream = new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress);
@@ -120,11 +156,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver
120 156
121 // Zero can never be a valid user id 157 // Zero can never be a valid user id
122 m_validUserUuids[UUID.Zero] = false; 158 m_validUserUuids[UUID.Zero] = false;
159
160 m_groupsModule = m_rootScene.RequestModuleInterface<IGroupsModule>();
161 m_assetService = m_rootScene.AssetService;
123 } 162 }
124 163
125 public ArchiveReadRequest(Scene scene, Stream loadStream, bool merge, bool skipAssets, Guid requestId) 164 public ArchiveReadRequest(Scene scene, Stream loadStream, bool merge, bool skipAssets, Guid requestId)
126 { 165 {
127 m_scene = scene; 166 m_rootScene = scene;
167 m_loadPath = null;
128 m_loadStream = loadStream; 168 m_loadStream = loadStream;
129 m_merge = merge; 169 m_merge = merge;
130 m_skipAssets = skipAssets; 170 m_skipAssets = skipAssets;
@@ -132,6 +172,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
132 172
133 // Zero can never be a valid user id 173 // Zero can never be a valid user id
134 m_validUserUuids[UUID.Zero] = false; 174 m_validUserUuids[UUID.Zero] = false;
175
176 m_groupsModule = m_rootScene.RequestModuleInterface<IGroupsModule>();
177 m_assetService = m_rootScene.AssetService;
135 } 178 }
136 179
137 /// <summary> 180 /// <summary>
@@ -139,25 +182,25 @@ namespace OpenSim.Region.CoreModules.World.Archiver
139 /// </summary> 182 /// </summary>
140 public void DearchiveRegion() 183 public void DearchiveRegion()
141 { 184 {
142 // The same code can handle dearchiving 0.1 and 0.2 OpenSim Archive versions
143 DearchiveRegion0DotStar();
144 }
145
146 private void DearchiveRegion0DotStar()
147 {
148 int successfulAssetRestores = 0; 185 int successfulAssetRestores = 0;
149 int failedAssetRestores = 0; 186 int failedAssetRestores = 0;
150 List<string> serialisedSceneObjects = new List<string>();
151 List<string> serialisedParcels = new List<string>();
152 string filePath = "NONE";
153 187
154 TarArchiveReader archive = new TarArchiveReader(m_loadStream); 188 DearchiveScenesInfo dearchivedScenes;
189
190 // We dearchive all the scenes at once, because the files in the TAR archive might be mixed.
191 // Therefore, we have to keep track of the dearchive context of all the scenes.
192 Dictionary<UUID, DearchiveContext> sceneContexts = new Dictionary<UUID, DearchiveContext>();
193
194 string fullPath = "NONE";
195 TarArchiveReader archive = null;
155 byte[] data; 196 byte[] data;
156 TarArchiveReader.TarEntryType entryType; 197 TarArchiveReader.TarEntryType entryType;
157 198
158 try 199 try
159 { 200 {
160 while ((data = archive.ReadEntry(out filePath, out entryType)) != null) 201 FindAndLoadControlFile(out archive, out dearchivedScenes);
202
203 while ((data = archive.ReadEntry(out fullPath, out entryType)) != null)
161 { 204 {
162 //m_log.DebugFormat( 205 //m_log.DebugFormat(
163 // "[ARCHIVER]: Successfully read {0} ({1} bytes)", filePath, data.Length); 206 // "[ARCHIVER]: Successfully read {0} ({1} bytes)", filePath, data.Length);
@@ -165,9 +208,30 @@ namespace OpenSim.Region.CoreModules.World.Archiver
165 if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType) 208 if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType)
166 continue; 209 continue;
167 210
211
212 // Find the scene that this file belongs to
213
214 Scene scene;
215 string filePath;
216 if (!dearchivedScenes.GetRegionFromPath(fullPath, out scene, out filePath))
217 continue; // this file belongs to a region that we're not loading
218
219 DearchiveContext sceneContext = null;
220 if (scene != null)
221 {
222 if (!sceneContexts.TryGetValue(scene.RegionInfo.RegionID, out sceneContext))
223 {
224 sceneContext = new DearchiveContext(scene);
225 sceneContexts.Add(scene.RegionInfo.RegionID, sceneContext);
226 }
227 }
228
229
230 // Process the file
231
168 if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH)) 232 if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH))
169 { 233 {
170 serialisedSceneObjects.Add(Encoding.UTF8.GetString(data)); 234 sceneContext.SerialisedSceneObjects.Add(Encoding.UTF8.GetString(data));
171 } 235 }
172 else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH) && !m_skipAssets) 236 else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH) && !m_skipAssets)
173 { 237 {
@@ -181,19 +245,19 @@ namespace OpenSim.Region.CoreModules.World.Archiver
181 } 245 }
182 else if (!m_merge && filePath.StartsWith(ArchiveConstants.TERRAINS_PATH)) 246 else if (!m_merge && filePath.StartsWith(ArchiveConstants.TERRAINS_PATH))
183 { 247 {
184 LoadTerrain(filePath, data); 248 LoadTerrain(scene, filePath, data);
185 } 249 }
186 else if (!m_merge && filePath.StartsWith(ArchiveConstants.SETTINGS_PATH)) 250 else if (!m_merge && filePath.StartsWith(ArchiveConstants.SETTINGS_PATH))
187 { 251 {
188 LoadRegionSettings(filePath, data); 252 LoadRegionSettings(scene, filePath, data, dearchivedScenes);
189 } 253 }
190 else if (!m_merge && filePath.StartsWith(ArchiveConstants.LANDDATA_PATH)) 254 else if (!m_merge && filePath.StartsWith(ArchiveConstants.LANDDATA_PATH))
191 { 255 {
192 serialisedParcels.Add(Encoding.UTF8.GetString(data)); 256 sceneContext.SerialisedParcels.Add(Encoding.UTF8.GetString(data));
193 } 257 }
194 else if (filePath == ArchiveConstants.CONTROL_FILE_PATH) 258 else if (filePath == ArchiveConstants.CONTROL_FILE_PATH)
195 { 259 {
196 LoadControlFile(filePath, data); 260 // Ignore, because we already read the control file
197 } 261 }
198 } 262 }
199 263
@@ -201,15 +265,16 @@ namespace OpenSim.Region.CoreModules.World.Archiver
201 } 265 }
202 catch (Exception e) 266 catch (Exception e)
203 { 267 {
204 m_log.ErrorFormat( 268 m_log.Error(
205 "[ARCHIVER]: Aborting load with error in archive file {0}. {1}", filePath, e); 269 String.Format("[ARCHIVER]: Aborting load with error in archive file {0} ", fullPath), e);
206 m_errorMessage += e.ToString(); 270 m_errorMessage += e.ToString();
207 m_scene.EventManager.TriggerOarFileLoaded(m_requestId, m_errorMessage); 271 m_rootScene.EventManager.TriggerOarFileLoaded(m_requestId, new List<UUID>(), m_errorMessage);
208 return; 272 return;
209 } 273 }
210 finally 274 finally
211 { 275 {
212 archive.Close(); 276 if (archive != null)
277 archive.Close();
213 } 278 }
214 279
215 if (!m_skipAssets) 280 if (!m_skipAssets)
@@ -223,32 +288,143 @@ namespace OpenSim.Region.CoreModules.World.Archiver
223 } 288 }
224 } 289 }
225 290
226 if (!m_merge) 291 foreach (DearchiveContext sceneContext in sceneContexts.Values)
227 { 292 {
228 m_log.Info("[ARCHIVER]: Clearing all existing scene objects"); 293 m_log.InfoFormat("[ARCHIVER]: Loading region {0}", sceneContext.Scene.RegionInfo.RegionName);
229 m_scene.DeleteAllSceneObjects(); 294
295 if (!m_merge)
296 {
297 m_log.Info("[ARCHIVER]: Clearing all existing scene objects");
298 sceneContext.Scene.DeleteAllSceneObjects();
299 }
300
301 try
302 {
303 LoadParcels(sceneContext.Scene, sceneContext.SerialisedParcels);
304 LoadObjects(sceneContext.Scene, sceneContext.SerialisedSceneObjects, sceneContext.SceneObjects);
305
306 // Inform any interested parties that the region has changed. We waited until now so that all
307 // of the region's objects will be loaded when we send this notification.
308 IEstateModule estateModule = sceneContext.Scene.RequestModuleInterface<IEstateModule>();
309 if (estateModule != null)
310 estateModule.TriggerRegionInfoChange();
311 }
312 catch (Exception e)
313 {
314 m_log.Error("[ARCHIVER]: Error loading parcels or objects ", e);
315 m_errorMessage += e.ToString();
316 m_rootScene.EventManager.TriggerOarFileLoaded(m_requestId, new List<UUID>(), m_errorMessage);
317 return;
318 }
230 } 319 }
231 320
232 LoadParcels(serialisedParcels); 321 // Start the scripts. We delayed this because we want the OAR to finish loading ASAP, so
233 LoadObjects(serialisedSceneObjects); 322 // that users can enter the scene. If we allow the scripts to start in the loop above
323 // then they significantly increase the time until the OAR finishes loading.
324 Util.FireAndForget(delegate(object o)
325 {
326 Thread.Sleep(15000);
327 m_log.Info("[ARCHIVER]: Starting scripts in scene objects");
328
329 foreach (DearchiveContext sceneContext in sceneContexts.Values)
330 {
331 foreach (SceneObjectGroup sceneObject in sceneContext.SceneObjects)
332 {
333 sceneObject.CreateScriptInstances(0, false, sceneContext.Scene.DefaultScriptEngine, 0); // StateSource.RegionStart
334 sceneObject.ResumeScripts();
335 }
336
337 sceneContext.SceneObjects.Clear();
338 }
339 });
234 340
235 m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive"); 341 m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive");
236 342
237 m_scene.EventManager.TriggerOarFileLoaded(m_requestId, m_errorMessage); 343 m_rootScene.EventManager.TriggerOarFileLoaded(m_requestId, dearchivedScenes.GetLoadedScenes(), m_errorMessage);
344 }
345
346 /// <summary>
347 /// Searches through the files in the archive for the control file, and reads it.
348 /// We must read the control file first, in order to know which regions are available.
349 /// </summary>
350 /// <remarks>
351 /// In most cases the control file *is* first, since that's how we create archives. However,
352 /// it's possible that someone rewrote the archive externally so we can't rely on this fact.
353 /// </remarks>
354 /// <param name="archive"></param>
355 /// <param name="dearchivedScenes"></param>
356 private void FindAndLoadControlFile(out TarArchiveReader archive, out DearchiveScenesInfo dearchivedScenes)
357 {
358 archive = new TarArchiveReader(m_loadStream);
359 dearchivedScenes = new DearchiveScenesInfo();
360
361 string filePath;
362 byte[] data;
363 TarArchiveReader.TarEntryType entryType;
364 bool firstFile = true;
365
366 while ((data = archive.ReadEntry(out filePath, out entryType)) != null)
367 {
368 if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType)
369 continue;
370
371 if (filePath == ArchiveConstants.CONTROL_FILE_PATH)
372 {
373 LoadControlFile(filePath, data, dearchivedScenes);
374
375 // Find which scenes are available in the simulator
376 ArchiveScenesGroup simulatorScenes = new ArchiveScenesGroup();
377 SceneManager.Instance.ForEachScene(delegate(Scene scene2)
378 {
379 simulatorScenes.AddScene(scene2);
380 });
381 simulatorScenes.CalcSceneLocations();
382 dearchivedScenes.SetSimulatorScenes(m_rootScene, simulatorScenes);
383
384 // If the control file wasn't the first file then reset the read pointer
385 if (!firstFile)
386 {
387 m_log.Warn("Control file wasn't the first file in the archive");
388 if (m_loadStream.CanSeek)
389 {
390 m_loadStream.Seek(0, SeekOrigin.Begin);
391 }
392 else if (m_loadPath != null)
393 {
394 archive.Close();
395 archive = null;
396 m_loadStream.Close();
397 m_loadStream = null;
398 m_loadStream = new GZipStream(ArchiveHelpers.GetStream(m_loadPath), CompressionMode.Decompress);
399 archive = new TarArchiveReader(m_loadStream);
400 }
401 else
402 {
403 // There isn't currently a scenario where this happens, but it's best to add a check just in case
404 throw new Exception("Error reading archive: control file wasn't the first file, and the input stream doesn't allow seeking");
405 }
406 }
407
408 return;
409 }
410
411 firstFile = false;
412 }
413
414 throw new Exception("Control file not found");
238 } 415 }
239 416
240 /// <summary> 417 /// <summary>
241 /// Load serialized scene objects. 418 /// Load serialized scene objects.
242 /// </summary> 419 /// </summary>
243 /// <param name="serialisedSceneObjects"></param> 420 protected void LoadObjects(Scene scene, List<string> serialisedSceneObjects, List<SceneObjectGroup> sceneObjects)
244 protected void LoadObjects(List<string> serialisedSceneObjects)
245 { 421 {
246 // Reload serialized prims 422 // Reload serialized prims
247 m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count); 423 m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count);
248 424
249 UUID oldTelehubUUID = m_scene.RegionInfo.RegionSettings.TelehubObject; 425 UUID oldTelehubUUID = scene.RegionInfo.RegionSettings.TelehubObject;
250 426
251 IRegionSerialiserModule serialiser = m_scene.RequestModuleInterface<IRegionSerialiserModule>(); 427 IRegionSerialiserModule serialiser = scene.RequestModuleInterface<IRegionSerialiserModule>();
252 int sceneObjectsLoadedCount = 0; 428 int sceneObjectsLoadedCount = 0;
253 429
254 foreach (string serialisedSceneObject in serialisedSceneObjects) 430 foreach (string serialisedSceneObject in serialisedSceneObjects)
@@ -269,7 +445,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
269 445
270 SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); 446 SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject);
271 447
272 bool isTelehub = (sceneObject.UUID == oldTelehubUUID); 448 bool isTelehub = (sceneObject.UUID == oldTelehubUUID) && (oldTelehubUUID != UUID.Zero);
273 449
274 // For now, give all incoming scene objects new uuids. This will allow scenes to be cloned 450 // For now, give all incoming scene objects new uuids. This will allow scenes to be cloned
275 // on the same region server and multiple examples a single object archive to be imported 451 // on the same region server and multiple examples a single object archive to be imported
@@ -279,8 +455,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
279 if (isTelehub) 455 if (isTelehub)
280 { 456 {
281 // Change the Telehub Object to the new UUID 457 // Change the Telehub Object to the new UUID
282 m_scene.RegionInfo.RegionSettings.TelehubObject = sceneObject.UUID; 458 scene.RegionInfo.RegionSettings.TelehubObject = sceneObject.UUID;
283 m_scene.RegionInfo.RegionSettings.Save(); 459 scene.RegionInfo.RegionSettings.Save();
284 oldTelehubUUID = UUID.Zero; 460 oldTelehubUUID = UUID.Zero;
285 } 461 }
286 462
@@ -290,17 +466,20 @@ namespace OpenSim.Region.CoreModules.World.Archiver
290 { 466 {
291 if (part.CreatorData == null || part.CreatorData == string.Empty) 467 if (part.CreatorData == null || part.CreatorData == string.Empty)
292 { 468 {
293 if (!ResolveUserUuid(part.CreatorID)) 469 if (!ResolveUserUuid(scene, part.CreatorID))
294 part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; 470 part.CreatorID = scene.RegionInfo.EstateSettings.EstateOwner;
295 } 471 }
296 if (UserManager != null) 472 if (UserManager != null)
297 UserManager.AddUser(part.CreatorID, part.CreatorData); 473 UserManager.AddUser(part.CreatorID, part.CreatorData);
298 474
299 if (!ResolveUserUuid(part.OwnerID)) 475 if (!ResolveUserUuid(scene, part.OwnerID))
300 part.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 476 part.OwnerID = scene.RegionInfo.EstateSettings.EstateOwner;
477
478 if (!ResolveUserUuid(scene, part.LastOwnerID))
479 part.LastOwnerID = scene.RegionInfo.EstateSettings.EstateOwner;
301 480
302 if (!ResolveUserUuid(part.LastOwnerID)) 481 if (!ResolveGroupUuid(part.GroupID))
303 part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 482 part.GroupID = UUID.Zero;
304 483
305 // And zap any troublesome sit target information 484 // And zap any troublesome sit target information
306// part.SitTargetOrientation = new Quaternion(0, 0, 0, 1); 485// part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
@@ -311,14 +490,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
311 // being no copy/no mod for everyone 490 // being no copy/no mod for everyone
312 lock (part.TaskInventory) 491 lock (part.TaskInventory)
313 { 492 {
314 if (!ResolveUserUuid(part.CreatorID)) 493 if (!ResolveUserUuid(scene, part.CreatorID))
315 part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; 494 part.CreatorID = scene.RegionInfo.EstateSettings.EstateOwner;
316 495
317 if (!ResolveUserUuid(part.OwnerID)) 496 if (!ResolveUserUuid(scene, part.OwnerID))
318 part.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 497 part.OwnerID = scene.RegionInfo.EstateSettings.EstateOwner;
319 498
320 if (!ResolveUserUuid(part.LastOwnerID)) 499 if (!ResolveUserUuid(scene, part.LastOwnerID))
321 part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 500 part.LastOwnerID = scene.RegionInfo.EstateSettings.EstateOwner;
322 501
323 // And zap any troublesome sit target information 502 // And zap any troublesome sit target information
324 part.SitTargetOrientation = new Quaternion(0, 0, 0, 1); 503 part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
@@ -331,26 +510,31 @@ namespace OpenSim.Region.CoreModules.World.Archiver
331 TaskInventoryDictionary inv = part.TaskInventory; 510 TaskInventoryDictionary inv = part.TaskInventory;
332 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv) 511 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv)
333 { 512 {
334 if (!ResolveUserUuid(kvp.Value.OwnerID)) 513 if (!ResolveUserUuid(scene, kvp.Value.OwnerID))
335 { 514 {
336 kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 515 kvp.Value.OwnerID = scene.RegionInfo.EstateSettings.EstateOwner;
337 } 516 }
517
338 if (kvp.Value.CreatorData == null || kvp.Value.CreatorData == string.Empty) 518 if (kvp.Value.CreatorData == null || kvp.Value.CreatorData == string.Empty)
339 { 519 {
340 if (!ResolveUserUuid(kvp.Value.CreatorID)) 520 if (!ResolveUserUuid(scene, kvp.Value.CreatorID))
341 kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; 521 kvp.Value.CreatorID = scene.RegionInfo.EstateSettings.EstateOwner;
342 } 522 }
523
343 if (UserManager != null) 524 if (UserManager != null)
344 UserManager.AddUser(kvp.Value.CreatorID, kvp.Value.CreatorData); 525 UserManager.AddUser(kvp.Value.CreatorID, kvp.Value.CreatorData);
526
527 if (!ResolveGroupUuid(kvp.Value.GroupID))
528 kvp.Value.GroupID = UUID.Zero;
345 } 529 }
346 part.TaskInventory.LockItemsForRead(false); 530 part.TaskInventory.LockItemsForRead(false);
347 } 531 }
348 } 532 }
349 533
350 if (m_scene.AddRestoredSceneObject(sceneObject, true, false)) 534 if (scene.AddRestoredSceneObject(sceneObject, true, false))
351 { 535 {
352 sceneObjectsLoadedCount++; 536 sceneObjectsLoadedCount++;
353 sceneObject.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, 0); 537 sceneObject.CreateScriptInstances(0, false, scene.DefaultScriptEngine, 0);
354 sceneObject.ResumeScripts(); 538 sceneObject.ResumeScripts();
355 } 539 }
356 } 540 }
@@ -365,16 +549,17 @@ namespace OpenSim.Region.CoreModules.World.Archiver
365 if (oldTelehubUUID != UUID.Zero) 549 if (oldTelehubUUID != UUID.Zero)
366 { 550 {
367 m_log.WarnFormat("Telehub object not found: {0}", oldTelehubUUID); 551 m_log.WarnFormat("Telehub object not found: {0}", oldTelehubUUID);
368 m_scene.RegionInfo.RegionSettings.TelehubObject = UUID.Zero; 552 scene.RegionInfo.RegionSettings.TelehubObject = UUID.Zero;
369 m_scene.RegionInfo.RegionSettings.ClearSpawnPoints(); 553 scene.RegionInfo.RegionSettings.ClearSpawnPoints();
370 } 554 }
371 } 555 }
372 556
373 /// <summary> 557 /// <summary>
374 /// Load serialized parcels. 558 /// Load serialized parcels.
375 /// </summary> 559 /// </summary>
560 /// <param name="scene"></param>
376 /// <param name="serialisedParcels"></param> 561 /// <param name="serialisedParcels"></param>
377 protected void LoadParcels(List<string> serialisedParcels) 562 protected void LoadParcels(Scene scene, List<string> serialisedParcels)
378 { 563 {
379 // Reload serialized parcels 564 // Reload serialized parcels
380 m_log.InfoFormat("[ARCHIVER]: Loading {0} parcels. Please wait.", serialisedParcels.Count); 565 m_log.InfoFormat("[ARCHIVER]: Loading {0} parcels. Please wait.", serialisedParcels.Count);
@@ -382,9 +567,27 @@ namespace OpenSim.Region.CoreModules.World.Archiver
382 foreach (string serialisedParcel in serialisedParcels) 567 foreach (string serialisedParcel in serialisedParcels)
383 { 568 {
384 LandData parcel = LandDataSerializer.Deserialize(serialisedParcel); 569 LandData parcel = LandDataSerializer.Deserialize(serialisedParcel);
385 if (!ResolveUserUuid(parcel.OwnerID))
386 parcel.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
387 570
571 // Validate User and Group UUID's
572
573 if (!ResolveUserUuid(scene, parcel.OwnerID))
574 parcel.OwnerID = m_rootScene.RegionInfo.EstateSettings.EstateOwner;
575
576 if (!ResolveGroupUuid(parcel.GroupID))
577 {
578 parcel.GroupID = UUID.Zero;
579 parcel.IsGroupOwned = false;
580 }
581
582 List<LandAccessEntry> accessList = new List<LandAccessEntry>();
583 foreach (LandAccessEntry entry in parcel.ParcelAccessList)
584 {
585 if (ResolveUserUuid(scene, entry.AgentID))
586 accessList.Add(entry);
587 // else, drop this access rule
588 }
589 parcel.ParcelAccessList = accessList;
590
388// m_log.DebugFormat( 591// m_log.DebugFormat(
389// "[ARCHIVER]: Adding parcel {0}, local id {1}, area {2}", 592// "[ARCHIVER]: Adding parcel {0}, local id {1}, area {2}",
390// parcel.Name, parcel.LocalID, parcel.Area); 593// parcel.Name, parcel.LocalID, parcel.Area);
@@ -395,23 +598,24 @@ namespace OpenSim.Region.CoreModules.World.Archiver
395 if (!m_merge) 598 if (!m_merge)
396 { 599 {
397 bool setupDefaultParcel = (landData.Count == 0); 600 bool setupDefaultParcel = (landData.Count == 0);
398 m_scene.LandChannel.Clear(setupDefaultParcel); 601 scene.LandChannel.Clear(setupDefaultParcel);
399 } 602 }
400 603
401 m_scene.EventManager.TriggerIncomingLandDataFromStorage(landData); 604 scene.EventManager.TriggerIncomingLandDataFromStorage(landData);
402 m_log.InfoFormat("[ARCHIVER]: Restored {0} parcels.", landData.Count); 605 m_log.InfoFormat("[ARCHIVER]: Restored {0} parcels.", landData.Count);
403 } 606 }
404 607
405 /// <summary> 608 /// <summary>
406 /// Look up the given user id to check whether it's one that is valid for this grid. 609 /// Look up the given user id to check whether it's one that is valid for this grid.
407 /// </summary> 610 /// </summary>
611 /// <param name="scene"></param>
408 /// <param name="uuid"></param> 612 /// <param name="uuid"></param>
409 /// <returns></returns> 613 /// <returns></returns>
410 private bool ResolveUserUuid(UUID uuid) 614 private bool ResolveUserUuid(Scene scene, UUID uuid)
411 { 615 {
412 if (!m_validUserUuids.ContainsKey(uuid)) 616 if (!m_validUserUuids.ContainsKey(uuid))
413 { 617 {
414 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid); 618 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, uuid);
415 m_validUserUuids.Add(uuid, account != null); 619 m_validUserUuids.Add(uuid, account != null);
416 } 620 }
417 621
@@ -419,6 +623,30 @@ namespace OpenSim.Region.CoreModules.World.Archiver
419 } 623 }
420 624
421 /// <summary> 625 /// <summary>
626 /// Look up the given group id to check whether it's one that is valid for this grid.
627 /// </summary>
628 /// <param name="uuid"></param>
629 /// <returns></returns>
630 private bool ResolveGroupUuid(UUID uuid)
631 {
632 if (uuid == UUID.Zero)
633 return true; // this means the object has no group
634
635 if (!m_validGroupUuids.ContainsKey(uuid))
636 {
637 bool exists;
638
639 if (m_groupsModule == null)
640 exists = false;
641 else
642 exists = (m_groupsModule.GetGroupRecord(uuid) != null);
643
644 m_validGroupUuids.Add(uuid, exists);
645 }
646
647 return m_validGroupUuids[uuid];
648 }
649
422 /// Load an asset 650 /// Load an asset
423 /// </summary> 651 /// </summary>
424 /// <param name="assetFilename"></param> 652 /// <param name="assetFilename"></param>
@@ -442,7 +670,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
442 string extension = filename.Substring(i); 670 string extension = filename.Substring(i);
443 string uuid = filename.Remove(filename.Length - extension.Length); 671 string uuid = filename.Remove(filename.Length - extension.Length);
444 672
445 if (m_scene.AssetService.GetMetadata(uuid) != null) 673 if (m_assetService.GetMetadata(uuid) != null)
446 { 674 {
447 // m_log.DebugFormat("[ARCHIVER]: found existing asset {0}",uuid); 675 // m_log.DebugFormat("[ARCHIVER]: found existing asset {0}",uuid);
448 return true; 676 return true;
@@ -462,7 +690,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
462 690
463 // We're relying on the asset service to do the sensible thing and not store the asset if it already 691 // We're relying on the asset service to do the sensible thing and not store the asset if it already
464 // exists. 692 // exists.
465 m_scene.AssetService.Store(asset); 693 m_assetService.Store(asset);
466 694
467 /** 695 /**
468 * Create layers on decode for image assets. This is likely to significantly increase the time to load archives so 696 * Create layers on decode for image assets. This is likely to significantly increase the time to load archives so
@@ -490,12 +718,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
490 /// <summary> 718 /// <summary>
491 /// Load region settings data 719 /// Load region settings data
492 /// </summary> 720 /// </summary>
721 /// <param name="scene"></param>
493 /// <param name="settingsPath"></param> 722 /// <param name="settingsPath"></param>
494 /// <param name="data"></param> 723 /// <param name="data"></param>
724 /// <param name="dearchivedScenes"></param>
495 /// <returns> 725 /// <returns>
496 /// true if settings were loaded successfully, false otherwise 726 /// true if settings were loaded successfully, false otherwise
497 /// </returns> 727 /// </returns>
498 private bool LoadRegionSettings(string settingsPath, byte[] data) 728 private bool LoadRegionSettings(Scene scene, string settingsPath, byte[] data, DearchiveScenesInfo dearchivedScenes)
499 { 729 {
500 RegionSettings loadedRegionSettings; 730 RegionSettings loadedRegionSettings;
501 731
@@ -511,7 +741,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
511 return false; 741 return false;
512 } 742 }
513 743
514 RegionSettings currentRegionSettings = m_scene.RegionInfo.RegionSettings; 744 RegionSettings currentRegionSettings = scene.RegionInfo.RegionSettings;
515 745
516 currentRegionSettings.AgentLimit = loadedRegionSettings.AgentLimit; 746 currentRegionSettings.AgentLimit = loadedRegionSettings.AgentLimit;
517 currentRegionSettings.AllowDamage = loadedRegionSettings.AllowDamage; 747 currentRegionSettings.AllowDamage = loadedRegionSettings.AllowDamage;
@@ -548,12 +778,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
548 foreach (SpawnPoint sp in loadedRegionSettings.SpawnPoints()) 778 foreach (SpawnPoint sp in loadedRegionSettings.SpawnPoints())
549 currentRegionSettings.AddSpawnPoint(sp); 779 currentRegionSettings.AddSpawnPoint(sp);
550 780
781 currentRegionSettings.LoadedCreationDateTime = dearchivedScenes.LoadedCreationDateTime;
782 currentRegionSettings.LoadedCreationID = dearchivedScenes.GetOriginalRegionID(scene.RegionInfo.RegionID).ToString();
783
551 currentRegionSettings.Save(); 784 currentRegionSettings.Save();
552 785
553 m_scene.TriggerEstateSunUpdate(); 786 scene.TriggerEstateSunUpdate();
554 787
555 IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>(); 788 IEstateModule estateModule = scene.RequestModuleInterface<IEstateModule>();
556
557 if (estateModule != null) 789 if (estateModule != null)
558 estateModule.sendRegionHandshakeToAll(); 790 estateModule.sendRegionHandshakeToAll();
559 791
@@ -563,14 +795,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver
563 /// <summary> 795 /// <summary>
564 /// Load terrain data 796 /// Load terrain data
565 /// </summary> 797 /// </summary>
798 /// <param name="scene"></param>
566 /// <param name="terrainPath"></param> 799 /// <param name="terrainPath"></param>
567 /// <param name="data"></param> 800 /// <param name="data"></param>
568 /// <returns> 801 /// <returns>
569 /// true if terrain was resolved successfully, false otherwise. 802 /// true if terrain was resolved successfully, false otherwise.
570 /// </returns> 803 /// </returns>
571 private bool LoadTerrain(string terrainPath, byte[] data) 804 private bool LoadTerrain(Scene scene, string terrainPath, byte[] data)
572 { 805 {
573 ITerrainModule terrainModule = m_scene.RequestModuleInterface<ITerrainModule>(); 806 ITerrainModule terrainModule = scene.RequestModuleInterface<ITerrainModule>();
574 807
575 MemoryStream ms = new MemoryStream(data); 808 MemoryStream ms = new MemoryStream(data);
576 terrainModule.LoadFromStream(terrainPath, ms); 809 terrainModule.LoadFromStream(terrainPath, ms);
@@ -586,17 +819,18 @@ namespace OpenSim.Region.CoreModules.World.Archiver
586 /// </summary> 819 /// </summary>
587 /// <param name="path"></param> 820 /// <param name="path"></param>
588 /// <param name="data"></param> 821 /// <param name="data"></param>
589 public void LoadControlFile(string path, byte[] data) 822 /// <param name="dearchivedScenes"></param>
823 public DearchiveScenesInfo LoadControlFile(string path, byte[] data, DearchiveScenesInfo dearchivedScenes)
590 { 824 {
591 XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable()); 825 XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable());
592 XmlParserContext context = new XmlParserContext(null, nsmgr, null, XmlSpace.None); 826 XmlParserContext context = new XmlParserContext(null, nsmgr, null, XmlSpace.None);
593 XmlTextReader xtr = new XmlTextReader(Encoding.ASCII.GetString(data), XmlNodeType.Document, context); 827 XmlTextReader xtr = new XmlTextReader(Encoding.ASCII.GetString(data), XmlNodeType.Document, context);
594 828
595 RegionSettings currentRegionSettings = m_scene.RegionInfo.RegionSettings; 829 // Loaded metadata will be empty if no information exists in the archive
830 dearchivedScenes.LoadedCreationDateTime = 0;
831 dearchivedScenes.DefaultOriginalID = "";
596 832
597 // Loaded metadata will empty if no information exists in the archive 833 bool multiRegion = false;
598 currentRegionSettings.LoadedCreationDateTime = 0;
599 currentRegionSettings.LoadedCreationID = "";
600 834
601 while (xtr.Read()) 835 while (xtr.Read())
602 { 836 {
@@ -622,18 +856,44 @@ namespace OpenSim.Region.CoreModules.World.Archiver
622 { 856 {
623 int value; 857 int value;
624 if (Int32.TryParse(xtr.ReadElementContentAsString(), out value)) 858 if (Int32.TryParse(xtr.ReadElementContentAsString(), out value))
625 currentRegionSettings.LoadedCreationDateTime = value; 859 dearchivedScenes.LoadedCreationDateTime = value;
626 } 860 }
627 else if (xtr.Name.ToString() == "id") 861 else if (xtr.Name.ToString() == "row")
862 {
863 multiRegion = true;
864 dearchivedScenes.StartRow();
865 }
866 else if (xtr.Name.ToString() == "region")
867 {
868 dearchivedScenes.StartRegion();
869 }
870 else if (xtr.Name.ToString() == "id")
871 {
872 string id = xtr.ReadElementContentAsString();
873 dearchivedScenes.DefaultOriginalID = id;
874 if (multiRegion)
875 dearchivedScenes.SetRegionOriginalID(id);
876 }
877 else if (xtr.Name.ToString() == "dir")
628 { 878 {
629 currentRegionSettings.LoadedCreationID = xtr.ReadElementContentAsString(); 879 dearchivedScenes.SetRegionDirectory(xtr.ReadElementContentAsString());
630 } 880 }
631 } 881 }
632 } 882 }
633 883
634 currentRegionSettings.Save(); 884 dearchivedScenes.MultiRegionFormat = multiRegion;
635 885 if (!multiRegion)
886 {
887 // Add the single scene
888 dearchivedScenes.StartRow();
889 dearchivedScenes.StartRegion();
890 dearchivedScenes.SetRegionOriginalID(dearchivedScenes.DefaultOriginalID);
891 dearchivedScenes.SetRegionDirectory("");
892 }
893
636 ControlFileLoaded = true; 894 ControlFileLoaded = true;
895
896 return dearchivedScenes;
637 } 897 }
638 } 898 }
639} \ No newline at end of file 899}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveScenesGroup.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveScenesGroup.cs
new file mode 100644
index 0000000..d8dace2
--- /dev/null
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveScenesGroup.cs
@@ -0,0 +1,176 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Text;
32using OpenSim.Region.Framework.Scenes;
33using OpenMetaverse;
34using System.Drawing;
35
36namespace OpenSim.Region.CoreModules.World.Archiver
37{
38 /// <summary>
39 /// A group of regions arranged in a rectangle, possibly with holes.
40 /// </summary>
41 /// <remarks>
42 /// The regions usually (but not necessarily) belong to an archive file, in which case we
43 /// store additional information used to create the archive (e.g., each region's
44 /// directory within the archive).
45 /// </remarks>
46 public class ArchiveScenesGroup
47 {
48 /// <summary>
49 /// All the regions. The outer dictionary contains rows (key: Y coordinate).
50 /// The inner dictionaries contain each row's regions (key: X coordinate).
51 /// </summary>
52 public SortedDictionary<uint, SortedDictionary<uint, Scene>> Regions { get; set; }
53
54 /// <summary>
55 /// The subdirectory where each region is stored in the archive.
56 /// </summary>
57 protected Dictionary<UUID, string> m_regionDirs;
58
59 /// <summary>
60 /// The grid coordinates of the regions' bounding box.
61 /// </summary>
62 public Rectangle Rect { get; set; }
63
64
65 public ArchiveScenesGroup()
66 {
67 Regions = new SortedDictionary<uint, SortedDictionary<uint, Scene>>();
68 m_regionDirs = new Dictionary<UUID, string>();
69 Rect = new Rectangle(0, 0, 0, 0);
70 }
71
72 public void AddScene(Scene scene)
73 {
74 uint x = scene.RegionInfo.RegionLocX;
75 uint y = scene.RegionInfo.RegionLocY;
76
77 SortedDictionary<uint, Scene> row;
78 if (!Regions.TryGetValue(y, out row))
79 {
80 row = new SortedDictionary<uint, Scene>();
81 Regions[y] = row;
82 }
83
84 row[x] = scene;
85 }
86
87 /// <summary>
88 /// Called after all the scenes have been added. Performs calculations that require
89 /// knowledge of all the scenes.
90 /// </summary>
91 public void CalcSceneLocations()
92 {
93 if (Regions.Count == 0)
94 return;
95
96 // Find the bounding rectangle
97
98 uint firstY = Regions.First().Key;
99 uint lastY = Regions.Last().Key;
100
101 uint? firstX = null;
102 uint? lastX = null;
103
104 foreach (SortedDictionary<uint, Scene> row in Regions.Values)
105 {
106 uint curFirstX = row.First().Key;
107 uint curLastX = row.Last().Key;
108
109 firstX = (firstX == null) ? curFirstX : (firstX < curFirstX) ? firstX : curFirstX;
110 lastX = (lastX == null) ? curLastX : (lastX > curLastX) ? lastX : curLastX;
111 }
112
113 Rect = new Rectangle((int)firstX, (int)firstY, (int)(lastX - firstX + 1), (int)(lastY - firstY + 1));
114
115
116 // Calculate the subdirectory in which each region will be stored in the archive
117
118 m_regionDirs.Clear();
119 ForEachScene(delegate(Scene scene)
120 {
121 // We add the region's coordinates to ensure uniqueness even if multiple regions have the same name
122 string path = string.Format("{0}_{1}_{2}",
123 scene.RegionInfo.RegionLocX - Rect.X + 1,
124 scene.RegionInfo.RegionLocY - Rect.Y + 1,
125 scene.RegionInfo.RegionName.Replace(' ', '_'));
126 m_regionDirs[scene.RegionInfo.RegionID] = path;
127 });
128 }
129
130 /// <summary>
131 /// Returns the subdirectory where the region is stored.
132 /// </summary>
133 /// <param name="regionID"></param>
134 /// <returns></returns>
135 public string GetRegionDir(UUID regionID)
136 {
137 return m_regionDirs[regionID];
138 }
139
140 /// <summary>
141 /// Performs an action on all the scenes in this order: rows from South to North,
142 /// and within each row West to East.
143 /// </summary>
144 /// <param name="action"></param>
145 public void ForEachScene(Action<Scene> action)
146 {
147 foreach (SortedDictionary<uint, Scene> row in Regions.Values)
148 {
149 foreach (Scene scene in row.Values)
150 {
151 action(scene);
152 }
153 }
154 }
155
156 /// <summary>
157 /// Returns the scene at position 'location'.
158 /// </summary>
159 /// <param name="location">A location in the grid</param>
160 /// <param name="scene">The scene at this location</param>
161 /// <returns>Whether the scene was found</returns>
162 public bool TryGetScene(Point location, out Scene scene)
163 {
164 SortedDictionary<uint, Scene> row;
165 if (Regions.TryGetValue((uint)location.Y, out row))
166 {
167 if (row.TryGetValue((uint)location.X, out scene))
168 return true;
169 }
170
171 scene = null;
172 return false;
173 }
174
175 }
176}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
new file mode 100644
index 0000000..d751b1c
--- /dev/null
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
@@ -0,0 +1,634 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.IO.Compression;
32using System.Reflection;
33using System.Text.RegularExpressions;
34using System.Threading;
35using System.Xml;
36using log4net;
37using OpenMetaverse;
38using OpenSim.Framework;
39using OpenSim.Framework.Serialization;
40using OpenSim.Region.CoreModules.World.Terrain;
41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.Framework.Scenes;
43using Ionic.Zlib;
44using GZipStream = Ionic.Zlib.GZipStream;
45using CompressionMode = Ionic.Zlib.CompressionMode;
46using OpenSim.Framework.Serialization.External;
47
48namespace OpenSim.Region.CoreModules.World.Archiver
49{
50 /// <summary>
51 /// Prepare to write out an archive.
52 /// </summary>
53 public class ArchiveWriteRequest
54 {
55 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56
57 /// <summary>
58 /// The minimum major version of OAR that we can write.
59 /// </summary>
60 public static int MIN_MAJOR_VERSION = 0;
61
62 /// <summary>
63 /// The maximum major version of OAR that we can write.
64 /// </summary>
65 public static int MAX_MAJOR_VERSION = 1;
66
67 /// <summary>
68 /// Whether we're saving a multi-region archive.
69 /// </summary>
70 public bool MultiRegionFormat { get; set; }
71
72 /// <summary>
73 /// Determine whether this archive will save assets. Default is true.
74 /// </summary>
75 public bool SaveAssets { get; set; }
76
77 /// <summary>
78 /// Determines which objects will be included in the archive, according to their permissions.
79 /// Default is null, meaning no permission checks.
80 /// </summary>
81 public string CheckPermissions { get; set; }
82
83 protected Scene m_rootScene;
84 protected Stream m_saveStream;
85 protected TarArchiveWriter m_archiveWriter;
86 protected Guid m_requestId;
87 protected Dictionary<string, object> m_options;
88
89 /// <summary>
90 /// Constructor
91 /// </summary>
92 /// <param name="module">Calling module</param>
93 /// <param name="savePath">The path to which to save data.</param>
94 /// <param name="requestId">The id associated with this request</param>
95 /// <exception cref="System.IO.IOException">
96 /// If there was a problem opening a stream for the file specified by the savePath
97 /// </exception>
98 public ArchiveWriteRequest(Scene scene, string savePath, Guid requestId) : this(scene, requestId)
99 {
100 try
101 {
102 m_saveStream = new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress, CompressionLevel.BestCompression);
103 }
104 catch (EntryPointNotFoundException e)
105 {
106 m_log.ErrorFormat(
107 "[ARCHIVER]: Mismatch between Mono and zlib1g library version when trying to create compression stream."
108 + "If you've manually installed Mono, have you appropriately updated zlib1g as well?");
109 m_log.ErrorFormat("{0} {1}", e.Message, e.StackTrace);
110 }
111 }
112
113 /// <summary>
114 /// Constructor.
115 /// </summary>
116 /// <param name="scene">The root scene to archive</param>
117 /// <param name="saveStream">The stream to which to save data.</param>
118 /// <param name="requestId">The id associated with this request</param>
119 public ArchiveWriteRequest(Scene scene, Stream saveStream, Guid requestId) : this(scene, requestId)
120 {
121 m_saveStream = saveStream;
122 }
123
124 protected ArchiveWriteRequest(Scene scene, Guid requestId)
125 {
126 m_rootScene = scene;
127 m_requestId = requestId;
128 m_archiveWriter = null;
129
130 MultiRegionFormat = false;
131 SaveAssets = true;
132 CheckPermissions = null;
133 }
134
135 /// <summary>
136 /// Archive the region requested.
137 /// </summary>
138 /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception>
139 public void ArchiveRegion(Dictionary<string, object> options)
140 {
141 m_options = options;
142
143 if (options.ContainsKey("all") && (bool)options["all"])
144 MultiRegionFormat = true;
145
146 if (options.ContainsKey("noassets") && (bool)options["noassets"])
147 SaveAssets = false;
148
149 Object temp;
150 if (options.TryGetValue("checkPermissions", out temp))
151 CheckPermissions = (string)temp;
152
153
154 // Find the regions to archive
155 ArchiveScenesGroup scenesGroup = new ArchiveScenesGroup();
156 if (MultiRegionFormat)
157 {
158 m_log.InfoFormat("[ARCHIVER]: Saving {0} regions", SceneManager.Instance.Scenes.Count);
159 SceneManager.Instance.ForEachScene(delegate(Scene scene)
160 {
161 scenesGroup.AddScene(scene);
162 });
163 }
164 else
165 {
166 scenesGroup.AddScene(m_rootScene);
167 }
168 scenesGroup.CalcSceneLocations();
169
170
171 m_archiveWriter = new TarArchiveWriter(m_saveStream);
172
173 try
174 {
175 // Write out control file. It should be first so that it will be found ASAP when loading the file.
176 m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(scenesGroup));
177 m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");
178
179 // Archive the regions
180
181 Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>();
182
183 scenesGroup.ForEachScene(delegate(Scene scene)
184 {
185 string regionDir = MultiRegionFormat ? scenesGroup.GetRegionDir(scene.RegionInfo.RegionID) : "";
186 ArchiveOneRegion(scene, regionDir, assetUuids);
187 });
188
189 // Archive the assets
190
191 if (SaveAssets)
192 {
193 m_log.DebugFormat("[ARCHIVER]: Saving {0} assets", assetUuids.Count);
194
195 // Asynchronously request all the assets required to perform this archive operation
196 AssetsRequest ar
197 = new AssetsRequest(
198 new AssetsArchiver(m_archiveWriter), assetUuids,
199 m_rootScene.AssetService, m_rootScene.UserAccountService,
200 m_rootScene.RegionInfo.ScopeID, options, ReceivedAllAssets);
201
202 Util.FireAndForget(o => ar.Execute());
203
204 // CloseArchive() will be called from ReceivedAllAssets()
205 }
206 else
207 {
208 m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified");
209 CloseArchive(string.Empty);
210 }
211 }
212 catch (Exception e)
213 {
214 CloseArchive(e.Message);
215 throw;
216 }
217 }
218
219
220 private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary<UUID, AssetType> assetUuids)
221 {
222 m_log.InfoFormat("[ARCHIVER]: Writing region {0}", scene.RegionInfo.RegionName);
223
224 EntityBase[] entities = scene.GetEntities();
225 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
226
227 int numObjectsSkippedPermissions = 0;
228
229 // Filter entities so that we only have scene objects.
230 // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods
231 // end up having to do this
232 IPermissionsModule permissionsModule = scene.RequestModuleInterface<IPermissionsModule>();
233 foreach (EntityBase entity in entities)
234 {
235 if (entity is SceneObjectGroup)
236 {
237 SceneObjectGroup sceneObject = (SceneObjectGroup)entity;
238
239 if (!sceneObject.IsDeleted && !sceneObject.IsAttachment)
240 {
241 if (!CanUserArchiveObject(scene.RegionInfo.EstateSettings.EstateOwner, sceneObject, CheckPermissions, permissionsModule))
242 {
243 // The user isn't allowed to copy/transfer this object, so it will not be included in the OAR.
244 ++numObjectsSkippedPermissions;
245 }
246 else
247 {
248 sceneObjects.Add(sceneObject);
249 }
250 }
251 }
252 }
253
254 if (SaveAssets)
255 {
256 UuidGatherer assetGatherer = new UuidGatherer(scene.AssetService);
257 int prevAssets = assetUuids.Count;
258
259 foreach (SceneObjectGroup sceneObject in sceneObjects)
260 {
261 assetGatherer.GatherAssetUuids(sceneObject, assetUuids);
262 }
263
264 m_log.DebugFormat(
265 "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
266 sceneObjects.Count, assetUuids.Count - prevAssets);
267 }
268
269 if (numObjectsSkippedPermissions > 0)
270 {
271 m_log.DebugFormat(
272 "[ARCHIVER]: {0} scene objects skipped due to lack of permissions",
273 numObjectsSkippedPermissions);
274 }
275
276 // Make sure that we also request terrain texture assets
277 RegionSettings regionSettings = scene.RegionInfo.RegionSettings;
278
279 if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1)
280 assetUuids[regionSettings.TerrainTexture1] = AssetType.Texture;
281
282 if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2)
283 assetUuids[regionSettings.TerrainTexture2] = AssetType.Texture;
284
285 if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3)
286 assetUuids[regionSettings.TerrainTexture3] = AssetType.Texture;
287
288 if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4)
289 assetUuids[regionSettings.TerrainTexture4] = AssetType.Texture;
290
291 Save(scene, sceneObjects, regionDir);
292 }
293
294 /// <summary>
295 /// Checks whether the user has permission to export an object group to an OAR.
296 /// </summary>
297 /// <param name="user">The user</param>
298 /// <param name="objGroup">The object group</param>
299 /// <param name="checkPermissions">Which permissions to check: "C" = Copy, "T" = Transfer</param>
300 /// <param name="permissionsModule">The scene's permissions module</param>
301 /// <returns>Whether the user is allowed to export the object to an OAR</returns>
302 private bool CanUserArchiveObject(UUID user, SceneObjectGroup objGroup, string checkPermissions, IPermissionsModule permissionsModule)
303 {
304 if (checkPermissions == null)
305 return true;
306
307 if (permissionsModule == null)
308 return true; // this shouldn't happen
309
310 // Check whether the user is permitted to export all of the parts in the SOG. If any
311 // part can't be exported then the entire SOG can't be exported.
312
313 bool permitted = true;
314 //int primNumber = 1;
315
316 foreach (SceneObjectPart obj in objGroup.Parts)
317 {
318 uint perm;
319 PermissionClass permissionClass = permissionsModule.GetPermissionClass(user, obj);
320 switch (permissionClass)
321 {
322 case PermissionClass.Owner:
323 perm = obj.BaseMask;
324 break;
325 case PermissionClass.Group:
326 perm = obj.GroupMask | obj.EveryoneMask;
327 break;
328 case PermissionClass.Everyone:
329 default:
330 perm = obj.EveryoneMask;
331 break;
332 }
333
334 bool canCopy = (perm & (uint)PermissionMask.Copy) != 0;
335 bool canTransfer = (perm & (uint)PermissionMask.Transfer) != 0;
336
337 // Special case: if Everyone can copy the object then this implies it can also be
338 // Transferred.
339 // However, if the user is the Owner then we don't check EveryoneMask, because it seems that the mask
340 // always (incorrectly) includes the Copy bit set in this case. But that's a mistake: the viewer
341 // does NOT show that the object has Everyone-Copy permissions, and doesn't allow it to be copied.
342 if (permissionClass != PermissionClass.Owner)
343 canTransfer |= (obj.EveryoneMask & (uint)PermissionMask.Copy) != 0;
344
345 bool partPermitted = true;
346 if (checkPermissions.Contains("C") && !canCopy)
347 partPermitted = false;
348 if (checkPermissions.Contains("T") && !canTransfer)
349 partPermitted = false;
350
351 // If the user is the Creator of the object then it can always be included in the OAR
352 bool creator = (obj.CreatorID.Guid == user.Guid);
353 if (creator)
354 partPermitted = true;
355
356 //string name = (objGroup.PrimCount == 1) ? objGroup.Name : string.Format("{0} ({1}/{2})", obj.Name, primNumber, objGroup.PrimCount);
357 //m_log.DebugFormat("[ARCHIVER]: Object permissions: {0}: Base={1:X4}, Owner={2:X4}, Everyone={3:X4}, permissionClass={4}, checkPermissions={5}, canCopy={6}, canTransfer={7}, creator={8}, permitted={9}",
358 // name, obj.BaseMask, obj.OwnerMask, obj.EveryoneMask,
359 // permissionClass, checkPermissions, canCopy, canTransfer, creator, partPermitted);
360
361 if (!partPermitted)
362 {
363 permitted = false;
364 break;
365 }
366
367 //++primNumber;
368 }
369
370 return permitted;
371 }
372
373 /// <summary>
374 /// Create the control file.
375 /// </summary>
376 /// <returns></returns>
377 public string CreateControlFile(ArchiveScenesGroup scenesGroup)
378 {
379 int majorVersion;
380 int minorVersion;
381
382 if (MultiRegionFormat)
383 {
384 majorVersion = MAX_MAJOR_VERSION;
385 minorVersion = 0;
386 }
387 else
388 {
389 // To support older versions of OpenSim, we continue to create single-region OARs
390 // using the old file format. In the future this format will be discontinued.
391 majorVersion = 0;
392 minorVersion = 8;
393 }
394//
395// if (m_options.ContainsKey("version"))
396// {
397// string[] parts = m_options["version"].ToString().Split('.');
398// if (parts.Length >= 1)
399// {
400// majorVersion = Int32.Parse(parts[0]);
401//
402// if (parts.Length >= 2)
403// minorVersion = Int32.Parse(parts[1]);
404// }
405// }
406//
407// if (majorVersion < MIN_MAJOR_VERSION || majorVersion > MAX_MAJOR_VERSION)
408// {
409// throw new Exception(
410// string.Format(
411// "OAR version number for save must be between {0} and {1}",
412// MIN_MAJOR_VERSION, MAX_MAJOR_VERSION));
413// }
414// else if (majorVersion == MAX_MAJOR_VERSION)
415// {
416// // Force 1.0
417// minorVersion = 0;
418// }
419// else if (majorVersion == MIN_MAJOR_VERSION)
420// {
421// // Force 0.4
422// minorVersion = 4;
423// }
424
425 m_log.InfoFormat("[ARCHIVER]: Creating version {0}.{1} OAR", majorVersion, minorVersion);
426 if (majorVersion == 1)
427 {
428 m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim versions prior to 0.7.4. Do not use the --all option if you want to produce a compatible OAR");
429 }
430
431 String s;
432
433 using (StringWriter sw = new StringWriter())
434 {
435 using (XmlTextWriter xtw = new XmlTextWriter(sw))
436 {
437 xtw.Formatting = Formatting.Indented;
438 xtw.WriteStartDocument();
439 xtw.WriteStartElement("archive");
440 xtw.WriteAttributeString("major_version", majorVersion.ToString());
441 xtw.WriteAttributeString("minor_version", minorVersion.ToString());
442
443 xtw.WriteStartElement("creation_info");
444 DateTime now = DateTime.UtcNow;
445 TimeSpan t = now - new DateTime(1970, 1, 1);
446 xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString());
447 if (!MultiRegionFormat)
448 xtw.WriteElementString("id", m_rootScene.RegionInfo.RegionID.ToString());
449 xtw.WriteEndElement();
450
451 xtw.WriteElementString("assets_included", SaveAssets.ToString());
452
453 if (MultiRegionFormat)
454 {
455 WriteRegionsManifest(scenesGroup, xtw);
456 }
457 else
458 {
459 xtw.WriteStartElement("region_info");
460 WriteRegionInfo(m_rootScene, xtw);
461 xtw.WriteEndElement();
462 }
463
464 xtw.WriteEndElement();
465
466 xtw.Flush();
467 }
468
469 s = sw.ToString();
470 }
471
472 return s;
473 }
474
475 /// <summary>
476 /// Writes the list of regions included in a multi-region OAR.
477 /// </summary>
478 private static void WriteRegionsManifest(ArchiveScenesGroup scenesGroup, XmlTextWriter xtw)
479 {
480 xtw.WriteStartElement("regions");
481
482 // Write the regions in order: rows from South to North, then regions from West to East.
483 // The list of regions can have "holes"; we write empty elements in their position.
484
485 for (uint y = (uint)scenesGroup.Rect.Top; y < scenesGroup.Rect.Bottom; ++y)
486 {
487 SortedDictionary<uint, Scene> row;
488 if (scenesGroup.Regions.TryGetValue(y, out row))
489 {
490 xtw.WriteStartElement("row");
491
492 for (uint x = (uint)scenesGroup.Rect.Left; x < scenesGroup.Rect.Right; ++x)
493 {
494 Scene scene;
495 if (row.TryGetValue(x, out scene))
496 {
497 xtw.WriteStartElement("region");
498 xtw.WriteElementString("id", scene.RegionInfo.RegionID.ToString());
499 xtw.WriteElementString("dir", scenesGroup.GetRegionDir(scene.RegionInfo.RegionID));
500 WriteRegionInfo(scene, xtw);
501 xtw.WriteEndElement();
502 }
503 else
504 {
505 // Write a placeholder for a missing region
506 xtw.WriteElementString("region", "");
507 }
508 }
509
510 xtw.WriteEndElement();
511 }
512 else
513 {
514 // Write a placeholder for a missing row
515 xtw.WriteElementString("row", "");
516 }
517 }
518
519 xtw.WriteEndElement(); // "regions"
520 }
521
522 protected static void WriteRegionInfo(Scene scene, XmlTextWriter xtw)
523 {
524 bool isMegaregion;
525 Vector2 size;
526
527 IRegionCombinerModule rcMod = scene.RequestModuleInterface<IRegionCombinerModule>();
528
529 if (rcMod != null)
530 isMegaregion = rcMod.IsRootForMegaregion(scene.RegionInfo.RegionID);
531 else
532 isMegaregion = false;
533
534 if (isMegaregion)
535 size = rcMod.GetSizeOfMegaregion(scene.RegionInfo.RegionID);
536 else
537 size = new Vector2((float)Constants.RegionSize, (float)Constants.RegionSize);
538
539 xtw.WriteElementString("is_megaregion", isMegaregion.ToString());
540 xtw.WriteElementString("size_in_meters", string.Format("{0},{1}", size.X, size.Y));
541 }
542
543
544 protected void Save(Scene scene, List<SceneObjectGroup> sceneObjects, string regionDir)
545 {
546 if (regionDir != string.Empty)
547 regionDir = ArchiveConstants.REGIONS_PATH + regionDir + "/";
548
549 m_log.InfoFormat("[ARCHIVER]: Adding region settings to archive.");
550
551 // Write out region settings
552 string settingsPath = String.Format("{0}{1}{2}.xml",
553 regionDir, ArchiveConstants.SETTINGS_PATH, scene.RegionInfo.RegionName);
554 m_archiveWriter.WriteFile(settingsPath, RegionSettingsSerializer.Serialize(scene.RegionInfo.RegionSettings));
555
556 m_log.InfoFormat("[ARCHIVER]: Adding parcel settings to archive.");
557
558 // Write out land data (aka parcel) settings
559 List<ILandObject> landObjects = scene.LandChannel.AllParcels();
560 foreach (ILandObject lo in landObjects)
561 {
562 LandData landData = lo.LandData;
563 string landDataPath = String.Format("{0}{1}{2}.xml",
564 regionDir, ArchiveConstants.LANDDATA_PATH, landData.GlobalID.ToString());
565 m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData, m_options));
566 }
567
568 m_log.InfoFormat("[ARCHIVER]: Adding terrain information to archive.");
569
570 // Write out terrain
571 string terrainPath = String.Format("{0}{1}{2}.r32",
572 regionDir, ArchiveConstants.TERRAINS_PATH, scene.RegionInfo.RegionName);
573
574 MemoryStream ms = new MemoryStream();
575 scene.RequestModuleInterface<ITerrainModule>().SaveToStream(terrainPath, ms);
576 m_archiveWriter.WriteFile(terrainPath, ms.ToArray());
577 ms.Close();
578
579 m_log.InfoFormat("[ARCHIVER]: Adding scene objects to archive.");
580
581 // Write out scene object metadata
582 IRegionSerialiserModule serializer = scene.RequestModuleInterface<IRegionSerialiserModule>();
583 foreach (SceneObjectGroup sceneObject in sceneObjects)
584 {
585 //m_log.DebugFormat("[ARCHIVER]: Saving {0} {1}, {2}", entity.Name, entity.UUID, entity.GetType());
586
587 string serializedObject = serializer.SerializeGroupToXml2(sceneObject, m_options);
588 string objectPath = string.Format("{0}{1}", regionDir, ArchiveHelpers.CreateObjectPath(sceneObject));
589 m_archiveWriter.WriteFile(objectPath, serializedObject);
590 }
591 }
592
593 protected void ReceivedAllAssets(
594 ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids)
595 {
596 foreach (UUID uuid in assetsNotFoundUuids)
597 {
598 m_log.DebugFormat("[ARCHIVER]: Could not find asset {0}", uuid);
599 }
600
601 // m_log.InfoFormat(
602 // "[ARCHIVER]: Received {0} of {1} assets requested",
603 // assetsFoundUuids.Count, assetsFoundUuids.Count + assetsNotFoundUuids.Count);
604
605 CloseArchive(String.Empty);
606 }
607
608
609 /// <summary>
610 /// Closes the archive and notifies that we're done.
611 /// </summary>
612 /// <param name="errorMessage">The error that occurred, or empty for success</param>
613 protected void CloseArchive(string errorMessage)
614 {
615 try
616 {
617 if (m_archiveWriter != null)
618 m_archiveWriter.Close();
619 m_saveStream.Close();
620 }
621 catch (Exception e)
622 {
623 m_log.Error(string.Format("[ARCHIVER]: Error closing archive: {0} ", e.Message), e);
624 if (errorMessage == string.Empty)
625 errorMessage = e.Message;
626 }
627
628 m_log.InfoFormat("[ARCHIVER]: Finished writing out OAR for {0}", m_rootScene.RegionInfo.RegionName);
629
630 m_rootScene.EventManager.TriggerOarFileSaved(m_requestId, errorMessage);
631 }
632
633 }
634}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs
deleted file mode 100644
index 0780d86..0000000
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs
+++ /dev/null
@@ -1,153 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Reflection;
32using System.Xml;
33using log4net;
34using OpenMetaverse;
35using OpenSim.Framework;
36using OpenSim.Framework.Serialization;
37using OpenSim.Framework.Serialization.External;
38using OpenSim.Region.CoreModules.World.Terrain;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41
42namespace OpenSim.Region.CoreModules.World.Archiver
43{
44 /// <summary>
45 /// Method called when all the necessary assets for an archive request have been received.
46 /// </summary>
47 public delegate void AssetsRequestCallback(
48 ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids);
49
50 /// <summary>
51 /// Execute the write of an archive once we have received all the necessary data
52 /// </summary>
53 public class ArchiveWriteRequestExecution
54 {
55 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56
57 protected ITerrainModule m_terrainModule;
58 protected IRegionSerialiserModule m_serialiser;
59 protected List<SceneObjectGroup> m_sceneObjects;
60 protected Scene m_scene;
61 protected TarArchiveWriter m_archiveWriter;
62 protected Guid m_requestId;
63 protected Dictionary<string, object> m_options;
64
65 public ArchiveWriteRequestExecution(
66 List<SceneObjectGroup> sceneObjects,
67 ITerrainModule terrainModule,
68 IRegionSerialiserModule serialiser,
69 Scene scene,
70 TarArchiveWriter archiveWriter,
71 Guid requestId,
72 Dictionary<string, object> options)
73 {
74 m_sceneObjects = sceneObjects;
75 m_terrainModule = terrainModule;
76 m_serialiser = serialiser;
77 m_scene = scene;
78 m_archiveWriter = archiveWriter;
79 m_requestId = requestId;
80 m_options = options;
81 }
82
83 protected internal void ReceivedAllAssets(
84 ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids)
85 {
86 try
87 {
88 Save(assetsFoundUuids, assetsNotFoundUuids);
89 }
90 finally
91 {
92 m_archiveWriter.Close();
93 }
94
95 m_log.InfoFormat("[ARCHIVER]: Finished writing out OAR for {0}", m_scene.RegionInfo.RegionName);
96
97 m_scene.EventManager.TriggerOarFileSaved(m_requestId, String.Empty);
98 }
99
100 protected internal void Save(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids)
101 {
102 foreach (UUID uuid in assetsNotFoundUuids)
103 {
104 m_log.DebugFormat("[ARCHIVER]: Could not find asset {0}", uuid);
105 }
106
107// m_log.InfoFormat(
108// "[ARCHIVER]: Received {0} of {1} assets requested",
109// assetsFoundUuids.Count, assetsFoundUuids.Count + assetsNotFoundUuids.Count);
110
111 m_log.InfoFormat("[ARCHIVER]: Adding region settings to archive.");
112
113 // Write out region settings
114 string settingsPath
115 = String.Format("{0}{1}.xml", ArchiveConstants.SETTINGS_PATH, m_scene.RegionInfo.RegionName);
116 m_archiveWriter.WriteFile(settingsPath, RegionSettingsSerializer.Serialize(m_scene.RegionInfo.RegionSettings));
117
118 m_log.InfoFormat("[ARCHIVER]: Adding parcel settings to archive.");
119
120 // Write out land data (aka parcel) settings
121 List<ILandObject>landObjects = m_scene.LandChannel.AllParcels();
122 foreach (ILandObject lo in landObjects)
123 {
124 LandData landData = lo.LandData;
125 string landDataPath = String.Format("{0}{1}.xml", ArchiveConstants.LANDDATA_PATH,
126 landData.GlobalID.ToString());
127 m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData, m_options));
128 }
129
130 m_log.InfoFormat("[ARCHIVER]: Adding terrain information to archive.");
131
132 // Write out terrain
133 string terrainPath
134 = String.Format("{0}{1}.r32", ArchiveConstants.TERRAINS_PATH, m_scene.RegionInfo.RegionName);
135
136 MemoryStream ms = new MemoryStream();
137 m_terrainModule.SaveToStream(terrainPath, ms);
138 m_archiveWriter.WriteFile(terrainPath, ms.ToArray());
139 ms.Close();
140
141 m_log.InfoFormat("[ARCHIVER]: Adding scene objects to archive.");
142
143 // Write out scene object metadata
144 foreach (SceneObjectGroup sceneObject in m_sceneObjects)
145 {
146 //m_log.DebugFormat("[ARCHIVER]: Saving {0} {1}, {2}", entity.Name, entity.UUID, entity.GetType());
147
148 string serializedObject = m_serialiser.SerializeGroupToXml2(sceneObject, m_options);
149 m_archiveWriter.WriteFile(ArchiveHelpers.CreateObjectPath(sceneObject), serializedObject);
150 }
151 }
152 }
153} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
deleted file mode 100644
index 4edaaca..0000000
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
+++ /dev/null
@@ -1,438 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.IO.Compression;
32using System.Reflection;
33using System.Text.RegularExpressions;
34using System.Threading;
35using System.Xml;
36using log4net;
37using OpenMetaverse;
38using OpenSim.Framework;
39using OpenSim.Framework.Serialization;
40using OpenSim.Region.CoreModules.World.Terrain;
41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.Framework.Scenes;
43using Ionic.Zlib;
44using GZipStream = Ionic.Zlib.GZipStream;
45using CompressionMode = Ionic.Zlib.CompressionMode;
46
47namespace OpenSim.Region.CoreModules.World.Archiver
48{
49 /// <summary>
50 /// Prepare to write out an archive.
51 /// </summary>
52 public class ArchiveWriteRequestPreparation
53 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55
56 /// <summary>
57 /// The minimum major version of OAR that we can write.
58 /// </summary>
59 public static int MIN_MAJOR_VERSION = 0;
60
61 /// <summary>
62 /// The maximum major version of OAR that we can write.
63 /// </summary>
64 public static int MAX_MAJOR_VERSION = 0;
65
66 /// <summary>
67 /// Determine whether this archive will save assets. Default is true.
68 /// </summary>
69 public bool SaveAssets { get; set; }
70
71 protected ArchiverModule m_module;
72 protected Scene m_scene;
73 protected Stream m_saveStream;
74 protected Guid m_requestId;
75
76 /// <summary>
77 /// Constructor
78 /// </summary>
79 /// <param name="module">Calling module</param>
80 /// <param name="savePath">The path to which to save data.</param>
81 /// <param name="requestId">The id associated with this request</param>
82 /// <exception cref="System.IO.IOException">
83 /// If there was a problem opening a stream for the file specified by the savePath
84 /// </exception>
85 public ArchiveWriteRequestPreparation(ArchiverModule module, string savePath, Guid requestId) : this(module, requestId)
86 {
87 try
88 {
89 m_saveStream = new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress, CompressionLevel.BestCompression);
90 }
91 catch (EntryPointNotFoundException e)
92 {
93 m_log.ErrorFormat(
94 "[ARCHIVER]: Mismatch between Mono and zlib1g library version when trying to create compression stream."
95 + "If you've manually installed Mono, have you appropriately updated zlib1g as well?");
96 m_log.ErrorFormat("{0} {1}", e.Message, e.StackTrace);
97 }
98 }
99
100 /// <summary>
101 /// Constructor.
102 /// </summary>
103 /// <param name="module">Calling module</param>
104 /// <param name="saveStream">The stream to which to save data.</param>
105 /// <param name="requestId">The id associated with this request</param>
106 public ArchiveWriteRequestPreparation(ArchiverModule module, Stream saveStream, Guid requestId) : this(module, requestId)
107 {
108 m_saveStream = saveStream;
109 }
110
111 protected ArchiveWriteRequestPreparation(ArchiverModule module, Guid requestId)
112 {
113 m_module = module;
114
115 // FIXME: This is only here for regression test purposes since they do not supply a module. Need to fix
116 // this.
117 if (m_module != null)
118 m_scene = m_module.Scene;
119
120 m_requestId = requestId;
121
122 SaveAssets = true;
123 }
124
125 /// <summary>
126 /// Archive the region requested.
127 /// </summary>
128 /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception>
129 public void ArchiveRegion(Dictionary<string, object> options)
130 {
131 if (options.ContainsKey("noassets") && (bool)options["noassets"])
132 SaveAssets = false;
133
134 try
135 {
136 Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>();
137
138 EntityBase[] entities = m_scene.GetEntities();
139 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
140
141 string checkPermissions = null;
142 int numObjectsSkippedPermissions = 0;
143 Object temp;
144 if (options.TryGetValue("checkPermissions", out temp))
145 checkPermissions = (string)temp;
146
147 // Filter entities so that we only have scene objects.
148 // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods
149 // end up having to do this
150 foreach (EntityBase entity in entities)
151 {
152 if (entity is SceneObjectGroup)
153 {
154 SceneObjectGroup sceneObject = (SceneObjectGroup)entity;
155
156 if (!sceneObject.IsDeleted && !sceneObject.IsAttachment)
157 {
158 if (!CanUserArchiveObject(m_scene.RegionInfo.EstateSettings.EstateOwner, sceneObject, checkPermissions))
159 {
160 // The user isn't allowed to copy/transfer this object, so it will not be included in the OAR.
161 ++numObjectsSkippedPermissions;
162 }
163 else
164 {
165 sceneObjects.Add(sceneObject);
166 }
167 }
168 }
169 }
170
171 if (SaveAssets)
172 {
173 UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService);
174
175 foreach (SceneObjectGroup sceneObject in sceneObjects)
176 {
177 assetGatherer.GatherAssetUuids(sceneObject, assetUuids);
178 }
179
180 m_log.DebugFormat(
181 "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
182 sceneObjects.Count, assetUuids.Count);
183 }
184 else
185 {
186 m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified");
187 }
188
189 if (numObjectsSkippedPermissions > 0)
190 {
191 m_log.DebugFormat(
192 "[ARCHIVER]: {0} scene objects skipped due to lack of permissions",
193 numObjectsSkippedPermissions);
194 }
195
196 // Make sure that we also request terrain texture assets
197 RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings;
198
199 if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1)
200 assetUuids[regionSettings.TerrainTexture1] = AssetType.Texture;
201
202 if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2)
203 assetUuids[regionSettings.TerrainTexture2] = AssetType.Texture;
204
205 if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3)
206 assetUuids[regionSettings.TerrainTexture3] = AssetType.Texture;
207
208 if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4)
209 assetUuids[regionSettings.TerrainTexture4] = AssetType.Texture;
210
211 TarArchiveWriter archiveWriter = new TarArchiveWriter(m_saveStream);
212
213 // Asynchronously request all the assets required to perform this archive operation
214 ArchiveWriteRequestExecution awre
215 = new ArchiveWriteRequestExecution(
216 sceneObjects,
217 m_scene.RequestModuleInterface<ITerrainModule>(),
218 m_scene.RequestModuleInterface<IRegionSerialiserModule>(),
219 m_scene,
220 archiveWriter,
221 m_requestId,
222 options);
223
224 m_log.InfoFormat("[ARCHIVER]: Creating archive file. This may take some time.");
225
226 // Write out control file. This has to be done first so that subsequent loaders will see this file first
227 // XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this
228 archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options));
229 m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");
230
231 if (SaveAssets)
232 {
233 AssetsRequest ar
234 = new AssetsRequest(
235 new AssetsArchiver(archiveWriter), assetUuids,
236 m_scene.AssetService, m_scene.UserAccountService,
237 m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets);
238
239 Util.FireAndForget(o => ar.Execute());
240 }
241 else
242 {
243 awre.ReceivedAllAssets(new List<UUID>(), new List<UUID>());
244 }
245 }
246 catch (Exception)
247 {
248 m_saveStream.Close();
249 throw;
250 }
251 }
252
253 /// <summary>
254 /// Checks whether the user has permission to export an object group to an OAR.
255 /// </summary>
256 /// <param name="user">The user</param>
257 /// <param name="objGroup">The object group</param>
258 /// <param name="checkPermissions">Which permissions to check: "C" = Copy, "T" = Transfer</param>
259 /// <returns>Whether the user is allowed to export the object to an OAR</returns>
260 private bool CanUserArchiveObject(UUID user, SceneObjectGroup objGroup, string checkPermissions)
261 {
262 if (checkPermissions == null)
263 return true;
264
265 IPermissionsModule module = m_scene.RequestModuleInterface<IPermissionsModule>();
266 if (module == null)
267 return true; // this shouldn't happen
268
269 // Check whether the user is permitted to export all of the parts in the SOG. If any
270 // part can't be exported then the entire SOG can't be exported.
271
272 bool permitted = true;
273 //int primNumber = 1;
274
275 foreach (SceneObjectPart obj in objGroup.Parts)
276 {
277 uint perm;
278 PermissionClass permissionClass = module.GetPermissionClass(user, obj);
279 switch (permissionClass)
280 {
281 case PermissionClass.Owner:
282 perm = obj.BaseMask;
283 break;
284 case PermissionClass.Group:
285 perm = obj.GroupMask | obj.EveryoneMask;
286 break;
287 case PermissionClass.Everyone:
288 default:
289 perm = obj.EveryoneMask;
290 break;
291 }
292
293 bool canCopy = (perm & (uint)PermissionMask.Copy) != 0;
294 bool canTransfer = (perm & (uint)PermissionMask.Transfer) != 0;
295
296 // Special case: if Everyone can copy the object then this implies it can also be
297 // Transferred.
298 // However, if the user is the Owner then we don't check EveryoneMask, because it seems that the mask
299 // always (incorrectly) includes the Copy bit set in this case. But that's a mistake: the viewer
300 // does NOT show that the object has Everyone-Copy permissions, and doesn't allow it to be copied.
301 if (permissionClass != PermissionClass.Owner)
302 canTransfer |= (obj.EveryoneMask & (uint)PermissionMask.Copy) != 0;
303
304 bool partPermitted = true;
305 if (checkPermissions.Contains("C") && !canCopy)
306 partPermitted = false;
307 if (checkPermissions.Contains("T") && !canTransfer)
308 partPermitted = false;
309
310 // If the user is the Creator of the object then it can always be included in the OAR
311 bool creator = (obj.CreatorID.Guid == user.Guid);
312 if (creator)
313 partPermitted = true;
314
315 //string name = (objGroup.PrimCount == 1) ? objGroup.Name : string.Format("{0} ({1}/{2})", obj.Name, primNumber, objGroup.PrimCount);
316 //m_log.DebugFormat("[ARCHIVER]: Object permissions: {0}: Base={1:X4}, Owner={2:X4}, Everyone={3:X4}, permissionClass={4}, checkPermissions={5}, canCopy={6}, canTransfer={7}, creator={8}, permitted={9}",
317 // name, obj.BaseMask, obj.OwnerMask, obj.EveryoneMask,
318 // permissionClass, checkPermissions, canCopy, canTransfer, creator, partPermitted);
319
320 if (!partPermitted)
321 {
322 permitted = false;
323 break;
324 }
325
326 //++primNumber;
327 }
328
329 return permitted;
330 }
331
332 /// <summary>
333 /// Create the control file for the most up to date archive
334 /// </summary>
335 /// <returns></returns>
336 public string CreateControlFile(Dictionary<string, object> options)
337 {
338 int majorVersion = MAX_MAJOR_VERSION, minorVersion = 8;
339//
340// if (options.ContainsKey("version"))
341// {
342// string[] parts = options["version"].ToString().Split('.');
343// if (parts.Length >= 1)
344// {
345// majorVersion = Int32.Parse(parts[0]);
346//
347// if (parts.Length >= 2)
348// minorVersion = Int32.Parse(parts[1]);
349// }
350// }
351//
352// if (majorVersion < MIN_MAJOR_VERSION || majorVersion > MAX_MAJOR_VERSION)
353// {
354// throw new Exception(
355// string.Format(
356// "OAR version number for save must be between {0} and {1}",
357// MIN_MAJOR_VERSION, MAX_MAJOR_VERSION));
358// }
359// else if (majorVersion == MAX_MAJOR_VERSION)
360// {
361// // Force 1.0
362// minorVersion = 0;
363// }
364// else if (majorVersion == MIN_MAJOR_VERSION)
365// {
366// // Force 0.4
367// minorVersion = 4;
368// }
369
370 m_log.InfoFormat("[ARCHIVER]: Creating version {0}.{1} OAR", majorVersion, minorVersion);
371 //if (majorVersion == 1)
372 //{
373 // m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR");
374 //}
375
376 String s;
377
378 using (StringWriter sw = new StringWriter())
379 {
380 using (XmlTextWriter xtw = new XmlTextWriter(sw))
381 {
382 xtw.Formatting = Formatting.Indented;
383 xtw.WriteStartDocument();
384 xtw.WriteStartElement("archive");
385 xtw.WriteAttributeString("major_version", majorVersion.ToString());
386 xtw.WriteAttributeString("minor_version", minorVersion.ToString());
387
388 xtw.WriteStartElement("creation_info");
389 DateTime now = DateTime.UtcNow;
390 TimeSpan t = now - new DateTime(1970, 1, 1);
391 xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString());
392 xtw.WriteElementString("id", UUID.Random().ToString());
393 xtw.WriteEndElement();
394
395 xtw.WriteStartElement("region_info");
396
397 bool isMegaregion;
398 Vector2 size;
399 IRegionCombinerModule rcMod = null;
400
401 // FIXME: This is only here for regression test purposes since they do not supply a module. Need to fix
402 // this, possibly by doing control file creation somewhere else.
403 if (m_module != null)
404 rcMod = m_module.RegionCombinerModule;
405
406 if (rcMod != null)
407 isMegaregion = rcMod.IsRootForMegaregion(m_scene.RegionInfo.RegionID);
408 else
409 isMegaregion = false;
410
411 if (isMegaregion)
412 size = rcMod.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID);
413 else
414 size = new Vector2((float)Constants.RegionSize, (float)Constants.RegionSize);
415
416 xtw.WriteElementString("is_megaregion", isMegaregion.ToString());
417 xtw.WriteElementString("size_in_meters", string.Format("{0},{1}", size.X, size.Y));
418
419 xtw.WriteEndElement();
420
421 xtw.WriteElementString("assets_included", SaveAssets.ToString());
422
423 xtw.WriteEndElement();
424
425 xtw.Flush();
426 }
427
428 s = sw.ToString();
429 }
430
431// if (m_scene != null)
432// Console.WriteLine(
433// "[ARCHIVE WRITE REQUEST PREPARATION]: Control file for {0} is: {1}", m_scene.RegionInfo.RegionName, s);
434
435 return s;
436 }
437 }
438}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
index bf3b124..1be6386 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
@@ -32,6 +32,9 @@ using System.Reflection;
32using log4net; 32using log4net;
33using NDesk.Options; 33using NDesk.Options;
34using Nini.Config; 34using Nini.Config;
35using Mono.Addins;
36using OpenSim.Framework;
37using OpenSim.Framework.Console;
35using OpenSim.Region.Framework.Interfaces; 38using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
37 40
@@ -40,6 +43,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
40 /// <summary> 43 /// <summary>
41 /// This module loads and saves OpenSimulator region archives 44 /// This module loads and saves OpenSimulator region archives
42 /// </summary> 45 /// </summary>
46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ArchiverModule")]
43 public class ArchiverModule : INonSharedRegionModule, IRegionArchiverModule 47 public class ArchiverModule : INonSharedRegionModule, IRegionArchiverModule
44 { 48 {
45 private static readonly ILog m_log = 49 private static readonly ILog m_log =
@@ -117,7 +121,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
117// 121//
118// foreach (string param in mainParams) 122// foreach (string param in mainParams)
119// m_log.DebugFormat("GOT PARAM [{0}]", param); 123// m_log.DebugFormat("GOT PARAM [{0}]", param);
120 124
121 if (mainParams.Count > 2) 125 if (mainParams.Count > 2)
122 { 126 {
123 DearchiveRegion(mainParams[2], mergeOar, skipAssets, Guid.Empty); 127 DearchiveRegion(mainParams[2], mergeOar, skipAssets, Guid.Empty);
@@ -146,17 +150,22 @@ namespace OpenSim.Region.CoreModules.World.Archiver
146 ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); 150 ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; });
147 ops.Add("publish", v => options["wipe-owners"] = v != null); 151 ops.Add("publish", v => options["wipe-owners"] = v != null);
148 ops.Add("perm=", delegate(string v) { options["checkPermissions"] = v; }); 152 ops.Add("perm=", delegate(string v) { options["checkPermissions"] = v; });
153 ops.Add("all", delegate(string v) { options["all"] = v != null; });
149 154
150 List<string> mainParams = ops.Parse(cmdparams); 155 List<string> mainParams = ops.Parse(cmdparams);
151 156
157 string path;
152 if (mainParams.Count > 2) 158 if (mainParams.Count > 2)
153 { 159 path = mainParams[2];
154 ArchiveRegion(mainParams[2], options);
155 }
156 else 160 else
157 { 161 path = DEFAULT_OAR_BACKUP_FILENAME;
158 ArchiveRegion(DEFAULT_OAR_BACKUP_FILENAME, options); 162
159 } 163 // Not doing this right now as this causes some problems with auto-backup systems. Maybe a force flag is
164 // needed
165// if (!ConsoleUtil.CheckFileDoesNotExist(MainConsole.Instance, path))
166// return;
167
168 ArchiveRegion(path, options);
160 } 169 }
161 170
162 public void ArchiveRegion(string savePath, Dictionary<string, object> options) 171 public void ArchiveRegion(string savePath, Dictionary<string, object> options)
@@ -169,7 +178,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
169 m_log.InfoFormat( 178 m_log.InfoFormat(
170 "[ARCHIVER]: Writing archive for region {0} to {1}", Scene.RegionInfo.RegionName, savePath); 179 "[ARCHIVER]: Writing archive for region {0} to {1}", Scene.RegionInfo.RegionName, savePath);
171 180
172 new ArchiveWriteRequestPreparation(this, savePath, requestId).ArchiveRegion(options); 181 new ArchiveWriteRequest(Scene, savePath, requestId).ArchiveRegion(options);
173 } 182 }
174 183
175 public void ArchiveRegion(Stream saveStream) 184 public void ArchiveRegion(Stream saveStream)
@@ -184,7 +193,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
184 193
185 public void ArchiveRegion(Stream saveStream, Guid requestId, Dictionary<string, object> options) 194 public void ArchiveRegion(Stream saveStream, Guid requestId, Dictionary<string, object> options)
186 { 195 {
187 new ArchiveWriteRequestPreparation(this, saveStream, requestId).ArchiveRegion(options); 196 new ArchiveWriteRequest(Scene, saveStream, requestId).ArchiveRegion(options);
188 } 197 }
189 198
190 public void DearchiveRegion(string loadPath) 199 public void DearchiveRegion(string loadPath)
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
index 89e9593..e2f8833 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
@@ -46,6 +46,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver
46 { 46 {
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48 48
49 /// <summary>
50 /// Method called when all the necessary assets for an archive request have been received.
51 /// </summary>
52 public delegate void AssetsRequestCallback(
53 ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids);
54
49 enum RequestState 55 enum RequestState
50 { 56 {
51 Initial, 57 Initial,
@@ -123,6 +129,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver
123 m_options = options; 129 m_options = options;
124 m_repliesRequired = uuids.Count; 130 m_repliesRequired = uuids.Count;
125 131
132 // FIXME: This is a really poor way of handling the timeout since it will always leave the original requesting thread
133 // hanging. Need to restructure so an original request thread waits for a ManualResetEvent on asset received
134 // so we can properly abort that thread. Or request all assets synchronously, though that would be a more
135 // radical change
126 m_requestCallbackTimer = new System.Timers.Timer(TIMEOUT); 136 m_requestCallbackTimer = new System.Timers.Timer(TIMEOUT);
127 m_requestCallbackTimer.AutoReset = false; 137 m_requestCallbackTimer.AutoReset = false;
128 m_requestCallbackTimer.Elapsed += new ElapsedEventHandler(OnRequestCallbackTimeout); 138 m_requestCallbackTimer.Elapsed += new ElapsedEventHandler(OnRequestCallbackTimeout);
diff --git a/OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs b/OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs
new file mode 100644
index 0000000..3dcc020
--- /dev/null
+++ b/OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs
@@ -0,0 +1,232 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Text;
32using OpenSim.Region.Framework.Scenes;
33using OpenMetaverse;
34using System.Drawing;
35using log4net;
36using System.Reflection;
37using OpenSim.Framework.Serialization;
38
39namespace OpenSim.Region.CoreModules.World.Archiver
40{
41 /// <summary>
42 /// The regions included in an OAR file.
43 /// </summary>
44 public class DearchiveScenesInfo
45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 /// <summary>
49 /// One region in the archive.
50 /// </summary>
51 public class RegionInfo
52 {
53 /// <summary>
54 /// The subdirectory in which the region is stored.
55 /// </summary>
56 public string Directory { get; set; }
57
58 /// <summary>
59 /// The region's coordinates (relative to the South-West corner of the block).
60 /// </summary>
61 public Point Location { get; set; }
62
63 /// <summary>
64 /// The UUID of the original scene from which this archived region was saved.
65 /// </summary>
66 public string OriginalID { get; set; }
67
68 /// <summary>
69 /// The scene in the current simulator into which this region is loaded.
70 /// If null then the region doesn't have a corresponding scene, and it won't be loaded.
71 /// </summary>
72 public Scene Scene { get; set; }
73 }
74
75 /// <summary>
76 /// Whether this archive uses the multi-region format.
77 /// </summary>
78 public Boolean MultiRegionFormat { get; set; }
79
80 /// <summary>
81 /// Maps (Region directory -> region)
82 /// </summary>
83 protected Dictionary<string, RegionInfo> m_directory2region = new Dictionary<string, RegionInfo>();
84
85 /// <summary>
86 /// Maps (UUID of the scene in the simulator where the region will be loaded -> region)
87 /// </summary>
88 protected Dictionary<UUID, RegionInfo> m_newId2region = new Dictionary<UUID, RegionInfo>();
89
90 public int LoadedCreationDateTime { get; set; }
91 public string DefaultOriginalID { get; set; }
92
93 // These variables are used while reading the archive control file
94 protected int? m_curY = null;
95 protected int? m_curX = null;
96 protected RegionInfo m_curRegion;
97
98
99 public DearchiveScenesInfo()
100 {
101 MultiRegionFormat = false;
102 }
103
104
105 // The following methods are used while reading the archive control file
106
107 public void StartRow()
108 {
109 m_curY = (m_curY == null) ? 0 : m_curY + 1;
110 m_curX = null;
111 }
112
113 public void StartRegion()
114 {
115 m_curX = (m_curX == null) ? 0 : m_curX + 1;
116 // Note: this doesn't mean we have a real region in this location; this could just be a "hole"
117 }
118
119 public void SetRegionOriginalID(string id)
120 {
121 m_curRegion = new RegionInfo();
122 m_curRegion.Location = new Point((int)m_curX, (int)m_curY);
123 m_curRegion.OriginalID = id;
124 // 'curRegion' will be saved in 'm_directory2region' when SetRegionDir() is called
125 }
126
127 public void SetRegionDirectory(string directory)
128 {
129 m_curRegion.Directory = directory;
130 m_directory2region[directory] = m_curRegion;
131 }
132
133
134 /// <summary>
135 /// Sets all the scenes present in the simulator.
136 /// </summary>
137 /// <remarks>
138 /// This method matches regions in the archive to scenes in the simulator according to
139 /// their relative position. We only load regions if there's an existing Scene in the
140 /// grid location where the region should be loaded.
141 /// </remarks>
142 /// <param name="rootScene">The scene where the Load OAR operation was run</param>
143 /// <param name="simulatorScenes">All the scenes in the simulator</param>
144 public void SetSimulatorScenes(Scene rootScene, ArchiveScenesGroup simulatorScenes)
145 {
146 foreach (RegionInfo archivedRegion in m_directory2region.Values)
147 {
148 Point location = new Point((int)rootScene.RegionInfo.RegionLocX, (int)rootScene.RegionInfo.RegionLocY);
149 location.Offset(archivedRegion.Location);
150
151 Scene scene;
152 if (simulatorScenes.TryGetScene(location, out scene))
153 {
154 archivedRegion.Scene = scene;
155 m_newId2region[scene.RegionInfo.RegionID] = archivedRegion;
156 }
157 else
158 {
159 m_log.WarnFormat("[ARCHIVER]: Not loading archived region {0} because there's no existing region at location {1},{2}",
160 archivedRegion.Directory, location.X, location.Y);
161 }
162 }
163 }
164
165 /// <summary>
166 /// Returns the archived region according to the path of a file in the archive.
167 /// Also, converts the full path into a path that is relative to the region's directory.
168 /// </summary>
169 /// <param name="fullPath">The path of a file in the archive</param>
170 /// <param name="scene">The corresponding Scene, or null if none</param>
171 /// <param name="relativePath">The path relative to the region's directory. (Or the original
172 /// path, if this file doesn't belong to a region.)</param>
173 /// <returns>True: use this file; False: skip it</returns>
174 public bool GetRegionFromPath(string fullPath, out Scene scene, out string relativePath)
175 {
176 scene = null;
177 relativePath = fullPath;
178
179 if (!MultiRegionFormat)
180 {
181 if (m_newId2region.Count > 0)
182 scene = m_newId2region.First().Value.Scene;
183 return true;
184 }
185
186 if (!fullPath.StartsWith(ArchiveConstants.REGIONS_PATH))
187 return true; // this file doesn't belong to a region
188
189 string[] parts = fullPath.Split(new Char[] { '/' }, 3);
190 if (parts.Length != 3)
191 return false;
192 string regionDirectory = parts[1];
193 relativePath = parts[2];
194
195 RegionInfo region;
196 if (m_directory2region.TryGetValue(regionDirectory, out region))
197 {
198 scene = region.Scene;
199 return (scene != null);
200 }
201 else
202 {
203 return false;
204 }
205 }
206
207 /// <summary>
208 /// Returns the original UUID of a region (from the simulator where the OAR was saved),
209 /// given the UUID of the scene it was loaded into in the current simulator.
210 /// </summary>
211 /// <param name="newID"></param>
212 /// <returns></returns>
213 public string GetOriginalRegionID(UUID newID)
214 {
215 RegionInfo region;
216 if (m_newId2region.TryGetValue(newID, out region))
217 return region.OriginalID;
218 else
219 return DefaultOriginalID;
220 }
221
222 /// <summary>
223 /// Returns the scenes that have been (or will be) loaded.
224 /// </summary>
225 /// <returns></returns>
226 public List<UUID> GetLoadedScenes()
227 {
228 return m_newId2region.Keys.ToList();
229 }
230
231 }
232}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
index 5deaf52..82f49b0 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
@@ -47,32 +47,41 @@ using ArchiveConstants = OpenSim.Framework.Serialization.ArchiveConstants;
47using TarArchiveReader = OpenSim.Framework.Serialization.TarArchiveReader; 47using TarArchiveReader = OpenSim.Framework.Serialization.TarArchiveReader;
48using TarArchiveWriter = OpenSim.Framework.Serialization.TarArchiveWriter; 48using TarArchiveWriter = OpenSim.Framework.Serialization.TarArchiveWriter;
49using RegionSettings = OpenSim.Framework.RegionSettings; 49using RegionSettings = OpenSim.Framework.RegionSettings;
50using OpenSim.Region.Framework.Interfaces;
50 51
51namespace OpenSim.Region.CoreModules.World.Archiver.Tests 52namespace OpenSim.Region.CoreModules.World.Archiver.Tests
52{ 53{
53 [TestFixture] 54 [TestFixture]
54 public class ArchiverTests 55 public class ArchiverTests : OpenSimTestCase
55 { 56 {
56 private Guid m_lastRequestId; 57 private Guid m_lastRequestId;
57 private string m_lastErrorMessage; 58 private string m_lastErrorMessage;
58 59
60 protected SceneHelpers m_sceneHelpers;
59 protected TestScene m_scene; 61 protected TestScene m_scene;
60 protected ArchiverModule m_archiverModule; 62 protected ArchiverModule m_archiverModule;
63 protected SerialiserModule m_serialiserModule;
61 64
62 protected TaskInventoryItem m_soundItem; 65 protected TaskInventoryItem m_soundItem;
63 66
64 [SetUp] 67 [SetUp]
65 public void SetUp() 68 public override void SetUp()
66 { 69 {
70 base.SetUp();
71
72 // FIXME: Do something about this - relying on statics in unit tests causes trouble sooner or later
73 new SceneManager();
74
67 m_archiverModule = new ArchiverModule(); 75 m_archiverModule = new ArchiverModule();
68 SerialiserModule serialiserModule = new SerialiserModule(); 76 m_serialiserModule = new SerialiserModule();
69 TerrainModule terrainModule = new TerrainModule(); 77 TerrainModule terrainModule = new TerrainModule();
70 78
71 m_scene = new SceneHelpers().SetupScene(); 79 m_sceneHelpers = new SceneHelpers();
72 SceneHelpers.SetupSceneModules(m_scene, m_archiverModule, serialiserModule, terrainModule); 80 m_scene = m_sceneHelpers.SetupScene();
81 SceneHelpers.SetupSceneModules(m_scene, m_archiverModule, m_serialiserModule, terrainModule);
73 } 82 }
74 83
75 private void LoadCompleted(Guid requestId, string errorMessage) 84 private void LoadCompleted(Guid requestId, List<UUID> loadedScenes, string errorMessage)
76 { 85 {
77 lock (this) 86 lock (this)
78 { 87 {
@@ -128,26 +137,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
128 TestHelpers.InMethod(); 137 TestHelpers.InMethod();
129// log4net.Config.XmlConfigurator.Configure(); 138// log4net.Config.XmlConfigurator.Configure();
130 139
131 SceneObjectPart part1 = CreateSceneObjectPart1(); 140 SceneObjectGroup sog1;
132 SceneObjectGroup sog1 = new SceneObjectGroup(part1); 141 SceneObjectGroup sog2;
133 m_scene.AddNewSceneObject(sog1, false); 142 UUID ncAssetUuid;
134 143 CreateTestObjects(m_scene, out sog1, out sog2, out ncAssetUuid);
135 SceneObjectPart part2 = CreateSceneObjectPart2();
136
137 AssetNotecard nc = new AssetNotecard();
138 nc.BodyText = "Hello World!";
139 nc.Encode();
140 UUID ncAssetUuid = new UUID("00000000-0000-0000-1000-000000000000");
141 UUID ncItemUuid = new UUID("00000000-0000-0000-1100-000000000000");
142 AssetBase ncAsset
143 = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero);
144 m_scene.AssetService.Store(ncAsset);
145 SceneObjectGroup sog2 = new SceneObjectGroup(part2);
146 TaskInventoryItem ncItem
147 = new TaskInventoryItem { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid };
148 part2.Inventory.AddInventoryItem(ncItem, true);
149
150 m_scene.AddNewSceneObject(sog2, false);
151 144
152 MemoryStream archiveWriteStream = new MemoryStream(); 145 MemoryStream archiveWriteStream = new MemoryStream();
153 m_scene.EventManager.OnOarFileSaved += SaveCompleted; 146 m_scene.EventManager.OnOarFileSaved += SaveCompleted;
@@ -186,7 +179,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
186 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); 179 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH));
187 180
188 ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, false, false, Guid.Empty); 181 ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, false, false, Guid.Empty);
189 arr.LoadControlFile(filePath, data); 182 arr.LoadControlFile(filePath, data, new DearchiveScenesInfo());
190 183
191 Assert.That(arr.ControlFileLoaded, Is.True); 184 Assert.That(arr.ControlFileLoaded, Is.True);
192 185
@@ -211,6 +204,30 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
211 // TODO: Test presence of more files and contents of files. 204 // TODO: Test presence of more files and contents of files.
212 } 205 }
213 206
207 private void CreateTestObjects(Scene scene, out SceneObjectGroup sog1, out SceneObjectGroup sog2, out UUID ncAssetUuid)
208 {
209 SceneObjectPart part1 = CreateSceneObjectPart1();
210 sog1 = new SceneObjectGroup(part1);
211 scene.AddNewSceneObject(sog1, false);
212
213 AssetNotecard nc = new AssetNotecard();
214 nc.BodyText = "Hello World!";
215 nc.Encode();
216 ncAssetUuid = UUID.Random();
217 UUID ncItemUuid = UUID.Random();
218 AssetBase ncAsset
219 = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero);
220 m_scene.AssetService.Store(ncAsset);
221
222 TaskInventoryItem ncItem
223 = new TaskInventoryItem { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid };
224 SceneObjectPart part2 = CreateSceneObjectPart2();
225 sog2 = new SceneObjectGroup(part2);
226 part2.Inventory.AddInventoryItem(ncItem, true);
227
228 scene.AddNewSceneObject(sog2, false);
229 }
230
214 /// <summary> 231 /// <summary>
215 /// Test saving an OpenSim Region Archive with the no assets option 232 /// Test saving an OpenSim Region Archive with the no assets option
216 /// </summary> 233 /// </summary>
@@ -270,7 +287,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
270 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); 287 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH));
271 288
272 ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, false, false, Guid.Empty); 289 ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, false, false, Guid.Empty);
273 arr.LoadControlFile(filePath, data); 290 arr.LoadControlFile(filePath, data, new DearchiveScenesInfo());
274 291
275 Assert.That(arr.ControlFileLoaded, Is.True); 292 Assert.That(arr.ControlFileLoaded, Is.True);
276 293
@@ -307,7 +324,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
307 324
308 tar.WriteFile( 325 tar.WriteFile(
309 ArchiveConstants.CONTROL_FILE_PATH, 326 ArchiveConstants.CONTROL_FILE_PATH,
310 new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>())); 327 new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup()));
311 328
312 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ownerId, "obj1-", 0x11); 329 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ownerId, "obj1-", 0x11);
313 SceneObjectPart sop2 330 SceneObjectPart sop2
@@ -362,11 +379,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
362 // Also check that direct entries which will also have a file entry containing that directory doesn't 379 // Also check that direct entries which will also have a file entry containing that directory doesn't
363 // upset load 380 // upset load
364 tar.WriteDir(ArchiveConstants.TERRAINS_PATH); 381 tar.WriteDir(ArchiveConstants.TERRAINS_PATH);
365 382
366 tar.WriteFile( 383 tar.WriteFile(
367 ArchiveConstants.CONTROL_FILE_PATH, 384 ArchiveConstants.CONTROL_FILE_PATH,
368 new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>())); 385 new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup()));
369
370 SceneObjectPart part1 = CreateSceneObjectPart1(); 386 SceneObjectPart part1 = CreateSceneObjectPart1();
371 387
372 part1.SitTargetOrientation = new Quaternion(0.2f, 0.3f, 0.4f, 0.5f); 388 part1.SitTargetOrientation = new Quaternion(0.2f, 0.3f, 0.4f, 0.5f);
@@ -389,31 +405,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
389 Assert.That(soundDataResourceName, Is.Not.Null); 405 Assert.That(soundDataResourceName, Is.Not.Null);
390 406
391 byte[] soundData; 407 byte[] soundData;
392 Console.WriteLine("Loading " + soundDataResourceName); 408 UUID soundUuid;
393 using (Stream resource = assembly.GetManifestResourceStream(soundDataResourceName)) 409 CreateSoundAsset(tar, assembly, soundDataResourceName, out soundData, out soundUuid);
394 { 410
395 using (BinaryReader br = new BinaryReader(resource)) 411 TaskInventoryItem item1
396 { 412 = new TaskInventoryItem { AssetID = soundUuid, ItemID = soundItemUuid, Name = soundItemName };
397 // FIXME: Use the inspector instead 413 part1.Inventory.AddInventoryItem(item1, true);
398 soundData = br.ReadBytes(99999999);
399 UUID soundUuid = UUID.Parse("00000000-0000-0000-0000-000000000001");
400 string soundAssetFileName
401 = ArchiveConstants.ASSETS_PATH + soundUuid
402 + ArchiveConstants.ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.SoundWAV];
403 tar.WriteFile(soundAssetFileName, soundData);
404
405 /*
406 AssetBase soundAsset = AssetHelpers.CreateAsset(soundUuid, soundData);
407 scene.AssetService.Store(soundAsset);
408 asset1FileName = ArchiveConstants.ASSETS_PATH + soundUuid + ".wav";
409 */
410
411 TaskInventoryItem item1
412 = new TaskInventoryItem { AssetID = soundUuid, ItemID = soundItemUuid, Name = soundItemName };
413 part1.Inventory.AddInventoryItem(item1, true);
414 }
415 }
416
417 m_scene.AddNewSceneObject(object1, false); 414 m_scene.AddNewSceneObject(object1, false);
418 415
419 string object1FileName = string.Format( 416 string object1FileName = string.Format(
@@ -435,6 +432,34 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
435 432
436 Assert.That(m_lastErrorMessage, Is.Null); 433 Assert.That(m_lastErrorMessage, Is.Null);
437 434
435 TestLoadedRegion(part1, soundItemName, soundData);
436 }
437
438 private static void CreateSoundAsset(TarArchiveWriter tar, Assembly assembly, string soundDataResourceName, out byte[] soundData, out UUID soundUuid)
439 {
440 using (Stream resource = assembly.GetManifestResourceStream(soundDataResourceName))
441 {
442 using (BinaryReader br = new BinaryReader(resource))
443 {
444 // FIXME: Use the inspector instead
445 soundData = br.ReadBytes(99999999);
446 soundUuid = UUID.Parse("00000000-0000-0000-0000-000000000001");
447 string soundAssetFileName
448 = ArchiveConstants.ASSETS_PATH + soundUuid
449 + ArchiveConstants.ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.SoundWAV];
450 tar.WriteFile(soundAssetFileName, soundData);
451
452 /*
453 AssetBase soundAsset = AssetHelpers.CreateAsset(soundUuid, soundData);
454 scene.AssetService.Store(soundAsset);
455 asset1FileName = ArchiveConstants.ASSETS_PATH + soundUuid + ".wav";
456 */
457 }
458 }
459 }
460
461 private void TestLoadedRegion(SceneObjectPart part1, string soundItemName, byte[] soundData)
462 {
438 SceneObjectPart object1PartLoaded = m_scene.GetSceneObjectPart(part1.Name); 463 SceneObjectPart object1PartLoaded = m_scene.GetSceneObjectPart(part1.Name);
439 464
440 Assert.That(object1PartLoaded, Is.Not.Null, "object1 was not loaded"); 465 Assert.That(object1PartLoaded, Is.Not.Null, "object1 was not loaded");
@@ -454,9 +479,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
454 Assert.That(loadedSoundAsset.Data, Is.EqualTo(soundData), "saved and loaded sound data do not match"); 479 Assert.That(loadedSoundAsset.Data, Is.EqualTo(soundData), "saved and loaded sound data do not match");
455 480
456 Assert.Greater(m_scene.LandChannel.AllParcels().Count, 0, "incorrect number of parcels"); 481 Assert.Greater(m_scene.LandChannel.AllParcels().Count, 0, "incorrect number of parcels");
457
458 // Temporary
459 Console.WriteLine("Successfully completed {0}", MethodBase.GetCurrentMethod());
460 } 482 }
461 483
462 /// <summary> 484 /// <summary>
@@ -516,7 +538,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
516 SerialiserModule serialiserModule = new SerialiserModule(); 538 SerialiserModule serialiserModule = new SerialiserModule();
517 TerrainModule terrainModule = new TerrainModule(); 539 TerrainModule terrainModule = new TerrainModule();
518 540
519 TestScene scene2 = new SceneHelpers().SetupScene(); 541 m_sceneHelpers = new SceneHelpers();
542 TestScene scene2 = m_sceneHelpers.SetupScene();
520 SceneHelpers.SetupSceneModules(scene2, archiverModule, serialiserModule, terrainModule); 543 SceneHelpers.SetupSceneModules(scene2, archiverModule, serialiserModule, terrainModule);
521 544
522 // Make sure there's a valid owner for the owner we saved (this should have been wiped if the code is 545 // Make sure there's a valid owner for the owner we saved (this should have been wiped if the code is
@@ -554,7 +577,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
554 tar.WriteDir(ArchiveConstants.TERRAINS_PATH); 577 tar.WriteDir(ArchiveConstants.TERRAINS_PATH);
555 tar.WriteFile( 578 tar.WriteFile(
556 ArchiveConstants.CONTROL_FILE_PATH, 579 ArchiveConstants.CONTROL_FILE_PATH,
557 new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>())); 580 new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup()));
558 581
559 RegionSettings rs = new RegionSettings(); 582 RegionSettings rs = new RegionSettings();
560 rs.AgentLimit = 17; 583 rs.AgentLimit = 17;
@@ -664,7 +687,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
664 SerialiserModule serialiserModule = new SerialiserModule(); 687 SerialiserModule serialiserModule = new SerialiserModule();
665 TerrainModule terrainModule = new TerrainModule(); 688 TerrainModule terrainModule = new TerrainModule();
666 689
667 Scene scene = new SceneHelpers().SetupScene(); 690 Scene scene = m_sceneHelpers.SetupScene();
668 SceneHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule); 691 SceneHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule);
669 692
670 m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false); 693 m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false);
@@ -700,5 +723,258 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
700 Assert.That(object2PartMerged.GroupPosition, Is.EqualTo(part2.GroupPosition), "object2 group position not equal after merge"); 723 Assert.That(object2PartMerged.GroupPosition, Is.EqualTo(part2.GroupPosition), "object2 group position not equal after merge");
701 } 724 }
702 } 725 }
726
727 /// <summary>
728 /// Test saving a multi-region OAR.
729 /// </summary>
730 [Test]
731 public void TestSaveMultiRegionOar()
732 {
733 TestHelpers.InMethod();
734
735 // Create test regions
736
737 int WIDTH = 2;
738 int HEIGHT = 2;
739
740 List<Scene> scenes = new List<Scene>();
741
742 // Maps (Directory in OAR file -> scene)
743 Dictionary<string, Scene> regionPaths = new Dictionary<string, Scene>();
744
745 // Maps (Scene -> expected object paths)
746 Dictionary<UUID, List<string>> expectedPaths = new Dictionary<UUID, List<string>>();
747
748 // List of expected assets
749 List<UUID> expectedAssets = new List<UUID>();
750
751 for (uint y = 0; y < HEIGHT; y++)
752 {
753 for (uint x = 0; x < WIDTH; x++)
754 {
755 Scene scene;
756 if (x == 0 && y == 0)
757 {
758 scene = m_scene; // this scene was already created in SetUp()
759 }
760 else
761 {
762 scene = m_sceneHelpers.SetupScene(string.Format("Unit test region {0}", (y * WIDTH) + x + 1), UUID.Random(), 1000 + x, 1000 + y);
763 SceneHelpers.SetupSceneModules(scene, new ArchiverModule(), m_serialiserModule, new TerrainModule());
764 }
765 scenes.Add(scene);
766
767 string dir = String.Format("{0}_{1}_{2}", x + 1, y + 1, scene.RegionInfo.RegionName.Replace(" ", "_"));
768 regionPaths[dir] = scene;
769
770 SceneObjectGroup sog1;
771 SceneObjectGroup sog2;
772 UUID ncAssetUuid;
773
774 CreateTestObjects(scene, out sog1, out sog2, out ncAssetUuid);
775
776 expectedPaths[scene.RegionInfo.RegionID] = new List<string>();
777 expectedPaths[scene.RegionInfo.RegionID].Add(ArchiveHelpers.CreateObjectPath(sog1));
778 expectedPaths[scene.RegionInfo.RegionID].Add(ArchiveHelpers.CreateObjectPath(sog2));
779
780 expectedAssets.Add(ncAssetUuid);
781 }
782 }
783
784
785 // Save OAR
786
787 MemoryStream archiveWriteStream = new MemoryStream();
788 m_scene.EventManager.OnOarFileSaved += SaveCompleted;
789
790 Guid requestId = new Guid("00000000-0000-0000-0000-808080808080");
791
792 Dictionary<string, Object> options = new Dictionary<string, Object>();
793 options.Add("all", true);
794
795 lock (this)
796 {
797 m_archiverModule.ArchiveRegion(archiveWriteStream, requestId, options);
798 Monitor.Wait(this, 60000);
799 }
800
801
802 // Check that the OAR contains the expected data
803
804 Assert.That(m_lastRequestId, Is.EqualTo(requestId));
805
806 byte[] archive = archiveWriteStream.ToArray();
807 MemoryStream archiveReadStream = new MemoryStream(archive);
808 TarArchiveReader tar = new TarArchiveReader(archiveReadStream);
809
810 Dictionary<UUID, List<string>> foundPaths = new Dictionary<UUID, List<string>>();
811 List<UUID> foundAssets = new List<UUID>();
812
813 foreach (Scene scene in scenes)
814 {
815 foundPaths[scene.RegionInfo.RegionID] = new List<string>();
816 }
817
818 string filePath;
819 TarArchiveReader.TarEntryType tarEntryType;
820
821 byte[] data = tar.ReadEntry(out filePath, out tarEntryType);
822 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH));
823
824 ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, false, false, Guid.Empty);
825 arr.LoadControlFile(filePath, data, new DearchiveScenesInfo());
826
827 Assert.That(arr.ControlFileLoaded, Is.True);
828
829 while (tar.ReadEntry(out filePath, out tarEntryType) != null)
830 {
831 if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
832 {
833 // Assets are shared, so this file doesn't belong to any specific region.
834 string fileName = filePath.Remove(0, ArchiveConstants.ASSETS_PATH.Length);
835 if (fileName.EndsWith("_notecard.txt"))
836 foundAssets.Add(UUID.Parse(fileName.Substring(0, fileName.Length - "_notecard.txt".Length)));
837 }
838 else
839 {
840 // This file belongs to one of the regions. Find out which one.
841 Assert.IsTrue(filePath.StartsWith(ArchiveConstants.REGIONS_PATH));
842 string[] parts = filePath.Split(new Char[] { '/' }, 3);
843 Assert.AreEqual(3, parts.Length);
844 string regionDirectory = parts[1];
845 string relativePath = parts[2];
846 Scene scene = regionPaths[regionDirectory];
847
848 if (relativePath.StartsWith(ArchiveConstants.OBJECTS_PATH))
849 {
850 foundPaths[scene.RegionInfo.RegionID].Add(relativePath);
851 }
852 }
853 }
854
855 Assert.AreEqual(scenes.Count, foundPaths.Count);
856 foreach (Scene scene in scenes)
857 {
858 Assert.That(foundPaths[scene.RegionInfo.RegionID], Is.EquivalentTo(expectedPaths[scene.RegionInfo.RegionID]));
859 }
860
861 Assert.That(foundAssets, Is.EquivalentTo(expectedAssets));
862 }
863
864 /// <summary>
865 /// Test loading a multi-region OAR.
866 /// </summary>
867 [Test]
868 public void TestLoadMultiRegionOar()
869 {
870 TestHelpers.InMethod();
871
872 // Create an ArchiveScenesGroup with the regions in the OAR. This is needed to generate the control file.
873
874 int WIDTH = 2;
875 int HEIGHT = 2;
876
877 for (uint y = 0; y < HEIGHT; y++)
878 {
879 for (uint x = 0; x < WIDTH; x++)
880 {
881 Scene scene;
882 if (x == 0 && y == 0)
883 {
884 scene = m_scene; // this scene was already created in SetUp()
885 }
886 else
887 {
888 scene = m_sceneHelpers.SetupScene(string.Format("Unit test region {0}", (y * WIDTH) + x + 1), UUID.Random(), 1000 + x, 1000 + y);
889 SceneHelpers.SetupSceneModules(scene, new ArchiverModule(), m_serialiserModule, new TerrainModule());
890 }
891 }
892 }
893
894 ArchiveScenesGroup scenesGroup = new ArchiveScenesGroup();
895 SceneManager.Instance.ForEachScene(delegate(Scene scene)
896 {
897 scenesGroup.AddScene(scene);
898 });
899 scenesGroup.CalcSceneLocations();
900
901 // Generate the OAR file
902
903 MemoryStream archiveWriteStream = new MemoryStream();
904 TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
905
906 ArchiveWriteRequest writeRequest = new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty);
907 writeRequest.MultiRegionFormat = true;
908 tar.WriteFile(
909 ArchiveConstants.CONTROL_FILE_PATH, writeRequest.CreateControlFile(scenesGroup));
910
911 SceneObjectPart part1 = CreateSceneObjectPart1();
912 part1.SitTargetOrientation = new Quaternion(0.2f, 0.3f, 0.4f, 0.5f);
913 part1.SitTargetPosition = new Vector3(1, 2, 3);
914
915 SceneObjectGroup object1 = new SceneObjectGroup(part1);
916
917 // Let's put some inventory items into our object
918 string soundItemName = "sound-item1";
919 UUID soundItemUuid = UUID.Parse("00000000-0000-0000-0000-000000000002");
920 Type type = GetType();
921 Assembly assembly = type.Assembly;
922 string soundDataResourceName = null;
923 string[] names = assembly.GetManifestResourceNames();
924 foreach (string name in names)
925 {
926 if (name.EndsWith(".Resources.test-sound.wav"))
927 soundDataResourceName = name;
928 }
929 Assert.That(soundDataResourceName, Is.Not.Null);
930
931 byte[] soundData;
932 UUID soundUuid;
933 CreateSoundAsset(tar, assembly, soundDataResourceName, out soundData, out soundUuid);
934
935 TaskInventoryItem item1
936 = new TaskInventoryItem { AssetID = soundUuid, ItemID = soundItemUuid, Name = soundItemName };
937 part1.Inventory.AddInventoryItem(item1, true);
938 m_scene.AddNewSceneObject(object1, false);
939
940 string object1FileName = string.Format(
941 "{0}_{1:000}-{2:000}-{3:000}__{4}.xml",
942 part1.Name,
943 Math.Round(part1.GroupPosition.X), Math.Round(part1.GroupPosition.Y), Math.Round(part1.GroupPosition.Z),
944 part1.UUID);
945 string path = "regions/1_1_Unit_test_region/" + ArchiveConstants.OBJECTS_PATH + object1FileName;
946 tar.WriteFile(path, SceneObjectSerializer.ToXml2Format(object1));
947
948 tar.Close();
949
950
951 // Delete the current objects, to test that they're loaded from the OAR and didn't
952 // just remain in the scene.
953 SceneManager.Instance.ForEachScene(delegate(Scene scene)
954 {
955 scene.DeleteAllSceneObjects();
956 });
957
958 // Create a "hole", to test that that the corresponding region isn't loaded from the OAR
959 SceneManager.Instance.CloseScene(SceneManager.Instance.Scenes[1]);
960
961
962 // Check thay the OAR file contains the expected data
963
964 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
965
966 lock (this)
967 {
968 m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
969 m_archiverModule.DearchiveRegion(archiveReadStream);
970 }
971
972 Assert.That(m_lastErrorMessage, Is.Null);
973
974 Assert.AreEqual(3, SceneManager.Instance.Scenes.Count);
975
976 TestLoadedRegion(part1, soundItemName, soundData);
977 }
978
703 } 979 }
704} 980}
diff --git a/OpenSim/Region/CoreModules/World/Cloud/CloudModule.cs b/OpenSim/Region/CoreModules/World/Cloud/CloudModule.cs
index 5fa3dc2..d217f36 100644
--- a/OpenSim/Region/CoreModules/World/Cloud/CloudModule.cs
+++ b/OpenSim/Region/CoreModules/World/Cloud/CloudModule.cs
@@ -27,15 +27,17 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using Mono.Addins;
30using Nini.Config; 31using Nini.Config;
31using OpenMetaverse; 32using OpenMetaverse;
32using OpenSim.Framework; 33using OpenSim.Framework;
33using OpenSim.Region.Framework.Interfaces; 34using OpenSim.Region.Framework.Interfaces;
34using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
35 36
36namespace OpenSim.Region.CoreModules 37namespace OpenSim.Region.CoreModules.World
37{ 38{
38 public class CloudModule : ICloudModule 39 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "CloudModule")]
40 public class CloudModule : ICloudModule, INonSharedRegionModule
39 { 41 {
40// private static readonly log4net.ILog m_log 42// private static readonly log4net.ILog m_log
41// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 43// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
@@ -48,7 +50,7 @@ namespace OpenSim.Region.CoreModules
48 private float m_cloudDensity = 1.0F; 50 private float m_cloudDensity = 1.0F;
49 private float[] cloudCover = new float[16 * 16]; 51 private float[] cloudCover = new float[16 * 16];
50 52
51 public void Initialise(Scene scene, IConfigSource config) 53 public void Initialise(IConfigSource config)
52 { 54 {
53 IConfig cloudConfig = config.Configs["Cloud"]; 55 IConfig cloudConfig = config.Configs["Cloud"];
54 56
@@ -59,21 +61,40 @@ namespace OpenSim.Region.CoreModules
59 m_frameUpdateRate = cloudConfig.GetInt("cloud_update_rate", 1000); 61 m_frameUpdateRate = cloudConfig.GetInt("cloud_update_rate", 1000);
60 } 62 }
61 63
62 if (m_enabled) 64 }
63 {
64 65
65 m_scene = scene; 66 public void AddRegion(Scene scene)
67 {
68 if (!m_enabled)
69 return;
66 70
67 scene.EventManager.OnNewClient += CloudsToClient; 71 m_scene = scene;
68 scene.RegisterModuleInterface<ICloudModule>(this);
69 scene.EventManager.OnFrame += CloudUpdate;
70 72
71 GenerateCloudCover(); 73 scene.EventManager.OnNewClient += CloudsToClient;
74 scene.RegisterModuleInterface<ICloudModule>(this);
75 scene.EventManager.OnFrame += CloudUpdate;
72 76
73 m_ready = true; 77 GenerateCloudCover();
74 78
75 } 79 m_ready = true;
80 }
81
82 public void RemoveRegion(Scene scene)
83 {
84 if (!m_enabled)
85 return;
76 86
87 m_ready = false;
88 // Remove our hooks
89 m_scene.EventManager.OnNewClient -= CloudsToClient;
90 m_scene.EventManager.OnFrame -= CloudUpdate;
91 m_scene.UnregisterModuleInterface<ICloudModule>(this);
92
93 m_scene = null;
94 }
95
96 public void RegionLoaded(Scene scene)
97 {
77 } 98 }
78 99
79 public void PostInitialise() 100 public void PostInitialise()
@@ -82,13 +103,6 @@ namespace OpenSim.Region.CoreModules
82 103
83 public void Close() 104 public void Close()
84 { 105 {
85 if (m_enabled)
86 {
87 m_ready = false;
88 // Remove our hooks
89 m_scene.EventManager.OnNewClient -= CloudsToClient;
90 m_scene.EventManager.OnFrame -= CloudUpdate;
91 }
92 } 106 }
93 107
94 public string Name 108 public string Name
@@ -96,12 +110,11 @@ namespace OpenSim.Region.CoreModules
96 get { return "CloudModule"; } 110 get { return "CloudModule"; }
97 } 111 }
98 112
99 public bool IsSharedModule 113 public Type ReplaceableInterface
100 { 114 {
101 get { return false; } 115 get { return null; }
102 } 116 }
103 117
104
105 public float CloudCover(int x, int y, int z) 118 public float CloudCover(int x, int y, int z)
106 { 119 {
107 float cover = 0f; 120 float cover = 0f;
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index fdef9d8..dc062b6 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -40,6 +40,7 @@ using OpenMetaverse;
40using OpenSim.Framework; 40using OpenSim.Framework;
41using OpenSim.Region.Framework.Interfaces; 41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.Framework.Scenes; 42using OpenSim.Region.Framework.Scenes;
43using RegionFlags = OpenMetaverse.RegionFlags;
43 44
44namespace OpenSim.Region.CoreModules.World.Estate 45namespace OpenSim.Region.CoreModules.World.Estate
45{ 46{
@@ -293,6 +294,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
293 } 294 }
294 295
295 restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), false); 296 restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), false);
297
298 m_log.InfoFormat(
299 "User {0} requested restart of region {1} in {2} seconds",
300 remoteClient.Name, Scene.Name, times.Count != 0 ? times[0] : 0);
296 } 301 }
297 } 302 }
298 303
@@ -317,7 +322,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
317 322
318 if ((estateAccessType & 4) != 0) // User add 323 if ((estateAccessType & 4) != 0) // User add
319 { 324 {
320 if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || Scene.Permissions.BypassPermissions()) 325 if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true))
321 { 326 {
322 if ((estateAccessType & 1) != 0) // All estates 327 if ((estateAccessType & 1) != 0) // All estates
323 { 328 {
@@ -349,7 +354,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
349 } 354 }
350 if ((estateAccessType & 8) != 0) // User remove 355 if ((estateAccessType & 8) != 0) // User remove
351 { 356 {
352 if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || Scene.Permissions.BypassPermissions()) 357 if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true))
353 { 358 {
354 if ((estateAccessType & 1) != 0) // All estates 359 if ((estateAccessType & 1) != 0) // All estates
355 { 360 {
@@ -380,7 +385,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
380 } 385 }
381 if ((estateAccessType & 16) != 0) // Group add 386 if ((estateAccessType & 16) != 0) // Group add
382 { 387 {
383 if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || Scene.Permissions.BypassPermissions()) 388 if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true))
384 { 389 {
385 if ((estateAccessType & 1) != 0) // All estates 390 if ((estateAccessType & 1) != 0) // All estates
386 { 391 {
@@ -409,9 +414,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
409 remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); 414 remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions");
410 } 415 }
411 } 416 }
417
412 if ((estateAccessType & 32) != 0) // Group remove 418 if ((estateAccessType & 32) != 0) // Group remove
413 { 419 {
414 if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || Scene.Permissions.BypassPermissions()) 420 if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true))
415 { 421 {
416 if ((estateAccessType & 1) != 0) // All estates 422 if ((estateAccessType & 1) != 0) // All estates
417 { 423 {
@@ -440,9 +446,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
440 remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); 446 remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions");
441 } 447 }
442 } 448 }
449
443 if ((estateAccessType & 64) != 0) // Ban add 450 if ((estateAccessType & 64) != 0) // Ban add
444 { 451 {
445 if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false) || Scene.Permissions.BypassPermissions()) 452 if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false))
446 { 453 {
447 EstateBan[] banlistcheck = Scene.RegionInfo.EstateSettings.EstateBans; 454 EstateBan[] banlistcheck = Scene.RegionInfo.EstateSettings.EstateBans;
448 455
@@ -521,9 +528,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
521 remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); 528 remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions");
522 } 529 }
523 } 530 }
531
524 if ((estateAccessType & 128) != 0) // Ban remove 532 if ((estateAccessType & 128) != 0) // Ban remove
525 { 533 {
526 if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false) || Scene.Permissions.BypassPermissions()) 534 if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false))
527 { 535 {
528 EstateBan[] banlistcheck = Scene.RegionInfo.EstateSettings.EstateBans; 536 EstateBan[] banlistcheck = Scene.RegionInfo.EstateSettings.EstateBans;
529 537
@@ -576,9 +584,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
576 remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); 584 remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions");
577 } 585 }
578 } 586 }
587
579 if ((estateAccessType & 256) != 0) // Manager add 588 if ((estateAccessType & 256) != 0) // Manager add
580 { 589 {
581 if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || Scene.Permissions.BypassPermissions()) 590 if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true))
582 { 591 {
583 if ((estateAccessType & 1) != 0) // All estates 592 if ((estateAccessType & 1) != 0) // All estates
584 { 593 {
@@ -607,9 +616,10 @@ namespace OpenSim.Region.CoreModules.World.Estate
607 remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); 616 remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions");
608 } 617 }
609 } 618 }
619
610 if ((estateAccessType & 512) != 0) // Manager remove 620 if ((estateAccessType & 512) != 0) // Manager remove
611 { 621 {
612 if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || Scene.Permissions.BypassPermissions()) 622 if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true))
613 { 623 {
614 if ((estateAccessType & 1) != 0) // All estates 624 if ((estateAccessType & 1) != 0) // All estates
615 { 625 {
@@ -1108,7 +1118,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
1108 1118
1109 #endregion 1119 #endregion
1110 1120
1111 #region IRegionModule Members 1121 #region Region Module interface
1112 1122
1113 public string Name { get { return "EstateManagementModule"; } } 1123 public string Name { get { return "EstateManagementModule"; } }
1114 1124
diff --git a/OpenSim/Region/CoreModules/World/Land/DwellModule.cs b/OpenSim/Region/CoreModules/World/Land/DwellModule.cs
new file mode 100644
index 0000000..bd22155
--- /dev/null
+++ b/OpenSim/Region/CoreModules/World/Land/DwellModule.cs
@@ -0,0 +1,112 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Diagnostics;
32using System.Reflection;
33using System.Text;
34using log4net;
35using Nini.Config;
36using OpenMetaverse;
37using OpenMetaverse.StructuredData;
38using OpenMetaverse.Messages.Linden;
39using Mono.Addins;
40using OpenSim.Framework;
41using OpenSim.Framework.Capabilities;
42using OpenSim.Framework.Console;
43using OpenSim.Framework.Servers;
44using OpenSim.Framework.Servers.HttpServer;
45using OpenSim.Region.CoreModules.Framework.InterfaceCommander;
46using OpenSim.Region.Framework.Interfaces;
47using OpenSim.Region.Framework.Scenes;
48using OpenSim.Region.Physics.Manager;
49using OpenSim.Services.Interfaces;
50using Caps = OpenSim.Framework.Capabilities.Caps;
51using GridRegion = OpenSim.Services.Interfaces.GridRegion;
52
53namespace OpenSim.Region.CoreModules.World.Land
54{
55 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DwellModule")]
56 public class DwellModule : IDwellModule, INonSharedRegionModule
57 {
58 private Scene m_scene;
59
60 public Type ReplaceableInterface
61 {
62 get { return typeof(IDwellModule); }
63 }
64
65 public string Name
66 {
67 get { return "DwellModule"; }
68 }
69
70 public void Initialise(IConfigSource source)
71 {
72 }
73
74 public void AddRegion(Scene scene)
75 {
76 m_scene = scene;
77
78 m_scene.EventManager.OnNewClient += OnNewClient;
79 }
80
81 public void RegionLoaded(Scene scene)
82 {
83 }
84
85 public void RemoveRegion(Scene scene)
86 {
87 }
88
89 public void Close()
90 {
91 }
92
93 public void OnNewClient(IClientAPI client)
94 {
95 client.OnParcelDwellRequest += ClientOnParcelDwellRequest;
96 }
97
98 private void ClientOnParcelDwellRequest(int localID, IClientAPI client)
99 {
100 ILandObject parcel = m_scene.LandChannel.GetLandObject(localID);
101 if (parcel == null)
102 return;
103
104 client.SendParcelDwellReply(localID, parcel.LandData.GlobalID, parcel.LandData.Dwell);
105 }
106
107 public int GetDwell(UUID parcelID)
108 {
109 return 0;
110 }
111 }
112}
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index aae6603..1193057 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -36,6 +36,7 @@ using Nini.Config;
36using OpenMetaverse; 36using OpenMetaverse;
37using OpenMetaverse.StructuredData; 37using OpenMetaverse.StructuredData;
38using OpenMetaverse.Messages.Linden; 38using OpenMetaverse.Messages.Linden;
39using Mono.Addins;
39using OpenSim.Framework; 40using OpenSim.Framework;
40using OpenSim.Framework.Capabilities; 41using OpenSim.Framework.Capabilities;
41using OpenSim.Framework.Console; 42using OpenSim.Framework.Console;
@@ -60,6 +61,7 @@ namespace OpenSim.Region.CoreModules.World.Land
60 public byte RegionAccess; 61 public byte RegionAccess;
61 } 62 }
62 63
64 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LandManagementModule")]
63 public class LandManagementModule : INonSharedRegionModule 65 public class LandManagementModule : INonSharedRegionModule
64 { 66 {
65 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 67 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -927,6 +929,7 @@ namespace OpenSim.Region.CoreModules.World.Land
927 ILandObject newLand = startLandObject.Copy(); 929 ILandObject newLand = startLandObject.Copy();
928 newLand.LandData.Name = newLand.LandData.Name; 930 newLand.LandData.Name = newLand.LandData.Name;
929 newLand.LandData.GlobalID = UUID.Random(); 931 newLand.LandData.GlobalID = UUID.Random();
932 newLand.LandData.Dwell = 0;
930 933
931 newLand.SetLandBitmap(newLand.GetSquareLandBitmap(start_x, start_y, end_x, end_y)); 934 newLand.SetLandBitmap(newLand.GetSquareLandBitmap(start_x, start_y, end_x, end_y));
932 935
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index 4f06737..d5b2adb 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
@@ -33,6 +33,7 @@ using OpenMetaverse;
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Region.Framework.Interfaces; 34using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
36using RegionFlags = OpenMetaverse.RegionFlags;
36 37
37namespace OpenSim.Region.CoreModules.World.Land 38namespace OpenSim.Region.CoreModules.World.Land
38{ 39{
diff --git a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
index 102b4d7..55b8227 100644
--- a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
@@ -34,6 +34,7 @@ using log4net;
34using Nini.Config; 34using Nini.Config;
35using OpenMetaverse; 35using OpenMetaverse;
36using OpenSim.Framework; 36using OpenSim.Framework;
37using Mono.Addins;
37using OpenSim.Region.Framework.Interfaces; 38using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
39using OpenSim.Services.Interfaces; 40using OpenSim.Services.Interfaces;
@@ -49,6 +50,7 @@ namespace OpenSim.Region.CoreModules.World.Land
49 public Dictionary <UUID, int> Users = new Dictionary <UUID, int>(); 50 public Dictionary <UUID, int> Users = new Dictionary <UUID, int>();
50 } 51 }
51 52
53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "PrimCountModule")]
52 public class PrimCountModule : IPrimCountModule, INonSharedRegionModule 54 public class PrimCountModule : IPrimCountModule, INonSharedRegionModule
53 { 55 {
54// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 56// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -69,7 +71,7 @@ namespace OpenSim.Region.CoreModules.World.Land
69 /// without recounting the whole sim. 71 /// without recounting the whole sim.
70 /// 72 ///
71 /// We start out tainted so that the first get call resets the various prim counts. 73 /// We start out tainted so that the first get call resets the various prim counts.
72 /// <value> 74 /// </value>
73 private bool m_Tainted = true; 75 private bool m_Tainted = true;
74 76
75 private Object m_TaintLock = new Object(); 77 private Object m_TaintLock = new Object();
diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs
index aa306c7..8a422b0 100644
--- a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs
+++ b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs
@@ -30,6 +30,7 @@ using System.Collections.Generic;
30using System.Drawing; 30using System.Drawing;
31using System.Reflection; 31using System.Reflection;
32using log4net; 32using log4net;
33using Mono.Addins;
33using Nini.Config; 34using Nini.Config;
34using OpenMetaverse; 35using OpenMetaverse;
35using OpenMetaverse.Imaging; 36using OpenMetaverse.Imaging;
@@ -59,6 +60,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap
59 public face[] trns; 60 public face[] trns;
60 } 61 }
61 62
63 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MapImageModule")]
62 public class MapImageModule : IMapImageGenerator, INonSharedRegionModule 64 public class MapImageModule : IMapImageGenerator, INonSharedRegionModule
63 { 65 {
64 private static readonly ILog m_log = 66 private static readonly ILog m_log =
@@ -131,7 +133,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap
131 133
132 #endregion 134 #endregion
133 135
134 #region IRegionModule Members 136 #region Region Module interface
135 137
136 public void Initialise(IConfigSource source) 138 public void Initialise(IConfigSource source)
137 { 139 {
diff --git a/OpenSim/Region/CoreModules/LightShare/EnvironmentModule.cs b/OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs
index 1526886..c3cea7a 100644
--- a/OpenSim/Region/CoreModules/LightShare/EnvironmentModule.cs
+++ b/OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs
@@ -51,10 +51,10 @@ namespace OpenSim.Region.CoreModules.World.LightShare
51 private Scene m_scene = null; 51 private Scene m_scene = null;
52 private UUID regionID = UUID.Zero; 52 private UUID regionID = UUID.Zero;
53 private static bool Enabled = false; 53 private static bool Enabled = false;
54 54
55 private static readonly string capsName = "EnvironmentSettings"; 55 private static readonly string capsName = "EnvironmentSettings";
56 private static readonly string capsBase = "/CAPS/0020/"; 56 private static readonly string capsBase = "/CAPS/0020/";
57 57
58 private LLSDEnvironmentSetResponse setResponse = null; 58 private LLSDEnvironmentSetResponse setResponse = null;
59 59
60 #region INonSharedRegionModule 60 #region INonSharedRegionModule
@@ -72,7 +72,7 @@ namespace OpenSim.Region.CoreModules.World.LightShare
72 } 72 }
73 73
74 Enabled = true; 74 Enabled = true;
75 75
76 m_log.InfoFormat("[{0}]: Module is enabled.", Name); 76 m_log.InfoFormat("[{0}]: Module is enabled.", Name);
77 } 77 }
78 78
@@ -132,8 +132,8 @@ namespace OpenSim.Region.CoreModules.World.LightShare
132 #region Events 132 #region Events
133 private void OnRegisterCaps(UUID agentID, Caps caps) 133 private void OnRegisterCaps(UUID agentID, Caps caps)
134 { 134 {
135// m_log.DebugFormat("[{0}]: Register capability for agentID {1} in region {2}", 135 // m_log.DebugFormat("[{0}]: Register capability for agentID {1} in region {2}",
136// Name, agentID, caps.RegionName); 136 // Name, agentID, caps.RegionName);
137 137
138 string capsPath = capsBase + UUID.Random(); 138 string capsPath = capsBase + UUID.Random();
139 139
@@ -163,8 +163,8 @@ namespace OpenSim.Region.CoreModules.World.LightShare
163 private string GetEnvironmentSettings(string request, string path, string param, 163 private string GetEnvironmentSettings(string request, string path, string param,
164 UUID agentID, Caps caps) 164 UUID agentID, Caps caps)
165 { 165 {
166// m_log.DebugFormat("[{0}]: Environment GET handle for agentID {1} in region {2}", 166 // m_log.DebugFormat("[{0}]: Environment GET handle for agentID {1} in region {2}",
167// Name, agentID, caps.RegionName); 167 // Name, agentID, caps.RegionName);
168 168
169 string env = String.Empty; 169 string env = String.Empty;
170 170
@@ -188,8 +188,8 @@ namespace OpenSim.Region.CoreModules.World.LightShare
188 UUID agentID, Caps caps) 188 UUID agentID, Caps caps)
189 { 189 {
190 190
191// m_log.DebugFormat("[{0}]: Environment SET handle from agentID {1} in region {2}", 191 // m_log.DebugFormat("[{0}]: Environment SET handle from agentID {1} in region {2}",
192// Name, agentID, caps.RegionName); 192 // Name, agentID, caps.RegionName);
193 193
194 setResponse.regionID = regionID; 194 setResponse.regionID = regionID;
195 setResponse.success = false; 195 setResponse.success = false;
@@ -204,7 +204,7 @@ namespace OpenSim.Region.CoreModules.World.LightShare
204 { 204 {
205 m_scene.SimulationDataService.StoreRegionEnvironmentSettings(regionID, request); 205 m_scene.SimulationDataService.StoreRegionEnvironmentSettings(regionID, request);
206 setResponse.success = true; 206 setResponse.success = true;
207 207
208 m_log.InfoFormat("[{0}]: New Environment settings has been saved from agentID {1} in region {2}", 208 m_log.InfoFormat("[{0}]: New Environment settings has been saved from agentID {1} in region {2}",
209 Name, agentID, caps.RegionName); 209 Name, agentID, caps.RegionName);
210 } 210 }
diff --git a/OpenSim/Region/CoreModules/LightShare/LightShareModule.cs b/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs
index f49641f..6f92ef6 100644
--- a/OpenSim/Region/CoreModules/LightShare/LightShareModule.cs
+++ b/OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs
@@ -27,21 +27,20 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO;
31using System.Reflection; 30using System.Reflection;
32using OpenMetaverse; 31using OpenMetaverse;
33using log4net;
34using Nini.Config;
35using OpenSim.Data;
36using OpenSim.Framework; 32using OpenSim.Framework;
37using OpenSim.Region.CoreModules.Framework.InterfaceCommander; 33using OpenSim.Region.CoreModules.Framework.InterfaceCommander;
38using OpenSim.Region.Framework.Interfaces; 34using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
40 36using log4net;
37using Nini.Config;
38using Mono.Addins;
41 39
42namespace OpenSim.Region.CoreModules.World.LightShare 40namespace OpenSim.Region.CoreModules.World.LightShare
43{ 41{
44 public class LightShareModule : IRegionModule, ICommandableModule 42 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LightShareModule")]
43 public class LightShareModule : INonSharedRegionModule, ILightShareModule, ICommandableModule
45 { 44 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47 private readonly Commander m_commander = new Commander("windlight"); 46 private readonly Commander m_commander = new Commander("windlight");
@@ -57,48 +56,86 @@ namespace OpenSim.Region.CoreModules.World.LightShare
57 56
58 #endregion 57 #endregion
59 58
60 #region IRegionModule Members 59 #region INonSharedRegionModule Members
61 60
62 public static bool EnableWindlight 61 public void Initialise(IConfigSource config)
63 { 62 {
64 get 63 try
65 { 64 {
66 return m_enableWindlight; 65 m_enableWindlight = config.Configs["LightShare"].GetBoolean("enable_windlight", false);
67 } 66 }
68 set 67 catch (Exception)
69 { 68 {
69 m_log.Debug("[WINDLIGHT]: ini failure for enable_windlight - using default");
70 } 70 }
71
72 m_log.DebugFormat("[WINDLIGHT]: windlight module {0}", (m_enableWindlight ? "enabled" : "disabled"));
71 } 73 }
72 74
73 public void Initialise(Scene scene, IConfigSource config) 75 public void AddRegion(Scene scene)
74 { 76 {
77 if (!m_enableWindlight)
78 return;
79
75 m_scene = scene; 80 m_scene = scene;
76 m_scene.RegisterModuleInterface<IRegionModule>(this); 81 m_scene.RegisterModuleInterface<ILightShareModule>(this);
77 m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; 82 m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole;
78 83
79 // ini file settings 84 m_scene.EventManager.OnMakeRootAgent += EventManager_OnMakeRootAgent;
80 try 85 m_scene.EventManager.OnSaveNewWindlightProfile += EventManager_OnSaveNewWindlightProfile;
81 { 86 m_scene.EventManager.OnSendNewWindlightProfileTargeted += EventManager_OnSendNewWindlightProfileTargeted;
82 m_enableWindlight = config.Configs["LightShare"].GetBoolean("enable_windlight", false); 87 m_scene.LoadWindlightProfile();
83 } 88
84 catch (Exception) 89 InstallCommands();
90 }
91
92 public void RemoveRegion(Scene scene)
93 {
94 if (!m_enableWindlight)
95 return;
96
97 m_scene.EventManager.OnPluginConsole -= EventManager_OnPluginConsole;
98
99 m_scene.EventManager.OnMakeRootAgent -= EventManager_OnMakeRootAgent;
100 m_scene.EventManager.OnSaveNewWindlightProfile -= EventManager_OnSaveNewWindlightProfile;
101 m_scene.EventManager.OnSendNewWindlightProfileTargeted -= EventManager_OnSendNewWindlightProfileTargeted;
102
103 m_scene = null;
104 }
105
106 public void Close()
107 {
108 }
109
110 public string Name
111 {
112 get { return "LightShareModule"; }
113 }
114
115 public void RegionLoaded(Scene scene)
116 {
117 }
118
119 public Type ReplaceableInterface
120 {
121 get { return null; }
122 }
123
124 #endregion
125
126 public static bool EnableWindlight
127 {
128 get
85 { 129 {
86 m_log.Debug("[WINDLIGHT]: ini failure for enable_windlight - using default"); 130 return m_enableWindlight;
87 } 131 }
88 132 set
89 if (m_enableWindlight)
90 { 133 {
91 m_scene.EventManager.OnMakeRootAgent += EventManager_OnMakeRootAgent;
92 m_scene.EventManager.OnSaveNewWindlightProfile += EventManager_OnSaveNewWindlightProfile;
93 m_scene.EventManager.OnSendNewWindlightProfileTargeted += EventManager_OnSendNewWindlightProfileTargeted;
94 m_scene.LoadWindlightProfile();
95 } 134 }
96
97 InstallCommands();
98
99 m_log.Debug("[WINDLIGHT]: Initialised windlight module");
100 } 135 }
101 136
137 #region events
138
102 private List<byte[]> compileWindlightSettings(RegionLightShareData wl) 139 private List<byte[]> compileWindlightSettings(RegionLightShareData wl)
103 { 140 {
104 byte[] mBlock = new Byte[249]; 141 byte[] mBlock = new Byte[249];
@@ -153,6 +190,9 @@ namespace OpenSim.Region.CoreModules.World.LightShare
153 190
154 public void SendProfileToClient(IClientAPI client, RegionLightShareData wl) 191 public void SendProfileToClient(IClientAPI client, RegionLightShareData wl)
155 { 192 {
193 if (client == null)
194 return;
195
156 if (m_enableWindlight) 196 if (m_enableWindlight)
157 { 197 {
158 if (m_scene.RegionInfo.WindlightSettings.valid) 198 if (m_scene.RegionInfo.WindlightSettings.valid)
@@ -187,29 +227,6 @@ namespace OpenSim.Region.CoreModules.World.LightShare
187 m_scene.ForEachRootClient(SendProfileToClient); 227 m_scene.ForEachRootClient(SendProfileToClient);
188 } 228 }
189 229
190 public void PostInitialise()
191 {
192
193 }
194
195 public void Close()
196 {
197 }
198
199 public string Name
200 {
201 get { return "LightShareModule"; }
202 }
203
204 public bool IsSharedModule
205 {
206 get { return false; }
207 }
208
209 #endregion
210
211 #region events
212
213 #endregion 230 #endregion
214 231
215 #region ICommandableModule Members 232 #region ICommandableModule Members
@@ -244,7 +261,7 @@ namespace OpenSim.Region.CoreModules.World.LightShare
244 private void HandleDisable(Object[] args) 261 private void HandleDisable(Object[] args)
245 { 262 {
246 m_log.InfoFormat("[WINDLIGHT]: Plugin now disabled"); 263 m_log.InfoFormat("[WINDLIGHT]: Plugin now disabled");
247 m_enableWindlight=false; 264 m_enableWindlight = false;
248 } 265 }
249 266
250 private void HandleEnable(Object[] args) 267 private void HandleEnable(Object[] args)
diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
index 09f6758..ab8f143 100644
--- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
@@ -27,9 +27,12 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO;
31using System.Linq;
30using System.Reflection; 32using System.Reflection;
31using System.Text; 33using System.Text;
32using System.Text.RegularExpressions; 34using System.Text.RegularExpressions;
35using System.Xml;
33using log4net; 36using log4net;
34using Mono.Addins; 37using Mono.Addins;
35using NDesk.Options; 38using NDesk.Options;
@@ -40,6 +43,7 @@ using OpenSim.Framework.Console;
40using OpenSim.Framework.Monitoring; 43using OpenSim.Framework.Monitoring;
41using OpenSim.Region.Framework.Interfaces; 44using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.Framework.Scenes; 45using OpenSim.Region.Framework.Scenes;
46using OpenSim.Region.Framework.Scenes.Serialization;
43 47
44namespace OpenSim.Region.CoreModules.World.Objects.Commands 48namespace OpenSim.Region.CoreModules.World.Objects.Commands
45{ 49{
@@ -83,52 +87,85 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
83 m_console.Commands.AddCommand( 87 m_console.Commands.AddCommand(
84 "Objects", false, "delete object owner", 88 "Objects", false, "delete object owner",
85 "delete object owner <UUID>", 89 "delete object owner <UUID>",
86 "Delete a scene object by owner", HandleDeleteObject); 90 "Delete scene objects by owner",
91 "Command will ask for confirmation before proceeding.",
92 HandleDeleteObject);
87 93
88 m_console.Commands.AddCommand( 94 m_console.Commands.AddCommand(
89 "Objects", false, "delete object creator", 95 "Objects", false, "delete object creator",
90 "delete object creator <UUID>", 96 "delete object creator <UUID>",
91 "Delete a scene object by creator", HandleDeleteObject); 97 "Delete scene objects by creator",
98 "Command will ask for confirmation before proceeding.",
99 HandleDeleteObject);
92 100
93 m_console.Commands.AddCommand( 101 m_console.Commands.AddCommand(
94 "Objects", false, "delete object uuid", 102 "Objects", false, "delete object id",
95 "delete object uuid <UUID>", 103 "delete object id <UUID-or-localID>",
96 "Delete a scene object by uuid", HandleDeleteObject); 104 "Delete a scene object by uuid or localID",
105 HandleDeleteObject);
97 106
98 m_console.Commands.AddCommand( 107 m_console.Commands.AddCommand(
99 "Objects", false, "delete object name", 108 "Objects", false, "delete object name",
100 "delete object name [--regex] <name>", 109 "delete object name [--regex] <name>",
101 "Delete a scene object by name.", 110 "Delete a scene object by name.",
102 "If --regex is specified then the name is treatead as a regular expression", 111 "Command will ask for confirmation before proceeding.\n"
112 + "If --regex is specified then the name is treatead as a regular expression",
103 HandleDeleteObject); 113 HandleDeleteObject);
104 114
105 m_console.Commands.AddCommand( 115 m_console.Commands.AddCommand(
106 "Objects", false, "delete object outside", 116 "Objects", false, "delete object outside",
107 "delete object outside", 117 "delete object outside",
108 "Delete all scene objects outside region boundaries", HandleDeleteObject); 118 "Delete all scene objects outside region boundaries",
119 "Command will ask for confirmation before proceeding.",
120 HandleDeleteObject);
109 121
110 m_console.Commands.AddCommand( 122 m_console.Commands.AddCommand(
111 "Objects", 123 "Objects",
112 false, 124 false,
113 "show object uuid", 125 "delete object pos",
114 "show object uuid <UUID>", 126 "delete object pos <start-coord> to <end-coord>",
115 "Show details of a scene object with the given UUID", HandleShowObjectByUuid); 127 "Delete scene objects within the given area.",
128 ConsoleUtil.CoordHelp,
129 HandleDeleteObject);
130
131 m_console.Commands.AddCommand(
132 "Objects",
133 false,
134 "show object id",
135 "show object id [--full] <UUID-or-localID>",
136 "Show details of a scene object with the given UUID or localID",
137 "The --full option will print out information on all the parts of the object.\n"
138 + "For yet more detailed part information, use the \"show part\" commands.",
139 HandleShowObjectById);
116 140
117 m_console.Commands.AddCommand( 141 m_console.Commands.AddCommand(
118 "Objects", 142 "Objects",
119 false, 143 false,
120 "show object name", 144 "show object name",
121 "show object name [--regex] <name>", 145 "show object name [--full] [--regex] <name>",
122 "Show details of scene objects with the given name.", 146 "Show details of scene objects with the given name.",
123 "If --regex is specified then the name is treatead as a regular expression", 147 "The --full option will print out information on all the parts of the object.\n"
148 + "For yet more detailed part information, use the \"show part\" commands.\n"
149 + "If --regex is specified then the name is treatead as a regular expression.",
124 HandleShowObjectByName); 150 HandleShowObjectByName);
125 151
126 m_console.Commands.AddCommand( 152 m_console.Commands.AddCommand(
127 "Objects", 153 "Objects",
128 false, 154 false,
129 "show part uuid", 155 "show object pos",
130 "show part uuid <UUID>", 156 "show object pos [--full] <start-coord> to <end-coord>",
131 "Show details of a scene object parts with the given UUID", HandleShowPartByUuid); 157 "Show details of scene objects within the given area.",
158 "The --full option will print out information on all the parts of the object.\n"
159 + "For yet more detailed part information, use the \"show part\" commands.\n"
160 + ConsoleUtil.CoordHelp,
161 HandleShowObjectByPos);
162
163 m_console.Commands.AddCommand(
164 "Objects",
165 false,
166 "show part id",
167 "show part id <UUID-or-localID>",
168 "Show details of a scene object part with the given UUID or localID", HandleShowPartById);
132 169
133 m_console.Commands.AddCommand( 170 m_console.Commands.AddCommand(
134 "Objects", 171 "Objects",
@@ -136,8 +173,28 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
136 "show part name", 173 "show part name",
137 "show part name [--regex] <name>", 174 "show part name [--regex] <name>",
138 "Show details of scene object parts with the given name.", 175 "Show details of scene object parts with the given name.",
139 "If --regex is specified then the name is treatead as a regular expression", 176 "If --regex is specified then the name is treated as a regular expression",
140 HandleShowPartByName); 177 HandleShowPartByName);
178
179 m_console.Commands.AddCommand(
180 "Objects",
181 false,
182 "show part pos",
183 "show part pos <start-coord> to <end-coord>",
184 "Show details of scene object parts within the given area.",
185 ConsoleUtil.CoordHelp,
186 HandleShowPartByPos);
187
188 m_console.Commands.AddCommand(
189 "Objects",
190 false,
191 "dump object id",
192 "dump object id <UUID-or-localID>",
193 "Dump the formatted serialization of the given object to the file <UUID>.xml",
194 "e.g. dump object uuid c1ed6809-cc24-4061-a4c2-93082a2d1f1d will dump serialization to c1ed6809-cc24-4061-a4c2-93082a2d1f1d.xml\n"
195 + "To locate the UUID or localID in the first place, you need to use the other show object commands.\n"
196 + "If a local ID is given then the filename used is still that for the UUID",
197 HandleDumpObjectById);
141 } 198 }
142 199
143 public void RemoveRegion(Scene scene) 200 public void RemoveRegion(Scene scene)
@@ -150,25 +207,75 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
150// m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); 207// m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
151 } 208 }
152 209
153 private void HandleShowObjectByUuid(string module, string[] cmd) 210 /// <summary>
211 /// Outputs the sogs to console.
212 /// </summary>
213 /// <param name='searchPredicate'></param>
214 /// <param name='showFull'>If true then output all part details. If false then output summary.</param>
215 private void OutputSogsToConsole(Predicate<SceneObjectGroup> searchPredicate, bool showFull)
216 {
217 List<SceneObjectGroup> sceneObjects = m_scene.GetSceneObjectGroups().FindAll(searchPredicate);
218
219 StringBuilder sb = new StringBuilder();
220
221 foreach (SceneObjectGroup so in sceneObjects)
222 {
223 AddSceneObjectReport(sb, so, showFull);
224 sb.Append("\n");
225 }
226
227 sb.AppendFormat("{0} object(s) found in {1}\n", sceneObjects.Count, m_scene.Name);
228
229 m_console.OutputFormat(sb.ToString());
230 }
231
232 private void OutputSopsToConsole(Predicate<SceneObjectPart> searchPredicate, bool showFull)
233 {
234 List<SceneObjectGroup> sceneObjects = m_scene.GetSceneObjectGroups();
235 List<SceneObjectPart> parts = new List<SceneObjectPart>();
236
237 sceneObjects.ForEach(so => parts.AddRange(Array.FindAll<SceneObjectPart>(so.Parts, searchPredicate)));
238
239 StringBuilder sb = new StringBuilder();
240
241 foreach (SceneObjectPart part in parts)
242 {
243 AddScenePartReport(sb, part, showFull);
244 sb.Append("\n");
245 }
246
247 sb.AppendFormat("{0} parts found in {1}\n", parts.Count, m_scene.Name);
248
249 m_console.OutputFormat(sb.ToString());
250 }
251
252 private void HandleShowObjectById(string module, string[] cmdparams)
154 { 253 {
155 if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) 254 if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
156 return; 255 return;
157 256
158 if (cmd.Length < 4) 257 bool showFull = false;
258 OptionSet options = new OptionSet().Add("full", v => showFull = v != null );
259
260 List<string> mainParams = options.Parse(cmdparams);
261
262 if (mainParams.Count < 4)
159 { 263 {
160 m_console.OutputFormat("Usage: show object uuid <uuid>"); 264 m_console.OutputFormat("Usage: show object uuid <uuid>");
161 return; 265 return;
162 } 266 }
163 267
164 UUID objectUuid; 268 UUID uuid;
165 if (!UUID.TryParse(cmd[3], out objectUuid)) 269 uint localId;
166 { 270 if (!ConsoleUtil.TryParseConsoleId(m_console, mainParams[3], out uuid, out localId))
167 m_console.OutputFormat("{0} is not a valid uuid", cmd[3]);
168 return; 271 return;
169 }
170 272
171 SceneObjectGroup so = m_scene.GetSceneObjectGroup(objectUuid); 273 SceneObjectGroup so;
274
275 if (localId != ConsoleUtil.LocalIdNotFound)
276 so = m_scene.GetSceneObjectGroup(localId);
277 else
278 so = m_scene.GetSceneObjectGroup(uuid);
172 279
173 if (so == null) 280 if (so == null)
174 { 281 {
@@ -177,7 +284,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
177 } 284 }
178 285
179 StringBuilder sb = new StringBuilder(); 286 StringBuilder sb = new StringBuilder();
180 AddSceneObjectReport(sb, so); 287 AddSceneObjectReport(sb, so, showFull);
181 288
182 m_console.OutputFormat(sb.ToString()); 289 m_console.OutputFormat(sb.ToString());
183 } 290 }
@@ -187,70 +294,91 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
187 if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) 294 if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
188 return; 295 return;
189 296
297 bool showFull = false;
190 bool useRegex = false; 298 bool useRegex = false;
191 OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null ); 299 OptionSet options = new OptionSet();
300 options.Add("full", v => showFull = v != null );
301 options.Add("regex", v => useRegex = v != null );
192 302
193 List<string> mainParams = options.Parse(cmdparams); 303 List<string> mainParams = options.Parse(cmdparams);
194 304
195 if (mainParams.Count < 4) 305 if (mainParams.Count < 4)
196 { 306 {
197 m_console.OutputFormat("Usage: show object name [--regex] <name>"); 307 m_console.OutputFormat("Usage: show object name [--full] [--regex] <name>");
198 return; 308 return;
199 } 309 }
200 310
201 string name = mainParams[3]; 311 string name = mainParams[3];
202 312
203 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); 313 Predicate<SceneObjectGroup> searchPredicate;
204 Action<SceneObjectGroup> searchAction;
205 314
206 if (useRegex) 315 if (useRegex)
207 { 316 {
208 Regex nameRegex = new Regex(name); 317 Regex nameRegex = new Regex(name);
209 searchAction = so => { if (nameRegex.IsMatch(so.Name)) { sceneObjects.Add(so); }}; 318 searchPredicate = so => nameRegex.IsMatch(so.Name);
210 } 319 }
211 else 320 else
212 { 321 {
213 searchAction = so => { if (so.Name == name) { sceneObjects.Add(so); }}; 322 searchPredicate = so => so.Name == name;
214 } 323 }
215 324
216 m_scene.ForEachSOG(searchAction); 325 OutputSogsToConsole(searchPredicate, showFull);
326 }
217 327
218 if (sceneObjects.Count == 0) 328 private void HandleShowObjectByPos(string module, string[] cmdparams)
219 { 329 {
220 m_console.OutputFormat("No objects with name {0} found in {1}", name, m_scene.RegionInfo.RegionName); 330 if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
221 return; 331 return;
222 }
223 332
224 StringBuilder sb = new StringBuilder(); 333 bool showFull = false;
334 OptionSet options = new OptionSet().Add("full", v => showFull = v != null );
225 335
226 foreach (SceneObjectGroup so in sceneObjects) 336 List<string> mainParams = options.Parse(cmdparams);
337
338 if (mainParams.Count < 5)
227 { 339 {
228 AddSceneObjectReport(sb, so); 340 m_console.OutputFormat("Usage: show object pos [--full] <start-coord> to <end-coord>");
229 sb.Append("\n"); 341 return;
230 } 342 }
231 343
232 m_console.OutputFormat(sb.ToString()); 344 Vector3 startVector, endVector;
345
346 if (!TryParseVectorRange(cmdparams.Skip(3).Take(3), out startVector, out endVector))
347 return;
348
349 Predicate<SceneObjectGroup> searchPredicate
350 = so => Util.IsInsideBox(so.AbsolutePosition, startVector, endVector);
351
352 OutputSogsToConsole(searchPredicate, showFull);
233 } 353 }
234 354
235 private void HandleShowPartByUuid(string module, string[] cmd) 355 private void HandleShowPartById(string module, string[] cmdparams)
236 { 356 {
237 if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) 357 if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
238 return; 358 return;
239 359
240 if (cmd.Length < 4) 360// bool showFull = false;
361 OptionSet options = new OptionSet();
362// options.Add("full", v => showFull = v != null );
363
364 List<string> mainParams = options.Parse(cmdparams);
365
366 if (mainParams.Count < 4)
241 { 367 {
242 m_console.OutputFormat("Usage: show part uuid <uuid>"); 368 m_console.OutputFormat("Usage: show part id [--full] <UUID-or-localID>");
243 return; 369 return;
244 } 370 }
245 371
246 UUID objectUuid; 372 UUID objectUuid;
247 if (!UUID.TryParse(cmd[3], out objectUuid)) 373 uint localId;
248 { 374 if (!ConsoleUtil.TryParseConsoleId(m_console, mainParams[3], out objectUuid, out localId))
249 m_console.OutputFormat("{0} is not a valid uuid", cmd[3]);
250 return; 375 return;
251 }
252 376
253 SceneObjectPart sop = m_scene.GetSceneObjectPart(objectUuid); 377 SceneObjectPart sop;
378 if (localId == ConsoleUtil.LocalIdNotFound)
379 sop = m_scene.GetSceneObjectPart(objectUuid);
380 else
381 sop = m_scene.GetSceneObjectPart(localId);
254 382
255 if (sop == null) 383 if (sop == null)
256 { 384 {
@@ -259,84 +387,239 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
259 } 387 }
260 388
261 StringBuilder sb = new StringBuilder(); 389 StringBuilder sb = new StringBuilder();
262 AddScenePartReport(sb, sop); 390 AddScenePartReport(sb, sop, true);
263 391
264 m_console.OutputFormat(sb.ToString()); 392 m_console.OutputFormat(sb.ToString());
265 } 393 }
266 394
395 private void HandleShowPartByPos(string module, string[] cmdparams)
396 {
397 if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
398 return;
399
400// bool showFull = false;
401 OptionSet options = new OptionSet();
402// options.Add("full", v => showFull = v != null );
403
404 List<string> mainParams = options.Parse(cmdparams);
405
406 if (mainParams.Count < 5)
407 {
408 m_console.OutputFormat("Usage: show part pos [--full] <start-coord> to <end-coord>");
409 return;
410 }
411
412 string rawConsoleStartVector = mainParams[3];
413 Vector3 startVector;
414
415 if (!ConsoleUtil.TryParseConsoleMinVector(rawConsoleStartVector, out startVector))
416 {
417 m_console.OutputFormat("Error: Start vector {0} does not have a valid format", rawConsoleStartVector);
418 return;
419 }
420
421 string rawConsoleEndVector = mainParams[5];
422 Vector3 endVector;
423
424 if (!ConsoleUtil.TryParseConsoleMaxVector(rawConsoleEndVector, out endVector))
425 {
426 m_console.OutputFormat("Error: End vector {0} does not have a valid format", rawConsoleEndVector);
427 return;
428 }
429
430 OutputSopsToConsole(sop => Util.IsInsideBox(sop.AbsolutePosition, startVector, endVector), true);
431 }
432
267 private void HandleShowPartByName(string module, string[] cmdparams) 433 private void HandleShowPartByName(string module, string[] cmdparams)
268 { 434 {
269 if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) 435 if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
270 return; 436 return;
271 437
438// bool showFull = false;
272 bool useRegex = false; 439 bool useRegex = false;
273 OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null ); 440 OptionSet options = new OptionSet();
441// options.Add("full", v => showFull = v != null );
442 options.Add("regex", v => useRegex = v != null );
274 443
275 List<string> mainParams = options.Parse(cmdparams); 444 List<string> mainParams = options.Parse(cmdparams);
276 445
277 if (mainParams.Count < 4) 446 if (mainParams.Count < 4)
278 { 447 {
279 m_console.OutputFormat("Usage: show part name [--regex] <name>"); 448 m_console.OutputFormat("Usage: show part name [--full] [--regex] <name>");
280 return; 449 return;
281 } 450 }
282 451
283 string name = mainParams[3]; 452 string name = mainParams[3];
284 453
285 List<SceneObjectPart> parts = new List<SceneObjectPart>(); 454 Predicate<SceneObjectPart> searchPredicate;
286
287 Action<SceneObjectGroup> searchAction;
288 455
289 if (useRegex) 456 if (useRegex)
290 { 457 {
291 Regex nameRegex = new Regex(name); 458 Regex nameRegex = new Regex(name);
292 searchAction = so => so.ForEachPart(sop => { if (nameRegex.IsMatch(sop.Name)) { parts.Add(sop); } }); 459 searchPredicate = sop => nameRegex.IsMatch(sop.Name);
293 } 460 }
294 else 461 else
295 { 462 {
296 searchAction = so => so.ForEachPart(sop => { if (sop.Name == name) { parts.Add(sop); } }); 463 searchPredicate = sop => sop.Name == name;
297 } 464 }
298 465
299 m_scene.ForEachSOG(searchAction); 466 OutputSopsToConsole(searchPredicate, true);
467 }
468
469 private void HandleDumpObjectById(string module, string[] cmdparams)
470 {
471 if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
472 return;
300 473
301 if (parts.Count == 0) 474 if (cmdparams.Length < 4)
302 { 475 {
303 m_console.OutputFormat("No parts with name {0} found in {1}", name, m_scene.RegionInfo.RegionName); 476 m_console.OutputFormat("Usage: dump object id <UUID-or-localID>");
304 return; 477 return;
305 } 478 }
306 479
307 StringBuilder sb = new StringBuilder(); 480 UUID objectUuid;
481 uint localId;
482 if (!ConsoleUtil.TryParseConsoleId(m_console, cmdparams[3], out objectUuid, out localId))
483 return;
308 484
309 foreach (SceneObjectPart part in parts) 485 SceneObjectGroup so;
486 if (localId == ConsoleUtil.LocalIdNotFound)
487 so = m_scene.GetSceneObjectGroup(objectUuid);
488 else
489 so = m_scene.GetSceneObjectGroup(localId);
490
491 if (so == null)
310 { 492 {
311 AddScenePartReport(sb, part); 493// m_console.OutputFormat("No part found with uuid {0}", objectUuid);
312 sb.Append("\n"); 494 return;
313 } 495 }
314 496
315 m_console.OutputFormat(sb.ToString()); 497 // In case we found it via local ID.
498 objectUuid = so.UUID;
499
500 string fileName = string.Format("{0}.xml", objectUuid);
501
502 if (!ConsoleUtil.CheckFileDoesNotExist(m_console, fileName))
503 return;
504
505 using (XmlTextWriter xtw = new XmlTextWriter(fileName, Encoding.UTF8))
506 {
507 xtw.Formatting = Formatting.Indented;
508 SceneObjectSerializer.ToOriginalXmlFormat(so, xtw, true);
509 }
510
511 m_console.OutputFormat("Object dumped to file {0}", fileName);
316 } 512 }
317 513
318 private StringBuilder AddSceneObjectReport(StringBuilder sb, SceneObjectGroup so) 514 /// <summary>
515 /// Append a scene object report to an input StringBuilder
516 /// </summary>
517 /// <returns></returns>
518 /// <param name='sb'></param>
519 /// <param name='so'</param>
520 /// <param name='showFull'>
521 /// If true then information on all parts of an object is appended.
522 /// If false then only summary information about an object is appended.
523 /// </param>
524 private StringBuilder AddSceneObjectReport(StringBuilder sb, SceneObjectGroup so, bool showFull)
319 { 525 {
320 sb.AppendFormat("Name: {0}\n", so.Name); 526 if (showFull)
321 sb.AppendFormat("Description: {0}\n", so.Description); 527 {
322 sb.AppendFormat("Location: {0} @ {1}\n", so.AbsolutePosition, so.Scene.RegionInfo.RegionName); 528 foreach (SceneObjectPart sop in so.Parts)
323 sb.AppendFormat("Parts: {0}\n", so.PrimCount); 529 {
324 sb.AppendFormat("Flags: {0}\n", so.RootPart.Flags); 530 AddScenePartReport(sb, sop, false);
531 sb.Append("\n");
532 }
533 }
534 else
535 {
536 AddSummarySceneObjectReport(sb, so);
537 }
325 538
326 return sb; 539 return sb;
327 } 540 }
328 541
329 private StringBuilder AddScenePartReport(StringBuilder sb, SceneObjectPart sop) 542 private StringBuilder AddSummarySceneObjectReport(StringBuilder sb, SceneObjectGroup so)
330 { 543 {
331 sb.AppendFormat("Name: {0}\n", sop.Name); 544 ConsoleDisplayList cdl = new ConsoleDisplayList();
332 sb.AppendFormat("Description: {0}\n", sop.Description); 545 cdl.AddRow("Name", so.Name);
333 sb.AppendFormat("Location: {0} @ {1}\n", sop.AbsolutePosition, sop.ParentGroup.Scene.RegionInfo.RegionName); 546 cdl.AddRow("Descrition", so.Description);
334 sb.AppendFormat("Parent: {0}", 547 cdl.AddRow("Local ID", so.LocalId);
335 sop.IsRoot ? "Is Root\n" : string.Format("{0} {1}\n", sop.ParentGroup.Name, sop.ParentGroup.UUID)); 548 cdl.AddRow("UUID", so.UUID);
336 sb.AppendFormat("Link number: {0}\n", sop.LinkNum); 549 cdl.AddRow("Location", string.Format("{0} @ {1}", so.AbsolutePosition, so.Scene.Name));
337 sb.AppendFormat("Flags: {0}\n", sop.Flags); 550 cdl.AddRow("Parts", so.PrimCount);
551 cdl.AddRow("Flags", so.RootPart.Flags);
552
553 return sb.Append(cdl.ToString());
554 }
338 555
339 return sb; 556 /// <summary>
557 /// Append a scene object part report to an input StringBuilder
558 /// </summary>
559 /// <returns></returns>
560 /// <param name='sb'></param>
561 /// <param name='sop'</param>
562 /// <param name='showFull'>
563 /// If true then information on each inventory item will be shown.
564 /// If false then only summary inventory information is shown.
565 /// </param>
566 private StringBuilder AddScenePartReport(StringBuilder sb, SceneObjectPart sop, bool showFull)
567 {
568 ConsoleDisplayList cdl = new ConsoleDisplayList();
569 cdl.AddRow("Name", sop.Name);
570 cdl.AddRow("Description", sop.Description);
571 cdl.AddRow("Local ID", sop.LocalId);
572 cdl.AddRow("UUID", sop.UUID);
573 cdl.AddRow("Location", string.Format("{0} @ {1}", sop.AbsolutePosition, sop.ParentGroup.Scene.Name));
574 cdl.AddRow(
575 "Parent",
576 sop.IsRoot ? "Is Root" : string.Format("{0} {1}", sop.ParentGroup.Name, sop.ParentGroup.UUID));
577 cdl.AddRow("Link number", sop.LinkNum);
578 cdl.AddRow("Flags", sop.Flags);
579
580 object itemsOutput;
581 if (showFull)
582 {
583 StringBuilder itemsSb = new StringBuilder("\n");
584 itemsOutput = AddScenePartItemsReport(itemsSb, sop.Inventory).ToString();
585 }
586 else
587 {
588 itemsOutput = sop.Inventory.Count;
589 }
590
591
592 cdl.AddRow("Items", itemsOutput);
593
594 return sb.Append(cdl.ToString());
595 }
596
597 private StringBuilder AddScenePartItemsReport(StringBuilder sb, IEntityInventory inv)
598 {
599 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
600 cdt.Indent = 2;
601
602 cdt.AddColumn("Name", 50);
603 cdt.AddColumn("Type", 12);
604 cdt.AddColumn("Running", 7);
605 cdt.AddColumn("Item UUID", 36);
606 cdt.AddColumn("Asset UUID", 36);
607
608 foreach (TaskInventoryItem item in inv.GetInventoryItems())
609 {
610 bool foundScriptInstance, scriptRunning;
611 foundScriptInstance
612 = SceneObjectPartInventory.TryGetScriptInstanceRunning(m_scene, item, out scriptRunning);
613
614 cdt.AddRow(
615 item.Name,
616 ((InventoryType)item.InvType).ToString(),
617 foundScriptInstance ? scriptRunning.ToString() : "n/a",
618 item.ItemID.ToString(),
619 item.AssetID.ToString());
620 }
621
622 return sb.Append(cdt.ToString());
340 } 623 }
341 624
342 private void HandleDeleteObject(string module, string[] cmd) 625 private void HandleDeleteObject(string module, string[] cmd)
@@ -398,19 +681,24 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
398 681
399 break; 682 break;
400 683
401 case "uuid": 684 case "id":
402 if (!UUID.TryParse(o, out match)) 685 UUID uuid;
686 uint localId;
687 if (!ConsoleUtil.TryParseConsoleId(m_console, o, out uuid, out localId))
403 return; 688 return;
404 689
405 requireConfirmation = false; 690 requireConfirmation = false;
406 deletes = new List<SceneObjectGroup>(); 691 deletes = new List<SceneObjectGroup>();
407 692
408 m_scene.ForEachSOG(delegate (SceneObjectGroup g) 693 SceneObjectGroup so;
409 { 694 if (localId == ConsoleUtil.LocalIdNotFound)
410 if (g.UUID == match && !g.IsAttachment) 695 so = m_scene.GetSceneObjectGroup(uuid);
411 deletes.Add(g); 696 else
412 }); 697 so = m_scene.GetSceneObjectGroup(localId);
413 698
699 if (!so.IsAttachment)
700 deletes.Add(so);
701
414 // if (deletes.Count == 0) 702 // if (deletes.Count == 0)
415 // m_console.OutputFormat("No objects were found with uuid {0}", match); 703 // m_console.OutputFormat("No objects were found with uuid {0}", match);
416 704
@@ -450,6 +738,10 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
450 738
451 break; 739 break;
452 740
741 case "pos":
742 deletes = GetDeleteCandidatesByPos(module, cmd);
743 break;
744
453 default: 745 default:
454 m_console.OutputFormat("Unrecognized mode {0}", mode); 746 m_console.OutputFormat("Unrecognized mode {0}", mode);
455 return; 747 return;
@@ -464,7 +756,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
464 string.Format( 756 string.Format(
465 "Are you sure that you want to delete {0} objects from {1}", 757 "Are you sure that you want to delete {0} objects from {1}",
466 deletes.Count, m_scene.RegionInfo.RegionName), 758 deletes.Count, m_scene.RegionInfo.RegionName),
467 "n"); 759 "y/N");
468 760
469 if (response.ToLower() != "y") 761 if (response.ToLower() != "y")
470 { 762 {
@@ -486,9 +778,6 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
486 778
487 private List<SceneObjectGroup> GetDeleteCandidatesByName(string module, string[] cmdparams) 779 private List<SceneObjectGroup> GetDeleteCandidatesByName(string module, string[] cmdparams)
488 { 780 {
489 if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
490 return null;
491
492 bool useRegex = false; 781 bool useRegex = false;
493 OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null ); 782 OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null );
494 783
@@ -522,5 +811,52 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
522 811
523 return sceneObjects; 812 return sceneObjects;
524 } 813 }
814
815 /// <summary>
816 /// Get scene object delete candidates by position
817 /// </summary>
818 /// <param name='module'></param>
819 /// <param name='cmdparams'></param>
820 /// <returns>null if parsing failed on one of the arguments, otherwise a list of objects to delete. If there
821 /// are no objects to delete then the list will be empty./returns>
822 private List<SceneObjectGroup> GetDeleteCandidatesByPos(string module, string[] cmdparams)
823 {
824 if (cmdparams.Length < 5)
825 {
826 m_console.OutputFormat("Usage: delete object pos <start-coord> to <end-coord>");
827 return null;
828 }
829
830 Vector3 startVector, endVector;
831
832 if (!TryParseVectorRange(cmdparams.Skip(3).Take(3), out startVector, out endVector))
833 return null;
834
835 return m_scene.GetSceneObjectGroups().FindAll(
836 so => !so.IsAttachment && Util.IsInsideBox(so.AbsolutePosition, startVector, endVector));
837 }
838
839 private bool TryParseVectorRange(IEnumerable<string> rawComponents, out Vector3 startVector, out Vector3 endVector)
840 {
841 string rawConsoleStartVector = rawComponents.Take(1).Single();
842
843 if (!ConsoleUtil.TryParseConsoleMinVector(rawConsoleStartVector, out startVector))
844 {
845 m_console.OutputFormat("Error: Start vector {0} does not have a valid format", rawConsoleStartVector);
846 endVector = Vector3.Zero;
847
848 return false;
849 }
850
851 string rawConsoleEndVector = rawComponents.Skip(1).Take(1).Single();
852
853 if (!ConsoleUtil.TryParseConsoleMaxVector(rawConsoleEndVector, out endVector))
854 {
855 m_console.OutputFormat("Error: End vector {0} does not have a valid format", rawConsoleEndVector);
856 return false;
857 }
858
859 return true;
860 }
525 } 861 }
526} \ No newline at end of file 862} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index f3d38bc..ddaa227 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -37,13 +37,17 @@ using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces; 38using OpenSim.Services.Interfaces;
39 39
40using Mono.Addins;
41
40namespace OpenSim.Region.CoreModules.World.Permissions 42namespace OpenSim.Region.CoreModules.World.Permissions
41{ 43{
42 public class PermissionsModule : IRegionModule, IPermissionsModule 44 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "PermissionsModule")]
45 public class PermissionsModule : INonSharedRegionModule, IPermissionsModule
43 { 46 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 48
46 protected Scene m_scene; 49 protected Scene m_scene;
50 protected bool m_Enabled;
47 51
48 private InventoryFolderImpl m_libraryRootFolder; 52 private InventoryFolderImpl m_libraryRootFolder;
49 protected InventoryFolderImpl LibraryRootFolder 53 protected InventoryFolderImpl LibraryRootFolder
@@ -114,18 +118,44 @@ namespace OpenSim.Region.CoreModules.World.Permissions
114 private Dictionary<string, bool> GrantVB = new Dictionary<string, bool>(); 118 private Dictionary<string, bool> GrantVB = new Dictionary<string, bool>();
115 private Dictionary<string, bool> GrantJS = new Dictionary<string, bool>(); 119 private Dictionary<string, bool> GrantJS = new Dictionary<string, bool>();
116 private Dictionary<string, bool> GrantYP = new Dictionary<string, bool>(); 120 private Dictionary<string, bool> GrantYP = new Dictionary<string, bool>();
121
117 private IFriendsModule m_friendsModule; 122 private IFriendsModule m_friendsModule;
123 private IFriendsModule FriendsModule
124 {
125 get
126 {
127 if (m_friendsModule == null)
128 m_friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
129 return m_friendsModule;
130 }
131 }
118 private IGroupsModule m_groupsModule; 132 private IGroupsModule m_groupsModule;
119 private IMoapModule m_moapModule; 133 private IGroupsModule GroupsModule
134 {
135 get
136 {
137 if (m_groupsModule == null)
138 m_groupsModule = m_scene.RequestModuleInterface<IGroupsModule>();
139 return m_groupsModule;
140 }
141 }
120 142
143 private IMoapModule m_moapModule;
144 private IMoapModule MoapModule
145 {
146 get
147 {
148 if (m_moapModule == null)
149 m_moapModule = m_scene.RequestModuleInterface<IMoapModule>();
150 return m_moapModule;
151 }
152 }
121 #endregion 153 #endregion
122 154
123 #region IRegionModule Members 155 #region INonSharedRegionModule Members
124 156
125 public void Initialise(Scene scene, IConfigSource config) 157 public void Initialise(IConfigSource config)
126 { 158 {
127 m_scene = scene;
128
129 IConfig myConfig = config.Configs["Startup"]; 159 IConfig myConfig = config.Configs["Startup"];
130 160
131 string permissionModules = myConfig.GetString("permissionmodules", "DefaultPermissionsModule"); 161 string permissionModules = myConfig.GetString("permissionmodules", "DefaultPermissionsModule");
@@ -135,6 +165,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
135 if (!modules.Contains("DefaultPermissionsModule")) 165 if (!modules.Contains("DefaultPermissionsModule"))
136 return; 166 return;
137 167
168 m_Enabled = true;
169
138 m_allowGridGods = myConfig.GetBoolean("allow_grid_gods", false); 170 m_allowGridGods = myConfig.GetBoolean("allow_grid_gods", false);
139 m_bypassPermissions = !myConfig.GetBoolean("serverside_object_permissions", true); 171 m_bypassPermissions = !myConfig.GetBoolean("serverside_object_permissions", true);
140 m_propagatePermissions = myConfig.GetBoolean("propagate_permissions", true); 172 m_propagatePermissions = myConfig.GetBoolean("propagate_permissions", true);
@@ -144,7 +176,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
144 176
145 m_SimpleBuildPermissions = myConfig.GetBoolean("simple_build_permissions", false); 177 m_SimpleBuildPermissions = myConfig.GetBoolean("simple_build_permissions", false);
146 178
147 m_allowedScriptCreators 179 m_allowedScriptCreators
148 = ParseUserSetConfigSetting(myConfig, "allowed_script_creators", m_allowedScriptCreators); 180 = ParseUserSetConfigSetting(myConfig, "allowed_script_creators", m_allowedScriptCreators);
149 m_allowedScriptEditors 181 m_allowedScriptEditors
150 = ParseUserSetConfigSetting(myConfig, "allowed_script_editors", m_allowedScriptEditors); 182 = ParseUserSetConfigSetting(myConfig, "allowed_script_editors", m_allowedScriptEditors);
@@ -154,6 +186,64 @@ namespace OpenSim.Region.CoreModules.World.Permissions
154 else 186 else
155 m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks"); 187 m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks");
156 188
189 string grant = myConfig.GetString("GrantLSL", "");
190 if (grant.Length > 0)
191 {
192 foreach (string uuidl in grant.Split(','))
193 {
194 string uuid = uuidl.Trim(" \t".ToCharArray());
195 GrantLSL.Add(uuid, true);
196 }
197 }
198
199 grant = myConfig.GetString("GrantCS", "");
200 if (grant.Length > 0)
201 {
202 foreach (string uuidl in grant.Split(','))
203 {
204 string uuid = uuidl.Trim(" \t".ToCharArray());
205 GrantCS.Add(uuid, true);
206 }
207 }
208
209 grant = myConfig.GetString("GrantVB", "");
210 if (grant.Length > 0)
211 {
212 foreach (string uuidl in grant.Split(','))
213 {
214 string uuid = uuidl.Trim(" \t".ToCharArray());
215 GrantVB.Add(uuid, true);
216 }
217 }
218
219 grant = myConfig.GetString("GrantJS", "");
220 if (grant.Length > 0)
221 {
222 foreach (string uuidl in grant.Split(','))
223 {
224 string uuid = uuidl.Trim(" \t".ToCharArray());
225 GrantJS.Add(uuid, true);
226 }
227 }
228
229 grant = myConfig.GetString("GrantYP", "");
230 if (grant.Length > 0)
231 {
232 foreach (string uuidl in grant.Split(','))
233 {
234 string uuid = uuidl.Trim(" \t".ToCharArray());
235 GrantYP.Add(uuid, true);
236 }
237 }
238 }
239
240 public void AddRegion(Scene scene)
241 {
242 if (!m_Enabled)
243 return;
244
245 m_scene = scene;
246
157 scene.RegisterModuleInterface<IPermissionsModule>(this); 247 scene.RegisterModuleInterface<IPermissionsModule>(this);
158 248
159 //Register functions with Scene External Checks! 249 //Register functions with Scene External Checks!
@@ -169,44 +259,44 @@ namespace OpenSim.Region.CoreModules.World.Permissions
169 m_scene.Permissions.OnIsGridGod += IsGridGod; 259 m_scene.Permissions.OnIsGridGod += IsGridGod;
170 m_scene.Permissions.OnIsAdministrator += IsAdministrator; 260 m_scene.Permissions.OnIsAdministrator += IsAdministrator;
171 m_scene.Permissions.OnDuplicateObject += CanDuplicateObject; 261 m_scene.Permissions.OnDuplicateObject += CanDuplicateObject;
172 m_scene.Permissions.OnDeleteObject += CanDeleteObject; //MAYBE FULLY IMPLEMENTED 262 m_scene.Permissions.OnDeleteObject += CanDeleteObject;
173 m_scene.Permissions.OnEditObject += CanEditObject; //MAYBE FULLY IMPLEMENTED 263 m_scene.Permissions.OnEditObject += CanEditObject;
174 m_scene.Permissions.OnEditParcelProperties += CanEditParcelProperties; //MAYBE FULLY IMPLEMENTED 264 m_scene.Permissions.OnEditParcelProperties += CanEditParcelProperties;
175 m_scene.Permissions.OnInstantMessage += CanInstantMessage; 265 m_scene.Permissions.OnInstantMessage += CanInstantMessage;
176 m_scene.Permissions.OnInventoryTransfer += CanInventoryTransfer; //NOT YET IMPLEMENTED 266 m_scene.Permissions.OnInventoryTransfer += CanInventoryTransfer;
177 m_scene.Permissions.OnIssueEstateCommand += CanIssueEstateCommand; //FULLY IMPLEMENTED 267 m_scene.Permissions.OnIssueEstateCommand += CanIssueEstateCommand;
178 m_scene.Permissions.OnMoveObject += CanMoveObject; //MAYBE FULLY IMPLEMENTED 268 m_scene.Permissions.OnMoveObject += CanMoveObject;
179 m_scene.Permissions.OnObjectEntry += CanObjectEntry; 269 m_scene.Permissions.OnObjectEntry += CanObjectEntry;
180 m_scene.Permissions.OnReturnObjects += CanReturnObjects; //NOT YET IMPLEMENTED 270 m_scene.Permissions.OnReturnObjects += CanReturnObjects;
181 m_scene.Permissions.OnRezObject += CanRezObject; //MAYBE FULLY IMPLEMENTED 271 m_scene.Permissions.OnRezObject += CanRezObject;
182 m_scene.Permissions.OnRunConsoleCommand += CanRunConsoleCommand; 272 m_scene.Permissions.OnRunConsoleCommand += CanRunConsoleCommand;
183 m_scene.Permissions.OnRunScript += CanRunScript; //NOT YET IMPLEMENTED 273 m_scene.Permissions.OnRunScript += CanRunScript;
184 m_scene.Permissions.OnCompileScript += CanCompileScript; 274 m_scene.Permissions.OnCompileScript += CanCompileScript;
185 m_scene.Permissions.OnSellParcel += CanSellParcel; 275 m_scene.Permissions.OnSellParcel += CanSellParcel;
186 m_scene.Permissions.OnTakeObject += CanTakeObject; 276 m_scene.Permissions.OnTakeObject += CanTakeObject;
187 m_scene.Permissions.OnTakeCopyObject += CanTakeCopyObject; 277 m_scene.Permissions.OnTakeCopyObject += CanTakeCopyObject;
188 m_scene.Permissions.OnTerraformLand += CanTerraformLand; 278 m_scene.Permissions.OnTerraformLand += CanTerraformLand;
189 m_scene.Permissions.OnLinkObject += CanLinkObject; //NOT YET IMPLEMENTED 279 m_scene.Permissions.OnLinkObject += CanLinkObject;
190 m_scene.Permissions.OnDelinkObject += CanDelinkObject; //NOT YET IMPLEMENTED 280 m_scene.Permissions.OnDelinkObject += CanDelinkObject;
191 m_scene.Permissions.OnBuyLand += CanBuyLand; //NOT YET IMPLEMENTED 281 m_scene.Permissions.OnBuyLand += CanBuyLand;
192 282
193 m_scene.Permissions.OnViewNotecard += CanViewNotecard; //NOT YET IMPLEMENTED 283 m_scene.Permissions.OnViewNotecard += CanViewNotecard;
194 m_scene.Permissions.OnViewScript += CanViewScript; //NOT YET IMPLEMENTED 284 m_scene.Permissions.OnViewScript += CanViewScript;
195 m_scene.Permissions.OnEditNotecard += CanEditNotecard; //NOT YET IMPLEMENTED 285 m_scene.Permissions.OnEditNotecard += CanEditNotecard;
196 m_scene.Permissions.OnEditScript += CanEditScript; //NOT YET IMPLEMENTED 286 m_scene.Permissions.OnEditScript += CanEditScript;
197 287
198 m_scene.Permissions.OnCreateObjectInventory += CanCreateObjectInventory; 288 m_scene.Permissions.OnCreateObjectInventory += CanCreateObjectInventory;
199 m_scene.Permissions.OnEditObjectInventory += CanEditObjectInventory;//MAYBE FULLY IMPLEMENTED 289 m_scene.Permissions.OnEditObjectInventory += CanEditObjectInventory;
200 m_scene.Permissions.OnCopyObjectInventory += CanCopyObjectInventory; //NOT YET IMPLEMENTED 290 m_scene.Permissions.OnCopyObjectInventory += CanCopyObjectInventory;
201 m_scene.Permissions.OnDeleteObjectInventory += CanDeleteObjectInventory; //NOT YET IMPLEMENTED 291 m_scene.Permissions.OnDeleteObjectInventory += CanDeleteObjectInventory;
202 m_scene.Permissions.OnResetScript += CanResetScript; 292 m_scene.Permissions.OnResetScript += CanResetScript;
203 293
204 m_scene.Permissions.OnCreateUserInventory += CanCreateUserInventory; //NOT YET IMPLEMENTED 294 m_scene.Permissions.OnCreateUserInventory += CanCreateUserInventory;
205 m_scene.Permissions.OnCopyUserInventory += CanCopyUserInventory; //NOT YET IMPLEMENTED 295 m_scene.Permissions.OnCopyUserInventory += CanCopyUserInventory;
206 m_scene.Permissions.OnEditUserInventory += CanEditUserInventory; //NOT YET IMPLEMENTED 296 m_scene.Permissions.OnEditUserInventory += CanEditUserInventory;
207 m_scene.Permissions.OnDeleteUserInventory += CanDeleteUserInventory; //NOT YET IMPLEMENTED 297 m_scene.Permissions.OnDeleteUserInventory += CanDeleteUserInventory;
208 298
209 m_scene.Permissions.OnTeleport += CanTeleport; //NOT YET IMPLEMENTED 299 m_scene.Permissions.OnTeleport += CanTeleport;
210 300
211 m_scene.Permissions.OnControlPrimMedia += CanControlPrimMedia; 301 m_scene.Permissions.OnControlPrimMedia += CanControlPrimMedia;
212 m_scene.Permissions.OnInteractWithPrimMedia += CanInteractWithPrimMedia; 302 m_scene.Permissions.OnInteractWithPrimMedia += CanInteractWithPrimMedia;
@@ -226,52 +316,38 @@ namespace OpenSim.Region.CoreModules.World.Permissions
226 "Turn on permissions debugging", 316 "Turn on permissions debugging",
227 HandleDebugPermissions); 317 HandleDebugPermissions);
228 318
229 string grant = myConfig.GetString("GrantLSL",""); 319 }
230 if (grant.Length > 0) {
231 foreach (string uuidl in grant.Split(',')) {
232 string uuid = uuidl.Trim(" \t".ToCharArray());
233 GrantLSL.Add(uuid, true);
234 }
235 }
236 320
237 grant = myConfig.GetString("GrantCS",""); 321 public void RegionLoaded(Scene scene)
238 if (grant.Length > 0) { 322 {
239 foreach (string uuidl in grant.Split(',')) { 323 }
240 string uuid = uuidl.Trim(" \t".ToCharArray());
241 GrantCS.Add(uuid, true);
242 }
243 }
244 324
245 grant = myConfig.GetString("GrantVB",""); 325 public void RemoveRegion(Scene scene)
246 if (grant.Length > 0) { 326 {
247 foreach (string uuidl in grant.Split(',')) { 327 if (!m_Enabled)
248 string uuid = uuidl.Trim(" \t".ToCharArray()); 328 return;
249 GrantVB.Add(uuid, true);
250 }
251 }
252 329
253 grant = myConfig.GetString("GrantJS", ""); 330 m_scene.UnregisterModuleInterface<IPermissionsModule>(this);
254 if (grant.Length > 0) 331 }
255 {
256 foreach (string uuidl in grant.Split(','))
257 {
258 string uuid = uuidl.Trim(" \t".ToCharArray());
259 GrantJS.Add(uuid, true);
260 }
261 }
262 332
263 grant = myConfig.GetString("GrantYP", ""); 333 public void Close()
264 if (grant.Length > 0) 334 {
265 { 335 }
266 foreach (string uuidl in grant.Split(',')) 336
267 { 337 public string Name
268 string uuid = uuidl.Trim(" \t".ToCharArray()); 338 {
269 GrantYP.Add(uuid, true); 339 get { return "PermissionsModule"; }
270 } 340 }
271 }
272 341
342 public Type ReplaceableInterface
343 {
344 get { return null; }
273 } 345 }
274 346
347 #endregion
348
349 #region Console command handlers
350
275 public void HandleBypassPermissions(string module, string[] args) 351 public void HandleBypassPermissions(string module, string[] args)
276 { 352 {
277 if (m_scene.ConsoleScene() != null && 353 if (m_scene.ConsoleScene() != null &&
@@ -290,7 +366,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
290 m_bypassPermissions = val; 366 m_bypassPermissions = val;
291 367
292 m_log.InfoFormat( 368 m_log.InfoFormat(
293 "[PERMISSIONS]: Set permissions bypass to {0} for {1}", 369 "[PERMISSIONS]: Set permissions bypass to {0} for {1}",
294 m_bypassPermissions, m_scene.RegionInfo.RegionName); 370 m_bypassPermissions, m_scene.RegionInfo.RegionName);
295 } 371 }
296 } 372 }
@@ -343,39 +419,6 @@ namespace OpenSim.Region.CoreModules.World.Permissions
343 } 419 }
344 } 420 }
345 421
346 public void PostInitialise()
347 {
348 m_friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
349
350 if (m_friendsModule == null)
351 m_log.Debug("[PERMISSIONS]: Friends module not found, friend permissions will not work");
352
353 m_groupsModule = m_scene.RequestModuleInterface<IGroupsModule>();
354
355 if (m_groupsModule == null)
356 m_log.Debug("[PERMISSIONS]: Groups module not found, group permissions will not work");
357
358 m_moapModule = m_scene.RequestModuleInterface<IMoapModule>();
359
360 // This log line will be commented out when no longer required for debugging
361// if (m_moapModule == null)
362// m_log.Warn("[PERMISSIONS]: Media on a prim module not found, media on a prim permissions will not work");
363 }
364
365 public void Close()
366 {
367 }
368
369 public string Name
370 {
371 get { return "DefaultPermissionsModule"; }
372 }
373
374 public bool IsSharedModule
375 {
376 get { return false; }
377 }
378
379 #endregion 422 #endregion
380 423
381 #region Helper Functions 424 #region Helper Functions
@@ -400,10 +443,10 @@ namespace OpenSim.Region.CoreModules.World.Permissions
400 /// <returns></returns> 443 /// <returns></returns>
401 protected bool IsGroupMember(UUID groupID, UUID userID, ulong powers) 444 protected bool IsGroupMember(UUID groupID, UUID userID, ulong powers)
402 { 445 {
403 if (null == m_groupsModule) 446 if (null == GroupsModule)
404 return false; 447 return false;
405 448
406 GroupMembershipData gmd = m_groupsModule.GetMembershipData(groupID, userID); 449 GroupMembershipData gmd = GroupsModule.GetMembershipData(groupID, userID);
407 450
408 if (gmd != null) 451 if (gmd != null)
409 { 452 {
@@ -503,10 +546,10 @@ namespace OpenSim.Region.CoreModules.World.Permissions
503 if (user == UUID.Zero) 546 if (user == UUID.Zero)
504 return false; 547 return false;
505 548
506 if (m_friendsModule == null) 549 if (FriendsModule == null)
507 return false; 550 return false;
508 551
509 int friendPerms = m_friendsModule.GetRightsGrantedByFriend(user, objectOwner); 552 int friendPerms = FriendsModule.GetRightsGrantedByFriend(user, objectOwner);
510 return (friendPerms & (int)FriendRights.CanModifyObjects) != 0; 553 return (friendPerms & (int)FriendRights.CanModifyObjects) != 0;
511 } 554 }
512 555
@@ -1915,14 +1958,14 @@ namespace OpenSim.Region.CoreModules.World.Permissions
1915// "[PERMISSONS]: Performing CanControlPrimMedia check with agentID {0}, primID {1}, face {2}", 1958// "[PERMISSONS]: Performing CanControlPrimMedia check with agentID {0}, primID {1}, face {2}",
1916// agentID, primID, face); 1959// agentID, primID, face);
1917 1960
1918 if (null == m_moapModule) 1961 if (null == MoapModule)
1919 return false; 1962 return false;
1920 1963
1921 SceneObjectPart part = m_scene.GetSceneObjectPart(primID); 1964 SceneObjectPart part = m_scene.GetSceneObjectPart(primID);
1922 if (null == part) 1965 if (null == part)
1923 return false; 1966 return false;
1924 1967
1925 MediaEntry me = m_moapModule.GetMediaEntry(part, face); 1968 MediaEntry me = MoapModule.GetMediaEntry(part, face);
1926 1969
1927 // If there is no existing media entry then it can be controlled (in this context, created). 1970 // If there is no existing media entry then it can be controlled (in this context, created).
1928 if (null == me) 1971 if (null == me)
@@ -1941,14 +1984,14 @@ namespace OpenSim.Region.CoreModules.World.Permissions
1941// "[PERMISSONS]: Performing CanInteractWithPrimMedia check with agentID {0}, primID {1}, face {2}", 1984// "[PERMISSONS]: Performing CanInteractWithPrimMedia check with agentID {0}, primID {1}, face {2}",
1942// agentID, primID, face); 1985// agentID, primID, face);
1943 1986
1944 if (null == m_moapModule) 1987 if (null == MoapModule)
1945 return false; 1988 return false;
1946 1989
1947 SceneObjectPart part = m_scene.GetSceneObjectPart(primID); 1990 SceneObjectPart part = m_scene.GetSceneObjectPart(primID);
1948 if (null == part) 1991 if (null == part)
1949 return false; 1992 return false;
1950 1993
1951 MediaEntry me = m_moapModule.GetMediaEntry(part, face); 1994 MediaEntry me = MoapModule.GetMediaEntry(part, face);
1952 1995
1953 // If there is no existing media entry then it can be controlled (in this context, created). 1996 // If there is no existing media entry then it can be controlled (in this context, created).
1954 if (null == me) 1997 if (null == me)
diff --git a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
index 287738a..9c441ed 100644
--- a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
+++ b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Linq;
29using System.Reflection; 30using System.Reflection;
30using System.Timers; 31using System.Timers;
31using System.IO; 32using System.IO;
@@ -305,6 +306,9 @@ namespace OpenSim.Region.CoreModules.World.Region
305 for (int i = 4 ; i < args.Length ; i++) 306 for (int i = 4 ; i < args.Length ; i++)
306 times.Add(Convert.ToInt32(args[i])); 307 times.Add(Convert.ToInt32(args[i]));
307 308
309 MainConsole.Instance.OutputFormat(
310 "Region {0} scheduled for restart in {1} seconds", m_Scene.Name, times.Sum());
311
308 ScheduleRestart(UUID.Zero, args[3], times.ToArray(), notice); 312 ScheduleRestart(UUID.Zero, args[3], times.ToArray(), notice);
309 } 313 }
310 314
@@ -328,4 +332,4 @@ namespace OpenSim.Region.CoreModules.World.Region
328 } 332 }
329 } 333 }
330 } 334 }
331} 335} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/World/Serialiser/SerialiserModule.cs b/OpenSim/Region/CoreModules/World/Serialiser/SerialiserModule.cs
index 0e861a1..e0247d9 100644
--- a/OpenSim/Region/CoreModules/World/Serialiser/SerialiserModule.cs
+++ b/OpenSim/Region/CoreModules/World/Serialiser/SerialiserModule.cs
@@ -32,6 +32,7 @@ using System.Reflection;
32 32
33using log4net; 33using log4net;
34using Nini.Config; 34using Nini.Config;
35using Mono.Addins;
35 36
36using OpenMetaverse; 37using OpenMetaverse;
37using OpenSim.Region.CoreModules.Framework.InterfaceCommander; 38using OpenSim.Region.CoreModules.Framework.InterfaceCommander;
@@ -41,6 +42,7 @@ using OpenSim.Region.Framework.Scenes.Serialization;
41 42
42namespace OpenSim.Region.CoreModules.World.Serialiser 43namespace OpenSim.Region.CoreModules.World.Serialiser
43{ 44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SerialiserModule")]
44 public class SerialiserModule : ISharedRegionModule, IRegionSerialiserModule 46 public class SerialiserModule : ISharedRegionModule, IRegionSerialiserModule
45 { 47 {
46 private static readonly ILog m_log = 48 private static readonly ILog m_log =
diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
index 14c1a39..513a8f5 100644
--- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
+++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -24,56 +24,110 @@
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27
28using System; 27using System;
28using System.IO;
29using System.Collections.Generic;
30using System.Reflection;
31
29using Nini.Config; 32using Nini.Config;
30using OpenMetaverse; 33using OpenMetaverse;
34using log4net;
35using Mono.Addins;
36
31using OpenSim.Framework; 37using OpenSim.Framework;
32using OpenSim.Region.Framework.Interfaces; 38using OpenSim.Region.Framework.Interfaces;
33using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
34using System.Reflection;
35using log4net;
36 40
37namespace OpenSim.Region.CoreModules.World.Sound 41namespace OpenSim.Region.CoreModules.World.Sound
38{ 42{
39 public class SoundModule : IRegionModule, ISoundModule 43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SoundModule")]
44 public class SoundModule : INonSharedRegionModule, ISoundModule
40 { 45 {
41// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 private static readonly ILog m_log = LogManager.GetLogger(
42 47 MethodBase.GetCurrentMethod().DeclaringType);
43 protected Scene m_scene; 48
44 49 private Scene m_scene;
45 public void Initialise(Scene scene, IConfigSource source) 50
51 public bool Enabled { get; private set; }
52
53 public float MaxDistance { get; private set; }
54
55 #region INonSharedRegionModule
56
57 public void Initialise(IConfigSource configSource)
58 {
59 IConfig config = configSource.Configs["Sounds"];
60
61 if (config == null)
62 {
63 Enabled = true;
64 MaxDistance = 100.0f;
65 }
66 else
67 {
68 Enabled = config.GetString("Module", "OpenSim.Region.CoreModules.dll:SoundModule") ==
69 Path.GetFileName(Assembly.GetExecutingAssembly().Location)
70 + ":" + MethodBase.GetCurrentMethod().DeclaringType.Name;
71 MaxDistance = config.GetFloat("MaxDistance", 100.0f);
72 }
73 }
74
75 public void AddRegion(Scene scene) { }
76
77 public void RemoveRegion(Scene scene)
46 { 78 {
79 m_scene.EventManager.OnClientLogin -= OnNewClient;
80 }
81
82 public void RegionLoaded(Scene scene)
83 {
84 if (!Enabled)
85 return;
86
47 m_scene = scene; 87 m_scene = scene;
48 88 m_scene.EventManager.OnClientLogin += OnNewClient;
49 m_scene.EventManager.OnNewClient += OnNewClient; 89
50
51 m_scene.RegisterModuleInterface<ISoundModule>(this); 90 m_scene.RegisterModuleInterface<ISoundModule>(this);
52 } 91 }
53 92
54 public void PostInitialise() {} 93 public void Close() { }
55 public void Close() {} 94
95 public Type ReplaceableInterface
96 {
97 get { return typeof(ISoundModule); }
98 }
99
56 public string Name { get { return "Sound Module"; } } 100 public string Name { get { return "Sound Module"; } }
57 public bool IsSharedModule { get { return false; } } 101
58 102 #endregion
103
104 #region Event Handlers
105
59 private void OnNewClient(IClientAPI client) 106 private void OnNewClient(IClientAPI client)
60 { 107 {
61 client.OnSoundTrigger += TriggerSound; 108 client.OnSoundTrigger += TriggerSound;
62 } 109 }
63 110
111 #endregion
112
113 #region ISoundModule
114
64 public virtual void PlayAttachedSound( 115 public virtual void PlayAttachedSound(
65 UUID soundID, UUID ownerID, UUID objectID, double gain, Vector3 position, byte flags, float radius) 116 UUID soundID, UUID ownerID, UUID objectID, double gain, Vector3 position, byte flags, float radius)
66 { 117 {
67 SceneObjectPart part = m_scene.GetSceneObjectPart(objectID); 118 SceneObjectPart part;
68 if (part == null) 119 if (!m_scene.TryGetSceneObjectPart(objectID, out part))
69 return; 120 return;
70 121
71 SceneObjectGroup grp = part.ParentGroup; 122 SceneObjectGroup grp = part.ParentGroup;
72 123
124 if (radius == 0)
125 radius = MaxDistance;
126
73 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) 127 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp)
74 { 128 {
75 double dis = Util.GetDistanceTo(sp.AbsolutePosition, position); 129 double dis = Util.GetDistanceTo(sp.AbsolutePosition, position);
76 if (dis > 100.0) // Max audio distance 130 if (dis > MaxDistance) // Max audio distance
77 return; 131 return;
78 132
79 if (grp.IsAttachment) 133 if (grp.IsAttachment)
@@ -86,23 +140,21 @@ namespace OpenSim.Region.CoreModules.World.Sound
86 } 140 }
87 141
88 // Scale by distance 142 // Scale by distance
89 if (radius == 0) 143 double thisSpGain = gain * ((radius - dis) / radius);
90 gain = (float)((double)gain * ((100.0 - dis) / 100.0));
91 else
92 gain = (float)((double)gain * ((radius - dis) / radius));
93 144
94 sp.ControllingClient.SendPlayAttachedSound(soundID, objectID, ownerID, (float)gain, flags); 145 sp.ControllingClient.SendPlayAttachedSound(soundID, objectID,
146 ownerID, (float)thisSpGain, flags);
95 }); 147 });
96 } 148 }
97 149
98 public virtual void TriggerSound( 150 public virtual void TriggerSound(
99 UUID soundId, UUID ownerID, UUID objectID, UUID parentID, double gain, Vector3 position, UInt64 handle, float radius) 151 UUID soundId, UUID ownerID, UUID objectID, UUID parentID, double gain, Vector3 position, UInt64 handle, float radius)
100 { 152 {
101 SceneObjectPart part = m_scene.GetSceneObjectPart(objectID); 153 SceneObjectPart part;
102 if (part == null) 154 if (!m_scene.TryGetSceneObjectPart(objectID, out part))
103 { 155 {
104 ScenePresence sp; 156 ScenePresence sp;
105 if (!m_scene.TryGetScenePresence(objectID, out sp)) 157 if (!m_scene.TryGetScenePresence(ownerID, out sp))
106 return; 158 return;
107 } 159 }
108 else 160 else
@@ -116,24 +168,207 @@ namespace OpenSim.Region.CoreModules.World.Sound
116 } 168 }
117 } 169 }
118 170
171 if (radius == 0)
172 radius = MaxDistance;
173
119 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) 174 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp)
120 { 175 {
121 double dis = Util.GetDistanceTo(sp.AbsolutePosition, position); 176 double dis = Util.GetDistanceTo(sp.AbsolutePosition, position);
122 177
123 if (dis > 100.0) // Max audio distance 178 if (dis > MaxDistance) // Max audio distance
124 return; 179 return;
125 180
126 float thisSpGain;
127
128 // Scale by distance 181 // Scale by distance
129 if (radius == 0) 182 double thisSpGain = gain * ((radius - dis) / radius);
130 thisSpGain = (float)((double)gain * ((100.0 - dis) / 100.0)); 183
184 sp.ControllingClient.SendTriggeredSound(soundId, ownerID,
185 objectID, parentID, handle, position,
186 (float)thisSpGain);
187 });
188 }
189
190 public virtual void StopSound(UUID objectID)
191 {
192 SceneObjectPart m_host;
193 if (!m_scene.TryGetSceneObjectPart(objectID, out m_host))
194 return;
195
196 StopSound(m_host);
197 }
198
199 private static void StopSound(SceneObjectPart m_host)
200 {
201 m_host.AdjustSoundGain(0);
202 // Xantor 20080528: Clear prim data of sound instead
203 if (m_host.ParentGroup.LoopSoundSlavePrims.Contains(m_host))
204 {
205 if (m_host.ParentGroup.LoopSoundMasterPrim == m_host)
206 {
207 foreach (SceneObjectPart part in m_host.ParentGroup.LoopSoundSlavePrims)
208 {
209 part.Sound = UUID.Zero;
210 part.SoundFlags = 1 << 5;
211 part.SoundRadius = 0;
212 part.ScheduleFullUpdate();
213 part.SendFullUpdateToAllClients();
214 }
215 m_host.ParentGroup.LoopSoundMasterPrim = null;
216 m_host.ParentGroup.LoopSoundSlavePrims.Clear();
217 }
218 else
219 {
220 m_host.Sound = UUID.Zero;
221 m_host.SoundFlags = 1 << 5;
222 m_host.SoundRadius = 0;
223 m_host.ScheduleFullUpdate();
224 m_host.SendFullUpdateToAllClients();
225 }
226 }
227 else
228 {
229 m_host.Sound = UUID.Zero;
230 m_host.SoundFlags = 1 << 5;
231 m_host.SoundRadius = 0;
232 m_host.ScheduleFullUpdate();
233 m_host.SendFullUpdateToAllClients();
234 }
235 }
236
237 public virtual void PreloadSound(UUID objectID, UUID soundID, float radius)
238 {
239 SceneObjectPart part;
240 if (soundID == UUID.Zero
241 || !m_scene.TryGetSceneObjectPart(objectID, out part))
242 {
243 return;
244 }
245
246 if (radius == 0)
247 radius = MaxDistance;
248
249 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp)
250 {
251 if (!(Util.GetDistanceTo(sp.AbsolutePosition, part.AbsolutePosition) >= MaxDistance))
252 sp.ControllingClient.SendPreLoadSound(objectID, objectID, soundID);
253 });
254 }
255
256 // Xantor 20080528 we should do this differently.
257 // 1) apply the sound to the object
258 // 2) schedule full update
259 // just sending the sound out once doesn't work so well when other avatars come in view later on
260 // or when the prim gets moved, changed, sat on, whatever
261 // see large number of mantises (mantes?)
262 // 20080530 Updated to remove code duplication
263 // 20080530 Stop sound if there is one, otherwise volume only changes don't work
264 public void LoopSound(UUID objectID, UUID soundID,
265 double volume, double radius, bool isMaster)
266 {
267 SceneObjectPart m_host;
268 if (!m_scene.TryGetSceneObjectPart(objectID, out m_host))
269 return;
270
271 if (isMaster)
272 m_host.ParentGroup.LoopSoundMasterPrim = m_host;
273
274 if (m_host.Sound != UUID.Zero)
275 StopSound(m_host);
276
277 m_host.Sound = soundID;
278 m_host.SoundGain = volume;
279 m_host.SoundFlags = 1; // looping
280 m_host.SoundRadius = radius;
281
282 m_host.ScheduleFullUpdate();
283 m_host.SendFullUpdateToAllClients();
284 }
285
286 public void SendSound(UUID objectID, UUID soundID, double volume,
287 bool triggered, byte flags, float radius, bool useMaster,
288 bool isMaster)
289 {
290 if (soundID == UUID.Zero)
291 return;
292
293 SceneObjectPart part;
294 if (!m_scene.TryGetSceneObjectPart(objectID, out part))
295 return;
296
297 volume = Util.Clip((float)volume, 0, 1);
298
299 UUID parentID = part.ParentGroup.UUID;
300
301 Vector3 position = part.AbsolutePosition; // region local
302 ulong regionHandle = m_scene.RegionInfo.RegionHandle;
303
304 if (useMaster)
305 {
306 if (isMaster)
307 {
308 if (triggered)
309 TriggerSound(soundID, part.OwnerID, part.UUID, parentID, volume, position, regionHandle, radius);
310 else
311 PlayAttachedSound(soundID, part.OwnerID, part.UUID, volume, position, flags, radius);
312 part.ParentGroup.PlaySoundMasterPrim = part;
313 if (triggered)
314 TriggerSound(soundID, part.OwnerID, part.UUID, parentID, volume, position, regionHandle, radius);
315 else
316 PlayAttachedSound(soundID, part.OwnerID, part.UUID, volume, position, flags, radius);
317 foreach (SceneObjectPart prim in part.ParentGroup.PlaySoundSlavePrims)
318 {
319 position = prim.AbsolutePosition; // region local
320 if (triggered)
321 TriggerSound(soundID, part.OwnerID, prim.UUID, parentID, volume, position, regionHandle, radius);
322 else
323 PlayAttachedSound(soundID, part.OwnerID, prim.UUID, volume, position, flags, radius);
324 }
325 part.ParentGroup.PlaySoundSlavePrims.Clear();
326 part.ParentGroup.PlaySoundMasterPrim = null;
327 }
131 else 328 else
132 thisSpGain = (float)((double)gain * ((radius - dis) / radius)); 329 {
330 part.ParentGroup.PlaySoundSlavePrims.Add(part);
331 }
332 }
333 else
334 {
335 if (triggered)
336 TriggerSound(soundID, part.OwnerID, part.UUID, parentID, volume, position, regionHandle, radius);
337 else
338 PlayAttachedSound(soundID, part.OwnerID, part.UUID, volume, position, flags, radius);
339 }
340 }
133 341
134 sp.ControllingClient.SendTriggeredSound( 342 public void TriggerSoundLimited(UUID objectID, UUID sound,
135 soundId, ownerID, objectID, parentID, handle, position, thisSpGain); 343 double volume, Vector3 min, Vector3 max)
344 {
345 if (sound == UUID.Zero)
346 return;
347
348 SceneObjectPart part;
349 if (!m_scene.TryGetSceneObjectPart(objectID, out part))
350 return;
351
352 m_scene.ForEachRootScenePresence(delegate(ScenePresence sp)
353 {
354 double dis = Util.GetDistanceTo(sp.AbsolutePosition,
355 part.AbsolutePosition);
356
357 if (dis > MaxDistance) // Max audio distance
358 return;
359 else if (!Util.IsInsideBox(sp.AbsolutePosition, min, max))
360 return;
361
362 // Scale by distance
363 double thisSpGain = volume * ((MaxDistance - dis) / MaxDistance);
364
365 sp.ControllingClient.SendTriggeredSound(sound, part.OwnerID,
366 part.UUID, part.ParentGroup.UUID,
367 m_scene.RegionInfo.RegionHandle,
368 part.AbsolutePosition, (float)thisSpGain);
136 }); 369 });
137 } 370 }
371
372 #endregion
138 } 373 }
139} 374}
diff --git a/OpenSim/Region/CoreModules/World/Sun/SunModule.cs b/OpenSim/Region/CoreModules/World/Sun/SunModule.cs
index 9a954b8..a321c09 100644
--- a/OpenSim/Region/CoreModules/World/Sun/SunModule.cs
+++ b/OpenSim/Region/CoreModules/World/Sun/SunModule.cs
@@ -29,6 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using log4net; 31using log4net;
32using Mono.Addins;
32using Nini.Config; 33using Nini.Config;
33using OpenMetaverse; 34using OpenMetaverse;
34using OpenSim.Framework; 35using OpenSim.Framework;
@@ -37,6 +38,7 @@ using OpenSim.Region.Framework.Scenes;
37 38
38namespace OpenSim.Region.CoreModules 39namespace OpenSim.Region.CoreModules
39{ 40{
41 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SunModule")]
40 public class SunModule : ISunModule 42 public class SunModule : ISunModule
41 { 43 {
42 /// <summary> 44 /// <summary>
@@ -267,26 +269,17 @@ namespace OpenSim.Region.CoreModules
267 return GetCurrentSunHour() + 6.0f; 269 return GetCurrentSunHour() + 6.0f;
268 } 270 }
269 271
270 #region IRegion Methods 272 #region INonSharedRegion Methods
271 273
272 // Called immediately after the module is loaded for a given region 274 // Called immediately after the module is loaded for a given region
273 // i.e. Immediately after instance creation. 275 // i.e. Immediately after instance creation.
274 public void Initialise(Scene scene, IConfigSource config) 276 public void Initialise(IConfigSource config)
275 { 277 {
276 m_scene = scene;
277 m_frame = 0; 278 m_frame = 0;
278 279
279 // This one puts an entry in the main help screen 280 // This one puts an entry in the main help screen
280// m_scene.AddCommand("Regions", this, "sun", "sun", "Usage: sun [param] [value] - Get or Update Sun module paramater", null); 281// m_scene.AddCommand("Regions", this, "sun", "sun", "Usage: sun [param] [value] - Get or Update Sun module paramater", null);
281 282
282 // This one enables the ability to type just "sun" without any parameters
283// m_scene.AddCommand("Regions", this, "sun", "", "", HandleSunConsoleCommand);
284 foreach (KeyValuePair<string, string> kvp in GetParamList())
285 {
286 string sunCommand = string.Format("sun {0}", kvp.Key);
287 m_scene.AddCommand("Regions", this, sunCommand, string.Format("{0} [<value>]", sunCommand), kvp.Value, "", HandleSunConsoleCommand);
288 }
289
290 TimeZone local = TimeZone.CurrentTimeZone; 283 TimeZone local = TimeZone.CurrentTimeZone;
291 TicksUTCOffset = local.GetUtcOffset(local.ToLocalTime(DateTime.Now)).Ticks; 284 TicksUTCOffset = local.GetUtcOffset(local.ToLocalTime(DateTime.Now)).Ticks;
292 m_log.DebugFormat("[SUN]: localtime offset is {0}", TicksUTCOffset); 285 m_log.DebugFormat("[SUN]: localtime offset is {0}", TicksUTCOffset);
@@ -358,15 +351,6 @@ namespace OpenSim.Region.CoreModules
358 HorizonShift = m_HorizonShift; // Z axis translation 351 HorizonShift = m_HorizonShift; // Z axis translation
359 // HoursToRadians = (SunCycle/24)*VWTimeRatio; 352 // HoursToRadians = (SunCycle/24)*VWTimeRatio;
360 353
361 // Insert our event handling hooks
362
363 scene.EventManager.OnFrame += SunUpdate;
364 scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel;
365 scene.EventManager.OnEstateToolsSunUpdate += EstateToolsSunUpdate;
366 scene.EventManager.OnGetCurrentTimeAsLindenSunHour += GetCurrentTimeAsLindenSunHour;
367
368 ready = true;
369
370 m_log.Debug("[SUN]: Mode is " + m_RegionMode); 354 m_log.Debug("[SUN]: Mode is " + m_RegionMode);
371 m_log.Debug("[SUN]: Initialization completed. Day is " + SecondsPerSunCycle + " seconds, and year is " + m_YearLengthDays + " days"); 355 m_log.Debug("[SUN]: Initialization completed. Day is " + SecondsPerSunCycle + " seconds, and year is " + m_YearLengthDays + " days");
372 m_log.Debug("[SUN]: Axis offset is " + m_HorizonShift); 356 m_log.Debug("[SUN]: Axis offset is " + m_HorizonShift);
@@ -376,14 +360,37 @@ namespace OpenSim.Region.CoreModules
376 break; 360 break;
377 } 361 }
378 362
379 scene.RegisterModuleInterface<ISunModule>(this);
380 } 363 }
381 364
382 public void PostInitialise() 365 public Type ReplaceableInterface
383 { 366 {
367 get { return null; }
384 } 368 }
385 369
386 public void Close() 370 public void AddRegion(Scene scene)
371 {
372 m_scene = scene;
373 // Insert our event handling hooks
374
375 scene.EventManager.OnFrame += SunUpdate;
376 scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel;
377 scene.EventManager.OnEstateToolsSunUpdate += EstateToolsSunUpdate;
378 scene.EventManager.OnGetCurrentTimeAsLindenSunHour += GetCurrentTimeAsLindenSunHour;
379
380 scene.RegisterModuleInterface<ISunModule>(this);
381
382 // This one enables the ability to type just "sun" without any parameters
383 // m_scene.AddCommand("Regions", this, "sun", "", "", HandleSunConsoleCommand);
384 foreach (KeyValuePair<string, string> kvp in GetParamList())
385 {
386 string sunCommand = string.Format("sun {0}", kvp.Key);
387 m_scene.AddCommand("Regions", this, sunCommand, string.Format("{0} [<value>]", sunCommand), kvp.Value, "", HandleSunConsoleCommand);
388 }
389
390 ready = true;
391 }
392
393 public void RemoveRegion(Scene scene)
387 { 394 {
388 ready = false; 395 ready = false;
389 396
@@ -394,14 +401,17 @@ namespace OpenSim.Region.CoreModules
394 m_scene.EventManager.OnGetCurrentTimeAsLindenSunHour -= GetCurrentTimeAsLindenSunHour; 401 m_scene.EventManager.OnGetCurrentTimeAsLindenSunHour -= GetCurrentTimeAsLindenSunHour;
395 } 402 }
396 403
397 public string Name 404 public void RegionLoaded(Scene scene)
398 { 405 {
399 get { return "SunModule"; }
400 } 406 }
401 407
402 public bool IsSharedModule 408 public void Close()
403 { 409 {
404 get { return false; } 410 }
411
412 public string Name
413 {
414 get { return "SunModule"; }
405 } 415 }
406 416
407 #endregion 417 #endregion
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index 402b9fb..33aabe4 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -33,6 +33,7 @@ using System.Net;
33using log4net; 33using log4net;
34using Nini.Config; 34using Nini.Config;
35using OpenMetaverse; 35using OpenMetaverse;
36using Mono.Addins;
36using OpenSim.Framework; 37using OpenSim.Framework;
37using OpenSim.Region.CoreModules.Framework.InterfaceCommander; 38using OpenSim.Region.CoreModules.Framework.InterfaceCommander;
38using OpenSim.Region.CoreModules.World.Terrain.FileLoaders; 39using OpenSim.Region.CoreModules.World.Terrain.FileLoaders;
@@ -43,6 +44,7 @@ using OpenSim.Region.Framework.Scenes;
43 44
44namespace OpenSim.Region.CoreModules.World.Terrain 45namespace OpenSim.Region.CoreModules.World.Terrain
45{ 46{
47 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "TerrainModule")]
46 public class TerrainModule : INonSharedRegionModule, ICommandableModule, ITerrainModule 48 public class TerrainModule : INonSharedRegionModule, ICommandableModule, ITerrainModule
47 { 49 {
48 #region StandardTerrainEffects enum 50 #region StandardTerrainEffects enum
@@ -414,6 +416,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
414 private void LoadPlugins() 416 private void LoadPlugins()
415 { 417 {
416 m_plugineffects = new Dictionary<string, ITerrainEffect>(); 418 m_plugineffects = new Dictionary<string, ITerrainEffect>();
419 LoadPlugins(Assembly.GetCallingAssembly());
417 string plugineffectsPath = "Terrain"; 420 string plugineffectsPath = "Terrain";
418 421
419 // Load the files in the Terrain/ dir 422 // Load the files in the Terrain/ dir
@@ -427,34 +430,39 @@ namespace OpenSim.Region.CoreModules.World.Terrain
427 try 430 try
428 { 431 {
429 Assembly library = Assembly.LoadFrom(file); 432 Assembly library = Assembly.LoadFrom(file);
430 foreach (Type pluginType in library.GetTypes()) 433 LoadPlugins(library);
431 { 434 }
432 try 435 catch (BadImageFormatException)
433 { 436 {
434 if (pluginType.IsAbstract || pluginType.IsNotPublic) 437 }
435 continue; 438 }
439 }
436 440
437 string typeName = pluginType.Name; 441 private void LoadPlugins(Assembly library)
442 {
443 foreach (Type pluginType in library.GetTypes())
444 {
445 try
446 {
447 if (pluginType.IsAbstract || pluginType.IsNotPublic)
448 continue;
438 449
439 if (pluginType.GetInterface("ITerrainEffect", false) != null) 450 string typeName = pluginType.Name;
440 {
441 ITerrainEffect terEffect = (ITerrainEffect) Activator.CreateInstance(library.GetType(pluginType.ToString()));
442 451
443 InstallPlugin(typeName, terEffect); 452 if (pluginType.GetInterface("ITerrainEffect", false) != null)
444 } 453 {
445 else if (pluginType.GetInterface("ITerrainLoader", false) != null) 454 ITerrainEffect terEffect = (ITerrainEffect)Activator.CreateInstance(library.GetType(pluginType.ToString()));
446 { 455
447 ITerrainLoader terLoader = (ITerrainLoader) Activator.CreateInstance(library.GetType(pluginType.ToString())); 456 InstallPlugin(typeName, terEffect);
448 m_loaders[terLoader.FileExtension] = terLoader; 457 }
449 m_log.Info("L ... " + typeName); 458 else if (pluginType.GetInterface("ITerrainLoader", false) != null)
450 } 459 {
451 } 460 ITerrainLoader terLoader = (ITerrainLoader)Activator.CreateInstance(library.GetType(pluginType.ToString()));
452 catch (AmbiguousMatchException) 461 m_loaders[terLoader.FileExtension] = terLoader;
453 { 462 m_log.Info("L ... " + typeName);
454 }
455 } 463 }
456 } 464 }
457 catch (BadImageFormatException) 465 catch (AmbiguousMatchException)
458 { 466 {
459 } 467 }
460 } 468 }
@@ -1178,7 +1186,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1178 1186
1179 private void InterfaceRunPluginEffect(Object[] args) 1187 private void InterfaceRunPluginEffect(Object[] args)
1180 { 1188 {
1181 if ((string) args[0] == "list") 1189 string firstArg = (string)args[0];
1190 if (firstArg == "list")
1182 { 1191 {
1183 m_log.Info("List of loaded plugins"); 1192 m_log.Info("List of loaded plugins");
1184 foreach (KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects) 1193 foreach (KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects)
@@ -1187,14 +1196,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1187 } 1196 }
1188 return; 1197 return;
1189 } 1198 }
1190 if ((string) args[0] == "reload") 1199 if (firstArg == "reload")
1191 { 1200 {
1192 LoadPlugins(); 1201 LoadPlugins();
1193 return; 1202 return;
1194 } 1203 }
1195 if (m_plugineffects.ContainsKey((string) args[0])) 1204 if (m_plugineffects.ContainsKey(firstArg))
1196 { 1205 {
1197 m_plugineffects[(string) args[0]].RunEffect(m_channel); 1206 m_plugineffects[firstArg].RunEffect(m_channel);
1198 CheckForTerrainUpdates(); 1207 CheckForTerrainUpdates();
1199 } 1208 }
1200 else 1209 else
diff --git a/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs b/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs
index f5f35bb..3f5d375 100644
--- a/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs
+++ b/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs
@@ -28,15 +28,17 @@
28using System; 28using System;
29using System.Reflection; 29using System.Reflection;
30using log4net; 30using log4net;
31using Mono.Addins;
31using Nini.Config; 32using Nini.Config;
32using OpenMetaverse; 33using OpenMetaverse;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Region.Framework.Interfaces; 35using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
36 37
37namespace OpenSim.Region.CoreModules.Avatar.Vegetation 38namespace OpenSim.Region.CoreModules.World.Vegetation
38{ 39{
39 public class VegetationModule : IRegionModule, IVegetationModule 40 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "VegetationModule")]
41 public class VegetationModule : INonSharedRegionModule, IVegetationModule
40 { 42 {
41 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
42 44
@@ -45,16 +47,32 @@ namespace OpenSim.Region.CoreModules.Avatar.Vegetation
45 protected static readonly PCode[] creationCapabilities = new PCode[] { PCode.Grass, PCode.NewTree, PCode.Tree }; 47 protected static readonly PCode[] creationCapabilities = new PCode[] { PCode.Grass, PCode.NewTree, PCode.Tree };
46 public PCode[] CreationCapabilities { get { return creationCapabilities; } } 48 public PCode[] CreationCapabilities { get { return creationCapabilities; } }
47 49
48 public void Initialise(Scene scene, IConfigSource source) 50 public void Initialise(IConfigSource source)
51 {
52 }
53
54 public void AddRegion(Scene scene)
49 { 55 {
50 m_scene = scene; 56 m_scene = scene;
51 m_scene.RegisterModuleInterface<IVegetationModule>(this); 57 m_scene.RegisterModuleInterface<IVegetationModule>(this);
52 } 58 }
53 59
54 public void PostInitialise() {} 60 public void RemoveRegion(Scene scene)
61 {
62 m_scene.UnregisterModuleInterface<IVegetationModule>(this);
63 }
64
55 public void Close() {} 65 public void Close() {}
56 public string Name { get { return "Vegetation Module"; } } 66 public string Name { get { return "Vegetation Module"; } }
57 public bool IsSharedModule { get { return false; } } 67
68 public Type ReplaceableInterface
69 {
70 get { return null; }
71 }
72
73 public void RegionLoaded(Scene scene)
74 {
75 }
58 76
59 public SceneObjectGroup AddTree( 77 public SceneObjectGroup AddTree(
60 UUID uuid, UUID groupID, Vector3 scale, Quaternion rotation, Vector3 position, Tree treeType, bool newTree) 78 UUID uuid, UUID groupID, Vector3 scale, Quaternion rotation, Vector3 position, Tree treeType, bool newTree)
diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
index 3c48d07..7ef44db 100644
--- a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
+++ b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
@@ -35,6 +35,7 @@ using CSJ2K;
35using Nini.Config; 35using Nini.Config;
36using log4net; 36using log4net;
37using Rednettle.Warp3D; 37using Rednettle.Warp3D;
38using Mono.Addins;
38using OpenMetaverse; 39using OpenMetaverse;
39using OpenMetaverse.Imaging; 40using OpenMetaverse.Imaging;
40using OpenMetaverse.Rendering; 41using OpenMetaverse.Rendering;
@@ -49,6 +50,7 @@ using WarpRenderer = global::Warp3D.Warp3D;
49 50
50namespace OpenSim.Region.CoreModules.World.Warp3DMap 51namespace OpenSim.Region.CoreModules.World.Warp3DMap
51{ 52{
53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "Warp3DImageModule")]
52 public class Warp3DImageModule : IMapImageGenerator, INonSharedRegionModule 54 public class Warp3DImageModule : IMapImageGenerator, INonSharedRegionModule
53 { 55 {
54 private static readonly UUID TEXTURE_METADATA_MAGIC = new UUID("802dc0e0-f080-4931-8b57-d1be8611c4f3"); 56 private static readonly UUID TEXTURE_METADATA_MAGIC = new UUID("802dc0e0-f080-4931-8b57-d1be8611c4f3");
@@ -66,7 +68,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
66 private Bitmap lastImage = null; 68 private Bitmap lastImage = null;
67 private DateTime lastImageTime = DateTime.MinValue; 69 private DateTime lastImageTime = DateTime.MinValue;
68 70
69 #region IRegionModule Members 71 #region Region Module interface
70 72
71 public void Initialise(IConfigSource source) 73 public void Initialise(IConfigSource source)
72 { 74 {
@@ -222,6 +224,13 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
222 bitmap = ImageUtils.ResizeImage(origBitmap, viewport.Width, viewport.Height); 224 bitmap = ImageUtils.ResizeImage(origBitmap, viewport.Width, viewport.Height);
223 } 225 }
224 226
227 // XXX: It shouldn't really be necesary to force a GC here as one should occur anyway pretty shortly
228 // afterwards. It's generally regarded as a bad idea to manually GC. If Warp3D is using lots of memory
229 // then this may be some issue with the Warp3D code itself, though it's also quite possible that generating
230 // this map tile simply takes a lot of memory.
231 GC.Collect();
232 m_log.Debug("[WARP 3D IMAGE MODULE]: GC.Collect()");
233
225 return bitmap; 234 return bitmap;
226 } 235 }
227 236
diff --git a/OpenSim/Region/CoreModules/World/Wind/Plugins/ConfigurableWind.cs b/OpenSim/Region/CoreModules/World/Wind/Plugins/ConfigurableWind.cs
index 9d47e19..6af4050 100644
--- a/OpenSim/Region/CoreModules/World/Wind/Plugins/ConfigurableWind.cs
+++ b/OpenSim/Region/CoreModules/World/Wind/Plugins/ConfigurableWind.cs
@@ -31,12 +31,14 @@ using System.Reflection;
31 31
32using log4net; 32using log4net;
33using OpenMetaverse; 33using OpenMetaverse;
34using Mono.Addins;
34 35
35using OpenSim.Region.Framework.Interfaces; 36using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.CoreModules.World.Wind; 37using OpenSim.Region.CoreModules.World.Wind;
37 38
38namespace OpenSim.Region.CoreModules.World.Wind.Plugins 39namespace OpenSim.Region.CoreModules.World.Wind.Plugins
39{ 40{
41 [Extension(Path = "/OpenSim/WindModule", NodeName = "WindModel", Id = "ConfigurableWind")]
40 class ConfigurableWind : Mono.Addins.TypeExtensionNode, IWindModelPlugin 42 class ConfigurableWind : Mono.Addins.TypeExtensionNode, IWindModelPlugin
41 { 43 {
42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
diff --git a/OpenSim/Region/CoreModules/World/Wind/Plugins/SimpleRandomWind.cs b/OpenSim/Region/CoreModules/World/Wind/Plugins/SimpleRandomWind.cs
index 071e20b..fcb0c10 100644
--- a/OpenSim/Region/CoreModules/World/Wind/Plugins/SimpleRandomWind.cs
+++ b/OpenSim/Region/CoreModules/World/Wind/Plugins/SimpleRandomWind.cs
@@ -29,11 +29,13 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30 30
31using OpenMetaverse; 31using OpenMetaverse;
32using Mono.Addins;
32 33
33using OpenSim.Region.Framework.Interfaces; 34using OpenSim.Region.Framework.Interfaces;
34 35
35namespace OpenSim.Region.CoreModules.World.Wind.Plugins 36namespace OpenSim.Region.CoreModules.World.Wind.Plugins
36{ 37{
38 [Extension(Path = "/OpenSim/WindModule", NodeName = "WindModel", Id = "SimpleRandomWind")]
37 class SimpleRandomWind : Mono.Addins.TypeExtensionNode, IWindModelPlugin 39 class SimpleRandomWind : Mono.Addins.TypeExtensionNode, IWindModelPlugin
38 { 40 {
39 private Vector2[] m_windSpeeds = new Vector2[16 * 16]; 41 private Vector2[] m_windSpeeds = new Vector2[16 * 16];
diff --git a/OpenSim/Region/CoreModules/World/Wind/WindModule.cs b/OpenSim/Region/CoreModules/World/Wind/WindModule.cs
index 7b6fbda..fd8e2b4 100644
--- a/OpenSim/Region/CoreModules/World/Wind/WindModule.cs
+++ b/OpenSim/Region/CoreModules/World/Wind/WindModule.cs
@@ -40,6 +40,7 @@ using OpenSim.Region.CoreModules.World.Wind;
40 40
41namespace OpenSim.Region.CoreModules 41namespace OpenSim.Region.CoreModules
42{ 42{
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WindModule")]
43 public class WindModule : IWindModule 44 public class WindModule : IWindModule
44 { 45 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -52,31 +53,31 @@ namespace OpenSim.Region.CoreModules
52 private bool m_ready = false; 53 private bool m_ready = false;
53 54
54 private bool m_enabled = false; 55 private bool m_enabled = false;
55 56 private IConfig m_windConfig;
56 private IWindModelPlugin m_activeWindPlugin = null; 57 private IWindModelPlugin m_activeWindPlugin = null;
57 private const string m_dWindPluginName = "SimpleRandomWind"; 58 private string m_dWindPluginName = "SimpleRandomWind";
58 private Dictionary<string, IWindModelPlugin> m_availableWindPlugins = new Dictionary<string, IWindModelPlugin>(); 59 private Dictionary<string, IWindModelPlugin> m_availableWindPlugins = new Dictionary<string, IWindModelPlugin>();
59 60
60 // Simplified windSpeeds based on the fact that the client protocal tracks at a resolution of 16m 61 // Simplified windSpeeds based on the fact that the client protocal tracks at a resolution of 16m
61 private Vector2[] windSpeeds = new Vector2[16 * 16]; 62 private Vector2[] windSpeeds = new Vector2[16 * 16];
62 63
63 #region IRegion Methods 64 #region INonSharedRegionModule Methods
64 65
65 public void Initialise(Scene scene, IConfigSource config) 66 public void Initialise(IConfigSource config)
66 { 67 {
67 IConfig windConfig = config.Configs["Wind"]; 68 m_windConfig = config.Configs["Wind"];
68 string desiredWindPlugin = m_dWindPluginName; 69 string desiredWindPlugin = m_dWindPluginName;
69 70
70 if (windConfig != null) 71 if (m_windConfig != null)
71 { 72 {
72 m_enabled = windConfig.GetBoolean("enabled", true); 73 m_enabled = m_windConfig.GetBoolean("enabled", true);
73 74
74 m_frameUpdateRate = windConfig.GetInt("wind_update_rate", 150); 75 m_frameUpdateRate = m_windConfig.GetInt("wind_update_rate", 150);
75 76
76 // Determine which wind model plugin is desired 77 // Determine which wind model plugin is desired
77 if (windConfig.Contains("wind_plugin")) 78 if (m_windConfig.Contains("wind_plugin"))
78 { 79 {
79 desiredWindPlugin = windConfig.GetString("wind_plugin"); 80 m_dWindPluginName = m_windConfig.GetString("wind_plugin", m_dWindPluginName);
80 } 81 }
81 } 82 }
82 83
@@ -84,104 +85,111 @@ namespace OpenSim.Region.CoreModules
84 { 85 {
85 m_log.InfoFormat("[WIND] Enabled with an update rate of {0} frames.", m_frameUpdateRate); 86 m_log.InfoFormat("[WIND] Enabled with an update rate of {0} frames.", m_frameUpdateRate);
86 87
87 m_scene = scene; 88 }
88 m_frame = 0;
89
90 // Register all the Wind Model Plug-ins
91 foreach (IWindModelPlugin windPlugin in AddinManager.GetExtensionObjects("/OpenSim/WindModule", false))
92 {
93 m_log.InfoFormat("[WIND] Found Plugin: {0}", windPlugin.Name);
94 m_availableWindPlugins.Add(windPlugin.Name, windPlugin);
95 }
96 89
97 // Check for desired plugin 90 }
98 if (m_availableWindPlugins.ContainsKey(desiredWindPlugin))
99 {
100 m_activeWindPlugin = m_availableWindPlugins[desiredWindPlugin];
101 91
102 m_log.InfoFormat("[WIND] {0} plugin found, initializing.", desiredWindPlugin); 92 public void AddRegion(Scene scene)
93 {
94 if (!m_enabled)
95 return;
103 96
104 if (windConfig != null) 97 m_scene = scene;
105 { 98 m_frame = 0;
106 m_activeWindPlugin.Initialise();
107 m_activeWindPlugin.WindConfig(m_scene, windConfig);
108 }
109 }
110 99
100 // Register all the Wind Model Plug-ins
101 foreach (IWindModelPlugin windPlugin in AddinManager.GetExtensionObjects("/OpenSim/WindModule", false))
102 {
103 m_log.InfoFormat("[WIND] Found Plugin: {0}", windPlugin.Name);
104 m_availableWindPlugins.Add(windPlugin.Name, windPlugin);
105 }
111 106
112 // if the plug-in wasn't found, default to no wind. 107 // Check for desired plugin
113 if (m_activeWindPlugin == null) 108 if (m_availableWindPlugins.ContainsKey(m_dWindPluginName))
114 { 109 {
115 m_log.ErrorFormat("[WIND] Could not find specified wind plug-in: {0}", desiredWindPlugin); 110 m_activeWindPlugin = m_availableWindPlugins[m_dWindPluginName];
116 m_log.ErrorFormat("[WIND] Defaulting to no wind.");
117 }
118 111
119 // This one puts an entry in the main help screen 112 m_log.InfoFormat("[WIND] {0} plugin found, initializing.", m_dWindPluginName);
120// m_scene.AddCommand("Regions", this, "wind", "wind", "Usage: wind <plugin> <param> [value] - Get or Update Wind paramaters", null);
121
122 // This one enables the ability to type just the base command without any parameters
123// m_scene.AddCommand("Regions", this, "wind", "", "", HandleConsoleCommand);
124 113
125 // Get a list of the parameters for each plugin 114 if (m_windConfig != null)
126 foreach (IWindModelPlugin windPlugin in m_availableWindPlugins.Values)
127 { 115 {
128// m_scene.AddCommand("Regions", this, String.Format("wind base wind_plugin {0}", windPlugin.Name), String.Format("{0} - {1}", windPlugin.Name, windPlugin.Description), "", HandleConsoleBaseCommand); 116 m_activeWindPlugin.Initialise();
129 m_scene.AddCommand( 117 m_activeWindPlugin.WindConfig(m_scene, m_windConfig);
130 "Regions",
131 this,
132 "wind base wind_update_rate",
133 "wind base wind_update_rate [<value>]",
134 "Get or set the wind update rate.",
135 "",
136 HandleConsoleBaseCommand);
137
138 foreach (KeyValuePair<string, string> kvp in windPlugin.WindParams())
139 {
140 string windCommand = String.Format("wind {0} {1}", windPlugin.Name, kvp.Key);
141 m_scene.AddCommand("Regions", this, windCommand, string.Format("{0} [<value>]", windCommand), kvp.Value, "", HandleConsoleParamCommand);
142 }
143 } 118 }
119 }
144 120
145 // Register event handlers for when Avatars enter the region, and frame ticks
146 m_scene.EventManager.OnFrame += WindUpdate;
147 m_scene.EventManager.OnMakeRootAgent += OnAgentEnteredRegion;
148 121
149 // Register the wind module 122 // if the plug-in wasn't found, default to no wind.
150 m_scene.RegisterModuleInterface<IWindModule>(this); 123 if (m_activeWindPlugin == null)
124 {
125 m_log.ErrorFormat("[WIND] Could not find specified wind plug-in: {0}", m_dWindPluginName);
126 m_log.ErrorFormat("[WIND] Defaulting to no wind.");
127 }
151 128
152 // Generate initial wind values 129 // This one puts an entry in the main help screen
153 GenWindPos(); 130 // m_scene.AddCommand("Regions", this, "wind", "wind", "Usage: wind <plugin> <param> [value] - Get or Update Wind paramaters", null);
154 131
155 // Mark Module Ready for duty 132 // This one enables the ability to type just the base command without any parameters
156 m_ready = true; 133 // m_scene.AddCommand("Regions", this, "wind", "", "", HandleConsoleCommand);
157 134
135 // Get a list of the parameters for each plugin
136 foreach (IWindModelPlugin windPlugin in m_availableWindPlugins.Values)
137 {
138 // m_scene.AddCommand("Regions", this, String.Format("wind base wind_plugin {0}", windPlugin.Name), String.Format("{0} - {1}", windPlugin.Name, windPlugin.Description), "", HandleConsoleBaseCommand);
139 m_scene.AddCommand(
140 "Regions",
141 this,
142 "wind base wind_update_rate",
143 "wind base wind_update_rate [<value>]",
144 "Get or set the wind update rate.",
145 "",
146 HandleConsoleBaseCommand);
147
148 foreach (KeyValuePair<string, string> kvp in windPlugin.WindParams())
149 {
150 string windCommand = String.Format("wind {0} {1}", windPlugin.Name, kvp.Key);
151 m_scene.AddCommand("Regions", this, windCommand, string.Format("{0} [<value>]", windCommand), kvp.Value, "", HandleConsoleParamCommand);
152 }
158 } 153 }
159 154
160 } 155 // Register event handlers for when Avatars enter the region, and frame ticks
156 m_scene.EventManager.OnFrame += WindUpdate;
157 m_scene.EventManager.OnMakeRootAgent += OnAgentEnteredRegion;
161 158
162 public void PostInitialise() 159 // Register the wind module
163 { 160 m_scene.RegisterModuleInterface<IWindModule>(this);
161
162 // Generate initial wind values
163 GenWindPos();
164
165 // Mark Module Ready for duty
166 m_ready = true;
164 } 167 }
165 168
166 public void Close() 169 public void RemoveRegion(Scene scene)
167 { 170 {
168 if (m_enabled) 171 if (!m_enabled)
172 return;
173
174 m_ready = false;
175
176 // REVIEW: If a region module is closed, is there a possibility that it'll re-open/initialize ??
177 m_activeWindPlugin = null;
178 foreach (IWindModelPlugin windPlugin in m_availableWindPlugins.Values)
169 { 179 {
170 m_ready = false; 180 windPlugin.Dispose();
181 }
171 182
172 // REVIEW: If a region module is closed, is there a possibility that it'll re-open/initialize ?? 183 m_availableWindPlugins.Clear();
173 m_activeWindPlugin = null;
174 foreach (IWindModelPlugin windPlugin in m_availableWindPlugins.Values)
175 {
176 windPlugin.Dispose();
177 }
178 184
179 m_availableWindPlugins.Clear(); 185 // Remove our hooks
186 m_scene.EventManager.OnFrame -= WindUpdate;
187 m_scene.EventManager.OnMakeRootAgent -= OnAgentEnteredRegion;
180 188
181 // Remove our hooks 189 }
182 m_scene.EventManager.OnFrame -= WindUpdate; 190
183 m_scene.EventManager.OnMakeRootAgent -= OnAgentEnteredRegion; 191 public void Close()
184 } 192 {
185 } 193 }
186 194
187 public string Name 195 public string Name
@@ -189,11 +197,14 @@ namespace OpenSim.Region.CoreModules
189 get { return "WindModule"; } 197 get { return "WindModule"; }
190 } 198 }
191 199
192 public bool IsSharedModule 200 public Type ReplaceableInterface
193 { 201 {
194 get { return false; } 202 get { return null; }
195 } 203 }
196 204
205 public void RegionLoaded(Scene scene)
206 {
207 }
197 208
198 #endregion 209 #endregion
199 210
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
index 2417b1a..4c96a50 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
@@ -24,11 +24,13 @@
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27using System;
27using System.Collections.Generic; 28using System.Collections.Generic;
28using System.Reflection; 29using System.Reflection;
29using log4net; 30using log4net;
30using Nini.Config; 31using Nini.Config;
31using OpenMetaverse; 32using OpenMetaverse;
33using Mono.Addins;
32using OpenSim.Framework; 34using OpenSim.Framework;
33using OpenSim.Region.Framework.Interfaces; 35using OpenSim.Region.Framework.Interfaces;
34using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
@@ -37,16 +39,22 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
37 39
38namespace OpenSim.Region.CoreModules.World.WorldMap 40namespace OpenSim.Region.CoreModules.World.WorldMap
39{ 41{
40 public class MapSearchModule : IRegionModule 42 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MapSearchModule")]
43 public class MapSearchModule : ISharedRegionModule
41 { 44 {
42 private static readonly ILog m_log = 45 private static readonly ILog m_log =
43 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44 47
45 Scene m_scene = null; // only need one for communication with GridService 48 Scene m_scene = null; // only need one for communication with GridService
46 List<Scene> m_scenes = new List<Scene>(); 49 List<Scene> m_scenes = new List<Scene>();
50 List<UUID> m_Clients;
47 51
48 #region IRegionModule Members 52 #region ISharedRegionModule Members
49 public void Initialise(Scene scene, IConfigSource source) 53 public void Initialise(IConfigSource source)
54 {
55 }
56
57 public void AddRegion(Scene scene)
50 { 58 {
51 if (m_scene == null) 59 if (m_scene == null)
52 { 60 {
@@ -55,6 +63,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
55 63
56 m_scenes.Add(scene); 64 m_scenes.Add(scene);
57 scene.EventManager.OnNewClient += OnNewClient; 65 scene.EventManager.OnNewClient += OnNewClient;
66 m_Clients = new List<UUID>();
67 }
68
69 public void RemoveRegion(Scene scene)
70 {
71 m_scenes.Remove(scene);
72 if (m_scene == scene && m_scenes.Count > 0)
73 m_scene = m_scenes[0];
74
75 scene.EventManager.OnNewClient -= OnNewClient;
58 } 76 }
59 77
60 public void PostInitialise() 78 public void PostInitialise()
@@ -72,16 +90,40 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
72 get { return "MapSearchModule"; } 90 get { return "MapSearchModule"; }
73 } 91 }
74 92
75 public bool IsSharedModule 93 public Type ReplaceableInterface
76 { 94 {
77 get { return true; } 95 get { return null; }
78 } 96 }
79 97
98 public void RegionLoaded(Scene scene)
99 {
100 }
80 #endregion 101 #endregion
81 102
82 private void OnNewClient(IClientAPI client) 103 private void OnNewClient(IClientAPI client)
83 { 104 {
84 client.OnMapNameRequest += OnMapNameRequest; 105 client.OnMapNameRequest += OnMapNameRequestHandler;
106 }
107
108 private void OnMapNameRequestHandler(IClientAPI remoteClient, string mapName, uint flags)
109 {
110 lock (m_Clients)
111 {
112 if (m_Clients.Contains(remoteClient.AgentId))
113 return;
114
115 m_Clients.Add(remoteClient.AgentId);
116 }
117
118 try
119 {
120 OnMapNameRequest(remoteClient, mapName, flags);
121 }
122 finally
123 {
124 lock (m_Clients)
125 m_Clients.Remove(remoteClient.AgentId);
126 }
85 } 127 }
86 128
87 private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) 129 private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags)
@@ -175,6 +217,20 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
175 }); 217 });
176 } 218 }
177 219
220 private void AddFinalBlock(List<MapBlockData> blocks)
221 {
222 // final block, closing the search result
223 MapBlockData data = new MapBlockData();
224 data.Agents = 0;
225 data.Access = 255;
226 data.MapImageId = UUID.Zero;
227 data.Name = "";
228 data.RegionFlags = 0;
229 data.WaterHeight = 0; // not used
230 data.X = 0;
231 data.Y = 0;
232 blocks.Add(data);
233 }
178// private Scene GetClientScene(IClientAPI client) 234// private Scene GetClientScene(IClientAPI client)
179// { 235// {
180// foreach (Scene s in m_scenes) 236// foreach (Scene s in m_scenes)
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index 26b406e..2184a59 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -40,6 +40,7 @@ using Nini.Config;
40using OpenMetaverse; 40using OpenMetaverse;
41using OpenMetaverse.Imaging; 41using OpenMetaverse.Imaging;
42using OpenMetaverse.StructuredData; 42using OpenMetaverse.StructuredData;
43using Mono.Addins;
43using OpenSim.Framework; 44using OpenSim.Framework;
44using OpenSim.Framework.Capabilities; 45using OpenSim.Framework.Capabilities;
45using OpenSim.Framework.Monitoring; 46using OpenSim.Framework.Monitoring;
@@ -55,6 +56,7 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
55 56
56namespace OpenSim.Region.CoreModules.World.WorldMap 57namespace OpenSim.Region.CoreModules.World.WorldMap
57{ 58{
59 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WorldMapModule")]
58 public class WorldMapModule : INonSharedRegionModule, IWorldMapModule 60 public class WorldMapModule : INonSharedRegionModule, IWorldMapModule
59 { 61 {
60 private static readonly ILog m_log = 62 private static readonly ILog m_log =