aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorMelanie2009-10-05 10:17:23 +0100
committerMelanie2009-10-05 10:17:23 +0100
commit0744292b479446eb1ebec828afafacc0189709ca (patch)
tree3c43b5f425aff61d3625b75b7aef35ce5062ae56 /OpenSim/Region
parentMerge branch 'master' into vehicles (diff)
parentMake the asset connector async Get overload return false if the asset (diff)
downloadopensim-SC_OLD-0744292b479446eb1ebec828afafacc0189709ca.zip
opensim-SC_OLD-0744292b479446eb1ebec828afafacc0189709ca.tar.gz
opensim-SC_OLD-0744292b479446eb1ebec828afafacc0189709ca.tar.bz2
opensim-SC_OLD-0744292b479446eb1ebec828afafacc0189709ca.tar.xz
Merge branch 'master' into vehicles
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Application/Application.cs11
-rw-r--r--OpenSim/Region/Application/OpenSimBase.cs6
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs299
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs4
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs242
-rw-r--r--OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs25
-rw-r--r--OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs18
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs10
-rw-r--r--OpenSim/Region/DataSnapshot/DataSnapshotManager.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs7
-rw-r--r--OpenSim/Region/Framework/Scenes/TerrainChannel.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs4
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs4
-rw-r--r--OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs2
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs31
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs2
20 files changed, 323 insertions, 358 deletions
diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs
index 241af53..33b01e5 100644
--- a/OpenSim/Region/Application/Application.cs
+++ b/OpenSim/Region/Application/Application.cs
@@ -205,13 +205,10 @@ namespace OpenSim
205 Directory.CreateDirectory(m_crashDir); 205 Directory.CreateDirectory(m_crashDir);
206 } 206 }
207 string log = Util.GetUniqueFilename(ex.GetType() + ".txt"); 207 string log = Util.GetUniqueFilename(ex.GetType() + ".txt");
208 StreamWriter m_crashLog = 208 using (StreamWriter m_crashLog = new StreamWriter(Path.Combine(m_crashDir, log)))
209 new StreamWriter( 209 {
210 Path.Combine(m_crashDir, log) 210 m_crashLog.WriteLine(msg);
211 ); 211 }
212
213 m_crashLog.WriteLine(msg);
214 m_crashLog.Close();
215 212
216 File.Copy("OpenSim.ini", Path.Combine(m_crashDir, log + "_OpenSim.ini"), true); 213 File.Copy("OpenSim.ini", Path.Combine(m_crashDir, log + "_OpenSim.ini"), true);
217 } 214 }
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs
index 468c5d7..6e7a2a0 100644
--- a/OpenSim/Region/Application/OpenSimBase.cs
+++ b/OpenSim/Region/Application/OpenSimBase.cs
@@ -699,7 +699,7 @@ namespace OpenSim
699 public byte[] Handle(string path, Stream request, 699 public byte[] Handle(string path, Stream request,
700 OSHttpRequest httpRequest, OSHttpResponse httpResponse) 700 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
701 { 701 {
702 return Encoding.UTF8.GetBytes("OK"); 702 return Util.UTF8.GetBytes("OK");
703 } 703 }
704 704
705 public string ContentType 705 public string ContentType
@@ -736,7 +736,7 @@ namespace OpenSim
736 public byte[] Handle(string path, Stream request, 736 public byte[] Handle(string path, Stream request,
737 OSHttpRequest httpRequest, OSHttpResponse httpResponse) 737 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
738 { 738 {
739 return Encoding.UTF8.GetBytes(m_opensim.StatReport(httpRequest)); 739 return Util.UTF8.GetBytes(m_opensim.StatReport(httpRequest));
740 } 740 }
741 741
742 public string ContentType 742 public string ContentType
@@ -777,7 +777,7 @@ namespace OpenSim
777 public byte[] Handle(string path, Stream request, 777 public byte[] Handle(string path, Stream request,
778 OSHttpRequest httpRequest, OSHttpResponse httpResponse) 778 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
779 { 779 {
780 return Encoding.UTF8.GetBytes(m_opensim.StatReport(httpRequest)); 780 return Util.UTF8.GetBytes(m_opensim.StatReport(httpRequest));
781 } 781 }
782 782
783 public string ContentType 783 public string ContentType
diff --git a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
index 5f549b5..19ad0b4 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
@@ -47,69 +47,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
47 47
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 49
50 public uint m_lastSequence; 50 public uint LastSequence;
51 public float m_requestedPriority; 51 public float Priority;
52 public uint m_requestedPacketNumber; 52 public uint StartPacket;
53 public sbyte m_requestedDiscardLevel; 53 public sbyte DiscardLevel;
54 public UUID m_requestedUUID; 54 public UUID TextureID;
55 public IJ2KDecoder m_j2kDecodeModule; 55 public IJ2KDecoder J2KDecoder;
56 public IAssetService m_assetCache; 56 public IAssetService AssetService;
57 public OpenJPEG.J2KLayerInfo[] m_layers; 57 public OpenJPEG.J2KLayerInfo[] Layers;
58 public bool m_decoded; 58 public bool IsDecoded;
59 public bool m_hasasset; 59 public bool HasAsset;
60 public C5.IPriorityQueueHandle<J2KImage> m_priorityQueueHandle; 60 public C5.IPriorityQueueHandle<J2KImage> PriorityQueueHandle;
61 61
62 private uint m_packetNumber; 62 private uint m_currentPacket;
63 private bool m_decoderequested; 63 private bool m_decodeRequested;
64 private bool m_asset_requested; 64 private bool m_assetRequested;
65 private bool m_sentinfo; 65 private bool m_sentInfo;
66 private uint m_stopPacket; 66 private uint m_stopPacket;
67 private AssetBase m_asset; 67 private byte[] m_asset;
68 private int m_assetDataLength;
69 private LLImageManager m_imageManager; 68 private LLImageManager m_imageManager;
70 69
71 #region Properties
72
73 public uint m_pPacketNumber
74 {
75 get { return m_packetNumber; }
76 }
77 public uint m_pStopPacketNumber
78 {
79 get { return m_stopPacket; }
80 }
81
82 public byte[] Data
83 {
84 get
85 {
86 if (m_asset != null)
87 return m_asset.Data;
88 else
89 return null;
90 }
91 }
92
93 public ushort TexturePacketCount()
94 {
95 if (!m_decoded)
96 return 0;
97
98 try
99 {
100 return (ushort)(((m_assetDataLength - FIRST_PACKET_SIZE + IMAGE_PACKET_SIZE - 1) / IMAGE_PACKET_SIZE) + 1);
101 }
102 catch (Exception)
103 {
104 // If the asset is missing/destroyed/truncated, we will land
105 // here
106 //
107 return 0;
108 }
109 }
110
111 #endregion Properties
112
113 public J2KImage(LLImageManager imageManager) 70 public J2KImage(LLImageManager imageManager)
114 { 71 {
115 m_imageManager = imageManager; 72 m_imageManager = imageManager;
@@ -117,33 +74,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
117 74
118 public bool SendPackets(LLClientView client, int maxpack) 75 public bool SendPackets(LLClientView client, int maxpack)
119 { 76 {
120 if (m_packetNumber <= m_stopPacket) 77 if (m_currentPacket <= m_stopPacket)
121 { 78 {
122 bool SendMore = true; 79 bool SendMore = true;
123 if (!m_sentinfo || (m_packetNumber == 0)) 80 if (!m_sentInfo || (m_currentPacket == 0))
124 { 81 {
125 if (SendFirstPacket(client)) 82 if (SendFirstPacket(client))
126 { 83 {
127 SendMore = false; 84 SendMore = false;
128 } 85 }
129 m_sentinfo = true; 86 m_sentInfo = true;
130 m_packetNumber++; 87 m_currentPacket++;
131 } 88 }
132 // bool ignoreStop = false; 89 if (m_currentPacket < 2)
133 if (m_packetNumber < 2)
134 { 90 {
135 m_packetNumber = 2; 91 m_currentPacket = 2;
136 } 92 }
137 93
138 int count = 0; 94 int count = 0;
139 while (SendMore && count < maxpack && m_packetNumber <= m_stopPacket) 95 while (SendMore && count < maxpack && m_currentPacket <= m_stopPacket)
140 { 96 {
141 count++; 97 count++;
142 SendMore = SendPacket(client); 98 SendMore = SendPacket(client);
143 m_packetNumber++; 99 m_currentPacket++;
144 } 100 }
145 101
146 if (m_packetNumber > m_stopPacket) 102 if (m_currentPacket > m_stopPacket)
147 return true; 103 return true;
148 } 104 }
149 105
@@ -156,68 +112,76 @@ namespace OpenSim.Region.ClientStack.LindenUDP
156 //and assign the real discardLevel and packetNumber 112 //and assign the real discardLevel and packetNumber
157 //assuming of course that the connected client might be bonkers 113 //assuming of course that the connected client might be bonkers
158 114
159 if (!m_hasasset) 115 if (!HasAsset)
160 { 116 {
161 if (!m_asset_requested) 117 if (!m_assetRequested)
162 { 118 {
163 m_asset_requested = true; 119 m_assetRequested = true;
164 m_assetCache.Get(m_requestedUUID.ToString(), this, AssetReceived); 120 AssetService.Get(TextureID.ToString(), this, AssetReceived);
165 } 121 }
166 } 122 }
167 else 123 else
168 { 124 {
169 if (!m_decoded) 125 if (!IsDecoded)
170 { 126 {
171 //We need to decode the requested image first 127 //We need to decode the requested image first
172 if (!m_decoderequested) 128 if (!m_decodeRequested)
173 { 129 {
174 //Request decode 130 //Request decode
175 m_decoderequested = true; 131 m_decodeRequested = true;
176 // Do we have a jpeg decoder? 132 // Do we have a jpeg decoder?
177 if (m_j2kDecodeModule != null) 133 if (J2KDecoder != null)
178 { 134 {
179 if (Data == null) 135 if (m_asset == null)
180 { 136 {
181 J2KDecodedCallback(m_requestedUUID, new OpenJPEG.J2KLayerInfo[0]); 137 J2KDecodedCallback(TextureID, new OpenJPEG.J2KLayerInfo[0]);
182 } 138 }
183 else 139 else
184 { 140 {
185 // Send it off to the jpeg decoder 141 // Send it off to the jpeg decoder
186 m_j2kDecodeModule.BeginDecode(m_requestedUUID, Data, J2KDecodedCallback); 142 J2KDecoder.BeginDecode(TextureID, m_asset, J2KDecodedCallback);
187 } 143 }
188 144
189 } 145 }
190 else 146 else
191 { 147 {
192 J2KDecodedCallback(m_requestedUUID, new OpenJPEG.J2KLayerInfo[0]); 148 J2KDecodedCallback(TextureID, new OpenJPEG.J2KLayerInfo[0]);
193 } 149 }
194 } 150 }
195 } 151 }
196 else 152 else
197 { 153 {
198 // Check for missing image asset data 154 // Check for missing image asset data
199 if (m_asset == null || m_asset.Data == null) 155 if (m_asset == null)
200 { 156 {
201 // FIXME: 157 m_log.Warn("[J2KIMAGE]: RunUpdate() called with missing asset data (no missing image texture?). Canceling texture transfer");
202 m_packetNumber = m_stopPacket; 158 m_currentPacket = m_stopPacket;
203 return; 159 return;
204 } 160 }
205 161
206 if (m_requestedDiscardLevel >= 0 || m_stopPacket == 0) 162 if (DiscardLevel >= 0 || m_stopPacket == 0)
207 { 163 {
208 int maxDiscardLevel = Math.Max(0, m_layers.Length - 1); 164 // This shouldn't happen, but if it does, we really can't proceed
165 if (Layers == null)
166 {
167 m_log.Warn("[J2KIMAGE]: RunUpdate() called with missing Layers. Canceling texture transfer");
168 m_currentPacket = m_stopPacket;
169 return;
170 }
171
172 int maxDiscardLevel = Math.Max(0, Layers.Length - 1);
209 173
210 // Treat initial texture downloads with a DiscardLevel of -1 a request for the highest DiscardLevel 174 // Treat initial texture downloads with a DiscardLevel of -1 a request for the highest DiscardLevel
211 if (m_requestedDiscardLevel < 0 && m_stopPacket == 0) 175 if (DiscardLevel < 0 && m_stopPacket == 0)
212 m_requestedDiscardLevel = (sbyte)maxDiscardLevel; 176 DiscardLevel = (sbyte)maxDiscardLevel;
213 177
214 // Clamp at the highest discard level 178 // Clamp at the highest discard level
215 m_requestedDiscardLevel = (sbyte)Math.Min(m_requestedDiscardLevel, maxDiscardLevel); 179 DiscardLevel = (sbyte)Math.Min(DiscardLevel, maxDiscardLevel);
216 180
217 //Calculate the m_stopPacket 181 //Calculate the m_stopPacket
218 if (m_layers.Length > 0) 182 if (Layers.Length > 0)
219 { 183 {
220 m_stopPacket = (uint)GetPacketForBytePosition(m_layers[(m_layers.Length - 1) - m_requestedDiscardLevel].End); 184 m_stopPacket = (uint)GetPacketForBytePosition(Layers[(Layers.Length - 1) - DiscardLevel].End);
221 //I don't know why, but the viewer seems to expect the final packet if the file 185 //I don't know why, but the viewer seems to expect the final packet if the file
222 //is just one packet bigger. 186 //is just one packet bigger.
223 if (TexturePacketCount() == m_stopPacket + 1) 187 if (TexturePacketCount() == m_stopPacket + 1)
@@ -230,32 +194,65 @@ namespace OpenSim.Region.ClientStack.LindenUDP
230 m_stopPacket = TexturePacketCount(); 194 m_stopPacket = TexturePacketCount();
231 } 195 }
232 196
233 m_packetNumber = m_requestedPacketNumber; 197 m_currentPacket = StartPacket;
234 } 198 }
235 199
236 if (m_imageManager.Client.PacketHandler.GetQueueCount(ThrottleOutPacketType.Texture) == 0) 200 if ((m_imageManager != null) && (m_imageManager.Client != null) && (m_imageManager.Client.PacketHandler != null))
237 { 201 if (m_imageManager.Client.PacketHandler.GetQueueCount(ThrottleOutPacketType.Texture) == 0)
238 //m_log.Debug("No textures queued, sending one packet to kickstart it"); 202 {
239 SendPacket(m_imageManager.Client); 203 //m_log.Debug("No textures queued, sending one packet to kickstart it");
240 } 204 SendPacket(m_imageManager.Client);
205 }
241 } 206 }
242 } 207 }
243 } 208 }
244 209
210 private bool SendFirstPacket(LLClientView client)
211 {
212 if (m_asset == null)
213 {
214 m_log.Warn("[J2KIMAGE]: Sending ImageNotInDatabase for texture " + TextureID);
215 client.SendImageNotFound(TextureID);
216 return true;
217 }
218 else if (m_asset.Length <= FIRST_PACKET_SIZE)
219 {
220 // We have less then one packet's worth of data
221 client.SendImageFirstPart(1, TextureID, (uint)m_asset.Length, m_asset, 2);
222 m_stopPacket = 0;
223 return true;
224 }
225 else
226 {
227 // This is going to be a multi-packet texture download
228 byte[] firstImageData = new byte[FIRST_PACKET_SIZE];
229
230 try { Buffer.BlockCopy(m_asset, 0, firstImageData, 0, FIRST_PACKET_SIZE); }
231 catch (Exception)
232 {
233 m_log.ErrorFormat("[J2KIMAGE]: Texture block copy for the first packet failed. textureid={0}, assetlength={1}", TextureID, m_asset.Length);
234 return true;
235 }
236
237 client.SendImageFirstPart(TexturePacketCount(), TextureID, (uint)m_asset.Length, firstImageData, (byte)ImageCodec.J2C);
238 }
239 return false;
240 }
241
245 private bool SendPacket(LLClientView client) 242 private bool SendPacket(LLClientView client)
246 { 243 {
247 bool complete = false; 244 bool complete = false;
248 int imagePacketSize = ((int)m_packetNumber == (TexturePacketCount())) ? LastPacketSize() : IMAGE_PACKET_SIZE; 245 int imagePacketSize = ((int)m_currentPacket == (TexturePacketCount())) ? LastPacketSize() : IMAGE_PACKET_SIZE;
249 246
250 try 247 try
251 { 248 {
252 if ((CurrentBytePosition() + IMAGE_PACKET_SIZE) > m_assetDataLength) 249 if ((CurrentBytePosition() + IMAGE_PACKET_SIZE) > m_asset.Length)
253 { 250 {
254 imagePacketSize = LastPacketSize(); 251 imagePacketSize = LastPacketSize();
255 complete = true; 252 complete = true;
256 if ((CurrentBytePosition() + imagePacketSize) > m_assetDataLength) 253 if ((CurrentBytePosition() + imagePacketSize) > m_asset.Length)
257 { 254 {
258 imagePacketSize = m_assetDataLength - CurrentBytePosition(); 255 imagePacketSize = m_asset.Length - CurrentBytePosition();
259 complete = true; 256 complete = true;
260 } 257 }
261 } 258 }
@@ -266,27 +263,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
266 if (imagePacketSize > 0) 263 if (imagePacketSize > 0)
267 { 264 {
268 byte[] imageData = new byte[imagePacketSize]; 265 byte[] imageData = new byte[imagePacketSize];
269 try 266 int currentPosition = CurrentBytePosition();
270 { 267
271 Buffer.BlockCopy(m_asset.Data, CurrentBytePosition(), imageData, 0, imagePacketSize); 268 try { Buffer.BlockCopy(m_asset, currentPosition, imageData, 0, imagePacketSize); }
272 }
273 catch (Exception e) 269 catch (Exception e)
274 { 270 {
275 m_log.Error("Error copying texture block. Out of memory? imagePacketSize was " + imagePacketSize.ToString() + " on packet " + m_packetNumber.ToString() + " out of " + m_stopPacket.ToString() + ". Exception: " + e.ToString()); 271 m_log.ErrorFormat("[J2KIMAGE]: Texture block copy for the first packet failed. textureid={0}, assetlength={1}, currentposition={2}, imagepacketsize={3}, exception={4}",
272 TextureID, m_asset.Length, currentPosition, imagePacketSize, e.Message);
276 return false; 273 return false;
277 } 274 }
278 275
279 //Send the packet 276 //Send the packet
280 client.SendImageNextPart((ushort)(m_packetNumber - 1), m_requestedUUID, imageData); 277 client.SendImageNextPart((ushort)(m_currentPacket - 1), TextureID, imageData);
281 }
282 if (complete)
283 {
284 return false;
285 }
286 else
287 {
288 return true;
289 } 278 }
279
280 return !complete;
290 } 281 }
291 catch (Exception) 282 catch (Exception)
292 { 283 {
@@ -294,6 +285,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
294 } 285 }
295 } 286 }
296 287
288 private ushort TexturePacketCount()
289 {
290 if (!IsDecoded)
291 return 0;
292
293 if (m_asset == null)
294 return 0;
295
296 if (m_asset.Length <= FIRST_PACKET_SIZE)
297 return 1;
298
299 return (ushort)(((m_asset.Length - FIRST_PACKET_SIZE + IMAGE_PACKET_SIZE - 1) / IMAGE_PACKET_SIZE) + 1);
300 }
301
297 private int GetPacketForBytePosition(int bytePosition) 302 private int GetPacketForBytePosition(int bytePosition)
298 { 303 {
299 return ((bytePosition - FIRST_PACKET_SIZE + IMAGE_PACKET_SIZE - 1) / IMAGE_PACKET_SIZE) + 1; 304 return ((bytePosition - FIRST_PACKET_SIZE + IMAGE_PACKET_SIZE - 1) / IMAGE_PACKET_SIZE) + 1;
@@ -301,9 +306,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
301 306
302 private int LastPacketSize() 307 private int LastPacketSize()
303 { 308 {
304 if (m_packetNumber == 1) 309 if (m_currentPacket == 1)
305 return m_assetDataLength; 310 return m_asset.Length;
306 int lastsize = (m_assetDataLength - FIRST_PACKET_SIZE) % IMAGE_PACKET_SIZE; 311 int lastsize = (m_asset.Length - FIRST_PACKET_SIZE) % IMAGE_PACKET_SIZE;
307 //If the last packet size is zero, it's really cImagePacketSize, it sits on the boundary 312 //If the last packet size is zero, it's really cImagePacketSize, it sits on the boundary
308 if (lastsize == 0) 313 if (lastsize == 0)
309 { 314 {
@@ -314,12 +319,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
314 319
315 private int CurrentBytePosition() 320 private int CurrentBytePosition()
316 { 321 {
317 if (m_packetNumber == 0) 322 if (m_currentPacket == 0)
318 return 0; 323 return 0;
319 if (m_packetNumber == 1) 324 if (m_currentPacket == 1)
320 return FIRST_PACKET_SIZE; 325 return FIRST_PACKET_SIZE;
321 326
322 int result = FIRST_PACKET_SIZE + ((int)m_packetNumber - 2) * IMAGE_PACKET_SIZE; 327 int result = FIRST_PACKET_SIZE + ((int)m_currentPacket - 2) * IMAGE_PACKET_SIZE;
323 if (result < 0) 328 if (result < 0)
324 { 329 {
325 result = FIRST_PACKET_SIZE; 330 result = FIRST_PACKET_SIZE;
@@ -327,68 +332,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
327 return result; 332 return result;
328 } 333 }
329 334
330 private bool SendFirstPacket(LLClientView client)
331 {
332 // this means we don't have
333 if (Data == null)
334 {
335 client.SendImageNotFound(m_requestedUUID);
336 m_log.WarnFormat("[TEXTURE]: Got null Data element on a asset {0}.. and the missing image Data property is also null", m_requestedUUID);
337 return true;
338 }
339 // Do we have less then 1 packet's worth of data?
340 else if (m_assetDataLength <= FIRST_PACKET_SIZE)
341 {
342 // Send only 1 packet
343 client.SendImageFirstPart(1, m_requestedUUID, (uint)m_assetDataLength, m_asset.Data, 2);
344 m_stopPacket = 0;
345 return true;
346 }
347 else
348 {
349 byte[] firstImageData = new byte[FIRST_PACKET_SIZE];
350 try
351 {
352 Buffer.BlockCopy(m_asset.Data, 0, firstImageData, 0, (int)FIRST_PACKET_SIZE);
353 client.SendImageFirstPart(TexturePacketCount(), m_requestedUUID, (uint)m_assetDataLength, firstImageData, 2);
354 }
355 catch (Exception)
356 {
357 m_log.Error("Texture block copy failed. Possibly out of memory?");
358 return true;
359 }
360 }
361 return false;
362 }
363
364 private void J2KDecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers) 335 private void J2KDecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers)
365 { 336 {
366 m_layers = layers; 337 Layers = layers;
367 m_decoded = true; 338 IsDecoded = true;
368 RunUpdate(); 339 RunUpdate();
369 } 340 }
370 341
371 private void AssetDataCallback(UUID AssetID, AssetBase asset) 342 private void AssetDataCallback(UUID AssetID, AssetBase asset)
372 { 343 {
373 m_hasasset = true; 344 HasAsset = true;
374 345
375 if (asset == null || asset.Data == null) 346 if (asset == null || asset.Data == null)
376 { 347 {
377 if (m_imageManager.MissingImage != null) 348 if (m_imageManager.MissingImage != null)
378 { 349 {
379 m_asset = m_imageManager.MissingImage; 350 m_asset = m_imageManager.MissingImage.Data;
380 m_assetDataLength = m_asset.Data.Length;
381 } 351 }
382 else 352 else
383 { 353 {
384 m_asset = null; 354 m_asset = null;
385 m_decoded = true; 355 IsDecoded = true;
386 } 356 }
387 } 357 }
388 else 358 else
389 { 359 {
390 m_asset = asset; 360 m_asset = asset.Data;
391 m_assetDataLength = m_asset.Data.Length;
392 } 361 }
393 362
394 RunUpdate(); 363 RunUpdate();
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 3b43771..0052729 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -4751,7 +4751,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4751 { 4751 {
4752 Hashtable mp = (Hashtable)simMapProfiles[iii]; 4752 Hashtable mp = (Hashtable)simMapProfiles[iii];
4753 mbReply.Data[iii] = new MapBlockReplyPacket.DataBlock(); 4753 mbReply.Data[iii] = new MapBlockReplyPacket.DataBlock();
4754 mbReply.Data[iii].Name = System.Text.Encoding.UTF8.GetBytes((string)mp["name"]); 4754 mbReply.Data[iii].Name = Util.UTF8.GetBytes((string)mp["name"]);
4755 mbReply.Data[iii].Access = System.Convert.ToByte(mp["access"]); 4755 mbReply.Data[iii].Access = System.Convert.ToByte(mp["access"]);
4756 mbReply.Data[iii].Agents = System.Convert.ToByte(mp["agents"]); 4756 mbReply.Data[iii].Agents = System.Convert.ToByte(mp["agents"]);
4757 mbReply.Data[iii].MapImageID = new UUID((string)mp["map-image-id"]); 4757 mbReply.Data[iii].MapImageID = new UUID((string)mp["map-image-id"]);
@@ -7341,7 +7341,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7341 } 7341 }
7342 #endregion 7342 #endregion
7343 7343
7344 string mapName = Encoding.UTF8.GetString(map.NameData.Name, 0, 7344 string mapName = Util.UTF8.GetString(map.NameData.Name, 0,
7345 map.NameData.Name.Length - 1); 7345 map.NameData.Name.Length - 1);
7346 handlerMapNameRequest = OnMapNameRequest; 7346 handlerMapNameRequest = OnMapNameRequest;
7347 if (handlerMapNameRequest != null) 7347 if (handlerMapNameRequest != null)
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
index a484fdf..2120d33 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
@@ -45,48 +45,43 @@ namespace OpenSim.Region.ClientStack.LindenUDP
45 { 45 {
46 public int Compare(J2KImage x, J2KImage y) 46 public int Compare(J2KImage x, J2KImage y)
47 { 47 {
48 return x.m_requestedPriority.CompareTo(y.m_requestedPriority); 48 return x.Priority.CompareTo(y.Priority);
49 } 49 }
50 } 50 }
51 51
52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53 private bool m_shuttingdown = false; 53 private bool m_shuttingdown;
54 private long m_lastloopprocessed = 0; 54 private long m_lastloopprocessed;
55 private AssetBase m_missingImage = null; 55 private AssetBase m_missingImage;
56
57 private LLClientView m_client; //Client we're assigned to 56 private LLClientView m_client; //Client we're assigned to
58 private IAssetService m_assetCache; //Asset Cache 57 private IAssetService m_assetCache; //Asset Cache
59 private IJ2KDecoder m_j2kDecodeModule; //Our J2K module 58 private IJ2KDecoder m_j2kDecodeModule; //Our J2K module
60 private C5.IntervalHeap<J2KImage> m_priorityQueue = new C5.IntervalHeap<J2KImage>(10, new J2KImageComparer()); 59 private C5.IntervalHeap<J2KImage> m_priorityQueue = new C5.IntervalHeap<J2KImage>(10, new J2KImageComparer());
60 private object m_syncRoot = new object();
61
62 public LLClientView Client { get { return m_client; } }
63 public AssetBase MissingImage { get { return m_missingImage; } }
61 64
62 public LLImageManager(LLClientView client, IAssetService pAssetCache, IJ2KDecoder pJ2kDecodeModule) 65 public LLImageManager(LLClientView client, IAssetService pAssetCache, IJ2KDecoder pJ2kDecodeModule)
63 { 66 {
64 m_client = client; 67 m_client = client;
65 m_assetCache = pAssetCache; 68 m_assetCache = pAssetCache;
69
66 if (pAssetCache != null) 70 if (pAssetCache != null)
67 m_missingImage = pAssetCache.Get("5748decc-f629-461c-9a36-a35a221fe21f"); 71 m_missingImage = pAssetCache.Get("5748decc-f629-461c-9a36-a35a221fe21f");
68 else 72
69 m_log.Error("[ClientView] - couldn't set missing image asset, falling back to missing image packet. This is known to crash the client"); 73 if (m_missingImage == null)
74 m_log.Error("[ClientView] - Couldn't set missing image asset, falling back to missing image packet. This is known to crash the client");
70 75
71 m_j2kDecodeModule = pJ2kDecodeModule; 76 m_j2kDecodeModule = pJ2kDecodeModule;
72 } 77 }
73 78
74 public LLClientView Client 79 /// <summary>
75 { 80 /// Handles an incoming texture request or update to an existing texture request
76 get { return m_client; } 81 /// </summary>
77 } 82 /// <param name="newRequest"></param>
78
79 public AssetBase MissingImage
80 {
81 get { return m_missingImage; }
82 }
83
84 public void EnqueueReq(TextureRequestArgs newRequest) 83 public void EnqueueReq(TextureRequestArgs newRequest)
85 { 84 {
86 //newRequest is the properties of our new texture fetch request.
87 //Basically, here is where we queue up "new" requests..
88 // .. or modify existing requests to suit.
89
90 //Make sure we're not shutting down.. 85 //Make sure we're not shutting down..
91 if (!m_shuttingdown) 86 if (!m_shuttingdown)
92 { 87 {
@@ -94,7 +89,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
94 89
95 // Do a linear search for this texture download 90 // Do a linear search for this texture download
96 lock (m_priorityQueue) 91 lock (m_priorityQueue)
97 m_priorityQueue.Find(delegate(J2KImage img) { return img.m_requestedUUID == newRequest.RequestedAssetID; }, out imgrequest); 92 m_priorityQueue.Find(delegate(J2KImage img) { return img.TextureID == newRequest.RequestedAssetID; }, out imgrequest);
98 93
99 if (imgrequest != null) 94 if (imgrequest != null)
100 { 95 {
@@ -105,7 +100,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
105 try 100 try
106 { 101 {
107 lock (m_priorityQueue) 102 lock (m_priorityQueue)
108 m_priorityQueue.Delete(imgrequest.m_priorityQueueHandle); 103 m_priorityQueue.Delete(imgrequest.PriorityQueueHandle);
109 } 104 }
110 catch (Exception) { } 105 catch (Exception) { }
111 } 106 }
@@ -116,30 +111,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
116 111
117 //Check the packet sequence to make sure this isn't older than 112 //Check the packet sequence to make sure this isn't older than
118 //one we've already received 113 //one we've already received
119 if (newRequest.requestSequence > imgrequest.m_lastSequence) 114 if (newRequest.requestSequence > imgrequest.LastSequence)
120 { 115 {
121 //Update the sequence number of the last RequestImage packet 116 //Update the sequence number of the last RequestImage packet
122 imgrequest.m_lastSequence = newRequest.requestSequence; 117 imgrequest.LastSequence = newRequest.requestSequence;
123 118
124 //Update the requested discard level 119 //Update the requested discard level
125 imgrequest.m_requestedDiscardLevel = newRequest.DiscardLevel; 120 imgrequest.DiscardLevel = newRequest.DiscardLevel;
126 121
127 //Update the requested packet number 122 //Update the requested packet number
128 imgrequest.m_requestedPacketNumber = newRequest.PacketNumber; 123 imgrequest.StartPacket = Math.Max(1, newRequest.PacketNumber);
129 124
130 //Update the requested priority 125 //Update the requested priority
131 imgrequest.m_requestedPriority = newRequest.Priority; 126 imgrequest.Priority = newRequest.Priority;
132 try 127 UpdateImageInQueue(imgrequest);
133 {
134 lock (m_priorityQueue)
135 m_priorityQueue.Replace(imgrequest.m_priorityQueueHandle, imgrequest);
136 }
137 catch (Exception)
138 {
139 imgrequest.m_priorityQueueHandle = null;
140 lock (m_priorityQueue)
141 m_priorityQueue.Add(ref imgrequest.m_priorityQueueHandle, imgrequest);
142 }
143 128
144 //Run an update 129 //Run an update
145 imgrequest.RunUpdate(); 130 imgrequest.RunUpdate();
@@ -159,31 +144,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
159 // newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority); 144 // newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority);
160 145
161 imgrequest = new J2KImage(this); 146 imgrequest = new J2KImage(this);
162 147 imgrequest.J2KDecoder = m_j2kDecodeModule;
163 //Assign our decoder module 148 imgrequest.AssetService = m_assetCache;
164 imgrequest.m_j2kDecodeModule = m_j2kDecodeModule; 149 imgrequest.DiscardLevel = newRequest.DiscardLevel;
165 150 imgrequest.StartPacket = Math.Max(1, newRequest.PacketNumber);
166 //Assign our asset cache module 151 imgrequest.Priority = newRequest.Priority;
167 imgrequest.m_assetCache = m_assetCache; 152 imgrequest.TextureID = newRequest.RequestedAssetID;
168 153 imgrequest.Priority = newRequest.Priority;
169 //Assign the requested discard level
170 imgrequest.m_requestedDiscardLevel = newRequest.DiscardLevel;
171
172 //Assign the requested packet number
173 imgrequest.m_requestedPacketNumber = newRequest.PacketNumber;
174
175 //Assign the requested priority
176 imgrequest.m_requestedPriority = newRequest.Priority;
177
178 //Assign the asset uuid
179 imgrequest.m_requestedUUID = newRequest.RequestedAssetID;
180
181 //Assign the requested priority
182 imgrequest.m_requestedPriority = newRequest.Priority;
183 154
184 //Add this download to the priority queue 155 //Add this download to the priority queue
185 lock (m_priorityQueue) 156 AddImageToQueue(imgrequest);
186 m_priorityQueue.Add(ref imgrequest.m_priorityQueueHandle, imgrequest);
187 157
188 //Run an update 158 //Run an update
189 imgrequest.RunUpdate(); 159 imgrequest.RunUpdate();
@@ -194,105 +164,99 @@ namespace OpenSim.Region.ClientStack.LindenUDP
194 164
195 public bool ProcessImageQueue(int count, int maxpack) 165 public bool ProcessImageQueue(int count, int maxpack)
196 { 166 {
197 lock (this) 167 J2KImage imagereq;
198 { 168 int numCollected = 0;
199 //count is the number of textures we want to process in one go.
200 //As part of this class re-write, that number will probably rise
201 //since we're processing in a more efficient manner.
202
203 // this can happen during Close()
204 if (m_client == null)
205 return false;
206
207 int numCollected = 0;
208
209 //Calculate our threshold
210 int threshold;
211 if (m_lastloopprocessed == 0)
212 {
213 if (m_client.PacketHandler == null || m_client.PacketHandler.PacketQueue == null || m_client.PacketHandler.PacketQueue.TextureThrottle == null)
214 return false;
215 //This is decent for a semi fast machine, but we'll calculate it more accurately based on time below
216 threshold = m_client.PacketHandler.PacketQueue.TextureThrottle.Current / 6300;
217 m_lastloopprocessed = DateTime.Now.Ticks;
218 }
219 else
220 {
221 double throttleseconds = ((double)DateTime.Now.Ticks - (double)m_lastloopprocessed) / (double)TimeSpan.TicksPerSecond;
222 throttleseconds = throttleseconds * m_client.PacketHandler.PacketQueue.TextureThrottle.Current;
223
224 //Average of 1000 bytes per packet
225 throttleseconds = throttleseconds / 1000;
226
227 //Safe-zone multiplier of 2.0
228 threshold = (int)(throttleseconds * 2.0);
229 m_lastloopprocessed = DateTime.Now.Ticks;
230
231 }
232 169
233 if (m_client.PacketHandler == null) 170 //lock (m_syncRoot)
234 return false; 171 //{
172 m_lastloopprocessed = DateTime.Now.Ticks;
235 173
236 if (m_client.PacketHandler.PacketQueue == null) 174 // This can happen during Close()
175 if (m_client == null || m_client.PacketHandler == null || m_client.PacketHandler.PacketQueue == null)
237 return false; 176 return false;
238 177
239 if (threshold < 10) 178 while ((imagereq = GetHighestPriorityImage()) != null)
240 threshold = 10;
241
242 //Uncomment this to see what the texture stack is doing
243 //m_log.Debug("Queue: " + m_client.PacketHandler.PacketQueue.getQueueCount(ThrottleOutPacketType.Texture).ToString() + " Threshold: " + threshold.ToString() + " outstanding: " + m_outstandingtextures.ToString());
244 if (true) //m_client.PacketHandler.PacketQueue.GetQueueCount(ThrottleOutPacketType.Texture) < threshold)
245 { 179 {
246 while (m_priorityQueue.Count > 0) 180 if (imagereq.IsDecoded == true)
247 { 181 {
248 J2KImage imagereq = null; 182 ++numCollected;
249 lock (m_priorityQueue)
250 imagereq = m_priorityQueue.FindMax();
251 183
252 if (imagereq.m_decoded == true) 184 if (imagereq.SendPackets(m_client, maxpack))
253 { 185 {
254 // we need to test this here now that we are dropping assets 186 // Send complete. Destroy any knowledge of this transfer
255 if (!imagereq.m_hasasset) 187 RemoveImageFromQueue(imagereq);
256 {
257 m_log.WarnFormat("[LLIMAGE MANAGER]: Re-requesting the image asset {0}", imagereq.m_requestedUUID);
258 imagereq.RunUpdate();
259 continue;
260 }
261
262 ++numCollected;
263
264 //SendPackets will send up to ten packets per cycle
265 if (imagereq.SendPackets(m_client, maxpack))
266 {
267 // Send complete. Destroy any knowledge of this transfer
268 try
269 {
270 lock (m_priorityQueue)
271 m_priorityQueue.Delete(imagereq.m_priorityQueueHandle);
272 }
273 catch (Exception) { }
274 }
275 } 188 }
276
277 if (numCollected == count)
278 break;
279 } 189 }
190
191 if (numCollected == count)
192 break;
280 } 193 }
194 //}
281 195
282 return m_priorityQueue.Count > 0; 196 return m_priorityQueue.Count > 0;
283 }
284 } 197 }
285 198
286 //Faux destructor 199 //Faux destructor
287 public void Close() 200 public void Close()
288 { 201 {
289
290 m_shuttingdown = true; 202 m_shuttingdown = true;
291 m_j2kDecodeModule = null; 203 m_j2kDecodeModule = null;
292 m_assetCache = null; 204 m_assetCache = null;
293 m_client = null; 205 m_client = null;
294 } 206 }
295 207
208 #region Priority Queue Helpers
209
210 J2KImage GetHighestPriorityImage()
211 {
212 J2KImage image = null;
213
214 lock (m_priorityQueue)
215 {
216
217 if (m_priorityQueue.Count > 0)
218 {
219 try
220 {
221 image = m_priorityQueue.FindMax();
222 }
223 catch (Exception) { }
224 }
225 }
226 return image;
227 }
228
229 void AddImageToQueue(J2KImage image)
230 {
231 image.PriorityQueueHandle = null;
232
233 lock (m_priorityQueue)
234 m_priorityQueue.Add(ref image.PriorityQueueHandle, image);
235 }
236
237 void RemoveImageFromQueue(J2KImage image)
238 {
239 try
240 {
241 lock (m_priorityQueue)
242 m_priorityQueue.Delete(image.PriorityQueueHandle);
243 }
244 catch (Exception) { }
245 }
246
247 void UpdateImageInQueue(J2KImage image)
248 {
249 lock (m_priorityQueue)
250 {
251 try { m_priorityQueue.Replace(image.PriorityQueueHandle, image); }
252 catch (Exception)
253 {
254 image.PriorityQueueHandle = null;
255 m_priorityQueue.Add(ref image.PriorityQueueHandle, image);
256 }
257 }
258 }
296 259
260 #endregion Priority Queue Helpers
297 } 261 }
298} 262}
diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
index a0f359b..7456e8c 100644
--- a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
@@ -257,7 +257,7 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
257 stringResult.AppendFormat("{0}|{1}|{2}{3}", Layers[i].Start, Layers[i].End, Layers[i].End - Layers[i].Start, strEnd); 257 stringResult.AppendFormat("{0}|{1}|{2}{3}", Layers[i].Start, Layers[i].End, Layers[i].End - Layers[i].Start, strEnd);
258 } 258 }
259 259
260 layerDecodeAsset.Data = Encoding.UTF8.GetBytes(stringResult.ToString()); 260 layerDecodeAsset.Data = Util.UTF8.GetBytes(stringResult.ToString());
261 261
262 #endregion Serialize Layer Data 262 #endregion Serialize Layer Data
263 263
@@ -280,7 +280,7 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
280 { 280 {
281 #region Deserialize Layer Data 281 #region Deserialize Layer Data
282 282
283 string readResult = Encoding.UTF8.GetString(layerDecodeAsset.Data); 283 string readResult = Util.UTF8.GetString(layerDecodeAsset.Data);
284 string[] lines = readResult.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); 284 string[] lines = readResult.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
285 285
286 if (lines.Length == 0) 286 if (lines.Length == 0)
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index 817e0d4..c0bb70c 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -323,13 +323,13 @@ namespace Flotsam.RegionModules.AssetCache
323 string filename = GetFileName(id); 323 string filename = GetFileName(id);
324 if (File.Exists(filename)) 324 if (File.Exists(filename))
325 { 325 {
326 FileStream stream = null;
326 try 327 try
327 { 328 {
328 FileStream stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read); 329 stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
329 BinaryFormatter bformatter = new BinaryFormatter(); 330 BinaryFormatter bformatter = new BinaryFormatter();
330 331
331 asset = (AssetBase)bformatter.Deserialize(stream); 332 asset = (AssetBase)bformatter.Deserialize(stream);
332 stream.Close();
333 333
334 UpdateMemoryCache(id, asset); 334 UpdateMemoryCache(id, asset);
335 335
@@ -349,6 +349,11 @@ namespace Flotsam.RegionModules.AssetCache
349 { 349 {
350 LogException(e); 350 LogException(e);
351 } 351 }
352 finally
353 {
354 if (stream != null)
355 stream.Close();
356 }
352 } 357 }
353 358
354 359
@@ -493,19 +498,20 @@ namespace Flotsam.RegionModules.AssetCache
493 498
494 private void WriteFileCache(string filename, AssetBase asset) 499 private void WriteFileCache(string filename, AssetBase asset)
495 { 500 {
501 Stream stream = null;
502 // Make sure the target cache directory exists
503 string directory = Path.GetDirectoryName(filename);
504 // Write file first to a temp name, so that it doesn't look
505 // like it's already cached while it's still writing.
506 string tempname = Path.Combine(directory, Path.GetRandomFileName());
496 try 507 try
497 { 508 {
498 // Make sure the target cache directory exists
499 string directory = Path.GetDirectoryName(filename);
500 if (!Directory.Exists(directory)) 509 if (!Directory.Exists(directory))
501 { 510 {
502 Directory.CreateDirectory(directory); 511 Directory.CreateDirectory(directory);
503 } 512 }
504 513
505 // Write file first to a temp name, so that it doesn't look 514 stream = File.Open(tempname, FileMode.Create);
506 // like it's already cached while it's still writing.
507 string tempname = Path.Combine(directory, Path.GetRandomFileName());
508 Stream stream = File.Open(tempname, FileMode.Create);
509 BinaryFormatter bformatter = new BinaryFormatter(); 515 BinaryFormatter bformatter = new BinaryFormatter();
510 bformatter.Serialize(stream, asset); 516 bformatter.Serialize(stream, asset);
511 stream.Close(); 517 stream.Close();
@@ -522,6 +528,9 @@ namespace Flotsam.RegionModules.AssetCache
522 } 528 }
523 finally 529 finally
524 { 530 {
531 if (stream != null)
532 stream.Close();
533
525 // Even if the write fails with an exception, we need to make sure 534 // Even if the write fails with an exception, we need to make sure
526 // that we release the lock on that file, otherwise it'll never get 535 // that we release the lock on that file, otherwise it'll never get
527 // cached 536 // cached
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
index 50d7c97..45e724d 100644
--- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
@@ -367,7 +367,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
367 // Encode outbound data 367 // Encode outbound data
368 if (OutboundBody.Length > 0) 368 if (OutboundBody.Length > 0)
369 { 369 {
370 byte[] data = Encoding.UTF8.GetBytes(OutboundBody); 370 byte[] data = Util.UTF8.GetBytes(OutboundBody);
371 371
372 Request.ContentLength = data.Length; 372 Request.ContentLength = data.Length;
373 Stream bstream = Request.GetRequestStream(); 373 Stream bstream = Request.GetRequestStream();
@@ -390,7 +390,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
390 if (count != 0) 390 if (count != 0)
391 { 391 {
392 // translate from bytes to ASCII text 392 // translate from bytes to ASCII text
393 tempString = Encoding.UTF8.GetString(buf, 0, count); 393 tempString = Util.UTF8.GetString(buf, 0, count);
394 394
395 // continue building the string 395 // continue building the string
396 sb.Append(tempString); 396 sb.Append(tempString);
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 040d0a3..901144a 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -397,10 +397,15 @@ namespace OpenSim.Region.CoreModules.World.Permissions
397 // with the powers requested (powers = 0 for no powers check) 397 // with the powers requested (powers = 0 for no powers check)
398 protected bool IsGroupMember(UUID groupID, UUID userID, ulong powers) 398 protected bool IsGroupMember(UUID groupID, UUID userID, ulong powers)
399 { 399 {
400 IClientAPI client = m_scene.GetScenePresence(userID).ControllingClient; 400 ScenePresence sp = m_scene.GetScenePresence(userID);
401 401 if (sp != null)
402 return ((groupID == client.ActiveGroupId) && (client.ActiveGroupPowers != 0) && 402 {
403 ((powers == 0) || ((client.ActiveGroupPowers & powers) == powers))); 403 IClientAPI client = sp.ControllingClient;
404
405 return ((groupID == client.ActiveGroupId) && (client.ActiveGroupPowers != 0) &&
406 ((powers == 0) || ((client.ActiveGroupPowers & powers) == powers)));
407 }
408 return false;
404 } 409 }
405 410
406 /// <summary> 411 /// <summary>
@@ -576,9 +581,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions
576 return objectOwnerMask; 581 return objectOwnerMask;
577 } 582 }
578 583
584 if ((objectOwnerMask & (uint)PermissionMask.Transfer) != 0 && task.ObjectSaleType != 0)
585 objectEveryoneMask |= (uint)PrimFlags.ObjectTransfer;
586
579 // Group permissions 587 // Group permissions
580 if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0)) 588 if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0))
581 return objectGroupMask; 589 return objectGroupMask | objectEveryoneMask;
582 590
583 return objectEveryoneMask; 591 return objectEveryoneMask;
584 } 592 }
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs
index 3eb7cd2..a70ef13 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/LLRAW.cs
@@ -36,10 +36,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
36 { 36 {
37 public struct HeightmapLookupValue : IComparable<HeightmapLookupValue> 37 public struct HeightmapLookupValue : IComparable<HeightmapLookupValue>
38 { 38 {
39 public int Index; 39 public ushort Index;
40 public double Value; 40 public float Value;
41 41
42 public HeightmapLookupValue(int index, double value) 42 public HeightmapLookupValue(ushort index, float value)
43 { 43 {
44 Index = index; 44 Index = index;
45 Value = value; 45 Value = value;
@@ -62,7 +62,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
62 { 62 {
63 for (int j = 0; j < 256; j++) 63 for (int j = 0; j < 256; j++)
64 { 64 {
65 LookupHeightTable[i + (j * 256)] = new HeightmapLookupValue(i + (j * 256), ((double)i * ((double)j / 128.0d))); 65 LookupHeightTable[i + (j * 256)] = new HeightmapLookupValue((ushort)(i + (j * 256)), (float)((double)i * ((double)j / 128.0d)));
66 } 66 }
67 } 67 }
68 Array.Sort<HeightmapLookupValue>(LookupHeightTable); 68 Array.Sort<HeightmapLookupValue>(LookupHeightTable);
@@ -196,7 +196,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
196 196
197 // The lookup table is pre-sorted, so we either find an exact match or 197 // The lookup table is pre-sorted, so we either find an exact match or
198 // the next closest (smaller) match with a binary search 198 // the next closest (smaller) match with a binary search
199 index = Array.BinarySearch<HeightmapLookupValue>(LookupHeightTable, new HeightmapLookupValue(0, t)); 199 index = Array.BinarySearch<HeightmapLookupValue>(LookupHeightTable, new HeightmapLookupValue(0, (float)t));
200 if (index < 0) 200 if (index < 0)
201 index = ~index - 1; 201 index = ~index - 1;
202 202
diff --git a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs
index 080bd5a..4df9094 100644
--- a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs
+++ b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs
@@ -352,7 +352,7 @@ namespace OpenSim.Region.DataSnapshot
352 m_log.WarnFormat("[DATASNAPSHOT]: Unable to decode reply from data service. Ignoring. {0}", e.StackTrace); 352 m_log.WarnFormat("[DATASNAPSHOT]: Unable to decode reply from data service. Ignoring. {0}", e.StackTrace);
353 } 353 }
354 // This is not quite working, so... 354 // This is not quite working, so...
355 // string responseStr = Encoding.UTF8.GetString(response); 355 // string responseStr = Util.UTF8.GetString(response);
356 m_log.Info("[DATASNAPSHOT]: data service notified: " + url); 356 m_log.Info("[DATASNAPSHOT]: data service notified: " + url);
357 } 357 }
358 358
diff --git a/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs b/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs
index 73f918e..e9660b1 100644
--- a/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs
+++ b/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs
@@ -73,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes
73 73
74 public byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse) 74 public byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
75 { 75 {
76 return Encoding.UTF8.GetBytes(Report()); 76 return Util.UTF8.GetBytes(Report());
77 } 77 }
78 78
79 public string ContentType 79 public string ContentType
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index b4cfc48..23a7021 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -1332,7 +1332,8 @@ if (m_shape != null) {
1332 bool RigidBody = isPhysical && !isPhantom; 1332 bool RigidBody = isPhysical && !isPhantom;
1333 1333
1334 // The only time the physics scene shouldn't know about the prim is if it's phantom or an attachment, which is phantom by definition 1334 // The only time the physics scene shouldn't know about the prim is if it's phantom or an attachment, which is phantom by definition
1335 if (!isPhantom && !IsAttachment) 1335 // or flexible
1336 if (!isPhantom && !IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible))
1336 { 1337 {
1337 PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( 1338 PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape(
1338 Name, 1339 Name,
@@ -3395,8 +3396,8 @@ if (m_shape != null) {
3395 } 3396 }
3396 } 3397 }
3397 3398
3398 3399
3399 if (IsPhantom || IsAttachment) // note: this may have been changed above in the case of joints 3400 if (IsPhantom || IsAttachment || (Shape.PathCurve == (byte)Extrusion.Flexible)) // note: this may have been changed above in the case of joints
3400 { 3401 {
3401 AddFlag(PrimFlags.Phantom); 3402 AddFlag(PrimFlags.Phantom);
3402 if (PhysActor != null) 3403 if (PhysActor != null)
diff --git a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
index 8209ff6..ca6210d 100644
--- a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
+++ b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs
@@ -172,7 +172,7 @@ namespace OpenSim.Region.Framework.Scenes
172 public string SaveToXmlString() 172 public string SaveToXmlString()
173 { 173 {
174 XmlWriterSettings settings = new XmlWriterSettings(); 174 XmlWriterSettings settings = new XmlWriterSettings();
175 settings.Encoding = Encoding.UTF8; 175 settings.Encoding = Util.UTF8;
176 using (StringWriter sw = new StringWriter()) 176 using (StringWriter sw = new StringWriter())
177 { 177 {
178 using (XmlWriter writer = XmlWriter.Create(sw, settings)) 178 using (XmlWriter writer = XmlWriter.Create(sw, settings))
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index ee2d2db..4364627 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -81,7 +81,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
81 { 81 {
82 m_log.Info("[IRCd] Sending >>> " + command); 82 m_log.Info("[IRCd] Sending >>> " + command);
83 83
84 byte[] buf = Encoding.UTF8.GetBytes(command + "\r\n"); 84 byte[] buf = Util.UTF8.GetBytes(command + "\r\n");
85 85
86 m_client.GetStream().BeginWrite(buf, 0, buf.Length, SendComplete, null); 86 m_client.GetStream().BeginWrite(buf, 0, buf.Length, SendComplete, null);
87 } 87 }
@@ -109,7 +109,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
109 byte[] buf = new byte[8]; // RFC1459 defines max message size as 512. 109 byte[] buf = new byte[8]; // RFC1459 defines max message size as 512.
110 110
111 int count = m_client.GetStream().Read(buf, 0, buf.Length); 111 int count = m_client.GetStream().Read(buf, 0, buf.Length);
112 string line = Encoding.UTF8.GetString(buf, 0, count); 112 string line = Util.UTF8.GetString(buf, 0, count);
113 113
114 strbuf += line; 114 strbuf += line;
115 115
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
index c7bb56a..b04b076 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
@@ -559,7 +559,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
559 559
560 if (method == "POST") 560 if (method == "POST")
561 { 561 {
562 byte[] contentreq = Encoding.UTF8.GetBytes(body); 562 byte[] contentreq = Util.UTF8.GetBytes(body);
563 forwardreq.ContentLength = contentreq.Length; 563 forwardreq.ContentLength = contentreq.Length;
564 Stream reqStream = forwardreq.GetRequestStream(); 564 Stream reqStream = forwardreq.GetRequestStream();
565 reqStream.Write(contentreq, 0, contentreq.Length); 565 reqStream.Write(contentreq, 0, contentreq.Length);
@@ -567,7 +567,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
567 } 567 }
568 568
569 HttpWebResponse fwdrsp = (HttpWebResponse)forwardreq.GetResponse(); 569 HttpWebResponse fwdrsp = (HttpWebResponse)forwardreq.GetResponse();
570 Encoding encoding = Encoding.UTF8; 570 Encoding encoding = Util.UTF8;
571 StreamReader fwdresponsestream = new StreamReader(fwdrsp.GetResponseStream(), encoding); 571 StreamReader fwdresponsestream = new StreamReader(fwdrsp.GetResponseStream(), encoding);
572 fwdresponsestr = fwdresponsestream.ReadToEnd(); 572 fwdresponsestr = fwdresponsestream.ReadToEnd();
573 fwdresponsecontenttype = fwdrsp.ContentType; 573 fwdresponsecontenttype = fwdrsp.ContentType;
diff --git a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs
index 3044b17..e3fbb6e 100644
--- a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs
+++ b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs
@@ -539,7 +539,7 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
539 { 539 {
540 XmlSerializer xs = new XmlSerializer(typeof(Copse)); 540 XmlSerializer xs = new XmlSerializer(typeof(Copse));
541 541
542 using (XmlTextWriter writer = new XmlTextWriter(fileName, System.Text.Encoding.UTF8)) 542 using (XmlTextWriter writer = new XmlTextWriter(fileName, Util.UTF8))
543 { 543 {
544 writer.Formatting = Formatting.Indented; 544 writer.Formatting = Formatting.Indented;
545 xs.Serialize(writer, obj); 545 xs.Serialize(writer, obj);
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index d56ddc8..0e29ccc 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -224,6 +224,14 @@ namespace OpenSim.Region.Physics.Meshing
224 for (int i = 0; i < lodBytes.Length; i++) 224 for (int i = 0; i < lodBytes.Length; i++)
225 hash = djb2(hash, lodBytes[i]); 225 hash = djb2(hash, lodBytes[i]);
226 226
227 // include sculpt UUID
228 if (pbs.SculptEntry)
229 {
230 scaleBytes = pbs.SculptTexture.GetBytes();
231 for (int i = 0; i < scaleBytes.Length; i++)
232 hash = djb2(hash, scaleBytes[i]);
233 }
234
227 return hash; 235 return hash;
228 } 236 }
229 237
@@ -330,7 +338,7 @@ namespace OpenSim.Region.Physics.Meshing
330 bool invert = ((primShape.SculptType & 64) != 0); 338 bool invert = ((primShape.SculptType & 64) != 0);
331 339
332 sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert); 340 sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert);
333 341
334 idata.Dispose(); 342 idata.Dispose();
335 343
336 sculptMesh.DumpRaw(baseDir, primName, "primMesh"); 344 sculptMesh.DumpRaw(baseDir, primName, "primMesh");
@@ -389,7 +397,7 @@ namespace OpenSim.Region.Physics.Meshing
389 primMesh.pathCutBegin = pathBegin; 397 primMesh.pathCutBegin = pathBegin;
390 primMesh.pathCutEnd = pathEnd; 398 primMesh.pathCutEnd = pathEnd;
391 399
392 if (primShape.PathCurve == (byte)Extrusion.Straight) 400 if (primShape.PathCurve == (byte)Extrusion.Straight || primShape.PathCurve == (byte) Extrusion.Flexible)
393 { 401 {
394 primMesh.twistBegin = primShape.PathTwistBegin * 18 / 10; 402 primMesh.twistBegin = primShape.PathTwistBegin * 18 / 10;
395 primMesh.twistEnd = primShape.PathTwist * 18 / 10; 403 primMesh.twistEnd = primShape.PathTwist * 18 / 10;
@@ -484,12 +492,18 @@ namespace OpenSim.Region.Physics.Meshing
484 492
485 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size, float lod, bool isPhysical) 493 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size, float lod, bool isPhysical)
486 { 494 {
495 Mesh mesh = null;
496 ulong key = 0;
497
487 // If this mesh has been created already, return it instead of creating another copy 498 // If this mesh has been created already, return it instead of creating another copy
488 // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory 499 // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory
489 ulong key = GetMeshKey(primShape, size, lod); 500
490 Mesh mesh = null; 501 if (! primShape.SculptEntry)
491 if (m_uniqueMeshes.TryGetValue(key, out mesh)) 502 {
492 return mesh; 503 key = GetMeshKey(primShape, size, lod);
504 if (m_uniqueMeshes.TryGetValue(key, out mesh))
505 return mesh;
506 }
493 507
494 if (size.X < 0.01f) size.X = 0.01f; 508 if (size.X < 0.01f) size.X = 0.01f;
495 if (size.Y < 0.01f) size.Y = 0.01f; 509 if (size.Y < 0.01f) size.Y = 0.01f;
@@ -512,7 +526,10 @@ namespace OpenSim.Region.Physics.Meshing
512 // trim the vertex and triangle lists to free up memory 526 // trim the vertex and triangle lists to free up memory
513 mesh.TrimExcess(); 527 mesh.TrimExcess();
514 } 528 }
515 m_uniqueMeshes.Add(key, mesh); 529
530 if (!primShape.SculptEntry)
531 m_uniqueMeshes.Add(key, mesh);
532
516 return mesh; 533 return mesh;
517 } 534 }
518 } 535 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index ca67a64..b79c356 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -7080,7 +7080,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7080 try 7080 try
7081 { 7081 {
7082 byte[] encData_byte = new byte[str.Length]; 7082 byte[] encData_byte = new byte[str.Length];
7083 encData_byte = Encoding.UTF8.GetBytes(str); 7083 encData_byte = Util.UTF8.GetBytes(str);
7084 string encodedData = Convert.ToBase64String(encData_byte); 7084 string encodedData = Convert.ToBase64String(encData_byte);
7085 return encodedData; 7085 return encodedData;
7086 } 7086 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 59525b6..4cb4b61 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -1491,7 +1491,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1491 notecardData = "Linden text version 2\n{\nLLEmbeddedItems version 1\n{\ncount 0\n}\nText length " 1491 notecardData = "Linden text version 2\n{\nLLEmbeddedItems version 1\n{\ncount 0\n}\nText length "
1492 + textLength.ToString() + "\n" + notecardData + "}\n"; 1492 + textLength.ToString() + "\n" + notecardData + "}\n";
1493 1493
1494 asset.Data = Encoding.UTF8.GetBytes(notecardData); 1494 asset.Data = Util.UTF8.GetBytes(notecardData);
1495 World.AssetService.Store(asset); 1495 World.AssetService.Store(asset);
1496 1496
1497 // Create Task Entry 1497 // Create Task Entry