diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs | 173 |
1 files changed, 161 insertions, 12 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs index 8add4bb..0aa4693 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs | |||
@@ -28,6 +28,7 @@ | |||
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; |
@@ -38,6 +39,13 @@ 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 List<UUID> defaultIDs = new List<UUID> { | ||
44 | new UUID("5748decc-f629-461c-9a36-a35a221fe21f"), | ||
45 | new UUID("7ca39b4c-bd19-4699-aff7-f93fd03d3e7b"), | ||
46 | new UUID("6522e74d-1660-4e7f-b601-6f48c1659a77"), | ||
47 | new UUID("c228d1cf-4b5d-4ba8-84f4-899a0796aa97") | ||
48 | }; | ||
41 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 49 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
42 | 50 | ||
43 | /// <summary> | 51 | /// <summary> |
@@ -85,6 +93,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
85 | 93 | ||
86 | private sbyte type = 0; | 94 | private sbyte type = 0; |
87 | private byte wearableType = 0; | 95 | private byte wearableType = 0; |
96 | private byte[] m_oldData = null; | ||
88 | public ulong XferID; | 97 | public ulong XferID; |
89 | private Scene m_Scene; | 98 | private Scene m_Scene; |
90 | 99 | ||
@@ -127,18 +136,27 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
127 | 136 | ||
128 | if (XferID == xferID) | 137 | if (XferID == xferID) |
129 | { | 138 | { |
130 | if (m_asset.Data.Length > 1) | 139 | lock (this) |
131 | { | 140 | { |
132 | byte[] destinationArray = new byte[m_asset.Data.Length + data.Length]; | 141 | int assetLength = m_asset.Data.Length; |
133 | Array.Copy(m_asset.Data, 0, destinationArray, 0, m_asset.Data.Length); | 142 | int dataLength = data.Length; |
134 | Array.Copy(data, 0, destinationArray, m_asset.Data.Length, data.Length); | 143 | |
135 | m_asset.Data = destinationArray; | 144 | if (m_asset.Data.Length > 1) |
136 | } | 145 | { |
137 | else | 146 | byte[] destinationArray = new byte[assetLength + dataLength]; |
138 | { | 147 | Array.Copy(m_asset.Data, 0, destinationArray, 0, assetLength); |
139 | byte[] buffer2 = new byte[data.Length - 4]; | 148 | Array.Copy(data, 0, destinationArray, assetLength, dataLength); |
140 | Array.Copy(data, 4, buffer2, 0, data.Length - 4); | 149 | m_asset.Data = destinationArray; |
141 | m_asset.Data = buffer2; | 150 | } |
151 | else | ||
152 | { | ||
153 | if (dataLength > 4) | ||
154 | { | ||
155 | byte[] buffer2 = new byte[dataLength - 4]; | ||
156 | Array.Copy(data, 4, buffer2, 0, dataLength - 4); | ||
157 | m_asset.Data = buffer2; | ||
158 | } | ||
159 | } | ||
142 | } | 160 | } |
143 | 161 | ||
144 | ourClient.SendConfirmXfer(xferID, packetID); | 162 | ourClient.SendConfirmXfer(xferID, packetID); |
@@ -393,6 +411,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
393 | 411 | ||
394 | private void CompleteCreateItem(uint callbackID) | 412 | private void CompleteCreateItem(uint callbackID) |
395 | { | 413 | { |
414 | ValidateAssets(); | ||
396 | m_Scene.AssetService.Store(m_asset); | 415 | m_Scene.AssetService.Store(m_asset); |
397 | 416 | ||
398 | InventoryItemBase item = new InventoryItemBase(); | 417 | InventoryItemBase item = new InventoryItemBase(); |
@@ -413,6 +432,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
413 | item.Flags = (uint) wearableType; | 432 | item.Flags = (uint) wearableType; |
414 | item.CreationDate = Util.UnixTimeSinceEpoch(); | 433 | item.CreationDate = Util.UnixTimeSinceEpoch(); |
415 | 434 | ||
435 | m_log.DebugFormat("[XFER]: Created item {0} with asset {1}", | ||
436 | item.ID, item.AssetID); | ||
437 | |||
416 | if (m_Scene.AddInventoryItem(item)) | 438 | if (m_Scene.AddInventoryItem(item)) |
417 | ourClient.SendInventoryItemCreateUpdate(item, callbackID); | 439 | ourClient.SendInventoryItemCreateUpdate(item, callbackID); |
418 | else | 440 | else |
@@ -420,5 +442,132 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
420 | 442 | ||
421 | m_transactions.RemoveXferUploader(m_transactionID); | 443 | m_transactions.RemoveXferUploader(m_transactionID); |
422 | } | 444 | } |
445 | |||
446 | private void ValidateAssets() | ||
447 | { | ||
448 | if (m_asset.Type == (sbyte)AssetType.Clothing || | ||
449 | m_asset.Type == (sbyte)AssetType.Bodypart) | ||
450 | { | ||
451 | string content = System.Text.Encoding.ASCII.GetString(m_asset.Data); | ||
452 | string[] lines = content.Split(new char[] {'\n'}); | ||
453 | |||
454 | List<string> validated = new List<string>(); | ||
455 | |||
456 | Dictionary<int, UUID> allowed = ExtractTexturesFromOldData(); | ||
457 | |||
458 | int textures = 0; | ||
459 | |||
460 | foreach (string line in lines) | ||
461 | { | ||
462 | try | ||
463 | { | ||
464 | if (line.StartsWith("textures ")) | ||
465 | { | ||
466 | textures = Convert.ToInt32(line.Substring(9)); | ||
467 | validated.Add(line); | ||
468 | } | ||
469 | else if (textures > 0) | ||
470 | { | ||
471 | string[] parts = line.Split(new char[] {' '}); | ||
472 | |||
473 | UUID tx = new UUID(parts[1]); | ||
474 | int id = Convert.ToInt32(parts[0]); | ||
475 | |||
476 | if (defaultIDs.Contains(tx) || tx == UUID.Zero || | ||
477 | (allowed.ContainsKey(id) && allowed[id] == tx)) | ||
478 | { | ||
479 | validated.Add(parts[0] + " " + tx.ToString()); | ||
480 | } | ||
481 | else | ||
482 | { | ||
483 | int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, tx); | ||
484 | int full = (int)(PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Copy); | ||
485 | |||
486 | if ((perms & full) != full) | ||
487 | { | ||
488 | m_log.ErrorFormat("[ASSET UPLOADER]: REJECTED update with texture {0} from {1} because they do not own the texture", tx, ourClient.AgentId); | ||
489 | validated.Add(parts[0] + " " + UUID.Zero.ToString()); | ||
490 | } | ||
491 | else | ||
492 | { | ||
493 | validated.Add(line); | ||
494 | } | ||
495 | } | ||
496 | textures--; | ||
497 | } | ||
498 | else | ||
499 | { | ||
500 | validated.Add(line); | ||
501 | } | ||
502 | } | ||
503 | catch | ||
504 | { | ||
505 | // If it's malformed, skip it | ||
506 | } | ||
507 | } | ||
508 | |||
509 | string final = String.Join("\n", validated.ToArray()); | ||
510 | |||
511 | m_asset.Data = System.Text.Encoding.ASCII.GetBytes(final); | ||
512 | } | ||
513 | } | ||
514 | |||
515 | /// <summary> | ||
516 | /// Get the asset data uploaded in this transfer. | ||
517 | /// </summary> | ||
518 | /// <returns>null if the asset has not finished uploading</returns> | ||
519 | public AssetBase GetAssetData() | ||
520 | { | ||
521 | if (m_uploadState == UploadState.Complete) | ||
522 | { | ||
523 | ValidateAssets(); | ||
524 | return m_asset; | ||
525 | } | ||
526 | |||
527 | return null; | ||
528 | } | ||
529 | |||
530 | public void SetOldData(byte[] d) | ||
531 | { | ||
532 | m_oldData = d; | ||
533 | } | ||
534 | |||
535 | private Dictionary<int,UUID> ExtractTexturesFromOldData() | ||
536 | { | ||
537 | Dictionary<int,UUID> result = new Dictionary<int,UUID>(); | ||
538 | if (m_oldData == null) | ||
539 | return result; | ||
540 | |||
541 | string content = System.Text.Encoding.ASCII.GetString(m_oldData); | ||
542 | string[] lines = content.Split(new char[] {'\n'}); | ||
543 | |||
544 | int textures = 0; | ||
545 | |||
546 | foreach (string line in lines) | ||
547 | { | ||
548 | try | ||
549 | { | ||
550 | if (line.StartsWith("textures ")) | ||
551 | { | ||
552 | textures = Convert.ToInt32(line.Substring(9)); | ||
553 | } | ||
554 | else if (textures > 0) | ||
555 | { | ||
556 | string[] parts = line.Split(new char[] {' '}); | ||
557 | |||
558 | UUID tx = new UUID(parts[1]); | ||
559 | int id = Convert.ToInt32(parts[0]); | ||
560 | result[id] = tx; | ||
561 | textures--; | ||
562 | } | ||
563 | } | ||
564 | catch | ||
565 | { | ||
566 | // If it's malformed, skip it | ||
567 | } | ||
568 | } | ||
569 | |||
570 | return result; | ||
571 | } | ||
423 | } | 572 | } |
424 | } \ No newline at end of file | 573 | } |