diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs | 158 |
1 files changed, 140 insertions, 18 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs index 4609738..b8c8c85 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs | |||
@@ -28,16 +28,19 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.IO; | 29 | using System.IO; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using System.Collections.Generic; | ||
31 | using log4net; | 32 | using log4net; |
32 | using OpenMetaverse; | 33 | using OpenMetaverse; |
33 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
34 | 35 | using OpenSim.Region.Framework.Scenes; | |
35 | using OpenSim.Services.Interfaces; | 36 | using OpenSim.Services.Interfaces; |
36 | 37 | ||
37 | namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | 38 | namespace OpenSim.Region.CoreModules.Agent.AssetTransaction |
38 | { | 39 | { |
39 | public class AssetXferUploader | 40 | public class AssetXferUploader |
40 | { | 41 | { |
42 | // Viewer's notion of the default texture | ||
43 | private UUID defaultID = new UUID("5748decc-f629-461c-9a36-a35a221fe21f"); | ||
41 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 44 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
42 | 45 | ||
43 | private AssetBase m_asset; | 46 | private AssetBase m_asset; |
@@ -50,17 +53,18 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
50 | private bool m_finished = false; | 53 | private bool m_finished = false; |
51 | private string m_name = String.Empty; | 54 | private string m_name = String.Empty; |
52 | private bool m_storeLocal; | 55 | private bool m_storeLocal; |
53 | private AgentAssetTransactions m_userTransactions; | ||
54 | private uint nextPerm = 0; | 56 | private uint nextPerm = 0; |
55 | private IClientAPI ourClient; | 57 | private IClientAPI ourClient; |
56 | private UUID TransactionID = UUID.Zero; | 58 | private UUID TransactionID = UUID.Zero; |
57 | private sbyte type = 0; | 59 | private sbyte type = 0; |
58 | private byte wearableType = 0; | 60 | private byte wearableType = 0; |
61 | private byte[] m_oldData = null; | ||
59 | public ulong XferID; | 62 | public ulong XferID; |
63 | private Scene m_Scene; | ||
60 | 64 | ||
61 | public AssetXferUploader(AgentAssetTransactions transactions, bool dumpAssetToFile) | 65 | public AssetXferUploader(Scene scene, bool dumpAssetToFile) |
62 | { | 66 | { |
63 | m_userTransactions = transactions; | 67 | m_Scene = scene; |
64 | m_dumpAssetToFile = dumpAssetToFile; | 68 | m_dumpAssetToFile = dumpAssetToFile; |
65 | } | 69 | } |
66 | 70 | ||
@@ -108,11 +112,13 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
108 | /// <param name="packetID"></param> | 112 | /// <param name="packetID"></param> |
109 | /// <param name="data"></param> | 113 | /// <param name="data"></param> |
110 | /// <returns>True if the transfer is complete, false otherwise</returns> | 114 | /// <returns>True if the transfer is complete, false otherwise</returns> |
111 | public bool Initialise(IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type, byte[] data, | 115 | public bool Initialise(IClientAPI remoteClient, UUID assetID, |
112 | bool storeLocal, bool tempFile) | 116 | UUID transaction, sbyte type, byte[] data, bool storeLocal, |
117 | bool tempFile) | ||
113 | { | 118 | { |
114 | ourClient = remoteClient; | 119 | ourClient = remoteClient; |
115 | m_asset = new AssetBase(assetID, "blank", type, remoteClient.AgentId.ToString()); | 120 | m_asset = new AssetBase(assetID, "blank", type, |
121 | remoteClient.AgentId.ToString()); | ||
116 | m_asset.Data = data; | 122 | m_asset.Data = data; |
117 | m_asset.Description = "empty"; | 123 | m_asset.Description = "empty"; |
118 | m_asset.Local = storeLocal; | 124 | m_asset.Local = storeLocal; |
@@ -137,12 +143,14 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
137 | protected void RequestStartXfer() | 143 | protected void RequestStartXfer() |
138 | { | 144 | { |
139 | XferID = Util.GetNextXferID(); | 145 | XferID = Util.GetNextXferID(); |
140 | ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, 0, new byte[0]); | 146 | ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, |
147 | 0, new byte[0]); | ||
141 | } | 148 | } |
142 | 149 | ||
143 | protected void SendCompleteMessage() | 150 | protected void SendCompleteMessage() |
144 | { | 151 | { |
145 | ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, m_asset.FullID); | 152 | ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, |
153 | m_asset.FullID); | ||
146 | 154 | ||
147 | m_finished = true; | 155 | m_finished = true; |
148 | if (m_createItem) | 156 | if (m_createItem) |
@@ -151,18 +159,20 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
151 | } | 159 | } |
152 | else if (m_storeLocal) | 160 | else if (m_storeLocal) |
153 | { | 161 | { |
154 | m_userTransactions.Manager.MyScene.AssetService.Store(m_asset); | 162 | m_Scene.AssetService.Store(m_asset); |
155 | } | 163 | } |
156 | 164 | ||
157 | m_log.DebugFormat( | 165 | m_log.DebugFormat( |
158 | "[ASSET TRANSACTIONS]: Uploaded asset {0} for transaction {1}", m_asset.FullID, TransactionID); | 166 | "[ASSET TRANSACTIONS]: Uploaded asset {0} for transaction {1}", |
167 | m_asset.FullID, TransactionID); | ||
159 | 168 | ||
160 | if (m_dumpAssetToFile) | 169 | if (m_dumpAssetToFile) |
161 | { | 170 | { |
162 | DateTime now = DateTime.Now; | 171 | DateTime now = DateTime.Now; |
163 | string filename = | 172 | string filename = |
164 | String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat", now.Year, now.Month, now.Day, | 173 | String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat", |
165 | now.Hour, now.Minute, now.Second, m_asset.Name, m_asset.Type); | 174 | now.Year, now.Month, now.Day, now.Hour, now.Minute, |
175 | now.Second, m_asset.Name, m_asset.Type); | ||
166 | SaveAssetToFile(filename, m_asset.Data); | 176 | SaveAssetToFile(filename, m_asset.Data); |
167 | } | 177 | } |
168 | } | 178 | } |
@@ -181,9 +191,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
181 | fs.Close(); | 191 | fs.Close(); |
182 | } | 192 | } |
183 | 193 | ||
184 | public void RequestCreateInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID, | 194 | public void RequestCreateInventoryItem(IClientAPI remoteClient, |
185 | uint callbackID, string description, string name, sbyte invType, | 195 | UUID transactionID, UUID folderID, uint callbackID, |
186 | sbyte type, byte wearableType, uint nextOwnerMask) | 196 | string description, string name, sbyte invType, |
197 | sbyte type, byte wearableType, uint nextOwnerMask) | ||
187 | { | 198 | { |
188 | if (TransactionID == transactionID) | 199 | if (TransactionID == transactionID) |
189 | { | 200 | { |
@@ -212,7 +223,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
212 | 223 | ||
213 | private void DoCreateItem(uint callbackID) | 224 | private void DoCreateItem(uint callbackID) |
214 | { | 225 | { |
215 | m_userTransactions.Manager.MyScene.AssetService.Store(m_asset); | 226 | ValidateAssets(); |
227 | m_Scene.AssetService.Store(m_asset); | ||
216 | 228 | ||
217 | InventoryItemBase item = new InventoryItemBase(); | 229 | InventoryItemBase item = new InventoryItemBase(); |
218 | item.Owner = ourClient.AgentId; | 230 | item.Owner = ourClient.AgentId; |
@@ -232,12 +244,77 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
232 | item.Flags = (uint) wearableType; | 244 | item.Flags = (uint) wearableType; |
233 | item.CreationDate = Util.UnixTimeSinceEpoch(); | 245 | item.CreationDate = Util.UnixTimeSinceEpoch(); |
234 | 246 | ||
235 | if (m_userTransactions.Manager.MyScene.AddInventoryItem(item)) | 247 | if (m_Scene.AddInventoryItem(item)) |
236 | ourClient.SendInventoryItemCreateUpdate(item, callbackID); | 248 | ourClient.SendInventoryItemCreateUpdate(item, callbackID); |
237 | else | 249 | else |
238 | ourClient.SendAlertMessage("Unable to create inventory item"); | 250 | ourClient.SendAlertMessage("Unable to create inventory item"); |
239 | } | 251 | } |
240 | 252 | ||
253 | private void ValidateAssets() | ||
254 | { | ||
255 | if (m_asset.Type == (sbyte)AssetType.Clothing || | ||
256 | m_asset.Type == (sbyte)AssetType.Bodypart) | ||
257 | { | ||
258 | string content = System.Text.Encoding.ASCII.GetString(m_asset.Data); | ||
259 | string[] lines = content.Split(new char[] {'\n'}); | ||
260 | |||
261 | List<string> validated = new List<string>(); | ||
262 | |||
263 | Dictionary<int, UUID> allowed = ExtractTexturesFromOldData(); | ||
264 | |||
265 | int textures = 0; | ||
266 | |||
267 | foreach (string line in lines) | ||
268 | { | ||
269 | try | ||
270 | { | ||
271 | if (line.StartsWith("textures ")) | ||
272 | { | ||
273 | textures = Convert.ToInt32(line.Substring(9)); | ||
274 | validated.Add(line); | ||
275 | } | ||
276 | else if (textures > 0) | ||
277 | { | ||
278 | string[] parts = line.Split(new char[] {' '}); | ||
279 | |||
280 | UUID tx = new UUID(parts[1]); | ||
281 | int id = Convert.ToInt32(parts[0]); | ||
282 | |||
283 | if (tx == defaultID || tx == UUID.Zero || | ||
284 | (allowed.ContainsKey(id) && allowed[id] == tx)) | ||
285 | { | ||
286 | validated.Add(parts[0] + " " + tx.ToString()); | ||
287 | } | ||
288 | else | ||
289 | { | ||
290 | int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, tx); | ||
291 | int full = (int)(PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Copy); | ||
292 | |||
293 | if ((perms & full) != full) | ||
294 | { | ||
295 | m_log.ErrorFormat("[ASSET UPLOADER]: REJECTED update with texture {0} from {1} because they do not own the texture", tx, ourClient.AgentId); | ||
296 | validated.Add(parts[0] + " " + defaultID.ToString()); | ||
297 | } | ||
298 | } | ||
299 | textures--; | ||
300 | } | ||
301 | else | ||
302 | { | ||
303 | validated.Add(line); | ||
304 | } | ||
305 | } | ||
306 | catch | ||
307 | { | ||
308 | // If it's malformed, skip it | ||
309 | } | ||
310 | } | ||
311 | |||
312 | string final = String.Join("\n", validated.ToArray()); | ||
313 | |||
314 | m_asset.Data = System.Text.Encoding.ASCII.GetBytes(final); | ||
315 | } | ||
316 | } | ||
317 | |||
241 | /// <summary> | 318 | /// <summary> |
242 | /// Get the asset data uploaded in this transfer. | 319 | /// Get the asset data uploaded in this transfer. |
243 | /// </summary> | 320 | /// </summary> |
@@ -246,10 +323,55 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
246 | { | 323 | { |
247 | if (m_finished) | 324 | if (m_finished) |
248 | { | 325 | { |
326 | ValidateAssets(); | ||
249 | return m_asset; | 327 | return m_asset; |
250 | } | 328 | } |
251 | 329 | ||
252 | return null; | 330 | return null; |
253 | } | 331 | } |
332 | |||
333 | public void SetOldData(byte[] d) | ||
334 | { | ||
335 | m_oldData = d; | ||
336 | } | ||
337 | |||
338 | private Dictionary<int,UUID> ExtractTexturesFromOldData() | ||
339 | { | ||
340 | Dictionary<int,UUID> result = new Dictionary<int,UUID>(); | ||
341 | if (m_oldData == null) | ||
342 | return result; | ||
343 | |||
344 | string content = System.Text.Encoding.ASCII.GetString(m_oldData); | ||
345 | string[] lines = content.Split(new char[] {'\n'}); | ||
346 | |||
347 | int textures = 0; | ||
348 | |||
349 | foreach (string line in lines) | ||
350 | { | ||
351 | try | ||
352 | { | ||
353 | if (line.StartsWith("textures ")) | ||
354 | { | ||
355 | textures = Convert.ToInt32(line.Substring(9)); | ||
356 | } | ||
357 | else if (textures > 0) | ||
358 | { | ||
359 | string[] parts = line.Split(new char[] {' '}); | ||
360 | |||
361 | UUID tx = new UUID(parts[1]); | ||
362 | int id = Convert.ToInt32(parts[0]); | ||
363 | result[id] = tx; | ||
364 | textures--; | ||
365 | } | ||
366 | } | ||
367 | catch | ||
368 | { | ||
369 | // If it's malformed, skip it | ||
370 | } | ||
371 | } | ||
372 | |||
373 | return result; | ||
374 | } | ||
254 | } | 375 | } |
255 | } | 376 | } |
377 | |||