aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Scripting
diff options
context:
space:
mode:
authorteravus2012-11-15 10:05:16 -0500
committerteravus2012-11-15 10:05:16 -0500
commite9153e1d1aae50024d8cd05fe14a9bce34343a0e (patch)
treebc111d34f95a26b99c7e34d9e495dc14d1802cc3 /OpenSim/Region/CoreModules/Scripting
parentMerge master into teravuswork (diff)
downloadopensim-SC-e9153e1d1aae50024d8cd05fe14a9bce34343a0e.zip
opensim-SC-e9153e1d1aae50024d8cd05fe14a9bce34343a0e.tar.gz
opensim-SC-e9153e1d1aae50024d8cd05fe14a9bce34343a0e.tar.bz2
opensim-SC-e9153e1d1aae50024d8cd05fe14a9bce34343a0e.tar.xz
Revert "Merge master into teravuswork", it should have been avination, not master.
This reverts commit dfac269032300872c4d0dc507f4f9062d102b0f4, reversing changes made to 619c39e5144f15aca129d6d999bcc5c34133ee64.
Diffstat (limited to 'OpenSim/Region/CoreModules/Scripting')
-rw-r--r--OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs61
-rw-r--r--OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs277
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs17
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs49
-rw-r--r--OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs383
-rw-r--r--OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs281
-rw-r--r--OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs159
-rw-r--r--OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs133
8 files changed, 159 insertions, 1201 deletions
diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs
deleted file mode 100644
index fce9490..0000000
--- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs
+++ /dev/null
@@ -1,61 +0,0 @@
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 OpenSimulator 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;
29using System.Drawing;
30using OpenSim.Region.Framework.Interfaces;
31
32namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
33{
34 public class DynamicTexture : IDynamicTexture
35 {
36 public string InputCommands { get; private set; }
37 public Uri InputUri { get; private set; }
38 public string InputParams { get; private set; }
39 public byte[] Data { get; private set; }
40 public Size Size { get; private set; }
41 public bool IsReuseable { get; private set; }
42
43 public DynamicTexture(string inputCommands, string inputParams, byte[] data, Size size, bool isReuseable)
44 {
45 InputCommands = inputCommands;
46 InputParams = inputParams;
47 Data = data;
48 Size = size;
49 IsReuseable = isReuseable;
50 }
51
52 public DynamicTexture(Uri inputUri, string inputParams, byte[] data, Size size, bool isReuseable)
53 {
54 InputUri = inputUri;
55 InputParams = inputParams;
56 Data = data;
57 Size = size;
58 IsReuseable = isReuseable;
59 }
60 }
61} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
index 93a045e..18bd018 100644
--- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
@@ -42,29 +42,13 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
42{ 42{
43 public class DynamicTextureModule : IRegionModule, IDynamicTextureManager 43 public class DynamicTextureModule : IRegionModule, IDynamicTextureManager
44 { 44 {
45// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 45 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 46
47 private const int ALL_SIDES = -1; 47 private const int ALL_SIDES = -1;
48 48
49 public const int DISP_EXPIRE = 1; 49 public const int DISP_EXPIRE = 1;
50 public const int DISP_TEMP = 2; 50 public const int DISP_TEMP = 2;
51 51
52 /// <summary>
53 /// If true then where possible dynamic textures are reused.
54 /// </summary>
55 public bool ReuseTextures { get; set; }
56
57 /// <summary>
58 /// If false, then textures which have a low data size are not reused when ReuseTextures = true.
59 /// </summary>
60 /// <remarks>
61 /// LL viewers 3.3.4 and before appear to not fully render textures pulled from the viewer cache if those
62 /// textures have a relatively high pixel surface but a small data size. Typically, this appears to happen
63 /// if the data size is smaller than the viewer's discard level 2 size estimate. So if this is setting is
64 /// false, textures smaller than the calculation in IsSizeReuseable are always regenerated rather than reused
65 /// to work around this problem.</remarks>
66 public bool ReuseLowDataTextures { get; set; }
67
68 private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>(); 52 private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>();
69 53
70 private Dictionary<string, IDynamicTextureRender> RenderPlugins = 54 private Dictionary<string, IDynamicTextureRender> RenderPlugins =
@@ -72,15 +56,6 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
72 56
73 private Dictionary<UUID, DynamicTextureUpdater> Updaters = new Dictionary<UUID, DynamicTextureUpdater>(); 57 private Dictionary<UUID, DynamicTextureUpdater> Updaters = new Dictionary<UUID, DynamicTextureUpdater>();
74 58
75 /// <summary>
76 /// Record dynamic textures that we can reuse for a given data and parameter combination rather than
77 /// regenerate.
78 /// </summary>
79 /// <remarks>
80 /// Key is string.Format("{0}{1}", data
81 /// </remarks>
82 private Cache m_reuseableDynamicTextures;
83
84 #region IDynamicTextureManager Members 59 #region IDynamicTextureManager Members
85 60
86 public void RegisterRender(string handleType, IDynamicTextureRender render) 61 public void RegisterRender(string handleType, IDynamicTextureRender render)
@@ -94,17 +69,17 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
94 /// <summary> 69 /// <summary>
95 /// Called by code which actually renders the dynamic texture to supply texture data. 70 /// Called by code which actually renders the dynamic texture to supply texture data.
96 /// </summary> 71 /// </summary>
97 /// <param name="updaterId"></param> 72 /// <param name="id"></param>
98 /// <param name="texture"></param> 73 /// <param name="data"></param>
99 public void ReturnData(UUID updaterId, IDynamicTexture texture) 74 public void ReturnData(UUID id, byte[] data)
100 { 75 {
101 DynamicTextureUpdater updater = null; 76 DynamicTextureUpdater updater = null;
102 77
103 lock (Updaters) 78 lock (Updaters)
104 { 79 {
105 if (Updaters.ContainsKey(updaterId)) 80 if (Updaters.ContainsKey(id))
106 { 81 {
107 updater = Updaters[updaterId]; 82 updater = Updaters[id];
108 } 83 }
109 } 84 }
110 85
@@ -113,16 +88,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
113 if (RegisteredScenes.ContainsKey(updater.SimUUID)) 88 if (RegisteredScenes.ContainsKey(updater.SimUUID))
114 { 89 {
115 Scene scene = RegisteredScenes[updater.SimUUID]; 90 Scene scene = RegisteredScenes[updater.SimUUID];
116 UUID newTextureID = updater.DataReceived(texture.Data, scene); 91 updater.DataReceived(data, scene);
117
118 if (ReuseTextures
119 && !updater.BlendWithOldTexture
120 && texture.IsReuseable
121 && (ReuseLowDataTextures || IsDataSizeReuseable(texture)))
122 {
123 m_reuseableDynamicTextures.Store(
124 GenerateReusableTextureKey(texture.InputCommands, texture.InputParams), newTextureID);
125 }
126 } 92 }
127 } 93 }
128 94
@@ -138,27 +104,6 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
138 } 104 }
139 } 105 }
140 106
141 /// <summary>
142 /// Determines whether the texture is reuseable based on its data size.
143 /// </summary>
144 /// <remarks>
145 /// This is a workaround for a viewer bug where very small data size textures relative to their pixel size
146 /// are not redisplayed properly when pulled from cache. The calculation here is based on the typical discard
147 /// level of 2, a 'rate' of 0.125 and 4 components (which makes for a factor of 0.5).
148 /// </remarks>
149 /// <returns></returns>
150 private bool IsDataSizeReuseable(IDynamicTexture texture)
151 {
152// Console.WriteLine("{0} {1}", texture.Size.Width, texture.Size.Height);
153 int discardLevel2DataThreshold = (int)Math.Ceiling((texture.Size.Width >> 2) * (texture.Size.Height >> 2) * 0.5);
154
155// m_log.DebugFormat(
156// "[DYNAMIC TEXTURE MODULE]: Discard level 2 threshold {0}, texture data length {1}",
157// discardLevel2DataThreshold, texture.Data.Length);
158
159 return discardLevel2DataThreshold < texture.Data.Length;
160 }
161
162 public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, 107 public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url,
163 string extraParams, int updateTimer) 108 string extraParams, int updateTimer)
164 { 109 {
@@ -222,61 +167,22 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
222 public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, 167 public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data,
223 string extraParams, int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face) 168 string extraParams, int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face)
224 { 169 {
225 if (!RenderPlugins.ContainsKey(contentType)) 170 if (RenderPlugins.ContainsKey(contentType))
226 return UUID.Zero;
227
228 Scene scene;
229 RegisteredScenes.TryGetValue(simID, out scene);
230
231 if (scene == null)
232 return UUID.Zero;
233
234 SceneObjectPart part = scene.GetSceneObjectPart(primID);
235
236 if (part == null)
237 return UUID.Zero;
238
239 // If we want to reuse dynamic textures then we have to ignore any request from the caller to expire
240 // them.
241 if (ReuseTextures)
242 disp = disp & ~DISP_EXPIRE;
243
244 DynamicTextureUpdater updater = new DynamicTextureUpdater();
245 updater.SimUUID = simID;
246 updater.PrimID = primID;
247 updater.ContentType = contentType;
248 updater.BodyData = data;
249 updater.UpdateTimer = updateTimer;
250 updater.UpdaterID = UUID.Random();
251 updater.Params = extraParams;
252 updater.BlendWithOldTexture = SetBlending;
253 updater.FrontAlpha = AlphaValue;
254 updater.Face = face;
255 updater.Url = "Local image";
256 updater.Disp = disp;
257
258 object objReusableTextureUUID = null;
259
260 if (ReuseTextures && !updater.BlendWithOldTexture)
261 { 171 {
262 string reuseableTextureKey = GenerateReusableTextureKey(data, extraParams); 172 DynamicTextureUpdater updater = new DynamicTextureUpdater();
263 objReusableTextureUUID = m_reuseableDynamicTextures.Get(reuseableTextureKey); 173 updater.SimUUID = simID;
264 174 updater.PrimID = primID;
265 if (objReusableTextureUUID != null) 175 updater.ContentType = contentType;
266 { 176 updater.BodyData = data;
267 // If something else has removed this temporary asset from the cache, detect and invalidate 177 updater.UpdateTimer = updateTimer;
268 // our cached uuid. 178 updater.UpdaterID = UUID.Random();
269 if (scene.AssetService.GetMetadata(objReusableTextureUUID.ToString()) == null) 179 updater.Params = extraParams;
270 { 180 updater.BlendWithOldTexture = SetBlending;
271 m_reuseableDynamicTextures.Invalidate(reuseableTextureKey); 181 updater.FrontAlpha = AlphaValue;
272 objReusableTextureUUID = null; 182 updater.Face = face;
273 } 183 updater.Url = "Local image";
274 } 184 updater.Disp = disp;
275 }
276 185
277 // We cannot reuse a dynamic texture if the data is going to be blended with something already there.
278 if (objReusableTextureUUID == null)
279 {
280 lock (Updaters) 186 lock (Updaters)
281 { 187 {
282 if (!Updaters.ContainsKey(updater.UpdaterID)) 188 if (!Updaters.ContainsKey(updater.UpdaterID))
@@ -285,29 +191,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
285 } 191 }
286 } 192 }
287 193
288// m_log.DebugFormat(
289// "[DYNAMIC TEXTURE MODULE]: Requesting generation of new dynamic texture for {0} in {1}",
290// part.Name, part.ParentGroup.Scene.Name);
291
292 RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams); 194 RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams);
195 return updater.UpdaterID;
293 } 196 }
294 else 197
295 { 198 return UUID.Zero;
296// m_log.DebugFormat(
297// "[DYNAMIC TEXTURE MODULE]: Reusing cached texture {0} for {1} in {2}",
298// objReusableTextureUUID, part.Name, part.ParentGroup.Scene.Name);
299
300 // No need to add to updaters as the texture is always the same. Not that this functionality
301 // apppears to be implemented anyway.
302 updater.UpdatePart(part, (UUID)objReusableTextureUUID);
303 }
304
305 return updater.UpdaterID;
306 }
307
308 private string GenerateReusableTextureKey(string data, string extraParams)
309 {
310 return string.Format("{0}{1}", data, extraParams);
311 } 199 }
312 200
313 public void GetDrawStringSize(string contentType, string text, string fontName, int fontSize, 201 public void GetDrawStringSize(string contentType, string text, string fontName, int fontSize,
@@ -327,13 +215,6 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
327 215
328 public void Initialise(Scene scene, IConfigSource config) 216 public void Initialise(Scene scene, IConfigSource config)
329 { 217 {
330 IConfig texturesConfig = config.Configs["Textures"];
331 if (texturesConfig != null)
332 {
333 ReuseTextures = texturesConfig.GetBoolean("ReuseDynamicTextures", false);
334 ReuseLowDataTextures = texturesConfig.GetBoolean("ReuseDynamicLowDataTextures", false);
335 }
336
337 if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) 218 if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
338 { 219 {
339 RegisteredScenes.Add(scene.RegionInfo.RegionID, scene); 220 RegisteredScenes.Add(scene.RegionInfo.RegionID, scene);
@@ -343,11 +224,6 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
343 224
344 public void PostInitialise() 225 public void PostInitialise()
345 { 226 {
346 if (ReuseTextures)
347 {
348 m_reuseableDynamicTextures = new Cache(CacheMedium.Memory, CacheStrategy.Conservative);
349 m_reuseableDynamicTextures.DefaultTTL = new TimeSpan(24, 0, 0);
350 }
351 } 227 }
352 228
353 public void Close() 229 public void Close()
@@ -393,60 +269,9 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
393 } 269 }
394 270
395 /// <summary> 271 /// <summary>
396 /// Update the given part with the new texture.
397 /// </summary>
398 /// <returns>
399 /// The old texture UUID.
400 /// </returns>
401 public UUID UpdatePart(SceneObjectPart part, UUID textureID)
402 {
403 UUID oldID;
404
405 lock (part)
406 {
407 // mostly keep the values from before
408 Primitive.TextureEntry tmptex = part.Shape.Textures;
409
410 // FIXME: Need to return the appropriate ID if only a single face is replaced.
411 oldID = tmptex.DefaultTexture.TextureID;
412
413 if (Face == ALL_SIDES)
414 {
415 oldID = tmptex.DefaultTexture.TextureID;
416 tmptex.DefaultTexture.TextureID = textureID;
417 }
418 else
419 {
420 try
421 {
422 Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face);
423 texface.TextureID = textureID;
424 tmptex.FaceTextures[Face] = texface;
425 }
426 catch (Exception)
427 {
428 tmptex.DefaultTexture.TextureID = textureID;
429 }
430 }
431
432 // I'm pretty sure we always want to force this to true
433 // I'm pretty sure noone whats to set fullbright true if it wasn't true before.
434 // tmptex.DefaultTexture.Fullbright = true;
435
436 part.UpdateTextureEntry(tmptex.GetBytes());
437 }
438
439 return oldID;
440 }
441
442 /// <summary>
443 /// Called once new texture data has been received for this updater. 272 /// Called once new texture data has been received for this updater.
444 /// </summary> 273 /// </summary>
445 /// <param name="data"></param> 274 public void DataReceived(byte[] data, Scene scene)
446 /// <param name="scene"></param>
447 /// <param name="isReuseable">True if the data given is reuseable.</param>
448 /// <returns>The asset UUID given to the incoming data.</returns>
449 public UUID DataReceived(byte[] data, Scene scene)
450 { 275 {
451 SceneObjectPart part = scene.GetSceneObjectPart(PrimID); 276 SceneObjectPart part = scene.GetSceneObjectPart(PrimID);
452 277
@@ -456,8 +281,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
456 String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url); 281 String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url);
457 scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say, 282 scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say,
458 0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false); 283 0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false);
459 284 return;
460 return UUID.Zero;
461 } 285 }
462 286
463 byte[] assetData = null; 287 byte[] assetData = null;
@@ -495,29 +319,56 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
495 IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface<IJ2KDecoder>(); 319 IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface<IJ2KDecoder>();
496 if (cacheLayerDecode != null) 320 if (cacheLayerDecode != null)
497 { 321 {
498 if (!cacheLayerDecode.Decode(asset.FullID, asset.Data)) 322 cacheLayerDecode.Decode(asset.FullID, asset.Data);
499 m_log.WarnFormat( 323 cacheLayerDecode = null;
500 "[DYNAMIC TEXTURE MODULE]: Decoding of dynamically generated asset {0} for {1} in {2} failed",
501 asset.ID, part.Name, part.ParentGroup.Scene.Name);
502 } 324 }
503 325
504 UUID oldID = UpdatePart(part, asset.FullID); 326 UUID oldID = UUID.Zero;
505 327
506 if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0)) 328 lock (part)
507 { 329 {
508 if (oldAsset == null) 330 // mostly keep the values from before
509 oldAsset = scene.AssetService.Get(oldID.ToString()); 331 Primitive.TextureEntry tmptex = part.Shape.Textures;
332
333 // remove the old asset from the cache
334 oldID = tmptex.DefaultTexture.TextureID;
335
336 if (Face == ALL_SIDES)
337 {
338 tmptex.DefaultTexture.TextureID = asset.FullID;
339 }
340 else
341 {
342 try
343 {
344 Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face);
345 texface.TextureID = asset.FullID;
346 tmptex.FaceTextures[Face] = texface;
347 }
348 catch (Exception)
349 {
350 tmptex.DefaultTexture.TextureID = asset.FullID;
351 }
352 }
510 353
354 // I'm pretty sure we always want to force this to true
355 // I'm pretty sure noone whats to set fullbright true if it wasn't true before.
356 // tmptex.DefaultTexture.Fullbright = true;
357
358 part.UpdateTextureEntry(tmptex.GetBytes());
359 }
360
361 if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0))
362 {
363 if (oldAsset == null) oldAsset = scene.AssetService.Get(oldID.ToString());
511 if (oldAsset != null) 364 if (oldAsset != null)
512 { 365 {
513 if (oldAsset.Temporary) 366 if (oldAsset.Temporary == true)
514 { 367 {
515 scene.AssetService.Delete(oldID.ToString()); 368 scene.AssetService.Delete(oldID.ToString());
516 } 369 }
517 } 370 }
518 } 371 }
519
520 return asset.FullID;
521 } 372 }
522 373
523 private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha) 374 private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha)
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
index 0b9174f..56221aa 100644
--- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
@@ -58,7 +58,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
58 public string body; 58 public string body;
59 public int responseCode; 59 public int responseCode;
60 public string responseBody; 60 public string responseBody;
61 public string responseType = "text/plain";
62 //public ManualResetEvent ev; 61 //public ManualResetEvent ev;
63 public bool requestDone; 62 public bool requestDone;
64 public int startTime; 63 public int startTime;
@@ -271,22 +270,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
271 } 270 }
272 } 271 }
273 272
274 public void HttpContentType(UUID request, string type)
275 {
276 lock (m_UrlMap)
277 {
278 if (m_RequestMap.ContainsKey(request))
279 {
280 UrlData urlData = m_RequestMap[request];
281 urlData.requests[request].responseType = type;
282 }
283 else
284 {
285 m_log.Info("[HttpRequestHandler] There is no http-in request with id " + request.ToString());
286 }
287 }
288 }
289
290 public void HttpResponse(UUID request, int status, string body) 273 public void HttpResponse(UUID request, int status, string body)
291 { 274 {
292 lock (m_RequestMap) 275 lock (m_RequestMap)
diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
index 45e6527..6f83948 100644
--- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
@@ -32,7 +32,6 @@ using System.Net;
32using Nini.Config; 32using Nini.Config;
33using OpenMetaverse; 33using OpenMetaverse;
34using OpenMetaverse.Imaging; 34using OpenMetaverse.Imaging;
35using OpenSim.Region.CoreModules.Scripting.DynamicTexture;
36using OpenSim.Region.Framework.Interfaces; 35using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
38using log4net; 37using log4net;
@@ -68,18 +67,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
68 return true; 67 return true;
69 } 68 }
70 69
71// public bool AlwaysIdenticalConversion(string bodyData, string extraParams) 70 public byte[] ConvertUrl(string url, string extraParams)
72// {
73// // We don't support conversion of body data.
74// return false;
75// }
76
77 public IDynamicTexture ConvertUrl(string url, string extraParams)
78 { 71 {
79 return null; 72 return null;
80 } 73 }
81 74
82 public IDynamicTexture ConvertData(string bodyData, string extraParams) 75 public byte[] ConvertStream(Stream data, string extraParams)
83 { 76 {
84 return null; 77 return null;
85 } 78 }
@@ -172,11 +165,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
172 165
173 private void HttpRequestReturn(IAsyncResult result) 166 private void HttpRequestReturn(IAsyncResult result)
174 { 167 {
168
175 RequestState state = (RequestState) result.AsyncState; 169 RequestState state = (RequestState) result.AsyncState;
176 WebRequest request = (WebRequest) state.Request; 170 WebRequest request = (WebRequest) state.Request;
177 Stream stream = null; 171 Stream stream = null;
178 byte[] imageJ2000 = new byte[0]; 172 byte[] imageJ2000 = new byte[0];
179 Size newSize = new Size(0, 0);
180 173
181 try 174 try
182 { 175 {
@@ -189,43 +182,37 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
189 try 182 try
190 { 183 {
191 Bitmap image = new Bitmap(stream); 184 Bitmap image = new Bitmap(stream);
185 Size newsize;
192 186
193 // TODO: make this a bit less hard coded 187 // TODO: make this a bit less hard coded
194 if ((image.Height < 64) && (image.Width < 64)) 188 if ((image.Height < 64) && (image.Width < 64))
195 { 189 {
196 newSize.Width = 32; 190 newsize = new Size(32, 32);
197 newSize.Height = 32;
198 } 191 }
199 else if ((image.Height < 128) && (image.Width < 128)) 192 else if ((image.Height < 128) && (image.Width < 128))
200 { 193 {
201 newSize.Width = 64; 194 newsize = new Size(64, 64);
202 newSize.Height = 64;
203 } 195 }
204 else if ((image.Height < 256) && (image.Width < 256)) 196 else if ((image.Height < 256) && (image.Width < 256))
205 { 197 {
206 newSize.Width = 128; 198 newsize = new Size(128, 128);
207 newSize.Height = 128;
208 } 199 }
209 else if ((image.Height < 512 && image.Width < 512)) 200 else if ((image.Height < 512 && image.Width < 512))
210 { 201 {
211 newSize.Width = 256; 202 newsize = new Size(256, 256);
212 newSize.Height = 256;
213 } 203 }
214 else if ((image.Height < 1024 && image.Width < 1024)) 204 else if ((image.Height < 1024 && image.Width < 1024))
215 { 205 {
216 newSize.Width = 512; 206 newsize = new Size(512, 512);
217 newSize.Height = 512;
218 } 207 }
219 else 208 else
220 { 209 {
221 newSize.Width = 1024; 210 newsize = new Size(1024, 1024);
222 newSize.Height = 1024;
223 } 211 }
224 212
225 using (Bitmap resize = new Bitmap(image, newSize)) 213 Bitmap resize = new Bitmap(image, newsize);
226 { 214
227 imageJ2000 = OpenJPEG.EncodeFromImage(resize, true); 215 imageJ2000 = OpenJPEG.EncodeFromImage(resize, true);
228 }
229 } 216 }
230 catch (Exception) 217 catch (Exception)
231 { 218 {
@@ -240,6 +227,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
240 } 227 }
241 catch (WebException) 228 catch (WebException)
242 { 229 {
230
243 } 231 }
244 finally 232 finally
245 { 233 {
@@ -248,14 +236,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
248 stream.Close(); 236 stream.Close();
249 } 237 }
250 } 238 }
251 239 m_log.DebugFormat("[LOADIMAGEURLMODULE] Returning {0} bytes of image data for request {1}",
252 m_log.DebugFormat("[LOADIMAGEURLMODULE]: Returning {0} bytes of image data for request {1}",
253 imageJ2000.Length, state.RequestID); 240 imageJ2000.Length, state.RequestID);
254 241 m_textureManager.ReturnData(state.RequestID, imageJ2000);
255 m_textureManager.ReturnData(
256 state.RequestID,
257 new OpenSim.Region.CoreModules.Scripting.DynamicTexture.DynamicTexture(
258 request.RequestUri, null, imageJ2000, newSize, false));
259 } 242 }
260 243
261 #region Nested type: RequestState 244 #region Nested type: RequestState
diff --git a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
deleted file mode 100644
index dc54c3f..0000000
--- a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
+++ /dev/null
@@ -1,383 +0,0 @@
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 OpenSimulator 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;
29using System.Reflection;
30using System.Collections.Generic;
31using Nini.Config;
32using log4net;
33using OpenSim.Framework;
34using OpenSim.Region.Framework.Interfaces;
35using OpenSim.Region.Framework.Scenes;
36using Mono.Addins;
37using OpenMetaverse;
38using System.Linq;
39using System.Linq.Expressions;
40
41namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
42{
43 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ScriptModuleCommsModule")]
44 class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms
45 {
46 private static readonly ILog m_log =
47 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48
49 private Dictionary<string,object> m_constants = new Dictionary<string,object>();
50
51#region ScriptInvocation
52 protected class ScriptInvocationData
53 {
54 public Delegate ScriptInvocationDelegate { get; private set; }
55 public string FunctionName { get; private set; }
56 public Type[] TypeSignature { get; private set; }
57 public Type ReturnType { get; private set; }
58
59 public ScriptInvocationData(string fname, Delegate fn, Type[] callsig, Type returnsig)
60 {
61 FunctionName = fname;
62 ScriptInvocationDelegate = fn;
63 TypeSignature = callsig;
64 ReturnType = returnsig;
65 }
66 }
67
68 private Dictionary<string,ScriptInvocationData> m_scriptInvocation = new Dictionary<string,ScriptInvocationData>();
69#endregion
70
71 private IScriptModule m_scriptModule = null;
72 public event ScriptCommand OnScriptCommand;
73
74#region RegionModuleInterface
75 public void Initialise(IConfigSource config)
76 {
77 }
78
79 public void AddRegion(Scene scene)
80 {
81 scene.RegisterModuleInterface<IScriptModuleComms>(this);
82 }
83
84 public void RemoveRegion(Scene scene)
85 {
86 }
87
88 public void RegionLoaded(Scene scene)
89 {
90 m_scriptModule = scene.RequestModuleInterface<IScriptModule>();
91
92 if (m_scriptModule != null)
93 m_log.Info("[MODULE COMMANDS]: Script engine found, module active");
94 }
95
96 public string Name
97 {
98 get { return "ScriptModuleCommsModule"; }
99 }
100
101 public Type ReplaceableInterface
102 {
103 get { return null; }
104 }
105
106 public void Close()
107 {
108 }
109#endregion
110
111#region ScriptModuleComms
112
113 public void RaiseEvent(UUID script, string id, string module, string command, string k)
114 {
115 ScriptCommand c = OnScriptCommand;
116
117 if (c == null)
118 return;
119
120 c(script, id, module, command, k);
121 }
122
123 public void DispatchReply(UUID script, int code, string text, string k)
124 {
125 if (m_scriptModule == null)
126 return;
127
128 Object[] args = new Object[] {-1, code, text, k};
129
130 m_scriptModule.PostScriptEvent(script, "link_message", args);
131 }
132
133 private static MethodInfo GetMethodInfoFromType(Type target, string meth, bool searchInstanceMethods)
134 {
135 BindingFlags getMethodFlags =
136 BindingFlags.NonPublic | BindingFlags.Public;
137
138 if (searchInstanceMethods)
139 getMethodFlags |= BindingFlags.Instance;
140 else
141 getMethodFlags |= BindingFlags.Static;
142
143 return target.GetMethod(meth, getMethodFlags);
144 }
145
146 public void RegisterScriptInvocation(object target, string meth)
147 {
148 MethodInfo mi = GetMethodInfoFromType(target.GetType(), meth, true);
149 if (mi == null)
150 {
151 m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}", meth);
152 return;
153 }
154
155 RegisterScriptInvocation(target, mi);
156 }
157
158 public void RegisterScriptInvocation(object target, string[] meth)
159 {
160 foreach (string m in meth)
161 RegisterScriptInvocation(target, m);
162 }
163
164 public void RegisterScriptInvocation(object target, MethodInfo mi)
165 {
166 m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, (target is Type) ? ((Type)target).Name : target.GetType().Name);
167
168 Type delegateType;
169 List<Type> typeArgs = mi.GetParameters()
170 .Select(p => p.ParameterType)
171 .ToList();
172
173 if (mi.ReturnType == typeof(void))
174 {
175 delegateType = Expression.GetActionType(typeArgs.ToArray());
176 }
177 else
178 {
179 typeArgs.Add(mi.ReturnType);
180 delegateType = Expression.GetFuncType(typeArgs.ToArray());
181 }
182
183 Delegate fcall;
184 if (!(target is Type))
185 fcall = Delegate.CreateDelegate(delegateType, target, mi);
186 else
187 fcall = Delegate.CreateDelegate(delegateType, (Type)target, mi.Name);
188
189 lock (m_scriptInvocation)
190 {
191 ParameterInfo[] parameters = fcall.Method.GetParameters();
192 if (parameters.Length < 2) // Must have two UUID params
193 return;
194
195 // Hide the first two parameters
196 Type[] parmTypes = new Type[parameters.Length - 2];
197 for (int i = 2; i < parameters.Length; i++)
198 parmTypes[i - 2] = parameters[i].ParameterType;
199 m_scriptInvocation[fcall.Method.Name] = new ScriptInvocationData(fcall.Method.Name, fcall, parmTypes, fcall.Method.ReturnType);
200 }
201 }
202
203 public void RegisterScriptInvocation(Type target, string[] methods)
204 {
205 foreach (string method in methods)
206 {
207 MethodInfo mi = GetMethodInfoFromType(target, method, false);
208 if (mi == null)
209 m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}", method);
210 else
211 RegisterScriptInvocation(target, mi);
212 }
213 }
214
215 public void RegisterScriptInvocations(IRegionModuleBase target)
216 {
217 foreach(MethodInfo method in target.GetType().GetMethods(
218 BindingFlags.Public | BindingFlags.Instance |
219 BindingFlags.Static))
220 {
221 if(method.GetCustomAttributes(
222 typeof(ScriptInvocationAttribute), true).Any())
223 {
224 if(method.IsStatic)
225 RegisterScriptInvocation(target.GetType(), method);
226 else
227 RegisterScriptInvocation(target, method);
228 }
229 }
230 }
231
232 public Delegate[] GetScriptInvocationList()
233 {
234 List<Delegate> ret = new List<Delegate>();
235
236 lock (m_scriptInvocation)
237 {
238 foreach (ScriptInvocationData d in m_scriptInvocation.Values)
239 ret.Add(d.ScriptInvocationDelegate);
240 }
241 return ret.ToArray();
242 }
243
244 public string LookupModInvocation(string fname)
245 {
246 lock (m_scriptInvocation)
247 {
248 ScriptInvocationData sid;
249 if (m_scriptInvocation.TryGetValue(fname,out sid))
250 {
251 if (sid.ReturnType == typeof(string))
252 return "modInvokeS";
253 else if (sid.ReturnType == typeof(int))
254 return "modInvokeI";
255 else if (sid.ReturnType == typeof(float))
256 return "modInvokeF";
257 else if (sid.ReturnType == typeof(UUID))
258 return "modInvokeK";
259 else if (sid.ReturnType == typeof(OpenMetaverse.Vector3))
260 return "modInvokeV";
261 else if (sid.ReturnType == typeof(OpenMetaverse.Quaternion))
262 return "modInvokeR";
263 else if (sid.ReturnType == typeof(object[]))
264 return "modInvokeL";
265
266 m_log.WarnFormat("[MODULE COMMANDS] failed to find match for {0} with return type {1}",fname,sid.ReturnType.Name);
267 }
268 }
269
270 return null;
271 }
272
273 public Delegate LookupScriptInvocation(string fname)
274 {
275 lock (m_scriptInvocation)
276 {
277 ScriptInvocationData sid;
278 if (m_scriptInvocation.TryGetValue(fname,out sid))
279 return sid.ScriptInvocationDelegate;
280 }
281
282 return null;
283 }
284
285 public Type[] LookupTypeSignature(string fname)
286 {
287 lock (m_scriptInvocation)
288 {
289 ScriptInvocationData sid;
290 if (m_scriptInvocation.TryGetValue(fname,out sid))
291 return sid.TypeSignature;
292 }
293
294 return null;
295 }
296
297 public Type LookupReturnType(string fname)
298 {
299 lock (m_scriptInvocation)
300 {
301 ScriptInvocationData sid;
302 if (m_scriptInvocation.TryGetValue(fname,out sid))
303 return sid.ReturnType;
304 }
305
306 return null;
307 }
308
309 public object InvokeOperation(UUID hostid, UUID scriptid, string fname, params object[] parms)
310 {
311 List<object> olist = new List<object>();
312 olist.Add(hostid);
313 olist.Add(scriptid);
314 foreach (object o in parms)
315 olist.Add(o);
316 Delegate fn = LookupScriptInvocation(fname);
317 return fn.DynamicInvoke(olist.ToArray());
318 }
319
320 /// <summary>
321 /// Operation to for a region module to register a constant to be used
322 /// by the script engine
323 /// </summary>
324 public void RegisterConstant(string cname, object value)
325 {
326 m_log.DebugFormat("[MODULE COMMANDS] register constant <{0}> with value {1}",cname,value.ToString());
327 lock (m_constants)
328 {
329 m_constants.Add(cname,value);
330 }
331 }
332
333 public void RegisterConstants(IRegionModuleBase target)
334 {
335 foreach (FieldInfo field in target.GetType().GetFields(
336 BindingFlags.Public | BindingFlags.Static |
337 BindingFlags.Instance))
338 {
339 if (field.GetCustomAttributes(
340 typeof(ScriptConstantAttribute), true).Any())
341 {
342 RegisterConstant(field.Name, field.GetValue(target));
343 }
344 }
345 }
346
347 /// <summary>
348 /// Operation to check for a registered constant
349 /// </summary>
350 public object LookupModConstant(string cname)
351 {
352 // m_log.DebugFormat("[MODULE COMMANDS] lookup constant <{0}>",cname);
353
354 lock (m_constants)
355 {
356 object value = null;
357 if (m_constants.TryGetValue(cname,out value))
358 return value;
359 }
360
361 return null;
362 }
363
364 /// <summary>
365 /// Get all registered constants
366 /// </summary>
367 public Dictionary<string, object> GetConstants()
368 {
369 Dictionary<string, object> ret = new Dictionary<string, object>();
370
371 lock (m_constants)
372 {
373 foreach (KeyValuePair<string, object> kvp in m_constants)
374 ret[kvp.Key] = kvp.Value;
375 }
376
377 return ret;
378 }
379
380#endregion
381
382 }
383}
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
index 41baccc..9787c8c 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
@@ -45,292 +45,31 @@ using OpenSim.Tests.Common.Mock;
45namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests 45namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
46{ 46{
47 [TestFixture] 47 [TestFixture]
48 public class VectorRenderModuleTests : OpenSimTestCase 48 public class VectorRenderModuleTests
49 { 49 {
50 Scene m_scene;
51 DynamicTextureModule m_dtm;
52 VectorRenderModule m_vrm;
53
54 private void SetupScene(bool reuseTextures)
55 {
56 m_scene = new SceneHelpers().SetupScene();
57
58 m_dtm = new DynamicTextureModule();
59 m_dtm.ReuseTextures = reuseTextures;
60// m_dtm.ReuseLowDataTextures = reuseTextures;
61
62 m_vrm = new VectorRenderModule();
63
64 SceneHelpers.SetupSceneModules(m_scene, m_dtm, m_vrm);
65 }
66
67 [Test] 50 [Test]
68 public void TestDraw() 51 public void TestDraw()
69 { 52 {
70 TestHelpers.InMethod(); 53 TestHelpers.InMethod();
71 54
72 SetupScene(false); 55 Scene scene = new SceneHelpers().SetupScene();
73 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); 56 DynamicTextureModule dtm = new DynamicTextureModule();
74 UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; 57 VectorRenderModule vrm = new VectorRenderModule();
75 58 SceneHelpers.SetupSceneModules(scene, dtm, vrm);
76 m_dtm.AddDynamicTextureData(
77 m_scene.RegionInfo.RegionID,
78 so.UUID,
79 m_vrm.GetContentType(),
80 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;",
81 "",
82 0);
83
84 Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
85 }
86
87 [Test]
88 public void TestRepeatSameDraw()
89 {
90 TestHelpers.InMethod();
91
92 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
93
94 SetupScene(false);
95 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
96
97 m_dtm.AddDynamicTextureData(
98 m_scene.RegionInfo.RegionID,
99 so.UUID,
100 m_vrm.GetContentType(),
101 dtText,
102 "",
103 0);
104
105 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
106
107 m_dtm.AddDynamicTextureData(
108 m_scene.RegionInfo.RegionID,
109 so.UUID,
110 m_vrm.GetContentType(),
111 dtText,
112 "",
113 0);
114
115 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
116 }
117
118 [Test]
119 public void TestRepeatSameDrawDifferentExtraParams()
120 {
121 TestHelpers.InMethod();
122
123 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
124
125 SetupScene(false);
126 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
127
128 m_dtm.AddDynamicTextureData(
129 m_scene.RegionInfo.RegionID,
130 so.UUID,
131 m_vrm.GetContentType(),
132 dtText,
133 "",
134 0);
135
136 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
137
138 m_dtm.AddDynamicTextureData(
139 m_scene.RegionInfo.RegionID,
140 so.UUID,
141 m_vrm.GetContentType(),
142 dtText,
143 "alpha:250",
144 0);
145
146 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
147 }
148
149 [Test]
150 public void TestRepeatSameDrawContainingImage()
151 {
152 TestHelpers.InMethod();
153
154 string dtText
155 = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png";
156
157 SetupScene(false);
158 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
159
160 m_dtm.AddDynamicTextureData(
161 m_scene.RegionInfo.RegionID,
162 so.UUID,
163 m_vrm.GetContentType(),
164 dtText,
165 "",
166 0);
167
168 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
169
170 m_dtm.AddDynamicTextureData(
171 m_scene.RegionInfo.RegionID,
172 so.UUID,
173 m_vrm.GetContentType(),
174 dtText,
175 "",
176 0);
177
178 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
179 }
180
181 [Test]
182 public void TestDrawReusingTexture()
183 {
184 TestHelpers.InMethod();
185 59
186 SetupScene(true); 60 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene);
187 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
188 UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; 61 UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
189 62
190 m_dtm.AddDynamicTextureData( 63 dtm.AddDynamicTextureData(
191 m_scene.RegionInfo.RegionID, 64 scene.RegionInfo.RegionID,
192 so.UUID, 65 so.UUID,
193 m_vrm.GetContentType(), 66 vrm.GetContentType(),
194 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;", 67 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;",
195 "", 68 "",
196 0); 69 0);
197 70
198 Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
199 }
200
201 [Test]
202 public void TestRepeatSameDrawReusingTexture()
203 {
204 TestHelpers.InMethod();
205// TestHelpers.EnableLogging();
206
207 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
208
209 SetupScene(true);
210 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
211
212 m_dtm.AddDynamicTextureData(
213 m_scene.RegionInfo.RegionID,
214 so.UUID,
215 m_vrm.GetContentType(),
216 dtText,
217 "",
218 0);
219
220 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
221
222 m_dtm.AddDynamicTextureData(
223 m_scene.RegionInfo.RegionID,
224 so.UUID,
225 m_vrm.GetContentType(),
226 dtText,
227 "",
228 0);
229
230 Assert.That(firstDynamicTextureID, Is.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
231 }
232
233 /// <summary>
234 /// Test a low data dynamically generated texture such that it is treated as a low data texture that causes
235 /// problems for current viewers.
236 /// </summary>
237 /// <remarks>
238 /// As we do not set DynamicTextureModule.ReuseLowDataTextures = true in this test, it should not reuse the
239 /// texture
240 /// </remarks>
241 [Test]
242 public void TestRepeatSameDrawLowDataTexture()
243 {
244 TestHelpers.InMethod();
245// TestHelpers.EnableLogging();
246
247 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
248
249 SetupScene(true);
250 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
251
252 m_dtm.AddDynamicTextureData(
253 m_scene.RegionInfo.RegionID,
254 so.UUID,
255 m_vrm.GetContentType(),
256 dtText,
257 "1024",
258 0);
259
260 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
261
262 m_dtm.AddDynamicTextureData(
263 m_scene.RegionInfo.RegionID,
264 so.UUID,
265 m_vrm.GetContentType(),
266 dtText,
267 "1024",
268 0);
269
270 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
271 }
272
273 [Test]
274 public void TestRepeatSameDrawDifferentExtraParamsReusingTexture()
275 {
276 TestHelpers.InMethod();
277
278 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
279
280 SetupScene(true);
281 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
282
283 m_dtm.AddDynamicTextureData(
284 m_scene.RegionInfo.RegionID,
285 so.UUID,
286 m_vrm.GetContentType(),
287 dtText,
288 "",
289 0);
290
291 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
292
293 m_dtm.AddDynamicTextureData(
294 m_scene.RegionInfo.RegionID,
295 so.UUID,
296 m_vrm.GetContentType(),
297 dtText,
298 "alpha:250",
299 0);
300
301 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
302 }
303
304 [Test]
305 public void TestRepeatSameDrawContainingImageReusingTexture()
306 {
307 TestHelpers.InMethod();
308
309 string dtText
310 = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png";
311
312 SetupScene(true);
313 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
314
315 m_dtm.AddDynamicTextureData(
316 m_scene.RegionInfo.RegionID,
317 so.UUID,
318 m_vrm.GetContentType(),
319 dtText,
320 "",
321 0);
322
323 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
324
325 m_dtm.AddDynamicTextureData(
326 m_scene.RegionInfo.RegionID,
327 so.UUID,
328 m_vrm.GetContentType(),
329 dtText,
330 "",
331 0);
332 71
333 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); 72 Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
334 } 73 }
335 } 74 }
336} \ No newline at end of file 75} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
index 673c2d1..8b2f2f8 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
@@ -30,12 +30,10 @@ using System.Drawing;
30using System.Drawing.Imaging; 30using System.Drawing.Imaging;
31using System.Globalization; 31using System.Globalization;
32using System.IO; 32using System.IO;
33using System.Linq;
34using System.Net; 33using System.Net;
35using Nini.Config; 34using Nini.Config;
36using OpenMetaverse; 35using OpenMetaverse;
37using OpenMetaverse.Imaging; 36using OpenMetaverse.Imaging;
38using OpenSim.Region.CoreModules.Scripting.DynamicTexture;
39using OpenSim.Region.Framework.Interfaces; 37using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes; 38using OpenSim.Region.Framework.Scenes;
41using log4net; 39using log4net;
@@ -47,13 +45,9 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
47{ 45{
48 public class VectorRenderModule : IRegionModule, IDynamicTextureRender 46 public class VectorRenderModule : IRegionModule, IDynamicTextureRender
49 { 47 {
50 // These fields exist for testing purposes, please do not remove.
51// private static bool s_flipper;
52// private static byte[] s_asset1Data;
53// private static byte[] s_asset2Data;
54
55 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56 49
50 private string m_name = "VectorRenderModule";
57 private Scene m_scene; 51 private Scene m_scene;
58 private IDynamicTextureManager m_textureManager; 52 private IDynamicTextureManager m_textureManager;
59 private Graphics m_graph; 53 private Graphics m_graph;
@@ -67,12 +61,12 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
67 61
68 public string GetContentType() 62 public string GetContentType()
69 { 63 {
70 return "vector"; 64 return ("vector");
71 } 65 }
72 66
73 public string GetName() 67 public string GetName()
74 { 68 {
75 return Name; 69 return m_name;
76 } 70 }
77 71
78 public bool SupportsAsynchronous() 72 public bool SupportsAsynchronous()
@@ -80,20 +74,14 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
80 return true; 74 return true;
81 } 75 }
82 76
83// public bool AlwaysIdenticalConversion(string bodyData, string extraParams) 77 public byte[] ConvertUrl(string url, string extraParams)
84// {
85// string[] lines = GetLines(bodyData);
86// return lines.Any((str, r) => str.StartsWith("Image"));
87// }
88
89 public IDynamicTexture ConvertUrl(string url, string extraParams)
90 { 78 {
91 return null; 79 return null;
92 } 80 }
93 81
94 public IDynamicTexture ConvertData(string bodyData, string extraParams) 82 public byte[] ConvertStream(Stream data, string extraParams)
95 { 83 {
96 return Draw(bodyData, extraParams); 84 return null;
97 } 85 }
98 86
99 public bool AsyncConvertUrl(UUID id, string url, string extraParams) 87 public bool AsyncConvertUrl(UUID id, string url, string extraParams)
@@ -103,28 +91,21 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
103 91
104 public bool AsyncConvertData(UUID id, string bodyData, string extraParams) 92 public bool AsyncConvertData(UUID id, string bodyData, string extraParams)
105 { 93 {
106 // XXX: This isn't actually being done asynchronously! 94 Draw(bodyData, id, extraParams);
107 m_textureManager.ReturnData(id, ConvertData(bodyData, extraParams));
108
109 return true; 95 return true;
110 } 96 }
111 97
112 public void GetDrawStringSize(string text, string fontName, int fontSize, 98 public void GetDrawStringSize(string text, string fontName, int fontSize,
113 out double xSize, out double ySize) 99 out double xSize, out double ySize)
114 { 100 {
115 lock (this) 101 using (Font myFont = new Font(fontName, fontSize))
116 { 102 {
117 using (Font myFont = new Font(fontName, fontSize)) 103 SizeF stringSize = new SizeF();
104 lock (m_graph)
118 { 105 {
119 SizeF stringSize = new SizeF(); 106 stringSize = m_graph.MeasureString(text, myFont);
120 107 xSize = stringSize.Width;
121 // XXX: This lock may be unnecessary. 108 ySize = stringSize.Height;
122 lock (m_graph)
123 {
124 stringSize = m_graph.MeasureString(text, myFont);
125 xSize = stringSize.Width;
126 ySize = stringSize.Height;
127 }
128 } 109 }
129 } 110 }
130 } 111 }
@@ -163,13 +144,6 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
163 { 144 {
164 m_textureManager.RegisterRender(GetContentType(), this); 145 m_textureManager.RegisterRender(GetContentType(), this);
165 } 146 }
166
167 // This code exists for testing purposes, please do not remove.
168// s_asset1Data = m_scene.AssetService.Get("00000000-0000-1111-9999-000000000001").Data;
169// s_asset1Data = m_scene.AssetService.Get("9f4acf0d-1841-4e15-bdb8-3a12efc9dd8f").Data;
170
171 // Terrain dirt - smallest bin/assets file (6004 bytes)
172// s_asset2Data = m_scene.AssetService.Get("b8d3965a-ad78-bf43-699b-bff8eca6c975").Data;
173 } 147 }
174 148
175 public void Close() 149 public void Close()
@@ -178,7 +152,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
178 152
179 public string Name 153 public string Name
180 { 154 {
181 get { return "VectorRenderModule"; } 155 get { return m_name; }
182 } 156 }
183 157
184 public bool IsSharedModule 158 public bool IsSharedModule
@@ -188,7 +162,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
188 162
189 #endregion 163 #endregion
190 164
191 private IDynamicTexture Draw(string data, string extraParams) 165 private void Draw(string data, UUID id, string extraParams)
192 { 166 {
193 // We need to cater for old scripts that didnt use extraParams neatly, they use either an integer size which represents both width and height, or setalpha 167 // We need to cater for old scripts that didnt use extraParams neatly, they use either an integer size which represents both width and height, or setalpha
194 // we will now support multiple comma seperated params in the form width:256,height:512,alpha:255 168 // we will now support multiple comma seperated params in the form width:256,height:512,alpha:255
@@ -331,57 +305,40 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
331 305
332 Bitmap bitmap = null; 306 Bitmap bitmap = null;
333 Graphics graph = null; 307 Graphics graph = null;
334 bool reuseable = false;
335 308
336 try 309 try
337 { 310 {
338 // XXX: In testing, it appears that if multiple threads dispose of separate GDI+ objects simultaneously, 311 if (alpha == 256)
339 // the native malloc heap can become corrupted, possibly due to a double free(). This may be due to 312 bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
340 // bugs in the underlying libcairo used by mono's libgdiplus.dll on Linux/OSX. These problems were 313 else
341 // seen with both libcario 1.10.2-6.1ubuntu3 and 1.8.10-2ubuntu1. They go away if disposal is perfomed 314 bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
342 // under lock. 315
343 lock (this) 316 graph = Graphics.FromImage(bitmap);
344 {
345 if (alpha == 256)
346 bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
347 else
348 bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
349 317
350 graph = Graphics.FromImage(bitmap); 318 // this is really just to save people filling the
351 319 // background color in their scripts, only do when fully opaque
352 // this is really just to save people filling the 320 if (alpha >= 255)
353 // background color in their scripts, only do when fully opaque 321 {
354 if (alpha >= 255) 322 using (SolidBrush bgFillBrush = new SolidBrush(bgColor))
355 { 323 {
356 using (SolidBrush bgFillBrush = new SolidBrush(bgColor)) 324 graph.FillRectangle(bgFillBrush, 0, 0, width, height);
357 {
358 graph.FillRectangle(bgFillBrush, 0, 0, width, height);
359 }
360 } 325 }
361 326 }
362 for (int w = 0; w < bitmap.Width; w++) 327
328 for (int w = 0; w < bitmap.Width; w++)
329 {
330 if (alpha <= 255)
363 { 331 {
364 if (alpha <= 255) 332 for (int h = 0; h < bitmap.Height; h++)
365 { 333 {
366 for (int h = 0; h < bitmap.Height; h++) 334 bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h)));
367 {
368 bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h)));
369 }
370 } 335 }
371 } 336 }
372
373 GDIDraw(data, graph, altDataDelim, out reuseable);
374 } 337 }
375 338
339 GDIDraw(data, graph, altDataDelim);
340
376 byte[] imageJ2000 = new byte[0]; 341 byte[] imageJ2000 = new byte[0];
377
378 // This code exists for testing purposes, please do not remove.
379// if (s_flipper)
380// imageJ2000 = s_asset1Data;
381// else
382// imageJ2000 = s_asset2Data;
383//
384// s_flipper = !s_flipper;
385 342
386 try 343 try
387 { 344 {
@@ -394,24 +351,15 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
394 e.Message, e.StackTrace); 351 e.Message, e.StackTrace);
395 } 352 }
396 353
397 return new OpenSim.Region.CoreModules.Scripting.DynamicTexture.DynamicTexture( 354 m_textureManager.ReturnData(id, imageJ2000);
398 data, extraParams, imageJ2000, new Size(width, height), reuseable);
399 } 355 }
400 finally 356 finally
401 { 357 {
402 // XXX: In testing, it appears that if multiple threads dispose of separate GDI+ objects simultaneously, 358 if (graph != null)
403 // the native malloc heap can become corrupted, possibly due to a double free(). This may be due to 359 graph.Dispose();
404 // bugs in the underlying libcairo used by mono's libgdiplus.dll on Linux/OSX. These problems were 360
405 // seen with both libcario 1.10.2-6.1ubuntu3 and 1.8.10-2ubuntu1. They go away if disposal is perfomed 361 if (bitmap != null)
406 // under lock. 362 bitmap.Dispose();
407 lock (this)
408 {
409 if (graph != null)
410 graph.Dispose();
411
412 if (bitmap != null)
413 bitmap.Dispose();
414 }
415 } 363 }
416 } 364 }
417 365
@@ -470,21 +418,8 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
470 } 418 }
471*/ 419*/
472 420
473 /// <summary> 421 private void GDIDraw(string data, Graphics graph, char dataDelim)
474 /// Split input data into discrete command lines.
475 /// </summary>
476 /// <returns></returns>
477 /// <param name='data'></param>
478 /// <param name='dataDelim'></param>
479 private string[] GetLines(string data, char dataDelim)
480 {
481 char[] lineDelimiter = { dataDelim };
482 return data.Split(lineDelimiter);
483 }
484
485 private void GDIDraw(string data, Graphics graph, char dataDelim, out bool reuseable)
486 { 422 {
487 reuseable = true;
488 Point startPoint = new Point(0, 0); 423 Point startPoint = new Point(0, 0);
489 Point endPoint = new Point(0, 0); 424 Point endPoint = new Point(0, 0);
490 Pen drawPen = null; 425 Pen drawPen = null;
@@ -499,9 +434,11 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
499 myFont = new Font(fontName, fontSize); 434 myFont = new Font(fontName, fontSize);
500 myBrush = new SolidBrush(Color.Black); 435 myBrush = new SolidBrush(Color.Black);
501 436
437 char[] lineDelimiter = {dataDelim};
502 char[] partsDelimiter = {','}; 438 char[] partsDelimiter = {','};
439 string[] lines = data.Split(lineDelimiter);
503 440
504 foreach (string line in GetLines(data, dataDelim)) 441 foreach (string line in lines)
505 { 442 {
506 string nextLine = line.Trim(); 443 string nextLine = line.Trim();
507 //replace with switch, or even better, do some proper parsing 444 //replace with switch, or even better, do some proper parsing
@@ -532,10 +469,6 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
532 } 469 }
533 else if (nextLine.StartsWith("Image")) 470 else if (nextLine.StartsWith("Image"))
534 { 471 {
535 // We cannot reuse any generated texture involving fetching an image via HTTP since that image
536 // can change.
537 reuseable = false;
538
539 float x = 0; 472 float x = 0;
540 float y = 0; 473 float y = 0;
541 GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y); 474 GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y);
diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
index e167e31..07bb291 100644
--- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs
@@ -28,7 +28,6 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Text.RegularExpressions;
32using Nini.Config; 31using Nini.Config;
33using OpenMetaverse; 32using OpenMetaverse;
34using OpenSim.Framework; 33using OpenSim.Framework;
@@ -173,42 +172,12 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
173 /// <param name="hostID">UUID of the SceneObjectPart</param> 172 /// <param name="hostID">UUID of the SceneObjectPart</param>
174 /// <param name="channel">channel to listen on</param> 173 /// <param name="channel">channel to listen on</param>
175 /// <param name="name">name to filter on</param> 174 /// <param name="name">name to filter on</param>
176 /// <param name="id"> 175 /// <param name="id">key to filter on (user given, could be totally faked)</param>
177 /// key to filter on (user given, could be totally faked)
178 /// </param>
179 /// <param name="msg">msg to filter on</param>
180 /// <returns>number of the scripts handle</returns>
181 public int Listen(uint localID, UUID itemID, UUID hostID, int channel,
182 string name, UUID id, string msg)
183 {
184 return m_listenerManager.AddListener(localID, itemID, hostID,
185 channel, name, id, msg);
186 }
187
188 /// <summary>
189 /// Create a listen event callback with the specified filters.
190 /// The parameters localID,itemID are needed to uniquely identify
191 /// the script during 'peek' time. Parameter hostID is needed to
192 /// determine the position of the script.
193 /// </summary>
194 /// <param name="localID">localID of the script engine</param>
195 /// <param name="itemID">UUID of the script engine</param>
196 /// <param name="hostID">UUID of the SceneObjectPart</param>
197 /// <param name="channel">channel to listen on</param>
198 /// <param name="name">name to filter on</param>
199 /// <param name="id">
200 /// key to filter on (user given, could be totally faked)
201 /// </param>
202 /// <param name="msg">msg to filter on</param> 176 /// <param name="msg">msg to filter on</param>
203 /// <param name="regexBitfield">
204 /// Bitfield indicating which strings should be processed as regex.
205 /// </param>
206 /// <returns>number of the scripts handle</returns> 177 /// <returns>number of the scripts handle</returns>
207 public int Listen(uint localID, UUID itemID, UUID hostID, int channel, 178 public int Listen(uint localID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg)
208 string name, UUID id, string msg, int regexBitfield)
209 { 179 {
210 return m_listenerManager.AddListener(localID, itemID, hostID, 180 return m_listenerManager.AddListener(localID, itemID, hostID, channel, name, id, msg);
211 channel, name, id, msg, regexBitfield);
212 } 181 }
213 182
214 /// <summary> 183 /// <summary>
@@ -357,7 +326,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
357 if (channel == 0) 326 if (channel == 0)
358 { 327 {
359 // Channel 0 goes to viewer ONLY 328 // Channel 0 goes to viewer ONLY
360 m_scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Broadcast, 0, pos, name, id, target, false, false); 329 m_scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Broadcast, 0, pos, name, id, false, false, target);
361 return true; 330 return true;
362 } 331 }
363 332
@@ -501,25 +470,15 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
501 m_curlisteners = 0; 470 m_curlisteners = 0;
502 } 471 }
503 472
504 public int AddListener(uint localID, UUID itemID, UUID hostID, 473 public int AddListener(uint localID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg)
505 int channel, string name, UUID id, string msg)
506 {
507 return AddListener(localID, itemID, hostID, channel, name, id,
508 msg, 0);
509 }
510
511 public int AddListener(uint localID, UUID itemID, UUID hostID,
512 int channel, string name, UUID id, string msg,
513 int regexBitfield)
514 { 474 {
515 // do we already have a match on this particular filter event? 475 // do we already have a match on this particular filter event?
516 List<ListenerInfo> coll = GetListeners(itemID, channel, name, id, 476 List<ListenerInfo> coll = GetListeners(itemID, channel, name, id, msg);
517 msg);
518 477
519 if (coll.Count > 0) 478 if (coll.Count > 0)
520 { 479 {
521 // special case, called with same filter settings, return same 480 // special case, called with same filter settings, return same handle
522 // handle (2008-05-02, tested on 1.21.1 server, still holds) 481 // (2008-05-02, tested on 1.21.1 server, still holds)
523 return coll[0].GetHandle(); 482 return coll[0].GetHandle();
524 } 483 }
525 484
@@ -531,9 +490,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
531 490
532 if (newHandle > 0) 491 if (newHandle > 0)
533 { 492 {
534 ListenerInfo li = new ListenerInfo(newHandle, localID, 493 ListenerInfo li = new ListenerInfo(newHandle, localID, itemID, hostID, channel, name, id, msg);
535 itemID, hostID, channel, name, id, msg,
536 regexBitfield);
537 494
538 List<ListenerInfo> listeners; 495 List<ListenerInfo> listeners;
539 if (!m_listeners.TryGetValue(channel,out listeners)) 496 if (!m_listeners.TryGetValue(channel,out listeners))
@@ -674,22 +631,6 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
674 return -1; 631 return -1;
675 } 632 }
676 633
677 /// These are duplicated from ScriptBaseClass
678 /// http://opensimulator.org/mantis/view.php?id=6106#c21945
679 #region Constants for the bitfield parameter of osListenRegex
680
681 /// <summary>
682 /// process name parameter as regex
683 /// </summary>
684 public const int OS_LISTEN_REGEX_NAME = 0x1;
685
686 /// <summary>
687 /// process message parameter as regex
688 /// </summary>
689 public const int OS_LISTEN_REGEX_MESSAGE = 0x2;
690
691 #endregion
692
693 // Theres probably a more clever and efficient way to 634 // Theres probably a more clever and efficient way to
694 // do this, maybe with regex. 635 // do this, maybe with regex.
695 // PM2008: Ha, one could even be smart and define a specialized Enumerator. 636 // PM2008: Ha, one could even be smart and define a specialized Enumerator.
@@ -715,10 +656,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
715 { 656 {
716 continue; 657 continue;
717 } 658 }
718 if (li.GetName().Length > 0 && ( 659 if (li.GetName().Length > 0 && !li.GetName().Equals(name))
719 ((li.RegexBitfield & OS_LISTEN_REGEX_NAME) != OS_LISTEN_REGEX_NAME && !li.GetName().Equals(name)) ||
720 ((li.RegexBitfield & OS_LISTEN_REGEX_NAME) == OS_LISTEN_REGEX_NAME && !Regex.IsMatch(name, li.GetName()))
721 ))
722 { 660 {
723 continue; 661 continue;
724 } 662 }
@@ -726,10 +664,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
726 { 664 {
727 continue; 665 continue;
728 } 666 }
729 if (li.GetMessage().Length > 0 && ( 667 if (li.GetMessage().Length > 0 && !li.GetMessage().Equals(msg))
730 ((li.RegexBitfield & OS_LISTEN_REGEX_MESSAGE) != OS_LISTEN_REGEX_MESSAGE && !li.GetMessage().Equals(msg)) ||
731 ((li.RegexBitfield & OS_LISTEN_REGEX_MESSAGE) == OS_LISTEN_REGEX_MESSAGE && !Regex.IsMatch(msg, li.GetMessage()))
732 ))
733 { 668 {
734 continue; 669 continue;
735 } 670 }
@@ -762,13 +697,10 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
762 { 697 {
763 int idx = 0; 698 int idx = 0;
764 Object[] item = new Object[6]; 699 Object[] item = new Object[6];
765 int dataItemLength = 6;
766 700
767 while (idx < data.Length) 701 while (idx < data.Length)
768 { 702 {
769 dataItemLength = (idx + 7 == data.Length || (idx + 7 < data.Length && data[idx + 7] is bool)) ? 7 : 6; 703 Array.Copy(data, idx, item, 0, 6);
770 item = new Object[dataItemLength];
771 Array.Copy(data, idx, item, 0, dataItemLength);
772 704
773 ListenerInfo info = 705 ListenerInfo info =
774 ListenerInfo.FromData(localID, itemID, hostID, item); 706 ListenerInfo.FromData(localID, itemID, hostID, item);
@@ -780,12 +712,12 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
780 m_listeners[(int)item[2]].Add(info); 712 m_listeners[(int)item[2]].Add(info);
781 } 713 }
782 714
783 idx+=dataItemLength; 715 idx+=6;
784 } 716 }
785 } 717 }
786 } 718 }
787 719
788 public class ListenerInfo : IWorldCommListenerInfo 720 public class ListenerInfo: IWorldCommListenerInfo
789 { 721 {
790 private bool m_active; // Listener is active or not 722 private bool m_active; // Listener is active or not
791 private int m_handle; // Assigned handle of this listener 723 private int m_handle; // Assigned handle of this listener
@@ -799,29 +731,16 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
799 731
800 public ListenerInfo(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, UUID id, string message) 732 public ListenerInfo(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, UUID id, string message)
801 { 733 {
802 Initialise(handle, localID, ItemID, hostID, channel, name, id, 734 Initialise(handle, localID, ItemID, hostID, channel, name, id, message);
803 message, 0);
804 }
805
806 public ListenerInfo(int handle, uint localID, UUID ItemID,
807 UUID hostID, int channel, string name, UUID id,
808 string message, int regexBitfield)
809 {
810 Initialise(handle, localID, ItemID, hostID, channel, name, id,
811 message, regexBitfield);
812 } 735 }
813 736
814 public ListenerInfo(ListenerInfo li, string name, UUID id, string message) 737 public ListenerInfo(ListenerInfo li, string name, UUID id, string message)
815 { 738 {
816 Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID, li.m_channel, name, id, message, 0); 739 Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID, li.m_channel, name, id, message);
817 }
818
819 public ListenerInfo(ListenerInfo li, string name, UUID id, string message, int regexBitfield)
820 {
821 Initialise(li.m_handle, li.m_localID, li.m_itemID, li.m_hostID, li.m_channel, name, id, message, regexBitfield);
822 } 740 }
823 741
824 private void Initialise(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name, UUID id, string message, int regexBitfield) 742 private void Initialise(int handle, uint localID, UUID ItemID, UUID hostID, int channel, string name,
743 UUID id, string message)
825 { 744 {
826 m_active = true; 745 m_active = true;
827 m_handle = handle; 746 m_handle = handle;
@@ -832,12 +751,11 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
832 m_name = name; 751 m_name = name;
833 m_id = id; 752 m_id = id;
834 m_message = message; 753 m_message = message;
835 RegexBitfield = regexBitfield;
836 } 754 }
837 755
838 public Object[] GetSerializationData() 756 public Object[] GetSerializationData()
839 { 757 {
840 Object[] data = new Object[7]; 758 Object[] data = new Object[6];
841 759
842 data[0] = m_active; 760 data[0] = m_active;
843 data[1] = m_handle; 761 data[1] = m_handle;
@@ -845,19 +763,16 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
845 data[3] = m_name; 763 data[3] = m_name;
846 data[4] = m_id; 764 data[4] = m_id;
847 data[5] = m_message; 765 data[5] = m_message;
848 data[6] = RegexBitfield;
849 766
850 return data; 767 return data;
851 } 768 }
852 769
853 public static ListenerInfo FromData(uint localID, UUID ItemID, UUID hostID, Object[] data) 770 public static ListenerInfo FromData(uint localID, UUID ItemID, UUID hostID, Object[] data)
854 { 771 {
855 ListenerInfo linfo = new ListenerInfo((int)data[1], localID, ItemID, hostID, (int)data[2], (string)data[3], (UUID)data[4], (string)data[5]); 772 ListenerInfo linfo = new ListenerInfo((int)data[1], localID,
856 linfo.m_active = (bool)data[0]; 773 ItemID, hostID, (int)data[2], (string)data[3],
857 if (data.Length >= 7) 774 (UUID)data[4], (string)data[5]);
858 { 775 linfo.m_active=(bool)data[0];
859 linfo.RegexBitfield = (int)data[6];
860 }
861 776
862 return linfo; 777 return linfo;
863 } 778 }
@@ -916,7 +831,5 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
916 { 831 {
917 return m_id; 832 return m_id;
918 } 833 }
919
920 public int RegexBitfield { get; private set; }
921 } 834 }
922} 835}