diff options
9 files changed, 295 insertions, 436 deletions
diff --git a/OpenSim/Framework/Communications/Cache/AssetCache.cs b/OpenSim/Framework/Communications/Cache/AssetCache.cs index d5ac67b..c164f0c 100644 --- a/OpenSim/Framework/Communications/Cache/AssetCache.cs +++ b/OpenSim/Framework/Communications/Cache/AssetCache.cs | |||
@@ -36,8 +36,7 @@ using OpenSim.Framework.Console; | |||
36 | 36 | ||
37 | namespace OpenSim.Framework.Communications.Cache | 37 | namespace OpenSim.Framework.Communications.Cache |
38 | { | 38 | { |
39 | public delegate void DownloadComplete(AssetCache.TextureSender sender); | 39 | |
40 | |||
41 | public delegate void AssetRequestCallback(LLUUID assetID, AssetBase asset); | 40 | public delegate void AssetRequestCallback(LLUUID assetID, AssetBase asset); |
42 | 41 | ||
43 | /// <summary> | 42 | /// <summary> |
@@ -57,21 +56,11 @@ namespace OpenSim.Framework.Communications.Cache | |||
57 | public Dictionary<LLUUID, AssetRequest> RequestedTextures = new Dictionary<LLUUID, AssetRequest>(); | 56 | public Dictionary<LLUUID, AssetRequest> RequestedTextures = new Dictionary<LLUUID, AssetRequest>(); |
58 | //Textures requested from the asset server | 57 | //Textures requested from the asset server |
59 | 58 | ||
60 | public Dictionary<LLUUID, TextureSender> SendingTextures = new Dictionary<LLUUID, TextureSender>(); | ||
61 | |||
62 | public Dictionary<LLUUID, AssetRequestsList> RequestLists = new Dictionary<LLUUID, AssetRequestsList>(); | 59 | public Dictionary<LLUUID, AssetRequestsList> RequestLists = new Dictionary<LLUUID, AssetRequestsList>(); |
63 | 60 | ||
64 | private BlockingQueue<TextureSender> m_queueTextures = new BlockingQueue<TextureSender>(); | ||
65 | private Dictionary<LLUUID, List<LLUUID>> m_avatarReceivedTextures = new Dictionary<LLUUID, List<LLUUID>>(); | ||
66 | |||
67 | private Dictionary<LLUUID, Dictionary<LLUUID, int>> m_timesTextureSent = | ||
68 | new Dictionary<LLUUID, Dictionary<LLUUID, int>>(); | ||
69 | |||
70 | |||
71 | private IAssetServer m_assetServer; | 61 | private IAssetServer m_assetServer; |
72 | 62 | ||
73 | private Thread m_assetCacheThread; | 63 | private Thread m_assetCacheThread; |
74 | private Thread m_textureSenderThread; | ||
75 | private LogBase m_log; | 64 | private LogBase m_log; |
76 | 65 | ||
77 | /// <summary> | 66 | /// <summary> |
@@ -88,9 +77,7 @@ namespace OpenSim.Framework.Communications.Cache | |||
88 | m_assetCacheThread.IsBackground = true; | 77 | m_assetCacheThread.IsBackground = true; |
89 | m_assetCacheThread.Start(); | 78 | m_assetCacheThread.Start(); |
90 | 79 | ||
91 | m_textureSenderThread = new Thread(new ThreadStart(ProcessTextureSenders)); | 80 | |
92 | m_textureSenderThread.IsBackground = true; | ||
93 | m_textureSenderThread.Start(); | ||
94 | m_log = log; | 81 | m_log = log; |
95 | } | 82 | } |
96 | 83 | ||
@@ -104,7 +91,6 @@ namespace OpenSim.Framework.Communications.Cache | |||
104 | try | 91 | try |
105 | { | 92 | { |
106 | ProcessAssetQueue(); | 93 | ProcessAssetQueue(); |
107 | ProcessTextureQueue(); | ||
108 | Thread.Sleep(500); | 94 | Thread.Sleep(500); |
109 | } | 95 | } |
110 | catch (Exception e) | 96 | catch (Exception e) |
@@ -188,7 +174,7 @@ namespace OpenSim.Framework.Communications.Cache | |||
188 | 174 | ||
189 | if (asset.Type == 0) | 175 | if (asset.Type == 0) |
190 | { | 176 | { |
191 | if(Textures.ContainsKey(asset.FullID)) | 177 | if (Textures.ContainsKey(asset.FullID)) |
192 | { | 178 | { |
193 | result = "Duplicate ignored."; | 179 | result = "Duplicate ignored."; |
194 | } | 180 | } |
@@ -250,67 +236,7 @@ namespace OpenSim.Framework.Communications.Cache | |||
250 | return asset; | 236 | return asset; |
251 | } | 237 | } |
252 | 238 | ||
253 | /// <summary> | ||
254 | /// | ||
255 | /// </summary> | ||
256 | private void ProcessTextureQueue() | ||
257 | { | ||
258 | if (TextureRequests.Count == 0) | ||
259 | { | ||
260 | //no requests waiting | ||
261 | return; | ||
262 | } | ||
263 | int num; | ||
264 | num = TextureRequests.Count; | ||
265 | 239 | ||
266 | AssetRequest req; | ||
267 | for (int i = 0; i < num; i++) | ||
268 | { | ||
269 | req = (AssetRequest) TextureRequests[i]; | ||
270 | if (!SendingTextures.ContainsKey(req.ImageInfo.FullID)) | ||
271 | { | ||
272 | //Console.WriteLine("new texture to send"); | ||
273 | TextureSender sender = new TextureSender(req); | ||
274 | //sender.OnComplete += this.TextureSent; | ||
275 | SendingTextures.Add(req.ImageInfo.FullID, sender); | ||
276 | m_queueTextures.Enqueue(sender); | ||
277 | } | ||
278 | } | ||
279 | |||
280 | TextureRequests.Clear(); | ||
281 | } | ||
282 | |||
283 | public void ProcessTextureSenders() | ||
284 | { | ||
285 | while (true) | ||
286 | { | ||
287 | TextureSender sender = m_queueTextures.Dequeue(); | ||
288 | |||
289 | bool finished = sender.SendTexture(); | ||
290 | if (finished) | ||
291 | { | ||
292 | TextureSent(sender); | ||
293 | } | ||
294 | else | ||
295 | { | ||
296 | // Console.WriteLine("readding texture"); | ||
297 | m_queueTextures.Enqueue(sender); | ||
298 | } | ||
299 | } | ||
300 | } | ||
301 | |||
302 | /// <summary> | ||
303 | /// Event handler, called by a TextureSender object to say that texture has been sent | ||
304 | /// </summary> | ||
305 | /// <param name="sender"></param> | ||
306 | public void TextureSent(TextureSender sender) | ||
307 | { | ||
308 | if (SendingTextures.ContainsKey(sender.request.ImageInfo.FullID)) | ||
309 | { | ||
310 | SendingTextures.Remove(sender.request.ImageInfo.FullID); | ||
311 | // this.m_avatarReceivedTextures[sender.request.RequestUser.AgentId].Add(sender.request.ImageInfo.FullID); | ||
312 | } | ||
313 | } | ||
314 | 240 | ||
315 | public void AssetReceived(AssetBase asset, bool IsTexture) | 241 | public void AssetReceived(AssetBase asset, bool IsTexture) |
316 | { | 242 | { |
@@ -354,7 +280,7 @@ namespace OpenSim.Framework.Communications.Cache | |||
354 | if (assetInf.Data.LongLength > 600) | 280 | if (assetInf.Data.LongLength > 600) |
355 | { | 281 | { |
356 | //over 600 bytes so split up file | 282 | //over 600 bytes so split up file |
357 | req.NumPackets = 1 + (int) (assetInf.Data.Length - 600 + 999)/1000; | 283 | req.NumPackets = 1 + (int)(assetInf.Data.Length - 600 + 999) / 1000; |
358 | } | 284 | } |
359 | else | 285 | else |
360 | { | 286 | { |
@@ -400,6 +326,20 @@ namespace OpenSim.Framework.Communications.Cache | |||
400 | //} | 326 | //} |
401 | } | 327 | } |
402 | 328 | ||
329 | private int CalculateNumPackets(int length) | ||
330 | { | ||
331 | int numPackets = 1; | ||
332 | |||
333 | if (length > 600) | ||
334 | { | ||
335 | //over 600 bytes so split up file | ||
336 | int restData = (length - 600); | ||
337 | int restPackets = ((restData + 999) / 1000); | ||
338 | numPackets = 1 + restPackets; | ||
339 | } | ||
340 | |||
341 | return numPackets; | ||
342 | } | ||
403 | #region Assets | 343 | #region Assets |
404 | 344 | ||
405 | /// <summary> | 345 | /// <summary> |
@@ -458,7 +398,7 @@ namespace OpenSim.Framework.Communications.Cache | |||
458 | if (asset.Data.LongLength > 600) | 398 | if (asset.Data.LongLength > 600) |
459 | { | 399 | { |
460 | //over 600 bytes so split up file | 400 | //over 600 bytes so split up file |
461 | req.NumPackets = 1 + (int) (asset.Data.Length - 600 + 999)/1000; | 401 | req.NumPackets = 1 + (int)(asset.Data.Length - 600 + 999) / 1000; |
462 | } | 402 | } |
463 | else | 403 | else |
464 | { | 404 | { |
@@ -473,6 +413,7 @@ namespace OpenSim.Framework.Communications.Cache | |||
473 | /// </summary> | 413 | /// </summary> |
474 | private void ProcessAssetQueue() | 414 | private void ProcessAssetQueue() |
475 | { | 415 | { |
416 | //should move the asset downloading to a module, like has been done with texture downloading | ||
476 | if (AssetRequests.Count == 0) | 417 | if (AssetRequests.Count == 0) |
477 | { | 418 | { |
478 | //no requests waiting | 419 | //no requests waiting |
@@ -492,7 +433,7 @@ namespace OpenSim.Framework.Communications.Cache | |||
492 | AssetRequest req; | 433 | AssetRequest req; |
493 | for (int i = 0; i < num; i++) | 434 | for (int i = 0; i < num; i++) |
494 | { | 435 | { |
495 | req = (AssetRequest) AssetRequests[i]; | 436 | req = (AssetRequest)AssetRequests[i]; |
496 | //Console.WriteLine("sending asset " + req.RequestAssetID); | 437 | //Console.WriteLine("sending asset " + req.RequestAssetID); |
497 | TransferInfoPacket Transfer = new TransferInfoPacket(); | 438 | TransferInfoPacket Transfer = new TransferInfoPacket(); |
498 | Transfer.TransferInfo.ChannelType = 2; | 439 | Transfer.TransferInfo.ChannelType = 2; |
@@ -502,7 +443,7 @@ namespace OpenSim.Framework.Communications.Cache | |||
502 | { | 443 | { |
503 | Transfer.TransferInfo.Params = new byte[20]; | 444 | Transfer.TransferInfo.Params = new byte[20]; |
504 | Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); | 445 | Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); |
505 | int assType = (int) req.AssetInf.Type; | 446 | int assType = (int)req.AssetInf.Type; |
506 | Array.Copy(Helpers.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4); | 447 | Array.Copy(Helpers.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4); |
507 | } | 448 | } |
508 | else if (req.AssetRequestSource == 3) | 449 | else if (req.AssetRequestSource == 3) |
@@ -512,9 +453,9 @@ namespace OpenSim.Framework.Communications.Cache | |||
512 | //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); | 453 | //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); |
513 | //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16); | 454 | //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16); |
514 | } | 455 | } |
515 | Transfer.TransferInfo.Size = (int) req.AssetInf.Data.Length; | 456 | Transfer.TransferInfo.Size = (int)req.AssetInf.Data.Length; |
516 | Transfer.TransferInfo.TransferID = req.TransferRequestID; | 457 | Transfer.TransferInfo.TransferID = req.TransferRequestID; |
517 | req.RequestUser.OutPacket(Transfer,ThrottleOutPacketType.Asset); | 458 | req.RequestUser.OutPacket(Transfer, ThrottleOutPacketType.Asset); |
518 | 459 | ||
519 | if (req.NumPackets == 1) | 460 | if (req.NumPackets == 1) |
520 | { | 461 | { |
@@ -573,79 +514,6 @@ namespace OpenSim.Framework.Communications.Cache | |||
573 | 514 | ||
574 | #endregion | 515 | #endregion |
575 | 516 | ||
576 | #region Textures | ||
577 | |||
578 | /// <summary> | ||
579 | /// | ||
580 | /// </summary> | ||
581 | /// <param name="userInfo"></param> | ||
582 | /// <param name="imageID"></param> | ||
583 | public void AddTextureRequest(IClientAPI userInfo, LLUUID imageID, uint packetNumber, int discard) | ||
584 | { | ||
585 | // System.Console.WriteLine("texture request for " + imageID.ToStringHyphenated() + " packetnumber= " + packetNumber); | ||
586 | //check to see if texture is in local cache, if not request from asset server | ||
587 | if (!m_avatarReceivedTextures.ContainsKey(userInfo.AgentId)) | ||
588 | { | ||
589 | m_avatarReceivedTextures.Add(userInfo.AgentId, new List<LLUUID>()); | ||
590 | } | ||
591 | /* if(this.m_avatarReceivedTextures[userInfo.AgentId].Contains(imageID)) | ||
592 | { | ||
593 | //Console.WriteLine(userInfo.AgentId +" is requesting a image( "+ imageID+" that has already been sent to them"); | ||
594 | return; | ||
595 | }*/ | ||
596 | |||
597 | if (!Textures.ContainsKey(imageID)) | ||
598 | { | ||
599 | if (!RequestedTextures.ContainsKey(imageID)) | ||
600 | { | ||
601 | //not is cache so request from asset server | ||
602 | AssetRequest request = new AssetRequest(); | ||
603 | request.RequestUser = userInfo; | ||
604 | request.RequestAssetID = imageID; | ||
605 | request.IsTextureRequest = true; | ||
606 | request.DiscardLevel = discard; | ||
607 | RequestedTextures.Add(imageID, request); | ||
608 | m_assetServer.RequestAsset(imageID, true); | ||
609 | } | ||
610 | return; | ||
611 | } | ||
612 | |||
613 | // System.Console.WriteLine("texture already in cache"); | ||
614 | TextureImage imag = Textures[imageID]; | ||
615 | AssetRequest req = new AssetRequest(); | ||
616 | req.RequestUser = userInfo; | ||
617 | req.RequestAssetID = imageID; | ||
618 | req.IsTextureRequest = true; | ||
619 | req.ImageInfo = imag; | ||
620 | req.DiscardLevel = discard; | ||
621 | |||
622 | req.NumPackets = CalculateNumPackets(imag.Data.Length); | ||
623 | |||
624 | if (packetNumber != 0) | ||
625 | { | ||
626 | req.PacketCounter = (int) packetNumber; | ||
627 | } | ||
628 | |||
629 | TextureRequests.Add(req); | ||
630 | } | ||
631 | |||
632 | private int CalculateNumPackets(int length) | ||
633 | { | ||
634 | int numPackets = 1; | ||
635 | |||
636 | if (length > 600) | ||
637 | { | ||
638 | //over 600 bytes so split up file | ||
639 | int restData = (length - 600); | ||
640 | int restPackets = ((restData+999)/1000); | ||
641 | numPackets = 1 + restPackets; | ||
642 | } | ||
643 | |||
644 | return numPackets; | ||
645 | } | ||
646 | |||
647 | #endregion | ||
648 | |||
649 | public class AssetRequest | 517 | public class AssetRequest |
650 | { | 518 | { |
651 | public IClientAPI RequestUser; | 519 | public IClientAPI RequestUser; |
@@ -702,123 +570,28 @@ namespace OpenSim.Framework.Communications.Cache | |||
702 | } | 570 | } |
703 | } | 571 | } |
704 | 572 | ||
705 | public class TextureSender | ||
706 | { | ||
707 | public AssetRequest request; | ||
708 | private int counter = 0; | ||
709 | |||
710 | public TextureSender(AssetRequest req) | ||
711 | { | ||
712 | request = req; | ||
713 | } | ||
714 | |||
715 | public bool SendTexture() | ||
716 | { | ||
717 | SendPacket(); | ||
718 | counter++; | ||
719 | |||
720 | if ((request.PacketCounter >= request.NumPackets) || counter > 100 || (request.NumPackets == 1) || | ||
721 | (request.DiscardLevel == -1)) | ||
722 | { | ||
723 | return true; | ||
724 | } | ||
725 | return false; | ||
726 | } | ||
727 | 573 | ||
728 | public void SendPacket() | 574 | public class AssetRequestsList |
729 | { | 575 | { |
730 | AssetRequest req = request; | 576 | public LLUUID AssetID; |
731 | //Console.WriteLine("sending " + req.ImageInfo.FullID); | 577 | public List<NewAssetRequest> Requests = new List<NewAssetRequest>(); |
732 | if (req.PacketCounter == 0) | ||
733 | { | ||
734 | //first time for this request so send imagedata packet | ||
735 | if (req.NumPackets == 1) | ||
736 | { | ||
737 | //Console.WriteLine("only one packet so send whole file"); | ||
738 | ImageDataPacket im = new ImageDataPacket(); | ||
739 | im.Header.Reliable = false; | ||
740 | im.ImageID.Packets = 1; | ||
741 | im.ImageID.ID = req.ImageInfo.FullID; | ||
742 | im.ImageID.Size = (uint) req.ImageInfo.Data.Length; | ||
743 | im.ImageData.Data = req.ImageInfo.Data; | ||
744 | im.ImageID.Codec = 2; | ||
745 | req.RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); | ||
746 | req.PacketCounter++; | ||
747 | //req.ImageInfo.l= time; | ||
748 | //System.Console.WriteLine("sent texture: " + req.ImageInfo.FullID); | ||
749 | //Console.WriteLine("sending single packet for " + req.ImageInfo.FullID.ToStringHyphenated()); | ||
750 | } | ||
751 | else | ||
752 | { | ||
753 | //more than one packet so split file up | ||
754 | ImageDataPacket im = new ImageDataPacket(); | ||
755 | im.Header.Reliable = false; | ||
756 | im.ImageID.Packets = (ushort) (req.NumPackets); | ||
757 | im.ImageID.ID = req.ImageInfo.FullID; | ||
758 | im.ImageID.Size = (uint) req.ImageInfo.Data.Length; | ||
759 | im.ImageData.Data = new byte[600]; | ||
760 | Array.Copy(req.ImageInfo.Data, 0, im.ImageData.Data, 0, 600); | ||
761 | im.ImageID.Codec = 2; | ||
762 | req.RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); | ||
763 | |||
764 | req.PacketCounter++; | ||
765 | //req.ImageInfo.last_used = time; | ||
766 | //System.Console.WriteLine("sent first packet of texture: " + req.ImageInfo.FullID); | ||
767 | //Console.WriteLine("sending packet 1 for " + req.ImageInfo.FullID.ToStringHyphenated()); | ||
768 | } | ||
769 | } | ||
770 | else | ||
771 | { | ||
772 | //Console.WriteLine("sending packet " + req.PacketCounter + " for " + req.ImageInfo.FullID.ToStringHyphenated()); | ||
773 | //send imagepacket | ||
774 | //more than one packet so split file up | ||
775 | ImagePacketPacket im = new ImagePacketPacket(); | ||
776 | im.Header.Reliable = false; | ||
777 | im.ImageID.Packet = (ushort) (req.PacketCounter); | ||
778 | im.ImageID.ID = req.ImageInfo.FullID; | ||
779 | int size = req.ImageInfo.Data.Length - 600 - (1000*(req.PacketCounter - 1)); | ||
780 | if (size > 1000) size = 1000; | ||
781 | //Console.WriteLine("length= {0} counter= {1} size= {2}",req.ImageInfo.Data.Length, req.PacketCounter, size); | ||
782 | im.ImageData.Data = new byte[size]; | ||
783 | Array.Copy(req.ImageInfo.Data, 600 + (1000*(req.PacketCounter - 1)), im.ImageData.Data, 0, size); | ||
784 | req.RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); | ||
785 | req.PacketCounter++; | ||
786 | //req.ImageInfo.last_used = time; | ||
787 | //System.Console.WriteLine("sent a packet of texture: "+req.ImageInfo.FullID); | ||
788 | } | ||
789 | } | ||
790 | 578 | ||
791 | private void SaveAssetToFile(string filename, byte[] data) | 579 | public AssetRequestsList(LLUUID assetID) |
792 | { | 580 | { |
793 | FileStream fs = File.Create(filename); | 581 | AssetID = assetID; |
794 | BinaryWriter bw = new BinaryWriter(fs); | ||
795 | bw.Write(data); | ||
796 | bw.Close(); | ||
797 | fs.Close(); | ||
798 | } | 582 | } |
799 | } | 583 | } |
800 | } | ||
801 | |||
802 | public class AssetRequestsList | ||
803 | { | ||
804 | public LLUUID AssetID; | ||
805 | public List<NewAssetRequest> Requests = new List<NewAssetRequest>(); | ||
806 | 584 | ||
807 | public AssetRequestsList(LLUUID assetID) | 585 | public class NewAssetRequest |
808 | { | 586 | { |
809 | AssetID = assetID; | 587 | public LLUUID AssetID; |
810 | } | 588 | public AssetRequestCallback Callback; |
811 | } | ||
812 | |||
813 | public class NewAssetRequest | ||
814 | { | ||
815 | public LLUUID AssetID; | ||
816 | public AssetRequestCallback Callback; | ||
817 | 589 | ||
818 | public NewAssetRequest(LLUUID assetID, AssetRequestCallback callback) | 590 | public NewAssetRequest(LLUUID assetID, AssetRequestCallback callback) |
819 | { | 591 | { |
820 | AssetID = assetID; | 592 | AssetID = assetID; |
821 | Callback = callback; | 593 | Callback = callback; |
594 | } | ||
822 | } | 595 | } |
823 | } | 596 | } |
824 | } | 597 | } |
diff --git a/OpenSim/Framework/Communications/Cache/AssetTransactionManager.cs b/OpenSim/Framework/Communications/Cache/AssetTransactionManager.cs index 580c56a..7de84fa 100644 --- a/OpenSim/Framework/Communications/Cache/AssetTransactionManager.cs +++ b/OpenSim/Framework/Communications/Cache/AssetTransactionManager.cs | |||
@@ -83,7 +83,7 @@ namespace OpenSim.Framework.Communications.Cache | |||
83 | } | 83 | } |
84 | 84 | ||
85 | public void HandleUDPUploadRequest(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, | 85 | public void HandleUDPUploadRequest(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, |
86 | byte[] data, bool storeLocal) | 86 | byte[] data, bool storeLocal, bool tempFile) |
87 | { | 87 | { |
88 | // Console.WriteLine("asset upload of " + assetID); | 88 | // Console.WriteLine("asset upload of " + assetID); |
89 | AgentAssetTransactions transactions = GetUserTransActions(remoteClient.AgentId); | 89 | AgentAssetTransactions transactions = GetUserTransActions(remoteClient.AgentId); |
@@ -92,7 +92,7 @@ namespace OpenSim.Framework.Communications.Cache | |||
92 | AgentAssetTransactions.AssetXferUploader uploader = transactions.RequestXferUploader(transaction); | 92 | AgentAssetTransactions.AssetXferUploader uploader = transactions.RequestXferUploader(transaction); |
93 | if (uploader != null) | 93 | if (uploader != null) |
94 | { | 94 | { |
95 | uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal); | 95 | uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal, tempFile); |
96 | } | 96 | } |
97 | } | 97 | } |
98 | } | 98 | } |
diff --git a/OpenSim/Framework/Communications/Cache/AssetTransactions.cs b/OpenSim/Framework/Communications/Cache/AssetTransactions.cs index f972368..51b80e5 100644 --- a/OpenSim/Framework/Communications/Cache/AssetTransactions.cs +++ b/OpenSim/Framework/Communications/Cache/AssetTransactions.cs | |||
@@ -113,66 +113,6 @@ namespace OpenSim.Framework.Communications.Cache | |||
113 | } | 113 | } |
114 | 114 | ||
115 | // Nested Types | 115 | // Nested Types |
116 | public class AssetCapsUploader | ||
117 | { | ||
118 | // Fields | ||
119 | private BaseHttpServer httpListener; | ||
120 | private LLUUID inventoryItemID; | ||
121 | private string m_assetDescription = ""; | ||
122 | private string m_assetName = ""; | ||
123 | private LLUUID m_folderID; | ||
124 | private LLUUID newAssetID; | ||
125 | private bool m_dumpImageToFile; | ||
126 | private string uploaderPath = ""; | ||
127 | |||
128 | // Events | ||
129 | public event UpLoadedAsset OnUpLoad; | ||
130 | |||
131 | // Methods | ||
132 | public void Initialise(string assetName, string assetDescription, LLUUID assetID, LLUUID inventoryItem, | ||
133 | LLUUID folderID, string path, BaseHttpServer httpServer, bool dumpImageToFile) | ||
134 | { | ||
135 | m_assetName = assetName; | ||
136 | m_assetDescription = assetDescription; | ||
137 | m_folderID = folderID; | ||
138 | newAssetID = assetID; | ||
139 | inventoryItemID = inventoryItem; | ||
140 | uploaderPath = path; | ||
141 | httpListener = httpServer; | ||
142 | m_dumpImageToFile = dumpImageToFile; | ||
143 | } | ||
144 | |||
145 | private void SaveImageToFile(string filename, byte[] data) | ||
146 | { | ||
147 | FileStream output = File.Create(filename); | ||
148 | BinaryWriter writer = new BinaryWriter(output); | ||
149 | writer.Write(data); | ||
150 | writer.Close(); | ||
151 | output.Close(); | ||
152 | } | ||
153 | |||
154 | public string uploaderCaps(byte[] data, string path, string param) | ||
155 | { | ||
156 | LLUUID inventoryItemID = this.inventoryItemID; | ||
157 | string text = ""; | ||
158 | LLSDAssetUploadComplete complete = new LLSDAssetUploadComplete(); | ||
159 | complete.new_asset = newAssetID.ToStringHyphenated(); | ||
160 | complete.new_inventory_item = inventoryItemID; | ||
161 | complete.state = "complete"; | ||
162 | text = LLSDHelpers.SerialiseLLSDReply(complete); | ||
163 | httpListener.RemoveStreamHandler("POST", uploaderPath); | ||
164 | if (m_dumpImageToFile) | ||
165 | { | ||
166 | SaveImageToFile(m_assetName + ".jp2", data); | ||
167 | } | ||
168 | if (OnUpLoad != null) | ||
169 | { | ||
170 | OnUpLoad(m_assetName, "description", newAssetID, inventoryItemID, LLUUID.Zero, data, "", ""); | ||
171 | } | ||
172 | return text; | ||
173 | } | ||
174 | } | ||
175 | |||
176 | public class AssetXferUploader | 116 | public class AssetXferUploader |
177 | { | 117 | { |
178 | // Fields | 118 | // Fields |
@@ -230,7 +170,7 @@ namespace OpenSim.Framework.Communications.Cache | |||
230 | } | 170 | } |
231 | 171 | ||
232 | public void Initialise(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data, | 172 | public void Initialise(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data, |
233 | bool storeLocal) | 173 | bool storeLocal, bool tempFile) |
234 | { | 174 | { |
235 | ourClient = remoteClient; | 175 | ourClient = remoteClient; |
236 | Asset = new AssetBase(); | 176 | Asset = new AssetBase(); |
@@ -240,6 +180,9 @@ namespace OpenSim.Framework.Communications.Cache | |||
240 | Asset.Data = data; | 180 | Asset.Data = data; |
241 | Asset.Name = "blank"; | 181 | Asset.Name = "blank"; |
242 | Asset.Description = "empty"; | 182 | Asset.Description = "empty"; |
183 | Asset.Local = storeLocal; | ||
184 | Asset.Temporary = tempFile; | ||
185 | |||
243 | TransactionID = transaction; | 186 | TransactionID = transaction; |
244 | m_storeLocal = storeLocal; | 187 | m_storeLocal = storeLocal; |
245 | if (Asset.Data.Length > 2) | 188 | if (Asset.Data.Length > 2) |
@@ -368,6 +311,67 @@ namespace OpenSim.Framework.Communications.Cache | |||
368 | } | 311 | } |
369 | } | 312 | } |
370 | 313 | ||
314 | #region Nested Classes currently not in use (waiting for them to be enabled) | ||
315 | public class AssetCapsUploader | ||
316 | { | ||
317 | // Fields | ||
318 | private BaseHttpServer httpListener; | ||
319 | private LLUUID inventoryItemID; | ||
320 | private string m_assetDescription = ""; | ||
321 | private string m_assetName = ""; | ||
322 | private LLUUID m_folderID; | ||
323 | private LLUUID newAssetID; | ||
324 | private bool m_dumpImageToFile; | ||
325 | private string uploaderPath = ""; | ||
326 | |||
327 | // Events | ||
328 | public event UpLoadedAsset OnUpLoad; | ||
329 | |||
330 | // Methods | ||
331 | public void Initialise(string assetName, string assetDescription, LLUUID assetID, LLUUID inventoryItem, | ||
332 | LLUUID folderID, string path, BaseHttpServer httpServer, bool dumpImageToFile) | ||
333 | { | ||
334 | m_assetName = assetName; | ||
335 | m_assetDescription = assetDescription; | ||
336 | m_folderID = folderID; | ||
337 | newAssetID = assetID; | ||
338 | inventoryItemID = inventoryItem; | ||
339 | uploaderPath = path; | ||
340 | httpListener = httpServer; | ||
341 | m_dumpImageToFile = dumpImageToFile; | ||
342 | } | ||
343 | |||
344 | private void SaveImageToFile(string filename, byte[] data) | ||
345 | { | ||
346 | FileStream output = File.Create(filename); | ||
347 | BinaryWriter writer = new BinaryWriter(output); | ||
348 | writer.Write(data); | ||
349 | writer.Close(); | ||
350 | output.Close(); | ||
351 | } | ||
352 | |||
353 | public string uploaderCaps(byte[] data, string path, string param) | ||
354 | { | ||
355 | LLUUID inventoryItemID = this.inventoryItemID; | ||
356 | string text = ""; | ||
357 | LLSDAssetUploadComplete complete = new LLSDAssetUploadComplete(); | ||
358 | complete.new_asset = newAssetID.ToStringHyphenated(); | ||
359 | complete.new_inventory_item = inventoryItemID; | ||
360 | complete.state = "complete"; | ||
361 | text = LLSDHelpers.SerialiseLLSDReply(complete); | ||
362 | httpListener.RemoveStreamHandler("POST", uploaderPath); | ||
363 | if (m_dumpImageToFile) | ||
364 | { | ||
365 | SaveImageToFile(m_assetName + ".jp2", data); | ||
366 | } | ||
367 | if (OnUpLoad != null) | ||
368 | { | ||
369 | OnUpLoad(m_assetName, "description", newAssetID, inventoryItemID, LLUUID.Zero, data, "", ""); | ||
370 | } | ||
371 | return text; | ||
372 | } | ||
373 | } | ||
374 | |||
371 | public class NoteCardCapsUpdate | 375 | public class NoteCardCapsUpdate |
372 | { | 376 | { |
373 | // Fields | 377 | // Fields |
@@ -420,5 +424,6 @@ namespace OpenSim.Framework.Communications.Cache | |||
420 | return text; | 424 | return text; |
421 | } | 425 | } |
422 | } | 426 | } |
427 | #endregion | ||
423 | } | 428 | } |
424 | } | 429 | } |
diff --git a/OpenSim/Framework/Communications/Capabilities/LLSD.cs b/OpenSim/Framework/Communications/Capabilities/LLSD.cs index 60b5f75..4efeeb1 100644 --- a/OpenSim/Framework/Communications/Capabilities/LLSD.cs +++ b/OpenSim/Framework/Communications/Capabilities/LLSD.cs | |||
@@ -10,7 +10,7 @@ using System.Text; | |||
10 | namespace OpenSim.Region.Capabilities | 10 | namespace OpenSim.Region.Capabilities |
11 | { | 11 | { |
12 | /// <summary> | 12 | /// <summary> |
13 | /// | 13 | /// Borrowed from (a older version of ) libsl for now, as their new llsd code doesn't work we our decoding code. |
14 | /// </summary> | 14 | /// </summary> |
15 | public static class LLSD | 15 | public static class LLSD |
16 | { | 16 | { |
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 38410f4..6898f91 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs | |||
@@ -157,6 +157,13 @@ namespace OpenSim.Framework | |||
157 | protected LLUUID m_requestedAssetID; | 157 | protected LLUUID m_requestedAssetID; |
158 | private sbyte m_discardLevel; | 158 | private sbyte m_discardLevel; |
159 | private uint m_packetNumber; | 159 | private uint m_packetNumber; |
160 | private float m_priority; | ||
161 | |||
162 | public float Priority | ||
163 | { | ||
164 | get { return m_priority; } | ||
165 | set { m_priority = value; } | ||
166 | } | ||
160 | 167 | ||
161 | /// <summary> | 168 | /// <summary> |
162 | /// | 169 | /// |
@@ -348,7 +355,7 @@ namespace OpenSim.Framework | |||
348 | public delegate void RemoveTaskInventory(IClientAPI remoteClient, LLUUID itemID, uint localID); | 355 | public delegate void RemoveTaskInventory(IClientAPI remoteClient, LLUUID itemID, uint localID); |
349 | 356 | ||
350 | public delegate void UDPAssetUploadRequest( | 357 | public delegate void UDPAssetUploadRequest( |
351 | IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data, bool storeLocal); | 358 | IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data, bool storeLocal, bool tempFile); |
352 | 359 | ||
353 | public delegate void XferReceive(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data); | 360 | public delegate void XferReceive(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data); |
354 | 361 | ||
diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs index 31f01fc..1a544b8 100644 --- a/OpenSim/Region/ClientStack/ClientView.cs +++ b/OpenSim/Region/ClientStack/ClientView.cs | |||
@@ -2738,6 +2738,7 @@ namespace OpenSim.Region.ClientStack | |||
2738 | args.RequestedAssetID = imageRequest.RequestImage[i].Image; | 2738 | args.RequestedAssetID = imageRequest.RequestImage[i].Image; |
2739 | args.DiscardLevel = imageRequest.RequestImage[i].DiscardLevel; | 2739 | args.DiscardLevel = imageRequest.RequestImage[i].DiscardLevel; |
2740 | args.PacketNumber = imageRequest.RequestImage[i].Packet; | 2740 | args.PacketNumber = imageRequest.RequestImage[i].Packet; |
2741 | args.Priority = imageRequest.RequestImage[i].DownloadPriority; | ||
2741 | 2742 | ||
2742 | OnRequestTexture(this, args); | 2743 | OnRequestTexture(this, args); |
2743 | } | 2744 | } |
@@ -2761,7 +2762,7 @@ namespace OpenSim.Region.ClientStack | |||
2761 | LLUUID temp=libsecondlife.LLUUID.Combine(request.AssetBlock.TransactionID, SecureSessionId); | 2762 | LLUUID temp=libsecondlife.LLUUID.Combine(request.AssetBlock.TransactionID, SecureSessionId); |
2762 | OnAssetUploadRequest(this, temp, | 2763 | OnAssetUploadRequest(this, temp, |
2763 | request.AssetBlock.TransactionID, request.AssetBlock.Type, | 2764 | request.AssetBlock.TransactionID, request.AssetBlock.Type, |
2764 | request.AssetBlock.AssetData, request.AssetBlock.StoreLocal); | 2765 | request.AssetBlock.AssetData, request.AssetBlock.StoreLocal, request.AssetBlock.Tempfile); |
2765 | } | 2766 | } |
2766 | break; | 2767 | break; |
2767 | case PacketType.RequestXfer: | 2768 | case PacketType.RequestXfer: |
diff --git a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs b/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs index 66cdec7..702af19 100644 --- a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs +++ b/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs | |||
@@ -46,11 +46,10 @@ namespace OpenSim.Region.Environment.Modules | |||
46 | private Scene m_scene; | 46 | private Scene m_scene; |
47 | private List<Scene> m_scenes = new List<Scene>(); | 47 | private List<Scene> m_scenes = new List<Scene>(); |
48 | 48 | ||
49 | private Dictionary<LLUUID, Dictionary<LLUUID, AssetRequest>> ClientRequests = | ||
50 | new Dictionary<LLUUID, Dictionary<LLUUID, AssetRequest>>(); | ||
51 | |||
52 | private BlockingQueue<TextureSender> QueueSenders = new BlockingQueue<TextureSender>(); | 49 | private BlockingQueue<TextureSender> QueueSenders = new BlockingQueue<TextureSender>(); |
53 | private Dictionary<LLUUID, List<LLUUID>> InProcess = new Dictionary<LLUUID, List<LLUUID>>(); | 50 | |
51 | private Dictionary<LLUUID, UserTextureDownloadService> m_userTextureServices = new Dictionary<LLUUID, UserTextureDownloadService>(); | ||
52 | |||
54 | private Thread m_thread; | 53 | private Thread m_thread; |
55 | 54 | ||
56 | public TextureDownloadModule() | 55 | public TextureDownloadModule() |
@@ -85,55 +84,36 @@ namespace OpenSim.Region.Environment.Modules | |||
85 | 84 | ||
86 | public bool IsSharedModule | 85 | public bool IsSharedModule |
87 | { | 86 | { |
88 | get { return true; } | 87 | get { return false; } |
89 | } | 88 | } |
90 | 89 | ||
91 | public void NewClient(IClientAPI client) | 90 | public void NewClient(IClientAPI client) |
92 | { | 91 | { |
93 | lock (ClientRequests) | ||
94 | { | ||
95 | if (!ClientRequests.ContainsKey(client.AgentId)) | ||
96 | { | ||
97 | ClientRequests.Add(client.AgentId, new Dictionary<LLUUID, AssetRequest>()); | ||
98 | InProcess.Add(client.AgentId, new List<LLUUID>()); | ||
99 | } | ||
100 | } | ||
101 | client.OnRequestTexture += TextureRequest; | 92 | client.OnRequestTexture += TextureRequest; |
102 | |||
103 | } | 93 | } |
104 | 94 | ||
105 | public void TextureCallback(LLUUID textureID, AssetBase asset) | 95 | private bool TryGetUserTextureService(LLUUID userID, out UserTextureDownloadService textureService) |
106 | { | 96 | { |
107 | lock (ClientRequests) | 97 | lock (m_userTextureServices) |
108 | { | 98 | { |
109 | foreach (Dictionary<LLUUID, AssetRequest> reqList in ClientRequests.Values) | 99 | if (m_userTextureServices.TryGetValue(userID, out textureService)) |
110 | { | 100 | { |
111 | if (reqList.ContainsKey(textureID)) | 101 | return true; |
112 | { | ||
113 | //check the texture isn't already in the process of being sent to the client. | ||
114 | if (!InProcess[reqList[textureID].RequestUser.AgentId].Contains(textureID)) | ||
115 | { | ||
116 | TextureSender sender = new TextureSender(reqList[textureID], asset); | ||
117 | QueueSenders.Enqueue(sender); | ||
118 | InProcess[reqList[textureID].RequestUser.AgentId].Add(textureID); | ||
119 | reqList.Remove(textureID); | ||
120 | } | ||
121 | } | ||
122 | } | 102 | } |
103 | |||
104 | textureService = new UserTextureDownloadService(m_scene, QueueSenders); | ||
105 | m_userTextureServices.Add(userID, textureService); | ||
106 | return true; | ||
123 | } | 107 | } |
124 | } | 108 | } |
125 | 109 | ||
126 | public void TextureRequest(Object sender, TextureRequestArgs e) | 110 | public void TextureRequest(Object sender, TextureRequestArgs e) |
127 | { | 111 | { |
128 | IClientAPI client = (IClientAPI)sender; | 112 | IClientAPI client = (IClientAPI)sender; |
129 | if (!ClientRequests[client.AgentId].ContainsKey(e.RequestedAssetID)) | 113 | UserTextureDownloadService textureService; |
114 | if (TryGetUserTextureService(client.AgentId, out textureService)) | ||
130 | { | 115 | { |
131 | lock (ClientRequests) | 116 | textureService.HandleTextureRequest(client, e); |
132 | { | ||
133 | AssetRequest request = new AssetRequest(client, e.RequestedAssetID, e.DiscardLevel, e.PacketNumber); | ||
134 | ClientRequests[client.AgentId].Add(e.RequestedAssetID, request); | ||
135 | } | ||
136 | m_scene.AssetCache.GetAsset(e.RequestedAssetID, TextureCallback); | ||
137 | } | 117 | } |
138 | } | 118 | } |
139 | 119 | ||
@@ -142,57 +122,150 @@ namespace OpenSim.Region.Environment.Modules | |||
142 | while (true) | 122 | while (true) |
143 | { | 123 | { |
144 | TextureSender sender = QueueSenders.Dequeue(); | 124 | TextureSender sender = QueueSenders.Dequeue(); |
145 | bool finished = sender.SendTexture(); | 125 | if (sender.Cancel) |
146 | if (finished) | ||
147 | { | 126 | { |
148 | TextureSent(sender); | 127 | TextureSent(sender); |
149 | } | 128 | } |
150 | else | 129 | else |
151 | { | 130 | { |
152 | QueueSenders.Enqueue(sender); | 131 | bool finished = sender.SendTexturePacket(); |
132 | if (finished) | ||
133 | { | ||
134 | TextureSent(sender); | ||
135 | } | ||
136 | else | ||
137 | { | ||
138 | QueueSenders.Enqueue(sender); | ||
139 | } | ||
153 | } | 140 | } |
154 | } | 141 | } |
155 | } | 142 | } |
156 | 143 | ||
157 | private void TextureSent(TextureSender sender) | 144 | private void TextureSent(TextureSender sender) |
158 | { | 145 | { |
159 | if (InProcess[sender.request.RequestUser.AgentId].Contains(sender.request.RequestAssetID)) | 146 | sender.Sending = false; |
147 | } | ||
148 | |||
149 | public class UserTextureDownloadService | ||
150 | { | ||
151 | private Dictionary<LLUUID, TextureSender> m_textureSenders = new Dictionary<LLUUID, TextureSender>(); | ||
152 | |||
153 | private BlockingQueue<TextureSender> m_sharedSendersQueue; | ||
154 | |||
155 | private Scene m_scene; | ||
156 | |||
157 | public UserTextureDownloadService(Scene scene, BlockingQueue<TextureSender> sharedQueue) | ||
160 | { | 158 | { |
161 | InProcess[sender.request.RequestUser.AgentId].Remove(sender.request.RequestAssetID); | 159 | m_scene = scene; |
160 | m_sharedSendersQueue = sharedQueue; | ||
161 | } | ||
162 | |||
163 | public void HandleTextureRequest(IClientAPI client, TextureRequestArgs e) | ||
164 | { | ||
165 | //TODO: should be working out the data size/ number of packets to be sent for each discard level | ||
166 | if ((e.DiscardLevel >= 0) || (e.Priority != 0)) | ||
167 | { | ||
168 | lock (m_textureSenders) | ||
169 | { | ||
170 | if (!m_textureSenders.ContainsKey(e.RequestedAssetID)) | ||
171 | { | ||
172 | TextureSender requestHandler = new TextureSender(client, e.RequestedAssetID, e.DiscardLevel, e.PacketNumber); | ||
173 | m_textureSenders.Add(e.RequestedAssetID, requestHandler); | ||
174 | m_scene.AssetCache.GetAsset(e.RequestedAssetID, TextureCallback); | ||
175 | } | ||
176 | else | ||
177 | { | ||
178 | m_textureSenders[e.RequestedAssetID].UpdateRequest(e.DiscardLevel, e.PacketNumber); | ||
179 | m_textureSenders[e.RequestedAssetID].counter = 0; | ||
180 | if ((m_textureSenders[e.RequestedAssetID].ImageLoaded) && (m_textureSenders[e.RequestedAssetID].Sending ==false)) | ||
181 | { | ||
182 | m_textureSenders[e.RequestedAssetID].Sending = true; | ||
183 | m_sharedSendersQueue.Enqueue(m_textureSenders[e.RequestedAssetID]); | ||
184 | } | ||
185 | } | ||
186 | } | ||
187 | } | ||
188 | else | ||
189 | { | ||
190 | lock (m_textureSenders) | ||
191 | { | ||
192 | if (m_textureSenders.ContainsKey(e.RequestedAssetID)) | ||
193 | { | ||
194 | m_textureSenders[e.RequestedAssetID].Cancel = true; | ||
195 | } | ||
196 | } | ||
197 | } | ||
198 | } | ||
199 | |||
200 | public void TextureCallback(LLUUID textureID, AssetBase asset) | ||
201 | { | ||
202 | lock (m_textureSenders) | ||
203 | { | ||
204 | if (m_textureSenders.ContainsKey(textureID)) | ||
205 | { | ||
206 | if (!m_textureSenders[textureID].ImageLoaded) | ||
207 | { | ||
208 | m_textureSenders[textureID].TextureReceived(asset); | ||
209 | m_textureSenders[textureID].Sending = true; | ||
210 | m_textureSenders[textureID].counter = 0; | ||
211 | m_sharedSendersQueue.Enqueue(m_textureSenders[textureID]); | ||
212 | } | ||
213 | } | ||
214 | else | ||
215 | { | ||
216 | // Got a texture with no sender object to handle it, this shouldn't happen | ||
217 | } | ||
218 | } | ||
162 | } | 219 | } |
163 | } | 220 | } |
164 | 221 | ||
165 | public class TextureSender | 222 | public class TextureSender |
166 | { | 223 | { |
167 | public AssetRequest request; | 224 | public int counter = 0; |
168 | private int counter = 0; | ||
169 | private AssetBase m_asset; | 225 | private AssetBase m_asset; |
170 | public long DataPointer = 0; | 226 | public long DataPointer = 0; |
171 | public int NumPackets = 0; | 227 | public int NumPackets = 0; |
172 | public int PacketCounter = 0; | 228 | public int PacketCounter = 0; |
229 | public bool Cancel = false; | ||
230 | public bool ImageLoaded = false; | ||
231 | |||
232 | public bool Sending = false; | ||
173 | 233 | ||
174 | public TextureSender(AssetRequest req, AssetBase asset) | 234 | public IClientAPI RequestUser; |
235 | public LLUUID RequestedAssetID; | ||
236 | public int RequestedDiscardLevel = -1; | ||
237 | public uint StartPacketNumber = 0; | ||
238 | |||
239 | // private int m_sentDiscardLevel = -1; | ||
240 | |||
241 | public TextureSender(IClientAPI client, LLUUID textureID, int discardLevel, uint packetNumber) | ||
175 | { | 242 | { |
176 | request = req; | 243 | RequestUser = client; |
177 | m_asset = asset; | 244 | RequestedAssetID = textureID; |
245 | RequestedDiscardLevel = discardLevel; | ||
246 | StartPacketNumber = packetNumber; | ||
247 | } | ||
178 | 248 | ||
179 | if (asset.Data.LongLength > 600) | 249 | public void TextureReceived(AssetBase asset) |
180 | { | 250 | { |
181 | NumPackets = 2 + (int)(asset.Data.Length - 601) / 1000; | 251 | m_asset = asset; |
182 | } | 252 | NumPackets = CalculateNumPackets(asset.Data.Length); |
183 | else | 253 | PacketCounter = (int)StartPacketNumber; |
184 | { | 254 | ImageLoaded = true; |
185 | NumPackets = 1; | 255 | } |
186 | } | ||
187 | 256 | ||
188 | PacketCounter = (int)req.PacketNumber; | 257 | public void UpdateRequest(int discardLevel, uint packetNumber) |
258 | { | ||
259 | RequestedDiscardLevel = discardLevel; | ||
260 | StartPacketNumber = packetNumber; | ||
261 | PacketCounter = (int)StartPacketNumber; | ||
189 | } | 262 | } |
190 | 263 | ||
191 | public bool SendTexture() | 264 | public bool SendTexturePacket() |
192 | { | 265 | { |
193 | SendPacket(); | 266 | SendPacket(); |
194 | counter++; | 267 | counter++; |
195 | if ((PacketCounter >= NumPackets) || counter > 100 || (NumPackets == 1) || (request.DiscardLevel == -1)) | 268 | if ((NumPackets == 0) || (RequestedDiscardLevel == -1) || (PacketCounter > NumPackets) || ((RequestedDiscardLevel > 0) && (counter > 50 + (NumPackets / (RequestedDiscardLevel + 1)))) ) |
196 | { | 269 | { |
197 | return true; | 270 | return true; |
198 | } | 271 | } |
@@ -201,65 +274,68 @@ namespace OpenSim.Region.Environment.Modules | |||
201 | 274 | ||
202 | public void SendPacket() | 275 | public void SendPacket() |
203 | { | 276 | { |
204 | AssetRequest req = request; | 277 | if (PacketCounter <= NumPackets) |
205 | if (PacketCounter == 0) | ||
206 | { | 278 | { |
207 | if (NumPackets == 1) | 279 | if (PacketCounter == 0) |
208 | { | 280 | { |
209 | ImageDataPacket im = new ImageDataPacket(); | 281 | if (NumPackets == 0) |
210 | im.Header.Reliable = false; | 282 | { |
211 | im.ImageID.Packets = 1; | 283 | ImageDataPacket im = new ImageDataPacket(); |
212 | im.ImageID.ID = m_asset.FullID; | 284 | im.Header.Reliable = false; |
213 | im.ImageID.Size = (uint)m_asset.Data.Length; | 285 | im.ImageID.Packets = 0; |
214 | im.ImageData.Data = m_asset.Data; | 286 | im.ImageID.ID = m_asset.FullID; |
215 | im.ImageID.Codec = 2; | 287 | im.ImageID.Size = (uint)m_asset.Data.Length; |
216 | req.RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); | 288 | im.ImageData.Data = m_asset.Data; |
217 | PacketCounter++; | 289 | im.ImageID.Codec = 2; |
290 | RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); | ||
291 | PacketCounter++; | ||
292 | } | ||
293 | else | ||
294 | { | ||
295 | ImageDataPacket im = new ImageDataPacket(); | ||
296 | im.Header.Reliable = false; | ||
297 | im.ImageID.Packets = (ushort)(NumPackets); | ||
298 | im.ImageID.ID = m_asset.FullID; | ||
299 | im.ImageID.Size = (uint)m_asset.Data.Length; | ||
300 | im.ImageData.Data = new byte[600]; | ||
301 | Array.Copy(m_asset.Data, 0, im.ImageData.Data, 0, 600); | ||
302 | im.ImageID.Codec = 2; | ||
303 | RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); | ||
304 | PacketCounter++; | ||
305 | } | ||
218 | } | 306 | } |
219 | else | 307 | else |
220 | { | 308 | { |
221 | ImageDataPacket im = new ImageDataPacket(); | 309 | ImagePacketPacket im = new ImagePacketPacket(); |
222 | im.Header.Reliable = false; | 310 | im.Header.Reliable = false; |
223 | im.ImageID.Packets = (ushort)(NumPackets); | 311 | im.ImageID.Packet = (ushort)(PacketCounter); |
224 | im.ImageID.ID = m_asset.FullID; | 312 | im.ImageID.ID = m_asset.FullID; |
225 | im.ImageID.Size = (uint)m_asset.Data.Length; | 313 | int size = m_asset.Data.Length - 600 - (1000 * (PacketCounter - 1)); |
226 | im.ImageData.Data = new byte[600]; | 314 | if (size > 1000) size = 1000; |
227 | Array.Copy(m_asset.Data, 0, im.ImageData.Data, 0, 600); | 315 | im.ImageData.Data = new byte[size]; |
228 | im.ImageID.Codec = 2; | 316 | Array.Copy(m_asset.Data, 600 + (1000 * (PacketCounter - 1)), im.ImageData.Data, 0, size); |
229 | req.RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); | 317 | RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); |
230 | PacketCounter++; | 318 | PacketCounter++; |
231 | } | 319 | } |
232 | } | 320 | } |
233 | else | 321 | } |
322 | |||
323 | private int CalculateNumPackets(int length) | ||
324 | { | ||
325 | int numPackets = 0; | ||
326 | |||
327 | if (length > 600) | ||
234 | { | 328 | { |
235 | ImagePacketPacket im = new ImagePacketPacket(); | 329 | //over 600 bytes so split up file |
236 | im.Header.Reliable = false; | 330 | int restData = (length - 600); |
237 | im.ImageID.Packet = (ushort)(PacketCounter); | 331 | int restPackets = ((restData + 999) / 1000); |
238 | im.ImageID.ID = m_asset.FullID; | 332 | numPackets = restPackets; |
239 | int size = m_asset.Data.Length - 600 - (1000 * (PacketCounter - 1)); | ||
240 | if (size > 1000) size = 1000; | ||
241 | im.ImageData.Data = new byte[size]; | ||
242 | Array.Copy(m_asset.Data, 600 + (1000 * (PacketCounter - 1)), im.ImageData.Data, 0, size); | ||
243 | req.RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); | ||
244 | PacketCounter++; | ||
245 | } | 333 | } |
334 | |||
335 | return numPackets; | ||
246 | } | 336 | } |
247 | } | 337 | } |
248 | 338 | ||
249 | public class AssetRequest | ||
250 | { | ||
251 | public IClientAPI RequestUser; | ||
252 | public LLUUID RequestAssetID; | ||
253 | public int DiscardLevel = -1; | ||
254 | public uint PacketNumber = 0; | ||
255 | 339 | ||
256 | public AssetRequest(IClientAPI client, LLUUID textureID, int discardLevel, uint packetNumber) | ||
257 | { | ||
258 | RequestUser = client; | ||
259 | RequestAssetID = textureID; | ||
260 | DiscardLevel = discardLevel; | ||
261 | PacketNumber = packetNumber; | ||
262 | } | ||
263 | } | ||
264 | } | 340 | } |
265 | } \ No newline at end of file | 341 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Scenes/IScenePresenceBody.cs b/OpenSim/Region/Environment/Scenes/IScenePresenceBody.cs index 0f3bca1..b9d1232 100644 --- a/OpenSim/Region/Environment/Scenes/IScenePresenceBody.cs +++ b/OpenSim/Region/Environment/Scenes/IScenePresenceBody.cs | |||
@@ -35,8 +35,5 @@ namespace OpenSim.Region.Environment.Scenes | |||
35 | public interface IScenePresenceBody | 35 | public interface IScenePresenceBody |
36 | { | 36 | { |
37 | void processMovement(IClientAPI remoteClient, uint flags, LLQuaternion bodyRotation); | 37 | void processMovement(IClientAPI remoteClient, uint flags, LLQuaternion bodyRotation); |
38 | void SetAppearance(byte[] texture, AgentSetAppearancePacket.VisualParamBlock[] visualParam); | ||
39 | void SendOurAppearance(IClientAPI OurClient); | ||
40 | void SendAppearanceToOtherAgent(ScenePresence avatarInfo); | ||
41 | } | 38 | } |
42 | } \ No newline at end of file | 39 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index c5cb55c..e9d83a1 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs | |||
@@ -1019,7 +1019,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
1019 | ScenePresence avatar = null; | 1019 | ScenePresence avatar = null; |
1020 | 1020 | ||
1021 | AvatarAppearance appearance; | 1021 | AvatarAppearance appearance; |
1022 | LoadAvatarAppearance(client, out appearance); | 1022 | GetAvatarAppearance(client, out appearance); |
1023 | 1023 | ||
1024 | avatar = m_innerScene.CreateAndAddScenePresence(client, child, appearance); | 1024 | avatar = m_innerScene.CreateAndAddScenePresence(client, child, appearance); |
1025 | 1025 | ||
@@ -1031,7 +1031,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
1031 | return avatar; | 1031 | return avatar; |
1032 | } | 1032 | } |
1033 | 1033 | ||
1034 | protected void LoadAvatarAppearance(IClientAPI client, out AvatarAppearance appearance) | 1034 | protected void GetAvatarAppearance(IClientAPI client, out AvatarAppearance appearance) |
1035 | { | 1035 | { |
1036 | if (m_AvatarFactory == null || | 1036 | if (m_AvatarFactory == null || |
1037 | !m_AvatarFactory.TryGetAvatarAppearance(client.AgentId, out appearance)) | 1037 | !m_AvatarFactory.TryGetAvatarAppearance(client.AgentId, out appearance)) |