diff options
author | teravus | 2012-11-15 10:05:16 -0500 |
---|---|---|
committer | teravus | 2012-11-15 10:05:16 -0500 |
commit | e9153e1d1aae50024d8cd05fe14a9bce34343a0e (patch) | |
tree | bc111d34f95a26b99c7e34d9e495dc14d1802cc3 /OpenSim/Region/CoreModules | |
parent | Merge master into teravuswork (diff) | |
download | opensim-SC_OLD-e9153e1d1aae50024d8cd05fe14a9bce34343a0e.zip opensim-SC_OLD-e9153e1d1aae50024d8cd05fe14a9bce34343a0e.tar.gz opensim-SC_OLD-e9153e1d1aae50024d8cd05fe14a9bce34343a0e.tar.bz2 opensim-SC_OLD-e9153e1d1aae50024d8cd05fe14a9bce34343a0e.tar.xz |
Revert "Merge master into teravuswork", it should have been avination, not master.
This reverts commit dfac269032300872c4d0dc507f4f9062d102b0f4, reversing
changes made to 619c39e5144f15aca129d6d999bcc5c34133ee64.
Diffstat (limited to '')
62 files changed, 1778 insertions, 4763 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs index da1ff2e..8a4fd8f 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs | |||
@@ -57,36 +57,39 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
57 | } | 57 | } |
58 | 58 | ||
59 | /// <summary> | 59 | /// <summary> |
60 | /// Return the xfer uploader for the given transaction. | 60 | /// Return a xfer uploader if one does not already exist. |
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> | ||
66 | /// <param name="transactionID"></param> | 62 | /// <param name="transactionID"></param> |
67 | /// <returns>The asset xfer uploader</returns> | 63 | /// <param name="assetID"> |
68 | public AssetXferUploader RequestXferUploader(UUID transactionID) | 64 | /// We must transfer the new asset ID into the uploader on creation, otherwise |
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) | ||
69 | { | 74 | { |
70 | AssetXferUploader uploader; | ||
71 | |||
72 | lock (XferUploaders) | 75 | lock (XferUploaders) |
73 | { | 76 | { |
74 | if (!XferUploaders.ContainsKey(transactionID)) | 77 | if (!XferUploaders.ContainsKey(transactionID)) |
75 | { | 78 | { |
76 | uploader = new AssetXferUploader(this, m_Scene, transactionID, m_dumpAssetsToFile); | 79 | AssetXferUploader uploader = new AssetXferUploader(this, m_Scene, assetID, m_dumpAssetsToFile); |
77 | 80 | ||
78 | // m_log.DebugFormat( | 81 | // m_log.DebugFormat( |
79 | // "[AGENT ASSETS TRANSACTIONS]: Adding asset xfer uploader {0} since it didn't previously exist", transactionID); | 82 | // "[AGENT ASSETS TRANSACTIONS]: Adding asset xfer uploader {0} since it didn't previously exist", transactionID); |
80 | 83 | ||
81 | XferUploaders.Add(transactionID, uploader); | 84 | XferUploaders.Add(transactionID, uploader); |
82 | } | 85 | |
83 | else | 86 | return uploader; |
84 | { | ||
85 | uploader = XferUploaders[transactionID]; | ||
86 | } | 87 | } |
87 | } | 88 | } |
88 | 89 | ||
89 | return uploader; | 90 | m_log.WarnFormat("[AGENT ASSETS TRANSACTIONS]: Ignoring request for asset xfer uploader {0} since it already exists", transactionID); |
91 | |||
92 | return null; | ||
90 | } | 93 | } |
91 | 94 | ||
92 | public void HandleXfer(ulong xferID, uint packetID, byte[] data) | 95 | public void HandleXfer(ulong xferID, uint packetID, byte[] data) |
@@ -148,30 +151,117 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
148 | string description, string name, sbyte invType, | 151 | string description, string name, sbyte invType, |
149 | sbyte type, byte wearableType, uint nextOwnerMask) | 152 | sbyte type, byte wearableType, uint nextOwnerMask) |
150 | { | 153 | { |
151 | AssetXferUploader uploader = RequestXferUploader(transactionID); | 154 | AssetXferUploader uploader = null; |
155 | |||
156 | lock (XferUploaders) | ||
157 | { | ||
158 | if (XferUploaders.ContainsKey(transactionID)) | ||
159 | uploader = XferUploaders[transactionID]; | ||
160 | } | ||
152 | 161 | ||
153 | uploader.RequestCreateInventoryItem( | 162 | if (uploader != null) |
154 | remoteClient, folderID, callbackID, | 163 | { |
155 | description, name, invType, type, wearableType, nextOwnerMask); | 164 | uploader.RequestCreateInventoryItem( |
165 | remoteClient, transactionID, folderID, | ||
166 | callbackID, description, name, invType, type, | ||
167 | wearableType, nextOwnerMask); | ||
156 | 168 | ||
157 | return true; | 169 | 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; | ||
158 | } | 196 | } |
159 | 197 | ||
160 | public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient, | 198 | public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient, |
161 | SceneObjectPart part, UUID transactionID, | 199 | SceneObjectPart part, UUID transactionID, |
162 | TaskInventoryItem item) | 200 | TaskInventoryItem item) |
163 | { | 201 | { |
164 | AssetXferUploader uploader = RequestXferUploader(transactionID); | 202 | AssetXferUploader uploader = null; |
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; | ||
165 | 220 | ||
166 | uploader.RequestUpdateTaskInventoryItem(remoteClient, item); | 221 | if (asset != null) |
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 | } | ||
167 | } | 242 | } |
168 | 243 | ||
169 | public void RequestUpdateInventoryItem(IClientAPI remoteClient, | 244 | public void RequestUpdateInventoryItem(IClientAPI remoteClient, |
170 | UUID transactionID, InventoryItemBase item) | 245 | UUID transactionID, InventoryItemBase item) |
171 | { | 246 | { |
172 | AssetXferUploader uploader = RequestXferUploader(transactionID); | 247 | AssetXferUploader uploader = null; |
248 | |||
249 | lock (XferUploaders) | ||
250 | { | ||
251 | if (XferUploaders.ContainsKey(transactionID)) | ||
252 | uploader = XferUploaders[transactionID]; | ||
253 | } | ||
173 | 254 | ||
174 | uploader.RequestUpdateInventoryItem(remoteClient, item); | 255 | if (uploader != null) |
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 | } | ||
175 | } | 265 | } |
176 | } | 266 | } |
177 | } | 267 | } |
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs index 4bb8986..441c4ff 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs | |||
@@ -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 | "[ASSET TRANSACTION MODULE] Called HandleTaskItemUpdateFromTransaction with item {0} in {1} for {2} in {3}", | 218 | "[TRANSACTIONS MANAGER] 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,8 +274,13 @@ 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); | 277 | AssetXferUploader uploader = transactions.RequestXferUploader(transaction, assetID); |
278 | uploader.StartUpload(remoteClient, assetID, transaction, type, data, storeLocal, tempFile); | 278 | |
279 | if (uploader != null) | ||
280 | { | ||
281 | uploader.Initialise(remoteClient, assetID, transaction, type, | ||
282 | data, storeLocal, tempFile); | ||
283 | } | ||
279 | } | 284 | } |
280 | 285 | ||
281 | /// <summary> | 286 | /// <summary> |
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs index f6dd5af..4cedfe6 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs | |||
@@ -49,75 +49,39 @@ 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> | ||
65 | /// Reference to the object that holds this uploader. Used to remove ourselves from it's list if we | 52 | /// Reference to the object that holds this uploader. Used to remove ourselves from it's list if we |
66 | /// are performing a delayed update. | 53 | /// are performing a delayed update. |
67 | /// </summary> | 54 | /// </summary> |
68 | AgentAssetTransactions m_transactions; | 55 | AgentAssetTransactions m_transactions; |
69 | 56 | ||
70 | private UploadState m_uploadState = UploadState.New; | ||
71 | |||
72 | private AssetBase m_asset; | 57 | private AssetBase m_asset; |
73 | private UUID InventFolder = UUID.Zero; | 58 | private UUID InventFolder = UUID.Zero; |
74 | private sbyte invType = 0; | 59 | private sbyte invType = 0; |
75 | 60 | ||
76 | private bool m_createItem; | 61 | private bool m_createItem = false; |
77 | private uint m_createItemCallback; | 62 | private uint m_createItemCallback = 0; |
78 | 63 | private bool m_updateItem = false; | |
79 | private bool m_updateItem; | ||
80 | private InventoryItemBase m_updateItemData; | 64 | private InventoryItemBase m_updateItemData; |
81 | 65 | ||
82 | private bool m_updateTaskItem; | ||
83 | private TaskInventoryItem m_updateTaskItemData; | ||
84 | |||
85 | private string m_description = String.Empty; | 66 | private string m_description = String.Empty; |
86 | private bool m_dumpAssetToFile; | 67 | private bool m_dumpAssetToFile; |
68 | private bool m_finished = false; | ||
87 | private string m_name = String.Empty; | 69 | private string m_name = String.Empty; |
88 | // private bool m_storeLocal; | 70 | private bool m_storeLocal; |
89 | private uint nextPerm = 0; | 71 | private uint nextPerm = 0; |
90 | private IClientAPI ourClient; | 72 | private IClientAPI ourClient; |
91 | 73 | private UUID TransactionID = UUID.Zero; | |
92 | private UUID m_transactionID; | ||
93 | |||
94 | private sbyte type = 0; | 74 | private sbyte type = 0; |
95 | private byte wearableType = 0; | 75 | private byte wearableType = 0; |
96 | private byte[] m_oldData = null; | 76 | private byte[] m_oldData = null; |
97 | public ulong XferID; | 77 | public ulong XferID; |
98 | private Scene m_Scene; | 78 | private Scene m_Scene; |
99 | 79 | ||
100 | /// <summary> | 80 | public AssetXferUploader(AgentAssetTransactions transactions, Scene scene, UUID assetID, bool dumpAssetToFile) |
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) | ||
115 | { | 81 | { |
116 | m_asset = new AssetBase(); | ||
117 | |||
118 | m_transactions = transactions; | 82 | m_transactions = transactions; |
119 | m_transactionID = transactionID; | ||
120 | m_Scene = scene; | 83 | m_Scene = scene; |
84 | m_asset = new AssetBase() { FullID = assetID }; | ||
121 | m_dumpAssetToFile = dumpAssetToFile; | 85 | m_dumpAssetToFile = dumpAssetToFile; |
122 | } | 86 | } |
123 | 87 | ||
@@ -163,50 +127,30 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
163 | } | 127 | } |
164 | 128 | ||
165 | /// <summary> | 129 | /// <summary> |
166 | /// Start asset transfer from the client | 130 | /// Initialise asset transfer from the client |
167 | /// </summary> | 131 | /// </summary> |
168 | /// <param name="remoteClient"></param> | 132 | /// <param name="xferID"></param> |
169 | /// <param name="assetID"></param> | 133 | /// <param name="packetID"></param> |
170 | /// <param name="transaction"></param> | 134 | /// <param name="data"></param> |
171 | /// <param name="type"></param> | 135 | public void Initialise(IClientAPI remoteClient, UUID assetID, |
172 | /// <param name="data"> | 136 | UUID transaction, sbyte type, byte[] data, bool storeLocal, |
173 | /// Optional data. If present then the asset is created immediately with this data | 137 | bool tempFile) |
174 | /// rather than requesting an upload from the client. The data must be longer than 2 bytes. | ||
175 | /// </param> | ||
176 | /// <param name="storeLocal"></param> | ||
177 | /// <param name="tempFile"></param> | ||
178 | public void StartUpload( | ||
179 | IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type, byte[] data, bool storeLocal, | ||
180 | bool tempFile) | ||
181 | { | 138 | { |
182 | // m_log.DebugFormat( | 139 | // m_log.DebugFormat( |
183 | // "[ASSET XFER UPLOADER]: Initialised xfer from {0}, asset {1}, transaction {2}, type {3}, storeLocal {4}, tempFile {5}, already received data length {6}", | 140 | // "[ASSET XFER UPLOADER]: Initialised xfer from {0}, asset {1}, transaction {2}, type {3}, storeLocal {4}, tempFile {5}, already received data length {6}", |
184 | // remoteClient.Name, assetID, transaction, type, storeLocal, tempFile, data.Length); | 141 | // remoteClient.Name, assetID, transaction, type, storeLocal, tempFile, data.Length); |
185 | 142 | ||
186 | lock (this) | ||
187 | { | ||
188 | if (m_uploadState != UploadState.New) | ||
189 | { | ||
190 | m_log.WarnFormat( | ||
191 | "[ASSET XFER UPLOADER]: Tried to start upload of asset {0}, transaction {1} for {2} but this is already in state {3}. Aborting.", | ||
192 | assetID, transaction, remoteClient.Name, m_uploadState); | ||
193 | |||
194 | return; | ||
195 | } | ||
196 | |||
197 | m_uploadState = UploadState.Uploading; | ||
198 | } | ||
199 | |||
200 | ourClient = remoteClient; | 143 | ourClient = remoteClient; |
201 | 144 | m_asset.Name = "blank"; | |
202 | m_asset.FullID = assetID; | 145 | m_asset.Description = "empty"; |
203 | m_asset.Type = type; | 146 | m_asset.Type = type; |
204 | m_asset.CreatorID = remoteClient.AgentId.ToString(); | 147 | m_asset.CreatorID = remoteClient.AgentId.ToString(); |
205 | m_asset.Data = data; | 148 | m_asset.Data = data; |
206 | m_asset.Local = storeLocal; | 149 | m_asset.Local = storeLocal; |
207 | m_asset.Temporary = tempFile; | 150 | m_asset.Temporary = tempFile; |
208 | 151 | ||
209 | // m_storeLocal = storeLocal; | 152 | TransactionID = transaction; |
153 | m_storeLocal = storeLocal; | ||
210 | 154 | ||
211 | if (m_asset.Data.Length > 2) | 155 | if (m_asset.Data.Length > 2) |
212 | { | 156 | { |
@@ -231,35 +175,36 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
231 | 175 | ||
232 | protected void SendCompleteMessage() | 176 | protected void SendCompleteMessage() |
233 | { | 177 | { |
178 | ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, | ||
179 | m_asset.FullID); | ||
180 | |||
234 | // We must lock in order to avoid a race with a separate thread dealing with an inventory item or create | 181 | // We must lock in order to avoid a race with a separate thread dealing with an inventory item or create |
235 | // message from other client UDP. | 182 | // message from other client UDP. |
236 | lock (this) | 183 | lock (this) |
237 | { | 184 | { |
238 | m_uploadState = UploadState.Complete; | 185 | m_finished = true; |
239 | |||
240 | ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, m_asset.FullID); | ||
241 | |||
242 | if (m_createItem) | 186 | if (m_createItem) |
243 | { | 187 | { |
244 | CompleteCreateItem(m_createItemCallback); | 188 | DoCreateItem(m_createItemCallback); |
245 | } | 189 | } |
246 | else if (m_updateItem) | 190 | else if (m_updateItem) |
247 | { | 191 | { |
248 | CompleteItemUpdate(m_updateItemData); | 192 | StoreAssetForItemUpdate(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); | ||
249 | } | 198 | } |
250 | else if (m_updateTaskItem) | 199 | else if (m_storeLocal) |
251 | { | 200 | { |
252 | CompleteTaskItemUpdate(m_updateTaskItemData); | 201 | m_Scene.AssetService.Store(m_asset); |
253 | } | 202 | } |
254 | // else if (m_storeLocal) | ||
255 | // { | ||
256 | // m_Scene.AssetService.Store(m_asset); | ||
257 | // } | ||
258 | } | 203 | } |
259 | 204 | ||
260 | m_log.DebugFormat( | 205 | m_log.DebugFormat( |
261 | "[ASSET XFER UPLOADER]: Uploaded asset {0} for transaction {1}", | 206 | "[ASSET XFER UPLOADER]: Uploaded asset {0} for transaction {1}", |
262 | m_asset.FullID, m_transactionID); | 207 | m_asset.FullID, TransactionID); |
263 | 208 | ||
264 | if (m_dumpAssetToFile) | 209 | if (m_dumpAssetToFile) |
265 | { | 210 | { |
@@ -287,37 +232,40 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
287 | } | 232 | } |
288 | 233 | ||
289 | public void RequestCreateInventoryItem(IClientAPI remoteClient, | 234 | public void RequestCreateInventoryItem(IClientAPI remoteClient, |
290 | UUID folderID, uint callbackID, | 235 | UUID transactionID, UUID folderID, uint callbackID, |
291 | string description, string name, sbyte invType, | 236 | string description, string name, sbyte invType, |
292 | sbyte type, byte wearableType, uint nextOwnerMask) | 237 | sbyte type, byte wearableType, uint nextOwnerMask) |
293 | { | 238 | { |
294 | InventFolder = folderID; | 239 | if (TransactionID == transactionID) |
295 | m_name = name; | ||
296 | m_description = description; | ||
297 | this.type = type; | ||
298 | this.invType = invType; | ||
299 | this.wearableType = wearableType; | ||
300 | nextPerm = nextOwnerMask; | ||
301 | m_asset.Name = name; | ||
302 | m_asset.Description = description; | ||
303 | m_asset.Type = type; | ||
304 | |||
305 | // We must lock to avoid a race with a separate thread uploading the asset. | ||
306 | lock (this) | ||
307 | { | 240 | { |
308 | if (m_uploadState == UploadState.Complete) | 241 | InventFolder = folderID; |
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) | ||
309 | { | 254 | { |
310 | CompleteCreateItem(callbackID); | 255 | if (m_finished) |
311 | } | 256 | { |
312 | else | 257 | DoCreateItem(callbackID); |
313 | { | 258 | } |
314 | m_createItem = true; //set flag so the inventory item is created when upload is complete | 259 | else |
315 | m_createItemCallback = callbackID; | 260 | { |
261 | m_createItem = true; //set flag so the inventory item is created when upload is complete | ||
262 | m_createItemCallback = callbackID; | ||
263 | } | ||
316 | } | 264 | } |
317 | } | 265 | } |
318 | } | 266 | } |
319 | 267 | ||
320 | public void RequestUpdateInventoryItem(IClientAPI remoteClient, InventoryItemBase item) | 268 | public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, InventoryItemBase item) |
321 | { | 269 | { |
322 | // We must lock to avoid a race with a separate thread uploading the asset. | 270 | // We must lock to avoid a race with a separate thread uploading the asset. |
323 | lock (this) | 271 | lock (this) |
@@ -332,9 +280,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
332 | item.AssetID = m_asset.FullID; | 280 | item.AssetID = m_asset.FullID; |
333 | m_Scene.InventoryService.UpdateItem(item); | 281 | m_Scene.InventoryService.UpdateItem(item); |
334 | 282 | ||
335 | if (m_uploadState == UploadState.Complete) | 283 | if (m_finished) |
336 | { | 284 | { |
337 | CompleteItemUpdate(item); | 285 | StoreAssetForItemUpdate(item); |
338 | } | 286 | } |
339 | else | 287 | else |
340 | { | 288 | { |
@@ -348,59 +296,20 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
348 | } | 296 | } |
349 | } | 297 | } |
350 | 298 | ||
351 | public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient, TaskInventoryItem taskItem) | ||
352 | { | ||
353 | // We must lock to avoid a race with a separate thread uploading the asset. | ||
354 | lock (this) | ||
355 | { | ||
356 | m_asset.Name = taskItem.Name; | ||
357 | m_asset.Description = taskItem.Description; | ||
358 | m_asset.Type = (sbyte)taskItem.Type; | ||
359 | taskItem.AssetID = m_asset.FullID; | ||
360 | |||
361 | if (m_uploadState == UploadState.Complete) | ||
362 | { | ||
363 | CompleteTaskItemUpdate(taskItem); | ||
364 | } | ||
365 | else | ||
366 | { | ||
367 | m_updateTaskItem = true; | ||
368 | m_updateTaskItemData = taskItem; | ||
369 | } | ||
370 | } | ||
371 | } | ||
372 | |||
373 | /// <summary> | 299 | /// <summary> |
374 | /// Store the asset for the given item when it has been uploaded. | 300 | /// Store the asset for the given item. |
375 | /// </summary> | 301 | /// </summary> |
376 | /// <param name="item"></param> | 302 | /// <param name="item"></param> |
377 | private void CompleteItemUpdate(InventoryItemBase item) | 303 | private void StoreAssetForItemUpdate(InventoryItemBase item) |
378 | { | 304 | { |
379 | // m_log.DebugFormat( | 305 | // m_log.DebugFormat( |
380 | // "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}", | 306 | // "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}", |
381 | // m_asset.FullID, item.Name, ourClient.Name); | 307 | // m_asset.FullID, item.Name, ourClient.Name); |
382 | 308 | ||
383 | m_Scene.AssetService.Store(m_asset); | 309 | m_Scene.AssetService.Store(m_asset); |
384 | |||
385 | m_transactions.RemoveXferUploader(m_transactionID); | ||
386 | } | ||
387 | |||
388 | /// <summary> | ||
389 | /// Store the asset for the given task item when it has been uploaded. | ||
390 | /// </summary> | ||
391 | /// <param name="taskItem"></param> | ||
392 | private void CompleteTaskItemUpdate(TaskInventoryItem taskItem) | ||
393 | { | ||
394 | // m_log.DebugFormat( | ||
395 | // "[ASSET XFER UPLOADER]: Storing asset {0} for earlier task item update for {1} for {2}", | ||
396 | // m_asset.FullID, taskItem.Name, ourClient.Name); | ||
397 | |||
398 | m_Scene.AssetService.Store(m_asset); | ||
399 | |||
400 | m_transactions.RemoveXferUploader(m_transactionID); | ||
401 | } | 310 | } |
402 | 311 | ||
403 | private void CompleteCreateItem(uint callbackID) | 312 | private void DoCreateItem(uint callbackID) |
404 | { | 313 | { |
405 | ValidateAssets(); | 314 | ValidateAssets(); |
406 | m_Scene.AssetService.Store(m_asset); | 315 | m_Scene.AssetService.Store(m_asset); |
@@ -430,8 +339,6 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
430 | ourClient.SendInventoryItemCreateUpdate(item, callbackID); | 339 | ourClient.SendInventoryItemCreateUpdate(item, callbackID); |
431 | else | 340 | else |
432 | ourClient.SendAlertMessage("Unable to create inventory item"); | 341 | ourClient.SendAlertMessage("Unable to create inventory item"); |
433 | |||
434 | m_transactions.RemoveXferUploader(m_transactionID); | ||
435 | } | 342 | } |
436 | 343 | ||
437 | private void ValidateAssets() | 344 | private void ValidateAssets() |
@@ -509,7 +416,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
509 | /// <returns>null if the asset has not finished uploading</returns> | 416 | /// <returns>null if the asset has not finished uploading</returns> |
510 | public AssetBase GetAssetData() | 417 | public AssetBase GetAssetData() |
511 | { | 418 | { |
512 | if (m_uploadState == UploadState.Complete) | 419 | if (m_finished) |
513 | { | 420 | { |
514 | ValidateAssets(); | 421 | ValidateAssets(); |
515 | return m_asset; | 422 | return m_asset; |
@@ -562,3 +469,4 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
562 | } | 469 | } |
563 | } | 470 | } |
564 | } | 471 | } |
472 | |||
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index d1a563c..7d7176f 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | |||
@@ -52,7 +52,7 @@ using OpenSim.Services.Interfaces; | |||
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 | ||
55 | namespace OpenSim.Region.CoreModules.Asset | 55 | namespace Flotsam.RegionModules.AssetCache |
56 | { | 56 | { |
57 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] | 57 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] |
58 | public class FlotsamAssetCache : ISharedRegionModule, IImprovedAssetCache, IAssetService | 58 | public class FlotsamAssetCache : ISharedRegionModule, IImprovedAssetCache, IAssetService |
@@ -107,6 +107,8 @@ namespace OpenSim.Region.CoreModules.Asset | |||
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 | |||
110 | public FlotsamAssetCache() | 112 | public FlotsamAssetCache() |
111 | { | 113 | { |
112 | m_InvalidChars.AddRange(Path.GetInvalidPathChars()); | 114 | m_InvalidChars.AddRange(Path.GetInvalidPathChars()); |
@@ -168,6 +170,8 @@ namespace OpenSim.Region.CoreModules.Asset | |||
168 | m_CacheDirectoryTierLen = assetConfig.GetInt("CacheDirectoryTierLength", m_CacheDirectoryTierLen); | 170 | m_CacheDirectoryTierLen = assetConfig.GetInt("CacheDirectoryTierLength", m_CacheDirectoryTierLen); |
169 | 171 | ||
170 | m_CacheWarnAt = assetConfig.GetInt("CacheWarnAt", m_CacheWarnAt); | 172 | m_CacheWarnAt = assetConfig.GetInt("CacheWarnAt", m_CacheWarnAt); |
173 | |||
174 | m_DeepScanBeforePurge = assetConfig.GetBoolean("DeepScanBeforePurge", m_DeepScanBeforePurge); | ||
171 | } | 175 | } |
172 | 176 | ||
173 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory {0}", m_CacheDirectory); | 177 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory {0}", m_CacheDirectory); |
@@ -515,10 +519,13 @@ namespace OpenSim.Region.CoreModules.Asset | |||
515 | // Purge all files last accessed prior to this point | 519 | // Purge all files last accessed prior to this point |
516 | DateTime purgeLine = DateTime.Now - m_FileExpiration; | 520 | DateTime purgeLine = DateTime.Now - m_FileExpiration; |
517 | 521 | ||
518 | // An asset cache may contain local non-temporary assets that are not in the asset service. Therefore, | 522 | // An optional deep scan at this point will ensure assets present in scenes, |
519 | // before cleaning up expired files we must scan the objects in the scene to make sure that we retain | 523 | // or referenced by objects in the scene, but not recently accessed |
520 | // such local assets if they have not been recently accessed. | 524 | // are not purged. |
521 | TouchAllSceneAssets(false); | 525 | if (m_DeepScanBeforePurge) |
526 | { | ||
527 | CacheScenes(); | ||
528 | } | ||
522 | 529 | ||
523 | foreach (string dir in Directory.GetDirectories(m_CacheDirectory)) | 530 | foreach (string dir in Directory.GetDirectories(m_CacheDirectory)) |
524 | { | 531 | { |
@@ -711,14 +718,11 @@ namespace OpenSim.Region.CoreModules.Asset | |||
711 | 718 | ||
712 | /// <summary> | 719 | /// <summary> |
713 | /// Iterates through all Scenes, doing a deep scan through assets | 720 | /// Iterates through all Scenes, doing a deep scan through assets |
714 | /// to update the access time of all assets present in the scene or referenced by assets | 721 | /// to cache all assets present in the scene or referenced by assets |
715 | /// in the scene. | 722 | /// in the scene |
716 | /// </summary> | 723 | /// </summary> |
717 | /// <param name="storeUncached"> | 724 | /// <returns></returns> |
718 | /// If true, then assets scanned which are not found in cache are added to the cache. | 725 | private int CacheScenes() |
719 | /// </param> | ||
720 | /// <returns>Number of distinct asset references found in the scene.</returns> | ||
721 | private int TouchAllSceneAssets(bool storeUncached) | ||
722 | { | 726 | { |
723 | UuidGatherer gatherer = new UuidGatherer(m_AssetService); | 727 | UuidGatherer gatherer = new UuidGatherer(m_AssetService); |
724 | 728 | ||
@@ -741,7 +745,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
741 | { | 745 | { |
742 | File.SetLastAccessTime(filename, DateTime.Now); | 746 | File.SetLastAccessTime(filename, DateTime.Now); |
743 | } | 747 | } |
744 | else if (storeUncached) | 748 | else |
745 | { | 749 | { |
746 | m_AssetService.Get(assetID.ToString()); | 750 | m_AssetService.Get(assetID.ToString()); |
747 | } | 751 | } |
@@ -869,14 +873,13 @@ namespace OpenSim.Region.CoreModules.Asset | |||
869 | 873 | ||
870 | break; | 874 | break; |
871 | 875 | ||
876 | |||
872 | case "assets": | 877 | case "assets": |
873 | m_log.Info("[FLOTSAM ASSET CACHE]: Ensuring assets are cached for all scenes."); | 878 | m_log.Info("[FLOTSAM ASSET CACHE]: Caching all assets, in all scenes."); |
874 | 879 | ||
875 | Util.FireAndForget(delegate { | 880 | Util.FireAndForget(delegate { |
876 | int assetReferenceTotal = TouchAllSceneAssets(true); | 881 | int assetsCached = CacheScenes(); |
877 | m_log.InfoFormat( | 882 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Completed Scene Caching, {0} assets found.", assetsCached); |
878 | "[FLOTSAM ASSET CACHE]: Completed check with {0} assets.", | ||
879 | assetReferenceTotal); | ||
880 | }); | 883 | }); |
881 | 884 | ||
882 | break; | 885 | break; |
diff --git a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs index 1c2bfd0..c91b25f 100644 --- a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs +++ b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs | |||
@@ -35,6 +35,7 @@ using Nini.Config; | |||
35 | using NUnit.Framework; | 35 | using NUnit.Framework; |
36 | using OpenMetaverse; | 36 | using OpenMetaverse; |
37 | using OpenMetaverse.Assets; | 37 | using OpenMetaverse.Assets; |
38 | using Flotsam.RegionModules.AssetCache; | ||
38 | using OpenSim.Framework; | 39 | using OpenSim.Framework; |
39 | using OpenSim.Region.Framework.Scenes; | 40 | using OpenSim.Region.Framework.Scenes; |
40 | using OpenSim.Region.Framework.Scenes.Serialization; | 41 | using OpenSim.Region.Framework.Scenes.Serialization; |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index acd156e..951afd7 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -286,20 +286,6 @@ 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 | { | ||
303 | lock (sp.AttachmentsSyncLock) | 289 | lock (sp.AttachmentsSyncLock) |
304 | { | 290 | { |
305 | // m_log.DebugFormat( | 291 | // m_log.DebugFormat( |
@@ -475,11 +461,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
475 | 461 | ||
476 | public void DetachSingleAttachmentToGround(IScenePresence sp, uint soLocalId) | 462 | public void DetachSingleAttachmentToGround(IScenePresence sp, uint soLocalId) |
477 | { | 463 | { |
478 | DetachSingleAttachmentToGround(sp, soLocalId, sp.AbsolutePosition, Quaternion.Identity); | ||
479 | } | ||
480 | |||
481 | public void DetachSingleAttachmentToGround(IScenePresence sp, uint soLocalId, Vector3 absolutePos, Quaternion absoluteRot) | ||
482 | { | ||
483 | if (!Enabled) | 464 | if (!Enabled) |
484 | return; | 465 | return; |
485 | 466 | ||
@@ -521,11 +502,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
521 | so.FromItemID = UUID.Zero; | 502 | so.FromItemID = UUID.Zero; |
522 | 503 | ||
523 | SceneObjectPart rootPart = so.RootPart; | 504 | SceneObjectPart rootPart = so.RootPart; |
524 | so.AbsolutePosition = absolutePos; | 505 | so.AbsolutePosition = sp.AbsolutePosition; |
525 | if (absoluteRot != Quaternion.Identity) | ||
526 | { | ||
527 | so.UpdateGroupRotationR(absoluteRot); | ||
528 | } | ||
529 | so.AttachedAvatar = UUID.Zero; | 506 | so.AttachedAvatar = UUID.Zero; |
530 | rootPart.SetParentLocalId(0); | 507 | rootPart.SetParentLocalId(0); |
531 | so.ClearPartAttachmentData(); | 508 | so.ClearPartAttachmentData(); |
@@ -639,9 +616,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
639 | 616 | ||
640 | if (grp.HasGroupChanged) | 617 | if (grp.HasGroupChanged) |
641 | { | 618 | { |
642 | m_log.DebugFormat( | 619 | // m_log.DebugFormat( |
643 | "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", | 620 | // "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", |
644 | grp.UUID, grp.AttachmentPoint); | 621 | // grp.UUID, grp.AttachmentPoint); |
645 | 622 | ||
646 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, scriptedState); | 623 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, scriptedState); |
647 | 624 | ||
@@ -885,7 +862,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
885 | // This will throw if the attachment fails | 862 | // This will throw if the attachment fails |
886 | try | 863 | try |
887 | { | 864 | { |
888 | AttachObjectInternal(sp, objatt, attachmentPt, false, false, false); | 865 | AttachObject(sp, objatt, attachmentPt, false, false, false); |
889 | } | 866 | } |
890 | catch (Exception e) | 867 | catch (Exception e) |
891 | { | 868 | { |
@@ -956,9 +933,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
956 | 933 | ||
957 | InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID); | 934 | InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID); |
958 | item = m_scene.InventoryService.GetItem(item); | 935 | item = m_scene.InventoryService.GetItem(item); |
959 | if (item == null) | ||
960 | return; | ||
961 | |||
962 | bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); | 936 | bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); |
963 | if (changed && m_scene.AvatarFactory != null) | 937 | if (changed && m_scene.AvatarFactory != null) |
964 | { | 938 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 4e9d3f9..d9a619d 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | |||
@@ -62,10 +62,7 @@ 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; | ||
69 | 66 | ||
70 | [TestFixtureSetUp] | 67 | [TestFixtureSetUp] |
71 | public void FixtureInit() | 68 | public void FixtureInit() |
@@ -86,7 +83,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
86 | { | 83 | { |
87 | // Console.WriteLine("Got chat [{0}]", oscm.Message); | 84 | // Console.WriteLine("Got chat [{0}]", oscm.Message); |
88 | 85 | ||
89 | // m_osChatMessageReceived = oscm; | 86 | m_osChatMessageReceived = oscm; |
90 | m_chatEvent.Set(); | 87 | m_chatEvent.Set(); |
91 | } | 88 | } |
92 | 89 | ||
@@ -102,8 +99,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
102 | "attachments-test-scene", TestHelpers.ParseTail(999), 1000, 1000, config); | 99 | "attachments-test-scene", TestHelpers.ParseTail(999), 1000, 1000, config); |
103 | SceneHelpers.SetupSceneModules(scene, config, modules.ToArray()); | 100 | SceneHelpers.SetupSceneModules(scene, config, modules.ToArray()); |
104 | 101 | ||
105 | scene.EventManager.OnAttach += (localID, itemID, avatarID) => m_numberOfAttachEventsFired++; | ||
106 | |||
107 | return scene; | 102 | return scene; |
108 | } | 103 | } |
109 | 104 | ||
@@ -186,8 +181,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
186 | TestHelpers.InMethod(); | 181 | TestHelpers.InMethod(); |
187 | // TestHelpers.EnableLogging(); | 182 | // TestHelpers.EnableLogging(); |
188 | 183 | ||
189 | m_numberOfAttachEventsFired = 0; | ||
190 | |||
191 | Scene scene = CreateTestScene(); | 184 | Scene scene = CreateTestScene(); |
192 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); | 185 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); |
193 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); | 186 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); |
@@ -196,7 +189,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
196 | 189 | ||
197 | SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID); | 190 | SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID); |
198 | 191 | ||
199 | m_numberOfAttachEventsFired = 0; | ||
200 | scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false); | 192 | scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false); |
201 | 193 | ||
202 | // Check status on scene presence | 194 | // Check status on scene presence |
@@ -224,8 +216,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
224 | 216 | ||
225 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | 217 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); |
226 | 218 | ||
227 | // Check events | 219 | // TestHelpers.DisableLogging(); |
228 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); | ||
229 | } | 220 | } |
230 | 221 | ||
231 | /// <summary> | 222 | /// <summary> |
@@ -237,8 +228,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
237 | TestHelpers.InMethod(); | 228 | TestHelpers.InMethod(); |
238 | // TestHelpers.EnableLogging(); | 229 | // TestHelpers.EnableLogging(); |
239 | 230 | ||
240 | m_numberOfAttachEventsFired = 0; | ||
241 | |||
242 | Scene scene = CreateTestScene(); | 231 | Scene scene = CreateTestScene(); |
243 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); | 232 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); |
244 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); | 233 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); |
@@ -258,9 +247,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
258 | 247 | ||
259 | Assert.That(sp.HasAttachments(), Is.False); | 248 | Assert.That(sp.HasAttachments(), Is.False); |
260 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | 249 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); |
261 | |||
262 | // Check events | ||
263 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0)); | ||
264 | } | 250 | } |
265 | 251 | ||
266 | [Test] | 252 | [Test] |
@@ -275,7 +261,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
275 | 261 | ||
276 | InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); | 262 | InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); |
277 | 263 | ||
278 | m_numberOfAttachEventsFired = 0; | ||
279 | scene.AttachmentsModule.RezSingleAttachmentFromInventory( | 264 | scene.AttachmentsModule.RezSingleAttachmentFromInventory( |
280 | sp, attItem.ID, (uint)AttachmentPoint.Chest); | 265 | sp, attItem.ID, (uint)AttachmentPoint.Chest); |
281 | 266 | ||
@@ -295,9 +280,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
295 | Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); | 280 | Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); |
296 | 281 | ||
297 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | 282 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); |
298 | |||
299 | // Check events | ||
300 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); | ||
301 | } | 283 | } |
302 | 284 | ||
303 | /// <summary> | 285 | /// <summary> |
@@ -356,8 +338,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
356 | ISceneEntity so | 338 | ISceneEntity so |
357 | = scene.AttachmentsModule.RezSingleAttachmentFromInventory( | 339 | = scene.AttachmentsModule.RezSingleAttachmentFromInventory( |
358 | sp, attItem.ID, (uint)AttachmentPoint.Chest); | 340 | sp, attItem.ID, (uint)AttachmentPoint.Chest); |
359 | |||
360 | m_numberOfAttachEventsFired = 0; | ||
361 | scene.AttachmentsModule.DetachSingleAttachmentToGround(sp, so.LocalId); | 341 | scene.AttachmentsModule.DetachSingleAttachmentToGround(sp, so.LocalId); |
362 | 342 | ||
363 | // Check scene presence status | 343 | // Check scene presence status |
@@ -373,9 +353,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
373 | 353 | ||
374 | // Check object in scene | 354 | // Check object in scene |
375 | Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null); | 355 | Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null); |
376 | |||
377 | // Check events | ||
378 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); | ||
379 | } | 356 | } |
380 | 357 | ||
381 | [Test] | 358 | [Test] |
@@ -392,8 +369,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
392 | SceneObjectGroup so | 369 | SceneObjectGroup so |
393 | = (SceneObjectGroup)scene.AttachmentsModule.RezSingleAttachmentFromInventory( | 370 | = (SceneObjectGroup)scene.AttachmentsModule.RezSingleAttachmentFromInventory( |
394 | sp, attItem.ID, (uint)AttachmentPoint.Chest); | 371 | sp, attItem.ID, (uint)AttachmentPoint.Chest); |
395 | |||
396 | m_numberOfAttachEventsFired = 0; | ||
397 | scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, so); | 372 | scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, so); |
398 | 373 | ||
399 | // Check status on scene presence | 374 | // Check status on scene presence |
@@ -405,9 +380,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
405 | Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo(0)); | 380 | Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo(0)); |
406 | 381 | ||
407 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(0)); | 382 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(0)); |
408 | |||
409 | // Check events | ||
410 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); | ||
411 | } | 383 | } |
412 | 384 | ||
413 | /// <summary> | 385 | /// <summary> |
@@ -489,14 +461,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
489 | 461 | ||
490 | SceneObjectGroup rezzedAtt = presence.GetAttachments()[0]; | 462 | SceneObjectGroup rezzedAtt = presence.GetAttachments()[0]; |
491 | 463 | ||
492 | m_numberOfAttachEventsFired = 0; | 464 | scene.IncomingCloseAgent(presence.UUID); |
493 | scene.IncomingCloseAgent(presence.UUID, false); | ||
494 | 465 | ||
495 | // Check that we can't retrieve this attachment from the scene. | 466 | // Check that we can't retrieve this attachment from the scene. |
496 | Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null); | 467 | Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null); |
497 | |||
498 | // Check events | ||
499 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0)); | ||
500 | } | 468 | } |
501 | 469 | ||
502 | [Test] | 470 | [Test] |
@@ -512,8 +480,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
512 | AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); | 480 | AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); |
513 | acd.Appearance = new AvatarAppearance(); | 481 | acd.Appearance = new AvatarAppearance(); |
514 | acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); | 482 | acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); |
515 | |||
516 | m_numberOfAttachEventsFired = 0; | ||
517 | ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd); | 483 | ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd); |
518 | 484 | ||
519 | Assert.That(presence.HasAttachments(), Is.True); | 485 | Assert.That(presence.HasAttachments(), Is.True); |
@@ -536,9 +502,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
536 | Assert.That(presence.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); | 502 | Assert.That(presence.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); |
537 | 503 | ||
538 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | 504 | 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)); | ||
542 | } | 505 | } |
543 | 506 | ||
544 | [Test] | 507 | [Test] |
@@ -559,14 +522,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
559 | 522 | ||
560 | Vector3 newPosition = new Vector3(1, 2, 4); | 523 | Vector3 newPosition = new Vector3(1, 2, 4); |
561 | 524 | ||
562 | m_numberOfAttachEventsFired = 0; | ||
563 | scene.SceneGraph.UpdatePrimGroupPosition(attSo.LocalId, newPosition, sp.ControllingClient); | 525 | scene.SceneGraph.UpdatePrimGroupPosition(attSo.LocalId, newPosition, sp.ControllingClient); |
564 | 526 | ||
565 | Assert.That(attSo.AbsolutePosition, Is.EqualTo(sp.AbsolutePosition)); | 527 | Assert.That(attSo.AbsolutePosition, Is.EqualTo(sp.AbsolutePosition)); |
566 | Assert.That(attSo.RootPart.AttachedPos, Is.EqualTo(newPosition)); | 528 | Assert.That(attSo.RootPart.AttachedPos, Is.EqualTo(newPosition)); |
567 | |||
568 | // Check events | ||
569 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0)); | ||
570 | } | 529 | } |
571 | 530 | ||
572 | [Test] | 531 | [Test] |
@@ -615,7 +574,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
615 | Vector3 teleportPosition = new Vector3(10, 11, 12); | 574 | Vector3 teleportPosition = new Vector3(10, 11, 12); |
616 | Vector3 teleportLookAt = new Vector3(20, 21, 22); | 575 | Vector3 teleportLookAt = new Vector3(20, 21, 22); |
617 | 576 | ||
618 | m_numberOfAttachEventsFired = 0; | ||
619 | sceneA.RequestTeleportLocation( | 577 | sceneA.RequestTeleportLocation( |
620 | beforeTeleportSp.ControllingClient, | 578 | beforeTeleportSp.ControllingClient, |
621 | sceneB.RegionInfo.RegionHandle, | 579 | sceneB.RegionInfo.RegionHandle, |
@@ -658,9 +616,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
658 | Assert.That(actualSceneAAttachments.Count, Is.EqualTo(0)); | 616 | Assert.That(actualSceneAAttachments.Count, Is.EqualTo(0)); |
659 | 617 | ||
660 | Assert.That(sceneA.GetSceneObjectGroups().Count, Is.EqualTo(0)); | 618 | Assert.That(sceneA.GetSceneObjectGroups().Count, Is.EqualTo(0)); |
661 | |||
662 | // Check events | ||
663 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0)); | ||
664 | } | 619 | } |
620 | |||
621 | // I'm commenting this test because scene setup NEEDS InventoryService to | ||
622 | // be non-null | ||
623 | //[Test] | ||
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 | // } | ||
665 | } | 643 | } |
666 | } | 644 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index e3bf997..4cb4370 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -533,7 +533,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
533 | // Ignore ruth's assets | 533 | // Ignore ruth's assets |
534 | if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID) | 534 | if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID) |
535 | continue; | 535 | continue; |
536 | |||
537 | InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); | 536 | InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); |
538 | baseItem = invService.GetItem(baseItem); | 537 | baseItem = invService.GetItem(baseItem); |
539 | 538 | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index 4407e40..dbbb0ae 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs | |||
@@ -197,7 +197,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
197 | string fromName = c.From; | 197 | string fromName = c.From; |
198 | string fromNamePrefix = ""; | 198 | string fromNamePrefix = ""; |
199 | UUID fromID = UUID.Zero; | 199 | UUID fromID = UUID.Zero; |
200 | UUID ownerID = UUID.Zero; | ||
201 | string message = c.Message; | 200 | string message = c.Message; |
202 | IScene scene = c.Scene; | 201 | IScene scene = c.Scene; |
203 | UUID destination = c.Destination; | 202 | UUID destination = c.Destination; |
@@ -225,16 +224,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
225 | fromNamePrefix = m_adminPrefix; | 224 | fromNamePrefix = m_adminPrefix; |
226 | } | 225 | } |
227 | destination = UUID.Zero; // Avatars cant "SayTo" | 226 | destination = UUID.Zero; // Avatars cant "SayTo" |
228 | ownerID = c.Sender.AgentId; | ||
229 | |||
230 | break; | 227 | break; |
231 | 228 | ||
232 | case ChatSourceType.Object: | 229 | case ChatSourceType.Object: |
233 | fromID = c.SenderUUID; | 230 | fromID = c.SenderUUID; |
234 | 231 | ||
235 | if (c.SenderObject != null && c.SenderObject is SceneObjectPart) | ||
236 | ownerID = ((SceneObjectPart)c.SenderObject).OwnerID; | ||
237 | |||
238 | break; | 232 | break; |
239 | } | 233 | } |
240 | 234 | ||
@@ -268,16 +262,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
268 | // objects on a parcel with access restrictions | 262 | // objects on a parcel with access restrictions |
269 | if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true) | 263 | if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true) |
270 | { | 264 | { |
271 | if (destination != UUID.Zero) | 265 | if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromNamePrefix + fromName, c.Type, message, sourceType)) |
272 | { | 266 | receiverIDs.Add(presence.UUID); |
273 | if (TrySendChatMessage(presence, fromPos, regionPos, fromID, ownerID, fromNamePrefix + fromName, c.Type, message, sourceType, true)) | ||
274 | receiverIDs.Add(presence.UUID); | ||
275 | } | ||
276 | else | ||
277 | { | ||
278 | if (TrySendChatMessage(presence, fromPos, regionPos, fromID, ownerID, fromNamePrefix + fromName, c.Type, message, sourceType, false)) | ||
279 | receiverIDs.Add(presence.UUID); | ||
280 | } | ||
281 | } | 267 | } |
282 | } | 268 | } |
283 | } | 269 | } |
@@ -338,7 +324,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
338 | (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId)) | 324 | (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId)) |
339 | return; | 325 | return; |
340 | 326 | ||
341 | client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID, fromID, | 327 | client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID, |
342 | (byte)sourceType, (byte)ChatAudibleLevel.Fully); | 328 | (byte)sourceType, (byte)ChatAudibleLevel.Fully); |
343 | receiverIDs.Add(client.AgentId); | 329 | receiverIDs.Add(client.AgentId); |
344 | } | 330 | } |
@@ -355,20 +341,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
355 | /// <param name="fromPos"></param> | 341 | /// <param name="fromPos"></param> |
356 | /// <param name="regionPos">/param> | 342 | /// <param name="regionPos">/param> |
357 | /// <param name="fromAgentID"></param> | 343 | /// <param name="fromAgentID"></param> |
358 | /// <param name='ownerID'> | ||
359 | /// Owner of the message. For at least some messages from objects, this has to be correctly filled with the owner's UUID. | ||
360 | /// This is the case for script error messages in viewer 3 since LLViewer change EXT-7762 | ||
361 | /// </param> | ||
362 | /// <param name="fromName"></param> | 344 | /// <param name="fromName"></param> |
363 | /// <param name="type"></param> | 345 | /// <param name="type"></param> |
364 | /// <param name="message"></param> | 346 | /// <param name="message"></param> |
365 | /// <param name="src"></param> | 347 | /// <param name="src"></param> |
366 | /// <returns>true if the message was sent to the receiver, false if it was not sent due to failing a | 348 | /// <returns>true if the message was sent to the receiver, false if it was not sent due to failing a |
367 | /// precondition</returns> | 349 | /// precondition</returns> |
368 | protected virtual bool TrySendChatMessage( | 350 | protected virtual bool TrySendChatMessage(ScenePresence presence, Vector3 fromPos, Vector3 regionPos, |
369 | ScenePresence presence, Vector3 fromPos, Vector3 regionPos, | 351 | UUID fromAgentID, string fromName, ChatTypeEnum type, |
370 | UUID fromAgentID, UUID ownerID, string fromName, ChatTypeEnum type, | 352 | string message, ChatSourceType src) |
371 | string message, ChatSourceType src, bool ignoreDistance) | ||
372 | { | 353 | { |
373 | // don't send chat to child agents | 354 | // don't send chat to child agents |
374 | if (presence.IsChildAgent) return false; | 355 | if (presence.IsChildAgent) return false; |
@@ -388,9 +369,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
388 | } | 369 | } |
389 | 370 | ||
390 | // TODO: should change so the message is sent through the avatar rather than direct to the ClientView | 371 | // TODO: should change so the message is sent through the avatar rather than direct to the ClientView |
391 | presence.ControllingClient.SendChatMessage( | 372 | presence.ControllingClient.SendChatMessage(message, (byte) type, fromPos, fromName, |
392 | message, (byte) type, fromPos, fromName, | 373 | fromAgentID, (byte)src, (byte)ChatAudibleLevel.Fully); |
393 | fromAgentID, ownerID, (byte)src, (byte)ChatAudibleLevel.Fully); | ||
394 | 374 | ||
395 | return true; | 375 | return true; |
396 | } | 376 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs index 5ec0ea9..d942e87 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], true), | 144 | transactionID, false, new Vector3(), new byte[0]), |
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 f1903c3..24ec435 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs | |||
@@ -28,7 +28,6 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Linq; | ||
32 | using System.Reflection; | 31 | using System.Reflection; |
33 | using System.Threading; | 32 | using System.Threading; |
34 | using log4net; | 33 | using log4net; |
@@ -483,9 +482,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
483 | Util.FireAndForget( | 482 | Util.FireAndForget( |
484 | delegate | 483 | delegate |
485 | { | 484 | { |
486 | // m_log.DebugFormat( | 485 | m_log.DebugFormat( |
487 | // "[FRIENDS MODULE]: Notifying {0} friends of {1} of online status {2}", | 486 | "[FRIENDS MODULE]: Notifying {0} friends of {1} of online status {2}", |
488 | // friendList.Count, agentID, online); | 487 | friendList.Count, agentID, online); |
489 | 488 | ||
490 | // Notify about this user status | 489 | // Notify about this user status |
491 | StatusNotify(friendList, agentID, online); | 490 | StatusNotify(friendList, agentID, online); |
@@ -496,36 +495,42 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
496 | 495 | ||
497 | protected virtual void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online) | 496 | protected virtual void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online) |
498 | { | 497 | { |
499 | List<string> friendStringIds = friendList.ConvertAll<string>(friend => friend.Friend); | 498 | foreach (FriendInfo friend in friendList) |
500 | List<string> remoteFriendStringIds = new List<string>(); | ||
501 | foreach (string friendStringId in friendStringIds) | ||
502 | { | 499 | { |
503 | UUID friendUuid; | 500 | UUID friendID; |
504 | if (UUID.TryParse(friendStringId, out friendUuid)) | 501 | if (UUID.TryParse(friend.Friend, out friendID)) |
505 | { | 502 | { |
506 | if (LocalStatusNotification(userID, friendUuid, online)) | 503 | // Try local |
504 | if (LocalStatusNotification(userID, friendID, online)) | ||
507 | continue; | 505 | continue; |
508 | 506 | ||
509 | remoteFriendStringIds.Add(friendStringId); | 507 | // The friend is not here [as root]. Let's forward. |
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. | ||
510 | } | 530 | } |
511 | else | 531 | else |
512 | { | 532 | { |
513 | m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friendStringId); | 533 | m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend); |
514 | } | ||
515 | } | ||
516 | |||
517 | // We do this regrouping so that we can efficiently send a single request rather than one for each | ||
518 | // friend in what may be a very large friends list. | ||
519 | PresenceInfo[] friendSessions = PresenceService.GetAgents(remoteFriendStringIds.ToArray()); | ||
520 | |||
521 | foreach (PresenceInfo friendSession in friendSessions) | ||
522 | { | ||
523 | // let's guard against sessions-gone-bad | ||
524 | if (friendSession.RegionID != UUID.Zero) | ||
525 | { | ||
526 | GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); | ||
527 | //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName); | ||
528 | m_FriendsSimConnector.StatusNotify(region, userID, friendSession.UserID, online); | ||
529 | } | 534 | } |
530 | } | 535 | } |
531 | } | 536 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs index 82816d9..716cc69 100644 --- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs | |||
@@ -206,7 +206,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods | |||
206 | transferModule.SendInstantMessage(new GridInstantMessage( | 206 | transferModule.SendInstantMessage(new GridInstantMessage( |
207 | m_scene, godID, "God", agentID, (byte)250, false, | 207 | m_scene, godID, "God", agentID, (byte)250, false, |
208 | Utils.BytesToString(reason), UUID.Zero, true, | 208 | Utils.BytesToString(reason), UUID.Zero, true, |
209 | new Vector3(), new byte[] {(byte)kickflags}, true), | 209 | new Vector3(), new byte[] {(byte)kickflags}), |
210 | delegate(bool success) {} ); | 210 | delegate(bool success) {} ); |
211 | } | 211 | } |
212 | return; | 212 | return; |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index d0e88f6..6587ead 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} (asset UUID {2})", | 169 | "[INVENTORY ARCHIVER]: Saving item {0} {1} with asset {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,14 +337,11 @@ 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 | AssetsRequest ar | 340 | new AssetsRequest( |
341 | = new AssetsRequest( | 341 | new AssetsArchiver(m_archiveWriter), |
342 | new AssetsArchiver(m_archiveWriter), | 342 | m_assetUuids, m_scene.AssetService, |
343 | m_assetUuids, m_scene.AssetService, | 343 | m_scene.UserAccountService, m_scene.RegionInfo.ScopeID, |
344 | m_scene.UserAccountService, m_scene.RegionInfo.ScopeID, | 344 | options, ReceivedAllAssets).Execute(); |
345 | options, ReceivedAllAssets); | ||
346 | |||
347 | Util.FireAndForget(o => ar.Execute()); | ||
348 | } | 345 | } |
349 | else | 346 | else |
350 | { | 347 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs index 765b960..7d1fe68 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs | |||
@@ -35,7 +35,6 @@ using Nini.Config; | |||
35 | using OpenMetaverse; | 35 | using OpenMetaverse; |
36 | using OpenSim.Framework; | 36 | using OpenSim.Framework; |
37 | using OpenSim.Framework.Communications; | 37 | using OpenSim.Framework.Communications; |
38 | using OpenSim.Framework.Console; | ||
39 | using OpenSim.Region.Framework.Interfaces; | 38 | using OpenSim.Region.Framework.Interfaces; |
40 | using OpenSim.Region.Framework.Scenes; | 39 | using OpenSim.Region.Framework.Scenes; |
41 | using OpenSim.Services.Interfaces; | 40 | using OpenSim.Services.Interfaces; |
@@ -210,9 +209,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
210 | Guid id, string firstName, string lastName, string invPath, string pass, string savePath, | 209 | Guid id, string firstName, string lastName, string invPath, string pass, string savePath, |
211 | Dictionary<string, object> options) | 210 | Dictionary<string, object> options) |
212 | { | 211 | { |
213 | // if (!ConsoleUtil.CheckFileDoesNotExist(MainConsole.Instance, savePath)) | ||
214 | // return false; | ||
215 | |||
216 | if (m_scenes.Count > 0) | 212 | if (m_scenes.Count > 0) |
217 | { | 213 | { |
218 | UserAccount userInfo = GetUserInfo(firstName, lastName, pass); | 214 | 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 00727a4..1056865 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs | |||
@@ -82,25 +82,7 @@ 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 | |||
104 | [SetUp] | 86 | [SetUp] |
105 | public override void SetUp() | 87 | public override void SetUp() |
106 | { | 88 | { |
@@ -108,6 +90,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
108 | m_iarStream = new MemoryStream(m_iarStreamBytes); | 90 | m_iarStream = new MemoryStream(m_iarStreamBytes); |
109 | } | 91 | } |
110 | 92 | ||
93 | [TestFixtureSetUp] | ||
94 | public void FixtureSetup() | ||
95 | { | ||
96 | ConstructDefaultIarBytesForTestLoad(); | ||
97 | } | ||
98 | |||
111 | protected void ConstructDefaultIarBytesForTestLoad() | 99 | protected void ConstructDefaultIarBytesForTestLoad() |
112 | { | 100 | { |
113 | // log4net.Config.XmlConfigurator.Configure(); | 101 | // log4net.Config.XmlConfigurator.Configure(); |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index 06f6e49..b112b6d 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 | // TestHelpers.EnableLogging(); | 72 | // log4net.Config.XmlConfigurator.Configure(); |
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 | // TestHelpers.EnableLogging(); | 361 | // log4net.Config.XmlConfigurator.Configure(); |
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 e26beec..8176989 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs | |||
@@ -38,15 +38,15 @@ using OpenSim.Services.Interfaces; | |||
38 | 38 | ||
39 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | 39 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer |
40 | { | 40 | { |
41 | public class InventoryTransferModule : ISharedRegionModule | 41 | public class InventoryTransferModule : IInventoryTransferModule, ISharedRegionModule |
42 | { | 42 | { |
43 | private static readonly ILog m_log | 43 | private static readonly ILog m_log |
44 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 44 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
45 | 45 | ||
46 | /// <summary> | 46 | /// <summary> |
47 | private List<Scene> m_Scenelist = new List<Scene>(); | 47 | private List<Scene> m_Scenelist = new List<Scene>(); |
48 | // private Dictionary<UUID, Scene> m_AgentRegions = | 48 | private Dictionary<UUID, Scene> m_AgentRegions = |
49 | // new Dictionary<UUID, Scene>(); | 49 | new Dictionary<UUID, Scene>(); |
50 | 50 | ||
51 | private IMessageTransferModule m_TransferModule = null; | 51 | private IMessageTransferModule m_TransferModule = null; |
52 | private bool m_Enabled = true; | 52 | private bool m_Enabled = true; |
@@ -76,12 +76,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
76 | 76 | ||
77 | m_Scenelist.Add(scene); | 77 | m_Scenelist.Add(scene); |
78 | 78 | ||
79 | // scene.RegisterModuleInterface<IInventoryTransferModule>(this); | 79 | scene.RegisterModuleInterface<IInventoryTransferModule>(this); |
80 | 80 | ||
81 | scene.EventManager.OnNewClient += OnNewClient; | 81 | scene.EventManager.OnNewClient += OnNewClient; |
82 | // scene.EventManager.OnClientClosed += ClientLoggedOut; | 82 | scene.EventManager.OnClientClosed += ClientLoggedOut; |
83 | scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; | 83 | scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; |
84 | // scene.EventManager.OnSetRootAgentScene += OnSetRootAgentScene; | 84 | scene.EventManager.OnSetRootAgentScene += OnSetRootAgentScene; |
85 | } | 85 | } |
86 | 86 | ||
87 | public void RegionLoaded(Scene scene) | 87 | public void RegionLoaded(Scene scene) |
@@ -96,9 +96,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
96 | 96 | ||
97 | m_Scenelist.Clear(); | 97 | m_Scenelist.Clear(); |
98 | scene.EventManager.OnNewClient -= OnNewClient; | 98 | scene.EventManager.OnNewClient -= OnNewClient; |
99 | // scene.EventManager.OnClientClosed -= ClientLoggedOut; | 99 | scene.EventManager.OnClientClosed -= ClientLoggedOut; |
100 | scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; | 100 | scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; |
101 | // scene.EventManager.OnSetRootAgentScene -= OnSetRootAgentScene; | 101 | scene.EventManager.OnSetRootAgentScene -= OnSetRootAgentScene; |
102 | } | 102 | } |
103 | } | 103 | } |
104 | } | 104 | } |
@@ -106,9 +106,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
106 | public void RemoveRegion(Scene scene) | 106 | public void RemoveRegion(Scene scene) |
107 | { | 107 | { |
108 | scene.EventManager.OnNewClient -= OnNewClient; | 108 | scene.EventManager.OnNewClient -= OnNewClient; |
109 | // scene.EventManager.OnClientClosed -= ClientLoggedOut; | 109 | scene.EventManager.OnClientClosed -= ClientLoggedOut; |
110 | scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; | 110 | scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; |
111 | // scene.EventManager.OnSetRootAgentScene -= OnSetRootAgentScene; | 111 | scene.EventManager.OnSetRootAgentScene -= OnSetRootAgentScene; |
112 | m_Scenelist.Remove(scene); | 112 | m_Scenelist.Remove(scene); |
113 | } | 113 | } |
114 | 114 | ||
@@ -138,10 +138,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
138 | client.OnInstantMessage += OnInstantMessage; | 138 | client.OnInstantMessage += OnInstantMessage; |
139 | } | 139 | } |
140 | 140 | ||
141 | // protected void OnSetRootAgentScene(UUID id, Scene scene) | 141 | protected void OnSetRootAgentScene(UUID id, Scene scene) |
142 | // { | 142 | { |
143 | // m_AgentRegions[id] = scene; | 143 | m_AgentRegions[id] = scene; |
144 | // } | 144 | } |
145 | 145 | ||
146 | private Scene FindClientScene(UUID agentId) | 146 | private Scene FindClientScene(UUID agentId) |
147 | { | 147 | { |
@@ -313,11 +313,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
313 | m_TransferModule.SendInstantMessage(im, delegate(bool success) {}); | 313 | m_TransferModule.SendInstantMessage(im, delegate(bool success) {}); |
314 | } | 314 | } |
315 | } | 315 | } |
316 | |||
317 | // XXX: This code was placed here to try and accomdate RLV which moves given folders named #RLV/~<name> | ||
318 | // to a folder called name in #RLV. However, this approach may not be ultimately correct - from analysis | ||
319 | // of Firestorm 4.2.2 on sending an InventoryOffered instead of TaskInventoryOffered (as was previously | ||
320 | // done), the viewer itself would appear to move and rename the folder, rather than the simulator doing it here. | ||
321 | else if (im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted) | 316 | else if (im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted) |
322 | { | 317 | { |
323 | UUID destinationFolderID = UUID.Zero; | 318 | UUID destinationFolderID = UUID.Zero; |
@@ -329,16 +324,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
329 | 324 | ||
330 | if (destinationFolderID != UUID.Zero) | 325 | if (destinationFolderID != UUID.Zero) |
331 | { | 326 | { |
332 | InventoryFolderBase destinationFolder = new InventoryFolderBase(destinationFolderID, client.AgentId); | ||
333 | if (destinationFolder == null) | ||
334 | { | ||
335 | m_log.WarnFormat( | ||
336 | "[INVENTORY TRANSFER]: TaskInventoryAccepted message from {0} in {1} specified folder {2} which does not exist", | ||
337 | client.Name, scene.Name, destinationFolderID); | ||
338 | |||
339 | return; | ||
340 | } | ||
341 | |||
342 | IInventoryService invService = scene.InventoryService; | 327 | IInventoryService invService = scene.InventoryService; |
343 | 328 | ||
344 | UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip | 329 | UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip |
@@ -346,11 +331,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
346 | InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId); | 331 | InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId); |
347 | item = invService.GetItem(item); | 332 | item = invService.GetItem(item); |
348 | InventoryFolderBase folder = null; | 333 | InventoryFolderBase folder = null; |
349 | UUID? previousParentFolderID = null; | ||
350 | 334 | ||
351 | if (item != null) // It's an item | 335 | if (item != null) // It's an item |
352 | { | 336 | { |
353 | previousParentFolderID = item.Folder; | ||
354 | item.Folder = destinationFolderID; | 337 | item.Folder = destinationFolderID; |
355 | 338 | ||
356 | invService.DeleteItems(item.Owner, new List<UUID>() { item.ID }); | 339 | invService.DeleteItems(item.Owner, new List<UUID>() { item.ID }); |
@@ -363,22 +346,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
363 | 346 | ||
364 | if (folder != null) // It's a folder | 347 | if (folder != null) // It's a folder |
365 | { | 348 | { |
366 | previousParentFolderID = folder.ParentID; | ||
367 | folder.ParentID = destinationFolderID; | 349 | folder.ParentID = destinationFolderID; |
368 | invService.MoveFolder(folder); | 350 | invService.MoveFolder(folder); |
369 | } | 351 | } |
370 | } | 352 | } |
371 | |||
372 | // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code). | ||
373 | if (previousParentFolderID != null) | ||
374 | { | ||
375 | InventoryFolderBase previousParentFolder | ||
376 | = new InventoryFolderBase((UUID)previousParentFolderID, client.AgentId); | ||
377 | previousParentFolder = invService.GetFolder(previousParentFolder); | ||
378 | scene.SendInventoryUpdate(client, previousParentFolder, true, true); | ||
379 | |||
380 | scene.SendInventoryUpdate(client, destinationFolder, true, true); | ||
381 | } | ||
382 | } | 353 | } |
383 | } | 354 | } |
384 | else if ( | 355 | else if ( |
@@ -399,11 +370,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
399 | InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId); | 370 | InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId); |
400 | item = invService.GetItem(item); | 371 | item = invService.GetItem(item); |
401 | InventoryFolderBase folder = null; | 372 | InventoryFolderBase folder = null; |
402 | UUID? previousParentFolderID = null; | ||
403 | 373 | ||
404 | if (item != null && trashFolder != null) | 374 | if (item != null && trashFolder != null) |
405 | { | 375 | { |
406 | previousParentFolderID = item.Folder; | ||
407 | item.Folder = trashFolder.ID; | 376 | item.Folder = trashFolder.ID; |
408 | 377 | ||
409 | // Diva comment: can't we just update this item??? | 378 | // Diva comment: can't we just update this item??? |
@@ -419,7 +388,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
419 | 388 | ||
420 | if (folder != null & trashFolder != null) | 389 | if (folder != null & trashFolder != null) |
421 | { | 390 | { |
422 | previousParentFolderID = folder.ParentID; | ||
423 | folder.ParentID = trashFolder.ID; | 391 | folder.ParentID = trashFolder.ID; |
424 | invService.MoveFolder(folder); | 392 | invService.MoveFolder(folder); |
425 | client.SendBulkUpdateInventory(folder); | 393 | client.SendBulkUpdateInventory(folder); |
@@ -440,16 +408,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
440 | client.SendAgentAlertMessage("Unable to delete "+ | 408 | client.SendAgentAlertMessage("Unable to delete "+ |
441 | "received inventory" + reason, false); | 409 | "received inventory" + reason, false); |
442 | } | 410 | } |
443 | // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code). | ||
444 | else if (previousParentFolderID != null) | ||
445 | { | ||
446 | InventoryFolderBase previousParentFolder | ||
447 | = new InventoryFolderBase((UUID)previousParentFolderID, client.AgentId); | ||
448 | previousParentFolder = invService.GetFolder(previousParentFolder); | ||
449 | scene.SendInventoryUpdate(client, previousParentFolder, true, true); | ||
450 | |||
451 | scene.SendInventoryUpdate(client, trashFolder, true, true); | ||
452 | } | ||
453 | 411 | ||
454 | if (im.dialog == (byte)InstantMessageDialog.InventoryDeclined) | 412 | if (im.dialog == (byte)InstantMessageDialog.InventoryDeclined) |
455 | { | 413 | { |
@@ -468,69 +426,69 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
468 | } | 426 | } |
469 | } | 427 | } |
470 | 428 | ||
471 | // public bool NeedSceneCacheClear(UUID agentID, Scene scene) | 429 | public bool NeedSceneCacheClear(UUID agentID, Scene scene) |
472 | // { | 430 | { |
473 | // if (!m_AgentRegions.ContainsKey(agentID)) | 431 | if (!m_AgentRegions.ContainsKey(agentID)) |
474 | // { | 432 | { |
475 | // // Since we can get here two ways, we need to scan | 433 | // Since we can get here two ways, we need to scan |
476 | // // the scenes here. This is somewhat more expensive | 434 | // the scenes here. This is somewhat more expensive |
477 | // // but helps avoid a nasty bug | 435 | // but helps avoid a nasty bug |
478 | // // | 436 | // |
479 | // | 437 | |
480 | // foreach (Scene s in m_Scenelist) | 438 | foreach (Scene s in m_Scenelist) |
481 | // { | 439 | { |
482 | // ScenePresence presence; | 440 | ScenePresence presence; |
483 | // | 441 | |
484 | // if (s.TryGetScenePresence(agentID, out presence)) | 442 | if (s.TryGetScenePresence(agentID, out presence)) |
485 | // { | 443 | { |
486 | // // If the agent is in this scene, then we | 444 | // If the agent is in this scene, then we |
487 | // // are being called twice in a single | 445 | // are being called twice in a single |
488 | // // teleport. This is wasteful of cycles | 446 | // teleport. This is wasteful of cycles |
489 | // // but harmless due to this 2nd level check | 447 | // but harmless due to this 2nd level check |
490 | // // | 448 | // |
491 | // // If the agent is found in another scene | 449 | // If the agent is found in another scene |
492 | // // then the list wasn't current | 450 | // then the list wasn't current |
493 | // // | 451 | // |
494 | // // If the agent is totally unknown, then what | 452 | // If the agent is totally unknown, then what |
495 | // // are we even doing here?? | 453 | // are we even doing here?? |
496 | // // | 454 | // |
497 | // if (s == scene) | 455 | if (s == scene) |
498 | // { | 456 | { |
499 | // //m_log.Debug("[INVTRANSFERMOD]: s == scene. Returning true in " + scene.RegionInfo.RegionName); | 457 | //m_log.Debug("[INVTRANSFERMOD]: s == scene. Returning true in " + scene.RegionInfo.RegionName); |
500 | // return true; | 458 | return true; |
501 | // } | 459 | } |
502 | // else | 460 | else |
503 | // { | 461 | { |
504 | // //m_log.Debug("[INVTRANSFERMOD]: s != scene. Returning false in " + scene.RegionInfo.RegionName); | 462 | //m_log.Debug("[INVTRANSFERMOD]: s != scene. Returning false in " + scene.RegionInfo.RegionName); |
505 | // return false; | 463 | return false; |
506 | // } | 464 | } |
507 | // } | 465 | } |
508 | // } | 466 | } |
509 | // //m_log.Debug("[INVTRANSFERMOD]: agent not in scene. Returning true in " + scene.RegionInfo.RegionName); | 467 | //m_log.Debug("[INVTRANSFERMOD]: agent not in scene. Returning true in " + scene.RegionInfo.RegionName); |
510 | // return true; | 468 | return true; |
511 | // } | 469 | } |
512 | // | 470 | |
513 | // // The agent is left in current Scene, so we must be | 471 | // The agent is left in current Scene, so we must be |
514 | // // going to another instance | 472 | // going to another instance |
515 | // // | 473 | // |
516 | // if (m_AgentRegions[agentID] == scene) | 474 | if (m_AgentRegions[agentID] == scene) |
517 | // { | 475 | { |
518 | // //m_log.Debug("[INVTRANSFERMOD]: m_AgentRegions[agentID] == scene. Returning true in " + scene.RegionInfo.RegionName); | 476 | //m_log.Debug("[INVTRANSFERMOD]: m_AgentRegions[agentID] == scene. Returning true in " + scene.RegionInfo.RegionName); |
519 | // m_AgentRegions.Remove(agentID); | 477 | m_AgentRegions.Remove(agentID); |
520 | // return true; | 478 | return true; |
521 | // } | 479 | } |
522 | // | 480 | |
523 | // // Another region has claimed the agent | 481 | // Another region has claimed the agent |
524 | // // | 482 | // |
525 | // //m_log.Debug("[INVTRANSFERMOD]: last resort. Returning false in " + scene.RegionInfo.RegionName); | 483 | //m_log.Debug("[INVTRANSFERMOD]: last resort. Returning false in " + scene.RegionInfo.RegionName); |
526 | // return false; | 484 | return false; |
527 | // } | 485 | } |
528 | // | 486 | |
529 | // public void ClientLoggedOut(UUID agentID, Scene scene) | 487 | public void ClientLoggedOut(UUID agentID, Scene scene) |
530 | // { | 488 | { |
531 | // if (m_AgentRegions.ContainsKey(agentID)) | 489 | if (m_AgentRegions.ContainsKey(agentID)) |
532 | // m_AgentRegions.Remove(agentID); | 490 | m_AgentRegions.Remove(agentID); |
533 | // } | 491 | } |
534 | 492 | ||
535 | /// <summary> | 493 | /// <summary> |
536 | /// | 494 | /// |
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs index 9c369f6..92cf9d1 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs | |||
@@ -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], true); | 189 | new Byte[0]); |
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 1949459..a889984 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs | |||
@@ -173,7 +173,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure | |||
173 | client.FirstName+" "+client.LastName, targetid, | 173 | client.FirstName+" "+client.LastName, targetid, |
174 | (byte)InstantMessageDialog.GodLikeRequestTeleport, false, | 174 | (byte)InstantMessageDialog.GodLikeRequestTeleport, false, |
175 | message, dest, false, presence.AbsolutePosition, | 175 | message, dest, false, presence.AbsolutePosition, |
176 | new Byte[0], true); | 176 | new Byte[0]); |
177 | } | 177 | } |
178 | else | 178 | else |
179 | { | 179 | { |
@@ -181,7 +181,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure | |||
181 | client.FirstName+" "+client.LastName, targetid, | 181 | client.FirstName+" "+client.LastName, targetid, |
182 | (byte)InstantMessageDialog.RequestTeleport, false, | 182 | (byte)InstantMessageDialog.RequestTeleport, false, |
183 | message, dest, false, presence.AbsolutePosition, | 183 | message, dest, false, presence.AbsolutePosition, |
184 | new Byte[0], true); | 184 | new Byte[0]); |
185 | } | 185 | } |
186 | 186 | ||
187 | if (m_TransferModule != null) | 187 | if (m_TransferModule != null) |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 31e6ce9..880b2cc 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -327,14 +327,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
327 | return; | 327 | return; |
328 | } | 328 | } |
329 | 329 | ||
330 | // Validate assorted conditions | ||
331 | string reason = string.Empty; | ||
332 | if (!ValidateGenericConditions(sp, reg, finalDestination, teleportFlags, out reason)) | ||
333 | { | ||
334 | sp.ControllingClient.SendTeleportFailed(reason); | ||
335 | return; | ||
336 | } | ||
337 | |||
338 | // | 330 | // |
339 | // This is it | 331 | // This is it |
340 | // | 332 | // |
@@ -366,13 +358,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
366 | } | 358 | } |
367 | } | 359 | } |
368 | 360 | ||
369 | // Nothing to validate here | ||
370 | protected virtual bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason) | ||
371 | { | ||
372 | reason = String.Empty; | ||
373 | return true; | ||
374 | } | ||
375 | |||
376 | /// <summary> | 361 | /// <summary> |
377 | /// Determines whether this instance is within the max transfer distance. | 362 | /// Determines whether this instance is within the max transfer distance. |
378 | /// </summary> | 363 | /// </summary> |
@@ -488,11 +473,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
488 | // both regions | 473 | // both regions |
489 | if (sp.ParentID != (uint)0) | 474 | if (sp.ParentID != (uint)0) |
490 | sp.StandUp(); | 475 | sp.StandUp(); |
476 | |||
491 | else if (sp.Flying) | 477 | else if (sp.Flying) |
492 | teleportFlags |= (uint)TeleportFlags.IsFlying; | 478 | teleportFlags |= (uint)TeleportFlags.IsFlying; |
493 | 479 | ||
494 | // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to | ||
495 | // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested). | ||
496 | sp.ControllingClient.SendTeleportStart(teleportFlags); | 480 | sp.ControllingClient.SendTeleportStart(teleportFlags); |
497 | 481 | ||
498 | // the avatar.Close below will clear the child region list. We need this below for (possibly) | 482 | // the avatar.Close below will clear the child region list. We need this below for (possibly) |
@@ -568,11 +552,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
568 | // So let's wait | 552 | // So let's wait |
569 | Thread.Sleep(200); | 553 | Thread.Sleep(200); |
570 | 554 | ||
571 | // At least on LL 3.3.4 for teleports between different regions on the same simulator this appears | ||
572 | // unnecessary - teleport will succeed and SEED caps will be requested without it (though possibly | ||
573 | // only on TeleportFinish). This is untested for region teleport between different simulators | ||
574 | // though this probably also works. | ||
575 | m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); | 555 | m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); |
556 | |||
576 | } | 557 | } |
577 | else | 558 | else |
578 | { | 559 | { |
@@ -593,7 +574,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
593 | 574 | ||
594 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); | 575 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); |
595 | 576 | ||
596 | if (!UpdateAgent(reg, finalDestination, agent, sp)) | 577 | if (!UpdateAgent(reg, finalDestination, agent)) |
597 | { | 578 | { |
598 | // Region doesn't take it | 579 | // Region doesn't take it |
599 | m_log.WarnFormat( | 580 | m_log.WarnFormat( |
@@ -669,7 +650,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
669 | // an agent cannot teleport back to this region if it has teleported away. | 650 | // an agent cannot teleport back to this region if it has teleported away. |
670 | Thread.Sleep(3000); | 651 | Thread.Sleep(3000); |
671 | 652 | ||
672 | sp.Scene.IncomingCloseAgent(sp.UUID, false); | 653 | sp.Scene.IncomingCloseAgent(sp.UUID); |
673 | } | 654 | } |
674 | else | 655 | else |
675 | { | 656 | { |
@@ -677,14 +658,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
677 | sp.Reset(); | 658 | sp.Reset(); |
678 | } | 659 | } |
679 | 660 | ||
680 | // Commented pending deletion since this method no longer appears to do anything at all | 661 | // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! |
681 | // // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! | 662 | if (sp.Scene.NeedSceneCacheClear(sp.UUID)) |
682 | // if (sp.Scene.NeedSceneCacheClear(sp.UUID)) | 663 | { |
683 | // { | 664 | m_log.DebugFormat( |
684 | // m_log.DebugFormat( | 665 | "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", |
685 | // "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", | 666 | sp.UUID); |
686 | // sp.UUID); | 667 | } |
687 | // } | ||
688 | 668 | ||
689 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); | 669 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); |
690 | } | 670 | } |
@@ -721,7 +701,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
721 | return success; | 701 | return success; |
722 | } | 702 | } |
723 | 703 | ||
724 | protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent, ScenePresence sp) | 704 | protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent) |
725 | { | 705 | { |
726 | return Scene.SimulationService.UpdateAgent(finalDestination, agent); | 706 | return Scene.SimulationService.UpdateAgent(finalDestination, agent); |
727 | } | 707 | } |
@@ -1033,7 +1013,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1033 | Scene initiatingScene) | 1013 | Scene initiatingScene) |
1034 | { | 1014 | { |
1035 | Thread.Sleep(10000); | 1015 | Thread.Sleep(10000); |
1036 | |||
1037 | IMessageTransferModule im = initiatingScene.RequestModuleInterface<IMessageTransferModule>(); | 1016 | IMessageTransferModule im = initiatingScene.RequestModuleInterface<IMessageTransferModule>(); |
1038 | if (im != null) | 1017 | if (im != null) |
1039 | { | 1018 | { |
@@ -1046,22 +1025,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1046 | (uint)(int)position.X, | 1025 | (uint)(int)position.X, |
1047 | (uint)(int)position.Y, | 1026 | (uint)(int)position.Y, |
1048 | (uint)(int)position.Z); | 1027 | (uint)(int)position.Z); |
1049 | 1028 | GridInstantMessage m = new GridInstantMessage(initiatingScene, UUID.Zero, | |
1050 | GridInstantMessage m | 1029 | "Region", agent.UUID, |
1051 | = new GridInstantMessage( | 1030 | (byte)InstantMessageDialog.GodLikeRequestTeleport, false, |
1052 | initiatingScene, | 1031 | "", gotoLocation, false, new Vector3(127, 0, 0), |
1053 | UUID.Zero, | 1032 | new Byte[0]); |
1054 | "Region", | ||
1055 | agent.UUID, | ||
1056 | (byte)InstantMessageDialog.GodLikeRequestTeleport, | ||
1057 | false, | ||
1058 | "", | ||
1059 | gotoLocation, | ||
1060 | false, | ||
1061 | new Vector3(127, 0, 0), | ||
1062 | new Byte[0], | ||
1063 | false); | ||
1064 | |||
1065 | im.SendInstantMessage(m, delegate(bool success) | 1033 | im.SendInstantMessage(m, delegate(bool success) |
1066 | { | 1034 | { |
1067 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Client Initiating Teleport sending IM success = {0}", success); | 1035 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Client Initiating Teleport sending IM success = {0}", success); |
@@ -1223,11 +1191,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1223 | // the user may change their profile information in other region, | 1191 | // the user may change their profile information in other region, |
1224 | // so the userinfo in UserProfileCache is not reliable any more, delete it | 1192 | // so the userinfo in UserProfileCache is not reliable any more, delete it |
1225 | // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! | 1193 | // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! |
1226 | // if (agent.Scene.NeedSceneCacheClear(agent.UUID)) | 1194 | if (agent.Scene.NeedSceneCacheClear(agent.UUID)) |
1227 | // { | 1195 | { |
1228 | // m_log.DebugFormat( | 1196 | m_log.DebugFormat( |
1229 | // "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); | 1197 | "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); |
1230 | // } | 1198 | } |
1231 | 1199 | ||
1232 | //m_log.Debug("AFTER CROSS"); | 1200 | //m_log.Debug("AFTER CROSS"); |
1233 | //Scene.DumpChildrenSeeds(UUID); | 1201 | //Scene.DumpChildrenSeeds(UUID); |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index b16c37a..3010b59 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs | |||
@@ -54,59 +54,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
54 | 54 | ||
55 | private GatekeeperServiceConnector m_GatekeeperConnector; | 55 | private GatekeeperServiceConnector m_GatekeeperConnector; |
56 | 56 | ||
57 | protected bool m_RestrictAppearanceAbroad; | ||
58 | protected string m_AccountName; | ||
59 | protected List<AvatarAppearance> m_ExportedAppearances; | ||
60 | protected List<AvatarAttachment> m_Attachs; | ||
61 | |||
62 | protected List<AvatarAppearance> ExportedAppearance | ||
63 | { | ||
64 | get | ||
65 | { | ||
66 | if (m_ExportedAppearances != null) | ||
67 | return m_ExportedAppearances; | ||
68 | |||
69 | m_ExportedAppearances = new List<AvatarAppearance>(); | ||
70 | m_Attachs = new List<AvatarAttachment>(); | ||
71 | |||
72 | string[] names = m_AccountName.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); | ||
73 | |||
74 | foreach (string name in names) | ||
75 | { | ||
76 | string[] parts = name.Trim().Split(); | ||
77 | if (parts.Length != 2) | ||
78 | { | ||
79 | m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Wrong user account name format {0}. Specify 'First Last'", name); | ||
80 | return null; | ||
81 | } | ||
82 | UserAccount account = Scene.UserAccountService.GetUserAccount(UUID.Zero, parts[0], parts[1]); | ||
83 | if (account == null) | ||
84 | { | ||
85 | m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unknown account {0}", m_AccountName); | ||
86 | return null; | ||
87 | } | ||
88 | AvatarAppearance a = Scene.AvatarService.GetAppearance(account.PrincipalID); | ||
89 | if (a != null) | ||
90 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Successfully retrieved appearance for {0}", name); | ||
91 | |||
92 | foreach (AvatarAttachment att in a.GetAttachments()) | ||
93 | { | ||
94 | InventoryItemBase item = new InventoryItemBase(att.ItemID, account.PrincipalID); | ||
95 | item = Scene.InventoryService.GetItem(item); | ||
96 | if (item != null) | ||
97 | a.SetAttachment(att.AttachPoint, att.ItemID, item.AssetID); | ||
98 | else | ||
99 | m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unable to retrieve item {0} from inventory {1}", att.ItemID, name); | ||
100 | } | ||
101 | |||
102 | m_ExportedAppearances.Add(a); | ||
103 | m_Attachs.AddRange(a.GetAttachments()); | ||
104 | } | ||
105 | |||
106 | return m_ExportedAppearances; | ||
107 | } | ||
108 | } | ||
109 | |||
110 | #region ISharedRegionModule | 57 | #region ISharedRegionModule |
111 | 58 | ||
112 | public override string Name | 59 | public override string Name |
@@ -125,18 +72,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
125 | { | 72 | { |
126 | IConfig transferConfig = source.Configs["EntityTransfer"]; | 73 | IConfig transferConfig = source.Configs["EntityTransfer"]; |
127 | if (transferConfig != null) | 74 | if (transferConfig != null) |
128 | { | ||
129 | m_levelHGTeleport = transferConfig.GetInt("LevelHGTeleport", 0); | 75 | m_levelHGTeleport = transferConfig.GetInt("LevelHGTeleport", 0); |
130 | 76 | ||
131 | m_RestrictAppearanceAbroad = transferConfig.GetBoolean("RestrictAppearanceAbroad", false); | ||
132 | if (m_RestrictAppearanceAbroad) | ||
133 | { | ||
134 | m_AccountName = transferConfig.GetString("AccountForAppearance", string.Empty); | ||
135 | if (m_AccountName == string.Empty) | ||
136 | m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is on, but no account has been given for avatar appearance!"); | ||
137 | } | ||
138 | } | ||
139 | |||
140 | InitialiseCommon(source); | 77 | InitialiseCommon(source); |
141 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); | 78 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); |
142 | } | 79 | } |
@@ -148,36 +85,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
148 | base.AddRegion(scene); | 85 | base.AddRegion(scene); |
149 | 86 | ||
150 | if (m_Enabled) | 87 | if (m_Enabled) |
151 | { | ||
152 | scene.RegisterModuleInterface<IUserAgentVerificationModule>(this); | 88 | scene.RegisterModuleInterface<IUserAgentVerificationModule>(this); |
153 | scene.EventManager.OnIncomingSceneObject += OnIncomingSceneObject; | ||
154 | } | ||
155 | } | ||
156 | |||
157 | void OnIncomingSceneObject(SceneObjectGroup so) | ||
158 | { | ||
159 | if (!so.IsAttachment) | ||
160 | return; | ||
161 | |||
162 | if (so.Scene.UserManagementModule.IsLocalGridUser(so.AttachedAvatar)) | ||
163 | return; | ||
164 | |||
165 | // foreign user | ||
166 | AgentCircuitData aCircuit = so.Scene.AuthenticateHandler.GetAgentCircuitData(so.AttachedAvatar); | ||
167 | if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0) | ||
168 | { | ||
169 | if (aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) | ||
170 | { | ||
171 | string url = aCircuit.ServiceURLs["AssetServerURI"].ToString(); | ||
172 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Incoming attachement {0} for HG user {1} with asset server {2}", so.Name, so.AttachedAvatar, url); | ||
173 | Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>(); | ||
174 | HGUuidGatherer uuidGatherer = new HGUuidGatherer(so.Scene.AssetService, url); | ||
175 | uuidGatherer.GatherAssetUuids(so, ids); | ||
176 | |||
177 | foreach (KeyValuePair<UUID, AssetType> kvp in ids) | ||
178 | uuidGatherer.FetchAsset(kvp.Key); | ||
179 | } | ||
180 | } | ||
181 | } | 89 | } |
182 | 90 | ||
183 | protected override void OnNewClient(IClientAPI client) | 91 | protected override void OnNewClient(IClientAPI client) |
@@ -212,7 +120,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
212 | int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, region.RegionID); | 120 | int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, region.RegionID); |
213 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionID, flags); | 121 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionID, flags); |
214 | 122 | ||
215 | if ((flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0) | 123 | if ((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) |
216 | { | 124 | { |
217 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region {0} is hyperlink", region.RegionID); | 125 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region {0} is hyperlink", region.RegionID); |
218 | GridRegion real_destination = m_GatekeeperConnector.GetHyperlinkRegion(region, region.RegionID); | 126 | GridRegion real_destination = m_GatekeeperConnector.GetHyperlinkRegion(region, region.RegionID); |
@@ -232,7 +140,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
232 | return true; | 140 | return true; |
233 | 141 | ||
234 | int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID); | 142 | int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID); |
235 | if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0) | 143 | if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) |
236 | return true; | 144 | return true; |
237 | 145 | ||
238 | return false; | 146 | return false; |
@@ -245,8 +153,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
245 | { | 153 | { |
246 | // Log them out of this grid | 154 | // Log them out of this grid |
247 | Scene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId); | 155 | Scene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId); |
248 | string userId = Scene.UserManagementModule.GetUserUUI(sp.UUID); | ||
249 | Scene.GridUserService.LoggedOut(userId, UUID.Zero, Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); | ||
250 | } | 156 | } |
251 | } | 157 | } |
252 | 158 | ||
@@ -256,11 +162,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
256 | reason = string.Empty; | 162 | reason = string.Empty; |
257 | logout = false; | 163 | logout = false; |
258 | int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID); | 164 | int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID); |
259 | if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0) | 165 | if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) |
260 | { | 166 | { |
261 | // this user is going to another grid | 167 | // this user is going to another grid |
262 | // for local users, check if HyperGrid teleport is allowed, based on user level | 168 | // check if HyperGrid teleport is allowed, based on user level |
263 | if (Scene.UserManagementModule.IsLocalGridUser(sp.UUID) && sp.UserLevel < m_levelHGTeleport) | 169 | if (sp.UserLevel < m_levelHGTeleport) |
264 | { | 170 | { |
265 | m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unable to HG teleport agent due to insufficient UserLevel."); | 171 | m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unable to HG teleport agent due to insufficient UserLevel."); |
266 | reason = "Hypergrid teleport not allowed"; | 172 | reason = "Hypergrid teleport not allowed"; |
@@ -294,124 +200,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
294 | TeleportHome(id, client); | 200 | TeleportHome(id, client); |
295 | } | 201 | } |
296 | 202 | ||
297 | protected override bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason) | ||
298 | { | ||
299 | reason = "Please wear your grid's allowed appearance before teleporting to another grid"; | ||
300 | if (!m_RestrictAppearanceAbroad) | ||
301 | return true; | ||
302 | |||
303 | // The rest is only needed for controlling appearance | ||
304 | |||
305 | int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID); | ||
306 | if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0) | ||
307 | { | ||
308 | // this user is going to another grid | ||
309 | if (Scene.UserManagementModule.IsLocalGridUser(sp.UUID)) | ||
310 | { | ||
311 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is ON. Checking generic appearance"); | ||
312 | |||
313 | // Check wearables | ||
314 | for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) | ||
315 | { | ||
316 | for (int j = 0; j < sp.Appearance.Wearables[i].Count; j++) | ||
317 | { | ||
318 | if (sp.Appearance.Wearables[i] == null) | ||
319 | continue; | ||
320 | |||
321 | bool found = false; | ||
322 | foreach (AvatarAppearance a in ExportedAppearance) | ||
323 | if (a.Wearables[i] != null) | ||
324 | { | ||
325 | found = true; | ||
326 | break; | ||
327 | } | ||
328 | |||
329 | if (!found) | ||
330 | { | ||
331 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Wearable not allowed to go outside {0}", i); | ||
332 | return false; | ||
333 | } | ||
334 | |||
335 | found = false; | ||
336 | foreach (AvatarAppearance a in ExportedAppearance) | ||
337 | if (sp.Appearance.Wearables[i][j].AssetID == a.Wearables[i][j].AssetID) | ||
338 | { | ||
339 | found = true; | ||
340 | break; | ||
341 | } | ||
342 | |||
343 | if (!found) | ||
344 | { | ||
345 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Wearable not allowed to go outside {0}", i); | ||
346 | return false; | ||
347 | } | ||
348 | } | ||
349 | } | ||
350 | |||
351 | // Check attachments | ||
352 | foreach (AvatarAttachment att in sp.Appearance.GetAttachments()) | ||
353 | { | ||
354 | bool found = false; | ||
355 | foreach (AvatarAttachment att2 in m_Attachs) | ||
356 | { | ||
357 | if (att2.AssetID == att.AssetID) | ||
358 | { | ||
359 | found = true; | ||
360 | break; | ||
361 | } | ||
362 | } | ||
363 | if (!found) | ||
364 | { | ||
365 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Attachment not allowed to go outside {0}", att.AttachPoint); | ||
366 | return false; | ||
367 | } | ||
368 | } | ||
369 | } | ||
370 | } | ||
371 | |||
372 | reason = string.Empty; | ||
373 | return true; | ||
374 | } | ||
375 | |||
376 | |||
377 | //protected override bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agentData, ScenePresence sp) | ||
378 | //{ | ||
379 | // int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID); | ||
380 | // if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) | ||
381 | // { | ||
382 | // // this user is going to another grid | ||
383 | // if (m_RestrictAppearanceAbroad && Scene.UserManagementModule.IsLocalGridUser(agentData.AgentID)) | ||
384 | // { | ||
385 | // // We need to strip the agent off its appearance | ||
386 | // m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is ON. Sending generic appearance"); | ||
387 | |||
388 | // // Delete existing npc attachments | ||
389 | // Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, false); | ||
390 | |||
391 | // // XXX: We can't just use IAvatarFactoryModule.SetAppearance() yet since it doesn't transfer attachments | ||
392 | // AvatarAppearance newAppearance = new AvatarAppearance(ExportedAppearance, true); | ||
393 | // sp.Appearance = newAppearance; | ||
394 | |||
395 | // // Rez needed npc attachments | ||
396 | // Scene.AttachmentsModule.RezAttachments(sp); | ||
397 | |||
398 | |||
399 | // IAvatarFactoryModule module = Scene.RequestModuleInterface<IAvatarFactoryModule>(); | ||
400 | // //module.SendAppearance(sp.UUID); | ||
401 | // module.RequestRebake(sp, false); | ||
402 | |||
403 | // Scene.AttachmentsModule.CopyAttachments(sp, agentData); | ||
404 | // agentData.Appearance = sp.Appearance; | ||
405 | // } | ||
406 | // } | ||
407 | |||
408 | // foreach (AvatarAttachment a in agentData.Appearance.GetAttachments()) | ||
409 | // m_log.DebugFormat("[XXX]: {0}-{1}", a.ItemID, a.AssetID); | ||
410 | |||
411 | |||
412 | // return base.UpdateAgent(reg, finalDestination, agentData, sp); | ||
413 | //} | ||
414 | |||
415 | public override bool TeleportHome(UUID id, IClientAPI client) | 203 | public override bool TeleportHome(UUID id, IClientAPI client) |
416 | { | 204 | { |
417 | m_log.DebugFormat( | 205 | m_log.DebugFormat( |
@@ -587,4 +375,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
587 | return region; | 375 | return region; |
588 | } | 376 | } |
589 | } | 377 | } |
590 | } | 378 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs index f8ec6de..eaadc1b 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 AssetMetadata FetchMetadata(string url, UUID assetID) | 74 | public AssetBase FetchAsset(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 | AssetMetadata meta = m_scene.AssetService.GetMetadata(url + assetID.ToString()); | 79 | AssetBase asset = m_scene.AssetService.Get(url + assetID.ToString()); |
80 | 80 | ||
81 | if (meta != null) | 81 | if (asset != null) |
82 | m_log.DebugFormat("[HG ASSET MAPPER]: Fetched metadata for asset {0} of type {1} from {2} ", assetID, meta.Type, url); | 82 | { |
83 | else | 83 | m_log.DebugFormat("[HG ASSET MAPPER]: Copied asset {0} from {1} to local asset server. ", asset.ID, url); |
84 | m_log.DebugFormat("[HG ASSET MAPPER]: Unable to fetched metadata for asset {0} from {1} ", assetID, url); | 84 | return asset; |
85 | 85 | } | |
86 | return meta; | 86 | return null; |
87 | } | 87 | } |
88 | 88 | ||
89 | public bool PostAsset(string url, AssetBase asset) | 89 | public bool PostAsset(string url, AssetBase asset) |
@@ -93,7 +93,6 @@ 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; | ||
97 | // See long comment in AssetCache.AddAsset | 96 | // See long comment in AssetCache.AddAsset |
98 | if (!asset.Temporary || asset.Local) | 97 | if (!asset.Temporary || asset.Local) |
99 | { | 98 | { |
@@ -104,7 +103,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
104 | // not having a global naming infrastructure | 103 | // not having a global naming infrastructure |
105 | AssetBase asset1 = new AssetBase(asset.FullID, asset.Name, asset.Type, asset.Metadata.CreatorID); | 104 | AssetBase asset1 = new AssetBase(asset.FullID, asset.Name, asset.Type, asset.Metadata.CreatorID); |
106 | Copy(asset, asset1); | 105 | Copy(asset, asset1); |
107 | asset1.ID = url + asset.ID; | 106 | try |
107 | { | ||
108 | asset1.ID = url + asset.ID; | ||
109 | } | ||
110 | catch | ||
111 | { | ||
112 | m_log.Warn("[HG ASSET MAPPER]: Oops."); | ||
113 | } | ||
108 | 114 | ||
109 | AdjustIdentifiers(asset1.Metadata); | 115 | AdjustIdentifiers(asset1.Metadata); |
110 | if (asset1.Metadata.Type == (sbyte)AssetType.Object) | 116 | if (asset1.Metadata.Type == (sbyte)AssetType.Object) |
@@ -112,17 +118,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
112 | else | 118 | else |
113 | asset1.Data = asset.Data; | 119 | asset1.Data = asset.Data; |
114 | 120 | ||
115 | string id = m_scene.AssetService.Store(asset1); | 121 | m_scene.AssetService.Store(asset1); |
116 | if (id == string.Empty) | 122 | m_log.DebugFormat("[HG ASSET MAPPER]: Posted copy of asset {0} from local asset server to {1}", asset1.ID, url); |
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 success; | 124 | return true; |
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,17 +222,28 @@ 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 AssetService | 225 | // Get the item from the remote asset server onto the local AssetCache |
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); | ||
226 | 230 | ||
227 | AssetMetadata meta = FetchMetadata(userAssetURL, assetID); | 231 | if (asset != null) |
228 | if (meta == null) | 232 | { |
229 | return; | 233 | // OK, now fetch the inside. |
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); | ||
230 | 241 | ||
231 | // The act of gathering UUIDs downloads the assets from the remote server | 242 | m_log.DebugFormat("[HG ASSET MAPPER]: Successfully fetched asset {0} from asset server {1}", asset.ID, userAssetURL); |
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); | ||
235 | 243 | ||
244 | } | ||
245 | else | ||
246 | m_log.Warn("[HG ASSET MAPPER]: Could not fetch asset from remote asset server " + userAssetURL); | ||
236 | } | 247 | } |
237 | 248 | ||
238 | 249 | ||
@@ -246,23 +257,19 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
246 | if (asset != null) | 257 | if (asset != null) |
247 | { | 258 | { |
248 | Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>(); | 259 | Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>(); |
249 | HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, string.Empty); | 260 | HGUuidGatherer uuidGatherer = new HGUuidGatherer(this, m_scene.AssetService, string.Empty); |
250 | uuidGatherer.GatherAssetUuids(asset.FullID, (AssetType)asset.Type, ids); | 261 | uuidGatherer.GatherAssetUuids(asset.FullID, (AssetType)asset.Type, ids); |
251 | bool success = false; | ||
252 | foreach (UUID uuid in ids.Keys) | 262 | foreach (UUID uuid in ids.Keys) |
253 | { | 263 | { |
254 | asset = m_scene.AssetService.Get(uuid.ToString()); | 264 | asset = m_scene.AssetService.Get(uuid.ToString()); |
255 | if (asset == null) | 265 | if (asset == null) |
256 | m_log.DebugFormat("[HG ASSET MAPPER]: Could not find asset {0}", uuid); | 266 | m_log.DebugFormat("[HG ASSET MAPPER]: Could not find asset {0}", uuid); |
257 | else | 267 | else |
258 | success = PostAsset(userAssetURL, asset); | 268 | PostAsset(userAssetURL, asset); |
259 | } | 269 | } |
260 | 270 | ||
261 | // maybe all pieces got there... | 271 | // maybe all pieces got there... |
262 | if (!success) | 272 | m_log.DebugFormat("[HG ASSET MAPPER]: Successfully posted item {0} to asset server {1}", assetID, userAssetURL); |
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); | ||
266 | 273 | ||
267 | } | 274 | } |
268 | else | 275 | else |
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs index 6bb758e..cf72b58 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs | |||
@@ -92,7 +92,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
92 | m_HomeURI = thisModuleConfig.GetString("HomeURI", m_HomeURI); | 92 | m_HomeURI = thisModuleConfig.GetString("HomeURI", m_HomeURI); |
93 | m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true); | 93 | m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true); |
94 | m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty); | 94 | m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty); |
95 | m_RestrictInventoryAccessAbroad = thisModuleConfig.GetBoolean("RestrictInventoryAccessAbroad", true); | 95 | m_RestrictInventoryAccessAbroad = thisModuleConfig.GetBoolean("RestrictInventoryAccessAbroad", false); |
96 | } | 96 | } |
97 | else | 97 | else |
98 | m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!"); | 98 | m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!"); |
@@ -263,13 +263,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
263 | //} | 263 | //} |
264 | 264 | ||
265 | // OK, we're done fetching. Pass it up to the default RezObject | 265 | // OK, we're done fetching. Pass it up to the default RezObject |
266 | SceneObjectGroup sog = base.RezObject(remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection, | 266 | return base.RezObject(remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection, |
267 | RezSelected, RemoveItem, fromTaskID, attachment); | 267 | RezSelected, RemoveItem, fromTaskID, attachment); |
268 | |||
269 | if (sog == null) | ||
270 | remoteClient.SendAgentAlertMessage("Unable to rez: problem accessing inventory or locating assets", false); | ||
271 | |||
272 | return sog; | ||
273 | 268 | ||
274 | } | 269 | } |
275 | 270 | ||
@@ -313,8 +308,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
313 | protected override InventoryItemBase GetItem(UUID agentID, UUID itemID) | 308 | protected override InventoryItemBase GetItem(UUID agentID, UUID itemID) |
314 | { | 309 | { |
315 | InventoryItemBase item = base.GetItem(agentID, itemID); | 310 | InventoryItemBase item = base.GetItem(agentID, itemID); |
316 | if (item == null) | ||
317 | return null; | ||
318 | 311 | ||
319 | string userAssetServer = string.Empty; | 312 | string userAssetServer = string.Empty; |
320 | if (IsForeignUser(agentID, out userAssetServer)) | 313 | if (IsForeignUser(agentID, out userAssetServer)) |
@@ -351,7 +344,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
351 | 344 | ||
352 | private void ProcessInventoryForArriving(IClientAPI client) | 345 | private void ProcessInventoryForArriving(IClientAPI client) |
353 | { | 346 | { |
354 | // No-op for now, but we may need to do something for freign users inventory | ||
355 | } | 347 | } |
356 | 348 | ||
357 | // | 349 | // |
@@ -398,7 +390,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
398 | 390 | ||
399 | private void ProcessInventoryForLeaving(IClientAPI client) | 391 | private void ProcessInventoryForLeaving(IClientAPI client) |
400 | { | 392 | { |
401 | // No-op for now | ||
402 | } | 393 | } |
403 | 394 | ||
404 | #endregion | 395 | #endregion |
diff --git a/OpenSim/Region/ScriptEngine/Shared/ScriptException.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGUuidGatherer.cs index f55ba7e..fcb544f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/ScriptException.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGUuidGatherer.cs | |||
@@ -26,19 +26,32 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Runtime.Serialization; | 29 | using System.Collections.Generic; |
30 | 30 | ||
31 | namespace OpenSim.Region.ScriptEngine.Shared | 31 | using OpenSim.Framework; |
32 | using OpenSim.Region.Framework.Scenes; | ||
33 | using OpenSim.Services.Interfaces; | ||
34 | using OpenMetaverse; | ||
35 | |||
36 | namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | ||
32 | { | 37 | { |
33 | [Serializable] | 38 | public class HGUuidGatherer : UuidGatherer |
34 | public class ScriptException : Exception | ||
35 | { | 39 | { |
36 | public ScriptException() : base() {} | 40 | protected string m_assetServerURL; |
37 | 41 | protected HGAssetMapper m_assetMapper; | |
38 | public ScriptException(string message) : base(message) {} | ||
39 | 42 | ||
40 | public ScriptException(string message, Exception innerException) : base(message, innerException) {} | 43 | public HGUuidGatherer(HGAssetMapper assMap, IAssetService assetCache, string assetServerURL) : base(assetCache) |
44 | { | ||
45 | m_assetMapper = assMap; | ||
46 | m_assetServerURL = assetServerURL; | ||
47 | } | ||
41 | 48 | ||
42 | public ScriptException(SerializationInfo info, StreamingContext context) :base(info, context) {} | 49 | protected override AssetBase GetAsset(UUID uuid) |
50 | { | ||
51 | if (string.Empty == m_assetServerURL) | ||
52 | return m_assetCache.Get(uuid.ToString()); | ||
53 | else | ||
54 | return m_assetMapper.FetchAsset(m_assetServerURL, uuid); | ||
55 | } | ||
43 | } | 56 | } |
44 | } \ No newline at end of file | 57 | } |
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs index e411585..e135c21 100644 --- a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs | |||
@@ -95,14 +95,14 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
95 | { | 95 | { |
96 | foreach (IMonitor monitor in m_staticMonitors) | 96 | foreach (IMonitor monitor in m_staticMonitors) |
97 | { | 97 | { |
98 | MainConsole.Instance.OutputFormat( | 98 | m_log.InfoFormat( |
99 | "[MONITOR MODULE]: {0} reports {1} = {2}", | 99 | "[MONITOR MODULE]: {0} reports {1} = {2}", |
100 | m_scene.RegionInfo.RegionName, monitor.GetFriendlyName(), monitor.GetFriendlyValue()); | 100 | m_scene.RegionInfo.RegionName, monitor.GetFriendlyName(), monitor.GetFriendlyValue()); |
101 | } | 101 | } |
102 | 102 | ||
103 | foreach (KeyValuePair<string, float> tuple in m_scene.StatsReporter.GetExtraSimStats()) | 103 | foreach (KeyValuePair<string, float> tuple in m_scene.StatsReporter.GetExtraSimStats()) |
104 | { | 104 | { |
105 | MainConsole.Instance.OutputFormat( | 105 | m_log.InfoFormat( |
106 | "[MONITOR MODULE]: {0} reports {1} = {2}", | 106 | "[MONITOR MODULE]: {0} reports {1} = {2}", |
107 | m_scene.RegionInfo.RegionName, tuple.Key, tuple.Value); | 107 | m_scene.RegionInfo.RegionName, tuple.Key, tuple.Value); |
108 | } | 108 | } |
diff --git a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs index fd8d5e3..65e4c90 100755 --- a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs +++ b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs | |||
@@ -1,170 +1,161 @@ | |||
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 | ||
28 | using System; | 28 | using System; |
29 | using System.IO; | 29 | using System.IO; |
30 | using System.Text; | 30 | using System.Text; |
31 | using log4net; | 31 | using log4net; |
32 | 32 | ||
33 | namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging | 33 | namespace 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 Flush() | 114 | public void Write(string line) |
115 | { | 115 | { |
116 | if (!Enabled) return; | 116 | if (!Enabled) return; |
117 | if (m_logFile != null) | 117 | try |
118 | { | 118 | { |
119 | m_logFile.Flush(); | 119 | lock (m_logFileWriteLock) |
120 | } | 120 | { |
121 | } | 121 | DateTime now = DateTime.Now; |
122 | 122 | if (m_logFile == null || now > m_logFileEndTime) | |
123 | public void Write(string line) | 123 | { |
124 | { | 124 | if (m_logFile != null) |
125 | if (!Enabled) return; | 125 | { |
126 | try | 126 | m_logFile.Close(); |
127 | { | 127 | m_logFile.Dispose(); |
128 | lock (m_logFileWriteLock) | 128 | m_logFile = null; |
129 | { | 129 | } |
130 | DateTime now = DateTime.Now; | 130 | |
131 | if (m_logFile == null || now > m_logFileEndTime) | 131 | // First log file or time has expired, start writing to a new log file |
132 | { | 132 | m_logFileEndTime = now + m_logFileLife; |
133 | if (m_logFile != null) | 133 | string path = (m_logDirectory.Length > 0 ? m_logDirectory |
134 | { | 134 | + System.IO.Path.DirectorySeparatorChar.ToString() : "") |
135 | m_logFile.Close(); | 135 | + String.Format("{0}{1}.log", LogFileHeader, now.ToString("yyyyMMddHHmmss")); |
136 | m_logFile.Dispose(); | 136 | m_logFile = new StreamWriter(File.Open(path, FileMode.Append, FileAccess.Write)); |
137 | m_logFile = null; | 137 | } |
138 | } | 138 | if (m_logFile != null) |
139 | 139 | { | |
140 | // First log file or time has expired, start writing to a new log file | 140 | StringBuilder buff = new StringBuilder(line.Length + 25); |
141 | m_logFileEndTime = now + m_logFileLife; | 141 | buff.Append(now.ToString("yyyyMMddHHmmssfff")); |
142 | string path = (m_logDirectory.Length > 0 ? m_logDirectory | 142 | // buff.Append(now.ToString("yyyyMMddHHmmss")); |
143 | + System.IO.Path.DirectorySeparatorChar.ToString() : "") | 143 | buff.Append(","); |
144 | + String.Format("{0}{1}.log", LogFileHeader, now.ToString("yyyyMMddHHmmss")); | 144 | buff.Append(line); |
145 | m_logFile = new StreamWriter(File.Open(path, FileMode.Append, FileAccess.Write)); | 145 | buff.Append("\r\n"); |
146 | } | 146 | m_logFile.Write(buff.ToString()); |
147 | if (m_logFile != null) | 147 | } |
148 | { | 148 | } |
149 | StringBuilder buff = new StringBuilder(line.Length + 25); | 149 | } |
150 | buff.Append(now.ToString("yyyyMMddHHmmssfff")); | 150 | catch (Exception e) |
151 | // buff.Append(now.ToString("yyyyMMddHHmmss")); | 151 | { |
152 | buff.Append(","); | 152 | if (ErrorLogger != null) |
153 | buff.Append(line); | 153 | { |
154 | buff.Append("\r\n"); | 154 | ErrorLogger.ErrorFormat("{0}: FAILURE WRITING TO LOGFILE: {1}", LogHeader, e); |
155 | m_logFile.Write(buff.ToString()); | 155 | } |
156 | } | 156 | Enabled = false; |
157 | } | 157 | } |
158 | } | 158 | return; |
159 | catch (Exception e) | 159 | } |
160 | { | 160 | } |
161 | if (ErrorLogger != null) | 161 | } \ No newline at end of file |
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 acefc97..4eecaa2 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs | |||
@@ -137,9 +137,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
137 | ud.FirstName = words[0]; | 137 | ud.FirstName = words[0]; |
138 | ud.LastName = "@" + words[1]; | 138 | ud.LastName = "@" + words[1]; |
139 | users.Add(ud); | 139 | users.Add(ud); |
140 | // WARNING! that uriStr is not quite right... it may be missing the / at the end, | ||
141 | // which will cause trouble (duplicate entries on some tables). We should | ||
142 | // get the UUI instead from the UAS. TO BE FIXED. | ||
143 | AddUser(userID, names[0], names[1], uriStr); | 140 | AddUser(userID, names[0], names[1], uriStr); |
144 | m_log.DebugFormat("[USER MANAGEMENT MODULE]: User {0}@{1} found", words[0], words[1]); | 141 | m_log.DebugFormat("[USER MANAGEMENT MODULE]: User {0}@{1} found", words[0], words[1]); |
145 | } | 142 | } |
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index b4811da..f4ed67b 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs | |||
@@ -31,7 +31,6 @@ using System.Reflection; | |||
31 | 31 | ||
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Framework.Console; | 33 | using OpenSim.Framework.Console; |
34 | using OpenSim.Region.ClientStack.LindenUDP; | ||
35 | using OpenSim.Region.Framework; | 34 | using OpenSim.Region.Framework; |
36 | using OpenSim.Region.Framework.Interfaces; | 35 | using OpenSim.Region.Framework.Interfaces; |
37 | using OpenSim.Region.Framework.Scenes; | 36 | using OpenSim.Region.Framework.Scenes; |
@@ -430,7 +429,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
430 | 429 | ||
431 | public void AddUser(UUID uuid, string first, string last, string homeURL) | 430 | public void AddUser(UUID uuid, string first, string last, string homeURL) |
432 | { | 431 | { |
433 | //m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, first {1}, last {2}, url {3}", uuid, first, last, homeURL); | 432 | // 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); | 434 | AddUser(uuid, homeURL + ";" + first + " " + last); |
435 | } | 435 | } |
436 | 436 | ||
@@ -553,8 +553,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
553 | MainConsole.Instance.Output("-----------------------------------------------------------------------------"); | 553 | MainConsole.Instance.Output("-----------------------------------------------------------------------------"); |
554 | foreach (KeyValuePair<UUID, UserData> kvp in m_UserCache) | 554 | foreach (KeyValuePair<UUID, UserData> kvp in m_UserCache) |
555 | { | 555 | { |
556 | MainConsole.Instance.Output(String.Format("{0} {1} {2} ({3})", | 556 | MainConsole.Instance.Output(String.Format("{0} {1} {2}", |
557 | kvp.Key, kvp.Value.FirstName, kvp.Value.LastName, kvp.Value.HomeURL)); | 557 | kvp.Key, kvp.Value.FirstName, kvp.Value.LastName)); |
558 | } | 558 | } |
559 | 559 | ||
560 | return; | 560 | return; |
diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml index 6c73d91..424e0ab 100644 --- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml +++ b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml | |||
@@ -15,7 +15,6 @@ | |||
15 | <RegionModule id="InventoryAccessModule" type="OpenSim.Region.CoreModules.Framework.InventoryAccess.BasicInventoryAccessModule" /> | 15 | <RegionModule id="InventoryAccessModule" type="OpenSim.Region.CoreModules.Framework.InventoryAccess.BasicInventoryAccessModule" /> |
16 | <RegionModule id="HGInventoryAccessModule" type="OpenSim.Region.CoreModules.Framework.InventoryAccess.HGInventoryAccessModule" /> | 16 | <RegionModule id="HGInventoryAccessModule" type="OpenSim.Region.CoreModules.Framework.InventoryAccess.HGInventoryAccessModule" /> |
17 | <RegionModule id="LandManagementModule" type="OpenSim.Region.CoreModules.World.Land.LandManagementModule" /> | 17 | <RegionModule id="LandManagementModule" type="OpenSim.Region.CoreModules.World.Land.LandManagementModule" /> |
18 | <RegionModule id="DwellModule" type="OpenSim.Region.CoreModules.World.Land.DwellModule" /> | ||
19 | <RegionModule id="PrimCountModule" type="OpenSim.Region.CoreModules.World.Land.PrimCountModule" /> | 18 | <RegionModule id="PrimCountModule" type="OpenSim.Region.CoreModules.World.Land.PrimCountModule" /> |
20 | <RegionModule id="ExportSerialisationModule" type="OpenSim.Region.CoreModules.World.Serialiser.SerialiserModule" /> | 19 | <RegionModule id="ExportSerialisationModule" type="OpenSim.Region.CoreModules.World.Serialiser.SerialiserModule" /> |
21 | <RegionModule id="ArchiverModule" type="OpenSim.Region.CoreModules.World.Archiver.ArchiverModule" /> | 20 | <RegionModule id="ArchiverModule" type="OpenSim.Region.CoreModules.World.Archiver.ArchiverModule" /> |
diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs deleted file mode 100644 index fce9490..0000000 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs +++ /dev/null | |||
@@ -1,61 +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 | |||
28 | using System; | ||
29 | using System.Drawing; | ||
30 | using OpenSim.Region.Framework.Interfaces; | ||
31 | |||
32 | namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | ||
33 | { | ||
34 | public class DynamicTexture : IDynamicTexture | ||
35 | { | ||
36 | public string InputCommands { get; private set; } | ||
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 | |||
43 | public DynamicTexture(string inputCommands, string inputParams, byte[] data, Size size, bool isReuseable) | ||
44 | { | ||
45 | InputCommands = inputCommands; | ||
46 | InputParams = inputParams; | ||
47 | Data = data; | ||
48 | Size = size; | ||
49 | IsReuseable = isReuseable; | ||
50 | } | ||
51 | |||
52 | public DynamicTexture(Uri inputUri, string inputParams, byte[] data, Size size, bool isReuseable) | ||
53 | { | ||
54 | InputUri = inputUri; | ||
55 | InputParams = inputParams; | ||
56 | Data = data; | ||
57 | Size = size; | ||
58 | IsReuseable = isReuseable; | ||
59 | } | ||
60 | } | ||
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 93a045e..18bd018 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs | |||
@@ -42,29 +42,13 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
42 | { | 42 | { |
43 | public class DynamicTextureModule : IRegionModule, IDynamicTextureManager | 43 | public class DynamicTextureModule : IRegionModule, IDynamicTextureManager |
44 | { | 44 | { |
45 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 45 | //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
46 | 46 | ||
47 | private const int ALL_SIDES = -1; | 47 | private const int ALL_SIDES = -1; |
48 | 48 | ||
49 | public const int DISP_EXPIRE = 1; | 49 | public const int DISP_EXPIRE = 1; |
50 | public const int DISP_TEMP = 2; | 50 | public const int DISP_TEMP = 2; |
51 | 51 | ||
52 | /// <summary> | ||
53 | /// If true then where possible dynamic textures are reused. | ||
54 | /// </summary> | ||
55 | public bool ReuseTextures { get; set; } | ||
56 | |||
57 | /// <summary> | ||
58 | /// If false, then textures which have a low data size are not reused when ReuseTextures = true. | ||
59 | /// </summary> | ||
60 | /// <remarks> | ||
61 | /// LL viewers 3.3.4 and before appear to not fully render textures pulled from the viewer cache if those | ||
62 | /// textures have a relatively high pixel surface but a small data size. Typically, this appears to happen | ||
63 | /// if the data size is smaller than the viewer's discard level 2 size estimate. So if this is setting is | ||
64 | /// false, textures smaller than the calculation in IsSizeReuseable are always regenerated rather than reused | ||
65 | /// to work around this problem.</remarks> | ||
66 | public bool ReuseLowDataTextures { get; set; } | ||
67 | |||
68 | private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>(); | 52 | private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>(); |
69 | 53 | ||
70 | private Dictionary<string, IDynamicTextureRender> RenderPlugins = | 54 | private Dictionary<string, IDynamicTextureRender> RenderPlugins = |
@@ -72,15 +56,6 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
72 | 56 | ||
73 | private Dictionary<UUID, DynamicTextureUpdater> Updaters = new Dictionary<UUID, DynamicTextureUpdater>(); | 57 | private Dictionary<UUID, DynamicTextureUpdater> Updaters = new Dictionary<UUID, DynamicTextureUpdater>(); |
74 | 58 | ||
75 | /// <summary> | ||
76 | /// Record dynamic textures that we can reuse for a given data and parameter combination rather than | ||
77 | /// regenerate. | ||
78 | /// </summary> | ||
79 | /// <remarks> | ||
80 | /// Key is string.Format("{0}{1}", data | ||
81 | /// </remarks> | ||
82 | private Cache m_reuseableDynamicTextures; | ||
83 | |||
84 | #region IDynamicTextureManager Members | 59 | #region IDynamicTextureManager Members |
85 | 60 | ||
86 | public void RegisterRender(string handleType, IDynamicTextureRender render) | 61 | public void RegisterRender(string handleType, IDynamicTextureRender render) |
@@ -94,17 +69,17 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
94 | /// <summary> | 69 | /// <summary> |
95 | /// Called by code which actually renders the dynamic texture to supply texture data. | 70 | /// Called by code which actually renders the dynamic texture to supply texture data. |
96 | /// </summary> | 71 | /// </summary> |
97 | /// <param name="updaterId"></param> | 72 | /// <param name="id"></param> |
98 | /// <param name="texture"></param> | 73 | /// <param name="data"></param> |
99 | public void ReturnData(UUID updaterId, IDynamicTexture texture) | 74 | public void ReturnData(UUID id, byte[] data) |
100 | { | 75 | { |
101 | DynamicTextureUpdater updater = null; | 76 | DynamicTextureUpdater updater = null; |
102 | 77 | ||
103 | lock (Updaters) | 78 | lock (Updaters) |
104 | { | 79 | { |
105 | if (Updaters.ContainsKey(updaterId)) | 80 | if (Updaters.ContainsKey(id)) |
106 | { | 81 | { |
107 | updater = Updaters[updaterId]; | 82 | updater = Updaters[id]; |
108 | } | 83 | } |
109 | } | 84 | } |
110 | 85 | ||
@@ -113,16 +88,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
113 | if (RegisteredScenes.ContainsKey(updater.SimUUID)) | 88 | if (RegisteredScenes.ContainsKey(updater.SimUUID)) |
114 | { | 89 | { |
115 | Scene scene = RegisteredScenes[updater.SimUUID]; | 90 | Scene scene = RegisteredScenes[updater.SimUUID]; |
116 | UUID newTextureID = updater.DataReceived(texture.Data, scene); | 91 | updater.DataReceived(data, scene); |
117 | |||
118 | if (ReuseTextures | ||
119 | && !updater.BlendWithOldTexture | ||
120 | && texture.IsReuseable | ||
121 | && (ReuseLowDataTextures || IsDataSizeReuseable(texture))) | ||
122 | { | ||
123 | m_reuseableDynamicTextures.Store( | ||
124 | GenerateReusableTextureKey(texture.InputCommands, texture.InputParams), newTextureID); | ||
125 | } | ||
126 | } | 92 | } |
127 | } | 93 | } |
128 | 94 | ||
@@ -138,27 +104,6 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
138 | } | 104 | } |
139 | } | 105 | } |
140 | 106 | ||
141 | /// <summary> | ||
142 | /// Determines whether the texture is reuseable based on its data size. | ||
143 | /// </summary> | ||
144 | /// <remarks> | ||
145 | /// This is a workaround for a viewer bug where very small data size textures relative to their pixel size | ||
146 | /// are not redisplayed properly when pulled from cache. The calculation here is based on the typical discard | ||
147 | /// level of 2, a 'rate' of 0.125 and 4 components (which makes for a factor of 0.5). | ||
148 | /// </remarks> | ||
149 | /// <returns></returns> | ||
150 | private bool IsDataSizeReuseable(IDynamicTexture texture) | ||
151 | { | ||
152 | // Console.WriteLine("{0} {1}", texture.Size.Width, texture.Size.Height); | ||
153 | int discardLevel2DataThreshold = (int)Math.Ceiling((texture.Size.Width >> 2) * (texture.Size.Height >> 2) * 0.5); | ||
154 | |||
155 | // m_log.DebugFormat( | ||
156 | // "[DYNAMIC TEXTURE MODULE]: Discard level 2 threshold {0}, texture data length {1}", | ||
157 | // discardLevel2DataThreshold, texture.Data.Length); | ||
158 | |||
159 | return discardLevel2DataThreshold < texture.Data.Length; | ||
160 | } | ||
161 | |||
162 | public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, | 107 | public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, |
163 | string extraParams, int updateTimer) | 108 | string extraParams, int updateTimer) |
164 | { | 109 | { |
@@ -222,61 +167,22 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
222 | public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, | 167 | public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, |
223 | string extraParams, int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face) | 168 | string extraParams, int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face) |
224 | { | 169 | { |
225 | if (!RenderPlugins.ContainsKey(contentType)) | 170 | if (RenderPlugins.ContainsKey(contentType)) |
226 | return UUID.Zero; | ||
227 | |||
228 | Scene scene; | ||
229 | RegisteredScenes.TryGetValue(simID, out scene); | ||
230 | |||
231 | if (scene == null) | ||
232 | return UUID.Zero; | ||
233 | |||
234 | SceneObjectPart part = scene.GetSceneObjectPart(primID); | ||
235 | |||
236 | if (part == null) | ||
237 | return UUID.Zero; | ||
238 | |||
239 | // If we want to reuse dynamic textures then we have to ignore any request from the caller to expire | ||
240 | // them. | ||
241 | if (ReuseTextures) | ||
242 | disp = disp & ~DISP_EXPIRE; | ||
243 | |||
244 | DynamicTextureUpdater updater = new DynamicTextureUpdater(); | ||
245 | updater.SimUUID = simID; | ||
246 | updater.PrimID = primID; | ||
247 | updater.ContentType = contentType; | ||
248 | updater.BodyData = data; | ||
249 | updater.UpdateTimer = updateTimer; | ||
250 | updater.UpdaterID = UUID.Random(); | ||
251 | updater.Params = extraParams; | ||
252 | updater.BlendWithOldTexture = SetBlending; | ||
253 | updater.FrontAlpha = AlphaValue; | ||
254 | updater.Face = face; | ||
255 | updater.Url = "Local image"; | ||
256 | updater.Disp = disp; | ||
257 | |||
258 | object objReusableTextureUUID = null; | ||
259 | |||
260 | if (ReuseTextures && !updater.BlendWithOldTexture) | ||
261 | { | 171 | { |
262 | string reuseableTextureKey = GenerateReusableTextureKey(data, extraParams); | 172 | DynamicTextureUpdater updater = new DynamicTextureUpdater(); |
263 | objReusableTextureUUID = m_reuseableDynamicTextures.Get(reuseableTextureKey); | 173 | updater.SimUUID = simID; |
264 | 174 | updater.PrimID = primID; | |
265 | if (objReusableTextureUUID != null) | 175 | updater.ContentType = contentType; |
266 | { | 176 | updater.BodyData = data; |
267 | // If something else has removed this temporary asset from the cache, detect and invalidate | 177 | updater.UpdateTimer = updateTimer; |
268 | // our cached uuid. | 178 | updater.UpdaterID = UUID.Random(); |
269 | if (scene.AssetService.GetMetadata(objReusableTextureUUID.ToString()) == null) | 179 | updater.Params = extraParams; |
270 | { | 180 | updater.BlendWithOldTexture = SetBlending; |
271 | m_reuseableDynamicTextures.Invalidate(reuseableTextureKey); | 181 | updater.FrontAlpha = AlphaValue; |
272 | objReusableTextureUUID = null; | 182 | updater.Face = face; |
273 | } | 183 | updater.Url = "Local image"; |
274 | } | 184 | updater.Disp = disp; |
275 | } | ||
276 | 185 | ||
277 | // We cannot reuse a dynamic texture if the data is going to be blended with something already there. | ||
278 | if (objReusableTextureUUID == null) | ||
279 | { | ||
280 | lock (Updaters) | 186 | lock (Updaters) |
281 | { | 187 | { |
282 | if (!Updaters.ContainsKey(updater.UpdaterID)) | 188 | if (!Updaters.ContainsKey(updater.UpdaterID)) |
@@ -285,29 +191,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
285 | } | 191 | } |
286 | } | 192 | } |
287 | 193 | ||
288 | // m_log.DebugFormat( | ||
289 | // "[DYNAMIC TEXTURE MODULE]: Requesting generation of new dynamic texture for {0} in {1}", | ||
290 | // part.Name, part.ParentGroup.Scene.Name); | ||
291 | |||
292 | RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams); | 194 | RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams); |
195 | return updater.UpdaterID; | ||
293 | } | 196 | } |
294 | else | 197 | |
295 | { | 198 | return UUID.Zero; |
296 | // m_log.DebugFormat( | ||
297 | // "[DYNAMIC TEXTURE MODULE]: Reusing cached texture {0} for {1} in {2}", | ||
298 | // objReusableTextureUUID, part.Name, part.ParentGroup.Scene.Name); | ||
299 | |||
300 | // No need to add to updaters as the texture is always the same. Not that this functionality | ||
301 | // apppears to be implemented anyway. | ||
302 | updater.UpdatePart(part, (UUID)objReusableTextureUUID); | ||
303 | } | ||
304 | |||
305 | return updater.UpdaterID; | ||
306 | } | ||
307 | |||
308 | private string GenerateReusableTextureKey(string data, string extraParams) | ||
309 | { | ||
310 | return string.Format("{0}{1}", data, extraParams); | ||
311 | } | 199 | } |
312 | 200 | ||
313 | public void GetDrawStringSize(string contentType, string text, string fontName, int fontSize, | 201 | public void GetDrawStringSize(string contentType, string text, string fontName, int fontSize, |
@@ -327,13 +215,6 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
327 | 215 | ||
328 | public void Initialise(Scene scene, IConfigSource config) | 216 | public void Initialise(Scene scene, IConfigSource config) |
329 | { | 217 | { |
330 | IConfig texturesConfig = config.Configs["Textures"]; | ||
331 | if (texturesConfig != null) | ||
332 | { | ||
333 | ReuseTextures = texturesConfig.GetBoolean("ReuseDynamicTextures", false); | ||
334 | ReuseLowDataTextures = texturesConfig.GetBoolean("ReuseDynamicLowDataTextures", false); | ||
335 | } | ||
336 | |||
337 | if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) | 218 | if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) |
338 | { | 219 | { |
339 | RegisteredScenes.Add(scene.RegionInfo.RegionID, scene); | 220 | RegisteredScenes.Add(scene.RegionInfo.RegionID, scene); |
@@ -343,11 +224,6 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
343 | 224 | ||
344 | public void PostInitialise() | 225 | public void PostInitialise() |
345 | { | 226 | { |
346 | if (ReuseTextures) | ||
347 | { | ||
348 | m_reuseableDynamicTextures = new Cache(CacheMedium.Memory, CacheStrategy.Conservative); | ||
349 | m_reuseableDynamicTextures.DefaultTTL = new TimeSpan(24, 0, 0); | ||
350 | } | ||
351 | } | 227 | } |
352 | 228 | ||
353 | public void Close() | 229 | public void Close() |
@@ -393,60 +269,9 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
393 | } | 269 | } |
394 | 270 | ||
395 | /// <summary> | 271 | /// <summary> |
396 | /// Update the given part with the new texture. | ||
397 | /// </summary> | ||
398 | /// <returns> | ||
399 | /// The old texture UUID. | ||
400 | /// </returns> | ||
401 | public UUID UpdatePart(SceneObjectPart part, UUID textureID) | ||
402 | { | ||
403 | UUID oldID; | ||
404 | |||
405 | lock (part) | ||
406 | { | ||
407 | // mostly keep the values from before | ||
408 | Primitive.TextureEntry tmptex = part.Shape.Textures; | ||
409 | |||
410 | // FIXME: Need to return the appropriate ID if only a single face is replaced. | ||
411 | oldID = tmptex.DefaultTexture.TextureID; | ||
412 | |||
413 | if (Face == ALL_SIDES) | ||
414 | { | ||
415 | oldID = tmptex.DefaultTexture.TextureID; | ||
416 | tmptex.DefaultTexture.TextureID = textureID; | ||
417 | } | ||
418 | else | ||
419 | { | ||
420 | try | ||
421 | { | ||
422 | Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face); | ||
423 | texface.TextureID = textureID; | ||
424 | tmptex.FaceTextures[Face] = texface; | ||
425 | } | ||
426 | catch (Exception) | ||
427 | { | ||
428 | tmptex.DefaultTexture.TextureID = textureID; | ||
429 | } | ||
430 | } | ||
431 | |||
432 | // I'm pretty sure we always want to force this to true | ||
433 | // I'm pretty sure noone whats to set fullbright true if it wasn't true before. | ||
434 | // tmptex.DefaultTexture.Fullbright = true; | ||
435 | |||
436 | part.UpdateTextureEntry(tmptex.GetBytes()); | ||
437 | } | ||
438 | |||
439 | return oldID; | ||
440 | } | ||
441 | |||
442 | /// <summary> | ||
443 | /// Called once new texture data has been received for this updater. | 272 | /// Called once new texture data has been received for this updater. |
444 | /// </summary> | 273 | /// </summary> |
445 | /// <param name="data"></param> | 274 | public void DataReceived(byte[] data, Scene scene) |
446 | /// <param name="scene"></param> | ||
447 | /// <param name="isReuseable">True if the data given is reuseable.</param> | ||
448 | /// <returns>The asset UUID given to the incoming data.</returns> | ||
449 | public UUID DataReceived(byte[] data, Scene scene) | ||
450 | { | 275 | { |
451 | SceneObjectPart part = scene.GetSceneObjectPart(PrimID); | 276 | SceneObjectPart part = scene.GetSceneObjectPart(PrimID); |
452 | 277 | ||
@@ -456,8 +281,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
456 | String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url); | 281 | String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url); |
457 | scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say, | 282 | scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say, |
458 | 0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false); | 283 | 0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false); |
459 | 284 | return; | |
460 | return UUID.Zero; | ||
461 | } | 285 | } |
462 | 286 | ||
463 | byte[] assetData = null; | 287 | byte[] assetData = null; |
@@ -495,29 +319,56 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture | |||
495 | IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface<IJ2KDecoder>(); | 319 | IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface<IJ2KDecoder>(); |
496 | if (cacheLayerDecode != null) | 320 | if (cacheLayerDecode != null) |
497 | { | 321 | { |
498 | if (!cacheLayerDecode.Decode(asset.FullID, asset.Data)) | 322 | cacheLayerDecode.Decode(asset.FullID, asset.Data); |
499 | m_log.WarnFormat( | 323 | cacheLayerDecode = null; |
500 | "[DYNAMIC TEXTURE MODULE]: Decoding of dynamically generated asset {0} for {1} in {2} failed", | ||
501 | asset.ID, part.Name, part.ParentGroup.Scene.Name); | ||
502 | } | 324 | } |
503 | 325 | ||
504 | UUID oldID = UpdatePart(part, asset.FullID); | 326 | UUID oldID = UUID.Zero; |
505 | 327 | ||
506 | if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0)) | 328 | lock (part) |
507 | { | 329 | { |
508 | if (oldAsset == null) | 330 | // mostly keep the values from before |
509 | oldAsset = scene.AssetService.Get(oldID.ToString()); | 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 | } | ||
510 | 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 | |||
361 | if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0)) | ||
362 | { | ||
363 | if (oldAsset == null) oldAsset = scene.AssetService.Get(oldID.ToString()); | ||
511 | if (oldAsset != null) | 364 | if (oldAsset != null) |
512 | { | 365 | { |
513 | if (oldAsset.Temporary) | 366 | if (oldAsset.Temporary == true) |
514 | { | 367 | { |
515 | scene.AssetService.Delete(oldID.ToString()); | 368 | scene.AssetService.Delete(oldID.ToString()); |
516 | } | 369 | } |
517 | } | 370 | } |
518 | } | 371 | } |
519 | |||
520 | return asset.FullID; | ||
521 | } | 372 | } |
522 | 373 | ||
523 | private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha) | 374 | private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha) |
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index 0b9174f..56221aa 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs | |||
@@ -58,7 +58,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
58 | public string body; | 58 | public string body; |
59 | public int responseCode; | 59 | public int responseCode; |
60 | public string responseBody; | 60 | public string responseBody; |
61 | public string responseType = "text/plain"; | ||
62 | //public ManualResetEvent ev; | 61 | //public ManualResetEvent ev; |
63 | public bool requestDone; | 62 | public bool requestDone; |
64 | public int startTime; | 63 | public int startTime; |
@@ -271,22 +270,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
271 | } | 270 | } |
272 | } | 271 | } |
273 | 272 | ||
274 | public void HttpContentType(UUID request, string type) | ||
275 | { | ||
276 | lock (m_UrlMap) | ||
277 | { | ||
278 | if (m_RequestMap.ContainsKey(request)) | ||
279 | { | ||
280 | UrlData urlData = m_RequestMap[request]; | ||
281 | urlData.requests[request].responseType = type; | ||
282 | } | ||
283 | else | ||
284 | { | ||
285 | m_log.Info("[HttpRequestHandler] There is no http-in request with id " + request.ToString()); | ||
286 | } | ||
287 | } | ||
288 | } | ||
289 | |||
290 | public void HttpResponse(UUID request, int status, string body) | 273 | public void HttpResponse(UUID request, int status, string body) |
291 | { | 274 | { |
292 | lock (m_RequestMap) | 275 | lock (m_RequestMap) |
diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs index 45e6527..6f83948 100644 --- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs | |||
@@ -32,7 +32,6 @@ using System.Net; | |||
32 | using Nini.Config; | 32 | using Nini.Config; |
33 | using OpenMetaverse; | 33 | using OpenMetaverse; |
34 | using OpenMetaverse.Imaging; | 34 | using OpenMetaverse.Imaging; |
35 | using OpenSim.Region.CoreModules.Scripting.DynamicTexture; | ||
36 | using OpenSim.Region.Framework.Interfaces; | 35 | using OpenSim.Region.Framework.Interfaces; |
37 | using OpenSim.Region.Framework.Scenes; | 36 | using OpenSim.Region.Framework.Scenes; |
38 | using log4net; | 37 | using log4net; |
@@ -68,18 +67,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL | |||
68 | return true; | 67 | return true; |
69 | } | 68 | } |
70 | 69 | ||
71 | // public bool AlwaysIdenticalConversion(string bodyData, string extraParams) | 70 | public byte[] ConvertUrl(string url, string extraParams) |
72 | // { | ||
73 | // // We don't support conversion of body data. | ||
74 | // return false; | ||
75 | // } | ||
76 | |||
77 | public IDynamicTexture ConvertUrl(string url, string extraParams) | ||
78 | { | 71 | { |
79 | return null; | 72 | return null; |
80 | } | 73 | } |
81 | 74 | ||
82 | public IDynamicTexture ConvertData(string bodyData, string extraParams) | 75 | public byte[] ConvertStream(Stream data, string extraParams) |
83 | { | 76 | { |
84 | return null; | 77 | return null; |
85 | } | 78 | } |
@@ -172,11 +165,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL | |||
172 | 165 | ||
173 | private void HttpRequestReturn(IAsyncResult result) | 166 | private void HttpRequestReturn(IAsyncResult result) |
174 | { | 167 | { |
168 | |||
175 | RequestState state = (RequestState) result.AsyncState; | 169 | RequestState state = (RequestState) result.AsyncState; |
176 | WebRequest request = (WebRequest) state.Request; | 170 | WebRequest request = (WebRequest) state.Request; |
177 | Stream stream = null; | 171 | Stream stream = null; |
178 | byte[] imageJ2000 = new byte[0]; | 172 | byte[] imageJ2000 = new byte[0]; |
179 | Size newSize = new Size(0, 0); | ||
180 | 173 | ||
181 | try | 174 | try |
182 | { | 175 | { |
@@ -189,43 +182,37 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL | |||
189 | try | 182 | try |
190 | { | 183 | { |
191 | Bitmap image = new Bitmap(stream); | 184 | Bitmap image = new Bitmap(stream); |
185 | Size newsize; | ||
192 | 186 | ||
193 | // TODO: make this a bit less hard coded | 187 | // TODO: make this a bit less hard coded |
194 | if ((image.Height < 64) && (image.Width < 64)) | 188 | if ((image.Height < 64) && (image.Width < 64)) |
195 | { | 189 | { |
196 | newSize.Width = 32; | 190 | newsize = new Size(32, 32); |
197 | newSize.Height = 32; | ||
198 | } | 191 | } |
199 | else if ((image.Height < 128) && (image.Width < 128)) | 192 | else if ((image.Height < 128) && (image.Width < 128)) |
200 | { | 193 | { |
201 | newSize.Width = 64; | 194 | newsize = new Size(64, 64); |
202 | newSize.Height = 64; | ||
203 | } | 195 | } |
204 | else if ((image.Height < 256) && (image.Width < 256)) | 196 | else if ((image.Height < 256) && (image.Width < 256)) |
205 | { | 197 | { |
206 | newSize.Width = 128; | 198 | newsize = new Size(128, 128); |
207 | newSize.Height = 128; | ||
208 | } | 199 | } |
209 | else if ((image.Height < 512 && image.Width < 512)) | 200 | else if ((image.Height < 512 && image.Width < 512)) |
210 | { | 201 | { |
211 | newSize.Width = 256; | 202 | newsize = new Size(256, 256); |
212 | newSize.Height = 256; | ||
213 | } | 203 | } |
214 | else if ((image.Height < 1024 && image.Width < 1024)) | 204 | else if ((image.Height < 1024 && image.Width < 1024)) |
215 | { | 205 | { |
216 | newSize.Width = 512; | 206 | newsize = new Size(512, 512); |
217 | newSize.Height = 512; | ||
218 | } | 207 | } |
219 | else | 208 | else |
220 | { | 209 | { |
221 | newSize.Width = 1024; | 210 | newsize = new Size(1024, 1024); |
222 | newSize.Height = 1024; | ||
223 | } | 211 | } |
224 | 212 | ||
225 | using (Bitmap resize = new Bitmap(image, newSize)) | 213 | Bitmap resize = new Bitmap(image, newsize); |
226 | { | 214 | |
227 | imageJ2000 = OpenJPEG.EncodeFromImage(resize, true); | 215 | imageJ2000 = OpenJPEG.EncodeFromImage(resize, true); |
228 | } | ||
229 | } | 216 | } |
230 | catch (Exception) | 217 | catch (Exception) |
231 | { | 218 | { |
@@ -240,6 +227,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL | |||
240 | } | 227 | } |
241 | catch (WebException) | 228 | catch (WebException) |
242 | { | 229 | { |
230 | |||
243 | } | 231 | } |
244 | finally | 232 | finally |
245 | { | 233 | { |
@@ -248,14 +236,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL | |||
248 | stream.Close(); | 236 | stream.Close(); |
249 | } | 237 | } |
250 | } | 238 | } |
251 | 239 | m_log.DebugFormat("[LOADIMAGEURLMODULE] Returning {0} bytes of image data for request {1}", | |
252 | m_log.DebugFormat("[LOADIMAGEURLMODULE]: Returning {0} bytes of image data for request {1}", | ||
253 | imageJ2000.Length, state.RequestID); | 240 | imageJ2000.Length, state.RequestID); |
254 | 241 | m_textureManager.ReturnData(state.RequestID, imageJ2000); | |
255 | m_textureManager.ReturnData( | ||
256 | state.RequestID, | ||
257 | new OpenSim.Region.CoreModules.Scripting.DynamicTexture.DynamicTexture( | ||
258 | request.RequestUri, null, imageJ2000, newSize, false)); | ||
259 | } | 242 | } |
260 | 243 | ||
261 | #region Nested type: RequestState | 244 | #region Nested type: RequestState |
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs index 41baccc..9787c8c 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs | |||
@@ -45,292 +45,31 @@ using OpenSim.Tests.Common.Mock; | |||
45 | namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests | 45 | namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests |
46 | { | 46 | { |
47 | [TestFixture] | 47 | [TestFixture] |
48 | public class VectorRenderModuleTests : OpenSimTestCase | 48 | public class VectorRenderModuleTests |
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 | |||
67 | [Test] | 50 | [Test] |
68 | public void TestDraw() | 51 | public void TestDraw() |
69 | { | 52 | { |
70 | TestHelpers.InMethod(); | 53 | TestHelpers.InMethod(); |
71 | 54 | ||
72 | SetupScene(false); | 55 | Scene scene = new SceneHelpers().SetupScene(); |
73 | SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); | 56 | DynamicTextureModule dtm = new DynamicTextureModule(); |
74 | UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; | 57 | VectorRenderModule vrm = new VectorRenderModule(); |
75 | 58 | SceneHelpers.SetupSceneModules(scene, dtm, vrm); | |
76 | m_dtm.AddDynamicTextureData( | ||
77 | m_scene.RegionInfo.RegionID, | ||
78 | so.UUID, | ||
79 | m_vrm.GetContentType(), | ||
80 | "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;", | ||
81 | "", | ||
82 | 0); | ||
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 | 59 | ||
186 | SetupScene(true); | 60 | SceneObjectGroup so = SceneHelpers.AddSceneObject(scene); |
187 | SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); | ||
188 | UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; | 61 | UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; |
189 | 62 | ||
190 | m_dtm.AddDynamicTextureData( | 63 | dtm.AddDynamicTextureData( |
191 | m_scene.RegionInfo.RegionID, | 64 | scene.RegionInfo.RegionID, |
192 | so.UUID, | 65 | so.UUID, |
193 | m_vrm.GetContentType(), | 66 | vrm.GetContentType(), |
194 | "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;", | 67 | "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;", |
195 | "", | 68 | "", |
196 | 0); | 69 | 0); |
197 | 70 | ||
198 | Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); | ||
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 | 71 | ||
333 | Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); | 72 | Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); |
334 | } | 73 | } |
335 | } | 74 | } |
336 | } \ No newline at end of file | 75 | } \ 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 673c2d1..8b2f2f8 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs | |||
@@ -30,12 +30,10 @@ using System.Drawing; | |||
30 | using System.Drawing.Imaging; | 30 | using System.Drawing.Imaging; |
31 | using System.Globalization; | 31 | using System.Globalization; |
32 | using System.IO; | 32 | using System.IO; |
33 | using System.Linq; | ||
34 | using System.Net; | 33 | using System.Net; |
35 | using Nini.Config; | 34 | using Nini.Config; |
36 | using OpenMetaverse; | 35 | using OpenMetaverse; |
37 | using OpenMetaverse.Imaging; | 36 | using OpenMetaverse.Imaging; |
38 | using OpenSim.Region.CoreModules.Scripting.DynamicTexture; | ||
39 | using OpenSim.Region.Framework.Interfaces; | 37 | using OpenSim.Region.Framework.Interfaces; |
40 | using OpenSim.Region.Framework.Scenes; | 38 | using OpenSim.Region.Framework.Scenes; |
41 | using log4net; | 39 | using log4net; |
@@ -47,13 +45,9 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
47 | { | 45 | { |
48 | public class VectorRenderModule : IRegionModule, IDynamicTextureRender | 46 | public class VectorRenderModule : IRegionModule, IDynamicTextureRender |
49 | { | 47 | { |
50 | // These fields exist for testing purposes, please do not remove. | ||
51 | // private static bool s_flipper; | ||
52 | // private static byte[] s_asset1Data; | ||
53 | // private static byte[] s_asset2Data; | ||
54 | |||
55 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 48 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
56 | 49 | ||
50 | private string m_name = "VectorRenderModule"; | ||
57 | private Scene m_scene; | 51 | private Scene m_scene; |
58 | private IDynamicTextureManager m_textureManager; | 52 | private IDynamicTextureManager m_textureManager; |
59 | private Graphics m_graph; | 53 | private Graphics m_graph; |
@@ -67,12 +61,12 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
67 | 61 | ||
68 | public string GetContentType() | 62 | public string GetContentType() |
69 | { | 63 | { |
70 | return "vector"; | 64 | return ("vector"); |
71 | } | 65 | } |
72 | 66 | ||
73 | public string GetName() | 67 | public string GetName() |
74 | { | 68 | { |
75 | return Name; | 69 | return m_name; |
76 | } | 70 | } |
77 | 71 | ||
78 | public bool SupportsAsynchronous() | 72 | public bool SupportsAsynchronous() |
@@ -80,20 +74,14 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
80 | return true; | 74 | return true; |
81 | } | 75 | } |
82 | 76 | ||
83 | // public bool AlwaysIdenticalConversion(string bodyData, string extraParams) | 77 | public byte[] ConvertUrl(string url, string extraParams) |
84 | // { | ||
85 | // string[] lines = GetLines(bodyData); | ||
86 | // return lines.Any((str, r) => str.StartsWith("Image")); | ||
87 | // } | ||
88 | |||
89 | public IDynamicTexture ConvertUrl(string url, string extraParams) | ||
90 | { | 78 | { |
91 | return null; | 79 | return null; |
92 | } | 80 | } |
93 | 81 | ||
94 | public IDynamicTexture ConvertData(string bodyData, string extraParams) | 82 | public byte[] ConvertStream(Stream data, string extraParams) |
95 | { | 83 | { |
96 | return Draw(bodyData, extraParams); | 84 | return null; |
97 | } | 85 | } |
98 | 86 | ||
99 | public bool AsyncConvertUrl(UUID id, string url, string extraParams) | 87 | public bool AsyncConvertUrl(UUID id, string url, string extraParams) |
@@ -103,28 +91,21 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
103 | 91 | ||
104 | public bool AsyncConvertData(UUID id, string bodyData, string extraParams) | 92 | public bool AsyncConvertData(UUID id, string bodyData, string extraParams) |
105 | { | 93 | { |
106 | // XXX: This isn't actually being done asynchronously! | 94 | Draw(bodyData, id, extraParams); |
107 | m_textureManager.ReturnData(id, ConvertData(bodyData, extraParams)); | ||
108 | |||
109 | return true; | 95 | return true; |
110 | } | 96 | } |
111 | 97 | ||
112 | public void GetDrawStringSize(string text, string fontName, int fontSize, | 98 | public void GetDrawStringSize(string text, string fontName, int fontSize, |
113 | out double xSize, out double ySize) | 99 | out double xSize, out double ySize) |
114 | { | 100 | { |
115 | lock (this) | 101 | using (Font myFont = new Font(fontName, fontSize)) |
116 | { | 102 | { |
117 | using (Font myFont = new Font(fontName, fontSize)) | 103 | SizeF stringSize = new SizeF(); |
104 | lock (m_graph) | ||
118 | { | 105 | { |
119 | SizeF stringSize = new SizeF(); | 106 | stringSize = m_graph.MeasureString(text, myFont); |
120 | 107 | xSize = stringSize.Width; | |
121 | // XXX: This lock may be unnecessary. | 108 | ySize = stringSize.Height; |
122 | lock (m_graph) | ||
123 | { | ||
124 | stringSize = m_graph.MeasureString(text, myFont); | ||
125 | xSize = stringSize.Width; | ||
126 | ySize = stringSize.Height; | ||
127 | } | ||
128 | } | 109 | } |
129 | } | 110 | } |
130 | } | 111 | } |
@@ -163,13 +144,6 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
163 | { | 144 | { |
164 | m_textureManager.RegisterRender(GetContentType(), this); | 145 | m_textureManager.RegisterRender(GetContentType(), this); |
165 | } | 146 | } |
166 | |||
167 | // This code exists for testing purposes, please do not remove. | ||
168 | // s_asset1Data = m_scene.AssetService.Get("00000000-0000-1111-9999-000000000001").Data; | ||
169 | // s_asset1Data = m_scene.AssetService.Get("9f4acf0d-1841-4e15-bdb8-3a12efc9dd8f").Data; | ||
170 | |||
171 | // Terrain dirt - smallest bin/assets file (6004 bytes) | ||
172 | // s_asset2Data = m_scene.AssetService.Get("b8d3965a-ad78-bf43-699b-bff8eca6c975").Data; | ||
173 | } | 147 | } |
174 | 148 | ||
175 | public void Close() | 149 | public void Close() |
@@ -178,7 +152,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
178 | 152 | ||
179 | public string Name | 153 | public string Name |
180 | { | 154 | { |
181 | get { return "VectorRenderModule"; } | 155 | get { return m_name; } |
182 | } | 156 | } |
183 | 157 | ||
184 | public bool IsSharedModule | 158 | public bool IsSharedModule |
@@ -188,7 +162,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
188 | 162 | ||
189 | #endregion | 163 | #endregion |
190 | 164 | ||
191 | private IDynamicTexture Draw(string data, string extraParams) | 165 | private void Draw(string data, UUID id, string extraParams) |
192 | { | 166 | { |
193 | // 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 | 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 |
194 | // we will now support multiple comma seperated params in the form width:256,height:512,alpha:255 | 168 | // we will now support multiple comma seperated params in the form width:256,height:512,alpha:255 |
@@ -331,57 +305,40 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
331 | 305 | ||
332 | Bitmap bitmap = null; | 306 | Bitmap bitmap = null; |
333 | Graphics graph = null; | 307 | Graphics graph = null; |
334 | bool reuseable = false; | ||
335 | 308 | ||
336 | try | 309 | try |
337 | { | 310 | { |
338 | // XXX: In testing, it appears that if multiple threads dispose of separate GDI+ objects simultaneously, | 311 | if (alpha == 256) |
339 | // the native malloc heap can become corrupted, possibly due to a double free(). This may be due to | 312 | bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb); |
340 | // bugs in the underlying libcairo used by mono's libgdiplus.dll on Linux/OSX. These problems were | 313 | else |
341 | // seen with both libcario 1.10.2-6.1ubuntu3 and 1.8.10-2ubuntu1. They go away if disposal is perfomed | 314 | bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb); |
342 | // under lock. | 315 | |
343 | lock (this) | 316 | graph = Graphics.FromImage(bitmap); |
344 | { | ||
345 | if (alpha == 256) | ||
346 | bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb); | ||
347 | else | ||
348 | bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb); | ||
349 | 317 | ||
350 | graph = Graphics.FromImage(bitmap); | 318 | // this is really just to save people filling the |
351 | 319 | // background color in their scripts, only do when fully opaque | |
352 | // this is really just to save people filling the | 320 | if (alpha >= 255) |
353 | // background color in their scripts, only do when fully opaque | 321 | { |
354 | if (alpha >= 255) | 322 | using (SolidBrush bgFillBrush = new SolidBrush(bgColor)) |
355 | { | 323 | { |
356 | using (SolidBrush bgFillBrush = new SolidBrush(bgColor)) | 324 | graph.FillRectangle(bgFillBrush, 0, 0, width, height); |
357 | { | ||
358 | graph.FillRectangle(bgFillBrush, 0, 0, width, height); | ||
359 | } | ||
360 | } | 325 | } |
361 | 326 | } | |
362 | for (int w = 0; w < bitmap.Width; w++) | 327 | |
328 | for (int w = 0; w < bitmap.Width; w++) | ||
329 | { | ||
330 | if (alpha <= 255) | ||
363 | { | 331 | { |
364 | if (alpha <= 255) | 332 | for (int h = 0; h < bitmap.Height; h++) |
365 | { | 333 | { |
366 | for (int h = 0; h < bitmap.Height; h++) | 334 | bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h))); |
367 | { | ||
368 | bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h))); | ||
369 | } | ||
370 | } | 335 | } |
371 | } | 336 | } |
372 | |||
373 | GDIDraw(data, graph, altDataDelim, out reuseable); | ||
374 | } | 337 | } |
375 | 338 | ||
339 | GDIDraw(data, graph, altDataDelim); | ||
340 | |||
376 | byte[] imageJ2000 = new byte[0]; | 341 | byte[] imageJ2000 = new byte[0]; |
377 | |||
378 | // This code exists for testing purposes, please do not remove. | ||
379 | // if (s_flipper) | ||
380 | // imageJ2000 = s_asset1Data; | ||
381 | // else | ||
382 | // imageJ2000 = s_asset2Data; | ||
383 | // | ||
384 | // s_flipper = !s_flipper; | ||
385 | 342 | ||
386 | try | 343 | try |
387 | { | 344 | { |
@@ -394,24 +351,15 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
394 | e.Message, e.StackTrace); | 351 | e.Message, e.StackTrace); |
395 | } | 352 | } |
396 | 353 | ||
397 | return new OpenSim.Region.CoreModules.Scripting.DynamicTexture.DynamicTexture( | 354 | m_textureManager.ReturnData(id, imageJ2000); |
398 | data, extraParams, imageJ2000, new Size(width, height), reuseable); | ||
399 | } | 355 | } |
400 | finally | 356 | finally |
401 | { | 357 | { |
402 | // XXX: In testing, it appears that if multiple threads dispose of separate GDI+ objects simultaneously, | 358 | if (graph != null) |
403 | // the native malloc heap can become corrupted, possibly due to a double free(). This may be due to | 359 | graph.Dispose(); |
404 | // bugs in the underlying libcairo used by mono's libgdiplus.dll on Linux/OSX. These problems were | 360 | |
405 | // seen with both libcario 1.10.2-6.1ubuntu3 and 1.8.10-2ubuntu1. They go away if disposal is perfomed | 361 | if (bitmap != null) |
406 | // under lock. | 362 | bitmap.Dispose(); |
407 | lock (this) | ||
408 | { | ||
409 | if (graph != null) | ||
410 | graph.Dispose(); | ||
411 | |||
412 | if (bitmap != null) | ||
413 | bitmap.Dispose(); | ||
414 | } | ||
415 | } | 363 | } |
416 | } | 364 | } |
417 | 365 | ||
@@ -470,21 +418,8 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
470 | } | 418 | } |
471 | */ | 419 | */ |
472 | 420 | ||
473 | /// <summary> | 421 | private void GDIDraw(string data, Graphics graph, char dataDelim) |
474 | /// Split input data into discrete command lines. | ||
475 | /// </summary> | ||
476 | /// <returns></returns> | ||
477 | /// <param name='data'></param> | ||
478 | /// <param name='dataDelim'></param> | ||
479 | private string[] GetLines(string data, char dataDelim) | ||
480 | { | ||
481 | char[] lineDelimiter = { dataDelim }; | ||
482 | return data.Split(lineDelimiter); | ||
483 | } | ||
484 | |||
485 | private void GDIDraw(string data, Graphics graph, char dataDelim, out bool reuseable) | ||
486 | { | 422 | { |
487 | reuseable = true; | ||
488 | Point startPoint = new Point(0, 0); | 423 | Point startPoint = new Point(0, 0); |
489 | Point endPoint = new Point(0, 0); | 424 | Point endPoint = new Point(0, 0); |
490 | Pen drawPen = null; | 425 | Pen drawPen = null; |
@@ -499,9 +434,11 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
499 | myFont = new Font(fontName, fontSize); | 434 | myFont = new Font(fontName, fontSize); |
500 | myBrush = new SolidBrush(Color.Black); | 435 | myBrush = new SolidBrush(Color.Black); |
501 | 436 | ||
437 | char[] lineDelimiter = {dataDelim}; | ||
502 | char[] partsDelimiter = {','}; | 438 | char[] partsDelimiter = {','}; |
439 | string[] lines = data.Split(lineDelimiter); | ||
503 | 440 | ||
504 | foreach (string line in GetLines(data, dataDelim)) | 441 | foreach (string line in lines) |
505 | { | 442 | { |
506 | string nextLine = line.Trim(); | 443 | string nextLine = line.Trim(); |
507 | //replace with switch, or even better, do some proper parsing | 444 | //replace with switch, or even better, do some proper parsing |
@@ -532,10 +469,6 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender | |||
532 | } | 469 | } |
533 | else if (nextLine.StartsWith("Image")) | 470 | else if (nextLine.StartsWith("Image")) |
534 | { | 471 | { |
535 | // We cannot reuse any generated texture involving fetching an image via HTTP since that image | ||
536 | // can change. | ||
537 | reuseable = false; | ||
538 | |||
539 | float x = 0; | 472 | float x = 0; |
540 | float y = 0; | 473 | float y = 0; |
541 | GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y); | 474 | 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 e167e31..07bb291 100644 --- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs | |||
@@ -28,7 +28,6 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Text.RegularExpressions; | ||
32 | using Nini.Config; | 31 | using Nini.Config; |
33 | using OpenMetaverse; | 32 | using OpenMetaverse; |
34 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
@@ -173,42 +172,12 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm | |||
173 | /// <param name="hostID">UUID of the SceneObjectPart</param> | 172 | /// <param name="hostID">UUID of the SceneObjectPart</param> |
174 | /// <param name="channel">channel to listen on</param> | 173 | /// <param name="channel">channel to listen on</param> |
175 | /// <param name="name">name to filter on</param> | 174 | /// <param name="name">name to filter on</param> |
176 | /// <param name="id"> | 175 | /// <param name="id">key to filter on (user given, could be totally faked)</param> |
177 | /// key to filter on (user given, could be totally faked) | ||
178 | /// </param> | ||
179 | /// <param name="msg">msg to filter on</param> | ||
180 | /// <returns>number of the scripts handle</returns> | ||
181 | public int Listen(uint localID, UUID itemID, UUID hostID, int channel, | ||
182 | string name, UUID id, string msg) | ||
183 | { | ||
184 | return m_listenerManager.AddListener(localID, itemID, hostID, | ||
185 | channel, name, id, msg); | ||
186 | } | ||
187 | |||
188 | /// <summary> | ||
189 | /// Create a listen event callback with the specified filters. | ||
190 | /// The parameters localID,itemID are needed to uniquely identify | ||
191 | /// the script during 'peek' time. Parameter hostID is needed to | ||
192 | /// determine the position of the script. | ||
193 | /// </summary> | ||
194 | /// <param name="localID">localID of the script engine</param> | ||
195 | /// <param name="itemID">UUID of the script engine</param> | ||
196 | /// <param name="hostID">UUID of the SceneObjectPart</param> | ||
197 | /// <param name="channel">channel to listen on</param> | ||
198 | /// <param name="name">name to filter on</param> | ||
199 | /// <param name="id"> | ||
200 | /// key to filter on (user given, could be totally faked) | ||
201 | /// </param> | ||
202 | /// <param name="msg">msg to filter on</param> | 176 | /// <param name="msg">msg to filter on</param> |
203 | /// <param name="regexBitfield"> | ||
204 | /// Bitfield indicating which strings should be processed as regex. | ||
205 | /// </param> | ||
206 | /// <returns>number of the scripts handle</returns> | 177 | /// <returns>number of the scripts handle</returns> |
207 | public int Listen(uint localID, UUID itemID, UUID hostID, int channel, | 178 | public int Listen(uint localID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg) |
208 | string name, UUID id, string msg, int regexBitfield) | ||
209 | { | 179 | { |
210 | return m_listenerManager.AddListener(localID, itemID, hostID, | 180 | return m_listenerManager.AddListener(localID, itemID, hostID, channel, name, id, msg); |
211 | channel, name, id, msg, regexBitfield); | ||
212 | } | 181 | } |
213 | 182 | ||
214 | /// <summary> | 183 | /// <summary> |
@@ -357,7 +326,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm | |||
357 | if (channel == 0) | 326 | if (channel == 0) |
358 | { | 327 | { |
359 | // Channel 0 goes to viewer ONLY | 328 | // Channel 0 goes to viewer ONLY |
360 | m_scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Broadcast, 0, pos, name, id, target, false, false); | 329 | m_scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Broadcast, 0, pos, name, id, false, false, target); |
361 | return true; | 330 | return true; |
362 | } | 331 | } |
363 | 332 | ||
@@ -501,25 +470,15 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm | |||
501 | m_curlisteners = 0; | 470 | m_curlisteners = 0; |
502 | } | 471 | } |
503 | 472 | ||
504 | public int AddListener(uint localID, UUID itemID, UUID hostID, | 473 | public int AddListener(uint localID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg) |
505 | int channel, string name, UUID id, string msg) | ||
506 | { | ||
507 | return AddListener(localID, itemID, hostID, channel, name, id, | ||
508 | msg, 0); | ||
509 | } | ||
510 | |||
511 | public int AddListener(uint localID, UUID itemID, UUID hostID, | ||
512 | int channel, string name, UUID id, string msg, | ||
513 | int regexBitfield) | ||
514 | { | 474 | { |
515 | // do we already have a match on this particular filter event? | 475 | // do we already have a match on this particular filter event? |
516 | List<ListenerInfo> coll = GetListeners(itemID, channel, name, id, | 476 | List<ListenerInfo> coll = GetListeners(itemID, channel, name, id, msg); |
517 | msg); | ||
518 | 477 | ||
519 | if (coll.Count > 0) | 478 | if (coll.Count > 0) |
520 | { | 479 | { |
521 | // special case, called with same filter settings, return same | 480 | // special case, called with same filter settings, return same handle |
522 | // handle (2008-05-02, tested on 1.21.1 server, still holds) | 481 | // (2008-05-02, tested on 1.21.1 server, still holds) |
523 | return coll[0].GetHandle(); | 482 | return coll[0].GetHandle(); |
524 | } | 483 | } |
525 | 484 | ||
@@ -531,9 +490,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm | |||
531 | 490 | ||
532 | if (newHandle > 0) | 491 | if (newHandle > 0) |
533 | { | 492 | { |
534 | ListenerInfo li = new ListenerInfo(newHandle, localID, | 493 | ListenerInfo li = new ListenerInfo(newHandle, localID, itemID, hostID, channel, name, id, msg); |
535 | itemID, hostID, channel, name, id, msg, | ||
536 | regexBitfield); | ||
537 | 494 | ||
538 | List<ListenerInfo> listeners; | 495 | List<ListenerInfo> listeners; |
539 | if (!m_listeners.TryGetValue(channel,out listeners)) | 496 | if (!m_listeners.TryGetValue(channel,out listeners)) |
@@ -674,22 +631,6 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm | |||
674 | return -1; | 631 | return -1; |
675 | } | 632 | } |
676 | 633 | ||
677 | /// These are duplicated from ScriptBaseClass | ||
678 | /// http://opensimulator.org/mantis/view.php?id=6106#c21945 | ||
679 | #region Constants for the bitfield parameter of osListenRegex | ||
680 | |||
681 | /// <summary> | ||
682 | /// process name parameter as regex | ||
683 | /// </summary> | ||
684 | public const int OS_LISTEN_REGEX_NAME = 0x1; | ||
685 | |||
686 | /// <summary> | ||
687 | /// process message parameter as regex | ||
688 | /// </summary> | ||
689 | public const int OS_LISTEN_REGEX_MESSAGE = 0x2; | ||
690 | |||
691 | #endregion | ||
692 | |||
693 | // Theres probably a more clever and efficient way to | 634 | // Theres probably a more clever and efficient way to |
694 | // do this, maybe with regex. | 635 | // do this, maybe with regex. |
695 | // PM2008: Ha, one could even be smart and define a specialized Enumerator. | 636 | // PM2008: Ha, one could even be smart and define a specialized Enumerator. |
@@ -715,10 +656,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm | |||
715 | { | 656 | { |
716 | continue; | 657 | continue; |
717 | } | 658 | } |
718 | if (li.GetName().Length > 0 && ( | 659 | if (li.GetName().Length > 0 && !li.GetName().Equals(name)) |
719 | ((li.RegexBitfield & OS_LISTEN_REGEX_NAME) != OS_LISTEN_REGEX_NAME && !li.GetName().Equals(name)) || | ||
720 | ((li.RegexBitfield & OS_LISTEN_REGEX_NAME) == OS_LISTEN_REGEX_NAME && !Regex.IsMatch(name, li.GetName())) | ||
721 | )) | ||
722 | { | 660 | { |
723 | continue; | 661 | continue; |
724 | } | 662 | } |
@@ -726,10 +664,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm | |||
726 | { | 664 | { |
727 | continue; | 665 | continue; |
728 | } | 666 | } |
729 | if (li.GetMessage().Length > 0 && ( | 667 | if (li.GetMessage().Length > 0 && !li.GetMessage().Equals(msg)) |
730 | ((li.RegexBitfield & OS_LISTEN_REGEX_MESSAGE) != OS_LISTEN_REGEX_MESSAGE && !li.GetMessage().Equals(msg)) || | ||
731 | ((li.RegexBitfield & OS_LISTEN_REGEX_MESSAGE) == OS_LISTEN_REGEX_MESSAGE && !Regex.IsMatch(msg, li.GetMessage())) | ||
732 | )) | ||
733 | { | 668 | { |
734 | continue; | 669 | continue; |
735 | } | 670 | } |
@@ -762,13 +697,10 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm | |||
762 | { | 697 | { |
763 | int idx = 0; | 698 | int idx = 0; |
764 | Object[] item = new Object[6]; | 699 | Object[] item = new Object[6]; |
765 | int dataItemLength = 6; | ||
766 | 700 | ||
767 | while (idx < data.Length) | 701 | while (idx < data.Length) |
768 | { | 702 | { |
769 | dataItemLength = (idx + 7 == data.Length || (idx + 7 < data.Length && data[idx + 7] is bool)) ? 7 : 6; | 703 | Array.Copy(data, idx, item, 0, 6); |
770 | item = new Object[dataItemLength]; | ||
771 | Array.Copy(data, idx, item, 0, dataItemLength); | ||
772 | 704 | ||
773 | ListenerInfo info = | 705 | ListenerInfo info = |
774 | ListenerInfo.FromData(localID, itemID, hostID, item); | 706 | ListenerInfo.FromData(localID, itemID, hostID, item); |
@@ -780,12 +712,12 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm | |||
780 | m_listeners[(int)item[2]].Add(info); | 712 | m_listeners[(int)item[2]].Add(info); |
781 | } | 713 | } |
782 | 714 | ||
783 | idx+=dataItemLength; | 715 | idx+=6; |
784 | } | 716 | } |
785 | } | 717 | } |
786 | } | 718 | } |
787 | 719 | ||
788 | public class ListenerInfo : IWorldCommListenerInfo | 720 | public class ListenerInfo: IWorldCommListenerInfo |
789 | { | 721 | { |
790 | private bool m_active; // Listener is active or not | 722 | private bool m_active; // Listener is active or not |
791 | private int m_handle; // Assigned handle of this listener | 723 | private int m_handle; // Assigned handle of this listener |
@@ -799,29 +731,16 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm | |||
799 | 731 | ||
800 | public ListenerInfo(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, UUID id, string message) | 732 | public ListenerInfo(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, UUID id, string message) |
801 | { | 733 | { |
802 | Initialise(handle, localID, ItemID, hostID, channel, name, id, | 734 | Initialise(handle, localID, ItemID, hostID, channel, name, id, message); |
803 | message, 0); | ||
804 | } | ||
805 | |||
806 | public ListenerInfo(int handle, uint localID, UUID ItemID, | ||
807 | UUID hostID, int channel, string name, UUID id, | ||
808 | string message, int regexBitfield) | ||
809 | { | ||
810 | Initialise(handle, localID, ItemID, hostID, channel, name, id, | ||
811 | message, regexBitfield); | ||
812 | } | 735 | } |
813 | 736 | ||
814 | public ListenerInfo(ListenerInfo li, string name, UUID id, string message) | 737 | public ListenerInfo(ListenerInfo li, string name, UUID id, string message) |
815 | { | 738 | { |
816 | Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID, li.m_channel, name, id, message, 0); | 739 | Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID, li.m_channel, name, id, message); |
817 | } | ||
818 | |||
819 | public ListenerInfo(ListenerInfo li, string name, UUID id, string message, int regexBitfield) | ||
820 | { | ||
821 | Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID, li.m_channel, name, id, message, regexBitfield); | ||
822 | } | 740 | } |
823 | 741 | ||
824 | private void Initialise(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, UUID id, string message, int regexBitfield) | 742 | private void Initialise(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, |
743 | UUID id, string message) | ||
825 | { | 744 | { |
826 | m_active = true; | 745 | m_active = true; |
827 | m_handle = handle; | 746 | m_handle = handle; |
@@ -832,12 +751,11 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm | |||
832 | m_name = name; | 751 | m_name = name; |
833 | m_id = id; | 752 | m_id = id; |
834 | m_message = message; | 753 | m_message = message; |
835 | RegexBitfield = regexBitfield; | ||
836 | } | 754 | } |
837 | 755 | ||
838 | public Object[] GetSerializationData() | 756 | public Object[] GetSerializationData() |
839 | { | 757 | { |
840 | Object[] data = new Object[7]; | 758 | Object[] data = new Object[6]; |
841 | 759 | ||
842 | data[0] = m_active; | 760 | data[0] = m_active; |
843 | data[1] = m_handle; | 761 | data[1] = m_handle; |
@@ -845,19 +763,16 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm | |||
845 | data[3] = m_name; | 763 | data[3] = m_name; |
846 | data[4] = m_id; | 764 | data[4] = m_id; |
847 | data[5] = m_message; | 765 | data[5] = m_message; |
848 | data[6] = RegexBitfield; | ||
849 | 766 | ||
850 | return data; | 767 | return data; |
851 | } | 768 | } |
852 | 769 | ||
853 | public static ListenerInfo FromData(uint localID, UUID ItemID, UUID hostID, Object[] data) | 770 | public static ListenerInfo FromData(uint localID, UUID ItemID, UUID hostID, Object[] data) |
854 | { | 771 | { |
855 | ListenerInfo linfo = new ListenerInfo((int)data[1], localID, ItemID, hostID, (int)data[2], (string)data[3], (UUID)data[4], (string)data[5]); | 772 | ListenerInfo linfo = new ListenerInfo((int)data[1], localID, |
856 | linfo.m_active = (bool)data[0]; | 773 | ItemID, hostID, (int)data[2], (string)data[3], |
857 | if (data.Length >= 7) | 774 | (UUID)data[4], (string)data[5]); |
858 | { | 775 | linfo.m_active=(bool)data[0]; |
859 | linfo.RegexBitfield = (int)data[6]; | ||
860 | } | ||
861 | 776 | ||
862 | return linfo; | 777 | return linfo; |
863 | } | 778 | } |
@@ -916,7 +831,5 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm | |||
916 | { | 831 | { |
917 | return m_id; | 832 | return m_id; |
918 | } | 833 | } |
919 | |||
920 | public int RegexBitfield { get; private set; } | ||
921 | } | 834 | } |
922 | } | 835 | } |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs index 1e1c7d0..008465f 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs | |||
@@ -56,8 +56,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset | |||
56 | 56 | ||
57 | private bool m_Enabled = false; | 57 | private bool m_Enabled = false; |
58 | 58 | ||
59 | private AssetPermissions m_AssetPerms; | ||
60 | |||
61 | public Type ReplaceableInterface | 59 | public Type ReplaceableInterface |
62 | { | 60 | { |
63 | get { return null; } | 61 | get { return null; } |
@@ -130,9 +128,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset | |||
130 | if (m_LocalAssetServiceURI != string.Empty) | 128 | if (m_LocalAssetServiceURI != string.Empty) |
131 | m_LocalAssetServiceURI = m_LocalAssetServiceURI.Trim('/'); | 129 | m_LocalAssetServiceURI = m_LocalAssetServiceURI.Trim('/'); |
132 | 130 | ||
133 | IConfig hgConfig = source.Configs["HGAssetService"]; | ||
134 | m_AssetPerms = new AssetPermissions(hgConfig); // it's ok if arg is null | ||
135 | |||
136 | m_Enabled = true; | 131 | m_Enabled = true; |
137 | m_log.Info("[HG ASSET CONNECTOR]: HG asset broker enabled"); | 132 | m_log.Info("[HG ASSET CONNECTOR]: HG asset broker enabled"); |
138 | } | 133 | } |
@@ -211,11 +206,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset | |||
211 | asset = m_HGService.Get(id); | 206 | asset = m_HGService.Get(id); |
212 | if (asset != null) | 207 | if (asset != null) |
213 | { | 208 | { |
214 | // Now store it locally, if allowed | 209 | // Now store it locally |
215 | if (m_AssetPerms.AllowedImport(asset.Type)) | 210 | // For now, let me just do it for textures and scripts |
211 | if (((AssetType)asset.Type == AssetType.Texture) || | ||
212 | ((AssetType)asset.Type == AssetType.LSLBytecode) || | ||
213 | ((AssetType)asset.Type == AssetType.LSLText)) | ||
214 | { | ||
216 | m_GridService.Store(asset); | 215 | m_GridService.Store(asset); |
217 | else | 216 | } |
218 | return null; | ||
219 | } | 217 | } |
220 | } | 218 | } |
221 | else | 219 | else |
@@ -330,12 +328,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset | |||
330 | 328 | ||
331 | string id = string.Empty; | 329 | string id = string.Empty; |
332 | if (IsHG(asset.ID)) | 330 | if (IsHG(asset.ID)) |
333 | { | 331 | id = m_HGService.Store(asset); |
334 | if (m_AssetPerms.AllowedExport(asset.Type)) | ||
335 | id = m_HGService.Store(asset); | ||
336 | else | ||
337 | return String.Empty; | ||
338 | } | ||
339 | else | 332 | else |
340 | id = m_GridService.Store(asset); | 333 | id = m_GridService.Store(asset); |
341 | 334 | ||
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs index 449c1f1..c78915f 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs | |||
@@ -204,11 +204,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset | |||
204 | public byte[] GetData(string id) | 204 | public byte[] GetData(string id) |
205 | { | 205 | { |
206 | // m_log.DebugFormat("[LOCAL ASSET SERVICES CONNECTOR]: Requesting data for asset {0}", id); | 206 | // m_log.DebugFormat("[LOCAL ASSET SERVICES CONNECTOR]: Requesting data for asset {0}", id); |
207 | 207 | ||
208 | AssetBase asset = null; | 208 | AssetBase asset = m_Cache.Get(id); |
209 | |||
210 | if (m_Cache != null) | ||
211 | asset = m_Cache.Get(id); | ||
212 | 209 | ||
213 | if (asset != null) | 210 | if (asset != null) |
214 | return asset.Data; | 211 | return asset.Data; |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/Tests/AssetConnectorTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/Tests/AssetConnectorTests.cs deleted file mode 100644 index 1982473..0000000 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/Tests/AssetConnectorTests.cs +++ /dev/null | |||
@@ -1,136 +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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.IO; | ||
31 | using System.Reflection; | ||
32 | using System.Threading; | ||
33 | using log4net.Config; | ||
34 | using Nini.Config; | ||
35 | using NUnit.Framework; | ||
36 | using OpenMetaverse; | ||
37 | using OpenSim.Framework; | ||
38 | using OpenSim.Region.Framework.Scenes; | ||
39 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset; | ||
40 | using OpenSim.Tests.Common; | ||
41 | |||
42 | namespace 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/Grid/Tests/GridConnectorsTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs index 4338133..b286d17 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs | |||
@@ -43,15 +43,11 @@ using OpenSim.Tests.Common; | |||
43 | namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests | 43 | namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests |
44 | { | 44 | { |
45 | [TestFixture] | 45 | [TestFixture] |
46 | public class GridConnectorsTests : OpenSimTestCase | 46 | public class GridConnectorsTests |
47 | { | 47 | { |
48 | LocalGridServicesConnector m_LocalConnector; | 48 | LocalGridServicesConnector m_LocalConnector; |
49 | 49 | private void SetUp() | |
50 | [SetUp] | ||
51 | public override void SetUp() | ||
52 | { | 50 | { |
53 | base.SetUp(); | ||
54 | |||
55 | IConfigSource config = new IniConfigSource(); | 51 | IConfigSource config = new IniConfigSource(); |
56 | config.AddConfig("Modules"); | 52 | config.AddConfig("Modules"); |
57 | config.AddConfig("GridService"); | 53 | config.AddConfig("GridService"); |
@@ -75,6 +71,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests | |||
75 | TestHelpers.InMethod(); | 71 | TestHelpers.InMethod(); |
76 | // log4net.Config.XmlConfigurator.Configure(); | 72 | // log4net.Config.XmlConfigurator.Configure(); |
77 | 73 | ||
74 | SetUp(); | ||
75 | |||
78 | // Create 4 regions | 76 | // Create 4 regions |
79 | GridRegion r1 = new GridRegion(); | 77 | GridRegion r1 = new GridRegion(); |
80 | r1.RegionName = "Test Region 1"; | 78 | r1.RegionName = "Test Region 1"; |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs index 221f815..b0edce7 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs | |||
@@ -65,13 +65,11 @@ 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 | |||
68 | if (sp.PresenceType != PresenceType.Npc) | 70 | 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); | ||
72 | m_GridUserService.SetLastPosition( | 71 | m_GridUserService.SetLastPosition( |
73 | userid, UUID.Zero, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); | 72 | sp.UUID.ToString(), UUID.Zero, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); |
74 | } | ||
75 | } | 73 | } |
76 | 74 | ||
77 | public void OnNewClient(IClientAPI client) | 75 | public void OnNewClient(IClientAPI client) |
@@ -84,16 +82,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser | |||
84 | if (client.SceneAgent.IsChildAgent) | 82 | if (client.SceneAgent.IsChildAgent) |
85 | return; | 83 | return; |
86 | 84 | ||
87 | string userId = client.AgentId.ToString(); | 85 | // m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); |
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 | |||
95 | m_GridUserService.LoggedOut( | 86 | m_GridUserService.LoggedOut( |
96 | userId, client.SessionId, client.Scene.RegionInfo.RegionID, | 87 | client.AgentId.ToString(), client.SessionId, client.Scene.RegionInfo.RegionID, |
97 | client.SceneAgent.AbsolutePosition, client.SceneAgent.Lookat); | 88 | client.SceneAgent.AbsolutePosition, client.SceneAgent.Lookat); |
98 | } | 89 | } |
99 | } | 90 | } |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/RemoteGridUserServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/RemoteGridUserServiceConnector.cs index 04acf67..badb552 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/RemoteGridUserServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/RemoteGridUserServiceConnector.cs | |||
@@ -44,9 +44,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser | |||
44 | { | 44 | { |
45 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 45 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
46 | 46 | ||
47 | private const int KEEPTIME = 30; // 30 secs | ||
48 | private ExpiringCache<string, GridUserInfo> m_Infos = new ExpiringCache<string, GridUserInfo>(); | ||
49 | |||
50 | #region ISharedRegionModule | 47 | #region ISharedRegionModule |
51 | 48 | ||
52 | private bool m_Enabled = false; | 49 | private bool m_Enabled = false; |
@@ -131,60 +128,23 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser | |||
131 | 128 | ||
132 | public bool LoggedOut(string userID, UUID sessionID, UUID region, Vector3 position, Vector3 lookat) | 129 | public bool LoggedOut(string userID, UUID sessionID, UUID region, Vector3 position, Vector3 lookat) |
133 | { | 130 | { |
134 | if (m_Infos.Contains(userID)) | ||
135 | m_Infos.Remove(userID); | ||
136 | |||
137 | return m_RemoteConnector.LoggedOut(userID, sessionID, region, position, lookat); | 131 | return m_RemoteConnector.LoggedOut(userID, sessionID, region, position, lookat); |
138 | } | 132 | } |
139 | 133 | ||
140 | 134 | ||
141 | public bool SetHome(string userID, UUID regionID, Vector3 position, Vector3 lookAt) | 135 | public bool SetHome(string userID, UUID regionID, Vector3 position, Vector3 lookAt) |
142 | { | 136 | { |
143 | if (m_RemoteConnector.SetHome(userID, regionID, position, lookAt)) | 137 | return m_RemoteConnector.SetHome(userID, regionID, position, lookAt); |
144 | { | ||
145 | // Update the cache too | ||
146 | GridUserInfo info = null; | ||
147 | if (m_Infos.TryGetValue(userID, out info)) | ||
148 | { | ||
149 | info.HomeRegionID = regionID; | ||
150 | info.HomePosition = position; | ||
151 | info.HomeLookAt = lookAt; | ||
152 | } | ||
153 | return true; | ||
154 | } | ||
155 | |||
156 | return false; | ||
157 | } | 138 | } |
158 | 139 | ||
159 | public bool SetLastPosition(string userID, UUID sessionID, UUID regionID, Vector3 position, Vector3 lookAt) | 140 | public bool SetLastPosition(string userID, UUID sessionID, UUID regionID, Vector3 position, Vector3 lookAt) |
160 | { | 141 | { |
161 | if (m_RemoteConnector.SetLastPosition(userID, sessionID, regionID, position, lookAt)) | 142 | return m_RemoteConnector.SetLastPosition(userID, sessionID, regionID, position, lookAt); |
162 | { | ||
163 | // Update the cache too | ||
164 | GridUserInfo info = null; | ||
165 | if (m_Infos.TryGetValue(userID, out info)) | ||
166 | { | ||
167 | info.LastRegionID = regionID; | ||
168 | info.LastPosition = position; | ||
169 | info.LastLookAt = lookAt; | ||
170 | } | ||
171 | return true; | ||
172 | } | ||
173 | |||
174 | return false; | ||
175 | } | 143 | } |
176 | 144 | ||
177 | public GridUserInfo GetGridUserInfo(string userID) | 145 | public GridUserInfo GetGridUserInfo(string userID) |
178 | { | 146 | { |
179 | GridUserInfo info = null; | 147 | return m_RemoteConnector.GetGridUserInfo(userID); |
180 | if (m_Infos.TryGetValue(userID, out info)) | ||
181 | return info; | ||
182 | |||
183 | info = m_RemoteConnector.GetGridUserInfo(userID); | ||
184 | |||
185 | m_Infos.AddOrUpdate(userID, info, KEEPTIME); | ||
186 | |||
187 | return info; | ||
188 | } | 148 | } |
189 | 149 | ||
190 | public GridUserInfo[] GetGridUserInfo(string[] userID) | 150 | public GridUserInfo[] GetGridUserInfo(string[] userID) |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs index 8ed1833..6eb99ea 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs | |||
@@ -313,11 +313,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
313 | 313 | ||
314 | if (m_scenes.ContainsKey(destination.RegionID)) | 314 | if (m_scenes.ContainsKey(destination.RegionID)) |
315 | { | 315 | { |
316 | // m_log.DebugFormat( | 316 | Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id); }); |
317 | // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", | ||
318 | // s.RegionInfo.RegionName, destination.RegionHandle); | ||
319 | |||
320 | Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id, false); }); | ||
321 | return true; | 317 | return true; |
322 | } | 318 | } |
323 | //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); | 319 | //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index ade5e76..619550c 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs | |||
@@ -43,7 +43,6 @@ using OpenSim.Region.Framework.Interfaces; | |||
43 | using OpenSim.Region.Framework.Scenes; | 43 | using OpenSim.Region.Framework.Scenes; |
44 | using OpenSim.Region.Framework.Scenes.Serialization; | 44 | using OpenSim.Region.Framework.Scenes.Serialization; |
45 | using OpenSim.Services.Interfaces; | 45 | using OpenSim.Services.Interfaces; |
46 | using System.Threading; | ||
47 | 46 | ||
48 | namespace OpenSim.Region.CoreModules.World.Archiver | 47 | namespace OpenSim.Region.CoreModules.World.Archiver |
49 | { | 48 | { |
@@ -53,30 +52,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
53 | public class ArchiveReadRequest | 52 | public class ArchiveReadRequest |
54 | { | 53 | { |
55 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 54 | 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 | } | ||
78 | 55 | ||
79 | |||
80 | /// <summary> | 56 | /// <summary> |
81 | /// The maximum major version of OAR that we can read. Minor versions shouldn't need a max number since version | 57 | /// The maximum major version of OAR that we can read. Minor versions shouldn't need a max number since version |
82 | /// bumps here should be compatible. | 58 | /// bumps here should be compatible. |
@@ -86,10 +62,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
86 | /// <summary> | 62 | /// <summary> |
87 | /// Has the control file been loaded for this archive? | 63 | /// Has the control file been loaded for this archive? |
88 | /// </summary> | 64 | /// </summary> |
89 | public bool ControlFileLoaded { get; private set; } | 65 | public bool ControlFileLoaded { get; private set; } |
90 | 66 | ||
91 | protected string m_loadPath; | 67 | protected Scene m_scene; |
92 | protected Scene m_rootScene; | ||
93 | protected Stream m_loadStream; | 68 | protected Stream m_loadStream; |
94 | protected Guid m_requestId; | 69 | protected Guid m_requestId; |
95 | protected string m_errorMessage; | 70 | protected string m_errorMessage; |
@@ -116,27 +91,16 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
116 | { | 91 | { |
117 | if (m_UserMan == null) | 92 | if (m_UserMan == null) |
118 | { | 93 | { |
119 | m_UserMan = m_rootScene.RequestModuleInterface<IUserManagement>(); | 94 | m_UserMan = m_scene.RequestModuleInterface<IUserManagement>(); |
120 | } | 95 | } |
121 | return m_UserMan; | 96 | return m_UserMan; |
122 | } | 97 | } |
123 | } | 98 | } |
124 | 99 | ||
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 | |||
135 | public ArchiveReadRequest(Scene scene, string loadPath, bool merge, bool skipAssets, Guid requestId) | 100 | public ArchiveReadRequest(Scene scene, string loadPath, bool merge, bool skipAssets, Guid requestId) |
136 | { | 101 | { |
137 | m_rootScene = scene; | 102 | m_scene = scene; |
138 | 103 | ||
139 | m_loadPath = loadPath; | ||
140 | try | 104 | try |
141 | { | 105 | { |
142 | m_loadStream = new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress); | 106 | m_loadStream = new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress); |
@@ -156,15 +120,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
156 | 120 | ||
157 | // Zero can never be a valid user id | 121 | // Zero can never be a valid user id |
158 | m_validUserUuids[UUID.Zero] = false; | 122 | m_validUserUuids[UUID.Zero] = false; |
159 | |||
160 | m_groupsModule = m_rootScene.RequestModuleInterface<IGroupsModule>(); | ||
161 | m_assetService = m_rootScene.AssetService; | ||
162 | } | 123 | } |
163 | 124 | ||
164 | public ArchiveReadRequest(Scene scene, Stream loadStream, bool merge, bool skipAssets, Guid requestId) | 125 | public ArchiveReadRequest(Scene scene, Stream loadStream, bool merge, bool skipAssets, Guid requestId) |
165 | { | 126 | { |
166 | m_rootScene = scene; | 127 | m_scene = scene; |
167 | m_loadPath = null; | ||
168 | m_loadStream = loadStream; | 128 | m_loadStream = loadStream; |
169 | m_merge = merge; | 129 | m_merge = merge; |
170 | m_skipAssets = skipAssets; | 130 | m_skipAssets = skipAssets; |
@@ -172,9 +132,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
172 | 132 | ||
173 | // Zero can never be a valid user id | 133 | // Zero can never be a valid user id |
174 | m_validUserUuids[UUID.Zero] = false; | 134 | m_validUserUuids[UUID.Zero] = false; |
175 | |||
176 | m_groupsModule = m_rootScene.RequestModuleInterface<IGroupsModule>(); | ||
177 | m_assetService = m_rootScene.AssetService; | ||
178 | } | 135 | } |
179 | 136 | ||
180 | /// <summary> | 137 | /// <summary> |
@@ -182,25 +139,25 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
182 | /// </summary> | 139 | /// </summary> |
183 | public void DearchiveRegion() | 140 | public void DearchiveRegion() |
184 | { | 141 | { |
142 | // The same code can handle dearchiving 0.1 and 0.2 OpenSim Archive versions | ||
143 | DearchiveRegion0DotStar(); | ||
144 | } | ||
145 | |||
146 | private void DearchiveRegion0DotStar() | ||
147 | { | ||
185 | int successfulAssetRestores = 0; | 148 | int successfulAssetRestores = 0; |
186 | int failedAssetRestores = 0; | 149 | int failedAssetRestores = 0; |
150 | List<string> serialisedSceneObjects = new List<string>(); | ||
151 | List<string> serialisedParcels = new List<string>(); | ||
152 | string filePath = "NONE"; | ||
187 | 153 | ||
188 | DearchiveScenesInfo dearchivedScenes; | 154 | TarArchiveReader archive = new TarArchiveReader(m_loadStream); |
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; | ||
196 | byte[] data; | 155 | byte[] data; |
197 | TarArchiveReader.TarEntryType entryType; | 156 | TarArchiveReader.TarEntryType entryType; |
198 | 157 | ||
199 | try | 158 | try |
200 | { | 159 | { |
201 | FindAndLoadControlFile(out archive, out dearchivedScenes); | 160 | while ((data = archive.ReadEntry(out filePath, out entryType)) != null) |
202 | |||
203 | while ((data = archive.ReadEntry(out fullPath, out entryType)) != null) | ||
204 | { | 161 | { |
205 | //m_log.DebugFormat( | 162 | //m_log.DebugFormat( |
206 | // "[ARCHIVER]: Successfully read {0} ({1} bytes)", filePath, data.Length); | 163 | // "[ARCHIVER]: Successfully read {0} ({1} bytes)", filePath, data.Length); |
@@ -208,30 +165,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
208 | if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType) | 165 | if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType) |
209 | continue; | 166 | continue; |
210 | 167 | ||
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 | |||
232 | if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH)) | 168 | if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH)) |
233 | { | 169 | { |
234 | sceneContext.SerialisedSceneObjects.Add(Encoding.UTF8.GetString(data)); | 170 | serialisedSceneObjects.Add(Encoding.UTF8.GetString(data)); |
235 | } | 171 | } |
236 | else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH) && !m_skipAssets) | 172 | else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH) && !m_skipAssets) |
237 | { | 173 | { |
@@ -245,19 +181,19 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
245 | } | 181 | } |
246 | else if (!m_merge && filePath.StartsWith(ArchiveConstants.TERRAINS_PATH)) | 182 | else if (!m_merge && filePath.StartsWith(ArchiveConstants.TERRAINS_PATH)) |
247 | { | 183 | { |
248 | LoadTerrain(scene, filePath, data); | 184 | LoadTerrain(filePath, data); |
249 | } | 185 | } |
250 | else if (!m_merge && filePath.StartsWith(ArchiveConstants.SETTINGS_PATH)) | 186 | else if (!m_merge && filePath.StartsWith(ArchiveConstants.SETTINGS_PATH)) |
251 | { | 187 | { |
252 | LoadRegionSettings(scene, filePath, data, dearchivedScenes); | 188 | LoadRegionSettings(filePath, data); |
253 | } | 189 | } |
254 | else if (!m_merge && filePath.StartsWith(ArchiveConstants.LANDDATA_PATH)) | 190 | else if (!m_merge && filePath.StartsWith(ArchiveConstants.LANDDATA_PATH)) |
255 | { | 191 | { |
256 | sceneContext.SerialisedParcels.Add(Encoding.UTF8.GetString(data)); | 192 | serialisedParcels.Add(Encoding.UTF8.GetString(data)); |
257 | } | 193 | } |
258 | else if (filePath == ArchiveConstants.CONTROL_FILE_PATH) | 194 | else if (filePath == ArchiveConstants.CONTROL_FILE_PATH) |
259 | { | 195 | { |
260 | // Ignore, because we already read the control file | 196 | LoadControlFile(filePath, data); |
261 | } | 197 | } |
262 | } | 198 | } |
263 | 199 | ||
@@ -265,16 +201,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
265 | } | 201 | } |
266 | catch (Exception e) | 202 | catch (Exception e) |
267 | { | 203 | { |
268 | m_log.Error( | 204 | m_log.ErrorFormat( |
269 | String.Format("[ARCHIVER]: Aborting load with error in archive file {0} ", fullPath), e); | 205 | "[ARCHIVER]: Aborting load with error in archive file {0}. {1}", filePath, e); |
270 | m_errorMessage += e.ToString(); | 206 | m_errorMessage += e.ToString(); |
271 | m_rootScene.EventManager.TriggerOarFileLoaded(m_requestId, new List<UUID>(), m_errorMessage); | 207 | m_scene.EventManager.TriggerOarFileLoaded(m_requestId, m_errorMessage); |
272 | return; | 208 | return; |
273 | } | 209 | } |
274 | finally | 210 | finally |
275 | { | 211 | { |
276 | if (archive != null) | 212 | archive.Close(); |
277 | archive.Close(); | ||
278 | } | 213 | } |
279 | 214 | ||
280 | if (!m_skipAssets) | 215 | if (!m_skipAssets) |
@@ -288,143 +223,32 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
288 | } | 223 | } |
289 | } | 224 | } |
290 | 225 | ||
291 | foreach (DearchiveContext sceneContext in sceneContexts.Values) | 226 | if (!m_merge) |
292 | { | 227 | { |
293 | m_log.InfoFormat("[ARCHIVER]: Loading region {0}", sceneContext.Scene.RegionInfo.RegionName); | 228 | m_log.Info("[ARCHIVER]: Clearing all existing scene objects"); |
294 | 229 | m_scene.DeleteAllSceneObjects(); | |
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 | } | ||
319 | } | 230 | } |
320 | 231 | ||
321 | // Start the scripts. We delayed this because we want the OAR to finish loading ASAP, so | 232 | LoadParcels(serialisedParcels); |
322 | // that users can enter the scene. If we allow the scripts to start in the loop above | 233 | LoadObjects(serialisedSceneObjects); |
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 | }); | ||
340 | 234 | ||
341 | m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive"); | 235 | m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive"); |
342 | 236 | ||
343 | m_rootScene.EventManager.TriggerOarFileLoaded(m_requestId, dearchivedScenes.GetLoadedScenes(), m_errorMessage); | 237 | m_scene.EventManager.TriggerOarFileLoaded(m_requestId, 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"); | ||
415 | } | 238 | } |
416 | 239 | ||
417 | /// <summary> | 240 | /// <summary> |
418 | /// Load serialized scene objects. | 241 | /// Load serialized scene objects. |
419 | /// </summary> | 242 | /// </summary> |
420 | protected void LoadObjects(Scene scene, List<string> serialisedSceneObjects, List<SceneObjectGroup> sceneObjects) | 243 | /// <param name="serialisedSceneObjects"></param> |
244 | protected void LoadObjects(List<string> serialisedSceneObjects) | ||
421 | { | 245 | { |
422 | // Reload serialized prims | 246 | // Reload serialized prims |
423 | m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count); | 247 | m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count); |
424 | 248 | ||
425 | UUID oldTelehubUUID = scene.RegionInfo.RegionSettings.TelehubObject; | 249 | UUID oldTelehubUUID = m_scene.RegionInfo.RegionSettings.TelehubObject; |
426 | 250 | ||
427 | IRegionSerialiserModule serialiser = scene.RequestModuleInterface<IRegionSerialiserModule>(); | 251 | IRegionSerialiserModule serialiser = m_scene.RequestModuleInterface<IRegionSerialiserModule>(); |
428 | int sceneObjectsLoadedCount = 0; | 252 | int sceneObjectsLoadedCount = 0; |
429 | 253 | ||
430 | foreach (string serialisedSceneObject in serialisedSceneObjects) | 254 | foreach (string serialisedSceneObject in serialisedSceneObjects) |
@@ -445,7 +269,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
445 | 269 | ||
446 | SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); | 270 | SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); |
447 | 271 | ||
448 | bool isTelehub = (sceneObject.UUID == oldTelehubUUID) && (oldTelehubUUID != UUID.Zero); | 272 | bool isTelehub = (sceneObject.UUID == oldTelehubUUID); |
449 | 273 | ||
450 | // For now, give all incoming scene objects new uuids. This will allow scenes to be cloned | 274 | // For now, give all incoming scene objects new uuids. This will allow scenes to be cloned |
451 | // on the same region server and multiple examples a single object archive to be imported | 275 | // on the same region server and multiple examples a single object archive to be imported |
@@ -455,8 +279,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
455 | if (isTelehub) | 279 | if (isTelehub) |
456 | { | 280 | { |
457 | // Change the Telehub Object to the new UUID | 281 | // Change the Telehub Object to the new UUID |
458 | scene.RegionInfo.RegionSettings.TelehubObject = sceneObject.UUID; | 282 | m_scene.RegionInfo.RegionSettings.TelehubObject = sceneObject.UUID; |
459 | scene.RegionInfo.RegionSettings.Save(); | 283 | m_scene.RegionInfo.RegionSettings.Save(); |
460 | oldTelehubUUID = UUID.Zero; | 284 | oldTelehubUUID = UUID.Zero; |
461 | } | 285 | } |
462 | 286 | ||
@@ -466,20 +290,17 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
466 | { | 290 | { |
467 | if (part.CreatorData == null || part.CreatorData == string.Empty) | 291 | if (part.CreatorData == null || part.CreatorData == string.Empty) |
468 | { | 292 | { |
469 | if (!ResolveUserUuid(scene, part.CreatorID)) | 293 | if (!ResolveUserUuid(part.CreatorID)) |
470 | part.CreatorID = scene.RegionInfo.EstateSettings.EstateOwner; | 294 | part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; |
471 | } | 295 | } |
472 | if (UserManager != null) | 296 | if (UserManager != null) |
473 | UserManager.AddUser(part.CreatorID, part.CreatorData); | 297 | UserManager.AddUser(part.CreatorID, part.CreatorData); |
474 | 298 | ||
475 | if (!ResolveUserUuid(scene, part.OwnerID)) | 299 | if (!ResolveUserUuid(part.OwnerID)) |
476 | part.OwnerID = scene.RegionInfo.EstateSettings.EstateOwner; | 300 | part.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; |
477 | |||
478 | if (!ResolveUserUuid(scene, part.LastOwnerID)) | ||
479 | part.LastOwnerID = scene.RegionInfo.EstateSettings.EstateOwner; | ||
480 | 301 | ||
481 | if (!ResolveGroupUuid(part.GroupID)) | 302 | if (!ResolveUserUuid(part.LastOwnerID)) |
482 | part.GroupID = UUID.Zero; | 303 | part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; |
483 | 304 | ||
484 | // And zap any troublesome sit target information | 305 | // And zap any troublesome sit target information |
485 | // part.SitTargetOrientation = new Quaternion(0, 0, 0, 1); | 306 | // part.SitTargetOrientation = new Quaternion(0, 0, 0, 1); |
@@ -490,14 +311,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
490 | // being no copy/no mod for everyone | 311 | // being no copy/no mod for everyone |
491 | lock (part.TaskInventory) | 312 | lock (part.TaskInventory) |
492 | { | 313 | { |
493 | if (!ResolveUserUuid(scene, part.CreatorID)) | 314 | if (!ResolveUserUuid(part.CreatorID)) |
494 | part.CreatorID = scene.RegionInfo.EstateSettings.EstateOwner; | 315 | part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; |
495 | 316 | ||
496 | if (!ResolveUserUuid(scene, part.OwnerID)) | 317 | if (!ResolveUserUuid(part.OwnerID)) |
497 | part.OwnerID = scene.RegionInfo.EstateSettings.EstateOwner; | 318 | part.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; |
498 | 319 | ||
499 | if (!ResolveUserUuid(scene, part.LastOwnerID)) | 320 | if (!ResolveUserUuid(part.LastOwnerID)) |
500 | part.LastOwnerID = scene.RegionInfo.EstateSettings.EstateOwner; | 321 | part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; |
501 | 322 | ||
502 | // And zap any troublesome sit target information | 323 | // And zap any troublesome sit target information |
503 | part.SitTargetOrientation = new Quaternion(0, 0, 0, 1); | 324 | part.SitTargetOrientation = new Quaternion(0, 0, 0, 1); |
@@ -510,31 +331,26 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
510 | TaskInventoryDictionary inv = part.TaskInventory; | 331 | TaskInventoryDictionary inv = part.TaskInventory; |
511 | foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv) | 332 | foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv) |
512 | { | 333 | { |
513 | if (!ResolveUserUuid(scene, kvp.Value.OwnerID)) | 334 | if (!ResolveUserUuid(kvp.Value.OwnerID)) |
514 | { | 335 | { |
515 | kvp.Value.OwnerID = scene.RegionInfo.EstateSettings.EstateOwner; | 336 | kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; |
516 | } | 337 | } |
517 | |||
518 | if (kvp.Value.CreatorData == null || kvp.Value.CreatorData == string.Empty) | 338 | if (kvp.Value.CreatorData == null || kvp.Value.CreatorData == string.Empty) |
519 | { | 339 | { |
520 | if (!ResolveUserUuid(scene, kvp.Value.CreatorID)) | 340 | if (!ResolveUserUuid(kvp.Value.CreatorID)) |
521 | kvp.Value.CreatorID = scene.RegionInfo.EstateSettings.EstateOwner; | 341 | kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; |
522 | } | 342 | } |
523 | |||
524 | if (UserManager != null) | 343 | if (UserManager != null) |
525 | UserManager.AddUser(kvp.Value.CreatorID, kvp.Value.CreatorData); | 344 | UserManager.AddUser(kvp.Value.CreatorID, kvp.Value.CreatorData); |
526 | |||
527 | if (!ResolveGroupUuid(kvp.Value.GroupID)) | ||
528 | kvp.Value.GroupID = UUID.Zero; | ||
529 | } | 345 | } |
530 | part.TaskInventory.LockItemsForRead(false); | 346 | part.TaskInventory.LockItemsForRead(false); |
531 | } | 347 | } |
532 | } | 348 | } |
533 | 349 | ||
534 | if (scene.AddRestoredSceneObject(sceneObject, true, false)) | 350 | if (m_scene.AddRestoredSceneObject(sceneObject, true, false)) |
535 | { | 351 | { |
536 | sceneObjectsLoadedCount++; | 352 | sceneObjectsLoadedCount++; |
537 | sceneObject.CreateScriptInstances(0, false, scene.DefaultScriptEngine, 0); | 353 | sceneObject.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, 0); |
538 | sceneObject.ResumeScripts(); | 354 | sceneObject.ResumeScripts(); |
539 | } | 355 | } |
540 | } | 356 | } |
@@ -549,17 +365,16 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
549 | if (oldTelehubUUID != UUID.Zero) | 365 | if (oldTelehubUUID != UUID.Zero) |
550 | { | 366 | { |
551 | m_log.WarnFormat("Telehub object not found: {0}", oldTelehubUUID); | 367 | m_log.WarnFormat("Telehub object not found: {0}", oldTelehubUUID); |
552 | scene.RegionInfo.RegionSettings.TelehubObject = UUID.Zero; | 368 | m_scene.RegionInfo.RegionSettings.TelehubObject = UUID.Zero; |
553 | scene.RegionInfo.RegionSettings.ClearSpawnPoints(); | 369 | m_scene.RegionInfo.RegionSettings.ClearSpawnPoints(); |
554 | } | 370 | } |
555 | } | 371 | } |
556 | 372 | ||
557 | /// <summary> | 373 | /// <summary> |
558 | /// Load serialized parcels. | 374 | /// Load serialized parcels. |
559 | /// </summary> | 375 | /// </summary> |
560 | /// <param name="scene"></param> | ||
561 | /// <param name="serialisedParcels"></param> | 376 | /// <param name="serialisedParcels"></param> |
562 | protected void LoadParcels(Scene scene, List<string> serialisedParcels) | 377 | protected void LoadParcels(List<string> serialisedParcels) |
563 | { | 378 | { |
564 | // Reload serialized parcels | 379 | // Reload serialized parcels |
565 | m_log.InfoFormat("[ARCHIVER]: Loading {0} parcels. Please wait.", serialisedParcels.Count); | 380 | m_log.InfoFormat("[ARCHIVER]: Loading {0} parcels. Please wait.", serialisedParcels.Count); |
@@ -567,27 +382,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
567 | foreach (string serialisedParcel in serialisedParcels) | 382 | foreach (string serialisedParcel in serialisedParcels) |
568 | { | 383 | { |
569 | LandData parcel = LandDataSerializer.Deserialize(serialisedParcel); | 384 | LandData parcel = LandDataSerializer.Deserialize(serialisedParcel); |
385 | if (!ResolveUserUuid(parcel.OwnerID)) | ||
386 | parcel.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | ||
570 | 387 | ||
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 | |||
591 | // m_log.DebugFormat( | 388 | // m_log.DebugFormat( |
592 | // "[ARCHIVER]: Adding parcel {0}, local id {1}, area {2}", | 389 | // "[ARCHIVER]: Adding parcel {0}, local id {1}, area {2}", |
593 | // parcel.Name, parcel.LocalID, parcel.Area); | 390 | // parcel.Name, parcel.LocalID, parcel.Area); |
@@ -598,24 +395,23 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
598 | if (!m_merge) | 395 | if (!m_merge) |
599 | { | 396 | { |
600 | bool setupDefaultParcel = (landData.Count == 0); | 397 | bool setupDefaultParcel = (landData.Count == 0); |
601 | scene.LandChannel.Clear(setupDefaultParcel); | 398 | m_scene.LandChannel.Clear(setupDefaultParcel); |
602 | } | 399 | } |
603 | 400 | ||
604 | scene.EventManager.TriggerIncomingLandDataFromStorage(landData); | 401 | m_scene.EventManager.TriggerIncomingLandDataFromStorage(landData); |
605 | m_log.InfoFormat("[ARCHIVER]: Restored {0} parcels.", landData.Count); | 402 | m_log.InfoFormat("[ARCHIVER]: Restored {0} parcels.", landData.Count); |
606 | } | 403 | } |
607 | 404 | ||
608 | /// <summary> | 405 | /// <summary> |
609 | /// Look up the given user id to check whether it's one that is valid for this grid. | 406 | /// Look up the given user id to check whether it's one that is valid for this grid. |
610 | /// </summary> | 407 | /// </summary> |
611 | /// <param name="scene"></param> | ||
612 | /// <param name="uuid"></param> | 408 | /// <param name="uuid"></param> |
613 | /// <returns></returns> | 409 | /// <returns></returns> |
614 | private bool ResolveUserUuid(Scene scene, UUID uuid) | 410 | private bool ResolveUserUuid(UUID uuid) |
615 | { | 411 | { |
616 | if (!m_validUserUuids.ContainsKey(uuid)) | 412 | if (!m_validUserUuids.ContainsKey(uuid)) |
617 | { | 413 | { |
618 | UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, uuid); | 414 | UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid); |
619 | m_validUserUuids.Add(uuid, account != null); | 415 | m_validUserUuids.Add(uuid, account != null); |
620 | } | 416 | } |
621 | 417 | ||
@@ -623,30 +419,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
623 | } | 419 | } |
624 | 420 | ||
625 | /// <summary> | 421 | /// <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 | |||
650 | /// Load an asset | 422 | /// Load an asset |
651 | /// </summary> | 423 | /// </summary> |
652 | /// <param name="assetFilename"></param> | 424 | /// <param name="assetFilename"></param> |
@@ -670,7 +442,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
670 | string extension = filename.Substring(i); | 442 | string extension = filename.Substring(i); |
671 | string uuid = filename.Remove(filename.Length - extension.Length); | 443 | string uuid = filename.Remove(filename.Length - extension.Length); |
672 | 444 | ||
673 | if (m_assetService.GetMetadata(uuid) != null) | 445 | if (m_scene.AssetService.GetMetadata(uuid) != null) |
674 | { | 446 | { |
675 | // m_log.DebugFormat("[ARCHIVER]: found existing asset {0}",uuid); | 447 | // m_log.DebugFormat("[ARCHIVER]: found existing asset {0}",uuid); |
676 | return true; | 448 | return true; |
@@ -690,7 +462,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
690 | 462 | ||
691 | // We're relying on the asset service to do the sensible thing and not store the asset if it already | 463 | // We're relying on the asset service to do the sensible thing and not store the asset if it already |
692 | // exists. | 464 | // exists. |
693 | m_assetService.Store(asset); | 465 | m_scene.AssetService.Store(asset); |
694 | 466 | ||
695 | /** | 467 | /** |
696 | * Create layers on decode for image assets. This is likely to significantly increase the time to load archives so | 468 | * Create layers on decode for image assets. This is likely to significantly increase the time to load archives so |
@@ -718,14 +490,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
718 | /// <summary> | 490 | /// <summary> |
719 | /// Load region settings data | 491 | /// Load region settings data |
720 | /// </summary> | 492 | /// </summary> |
721 | /// <param name="scene"></param> | ||
722 | /// <param name="settingsPath"></param> | 493 | /// <param name="settingsPath"></param> |
723 | /// <param name="data"></param> | 494 | /// <param name="data"></param> |
724 | /// <param name="dearchivedScenes"></param> | ||
725 | /// <returns> | 495 | /// <returns> |
726 | /// true if settings were loaded successfully, false otherwise | 496 | /// true if settings were loaded successfully, false otherwise |
727 | /// </returns> | 497 | /// </returns> |
728 | private bool LoadRegionSettings(Scene scene, string settingsPath, byte[] data, DearchiveScenesInfo dearchivedScenes) | 498 | private bool LoadRegionSettings(string settingsPath, byte[] data) |
729 | { | 499 | { |
730 | RegionSettings loadedRegionSettings; | 500 | RegionSettings loadedRegionSettings; |
731 | 501 | ||
@@ -741,7 +511,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
741 | return false; | 511 | return false; |
742 | } | 512 | } |
743 | 513 | ||
744 | RegionSettings currentRegionSettings = scene.RegionInfo.RegionSettings; | 514 | RegionSettings currentRegionSettings = m_scene.RegionInfo.RegionSettings; |
745 | 515 | ||
746 | currentRegionSettings.AgentLimit = loadedRegionSettings.AgentLimit; | 516 | currentRegionSettings.AgentLimit = loadedRegionSettings.AgentLimit; |
747 | currentRegionSettings.AllowDamage = loadedRegionSettings.AllowDamage; | 517 | currentRegionSettings.AllowDamage = loadedRegionSettings.AllowDamage; |
@@ -778,14 +548,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
778 | foreach (SpawnPoint sp in loadedRegionSettings.SpawnPoints()) | 548 | foreach (SpawnPoint sp in loadedRegionSettings.SpawnPoints()) |
779 | currentRegionSettings.AddSpawnPoint(sp); | 549 | currentRegionSettings.AddSpawnPoint(sp); |
780 | 550 | ||
781 | currentRegionSettings.LoadedCreationDateTime = dearchivedScenes.LoadedCreationDateTime; | ||
782 | currentRegionSettings.LoadedCreationID = dearchivedScenes.GetOriginalRegionID(scene.RegionInfo.RegionID).ToString(); | ||
783 | |||
784 | currentRegionSettings.Save(); | 551 | currentRegionSettings.Save(); |
785 | 552 | ||
786 | scene.TriggerEstateSunUpdate(); | 553 | m_scene.TriggerEstateSunUpdate(); |
787 | 554 | ||
788 | IEstateModule estateModule = scene.RequestModuleInterface<IEstateModule>(); | 555 | IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>(); |
556 | |||
789 | if (estateModule != null) | 557 | if (estateModule != null) |
790 | estateModule.sendRegionHandshakeToAll(); | 558 | estateModule.sendRegionHandshakeToAll(); |
791 | 559 | ||
@@ -795,15 +563,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
795 | /// <summary> | 563 | /// <summary> |
796 | /// Load terrain data | 564 | /// Load terrain data |
797 | /// </summary> | 565 | /// </summary> |
798 | /// <param name="scene"></param> | ||
799 | /// <param name="terrainPath"></param> | 566 | /// <param name="terrainPath"></param> |
800 | /// <param name="data"></param> | 567 | /// <param name="data"></param> |
801 | /// <returns> | 568 | /// <returns> |
802 | /// true if terrain was resolved successfully, false otherwise. | 569 | /// true if terrain was resolved successfully, false otherwise. |
803 | /// </returns> | 570 | /// </returns> |
804 | private bool LoadTerrain(Scene scene, string terrainPath, byte[] data) | 571 | private bool LoadTerrain(string terrainPath, byte[] data) |
805 | { | 572 | { |
806 | ITerrainModule terrainModule = scene.RequestModuleInterface<ITerrainModule>(); | 573 | ITerrainModule terrainModule = m_scene.RequestModuleInterface<ITerrainModule>(); |
807 | 574 | ||
808 | MemoryStream ms = new MemoryStream(data); | 575 | MemoryStream ms = new MemoryStream(data); |
809 | terrainModule.LoadFromStream(terrainPath, ms); | 576 | terrainModule.LoadFromStream(terrainPath, ms); |
@@ -819,18 +586,17 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
819 | /// </summary> | 586 | /// </summary> |
820 | /// <param name="path"></param> | 587 | /// <param name="path"></param> |
821 | /// <param name="data"></param> | 588 | /// <param name="data"></param> |
822 | /// <param name="dearchivedScenes"></param> | 589 | public void LoadControlFile(string path, byte[] data) |
823 | public DearchiveScenesInfo LoadControlFile(string path, byte[] data, DearchiveScenesInfo dearchivedScenes) | ||
824 | { | 590 | { |
825 | XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable()); | 591 | XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable()); |
826 | XmlParserContext context = new XmlParserContext(null, nsmgr, null, XmlSpace.None); | 592 | XmlParserContext context = new XmlParserContext(null, nsmgr, null, XmlSpace.None); |
827 | XmlTextReader xtr = new XmlTextReader(Encoding.ASCII.GetString(data), XmlNodeType.Document, context); | 593 | XmlTextReader xtr = new XmlTextReader(Encoding.ASCII.GetString(data), XmlNodeType.Document, context); |
828 | 594 | ||
829 | // Loaded metadata will be empty if no information exists in the archive | 595 | RegionSettings currentRegionSettings = m_scene.RegionInfo.RegionSettings; |
830 | dearchivedScenes.LoadedCreationDateTime = 0; | ||
831 | dearchivedScenes.DefaultOriginalID = ""; | ||
832 | 596 | ||
833 | bool multiRegion = false; | 597 | // Loaded metadata will empty if no information exists in the archive |
598 | currentRegionSettings.LoadedCreationDateTime = 0; | ||
599 | currentRegionSettings.LoadedCreationID = ""; | ||
834 | 600 | ||
835 | while (xtr.Read()) | 601 | while (xtr.Read()) |
836 | { | 602 | { |
@@ -856,44 +622,18 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
856 | { | 622 | { |
857 | int value; | 623 | int value; |
858 | if (Int32.TryParse(xtr.ReadElementContentAsString(), out value)) | 624 | if (Int32.TryParse(xtr.ReadElementContentAsString(), out value)) |
859 | dearchivedScenes.LoadedCreationDateTime = value; | 625 | currentRegionSettings.LoadedCreationDateTime = value; |
860 | } | 626 | } |
861 | else if (xtr.Name.ToString() == "row") | 627 | else if (xtr.Name.ToString() == "id") |
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") | ||
878 | { | 628 | { |
879 | dearchivedScenes.SetRegionDirectory(xtr.ReadElementContentAsString()); | 629 | currentRegionSettings.LoadedCreationID = xtr.ReadElementContentAsString(); |
880 | } | 630 | } |
881 | } | 631 | } |
882 | } | 632 | } |
883 | 633 | ||
884 | dearchivedScenes.MultiRegionFormat = multiRegion; | 634 | currentRegionSettings.Save(); |
885 | if (!multiRegion) | 635 | |
886 | { | ||
887 | // Add the single scene | ||
888 | dearchivedScenes.StartRow(); | ||
889 | dearchivedScenes.StartRegion(); | ||
890 | dearchivedScenes.SetRegionOriginalID(dearchivedScenes.DefaultOriginalID); | ||
891 | dearchivedScenes.SetRegionDirectory(""); | ||
892 | } | ||
893 | |||
894 | ControlFileLoaded = true; | 636 | ControlFileLoaded = true; |
895 | |||
896 | return dearchivedScenes; | ||
897 | } | 637 | } |
898 | } | 638 | } |
899 | } | 639 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveScenesGroup.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveScenesGroup.cs deleted file mode 100644 index d8dace2..0000000 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveScenesGroup.cs +++ /dev/null | |||
@@ -1,176 +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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Linq; | ||
31 | using System.Text; | ||
32 | using OpenSim.Region.Framework.Scenes; | ||
33 | using OpenMetaverse; | ||
34 | using System.Drawing; | ||
35 | |||
36 | namespace 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 deleted file mode 100644 index d751b1c..0000000 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs +++ /dev/null | |||
@@ -1,634 +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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.IO; | ||
31 | using System.IO.Compression; | ||
32 | using System.Reflection; | ||
33 | using System.Text.RegularExpressions; | ||
34 | using System.Threading; | ||
35 | using System.Xml; | ||
36 | using log4net; | ||
37 | using OpenMetaverse; | ||
38 | using OpenSim.Framework; | ||
39 | using OpenSim.Framework.Serialization; | ||
40 | using OpenSim.Region.CoreModules.World.Terrain; | ||
41 | using OpenSim.Region.Framework.Interfaces; | ||
42 | using OpenSim.Region.Framework.Scenes; | ||
43 | using Ionic.Zlib; | ||
44 | using GZipStream = Ionic.Zlib.GZipStream; | ||
45 | using CompressionMode = Ionic.Zlib.CompressionMode; | ||
46 | using OpenSim.Framework.Serialization.External; | ||
47 | |||
48 | namespace 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 new file mode 100644 index 0000000..0780d86 --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs | |||
@@ -0,0 +1,153 @@ | |||
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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.IO; | ||
31 | using System.Reflection; | ||
32 | using System.Xml; | ||
33 | using log4net; | ||
34 | using OpenMetaverse; | ||
35 | using OpenSim.Framework; | ||
36 | using OpenSim.Framework.Serialization; | ||
37 | using OpenSim.Framework.Serialization.External; | ||
38 | using OpenSim.Region.CoreModules.World.Terrain; | ||
39 | using OpenSim.Region.Framework.Interfaces; | ||
40 | using OpenSim.Region.Framework.Scenes; | ||
41 | |||
42 | namespace 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 new file mode 100644 index 0000000..4edaaca --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs | |||
@@ -0,0 +1,438 @@ | |||
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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.IO; | ||
31 | using System.IO.Compression; | ||
32 | using System.Reflection; | ||
33 | using System.Text.RegularExpressions; | ||
34 | using System.Threading; | ||
35 | using System.Xml; | ||
36 | using log4net; | ||
37 | using OpenMetaverse; | ||
38 | using OpenSim.Framework; | ||
39 | using OpenSim.Framework.Serialization; | ||
40 | using OpenSim.Region.CoreModules.World.Terrain; | ||
41 | using OpenSim.Region.Framework.Interfaces; | ||
42 | using OpenSim.Region.Framework.Scenes; | ||
43 | using Ionic.Zlib; | ||
44 | using GZipStream = Ionic.Zlib.GZipStream; | ||
45 | using CompressionMode = Ionic.Zlib.CompressionMode; | ||
46 | |||
47 | namespace 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 abf3713..bf3b124 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs | |||
@@ -32,8 +32,6 @@ using System.Reflection; | |||
32 | using log4net; | 32 | using log4net; |
33 | using NDesk.Options; | 33 | using NDesk.Options; |
34 | using Nini.Config; | 34 | using Nini.Config; |
35 | using OpenSim.Framework; | ||
36 | using OpenSim.Framework.Console; | ||
37 | using OpenSim.Region.Framework.Interfaces; | 35 | using OpenSim.Region.Framework.Interfaces; |
38 | using OpenSim.Region.Framework.Scenes; | 36 | using OpenSim.Region.Framework.Scenes; |
39 | 37 | ||
@@ -119,7 +117,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
119 | // | 117 | // |
120 | // foreach (string param in mainParams) | 118 | // foreach (string param in mainParams) |
121 | // m_log.DebugFormat("GOT PARAM [{0}]", param); | 119 | // m_log.DebugFormat("GOT PARAM [{0}]", param); |
122 | 120 | ||
123 | if (mainParams.Count > 2) | 121 | if (mainParams.Count > 2) |
124 | { | 122 | { |
125 | DearchiveRegion(mainParams[2], mergeOar, skipAssets, Guid.Empty); | 123 | DearchiveRegion(mainParams[2], mergeOar, skipAssets, Guid.Empty); |
@@ -148,22 +146,17 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
148 | ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); | 146 | ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); |
149 | ops.Add("publish", v => options["wipe-owners"] = v != null); | 147 | ops.Add("publish", v => options["wipe-owners"] = v != null); |
150 | ops.Add("perm=", delegate(string v) { options["checkPermissions"] = v; }); | 148 | ops.Add("perm=", delegate(string v) { options["checkPermissions"] = v; }); |
151 | ops.Add("all", delegate(string v) { options["all"] = v != null; }); | ||
152 | 149 | ||
153 | List<string> mainParams = ops.Parse(cmdparams); | 150 | List<string> mainParams = ops.Parse(cmdparams); |
154 | 151 | ||
155 | string path; | ||
156 | if (mainParams.Count > 2) | 152 | if (mainParams.Count > 2) |
157 | path = mainParams[2]; | 153 | { |
154 | ArchiveRegion(mainParams[2], options); | ||
155 | } | ||
158 | else | 156 | else |
159 | path = DEFAULT_OAR_BACKUP_FILENAME; | 157 | { |
160 | 158 | ArchiveRegion(DEFAULT_OAR_BACKUP_FILENAME, options); | |
161 | // Not doing this right now as this causes some problems with auto-backup systems. Maybe a force flag is | 159 | } |
162 | // needed | ||
163 | // if (!ConsoleUtil.CheckFileDoesNotExist(MainConsole.Instance, path)) | ||
164 | // return; | ||
165 | |||
166 | ArchiveRegion(path, options); | ||
167 | } | 160 | } |
168 | 161 | ||
169 | public void ArchiveRegion(string savePath, Dictionary<string, object> options) | 162 | public void ArchiveRegion(string savePath, Dictionary<string, object> options) |
@@ -176,7 +169,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
176 | m_log.InfoFormat( | 169 | m_log.InfoFormat( |
177 | "[ARCHIVER]: Writing archive for region {0} to {1}", Scene.RegionInfo.RegionName, savePath); | 170 | "[ARCHIVER]: Writing archive for region {0} to {1}", Scene.RegionInfo.RegionName, savePath); |
178 | 171 | ||
179 | new ArchiveWriteRequest(Scene, savePath, requestId).ArchiveRegion(options); | 172 | new ArchiveWriteRequestPreparation(this, savePath, requestId).ArchiveRegion(options); |
180 | } | 173 | } |
181 | 174 | ||
182 | public void ArchiveRegion(Stream saveStream) | 175 | public void ArchiveRegion(Stream saveStream) |
@@ -191,7 +184,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
191 | 184 | ||
192 | public void ArchiveRegion(Stream saveStream, Guid requestId, Dictionary<string, object> options) | 185 | public void ArchiveRegion(Stream saveStream, Guid requestId, Dictionary<string, object> options) |
193 | { | 186 | { |
194 | new ArchiveWriteRequest(Scene, saveStream, requestId).ArchiveRegion(options); | 187 | new ArchiveWriteRequestPreparation(this, saveStream, requestId).ArchiveRegion(options); |
195 | } | 188 | } |
196 | 189 | ||
197 | public void DearchiveRegion(string loadPath) | 190 | public void DearchiveRegion(string loadPath) |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs index e2f8833..89e9593 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs | |||
@@ -46,12 +46,6 @@ 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 | |||
55 | enum RequestState | 49 | enum RequestState |
56 | { | 50 | { |
57 | Initial, | 51 | Initial, |
@@ -129,10 +123,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
129 | m_options = options; | 123 | m_options = options; |
130 | m_repliesRequired = uuids.Count; | 124 | m_repliesRequired = uuids.Count; |
131 | 125 | ||
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 | ||
136 | m_requestCallbackTimer = new System.Timers.Timer(TIMEOUT); | 126 | m_requestCallbackTimer = new System.Timers.Timer(TIMEOUT); |
137 | m_requestCallbackTimer.AutoReset = false; | 127 | m_requestCallbackTimer.AutoReset = false; |
138 | m_requestCallbackTimer.Elapsed += new ElapsedEventHandler(OnRequestCallbackTimeout); | 128 | m_requestCallbackTimer.Elapsed += new ElapsedEventHandler(OnRequestCallbackTimeout); |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs b/OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs deleted file mode 100644 index 3dcc020..0000000 --- a/OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs +++ /dev/null | |||
@@ -1,232 +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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Linq; | ||
31 | using System.Text; | ||
32 | using OpenSim.Region.Framework.Scenes; | ||
33 | using OpenMetaverse; | ||
34 | using System.Drawing; | ||
35 | using log4net; | ||
36 | using System.Reflection; | ||
37 | using OpenSim.Framework.Serialization; | ||
38 | |||
39 | namespace 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 82f49b0..5deaf52 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs | |||
@@ -47,41 +47,32 @@ using ArchiveConstants = OpenSim.Framework.Serialization.ArchiveConstants; | |||
47 | using TarArchiveReader = OpenSim.Framework.Serialization.TarArchiveReader; | 47 | using TarArchiveReader = OpenSim.Framework.Serialization.TarArchiveReader; |
48 | using TarArchiveWriter = OpenSim.Framework.Serialization.TarArchiveWriter; | 48 | using TarArchiveWriter = OpenSim.Framework.Serialization.TarArchiveWriter; |
49 | using RegionSettings = OpenSim.Framework.RegionSettings; | 49 | using RegionSettings = OpenSim.Framework.RegionSettings; |
50 | using OpenSim.Region.Framework.Interfaces; | ||
51 | 50 | ||
52 | namespace OpenSim.Region.CoreModules.World.Archiver.Tests | 51 | namespace OpenSim.Region.CoreModules.World.Archiver.Tests |
53 | { | 52 | { |
54 | [TestFixture] | 53 | [TestFixture] |
55 | public class ArchiverTests : OpenSimTestCase | 54 | public class ArchiverTests |
56 | { | 55 | { |
57 | private Guid m_lastRequestId; | 56 | private Guid m_lastRequestId; |
58 | private string m_lastErrorMessage; | 57 | private string m_lastErrorMessage; |
59 | 58 | ||
60 | protected SceneHelpers m_sceneHelpers; | ||
61 | protected TestScene m_scene; | 59 | protected TestScene m_scene; |
62 | protected ArchiverModule m_archiverModule; | 60 | protected ArchiverModule m_archiverModule; |
63 | protected SerialiserModule m_serialiserModule; | ||
64 | 61 | ||
65 | protected TaskInventoryItem m_soundItem; | 62 | protected TaskInventoryItem m_soundItem; |
66 | 63 | ||
67 | [SetUp] | 64 | [SetUp] |
68 | public override void SetUp() | 65 | public void SetUp() |
69 | { | 66 | { |
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 | |||
75 | m_archiverModule = new ArchiverModule(); | 67 | m_archiverModule = new ArchiverModule(); |
76 | m_serialiserModule = new SerialiserModule(); | 68 | SerialiserModule serialiserModule = new SerialiserModule(); |
77 | TerrainModule terrainModule = new TerrainModule(); | 69 | TerrainModule terrainModule = new TerrainModule(); |
78 | 70 | ||
79 | m_sceneHelpers = new SceneHelpers(); | 71 | m_scene = new SceneHelpers().SetupScene(); |
80 | m_scene = m_sceneHelpers.SetupScene(); | 72 | SceneHelpers.SetupSceneModules(m_scene, m_archiverModule, serialiserModule, terrainModule); |
81 | SceneHelpers.SetupSceneModules(m_scene, m_archiverModule, m_serialiserModule, terrainModule); | ||
82 | } | 73 | } |
83 | 74 | ||
84 | private void LoadCompleted(Guid requestId, List<UUID> loadedScenes, string errorMessage) | 75 | private void LoadCompleted(Guid requestId, string errorMessage) |
85 | { | 76 | { |
86 | lock (this) | 77 | lock (this) |
87 | { | 78 | { |
@@ -137,10 +128,26 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
137 | TestHelpers.InMethod(); | 128 | TestHelpers.InMethod(); |
138 | // log4net.Config.XmlConfigurator.Configure(); | 129 | // log4net.Config.XmlConfigurator.Configure(); |
139 | 130 | ||
140 | SceneObjectGroup sog1; | 131 | SceneObjectPart part1 = CreateSceneObjectPart1(); |
141 | SceneObjectGroup sog2; | 132 | SceneObjectGroup sog1 = new SceneObjectGroup(part1); |
142 | UUID ncAssetUuid; | 133 | m_scene.AddNewSceneObject(sog1, false); |
143 | CreateTestObjects(m_scene, out sog1, out sog2, out ncAssetUuid); | 134 | |
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); | ||
144 | 151 | ||
145 | MemoryStream archiveWriteStream = new MemoryStream(); | 152 | MemoryStream archiveWriteStream = new MemoryStream(); |
146 | m_scene.EventManager.OnOarFileSaved += SaveCompleted; | 153 | m_scene.EventManager.OnOarFileSaved += SaveCompleted; |
@@ -179,7 +186,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
179 | Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); | 186 | Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); |
180 | 187 | ||
181 | ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, false, false, Guid.Empty); | 188 | ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, false, false, Guid.Empty); |
182 | arr.LoadControlFile(filePath, data, new DearchiveScenesInfo()); | 189 | arr.LoadControlFile(filePath, data); |
183 | 190 | ||
184 | Assert.That(arr.ControlFileLoaded, Is.True); | 191 | Assert.That(arr.ControlFileLoaded, Is.True); |
185 | 192 | ||
@@ -204,30 +211,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
204 | // TODO: Test presence of more files and contents of files. | 211 | // TODO: Test presence of more files and contents of files. |
205 | } | 212 | } |
206 | 213 | ||
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 | |||
231 | /// <summary> | 214 | /// <summary> |
232 | /// Test saving an OpenSim Region Archive with the no assets option | 215 | /// Test saving an OpenSim Region Archive with the no assets option |
233 | /// </summary> | 216 | /// </summary> |
@@ -287,7 +270,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
287 | Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); | 270 | Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); |
288 | 271 | ||
289 | ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, false, false, Guid.Empty); | 272 | ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, false, false, Guid.Empty); |
290 | arr.LoadControlFile(filePath, data, new DearchiveScenesInfo()); | 273 | arr.LoadControlFile(filePath, data); |
291 | 274 | ||
292 | Assert.That(arr.ControlFileLoaded, Is.True); | 275 | Assert.That(arr.ControlFileLoaded, Is.True); |
293 | 276 | ||
@@ -324,7 +307,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
324 | 307 | ||
325 | tar.WriteFile( | 308 | tar.WriteFile( |
326 | ArchiveConstants.CONTROL_FILE_PATH, | 309 | ArchiveConstants.CONTROL_FILE_PATH, |
327 | new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup())); | 310 | new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>())); |
328 | 311 | ||
329 | SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ownerId, "obj1-", 0x11); | 312 | SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ownerId, "obj1-", 0x11); |
330 | SceneObjectPart sop2 | 313 | SceneObjectPart sop2 |
@@ -379,10 +362,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
379 | // Also check that direct entries which will also have a file entry containing that directory doesn't | 362 | // Also check that direct entries which will also have a file entry containing that directory doesn't |
380 | // upset load | 363 | // upset load |
381 | tar.WriteDir(ArchiveConstants.TERRAINS_PATH); | 364 | tar.WriteDir(ArchiveConstants.TERRAINS_PATH); |
382 | 365 | ||
383 | tar.WriteFile( | 366 | tar.WriteFile( |
384 | ArchiveConstants.CONTROL_FILE_PATH, | 367 | ArchiveConstants.CONTROL_FILE_PATH, |
385 | new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup())); | 368 | new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>())); |
369 | |||
386 | SceneObjectPart part1 = CreateSceneObjectPart1(); | 370 | SceneObjectPart part1 = CreateSceneObjectPart1(); |
387 | 371 | ||
388 | part1.SitTargetOrientation = new Quaternion(0.2f, 0.3f, 0.4f, 0.5f); | 372 | part1.SitTargetOrientation = new Quaternion(0.2f, 0.3f, 0.4f, 0.5f); |
@@ -405,12 +389,31 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
405 | Assert.That(soundDataResourceName, Is.Not.Null); | 389 | Assert.That(soundDataResourceName, Is.Not.Null); |
406 | 390 | ||
407 | byte[] soundData; | 391 | byte[] soundData; |
408 | UUID soundUuid; | 392 | Console.WriteLine("Loading " + soundDataResourceName); |
409 | CreateSoundAsset(tar, assembly, soundDataResourceName, out soundData, out soundUuid); | 393 | using (Stream resource = assembly.GetManifestResourceStream(soundDataResourceName)) |
410 | 394 | { | |
411 | TaskInventoryItem item1 | 395 | using (BinaryReader br = new BinaryReader(resource)) |
412 | = new TaskInventoryItem { AssetID = soundUuid, ItemID = soundItemUuid, Name = soundItemName }; | 396 | { |
413 | part1.Inventory.AddInventoryItem(item1, true); | 397 | // FIXME: Use the inspector instead |
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 | |||
414 | m_scene.AddNewSceneObject(object1, false); | 417 | m_scene.AddNewSceneObject(object1, false); |
415 | 418 | ||
416 | string object1FileName = string.Format( | 419 | string object1FileName = string.Format( |
@@ -432,34 +435,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
432 | 435 | ||
433 | Assert.That(m_lastErrorMessage, Is.Null); | 436 | Assert.That(m_lastErrorMessage, Is.Null); |
434 | 437 | ||
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 | { | ||
463 | SceneObjectPart object1PartLoaded = m_scene.GetSceneObjectPart(part1.Name); | 438 | SceneObjectPart object1PartLoaded = m_scene.GetSceneObjectPart(part1.Name); |
464 | 439 | ||
465 | Assert.That(object1PartLoaded, Is.Not.Null, "object1 was not loaded"); | 440 | Assert.That(object1PartLoaded, Is.Not.Null, "object1 was not loaded"); |
@@ -479,6 +454,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
479 | Assert.That(loadedSoundAsset.Data, Is.EqualTo(soundData), "saved and loaded sound data do not match"); | 454 | Assert.That(loadedSoundAsset.Data, Is.EqualTo(soundData), "saved and loaded sound data do not match"); |
480 | 455 | ||
481 | Assert.Greater(m_scene.LandChannel.AllParcels().Count, 0, "incorrect number of parcels"); | 456 | Assert.Greater(m_scene.LandChannel.AllParcels().Count, 0, "incorrect number of parcels"); |
457 | |||
458 | // Temporary | ||
459 | Console.WriteLine("Successfully completed {0}", MethodBase.GetCurrentMethod()); | ||
482 | } | 460 | } |
483 | 461 | ||
484 | /// <summary> | 462 | /// <summary> |
@@ -538,8 +516,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
538 | SerialiserModule serialiserModule = new SerialiserModule(); | 516 | SerialiserModule serialiserModule = new SerialiserModule(); |
539 | TerrainModule terrainModule = new TerrainModule(); | 517 | TerrainModule terrainModule = new TerrainModule(); |
540 | 518 | ||
541 | m_sceneHelpers = new SceneHelpers(); | 519 | TestScene scene2 = new SceneHelpers().SetupScene(); |
542 | TestScene scene2 = m_sceneHelpers.SetupScene(); | ||
543 | SceneHelpers.SetupSceneModules(scene2, archiverModule, serialiserModule, terrainModule); | 520 | SceneHelpers.SetupSceneModules(scene2, archiverModule, serialiserModule, terrainModule); |
544 | 521 | ||
545 | // Make sure there's a valid owner for the owner we saved (this should have been wiped if the code is | 522 | // Make sure there's a valid owner for the owner we saved (this should have been wiped if the code is |
@@ -577,7 +554,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
577 | tar.WriteDir(ArchiveConstants.TERRAINS_PATH); | 554 | tar.WriteDir(ArchiveConstants.TERRAINS_PATH); |
578 | tar.WriteFile( | 555 | tar.WriteFile( |
579 | ArchiveConstants.CONTROL_FILE_PATH, | 556 | ArchiveConstants.CONTROL_FILE_PATH, |
580 | new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup())); | 557 | new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>())); |
581 | 558 | ||
582 | RegionSettings rs = new RegionSettings(); | 559 | RegionSettings rs = new RegionSettings(); |
583 | rs.AgentLimit = 17; | 560 | rs.AgentLimit = 17; |
@@ -687,7 +664,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
687 | SerialiserModule serialiserModule = new SerialiserModule(); | 664 | SerialiserModule serialiserModule = new SerialiserModule(); |
688 | TerrainModule terrainModule = new TerrainModule(); | 665 | TerrainModule terrainModule = new TerrainModule(); |
689 | 666 | ||
690 | Scene scene = m_sceneHelpers.SetupScene(); | 667 | Scene scene = new SceneHelpers().SetupScene(); |
691 | SceneHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule); | 668 | SceneHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule); |
692 | 669 | ||
693 | m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false); | 670 | m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false); |
@@ -723,258 +700,5 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
723 | Assert.That(object2PartMerged.GroupPosition, Is.EqualTo(part2.GroupPosition), "object2 group position not equal after merge"); | 700 | Assert.That(object2PartMerged.GroupPosition, Is.EqualTo(part2.GroupPosition), "object2 group position not equal after merge"); |
724 | } | 701 | } |
725 | } | 702 | } |
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 | |||
979 | } | 703 | } |
980 | } | 704 | } |
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 5fd1bce..fdef9d8 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs | |||
@@ -40,7 +40,6 @@ using OpenMetaverse; | |||
40 | using OpenSim.Framework; | 40 | using OpenSim.Framework; |
41 | using OpenSim.Region.Framework.Interfaces; | 41 | using OpenSim.Region.Framework.Interfaces; |
42 | using OpenSim.Region.Framework.Scenes; | 42 | using OpenSim.Region.Framework.Scenes; |
43 | using RegionFlags = OpenMetaverse.RegionFlags; | ||
44 | 43 | ||
45 | namespace OpenSim.Region.CoreModules.World.Estate | 44 | namespace OpenSim.Region.CoreModules.World.Estate |
46 | { | 45 | { |
diff --git a/OpenSim/Region/CoreModules/World/Land/DwellModule.cs b/OpenSim/Region/CoreModules/World/Land/DwellModule.cs deleted file mode 100644 index d1f05a7..0000000 --- a/OpenSim/Region/CoreModules/World/Land/DwellModule.cs +++ /dev/null | |||
@@ -1,110 +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 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Diagnostics; | ||
32 | using System.Reflection; | ||
33 | using System.Text; | ||
34 | using log4net; | ||
35 | using Nini.Config; | ||
36 | using OpenMetaverse; | ||
37 | using OpenMetaverse.StructuredData; | ||
38 | using OpenMetaverse.Messages.Linden; | ||
39 | using OpenSim.Framework; | ||
40 | using OpenSim.Framework.Capabilities; | ||
41 | using OpenSim.Framework.Console; | ||
42 | using OpenSim.Framework.Servers; | ||
43 | using OpenSim.Framework.Servers.HttpServer; | ||
44 | using OpenSim.Region.CoreModules.Framework.InterfaceCommander; | ||
45 | using OpenSim.Region.Framework.Interfaces; | ||
46 | using OpenSim.Region.Framework.Scenes; | ||
47 | using OpenSim.Region.Physics.Manager; | ||
48 | using OpenSim.Services.Interfaces; | ||
49 | using Caps = OpenSim.Framework.Capabilities.Caps; | ||
50 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | ||
51 | |||
52 | namespace OpenSim.Region.CoreModules.World.Land | ||
53 | { | ||
54 | public class DwellModule : IDwellModule, INonSharedRegionModule | ||
55 | { | ||
56 | private Scene m_scene; | ||
57 | |||
58 | public Type ReplaceableInterface | ||
59 | { | ||
60 | get { return typeof(IDwellModule); } | ||
61 | } | ||
62 | |||
63 | public string Name | ||
64 | { | ||
65 | get { return "DwellModule"; } | ||
66 | } | ||
67 | |||
68 | public void Initialise(IConfigSource source) | ||
69 | { | ||
70 | } | ||
71 | |||
72 | public void AddRegion(Scene scene) | ||
73 | { | ||
74 | m_scene = scene; | ||
75 | |||
76 | m_scene.EventManager.OnNewClient += OnNewClient; | ||
77 | } | ||
78 | |||
79 | public void RegionLoaded(Scene scene) | ||
80 | { | ||
81 | } | ||
82 | |||
83 | public void RemoveRegion(Scene scene) | ||
84 | { | ||
85 | } | ||
86 | |||
87 | public void Close() | ||
88 | { | ||
89 | } | ||
90 | |||
91 | public void OnNewClient(IClientAPI client) | ||
92 | { | ||
93 | client.OnParcelDwellRequest += ClientOnParcelDwellRequest; | ||
94 | } | ||
95 | |||
96 | private void ClientOnParcelDwellRequest(int localID, IClientAPI client) | ||
97 | { | ||
98 | ILandObject parcel = m_scene.LandChannel.GetLandObject(localID); | ||
99 | if (parcel == null) | ||
100 | return; | ||
101 | |||
102 | client.SendParcelDwellReply(localID, parcel.LandData.GlobalID, parcel.LandData.Dwell); | ||
103 | } | ||
104 | |||
105 | public int GetDwell(UUID parcelID) | ||
106 | { | ||
107 | return 0; | ||
108 | } | ||
109 | } | ||
110 | } | ||
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index b5e2bc3..aae6603 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | |||
@@ -927,7 +927,6 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
927 | ILandObject newLand = startLandObject.Copy(); | 927 | ILandObject newLand = startLandObject.Copy(); |
928 | newLand.LandData.Name = newLand.LandData.Name; | 928 | newLand.LandData.Name = newLand.LandData.Name; |
929 | newLand.LandData.GlobalID = UUID.Random(); | 929 | newLand.LandData.GlobalID = UUID.Random(); |
930 | newLand.LandData.Dwell = 0; | ||
931 | 930 | ||
932 | newLand.SetLandBitmap(newLand.GetSquareLandBitmap(start_x, start_y, end_x, end_y)); | 931 | newLand.SetLandBitmap(newLand.GetSquareLandBitmap(start_x, start_y, end_x, end_y)); |
933 | 932 | ||
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index d5b2adb..4f06737 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs | |||
@@ -33,7 +33,6 @@ using OpenMetaverse; | |||
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Region.Framework.Interfaces; | 34 | using OpenSim.Region.Framework.Interfaces; |
35 | using OpenSim.Region.Framework.Scenes; | 35 | using OpenSim.Region.Framework.Scenes; |
36 | using RegionFlags = OpenMetaverse.RegionFlags; | ||
37 | 36 | ||
38 | namespace OpenSim.Region.CoreModules.World.Land | 37 | namespace OpenSim.Region.CoreModules.World.Land |
39 | { | 38 | { |
diff --git a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs index cbb3abe..102b4d7 100644 --- a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs | |||
@@ -69,7 +69,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
69 | /// without recounting the whole sim. | 69 | /// without recounting the whole sim. |
70 | /// | 70 | /// |
71 | /// We start out tainted so that the first get call resets the various prim counts. | 71 | /// We start out tainted so that the first get call resets the various prim counts. |
72 | /// </value> | 72 | /// <value> |
73 | private bool m_Tainted = true; | 73 | private bool m_Tainted = true; |
74 | 74 | ||
75 | private Object m_TaintLock = new Object(); | 75 | private Object m_TaintLock = new Object(); |
diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs index ab8f143..09f6758 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs | |||
@@ -27,12 +27,9 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.IO; | ||
31 | using System.Linq; | ||
32 | using System.Reflection; | 30 | using System.Reflection; |
33 | using System.Text; | 31 | using System.Text; |
34 | using System.Text.RegularExpressions; | 32 | using System.Text.RegularExpressions; |
35 | using System.Xml; | ||
36 | using log4net; | 33 | using log4net; |
37 | using Mono.Addins; | 34 | using Mono.Addins; |
38 | using NDesk.Options; | 35 | using NDesk.Options; |
@@ -43,7 +40,6 @@ using OpenSim.Framework.Console; | |||
43 | using OpenSim.Framework.Monitoring; | 40 | using OpenSim.Framework.Monitoring; |
44 | using OpenSim.Region.Framework.Interfaces; | 41 | using OpenSim.Region.Framework.Interfaces; |
45 | using OpenSim.Region.Framework.Scenes; | 42 | using OpenSim.Region.Framework.Scenes; |
46 | using OpenSim.Region.Framework.Scenes.Serialization; | ||
47 | 43 | ||
48 | namespace OpenSim.Region.CoreModules.World.Objects.Commands | 44 | namespace OpenSim.Region.CoreModules.World.Objects.Commands |
49 | { | 45 | { |
@@ -87,85 +83,52 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
87 | m_console.Commands.AddCommand( | 83 | m_console.Commands.AddCommand( |
88 | "Objects", false, "delete object owner", | 84 | "Objects", false, "delete object owner", |
89 | "delete object owner <UUID>", | 85 | "delete object owner <UUID>", |
90 | "Delete scene objects by owner", | 86 | "Delete a scene object by owner", HandleDeleteObject); |
91 | "Command will ask for confirmation before proceeding.", | ||
92 | HandleDeleteObject); | ||
93 | 87 | ||
94 | m_console.Commands.AddCommand( | 88 | m_console.Commands.AddCommand( |
95 | "Objects", false, "delete object creator", | 89 | "Objects", false, "delete object creator", |
96 | "delete object creator <UUID>", | 90 | "delete object creator <UUID>", |
97 | "Delete scene objects by creator", | 91 | "Delete a scene object by creator", HandleDeleteObject); |
98 | "Command will ask for confirmation before proceeding.", | ||
99 | HandleDeleteObject); | ||
100 | 92 | ||
101 | m_console.Commands.AddCommand( | 93 | m_console.Commands.AddCommand( |
102 | "Objects", false, "delete object id", | 94 | "Objects", false, "delete object uuid", |
103 | "delete object id <UUID-or-localID>", | 95 | "delete object uuid <UUID>", |
104 | "Delete a scene object by uuid or localID", | 96 | "Delete a scene object by uuid", HandleDeleteObject); |
105 | HandleDeleteObject); | ||
106 | 97 | ||
107 | m_console.Commands.AddCommand( | 98 | m_console.Commands.AddCommand( |
108 | "Objects", false, "delete object name", | 99 | "Objects", false, "delete object name", |
109 | "delete object name [--regex] <name>", | 100 | "delete object name [--regex] <name>", |
110 | "Delete a scene object by name.", | 101 | "Delete a scene object by name.", |
111 | "Command will ask for confirmation before proceeding.\n" | 102 | "If --regex is specified then the name is treatead as a regular expression", |
112 | + "If --regex is specified then the name is treatead as a regular expression", | ||
113 | HandleDeleteObject); | 103 | HandleDeleteObject); |
114 | 104 | ||
115 | m_console.Commands.AddCommand( | 105 | m_console.Commands.AddCommand( |
116 | "Objects", false, "delete object outside", | 106 | "Objects", false, "delete object outside", |
117 | "delete object outside", | 107 | "delete object outside", |
118 | "Delete all scene objects outside region boundaries", | 108 | "Delete all scene objects outside region boundaries", HandleDeleteObject); |
119 | "Command will ask for confirmation before proceeding.", | ||
120 | HandleDeleteObject); | ||
121 | 109 | ||
122 | m_console.Commands.AddCommand( | 110 | m_console.Commands.AddCommand( |
123 | "Objects", | 111 | "Objects", |
124 | false, | 112 | false, |
125 | "delete object pos", | 113 | "show object uuid", |
126 | "delete object pos <start-coord> to <end-coord>", | 114 | "show object uuid <UUID>", |
127 | "Delete scene objects within the given area.", | 115 | "Show details of a scene object with the given UUID", HandleShowObjectByUuid); |
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); | ||
140 | 116 | ||
141 | m_console.Commands.AddCommand( | 117 | m_console.Commands.AddCommand( |
142 | "Objects", | 118 | "Objects", |
143 | false, | 119 | false, |
144 | "show object name", | 120 | "show object name", |
145 | "show object name [--full] [--regex] <name>", | 121 | "show object name [--regex] <name>", |
146 | "Show details of scene objects with the given name.", | 122 | "Show details of scene objects with the given name.", |
147 | "The --full option will print out information on all the parts of the object.\n" | 123 | "If --regex is specified then the name is treatead as a regular expression", |
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.", | ||
150 | HandleShowObjectByName); | 124 | HandleShowObjectByName); |
151 | 125 | ||
152 | m_console.Commands.AddCommand( | 126 | m_console.Commands.AddCommand( |
153 | "Objects", | 127 | "Objects", |
154 | false, | 128 | false, |
155 | "show object pos", | 129 | "show part uuid", |
156 | "show object pos [--full] <start-coord> to <end-coord>", | 130 | "show part uuid <UUID>", |
157 | "Show details of scene objects within the given area.", | 131 | "Show details of a scene object parts with the given UUID", HandleShowPartByUuid); |
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); | ||
169 | 132 | ||
170 | m_console.Commands.AddCommand( | 133 | m_console.Commands.AddCommand( |
171 | "Objects", | 134 | "Objects", |
@@ -173,28 +136,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
173 | "show part name", | 136 | "show part name", |
174 | "show part name [--regex] <name>", | 137 | "show part name [--regex] <name>", |
175 | "Show details of scene object parts with the given name.", | 138 | "Show details of scene object parts with the given name.", |
176 | "If --regex is specified then the name is treated as a regular expression", | 139 | "If --regex is specified then the name is treatead as a regular expression", |
177 | HandleShowPartByName); | 140 | 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); | ||
198 | } | 141 | } |
199 | 142 | ||
200 | public void RemoveRegion(Scene scene) | 143 | public void RemoveRegion(Scene scene) |
@@ -207,75 +150,25 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
207 | // m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); | 150 | // m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); |
208 | } | 151 | } |
209 | 152 | ||
210 | /// <summary> | 153 | private void HandleShowObjectByUuid(string module, string[] cmd) |
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) | ||
253 | { | 154 | { |
254 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | 155 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) |
255 | return; | 156 | return; |
256 | 157 | ||
257 | bool showFull = false; | 158 | if (cmd.Length < 4) |
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) | ||
263 | { | 159 | { |
264 | m_console.OutputFormat("Usage: show object uuid <uuid>"); | 160 | m_console.OutputFormat("Usage: show object uuid <uuid>"); |
265 | return; | 161 | return; |
266 | } | 162 | } |
267 | 163 | ||
268 | UUID uuid; | 164 | UUID objectUuid; |
269 | uint localId; | 165 | if (!UUID.TryParse(cmd[3], out objectUuid)) |
270 | if (!ConsoleUtil.TryParseConsoleId(m_console, mainParams[3], out uuid, out localId)) | 166 | { |
167 | m_console.OutputFormat("{0} is not a valid uuid", cmd[3]); | ||
271 | return; | 168 | return; |
169 | } | ||
272 | 170 | ||
273 | SceneObjectGroup so; | 171 | SceneObjectGroup so = m_scene.GetSceneObjectGroup(objectUuid); |
274 | |||
275 | if (localId != ConsoleUtil.LocalIdNotFound) | ||
276 | so = m_scene.GetSceneObjectGroup(localId); | ||
277 | else | ||
278 | so = m_scene.GetSceneObjectGroup(uuid); | ||
279 | 172 | ||
280 | if (so == null) | 173 | if (so == null) |
281 | { | 174 | { |
@@ -284,7 +177,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
284 | } | 177 | } |
285 | 178 | ||
286 | StringBuilder sb = new StringBuilder(); | 179 | StringBuilder sb = new StringBuilder(); |
287 | AddSceneObjectReport(sb, so, showFull); | 180 | AddSceneObjectReport(sb, so); |
288 | 181 | ||
289 | m_console.OutputFormat(sb.ToString()); | 182 | m_console.OutputFormat(sb.ToString()); |
290 | } | 183 | } |
@@ -294,91 +187,70 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
294 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | 187 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) |
295 | return; | 188 | return; |
296 | 189 | ||
297 | bool showFull = false; | ||
298 | bool useRegex = false; | 190 | bool useRegex = false; |
299 | OptionSet options = new OptionSet(); | 191 | OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null ); |
300 | options.Add("full", v => showFull = v != null ); | ||
301 | options.Add("regex", v => useRegex = v != null ); | ||
302 | 192 | ||
303 | List<string> mainParams = options.Parse(cmdparams); | 193 | List<string> mainParams = options.Parse(cmdparams); |
304 | 194 | ||
305 | if (mainParams.Count < 4) | 195 | if (mainParams.Count < 4) |
306 | { | 196 | { |
307 | m_console.OutputFormat("Usage: show object name [--full] [--regex] <name>"); | 197 | m_console.OutputFormat("Usage: show object name [--regex] <name>"); |
308 | return; | 198 | return; |
309 | } | 199 | } |
310 | 200 | ||
311 | string name = mainParams[3]; | 201 | string name = mainParams[3]; |
312 | 202 | ||
313 | Predicate<SceneObjectGroup> searchPredicate; | 203 | List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); |
204 | Action<SceneObjectGroup> searchAction; | ||
314 | 205 | ||
315 | if (useRegex) | 206 | if (useRegex) |
316 | { | 207 | { |
317 | Regex nameRegex = new Regex(name); | 208 | Regex nameRegex = new Regex(name); |
318 | searchPredicate = so => nameRegex.IsMatch(so.Name); | 209 | searchAction = so => { if (nameRegex.IsMatch(so.Name)) { sceneObjects.Add(so); }}; |
319 | } | 210 | } |
320 | else | 211 | else |
321 | { | 212 | { |
322 | searchPredicate = so => so.Name == name; | 213 | searchAction = so => { if (so.Name == name) { sceneObjects.Add(so); }}; |
323 | } | 214 | } |
324 | 215 | ||
325 | OutputSogsToConsole(searchPredicate, showFull); | 216 | m_scene.ForEachSOG(searchAction); |
326 | } | ||
327 | |||
328 | private void HandleShowObjectByPos(string module, string[] cmdparams) | ||
329 | { | ||
330 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | ||
331 | return; | ||
332 | |||
333 | bool showFull = false; | ||
334 | OptionSet options = new OptionSet().Add("full", v => showFull = v != null ); | ||
335 | |||
336 | List<string> mainParams = options.Parse(cmdparams); | ||
337 | 217 | ||
338 | if (mainParams.Count < 5) | 218 | if (sceneObjects.Count == 0) |
339 | { | 219 | { |
340 | m_console.OutputFormat("Usage: show object pos [--full] <start-coord> to <end-coord>"); | 220 | m_console.OutputFormat("No objects with name {0} found in {1}", name, m_scene.RegionInfo.RegionName); |
341 | return; | 221 | return; |
342 | } | 222 | } |
343 | 223 | ||
344 | Vector3 startVector, endVector; | 224 | StringBuilder sb = new StringBuilder(); |
345 | |||
346 | if (!TryParseVectorRange(cmdparams.Skip(3).Take(3), out startVector, out endVector)) | ||
347 | return; | ||
348 | 225 | ||
349 | Predicate<SceneObjectGroup> searchPredicate | 226 | foreach (SceneObjectGroup so in sceneObjects) |
350 | = so => Util.IsInsideBox(so.AbsolutePosition, startVector, endVector); | 227 | { |
228 | AddSceneObjectReport(sb, so); | ||
229 | sb.Append("\n"); | ||
230 | } | ||
351 | 231 | ||
352 | OutputSogsToConsole(searchPredicate, showFull); | 232 | m_console.OutputFormat(sb.ToString()); |
353 | } | 233 | } |
354 | 234 | ||
355 | private void HandleShowPartById(string module, string[] cmdparams) | 235 | private void HandleShowPartByUuid(string module, string[] cmd) |
356 | { | 236 | { |
357 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | 237 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) |
358 | return; | 238 | return; |
359 | 239 | ||
360 | // bool showFull = false; | 240 | if (cmd.Length < 4) |
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) | ||
367 | { | 241 | { |
368 | m_console.OutputFormat("Usage: show part id [--full] <UUID-or-localID>"); | 242 | m_console.OutputFormat("Usage: show part uuid <uuid>"); |
369 | return; | 243 | return; |
370 | } | 244 | } |
371 | 245 | ||
372 | UUID objectUuid; | 246 | UUID objectUuid; |
373 | uint localId; | 247 | if (!UUID.TryParse(cmd[3], out objectUuid)) |
374 | if (!ConsoleUtil.TryParseConsoleId(m_console, mainParams[3], out objectUuid, out localId)) | 248 | { |
249 | m_console.OutputFormat("{0} is not a valid uuid", cmd[3]); | ||
375 | return; | 250 | return; |
251 | } | ||
376 | 252 | ||
377 | SceneObjectPart sop; | 253 | SceneObjectPart sop = m_scene.GetSceneObjectPart(objectUuid); |
378 | if (localId == ConsoleUtil.LocalIdNotFound) | ||
379 | sop = m_scene.GetSceneObjectPart(objectUuid); | ||
380 | else | ||
381 | sop = m_scene.GetSceneObjectPart(localId); | ||
382 | 254 | ||
383 | if (sop == null) | 255 | if (sop == null) |
384 | { | 256 | { |
@@ -387,239 +259,84 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
387 | } | 259 | } |
388 | 260 | ||
389 | StringBuilder sb = new StringBuilder(); | 261 | StringBuilder sb = new StringBuilder(); |
390 | AddScenePartReport(sb, sop, true); | 262 | AddScenePartReport(sb, sop); |
391 | 263 | ||
392 | m_console.OutputFormat(sb.ToString()); | 264 | m_console.OutputFormat(sb.ToString()); |
393 | } | 265 | } |
394 | 266 | ||
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 | |||
433 | private void HandleShowPartByName(string module, string[] cmdparams) | 267 | private void HandleShowPartByName(string module, string[] cmdparams) |
434 | { | 268 | { |
435 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | 269 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) |
436 | return; | 270 | return; |
437 | 271 | ||
438 | // bool showFull = false; | ||
439 | bool useRegex = false; | 272 | bool useRegex = false; |
440 | OptionSet options = new OptionSet(); | 273 | OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null ); |
441 | // options.Add("full", v => showFull = v != null ); | ||
442 | options.Add("regex", v => useRegex = v != null ); | ||
443 | 274 | ||
444 | List<string> mainParams = options.Parse(cmdparams); | 275 | List<string> mainParams = options.Parse(cmdparams); |
445 | 276 | ||
446 | if (mainParams.Count < 4) | 277 | if (mainParams.Count < 4) |
447 | { | 278 | { |
448 | m_console.OutputFormat("Usage: show part name [--full] [--regex] <name>"); | 279 | m_console.OutputFormat("Usage: show part name [--regex] <name>"); |
449 | return; | 280 | return; |
450 | } | 281 | } |
451 | 282 | ||
452 | string name = mainParams[3]; | 283 | string name = mainParams[3]; |
453 | 284 | ||
454 | Predicate<SceneObjectPart> searchPredicate; | 285 | List<SceneObjectPart> parts = new List<SceneObjectPart>(); |
286 | |||
287 | Action<SceneObjectGroup> searchAction; | ||
455 | 288 | ||
456 | if (useRegex) | 289 | if (useRegex) |
457 | { | 290 | { |
458 | Regex nameRegex = new Regex(name); | 291 | Regex nameRegex = new Regex(name); |
459 | searchPredicate = sop => nameRegex.IsMatch(sop.Name); | 292 | searchAction = so => so.ForEachPart(sop => { if (nameRegex.IsMatch(sop.Name)) { parts.Add(sop); } }); |
460 | } | 293 | } |
461 | else | 294 | else |
462 | { | 295 | { |
463 | searchPredicate = sop => sop.Name == name; | 296 | searchAction = so => so.ForEachPart(sop => { if (sop.Name == name) { parts.Add(sop); } }); |
464 | } | 297 | } |
465 | 298 | ||
466 | OutputSopsToConsole(searchPredicate, true); | 299 | m_scene.ForEachSOG(searchAction); |
467 | } | ||
468 | |||
469 | private void HandleDumpObjectById(string module, string[] cmdparams) | ||
470 | { | ||
471 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | ||
472 | return; | ||
473 | 300 | ||
474 | if (cmdparams.Length < 4) | 301 | if (parts.Count == 0) |
475 | { | 302 | { |
476 | m_console.OutputFormat("Usage: dump object id <UUID-or-localID>"); | 303 | m_console.OutputFormat("No parts with name {0} found in {1}", name, m_scene.RegionInfo.RegionName); |
477 | return; | 304 | return; |
478 | } | 305 | } |
479 | 306 | ||
480 | UUID objectUuid; | 307 | StringBuilder sb = new StringBuilder(); |
481 | uint localId; | ||
482 | if (!ConsoleUtil.TryParseConsoleId(m_console, cmdparams[3], out objectUuid, out localId)) | ||
483 | return; | ||
484 | |||
485 | SceneObjectGroup so; | ||
486 | if (localId == ConsoleUtil.LocalIdNotFound) | ||
487 | so = m_scene.GetSceneObjectGroup(objectUuid); | ||
488 | else | ||
489 | so = m_scene.GetSceneObjectGroup(localId); | ||
490 | 308 | ||
491 | if (so == null) | 309 | foreach (SceneObjectPart part in parts) |
492 | { | 310 | { |
493 | // m_console.OutputFormat("No part found with uuid {0}", objectUuid); | 311 | AddScenePartReport(sb, part); |
494 | return; | 312 | sb.Append("\n"); |
495 | } | 313 | } |
496 | 314 | ||
497 | // In case we found it via local ID. | 315 | m_console.OutputFormat(sb.ToString()); |
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); | ||
512 | } | 316 | } |
513 | 317 | ||
514 | /// <summary> | 318 | private StringBuilder AddSceneObjectReport(StringBuilder sb, SceneObjectGroup so) |
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) | ||
525 | { | 319 | { |
526 | if (showFull) | 320 | sb.AppendFormat("Name: {0}\n", so.Name); |
527 | { | 321 | sb.AppendFormat("Description: {0}\n", so.Description); |
528 | foreach (SceneObjectPart sop in so.Parts) | 322 | sb.AppendFormat("Location: {0} @ {1}\n", so.AbsolutePosition, so.Scene.RegionInfo.RegionName); |
529 | { | 323 | sb.AppendFormat("Parts: {0}\n", so.PrimCount); |
530 | AddScenePartReport(sb, sop, false); | 324 | sb.AppendFormat("Flags: {0}\n", so.RootPart.Flags); |
531 | sb.Append("\n"); | ||
532 | } | ||
533 | } | ||
534 | else | ||
535 | { | ||
536 | AddSummarySceneObjectReport(sb, so); | ||
537 | } | ||
538 | 325 | ||
539 | return sb; | 326 | return sb; |
540 | } | 327 | } |
541 | 328 | ||
542 | private StringBuilder AddSummarySceneObjectReport(StringBuilder sb, SceneObjectGroup so) | 329 | private StringBuilder AddScenePartReport(StringBuilder sb, SceneObjectPart sop) |
543 | { | ||
544 | ConsoleDisplayList cdl = new ConsoleDisplayList(); | ||
545 | cdl.AddRow("Name", so.Name); | ||
546 | cdl.AddRow("Descrition", so.Description); | ||
547 | cdl.AddRow("Local ID", so.LocalId); | ||
548 | cdl.AddRow("UUID", so.UUID); | ||
549 | cdl.AddRow("Location", string.Format("{0} @ {1}", so.AbsolutePosition, so.Scene.Name)); | ||
550 | cdl.AddRow("Parts", so.PrimCount); | ||
551 | cdl.AddRow("Flags", so.RootPart.Flags); | ||
552 | |||
553 | return sb.Append(cdl.ToString()); | ||
554 | } | ||
555 | |||
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 | { | 330 | { |
599 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); | 331 | sb.AppendFormat("Name: {0}\n", sop.Name); |
600 | cdt.Indent = 2; | 332 | sb.AppendFormat("Description: {0}\n", sop.Description); |
601 | 333 | sb.AppendFormat("Location: {0} @ {1}\n", sop.AbsolutePosition, sop.ParentGroup.Scene.RegionInfo.RegionName); | |
602 | cdt.AddColumn("Name", 50); | 334 | sb.AppendFormat("Parent: {0}", |
603 | cdt.AddColumn("Type", 12); | 335 | sop.IsRoot ? "Is Root\n" : string.Format("{0} {1}\n", sop.ParentGroup.Name, sop.ParentGroup.UUID)); |
604 | cdt.AddColumn("Running", 7); | 336 | sb.AppendFormat("Link number: {0}\n", sop.LinkNum); |
605 | cdt.AddColumn("Item UUID", 36); | 337 | sb.AppendFormat("Flags: {0}\n", sop.Flags); |
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 | 338 | ||
622 | return sb.Append(cdt.ToString()); | 339 | return sb; |
623 | } | 340 | } |
624 | 341 | ||
625 | private void HandleDeleteObject(string module, string[] cmd) | 342 | private void HandleDeleteObject(string module, string[] cmd) |
@@ -681,24 +398,19 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
681 | 398 | ||
682 | break; | 399 | break; |
683 | 400 | ||
684 | case "id": | 401 | case "uuid": |
685 | UUID uuid; | 402 | if (!UUID.TryParse(o, out match)) |
686 | uint localId; | ||
687 | if (!ConsoleUtil.TryParseConsoleId(m_console, o, out uuid, out localId)) | ||
688 | return; | 403 | return; |
689 | 404 | ||
690 | requireConfirmation = false; | 405 | requireConfirmation = false; |
691 | deletes = new List<SceneObjectGroup>(); | 406 | deletes = new List<SceneObjectGroup>(); |
692 | 407 | ||
693 | SceneObjectGroup so; | 408 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) |
694 | if (localId == ConsoleUtil.LocalIdNotFound) | 409 | { |
695 | so = m_scene.GetSceneObjectGroup(uuid); | 410 | if (g.UUID == match && !g.IsAttachment) |
696 | else | 411 | deletes.Add(g); |
697 | so = m_scene.GetSceneObjectGroup(localId); | 412 | }); |
698 | 413 | ||
699 | if (!so.IsAttachment) | ||
700 | deletes.Add(so); | ||
701 | |||
702 | // if (deletes.Count == 0) | 414 | // if (deletes.Count == 0) |
703 | // m_console.OutputFormat("No objects were found with uuid {0}", match); | 415 | // m_console.OutputFormat("No objects were found with uuid {0}", match); |
704 | 416 | ||
@@ -738,10 +450,6 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
738 | 450 | ||
739 | break; | 451 | break; |
740 | 452 | ||
741 | case "pos": | ||
742 | deletes = GetDeleteCandidatesByPos(module, cmd); | ||
743 | break; | ||
744 | |||
745 | default: | 453 | default: |
746 | m_console.OutputFormat("Unrecognized mode {0}", mode); | 454 | m_console.OutputFormat("Unrecognized mode {0}", mode); |
747 | return; | 455 | return; |
@@ -756,7 +464,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
756 | string.Format( | 464 | string.Format( |
757 | "Are you sure that you want to delete {0} objects from {1}", | 465 | "Are you sure that you want to delete {0} objects from {1}", |
758 | deletes.Count, m_scene.RegionInfo.RegionName), | 466 | deletes.Count, m_scene.RegionInfo.RegionName), |
759 | "y/N"); | 467 | "n"); |
760 | 468 | ||
761 | if (response.ToLower() != "y") | 469 | if (response.ToLower() != "y") |
762 | { | 470 | { |
@@ -778,6 +486,9 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
778 | 486 | ||
779 | private List<SceneObjectGroup> GetDeleteCandidatesByName(string module, string[] cmdparams) | 487 | private List<SceneObjectGroup> GetDeleteCandidatesByName(string module, string[] cmdparams) |
780 | { | 488 | { |
489 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | ||
490 | return null; | ||
491 | |||
781 | bool useRegex = false; | 492 | bool useRegex = false; |
782 | OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null ); | 493 | OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null ); |
783 | 494 | ||
@@ -811,52 +522,5 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
811 | 522 | ||
812 | return sceneObjects; | 523 | return sceneObjects; |
813 | } | 524 | } |
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 | } | ||
861 | } | 525 | } |
862 | } \ No newline at end of file | 526 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs index 513a8f5..14c1a39 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,110 +24,56 @@ | |||
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 | using System; | ||
28 | using System.IO; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | 27 | ||
28 | using System; | ||
32 | using Nini.Config; | 29 | using Nini.Config; |
33 | using OpenMetaverse; | 30 | using OpenMetaverse; |
34 | using log4net; | ||
35 | using Mono.Addins; | ||
36 | |||
37 | using OpenSim.Framework; | 31 | using OpenSim.Framework; |
38 | using OpenSim.Region.Framework.Interfaces; | 32 | using OpenSim.Region.Framework.Interfaces; |
39 | using OpenSim.Region.Framework.Scenes; | 33 | using OpenSim.Region.Framework.Scenes; |
34 | using System.Reflection; | ||
35 | using log4net; | ||
40 | 36 | ||
41 | namespace OpenSim.Region.CoreModules.World.Sound | 37 | namespace OpenSim.Region.CoreModules.World.Sound |
42 | { | 38 | { |
43 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SoundModule")] | 39 | public class SoundModule : IRegionModule, ISoundModule |
44 | public class SoundModule : INonSharedRegionModule, ISoundModule | ||
45 | { | 40 | { |
46 | private static readonly ILog m_log = LogManager.GetLogger( | 41 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
47 | MethodBase.GetCurrentMethod().DeclaringType); | 42 | |
48 | 43 | protected Scene m_scene; | |
49 | private Scene m_scene; | 44 | |
50 | 45 | public void Initialise(Scene scene, IConfigSource source) | |
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) | ||
78 | { | 46 | { |
79 | m_scene.EventManager.OnClientLogin -= OnNewClient; | ||
80 | } | ||
81 | |||
82 | public void RegionLoaded(Scene scene) | ||
83 | { | ||
84 | if (!Enabled) | ||
85 | return; | ||
86 | |||
87 | m_scene = scene; | 47 | m_scene = scene; |
88 | m_scene.EventManager.OnClientLogin += OnNewClient; | 48 | |
89 | 49 | m_scene.EventManager.OnNewClient += OnNewClient; | |
50 | |||
90 | m_scene.RegisterModuleInterface<ISoundModule>(this); | 51 | m_scene.RegisterModuleInterface<ISoundModule>(this); |
91 | } | 52 | } |
92 | 53 | ||
93 | public void Close() { } | 54 | public void PostInitialise() {} |
94 | 55 | public void Close() {} | |
95 | public Type ReplaceableInterface | ||
96 | { | ||
97 | get { return typeof(ISoundModule); } | ||
98 | } | ||
99 | |||
100 | public string Name { get { return "Sound Module"; } } | 56 | public string Name { get { return "Sound Module"; } } |
101 | 57 | public bool IsSharedModule { get { return false; } } | |
102 | #endregion | 58 | |
103 | |||
104 | #region Event Handlers | ||
105 | |||
106 | private void OnNewClient(IClientAPI client) | 59 | private void OnNewClient(IClientAPI client) |
107 | { | 60 | { |
108 | client.OnSoundTrigger += TriggerSound; | 61 | client.OnSoundTrigger += TriggerSound; |
109 | } | 62 | } |
110 | 63 | ||
111 | #endregion | ||
112 | |||
113 | #region ISoundModule | ||
114 | |||
115 | public virtual void PlayAttachedSound( | 64 | public virtual void PlayAttachedSound( |
116 | UUID soundID, UUID ownerID, UUID objectID, double gain, Vector3 position, byte flags, float radius) | 65 | UUID soundID, UUID ownerID, UUID objectID, double gain, Vector3 position, byte flags, float radius) |
117 | { | 66 | { |
118 | SceneObjectPart part; | 67 | SceneObjectPart part = m_scene.GetSceneObjectPart(objectID); |
119 | if (!m_scene.TryGetSceneObjectPart(objectID, out part)) | 68 | if (part == null) |
120 | return; | 69 | return; |
121 | 70 | ||
122 | SceneObjectGroup grp = part.ParentGroup; | 71 | SceneObjectGroup grp = part.ParentGroup; |
123 | 72 | ||
124 | if (radius == 0) | ||
125 | radius = MaxDistance; | ||
126 | |||
127 | m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) | 73 | m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) |
128 | { | 74 | { |
129 | double dis = Util.GetDistanceTo(sp.AbsolutePosition, position); | 75 | double dis = Util.GetDistanceTo(sp.AbsolutePosition, position); |
130 | if (dis > MaxDistance) // Max audio distance | 76 | if (dis > 100.0) // Max audio distance |
131 | return; | 77 | return; |
132 | 78 | ||
133 | if (grp.IsAttachment) | 79 | if (grp.IsAttachment) |
@@ -140,21 +86,23 @@ namespace OpenSim.Region.CoreModules.World.Sound | |||
140 | } | 86 | } |
141 | 87 | ||
142 | // Scale by distance | 88 | // Scale by distance |
143 | double thisSpGain = gain * ((radius - dis) / radius); | 89 | if (radius == 0) |
90 | gain = (float)((double)gain * ((100.0 - dis) / 100.0)); | ||
91 | else | ||
92 | gain = (float)((double)gain * ((radius - dis) / radius)); | ||
144 | 93 | ||
145 | sp.ControllingClient.SendPlayAttachedSound(soundID, objectID, | 94 | sp.ControllingClient.SendPlayAttachedSound(soundID, objectID, ownerID, (float)gain, flags); |
146 | ownerID, (float)thisSpGain, flags); | ||
147 | }); | 95 | }); |
148 | } | 96 | } |
149 | 97 | ||
150 | public virtual void TriggerSound( | 98 | public virtual void TriggerSound( |
151 | UUID soundId, UUID ownerID, UUID objectID, UUID parentID, double gain, Vector3 position, UInt64 handle, float radius) | 99 | UUID soundId, UUID ownerID, UUID objectID, UUID parentID, double gain, Vector3 position, UInt64 handle, float radius) |
152 | { | 100 | { |
153 | SceneObjectPart part; | 101 | SceneObjectPart part = m_scene.GetSceneObjectPart(objectID); |
154 | if (!m_scene.TryGetSceneObjectPart(objectID, out part)) | 102 | if (part == null) |
155 | { | 103 | { |
156 | ScenePresence sp; | 104 | ScenePresence sp; |
157 | if (!m_scene.TryGetScenePresence(ownerID, out sp)) | 105 | if (!m_scene.TryGetScenePresence(objectID, out sp)) |
158 | return; | 106 | return; |
159 | } | 107 | } |
160 | else | 108 | else |
@@ -168,207 +116,24 @@ namespace OpenSim.Region.CoreModules.World.Sound | |||
168 | } | 116 | } |
169 | } | 117 | } |
170 | 118 | ||
171 | if (radius == 0) | ||
172 | radius = MaxDistance; | ||
173 | |||
174 | m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) | 119 | m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) |
175 | { | 120 | { |
176 | double dis = Util.GetDistanceTo(sp.AbsolutePosition, position); | 121 | double dis = Util.GetDistanceTo(sp.AbsolutePosition, position); |
177 | 122 | ||
178 | if (dis > MaxDistance) // Max audio distance | 123 | if (dis > 100.0) // Max audio distance |
179 | return; | 124 | return; |
180 | 125 | ||
181 | // Scale by distance | 126 | float thisSpGain; |
182 | double thisSpGain = gain * ((radius - dis) / radius); | ||
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 | } | ||
328 | else | ||
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 | } | ||
341 | |||
342 | public void TriggerSoundLimited(UUID objectID, UUID sound, | ||
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 | 127 | ||
362 | // Scale by distance | 128 | // Scale by distance |
363 | double thisSpGain = volume * ((MaxDistance - dis) / MaxDistance); | 129 | if (radius == 0) |
130 | thisSpGain = (float)((double)gain * ((100.0 - dis) / 100.0)); | ||
131 | else | ||
132 | thisSpGain = (float)((double)gain * ((radius - dis) / radius)); | ||
364 | 133 | ||
365 | sp.ControllingClient.SendTriggeredSound(sound, part.OwnerID, | 134 | sp.ControllingClient.SendTriggeredSound( |
366 | part.UUID, part.ParentGroup.UUID, | 135 | soundId, ownerID, objectID, parentID, handle, position, thisSpGain); |
367 | m_scene.RegionInfo.RegionHandle, | ||
368 | part.AbsolutePosition, (float)thisSpGain); | ||
369 | }); | 136 | }); |
370 | } | 137 | } |
371 | |||
372 | #endregion | ||
373 | } | 138 | } |
374 | } | 139 | } |
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index d99567c..402b9fb 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs | |||
@@ -414,7 +414,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
414 | private void LoadPlugins() | 414 | private void LoadPlugins() |
415 | { | 415 | { |
416 | m_plugineffects = new Dictionary<string, ITerrainEffect>(); | 416 | m_plugineffects = new Dictionary<string, ITerrainEffect>(); |
417 | LoadPlugins(Assembly.GetCallingAssembly()); | ||
418 | string plugineffectsPath = "Terrain"; | 417 | string plugineffectsPath = "Terrain"; |
419 | 418 | ||
420 | // Load the files in the Terrain/ dir | 419 | // Load the files in the Terrain/ dir |
@@ -428,39 +427,34 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
428 | try | 427 | try |
429 | { | 428 | { |
430 | Assembly library = Assembly.LoadFrom(file); | 429 | Assembly library = Assembly.LoadFrom(file); |
431 | LoadPlugins(library); | 430 | foreach (Type pluginType in library.GetTypes()) |
432 | } | 431 | { |
433 | catch (BadImageFormatException) | 432 | try |
434 | { | 433 | { |
435 | } | 434 | if (pluginType.IsAbstract || pluginType.IsNotPublic) |
436 | } | 435 | continue; |
437 | } | ||
438 | |||
439 | private void LoadPlugins(Assembly library) | ||
440 | { | ||
441 | foreach (Type pluginType in library.GetTypes()) | ||
442 | { | ||
443 | try | ||
444 | { | ||
445 | if (pluginType.IsAbstract || pluginType.IsNotPublic) | ||
446 | continue; | ||
447 | 436 | ||
448 | string typeName = pluginType.Name; | 437 | string typeName = pluginType.Name; |
449 | 438 | ||
450 | if (pluginType.GetInterface("ITerrainEffect", false) != null) | 439 | if (pluginType.GetInterface("ITerrainEffect", false) != null) |
451 | { | 440 | { |
452 | ITerrainEffect terEffect = (ITerrainEffect)Activator.CreateInstance(library.GetType(pluginType.ToString())); | 441 | ITerrainEffect terEffect = (ITerrainEffect) Activator.CreateInstance(library.GetType(pluginType.ToString())); |
453 | 442 | ||
454 | InstallPlugin(typeName, terEffect); | 443 | InstallPlugin(typeName, terEffect); |
455 | } | 444 | } |
456 | else if (pluginType.GetInterface("ITerrainLoader", false) != null) | 445 | else if (pluginType.GetInterface("ITerrainLoader", false) != null) |
457 | { | 446 | { |
458 | ITerrainLoader terLoader = (ITerrainLoader)Activator.CreateInstance(library.GetType(pluginType.ToString())); | 447 | ITerrainLoader terLoader = (ITerrainLoader) Activator.CreateInstance(library.GetType(pluginType.ToString())); |
459 | m_loaders[terLoader.FileExtension] = terLoader; | 448 | m_loaders[terLoader.FileExtension] = terLoader; |
460 | m_log.Info("L ... " + typeName); | 449 | m_log.Info("L ... " + typeName); |
450 | } | ||
451 | } | ||
452 | catch (AmbiguousMatchException) | ||
453 | { | ||
454 | } | ||
461 | } | 455 | } |
462 | } | 456 | } |
463 | catch (AmbiguousMatchException) | 457 | catch (BadImageFormatException) |
464 | { | 458 | { |
465 | } | 459 | } |
466 | } | 460 | } |
@@ -1184,8 +1178,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1184 | 1178 | ||
1185 | private void InterfaceRunPluginEffect(Object[] args) | 1179 | private void InterfaceRunPluginEffect(Object[] args) |
1186 | { | 1180 | { |
1187 | string firstArg = (string)args[0]; | 1181 | if ((string) args[0] == "list") |
1188 | if (firstArg == "list") | ||
1189 | { | 1182 | { |
1190 | m_log.Info("List of loaded plugins"); | 1183 | m_log.Info("List of loaded plugins"); |
1191 | foreach (KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects) | 1184 | foreach (KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects) |
@@ -1194,14 +1187,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1194 | } | 1187 | } |
1195 | return; | 1188 | return; |
1196 | } | 1189 | } |
1197 | if (firstArg == "reload") | 1190 | if ((string) args[0] == "reload") |
1198 | { | 1191 | { |
1199 | LoadPlugins(); | 1192 | LoadPlugins(); |
1200 | return; | 1193 | return; |
1201 | } | 1194 | } |
1202 | if (m_plugineffects.ContainsKey(firstArg)) | 1195 | if (m_plugineffects.ContainsKey((string) args[0])) |
1203 | { | 1196 | { |
1204 | m_plugineffects[firstArg].RunEffect(m_channel); | 1197 | m_plugineffects[(string) args[0]].RunEffect(m_channel); |
1205 | CheckForTerrainUpdates(); | 1198 | CheckForTerrainUpdates(); |
1206 | } | 1199 | } |
1207 | else | 1200 | else |
diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs index 33f6c3f..3c48d07 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs | |||
@@ -222,13 +222,6 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
222 | bitmap = ImageUtils.ResizeImage(origBitmap, viewport.Width, viewport.Height); | 222 | bitmap = ImageUtils.ResizeImage(origBitmap, viewport.Width, viewport.Height); |
223 | } | 223 | } |
224 | 224 | ||
225 | // XXX: It shouldn't really be necesary to force a GC here as one should occur anyway pretty shortly | ||
226 | // afterwards. It's generally regarded as a bad idea to manually GC. If Warp3D is using lots of memory | ||
227 | // then this may be some issue with the Warp3D code itself, though it's also quite possible that generating | ||
228 | // this map tile simply takes a lot of memory. | ||
229 | GC.Collect(); | ||
230 | m_log.Debug("[WARP 3D IMAGE MODULE]: GC.Collect()"); | ||
231 | |||
232 | return bitmap; | 225 | return bitmap; |
233 | } | 226 | } |
234 | 227 | ||
diff --git a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs index dc54c3f..c5c96a9 100644 --- a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs | |||
@@ -130,25 +130,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms | |||
130 | m_scriptModule.PostScriptEvent(script, "link_message", args); | 130 | m_scriptModule.PostScriptEvent(script, "link_message", args); |
131 | } | 131 | } |
132 | 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) | 133 | public void RegisterScriptInvocation(object target, string meth) |
147 | { | 134 | { |
148 | MethodInfo mi = GetMethodInfoFromType(target.GetType(), meth, true); | 135 | MethodInfo mi = target.GetType().GetMethod(meth, |
136 | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); | ||
149 | if (mi == null) | 137 | if (mi == null) |
150 | { | 138 | { |
151 | m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}", meth); | 139 | m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}",meth); |
152 | return; | 140 | return; |
153 | } | 141 | } |
154 | 142 | ||
@@ -163,71 +151,38 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms | |||
163 | 151 | ||
164 | public void RegisterScriptInvocation(object target, MethodInfo mi) | 152 | public void RegisterScriptInvocation(object target, MethodInfo mi) |
165 | { | 153 | { |
166 | m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, (target is Type) ? ((Type)target).Name : target.GetType().Name); | 154 | m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, target.GetType().Name); |
167 | 155 | ||
168 | Type delegateType; | 156 | Type delegateType; |
169 | List<Type> typeArgs = mi.GetParameters() | 157 | var typeArgs = mi.GetParameters() |
170 | .Select(p => p.ParameterType) | 158 | .Select(p => p.ParameterType) |
171 | .ToList(); | 159 | .ToList(); |
172 | 160 | ||
173 | if (mi.ReturnType == typeof(void)) | 161 | if (mi.ReturnType == typeof(void)) |
174 | { | 162 | { |
175 | delegateType = Expression.GetActionType(typeArgs.ToArray()); | 163 | delegateType = Expression.GetActionType(typeArgs.ToArray()); |
176 | } | 164 | } |
177 | else | 165 | else |
178 | { | 166 | { |
179 | typeArgs.Add(mi.ReturnType); | 167 | typeArgs.Add(mi.ReturnType); |
180 | delegateType = Expression.GetFuncType(typeArgs.ToArray()); | 168 | delegateType = Expression.GetFuncType(typeArgs.ToArray()); |
181 | } | 169 | } |
182 | 170 | ||
183 | Delegate fcall; | 171 | Delegate fcall = Delegate.CreateDelegate(delegateType, target, mi); |
184 | if (!(target is Type)) | ||
185 | fcall = Delegate.CreateDelegate(delegateType, target, mi); | ||
186 | else | ||
187 | fcall = Delegate.CreateDelegate(delegateType, (Type)target, mi.Name); | ||
188 | 172 | ||
189 | lock (m_scriptInvocation) | 173 | lock (m_scriptInvocation) |
190 | { | 174 | { |
191 | ParameterInfo[] parameters = fcall.Method.GetParameters(); | 175 | ParameterInfo[] parameters = fcall.Method.GetParameters (); |
192 | if (parameters.Length < 2) // Must have two UUID params | 176 | if (parameters.Length < 2) // Must have two UUID params |
193 | return; | 177 | return; |
194 | 178 | ||
195 | // Hide the first two parameters | 179 | // Hide the first two parameters |
196 | Type[] parmTypes = new Type[parameters.Length - 2]; | 180 | Type[] parmTypes = new Type[parameters.Length - 2]; |
197 | for (int i = 2; i < parameters.Length; i++) | 181 | for (int i = 2 ; i < parameters.Length ; i++) |
198 | parmTypes[i - 2] = parameters[i].ParameterType; | 182 | parmTypes[i - 2] = parameters[i].ParameterType; |
199 | m_scriptInvocation[fcall.Method.Name] = new ScriptInvocationData(fcall.Method.Name, fcall, parmTypes, fcall.Method.ReturnType); | 183 | m_scriptInvocation[fcall.Method.Name] = new ScriptInvocationData(fcall.Method.Name, fcall, parmTypes, fcall.Method.ReturnType); |
200 | } | 184 | } |
201 | } | 185 | } |
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 | 186 | ||
232 | public Delegate[] GetScriptInvocationList() | 187 | public Delegate[] GetScriptInvocationList() |
233 | { | 188 | { |
@@ -330,20 +285,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms | |||
330 | } | 285 | } |
331 | } | 286 | } |
332 | 287 | ||
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> | 288 | /// <summary> |
348 | /// Operation to check for a registered constant | 289 | /// Operation to check for a registered constant |
349 | /// </summary> | 290 | /// </summary> |