aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/Agent
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Environment/Modules/Agent/AssetDownload/AssetDownloadModule.cs (renamed from OpenSim/Region/Environment/Modules/AssetDownloadModule.cs)666
-rw-r--r--OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AgentAssetsTransactions.cs (renamed from OpenSim/Region/Environment/Modules/AgentAssetsTransactions.cs)815
-rw-r--r--OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AssetTransactionModule.cs (renamed from OpenSim/Region/Environment/Modules/AgentAssetTransactionModule.cs)572
-rw-r--r--OpenSim/Region/Environment/Modules/Agent/TextureDownload/TextureDownloadModule.cs (renamed from OpenSim/Region/Environment/Modules/TextureDownloadModule.cs)433
-rw-r--r--OpenSim/Region/Environment/Modules/Agent/TextureDownload/TextureNotFoundSender.cs (renamed from OpenSim/Region/Environment/Modules/TextureNotFoundSender.cs)186
-rw-r--r--OpenSim/Region/Environment/Modules/Agent/TextureDownload/UserTextureDownloadService.cs (renamed from OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs)502
-rw-r--r--OpenSim/Region/Environment/Modules/Agent/TextureSender/TextureSender.cs (renamed from OpenSim/Region/Environment/Modules/TextureSender.cs)440
-rw-r--r--OpenSim/Region/Environment/Modules/Agent/Xfer/XferModule.cs (renamed from OpenSim/Region/Environment/Modules/XferModule.cs)450
8 files changed, 2031 insertions, 2033 deletions
diff --git a/OpenSim/Region/Environment/Modules/AssetDownloadModule.cs b/OpenSim/Region/Environment/Modules/Agent/AssetDownload/AssetDownloadModule.cs
index 97db31e..47c1479 100644
--- a/OpenSim/Region/Environment/Modules/AssetDownloadModule.cs
+++ b/OpenSim/Region/Environment/Modules/Agent/AssetDownload/AssetDownloadModule.cs
@@ -1,333 +1,333 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the 12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System.Collections.Generic; 28using System.Collections.Generic;
29using libsecondlife; 29using libsecondlife;
30using libsecondlife.Packets; 30using libsecondlife.Packets;
31using Nini.Config; 31using Nini.Config;
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Region.Environment.Interfaces; 33using OpenSim.Region.Environment.Interfaces;
34using OpenSim.Region.Environment.Scenes; 34using OpenSim.Region.Environment.Scenes;
35 35
36namespace OpenSim.Region.Environment.Modules 36namespace OpenSim.Region.Environment.Modules.Agent.AssetDownload
37{ 37{
38 public class AssetDownloadModule : IRegionModule 38 public class AssetDownloadModule : IRegionModule
39 { 39 {
40 private Scene m_scene; 40 private Scene m_scene;
41 private Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>(); 41 private Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>();
42 /// 42 ///
43 /// Assets requests (for each user) which are waiting for asset server data. This includes texture requests 43 /// Assets requests (for each user) which are waiting for asset server data. This includes texture requests
44 /// </summary> 44 /// </summary>
45 private Dictionary<LLUUID, Dictionary<LLUUID,AssetRequest>> RequestedAssets; 45 private Dictionary<LLUUID, Dictionary<LLUUID,AssetRequest>> RequestedAssets;
46 46
47 /// <summary> 47 /// <summary>
48 /// Asset requests with data which are ready to be sent back to requesters. This includes textures. 48 /// Asset requests with data which are ready to be sent back to requesters. This includes textures.
49 /// </summary> 49 /// </summary>
50 private List<AssetRequest> AssetRequests; 50 private List<AssetRequest> AssetRequests;
51 51
52 public AssetDownloadModule() 52 public AssetDownloadModule()
53 { 53 {
54 RequestedAssets = new Dictionary<LLUUID, Dictionary<LLUUID, AssetRequest>>(); 54 RequestedAssets = new Dictionary<LLUUID, Dictionary<LLUUID, AssetRequest>>();
55 AssetRequests = new List<AssetRequest>(); 55 AssetRequests = new List<AssetRequest>();
56 } 56 }
57 57
58 public void Initialise(Scene scene, IConfigSource config) 58 public void Initialise(Scene scene, IConfigSource config)
59 { 59 {
60 if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) 60 if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
61 { 61 {
62 RegisteredScenes.Add(scene.RegionInfo.RegionID, scene); 62 RegisteredScenes.Add(scene.RegionInfo.RegionID, scene);
63 // scene.EventManager.OnNewClient += NewClient; 63 // scene.EventManager.OnNewClient += NewClient;
64 } 64 }
65 65
66 if (m_scene == null) 66 if (m_scene == null)
67 { 67 {
68 m_scene = scene; 68 m_scene = scene;
69 // m_thread = new Thread(new ThreadStart(RunAssetQueue)); 69 // m_thread = new Thread(new ThreadStart(RunAssetQueue));
70 // m_thread.Name = "AssetDownloadQueueThread"; 70 // m_thread.Name = "AssetDownloadQueueThread";
71 // m_thread.IsBackground = true; 71 // m_thread.IsBackground = true;
72 // m_thread.Start(); 72 // m_thread.Start();
73 // OpenSim.Framework.ThreadTracker.Add(m_thread); 73 // OpenSim.Framework.ThreadTracker.Add(m_thread);
74 } 74 }
75 } 75 }
76 76
77 public void PostInitialise() 77 public void PostInitialise()
78 { 78 {
79 } 79 }
80 80
81 public void Close() 81 public void Close()
82 { 82 {
83 } 83 }
84 84
85 public string Name 85 public string Name
86 { 86 {
87 get { return "AssetDownloadModule"; } 87 get { return "AssetDownloadModule"; }
88 } 88 }
89 89
90 public bool IsSharedModule 90 public bool IsSharedModule
91 { 91 {
92 get { return true; } 92 get { return true; }
93 } 93 }
94 94
95 public void NewClient(IClientAPI client) 95 public void NewClient(IClientAPI client)
96 { 96 {
97 // client.OnRequestAsset += AddAssetRequest; 97 // client.OnRequestAsset += AddAssetRequest;
98 } 98 }
99 99
100 /// <summary> 100 /// <summary>
101 /// Make an asset request the result of which will be packeted up and sent directly back to the client. 101 /// Make an asset request the result of which will be packeted up and sent directly back to the client.
102 /// </summary> 102 /// </summary>
103 /// <param name="userInfo"></param> 103 /// <param name="userInfo"></param>
104 /// <param name="transferRequest"></param> 104 /// <param name="transferRequest"></param>
105 public void AddAssetRequest(IClientAPI userInfo, TransferRequestPacket transferRequest) 105 public void AddAssetRequest(IClientAPI userInfo, TransferRequestPacket transferRequest)
106 { 106 {
107 LLUUID requestID = null; 107 LLUUID requestID = null;
108 byte source = 2; 108 byte source = 2;
109 if (transferRequest.TransferInfo.SourceType == 2) 109 if (transferRequest.TransferInfo.SourceType == 2)
110 { 110 {
111 //direct asset request 111 //direct asset request
112 requestID = new LLUUID(transferRequest.TransferInfo.Params, 0); 112 requestID = new LLUUID(transferRequest.TransferInfo.Params, 0);
113 } 113 }
114 else if (transferRequest.TransferInfo.SourceType == 3) 114 else if (transferRequest.TransferInfo.SourceType == 3)
115 { 115 {
116 //inventory asset request 116 //inventory asset request
117 requestID = new LLUUID(transferRequest.TransferInfo.Params, 80); 117 requestID = new LLUUID(transferRequest.TransferInfo.Params, 80);
118 source = 3; 118 source = 3;
119 //Console.WriteLine("asset request " + requestID); 119 //Console.WriteLine("asset request " + requestID);
120 } 120 }
121 121
122 //not found asset 122 //not found asset
123 // so request from asset server 123 // so request from asset server
124 Dictionary<LLUUID, AssetRequest> userRequests = null; 124 Dictionary<LLUUID, AssetRequest> userRequests = null;
125 if (RequestedAssets.TryGetValue(userInfo.AgentId, out userRequests)) 125 if (RequestedAssets.TryGetValue(userInfo.AgentId, out userRequests))
126 { 126 {
127 if (!userRequests.ContainsKey(requestID)) 127 if (!userRequests.ContainsKey(requestID))
128 { 128 {
129 AssetRequest request = new AssetRequest(); 129 AssetRequest request = new AssetRequest();
130 request.RequestUser = userInfo; 130 request.RequestUser = userInfo;
131 request.RequestAssetID = requestID; 131 request.RequestAssetID = requestID;
132 request.TransferRequestID = transferRequest.TransferInfo.TransferID; 132 request.TransferRequestID = transferRequest.TransferInfo.TransferID;
133 request.AssetRequestSource = source; 133 request.AssetRequestSource = source;
134 request.Params = transferRequest.TransferInfo.Params; 134 request.Params = transferRequest.TransferInfo.Params;
135 userRequests[requestID] = request; 135 userRequests[requestID] = request;
136 m_scene.AssetCache.GetAsset(requestID, AssetCallback, false); 136 m_scene.AssetCache.GetAsset(requestID, AssetCallback, false);
137 } 137 }
138 } 138 }
139 else 139 else
140 { 140 {
141 userRequests = new Dictionary<LLUUID, AssetRequest>(); 141 userRequests = new Dictionary<LLUUID, AssetRequest>();
142 AssetRequest request = new AssetRequest(); 142 AssetRequest request = new AssetRequest();
143 request.RequestUser = userInfo; 143 request.RequestUser = userInfo;
144 request.RequestAssetID = requestID; 144 request.RequestAssetID = requestID;
145 request.TransferRequestID = transferRequest.TransferInfo.TransferID; 145 request.TransferRequestID = transferRequest.TransferInfo.TransferID;
146 request.AssetRequestSource = source; 146 request.AssetRequestSource = source;
147 request.Params = transferRequest.TransferInfo.Params; 147 request.Params = transferRequest.TransferInfo.Params;
148 userRequests.Add(requestID, request); 148 userRequests.Add(requestID, request);
149 RequestedAssets[userInfo.AgentId] = userRequests; 149 RequestedAssets[userInfo.AgentId] = userRequests;
150 m_scene.AssetCache.GetAsset(requestID, AssetCallback, false); 150 m_scene.AssetCache.GetAsset(requestID, AssetCallback, false);
151 } 151 }
152 } 152 }
153 153
154 public void AssetCallback(LLUUID assetID, AssetBase asset) 154 public void AssetCallback(LLUUID assetID, AssetBase asset)
155 { 155 {
156 if (asset != null) 156 if (asset != null)
157 { 157 {
158 foreach (Dictionary<LLUUID, AssetRequest> userRequests in RequestedAssets.Values) 158 foreach (Dictionary<LLUUID, AssetRequest> userRequests in RequestedAssets.Values)
159 { 159 {
160 if (userRequests.ContainsKey(assetID)) 160 if (userRequests.ContainsKey(assetID))
161 { 161 {
162 AssetRequest req = userRequests[assetID]; 162 AssetRequest req = userRequests[assetID];
163 if (req != null) 163 if (req != null)
164 { 164 {
165 req.AssetInf = asset; 165 req.AssetInf = asset;
166 req.NumPackets = CalculateNumPackets(asset.Data); 166 req.NumPackets = CalculateNumPackets(asset.Data);
167 167
168 userRequests.Remove(assetID); 168 userRequests.Remove(assetID);
169 AssetRequests.Add(req); 169 AssetRequests.Add(req);
170 } 170 }
171 } 171 }
172 } 172 }
173 } 173 }
174 } 174 }
175 175
176// TODO: unused 176// TODO: unused
177// private void RunAssetQueue() 177// private void RunAssetQueue()
178// { 178// {
179// while (true) 179// while (true)
180// { 180// {
181// try 181// try
182// { 182// {
183// ProcessAssetQueue(); 183// ProcessAssetQueue();
184// Thread.Sleep(500); 184// Thread.Sleep(500);
185// } 185// }
186// catch (Exception) 186// catch (Exception)
187// { 187// {
188// // m_log.Error("[ASSET CACHE]: " + e.ToString()); 188// // m_log.Error("[ASSET CACHE]: " + e.ToString());
189// } 189// }
190// } 190// }
191// } 191// }
192 192
193// TODO: unused 193// TODO: unused
194// /// <summary> 194// /// <summary>
195// /// Process the asset queue which sends packets directly back to the client. 195// /// Process the asset queue which sends packets directly back to the client.
196// /// </summary> 196// /// </summary>
197// private void ProcessAssetQueue() 197// private void ProcessAssetQueue()
198// { 198// {
199// //should move the asset downloading to a module, like has been done with texture downloading 199// //should move the asset downloading to a module, like has been done with texture downloading
200// if (AssetRequests.Count == 0) 200// if (AssetRequests.Count == 0)
201// { 201// {
202// //no requests waiting 202// //no requests waiting
203// return; 203// return;
204// } 204// }
205// // if less than 5, do all of them 205// // if less than 5, do all of them
206// int num = Math.Min(5, AssetRequests.Count); 206// int num = Math.Min(5, AssetRequests.Count);
207 207
208// AssetRequest req; 208// AssetRequest req;
209// for (int i = 0; i < num; i++) 209// for (int i = 0; i < num; i++)
210// { 210// {
211// req = (AssetRequest)AssetRequests[i]; 211// req = (AssetRequest)AssetRequests[i];
212// //Console.WriteLine("sending asset " + req.RequestAssetID); 212// //Console.WriteLine("sending asset " + req.RequestAssetID);
213// TransferInfoPacket Transfer = new TransferInfoPacket(); 213// TransferInfoPacket Transfer = new TransferInfoPacket();
214// Transfer.TransferInfo.ChannelType = 2; 214// Transfer.TransferInfo.ChannelType = 2;
215// Transfer.TransferInfo.Status = 0; 215// Transfer.TransferInfo.Status = 0;
216// Transfer.TransferInfo.TargetType = 0; 216// Transfer.TransferInfo.TargetType = 0;
217// if (req.AssetRequestSource == 2) 217// if (req.AssetRequestSource == 2)
218// { 218// {
219// Transfer.TransferInfo.Params = new byte[20]; 219// Transfer.TransferInfo.Params = new byte[20];
220// Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); 220// Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16);
221// int assType = (int)req.AssetInf.Type; 221// int assType = (int)req.AssetInf.Type;
222// Array.Copy(Helpers.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4); 222// Array.Copy(Helpers.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4);
223// } 223// }
224// else if (req.AssetRequestSource == 3) 224// else if (req.AssetRequestSource == 3)
225// { 225// {
226// Transfer.TransferInfo.Params = req.Params; 226// Transfer.TransferInfo.Params = req.Params;
227// // Transfer.TransferInfo.Params = new byte[100]; 227// // Transfer.TransferInfo.Params = new byte[100];
228// //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); 228// //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16);
229// //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16); 229// //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16);
230// } 230// }
231// Transfer.TransferInfo.Size = (int)req.AssetInf.Data.Length; 231// Transfer.TransferInfo.Size = (int)req.AssetInf.Data.Length;
232// Transfer.TransferInfo.TransferID = req.TransferRequestID; 232// Transfer.TransferInfo.TransferID = req.TransferRequestID;
233// req.RequestUser.OutPacket(Transfer, ThrottleOutPacketType.Asset); 233// req.RequestUser.OutPacket(Transfer, ThrottleOutPacketType.Asset);
234 234
235// if (req.NumPackets == 1) 235// if (req.NumPackets == 1)
236// { 236// {
237// TransferPacketPacket TransferPacket = new TransferPacketPacket(); 237// TransferPacketPacket TransferPacket = new TransferPacketPacket();
238// TransferPacket.TransferData.Packet = 0; 238// TransferPacket.TransferData.Packet = 0;
239// TransferPacket.TransferData.ChannelType = 2; 239// TransferPacket.TransferData.ChannelType = 2;
240// TransferPacket.TransferData.TransferID = req.TransferRequestID; 240// TransferPacket.TransferData.TransferID = req.TransferRequestID;
241// TransferPacket.TransferData.Data = req.AssetInf.Data; 241// TransferPacket.TransferData.Data = req.AssetInf.Data;
242// TransferPacket.TransferData.Status = 1; 242// TransferPacket.TransferData.Status = 1;
243// req.RequestUser.OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 243// req.RequestUser.OutPacket(TransferPacket, ThrottleOutPacketType.Asset);
244// } 244// }
245// else 245// else
246// { 246// {
247// int processedLength = 0; 247// int processedLength = 0;
248// // libsecondlife hardcodes 1500 as the maximum data chunk size 248// // libsecondlife hardcodes 1500 as the maximum data chunk size
249// int maxChunkSize = 1250; 249// int maxChunkSize = 1250;
250// int packetNumber = 0; 250// int packetNumber = 0;
251 251
252// while (processedLength < req.AssetInf.Data.Length) 252// while (processedLength < req.AssetInf.Data.Length)
253// { 253// {
254// TransferPacketPacket TransferPacket = new TransferPacketPacket(); 254// TransferPacketPacket TransferPacket = new TransferPacketPacket();
255// TransferPacket.TransferData.Packet = packetNumber; 255// TransferPacket.TransferData.Packet = packetNumber;
256// TransferPacket.TransferData.ChannelType = 2; 256// TransferPacket.TransferData.ChannelType = 2;
257// TransferPacket.TransferData.TransferID = req.TransferRequestID; 257// TransferPacket.TransferData.TransferID = req.TransferRequestID;
258 258
259// int chunkSize = Math.Min(req.AssetInf.Data.Length - processedLength, maxChunkSize); 259// int chunkSize = Math.Min(req.AssetInf.Data.Length - processedLength, maxChunkSize);
260// byte[] chunk = new byte[chunkSize]; 260// byte[] chunk = new byte[chunkSize];
261// Array.Copy(req.AssetInf.Data, processedLength, chunk, 0, chunk.Length); 261// Array.Copy(req.AssetInf.Data, processedLength, chunk, 0, chunk.Length);
262 262
263// TransferPacket.TransferData.Data = chunk; 263// TransferPacket.TransferData.Data = chunk;
264 264
265// // 0 indicates more packets to come, 1 indicates last packet 265// // 0 indicates more packets to come, 1 indicates last packet
266// if (req.AssetInf.Data.Length - processedLength > maxChunkSize) 266// if (req.AssetInf.Data.Length - processedLength > maxChunkSize)
267// { 267// {
268// TransferPacket.TransferData.Status = 0; 268// TransferPacket.TransferData.Status = 0;
269// } 269// }
270// else 270// else
271// { 271// {
272// TransferPacket.TransferData.Status = 1; 272// TransferPacket.TransferData.Status = 1;
273// } 273// }
274 274
275// req.RequestUser.OutPacket(TransferPacket, ThrottleOutPacketType.Asset); 275// req.RequestUser.OutPacket(TransferPacket, ThrottleOutPacketType.Asset);
276 276
277// processedLength += chunkSize; 277// processedLength += chunkSize;
278// packetNumber++; 278// packetNumber++;
279// } 279// }
280// } 280// }
281// } 281// }
282 282
283// //remove requests that have been completed 283// //remove requests that have been completed
284// for (int i = 0; i < num; i++) 284// for (int i = 0; i < num; i++)
285// { 285// {
286// AssetRequests.RemoveAt(0); 286// AssetRequests.RemoveAt(0);
287// } 287// }
288// } 288// }
289 289
290 /// <summary> 290 /// <summary>
291 /// Calculate the number of packets required to send the asset to the client. 291 /// Calculate the number of packets required to send the asset to the client.
292 /// </summary> 292 /// </summary>
293 /// <param name="data"></param> 293 /// <param name="data"></param>
294 /// <returns></returns> 294 /// <returns></returns>
295 private int CalculateNumPackets(byte[] data) 295 private int CalculateNumPackets(byte[] data)
296 { 296 {
297 const uint m_maxPacketSize = 600; 297 const uint m_maxPacketSize = 600;
298 int numPackets = 1; 298 int numPackets = 1;
299 299
300 if (data.LongLength > m_maxPacketSize) 300 if (data.LongLength > m_maxPacketSize)
301 { 301 {
302 // over max number of bytes so split up file 302 // over max number of bytes so split up file
303 long restData = data.LongLength - m_maxPacketSize; 303 long restData = data.LongLength - m_maxPacketSize;
304 int restPackets = (int)((restData + m_maxPacketSize - 1) / m_maxPacketSize); 304 int restPackets = (int)((restData + m_maxPacketSize - 1) / m_maxPacketSize);
305 numPackets += restPackets; 305 numPackets += restPackets;
306 } 306 }
307 307
308 return numPackets; 308 return numPackets;
309 } 309 }
310 310
311 public class AssetRequest 311 public class AssetRequest
312 { 312 {
313 public IClientAPI RequestUser; 313 public IClientAPI RequestUser;
314 public LLUUID RequestAssetID; 314 public LLUUID RequestAssetID;
315 public AssetBase AssetInf; 315 public AssetBase AssetInf;
316 public AssetBase ImageInfo; 316 public AssetBase ImageInfo;
317 public LLUUID TransferRequestID; 317 public LLUUID TransferRequestID;
318 public long DataPointer = 0; 318 public long DataPointer = 0;
319 public int NumPackets = 0; 319 public int NumPackets = 0;
320 public int PacketCounter = 0; 320 public int PacketCounter = 0;
321 public bool IsTextureRequest; 321 public bool IsTextureRequest;
322 public byte AssetRequestSource = 2; 322 public byte AssetRequestSource = 2;
323 public byte[] Params = null; 323 public byte[] Params = null;
324 //public bool AssetInCache; 324 //public bool AssetInCache;
325 //public int TimeRequested; 325 //public int TimeRequested;
326 public int DiscardLevel = -1; 326 public int DiscardLevel = -1;
327 327
328 public AssetRequest() 328 public AssetRequest()
329 { 329 {
330 } 330 }
331 } 331 }
332 } 332 }
333} 333} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/AgentAssetsTransactions.cs b/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AgentAssetsTransactions.cs
index 9fa173d..74bb247 100644
--- a/OpenSim/Region/Environment/Modules/AgentAssetsTransactions.cs
+++ b/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AgentAssetsTransactions.cs
@@ -1,408 +1,407 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the 12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO; 30using System.IO;
31using libsecondlife; 31using libsecondlife;
32using libsecondlife.Packets; 32using libsecondlife.Packets;
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Framework.Communications.Cache; 34using OpenSim.Framework.Communications.Cache;
35 35
36namespace OpenSim.Region.Environment.Modules 36namespace OpenSim.Region.Environment.Modules.Agent.AssetTransaction
37{ 37{
38 38 /// <summary>
39 /// <summary> 39 /// Manage asset transactions for a single agent.
40 /// Manage asset transactions for a single agent. 40 /// </summary>
41 /// </summary> 41 public class AgentAssetTransactions
42 public class AgentAssetTransactions 42 {
43 { 43 //private static readonly log4net.ILog m_log
44 //private static readonly log4net.ILog m_log 44 // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
45 // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 45
46 46 // Fields
47 // Fields 47 public LLUUID UserID;
48 public LLUUID UserID; 48 public Dictionary<LLUUID, AssetXferUploader> XferUploaders = new Dictionary<LLUUID, AssetXferUploader>();
49 public Dictionary<LLUUID, AssetXferUploader> XferUploaders = new Dictionary<LLUUID, AssetXferUploader>(); 49 public AgentAssetTransactionsManager Manager;
50 public AgentAssetTransactionsManager Manager; 50 private bool m_dumpAssetsToFile;
51 private bool m_dumpAssetsToFile; 51
52 52 // Methods
53 // Methods 53 public AgentAssetTransactions(LLUUID agentID, AgentAssetTransactionsManager manager, bool dumpAssetsToFile)
54 public AgentAssetTransactions(LLUUID agentID, AgentAssetTransactionsManager manager, bool dumpAssetsToFile) 54 {
55 { 55 UserID = agentID;
56 UserID = agentID; 56 Manager = manager;
57 Manager = manager; 57 m_dumpAssetsToFile = dumpAssetsToFile;
58 m_dumpAssetsToFile = dumpAssetsToFile; 58 }
59 } 59
60 60 public AssetXferUploader RequestXferUploader(LLUUID transactionID)
61 public AssetXferUploader RequestXferUploader(LLUUID transactionID) 61 {
62 { 62 if (!XferUploaders.ContainsKey(transactionID))
63 if (!XferUploaders.ContainsKey(transactionID)) 63 {
64 { 64 AssetXferUploader uploader = new AssetXferUploader(this, m_dumpAssetsToFile);
65 AssetXferUploader uploader = new AssetXferUploader(this, m_dumpAssetsToFile); 65
66 66 lock (XferUploaders)
67 lock (XferUploaders) 67 {
68 { 68 XferUploaders.Add(transactionID, uploader);
69 XferUploaders.Add(transactionID, uploader); 69 }
70 } 70
71 71 return uploader;
72 return uploader; 72 }
73 } 73 return null;
74 return null; 74 }
75 } 75
76 76 public void HandleXfer(ulong xferID, uint packetID, byte[] data)
77 public void HandleXfer(ulong xferID, uint packetID, byte[] data) 77 {
78 { 78 // AssetXferUploader uploaderFound = null;
79 // AssetXferUploader uploaderFound = null; 79
80 80 lock (XferUploaders)
81 lock (XferUploaders) 81 {
82 { 82 foreach (AssetXferUploader uploader in XferUploaders.Values)
83 foreach (AssetXferUploader uploader in XferUploaders.Values) 83 {
84 { 84 if (uploader.XferID == xferID)
85 if (uploader.XferID == xferID) 85 {
86 { 86 uploader.HandleXferPacket(xferID, packetID, data);
87 uploader.HandleXferPacket(xferID, packetID, data); 87 break;
88 break; 88 }
89 } 89 }
90 } 90 }
91 } 91 }
92 } 92
93 93 public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID,
94 public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, 94 uint callbackID, string description, string name, sbyte invType,
95 uint callbackID, string description, string name, sbyte invType, 95 sbyte type, byte wearableType, uint nextOwnerMask)
96 sbyte type, byte wearableType, uint nextOwnerMask) 96 {
97 { 97 if (XferUploaders.ContainsKey(transactionID))
98 if (XferUploaders.ContainsKey(transactionID)) 98 {
99 { 99 XferUploaders[transactionID].RequestCreateInventoryItem(remoteClient, transactionID, folderID,
100 XferUploaders[transactionID].RequestCreateInventoryItem(remoteClient, transactionID, folderID, 100 callbackID, description, name, invType, type,
101 callbackID, description, name, invType, type, 101 wearableType, nextOwnerMask);
102 wearableType, nextOwnerMask); 102 }
103 } 103 }
104 } 104
105 105 public void RequestUpdateInventoryItem(IClientAPI remoteClient, LLUUID transactionID,
106 public void RequestUpdateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, 106 InventoryItemBase item)
107 InventoryItemBase item) 107 {
108 { 108 if (XferUploaders.ContainsKey(transactionID))
109 if (XferUploaders.ContainsKey(transactionID)) 109 {
110 { 110 XferUploaders[transactionID].RequestUpdateInventoryItem(remoteClient, transactionID, item);
111 XferUploaders[transactionID].RequestUpdateInventoryItem(remoteClient, transactionID, item); 111 }
112 } 112 }
113 } 113
114 114 /// <summary>
115 /// <summary> 115 /// Get an uploaded asset. If the data is successfully retrieved, the transaction will be removed.
116 /// Get an uploaded asset. If the data is successfully retrieved, the transaction will be removed. 116 /// </summary>
117 /// </summary> 117 /// <param name="transactionID"></param>
118 /// <param name="transactionID"></param> 118 /// <returns>The asset if the upload has completed, null if it has not.</returns>
119 /// <returns>The asset if the upload has completed, null if it has not.</returns> 119 public AssetBase GetTransactionAsset(LLUUID transactionID)
120 public AssetBase GetTransactionAsset(LLUUID transactionID) 120 {
121 { 121 if (XferUploaders.ContainsKey(transactionID))
122 if (XferUploaders.ContainsKey(transactionID)) 122 {
123 { 123 AssetXferUploader uploader = XferUploaders[transactionID];
124 AssetXferUploader uploader = XferUploaders[transactionID]; 124 AssetBase asset = uploader.GetAssetData();
125 AssetBase asset = uploader.GetAssetData(); 125
126 126 lock (XferUploaders)
127 lock (XferUploaders) 127 {
128 { 128 XferUploaders.Remove(transactionID);
129 XferUploaders.Remove(transactionID); 129 }
130 } 130
131 131 return asset;
132 return asset; 132 }
133 } 133
134 134 return null;
135 return null; 135 }
136 } 136
137 137 // Nested Types
138 // Nested Types 138 public class AssetXferUploader
139 public class AssetXferUploader 139 {
140 { 140 // Fields
141 // Fields 141 public bool AddToInventory;
142 public bool AddToInventory; 142 public AssetBase Asset;
143 public AssetBase Asset; 143 public LLUUID InventFolder = LLUUID.Zero;
144 public LLUUID InventFolder = LLUUID.Zero; 144 private IClientAPI ourClient;
145 private IClientAPI ourClient; 145 public LLUUID TransactionID = LLUUID.Zero;
146 public LLUUID TransactionID = LLUUID.Zero; 146 public bool UploadComplete;
147 public bool UploadComplete; 147 public ulong XferID;
148 public ulong XferID; 148 private string m_name = String.Empty;
149 private string m_name = String.Empty; 149 private string m_description = String.Empty;
150 private string m_description = String.Empty; 150 private sbyte type = 0;
151 private sbyte type = 0; 151 private sbyte invType = 0;
152 private sbyte invType = 0; 152 private byte wearableType = 0;
153 private byte wearableType = 0; 153 private uint nextPerm = 0;
154 private uint nextPerm = 0; 154 private bool m_finished = false;
155 private bool m_finished = false; 155 private bool m_createItem = false;
156 private bool m_createItem = false; 156 private AgentAssetTransactions m_userTransactions;
157 private AgentAssetTransactions m_userTransactions; 157 private bool m_storeLocal;
158 private bool m_storeLocal; 158 private bool m_dumpAssetToFile;
159 private bool m_dumpAssetToFile; 159
160 160 public AssetXferUploader(AgentAssetTransactions transactions, bool dumpAssetToFile)
161 public AssetXferUploader(AgentAssetTransactions transactions, bool dumpAssetToFile) 161 {
162 { 162 m_userTransactions = transactions;
163 m_userTransactions = transactions; 163 m_dumpAssetToFile = dumpAssetToFile;
164 m_dumpAssetToFile = dumpAssetToFile; 164 }
165 } 165
166 166 /// <summary>
167 /// <summary> 167 /// Process transfer data received from the client.
168 /// Process transfer data received from the client. 168 /// </summary>
169 /// </summary> 169 /// <param name="xferID"></param>
170 /// <param name="xferID"></param> 170 /// <param name="packetID"></param>
171 /// <param name="packetID"></param> 171 /// <param name="data"></param>
172 /// <param name="data"></param> 172 /// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns>
173 /// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns> 173 public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data)
174 public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data) 174 {
175 { 175 if (XferID == xferID)
176 if (XferID == xferID) 176 {
177 { 177 if (Asset.Data.Length > 1)
178 if (Asset.Data.Length > 1) 178 {
179 { 179 byte[] destinationArray = new byte[Asset.Data.Length + data.Length];
180 byte[] destinationArray = new byte[Asset.Data.Length + data.Length]; 180 Array.Copy(Asset.Data, 0, destinationArray, 0, Asset.Data.Length);
181 Array.Copy(Asset.Data, 0, destinationArray, 0, Asset.Data.Length); 181 Array.Copy(data, 0, destinationArray, Asset.Data.Length, data.Length);
182 Array.Copy(data, 0, destinationArray, Asset.Data.Length, data.Length); 182 Asset.Data = destinationArray;
183 Asset.Data = destinationArray; 183 }
184 } 184 else
185 else 185 {
186 { 186 byte[] buffer2 = new byte[data.Length - 4];
187 byte[] buffer2 = new byte[data.Length - 4]; 187 Array.Copy(data, 4, buffer2, 0, data.Length - 4);
188 Array.Copy(data, 4, buffer2, 0, data.Length - 4); 188 Asset.Data = buffer2;
189 Asset.Data = buffer2; 189 }
190 } 190 ConfirmXferPacketPacket newPack = new ConfirmXferPacketPacket();
191 ConfirmXferPacketPacket newPack = new ConfirmXferPacketPacket(); 191 newPack.XferID.ID = xferID;
192 newPack.XferID.ID = xferID; 192 newPack.XferID.Packet = packetID;
193 newPack.XferID.Packet = packetID; 193 ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset);
194 ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); 194 if ((packetID & 0x80000000) != 0)
195 if ((packetID & 0x80000000) != 0) 195 {
196 { 196 SendCompleteMessage();
197 SendCompleteMessage(); 197 return true;
198 return true; 198 }
199 } 199 }
200 } 200
201 201 return false;
202 return false; 202 }
203 } 203
204 204 /// <summary>
205 /// <summary> 205 /// Initialise asset transfer from the client
206 /// Initialise asset transfer from the client 206 /// </summary>
207 /// </summary> 207 /// <param name="xferID"></param>
208 /// <param name="xferID"></param> 208 /// <param name="packetID"></param>
209 /// <param name="packetID"></param> 209 /// <param name="data"></param>
210 /// <param name="data"></param> 210 /// <returns>True if the transfer is complete, false otherwise</returns>
211 /// <returns>True if the transfer is complete, false otherwise</returns> 211 public bool Initialise(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data,
212 public bool Initialise(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data, 212 bool storeLocal, bool tempFile)
213 bool storeLocal, bool tempFile) 213 {
214 { 214 ourClient = remoteClient;
215 ourClient = remoteClient; 215 Asset = new AssetBase();
216 Asset = new AssetBase(); 216 Asset.FullID = assetID;
217 Asset.FullID = assetID; 217 Asset.InvType = type;
218 Asset.InvType = type; 218 Asset.Type = type;
219 Asset.Type = type; 219 Asset.Data = data;
220 Asset.Data = data; 220 Asset.Name = "blank";
221 Asset.Name = "blank"; 221 Asset.Description = "empty";
222 Asset.Description = "empty"; 222 Asset.Local = storeLocal;
223 Asset.Local = storeLocal; 223 Asset.Temporary = tempFile;
224 Asset.Temporary = tempFile; 224
225 225 TransactionID = transaction;
226 TransactionID = transaction; 226 m_storeLocal = storeLocal;
227 m_storeLocal = storeLocal; 227 if (Asset.Data.Length > 2)
228 if (Asset.Data.Length > 2) 228 {
229 { 229 SendCompleteMessage();
230 SendCompleteMessage(); 230 return true;
231 return true; 231 }
232 } 232 else
233 else 233 {
234 { 234 RequestStartXfer();
235 RequestStartXfer(); 235 }
236 } 236
237 237 return false;
238 return false; 238 }
239 } 239
240 240 protected void RequestStartXfer()
241 protected void RequestStartXfer() 241 {
242 { 242 UploadComplete = false;
243 UploadComplete = false; 243 XferID = Util.GetNextXferID();
244 XferID = Util.GetNextXferID(); 244 RequestXferPacket newPack = new RequestXferPacket();
245 RequestXferPacket newPack = new RequestXferPacket(); 245 newPack.XferID.ID = XferID;
246 newPack.XferID.ID = XferID; 246 newPack.XferID.VFileType = Asset.Type;
247 newPack.XferID.VFileType = Asset.Type; 247 newPack.XferID.VFileID = Asset.FullID;
248 newPack.XferID.VFileID = Asset.FullID; 248 newPack.XferID.FilePath = 0;
249 newPack.XferID.FilePath = 0; 249 newPack.XferID.Filename = new byte[0];
250 newPack.XferID.Filename = new byte[0]; 250 ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset);
251 ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); 251 }
252 } 252
253 253 protected void SendCompleteMessage()
254 protected void SendCompleteMessage() 254 {
255 { 255 UploadComplete = true;
256 UploadComplete = true; 256 AssetUploadCompletePacket newPack = new AssetUploadCompletePacket();
257 AssetUploadCompletePacket newPack = new AssetUploadCompletePacket(); 257 newPack.AssetBlock.Type = Asset.Type;
258 newPack.AssetBlock.Type = Asset.Type; 258 newPack.AssetBlock.Success = true;
259 newPack.AssetBlock.Success = true; 259 newPack.AssetBlock.UUID = Asset.FullID;
260 newPack.AssetBlock.UUID = Asset.FullID; 260 ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset);
261 ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); 261 m_finished = true;
262 m_finished = true; 262 if (m_createItem)
263 if (m_createItem) 263 {
264 { 264 DoCreateItem();
265 DoCreateItem(); 265 }
266 } 266 else if (m_storeLocal)
267 else if (m_storeLocal) 267 {
268 { 268 m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(Asset);
269 m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(Asset); 269 }
270 } 270
271 271 // Console.WriteLine("upload complete "+ this.TransactionID);
272 // Console.WriteLine("upload complete "+ this.TransactionID); 272
273 273 if (m_dumpAssetToFile)
274 if (m_dumpAssetToFile) 274 {
275 { 275 DateTime now = DateTime.Now;
276 DateTime now = DateTime.Now; 276 string filename =
277 string filename = 277 String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat", now.Year, now.Month, now.Day,
278 String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat", now.Year, now.Month, now.Day, 278 now.Hour, now.Minute, now.Second, Asset.Name, Asset.Type);
279 now.Hour, now.Minute, now.Second, Asset.Name, Asset.Type); 279 SaveAssetToFile(filename, Asset.Data);
280 SaveAssetToFile(filename, Asset.Data); 280 }
281 } 281 }
282 } 282
283 283 ///Left this in and commented in case there are unforseen issues
284 ///Left this in and commented in case there are unforseen issues 284 //private void SaveAssetToFile(string filename, byte[] data)
285 //private void SaveAssetToFile(string filename, byte[] data) 285 //{
286 //{ 286 // FileStream fs = File.Create(filename);
287 // FileStream fs = File.Create(filename); 287 // BinaryWriter bw = new BinaryWriter(fs);
288 // BinaryWriter bw = new BinaryWriter(fs); 288 // bw.Write(data);
289 // bw.Write(data); 289 // bw.Close();
290 // bw.Close(); 290 // fs.Close();
291 // fs.Close(); 291 //}
292 //} 292 private void SaveAssetToFile(string filename, byte[] data)
293 private void SaveAssetToFile(string filename, byte[] data) 293 {
294 { 294 string assetPath = "UserAssets";
295 string assetPath = "UserAssets"; 295 if (!Directory.Exists(assetPath))
296 if (!Directory.Exists(assetPath)) 296 {
297 { 297 Directory.CreateDirectory(assetPath);
298 Directory.CreateDirectory(assetPath); 298 }
299 } 299 FileStream fs = File.Create(Path.Combine(assetPath, filename));
300 FileStream fs = File.Create(Path.Combine(assetPath, filename)); 300 BinaryWriter bw = new BinaryWriter(fs);
301 BinaryWriter bw = new BinaryWriter(fs); 301 bw.Write(data);
302 bw.Write(data); 302 bw.Close();
303 bw.Close(); 303 fs.Close();
304 fs.Close(); 304 }
305 } 305
306 306 public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID,
307 public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, 307 uint callbackID, string description, string name, sbyte invType,
308 uint callbackID, string description, string name, sbyte invType, 308 sbyte type, byte wearableType, uint nextOwnerMask)
309 sbyte type, byte wearableType, uint nextOwnerMask) 309 {
310 { 310 if (TransactionID == transactionID)
311 if (TransactionID == transactionID) 311 {
312 { 312 InventFolder = folderID;
313 InventFolder = folderID; 313 m_name = name;
314 m_name = name; 314 m_description = description;
315 m_description = description; 315 this.type = type;
316 this.type = type; 316 this.invType = invType;
317 this.invType = invType; 317 this.wearableType = wearableType;
318 this.wearableType = wearableType; 318 nextPerm = nextOwnerMask;
319 nextPerm = nextOwnerMask; 319 Asset.Name = name;
320 Asset.Name = name; 320 Asset.Description = description;
321 Asset.Description = description; 321 Asset.Type = type;
322 Asset.Type = type; 322 Asset.InvType = invType;
323 Asset.InvType = invType; 323 m_createItem = true;
324 m_createItem = true; 324 if (m_finished)
325 if (m_finished) 325 {
326 { 326 DoCreateItem();
327 DoCreateItem(); 327 }
328 } 328 }
329 } 329 }
330 } 330
331 331 public void RequestUpdateInventoryItem(IClientAPI remoteClient, LLUUID transactionID,
332 public void RequestUpdateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, 332 InventoryItemBase item)
333 InventoryItemBase item) 333 {
334 { 334 if (TransactionID == transactionID)
335 if (TransactionID == transactionID) 335 {
336 { 336 CachedUserInfo userInfo =
337 CachedUserInfo userInfo = 337 m_userTransactions.Manager.MyScene.CommsManager.UserProfileCacheService.GetUserDetails(
338 m_userTransactions.Manager.MyScene.CommsManager.UserProfileCacheService.GetUserDetails( 338 remoteClient.AgentId);
339 remoteClient.AgentId); 339
340 340 if (userInfo != null)
341 if (userInfo != null) 341 {
342 { 342 LLUUID assetID = LLUUID.Combine(transactionID, remoteClient.SecureSessionId);
343 LLUUID assetID = LLUUID.Combine(transactionID, remoteClient.SecureSessionId); 343
344 344 AssetBase asset
345 AssetBase asset 345 = m_userTransactions.Manager.MyScene.CommsManager.AssetCache.GetAsset(
346 = m_userTransactions.Manager.MyScene.CommsManager.AssetCache.GetAsset( 346 assetID, (item.AssetType == (int) AssetType.Texture ? true : false));
347 assetID, (item.AssetType == (int) AssetType.Texture ? true : false)); 347
348 348 if (asset == null)
349 if (asset == null) 349 {
350 { 350 asset = m_userTransactions.GetTransactionAsset(transactionID);
351 asset = m_userTransactions.GetTransactionAsset(transactionID); 351 }
352 } 352
353 353 if (asset != null && asset.FullID == assetID)
354 if (asset != null && asset.FullID == assetID) 354 {
355 { 355 asset.Name = item.Name;
356 asset.Name = item.Name; 356 asset.Description = item.Description;
357 asset.Description = item.Description; 357 asset.InvType = (sbyte) item.InvType;
358 asset.InvType = (sbyte) item.InvType; 358 asset.Type = (sbyte) item.AssetType;
359 asset.Type = (sbyte) item.AssetType; 359 item.AssetID = asset.FullID;
360 item.AssetID = asset.FullID; 360
361 361 m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(Asset);
362 m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(Asset); 362 }
363 } 363
364 364 userInfo.UpdateItem(remoteClient.AgentId, item);
365 userInfo.UpdateItem(remoteClient.AgentId, item); 365 }
366 } 366 }
367 } 367 }
368 } 368
369 369 private void DoCreateItem()
370 private void DoCreateItem() 370 {
371 { 371 //really need to fix this call, if lbsa71 saw this he would die.
372 //really need to fix this call, if lbsa71 saw this he would die. 372 m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(Asset);
373 m_userTransactions.Manager.MyScene.CommsManager.AssetCache.AddAsset(Asset); 373 CachedUserInfo userInfo =
374 CachedUserInfo userInfo = 374 m_userTransactions.Manager.MyScene.CommsManager.UserProfileCacheService.GetUserDetails(ourClient.AgentId);
375 m_userTransactions.Manager.MyScene.CommsManager.UserProfileCacheService.GetUserDetails(ourClient.AgentId); 375 if (userInfo != null)
376 if (userInfo != null) 376 {
377 { 377 InventoryItemBase item = new InventoryItemBase();
378 InventoryItemBase item = new InventoryItemBase(); 378 item.Owner = ourClient.AgentId;
379 item.Owner = ourClient.AgentId; 379 item.Creator = ourClient.AgentId;
380 item.Creator = ourClient.AgentId; 380 item.ID = LLUUID.Random();
381 item.ID = LLUUID.Random(); 381 item.AssetID = Asset.FullID;
382 item.AssetID = Asset.FullID; 382 item.Description = m_description;
383 item.Description = m_description; 383 item.Name = m_name;
384 item.Name = m_name; 384 item.AssetType = type;
385 item.AssetType = type; 385 item.InvType = invType;
386 item.InvType = invType; 386 item.Folder = InventFolder;
387 item.Folder = InventFolder; 387 item.BasePermissions = 2147483647;
388 item.BasePermissions = 2147483647; 388 item.CurrentPermissions = 2147483647;
389 item.CurrentPermissions = 2147483647; 389 item.NextPermissions = nextPerm;
390 item.NextPermissions = nextPerm; 390 item.Flags = (uint)wearableType;
391 item.Flags = (uint)wearableType; 391
392 392 userInfo.AddItem(ourClient.AgentId, item);
393 userInfo.AddItem(ourClient.AgentId, item); 393 ourClient.SendInventoryItemCreateUpdate(item);
394 ourClient.SendInventoryItemCreateUpdate(item); 394 }
395 } 395 }
396 } 396
397 397 public AssetBase GetAssetData()
398 public AssetBase GetAssetData() 398 {
399 { 399 if (m_finished)
400 if (m_finished) 400 {
401 { 401 return Asset;
402 return Asset; 402 }
403 } 403 return null;
404 return null; 404 }
405 } 405 }
406 } 406 }
407 } 407} \ No newline at end of file
408}
diff --git a/OpenSim/Region/Environment/Modules/AgentAssetTransactionModule.cs b/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AssetTransactionModule.cs
index cec7192..ef81625 100644
--- a/OpenSim/Region/Environment/Modules/AgentAssetTransactionModule.cs
+++ b/OpenSim/Region/Environment/Modules/Agent/AssetTransaction/AssetTransactionModule.cs
@@ -1,286 +1,286 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the 12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using libsecondlife; 31using libsecondlife;
32using log4net; 32using log4net;
33using Nini.Config; 33using Nini.Config;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Region.Environment.Interfaces; 35using OpenSim.Region.Environment.Interfaces;
36using OpenSim.Region.Environment.Scenes; 36using OpenSim.Region.Environment.Modules.Agent.AssetTransaction;
37 37using OpenSim.Region.Environment.Scenes;
38namespace OpenSim.Region.Environment.Modules 38
39{ 39namespace OpenSim.Region.Environment.Modules.Agent.AssetTransaction
40 public class AgentAssetTransactionModule : IRegionModule, IAgentAssetTransactions 40{
41 { 41 public class AssetTransactionModule : IRegionModule, IAgentAssetTransactions
42 private Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>(); 42 {
43 private Scene m_scene = null; 43 private readonly Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>();
44 private bool m_dumpAssetsToFile = false; 44 private Scene m_scene = null;
45 45 private bool m_dumpAssetsToFile = false;
46 private AgentAssetTransactionsManager m_transactionManager; 46
47 47 private AgentAssetTransactionsManager m_transactionManager;
48 public AgentAssetTransactionModule() 48
49 { 49 public AssetTransactionModule()
50 // System.Console.WriteLine("creating AgentAssetTransactionModule"); 50 {
51 } 51 // System.Console.WriteLine("creating AgentAssetTransactionModule");
52 52 }
53 public void Initialise(Scene scene, IConfigSource config) 53
54 { 54 public void Initialise(Scene scene, IConfigSource config)
55 if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) 55 {
56 { 56 if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
57 // System.Console.WriteLine("initialising AgentAssetTransactionModule"); 57 {
58 RegisteredScenes.Add(scene.RegionInfo.RegionID, scene); 58 // System.Console.WriteLine("initialising AgentAssetTransactionModule");
59 scene.RegisterModuleInterface<IAgentAssetTransactions>(this); 59 RegisteredScenes.Add(scene.RegionInfo.RegionID, scene);
60 60 scene.RegisterModuleInterface<IAgentAssetTransactions>(this);
61 scene.EventManager.OnNewClient += NewClient; 61
62 } 62 scene.EventManager.OnNewClient += NewClient;
63 63 }
64 if (m_scene == null) 64
65 { 65 if (m_scene == null)
66 m_scene = scene; 66 {
67 if (config.Configs["StandAlone"] != null) 67 m_scene = scene;
68 { 68 if (config.Configs["StandAlone"] != null)
69 try 69 {
70 { 70 try
71 m_dumpAssetsToFile = config.Configs["StandAlone"].GetBoolean("dump_assets_to_file", false); 71 {
72 m_transactionManager = new AgentAssetTransactionsManager(m_scene, m_dumpAssetsToFile); 72 m_dumpAssetsToFile = config.Configs["StandAlone"].GetBoolean("dump_assets_to_file", false);
73 } 73 m_transactionManager = new AgentAssetTransactionsManager(m_scene, m_dumpAssetsToFile);
74 catch (Exception) 74 }
75 { 75 catch (Exception)
76 m_transactionManager = new AgentAssetTransactionsManager(m_scene, false); 76 {
77 } 77 m_transactionManager = new AgentAssetTransactionsManager(m_scene, false);
78 } 78 }
79 else 79 }
80 { 80 else
81 m_transactionManager = new AgentAssetTransactionsManager(m_scene, false); 81 {
82 } 82 m_transactionManager = new AgentAssetTransactionsManager(m_scene, false);
83 83 }
84 } 84
85 } 85 }
86 86 }
87 public void PostInitialise() 87
88 { 88 public void PostInitialise()
89 89 {
90 } 90
91 91 }
92 public void Close() 92
93 { 93 public void Close()
94 } 94 {
95 95 }
96 public string Name 96
97 { 97 public string Name
98 get { return "AgentTransactionModule"; } 98 {
99 } 99 get { return "AgentTransactionModule"; }
100 100 }
101 public bool IsSharedModule 101
102 { 102 public bool IsSharedModule
103 get { return true; } 103 {
104 } 104 get { return true; }
105 105 }
106 public void NewClient(IClientAPI client) 106
107 { 107 public void NewClient(IClientAPI client)
108 client.OnAssetUploadRequest += m_transactionManager.HandleUDPUploadRequest; 108 {
109 client.OnXferReceive += m_transactionManager.HandleXfer; 109 client.OnAssetUploadRequest += m_transactionManager.HandleUDPUploadRequest;
110 } 110 client.OnXferReceive += m_transactionManager.HandleXfer;
111 111 }
112 public void HandleItemCreationFromTransaction(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, 112
113 uint callbackID, string description, string name, sbyte invType, 113 public void HandleItemCreationFromTransaction(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID,
114 sbyte type, byte wearableType, uint nextOwnerMask) 114 uint callbackID, string description, string name, sbyte invType,
115 { 115 sbyte type, byte wearableType, uint nextOwnerMask)
116 m_transactionManager.HandleItemCreationFromTransaction(remoteClient, transactionID, folderID, callbackID, description, name, invType, type, wearableType, nextOwnerMask); 116 {
117 } 117 m_transactionManager.HandleItemCreationFromTransaction(remoteClient, transactionID, folderID, callbackID, description, name, invType, type, wearableType, nextOwnerMask);
118 118 }
119 public void HandleItemUpdateFromTransaction(IClientAPI remoteClient, LLUUID transactionID, 119
120 InventoryItemBase item) 120 public void HandleItemUpdateFromTransaction(IClientAPI remoteClient, LLUUID transactionID,
121 { 121 InventoryItemBase item)
122 m_transactionManager.HandleItemUpdateFromTransaction(remoteClient, transactionID, item); 122 {
123 } 123 m_transactionManager.HandleItemUpdateFromTransaction(remoteClient, transactionID, item);
124 124 }
125 public void RemoveAgentAssetTransactions(LLUUID userID) 125
126 { 126 public void RemoveAgentAssetTransactions(LLUUID userID)
127 m_transactionManager.RemoveAgentAssetTransactions(userID); 127 {
128 } 128 m_transactionManager.RemoveAgentAssetTransactions(userID);
129 } 129 }
130 130 }
131 //should merge this classes and clean up 131
132 public class AgentAssetTransactionsManager 132 public class AgentAssetTransactionsManager
133 { 133 {
134 private static readonly ILog m_log 134 private static readonly ILog m_log
135 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 135 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
136 136
137 // Fields 137 // Fields
138 public Scene MyScene; 138 public Scene MyScene;
139 139
140 /// <summary> 140 /// <summary>
141 /// Each agent has its own singleton collection of transactions 141 /// Each agent has its own singleton collection of transactions
142 /// </summary> 142 /// </summary>
143 private Dictionary<LLUUID, AgentAssetTransactions> AgentTransactions = 143 private Dictionary<LLUUID, AgentAssetTransactions> AgentTransactions =
144 new Dictionary<LLUUID, AgentAssetTransactions>(); 144 new Dictionary<LLUUID, AgentAssetTransactions>();
145 145
146 /// <summary> 146 /// <summary>
147 /// Should we dump uploaded assets to the filesystem? 147 /// Should we dump uploaded assets to the filesystem?
148 /// </summary> 148 /// </summary>
149 private bool m_dumpAssetsToFile; 149 private bool m_dumpAssetsToFile;
150 150
151 public AgentAssetTransactionsManager(Scene scene, bool dumpAssetsToFile) 151 public AgentAssetTransactionsManager(Scene scene, bool dumpAssetsToFile)
152 { 152 {
153 MyScene = scene; 153 MyScene = scene;
154 m_dumpAssetsToFile = dumpAssetsToFile; 154 m_dumpAssetsToFile = dumpAssetsToFile;
155 } 155 }
156 156
157 /// <summary> 157 /// <summary>
158 /// Get the collection of asset transactions for the given user. If one does not already exist, it 158 /// Get the collection of asset transactions for the given user. If one does not already exist, it
159 /// is created. 159 /// is created.
160 /// </summary> 160 /// </summary>
161 /// <param name="userID"></param> 161 /// <param name="userID"></param>
162 /// <returns></returns> 162 /// <returns></returns>
163 private AgentAssetTransactions GetUserTransactions(LLUUID userID) 163 private AgentAssetTransactions GetUserTransactions(LLUUID userID)
164 { 164 {
165 lock (AgentTransactions) 165 lock (AgentTransactions)
166 { 166 {
167 if (!AgentTransactions.ContainsKey(userID)) 167 if (!AgentTransactions.ContainsKey(userID))
168 { 168 {
169 AgentAssetTransactions transactions 169 AgentAssetTransactions transactions
170 = new AgentAssetTransactions(userID, this, m_dumpAssetsToFile); 170 = new AgentAssetTransactions(userID, this, m_dumpAssetsToFile);
171 AgentTransactions.Add(userID, transactions); 171 AgentTransactions.Add(userID, transactions);
172 } 172 }
173 173
174 return AgentTransactions[userID]; 174 return AgentTransactions[userID];
175 } 175 }
176 } 176 }
177 177
178 /// <summary> 178 /// <summary>
179 /// Remove the given agent asset transactions. This should be called when a client is departing 179 /// Remove the given agent asset transactions. This should be called when a client is departing
180 /// from a scene (and hence won't be making any more transactions here). 180 /// from a scene (and hence won't be making any more transactions here).
181 /// </summary> 181 /// </summary>
182 /// <param name="userID"></param> 182 /// <param name="userID"></param>
183 public void RemoveAgentAssetTransactions(LLUUID userID) 183 public void RemoveAgentAssetTransactions(LLUUID userID)
184 { 184 {
185 // m_log.DebugFormat("Removing agent asset transactions structure for agent {0}", userID); 185 // m_log.DebugFormat("Removing agent asset transactions structure for agent {0}", userID);
186 186
187 lock (AgentTransactions) 187 lock (AgentTransactions)
188 { 188 {
189 AgentTransactions.Remove(userID); 189 AgentTransactions.Remove(userID);
190 } 190 }
191 } 191 }
192 192
193 /// <summary> 193 /// <summary>
194 /// Create an inventory item from data that has been received through a transaction. 194 /// Create an inventory item from data that has been received through a transaction.
195 /// 195 ///
196 /// This is called when new clothing or body parts are created. It may also be called in other 196 /// This is called when new clothing or body parts are created. It may also be called in other
197 /// situations. 197 /// situations.
198 /// </summary> 198 /// </summary>
199 /// <param name="remoteClient"></param> 199 /// <param name="remoteClient"></param>
200 /// <param name="transactionID"></param> 200 /// <param name="transactionID"></param>
201 /// <param name="folderID"></param> 201 /// <param name="folderID"></param>
202 /// <param name="callbackID"></param> 202 /// <param name="callbackID"></param>
203 /// <param name="description"></param> 203 /// <param name="description"></param>
204 /// <param name="name"></param> 204 /// <param name="name"></param>
205 /// <param name="invType"></param> 205 /// <param name="invType"></param>
206 /// <param name="type"></param> 206 /// <param name="type"></param>
207 /// <param name="wearableType"></param> 207 /// <param name="wearableType"></param>
208 /// <param name="nextOwnerMask"></param> 208 /// <param name="nextOwnerMask"></param>
209 public void HandleItemCreationFromTransaction(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, 209 public void HandleItemCreationFromTransaction(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID,
210 uint callbackID, string description, string name, sbyte invType, 210 uint callbackID, string description, string name, sbyte invType,
211 sbyte type, byte wearableType, uint nextOwnerMask) 211 sbyte type, byte wearableType, uint nextOwnerMask)
212 { 212 {
213 m_log.DebugFormat( 213 m_log.DebugFormat(
214 "[TRANSACTIONS MANAGER] Called HandleItemCreationFromTransaction with item {0}", name); 214 "[TRANSACTIONS MANAGER] Called HandleItemCreationFromTransaction with item {0}", name);
215 215
216 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 216 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
217 217
218 transactions.RequestCreateInventoryItem( 218 transactions.RequestCreateInventoryItem(
219 remoteClient, transactionID, folderID, callbackID, description, 219 remoteClient, transactionID, folderID, callbackID, description,
220 name, invType, type, wearableType, nextOwnerMask); 220 name, invType, type, wearableType, nextOwnerMask);
221 } 221 }
222 222
223 /// <summary> 223 /// <summary>
224 /// Update an inventory item with data that has been received through a transaction. 224 /// Update an inventory item with data that has been received through a transaction.
225 /// 225 ///
226 /// This is called when clothing or body parts are updated (for instance, with new textures or 226 /// This is called when clothing or body parts are updated (for instance, with new textures or
227 /// colours). It may also be called in other situations. 227 /// colours). It may also be called in other situations.
228 /// </summary> 228 /// </summary>
229 /// <param name="remoteClient"></param> 229 /// <param name="remoteClient"></param>
230 /// <param name="transactionID"></param> 230 /// <param name="transactionID"></param>
231 /// <param name="item"></param> 231 /// <param name="item"></param>
232 public void HandleItemUpdateFromTransaction(IClientAPI remoteClient, LLUUID transactionID, 232 public void HandleItemUpdateFromTransaction(IClientAPI remoteClient, LLUUID transactionID,
233 InventoryItemBase item) 233 InventoryItemBase item)
234 { 234 {
235 m_log.DebugFormat( 235 m_log.DebugFormat(
236 "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}", 236 "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}",
237 item.Name); 237 item.Name);
238 238
239 AgentAssetTransactions transactions 239 AgentAssetTransactions transactions
240 = GetUserTransactions(remoteClient.AgentId); 240 = GetUserTransactions(remoteClient.AgentId);
241 241
242 transactions.RequestUpdateInventoryItem(remoteClient, transactionID, item); 242 transactions.RequestUpdateInventoryItem(remoteClient, transactionID, item);
243 } 243 }
244 244
245 /// <summary> 245 /// <summary>
246 /// Request that a client (agent) begin an asset transfer. 246 /// Request that a client (agent) begin an asset transfer.
247 /// </summary> 247 /// </summary>
248 /// <param name="remoteClient"></param> 248 /// <param name="remoteClient"></param>
249 /// <param name="assetID"></param> 249 /// <param name="assetID"></param>
250 /// <param name="transaction"></param> 250 /// <param name="transaction"></param>
251 /// <param name="type"></param> 251 /// <param name="type"></param>
252 /// <param name="data"></param></param> 252 /// <param name="data"></param></param>
253 /// <param name="tempFile"></param> 253 /// <param name="tempFile"></param>
254 public void HandleUDPUploadRequest(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, 254 public void HandleUDPUploadRequest(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type,
255 byte[] data, bool storeLocal, bool tempFile) 255 byte[] data, bool storeLocal, bool tempFile)
256 { 256 {
257 // Console.WriteLine("asset upload of " + assetID); 257 // Console.WriteLine("asset upload of " + assetID);
258 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 258 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
259 259
260 AgentAssetTransactions.AssetXferUploader uploader = transactions.RequestXferUploader(transaction); 260 AgentAssetTransactions.AssetXferUploader uploader = transactions.RequestXferUploader(transaction);
261 if (uploader != null) 261 if (uploader != null)
262 { 262 {
263 263
264 if (uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal, tempFile)) 264 if (uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal, tempFile))
265 { 265 {
266 266
267 } 267 }
268 } 268 }
269 } 269 }
270 270
271 /// <summary> 271 /// <summary>
272 /// Handle asset transfer data packets received in response to the asset upload request in 272 /// Handle asset transfer data packets received in response to the asset upload request in
273 /// HandleUDPUploadRequest() 273 /// HandleUDPUploadRequest()
274 /// </summary> 274 /// </summary>
275 /// <param name="remoteClient"></param> 275 /// <param name="remoteClient"></param>
276 /// <param name="xferID"></param> 276 /// <param name="xferID"></param>
277 /// <param name="packetID"></param> 277 /// <param name="packetID"></param>
278 /// <param name="data"></param> 278 /// <param name="data"></param>
279 public void HandleXfer(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data) 279 public void HandleXfer(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data)
280 { 280 {
281 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); 281 AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
282 282
283 transactions.HandleXfer(xferID, packetID, data); 283 transactions.HandleXfer(xferID, packetID, data);
284 } 284 }
285 } 285 }
286} 286} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs b/OpenSim/Region/Environment/Modules/Agent/TextureDownload/TextureDownloadModule.cs
index bde0dc0..b8899d2 100644
--- a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs
+++ b/OpenSim/Region/Environment/Modules/Agent/TextureDownload/TextureDownloadModule.cs
@@ -1,218 +1,215 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the 12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Threading; 30using System.Threading;
31using libsecondlife; 31using libsecondlife;
32using Nini.Config; 32using Nini.Config;
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Region.Environment.Interfaces; 34using OpenSim.Region.Environment.Interfaces;
35using OpenSim.Region.Environment.Scenes; 35using OpenSim.Region.Environment.Scenes;
36 36
37namespace OpenSim.Region.Environment.Modules 37namespace OpenSim.Region.Environment.Modules.Agent.TextureDownload
38{ 38{
39 //this is a first attempt, to start breaking the mess thats called the assetcache up. 39 public class TextureDownloadModule : IRegionModule
40 // basically this should be the texture sending (to clients) code moved out of assetcache 40 {
41 //and some small clean up 41 //private static readonly log4net.ILog m_log
42 public class TextureDownloadModule : IRegionModule 42 // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
43 { 43
44 //private static readonly log4net.ILog m_log 44 private Scene m_scene;
45 // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 45 private List<Scene> m_scenes = new List<Scene>();
46 46
47 private Scene m_scene; 47 /// <summary>
48 private List<Scene> m_scenes = new List<Scene>(); 48 /// There is one queue for all textures waiting to be sent, regardless of the requesting user.
49 49 /// </summary>
50 /// <summary> 50 private readonly BlockingQueue<ITextureSender> m_queueSenders
51 /// There is one queue for all textures waiting to be sent, regardless of the requesting user. 51 = new BlockingQueue<ITextureSender>();
52 /// </summary> 52
53 private readonly BlockingQueue<ITextureSender> m_queueSenders 53 /// <summary>
54 = new BlockingQueue<ITextureSender>(); 54 /// Each user has their own texture download service.
55 55 /// </summary>
56 /// <summary> 56 private readonly Dictionary<LLUUID, UserTextureDownloadService> m_userTextureServices =
57 /// Each user has their own texture download service. 57 new Dictionary<LLUUID, UserTextureDownloadService>();
58 /// </summary> 58
59 private readonly Dictionary<LLUUID, UserTextureDownloadService> m_userTextureServices = 59 private Thread m_thread;
60 new Dictionary<LLUUID, UserTextureDownloadService>(); 60
61 61 public TextureDownloadModule()
62 private Thread m_thread; 62 {
63 63 }
64 public TextureDownloadModule() 64
65 { 65 public void Initialise(Scene scene, IConfigSource config)
66 } 66 {
67 67 if (m_scene == null)
68 public void Initialise(Scene scene, IConfigSource config) 68 {
69 { 69 //Console.WriteLine("Creating Texture download module");
70 if (m_scene == null) 70 m_thread = new Thread(new ThreadStart(ProcessTextureSenders));
71 { 71 m_thread.Name = "ProcessTextureSenderThread";
72 //Console.WriteLine("Creating Texture download module"); 72 m_thread.IsBackground = true;
73 m_thread = new Thread(new ThreadStart(ProcessTextureSenders)); 73 m_thread.Start();
74 m_thread.Name = "ProcessTextureSenderThread"; 74 ThreadTracker.Add(m_thread);
75 m_thread.IsBackground = true; 75 }
76 m_thread.Start(); 76
77 ThreadTracker.Add(m_thread); 77 if (!m_scenes.Contains(scene))
78 } 78 {
79 79 m_scenes.Add(scene);
80 if (!m_scenes.Contains(scene)) 80 m_scene = scene;
81 { 81 m_scene.EventManager.OnNewClient += NewClient;
82 m_scenes.Add(scene); 82 m_scene.EventManager.OnRemovePresence += EventManager_OnRemovePresence;
83 m_scene = scene; 83 }
84 m_scene.EventManager.OnNewClient += NewClient; 84 }
85 m_scene.EventManager.OnRemovePresence += EventManager_OnRemovePresence; 85
86 } 86 /// <summary>
87 } 87 /// Cleanup the texture service related objects for the removed presence.
88 88 /// </summary>
89 /// <summary> 89 /// <param name="agentId"> </param>
90 /// Cleanup the texture service related objects for the removed presence. 90 private void EventManager_OnRemovePresence(LLUUID agentId)
91 /// </summary> 91 {
92 /// <param name="agentId"> </param> 92 UserTextureDownloadService textureService;
93 private void EventManager_OnRemovePresence(LLUUID agentId) 93
94 { 94 lock (m_userTextureServices)
95 UserTextureDownloadService textureService; 95 {
96 96 if (m_userTextureServices.TryGetValue(agentId, out textureService))
97 lock (m_userTextureServices) 97 {
98 { 98 textureService.Close();
99 if (m_userTextureServices.TryGetValue(agentId, out textureService)) 99
100 { 100 m_userTextureServices.Remove(agentId);
101 textureService.Close(); 101 }
102 102 }
103 m_userTextureServices.Remove(agentId); 103 }
104 } 104
105 } 105 public void PostInitialise()
106 } 106 {
107 107 }
108 public void PostInitialise() 108
109 { 109 public void Close()
110 } 110 {
111 111 }
112 public void Close() 112
113 { 113 public string Name
114 } 114 {
115 115 get { return "TextureDownloadModule"; }
116 public string Name 116 }
117 { 117
118 get { return "TextureDownloadModule"; } 118 public bool IsSharedModule
119 } 119 {
120 120 get { return false; }
121 public bool IsSharedModule 121 }
122 { 122
123 get { return false; } 123 public void NewClient(IClientAPI client)
124 } 124 {
125 125 client.OnRequestTexture += TextureRequest;
126 public void NewClient(IClientAPI client) 126 }
127 { 127
128 client.OnRequestTexture += TextureRequest; 128 /// <summary>
129 } 129 /// Does this user have a registered texture download service?
130 130 /// </summary>
131 /// <summary> 131 /// <param name="userID"></param>
132 /// Does this user have a registered texture download service? 132 /// <param name="textureService"></param>
133 /// </summary> 133 /// <returns>Always returns true, since a service is created if one does not already exist</returns>
134 /// <param name="userID"></param> 134 private bool TryGetUserTextureService(
135 /// <param name="textureService"></param> 135 IClientAPI client, out UserTextureDownloadService textureService)
136 /// <returns>Always returns true, since a service is created if one does not already exist</returns> 136 {
137 private bool TryGetUserTextureService( 137 lock (m_userTextureServices)
138 IClientAPI client, out UserTextureDownloadService textureService) 138 {
139 { 139 if (m_userTextureServices.TryGetValue(client.AgentId, out textureService))
140 lock (m_userTextureServices) 140 {
141 { 141 return true;
142 if (m_userTextureServices.TryGetValue(client.AgentId, out textureService)) 142 }
143 { 143
144 return true; 144 textureService = new UserTextureDownloadService(client, m_scene, m_queueSenders);
145 } 145 m_userTextureServices.Add(client.AgentId, textureService);
146 146
147 textureService = new UserTextureDownloadService(client, m_scene, m_queueSenders); 147 return true;
148 m_userTextureServices.Add(client.AgentId, textureService); 148 }
149 149 }
150 return true; 150
151 } 151 /// <summary>
152 } 152 /// Start the process of requesting a given texture.
153 153 /// </summary>
154 /// <summary> 154 /// <param name="sender"> </param>
155 /// Start the process of requesting a given texture. 155 /// <param name="e"></param>
156 /// </summary> 156 public void TextureRequest(Object sender, TextureRequestArgs e)
157 /// <param name="sender"> </param> 157 {
158 /// <param name="e"></param> 158 IClientAPI client = (IClientAPI) sender;
159 public void TextureRequest(Object sender, TextureRequestArgs e) 159 UserTextureDownloadService textureService;
160 { 160
161 IClientAPI client = (IClientAPI) sender; 161 if (TryGetUserTextureService(client, out textureService))
162 UserTextureDownloadService textureService; 162 {
163 163 textureService.HandleTextureRequest(e);
164 if (TryGetUserTextureService(client, out textureService)) 164 }
165 { 165 }
166 textureService.HandleTextureRequest(e); 166
167 } 167 /// <summary>
168 } 168 /// Entry point for the thread dedicated to processing the texture queue.
169 169 /// </summary>
170 /// <summary> 170 public void ProcessTextureSenders()
171 /// Entry point for the thread dedicated to processing the texture queue. 171 {
172 /// </summary> 172 ITextureSender sender = null;
173 public void ProcessTextureSenders() 173
174 { 174 while (true)
175 ITextureSender sender = null; 175 {
176 176 sender = m_queueSenders.Dequeue();
177 while (true) 177
178 { 178 if (sender.Cancel)
179 sender = m_queueSenders.Dequeue(); 179 {
180 180 TextureSent(sender);
181 if (sender.Cancel) 181
182 { 182 sender.Cancel = false;
183 TextureSent(sender); 183 }
184 184 else
185 sender.Cancel = false; 185 {
186 } 186 bool finished = sender.SendTexturePacket();
187 else 187 if (finished)
188 { 188 {
189 bool finished = sender.SendTexturePacket(); 189 TextureSent(sender);
190 if (finished) 190 }
191 { 191 else
192 TextureSent(sender); 192 {
193 } 193 m_queueSenders.Enqueue(sender);
194 else 194 }
195 { 195 }
196 m_queueSenders.Enqueue(sender); 196
197 } 197 // Make sure that any sender we currently have can get garbage collected
198 } 198 sender = null;
199 199
200 // Make sure that any sender we currently have can get garbage collected 200 //m_log.InfoFormat("[TEXTURE DOWNLOAD] Texture sender queue size: {0}", m_queueSenders.Count());
201 sender = null; 201 }
202 202 }
203 //m_log.InfoFormat("[TEXTURE DOWNLOAD] Texture sender queue size: {0}", m_queueSenders.Count()); 203
204 } 204 /// <summary>
205 } 205 /// Called when the texture has finished sending.
206 206 /// </summary>
207 /// <summary> 207 /// <param name="sender"></param>
208 /// Called when the texture has finished sending. 208 private void TextureSent(ITextureSender sender)
209 /// </summary> 209 {
210 /// <param name="sender"></param> 210 sender.Sending = false;
211 private void TextureSent(ITextureSender sender) 211 //m_log.DebugFormat("[TEXTURE DOWNLOAD]: Removing download stat for {0}", sender.assetID);
212 { 212 m_scene.AddPendingDownloads(-1);
213 sender.Sending = false; 213 }
214 //m_log.DebugFormat("[TEXTURE DOWNLOAD]: Removing download stat for {0}", sender.assetID); 214 }
215 m_scene.AddPendingDownloads(-1); 215} \ No newline at end of file
216 }
217 }
218}
diff --git a/OpenSim/Region/Environment/Modules/TextureNotFoundSender.cs b/OpenSim/Region/Environment/Modules/Agent/TextureDownload/TextureNotFoundSender.cs
index 7b835a1..6f11f73 100644
--- a/OpenSim/Region/Environment/Modules/TextureNotFoundSender.cs
+++ b/OpenSim/Region/Environment/Modules/Agent/TextureDownload/TextureNotFoundSender.cs
@@ -1,93 +1,93 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the 12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using libsecondlife; 28using libsecondlife;
29using libsecondlife.Packets; 29using libsecondlife.Packets;
30using OpenSim.Framework; 30using OpenSim.Framework;
31using OpenSim.Region.Environment.Interfaces; 31using OpenSim.Region.Environment.Interfaces;
32 32
33namespace OpenSim.Region.Environment.Modules 33namespace OpenSim.Region.Environment.Modules.Agent.TextureDownload
34{ 34{
35 /// <summary> 35 /// <summary>
36 /// Sends a 'texture not found' packet back to the client 36 /// Sends a 'texture not found' packet back to the client
37 /// </summary> 37 /// </summary>
38 public class TextureNotFoundSender : ITextureSender 38 public class TextureNotFoundSender : ITextureSender
39 { 39 {
40 //private static readonly log4net.ILog m_log 40 //private static readonly log4net.ILog m_log
41 // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 41 // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
42 42
43 private LLUUID m_textureId; 43 private LLUUID m_textureId;
44 private IClientAPI m_client; 44 private IClientAPI m_client;
45 45
46 // See ITextureSender 46 // See ITextureSender
47 public bool Sending 47 public bool Sending
48 { 48 {
49 get { return false; } 49 get { return false; }
50 set { m_sending = value; } 50 set { m_sending = value; }
51 } 51 }
52 52
53 private bool m_sending = false; 53 private bool m_sending = false;
54 54
55 // See ITextureSender 55 // See ITextureSender
56 public bool Cancel 56 public bool Cancel
57 { 57 {
58 get { return false; } 58 get { return false; }
59 set { m_cancel = value; } 59 set { m_cancel = value; }
60 } 60 }
61 61
62 private bool m_cancel = false; 62 private bool m_cancel = false;
63 63
64 public TextureNotFoundSender(IClientAPI client, LLUUID textureID) 64 public TextureNotFoundSender(IClientAPI client, LLUUID textureID)
65 { 65 {
66 m_client = client; 66 m_client = client;
67 m_textureId = textureID; 67 m_textureId = textureID;
68 } 68 }
69 69
70 // See ITextureSender 70 // See ITextureSender
71 public void UpdateRequest(int discardLevel, uint packetNumber) 71 public void UpdateRequest(int discardLevel, uint packetNumber)
72 { 72 {
73 // Not need to implement since priority changes don't affect this operation 73 // Not need to implement since priority changes don't affect this operation
74 } 74 }
75 75
76 // See ITextureSender 76 // See ITextureSender
77 public bool SendTexturePacket() 77 public bool SendTexturePacket()
78 { 78 {
79 //m_log.InfoFormat( 79 //m_log.InfoFormat(
80 // "[TEXTURE NOT FOUND SENDER]: Informing the client that texture {0} cannot be found", 80 // "[TEXTURE NOT FOUND SENDER]: Informing the client that texture {0} cannot be found",
81 // m_textureId); 81 // m_textureId);
82 82
83 ImageNotInDatabasePacket notFound = new ImageNotInDatabasePacket(); 83 ImageNotInDatabasePacket notFound = new ImageNotInDatabasePacket();
84 notFound.ImageID.ID = m_textureId; 84 notFound.ImageID.ID = m_textureId;
85 85
86 // XXX Temporarily disabling as this appears to be causing client crashes on at least 86 // XXX Temporarily disabling as this appears to be causing client crashes on at least
87 // 1.19.0(5) of the Linden Second Life client. 87 // 1.19.0(5) of the Linden Second Life client.
88 // m_client.OutPacket(notFound, ThrottleOutPacketType.Texture); 88 // m_client.OutPacket(notFound, ThrottleOutPacketType.Texture);
89 89
90 return true; 90 return true;
91 } 91 }
92 } 92 }
93} 93} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs b/OpenSim/Region/Environment/Modules/Agent/TextureDownload/UserTextureDownloadService.cs
index e46bf6d..08a22d6 100644
--- a/OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs
+++ b/OpenSim/Region/Environment/Modules/Agent/TextureDownload/UserTextureDownloadService.cs
@@ -1,250 +1,252 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the 12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.Reflection; 29using System.Reflection;
30using libsecondlife; 30using libsecondlife;
31using log4net; 31using log4net;
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Framework.Communications.Limit; 33using OpenSim.Framework.Communications.Limit;
34using OpenSim.Region.Environment.Interfaces; 34using OpenSim.Region.Environment.Interfaces;
35using OpenSim.Region.Environment.Scenes; 35using OpenSim.Region.Environment.Modules.Agent.TextureDownload;
36 36using OpenSim.Region.Environment.Modules.Agent.TextureSender;
37namespace OpenSim.Region.Environment.Modules 37using OpenSim.Region.Environment.Scenes;
38{ 38
39 /// <summary> 39namespace OpenSim.Region.Environment.Modules.Agent.TextureDownload
40 /// This module sets up texture senders in response to client texture requests, and places them on a 40{
41 /// processing queue once those senders have the appropriate data (i.e. a texture retrieved from the 41 /// <summary>
42 /// asset cache). 42 /// This module sets up texture senders in response to client texture requests, and places them on a
43 /// </summary> 43 /// processing queue once those senders have the appropriate data (i.e. a texture retrieved from the
44 public class UserTextureDownloadService 44 /// asset cache).
45 { 45 /// </summary>
46 private static readonly ILog m_log 46 public class UserTextureDownloadService
47 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 {
48 48 private static readonly ILog m_log
49 /// <summary> 49 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 /// We will allow the client to request the same texture n times before dropping further requests 50
51 /// 51 /// <summary>
52 /// This number includes repeated requests for the same texture at different resolutions (which we don't 52 /// We will allow the client to request the same texture n times before dropping further requests
53 /// currently handle properly as far as I know). However, this situation should be handled in a more 53 ///
54 /// sophisticated way. 54 /// This number includes repeated requests for the same texture at different resolutions (which we don't
55 /// </summary> 55 /// currently handle properly as far as I know). However, this situation should be handled in a more
56 private static readonly int MAX_ALLOWED_TEXTURE_REQUESTS = 5; 56 /// sophisticated way.
57 57 /// </summary>
58 /// <summary> 58 private static readonly int MAX_ALLOWED_TEXTURE_REQUESTS = 5;
59 /// We're going to limit requests for the same missing texture. 59
60 /// XXX This is really a temporary solution to deal with the situation where a client continually requests 60 /// <summary>
61 /// the same missing textures 61 /// We're going to limit requests for the same missing texture.
62 /// </summary> 62 /// XXX This is really a temporary solution to deal with the situation where a client continually requests
63 private readonly IRequestLimitStrategy<LLUUID> missingTextureLimitStrategy 63 /// the same missing textures
64 = new RepeatLimitStrategy<LLUUID>(MAX_ALLOWED_TEXTURE_REQUESTS); 64 /// </summary>
65 65 private readonly IRequestLimitStrategy<LLUUID> missingTextureLimitStrategy
66 /// <summary> 66 = new RepeatLimitStrategy<LLUUID>(MAX_ALLOWED_TEXTURE_REQUESTS);
67 /// XXX Also going to limit requests for found textures. 67
68 /// </summary> 68 /// <summary>
69 private readonly IRequestLimitStrategy<LLUUID> foundTextureLimitStrategy 69 /// XXX Also going to limit requests for found textures.
70 = new RepeatLimitStrategy<LLUUID>(MAX_ALLOWED_TEXTURE_REQUESTS); 70 /// </summary>
71 71 private readonly IRequestLimitStrategy<LLUUID> foundTextureLimitStrategy
72 /// <summary> 72 = new RepeatLimitStrategy<LLUUID>(MAX_ALLOWED_TEXTURE_REQUESTS);
73 /// Holds texture senders before they have received the appropriate texture from the asset cache. 73
74 /// </summary> 74 /// <summary>
75 private readonly Dictionary<LLUUID, TextureSender> m_textureSenders = new Dictionary<LLUUID, TextureSender>(); 75 /// Holds texture senders before they have received the appropriate texture from the asset cache.
76 76 /// </summary>
77 /// <summary> 77 private readonly Dictionary<LLUUID, TextureSender.TextureSender> m_textureSenders = new Dictionary<LLUUID, TextureSender.TextureSender>();
78 /// Texture Senders are placed in this queue once they have received their texture from the asset 78
79 /// cache. Another module actually invokes the send. 79 /// <summary>
80 /// </summary> 80 /// Texture Senders are placed in this queue once they have received their texture from the asset
81 private readonly BlockingQueue<ITextureSender> m_sharedSendersQueue; 81 /// cache. Another module actually invokes the send.
82 82 /// </summary>
83 private readonly Scene m_scene; 83 private readonly BlockingQueue<ITextureSender> m_sharedSendersQueue;
84 84
85 private readonly IClientAPI m_client; 85 private readonly Scene m_scene;
86 86
87 public UserTextureDownloadService( 87 private readonly IClientAPI m_client;
88 IClientAPI client, Scene scene, BlockingQueue<ITextureSender> sharedQueue) 88
89 { 89 public UserTextureDownloadService(
90 m_client = client; 90 IClientAPI client, Scene scene, BlockingQueue<ITextureSender> sharedQueue)
91 m_scene = scene; 91 {
92 m_sharedSendersQueue = sharedQueue; 92 m_client = client;
93 } 93 m_scene = scene;
94 94 m_sharedSendersQueue = sharedQueue;
95 /// <summary> 95 }
96 /// Handle a texture request. This involves creating a texture sender and placing it on the 96
97 /// previously passed in shared queue. 97 /// <summary>
98 /// </summary> 98 /// Handle a texture request. This involves creating a texture sender and placing it on the
99 /// <param name="e"></param> 99 /// previously passed in shared queue.
100 public void HandleTextureRequest(TextureRequestArgs e) 100 /// </summary>
101 { 101 /// <param name="e"></param>
102 TextureSender textureSender; 102 public void HandleTextureRequest(TextureRequestArgs e)
103 103 {
104 //TODO: should be working out the data size/ number of packets to be sent for each discard level 104 TextureSender.TextureSender textureSender;
105 if ((e.DiscardLevel >= 0) || (e.Priority != 0)) 105
106 { 106 //TODO: should be working out the data size/ number of packets to be sent for each discard level
107 lock (m_textureSenders) 107 if ((e.DiscardLevel >= 0) || (e.Priority != 0))
108 { 108 {
109 if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender)) 109 lock (m_textureSenders)
110 { 110 {
111 // If we've received new non UUID information for this request and it hasn't dispatched 111 if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender))
112 // yet, then update the request accordingly. 112 {
113 textureSender.UpdateRequest(e.DiscardLevel, e.PacketNumber); 113 // If we've received new non UUID information for this request and it hasn't dispatched
114 } 114 // yet, then update the request accordingly.
115 else 115 textureSender.UpdateRequest(e.DiscardLevel, e.PacketNumber);
116 { 116 }
117 if (!foundTextureLimitStrategy.AllowRequest(e.RequestedAssetID)) 117 else
118 { 118 {
119// m_log.DebugFormat( 119 if (!foundTextureLimitStrategy.AllowRequest(e.RequestedAssetID))
120// "[USER TEXTURE DOWNLOAD SERVICE]: Refusing request for {0} from client {1}", 120 {
121// e.RequestedAssetID, m_client.AgentId); 121// m_log.DebugFormat(
122 122// "[USER TEXTURE DOWNLOAD SERVICE]: Refusing request for {0} from client {1}",
123 return; 123// e.RequestedAssetID, m_client.AgentId);
124 } 124
125 else if (!missingTextureLimitStrategy.AllowRequest(e.RequestedAssetID)) 125 return;
126 { 126 }
127 if (missingTextureLimitStrategy.IsFirstRefusal(e.RequestedAssetID)) 127 else if (!missingTextureLimitStrategy.AllowRequest(e.RequestedAssetID))
128 { 128 {
129 // Commenting out this message for now as it causes too much noise with other 129 if (missingTextureLimitStrategy.IsFirstRefusal(e.RequestedAssetID))
130 // debug messages. 130 {
131 // TODO: possibly record this as a statistic in the future 131 // Commenting out this message for now as it causes too much noise with other
132 // 132 // debug messages.
133// m_log.DebugFormat( 133 // TODO: possibly record this as a statistic in the future
134// "[USER TEXTURE DOWNLOAD SERVICE]: Dropping requests for notified missing texture {0} for client {1} since we have received more than {2} requests", 134 //
135// e.RequestedAssetID, m_client.AgentId, MAX_ALLOWED_TEXTURE_REQUESTS); 135// m_log.DebugFormat(
136 } 136// "[USER TEXTURE DOWNLOAD SERVICE]: Dropping requests for notified missing texture {0} for client {1} since we have received more than {2} requests",
137 137// e.RequestedAssetID, m_client.AgentId, MAX_ALLOWED_TEXTURE_REQUESTS);
138 return; 138 }
139 } 139
140 140 return;
141 m_scene.AddPendingDownloads(1); 141 }
142 142
143 TextureSender requestHandler = new TextureSender(m_client, e.DiscardLevel, e.PacketNumber); 143 m_scene.AddPendingDownloads(1);
144 m_textureSenders.Add(e.RequestedAssetID, requestHandler); 144
145 145 TextureSender.TextureSender requestHandler = new TextureSender.TextureSender(m_client, e.DiscardLevel, e.PacketNumber);
146 m_scene.AssetCache.GetAsset(e.RequestedAssetID, TextureCallback, true); 146 m_textureSenders.Add(e.RequestedAssetID, requestHandler);
147 } 147
148 } 148 m_scene.AssetCache.GetAsset(e.RequestedAssetID, TextureCallback, true);
149 } 149 }
150 else 150 }
151 { 151 }
152 lock (m_textureSenders) 152 else
153 { 153 {
154 if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender)) 154 lock (m_textureSenders)
155 { 155 {
156 textureSender.Cancel = true; 156 if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender))
157 } 157 {
158 } 158 textureSender.Cancel = true;
159 } 159 }
160 } 160 }
161 161 }
162 /// <summary> 162 }
163 /// The callback for the asset cache when a texture has been retrieved. This method queues the 163
164 /// texture sender for processing. 164 /// <summary>
165 /// </summary> 165 /// The callback for the asset cache when a texture has been retrieved. This method queues the
166 /// <param name="textureID"></param> 166 /// texture sender for processing.
167 /// <param name="texture"></param> 167 /// </summary>
168 public void TextureCallback(LLUUID textureID, AssetBase texture) 168 /// <param name="textureID"></param>
169 { 169 /// <param name="texture"></param>
170 //m_log.DebugFormat("[USER TEXTURE DOWNLOAD SERVICE]: Calling TextureCallback with {0}, texture == null is {1}", textureID, (texture == null ? true : false)); 170 public void TextureCallback(LLUUID textureID, AssetBase texture)
171 171 {
172 lock (m_textureSenders) 172 //m_log.DebugFormat("[USER TEXTURE DOWNLOAD SERVICE]: Calling TextureCallback with {0}, texture == null is {1}", textureID, (texture == null ? true : false));
173 { 173
174 TextureSender textureSender; 174 lock (m_textureSenders)
175 175 {
176 if (m_textureSenders.TryGetValue(textureID, out textureSender)) 176 TextureSender.TextureSender textureSender;
177 { 177
178 // XXX It may be perfectly valid for a texture to have no data... but if we pass 178 if (m_textureSenders.TryGetValue(textureID, out textureSender))
179 // this on to the TextureSender it will blow up, so just discard for now. 179 {
180 // Needs investigation. 180 // XXX It may be perfectly valid for a texture to have no data... but if we pass
181 if (texture == null || texture.Data == null) 181 // this on to the TextureSender it will blow up, so just discard for now.
182 { 182 // Needs investigation.
183 if (!missingTextureLimitStrategy.IsMonitoringRequests(textureID)) 183 if (texture == null || texture.Data == null)
184 { 184 {
185 missingTextureLimitStrategy.MonitorRequests(textureID); 185 if (!missingTextureLimitStrategy.IsMonitoringRequests(textureID))
186 186 {
187 m_log.DebugFormat( 187 missingTextureLimitStrategy.MonitorRequests(textureID);
188 "[USER TEXTURE DOWNLOAD SERVICE]: Queueing first TextureNotFoundSender for {0}, client {1}", 188
189 textureID, m_client.AgentId); 189 m_log.DebugFormat(
190 } 190 "[USER TEXTURE DOWNLOAD SERVICE]: Queueing first TextureNotFoundSender for {0}, client {1}",
191 191 textureID, m_client.AgentId);
192 ITextureSender textureNotFoundSender = new TextureNotFoundSender(m_client, textureID); 192 }
193 EnqueueTextureSender(textureNotFoundSender); 193
194 } 194 ITextureSender textureNotFoundSender = new TextureNotFoundSender(m_client, textureID);
195 else 195 EnqueueTextureSender(textureNotFoundSender);
196 { 196 }
197 if (!textureSender.ImageLoaded) 197 else
198 { 198 {
199 textureSender.TextureReceived(texture); 199 if (!textureSender.ImageLoaded)
200 EnqueueTextureSender(textureSender); 200 {
201 201 textureSender.TextureReceived(texture);
202 foundTextureLimitStrategy.MonitorRequests(textureID); 202 EnqueueTextureSender(textureSender);
203 } 203
204 } 204 foundTextureLimitStrategy.MonitorRequests(textureID);
205 205 }
206 //m_log.InfoFormat("[TEXTURE SENDER] Removing texture sender with uuid {0}", textureID); 206 }
207 m_textureSenders.Remove(textureID); 207
208 //m_log.InfoFormat("[TEXTURE SENDER] Current texture senders in dictionary: {0}", m_textureSenders.Count); 208 //m_log.InfoFormat("[TEXTURE SENDER] Removing texture sender with uuid {0}", textureID);
209 } 209 m_textureSenders.Remove(textureID);
210 else 210 //m_log.InfoFormat("[TEXTURE SENDER] Current texture senders in dictionary: {0}", m_textureSenders.Count);
211 { 211 }
212 m_log.WarnFormat( 212 else
213 "Got a texture uuid {0} with no sender object to handle it, this shouldn't happen", 213 {
214 textureID); 214 m_log.WarnFormat(
215 } 215 "Got a texture uuid {0} with no sender object to handle it, this shouldn't happen",
216 } 216 textureID);
217 } 217 }
218 218 }
219 /// <summary> 219 }
220 /// Place a ready texture sender on the processing queue. 220
221 /// </summary> 221 /// <summary>
222 /// <param name="textureSender"></param> 222 /// Place a ready texture sender on the processing queue.
223 private void EnqueueTextureSender(ITextureSender textureSender) 223 /// </summary>
224 { 224 /// <param name="textureSender"></param>
225 textureSender.Cancel = false; 225 private void EnqueueTextureSender(ITextureSender textureSender)
226 textureSender.Sending = true; 226 {
227 227 textureSender.Cancel = false;
228 if (!m_sharedSendersQueue.Contains(textureSender)) 228 textureSender.Sending = true;
229 { 229
230 m_sharedSendersQueue.Enqueue(textureSender); 230 if (!m_sharedSendersQueue.Contains(textureSender))
231 } 231 {
232 } 232 m_sharedSendersQueue.Enqueue(textureSender);
233 233 }
234 /// <summary> 234 }
235 /// Close this module. 235
236 /// </summary> 236 /// <summary>
237 internal void Close() 237 /// Close this module.
238 { 238 /// </summary>
239 lock (m_textureSenders) 239 internal void Close()
240 { 240 {
241 foreach( TextureSender textureSender in m_textureSenders.Values ) 241 lock (m_textureSenders)
242 { 242 {
243 textureSender.Cancel = true; 243 foreach( TextureSender.TextureSender textureSender in m_textureSenders.Values )
244 } 244 {
245 245 textureSender.Cancel = true;
246 m_textureSenders.Clear(); 246 }
247 } 247
248 } 248 m_textureSenders.Clear();
249 } 249 }
250} 250 }
251 }
252} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/TextureSender.cs b/OpenSim/Region/Environment/Modules/Agent/TextureSender/TextureSender.cs
index e54a1a2..37b0652 100644
--- a/OpenSim/Region/Environment/Modules/TextureSender.cs
+++ b/OpenSim/Region/Environment/Modules/Agent/TextureSender/TextureSender.cs
@@ -1,220 +1,220 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the 12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Reflection; 29using System.Reflection;
30using libsecondlife.Packets; 30using libsecondlife.Packets;
31using log4net; 31using log4net;
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Region.Environment.Interfaces; 33using OpenSim.Region.Environment.Interfaces;
34 34
35namespace OpenSim.Region.Environment.Modules 35namespace OpenSim.Region.Environment.Modules.Agent.TextureSender
36{ 36{
37 /// <summary> 37 /// <summary>
38 /// A TextureSender handles the process of receiving a texture requested by the client from the 38 /// A TextureSender handles the process of receiving a texture requested by the client from the
39 /// AssetCache, and then sending that texture back to the client. 39 /// AssetCache, and then sending that texture back to the client.
40 /// </summary> 40 /// </summary>
41 public class TextureSender : ITextureSender 41 public class TextureSender : ITextureSender
42 { 42 {
43 private static readonly ILog m_log 43 private static readonly ILog m_log
44 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 45
46 /// <summary> 46 /// <summary>
47 /// Records the number of times texture send has been called. 47 /// Records the number of times texture send has been called.
48 /// </summary> 48 /// </summary>
49 public int counter = 0; 49 public int counter = 0;
50 50
51 /// <summary> 51 /// <summary>
52 /// Holds the texture asset to send. 52 /// Holds the texture asset to send.
53 /// </summary> 53 /// </summary>
54 private AssetBase m_asset; 54 private AssetBase m_asset;
55 55
56 //public LLUUID assetID { get { return m_asset.FullID; } } 56 //public LLUUID assetID { get { return m_asset.FullID; } }
57 57
58 /// <summary> 58 /// <summary>
59 /// This is actually the number of extra packets required to send the texture data! We always assume 59 /// This is actually the number of extra packets required to send the texture data! We always assume
60 /// at least one is required. 60 /// at least one is required.
61 /// </summary> 61 /// </summary>
62 private int NumPackets = 0; 62 private int NumPackets = 0;
63 63
64 /// <summary> 64 /// <summary>
65 /// Holds the packet number to send next. In this case, each packet is 1000 bytes long and starts 65 /// Holds the packet number to send next. In this case, each packet is 1000 bytes long and starts
66 /// at the 600th byte (0th indexed). 66 /// at the 600th byte (0th indexed).
67 /// </summary> 67 /// </summary>
68 private int PacketCounter = 0; 68 private int PacketCounter = 0;
69 69
70 // See ITextureSender 70 // See ITextureSender
71 public bool Cancel 71 public bool Cancel
72 { 72 {
73 get { return false; } 73 get { return false; }
74 set { m_cancel = value; } 74 set { m_cancel = value; }
75 } 75 }
76 76
77 private bool m_cancel = false; 77 private bool m_cancel = false;
78 78
79 // See ITextureSender 79 // See ITextureSender
80 public bool Sending 80 public bool Sending
81 { 81 {
82 get { return false; } 82 get { return false; }
83 set { m_sending = value; } 83 set { m_sending = value; }
84 } 84 }
85 85
86 private bool m_sending = false; 86 private bool m_sending = false;
87 87
88 public bool ImageLoaded = false; 88 public bool ImageLoaded = false;
89 89
90 private IClientAPI RequestUser; 90 private IClientAPI RequestUser;
91 91
92 private int RequestedDiscardLevel = -1; 92 private int RequestedDiscardLevel = -1;
93 private uint StartPacketNumber = 0; 93 private uint StartPacketNumber = 0;
94 94
95 public TextureSender(IClientAPI client, int discardLevel, uint packetNumber) 95 public TextureSender(IClientAPI client, int discardLevel, uint packetNumber)
96 { 96 {
97 RequestUser = client; 97 RequestUser = client;
98 RequestedDiscardLevel = discardLevel; 98 RequestedDiscardLevel = discardLevel;
99 StartPacketNumber = packetNumber; 99 StartPacketNumber = packetNumber;
100 } 100 }
101 101
102 /// <summary> 102 /// <summary>
103 /// Load up the texture data to send. 103 /// Load up the texture data to send.
104 /// </summary> 104 /// </summary>
105 /// <param name="asset"> 105 /// <param name="asset">
106 /// A <see cref="AssetBase"/> 106 /// A <see cref="AssetBase"/>
107 /// </param> 107 /// </param>
108 public void TextureReceived(AssetBase asset) 108 public void TextureReceived(AssetBase asset)
109 { 109 {
110 m_asset = asset; 110 m_asset = asset;
111 NumPackets = CalculateNumPackets(asset.Data.Length); 111 NumPackets = CalculateNumPackets(asset.Data.Length);
112 PacketCounter = (int) StartPacketNumber; 112 PacketCounter = (int) StartPacketNumber;
113 ImageLoaded = true; 113 ImageLoaded = true;
114 } 114 }
115 115
116 // See ITextureSender 116 // See ITextureSender
117 public void UpdateRequest(int discardLevel, uint packetNumber) 117 public void UpdateRequest(int discardLevel, uint packetNumber)
118 { 118 {
119 RequestedDiscardLevel = discardLevel; 119 RequestedDiscardLevel = discardLevel;
120 StartPacketNumber = packetNumber; 120 StartPacketNumber = packetNumber;
121 PacketCounter = (int) StartPacketNumber; 121 PacketCounter = (int) StartPacketNumber;
122 } 122 }
123 123
124 // See ITextureSender 124 // See ITextureSender
125 public bool SendTexturePacket() 125 public bool SendTexturePacket()
126 { 126 {
127 //m_log.DebugFormat("[TEXTURE SENDER]: Sending packet for {0}", m_asset.FullID); 127 //m_log.DebugFormat("[TEXTURE SENDER]: Sending packet for {0}", m_asset.FullID);
128 128
129 SendPacket(); 129 SendPacket();
130 counter++; 130 counter++;
131 if ((NumPackets == 0) || (RequestedDiscardLevel == -1) || (PacketCounter > NumPackets) || 131 if ((NumPackets == 0) || (RequestedDiscardLevel == -1) || (PacketCounter > NumPackets) ||
132 ((RequestedDiscardLevel > 0) && (counter > 50 + (NumPackets/(RequestedDiscardLevel + 1))))) 132 ((RequestedDiscardLevel > 0) && (counter > 50 + (NumPackets/(RequestedDiscardLevel + 1)))))
133 { 133 {
134 return true; 134 return true;
135 } 135 }
136 return false; 136 return false;
137 } 137 }
138 138
139 /// <summary> 139 /// <summary>
140 /// Sends a texture packet to the client. 140 /// Sends a texture packet to the client.
141 /// </summary> 141 /// </summary>
142 private void SendPacket() 142 private void SendPacket()
143 { 143 {
144 if (PacketCounter <= NumPackets) 144 if (PacketCounter <= NumPackets)
145 { 145 {
146 if (PacketCounter == 0) 146 if (PacketCounter == 0)
147 { 147 {
148 if (NumPackets == 0) 148 if (NumPackets == 0)
149 { 149 {
150 ImageDataPacket im = new ImageDataPacket(); 150 ImageDataPacket im = new ImageDataPacket();
151 im.Header.Reliable = false; 151 im.Header.Reliable = false;
152 im.ImageID.Packets = 1; 152 im.ImageID.Packets = 1;
153 im.ImageID.ID = m_asset.FullID; 153 im.ImageID.ID = m_asset.FullID;
154 im.ImageID.Size = (uint) m_asset.Data.Length; 154 im.ImageID.Size = (uint) m_asset.Data.Length;
155 im.ImageData.Data = m_asset.Data; 155 im.ImageData.Data = m_asset.Data;
156 im.ImageID.Codec = 2; 156 im.ImageID.Codec = 2;
157 RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); 157 RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
158 PacketCounter++; 158 PacketCounter++;
159 } 159 }
160 else 160 else
161 { 161 {
162 ImageDataPacket im = new ImageDataPacket(); 162 ImageDataPacket im = new ImageDataPacket();
163 im.Header.Reliable = false; 163 im.Header.Reliable = false;
164 im.ImageID.Packets = (ushort) (NumPackets); 164 im.ImageID.Packets = (ushort) (NumPackets);
165 im.ImageID.ID = m_asset.FullID; 165 im.ImageID.ID = m_asset.FullID;
166 im.ImageID.Size = (uint) m_asset.Data.Length; 166 im.ImageID.Size = (uint) m_asset.Data.Length;
167 im.ImageData.Data = new byte[600]; 167 im.ImageData.Data = new byte[600];
168 Array.Copy(m_asset.Data, 0, im.ImageData.Data, 0, 600); 168 Array.Copy(m_asset.Data, 0, im.ImageData.Data, 0, 600);
169 im.ImageID.Codec = 2; 169 im.ImageID.Codec = 2;
170 RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); 170 RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
171 PacketCounter++; 171 PacketCounter++;
172 } 172 }
173 } 173 }
174 else 174 else
175 { 175 {
176 ImagePacketPacket im = new ImagePacketPacket(); 176 ImagePacketPacket im = new ImagePacketPacket();
177 im.Header.Reliable = false; 177 im.Header.Reliable = false;
178 im.ImageID.Packet = (ushort) (PacketCounter); 178 im.ImageID.Packet = (ushort) (PacketCounter);
179 im.ImageID.ID = m_asset.FullID; 179 im.ImageID.ID = m_asset.FullID;
180 int size = m_asset.Data.Length - 600 - (1000*(PacketCounter - 1)); 180 int size = m_asset.Data.Length - 600 - (1000*(PacketCounter - 1));
181 if (size > 1000) size = 1000; 181 if (size > 1000) size = 1000;
182 im.ImageData.Data = new byte[size]; 182 im.ImageData.Data = new byte[size];
183 try 183 try
184 { 184 {
185 Array.Copy(m_asset.Data, 600 + (1000*(PacketCounter - 1)), im.ImageData.Data, 0, size); 185 Array.Copy(m_asset.Data, 600 + (1000*(PacketCounter - 1)), im.ImageData.Data, 0, size);
186 } 186 }
187 catch (ArgumentOutOfRangeException) 187 catch (ArgumentOutOfRangeException)
188 { 188 {
189 m_log.Error("[TEXTURE SENDER]: Unable to separate texture into multiple packets: Array bounds failure on asset:" + 189 m_log.Error("[TEXTURE SENDER]: Unable to separate texture into multiple packets: Array bounds failure on asset:" +
190 m_asset.FullID.ToString() ); 190 m_asset.FullID.ToString() );
191 return; 191 return;
192 } 192 }
193 RequestUser.OutPacket(im, ThrottleOutPacketType.Texture); 193 RequestUser.OutPacket(im, ThrottleOutPacketType.Texture);
194 PacketCounter++; 194 PacketCounter++;
195 } 195 }
196 } 196 }
197 } 197 }
198 198
199 /// <summary> 199 /// <summary>
200 /// Calculate the number of packets that will be required to send the texture loaded into this sender 200 /// Calculate the number of packets that will be required to send the texture loaded into this sender
201 /// This is actually the number of 1000 byte packets not including an initial 600 byte packet... 201 /// This is actually the number of 1000 byte packets not including an initial 600 byte packet...
202 /// </summary> 202 /// </summary>
203 /// <param name="length"></param> 203 /// <param name="length"></param>
204 /// <returns></returns> 204 /// <returns></returns>
205 private int CalculateNumPackets(int length) 205 private int CalculateNumPackets(int length)
206 { 206 {
207 int numPackets = 0; 207 int numPackets = 0;
208 208
209 if (length > 600) 209 if (length > 600)
210 { 210 {
211 //over 600 bytes so split up file 211 //over 600 bytes so split up file
212 int restData = (length - 600); 212 int restData = (length - 600);
213 int restPackets = ((restData + 999)/1000); 213 int restPackets = ((restData + 999)/1000);
214 numPackets = restPackets; 214 numPackets = restPackets;
215 } 215 }
216 216
217 return numPackets; 217 return numPackets;
218 } 218 }
219 } 219 }
220} 220} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Modules/XferModule.cs b/OpenSim/Region/Environment/Modules/Agent/Xfer/XferModule.cs
index 87bc1c5..b609f93 100644
--- a/OpenSim/Region/Environment/Modules/XferModule.cs
+++ b/OpenSim/Region/Environment/Modules/Agent/Xfer/XferModule.cs
@@ -1,225 +1,225 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the 12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using libsecondlife; 30using libsecondlife;
31using Nini.Config; 31using Nini.Config;
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Region.Environment.Interfaces; 33using OpenSim.Region.Environment.Interfaces;
34using OpenSim.Region.Environment.Scenes; 34using OpenSim.Region.Environment.Scenes;
35 35
36namespace OpenSim.Region.Environment.Modules 36namespace OpenSim.Region.Environment.Modules.Agent.Xfer
37{ 37{
38 public class XferModule : IRegionModule, IXfer 38 public class XferModule : IRegionModule, IXfer
39 { 39 {
40 public Dictionary<string, byte[]> NewFiles = new Dictionary<string, byte[]>(); 40 public Dictionary<string, byte[]> NewFiles = new Dictionary<string, byte[]>();
41 public Dictionary<ulong, XferDownLoad> Transfers = new Dictionary<ulong, XferDownLoad>(); 41 public Dictionary<ulong, XferDownLoad> Transfers = new Dictionary<ulong, XferDownLoad>();
42 42
43 private Scene m_scene; 43 private Scene m_scene;
44 44
45 public XferModule() 45 public XferModule()
46 { 46 {
47 } 47 }
48 48
49 public void Initialise(Scene scene, IConfigSource config) 49 public void Initialise(Scene scene, IConfigSource config)
50 { 50 {
51 m_scene = scene; 51 m_scene = scene;
52 m_scene.EventManager.OnNewClient += NewClient; 52 m_scene.EventManager.OnNewClient += NewClient;
53 53
54 m_scene.RegisterModuleInterface<IXfer>(this); 54 m_scene.RegisterModuleInterface<IXfer>(this);
55 } 55 }
56 56
57 public void PostInitialise() 57 public void PostInitialise()
58 { 58 {
59 } 59 }
60 60
61 public void Close() 61 public void Close()
62 { 62 {
63 } 63 }
64 64
65 public string Name 65 public string Name
66 { 66 {
67 get { return "XferModule"; } 67 get { return "XferModule"; }
68 } 68 }
69 69
70 public bool IsSharedModule 70 public bool IsSharedModule
71 { 71 {
72 get { return false; } 72 get { return false; }
73 } 73 }
74 74
75 public void NewClient(IClientAPI client) 75 public void NewClient(IClientAPI client)
76 { 76 {
77 client.OnRequestXfer += RequestXfer; 77 client.OnRequestXfer += RequestXfer;
78 client.OnConfirmXfer += AckPacket; 78 client.OnConfirmXfer += AckPacket;
79 } 79 }
80 80
81 /// <summary> 81 /// <summary>
82 /// 82 ///
83 /// </summary> 83 /// </summary>
84 /// <param name="remoteClient"></param> 84 /// <param name="remoteClient"></param>
85 /// <param name="xferID"></param> 85 /// <param name="xferID"></param>
86 /// <param name="fileName"></param> 86 /// <param name="fileName"></param>
87 public void RequestXfer(IClientAPI remoteClient, ulong xferID, string fileName) 87 public void RequestXfer(IClientAPI remoteClient, ulong xferID, string fileName)
88 { 88 {
89 lock (NewFiles) 89 lock (NewFiles)
90 { 90 {
91 if (NewFiles.ContainsKey(fileName)) 91 if (NewFiles.ContainsKey(fileName))
92 { 92 {
93 if (!Transfers.ContainsKey(xferID)) 93 if (!Transfers.ContainsKey(xferID))
94 { 94 {
95 byte[] fileData = NewFiles[fileName]; 95 byte[] fileData = NewFiles[fileName];
96 XferDownLoad transaction = new XferDownLoad(fileName, fileData, xferID, remoteClient); 96 XferDownLoad transaction = new XferDownLoad(fileName, fileData, xferID, remoteClient);
97 Transfers.Add(xferID, transaction); 97 Transfers.Add(xferID, transaction);
98 NewFiles.Remove(fileName); 98 NewFiles.Remove(fileName);
99 99
100 if (transaction.StartSend()) 100 if (transaction.StartSend())
101 { 101 {
102 Transfers.Remove(xferID); 102 Transfers.Remove(xferID);
103 } 103 }
104 } 104 }
105 } 105 }
106 } 106 }
107 } 107 }
108 108
109 public void AckPacket(IClientAPI remoteClient, ulong xferID, uint packet) 109 public void AckPacket(IClientAPI remoteClient, ulong xferID, uint packet)
110 { 110 {
111 if (Transfers.ContainsKey(xferID)) 111 if (Transfers.ContainsKey(xferID))
112 { 112 {
113 if (Transfers[xferID].AckPacket(packet)) 113 if (Transfers[xferID].AckPacket(packet))
114 { 114 {
115 { 115 {
116 Transfers.Remove(xferID); 116 Transfers.Remove(xferID);
117 } 117 }
118 } 118 }
119 } 119 }
120 } 120 }
121 121
122 public bool AddNewFile(string fileName, byte[] data) 122 public bool AddNewFile(string fileName, byte[] data)
123 { 123 {
124 lock (NewFiles) 124 lock (NewFiles)
125 { 125 {
126 if (NewFiles.ContainsKey(fileName)) 126 if (NewFiles.ContainsKey(fileName))
127 { 127 {
128 NewFiles[fileName] = data; 128 NewFiles[fileName] = data;
129 } 129 }
130 else 130 else
131 { 131 {
132 NewFiles.Add(fileName, data); 132 NewFiles.Add(fileName, data);
133 } 133 }
134 } 134 }
135 return true; 135 return true;
136 } 136 }
137 137
138 138
139 public class XferDownLoad 139 public class XferDownLoad
140 { 140 {
141 public byte[] Data = new byte[0]; 141 public byte[] Data = new byte[0];
142 public string FileName = String.Empty; 142 public string FileName = String.Empty;
143 public ulong XferID = 0; 143 public ulong XferID = 0;
144 public int DataPointer = 0; 144 public int DataPointer = 0;
145 public uint Packet = 0; 145 public uint Packet = 0;
146 public IClientAPI Client; 146 public IClientAPI Client;
147 public uint Serial = 1; 147 public uint Serial = 1;
148 private bool complete; 148 private bool complete;
149 149
150 public XferDownLoad(string fileName, byte[] data, ulong xferID, IClientAPI client) 150 public XferDownLoad(string fileName, byte[] data, ulong xferID, IClientAPI client)
151 { 151 {
152 FileName = fileName; 152 FileName = fileName;
153 Data = data; 153 Data = data;
154 XferID = xferID; 154 XferID = xferID;
155 Client = client; 155 Client = client;
156 } 156 }
157 157
158 public XferDownLoad() 158 public XferDownLoad()
159 { 159 {
160 } 160 }
161 161
162 /// <summary> 162 /// <summary>
163 /// Start a transfer 163 /// Start a transfer
164 /// </summary> 164 /// </summary>
165 /// <returns>True if the transfer is complete, false if not</returns> 165 /// <returns>True if the transfer is complete, false if not</returns>
166 public bool StartSend() 166 public bool StartSend()
167 { 167 {
168 if (Data.Length < 1000) 168 if (Data.Length < 1000)
169 { 169 {
170 // for now (testing ) we only support files under 1000 bytes 170 // for now (testing ) we only support files under 1000 bytes
171 byte[] transferData = new byte[Data.Length + 4]; 171 byte[] transferData = new byte[Data.Length + 4];
172 Array.Copy(Helpers.IntToBytes(Data.Length), 0, transferData, 0, 4); 172 Array.Copy(Helpers.IntToBytes(Data.Length), 0, transferData, 0, 4);
173 Array.Copy(Data, 0, transferData, 4, Data.Length); 173 Array.Copy(Data, 0, transferData, 4, Data.Length);
174 Client.SendXferPacket(XferID, 0 + 0x80000000, transferData); 174 Client.SendXferPacket(XferID, 0 + 0x80000000, transferData);
175 175
176 complete = true; 176 complete = true;
177 } 177 }
178 else 178 else
179 { 179 {
180 byte[] transferData = new byte[1000 + 4]; 180 byte[] transferData = new byte[1000 + 4];
181 Array.Copy(Helpers.IntToBytes(Data.Length), 0, transferData, 0, 4); 181 Array.Copy(Helpers.IntToBytes(Data.Length), 0, transferData, 0, 4);
182 Array.Copy(Data, 0, transferData, 4, 1000); 182 Array.Copy(Data, 0, transferData, 4, 1000);
183 Client.SendXferPacket(XferID, 0, transferData); 183 Client.SendXferPacket(XferID, 0, transferData);
184 Packet++; 184 Packet++;
185 DataPointer = 1000; 185 DataPointer = 1000;
186 } 186 }
187 187
188 return complete; 188 return complete;
189 } 189 }
190 190
191 /// <summary> 191 /// <summary>
192 /// Respond to an ack packet from the client 192 /// Respond to an ack packet from the client
193 /// </summary> 193 /// </summary>
194 /// <param name="packet"></param> 194 /// <param name="packet"></param>
195 /// <returns>True if the transfer is complete, false otherwise</returns> 195 /// <returns>True if the transfer is complete, false otherwise</returns>
196 public bool AckPacket(uint packet) 196 public bool AckPacket(uint packet)
197 { 197 {
198 if (!complete) 198 if (!complete)
199 { 199 {
200 if ((Data.Length - DataPointer) > 1000) 200 if ((Data.Length - DataPointer) > 1000)
201 { 201 {
202 byte[] transferData = new byte[1000]; 202 byte[] transferData = new byte[1000];
203 Array.Copy(Data, DataPointer, transferData, 0, 1000); 203 Array.Copy(Data, DataPointer, transferData, 0, 1000);
204 Client.SendXferPacket(XferID, Packet, transferData); 204 Client.SendXferPacket(XferID, Packet, transferData);
205 Packet++; 205 Packet++;
206 DataPointer += 1000; 206 DataPointer += 1000;
207 } 207 }
208 else 208 else
209 { 209 {
210 byte[] transferData = new byte[Data.Length - DataPointer]; 210 byte[] transferData = new byte[Data.Length - DataPointer];
211 Array.Copy(Data, DataPointer, transferData, 0, Data.Length - DataPointer); 211 Array.Copy(Data, DataPointer, transferData, 0, Data.Length - DataPointer);
212 uint endPacket = Packet |= (uint) 0x80000000; 212 uint endPacket = Packet |= (uint) 0x80000000;
213 Client.SendXferPacket(XferID, endPacket, transferData); 213 Client.SendXferPacket(XferID, endPacket, transferData);
214 Packet++; 214 Packet++;
215 DataPointer += (Data.Length - DataPointer); 215 DataPointer += (Data.Length - DataPointer);
216 216
217 complete = true; 217 complete = true;
218 } 218 }
219 } 219 }
220 220
221 return complete; 221 return complete;
222 } 222 }
223 } 223 }
224 } 224 }
225} 225} \ No newline at end of file