aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/Agent/TextureSender/TextureSender.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Environment/Modules/Agent/TextureSender/TextureSender.cs')
-rw-r--r--OpenSim/Region/Environment/Modules/Agent/TextureSender/TextureSender.cs444
1 files changed, 222 insertions, 222 deletions
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