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