aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Environment/Modules/TextureDownloadModule.cs197
1 files changed, 192 insertions, 5 deletions
diff --git a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs b/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs
index d3297c8..56e20d1 100644
--- a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs
+++ b/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs
@@ -25,9 +25,14 @@
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*/
28 28using System;
29using System.Collections.Generic;
30using System.Threading;
29using libsecondlife; 31using libsecondlife;
32using libsecondlife.Packets;
30using OpenSim.Framework.Interfaces; 33using OpenSim.Framework.Interfaces;
34using OpenSim.Framework.Types;
35using OpenSim.Framework.Utilities;
31using OpenSim.Region.Environment.Interfaces; 36using OpenSim.Region.Environment.Interfaces;
32using OpenSim.Region.Environment.Scenes; 37using OpenSim.Region.Environment.Scenes;
33using Nini.Config; 38using Nini.Config;
@@ -37,15 +42,28 @@ namespace OpenSim.Region.Environment.Modules
37 public class TextureDownloadModule : IRegionModule 42 public class TextureDownloadModule : IRegionModule
38 { 43 {
39 private Scene m_scene; 44 private Scene m_scene;
45 private List<Scene> m_scenes = new List<Scene>();
46 private Dictionary<LLUUID, Dictionary<LLUUID, AssetRequest>> ClientRequests = new Dictionary<LLUUID, Dictionary<LLUUID, AssetRequest>>();
47
48 private BlockingQueue<TextureSender> QueueSenders = new BlockingQueue<TextureSender>();
49 private Dictionary<LLUUID, List<LLUUID>> InProcess = new Dictionary<LLUUID, List<LLUUID>>();
50 // private Thread m_thread;
40 51
41 public TextureDownloadModule() 52 public TextureDownloadModule()
42 { 53 {
54 // m_thread = new Thread(new ThreadStart(ProcessTextureSenders));
55 // m_thread.IsBackground = true;
56 // m_thread.Start();
43 } 57 }
44 58
45 public void Initialise(Scene scene, IConfigSource config) 59 public void Initialise(Scene scene, IConfigSource config)
46 { 60 {
47 m_scene = scene; 61 if (!m_scenes.Contains(scene))
48 m_scene.EventManager.OnNewClient += NewClient; 62 {
63 m_scenes.Add(scene);
64 m_scene = scene;
65 m_scene.EventManager.OnNewClient += NewClient;
66 }
49 } 67 }
50 68
51 public void PostInitialise() 69 public void PostInitialise()
@@ -63,15 +81,184 @@ namespace OpenSim.Region.Environment.Modules
63 81
64 public bool IsSharedModule 82 public bool IsSharedModule
65 { 83 {
66 get { return false; } 84 get { return true; }
67 } 85 }
68 86
69 public void NewClient(IClientAPI client) 87 public void NewClient(IClientAPI client)
70 { 88 {
89 /* lock (ClientRequests)
90 {
91 if (!ClientRequests.ContainsKey(client.AgentId))
92 {
93 ClientRequests.Add(client.AgentId, new Dictionary<LLUUID, AssetRequest>());
94 InProcess.Add(client.AgentId, new List<LLUUID>());
95 }
96 }
97 client.OnRequestTexture += TextureRequest;
98 */
99 }
100
101 public void TextureCallback(LLUUID textureID, AssetBase asset)
102 {
103 lock (ClientRequests)
104 {
105 foreach (Dictionary<LLUUID, AssetRequest> reqList in ClientRequests.Values)
106 {
107 if (reqList.ContainsKey(textureID))
108 {
109 //check the texture isn't already in the process of being sent to the client.
110 if (!InProcess[reqList[textureID].RequestUser.AgentId].Contains(textureID))
111 {
112 TextureSender sender = new TextureSender(reqList[textureID], asset);
113 QueueSenders.Enqueue(sender);
114 InProcess[reqList[textureID].RequestUser.AgentId].Add(textureID);
115 reqList.Remove(textureID);
116 }
117 }
118 }
119 }
120 }
121
122 public void TextureRequest(Object sender, TextureRequestArgs e)
123 {
124 IClientAPI client = (IClientAPI)sender;
125 if (!ClientRequests[client.AgentId].ContainsKey(e.RequestedAssetID))
126 {
127 lock (ClientRequests)
128 {
129 AssetRequest request = new AssetRequest(client, e.RequestedAssetID, e.DiscardLevel, e.PacketNumber);
130 ClientRequests[client.AgentId].Add(e.RequestedAssetID, request);
131 }
132 m_scene.commsManager.AssetCache.GetAsset(e.RequestedAssetID, TextureCallback);
133 }
134 }
135
136 public void ProcessTextureSenders()
137 {
138 while (true)
139 {
140 TextureSender sender = this.QueueSenders.Dequeue();
141 bool finished = sender.SendTexture();
142 if (finished)
143 {
144 this.TextureSent(sender);
145 }
146 else
147 {
148 this.QueueSenders.Enqueue(sender);
149 }
150 }
151 }
152
153 private void TextureSent(TextureSender sender)
154 {
155 if (InProcess[sender.request.RequestUser.AgentId].Contains(sender.request.RequestAssetID))
156 {
157 InProcess[sender.request.RequestUser.AgentId].Remove(sender.request.RequestAssetID);
158 }
159 }
160
161 public class TextureSender
162 {
163 public AssetRequest request;
164 private int counter = 0;
165 private AssetBase m_asset;
166 public long DataPointer = 0;
167 public int NumPackets = 0;
168 public int PacketCounter = 0;
169
170 public TextureSender(AssetRequest req, AssetBase asset)
171 {
172 request = req;
173 m_asset = asset;
174
175 if (asset.Data.LongLength > 600)
176 {
177 NumPackets = 2 + (int)(asset.Data.Length - 601) / 1000;
178 }
179 else
180 {
181 NumPackets = 1;
182 }
183
184 PacketCounter = (int) req.PacketNumber;
185 }
186
187 public bool SendTexture()
188 {
189 SendPacket();
190 counter++;
191 if ((PacketCounter >= NumPackets) | counter > 100 | (NumPackets == 1) | (request.DiscardLevel == -1))
192 {
193 return true;
194 }
195 return false;
196 }
197
198 public void SendPacket()
199 {
200 AssetRequest req = request;
201 if (PacketCounter == 0)
202 {
203 if (NumPackets == 1)
204 {
205 ImageDataPacket im = new ImageDataPacket();
206 im.Header.Reliable = false;
207 im.ImageID.Packets = 1;
208 im.ImageID.ID = m_asset.FullID;
209 im.ImageID.Size = (uint)m_asset.Data.Length;
210 im.ImageData.Data = m_asset.Data;
211 im.ImageID.Codec = 2;
212 req.RequestUser.OutPacket(im);
213 PacketCounter++;
214 }
215 else
216 {
217 ImageDataPacket im = new ImageDataPacket();
218 im.Header.Reliable = false;
219 im.ImageID.Packets = (ushort)(NumPackets);
220 im.ImageID.ID = m_asset.FullID;
221 im.ImageID.Size = (uint)m_asset.Data.Length;
222 im.ImageData.Data = new byte[600];
223 Array.Copy(m_asset.Data, 0, im.ImageData.Data, 0, 600);
224 im.ImageID.Codec = 2;
225 req.RequestUser.OutPacket(im);
226 PacketCounter++;
227 }
228 }
229 else
230 {
231 ImagePacketPacket im = new ImagePacketPacket();
232 im.Header.Reliable = false;
233 im.ImageID.Packet = (ushort)(PacketCounter);
234 im.ImageID.ID = m_asset.FullID;
235 int size = m_asset.Data.Length - 600 - (1000 * (PacketCounter - 1));
236 if (size > 1000) size = 1000;
237 im.ImageData.Data = new byte[size];
238 Array.Copy(m_asset.Data, 600 + (1000 * (PacketCounter - 1)), im.ImageData.Data, 0, size);
239 req.RequestUser.OutPacket(im);
240 PacketCounter++;
241 }
242
243 }
244
71 } 245 }
72 246
73 public void TextureAssetCallback(LLUUID texture, byte[] data) 247 public class AssetRequest
74 { 248 {
249 public IClientAPI RequestUser;
250 public LLUUID RequestAssetID;
251 public int DiscardLevel = -1;
252 public uint PacketNumber = 0;
253
254 public AssetRequest(IClientAPI client, LLUUID textureID, int discardLevel, uint packetNumber)
255 {
256 RequestUser = client;
257 RequestAssetID = textureID;
258 DiscardLevel = discardLevel;
259 PacketNumber = packetNumber;
260 }
75 } 261 }
262
76 } 263 }
77} 264}