aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorMW2007-12-10 13:27:23 +0000
committerMW2007-12-10 13:27:23 +0000
commit611327e1040fa706665c543f67f9331a7e0136c5 (patch)
tree4426a50291dbc1c7c4ec065fd5c48921a767b658 /OpenSim
parentadded musings on llInstantMessage (diff)
downloadopensim-SC_OLD-611327e1040fa706665c543f67f9331a7e0136c5.zip
opensim-SC_OLD-611327e1040fa706665c543f67f9331a7e0136c5.tar.gz
opensim-SC_OLD-611327e1040fa706665c543f67f9331a7e0136c5.tar.bz2
opensim-SC_OLD-611327e1040fa706665c543f67f9331a7e0136c5.tar.xz
more work on texture downloading.
Refractored the TextureDownloadModule (but currently to make debugging easier, it is running as a non shared module, so this results in a instance of this module being created for each region (and a extra thread per region), this will be changed back soon. Removed the old texture handling/sending code from AssetCache. A few other small changes/fixes.
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Framework/Communications/Cache/AssetCache.cs303
-rw-r--r--OpenSim/Framework/Communications/Cache/AssetTransactionManager.cs4
-rw-r--r--OpenSim/Framework/Communications/Cache/AssetTransactions.cs127
-rw-r--r--OpenSim/Framework/Communications/Capabilities/LLSD.cs2
-rw-r--r--OpenSim/Framework/IClientAPI.cs9
-rw-r--r--OpenSim/Region/ClientStack/ClientView.cs3
-rw-r--r--OpenSim/Region/Environment/Modules/TextureDownloadModule.cs276
-rw-r--r--OpenSim/Region/Environment/Scenes/IScenePresenceBody.cs3
-rw-r--r--OpenSim/Region/Environment/Scenes/Scene.cs4
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
37namespace OpenSim.Framework.Communications.Cache 37namespace 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;
10namespace OpenSim.Region.Capabilities 10namespace 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))