aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/Agent/AssetDownload/AssetDownloadModule.cs
diff options
context:
space:
mode:
authorAdam Frisby2008-04-30 21:16:36 +0000
committerAdam Frisby2008-04-30 21:16:36 +0000
commitf5c312bc3c2567449c7268a54a08a54119f58d53 (patch)
tree424668a4bbec6873ebc5b8256f3671db102f5e9c /OpenSim/Region/Environment/Modules/Agent/AssetDownload/AssetDownloadModule.cs
parent* Adds the AuthbuyerID field to sqlite and makes use of it. (diff)
downloadopensim-SC-f5c312bc3c2567449c7268a54a08a54119f58d53.zip
opensim-SC-f5c312bc3c2567449c7268a54a08a54119f58d53.tar.gz
opensim-SC-f5c312bc3c2567449c7268a54a08a54119f58d53.tar.bz2
opensim-SC-f5c312bc3c2567449c7268a54a08a54119f58d53.tar.xz
* Refactored Environment/Modules directory - modules now reside in their own directory with any associated module-specific classes.
* Each module directory is currently inside one of the following category folders: Agent (Anything relating to do with Client<->Server communications.), Avatar (Anything to do with the avatar or presence inworld), Framework (Classes modules can use), Grid (Grid traffic, new OGS2 grid comms), Scripting (Scripting functions, etc), World (The enrivonment/scene, IE Sun/Tree modules.) * This should be moved into a seperate project file.
Diffstat (limited to 'OpenSim/Region/Environment/Modules/Agent/AssetDownload/AssetDownloadModule.cs')
-rw-r--r--OpenSim/Region/Environment/Modules/Agent/AssetDownload/AssetDownloadModule.cs333
1 files changed, 333 insertions, 0 deletions
diff --git a/OpenSim/Region/Environment/Modules/Agent/AssetDownload/AssetDownloadModule.cs b/OpenSim/Region/Environment/Modules/Agent/AssetDownload/AssetDownloadModule.cs
new file mode 100644
index 0000000..47c1479
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/Agent/AssetDownload/AssetDownloadModule.cs
@@ -0,0 +1,333 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections.Generic;
29using libsecondlife;
30using libsecondlife.Packets;
31using Nini.Config;
32using OpenSim.Framework;
33using OpenSim.Region.Environment.Interfaces;
34using OpenSim.Region.Environment.Scenes;
35
36namespace OpenSim.Region.Environment.Modules.Agent.AssetDownload
37{
38 public class AssetDownloadModule : IRegionModule
39 {
40 private Scene m_scene;
41 private Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>();
42 ///
43 /// Assets requests (for each user) which are waiting for asset server data. This includes texture requests
44 /// </summary>
45 private Dictionary<LLUUID, Dictionary<LLUUID,AssetRequest>> RequestedAssets;
46
47 /// <summary>
48 /// Asset requests with data which are ready to be sent back to requesters. This includes textures.
49 /// </summary>
50 private List<AssetRequest> AssetRequests;
51
52 public AssetDownloadModule()
53 {
54 RequestedAssets = new Dictionary<LLUUID, Dictionary<LLUUID, AssetRequest>>();
55 AssetRequests = new List<AssetRequest>();
56 }
57
58 public void Initialise(Scene scene, IConfigSource config)
59 {
60 if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
61 {
62 RegisteredScenes.Add(scene.RegionInfo.RegionID, scene);
63 // scene.EventManager.OnNewClient += NewClient;
64 }
65
66 if (m_scene == null)
67 {
68 m_scene = scene;
69 // m_thread = new Thread(new ThreadStart(RunAssetQueue));
70 // m_thread.Name = "AssetDownloadQueueThread";
71 // m_thread.IsBackground = true;
72 // m_thread.Start();
73 // OpenSim.Framework.ThreadTracker.Add(m_thread);
74 }
75 }
76
77 public void PostInitialise()
78 {
79 }
80
81 public void Close()
82 {
83 }
84
85 public string Name
86 {
87 get { return "AssetDownloadModule"; }
88 }
89
90 public bool IsSharedModule
91 {
92 get { return true; }
93 }
94
95 public void NewClient(IClientAPI client)
96 {
97 // client.OnRequestAsset += AddAssetRequest;
98 }
99
100 /// <summary>
101 /// Make an asset request the result of which will be packeted up and sent directly back to the client.
102 /// </summary>
103 /// <param name="userInfo"></param>
104 /// <param name="transferRequest"></param>
105 public void AddAssetRequest(IClientAPI userInfo, TransferRequestPacket transferRequest)
106 {
107 LLUUID requestID = null;
108 byte source = 2;
109 if (transferRequest.TransferInfo.SourceType == 2)
110 {
111 //direct asset request
112 requestID = new LLUUID(transferRequest.TransferInfo.Params, 0);
113 }
114 else if (transferRequest.TransferInfo.SourceType == 3)
115 {
116 //inventory asset request
117 requestID = new LLUUID(transferRequest.TransferInfo.Params, 80);
118 source = 3;
119 //Console.WriteLine("asset request " + requestID);
120 }
121
122 //not found asset
123 // so request from asset server
124 Dictionary<LLUUID, AssetRequest> userRequests = null;
125 if (RequestedAssets.TryGetValue(userInfo.AgentId, out userRequests))
126 {
127 if (!userRequests.ContainsKey(requestID))
128 {
129 AssetRequest request = new AssetRequest();
130 request.RequestUser = userInfo;
131 request.RequestAssetID = requestID;
132 request.TransferRequestID = transferRequest.TransferInfo.TransferID;
133 request.AssetRequestSource = source;
134 request.Params = transferRequest.TransferInfo.Params;
135 userRequests[requestID] = request;
136 m_scene.AssetCache.GetAsset(requestID, AssetCallback, false);
137 }
138 }
139 else
140 {
141 userRequests = new Dictionary<LLUUID, AssetRequest>();
142 AssetRequest request = new AssetRequest();
143 request.RequestUser = userInfo;
144 request.RequestAssetID = requestID;
145 request.TransferRequestID = transferRequest.TransferInfo.TransferID;
146 request.AssetRequestSource = source;
147 request.Params = transferRequest.TransferInfo.Params;
148 userRequests.Add(requestID, request);
149 RequestedAssets[userInfo.AgentId] = userRequests;
150 m_scene.AssetCache.GetAsset(requestID, AssetCallback, false);
151 }
152 }
153
154 public void AssetCallback(LLUUID assetID, AssetBase asset)
155 {
156 if (asset != null)
157 {
158 foreach (Dictionary<LLUUID, AssetRequest> userRequests in RequestedAssets.Values)
159 {
160 if (userRequests.ContainsKey(assetID))
161 {
162 AssetRequest req = userRequests[assetID];
163 if (req != null)
164 {
165 req.AssetInf = asset;
166 req.NumPackets = CalculateNumPackets(asset.Data);
167
168 userRequests.Remove(assetID);
169 AssetRequests.Add(req);
170 }
171 }
172 }
173 }
174 }
175
176// TODO: unused
177// private void RunAssetQueue()
178// {
179// while (true)
180// {
181// try
182// {
183// ProcessAssetQueue();
184// Thread.Sleep(500);
185// }
186// catch (Exception)
187// {
188// // m_log.Error("[ASSET CACHE]: " + e.ToString());
189// }
190// }
191// }
192
193// TODO: unused
194// /// <summary>
195// /// Process the asset queue which sends packets directly back to the client.
196// /// </summary>
197// private void ProcessAssetQueue()
198// {
199// //should move the asset downloading to a module, like has been done with texture downloading
200// if (AssetRequests.Count == 0)
201// {
202// //no requests waiting
203// return;
204// }
205// // if less than 5, do all of them
206// int num = Math.Min(5, AssetRequests.Count);
207
208// AssetRequest req;
209// for (int i = 0; i < num; i++)
210// {
211// req = (AssetRequest)AssetRequests[i];
212// //Console.WriteLine("sending asset " + req.RequestAssetID);
213// TransferInfoPacket Transfer = new TransferInfoPacket();
214// Transfer.TransferInfo.ChannelType = 2;
215// Transfer.TransferInfo.Status = 0;
216// Transfer.TransferInfo.TargetType = 0;
217// if (req.AssetRequestSource == 2)
218// {
219// Transfer.TransferInfo.Params = new byte[20];
220// Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16);
221// int assType = (int)req.AssetInf.Type;
222// Array.Copy(Helpers.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4);
223// }
224// else if (req.AssetRequestSource == 3)
225// {
226// Transfer.TransferInfo.Params = req.Params;
227// // Transfer.TransferInfo.Params = new byte[100];
228// //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16);
229// //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16);
230// }
231// Transfer.TransferInfo.Size = (int)req.AssetInf.Data.Length;
232// Transfer.TransferInfo.TransferID = req.TransferRequestID;
233// req.RequestUser.OutPacket(Transfer, ThrottleOutPacketType.Asset);
234
235// if (req.NumPackets == 1)
236// {
237// TransferPacketPacket TransferPacket = new TransferPacketPacket();
238// TransferPacket.TransferData.Packet = 0;
239// TransferPacket.TransferData.ChannelType = 2;
240// TransferPacket.TransferData.TransferID = req.TransferRequestID;
241// TransferPacket.TransferData.Data = req.AssetInf.Data;
242// TransferPacket.TransferData.Status = 1;
243// req.RequestUser.OutPacket(TransferPacket, ThrottleOutPacketType.Asset);
244// }
245// else
246// {
247// int processedLength = 0;
248// // libsecondlife hardcodes 1500 as the maximum data chunk size
249// int maxChunkSize = 1250;
250// int packetNumber = 0;
251
252// while (processedLength < req.AssetInf.Data.Length)
253// {
254// TransferPacketPacket TransferPacket = new TransferPacketPacket();
255// TransferPacket.TransferData.Packet = packetNumber;
256// TransferPacket.TransferData.ChannelType = 2;
257// TransferPacket.TransferData.TransferID = req.TransferRequestID;
258
259// int chunkSize = Math.Min(req.AssetInf.Data.Length - processedLength, maxChunkSize);
260// byte[] chunk = new byte[chunkSize];
261// Array.Copy(req.AssetInf.Data, processedLength, chunk, 0, chunk.Length);
262
263// TransferPacket.TransferData.Data = chunk;
264
265// // 0 indicates more packets to come, 1 indicates last packet
266// if (req.AssetInf.Data.Length - processedLength > maxChunkSize)
267// {
268// TransferPacket.TransferData.Status = 0;
269// }
270// else
271// {
272// TransferPacket.TransferData.Status = 1;
273// }
274
275// req.RequestUser.OutPacket(TransferPacket, ThrottleOutPacketType.Asset);
276
277// processedLength += chunkSize;
278// packetNumber++;
279// }
280// }
281// }
282
283// //remove requests that have been completed
284// for (int i = 0; i < num; i++)
285// {
286// AssetRequests.RemoveAt(0);
287// }
288// }
289
290 /// <summary>
291 /// Calculate the number of packets required to send the asset to the client.
292 /// </summary>
293 /// <param name="data"></param>
294 /// <returns></returns>
295 private int CalculateNumPackets(byte[] data)
296 {
297 const uint m_maxPacketSize = 600;
298 int numPackets = 1;
299
300 if (data.LongLength > m_maxPacketSize)
301 {
302 // over max number of bytes so split up file
303 long restData = data.LongLength - m_maxPacketSize;
304 int restPackets = (int)((restData + m_maxPacketSize - 1) / m_maxPacketSize);
305 numPackets += restPackets;
306 }
307
308 return numPackets;
309 }
310
311 public class AssetRequest
312 {
313 public IClientAPI RequestUser;
314 public LLUUID RequestAssetID;
315 public AssetBase AssetInf;
316 public AssetBase ImageInfo;
317 public LLUUID TransferRequestID;
318 public long DataPointer = 0;
319 public int NumPackets = 0;
320 public int PacketCounter = 0;
321 public bool IsTextureRequest;
322 public byte AssetRequestSource = 2;
323 public byte[] Params = null;
324 //public bool AssetInCache;
325 //public int TimeRequested;
326 public int DiscardLevel = -1;
327
328 public AssetRequest()
329 {
330 }
331 }
332 }
333} \ No newline at end of file