diff options
author | onefang | 2019-09-11 16:36:50 +1000 |
---|---|---|
committer | onefang | 2019-09-11 16:36:50 +1000 |
commit | 50cd1ffd32f69228e566f2b0b89f86ea0d9fe489 (patch) | |
tree | 52f2ab0c04f1a5d7d6ac5dc872981b4b156447e7 /OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |
parent | Renamed branch to SledjChisl. (diff) | |
parent | Bump to release flavour, build 0. (diff) | |
download | opensim-SC_OLD-50cd1ffd32f69228e566f2b0b89f86ea0d9fe489.zip opensim-SC_OLD-50cd1ffd32f69228e566f2b0b89f86ea0d9fe489.tar.gz opensim-SC_OLD-50cd1ffd32f69228e566f2b0b89f86ea0d9fe489.tar.bz2 opensim-SC_OLD-50cd1ffd32f69228e566f2b0b89f86ea0d9fe489.tar.xz |
Merge branch 'SledjChisl'
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs')
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 6280 |
1 files changed, 4061 insertions, 2219 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 1399880..ce2bfaf 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -28,6 +28,7 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Collections.Specialized; | ||
31 | using System.Diagnostics; | 32 | using System.Diagnostics; |
32 | using System.Drawing; | 33 | using System.Drawing; |
33 | using System.Drawing.Imaging; | 34 | using System.Drawing.Imaging; |
@@ -35,10 +36,12 @@ using System.Runtime.Remoting.Lifetime; | |||
35 | using System.Text; | 36 | using System.Text; |
36 | using System.Threading; | 37 | using System.Threading; |
37 | using System.Text.RegularExpressions; | 38 | using System.Text.RegularExpressions; |
39 | using System.Timers; | ||
38 | using Nini.Config; | 40 | using Nini.Config; |
39 | using log4net; | 41 | using log4net; |
40 | using OpenMetaverse; | 42 | using OpenMetaverse; |
41 | using OpenMetaverse.Assets; | 43 | using OpenMetaverse.Assets; |
44 | using OpenMetaverse.StructuredData; // LitJson is hidden on this | ||
42 | using OpenMetaverse.Packets; | 45 | using OpenMetaverse.Packets; |
43 | using OpenMetaverse.Rendering; | 46 | using OpenMetaverse.Rendering; |
44 | using OpenSim; | 47 | using OpenSim; |
@@ -49,6 +52,7 @@ using OpenSim.Region.CoreModules.World.Land; | |||
49 | using OpenSim.Region.CoreModules.World.Terrain; | 52 | using OpenSim.Region.CoreModules.World.Terrain; |
50 | using OpenSim.Region.Framework.Interfaces; | 53 | using OpenSim.Region.Framework.Interfaces; |
51 | using OpenSim.Region.Framework.Scenes; | 54 | using OpenSim.Region.Framework.Scenes; |
55 | using OpenSim.Region.Framework.Scenes.Serialization; | ||
52 | using OpenSim.Region.Framework.Scenes.Animation; | 56 | using OpenSim.Region.Framework.Scenes.Animation; |
53 | using OpenSim.Region.Framework.Scenes.Scripting; | 57 | using OpenSim.Region.Framework.Scenes.Scripting; |
54 | using OpenSim.Region.PhysicsModules.SharedBase; | 58 | using OpenSim.Region.PhysicsModules.SharedBase; |
@@ -72,6 +76,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; | |||
72 | using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; | 76 | using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; |
73 | using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; | 77 | using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; |
74 | using System.Reflection; | 78 | using System.Reflection; |
79 | using Timer = System.Timers.Timer; | ||
75 | using System.Linq; | 80 | using System.Linq; |
76 | using PermissionMask = OpenSim.Framework.PermissionMask; | 81 | using PermissionMask = OpenSim.Framework.PermissionMask; |
77 | 82 | ||
@@ -98,10 +103,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
98 | protected SceneObjectPart m_host; | 103 | protected SceneObjectPart m_host; |
99 | 104 | ||
100 | /// <summary> | 105 | /// <summary> |
101 | /// Used for script sleeps when we are using co-operative script termination. | ||
102 | /// </summary> | ||
103 | /// <remarks>null if co-operative script termination is not active</remarks> | ||
104 | /// <summary> | ||
105 | /// The item that hosts this script | 106 | /// The item that hosts this script |
106 | /// </summary> | 107 | /// </summary> |
107 | protected TaskInventoryItem m_item; | 108 | protected TaskInventoryItem m_item; |
@@ -112,14 +113,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
112 | protected float m_MinTimerInterval = 0.5f; | 113 | protected float m_MinTimerInterval = 0.5f; |
113 | protected float m_recoilScaleFactor = 0.0f; | 114 | protected float m_recoilScaleFactor = 0.0f; |
114 | 115 | ||
115 | protected DateTime m_timer = DateTime.Now; | 116 | protected double m_timer = Util.GetTimeStampMS(); |
116 | protected bool m_waitingForScriptAnswer = false; | 117 | protected bool m_waitingForScriptAnswer = false; |
117 | protected bool m_automaticLinkPermission = false; | 118 | protected bool m_automaticLinkPermission = false; |
118 | protected IMessageTransferModule m_TransferModule = null; | 119 | protected IMessageTransferModule m_TransferModule = null; |
119 | protected int m_notecardLineReadCharsMax = 255; | 120 | protected int m_notecardLineReadCharsMax = 255; |
120 | protected int m_scriptConsoleChannel = 0; | 121 | protected int m_scriptConsoleChannel = 0; |
121 | protected bool m_scriptConsoleChannelEnabled = false; | 122 | protected bool m_scriptConsoleChannelEnabled = false; |
123 | protected bool m_debuggerSafe = false; | ||
122 | protected IUrlModule m_UrlModule = null; | 124 | protected IUrlModule m_UrlModule = null; |
125 | |||
123 | protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); | 126 | protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); |
124 | protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. | 127 | protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. |
125 | protected string m_internalObjectHost = "lsl.opensim.local"; | 128 | protected string m_internalObjectHost = "lsl.opensim.local"; |
@@ -172,7 +175,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
172 | protected int m_maxHitsPerPrimInCastRay = 16; | 175 | protected int m_maxHitsPerPrimInCastRay = 16; |
173 | protected int m_maxHitsPerObjectInCastRay = 16; | 176 | protected int m_maxHitsPerObjectInCastRay = 16; |
174 | protected bool m_detectExitsInCastRay = false; | 177 | protected bool m_detectExitsInCastRay = false; |
175 | protected bool m_filterPartsInCastRay = false; | ||
176 | protected bool m_doAttachmentsInCastRay = false; | 178 | protected bool m_doAttachmentsInCastRay = false; |
177 | protected int m_msThrottleInCastRay = 200; | 179 | protected int m_msThrottleInCastRay = 200; |
178 | protected int m_msPerRegionInCastRay = 40; | 180 | protected int m_msPerRegionInCastRay = 40; |
@@ -183,6 +185,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
183 | protected bool m_useMeshCacheInCastRay = true; | 185 | protected bool m_useMeshCacheInCastRay = true; |
184 | protected static Dictionary<ulong, FacetedMesh> m_cachedMeshes = new Dictionary<ulong, FacetedMesh>(); | 186 | protected static Dictionary<ulong, FacetedMesh> m_cachedMeshes = new Dictionary<ulong, FacetedMesh>(); |
185 | 187 | ||
188 | // protected Timer m_ShoutSayTimer; | ||
189 | protected int m_SayShoutCount = 0; | ||
190 | DateTime m_lastSayShoutCheck; | ||
191 | |||
192 | private Dictionary<string, string> MovementAnimationsForLSL = | ||
193 | new Dictionary<string, string> { | ||
194 | {"CROUCH", "Crouching"}, | ||
195 | {"CROUCHWALK", "CrouchWalking"}, | ||
196 | {"FALLDOWN", "Falling Down"}, | ||
197 | {"FLY", "Flying"}, | ||
198 | {"FLYSLOW", "FlyingSlow"}, | ||
199 | {"HOVER", "Hovering"}, | ||
200 | {"HOVER_UP", "Hovering Up"}, | ||
201 | {"HOVER_DOWN", "Hovering Down"}, | ||
202 | {"JUMP", "Jumping"}, | ||
203 | {"LAND", "Landing"}, | ||
204 | {"PREJUMP", "PreJumping"}, | ||
205 | {"RUN", "Running"}, | ||
206 | {"SIT","Sitting"}, | ||
207 | {"SITGROUND","Sitting on Ground"}, | ||
208 | {"STAND", "Standing"}, | ||
209 | {"STANDUP", "Standing Up"}, | ||
210 | {"STRIDE","Striding"}, | ||
211 | {"SOFT_LAND", "Soft Landing"}, | ||
212 | {"TURNLEFT", "Turning Left"}, | ||
213 | {"TURNRIGHT", "Turning Right"}, | ||
214 | {"WALK", "Walking"} | ||
215 | }; | ||
216 | |||
186 | //An array of HTTP/1.1 headers that are not allowed to be used | 217 | //An array of HTTP/1.1 headers that are not allowed to be used |
187 | //as custom headers by llHTTPRequest. | 218 | //as custom headers by llHTTPRequest. |
188 | private string[] HttpStandardHeaders = | 219 | private string[] HttpStandardHeaders = |
@@ -203,9 +234,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
203 | public void Initialize( | 234 | public void Initialize( |
204 | IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item) | 235 | IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item) |
205 | { | 236 | { |
237 | m_lastSayShoutCheck = DateTime.UtcNow; | ||
238 | |||
206 | m_ScriptEngine = scriptEngine; | 239 | m_ScriptEngine = scriptEngine; |
207 | m_host = host; | 240 | m_host = host; |
208 | m_item = item; | 241 | m_item = item; |
242 | m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false); | ||
209 | 243 | ||
210 | LoadConfig(); | 244 | LoadConfig(); |
211 | 245 | ||
@@ -228,8 +262,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
228 | 262 | ||
229 | if (seConfig != null) | 263 | if (seConfig != null) |
230 | { | 264 | { |
231 | m_ScriptDistanceFactor = | ||
232 | seConfig.GetFloat("ScriptDistanceLimitFactor", m_ScriptDistanceFactor); | ||
233 | m_MinTimerInterval = | 265 | m_MinTimerInterval = |
234 | seConfig.GetFloat("MinTimerInterval", m_MinTimerInterval); | 266 | seConfig.GetFloat("MinTimerInterval", m_MinTimerInterval); |
235 | m_automaticLinkPermission = | 267 | m_automaticLinkPermission = |
@@ -296,7 +328,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
296 | m_maxHitsPerPrimInCastRay = lslConfig.GetInt("MaxHitsPerPrimInLlCastRay", m_maxHitsPerPrimInCastRay); | 328 | m_maxHitsPerPrimInCastRay = lslConfig.GetInt("MaxHitsPerPrimInLlCastRay", m_maxHitsPerPrimInCastRay); |
297 | m_maxHitsPerObjectInCastRay = lslConfig.GetInt("MaxHitsPerObjectInLlCastRay", m_maxHitsPerObjectInCastRay); | 329 | m_maxHitsPerObjectInCastRay = lslConfig.GetInt("MaxHitsPerObjectInLlCastRay", m_maxHitsPerObjectInCastRay); |
298 | m_detectExitsInCastRay = lslConfig.GetBoolean("DetectExitHitsInLlCastRay", m_detectExitsInCastRay); | 330 | m_detectExitsInCastRay = lslConfig.GetBoolean("DetectExitHitsInLlCastRay", m_detectExitsInCastRay); |
299 | m_filterPartsInCastRay = lslConfig.GetBoolean("FilterPartsInLlCastRay", m_filterPartsInCastRay); | ||
300 | m_doAttachmentsInCastRay = lslConfig.GetBoolean("DoAttachmentsInLlCastRay", m_doAttachmentsInCastRay); | 331 | m_doAttachmentsInCastRay = lslConfig.GetBoolean("DoAttachmentsInLlCastRay", m_doAttachmentsInCastRay); |
301 | m_msThrottleInCastRay = lslConfig.GetInt("ThrottleTimeInMsInLlCastRay", m_msThrottleInCastRay); | 332 | m_msThrottleInCastRay = lslConfig.GetInt("ThrottleTimeInMsInLlCastRay", m_msThrottleInCastRay); |
302 | m_msPerRegionInCastRay = lslConfig.GetInt("AvailableTimeInMsPerRegionInLlCastRay", m_msPerRegionInCastRay); | 333 | m_msPerRegionInCastRay = lslConfig.GetInt("AvailableTimeInMsPerRegionInLlCastRay", m_msPerRegionInCastRay); |
@@ -307,7 +338,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
307 | } | 338 | } |
308 | 339 | ||
309 | IConfig smtpConfig = seConfigSource.Configs["SMTP"]; | 340 | IConfig smtpConfig = seConfigSource.Configs["SMTP"]; |
310 | if (smtpConfig != null) | 341 | if (smtpConfig != null) |
311 | { | 342 | { |
312 | // there's an smtp config, so load in the snooze time. | 343 | // there's an smtp config, so load in the snooze time. |
313 | EMAIL_PAUSE_TIME = smtpConfig.GetInt("email_pause_time", EMAIL_PAUSE_TIME); | 344 | EMAIL_PAUSE_TIME = smtpConfig.GetInt("email_pause_time", EMAIL_PAUSE_TIME); |
@@ -315,6 +346,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
315 | m_internalObjectHost = smtpConfig.GetString("internal_object_host", m_internalObjectHost); | 346 | m_internalObjectHost = smtpConfig.GetString("internal_object_host", m_internalObjectHost); |
316 | } | 347 | } |
317 | } | 348 | } |
349 | //// m_sleepMsOnEmail = EMAIL_PAUSE_TIME * 1000; | ||
318 | } | 350 | } |
319 | 351 | ||
320 | public override Object InitializeLifetimeService() | 352 | public override Object InitializeLifetimeService() |
@@ -330,6 +362,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
330 | return lease; | 362 | return lease; |
331 | } | 363 | } |
332 | 364 | ||
365 | protected SceneObjectPart MonitoringObject() | ||
366 | { | ||
367 | UUID m = m_host.ParentGroup.MonitoringObject; | ||
368 | if (m == UUID.Zero) | ||
369 | return null; | ||
370 | |||
371 | SceneObjectPart p = m_ScriptEngine.World.GetSceneObjectPart(m); | ||
372 | if (p == null) | ||
373 | m_host.ParentGroup.MonitoringObject = UUID.Zero; | ||
374 | |||
375 | return p; | ||
376 | } | ||
377 | |||
333 | protected virtual void Sleep(int delay) | 378 | protected virtual void Sleep(int delay) |
334 | { | 379 | { |
335 | if (m_item == null) // Some unit tests don't set this | 380 | if (m_item == null) // Some unit tests don't set this |
@@ -351,6 +396,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
351 | get { return m_ScriptEngine.World; } | 396 | get { return m_ScriptEngine.World; } |
352 | } | 397 | } |
353 | 398 | ||
399 | [DebuggerNonUserCode] | ||
354 | public void state(string newState) | 400 | public void state(string newState) |
355 | { | 401 | { |
356 | m_ScriptEngine.SetState(m_item.ItemID, newState); | 402 | m_ScriptEngine.SetState(m_item.ItemID, newState); |
@@ -360,10 +406,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
360 | /// Reset the named script. The script must be present | 406 | /// Reset the named script. The script must be present |
361 | /// in the same prim. | 407 | /// in the same prim. |
362 | /// </summary> | 408 | /// </summary> |
409 | [DebuggerNonUserCode] | ||
363 | public void llResetScript() | 410 | public void llResetScript() |
364 | { | 411 | { |
365 | m_host.AddScriptLPS(1); | ||
366 | |||
367 | // We need to tell the URL module, if we hav one, to release | 412 | // We need to tell the URL module, if we hav one, to release |
368 | // the allocated URLs | 413 | // the allocated URLs |
369 | if (m_UrlModule != null) | 414 | if (m_UrlModule != null) |
@@ -376,20 +421,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
376 | { | 421 | { |
377 | UUID item; | 422 | UUID item; |
378 | 423 | ||
379 | m_host.AddScriptLPS(1); | 424 | if ((item = GetScriptByName(name)) == UUID.Zero) |
380 | 425 | { | |
381 | if ((item = GetScriptByName(name)) != UUID.Zero) | ||
382 | m_ScriptEngine.ResetScript(item); | ||
383 | else | ||
384 | Error("llResetOtherScript", "Can't find script '" + name + "'"); | 426 | Error("llResetOtherScript", "Can't find script '" + name + "'"); |
427 | return; | ||
428 | } | ||
429 | if(item == m_item.ItemID) | ||
430 | llResetScript(); | ||
431 | else | ||
432 | { | ||
433 | m_ScriptEngine.ResetScript(item); | ||
434 | } | ||
385 | } | 435 | } |
386 | 436 | ||
387 | public LSL_Integer llGetScriptState(string name) | 437 | public LSL_Integer llGetScriptState(string name) |
388 | { | 438 | { |
389 | UUID item; | 439 | UUID item; |
390 | 440 | ||
391 | m_host.AddScriptLPS(1); | ||
392 | |||
393 | if ((item = GetScriptByName(name)) != UUID.Zero) | 441 | if ((item = GetScriptByName(name)) != UUID.Zero) |
394 | { | 442 | { |
395 | return m_ScriptEngine.GetScriptState(item) ?1:0; | 443 | return m_ScriptEngine.GetScriptState(item) ?1:0; |
@@ -407,14 +455,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
407 | { | 455 | { |
408 | UUID item; | 456 | UUID item; |
409 | 457 | ||
410 | m_host.AddScriptLPS(1); | ||
411 | |||
412 | // These functions are supposed to be robust, | 458 | // These functions are supposed to be robust, |
413 | // so get the state one step at a time. | 459 | // so get the state one step at a time. |
414 | 460 | ||
415 | if ((item = GetScriptByName(name)) != UUID.Zero) | 461 | if ((item = GetScriptByName(name)) != UUID.Zero) |
416 | { | 462 | { |
417 | m_ScriptEngine.SetScriptState(item, run == 0 ? false : true); | 463 | m_ScriptEngine.SetScriptState(item, run == 0 ? false : true, item == m_item.ItemID); |
418 | } | 464 | } |
419 | else | 465 | else |
420 | { | 466 | { |
@@ -422,6 +468,58 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
422 | } | 468 | } |
423 | } | 469 | } |
424 | 470 | ||
471 | public List<ScenePresence> GetLinkAvatars(int linkType) | ||
472 | { | ||
473 | List<ScenePresence> ret = new List<ScenePresence>(); | ||
474 | if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted) | ||
475 | return ret; | ||
476 | |||
477 | // List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars(); | ||
478 | // this needs check | ||
479 | List<ScenePresence> avs = m_host.ParentGroup.GetSittingAvatars(); | ||
480 | switch (linkType) | ||
481 | { | ||
482 | case ScriptBaseClass.LINK_SET: | ||
483 | return avs; | ||
484 | |||
485 | case ScriptBaseClass.LINK_ROOT: | ||
486 | return ret; | ||
487 | |||
488 | case ScriptBaseClass.LINK_ALL_OTHERS: | ||
489 | return avs; | ||
490 | |||
491 | case ScriptBaseClass.LINK_ALL_CHILDREN: | ||
492 | return avs; | ||
493 | |||
494 | case ScriptBaseClass.LINK_THIS: | ||
495 | return ret; | ||
496 | |||
497 | default: | ||
498 | if (linkType < 0) | ||
499 | return ret; | ||
500 | |||
501 | int partCount = m_host.ParentGroup.GetPartCount(); | ||
502 | |||
503 | if (linkType <= partCount) | ||
504 | { | ||
505 | return ret; | ||
506 | } | ||
507 | else | ||
508 | { | ||
509 | linkType = linkType - partCount; | ||
510 | if (linkType > avs.Count) | ||
511 | { | ||
512 | return ret; | ||
513 | } | ||
514 | else | ||
515 | { | ||
516 | ret.Add(avs[linkType-1]); | ||
517 | return ret; | ||
518 | } | ||
519 | } | ||
520 | } | ||
521 | } | ||
522 | |||
425 | /// <summary> | 523 | /// <summary> |
426 | /// Get a given link entity from a linkset (linked objects and any sitting avatars). | 524 | /// Get a given link entity from a linkset (linked objects and any sitting avatars). |
427 | /// </summary> | 525 | /// </summary> |
@@ -501,7 +599,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
501 | public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) | 599 | public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) |
502 | { | 600 | { |
503 | List<SceneObjectPart> ret = new List<SceneObjectPart>(); | 601 | List<SceneObjectPart> ret = new List<SceneObjectPart>(); |
504 | ret.Add(part); | 602 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) |
603 | return ret; | ||
505 | 604 | ||
506 | switch (linkType) | 605 | switch (linkType) |
507 | { | 606 | { |
@@ -509,7 +608,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
509 | return new List<SceneObjectPart>(part.ParentGroup.Parts); | 608 | return new List<SceneObjectPart>(part.ParentGroup.Parts); |
510 | 609 | ||
511 | case ScriptBaseClass.LINK_ROOT: | 610 | case ScriptBaseClass.LINK_ROOT: |
512 | ret = new List<SceneObjectPart>(); | ||
513 | ret.Add(part.ParentGroup.RootPart); | 611 | ret.Add(part.ParentGroup.RootPart); |
514 | return ret; | 612 | return ret; |
515 | 613 | ||
@@ -529,16 +627,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
529 | return ret; | 627 | return ret; |
530 | 628 | ||
531 | case ScriptBaseClass.LINK_THIS: | 629 | case ScriptBaseClass.LINK_THIS: |
630 | ret.Add(part); | ||
532 | return ret; | 631 | return ret; |
533 | 632 | ||
534 | default: | 633 | default: |
535 | if (linkType < 0) | 634 | if (linkType < 0) |
536 | return new List<SceneObjectPart>(); | 635 | return ret; |
537 | 636 | ||
538 | SceneObjectPart target = part.ParentGroup.GetLinkNumPart(linkType); | 637 | SceneObjectPart target = part.ParentGroup.GetLinkNumPart(linkType); |
539 | if (target == null) | 638 | if (target == null) |
540 | return new List<SceneObjectPart>(); | 639 | return ret; |
541 | ret = new List<SceneObjectPart>(); | ||
542 | ret.Add(target); | 640 | ret.Add(target); |
543 | return ret; | 641 | return ret; |
544 | } | 642 | } |
@@ -595,44 +693,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
595 | //These are the implementations of the various ll-functions used by the LSL scripts. | 693 | //These are the implementations of the various ll-functions used by the LSL scripts. |
596 | public LSL_Float llSin(double f) | 694 | public LSL_Float llSin(double f) |
597 | { | 695 | { |
598 | m_host.AddScriptLPS(1); | ||
599 | return (double)Math.Sin(f); | 696 | return (double)Math.Sin(f); |
600 | } | 697 | } |
601 | 698 | ||
602 | public LSL_Float llCos(double f) | 699 | public LSL_Float llCos(double f) |
603 | { | 700 | { |
604 | m_host.AddScriptLPS(1); | ||
605 | return (double)Math.Cos(f); | 701 | return (double)Math.Cos(f); |
606 | } | 702 | } |
607 | 703 | ||
608 | public LSL_Float llTan(double f) | 704 | public LSL_Float llTan(double f) |
609 | { | 705 | { |
610 | m_host.AddScriptLPS(1); | ||
611 | return (double)Math.Tan(f); | 706 | return (double)Math.Tan(f); |
612 | } | 707 | } |
613 | 708 | ||
614 | public LSL_Float llAtan2(double x, double y) | 709 | public LSL_Float llAtan2(double x, double y) |
615 | { | 710 | { |
616 | m_host.AddScriptLPS(1); | ||
617 | return (double)Math.Atan2(x, y); | 711 | return (double)Math.Atan2(x, y); |
618 | } | 712 | } |
619 | 713 | ||
620 | public LSL_Float llSqrt(double f) | 714 | public LSL_Float llSqrt(double f) |
621 | { | 715 | { |
622 | m_host.AddScriptLPS(1); | ||
623 | return (double)Math.Sqrt(f); | 716 | return (double)Math.Sqrt(f); |
624 | } | 717 | } |
625 | 718 | ||
626 | public LSL_Float llPow(double fbase, double fexponent) | 719 | public LSL_Float llPow(double fbase, double fexponent) |
627 | { | 720 | { |
628 | m_host.AddScriptLPS(1); | ||
629 | return (double)Math.Pow(fbase, fexponent); | 721 | return (double)Math.Pow(fbase, fexponent); |
630 | } | 722 | } |
631 | 723 | ||
632 | public LSL_Integer llAbs(int i) | 724 | public LSL_Integer llAbs(int i) |
633 | { | 725 | { |
634 | // changed to replicate LSL behaviour whereby minimum int value is returned untouched. | 726 | // changed to replicate LSL behaviour whereby minimum int value is returned untouched. |
635 | m_host.AddScriptLPS(1); | ||
636 | if (i == Int32.MinValue) | 727 | if (i == Int32.MinValue) |
637 | return i; | 728 | return i; |
638 | else | 729 | else |
@@ -641,46 +732,41 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
641 | 732 | ||
642 | public LSL_Float llFabs(double f) | 733 | public LSL_Float llFabs(double f) |
643 | { | 734 | { |
644 | m_host.AddScriptLPS(1); | ||
645 | return (double)Math.Abs(f); | 735 | return (double)Math.Abs(f); |
646 | } | 736 | } |
647 | 737 | ||
648 | public LSL_Float llFrand(double mag) | 738 | public LSL_Float llFrand(double mag) |
649 | { | 739 | { |
650 | m_host.AddScriptLPS(1); | 740 | lock (Util.RandomClass) |
651 | 741 | { | |
652 | return Util.RandomClass.NextDouble() * mag; | 742 | return Util.RandomClass.NextDouble() * mag; |
743 | } | ||
653 | } | 744 | } |
654 | 745 | ||
655 | public LSL_Integer llFloor(double f) | 746 | public LSL_Integer llFloor(double f) |
656 | { | 747 | { |
657 | m_host.AddScriptLPS(1); | ||
658 | return (int)Math.Floor(f); | 748 | return (int)Math.Floor(f); |
659 | } | 749 | } |
660 | 750 | ||
661 | public LSL_Integer llCeil(double f) | 751 | public LSL_Integer llCeil(double f) |
662 | { | 752 | { |
663 | m_host.AddScriptLPS(1); | ||
664 | return (int)Math.Ceiling(f); | 753 | return (int)Math.Ceiling(f); |
665 | } | 754 | } |
666 | 755 | ||
667 | // Xantor 01/May/2008 fixed midpointrounding (2.5 becomes 3.0 instead of 2.0, default = ToEven) | 756 | // Xantor 01/May/2008 fixed midpointrounding (2.5 becomes 3.0 instead of 2.0, default = ToEven) |
668 | public LSL_Integer llRound(double f) | 757 | public LSL_Integer llRound(double f) |
669 | { | 758 | { |
670 | m_host.AddScriptLPS(1); | ||
671 | return (int)Math.Round(f, MidpointRounding.AwayFromZero); | 759 | return (int)Math.Round(f, MidpointRounding.AwayFromZero); |
672 | } | 760 | } |
673 | 761 | ||
674 | //This next group are vector operations involving squaring and square root. ckrinke | 762 | //This next group are vector operations involving squaring and square root. ckrinke |
675 | public LSL_Float llVecMag(LSL_Vector v) | 763 | public LSL_Float llVecMag(LSL_Vector v) |
676 | { | 764 | { |
677 | m_host.AddScriptLPS(1); | ||
678 | return LSL_Vector.Mag(v); | 765 | return LSL_Vector.Mag(v); |
679 | } | 766 | } |
680 | 767 | ||
681 | public LSL_Vector llVecNorm(LSL_Vector v) | 768 | public LSL_Vector llVecNorm(LSL_Vector v) |
682 | { | 769 | { |
683 | m_host.AddScriptLPS(1); | ||
684 | return LSL_Vector.Norm(v); | 770 | return LSL_Vector.Norm(v); |
685 | } | 771 | } |
686 | 772 | ||
@@ -694,37 +780,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
694 | 780 | ||
695 | public LSL_Float llVecDist(LSL_Vector a, LSL_Vector b) | 781 | public LSL_Float llVecDist(LSL_Vector a, LSL_Vector b) |
696 | { | 782 | { |
697 | m_host.AddScriptLPS(1); | ||
698 | return VecDist(a, b); | 783 | return VecDist(a, b); |
699 | } | 784 | } |
700 | 785 | ||
701 | //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke | 786 | //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke |
702 | 787 | ||
703 | /// <summary> | 788 | // Utility function for llRot2Euler |
704 | /// Convert an LSL rotation to a Euler vector. | ||
705 | /// </summary> | ||
706 | /// <remarks> | ||
707 | /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf | ||
708 | /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2 | ||
709 | /// </remarks> | ||
710 | /// <param name="r"></param> | ||
711 | /// <returns></returns> | ||
712 | public LSL_Vector llRot2Euler(LSL_Rotation r) | ||
713 | { | ||
714 | m_host.AddScriptLPS(1); | ||
715 | 789 | ||
716 | LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. | 790 | public LSL_Vector llRot2Euler(LSL_Rotation q1) |
717 | double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. | 791 | { |
718 | if (m == 0.0) return new LSL_Vector(); | 792 | LSL_Vector eul = new LSL_Vector(); |
719 | double x = Math.Atan2(-v.y, v.z); | ||
720 | double sin = v.x / m; | ||
721 | if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. | ||
722 | double y = Math.Asin(sin); | ||
723 | // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation | ||
724 | v = new LSL_Vector(1.0, 0.0, 0.0) * ((r * new LSL_Rotation(Math.Sin(-x / 2.0), 0.0, 0.0, Math.Cos(-x / 2.0))) * new LSL_Rotation(0.0, Math.Sin(-y / 2.0), 0.0, Math.Cos(-y / 2.0))); | ||
725 | double z = Math.Atan2(v.y, v.x); | ||
726 | 793 | ||
727 | return new LSL_Vector(x, y, z); | 794 | double sqw = q1.s*q1.s; |
795 | double sqx = q1.x*q1.x; | ||
796 | double sqy = q1.z*q1.z; | ||
797 | double sqz = q1.y*q1.y; | ||
798 | double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor | ||
799 | double test = q1.x*q1.z + q1.y*q1.s; | ||
800 | if (test > 0.4999*unit) { // singularity at north pole | ||
801 | eul.z = 2 * Math.Atan2(q1.x,q1.s); | ||
802 | eul.y = Math.PI/2; | ||
803 | eul.x = 0; | ||
804 | return eul; | ||
805 | } | ||
806 | if (test < -0.4999*unit) { // singularity at south pole | ||
807 | eul.z = -2 * Math.Atan2(q1.x,q1.s); | ||
808 | eul.y = -Math.PI/2; | ||
809 | eul.x = 0; | ||
810 | return eul; | ||
811 | } | ||
812 | eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw); | ||
813 | eul.y = Math.Asin(2*test/unit); | ||
814 | eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw); | ||
815 | return eul; | ||
728 | } | 816 | } |
729 | 817 | ||
730 | /* From wiki: | 818 | /* From wiki: |
@@ -774,28 +862,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
774 | 862 | ||
775 | public LSL_Rotation llEuler2Rot(LSL_Vector v) | 863 | public LSL_Rotation llEuler2Rot(LSL_Vector v) |
776 | { | 864 | { |
777 | m_host.AddScriptLPS(1); | ||
778 | |||
779 | double x,y,z,s; | 865 | double x,y,z,s; |
780 | 866 | v.x *= 0.5; | |
781 | double c1 = Math.Cos(v.x * 0.5); | 867 | v.y *= 0.5; |
782 | double c2 = Math.Cos(v.y * 0.5); | 868 | v.z *= 0.5; |
783 | double c3 = Math.Cos(v.z * 0.5); | 869 | double c1 = Math.Cos(v.x); |
784 | double s1 = Math.Sin(v.x * 0.5); | 870 | double c2 = Math.Cos(v.y); |
785 | double s2 = Math.Sin(v.y * 0.5); | 871 | double c1c2 = c1 * c2; |
786 | double s3 = Math.Sin(v.z * 0.5); | 872 | double s1 = Math.Sin(v.x); |
787 | 873 | double s2 = Math.Sin(v.y); | |
788 | x = s1 * c2 * c3 + c1 * s2 * s3; | 874 | double s1s2 = s1 * s2; |
789 | y = c1 * s2 * c3 - s1 * c2 * s3; | 875 | double c1s2 = c1 * s2; |
790 | z = s1 * s2 * c3 + c1 * c2 * s3; | 876 | double s1c2 = s1 * c2; |
791 | s = c1 * c2 * c3 - s1 * s2 * s3; | 877 | double c3 = Math.Cos(v.z); |
878 | double s3 = Math.Sin(v.z); | ||
879 | |||
880 | x = s1c2 * c3 + c1s2 * s3; | ||
881 | y = c1s2 * c3 - s1c2 * s3; | ||
882 | z = s1s2 * c3 + c1c2 * s3; | ||
883 | s = c1c2 * c3 - s1s2 * s3; | ||
792 | 884 | ||
793 | return new LSL_Rotation(x, y, z, s); | 885 | return new LSL_Rotation(x, y, z, s); |
794 | } | 886 | } |
795 | 887 | ||
796 | public LSL_Rotation llAxes2Rot(LSL_Vector fwd, LSL_Vector left, LSL_Vector up) | 888 | public LSL_Rotation llAxes2Rot(LSL_Vector fwd, LSL_Vector left, LSL_Vector up) |
797 | { | 889 | { |
798 | m_host.AddScriptLPS(1); | ||
799 | double s; | 890 | double s; |
800 | double tr = fwd.x + left.y + up.z + 1.0; | 891 | double tr = fwd.x + left.y + up.z + 1.0; |
801 | 892 | ||
@@ -850,8 +941,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
850 | 941 | ||
851 | public LSL_Vector llRot2Fwd(LSL_Rotation r) | 942 | public LSL_Vector llRot2Fwd(LSL_Rotation r) |
852 | { | 943 | { |
853 | m_host.AddScriptLPS(1); | ||
854 | |||
855 | double x, y, z, m; | 944 | double x, y, z, m; |
856 | 945 | ||
857 | m = r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s; | 946 | m = r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s; |
@@ -875,8 +964,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
875 | 964 | ||
876 | public LSL_Vector llRot2Left(LSL_Rotation r) | 965 | public LSL_Vector llRot2Left(LSL_Rotation r) |
877 | { | 966 | { |
878 | m_host.AddScriptLPS(1); | ||
879 | |||
880 | double x, y, z, m; | 967 | double x, y, z, m; |
881 | 968 | ||
882 | m = r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s; | 969 | m = r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s; |
@@ -900,7 +987,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
900 | 987 | ||
901 | public LSL_Vector llRot2Up(LSL_Rotation r) | 988 | public LSL_Vector llRot2Up(LSL_Rotation r) |
902 | { | 989 | { |
903 | m_host.AddScriptLPS(1); | ||
904 | double x, y, z, m; | 990 | double x, y, z, m; |
905 | 991 | ||
906 | m = r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s; | 992 | m = r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s; |
@@ -925,82 +1011,78 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
925 | public LSL_Rotation llRotBetween(LSL_Vector a, LSL_Vector b) | 1011 | public LSL_Rotation llRotBetween(LSL_Vector a, LSL_Vector b) |
926 | { | 1012 | { |
927 | //A and B should both be normalized | 1013 | //A and B should both be normalized |
928 | m_host.AddScriptLPS(1); | 1014 | /* This method is more accurate than the SL one, and thus causes problems |
929 | LSL_Rotation rotBetween; | 1015 | for scripts that deal with the SL inaccuracy around 180-degrees -.- .._. |
930 | // Check for zero vectors. If either is zero, return zero rotation. Otherwise, | 1016 | |
931 | // continue calculation. | 1017 | double dotProduct = LSL_Vector.Dot(a, b); |
932 | if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) | 1018 | LSL_Vector crossProduct = LSL_Vector.Cross(a, b); |
1019 | double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b); | ||
1020 | double angle = Math.Acos(dotProduct / magProduct); | ||
1021 | LSL_Vector axis = LSL_Vector.Norm(crossProduct); | ||
1022 | double s = Math.Sin(angle / 2); | ||
1023 | |||
1024 | double x = axis.x * s; | ||
1025 | double y = axis.y * s; | ||
1026 | double z = axis.z * s; | ||
1027 | double w = Math.Cos(angle / 2); | ||
1028 | |||
1029 | if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w)) | ||
1030 | return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); | ||
1031 | |||
1032 | return new LSL_Rotation((float)x, (float)y, (float)z, (float)w); | ||
1033 | */ | ||
1034 | |||
1035 | // This method mimics the 180 errors found in SL | ||
1036 | // See www.euclideanspace.com... angleBetween | ||
1037 | LSL_Vector vec_a = a; | ||
1038 | LSL_Vector vec_b = b; | ||
1039 | |||
1040 | // Eliminate zero length | ||
1041 | LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a); | ||
1042 | LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b); | ||
1043 | if (vec_a_mag < 0.00001 || | ||
1044 | vec_b_mag < 0.00001) | ||
933 | { | 1045 | { |
934 | rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); | 1046 | return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); |
935 | } | 1047 | } |
936 | else | 1048 | |
1049 | // Normalize | ||
1050 | vec_a = llVecNorm(vec_a); | ||
1051 | vec_b = llVecNorm(vec_b); | ||
1052 | |||
1053 | // Calculate axis and rotation angle | ||
1054 | LSL_Vector axis = vec_a % vec_b; | ||
1055 | LSL_Float cos_theta = vec_a * vec_b; | ||
1056 | |||
1057 | // Check if parallel | ||
1058 | if (cos_theta > 0.99999) | ||
937 | { | 1059 | { |
938 | a = LSL_Vector.Norm(a); | 1060 | return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); |
939 | b = LSL_Vector.Norm(b); | 1061 | } |
940 | double dotProduct = LSL_Vector.Dot(a, b); | 1062 | |
941 | // There are two degenerate cases possible. These are for vectors 180 or | 1063 | // Check if anti-parallel |
942 | // 0 degrees apart. These have to be detected and handled individually. | 1064 | else if (cos_theta < -0.99999) |
943 | // | 1065 | { |
944 | // Check for vectors 180 degrees apart. | 1066 | LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a); |
945 | // A dot product of -1 would mean the angle between vectors is 180 degrees. | 1067 | if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0); |
946 | if (dotProduct < -0.9999999f) | 1068 | return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0); |
947 | { | 1069 | } |
948 | // First assume X axis is orthogonal to the vectors. | 1070 | else // other rotation |
949 | LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); | 1071 | { |
950 | orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); | 1072 | LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f; |
951 | // Check for near zero vector. A very small non-zero number here will create | 1073 | axis = llVecNorm(axis); |
952 | // a rotation in an undesired direction. | 1074 | double x, y, z, s, t; |
953 | if (LSL_Vector.Mag(orthoVector) > 0.0001) | 1075 | s = Math.Cos(theta); |
954 | { | 1076 | t = Math.Sin(theta); |
955 | rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); | 1077 | x = axis.x * t; |
956 | } | 1078 | y = axis.y * t; |
957 | // If the magnitude of the vector was near zero, then assume the X axis is not | 1079 | z = axis.z * t; |
958 | // orthogonal and use the Z axis instead. | 1080 | return new LSL_Rotation(x,y,z,s); |
959 | else | ||
960 | { | ||
961 | // Set 180 z rotation. | ||
962 | rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f); | ||
963 | } | ||
964 | } | ||
965 | // Check for parallel vectors. | ||
966 | // A dot product of 1 would mean the angle between vectors is 0 degrees. | ||
967 | else if (dotProduct > 0.9999999f) | ||
968 | { | ||
969 | // Set zero rotation. | ||
970 | rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); | ||
971 | } | ||
972 | else | ||
973 | { | ||
974 | // All special checks have been performed so get the axis of rotation. | ||
975 | LSL_Vector crossProduct = LSL_Vector.Cross(a, b); | ||
976 | // Quarternion s value is the length of the unit vector + dot product. | ||
977 | double qs = 1.0 + dotProduct; | ||
978 | rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs); | ||
979 | // Normalize the rotation. | ||
980 | double mag = LSL_Rotation.Mag(rotBetween); | ||
981 | // We shouldn't have to worry about a divide by zero here. The qs value will be | ||
982 | // non-zero because we already know if we're here, then the dotProduct is not -1 so | ||
983 | // qs will not be zero. Also, we've already handled the input vectors being zero so the | ||
984 | // crossProduct vector should also not be zero. | ||
985 | rotBetween.x = rotBetween.x / mag; | ||
986 | rotBetween.y = rotBetween.y / mag; | ||
987 | rotBetween.z = rotBetween.z / mag; | ||
988 | rotBetween.s = rotBetween.s / mag; | ||
989 | // Check for undefined values and set zero rotation if any found. This code might not actually be required | ||
990 | // any longer since zero vectors are checked for at the top. | ||
991 | if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s)) | ||
992 | { | ||
993 | rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); | ||
994 | } | ||
995 | } | ||
996 | } | 1081 | } |
997 | return rotBetween; | ||
998 | } | 1082 | } |
999 | 1083 | ||
1000 | public void llWhisper(int channelID, string text) | 1084 | public void llWhisper(int channelID, string text) |
1001 | { | 1085 | { |
1002 | m_host.AddScriptLPS(1); | ||
1003 | |||
1004 | if (text.Length > 1023) | 1086 | if (text.Length > 1023) |
1005 | text = text.Substring(0, 1023); | 1087 | text = text.Substring(0, 1023); |
1006 | 1088 | ||
@@ -1012,9 +1094,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1012 | wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); | 1094 | wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); |
1013 | } | 1095 | } |
1014 | 1096 | ||
1097 | private void CheckSayShoutTime() | ||
1098 | { | ||
1099 | DateTime now = DateTime.UtcNow; | ||
1100 | if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec | ||
1101 | { | ||
1102 | m_lastSayShoutCheck = now; | ||
1103 | m_SayShoutCount = 0; | ||
1104 | } | ||
1105 | else | ||
1106 | m_SayShoutCount++; | ||
1107 | } | ||
1108 | |||
1015 | public void llSay(int channelID, string text) | 1109 | public void llSay(int channelID, string text) |
1016 | { | 1110 | { |
1017 | m_host.AddScriptLPS(1); | 1111 | if (channelID == 0) |
1112 | // m_SayShoutCount++; | ||
1113 | CheckSayShoutTime(); | ||
1114 | |||
1115 | //// if (m_SayShoutCount >= 11) | ||
1116 | //// ScriptSleep(2000); | ||
1018 | 1117 | ||
1019 | if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) | 1118 | if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) |
1020 | { | 1119 | { |
@@ -1036,7 +1135,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1036 | 1135 | ||
1037 | public void llShout(int channelID, string text) | 1136 | public void llShout(int channelID, string text) |
1038 | { | 1137 | { |
1039 | m_host.AddScriptLPS(1); | 1138 | if (channelID == 0) |
1139 | // m_SayShoutCount++; | ||
1140 | CheckSayShoutTime(); | ||
1141 | |||
1142 | //// if (m_SayShoutCount >= 11) | ||
1143 | //// ScriptSleep(2000); | ||
1040 | 1144 | ||
1041 | if (text.Length > 1023) | 1145 | if (text.Length > 1023) |
1042 | text = text.Substring(0, 1023); | 1146 | text = text.Substring(0, 1023); |
@@ -1060,10 +1164,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1060 | if (text.Length > 1023) | 1164 | if (text.Length > 1023) |
1061 | text = text.Substring(0, 1023); | 1165 | text = text.Substring(0, 1023); |
1062 | 1166 | ||
1063 | m_host.AddScriptLPS(1); | 1167 | // debug channel is also sent to avatars |
1168 | if (channelID == ScriptBaseClass.DEBUG_CHANNEL) | ||
1169 | { | ||
1170 | World.SimChat(Utils.StringToBytes(text), | ||
1171 | ChatTypeEnum.Shout, channelID, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true); | ||
1064 | 1172 | ||
1065 | World.SimChat(Utils.StringToBytes(text), | 1173 | } |
1066 | ChatTypeEnum.Region, channelID, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, false); | ||
1067 | 1174 | ||
1068 | IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); | 1175 | IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); |
1069 | if (wComm != null) | 1176 | if (wComm != null) |
@@ -1075,19 +1182,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1075 | if (msg.Length > 1023) | 1182 | if (msg.Length > 1023) |
1076 | msg = msg.Substring(0, 1023); | 1183 | msg = msg.Substring(0, 1023); |
1077 | 1184 | ||
1078 | m_host.AddScriptLPS(1); | ||
1079 | |||
1080 | if (channel == ScriptBaseClass.DEBUG_CHANNEL) | 1185 | if (channel == ScriptBaseClass.DEBUG_CHANNEL) |
1081 | { | ||
1082 | return; | 1186 | return; |
1083 | } | ||
1084 | 1187 | ||
1085 | UUID TargetID; | 1188 | UUID TargetID; |
1086 | UUID.TryParse(target, out TargetID); | 1189 | UUID.TryParse(target, out TargetID); |
1087 | 1190 | ||
1088 | World.SimChatToAgent(TargetID, Utils.StringToBytes(msg), | ||
1089 | channel, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true); | ||
1090 | |||
1091 | IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); | 1191 | IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); |
1092 | if (wComm != null) | 1192 | if (wComm != null) |
1093 | wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); | 1193 | wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); |
@@ -1095,7 +1195,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1095 | 1195 | ||
1096 | public LSL_Integer llListen(int channelID, string name, string ID, string msg) | 1196 | public LSL_Integer llListen(int channelID, string name, string ID, string msg) |
1097 | { | 1197 | { |
1098 | m_host.AddScriptLPS(1); | ||
1099 | UUID keyID; | 1198 | UUID keyID; |
1100 | UUID.TryParse(ID, out keyID); | 1199 | UUID.TryParse(ID, out keyID); |
1101 | IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); | 1200 | IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); |
@@ -1107,7 +1206,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1107 | 1206 | ||
1108 | public void llListenControl(int number, int active) | 1207 | public void llListenControl(int number, int active) |
1109 | { | 1208 | { |
1110 | m_host.AddScriptLPS(1); | ||
1111 | IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); | 1209 | IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); |
1112 | if (wComm != null) | 1210 | if (wComm != null) |
1113 | wComm.ListenControl(m_item.ItemID, number, active); | 1211 | wComm.ListenControl(m_item.ItemID, number, active); |
@@ -1115,7 +1213,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1115 | 1213 | ||
1116 | public void llListenRemove(int number) | 1214 | public void llListenRemove(int number) |
1117 | { | 1215 | { |
1118 | m_host.AddScriptLPS(1); | ||
1119 | IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); | 1216 | IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); |
1120 | if (wComm != null) | 1217 | if (wComm != null) |
1121 | wComm.ListenRemove(m_item.ItemID, number); | 1218 | wComm.ListenRemove(m_item.ItemID, number); |
@@ -1123,7 +1220,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1123 | 1220 | ||
1124 | public void llSensor(string name, string id, int type, double range, double arc) | 1221 | public void llSensor(string name, string id, int type, double range, double arc) |
1125 | { | 1222 | { |
1126 | m_host.AddScriptLPS(1); | ||
1127 | UUID keyID = UUID.Zero; | 1223 | UUID keyID = UUID.Zero; |
1128 | UUID.TryParse(id, out keyID); | 1224 | UUID.TryParse(id, out keyID); |
1129 | 1225 | ||
@@ -1132,7 +1228,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1132 | 1228 | ||
1133 | public void llSensorRepeat(string name, string id, int type, double range, double arc, double rate) | 1229 | public void llSensorRepeat(string name, string id, int type, double range, double arc, double rate) |
1134 | { | 1230 | { |
1135 | m_host.AddScriptLPS(1); | ||
1136 | UUID keyID = UUID.Zero; | 1231 | UUID keyID = UUID.Zero; |
1137 | UUID.TryParse(id, out keyID); | 1232 | UUID.TryParse(id, out keyID); |
1138 | 1233 | ||
@@ -1141,7 +1236,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1141 | 1236 | ||
1142 | public void llSensorRemove() | 1237 | public void llSensorRemove() |
1143 | { | 1238 | { |
1144 | m_host.AddScriptLPS(1); | ||
1145 | AsyncCommands.SensorRepeatPlugin.UnSetSenseRepeaterEvents(m_host.LocalId, m_item.ItemID); | 1239 | AsyncCommands.SensorRepeatPlugin.UnSetSenseRepeaterEvents(m_host.LocalId, m_item.ItemID); |
1146 | } | 1240 | } |
1147 | 1241 | ||
@@ -1182,7 +1276,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1182 | 1276 | ||
1183 | public LSL_String llDetectedName(int number) | 1277 | public LSL_String llDetectedName(int number) |
1184 | { | 1278 | { |
1185 | m_host.AddScriptLPS(1); | ||
1186 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); | 1279 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); |
1187 | if (detectedParams == null) | 1280 | if (detectedParams == null) |
1188 | return String.Empty; | 1281 | return String.Empty; |
@@ -1191,7 +1284,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1191 | 1284 | ||
1192 | public LSL_String llDetectedKey(int number) | 1285 | public LSL_String llDetectedKey(int number) |
1193 | { | 1286 | { |
1194 | m_host.AddScriptLPS(1); | ||
1195 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); | 1287 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); |
1196 | if (detectedParams == null) | 1288 | if (detectedParams == null) |
1197 | return String.Empty; | 1289 | return String.Empty; |
@@ -1200,7 +1292,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1200 | 1292 | ||
1201 | public LSL_String llDetectedOwner(int number) | 1293 | public LSL_String llDetectedOwner(int number) |
1202 | { | 1294 | { |
1203 | m_host.AddScriptLPS(1); | ||
1204 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); | 1295 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); |
1205 | if (detectedParams == null) | 1296 | if (detectedParams == null) |
1206 | return String.Empty; | 1297 | return String.Empty; |
@@ -1209,7 +1300,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1209 | 1300 | ||
1210 | public LSL_Integer llDetectedType(int number) | 1301 | public LSL_Integer llDetectedType(int number) |
1211 | { | 1302 | { |
1212 | m_host.AddScriptLPS(1); | ||
1213 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); | 1303 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); |
1214 | if (detectedParams == null) | 1304 | if (detectedParams == null) |
1215 | return 0; | 1305 | return 0; |
@@ -1218,7 +1308,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1218 | 1308 | ||
1219 | public LSL_Vector llDetectedPos(int number) | 1309 | public LSL_Vector llDetectedPos(int number) |
1220 | { | 1310 | { |
1221 | m_host.AddScriptLPS(1); | ||
1222 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); | 1311 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); |
1223 | if (detectedParams == null) | 1312 | if (detectedParams == null) |
1224 | return new LSL_Vector(); | 1313 | return new LSL_Vector(); |
@@ -1227,7 +1316,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1227 | 1316 | ||
1228 | public LSL_Vector llDetectedVel(int number) | 1317 | public LSL_Vector llDetectedVel(int number) |
1229 | { | 1318 | { |
1230 | m_host.AddScriptLPS(1); | ||
1231 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); | 1319 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); |
1232 | if (detectedParams == null) | 1320 | if (detectedParams == null) |
1233 | return new LSL_Vector(); | 1321 | return new LSL_Vector(); |
@@ -1236,7 +1324,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1236 | 1324 | ||
1237 | public LSL_Vector llDetectedGrab(int number) | 1325 | public LSL_Vector llDetectedGrab(int number) |
1238 | { | 1326 | { |
1239 | m_host.AddScriptLPS(1); | ||
1240 | DetectParams parms = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); | 1327 | DetectParams parms = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); |
1241 | if (parms == null) | 1328 | if (parms == null) |
1242 | return new LSL_Vector(0, 0, 0); | 1329 | return new LSL_Vector(0, 0, 0); |
@@ -1246,7 +1333,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1246 | 1333 | ||
1247 | public LSL_Rotation llDetectedRot(int number) | 1334 | public LSL_Rotation llDetectedRot(int number) |
1248 | { | 1335 | { |
1249 | m_host.AddScriptLPS(1); | ||
1250 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); | 1336 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); |
1251 | if (detectedParams == null) | 1337 | if (detectedParams == null) |
1252 | return new LSL_Rotation(); | 1338 | return new LSL_Rotation(); |
@@ -1255,7 +1341,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1255 | 1341 | ||
1256 | public LSL_Integer llDetectedGroup(int number) | 1342 | public LSL_Integer llDetectedGroup(int number) |
1257 | { | 1343 | { |
1258 | m_host.AddScriptLPS(1); | ||
1259 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); | 1344 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); |
1260 | if (detectedParams == null) | 1345 | if (detectedParams == null) |
1261 | return new LSL_Integer(0); | 1346 | return new LSL_Integer(0); |
@@ -1266,7 +1351,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1266 | 1351 | ||
1267 | public LSL_Integer llDetectedLinkNumber(int number) | 1352 | public LSL_Integer llDetectedLinkNumber(int number) |
1268 | { | 1353 | { |
1269 | m_host.AddScriptLPS(1); | ||
1270 | DetectParams parms = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); | 1354 | DetectParams parms = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); |
1271 | if (parms == null) | 1355 | if (parms == null) |
1272 | return new LSL_Integer(0); | 1356 | return new LSL_Integer(0); |
@@ -1279,7 +1363,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1279 | /// </summary> | 1363 | /// </summary> |
1280 | public LSL_Vector llDetectedTouchBinormal(int index) | 1364 | public LSL_Vector llDetectedTouchBinormal(int index) |
1281 | { | 1365 | { |
1282 | m_host.AddScriptLPS(1); | ||
1283 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); | 1366 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); |
1284 | if (detectedParams == null) | 1367 | if (detectedParams == null) |
1285 | return new LSL_Vector(); | 1368 | return new LSL_Vector(); |
@@ -1291,7 +1374,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1291 | /// </summary> | 1374 | /// </summary> |
1292 | public LSL_Integer llDetectedTouchFace(int index) | 1375 | public LSL_Integer llDetectedTouchFace(int index) |
1293 | { | 1376 | { |
1294 | m_host.AddScriptLPS(1); | ||
1295 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); | 1377 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); |
1296 | if (detectedParams == null) | 1378 | if (detectedParams == null) |
1297 | return new LSL_Integer(-1); | 1379 | return new LSL_Integer(-1); |
@@ -1303,7 +1385,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1303 | /// </summary> | 1385 | /// </summary> |
1304 | public LSL_Vector llDetectedTouchNormal(int index) | 1386 | public LSL_Vector llDetectedTouchNormal(int index) |
1305 | { | 1387 | { |
1306 | m_host.AddScriptLPS(1); | ||
1307 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); | 1388 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); |
1308 | if (detectedParams == null) | 1389 | if (detectedParams == null) |
1309 | return new LSL_Vector(); | 1390 | return new LSL_Vector(); |
@@ -1315,7 +1396,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1315 | /// </summary> | 1396 | /// </summary> |
1316 | public LSL_Vector llDetectedTouchPos(int index) | 1397 | public LSL_Vector llDetectedTouchPos(int index) |
1317 | { | 1398 | { |
1318 | m_host.AddScriptLPS(1); | ||
1319 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); | 1399 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); |
1320 | if (detectedParams == null) | 1400 | if (detectedParams == null) |
1321 | return new LSL_Vector(); | 1401 | return new LSL_Vector(); |
@@ -1327,7 +1407,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1327 | /// </summary> | 1407 | /// </summary> |
1328 | public LSL_Vector llDetectedTouchST(int index) | 1408 | public LSL_Vector llDetectedTouchST(int index) |
1329 | { | 1409 | { |
1330 | m_host.AddScriptLPS(1); | ||
1331 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); | 1410 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); |
1332 | if (detectedParams == null) | 1411 | if (detectedParams == null) |
1333 | return new LSL_Vector(-1.0, -1.0, 0.0); | 1412 | return new LSL_Vector(-1.0, -1.0, 0.0); |
@@ -1339,22 +1418,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1339 | /// </summary> | 1418 | /// </summary> |
1340 | public LSL_Vector llDetectedTouchUV(int index) | 1419 | public LSL_Vector llDetectedTouchUV(int index) |
1341 | { | 1420 | { |
1342 | m_host.AddScriptLPS(1); | ||
1343 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); | 1421 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); |
1344 | if (detectedParams == null) | 1422 | if (detectedParams == null) |
1345 | return new LSL_Vector(-1.0, -1.0, 0.0); | 1423 | return new LSL_Vector(-1.0, -1.0, 0.0); |
1346 | return detectedParams.TouchUV; | 1424 | return detectedParams.TouchUV; |
1347 | } | 1425 | } |
1348 | 1426 | ||
1427 | [DebuggerNonUserCode] | ||
1349 | public virtual void llDie() | 1428 | public virtual void llDie() |
1350 | { | 1429 | { |
1351 | m_host.AddScriptLPS(1); | 1430 | if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException(); |
1352 | throw new SelfDeleteException(); | ||
1353 | } | 1431 | } |
1354 | 1432 | ||
1355 | public LSL_Float llGround(LSL_Vector offset) | 1433 | public LSL_Float llGround(LSL_Vector offset) |
1356 | { | 1434 | { |
1357 | m_host.AddScriptLPS(1); | ||
1358 | Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset; | 1435 | Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset; |
1359 | 1436 | ||
1360 | //Get the slope normal. This gives us the equation of the plane tangent to the slope. | 1437 | //Get the slope normal. This gives us the equation of the plane tangent to the slope. |
@@ -1384,7 +1461,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1384 | 1461 | ||
1385 | public LSL_Float llCloud(LSL_Vector offset) | 1462 | public LSL_Float llCloud(LSL_Vector offset) |
1386 | { | 1463 | { |
1387 | m_host.AddScriptLPS(1); | ||
1388 | float cloudCover = 0f; | 1464 | float cloudCover = 0f; |
1389 | ICloudModule module = World.RequestModuleInterface<ICloudModule>(); | 1465 | ICloudModule module = World.RequestModuleInterface<ICloudModule>(); |
1390 | if (module != null) | 1466 | if (module != null) |
@@ -1401,7 +1477,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1401 | 1477 | ||
1402 | public LSL_Vector llWind(LSL_Vector offset) | 1478 | public LSL_Vector llWind(LSL_Vector offset) |
1403 | { | 1479 | { |
1404 | m_host.AddScriptLPS(1); | ||
1405 | LSL_Vector wind = new LSL_Vector(0, 0, 0); | 1480 | LSL_Vector wind = new LSL_Vector(0, 0, 0); |
1406 | IWindModule module = World.RequestModuleInterface<IWindModule>(); | 1481 | IWindModule module = World.RequestModuleInterface<IWindModule>(); |
1407 | if (module != null) | 1482 | if (module != null) |
@@ -1420,7 +1495,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1420 | 1495 | ||
1421 | public void llSetStatus(int status, int value) | 1496 | public void llSetStatus(int status, int value) |
1422 | { | 1497 | { |
1423 | m_host.AddScriptLPS(1); | 1498 | if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted) |
1499 | return; | ||
1424 | 1500 | ||
1425 | int statusrotationaxis = 0; | 1501 | int statusrotationaxis = 0; |
1426 | 1502 | ||
@@ -1431,18 +1507,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1431 | SceneObjectGroup group = m_host.ParentGroup; | 1507 | SceneObjectGroup group = m_host.ParentGroup; |
1432 | bool allow = true; | 1508 | bool allow = true; |
1433 | 1509 | ||
1510 | int maxprims = World.m_linksetPhysCapacity; | ||
1511 | bool checkShape = (maxprims > 0 && group.PrimCount > maxprims); | ||
1512 | |||
1434 | foreach (SceneObjectPart part in group.Parts) | 1513 | foreach (SceneObjectPart part in group.Parts) |
1435 | { | 1514 | { |
1515 | if (part.PhysicsShapeType == (byte)PhysicsShapeType.None) | ||
1516 | continue; | ||
1517 | |||
1436 | if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys) | 1518 | if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys) |
1437 | { | 1519 | { |
1438 | allow = false; | 1520 | allow = false; |
1439 | break; | 1521 | break; |
1440 | } | 1522 | } |
1523 | if (checkShape) | ||
1524 | { | ||
1525 | if (--maxprims < 0) | ||
1526 | { | ||
1527 | allow = false; | ||
1528 | break; | ||
1529 | } | ||
1530 | } | ||
1441 | } | 1531 | } |
1442 | 1532 | ||
1443 | if (!allow) | 1533 | if (!allow) |
1444 | return; | 1534 | return; |
1445 | 1535 | ||
1536 | if (m_host.ParentGroup.RootPart.PhysActor != null && | ||
1537 | m_host.ParentGroup.RootPart.PhysActor.IsPhysical) | ||
1538 | return; | ||
1539 | |||
1446 | m_host.ScriptSetPhysicsStatus(true); | 1540 | m_host.ScriptSetPhysicsStatus(true); |
1447 | } | 1541 | } |
1448 | else | 1542 | else |
@@ -1519,7 +1613,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1519 | 1613 | ||
1520 | public LSL_Integer llGetStatus(int status) | 1614 | public LSL_Integer llGetStatus(int status) |
1521 | { | 1615 | { |
1522 | m_host.AddScriptLPS(1); | ||
1523 | // m_log.Debug(m_host.ToString() + " status is " + m_host.GetEffectiveObjectFlags().ToString()); | 1616 | // m_log.Debug(m_host.ToString() + " status is " + m_host.GetEffectiveObjectFlags().ToString()); |
1524 | switch (status) | 1617 | switch (status) |
1525 | { | 1618 | { |
@@ -1586,9 +1679,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1586 | return 0; | 1679 | return 0; |
1587 | } | 1680 | } |
1588 | 1681 | ||
1682 | public LSL_Integer llScaleByFactor(double scaling_factor) | ||
1683 | { | ||
1684 | SceneObjectGroup group = m_host.ParentGroup; | ||
1685 | |||
1686 | if(scaling_factor < 1e-6) | ||
1687 | return ScriptBaseClass.FALSE; | ||
1688 | if(scaling_factor > 1e6) | ||
1689 | return ScriptBaseClass.FALSE; | ||
1690 | |||
1691 | if (group == null || group.IsDeleted || group.inTransit) | ||
1692 | return ScriptBaseClass.FALSE; | ||
1693 | |||
1694 | if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical) | ||
1695 | return ScriptBaseClass.FALSE; | ||
1696 | |||
1697 | if (group.RootPart.KeyframeMotion != null) | ||
1698 | return ScriptBaseClass.FALSE; | ||
1699 | |||
1700 | if(group.GroupResize(scaling_factor)) | ||
1701 | return ScriptBaseClass.TRUE; | ||
1702 | else | ||
1703 | return ScriptBaseClass.FALSE; | ||
1704 | } | ||
1705 | |||
1706 | public LSL_Float llGetMaxScaleFactor() | ||
1707 | { | ||
1708 | SceneObjectGroup group = m_host.ParentGroup; | ||
1709 | |||
1710 | if (group == null || group.IsDeleted || group.inTransit) | ||
1711 | return 1.0f; | ||
1712 | |||
1713 | return (LSL_Float)group.GetMaxGroupResizeScale(); | ||
1714 | } | ||
1715 | |||
1716 | public LSL_Float llGetMinScaleFactor() | ||
1717 | { | ||
1718 | SceneObjectGroup group = m_host.ParentGroup; | ||
1719 | |||
1720 | if (group == null || group.IsDeleted || group.inTransit) | ||
1721 | return 1.0f; | ||
1722 | |||
1723 | return (LSL_Float)group.GetMinGroupResizeScale(); | ||
1724 | } | ||
1725 | |||
1589 | public void llSetScale(LSL_Vector scale) | 1726 | public void llSetScale(LSL_Vector scale) |
1590 | { | 1727 | { |
1591 | m_host.AddScriptLPS(1); | ||
1592 | SetScale(m_host, scale); | 1728 | SetScale(m_host, scale); |
1593 | } | 1729 | } |
1594 | 1730 | ||
@@ -1624,13 +1760,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1624 | 1760 | ||
1625 | public LSL_Vector llGetScale() | 1761 | public LSL_Vector llGetScale() |
1626 | { | 1762 | { |
1627 | m_host.AddScriptLPS(1); | ||
1628 | return new LSL_Vector(m_host.Scale.X, m_host.Scale.Y, m_host.Scale.Z); | 1763 | return new LSL_Vector(m_host.Scale.X, m_host.Scale.Y, m_host.Scale.Z); |
1629 | } | 1764 | } |
1630 | 1765 | ||
1631 | public void llSetClickAction(int action) | 1766 | public void llSetClickAction(int action) |
1632 | { | 1767 | { |
1633 | m_host.AddScriptLPS(1); | ||
1634 | m_host.ClickAction = (byte)action; | 1768 | m_host.ClickAction = (byte)action; |
1635 | m_host.ParentGroup.HasGroupChanged = true; | 1769 | m_host.ParentGroup.HasGroupChanged = true; |
1636 | m_host.ScheduleFullUpdate(); | 1770 | m_host.ScheduleFullUpdate(); |
@@ -1639,7 +1773,49 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1639 | 1773 | ||
1640 | public void llSetColor(LSL_Vector color, int face) | 1774 | public void llSetColor(LSL_Vector color, int face) |
1641 | { | 1775 | { |
1642 | m_host.AddScriptLPS(1); | 1776 | SetColor(m_host, color, face); |
1777 | } | ||
1778 | |||
1779 | protected void SetColor(SceneObjectPart part, LSL_Vector color, int face) | ||
1780 | { | ||
1781 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | ||
1782 | return; | ||
1783 | |||
1784 | Primitive.TextureEntry tex = part.Shape.Textures; | ||
1785 | int nsides = GetNumberOfSides(part); | ||
1786 | Color4 texcolor; | ||
1787 | |||
1788 | if (face >= 0 && face < nsides) | ||
1789 | { | ||
1790 | texcolor = tex.CreateFace((uint)face).RGBA; | ||
1791 | texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f); | ||
1792 | texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f); | ||
1793 | texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f); | ||
1794 | tex.FaceTextures[face].RGBA = texcolor; | ||
1795 | part.UpdateTextureEntry(tex.GetBytes()); | ||
1796 | return; | ||
1797 | } | ||
1798 | else if (face == ScriptBaseClass.ALL_SIDES) | ||
1799 | { | ||
1800 | for (uint i = 0; i < nsides; i++) | ||
1801 | { | ||
1802 | if (tex.FaceTextures[i] != null) | ||
1803 | { | ||
1804 | texcolor = tex.FaceTextures[i].RGBA; | ||
1805 | texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f); | ||
1806 | texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f); | ||
1807 | texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f); | ||
1808 | tex.FaceTextures[i].RGBA = texcolor; | ||
1809 | } | ||
1810 | texcolor = tex.DefaultTexture.RGBA; | ||
1811 | texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f); | ||
1812 | texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f); | ||
1813 | texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f); | ||
1814 | tex.DefaultTexture.RGBA = texcolor; | ||
1815 | } | ||
1816 | part.UpdateTextureEntry(tex.GetBytes()); | ||
1817 | return; | ||
1818 | } | ||
1643 | 1819 | ||
1644 | if (face == ScriptBaseClass.ALL_SIDES) | 1820 | if (face == ScriptBaseClass.ALL_SIDES) |
1645 | face = SceneObjectPart.ALL_SIDES; | 1821 | face = SceneObjectPart.ALL_SIDES; |
@@ -1649,8 +1825,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1649 | 1825 | ||
1650 | public void llSetContentType(LSL_Key id, LSL_Integer type) | 1826 | public void llSetContentType(LSL_Key id, LSL_Integer type) |
1651 | { | 1827 | { |
1652 | m_host.AddScriptLPS(1); | ||
1653 | |||
1654 | if (m_UrlModule == null) | 1828 | if (m_UrlModule == null) |
1655 | return; | 1829 | return; |
1656 | 1830 | ||
@@ -1714,15 +1888,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1714 | } | 1888 | } |
1715 | } | 1889 | } |
1716 | 1890 | ||
1891 | /* | ||
1892 | public void llSetContentType(LSL_Key id, LSL_Integer content_type) | ||
1893 | { | ||
1894 | if (m_UrlModule != null) | ||
1895 | { | ||
1896 | string type = "text.plain"; | ||
1897 | if (content_type == (int)ScriptBaseClass.CONTENT_TYPE_HTML) | ||
1898 | type = "text/html"; | ||
1899 | |||
1900 | m_UrlModule.HttpContentType(new UUID(id),type); | ||
1901 | } | ||
1902 | } | ||
1903 | */ | ||
1717 | public void SetTexGen(SceneObjectPart part, int face,int style) | 1904 | public void SetTexGen(SceneObjectPart part, int face,int style) |
1718 | { | 1905 | { |
1906 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | ||
1907 | return; | ||
1908 | |||
1719 | Primitive.TextureEntry tex = part.Shape.Textures; | 1909 | Primitive.TextureEntry tex = part.Shape.Textures; |
1720 | MappingType textype; | 1910 | MappingType textype; |
1721 | textype = MappingType.Default; | 1911 | textype = MappingType.Default; |
1722 | if (style == (int)ScriptBaseClass.PRIM_TEXGEN_PLANAR) | 1912 | if (style == (int)ScriptBaseClass.PRIM_TEXGEN_PLANAR) |
1723 | textype = MappingType.Planar; | 1913 | textype = MappingType.Planar; |
1724 | 1914 | ||
1725 | if (face >= 0 && face < GetNumberOfSides(part)) | 1915 | int nsides = GetNumberOfSides(part); |
1916 | |||
1917 | if (face >= 0 && face < nsides) | ||
1726 | { | 1918 | { |
1727 | tex.CreateFace((uint) face); | 1919 | tex.CreateFace((uint) face); |
1728 | tex.FaceTextures[face].TexMapType = textype; | 1920 | tex.FaceTextures[face].TexMapType = textype; |
@@ -1731,7 +1923,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1731 | } | 1923 | } |
1732 | else if (face == ScriptBaseClass.ALL_SIDES) | 1924 | else if (face == ScriptBaseClass.ALL_SIDES) |
1733 | { | 1925 | { |
1734 | for (uint i = 0; i < GetNumberOfSides(part); i++) | 1926 | for (uint i = 0; i < nsides; i++) |
1735 | { | 1927 | { |
1736 | if (tex.FaceTextures[i] != null) | 1928 | if (tex.FaceTextures[i] != null) |
1737 | { | 1929 | { |
@@ -1746,8 +1938,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1746 | 1938 | ||
1747 | public void SetGlow(SceneObjectPart part, int face, float glow) | 1939 | public void SetGlow(SceneObjectPart part, int face, float glow) |
1748 | { | 1940 | { |
1941 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | ||
1942 | return; | ||
1943 | |||
1749 | Primitive.TextureEntry tex = part.Shape.Textures; | 1944 | Primitive.TextureEntry tex = part.Shape.Textures; |
1750 | if (face >= 0 && face < GetNumberOfSides(part)) | 1945 | int nsides = GetNumberOfSides(part); |
1946 | |||
1947 | if (face >= 0 && face < nsides) | ||
1751 | { | 1948 | { |
1752 | tex.CreateFace((uint) face); | 1949 | tex.CreateFace((uint) face); |
1753 | tex.FaceTextures[face].Glow = glow; | 1950 | tex.FaceTextures[face].Glow = glow; |
@@ -1756,7 +1953,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1756 | } | 1953 | } |
1757 | else if (face == ScriptBaseClass.ALL_SIDES) | 1954 | else if (face == ScriptBaseClass.ALL_SIDES) |
1758 | { | 1955 | { |
1759 | for (uint i = 0; i < GetNumberOfSides(part); i++) | 1956 | for (uint i = 0; i < nsides; i++) |
1760 | { | 1957 | { |
1761 | if (tex.FaceTextures[i] != null) | 1958 | if (tex.FaceTextures[i] != null) |
1762 | { | 1959 | { |
@@ -1771,6 +1968,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1771 | 1968 | ||
1772 | public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) | 1969 | public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) |
1773 | { | 1970 | { |
1971 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | ||
1972 | return; | ||
1774 | 1973 | ||
1775 | Shininess sval = new Shininess(); | 1974 | Shininess sval = new Shininess(); |
1776 | 1975 | ||
@@ -1793,8 +1992,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1793 | break; | 1992 | break; |
1794 | } | 1993 | } |
1795 | 1994 | ||
1995 | int nsides = GetNumberOfSides(part); | ||
1996 | |||
1796 | Primitive.TextureEntry tex = part.Shape.Textures; | 1997 | Primitive.TextureEntry tex = part.Shape.Textures; |
1797 | if (face >= 0 && face < GetNumberOfSides(part)) | 1998 | if (face >= 0 && face < nsides) |
1798 | { | 1999 | { |
1799 | tex.CreateFace((uint) face); | 2000 | tex.CreateFace((uint) face); |
1800 | tex.FaceTextures[face].Shiny = sval; | 2001 | tex.FaceTextures[face].Shiny = sval; |
@@ -1804,7 +2005,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1804 | } | 2005 | } |
1805 | else if (face == ScriptBaseClass.ALL_SIDES) | 2006 | else if (face == ScriptBaseClass.ALL_SIDES) |
1806 | { | 2007 | { |
1807 | for (uint i = 0; i < GetNumberOfSides(part); i++) | 2008 | for (uint i = 0; i < nsides; i++) |
1808 | { | 2009 | { |
1809 | if (tex.FaceTextures[i] != null) | 2010 | if (tex.FaceTextures[i] != null) |
1810 | { | 2011 | { |
@@ -1821,8 +2022,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1821 | 2022 | ||
1822 | public void SetFullBright(SceneObjectPart part, int face, bool bright) | 2023 | public void SetFullBright(SceneObjectPart part, int face, bool bright) |
1823 | { | 2024 | { |
2025 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | ||
2026 | return; | ||
2027 | |||
2028 | int nsides = GetNumberOfSides(part); | ||
1824 | Primitive.TextureEntry tex = part.Shape.Textures; | 2029 | Primitive.TextureEntry tex = part.Shape.Textures; |
1825 | if (face >= 0 && face < GetNumberOfSides(part)) | 2030 | if (face >= 0 && face < nsides) |
1826 | { | 2031 | { |
1827 | tex.CreateFace((uint) face); | 2032 | tex.CreateFace((uint) face); |
1828 | tex.FaceTextures[face].Fullbright = bright; | 2033 | tex.FaceTextures[face].Fullbright = bright; |
@@ -1831,7 +2036,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1831 | } | 2036 | } |
1832 | else if (face == ScriptBaseClass.ALL_SIDES) | 2037 | else if (face == ScriptBaseClass.ALL_SIDES) |
1833 | { | 2038 | { |
1834 | for (uint i = 0; i < GetNumberOfSides(part); i++) | 2039 | for (uint i = 0; i < nsides; i++) |
1835 | { | 2040 | { |
1836 | if (tex.FaceTextures[i] != null) | 2041 | if (tex.FaceTextures[i] != null) |
1837 | { | 2042 | { |
@@ -1846,23 +2051,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1846 | 2051 | ||
1847 | public LSL_Float llGetAlpha(int face) | 2052 | public LSL_Float llGetAlpha(int face) |
1848 | { | 2053 | { |
1849 | m_host.AddScriptLPS(1); | ||
1850 | |||
1851 | return GetAlpha(m_host, face); | 2054 | return GetAlpha(m_host, face); |
1852 | } | 2055 | } |
1853 | 2056 | ||
1854 | protected LSL_Float GetAlpha(SceneObjectPart part, int face) | 2057 | protected LSL_Float GetAlpha(SceneObjectPart part, int face) |
1855 | { | 2058 | { |
1856 | Primitive.TextureEntry tex = part.Shape.Textures; | 2059 | Primitive.TextureEntry tex = part.Shape.Textures; |
2060 | int nsides = GetNumberOfSides(part); | ||
1857 | if (face == ScriptBaseClass.ALL_SIDES) | 2061 | if (face == ScriptBaseClass.ALL_SIDES) |
1858 | { | 2062 | { |
1859 | int i; | 2063 | int i; |
1860 | double sum = 0.0; | 2064 | double sum = 0.0; |
1861 | for (i = 0 ; i < GetNumberOfSides(part); i++) | 2065 | for (i = 0 ; i < nsides; i++) |
1862 | sum += (double)tex.GetFace((uint)i).RGBA.A; | 2066 | sum += (double)tex.GetFace((uint)i).RGBA.A; |
1863 | return sum; | 2067 | return sum; |
1864 | } | 2068 | } |
1865 | if (face >= 0 && face < GetNumberOfSides(part)) | 2069 | if (face >= 0 && face < nsides) |
1866 | { | 2070 | { |
1867 | return (double)tex.GetFace((uint)face).RGBA.A; | 2071 | return (double)tex.GetFace((uint)face).RGBA.A; |
1868 | } | 2072 | } |
@@ -1871,26 +2075,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1871 | 2075 | ||
1872 | public void llSetAlpha(double alpha, int face) | 2076 | public void llSetAlpha(double alpha, int face) |
1873 | { | 2077 | { |
1874 | m_host.AddScriptLPS(1); | ||
1875 | |||
1876 | SetAlpha(m_host, alpha, face); | 2078 | SetAlpha(m_host, alpha, face); |
1877 | } | 2079 | } |
1878 | 2080 | ||
1879 | public void llSetLinkAlpha(int linknumber, double alpha, int face) | 2081 | public void llSetLinkAlpha(int linknumber, double alpha, int face) |
1880 | { | 2082 | { |
1881 | m_host.AddScriptLPS(1); | ||
1882 | |||
1883 | List<SceneObjectPart> parts = GetLinkParts(linknumber); | 2083 | List<SceneObjectPart> parts = GetLinkParts(linknumber); |
1884 | 2084 | if (parts.Count > 0) | |
1885 | foreach (SceneObjectPart part in parts) | 2085 | { |
1886 | SetAlpha(part, alpha, face); | 2086 | try |
2087 | { | ||
2088 | foreach (SceneObjectPart part in parts) | ||
2089 | SetAlpha(part, alpha, face); | ||
2090 | } | ||
2091 | finally { } | ||
2092 | } | ||
1887 | } | 2093 | } |
1888 | 2094 | ||
1889 | protected void SetAlpha(SceneObjectPart part, double alpha, int face) | 2095 | protected void SetAlpha(SceneObjectPart part, double alpha, int face) |
1890 | { | 2096 | { |
2097 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | ||
2098 | return; | ||
2099 | |||
1891 | Primitive.TextureEntry tex = part.Shape.Textures; | 2100 | Primitive.TextureEntry tex = part.Shape.Textures; |
2101 | int nsides = GetNumberOfSides(part); | ||
1892 | Color4 texcolor; | 2102 | Color4 texcolor; |
1893 | if (face >= 0 && face < GetNumberOfSides(part)) | 2103 | |
2104 | if (face >= 0 && face < nsides) | ||
1894 | { | 2105 | { |
1895 | texcolor = tex.CreateFace((uint)face).RGBA; | 2106 | texcolor = tex.CreateFace((uint)face).RGBA; |
1896 | texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f); | 2107 | texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f); |
@@ -1900,7 +2111,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1900 | } | 2111 | } |
1901 | else if (face == ScriptBaseClass.ALL_SIDES) | 2112 | else if (face == ScriptBaseClass.ALL_SIDES) |
1902 | { | 2113 | { |
1903 | for (int i = 0; i < GetNumberOfSides(part); i++) | 2114 | for (int i = 0; i < nsides; i++) |
1904 | { | 2115 | { |
1905 | if (tex.FaceTextures[i] != null) | 2116 | if (tex.FaceTextures[i] != null) |
1906 | { | 2117 | { |
@@ -1940,7 +2151,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1940 | protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, | 2151 | protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, |
1941 | float wind, float tension, LSL_Vector Force) | 2152 | float wind, float tension, LSL_Vector Force) |
1942 | { | 2153 | { |
1943 | if (part == null) | 2154 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) |
1944 | return; | 2155 | return; |
1945 | 2156 | ||
1946 | if (flexi) | 2157 | if (flexi) |
@@ -1981,7 +2192,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1981 | /// <param name="falloff"></param> | 2192 | /// <param name="falloff"></param> |
1982 | protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) | 2193 | protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) |
1983 | { | 2194 | { |
1984 | if (part == null) | 2195 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) |
1985 | return; | 2196 | return; |
1986 | 2197 | ||
1987 | if (light) | 2198 | if (light) |
@@ -2005,7 +2216,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2005 | 2216 | ||
2006 | public LSL_Vector llGetColor(int face) | 2217 | public LSL_Vector llGetColor(int face) |
2007 | { | 2218 | { |
2008 | m_host.AddScriptLPS(1); | ||
2009 | return GetColor(m_host, face); | 2219 | return GetColor(m_host, face); |
2010 | } | 2220 | } |
2011 | 2221 | ||
@@ -2014,11 +2224,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2014 | Primitive.TextureEntry tex = part.Shape.Textures; | 2224 | Primitive.TextureEntry tex = part.Shape.Textures; |
2015 | Color4 texcolor; | 2225 | Color4 texcolor; |
2016 | LSL_Vector rgb = new LSL_Vector(); | 2226 | LSL_Vector rgb = new LSL_Vector(); |
2227 | int nsides = GetNumberOfSides(part); | ||
2228 | |||
2017 | if (face == ScriptBaseClass.ALL_SIDES) | 2229 | if (face == ScriptBaseClass.ALL_SIDES) |
2018 | { | 2230 | { |
2019 | int i; | 2231 | int i; |
2020 | 2232 | for (i = 0; i < nsides; i++) | |
2021 | for (i = 0 ; i < GetNumberOfSides(part); i++) | ||
2022 | { | 2233 | { |
2023 | texcolor = tex.GetFace((uint)i).RGBA; | 2234 | texcolor = tex.GetFace((uint)i).RGBA; |
2024 | rgb.x += texcolor.R; | 2235 | rgb.x += texcolor.R; |
@@ -2026,14 +2237,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2026 | rgb.z += texcolor.B; | 2237 | rgb.z += texcolor.B; |
2027 | } | 2238 | } |
2028 | 2239 | ||
2029 | rgb.x /= (float)GetNumberOfSides(part); | 2240 | float invnsides = 1.0f / (float)nsides; |
2030 | rgb.y /= (float)GetNumberOfSides(part); | 2241 | |
2031 | rgb.z /= (float)GetNumberOfSides(part); | 2242 | rgb.x *= invnsides; |
2243 | rgb.y *= invnsides; | ||
2244 | rgb.z *= invnsides; | ||
2032 | 2245 | ||
2033 | return rgb; | 2246 | return rgb; |
2034 | } | 2247 | } |
2035 | 2248 | if (face >= 0 && face < nsides) | |
2036 | if (face >= 0 && face < GetNumberOfSides(part)) | ||
2037 | { | 2249 | { |
2038 | texcolor = tex.GetFace((uint)face).RGBA; | 2250 | texcolor = tex.GetFace((uint)face).RGBA; |
2039 | rgb.x = texcolor.R; | 2251 | rgb.x = texcolor.R; |
@@ -2050,22 +2262,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2050 | 2262 | ||
2051 | public void llSetTexture(string texture, int face) | 2263 | public void llSetTexture(string texture, int face) |
2052 | { | 2264 | { |
2053 | m_host.AddScriptLPS(1); | ||
2054 | SetTexture(m_host, texture, face); | 2265 | SetTexture(m_host, texture, face); |
2055 | } | 2266 | } |
2056 | 2267 | ||
2057 | public void llSetLinkTexture(int linknumber, string texture, int face) | 2268 | public void llSetLinkTexture(int linknumber, string texture, int face) |
2058 | { | 2269 | { |
2059 | m_host.AddScriptLPS(1); | ||
2060 | |||
2061 | List<SceneObjectPart> parts = GetLinkParts(linknumber); | 2270 | List<SceneObjectPart> parts = GetLinkParts(linknumber); |
2062 | 2271 | if (parts.Count > 0) | |
2063 | foreach (SceneObjectPart part in parts) | 2272 | { |
2064 | SetTexture(part, texture, face); | 2273 | try |
2274 | { | ||
2275 | foreach (SceneObjectPart part in parts) | ||
2276 | SetTexture(part, texture, face); | ||
2277 | } | ||
2278 | finally { } | ||
2279 | } | ||
2065 | } | 2280 | } |
2066 | 2281 | ||
2067 | protected void SetTexture(SceneObjectPart part, string texture, int face) | 2282 | protected void SetTexture(SceneObjectPart part, string texture, int face) |
2068 | { | 2283 | { |
2284 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | ||
2285 | return; | ||
2286 | |||
2069 | UUID textureID = new UUID(); | 2287 | UUID textureID = new UUID(); |
2070 | 2288 | ||
2071 | textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); | 2289 | textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); |
@@ -2075,9 +2293,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2075 | return; | 2293 | return; |
2076 | } | 2294 | } |
2077 | 2295 | ||
2296 | |||
2078 | Primitive.TextureEntry tex = part.Shape.Textures; | 2297 | Primitive.TextureEntry tex = part.Shape.Textures; |
2298 | int nsides = GetNumberOfSides(part); | ||
2079 | 2299 | ||
2080 | if (face >= 0 && face < GetNumberOfSides(part)) | 2300 | if (face >= 0 && face < nsides) |
2081 | { | 2301 | { |
2082 | Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); | 2302 | Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); |
2083 | texface.TextureID = textureID; | 2303 | texface.TextureID = textureID; |
@@ -2087,7 +2307,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2087 | } | 2307 | } |
2088 | else if (face == ScriptBaseClass.ALL_SIDES) | 2308 | else if (face == ScriptBaseClass.ALL_SIDES) |
2089 | { | 2309 | { |
2090 | for (uint i = 0; i < GetNumberOfSides(part); i++) | 2310 | for (uint i = 0; i < nsides; i++) |
2091 | { | 2311 | { |
2092 | if (tex.FaceTextures[i] != null) | 2312 | if (tex.FaceTextures[i] != null) |
2093 | { | 2313 | { |
@@ -2102,15 +2322,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2102 | 2322 | ||
2103 | public void llScaleTexture(double u, double v, int face) | 2323 | public void llScaleTexture(double u, double v, int face) |
2104 | { | 2324 | { |
2105 | m_host.AddScriptLPS(1); | ||
2106 | |||
2107 | ScaleTexture(m_host, u, v, face); | 2325 | ScaleTexture(m_host, u, v, face); |
2108 | } | 2326 | } |
2109 | 2327 | ||
2110 | protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) | 2328 | protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) |
2111 | { | 2329 | { |
2330 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | ||
2331 | return; | ||
2332 | |||
2112 | Primitive.TextureEntry tex = part.Shape.Textures; | 2333 | Primitive.TextureEntry tex = part.Shape.Textures; |
2113 | if (face >= 0 && face < GetNumberOfSides(part)) | 2334 | int nsides = GetNumberOfSides(part); |
2335 | |||
2336 | if (face >= 0 && face < nsides) | ||
2114 | { | 2337 | { |
2115 | Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); | 2338 | Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); |
2116 | texface.RepeatU = (float)u; | 2339 | texface.RepeatU = (float)u; |
@@ -2121,7 +2344,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2121 | } | 2344 | } |
2122 | if (face == ScriptBaseClass.ALL_SIDES) | 2345 | if (face == ScriptBaseClass.ALL_SIDES) |
2123 | { | 2346 | { |
2124 | for (int i = 0; i < GetNumberOfSides(part); i++) | 2347 | for (int i = 0; i < nsides; i++) |
2125 | { | 2348 | { |
2126 | if (tex.FaceTextures[i] != null) | 2349 | if (tex.FaceTextures[i] != null) |
2127 | { | 2350 | { |
@@ -2138,14 +2361,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2138 | 2361 | ||
2139 | public void llOffsetTexture(double u, double v, int face) | 2362 | public void llOffsetTexture(double u, double v, int face) |
2140 | { | 2363 | { |
2141 | m_host.AddScriptLPS(1); | ||
2142 | OffsetTexture(m_host, u, v, face); | 2364 | OffsetTexture(m_host, u, v, face); |
2143 | } | 2365 | } |
2144 | 2366 | ||
2145 | protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) | 2367 | protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) |
2146 | { | 2368 | { |
2369 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | ||
2370 | return; | ||
2371 | |||
2147 | Primitive.TextureEntry tex = part.Shape.Textures; | 2372 | Primitive.TextureEntry tex = part.Shape.Textures; |
2148 | if (face >= 0 && face < GetNumberOfSides(part)) | 2373 | int nsides = GetNumberOfSides(part); |
2374 | |||
2375 | if (face >= 0 && face < nsides) | ||
2149 | { | 2376 | { |
2150 | Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); | 2377 | Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); |
2151 | texface.OffsetU = (float)u; | 2378 | texface.OffsetU = (float)u; |
@@ -2156,7 +2383,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2156 | } | 2383 | } |
2157 | if (face == ScriptBaseClass.ALL_SIDES) | 2384 | if (face == ScriptBaseClass.ALL_SIDES) |
2158 | { | 2385 | { |
2159 | for (int i = 0; i < GetNumberOfSides(part); i++) | 2386 | for (int i = 0; i < nsides; i++) |
2160 | { | 2387 | { |
2161 | if (tex.FaceTextures[i] != null) | 2388 | if (tex.FaceTextures[i] != null) |
2162 | { | 2389 | { |
@@ -2173,14 +2400,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2173 | 2400 | ||
2174 | public void llRotateTexture(double rotation, int face) | 2401 | public void llRotateTexture(double rotation, int face) |
2175 | { | 2402 | { |
2176 | m_host.AddScriptLPS(1); | ||
2177 | RotateTexture(m_host, rotation, face); | 2403 | RotateTexture(m_host, rotation, face); |
2178 | } | 2404 | } |
2179 | 2405 | ||
2180 | protected void RotateTexture(SceneObjectPart part, double rotation, int face) | 2406 | protected void RotateTexture(SceneObjectPart part, double rotation, int face) |
2181 | { | 2407 | { |
2408 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | ||
2409 | return; | ||
2410 | |||
2182 | Primitive.TextureEntry tex = part.Shape.Textures; | 2411 | Primitive.TextureEntry tex = part.Shape.Textures; |
2183 | if (face >= 0 && face < GetNumberOfSides(part)) | 2412 | int nsides = GetNumberOfSides(part); |
2413 | |||
2414 | if (face >= 0 && face < nsides) | ||
2184 | { | 2415 | { |
2185 | Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); | 2416 | Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); |
2186 | texface.Rotation = (float)rotation; | 2417 | texface.Rotation = (float)rotation; |
@@ -2190,7 +2421,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2190 | } | 2421 | } |
2191 | if (face == ScriptBaseClass.ALL_SIDES) | 2422 | if (face == ScriptBaseClass.ALL_SIDES) |
2192 | { | 2423 | { |
2193 | for (int i = 0; i < GetNumberOfSides(part); i++) | 2424 | for (int i = 0; i < nsides; i++) |
2194 | { | 2425 | { |
2195 | if (tex.FaceTextures[i] != null) | 2426 | if (tex.FaceTextures[i] != null) |
2196 | { | 2427 | { |
@@ -2205,19 +2436,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2205 | 2436 | ||
2206 | public LSL_String llGetTexture(int face) | 2437 | public LSL_String llGetTexture(int face) |
2207 | { | 2438 | { |
2208 | m_host.AddScriptLPS(1); | ||
2209 | return GetTexture(m_host, face); | 2439 | return GetTexture(m_host, face); |
2210 | } | 2440 | } |
2211 | 2441 | ||
2212 | protected LSL_String GetTexture(SceneObjectPart part, int face) | 2442 | protected LSL_String GetTexture(SceneObjectPart part, int face) |
2213 | { | 2443 | { |
2214 | Primitive.TextureEntry tex = part.Shape.Textures; | 2444 | Primitive.TextureEntry tex = part.Shape.Textures; |
2445 | int nsides = GetNumberOfSides(part); | ||
2446 | |||
2215 | if (face == ScriptBaseClass.ALL_SIDES) | 2447 | if (face == ScriptBaseClass.ALL_SIDES) |
2216 | { | 2448 | { |
2217 | face = 0; | 2449 | face = 0; |
2218 | } | 2450 | } |
2219 | 2451 | ||
2220 | if (face >= 0 && face < GetNumberOfSides(part)) | 2452 | if (face >= 0 && face < nsides) |
2221 | { | 2453 | { |
2222 | Primitive.TextureEntryFace texface; | 2454 | Primitive.TextureEntryFace texface; |
2223 | texface = tex.GetFace((uint)face); | 2455 | texface = tex.GetFace((uint)face); |
@@ -2245,8 +2477,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2245 | 2477 | ||
2246 | public void llSetPos(LSL_Vector pos) | 2478 | public void llSetPos(LSL_Vector pos) |
2247 | { | 2479 | { |
2248 | m_host.AddScriptLPS(1); | ||
2249 | |||
2250 | SetPos(m_host, pos, true); | 2480 | SetPos(m_host, pos, true); |
2251 | } | 2481 | } |
2252 | 2482 | ||
@@ -2259,8 +2489,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2259 | /// <returns>1 if successful, 0 otherwise.</returns> | 2489 | /// <returns>1 if successful, 0 otherwise.</returns> |
2260 | public LSL_Integer llSetRegionPos(LSL_Vector pos) | 2490 | public LSL_Integer llSetRegionPos(LSL_Vector pos) |
2261 | { | 2491 | { |
2262 | m_host.AddScriptLPS(1); | ||
2263 | |||
2264 | // BEGIN WORKAROUND | 2492 | // BEGIN WORKAROUND |
2265 | // IF YOU GET REGION CROSSINGS WORKING WITH THIS FUNCTION, REPLACE THE WORKAROUND. | 2493 | // IF YOU GET REGION CROSSINGS WORKING WITH THIS FUNCTION, REPLACE THE WORKAROUND. |
2266 | // | 2494 | // |
@@ -2317,7 +2545,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2317 | return end; | 2545 | return end; |
2318 | } | 2546 | } |
2319 | 2547 | ||
2320 | protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos) | 2548 | protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos, bool adjust) |
2321 | { | 2549 | { |
2322 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | 2550 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) |
2323 | return fromPos; | 2551 | return fromPos; |
@@ -2333,9 +2561,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2333 | if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) | 2561 | if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) |
2334 | targetPos.z = ground; | 2562 | targetPos.z = ground; |
2335 | } | 2563 | } |
2336 | LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); | 2564 | if (adjust) |
2565 | return SetPosAdjust(fromPos, targetPos); | ||
2337 | 2566 | ||
2338 | return real_vec; | 2567 | return targetPos; |
2339 | } | 2568 | } |
2340 | 2569 | ||
2341 | /// <summary> | 2570 | /// <summary> |
@@ -2346,46 +2575,43 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2346 | /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> | 2575 | /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> |
2347 | protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) | 2576 | protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) |
2348 | { | 2577 | { |
2349 | // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) | 2578 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted || part.ParentGroup.inTransit) |
2579 | return; | ||
2580 | |||
2581 | |||
2350 | LSL_Vector currentPos = GetPartLocalPos(part); | 2582 | LSL_Vector currentPos = GetPartLocalPos(part); |
2583 | LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos, adjust); | ||
2351 | 2584 | ||
2352 | float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); | ||
2353 | bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); | ||
2354 | 2585 | ||
2355 | if (part.ParentGroup.RootPart == part) | 2586 | if (part.ParentGroup.RootPart == part) |
2356 | { | 2587 | { |
2357 | if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) | ||
2358 | targetPos.z = ground; | ||
2359 | SceneObjectGroup parent = part.ParentGroup; | 2588 | SceneObjectGroup parent = part.ParentGroup; |
2360 | parent.UpdateGroupPosition(!adjust ? targetPos : | 2589 | if (!parent.IsAttachment && !World.Permissions.CanObjectEntry(parent, false, (Vector3)toPos)) |
2361 | SetPosAdjust(currentPos, targetPos)); | 2590 | return; |
2591 | parent.UpdateGroupPosition((Vector3)toPos); | ||
2362 | } | 2592 | } |
2363 | else | 2593 | else |
2364 | { | 2594 | { |
2365 | part.OffsetPosition = !adjust ? targetPos : | 2595 | part.OffsetPosition = (Vector3)toPos; |
2366 | SetPosAdjust(currentPos, targetPos); | 2596 | // SceneObjectGroup parent = part.ParentGroup; |
2367 | SceneObjectGroup parent = part.ParentGroup; | 2597 | // parent.HasGroupChanged = true; |
2368 | parent.HasGroupChanged = true; | 2598 | // parent.ScheduleGroupForTerseUpdate(); |
2369 | parent.ScheduleGroupForTerseUpdate(); | 2599 | part.ScheduleTerseUpdate(); |
2370 | } | 2600 | } |
2371 | } | 2601 | } |
2372 | 2602 | ||
2373 | public LSL_Vector llGetPos() | 2603 | public LSL_Vector llGetPos() |
2374 | { | 2604 | { |
2375 | m_host.AddScriptLPS(1); | ||
2376 | return m_host.GetWorldPosition(); | 2605 | return m_host.GetWorldPosition(); |
2377 | } | 2606 | } |
2378 | 2607 | ||
2379 | public LSL_Vector llGetLocalPos() | 2608 | public LSL_Vector llGetLocalPos() |
2380 | { | 2609 | { |
2381 | m_host.AddScriptLPS(1); | ||
2382 | return GetPartLocalPos(m_host); | 2610 | return GetPartLocalPos(m_host); |
2383 | } | 2611 | } |
2384 | 2612 | ||
2385 | protected LSL_Vector GetPartLocalPos(SceneObjectPart part) | 2613 | protected LSL_Vector GetPartLocalPos(SceneObjectPart part) |
2386 | { | 2614 | { |
2387 | m_host.AddScriptLPS(1); | ||
2388 | |||
2389 | Vector3 pos; | 2615 | Vector3 pos; |
2390 | 2616 | ||
2391 | if (!part.IsRoot) | 2617 | if (!part.IsRoot) |
@@ -2395,13 +2621,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2395 | else | 2621 | else |
2396 | { | 2622 | { |
2397 | if (part.ParentGroup.IsAttachment) | 2623 | if (part.ParentGroup.IsAttachment) |
2398 | { | ||
2399 | pos = part.AttachedPos; | 2624 | pos = part.AttachedPos; |
2400 | } | ||
2401 | else | 2625 | else |
2402 | { | ||
2403 | pos = part.AbsolutePosition; | 2626 | pos = part.AbsolutePosition; |
2404 | } | ||
2405 | } | 2627 | } |
2406 | 2628 | ||
2407 | // m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); | 2629 | // m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); |
@@ -2411,10 +2633,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2411 | 2633 | ||
2412 | public void llSetRot(LSL_Rotation rot) | 2634 | public void llSetRot(LSL_Rotation rot) |
2413 | { | 2635 | { |
2414 | m_host.AddScriptLPS(1); | ||
2415 | |||
2416 | // try to let this work as in SL... | 2636 | // try to let this work as in SL... |
2417 | if (m_host.ParentID == 0) | 2637 | if (m_host.ParentID == 0 || (m_host.ParentGroup != null && m_host == m_host.ParentGroup.RootPart)) |
2418 | { | 2638 | { |
2419 | // special case: If we are root, rotate complete SOG to new rotation | 2639 | // special case: If we are root, rotate complete SOG to new rotation |
2420 | SetRot(m_host, rot); | 2640 | SetRot(m_host, rot); |
@@ -2432,31 +2652,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2432 | 2652 | ||
2433 | public void llSetLocalRot(LSL_Rotation rot) | 2653 | public void llSetLocalRot(LSL_Rotation rot) |
2434 | { | 2654 | { |
2435 | m_host.AddScriptLPS(1); | ||
2436 | SetRot(m_host, rot); | 2655 | SetRot(m_host, rot); |
2437 | } | 2656 | } |
2438 | 2657 | ||
2439 | protected void SetRot(SceneObjectPart part, Quaternion rot) | 2658 | protected void SetRot(SceneObjectPart part, Quaternion rot) |
2440 | { | 2659 | { |
2441 | part.UpdateRotation(rot); | 2660 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) |
2442 | // Update rotation does not move the object in the physics scene if it's a linkset. | 2661 | return; |
2443 | 2662 | ||
2444 | //KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type | 2663 | bool isroot = (part == part.ParentGroup.RootPart); |
2445 | // part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; | 2664 | bool isphys; |
2446 | 2665 | ||
2447 | // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line | ||
2448 | // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt | ||
2449 | // It's perfectly okay when the object is not an active physical body though. | ||
2450 | // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against | ||
2451 | // but only if the object is not physial and active. This is important for rotating doors. | ||
2452 | // without the absoluteposition = absoluteposition happening, the doors do not move in the physics | ||
2453 | // scene | ||
2454 | PhysicsActor pa = part.PhysActor; | 2666 | PhysicsActor pa = part.PhysActor; |
2455 | 2667 | ||
2456 | if (pa != null && !pa.IsPhysical) | 2668 | // keep using physactor ideia of isphysical |
2669 | // it should be SOP ideia of that | ||
2670 | // not much of a issue with ubOde | ||
2671 | if (pa != null && pa.IsPhysical) | ||
2672 | isphys = true; | ||
2673 | else | ||
2674 | isphys = false; | ||
2675 | |||
2676 | // SL doesn't let scripts rotate root of physical linksets | ||
2677 | if (isroot && isphys) | ||
2678 | return; | ||
2679 | |||
2680 | part.UpdateRotation(rot); | ||
2681 | |||
2682 | // Update rotation does not move the object in the physics engine if it's a non physical linkset | ||
2683 | // so do a nasty update of parts positions if is a root part rotation | ||
2684 | if (isroot && pa != null) // with if above implies non physical root part | ||
2457 | { | 2685 | { |
2458 | part.ParentGroup.ResetChildPrimPhysicsPositions(); | 2686 | part.ParentGroup.ResetChildPrimPhysicsPositions(); |
2459 | } | 2687 | } |
2688 | else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part | ||
2689 | { | ||
2690 | // List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars(); | ||
2691 | List<ScenePresence> sittingavas = part.ParentGroup.GetSittingAvatars(); | ||
2692 | if (sittingavas.Count > 0) | ||
2693 | { | ||
2694 | foreach (ScenePresence av in sittingavas) | ||
2695 | { | ||
2696 | if (isroot || part.LocalId == av.ParentID) | ||
2697 | av.SendTerseUpdateToAllClients(); | ||
2698 | } | ||
2699 | } | ||
2700 | } | ||
2460 | } | 2701 | } |
2461 | 2702 | ||
2462 | /// <summary> | 2703 | /// <summary> |
@@ -2471,8 +2712,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2471 | return llGetRootRotation(); | 2712 | return llGetRootRotation(); |
2472 | } | 2713 | } |
2473 | 2714 | ||
2474 | m_host.AddScriptLPS(1); | ||
2475 | Quaternion q = m_host.GetWorldRotation(); | 2715 | Quaternion q = m_host.GetWorldRotation(); |
2716 | |||
2717 | if (m_host.ParentGroup != null && m_host.ParentGroup.AttachmentPoint != 0) | ||
2718 | { | ||
2719 | ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar); | ||
2720 | if (avatar != null) | ||
2721 | { | ||
2722 | if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) | ||
2723 | q = avatar.CameraRotation * q; // Mouselook | ||
2724 | else | ||
2725 | q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate | ||
2726 | } | ||
2727 | } | ||
2728 | |||
2476 | return new LSL_Rotation(q.X, q.Y, q.Z, q.W); | 2729 | return new LSL_Rotation(q.X, q.Y, q.Z, q.W); |
2477 | } | 2730 | } |
2478 | 2731 | ||
@@ -2500,20 +2753,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2500 | return new LSL_Rotation(q); | 2753 | return new LSL_Rotation(q); |
2501 | } | 2754 | } |
2502 | 2755 | ||
2503 | return new LSL_Rotation(part.GetWorldRotation()); | 2756 | q = part.GetWorldRotation(); |
2757 | if (part.ParentGroup.AttachmentPoint != 0) | ||
2758 | { | ||
2759 | ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar); | ||
2760 | if (avatar != null) | ||
2761 | { | ||
2762 | if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) | ||
2763 | q = avatar.CameraRotation * q; // Mouselook | ||
2764 | else | ||
2765 | q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate | ||
2766 | } | ||
2767 | } | ||
2768 | |||
2769 | return new LSL_Rotation(q.X, q.Y, q.Z, q.W); | ||
2504 | } | 2770 | } |
2505 | 2771 | ||
2506 | public LSL_Rotation llGetLocalRot() | 2772 | public LSL_Rotation llGetLocalRot() |
2507 | { | 2773 | { |
2508 | m_host.AddScriptLPS(1); | 2774 | return GetPartLocalRot(m_host); |
2775 | } | ||
2509 | 2776 | ||
2510 | return new LSL_Rotation(m_host.RotationOffset); | 2777 | private LSL_Rotation GetPartLocalRot(SceneObjectPart part) |
2778 | { | ||
2779 | Quaternion rot = part.RotationOffset; | ||
2780 | return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W); | ||
2511 | } | 2781 | } |
2512 | 2782 | ||
2513 | public void llSetForce(LSL_Vector force, int local) | 2783 | public void llSetForce(LSL_Vector force, int local) |
2514 | { | 2784 | { |
2515 | m_host.AddScriptLPS(1); | ||
2516 | |||
2517 | if (!m_host.ParentGroup.IsDeleted) | 2785 | if (!m_host.ParentGroup.IsDeleted) |
2518 | { | 2786 | { |
2519 | if (local != 0) | 2787 | if (local != 0) |
@@ -2527,8 +2795,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2527 | { | 2795 | { |
2528 | LSL_Vector force = new LSL_Vector(0.0, 0.0, 0.0); | 2796 | LSL_Vector force = new LSL_Vector(0.0, 0.0, 0.0); |
2529 | 2797 | ||
2530 | m_host.AddScriptLPS(1); | ||
2531 | |||
2532 | if (!m_host.ParentGroup.IsDeleted) | 2798 | if (!m_host.ParentGroup.IsDeleted) |
2533 | { | 2799 | { |
2534 | force = m_host.ParentGroup.RootPart.GetForce(); | 2800 | force = m_host.ParentGroup.RootPart.GetForce(); |
@@ -2537,72 +2803,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2537 | return force; | 2803 | return force; |
2538 | } | 2804 | } |
2539 | 2805 | ||
2540 | public void llSetVelocity(LSL_Vector velocity, int local) | 2806 | public void llSetVelocity(LSL_Vector vel, int local) |
2541 | { | 2807 | { |
2542 | m_host.AddScriptLPS(1); | 2808 | m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0); |
2543 | |||
2544 | if (!m_host.ParentGroup.IsDeleted) | ||
2545 | { | ||
2546 | if (local != 0) | ||
2547 | velocity *= llGetRot(); | ||
2548 | |||
2549 | m_host.ParentGroup.RootPart.Velocity = velocity; | ||
2550 | } | ||
2551 | } | 2809 | } |
2552 | 2810 | ||
2553 | public void llSetAngularVelocity(LSL_Vector angularVelocity, int local) | 2811 | public void llSetAngularVelocity(LSL_Vector avel, int local) |
2554 | { | 2812 | { |
2555 | m_host.AddScriptLPS(1); | 2813 | m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0); |
2556 | |||
2557 | if (!m_host.ParentGroup.IsDeleted) | ||
2558 | { | ||
2559 | if (local != 0) | ||
2560 | angularVelocity *= llGetRot(); | ||
2561 | |||
2562 | m_host.ParentGroup.RootPart.AngularVelocity = angularVelocity; | ||
2563 | } | ||
2564 | } | 2814 | } |
2565 | |||
2566 | public LSL_Integer llTarget(LSL_Vector position, double range) | 2815 | public LSL_Integer llTarget(LSL_Vector position, double range) |
2567 | { | 2816 | { |
2568 | m_host.AddScriptLPS(1); | ||
2569 | return m_host.ParentGroup.registerTargetWaypoint(position, | 2817 | return m_host.ParentGroup.registerTargetWaypoint(position, |
2570 | (float)range); | 2818 | (float)range); |
2571 | } | 2819 | } |
2572 | 2820 | ||
2573 | public void llTargetRemove(int number) | 2821 | public void llTargetRemove(int number) |
2574 | { | 2822 | { |
2575 | m_host.AddScriptLPS(1); | ||
2576 | m_host.ParentGroup.unregisterTargetWaypoint(number); | 2823 | m_host.ParentGroup.unregisterTargetWaypoint(number); |
2577 | } | 2824 | } |
2578 | 2825 | ||
2579 | public LSL_Integer llRotTarget(LSL_Rotation rot, double error) | 2826 | public LSL_Integer llRotTarget(LSL_Rotation rot, double error) |
2580 | { | 2827 | { |
2581 | m_host.AddScriptLPS(1); | ||
2582 | return m_host.ParentGroup.registerRotTargetWaypoint(rot, (float)error); | 2828 | return m_host.ParentGroup.registerRotTargetWaypoint(rot, (float)error); |
2583 | } | 2829 | } |
2584 | 2830 | ||
2585 | public void llRotTargetRemove(int number) | 2831 | public void llRotTargetRemove(int number) |
2586 | { | 2832 | { |
2587 | m_host.AddScriptLPS(1); | ||
2588 | m_host.ParentGroup.unregisterRotTargetWaypoint(number); | 2833 | m_host.ParentGroup.unregisterRotTargetWaypoint(number); |
2589 | } | 2834 | } |
2590 | 2835 | ||
2591 | public void llMoveToTarget(LSL_Vector target, double tau) | 2836 | public void llMoveToTarget(LSL_Vector target, double tau) |
2592 | { | 2837 | { |
2593 | m_host.AddScriptLPS(1); | ||
2594 | m_host.MoveToTarget(target, (float)tau); | 2838 | m_host.MoveToTarget(target, (float)tau); |
2595 | } | 2839 | } |
2596 | 2840 | ||
2597 | public void llStopMoveToTarget() | 2841 | public void llStopMoveToTarget() |
2598 | { | 2842 | { |
2599 | m_host.AddScriptLPS(1); | ||
2600 | m_host.StopMoveToTarget(); | 2843 | m_host.StopMoveToTarget(); |
2601 | } | 2844 | } |
2602 | 2845 | ||
2603 | public void llApplyImpulse(LSL_Vector force, int local) | 2846 | public void llApplyImpulse(LSL_Vector force, int local) |
2604 | { | 2847 | { |
2605 | m_host.AddScriptLPS(1); | ||
2606 | //No energy force yet | 2848 | //No energy force yet |
2607 | Vector3 v = force; | 2849 | Vector3 v = force; |
2608 | if (v.Length() > 20000.0f) | 2850 | if (v.Length() > 20000.0f) |
@@ -2613,46 +2855,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2613 | m_host.ApplyImpulse(v, local != 0); | 2855 | m_host.ApplyImpulse(v, local != 0); |
2614 | } | 2856 | } |
2615 | 2857 | ||
2858 | |||
2616 | public void llApplyRotationalImpulse(LSL_Vector force, int local) | 2859 | public void llApplyRotationalImpulse(LSL_Vector force, int local) |
2617 | { | 2860 | { |
2618 | m_host.AddScriptLPS(1); | 2861 | m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0); |
2619 | m_host.ApplyAngularImpulse(force, local != 0); | ||
2620 | } | 2862 | } |
2621 | 2863 | ||
2622 | public void llSetTorque(LSL_Vector torque, int local) | 2864 | public void llSetTorque(LSL_Vector torque, int local) |
2623 | { | 2865 | { |
2624 | m_host.AddScriptLPS(1); | 2866 | m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0); |
2625 | m_host.SetAngularImpulse(torque, local != 0); | ||
2626 | } | 2867 | } |
2627 | 2868 | ||
2628 | public LSL_Vector llGetTorque() | 2869 | public LSL_Vector llGetTorque() |
2629 | { | 2870 | { |
2630 | m_host.AddScriptLPS(1); | ||
2631 | |||
2632 | return new LSL_Vector(m_host.ParentGroup.GetTorque()); | 2871 | return new LSL_Vector(m_host.ParentGroup.GetTorque()); |
2633 | } | 2872 | } |
2634 | 2873 | ||
2635 | public void llSetForceAndTorque(LSL_Vector force, LSL_Vector torque, int local) | 2874 | public void llSetForceAndTorque(LSL_Vector force, LSL_Vector torque, int local) |
2636 | { | 2875 | { |
2637 | m_host.AddScriptLPS(1); | ||
2638 | llSetForce(force, local); | 2876 | llSetForce(force, local); |
2639 | llSetTorque(torque, local); | 2877 | llSetTorque(torque, local); |
2640 | } | 2878 | } |
2641 | 2879 | ||
2880 | |||
2642 | public LSL_Vector llGetVel() | 2881 | public LSL_Vector llGetVel() |
2643 | { | 2882 | { |
2644 | m_host.AddScriptLPS(1); | 2883 | Vector3 vel = Vector3.Zero; |
2645 | |||
2646 | Vector3 vel; | ||
2647 | 2884 | ||
2648 | if (m_host.ParentGroup.IsAttachment) | 2885 | if (m_host.ParentGroup.IsAttachment) |
2649 | { | 2886 | { |
2650 | ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); | 2887 | ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); |
2651 | vel = avatar.GetWorldVelocity(); | 2888 | if (avatar != null) |
2889 | vel = avatar.GetWorldVelocity(); | ||
2652 | } | 2890 | } |
2653 | else | 2891 | else |
2654 | { | 2892 | { |
2655 | vel = m_host.Velocity; | 2893 | vel = m_host.ParentGroup.RootPart.Velocity; |
2656 | } | 2894 | } |
2657 | 2895 | ||
2658 | return new LSL_Vector(vel); | 2896 | return new LSL_Vector(vel); |
@@ -2660,54 +2898,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2660 | 2898 | ||
2661 | public LSL_Vector llGetAccel() | 2899 | public LSL_Vector llGetAccel() |
2662 | { | 2900 | { |
2663 | m_host.AddScriptLPS(1); | ||
2664 | |||
2665 | return new LSL_Vector(m_host.Acceleration); | 2901 | return new LSL_Vector(m_host.Acceleration); |
2666 | } | 2902 | } |
2667 | 2903 | ||
2668 | public LSL_Vector llGetOmega() | 2904 | public LSL_Vector llGetOmega() |
2669 | { | 2905 | { |
2670 | m_host.AddScriptLPS(1); | 2906 | Vector3 avel = m_host.AngularVelocity; |
2671 | 2907 | return new LSL_Vector(avel.X, avel.Y, avel.Z); | |
2672 | return new LSL_Vector(m_host.AngularVelocity); | ||
2673 | } | 2908 | } |
2674 | 2909 | ||
2675 | public LSL_Float llGetTimeOfDay() | 2910 | public LSL_Float llGetTimeOfDay() |
2676 | { | 2911 | { |
2677 | m_host.AddScriptLPS(1); | ||
2678 | return (double)((DateTime.Now.TimeOfDay.TotalMilliseconds / 1000) % (3600 * 4)); | 2912 | return (double)((DateTime.Now.TimeOfDay.TotalMilliseconds / 1000) % (3600 * 4)); |
2679 | } | 2913 | } |
2680 | 2914 | ||
2681 | public LSL_Float llGetWallclock() | 2915 | public LSL_Float llGetWallclock() |
2682 | { | 2916 | { |
2683 | m_host.AddScriptLPS(1); | ||
2684 | return DateTime.Now.TimeOfDay.TotalSeconds; | 2917 | return DateTime.Now.TimeOfDay.TotalSeconds; |
2685 | } | 2918 | } |
2686 | 2919 | ||
2687 | public LSL_Float llGetTime() | 2920 | public LSL_Float llGetTime() |
2688 | { | 2921 | { |
2689 | m_host.AddScriptLPS(1); | 2922 | double ScriptTime = Util.GetTimeStampMS() - m_timer; |
2690 | TimeSpan ScriptTime = DateTime.Now - m_timer; | 2923 | return (float)Math.Round((ScriptTime / 1000.0), 3); |
2691 | return (double)(ScriptTime.TotalMilliseconds / 1000); | ||
2692 | } | 2924 | } |
2693 | 2925 | ||
2694 | public void llResetTime() | 2926 | public void llResetTime() |
2695 | { | 2927 | { |
2696 | m_host.AddScriptLPS(1); | 2928 | m_timer = Util.GetTimeStampMS(); |
2697 | m_timer = DateTime.Now; | ||
2698 | } | 2929 | } |
2699 | 2930 | ||
2700 | public LSL_Float llGetAndResetTime() | 2931 | public LSL_Float llGetAndResetTime() |
2701 | { | 2932 | { |
2702 | m_host.AddScriptLPS(1); | 2933 | double now = Util.GetTimeStampMS(); |
2703 | TimeSpan ScriptTime = DateTime.Now - m_timer; | 2934 | double ScriptTime = now - m_timer; |
2704 | m_timer = DateTime.Now; | 2935 | m_timer = now; |
2705 | return (double)(ScriptTime.TotalMilliseconds / 1000); | 2936 | return (float)Math.Round((ScriptTime / 1000.0), 3); |
2706 | } | 2937 | } |
2707 | 2938 | ||
2708 | public void llSound(string sound, double volume, int queue, int loop) | 2939 | public void llSound(string sound, double volume, int queue, int loop) |
2709 | { | 2940 | { |
2710 | m_host.AddScriptLPS(1); | ||
2711 | Deprecated("llSound", "Use llPlaySound instead"); | 2941 | Deprecated("llSound", "Use llPlaySound instead"); |
2712 | } | 2942 | } |
2713 | 2943 | ||
@@ -2715,52 +2945,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2715 | // 20080530 Updated to remove code duplication | 2945 | // 20080530 Updated to remove code duplication |
2716 | public void llPlaySound(string sound, double volume) | 2946 | public void llPlaySound(string sound, double volume) |
2717 | { | 2947 | { |
2718 | m_host.AddScriptLPS(1); | ||
2719 | |||
2720 | // send the sound, once, to all clients in range | 2948 | // send the sound, once, to all clients in range |
2721 | if (m_SoundModule != null) | 2949 | if (m_SoundModule != null) |
2722 | { | 2950 | { |
2723 | m_SoundModule.SendSound( | 2951 | m_SoundModule.SendSound( |
2724 | m_host.UUID, | 2952 | m_host.UUID, |
2725 | ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), | 2953 | ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), |
2726 | volume, false, m_host.SoundQueueing ? (byte)SoundFlags.Queue : (byte)SoundFlags.None, | 2954 | volume, false, 0, |
2727 | 0, false, false); | 2955 | 0, false, false); |
2728 | } | 2956 | } |
2729 | } | 2957 | } |
2730 | 2958 | ||
2731 | public void llLoopSound(string sound, double volume) | 2959 | public void llLoopSound(string sound, double volume) |
2732 | { | 2960 | { |
2733 | m_host.AddScriptLPS(1); | ||
2734 | if (m_SoundModule != null) | 2961 | if (m_SoundModule != null) |
2735 | { | 2962 | { |
2736 | m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), | 2963 | m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), |
2737 | volume, 20, false); | 2964 | volume, 20, false,false); |
2738 | } | 2965 | } |
2739 | } | 2966 | } |
2740 | 2967 | ||
2741 | public void llLoopSoundMaster(string sound, double volume) | 2968 | public void llLoopSoundMaster(string sound, double volume) |
2742 | { | 2969 | { |
2743 | m_host.AddScriptLPS(1); | ||
2744 | if (m_SoundModule != null) | 2970 | if (m_SoundModule != null) |
2745 | { | 2971 | { |
2746 | m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), | 2972 | m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), |
2747 | volume, 20, true); | 2973 | volume, 20, true, false); |
2748 | } | 2974 | } |
2749 | } | 2975 | } |
2750 | 2976 | ||
2751 | public void llLoopSoundSlave(string sound, double volume) | 2977 | public void llLoopSoundSlave(string sound, double volume) |
2752 | { | 2978 | { |
2753 | m_host.AddScriptLPS(1); | 2979 | if (m_SoundModule != null) |
2754 | lock (m_host.ParentGroup.LoopSoundSlavePrims) | ||
2755 | { | 2980 | { |
2756 | m_host.ParentGroup.LoopSoundSlavePrims.Add(m_host); | 2981 | m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), |
2982 | volume, 20, false, true); | ||
2757 | } | 2983 | } |
2758 | } | 2984 | } |
2759 | 2985 | ||
2760 | public void llPlaySoundSlave(string sound, double volume) | 2986 | public void llPlaySoundSlave(string sound, double volume) |
2761 | { | 2987 | { |
2762 | m_host.AddScriptLPS(1); | ||
2763 | |||
2764 | // send the sound, once, to all clients in range | 2988 | // send the sound, once, to all clients in range |
2765 | if (m_SoundModule != null) | 2989 | if (m_SoundModule != null) |
2766 | { | 2990 | { |
@@ -2772,7 +2996,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2772 | 2996 | ||
2773 | public void llTriggerSound(string sound, double volume) | 2997 | public void llTriggerSound(string sound, double volume) |
2774 | { | 2998 | { |
2775 | m_host.AddScriptLPS(1); | ||
2776 | // send the sound, once, to all clients in rangeTrigger or play an attached sound in this part's inventory. | 2999 | // send the sound, once, to all clients in rangeTrigger or play an attached sound in this part's inventory. |
2777 | if (m_SoundModule != null) | 3000 | if (m_SoundModule != null) |
2778 | { | 3001 | { |
@@ -2784,15 +3007,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2784 | 3007 | ||
2785 | public void llStopSound() | 3008 | public void llStopSound() |
2786 | { | 3009 | { |
2787 | m_host.AddScriptLPS(1); | ||
2788 | |||
2789 | if (m_SoundModule != null) | 3010 | if (m_SoundModule != null) |
2790 | m_SoundModule.StopSound(m_host.UUID); | 3011 | m_SoundModule.StopSound(m_host.UUID); |
2791 | } | 3012 | } |
2792 | 3013 | ||
2793 | public void llPreloadSound(string sound) | 3014 | public void llPreloadSound(string sound) |
2794 | { | 3015 | { |
2795 | m_host.AddScriptLPS(1); | ||
2796 | if (m_SoundModule != null) | 3016 | if (m_SoundModule != null) |
2797 | m_SoundModule.PreloadSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), 0); | 3017 | m_SoundModule.PreloadSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), 0); |
2798 | } | 3018 | } |
@@ -2805,8 +3025,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2805 | /// </summary> | 3025 | /// </summary> |
2806 | public LSL_String llGetSubString(string src, int start, int end) | 3026 | public LSL_String llGetSubString(string src, int start, int end) |
2807 | { | 3027 | { |
2808 | m_host.AddScriptLPS(1); | ||
2809 | |||
2810 | // Normalize indices (if negative). | 3028 | // Normalize indices (if negative). |
2811 | // After normlaization they may still be | 3029 | // After normlaization they may still be |
2812 | // negative, but that is now relative to | 3030 | // negative, but that is now relative to |
@@ -2899,8 +3117,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2899 | /// </summary> | 3117 | /// </summary> |
2900 | public LSL_String llDeleteSubString(string src, int start, int end) | 3118 | public LSL_String llDeleteSubString(string src, int start, int end) |
2901 | { | 3119 | { |
2902 | m_host.AddScriptLPS(1); | ||
2903 | |||
2904 | // Normalize indices (if negative). | 3120 | // Normalize indices (if negative). |
2905 | // After normlaization they may still be | 3121 | // After normlaization they may still be |
2906 | // negative, but that is now relative to | 3122 | // negative, but that is now relative to |
@@ -2980,8 +3196,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2980 | /// </summary> | 3196 | /// </summary> |
2981 | public LSL_String llInsertString(string dest, int index, string src) | 3197 | public LSL_String llInsertString(string dest, int index, string src) |
2982 | { | 3198 | { |
2983 | m_host.AddScriptLPS(1); | ||
2984 | |||
2985 | // Normalize indices (if negative). | 3199 | // Normalize indices (if negative). |
2986 | // After normlaization they may still be | 3200 | // After normlaization they may still be |
2987 | // negative, but that is now relative to | 3201 | // negative, but that is now relative to |
@@ -3017,22 +3231,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3017 | 3231 | ||
3018 | public LSL_String llToUpper(string src) | 3232 | public LSL_String llToUpper(string src) |
3019 | { | 3233 | { |
3020 | m_host.AddScriptLPS(1); | ||
3021 | return src.ToUpper(); | 3234 | return src.ToUpper(); |
3022 | } | 3235 | } |
3023 | 3236 | ||
3024 | public LSL_String llToLower(string src) | 3237 | public LSL_String llToLower(string src) |
3025 | { | 3238 | { |
3026 | m_host.AddScriptLPS(1); | ||
3027 | return src.ToLower(); | 3239 | return src.ToLower(); |
3028 | } | 3240 | } |
3029 | 3241 | ||
3030 | public void llGiveMoney(string destination, int amount) | 3242 | public LSL_Integer llGiveMoney(string destination, int amount) |
3031 | { | 3243 | { |
3032 | Util.FireAndForget(x => | 3244 | Util.FireAndForget(x => |
3033 | { | 3245 | { |
3034 | m_host.AddScriptLPS(1); | ||
3035 | |||
3036 | if (m_item.PermsGranter == UUID.Zero) | 3246 | if (m_item.PermsGranter == UUID.Zero) |
3037 | return; | 3247 | return; |
3038 | 3248 | ||
@@ -3058,69 +3268,74 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3058 | return; | 3268 | return; |
3059 | } | 3269 | } |
3060 | 3270 | ||
3271 | string reason; | ||
3061 | money.ObjectGiveMoney( | 3272 | money.ObjectGiveMoney( |
3062 | m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); | 3273 | |
3274 | m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero, out reason); | ||
3063 | }, null, "LSL_Api.llGiveMoney"); | 3275 | }, null, "LSL_Api.llGiveMoney"); |
3276 | |||
3277 | return 0; | ||
3064 | } | 3278 | } |
3065 | 3279 | ||
3066 | public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) | 3280 | public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) |
3067 | { | 3281 | { |
3068 | m_host.AddScriptLPS(1); | ||
3069 | Deprecated("llMakeExplosion", "Use llParticleSystem instead"); | 3282 | Deprecated("llMakeExplosion", "Use llParticleSystem instead"); |
3070 | } | 3283 | } |
3071 | 3284 | ||
3072 | public void llMakeFountain(int particles, double scale, double vel, double lifetime, double arc, int bounce, string texture, LSL_Vector offset, double bounce_offset) | 3285 | public void llMakeFountain(int particles, double scale, double vel, double lifetime, double arc, int bounce, string texture, LSL_Vector offset, double bounce_offset) |
3073 | { | 3286 | { |
3074 | m_host.AddScriptLPS(1); | ||
3075 | Deprecated("llMakeFountain", "Use llParticleSystem instead"); | 3287 | Deprecated("llMakeFountain", "Use llParticleSystem instead"); |
3076 | } | 3288 | } |
3077 | 3289 | ||
3078 | public void llMakeSmoke(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) | 3290 | public void llMakeSmoke(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) |
3079 | { | 3291 | { |
3080 | m_host.AddScriptLPS(1); | ||
3081 | Deprecated("llMakeSmoke", "Use llParticleSystem instead"); | 3292 | Deprecated("llMakeSmoke", "Use llParticleSystem instead"); |
3082 | } | 3293 | } |
3083 | 3294 | ||
3084 | public void llMakeFire(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) | 3295 | public void llMakeFire(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) |
3085 | { | 3296 | { |
3086 | m_host.AddScriptLPS(1); | ||
3087 | Deprecated("llMakeFire", "Use llParticleSystem instead"); | 3297 | Deprecated("llMakeFire", "Use llParticleSystem instead"); |
3088 | } | 3298 | } |
3089 | 3299 | ||
3090 | public void llRezAtRoot(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param) | 3300 | public void llRezAtRoot(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param) |
3091 | { | 3301 | { |
3092 | m_host.AddScriptLPS(1); | 3302 | doObjectRez(inventory, pos, vel, rot, param, true); |
3303 | } | ||
3093 | 3304 | ||
3094 | Util.FireAndForget(x => | 3305 | public void doObjectRez(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param, bool atRoot) |
3095 | { | 3306 | { |
3096 | if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s)) | 3307 | if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s)) |
3097 | return; | 3308 | return; |
3098 | 3309 | ||
3099 | float dist = (float)llVecDist(llGetPos(), pos); | 3310 | float dist = (float)llVecDist(llGetPos(), pos); |
3100 | 3311 | ||
3101 | TaskInventoryItem item = m_host.Inventory.GetInventoryItem(inventory); | 3312 | TaskInventoryItem item = m_host.Inventory.GetInventoryItem(inventory); |
3102 | 3313 | ||
3103 | if (item == null) | 3314 | if (item == null) |
3104 | { | 3315 | { |
3105 | Error("llRezAtRoot", "Can't find object '" + inventory + "'"); | 3316 | Error("llRez(AtRoot/Object)", "Can't find object '" + inventory + "'"); |
3106 | return; | 3317 | return; |
3107 | } | 3318 | } |
3108 | 3319 | ||
3109 | if (item.InvType != (int)InventoryType.Object) | 3320 | if (item.InvType != (int)InventoryType.Object) |
3110 | { | 3321 | { |
3111 | Error("llRezAtRoot", "Can't create requested object; object is missing from database"); | 3322 | Error("llRez(AtRoot/Object)", "Can't create requested object; object is missing from database"); |
3112 | return; | 3323 | return; |
3113 | } | 3324 | } |
3114 | 3325 | ||
3115 | // need the magnitude later | 3326 | Util.FireAndForget(x => |
3116 | // float velmag = (float)Util.GetMagnitude(llvel); | 3327 | { |
3117 | 3328 | ||
3118 | List<SceneObjectGroup> new_groups = World.RezObject(m_host, item, pos, rot, vel, param); | 3329 | Quaternion wrot = rot; |
3330 | wrot.Normalize(); | ||
3331 | List<SceneObjectGroup> new_groups = World.RezObject(m_host, item, pos, wrot, vel, param, atRoot); | ||
3119 | 3332 | ||
3120 | // If either of these are null, then there was an unknown error. | 3333 | // If either of these are null, then there was an unknown error. |
3121 | if (new_groups == null) | 3334 | if (new_groups == null) |
3122 | return; | 3335 | return; |
3123 | 3336 | ||
3337 | bool notAttachment = !m_host.ParentGroup.IsAttachment; | ||
3338 | |||
3124 | foreach (SceneObjectGroup group in new_groups) | 3339 | foreach (SceneObjectGroup group in new_groups) |
3125 | { | 3340 | { |
3126 | // objects rezzed with this method are die_at_edge by default. | 3341 | // objects rezzed with this method are die_at_edge by default. |
@@ -3134,64 +3349,80 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3134 | group.RootPart.UUID.ToString()) }, | 3349 | group.RootPart.UUID.ToString()) }, |
3135 | new DetectParams[0])); | 3350 | new DetectParams[0])); |
3136 | 3351 | ||
3137 | float groupmass = group.GetMass(); | 3352 | if (notAttachment) |
3353 | { | ||
3354 | float groupmass = group.GetMass(); | ||
3138 | 3355 | ||
3139 | PhysicsActor pa = group.RootPart.PhysActor; | 3356 | PhysicsActor pa = group.RootPart.PhysActor; |
3140 | 3357 | ||
3141 | //Recoil. | 3358 | //Recoil. |
3142 | if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) | 3359 | if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) |
3143 | { | ||
3144 | Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; | ||
3145 | if (recoil != Vector3.Zero) | ||
3146 | { | 3360 | { |
3147 | llApplyImpulse(recoil, 0); | 3361 | Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; |
3362 | if (recoil != Vector3.Zero) | ||
3363 | { | ||
3364 | llApplyImpulse(recoil, 0); | ||
3365 | } | ||
3148 | } | 3366 | } |
3149 | } | 3367 | } |
3150 | // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) | 3368 | } |
3151 | } | 3369 | }, null, "LSL_Api.doObjectRez"); |
3152 | }, null, "LSL_Api.llRezAtRoot"); | 3370 | |
3153 | } | 3371 | } |
3154 | 3372 | ||
3155 | public void llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param) | 3373 | public void llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param) |
3156 | { | 3374 | { |
3157 | llRezAtRoot(inventory, pos, vel, rot, param); | 3375 | doObjectRez(inventory, pos, vel, rot, param, false); |
3158 | } | 3376 | } |
3159 | 3377 | ||
3160 | public void llLookAt(LSL_Vector target, double strength, double damping) | 3378 | public void llLookAt(LSL_Vector target, double strength, double damping) |
3161 | { | 3379 | { |
3162 | m_host.AddScriptLPS(1); | 3380 | // Get the normalized vector to the target |
3163 | // Determine where we are looking from | ||
3164 | LSL_Vector from = llGetPos(); | 3381 | LSL_Vector from = llGetPos(); |
3165 | 3382 | ||
3166 | // normalized direction to target | 3383 | // normalized direction to target |
3167 | LSL_Vector dir = llVecNorm(target - from); | 3384 | LSL_Vector dir = llVecNorm(target - from); |
3385 | |||
3168 | // use vertical to help compute left axis | 3386 | // use vertical to help compute left axis |
3169 | LSL_Vector up = new LSL_Vector(0.0, 0.0, 1.0); | 3387 | // LSL_Vector up = new LSL_Vector(0.0, 0.0, 1.0); |
3170 | // find normalized left axis parallel to horizon | 3388 | // find normalized left axis parallel to horizon |
3171 | LSL_Vector left = llVecNorm(LSL_Vector.Cross(up, dir)); | 3389 | // LSL_Vector left = llVecNorm(LSL_Vector.Cross(up, dir)); |
3390 | |||
3391 | LSL_Vector left = new LSL_Vector(-dir.y, dir.x, 0.0f); | ||
3392 | left = llVecNorm(left); | ||
3172 | // make up orthogonal to left and dir | 3393 | // make up orthogonal to left and dir |
3173 | up = LSL_Vector.Cross(dir, left); | 3394 | LSL_Vector up = LSL_Vector.Cross(dir, left); |
3174 | 3395 | ||
3175 | // compute rotation based on orthogonal axes | 3396 | // compute rotation based on orthogonal axes |
3397 | // and rotate so Z points to target with X below horizont | ||
3176 | LSL_Rotation rot = new LSL_Rotation(0.0, 0.707107, 0.0, 0.707107) * llAxes2Rot(dir, left, up); | 3398 | LSL_Rotation rot = new LSL_Rotation(0.0, 0.707107, 0.0, 0.707107) * llAxes2Rot(dir, left, up); |
3177 | 3399 | ||
3178 | // Per discussion with Melanie, for non-physical objects llLookAt appears to simply | 3400 | SceneObjectGroup sog = m_host.ParentGroup; |
3179 | // set the rotation of the object, copy that behavior | 3401 | if(sog == null || sog.IsDeleted) |
3180 | PhysicsActor pa = m_host.PhysActor; | 3402 | return; |
3181 | 3403 | ||
3182 | if (m_host.ParentGroup.IsAttachment || strength == 0 || pa == null || !pa.IsPhysical) | 3404 | if (!sog.UsesPhysics || sog.IsAttachment) |
3183 | { | 3405 | { |
3184 | llSetRot(rot); | 3406 | // Do nothing if either value is 0 (this has been checked in SL) |
3407 | if (strength <= 0.0 || damping <= 0.0) | ||
3408 | return; | ||
3409 | |||
3410 | llSetLocalRot(rot); | ||
3185 | } | 3411 | } |
3186 | else | 3412 | else |
3187 | { | 3413 | { |
3188 | m_host.StartLookAt(rot, (float)strength, (float)damping); | 3414 | if (strength == 0) |
3415 | { | ||
3416 | llSetLocalRot(rot); | ||
3417 | return; | ||
3418 | } | ||
3419 | |||
3420 | sog.StartLookAt(rot, (float)strength, (float)damping); | ||
3189 | } | 3421 | } |
3190 | } | 3422 | } |
3191 | 3423 | ||
3192 | public void llStopLookAt() | 3424 | public void llStopLookAt() |
3193 | { | 3425 | { |
3194 | m_host.AddScriptLPS(1); | ||
3195 | m_host.StopLookAt(); | 3426 | m_host.StopLookAt(); |
3196 | } | 3427 | } |
3197 | 3428 | ||
@@ -3199,7 +3430,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3199 | { | 3430 | { |
3200 | if (sec != 0.0 && sec < m_MinTimerInterval) | 3431 | if (sec != 0.0 && sec < m_MinTimerInterval) |
3201 | sec = m_MinTimerInterval; | 3432 | sec = m_MinTimerInterval; |
3202 | m_host.AddScriptLPS(1); | ||
3203 | // Setting timer repeat | 3433 | // Setting timer repeat |
3204 | AsyncCommands.TimerPlugin.SetTimerEvent(m_host.LocalId, m_item.ItemID, sec); | 3434 | AsyncCommands.TimerPlugin.SetTimerEvent(m_host.LocalId, m_item.ItemID, sec); |
3205 | } | 3435 | } |
@@ -3207,15 +3437,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3207 | public virtual void llSleep(double sec) | 3437 | public virtual void llSleep(double sec) |
3208 | { | 3438 | { |
3209 | // m_log.Info("llSleep snoozing " + sec + "s."); | 3439 | // m_log.Info("llSleep snoozing " + sec + "s."); |
3210 | m_host.AddScriptLPS(1); | ||
3211 | |||
3212 | Sleep((int)(sec * 1000)); | 3440 | Sleep((int)(sec * 1000)); |
3213 | } | 3441 | } |
3214 | 3442 | ||
3215 | public LSL_Float llGetMass() | 3443 | public LSL_Float llGetMass() |
3216 | { | 3444 | { |
3217 | m_host.AddScriptLPS(1); | ||
3218 | |||
3219 | if (m_host.ParentGroup.IsAttachment) | 3445 | if (m_host.ParentGroup.IsAttachment) |
3220 | { | 3446 | { |
3221 | ScenePresence attachedAvatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar); | 3447 | ScenePresence attachedAvatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar); |
@@ -3231,27 +3457,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3231 | } | 3457 | } |
3232 | else | 3458 | else |
3233 | { | 3459 | { |
3234 | if (m_host.IsRoot) | 3460 | // new SL always returns object mass |
3235 | { | 3461 | // if (m_host.IsRoot) |
3462 | // { | ||
3236 | return m_host.ParentGroup.GetMass(); | 3463 | return m_host.ParentGroup.GetMass(); |
3237 | } | 3464 | // } |
3238 | else | 3465 | // else |
3239 | { | 3466 | // { |
3240 | return m_host.GetMass(); | 3467 | // return m_host.GetMass(); |
3241 | } | 3468 | // } |
3242 | } | 3469 | } |
3243 | } | 3470 | } |
3244 | 3471 | ||
3245 | public LSL_Float llGetMassMKS() | 3472 | public LSL_Float llGetMassMKS() |
3246 | { | 3473 | { |
3247 | // this is what the wiki says it does! | 3474 | return 100f * llGetMass(); |
3248 | // http://wiki.secondlife.com/wiki/LlGetMassMKS | ||
3249 | return llGetMass() * 100.0; | ||
3250 | } | 3475 | } |
3251 | 3476 | ||
3252 | public void llCollisionFilter(string name, string id, int accept) | 3477 | public void llCollisionFilter(string name, string id, int accept) |
3253 | { | 3478 | { |
3254 | m_host.AddScriptLPS(1); | ||
3255 | m_host.CollisionFilter.Clear(); | 3479 | m_host.CollisionFilter.Clear(); |
3256 | UUID objectID; | 3480 | UUID objectID; |
3257 | 3481 | ||
@@ -3278,14 +3502,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3278 | } | 3502 | } |
3279 | } | 3503 | } |
3280 | } | 3504 | } |
3281 | |||
3282 | m_host.AddScriptLPS(1); | ||
3283 | } | 3505 | } |
3284 | 3506 | ||
3285 | public void llReleaseControls() | 3507 | public void llReleaseControls() |
3286 | { | 3508 | { |
3287 | m_host.AddScriptLPS(1); | ||
3288 | |||
3289 | if (m_item.PermsGranter != UUID.Zero) | 3509 | if (m_item.PermsGranter != UUID.Zero) |
3290 | { | 3510 | { |
3291 | ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); | 3511 | ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); |
@@ -3296,7 +3516,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3296 | { | 3516 | { |
3297 | // Unregister controls from Presence | 3517 | // Unregister controls from Presence |
3298 | presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); | 3518 | presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); |
3299 | // Remove Take Control permission. | 3519 | // Remove Take Control permission. |
3300 | m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS; | 3520 | m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS; |
3301 | } | 3521 | } |
3302 | } | 3522 | } |
@@ -3305,7 +3525,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3305 | 3525 | ||
3306 | public void llReleaseURL(string url) | 3526 | public void llReleaseURL(string url) |
3307 | { | 3527 | { |
3308 | m_host.AddScriptLPS(1); | ||
3309 | if (m_UrlModule != null) | 3528 | if (m_UrlModule != null) |
3310 | m_UrlModule.ReleaseURL(url); | 3529 | m_UrlModule.ReleaseURL(url); |
3311 | } | 3530 | } |
@@ -3353,11 +3572,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3353 | 3572 | ||
3354 | public void llAttachToAvatar(int attachmentPoint) | 3573 | public void llAttachToAvatar(int attachmentPoint) |
3355 | { | 3574 | { |
3356 | m_host.AddScriptLPS(1); | ||
3357 | |||
3358 | // if (m_host.ParentGroup.RootPart.AttachmentPoint == 0) | ||
3359 | // return; | ||
3360 | |||
3361 | if (m_item.PermsGranter != m_host.OwnerID) | 3575 | if (m_item.PermsGranter != m_host.OwnerID) |
3362 | return; | 3576 | return; |
3363 | 3577 | ||
@@ -3367,8 +3581,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3367 | 3581 | ||
3368 | public void llDetachFromAvatar() | 3582 | public void llDetachFromAvatar() |
3369 | { | 3583 | { |
3370 | m_host.AddScriptLPS(1); | ||
3371 | |||
3372 | if (m_host.ParentGroup.AttachmentPoint == 0) | 3584 | if (m_host.ParentGroup.AttachmentPoint == 0) |
3373 | return; | 3585 | return; |
3374 | 3586 | ||
@@ -3381,26 +3593,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3381 | 3593 | ||
3382 | public void llTakeCamera(string avatar) | 3594 | public void llTakeCamera(string avatar) |
3383 | { | 3595 | { |
3384 | m_host.AddScriptLPS(1); | ||
3385 | Deprecated("llTakeCamera", "Use llSetCameraParams instead"); | 3596 | Deprecated("llTakeCamera", "Use llSetCameraParams instead"); |
3386 | } | 3597 | } |
3387 | 3598 | ||
3388 | public void llReleaseCamera(string avatar) | 3599 | public void llReleaseCamera(string avatar) |
3389 | { | 3600 | { |
3390 | m_host.AddScriptLPS(1); | ||
3391 | Deprecated("llReleaseCamera", "Use llClearCameraParams instead"); | 3601 | Deprecated("llReleaseCamera", "Use llClearCameraParams instead"); |
3392 | } | 3602 | } |
3393 | 3603 | ||
3394 | public LSL_String llGetOwner() | 3604 | public LSL_String llGetOwner() |
3395 | { | 3605 | { |
3396 | m_host.AddScriptLPS(1); | ||
3397 | |||
3398 | return m_host.OwnerID.ToString(); | 3606 | return m_host.OwnerID.ToString(); |
3399 | } | 3607 | } |
3400 | 3608 | ||
3401 | public void llInstantMessage(string user, string message) | 3609 | public void llInstantMessage(string user, string message) |
3402 | { | 3610 | { |
3403 | m_host.AddScriptLPS(1); | 3611 | UUID result; |
3612 | if (!UUID.TryParse(user, out result) || result == UUID.Zero) | ||
3613 | { | ||
3614 | Error("llInstantMessage","An invalid key was passed to llInstantMessage"); | ||
3615 | //// ScriptSleep(2000); | ||
3616 | return; | ||
3617 | } | ||
3404 | 3618 | ||
3405 | // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. | 3619 | // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. |
3406 | // InstantMessageModule.OnInstantMessage searches through a list of scenes for a client matching the toAgent, | 3620 | // InstantMessageModule.OnInstantMessage searches through a list of scenes for a client matching the toAgent, |
@@ -3411,31 +3625,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3411 | 3625 | ||
3412 | // TODO: figure out values for client, fromSession, and imSessionID | 3626 | // TODO: figure out values for client, fromSession, and imSessionID |
3413 | // client.SendInstantMessage(m_host.UUID, fromSession, message, user, imSessionID, m_host.Name, AgentManager.InstantMessageDialog.MessageFromAgent, (uint)Util.UnixTimeSinceEpoch()); | 3627 | // client.SendInstantMessage(m_host.UUID, fromSession, message, user, imSessionID, m_host.Name, AgentManager.InstantMessageDialog.MessageFromAgent, (uint)Util.UnixTimeSinceEpoch()); |
3628 | UUID friendTransactionID = UUID.Random(); | ||
3629 | |||
3630 | //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); | ||
3414 | 3631 | ||
3415 | GridInstantMessage msg = new GridInstantMessage(); | 3632 | GridInstantMessage msg = new GridInstantMessage(); |
3416 | msg.fromAgentID = new Guid(m_host.OwnerID.ToString()); // fromAgentID.Guid; | 3633 | msg.fromAgentID = new Guid(m_host.OwnerID.ToString()); // fromAgentID.Guid; |
3417 | msg.toAgentID = new Guid(user); // toAgentID.Guid; | 3634 | msg.toAgentID = new Guid(user); // toAgentID.Guid; |
3418 | msg.imSessionID = new Guid(m_host.UUID.ToString()); // This is the item we're mucking with here | 3635 | msg.imSessionID = new Guid(m_host.UUID.ToString()); // This is the item we're mucking with here |
3419 | // m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); | 3636 | msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); |
3420 | // m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); | 3637 | msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; |
3421 | msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; | 3638 | |
3422 | //if (client != null) | ||
3423 | //{ | ||
3424 | msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; | ||
3425 | //} | ||
3426 | //else | ||
3427 | //{ | ||
3428 | // msg.fromAgentName = "(hippos)";// Added for posterity. This means that we can't figure out who sent it | ||
3429 | //} | ||
3430 | // Cap the message length at 1024. | ||
3431 | if (message != null && message.Length > 1024) | 3639 | if (message != null && message.Length > 1024) |
3432 | msg.message = message.Substring(0, 1024); | 3640 | msg.message = message.Substring(0, 1024); |
3433 | else | 3641 | else |
3434 | msg.message = message; | 3642 | msg.message = message; |
3435 | msg.dialog = (byte)19; // messgage from script ??? // dialog; | 3643 | msg.dialog = (byte)19; // MessageFromObject |
3436 | msg.fromGroup = false;// fromGroup; | 3644 | msg.fromGroup = false;// fromGroup; |
3437 | msg.offline = (byte)0; //offline; | 3645 | msg.offline = (byte)0; //offline; |
3438 | msg.ParentEstateID = 0; //ParentEstateID; | 3646 | msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID; |
3439 | msg.Position = new Vector3(m_host.AbsolutePosition); | 3647 | msg.Position = new Vector3(m_host.AbsolutePosition); |
3440 | msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; | 3648 | msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; |
3441 | 3649 | ||
@@ -3456,7 +3664,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3456 | 3664 | ||
3457 | public void llEmail(string address, string subject, string message) | 3665 | public void llEmail(string address, string subject, string message) |
3458 | { | 3666 | { |
3459 | m_host.AddScriptLPS(1); | ||
3460 | IEmailModule emailModule = m_ScriptEngine.World.RequestModuleInterface<IEmailModule>(); | 3667 | IEmailModule emailModule = m_ScriptEngine.World.RequestModuleInterface<IEmailModule>(); |
3461 | if (emailModule == null) | 3668 | if (emailModule == null) |
3462 | { | 3669 | { |
@@ -3489,11 +3696,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3489 | } | 3696 | } |
3490 | 3697 | ||
3491 | emailModule.SendEmail(m_host.UUID, address, subject, message); | 3698 | emailModule.SendEmail(m_host.UUID, address, subject, message); |
3699 | //// ScriptSleep(m_sleepMsOnEmail); | ||
3492 | } | 3700 | } |
3493 | 3701 | ||
3494 | public void llGetNextEmail(string address, string subject) | 3702 | public void llGetNextEmail(string address, string subject) |
3495 | { | 3703 | { |
3496 | m_host.AddScriptLPS(1); | ||
3497 | IEmailModule emailModule = m_ScriptEngine.World.RequestModuleInterface<IEmailModule>(); | 3704 | IEmailModule emailModule = m_ScriptEngine.World.RequestModuleInterface<IEmailModule>(); |
3498 | if (emailModule == null) | 3705 | if (emailModule == null) |
3499 | { | 3706 | { |
@@ -3521,20 +3728,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3521 | 3728 | ||
3522 | public LSL_String llGetKey() | 3729 | public LSL_String llGetKey() |
3523 | { | 3730 | { |
3524 | m_host.AddScriptLPS(1); | ||
3525 | return m_host.UUID.ToString(); | 3731 | return m_host.UUID.ToString(); |
3526 | } | 3732 | } |
3527 | 3733 | ||
3528 | public LSL_Key llGenerateKey() | 3734 | public LSL_Key llGenerateKey() |
3529 | { | 3735 | { |
3530 | m_host.AddScriptLPS(1); | ||
3531 | return UUID.Random().ToString(); | 3736 | return UUID.Random().ToString(); |
3532 | } | 3737 | } |
3533 | 3738 | ||
3534 | public void llSetBuoyancy(double buoyancy) | 3739 | public void llSetBuoyancy(double buoyancy) |
3535 | { | 3740 | { |
3536 | m_host.AddScriptLPS(1); | ||
3537 | |||
3538 | if (!m_host.ParentGroup.IsDeleted) | 3741 | if (!m_host.ParentGroup.IsDeleted) |
3539 | { | 3742 | { |
3540 | m_host.ParentGroup.RootPart.SetBuoyancy((float)buoyancy); | 3743 | m_host.ParentGroup.RootPart.SetBuoyancy((float)buoyancy); |
@@ -3549,32 +3752,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3549 | /// <param name="tau">Number of seconds over which to reach target</param> | 3752 | /// <param name="tau">Number of seconds over which to reach target</param> |
3550 | public void llSetHoverHeight(double height, int water, double tau) | 3753 | public void llSetHoverHeight(double height, int water, double tau) |
3551 | { | 3754 | { |
3552 | m_host.AddScriptLPS(1); | 3755 | PIDHoverType hoverType = PIDHoverType.Ground; |
3553 | 3756 | if (water != 0) | |
3554 | if (m_host.PhysActor != null) | ||
3555 | { | 3757 | { |
3556 | PIDHoverType hoverType = PIDHoverType.Ground; | 3758 | hoverType = PIDHoverType.GroundAndWater; |
3557 | if (water != 0) | ||
3558 | { | ||
3559 | hoverType = PIDHoverType.GroundAndWater; | ||
3560 | } | ||
3561 | |||
3562 | m_host.SetHoverHeight((float)height, hoverType, (float)tau); | ||
3563 | } | 3759 | } |
3760 | m_host.SetHoverHeight((float)height, hoverType, (float)tau); | ||
3564 | } | 3761 | } |
3565 | 3762 | ||
3566 | public void llStopHover() | 3763 | public void llStopHover() |
3567 | { | 3764 | { |
3568 | m_host.AddScriptLPS(1); | 3765 | m_host.SetHoverHeight(0f, PIDHoverType.Ground, 0f); |
3569 | if (m_host.PhysActor != null) | ||
3570 | { | ||
3571 | m_host.SetHoverHeight(0f, PIDHoverType.Ground, 0f); | ||
3572 | } | ||
3573 | } | 3766 | } |
3574 | 3767 | ||
3575 | public void llMinEventDelay(double delay) | 3768 | public void llMinEventDelay(double delay) |
3576 | { | 3769 | { |
3577 | m_host.AddScriptLPS(1); | ||
3578 | try | 3770 | try |
3579 | { | 3771 | { |
3580 | m_ScriptEngine.SetMinEventDelay(m_item.ItemID, delay); | 3772 | m_ScriptEngine.SetMinEventDelay(m_item.ItemID, delay); |
@@ -3588,31 +3780,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3588 | 3780 | ||
3589 | public void llSoundPreload(string sound) | 3781 | public void llSoundPreload(string sound) |
3590 | { | 3782 | { |
3591 | m_host.AddScriptLPS(1); | ||
3592 | Deprecated("llSoundPreload", "Use llPreloadSound instead"); | 3783 | Deprecated("llSoundPreload", "Use llPreloadSound instead"); |
3593 | } | 3784 | } |
3594 | 3785 | ||
3595 | public void llRotLookAt(LSL_Rotation target, double strength, double damping) | 3786 | public void llRotLookAt(LSL_Rotation target, double strength, double damping) |
3596 | { | 3787 | { |
3597 | m_host.AddScriptLPS(1); | ||
3598 | |||
3599 | // Per discussion with Melanie, for non-physical objects llLookAt appears to simply | 3788 | // Per discussion with Melanie, for non-physical objects llLookAt appears to simply |
3600 | // set the rotation of the object, copy that behavior | 3789 | // set the rotation of the object, copy that behavior |
3601 | PhysicsActor pa = m_host.PhysActor; | 3790 | SceneObjectGroup sog = m_host.ParentGroup; |
3791 | if(sog == null || sog.IsDeleted) | ||
3792 | return; | ||
3602 | 3793 | ||
3603 | if (strength == 0 || pa == null || !pa.IsPhysical) | 3794 | if (strength == 0 || !sog.UsesPhysics || sog.IsAttachment) |
3604 | { | 3795 | { |
3605 | llSetLocalRot(target); | 3796 | llSetLocalRot(target); |
3606 | } | 3797 | } |
3607 | else | 3798 | else |
3608 | { | 3799 | { |
3609 | m_host.RotLookAt(target, (float)strength, (float)damping); | 3800 | sog.RotLookAt(target, (float)strength, (float)damping); |
3610 | } | 3801 | } |
3611 | } | 3802 | } |
3612 | 3803 | ||
3613 | public LSL_Integer llStringLength(string str) | 3804 | public LSL_Integer llStringLength(string str) |
3614 | { | 3805 | { |
3615 | m_host.AddScriptLPS(1); | ||
3616 | if (str.Length > 0) | 3806 | if (str.Length > 0) |
3617 | { | 3807 | { |
3618 | return str.Length; | 3808 | return str.Length; |
@@ -3625,8 +3815,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3625 | 3815 | ||
3626 | public void llStartAnimation(string anim) | 3816 | public void llStartAnimation(string anim) |
3627 | { | 3817 | { |
3628 | m_host.AddScriptLPS(1); | ||
3629 | |||
3630 | if (m_item.PermsGranter == UUID.Zero) | 3818 | if (m_item.PermsGranter == UUID.Zero) |
3631 | return; | 3819 | return; |
3632 | 3820 | ||
@@ -3648,8 +3836,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3648 | 3836 | ||
3649 | public void llStopAnimation(string anim) | 3837 | public void llStopAnimation(string anim) |
3650 | { | 3838 | { |
3651 | m_host.AddScriptLPS(1); | ||
3652 | |||
3653 | if (m_item.PermsGranter == UUID.Zero) | 3839 | if (m_item.PermsGranter == UUID.Zero) |
3654 | return; | 3840 | return; |
3655 | 3841 | ||
@@ -3671,17 +3857,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3671 | 3857 | ||
3672 | public void llPointAt(LSL_Vector pos) | 3858 | public void llPointAt(LSL_Vector pos) |
3673 | { | 3859 | { |
3674 | m_host.AddScriptLPS(1); | ||
3675 | } | 3860 | } |
3676 | 3861 | ||
3677 | public void llStopPointAt() | 3862 | public void llStopPointAt() |
3678 | { | 3863 | { |
3679 | m_host.AddScriptLPS(1); | ||
3680 | } | 3864 | } |
3681 | 3865 | ||
3682 | public void llTargetOmega(LSL_Vector axis, double spinrate, double gain) | 3866 | public void llTargetOmega(LSL_Vector axis, double spinrate, double gain) |
3683 | { | 3867 | { |
3684 | m_host.AddScriptLPS(1); | ||
3685 | TargetOmega(m_host, axis, spinrate, gain); | 3868 | TargetOmega(m_host, axis, spinrate, gain); |
3686 | } | 3869 | } |
3687 | 3870 | ||
@@ -3695,7 +3878,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3695 | 3878 | ||
3696 | public LSL_Integer llGetStartParameter() | 3879 | public LSL_Integer llGetStartParameter() |
3697 | { | 3880 | { |
3698 | m_host.AddScriptLPS(1); | ||
3699 | return m_ScriptEngine.GetStartParameter(m_item.ItemID); | 3881 | return m_ScriptEngine.GetStartParameter(m_item.ItemID); |
3700 | } | 3882 | } |
3701 | 3883 | ||
@@ -3724,8 +3906,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3724 | if (m_item.PermsGranter != agentID || (perm & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) | 3906 | if (m_item.PermsGranter != agentID || (perm & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) |
3725 | llReleaseControls(); | 3907 | llReleaseControls(); |
3726 | 3908 | ||
3727 | m_host.AddScriptLPS(1); | ||
3728 | |||
3729 | int implicitPerms = 0; | 3909 | int implicitPerms = 0; |
3730 | 3910 | ||
3731 | if (m_host.ParentGroup.IsAttachment && (UUID)agent == m_host.ParentGroup.AttachedAvatar) | 3911 | if (m_host.ParentGroup.IsAttachment && (UUID)agent == m_host.ParentGroup.AttachedAvatar) |
@@ -3735,7 +3915,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3735 | ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | | 3915 | ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | |
3736 | ScriptBaseClass.PERMISSION_CONTROL_CAMERA | | 3916 | ScriptBaseClass.PERMISSION_CONTROL_CAMERA | |
3737 | ScriptBaseClass.PERMISSION_TRACK_CAMERA | | 3917 | ScriptBaseClass.PERMISSION_TRACK_CAMERA | |
3738 | ScriptBaseClass.PERMISSION_ATTACH; | 3918 | ScriptBaseClass.PERMISSION_ATTACH | |
3919 | ScriptBaseClass.PERMISSION_OVERRIDE_ANIMATIONS; | ||
3739 | } | 3920 | } |
3740 | else | 3921 | else |
3741 | { | 3922 | { |
@@ -3752,15 +3933,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3752 | if (World.GetExtraSetting("auto_grant_attach_perms") == "true") | 3933 | if (World.GetExtraSetting("auto_grant_attach_perms") == "true") |
3753 | implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; | 3934 | implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; |
3754 | } | 3935 | } |
3936 | if (World.GetExtraSetting("auto_grant_all_perms") == "true") | ||
3937 | { | ||
3938 | implicitPerms = perm; | ||
3939 | } | ||
3755 | } | 3940 | } |
3756 | 3941 | ||
3757 | if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms | 3942 | if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms |
3758 | { | 3943 | { |
3759 | lock (m_host.TaskInventory) | 3944 | m_host.TaskInventory.LockItemsForWrite(true); |
3760 | { | 3945 | m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; |
3761 | m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; | 3946 | m_host.TaskInventory[m_item.ItemID].PermsMask = perm; |
3762 | m_host.TaskInventory[m_item.ItemID].PermsMask = perm; | 3947 | m_host.TaskInventory.LockItemsForWrite(false); |
3763 | } | ||
3764 | 3948 | ||
3765 | m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( | 3949 | m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( |
3766 | "run_time_permissions", new Object[] { | 3950 | "run_time_permissions", new Object[] { |
@@ -3771,7 +3955,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3771 | } | 3955 | } |
3772 | 3956 | ||
3773 | ScenePresence presence = World.GetScenePresence(agentID); | 3957 | ScenePresence presence = World.GetScenePresence(agentID); |
3774 | 3958 | ||
3775 | if (presence != null) | 3959 | if (presence != null) |
3776 | { | 3960 | { |
3777 | // If permissions are being requested from an NPC and were not implicitly granted above then | 3961 | // If permissions are being requested from an NPC and were not implicitly granted above then |
@@ -3804,11 +3988,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3804 | 3988 | ||
3805 | if (!m_waitingForScriptAnswer) | 3989 | if (!m_waitingForScriptAnswer) |
3806 | { | 3990 | { |
3807 | lock (m_host.TaskInventory) | 3991 | m_host.TaskInventory.LockItemsForWrite(true); |
3808 | { | 3992 | m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; |
3809 | m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; | 3993 | m_host.TaskInventory[m_item.ItemID].PermsMask = 0; |
3810 | m_host.TaskInventory[m_item.ItemID].PermsMask = 0; | 3994 | m_host.TaskInventory.LockItemsForWrite(false); |
3811 | } | ||
3812 | 3995 | ||
3813 | presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; | 3996 | presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; |
3814 | m_waitingForScriptAnswer=true; | 3997 | m_waitingForScriptAnswer=true; |
@@ -3837,27 +4020,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3837 | if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) | 4020 | if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) |
3838 | llReleaseControls(); | 4021 | llReleaseControls(); |
3839 | 4022 | ||
3840 | lock (m_host.TaskInventory) | 4023 | m_host.TaskInventory.LockItemsForWrite(true); |
3841 | { | 4024 | m_host.TaskInventory[m_item.ItemID].PermsMask = answer; |
3842 | m_host.TaskInventory[m_item.ItemID].PermsMask = answer; | 4025 | m_host.TaskInventory.LockItemsForWrite(false); |
3843 | } | ||
3844 | 4026 | ||
3845 | m_ScriptEngine.PostScriptEvent( | 4027 | m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( |
3846 | m_item.ItemID, | 4028 | "run_time_permissions", new Object[] { |
3847 | new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); | 4029 | new LSL_Integer(answer) }, |
4030 | new DetectParams[0])); | ||
3848 | } | 4031 | } |
3849 | 4032 | ||
3850 | public LSL_String llGetPermissionsKey() | 4033 | public LSL_String llGetPermissionsKey() |
3851 | { | 4034 | { |
3852 | m_host.AddScriptLPS(1); | ||
3853 | |||
3854 | return m_item.PermsGranter.ToString(); | 4035 | return m_item.PermsGranter.ToString(); |
3855 | } | 4036 | } |
3856 | 4037 | ||
3857 | public LSL_Integer llGetPermissions() | 4038 | public LSL_Integer llGetPermissions() |
3858 | { | 4039 | { |
3859 | m_host.AddScriptLPS(1); | ||
3860 | |||
3861 | int perms = m_item.PermsMask; | 4040 | int perms = m_item.PermsMask; |
3862 | 4041 | ||
3863 | if (m_automaticLinkPermission) | 4042 | if (m_automaticLinkPermission) |
@@ -3868,8 +4047,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3868 | 4047 | ||
3869 | public LSL_Integer llGetLinkNumber() | 4048 | public LSL_Integer llGetLinkNumber() |
3870 | { | 4049 | { |
3871 | m_host.AddScriptLPS(1); | ||
3872 | |||
3873 | if (m_host.ParentGroup.PrimCount > 1) | 4050 | if (m_host.ParentGroup.PrimCount > 1) |
3874 | { | 4051 | { |
3875 | return m_host.LinkNum; | 4052 | return m_host.LinkNum; |
@@ -3883,14 +4060,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3883 | public void llSetLinkColor(int linknumber, LSL_Vector color, int face) | 4060 | public void llSetLinkColor(int linknumber, LSL_Vector color, int face) |
3884 | { | 4061 | { |
3885 | List<SceneObjectPart> parts = GetLinkParts(linknumber); | 4062 | List<SceneObjectPart> parts = GetLinkParts(linknumber); |
3886 | 4063 | if (parts.Count > 0) | |
3887 | foreach (SceneObjectPart part in parts) | 4064 | { |
3888 | part.SetFaceColorAlpha(face, color, null); | 4065 | try |
4066 | { | ||
4067 | foreach (SceneObjectPart part in parts) | ||
4068 | part.SetFaceColorAlpha(face, color, null); | ||
4069 | } | ||
4070 | finally { } | ||
4071 | } | ||
3889 | } | 4072 | } |
3890 | 4073 | ||
3891 | public void llCreateLink(string target, int parent) | 4074 | public void llCreateLink(string target, int parent) |
3892 | { | 4075 | { |
3893 | m_host.AddScriptLPS(1); | 4076 | UUID targetID; |
4077 | |||
4078 | if (!UUID.TryParse(target, out targetID)) | ||
4079 | return; | ||
3894 | 4080 | ||
3895 | if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 | 4081 | if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 |
3896 | && !m_automaticLinkPermission) | 4082 | && !m_automaticLinkPermission) |
@@ -3907,9 +4093,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3907 | UUID targetID; | 4093 | UUID targetID; |
3908 | 4094 | ||
3909 | if (!UUID.TryParse(target, out targetID)) | 4095 | if (!UUID.TryParse(target, out targetID)) |
3910 | return; | 4096 | return; |
3911 | 4097 | ||
3912 | SceneObjectPart targetPart = World.GetSceneObjectPart((UUID)targetID); | 4098 | SceneObjectPart targetPart = World.GetSceneObjectPart((UUID)targetID); |
4099 | if (targetPart == null) | ||
4100 | return; | ||
3913 | 4101 | ||
3914 | if (targetPart.ParentGroup.AttachmentPoint != 0) | 4102 | if (targetPart.ParentGroup.AttachmentPoint != 0) |
3915 | return; // Fail silently if attached | 4103 | return; // Fail silently if attached |
@@ -3919,23 +4107,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3919 | 4107 | ||
3920 | SceneObjectGroup parentPrim = null, childPrim = null; | 4108 | SceneObjectGroup parentPrim = null, childPrim = null; |
3921 | 4109 | ||
3922 | if (targetPart != null) | 4110 | if (parent != 0) |
3923 | { | 4111 | { |
3924 | if (parent != 0) | 4112 | parentPrim = m_host.ParentGroup; |
3925 | { | 4113 | childPrim = targetPart.ParentGroup; |
3926 | parentPrim = m_host.ParentGroup; | ||
3927 | childPrim = targetPart.ParentGroup; | ||
3928 | } | ||
3929 | else | ||
3930 | { | ||
3931 | parentPrim = targetPart.ParentGroup; | ||
3932 | childPrim = m_host.ParentGroup; | ||
3933 | } | ||
3934 | |||
3935 | // Required for linking | ||
3936 | childPrim.RootPart.ClearUpdateSchedule(); | ||
3937 | parentPrim.LinkToGroup(childPrim, true); | ||
3938 | } | 4114 | } |
4115 | else | ||
4116 | { | ||
4117 | parentPrim = targetPart.ParentGroup; | ||
4118 | childPrim = m_host.ParentGroup; | ||
4119 | } | ||
4120 | |||
4121 | // Required for linking | ||
4122 | childPrim.RootPart.ClearUpdateSchedule(); | ||
4123 | parentPrim.LinkToGroup(childPrim, true); | ||
4124 | |||
3939 | 4125 | ||
3940 | parentPrim.TriggerScriptChangedEvent(Changed.LINK); | 4126 | parentPrim.TriggerScriptChangedEvent(Changed.LINK); |
3941 | parentPrim.RootPart.CreateSelected = true; | 4127 | parentPrim.RootPart.CreateSelected = true; |
@@ -3953,8 +4139,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3953 | 4139 | ||
3954 | public void llBreakLink(int linknum) | 4140 | public void llBreakLink(int linknum) |
3955 | { | 4141 | { |
3956 | m_host.AddScriptLPS(1); | ||
3957 | |||
3958 | if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 | 4142 | if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 |
3959 | && !m_automaticLinkPermission) | 4143 | && !m_automaticLinkPermission) |
3960 | { | 4144 | { |
@@ -4005,10 +4189,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4005 | // Restructuring Multiple Prims. | 4189 | // Restructuring Multiple Prims. |
4006 | List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); | 4190 | List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); |
4007 | parts.Remove(parentPrim.RootPart); | 4191 | parts.Remove(parentPrim.RootPart); |
4008 | foreach (SceneObjectPart part in parts) | 4192 | if (parts.Count > 0) |
4009 | { | 4193 | { |
4010 | parentPrim.DelinkFromGroup(part.LocalId, true); | 4194 | try |
4011 | } | 4195 | { |
4196 | foreach (SceneObjectPart part in parts) | ||
4197 | { | ||
4198 | parentPrim.DelinkFromGroup(part.LocalId, true); | ||
4199 | } | ||
4200 | } | ||
4201 | finally { } | ||
4202 | } | ||
4203 | |||
4012 | parentPrim.HasGroupChanged = true; | 4204 | parentPrim.HasGroupChanged = true; |
4013 | parentPrim.ScheduleGroupForFullUpdate(); | 4205 | parentPrim.ScheduleGroupForFullUpdate(); |
4014 | parentPrim.TriggerScriptChangedEvent(Changed.LINK); | 4206 | parentPrim.TriggerScriptChangedEvent(Changed.LINK); |
@@ -4017,12 +4209,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4017 | { | 4209 | { |
4018 | SceneObjectPart newRoot = parts[0]; | 4210 | SceneObjectPart newRoot = parts[0]; |
4019 | parts.Remove(newRoot); | 4211 | parts.Remove(newRoot); |
4020 | foreach (SceneObjectPart part in parts) | 4212 | |
4213 | try | ||
4021 | { | 4214 | { |
4022 | // Required for linking | 4215 | foreach (SceneObjectPart part in parts) |
4023 | part.ClearUpdateSchedule(); | 4216 | { |
4024 | newRoot.ParentGroup.LinkToGroup(part.ParentGroup); | 4217 | part.ClearUpdateSchedule(); |
4218 | newRoot.ParentGroup.LinkToGroup(part.ParentGroup); | ||
4219 | } | ||
4025 | } | 4220 | } |
4221 | finally { } | ||
4222 | |||
4026 | newRoot.ParentGroup.HasGroupChanged = true; | 4223 | newRoot.ParentGroup.HasGroupChanged = true; |
4027 | newRoot.ParentGroup.ScheduleGroupForFullUpdate(); | 4224 | newRoot.ParentGroup.ScheduleGroupForFullUpdate(); |
4028 | } | 4225 | } |
@@ -4041,15 +4238,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4041 | 4238 | ||
4042 | public void llBreakAllLinks() | 4239 | public void llBreakAllLinks() |
4043 | { | 4240 | { |
4044 | m_host.AddScriptLPS(1); | 4241 | TaskInventoryItem item = m_item; |
4045 | 4242 | ||
4046 | if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 | 4243 | if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 |
4047 | && !m_automaticLinkPermission) | 4244 | && !m_automaticLinkPermission) |
4048 | { | 4245 | { |
4049 | Error("llBreakAllLinks", "PERMISSION_CHANGE_LINKS permission not set"); | 4246 | Error("llBreakAllLinks","Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); |
4050 | return; | 4247 | return; |
4051 | } | 4248 | } |
4052 | |||
4053 | BreakAllLinks(); | 4249 | BreakAllLinks(); |
4054 | } | 4250 | } |
4055 | 4251 | ||
@@ -4073,14 +4269,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4073 | 4269 | ||
4074 | public LSL_String llGetLinkKey(int linknum) | 4270 | public LSL_String llGetLinkKey(int linknum) |
4075 | { | 4271 | { |
4076 | m_host.AddScriptLPS(1); | 4272 | SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); |
4273 | if (part != null) | ||
4274 | { | ||
4275 | return part.UUID.ToString(); | ||
4276 | } | ||
4277 | else | ||
4278 | { | ||
4279 | if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1)) | ||
4280 | { | ||
4281 | linknum -= (m_host.ParentGroup.PrimCount) + 1; | ||
4077 | 4282 | ||
4078 | ISceneEntity entity = GetLinkEntity(m_host, linknum); | 4283 | if (linknum < 0) |
4284 | return UUID.Zero.ToString(); | ||
4079 | 4285 | ||
4080 | if (entity != null) | 4286 | List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET); |
4081 | return entity.UUID.ToString(); | 4287 | if (avatars.Count > linknum) |
4082 | else | 4288 | { |
4083 | return ScriptBaseClass.NULL_KEY; | 4289 | return avatars[linknum].UUID.ToString(); |
4290 | } | ||
4291 | } | ||
4292 | return UUID.Zero.ToString(); | ||
4293 | } | ||
4084 | } | 4294 | } |
4085 | 4295 | ||
4086 | /// <summary> | 4296 | /// <summary> |
@@ -4124,8 +4334,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4124 | /// </remarks> | 4334 | /// </remarks> |
4125 | public LSL_String llGetLinkName(int linknum) | 4335 | public LSL_String llGetLinkName(int linknum) |
4126 | { | 4336 | { |
4127 | m_host.AddScriptLPS(1); | ||
4128 | |||
4129 | ISceneEntity entity = GetLinkEntity(m_host, linknum); | 4337 | ISceneEntity entity = GetLinkEntity(m_host, linknum); |
4130 | 4338 | ||
4131 | if (entity != null) | 4339 | if (entity != null) |
@@ -4136,38 +4344,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4136 | 4344 | ||
4137 | public LSL_Integer llGetInventoryNumber(int type) | 4345 | public LSL_Integer llGetInventoryNumber(int type) |
4138 | { | 4346 | { |
4139 | m_host.AddScriptLPS(1); | ||
4140 | int count = 0; | 4347 | int count = 0; |
4141 | 4348 | ||
4142 | lock (m_host.TaskInventory) | 4349 | m_host.TaskInventory.LockItemsForRead(true); |
4350 | foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) | ||
4143 | { | 4351 | { |
4144 | foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) | 4352 | if (inv.Value.Type == type || type == -1) |
4145 | { | 4353 | { |
4146 | if (inv.Value.Type == type || type == -1) | 4354 | count = count + 1; |
4147 | { | ||
4148 | count = count + 1; | ||
4149 | } | ||
4150 | } | 4355 | } |
4151 | } | 4356 | } |
4152 | 4357 | ||
4358 | m_host.TaskInventory.LockItemsForRead(false); | ||
4153 | return count; | 4359 | return count; |
4154 | } | 4360 | } |
4155 | 4361 | ||
4156 | public LSL_String llGetInventoryName(int type, int number) | 4362 | public LSL_String llGetInventoryName(int type, int number) |
4157 | { | 4363 | { |
4158 | m_host.AddScriptLPS(1); | ||
4159 | ArrayList keys = new ArrayList(); | 4364 | ArrayList keys = new ArrayList(); |
4160 | 4365 | ||
4161 | lock (m_host.TaskInventory) | 4366 | m_host.TaskInventory.LockItemsForRead(true); |
4367 | foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) | ||
4162 | { | 4368 | { |
4163 | foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) | 4369 | if (inv.Value.Type == type || type == -1) |
4164 | { | 4370 | { |
4165 | if (inv.Value.Type == type || type == -1) | 4371 | keys.Add(inv.Value.Name); |
4166 | { | ||
4167 | keys.Add(inv.Value.Name); | ||
4168 | } | ||
4169 | } | 4372 | } |
4170 | } | 4373 | } |
4374 | m_host.TaskInventory.LockItemsForRead(false); | ||
4171 | 4375 | ||
4172 | if (keys.Count == 0) | 4376 | if (keys.Count == 0) |
4173 | { | 4377 | { |
@@ -4183,15 +4387,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4183 | 4387 | ||
4184 | public LSL_Float llGetEnergy() | 4388 | public LSL_Float llGetEnergy() |
4185 | { | 4389 | { |
4186 | m_host.AddScriptLPS(1); | ||
4187 | // TODO: figure out real energy value | 4390 | // TODO: figure out real energy value |
4188 | return 1.0f; | 4391 | return 1.0f; |
4189 | } | 4392 | } |
4190 | 4393 | ||
4191 | public void llGiveInventory(string destination, string inventory) | 4394 | public void llGiveInventory(string destination, string inventory) |
4192 | { | 4395 | { |
4193 | m_host.AddScriptLPS(1); | ||
4194 | |||
4195 | UUID destId = UUID.Zero; | 4396 | UUID destId = UUID.Zero; |
4196 | 4397 | ||
4197 | if (!UUID.TryParse(destination, out destId)) | 4398 | if (!UUID.TryParse(destination, out destId)) |
@@ -4237,39 +4438,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4237 | } | 4438 | } |
4238 | } | 4439 | } |
4239 | } | 4440 | } |
4441 | |||
4240 | // destination is an avatar | 4442 | // destination is an avatar |
4241 | string message; | 4443 | string message; |
4242 | InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId, out message); | 4444 | InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId, out message); |
4243 | 4445 | ||
4244 | if (agentItem == null) | 4446 | if (agentItem == null) |
4245 | { | 4447 | { |
4246 | llSay(0, message); | 4448 | llSay(0, message); |
4247 | return; | 4449 | return; |
4248 | } | 4450 | } |
4249 | 4451 | ||
4250 | if (m_TransferModule != null) | 4452 | byte[] bucket = new byte[1]; |
4251 | { | 4453 | bucket[0] = (byte)item.Type; |
4252 | byte[] bucket = new byte[1]; | 4454 | //byte[] objBytes = agentItem.ID.GetBytes(); |
4253 | bucket[0] = (byte)item.Type; | 4455 | //Array.Copy(objBytes, 0, bucket, 1, 16); |
4254 | 4456 | ||
4255 | GridInstantMessage msg = new GridInstantMessage(World, | 4457 | GridInstantMessage msg = new GridInstantMessage(World, |
4256 | m_host.OwnerID, m_host.Name, destId, | 4458 | m_host.OwnerID, m_host.Name, destId, |
4257 | (byte)InstantMessageDialog.TaskInventoryOffered, | 4459 | (byte)InstantMessageDialog.TaskInventoryOffered, |
4258 | false, item.Name+". "+m_host.Name+" is located at "+ | 4460 | false, item.Name+". "+m_host.Name+" is located at "+ |
4259 | World.RegionInfo.RegionName+" "+ | 4461 | World.RegionInfo.RegionName+" "+ |
4260 | m_host.AbsolutePosition.ToString(), | 4462 | m_host.AbsolutePosition.ToString(), |
4261 | agentItem.ID, true, m_host.AbsolutePosition, | 4463 | agentItem.ID, true, m_host.AbsolutePosition, |
4262 | bucket, true); | 4464 | bucket, true); |
4465 | |||
4466 | ScenePresence sp; | ||
4263 | 4467 | ||
4264 | m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); | 4468 | if (World.TryGetScenePresence(destId, out sp)) |
4469 | { | ||
4470 | sp.ControllingClient.SendInstantMessage(msg); | ||
4471 | } | ||
4472 | else | ||
4473 | { | ||
4474 | if (m_TransferModule != null) | ||
4475 | m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); | ||
4265 | } | 4476 | } |
4266 | } | 4477 | } |
4267 | } | 4478 | } |
4268 | 4479 | ||
4480 | [DebuggerNonUserCode] | ||
4269 | public void llRemoveInventory(string name) | 4481 | public void llRemoveInventory(string name) |
4270 | { | 4482 | { |
4271 | m_host.AddScriptLPS(1); | ||
4272 | |||
4273 | TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); | 4483 | TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); |
4274 | 4484 | ||
4275 | if (item == null) | 4485 | if (item == null) |
@@ -4283,33 +4493,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4283 | 4493 | ||
4284 | public void llSetText(string text, LSL_Vector color, double alpha) | 4494 | public void llSetText(string text, LSL_Vector color, double alpha) |
4285 | { | 4495 | { |
4286 | m_host.AddScriptLPS(1); | ||
4287 | Vector3 av3 = Util.Clip(color, 0.0f, 1.0f); | 4496 | Vector3 av3 = Util.Clip(color, 0.0f, 1.0f); |
4288 | if (text.Length > 254) | ||
4289 | text = text.Remove(254); | ||
4290 | |||
4291 | byte[] data; | 4497 | byte[] data; |
4292 | do | 4498 | data = Util.StringToBytes256(text); |
4293 | { | 4499 | text = Util.UTF8.GetString(data); |
4294 | data = Util.UTF8.GetBytes(text); | ||
4295 | if (data.Length > 254) | ||
4296 | text = text.Substring(0, text.Length - 1); | ||
4297 | } while (data.Length > 254); | ||
4298 | |||
4299 | m_host.SetText(text, av3, Util.Clip((float)alpha, 0.0f, 1.0f)); | 4500 | m_host.SetText(text, av3, Util.Clip((float)alpha, 0.0f, 1.0f)); |
4300 | //m_host.ParentGroup.HasGroupChanged = true; | ||
4301 | //m_host.ParentGroup.ScheduleGroupForFullUpdate(); | ||
4302 | } | 4501 | } |
4303 | 4502 | ||
4304 | public LSL_Float llWater(LSL_Vector offset) | 4503 | public LSL_Float llWater(LSL_Vector offset) |
4305 | { | 4504 | { |
4306 | m_host.AddScriptLPS(1); | ||
4307 | return World.RegionInfo.RegionSettings.WaterHeight; | 4505 | return World.RegionInfo.RegionSettings.WaterHeight; |
4308 | } | 4506 | } |
4309 | 4507 | ||
4310 | public void llPassTouches(int pass) | 4508 | public void llPassTouches(int pass) |
4311 | { | 4509 | { |
4312 | m_host.AddScriptLPS(1); | ||
4313 | if (pass != 0) | 4510 | if (pass != 0) |
4314 | m_host.PassTouches = true; | 4511 | m_host.PassTouches = true; |
4315 | else | 4512 | else |
@@ -4318,16 +4515,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4318 | 4515 | ||
4319 | public LSL_String llRequestAgentData(string id, int data) | 4516 | public LSL_String llRequestAgentData(string id, int data) |
4320 | { | 4517 | { |
4321 | m_host.AddScriptLPS(1); | 4518 | UUID uuid; |
4322 | 4519 | if (UUID.TryParse(id, out uuid)) | |
4323 | UUID uuid = (UUID)id; | ||
4324 | PresenceInfo pinfo = null; | ||
4325 | UserAccount account; | ||
4326 | |||
4327 | UserInfoCacheEntry ce; | ||
4328 | |||
4329 | lock (m_userInfoCache) | ||
4330 | { | 4520 | { |
4521 | PresenceInfo pinfo = null; | ||
4522 | UserAccount account; | ||
4523 | |||
4524 | UserInfoCacheEntry ce; | ||
4331 | if (!m_userInfoCache.TryGetValue(uuid, out ce)) | 4525 | if (!m_userInfoCache.TryGetValue(uuid, out ce)) |
4332 | { | 4526 | { |
4333 | account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); | 4527 | account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); |
@@ -4353,7 +4547,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4353 | ce.time = Util.EnvironmentTickCount(); | 4547 | ce.time = Util.EnvironmentTickCount(); |
4354 | ce.account = account; | 4548 | ce.account = account; |
4355 | ce.pinfo = pinfo; | 4549 | ce.pinfo = pinfo; |
4356 | |||
4357 | m_userInfoCache[uuid] = ce; | 4550 | m_userInfoCache[uuid] = ce; |
4358 | } | 4551 | } |
4359 | else | 4552 | else |
@@ -4362,83 +4555,81 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4362 | return UUID.Zero.ToString(); | 4555 | return UUID.Zero.ToString(); |
4363 | 4556 | ||
4364 | account = ce.account; | 4557 | account = ce.account; |
4558 | pinfo = ce.pinfo; | ||
4559 | } | ||
4365 | 4560 | ||
4366 | if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) | 4561 | if (Util.EnvironmentTickCount() < ce.time || |
4367 | >= LlRequestAgentDataCacheTimeoutMs) | 4562 | (Util.EnvironmentTickCount() - ce.time) >= LlRequestAgentDataCacheTimeoutMs) |
4563 | { | ||
4564 | PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); | ||
4565 | if (pinfos != null && pinfos.Length > 0) | ||
4368 | { | 4566 | { |
4369 | PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); | 4567 | foreach (PresenceInfo p in pinfos) |
4370 | if (pinfos != null && pinfos.Length > 0) | ||
4371 | { | 4568 | { |
4372 | foreach (PresenceInfo p in pinfos) | 4569 | if (p.RegionID != UUID.Zero) |
4373 | { | 4570 | { |
4374 | if (p.RegionID != UUID.Zero) | 4571 | pinfo = p; |
4375 | { | ||
4376 | pinfo = p; | ||
4377 | } | ||
4378 | } | 4572 | } |
4379 | } | 4573 | } |
4380 | else | ||
4381 | { | ||
4382 | pinfo = null; | ||
4383 | } | ||
4384 | |||
4385 | ce.time = Util.EnvironmentTickCount(); | ||
4386 | ce.pinfo = pinfo; | ||
4387 | } | 4574 | } |
4388 | else | 4575 | else |
4389 | { | 4576 | pinfo = null; |
4390 | pinfo = ce.pinfo; | 4577 | |
4391 | } | 4578 | ce.time = Util.EnvironmentTickCount(); |
4579 | ce.pinfo = pinfo; | ||
4392 | } | 4580 | } |
4393 | } | ||
4394 | 4581 | ||
4395 | string reply = String.Empty; | 4582 | string reply = String.Empty; |
4396 | 4583 | ||
4397 | switch (data) | 4584 | switch (data) |
4398 | { | 4585 | { |
4399 | case ScriptBaseClass.DATA_ONLINE: | 4586 | case ScriptBaseClass.DATA_ONLINE: // DATA_ONLINE (0|1) |
4400 | if (pinfo != null && pinfo.RegionID != UUID.Zero) | 4587 | if (pinfo != null && pinfo.RegionID != UUID.Zero) |
4401 | reply = "1"; | 4588 | reply = "1"; |
4402 | else | 4589 | else |
4403 | reply = "0"; | 4590 | reply = "0"; |
4404 | break; | 4591 | break; |
4405 | case ScriptBaseClass.DATA_NAME: // (First Last) | 4592 | case ScriptBaseClass.DATA_NAME: // DATA_NAME (First Last) |
4406 | reply = account.FirstName + " " + account.LastName; | 4593 | reply = account.FirstName + " " + account.LastName; |
4407 | break; | 4594 | break; |
4408 | case ScriptBaseClass.DATA_BORN: // (YYYY-MM-DD) | 4595 | case ScriptBaseClass.DATA_BORN: // DATA_BORN (YYYY-MM-DD) |
4409 | DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); | 4596 | DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); |
4410 | born = born.AddSeconds(account.Created); | 4597 | born = born.AddSeconds(account.Created); |
4411 | reply = born.ToString("yyyy-MM-dd"); | 4598 | reply = born.ToString("yyyy-MM-dd"); |
4412 | break; | 4599 | break; |
4413 | case ScriptBaseClass.DATA_RATING: // (0,0,0,0,0,0) | 4600 | case ScriptBaseClass.DATA_RATING: // DATA_RATING (0,0,0,0,0,0) |
4414 | reply = "0,0,0,0,0,0"; | 4601 | reply = "0,0,0,0,0,0"; |
4415 | break; | 4602 | break; |
4416 | case 7: // DATA_USERLEVEL (integer). This is not available in LL and so has no constant. | 4603 | case 7: // DATA_USERLEVEL (integer). This is not available in LL and so has no constant. |
4417 | reply = account.UserLevel.ToString(); | 4604 | reply = account.UserLevel.ToString(); |
4418 | break; | 4605 | break; |
4419 | case ScriptBaseClass.DATA_PAYINFO: // (0|1|2|3) | 4606 | case ScriptBaseClass.DATA_PAYINFO: // DATA_PAYINFO (0|1|2|3) |
4420 | reply = "0"; | 4607 | reply = "0"; |
4421 | break; | 4608 | break; |
4422 | default: | 4609 | default: |
4423 | return UUID.Zero.ToString(); // Raise no event | 4610 | return UUID.Zero.ToString(); // Raise no event |
4424 | } | 4611 | } |
4425 | 4612 | ||
4426 | UUID rq = UUID.Random(); | 4613 | UUID rq = UUID.Random(); |
4427 | 4614 | ||
4428 | UUID tid = AsyncCommands. | 4615 | UUID tid = AsyncCommands. |
4429 | DataserverPlugin.RegisterRequest(m_host.LocalId, | 4616 | DataserverPlugin.RegisterRequest(m_host.LocalId, |
4430 | m_item.ItemID, rq.ToString()); | 4617 | m_item.ItemID, rq.ToString()); |
4431 | 4618 | ||
4432 | AsyncCommands. | 4619 | AsyncCommands. |
4433 | DataserverPlugin.DataserverReply(rq.ToString(), reply); | 4620 | DataserverPlugin.DataserverReply(rq.ToString(), reply); |
4434 | 4621 | ||
4435 | return tid.ToString(); | 4622 | return tid.ToString(); |
4623 | } | ||
4624 | else | ||
4625 | { | ||
4626 | Error("llRequestAgentData","Invalid UUID passed to llRequestAgentData."); | ||
4627 | } | ||
4628 | return ""; | ||
4436 | } | 4629 | } |
4437 | 4630 | ||
4438 | public LSL_String llRequestInventoryData(string name) | 4631 | public LSL_String llRequestInventoryData(string name) |
4439 | { | 4632 | { |
4440 | m_host.AddScriptLPS(1); | ||
4441 | |||
4442 | foreach (TaskInventoryItem item in m_host.Inventory.GetInventoryItems()) | 4633 | foreach (TaskInventoryItem item in m_host.Inventory.GetInventoryItems()) |
4443 | { | 4634 | { |
4444 | if (item.Type == 3 && item.Name == name) | 4635 | if (item.Type == 3 && item.Name == name) |
@@ -4473,23 +4664,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4473 | 4664 | ||
4474 | public void llSetDamage(double damage) | 4665 | public void llSetDamage(double damage) |
4475 | { | 4666 | { |
4476 | m_host.AddScriptLPS(1); | ||
4477 | m_host.ParentGroup.Damage = (float)damage; | 4667 | m_host.ParentGroup.Damage = (float)damage; |
4478 | } | 4668 | } |
4479 | 4669 | ||
4480 | public void llTeleportAgentHome(string agent) | 4670 | public void llTeleportAgentHome(string agent) |
4481 | { | 4671 | { |
4482 | m_host.AddScriptLPS(1); | ||
4483 | UUID agentId = new UUID(); | 4672 | UUID agentId = new UUID(); |
4484 | if (UUID.TryParse(agent, out agentId)) | 4673 | if (UUID.TryParse(agent, out agentId)) |
4485 | { | 4674 | { |
4486 | ScenePresence presence = World.GetScenePresence(agentId); | 4675 | ScenePresence presence = World.GetScenePresence(agentId); |
4487 | if (presence != null) | 4676 | if (presence != null && presence.PresenceType != PresenceType.Npc) |
4488 | { | 4677 | { |
4678 | // agent must not be a god | ||
4679 | if (presence.GodController.UserLevel >= 200) return; | ||
4680 | |||
4489 | // agent must be over the owners land | 4681 | // agent must be over the owners land |
4490 | if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) | 4682 | if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) |
4491 | { | 4683 | { |
4492 | World.TeleportClientHome(agentId, presence.ControllingClient); | 4684 | if (!World.TeleportClientHome(agentId, presence.ControllingClient)) |
4685 | { | ||
4686 | // They can't be teleported home for some reason | ||
4687 | GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6")); | ||
4688 | if (regionInfo != null) | ||
4689 | { | ||
4690 | World.RequestTeleportLocation( | ||
4691 | presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero, | ||
4692 | (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome | Constants.TeleportFlags.ViaScript)); | ||
4693 | } | ||
4694 | } | ||
4493 | } | 4695 | } |
4494 | } | 4696 | } |
4495 | } | 4697 | } |
@@ -4497,7 +4699,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4497 | 4699 | ||
4498 | public void llTeleportAgent(string agent, string destination, LSL_Vector targetPos, LSL_Vector targetLookAt) | 4700 | public void llTeleportAgent(string agent, string destination, LSL_Vector targetPos, LSL_Vector targetLookAt) |
4499 | { | 4701 | { |
4500 | m_host.AddScriptLPS(1); | ||
4501 | UUID agentId = new UUID(); | 4702 | UUID agentId = new UUID(); |
4502 | 4703 | ||
4503 | if (UUID.TryParse(agent, out agentId)) | 4704 | if (UUID.TryParse(agent, out agentId)) |
@@ -4505,20 +4706,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4505 | ScenePresence presence = World.GetScenePresence(agentId); | 4706 | ScenePresence presence = World.GetScenePresence(agentId); |
4506 | if (presence != null && presence.PresenceType != PresenceType.Npc) | 4707 | if (presence != null && presence.PresenceType != PresenceType.Npc) |
4507 | { | 4708 | { |
4508 | // agent must not be a god | ||
4509 | if (presence.GodLevel >= 200) return; | ||
4510 | |||
4511 | if (destination == String.Empty) | 4709 | if (destination == String.Empty) |
4512 | destination = World.RegionInfo.RegionName; | 4710 | destination = World.RegionInfo.RegionName; |
4513 | 4711 | ||
4514 | // agent must be over the owners land | 4712 | if (m_item.PermsGranter == agentId) |
4515 | if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) | 4713 | { |
4714 | if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0) | ||
4715 | { | ||
4716 | DoLLTeleport(presence, destination, targetPos, targetLookAt); | ||
4717 | } | ||
4718 | } | ||
4719 | |||
4720 | // agent must be wearing the object | ||
4721 | if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) | ||
4516 | { | 4722 | { |
4517 | DoLLTeleport(presence, destination, targetPos, targetLookAt); | 4723 | DoLLTeleport(presence, destination, targetPos, targetLookAt); |
4518 | } | 4724 | } |
4519 | else // or must be wearing the prim | 4725 | else |
4520 | { | 4726 | { |
4521 | if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) | 4727 | // agent must not be a god |
4728 | if (presence.IsViewerUIGod) return; | ||
4729 | |||
4730 | // agent must be over the owners land | ||
4731 | ILandObject agentLand = World.LandChannel.GetLandObject(presence.AbsolutePosition); | ||
4732 | ILandObject objectLand = World.LandChannel.GetLandObject(m_host.AbsolutePosition); | ||
4733 | if (m_host.OwnerID == objectLand.LandData.OwnerID && m_host.OwnerID == agentLand.LandData.OwnerID) | ||
4522 | { | 4734 | { |
4523 | DoLLTeleport(presence, destination, targetPos, targetLookAt); | 4735 | DoLLTeleport(presence, destination, targetPos, targetLookAt); |
4524 | } | 4736 | } |
@@ -4529,30 +4741,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4529 | 4741 | ||
4530 | public void llTeleportAgentGlobalCoords(string agent, LSL_Vector global_coords, LSL_Vector targetPos, LSL_Vector targetLookAt) | 4742 | public void llTeleportAgentGlobalCoords(string agent, LSL_Vector global_coords, LSL_Vector targetPos, LSL_Vector targetLookAt) |
4531 | { | 4743 | { |
4532 | m_host.AddScriptLPS(1); | ||
4533 | UUID agentId = new UUID(); | 4744 | UUID agentId = new UUID(); |
4534 | 4745 | ||
4535 | ulong regionHandle = Util.RegionWorldLocToHandle((uint)global_coords.x, (uint)global_coords.y); | 4746 | ulong regionHandle = Util.RegionWorldLocToHandle((uint)global_coords.x, (uint)global_coords.y); |
4536 | 4747 | ||
4537 | if (UUID.TryParse(agent, out agentId)) | 4748 | if (UUID.TryParse(agent, out agentId)) |
4538 | { | 4749 | { |
4750 | // This function is owner only! | ||
4751 | if (m_host.OwnerID != agentId) | ||
4752 | return; | ||
4753 | |||
4539 | ScenePresence presence = World.GetScenePresence(agentId); | 4754 | ScenePresence presence = World.GetScenePresence(agentId); |
4540 | if (presence != null && presence.PresenceType != PresenceType.Npc) | 4755 | |
4756 | if (presence == null || presence.PresenceType == PresenceType.Npc) | ||
4757 | return; | ||
4758 | |||
4759 | // Can't TP sitting avatars | ||
4760 | if (presence.ParentID != 0) // Sitting | ||
4761 | return; | ||
4762 | |||
4763 | if (m_item.PermsGranter == agentId) | ||
4541 | { | 4764 | { |
4542 | // agent must not be a god | 4765 | // If attached using llAttachToAvatarTemp, cowardly refuse |
4543 | if (presence.GodLevel >= 200) return; | 4766 | if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.ParentGroup.FromItemID == UUID.Zero) |
4767 | return; | ||
4544 | 4768 | ||
4545 | // agent must be over the owners land | 4769 | if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0) |
4546 | if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) | ||
4547 | { | ||
4548 | World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); | ||
4549 | } | ||
4550 | else // or must be wearing the prim | ||
4551 | { | 4770 | { |
4552 | if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) | 4771 | World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)(Constants.TeleportFlags.ViaLocation | Constants.TeleportFlags.ViaScript)); |
4553 | { | ||
4554 | World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); | ||
4555 | } | ||
4556 | } | 4772 | } |
4557 | } | 4773 | } |
4558 | } | 4774 | } |
@@ -4566,7 +4782,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4566 | // Use it as a sim name | 4782 | // Use it as a sim name |
4567 | if (assetID == UUID.Zero) | 4783 | if (assetID == UUID.Zero) |
4568 | { | 4784 | { |
4569 | World.RequestTeleportLocation(sp.ControllingClient, destination, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); | 4785 | World.RequestTeleportLocation(sp.ControllingClient, destination, targetPos, targetLookAt, (uint)(Constants.TeleportFlags.ViaLocation | Constants.TeleportFlags.ViaScript)); |
4570 | return; | 4786 | return; |
4571 | } | 4787 | } |
4572 | 4788 | ||
@@ -4579,7 +4795,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4579 | 4795 | ||
4580 | AssetLandmark lm = new AssetLandmark(lma); | 4796 | AssetLandmark lm = new AssetLandmark(lma); |
4581 | 4797 | ||
4582 | World.RequestTeleportLocation(sp.ControllingClient, lm.RegionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); | 4798 | World.RequestTeleportLocation(sp.ControllingClient, lm.RegionHandle, targetPos, targetLookAt, (uint)(Constants.TeleportFlags.ViaLocation | Constants.TeleportFlags.ViaScript)); |
4583 | } | 4799 | } |
4584 | 4800 | ||
4585 | public void llTextBox(string agent, string message, int chatChannel) | 4801 | public void llTextBox(string agent, string message, int chatChannel) |
@@ -4589,7 +4805,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4589 | if (dm == null) | 4805 | if (dm == null) |
4590 | return; | 4806 | return; |
4591 | 4807 | ||
4592 | m_host.AddScriptLPS(1); | ||
4593 | UUID av = new UUID(); | 4808 | UUID av = new UUID(); |
4594 | if (!UUID.TryParse(agent,out av)) | 4809 | if (!UUID.TryParse(agent,out av)) |
4595 | { | 4810 | { |
@@ -4601,9 +4816,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4601 | { | 4816 | { |
4602 | Error("llTextBox", "Empty message"); | 4817 | Error("llTextBox", "Empty message"); |
4603 | } | 4818 | } |
4604 | else if (message.Length > 512) | 4819 | else if (Encoding.UTF8.GetByteCount(message) > 512) |
4605 | { | 4820 | { |
4606 | Error("llTextBox", "Message more than 512 characters"); | 4821 | Error("llTextBox", "Message longer than 512 bytes"); |
4607 | } | 4822 | } |
4608 | else | 4823 | else |
4609 | { | 4824 | { |
@@ -4613,7 +4828,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4613 | 4828 | ||
4614 | public void llModifyLand(int action, int brush) | 4829 | public void llModifyLand(int action, int brush) |
4615 | { | 4830 | { |
4616 | m_host.AddScriptLPS(1); | ||
4617 | ITerrainModule tm = m_ScriptEngine.World.RequestModuleInterface<ITerrainModule>(); | 4831 | ITerrainModule tm = m_ScriptEngine.World.RequestModuleInterface<ITerrainModule>(); |
4618 | if (tm != null) | 4832 | if (tm != null) |
4619 | { | 4833 | { |
@@ -4623,17 +4837,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4623 | 4837 | ||
4624 | public void llCollisionSound(string impact_sound, double impact_volume) | 4838 | public void llCollisionSound(string impact_sound, double impact_volume) |
4625 | { | 4839 | { |
4626 | m_host.AddScriptLPS(1); | 4840 | if(impact_sound == "") |
4841 | { | ||
4842 | m_host.CollisionSoundVolume = (float)impact_volume; | ||
4843 | m_host.CollisionSound = m_host.invalidCollisionSoundUUID; | ||
4844 | m_host.CollisionSoundType = -1; // disable all sounds | ||
4845 | m_host.aggregateScriptEvents(); | ||
4846 | return; | ||
4847 | } | ||
4627 | 4848 | ||
4628 | // TODO: Parameter check logic required. | 4849 | // TODO: Parameter check logic required. |
4629 | m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound); | 4850 | UUID soundId = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound); |
4630 | m_host.CollisionSoundVolume = (float)impact_volume; | 4851 | if(soundId != UUID.Zero) |
4852 | { | ||
4853 | m_host.CollisionSound = soundId; | ||
4854 | m_host.CollisionSoundVolume = (float)impact_volume; | ||
4855 | m_host.CollisionSoundType = 1; | ||
4856 | } | ||
4857 | else | ||
4858 | m_host.CollisionSoundType = -1; | ||
4859 | |||
4860 | m_host.aggregateScriptEvents(); | ||
4631 | } | 4861 | } |
4632 | 4862 | ||
4633 | public LSL_String llGetAnimation(string id) | 4863 | public LSL_String llGetAnimation(string id) |
4634 | { | 4864 | { |
4635 | // This should only return a value if the avatar is in the same region | 4865 | // This should only return a value if the avatar is in the same region |
4636 | m_host.AddScriptLPS(1); | ||
4637 | UUID avatar = (UUID)id; | 4866 | UUID avatar = (UUID)id; |
4638 | ScenePresence presence = World.GetScenePresence(avatar); | 4867 | ScenePresence presence = World.GetScenePresence(avatar); |
4639 | if (presence == null) | 4868 | if (presence == null) |
@@ -4641,14 +4870,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4641 | 4870 | ||
4642 | if (m_host.RegionHandle == presence.RegionHandle) | 4871 | if (m_host.RegionHandle == presence.RegionHandle) |
4643 | { | 4872 | { |
4644 | Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames; | ||
4645 | |||
4646 | if (presence != null) | 4873 | if (presence != null) |
4647 | { | 4874 | { |
4648 | AnimationSet currentAnims = presence.Animator.Animations; | 4875 | // if (presence.SitGround) |
4649 | string currentAnimationState = String.Empty; | 4876 | // return "Sitting on Ground"; |
4650 | if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) | 4877 | // if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero) |
4651 | return currentAnimationState; | 4878 | // return "Sitting"; |
4879 | |||
4880 | string movementAnimation = presence.Animator.CurrentMovementAnimation; | ||
4881 | string lslMovementAnimation; | ||
4882 | |||
4883 | if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation)) | ||
4884 | return lslMovementAnimation; | ||
4652 | } | 4885 | } |
4653 | } | 4886 | } |
4654 | 4887 | ||
@@ -4657,8 +4890,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4657 | 4890 | ||
4658 | public void llMessageLinked(int linknumber, int num, string msg, string id) | 4891 | public void llMessageLinked(int linknumber, int num, string msg, string id) |
4659 | { | 4892 | { |
4660 | m_host.AddScriptLPS(1); | ||
4661 | |||
4662 | List<SceneObjectPart> parts = GetLinkParts(linknumber); | 4893 | List<SceneObjectPart> parts = GetLinkParts(linknumber); |
4663 | 4894 | ||
4664 | UUID partItemID; | 4895 | UUID partItemID; |
@@ -4688,7 +4919,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4688 | 4919 | ||
4689 | public void llPushObject(string target, LSL_Vector impulse, LSL_Vector ang_impulse, int local) | 4920 | public void llPushObject(string target, LSL_Vector impulse, LSL_Vector ang_impulse, int local) |
4690 | { | 4921 | { |
4691 | m_host.AddScriptLPS(1); | ||
4692 | bool pushrestricted = World.RegionInfo.RegionSettings.RestrictPushing; | 4922 | bool pushrestricted = World.RegionInfo.RegionSettings.RestrictPushing; |
4693 | bool pushAllowed = false; | 4923 | bool pushAllowed = false; |
4694 | 4924 | ||
@@ -4712,7 +4942,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4712 | return; | 4942 | return; |
4713 | 4943 | ||
4714 | // Pushee is in GodMode this pushing object isn't owned by them | 4944 | // Pushee is in GodMode this pushing object isn't owned by them |
4715 | if (avatar.GodLevel > 0 && m_host.OwnerID != targetID) | 4945 | if (avatar.IsViewerUIGod && m_host.OwnerID != targetID) |
4716 | return; | 4946 | return; |
4717 | 4947 | ||
4718 | pusheeav = avatar; | 4948 | pusheeav = avatar; |
@@ -4796,7 +5026,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4796 | { | 5026 | { |
4797 | float distance = (PusheePos - m_host.AbsolutePosition).Length(); | 5027 | float distance = (PusheePos - m_host.AbsolutePosition).Length(); |
4798 | float distance_term = distance * distance * distance; // Script Energy | 5028 | float distance_term = distance * distance * distance; // Script Energy |
4799 | float pusher_mass = m_host.GetMass(); | 5029 | // use total object mass and not part |
5030 | float pusher_mass = m_host.ParentGroup.GetMass(); | ||
4800 | 5031 | ||
4801 | float PUSH_ATTENUATION_DISTANCE = 17f; | 5032 | float PUSH_ATTENUATION_DISTANCE = 17f; |
4802 | float PUSH_ATTENUATION_SCALE = 5f; | 5033 | float PUSH_ATTENUATION_SCALE = 5f; |
@@ -4831,7 +5062,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4831 | { | 5062 | { |
4832 | if (local != 0) | 5063 | if (local != 0) |
4833 | { | 5064 | { |
4834 | applied_linear_impulse *= m_host.GetWorldRotation(); | 5065 | // applied_linear_impulse *= m_host.GetWorldRotation(); |
5066 | applied_linear_impulse *= pusheeav.GetWorldRotation(); | ||
4835 | } | 5067 | } |
4836 | 5068 | ||
4837 | pa.AddForce(applied_linear_impulse, true); | 5069 | pa.AddForce(applied_linear_impulse, true); |
@@ -4853,7 +5085,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4853 | 5085 | ||
4854 | public void llPassCollisions(int pass) | 5086 | public void llPassCollisions(int pass) |
4855 | { | 5087 | { |
4856 | m_host.AddScriptLPS(1); | ||
4857 | if (pass == 0) | 5088 | if (pass == 0) |
4858 | { | 5089 | { |
4859 | m_host.PassCollisions = false; | 5090 | m_host.PassCollisions = false; |
@@ -4866,15 +5097,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4866 | 5097 | ||
4867 | public LSL_String llGetScriptName() | 5098 | public LSL_String llGetScriptName() |
4868 | { | 5099 | { |
4869 | m_host.AddScriptLPS(1); | ||
4870 | |||
4871 | return m_item.Name != null ? m_item.Name : String.Empty; | 5100 | return m_item.Name != null ? m_item.Name : String.Empty; |
4872 | } | 5101 | } |
4873 | 5102 | ||
4874 | public LSL_Integer llGetLinkNumberOfSides(int link) | 5103 | public LSL_Integer llGetLinkNumberOfSides(int link) |
4875 | { | 5104 | { |
4876 | m_host.AddScriptLPS(1); | ||
4877 | |||
4878 | SceneObjectPart linkedPart; | 5105 | SceneObjectPart linkedPart; |
4879 | 5106 | ||
4880 | if (link == ScriptBaseClass.LINK_ROOT) | 5107 | if (link == ScriptBaseClass.LINK_ROOT) |
@@ -4889,22 +5116,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4889 | 5116 | ||
4890 | public LSL_Integer llGetNumberOfSides() | 5117 | public LSL_Integer llGetNumberOfSides() |
4891 | { | 5118 | { |
4892 | m_host.AddScriptLPS(1); | 5119 | return m_host.GetNumberOfSides(); |
4893 | |||
4894 | return GetNumberOfSides(m_host); | ||
4895 | } | 5120 | } |
4896 | 5121 | ||
4897 | protected int GetNumberOfSides(SceneObjectPart part) | 5122 | protected int GetNumberOfSides(SceneObjectPart part) |
4898 | { | 5123 | { |
4899 | int sides = part.GetNumberOfSides(); | 5124 | return part.GetNumberOfSides(); |
4900 | |||
4901 | if (part.GetPrimType() == PrimType.SPHERE && part.Shape.ProfileHollow > 0) | ||
4902 | { | ||
4903 | // Make up for a bug where LSL shows 4 sides rather than 2 | ||
4904 | sides += 2; | ||
4905 | } | ||
4906 | |||
4907 | return sides; | ||
4908 | } | 5125 | } |
4909 | 5126 | ||
4910 | 5127 | ||
@@ -4936,8 +5153,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4936 | // q = cos(a/2) + i (x * sin(a/2)) + j (y * sin(a/2)) + k (z * sin(a/2)) | 5153 | // q = cos(a/2) + i (x * sin(a/2)) + j (y * sin(a/2)) + k (z * sin(a/2)) |
4937 | public LSL_Rotation llAxisAngle2Rot(LSL_Vector axis, double angle) | 5154 | public LSL_Rotation llAxisAngle2Rot(LSL_Vector axis, double angle) |
4938 | { | 5155 | { |
4939 | m_host.AddScriptLPS(1); | ||
4940 | |||
4941 | double x, y, z, s, t; | 5156 | double x, y, z, s, t; |
4942 | 5157 | ||
4943 | s = Math.Cos(angle * 0.5); | 5158 | s = Math.Cos(angle * 0.5); |
@@ -4957,35 +5172,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4957 | /// <param name='rot'></param> | 5172 | /// <param name='rot'></param> |
4958 | public LSL_Vector llRot2Axis(LSL_Rotation rot) | 5173 | public LSL_Vector llRot2Axis(LSL_Rotation rot) |
4959 | { | 5174 | { |
4960 | m_host.AddScriptLPS(1); | 5175 | rot.Normalize(); |
4961 | |||
4962 | if (Math.Abs(rot.s) > 1) // normalization needed | ||
4963 | rot.Normalize(); | ||
4964 | 5176 | ||
4965 | double s = Math.Sqrt(1 - rot.s * rot.s); | 5177 | double s = Math.Sqrt(1 - rot.s * rot.s); |
4966 | if (s < 0.001) | 5178 | if (s < 1e-8) |
4967 | { | 5179 | return new LSL_Vector(0, 0, 0); |
4968 | return new LSL_Vector(1, 0, 0); | 5180 | |
4969 | } | 5181 | double invS = 1.0 / s; |
4970 | else | 5182 | if (rot.s < 0) |
4971 | { | 5183 | invS = -invS; |
4972 | double invS = 1.0 / s; | 5184 | return new LSL_Vector(rot.x * invS, rot.y * invS, rot.z * invS); |
4973 | if (rot.s < 0) invS = -invS; | ||
4974 | return new LSL_Vector(rot.x * invS, rot.y * invS, rot.z * invS); | ||
4975 | } | ||
4976 | } | 5185 | } |
4977 | 5186 | ||
4978 | 5187 | ||
4979 | // Returns the angle of a quaternion (see llRot2Axis for the axis) | 5188 | // Returns the angle of a quaternion (see llRot2Axis for the axis) |
4980 | public LSL_Float llRot2Angle(LSL_Rotation rot) | 5189 | public LSL_Float llRot2Angle(LSL_Rotation rot) |
4981 | { | 5190 | { |
4982 | m_host.AddScriptLPS(1); | 5191 | rot.Normalize(); |
4983 | |||
4984 | if (Math.Abs(rot.s) > 1) // normalization needed | ||
4985 | rot.Normalize(); | ||
4986 | 5192 | ||
4987 | double angle = 2 * Math.Acos(rot.s); | 5193 | double angle = 2 * Math.Acos(rot.s); |
4988 | if (angle > Math.PI) | 5194 | if (angle > Math.PI) |
4989 | angle = 2 * Math.PI - angle; | 5195 | angle = 2 * Math.PI - angle; |
4990 | 5196 | ||
4991 | return angle; | 5197 | return angle; |
@@ -4993,21 +5199,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
4993 | 5199 | ||
4994 | public LSL_Float llAcos(double val) | 5200 | public LSL_Float llAcos(double val) |
4995 | { | 5201 | { |
4996 | m_host.AddScriptLPS(1); | ||
4997 | return (double)Math.Acos(val); | 5202 | return (double)Math.Acos(val); |
4998 | } | 5203 | } |
4999 | 5204 | ||
5000 | public LSL_Float llAsin(double val) | 5205 | public LSL_Float llAsin(double val) |
5001 | { | 5206 | { |
5002 | m_host.AddScriptLPS(1); | ||
5003 | return (double)Math.Asin(val); | 5207 | return (double)Math.Asin(val); |
5004 | } | 5208 | } |
5005 | 5209 | ||
5006 | // jcochran 5/jan/2012 | 5210 | // jcochran 5/jan/2012 |
5007 | public LSL_Float llAngleBetween(LSL_Rotation a, LSL_Rotation b) | 5211 | public LSL_Float llAngleBetween(LSL_Rotation a, LSL_Rotation b) |
5008 | { | 5212 | { |
5009 | m_host.AddScriptLPS(1); | ||
5010 | |||
5011 | double aa = (a.x * a.x + a.y * a.y + a.z * a.z + a.s * a.s); | 5213 | double aa = (a.x * a.x + a.y * a.y + a.z * a.z + a.s * a.s); |
5012 | double bb = (b.x * b.x + b.y * b.y + b.z * b.z + b.s * b.s); | 5214 | double bb = (b.x * b.x + b.y * b.y + b.z * b.z + b.s * b.s); |
5013 | double aa_bb = aa * bb; | 5215 | double aa_bb = aa * bb; |
@@ -5020,8 +5222,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5020 | 5222 | ||
5021 | public LSL_String llGetInventoryKey(string name) | 5223 | public LSL_String llGetInventoryKey(string name) |
5022 | { | 5224 | { |
5023 | m_host.AddScriptLPS(1); | ||
5024 | |||
5025 | TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); | 5225 | TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); |
5026 | 5226 | ||
5027 | if (item == null) | 5227 | if (item == null) |
@@ -5039,8 +5239,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5039 | 5239 | ||
5040 | public void llAllowInventoryDrop(int add) | 5240 | public void llAllowInventoryDrop(int add) |
5041 | { | 5241 | { |
5042 | m_host.AddScriptLPS(1); | ||
5043 | |||
5044 | if (add != 0) | 5242 | if (add != 0) |
5045 | m_host.ParentGroup.RootPart.AllowedDrop = true; | 5243 | m_host.ParentGroup.RootPart.AllowedDrop = true; |
5046 | else | 5244 | else |
@@ -5052,8 +5250,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5052 | 5250 | ||
5053 | public LSL_Vector llGetSunDirection() | 5251 | public LSL_Vector llGetSunDirection() |
5054 | { | 5252 | { |
5055 | m_host.AddScriptLPS(1); | ||
5056 | |||
5057 | LSL_Vector SunDoubleVector3; | 5253 | LSL_Vector SunDoubleVector3; |
5058 | Vector3 SunFloatVector3; | 5254 | Vector3 SunFloatVector3; |
5059 | 5255 | ||
@@ -5069,7 +5265,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5069 | 5265 | ||
5070 | public LSL_Vector llGetTextureOffset(int face) | 5266 | public LSL_Vector llGetTextureOffset(int face) |
5071 | { | 5267 | { |
5072 | m_host.AddScriptLPS(1); | ||
5073 | return GetTextureOffset(m_host, face); | 5268 | return GetTextureOffset(m_host, face); |
5074 | } | 5269 | } |
5075 | 5270 | ||
@@ -5096,7 +5291,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5096 | 5291 | ||
5097 | public LSL_Vector llGetTextureScale(int side) | 5292 | public LSL_Vector llGetTextureScale(int side) |
5098 | { | 5293 | { |
5099 | m_host.AddScriptLPS(1); | ||
5100 | Primitive.TextureEntry tex = m_host.Shape.Textures; | 5294 | Primitive.TextureEntry tex = m_host.Shape.Textures; |
5101 | LSL_Vector scale; | 5295 | LSL_Vector scale; |
5102 | if (side == -1) | 5296 | if (side == -1) |
@@ -5111,7 +5305,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5111 | 5305 | ||
5112 | public LSL_Float llGetTextureRot(int face) | 5306 | public LSL_Float llGetTextureRot(int face) |
5113 | { | 5307 | { |
5114 | m_host.AddScriptLPS(1); | ||
5115 | return GetTextureRot(m_host, face); | 5308 | return GetTextureRot(m_host, face); |
5116 | } | 5309 | } |
5117 | 5310 | ||
@@ -5134,13 +5327,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5134 | 5327 | ||
5135 | public LSL_Integer llSubStringIndex(string source, string pattern) | 5328 | public LSL_Integer llSubStringIndex(string source, string pattern) |
5136 | { | 5329 | { |
5137 | m_host.AddScriptLPS(1); | ||
5138 | return source.IndexOf(pattern); | 5330 | return source.IndexOf(pattern); |
5139 | } | 5331 | } |
5140 | 5332 | ||
5141 | public LSL_String llGetOwnerKey(string id) | 5333 | public LSL_String llGetOwnerKey(string id) |
5142 | { | 5334 | { |
5143 | m_host.AddScriptLPS(1); | ||
5144 | UUID key = new UUID(); | 5335 | UUID key = new UUID(); |
5145 | if (UUID.TryParse(id, out key)) | 5336 | if (UUID.TryParse(id, out key)) |
5146 | { | 5337 | { |
@@ -5165,15 +5356,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5165 | 5356 | ||
5166 | public LSL_Vector llGetCenterOfMass() | 5357 | public LSL_Vector llGetCenterOfMass() |
5167 | { | 5358 | { |
5168 | m_host.AddScriptLPS(1); | ||
5169 | |||
5170 | return new LSL_Vector(m_host.GetCenterOfMass()); | 5359 | return new LSL_Vector(m_host.GetCenterOfMass()); |
5171 | } | 5360 | } |
5172 | 5361 | ||
5173 | public LSL_List llListSort(LSL_List src, int stride, int ascending) | 5362 | public LSL_List llListSort(LSL_List src, int stride, int ascending) |
5174 | { | 5363 | { |
5175 | m_host.AddScriptLPS(1); | ||
5176 | |||
5177 | if (stride <= 0) | 5364 | if (stride <= 0) |
5178 | { | 5365 | { |
5179 | stride = 1; | 5366 | stride = 1; |
@@ -5183,45 +5370,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5183 | 5370 | ||
5184 | public LSL_Integer llGetListLength(LSL_List src) | 5371 | public LSL_Integer llGetListLength(LSL_List src) |
5185 | { | 5372 | { |
5186 | m_host.AddScriptLPS(1); | 5373 | return src.Length; |
5187 | |||
5188 | if (src == null) | ||
5189 | { | ||
5190 | return 0; | ||
5191 | } | ||
5192 | else | ||
5193 | { | ||
5194 | return src.Length; | ||
5195 | } | ||
5196 | } | 5374 | } |
5197 | 5375 | ||
5198 | public LSL_Integer llList2Integer(LSL_List src, int index) | 5376 | public LSL_Integer llList2Integer(LSL_List src, int index) |
5199 | { | 5377 | { |
5200 | m_host.AddScriptLPS(1); | ||
5201 | if (index < 0) | 5378 | if (index < 0) |
5202 | { | ||
5203 | index = src.Length + index; | 5379 | index = src.Length + index; |
5204 | } | 5380 | |
5205 | if (index >= src.Length || index < 0) | 5381 | if (index >= src.Length || index < 0) |
5206 | { | ||
5207 | return 0; | 5382 | return 0; |
5208 | } | 5383 | |
5384 | object item = src.Data[index]; | ||
5209 | 5385 | ||
5210 | // Vectors & Rotations always return zero in SL, but | 5386 | // Vectors & Rotations always return zero in SL, but |
5211 | // keys don't always return zero, it seems to be a bit complex. | 5387 | // keys don't always return zero, it seems to be a bit complex. |
5212 | else if (src.Data[index] is LSL_Vector || | 5388 | if (item is LSL_Vector || item is LSL_Rotation) |
5213 | src.Data[index] is LSL_Rotation) | ||
5214 | { | ||
5215 | return 0; | 5389 | return 0; |
5216 | } | 5390 | |
5217 | try | 5391 | try |
5218 | { | 5392 | { |
5219 | 5393 | if (item is LSL_Integer) | |
5220 | if (src.Data[index] is LSL_Integer) | 5394 | return (LSL_Integer)item; |
5221 | return (LSL_Integer)src.Data[index]; | 5395 | else if (item is LSL_Float) |
5222 | else if (src.Data[index] is LSL_Float) | 5396 | return Convert.ToInt32(((LSL_Float)item).value);; |
5223 | return Convert.ToInt32(((LSL_Float)src.Data[index]).value); | 5397 | return new LSL_Integer(item.ToString()); |
5224 | return new LSL_Integer(src.Data[index].ToString()); | ||
5225 | } | 5398 | } |
5226 | catch (FormatException) | 5399 | catch (FormatException) |
5227 | { | 5400 | { |
@@ -5231,40 +5404,51 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5231 | 5404 | ||
5232 | public LSL_Float llList2Float(LSL_List src, int index) | 5405 | public LSL_Float llList2Float(LSL_List src, int index) |
5233 | { | 5406 | { |
5234 | m_host.AddScriptLPS(1); | ||
5235 | if (index < 0) | 5407 | if (index < 0) |
5236 | { | ||
5237 | index = src.Length + index; | 5408 | index = src.Length + index; |
5238 | } | 5409 | |
5239 | if (index >= src.Length || index < 0) | 5410 | if (index >= src.Length || index < 0) |
5240 | { | 5411 | return 0; |
5241 | return 0.0; | 5412 | |
5242 | } | 5413 | object item = src.Data[index]; |
5243 | 5414 | ||
5244 | // Vectors & Rotations always return zero in SL | 5415 | // Vectors & Rotations always return zero in SL |
5245 | else if (src.Data[index] is LSL_Vector || | 5416 | if(item is LSL_Vector || item is LSL_Rotation) |
5246 | src.Data[index] is LSL_Rotation) | ||
5247 | { | ||
5248 | return 0; | 5417 | return 0; |
5249 | } | 5418 | |
5250 | // valid keys seem to get parsed as integers then converted to floats | 5419 | // valid keys seem to get parsed as integers then converted to floats |
5251 | else | 5420 | if (item is LSL_Key) |
5252 | { | 5421 | { |
5253 | UUID uuidt; | 5422 | UUID uuidt; |
5254 | if (src.Data[index] is LSL_Key && UUID.TryParse(src.Data[index].ToString(), out uuidt)) | 5423 | string s = item.ToString(); |
5255 | { | 5424 | if(UUID.TryParse(s, out uuidt)) |
5256 | return Convert.ToDouble(new LSL_Integer(src.Data[index].ToString()).value); | 5425 | return Convert.ToDouble(new LSL_Integer(s).value); |
5257 | } | 5426 | // we can't do this because a string is also a LSL_Key for now :( |
5427 | // else | ||
5428 | // return 0; | ||
5258 | } | 5429 | } |
5430 | |||
5259 | try | 5431 | try |
5260 | { | 5432 | { |
5261 | if (src.Data[index] is LSL_Integer) | 5433 | if (item is LSL_Integer) |
5262 | return Convert.ToDouble(((LSL_Integer)src.Data[index]).value); | 5434 | return Convert.ToDouble(((LSL_Integer)item).value); |
5263 | else if (src.Data[index] is LSL_Float) | 5435 | else if (item is LSL_Float) |
5264 | return Convert.ToDouble(((LSL_Float)src.Data[index]).value); | 5436 | return Convert.ToDouble(((LSL_Float)item).value); |
5265 | else if (src.Data[index] is LSL_String) | 5437 | else if (item is LSL_String) |
5266 | return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); | 5438 | { |
5267 | return Convert.ToDouble(src.Data[index]); | 5439 | string str = ((LSL_String)item).m_string; |
5440 | Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)"); | ||
5441 | if (m != Match.Empty) | ||
5442 | { | ||
5443 | str = m.Value; | ||
5444 | double d = 0.0; | ||
5445 | if (!Double.TryParse(str, out d)) | ||
5446 | return 0.0; | ||
5447 | return d; | ||
5448 | } | ||
5449 | return 0.0; | ||
5450 | } | ||
5451 | return Convert.ToDouble(item); | ||
5268 | } | 5452 | } |
5269 | catch (FormatException) | 5453 | catch (FormatException) |
5270 | { | 5454 | { |
@@ -5274,30 +5458,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5274 | 5458 | ||
5275 | public LSL_String llList2String(LSL_List src, int index) | 5459 | public LSL_String llList2String(LSL_List src, int index) |
5276 | { | 5460 | { |
5277 | m_host.AddScriptLPS(1); | ||
5278 | if (index < 0) | 5461 | if (index < 0) |
5279 | { | ||
5280 | index = src.Length + index; | 5462 | index = src.Length + index; |
5281 | } | 5463 | |
5282 | if (index >= src.Length || index < 0) | 5464 | if (index >= src.Length || index < 0) |
5283 | { | ||
5284 | return String.Empty; | 5465 | return String.Empty; |
5285 | } | 5466 | |
5286 | return src.Data[index].ToString(); | 5467 | return src.Data[index].ToString(); |
5287 | } | 5468 | } |
5288 | 5469 | ||
5289 | public LSL_Key llList2Key(LSL_List src, int index) | 5470 | public LSL_Key llList2Key(LSL_List src, int index) |
5290 | { | 5471 | { |
5291 | m_host.AddScriptLPS(1); | ||
5292 | if (index < 0) | 5472 | if (index < 0) |
5293 | { | ||
5294 | index = src.Length + index; | 5473 | index = src.Length + index; |
5295 | } | ||
5296 | 5474 | ||
5297 | if (index >= src.Length || index < 0) | 5475 | if (index >= src.Length || index < 0) |
5298 | { | 5476 | return String.Empty; |
5299 | return ""; | 5477 | |
5300 | } | 5478 | object item = src.Data[index]; |
5301 | 5479 | ||
5302 | // SL spits out an empty string for types other than key & string | 5480 | // SL spits out an empty string for types other than key & string |
5303 | // At the time of patching, LSL_Key is currently LSL_String, | 5481 | // At the time of patching, LSL_Key is currently LSL_String, |
@@ -5306,31 +5484,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5306 | // as it's own struct | 5484 | // as it's own struct |
5307 | // NOTE: 3rd case is needed because a NULL_KEY comes through as | 5485 | // NOTE: 3rd case is needed because a NULL_KEY comes through as |
5308 | // type 'obj' and wrongly returns "" | 5486 | // type 'obj' and wrongly returns "" |
5309 | else if (!(src.Data[index] is LSL_String || | 5487 | if (!(item is LSL_String || |
5310 | src.Data[index] is LSL_Key || | 5488 | item is LSL_Key || |
5311 | src.Data[index].ToString() == "00000000-0000-0000-0000-000000000000")) | 5489 | item.ToString() == "00000000-0000-0000-0000-000000000000")) |
5312 | { | 5490 | { |
5313 | return ""; | 5491 | return String.Empty; |
5314 | } | 5492 | } |
5315 | 5493 | ||
5316 | return src.Data[index].ToString(); | 5494 | return item.ToString(); |
5317 | } | 5495 | } |
5318 | 5496 | ||
5319 | public LSL_Vector llList2Vector(LSL_List src, int index) | 5497 | public LSL_Vector llList2Vector(LSL_List src, int index) |
5320 | { | 5498 | { |
5321 | m_host.AddScriptLPS(1); | ||
5322 | if (index < 0) | 5499 | if (index < 0) |
5323 | { | ||
5324 | index = src.Length + index; | 5500 | index = src.Length + index; |
5325 | } | 5501 | |
5326 | if (index >= src.Length || index < 0) | 5502 | if (index >= src.Length || index < 0) |
5327 | { | ||
5328 | return new LSL_Vector(0, 0, 0); | 5503 | return new LSL_Vector(0, 0, 0); |
5329 | } | 5504 | |
5330 | if (src.Data[index].GetType() == typeof(LSL_Vector)) | 5505 | object item = src.Data[index]; |
5331 | { | 5506 | |
5332 | return (LSL_Vector)src.Data[index]; | 5507 | if (item.GetType() == typeof(LSL_Vector)) |
5333 | } | 5508 | return (LSL_Vector)item; |
5334 | 5509 | ||
5335 | // SL spits always out ZERO_VECTOR for anything other than | 5510 | // SL spits always out ZERO_VECTOR for anything other than |
5336 | // strings or vectors. Although keys always return ZERO_VECTOR, | 5511 | // strings or vectors. Although keys always return ZERO_VECTOR, |
@@ -5338,28 +5513,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5338 | // a string, a key as string and a string that by coincidence | 5513 | // a string, a key as string and a string that by coincidence |
5339 | // is a string, so we're going to leave that up to the | 5514 | // is a string, so we're going to leave that up to the |
5340 | // LSL_Vector constructor. | 5515 | // LSL_Vector constructor. |
5341 | else if (!(src.Data[index] is LSL_String || | 5516 | if(item is LSL_Vector) |
5342 | src.Data[index] is LSL_Vector)) | 5517 | return (LSL_Vector) item; |
5343 | { | 5518 | |
5344 | return new LSL_Vector(0, 0, 0); | 5519 | if (item is LSL_String) |
5345 | } | 5520 | return new LSL_Vector(item.ToString()); |
5346 | else | 5521 | |
5347 | { | 5522 | return new LSL_Vector(0, 0, 0); |
5348 | return new LSL_Vector(src.Data[index].ToString()); | ||
5349 | } | ||
5350 | } | 5523 | } |
5351 | 5524 | ||
5352 | public LSL_Rotation llList2Rot(LSL_List src, int index) | 5525 | public LSL_Rotation llList2Rot(LSL_List src, int index) |
5353 | { | 5526 | { |
5354 | m_host.AddScriptLPS(1); | ||
5355 | if (index < 0) | 5527 | if (index < 0) |
5356 | { | ||
5357 | index = src.Length + index; | 5528 | index = src.Length + index; |
5358 | } | 5529 | |
5359 | if (index >= src.Length || index < 0) | 5530 | if (index >= src.Length || index < 0) |
5360 | { | ||
5361 | return new LSL_Rotation(0, 0, 0, 1); | 5531 | return new LSL_Rotation(0, 0, 0, 1); |
5362 | } | 5532 | |
5533 | object item = src.Data[index]; | ||
5363 | 5534 | ||
5364 | // SL spits always out ZERO_ROTATION for anything other than | 5535 | // SL spits always out ZERO_ROTATION for anything other than |
5365 | // strings or vectors. Although keys always return ZERO_ROTATION, | 5536 | // strings or vectors. Although keys always return ZERO_ROTATION, |
@@ -5367,24 +5538,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5367 | // a string, a key as string and a string that by coincidence | 5538 | // a string, a key as string and a string that by coincidence |
5368 | // is a string, so we're going to leave that up to the | 5539 | // is a string, so we're going to leave that up to the |
5369 | // LSL_Rotation constructor. | 5540 | // LSL_Rotation constructor. |
5370 | else if (!(src.Data[index] is LSL_String || | 5541 | |
5371 | src.Data[index] is LSL_Rotation)) | 5542 | if (item.GetType() == typeof(LSL_Rotation)) |
5372 | { | 5543 | return (LSL_Rotation)item; |
5373 | return new LSL_Rotation(0, 0, 0, 1); | 5544 | |
5374 | } | 5545 | if (item is LSL_String) |
5375 | else if (src.Data[index].GetType() == typeof(LSL_Rotation)) | ||
5376 | { | ||
5377 | return (LSL_Rotation)src.Data[index]; | ||
5378 | } | ||
5379 | else | ||
5380 | { | ||
5381 | return new LSL_Rotation(src.Data[index].ToString()); | 5546 | return new LSL_Rotation(src.Data[index].ToString()); |
5382 | } | 5547 | |
5548 | return new LSL_Rotation(0, 0, 0, 1); | ||
5383 | } | 5549 | } |
5384 | 5550 | ||
5385 | public LSL_List llList2List(LSL_List src, int start, int end) | 5551 | public LSL_List llList2List(LSL_List src, int start, int end) |
5386 | { | 5552 | { |
5387 | m_host.AddScriptLPS(1); | ||
5388 | return src.GetSublist(start, end); | 5553 | return src.GetSublist(start, end); |
5389 | } | 5554 | } |
5390 | 5555 | ||
@@ -5395,7 +5560,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5395 | 5560 | ||
5396 | public LSL_Integer llGetListEntryType(LSL_List src, int index) | 5561 | public LSL_Integer llGetListEntryType(LSL_List src, int index) |
5397 | { | 5562 | { |
5398 | m_host.AddScriptLPS(1); | ||
5399 | if (index < 0) | 5563 | if (index < 0) |
5400 | { | 5564 | { |
5401 | index = src.Length + index; | 5565 | index = src.Length + index; |
@@ -5439,8 +5603,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5439 | /// </summary> | 5603 | /// </summary> |
5440 | public LSL_String llList2CSV(LSL_List src) | 5604 | public LSL_String llList2CSV(LSL_List src) |
5441 | { | 5605 | { |
5442 | m_host.AddScriptLPS(1); | ||
5443 | |||
5444 | return string.Join(", ", | 5606 | return string.Join(", ", |
5445 | (new List<object>(src.Data)).ConvertAll<string>(o => | 5607 | (new List<object>(src.Data)).ConvertAll<string>(o => |
5446 | { | 5608 | { |
@@ -5464,8 +5626,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5464 | int start = 0; | 5626 | int start = 0; |
5465 | int length = 0; | 5627 | int length = 0; |
5466 | 5628 | ||
5467 | m_host.AddScriptLPS(1); | ||
5468 | |||
5469 | for (int i = 0; i < src.Length; i++) | 5629 | for (int i = 0; i < src.Length; i++) |
5470 | { | 5630 | { |
5471 | switch (src[i]) | 5631 | switch (src[i]) |
@@ -5521,8 +5681,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5521 | int chunkk; | 5681 | int chunkk; |
5522 | int[] chunks; | 5682 | int[] chunks; |
5523 | 5683 | ||
5524 | m_host.AddScriptLPS(1); | ||
5525 | |||
5526 | if (stride <= 0) | 5684 | if (stride <= 0) |
5527 | { | 5685 | { |
5528 | stride = 1; | 5686 | stride = 1; |
@@ -5567,7 +5725,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5567 | } | 5725 | } |
5568 | } | 5726 | } |
5569 | } | 5727 | } |
5570 | else { | 5728 | else |
5729 | { | ||
5571 | object[] array = new object[src.Length]; | 5730 | object[] array = new object[src.Length]; |
5572 | Array.Copy(src.Data, 0, array, 0, src.Length); | 5731 | Array.Copy(src.Data, 0, array, 0, src.Length); |
5573 | result = new LSL_List(array); | 5732 | result = new LSL_List(array); |
@@ -5592,8 +5751,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5592 | int[] ei = new int[2]; | 5751 | int[] ei = new int[2]; |
5593 | bool twopass = false; | 5752 | bool twopass = false; |
5594 | 5753 | ||
5595 | m_host.AddScriptLPS(1); | ||
5596 | |||
5597 | // First step is always to deal with negative indices | 5754 | // First step is always to deal with negative indices |
5598 | 5755 | ||
5599 | if (start < 0) | 5756 | if (start < 0) |
@@ -5673,19 +5830,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5673 | 5830 | ||
5674 | public LSL_Integer llGetRegionAgentCount() | 5831 | public LSL_Integer llGetRegionAgentCount() |
5675 | { | 5832 | { |
5676 | m_host.AddScriptLPS(1); | 5833 | int count = 0; |
5677 | return new LSL_Integer(World.GetRootAgentCount()); | 5834 | World.ForEachRootScenePresence(delegate(ScenePresence sp) { |
5835 | count++; | ||
5836 | }); | ||
5837 | |||
5838 | return new LSL_Integer(count); | ||
5678 | } | 5839 | } |
5679 | 5840 | ||
5680 | public LSL_Vector llGetRegionCorner() | 5841 | public LSL_Vector llGetRegionCorner() |
5681 | { | 5842 | { |
5682 | m_host.AddScriptLPS(1); | ||
5683 | return new LSL_Vector(World.RegionInfo.WorldLocX, World.RegionInfo.WorldLocY, 0); | 5843 | return new LSL_Vector(World.RegionInfo.WorldLocX, World.RegionInfo.WorldLocY, 0); |
5684 | } | 5844 | } |
5685 | 5845 | ||
5686 | public LSL_String llGetEnv(LSL_String name) | 5846 | public LSL_String llGetEnv(LSL_String name) |
5687 | { | 5847 | { |
5688 | m_host.AddScriptLPS(1); | ||
5689 | if (name == "agent_limit") | 5848 | if (name == "agent_limit") |
5690 | { | 5849 | { |
5691 | return World.RegionInfo.RegionSettings.AgentLimit.ToString(); | 5850 | return World.RegionInfo.RegionSettings.AgentLimit.ToString(); |
@@ -5742,10 +5901,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5742 | IUrlModule UrlModule = World.RequestModuleInterface<IUrlModule>(); | 5901 | IUrlModule UrlModule = World.RequestModuleInterface<IUrlModule>(); |
5743 | return UrlModule.ExternalHostNameForLSL; | 5902 | return UrlModule.ExternalHostNameForLSL; |
5744 | } | 5903 | } |
5904 | else if (name == "region_max_prims") | ||
5905 | { | ||
5906 | return World.RegionInfo.ObjectCapacity.ToString(); | ||
5907 | } | ||
5908 | else if (name == "region_object_bonus") | ||
5909 | { | ||
5910 | return World.RegionInfo.RegionSettings.ObjectBonus.ToString(); | ||
5911 | } | ||
5745 | else | 5912 | else |
5746 | { | 5913 | { |
5747 | return ""; | 5914 | return ""; |
5748 | } | 5915 | } |
5916 | |||
5749 | } | 5917 | } |
5750 | 5918 | ||
5751 | /// <summary> | 5919 | /// <summary> |
@@ -5760,8 +5928,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5760 | LSL_List pref; | 5928 | LSL_List pref; |
5761 | LSL_List suff; | 5929 | LSL_List suff; |
5762 | 5930 | ||
5763 | m_host.AddScriptLPS(1); | ||
5764 | |||
5765 | if (index < 0) | 5931 | if (index < 0) |
5766 | { | 5932 | { |
5767 | index = index+dest.Length; | 5933 | index = index+dest.Length; |
@@ -5814,24 +5980,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5814 | int index = -1; | 5980 | int index = -1; |
5815 | int length = src.Length - test.Length + 1; | 5981 | int length = src.Length - test.Length + 1; |
5816 | 5982 | ||
5817 | m_host.AddScriptLPS(1); | ||
5818 | |||
5819 | // If either list is empty, do not match | 5983 | // If either list is empty, do not match |
5820 | if (src.Length != 0 && test.Length != 0) | 5984 | if (src.Length != 0 && test.Length != 0) |
5821 | { | 5985 | { |
5822 | for (int i = 0; i < length; i++) | 5986 | for (int i = 0; i < length; i++) |
5823 | { | 5987 | { |
5988 | //// int needle = llGetListEntryType(test, 0).value; | ||
5989 | //// int haystack = llGetListEntryType(src, i).value; | ||
5990 | |||
5824 | // Why this piece of insanity? This is because most script constants are C# value types (e.g. int) | 5991 | // Why this piece of insanity? This is because most script constants are C# value types (e.g. int) |
5825 | // rather than wrapped LSL types. Such a script constant does not have int.Equal(LSL_Integer) code | 5992 | // rather than wrapped LSL types. Such a script constant does not have int.Equal(LSL_Integer) code |
5826 | // and so the comparison fails even if the LSL_Integer conceptually has the same value. | 5993 | // and so the comparison fails even if the LSL_Integer conceptually has the same value. |
5827 | // Therefore, here we test Equals on both the source and destination objects. | 5994 | // Therefore, here we test Equals on both the source and destination objects. |
5828 | // However, a future better approach may be use LSL struct script constants (e.g. LSL_Integer(1)). | 5995 | // However, a future better approach may be use LSL struct script constants (e.g. LSL_Integer(1)). |
5996 | |||
5997 | // The commented out bit of insanity was to check the LSL types are the same as well, which we don't really want. | ||
5829 | if (src.Data[i].Equals(test.Data[0]) || test.Data[0].Equals(src.Data[i])) | 5998 | if (src.Data[i].Equals(test.Data[0]) || test.Data[0].Equals(src.Data[i])) |
5999 | //// if ((needle == haystack) && (src.Data[i].Equals(test.Data[0]) || test.Data[0].Equals(src.Data[i]))) | ||
5830 | { | 6000 | { |
5831 | int j; | 6001 | int j; |
5832 | for (j = 1; j < test.Length; j++) | 6002 | for (j = 1; j < test.Length; j++) |
5833 | if (!(src.Data[i+j].Equals(test.Data[j]) || test.Data[j].Equals(src.Data[i+j]))) | 6003 | if (!(src.Data[i+j].Equals(test.Data[j]) || test.Data[j].Equals(src.Data[i+j]))) |
6004 | { | ||
6005 | //// needle = llGetListEntryType(test, j).value; | ||
6006 | //// haystack = llGetListEntryType(src, i+j).value; | ||
6007 | |||
6008 | //// if ((needle != haystack) || (!(src.Data[i+j].Equals(test.Data[j]) || test.Data[j].Equals(src.Data[i+j])))) | ||
5834 | break; | 6009 | break; |
6010 | } | ||
5835 | 6011 | ||
5836 | if (j == test.Length) | 6012 | if (j == test.Length) |
5837 | { | 6013 | { |
@@ -5847,19 +6023,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5847 | 6023 | ||
5848 | public LSL_String llGetObjectName() | 6024 | public LSL_String llGetObjectName() |
5849 | { | 6025 | { |
5850 | m_host.AddScriptLPS(1); | ||
5851 | return m_host.Name !=null ? m_host.Name : String.Empty; | 6026 | return m_host.Name !=null ? m_host.Name : String.Empty; |
5852 | } | 6027 | } |
5853 | 6028 | ||
5854 | public void llSetObjectName(string name) | 6029 | public void llSetObjectName(string name) |
5855 | { | 6030 | { |
5856 | m_host.AddScriptLPS(1); | ||
5857 | m_host.Name = name != null ? name : String.Empty; | 6031 | m_host.Name = name != null ? name : String.Empty; |
5858 | } | 6032 | } |
5859 | 6033 | ||
5860 | public LSL_String llGetDate() | 6034 | public LSL_String llGetDate() |
5861 | { | 6035 | { |
5862 | m_host.AddScriptLPS(1); | ||
5863 | DateTime date = DateTime.Now.ToUniversalTime(); | 6036 | DateTime date = DateTime.Now.ToUniversalTime(); |
5864 | string result = date.ToString("yyyy-MM-dd"); | 6037 | string result = date.ToString("yyyy-MM-dd"); |
5865 | return result; | 6038 | return result; |
@@ -5867,66 +6040,61 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5867 | 6040 | ||
5868 | public LSL_Integer llEdgeOfWorld(LSL_Vector pos, LSL_Vector dir) | 6041 | public LSL_Integer llEdgeOfWorld(LSL_Vector pos, LSL_Vector dir) |
5869 | { | 6042 | { |
5870 | m_host.AddScriptLPS(1); | 6043 | if(dir.x == 0 && dir.y == 0) |
6044 | return 1; // SL wiki | ||
6045 | |||
6046 | float rsx = World.RegionInfo.RegionSizeX; | ||
6047 | float rsy = World.RegionInfo.RegionSizeY; | ||
6048 | |||
6049 | // can understand what sl does if position is not in region, so do something :) | ||
6050 | float px = (float)Util.Clamp(pos.x, 0.5, rsx - 0.5); | ||
6051 | float py = (float)Util.Clamp(pos.y, 0.5, rsy - 0.5); | ||
5871 | 6052 | ||
5872 | // edge will be used to pass the Region Coordinates offset | 6053 | float ex, ey; |
5873 | // we want to check for a neighboring sim | ||
5874 | LSL_Vector edge = new LSL_Vector(0, 0, 0); | ||
5875 | 6054 | ||
5876 | if (dir.x == 0) | 6055 | if (dir.x == 0) |
5877 | { | 6056 | { |
5878 | if (dir.y == 0) | 6057 | ex = px; |
5879 | { | 6058 | ey = dir.y > 0 ? rsy + 1.0f : -1.0f; |
5880 | // Direction vector is 0,0 so return | 6059 | } |
5881 | // false since we're staying in the sim | 6060 | else if(dir.y == 0) |
5882 | return 0; | 6061 | { |
5883 | } | 6062 | ex = dir.x > 0 ? rsx + 1.0f : -1.0f; |
5884 | else | 6063 | ey = py; |
5885 | { | ||
5886 | // Y is the only valid direction | ||
5887 | edge.y = dir.y / Math.Abs(dir.y); | ||
5888 | } | ||
5889 | } | 6064 | } |
5890 | else | 6065 | else |
5891 | { | 6066 | { |
5892 | LSL_Float mag; | 6067 | float dx = (float) dir.x; |
5893 | if (dir.x > 0) | 6068 | float dy = (float) dir.y; |
5894 | { | ||
5895 | mag = (World.RegionInfo.RegionSizeX - pos.x) / dir.x; | ||
5896 | } | ||
5897 | else | ||
5898 | { | ||
5899 | mag = (pos.x/dir.x); | ||
5900 | } | ||
5901 | 6069 | ||
5902 | mag = Math.Abs(mag); | 6070 | float t1 = dx * dx + dy * dy; |
6071 | t1 = (float)Math.Sqrt(t1); | ||
6072 | dx /= t1; | ||
6073 | dy /= t1; | ||
5903 | 6074 | ||
5904 | edge.y = pos.y + (dir.y * mag); | 6075 | if(dx > 0) |
5905 | 6076 | t1 = (rsx + 1f - px)/dx; | |
5906 | if (edge.y > World.RegionInfo.RegionSizeY || edge.y < 0) | ||
5907 | { | ||
5908 | // Y goes out of bounds first | ||
5909 | edge.y = dir.y / Math.Abs(dir.y); | ||
5910 | } | ||
5911 | else | 6077 | else |
5912 | { | 6078 | t1 = -(px + 1f)/dx; |
5913 | // X goes out of bounds first or its a corner exit | ||
5914 | edge.y = 0; | ||
5915 | edge.x = dir.x / Math.Abs(dir.x); | ||
5916 | } | ||
5917 | } | ||
5918 | 6079 | ||
5919 | List<GridRegion> neighbors = World.GridService.GetNeighbours(World.RegionInfo.ScopeID, World.RegionInfo.RegionID); | 6080 | float t2; |
6081 | if(dy > 0) | ||
6082 | t2 = (rsy + 1f - py)/dy; | ||
6083 | else | ||
6084 | t2 = -(py + 1f)/dy; | ||
5920 | 6085 | ||
5921 | uint neighborX = World.RegionInfo.RegionLocX + (uint)dir.x; | 6086 | if(t1 > t2) |
5922 | uint neighborY = World.RegionInfo.RegionLocY + (uint)dir.y; | 6087 | t1 = t2; |
5923 | 6088 | ||
5924 | foreach (GridRegion sri in neighbors) | 6089 | ex = px + t1 * dx; |
5925 | { | 6090 | ey = py + t1 * dy; |
5926 | if (sri.RegionCoordX == neighborX && sri.RegionCoordY == neighborY) | ||
5927 | return 0; | ||
5928 | } | 6091 | } |
5929 | 6092 | ||
6093 | ex += World.RegionInfo.WorldLocX; | ||
6094 | ey += World.RegionInfo.WorldLocY; | ||
6095 | |||
6096 | if(World.GridService.GetRegionByPosition(World.RegionInfo.ScopeID, (int)ex, (int)ey) != null) | ||
6097 | return 0; | ||
5930 | return 1; | 6098 | return 1; |
5931 | } | 6099 | } |
5932 | 6100 | ||
@@ -5937,8 +6105,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5937 | /// </summary> | 6105 | /// </summary> |
5938 | public LSL_Integer llGetAgentInfo(string id) | 6106 | public LSL_Integer llGetAgentInfo(string id) |
5939 | { | 6107 | { |
5940 | m_host.AddScriptLPS(1); | ||
5941 | |||
5942 | UUID key = new UUID(); | 6108 | UUID key = new UUID(); |
5943 | if (!UUID.TryParse(id, out key)) | 6109 | if (!UUID.TryParse(id, out key)) |
5944 | { | 6110 | { |
@@ -5980,6 +6146,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5980 | flags |= ScriptBaseClass.AGENT_AWAY; | 6146 | flags |= ScriptBaseClass.AGENT_AWAY; |
5981 | } | 6147 | } |
5982 | 6148 | ||
6149 | UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67"); | ||
6150 | UUID[] anims = agent.Animator.GetAnimationArray(); | ||
6151 | if (Array.Exists<UUID>(anims, a => { return a == busy; })) | ||
6152 | { | ||
6153 | flags |= ScriptBaseClass.AGENT_BUSY; | ||
6154 | } | ||
6155 | |||
5983 | // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? | 6156 | // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? |
5984 | if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) | 6157 | if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) |
5985 | { | 6158 | { |
@@ -6027,13 +6200,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6027 | flags |= ScriptBaseClass.AGENT_SITTING; | 6200 | flags |= ScriptBaseClass.AGENT_SITTING; |
6028 | } | 6201 | } |
6029 | 6202 | ||
6203 | if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0) | ||
6204 | { | ||
6205 | flags |= ScriptBaseClass.AGENT_MALE; | ||
6206 | } | ||
6207 | |||
6030 | return flags; | 6208 | return flags; |
6031 | } | 6209 | } |
6032 | 6210 | ||
6033 | public LSL_String llGetAgentLanguage(string id) | 6211 | public LSL_String llGetAgentLanguage(string id) |
6034 | { | 6212 | { |
6035 | // This should only return a value if the avatar is in the same region, but eh. idc. | 6213 | // This should only return a value if the avatar is in the same region, but eh. idc. |
6036 | m_host.AddScriptLPS(1); | ||
6037 | if (World.AgentPreferencesService == null) | 6214 | if (World.AgentPreferencesService == null) |
6038 | { | 6215 | { |
6039 | Error("llGetAgentLanguage", "No AgentPreferencesService present"); | 6216 | Error("llGetAgentLanguage", "No AgentPreferencesService present"); |
@@ -6056,10 +6233,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6056 | /// AGENT_LIST_PARCEL - all in the same parcel as the scripted object | 6233 | /// AGENT_LIST_PARCEL - all in the same parcel as the scripted object |
6057 | /// AGENT_LIST_PARCEL_OWNER - all in any parcel owned by the owner of the | 6234 | /// AGENT_LIST_PARCEL_OWNER - all in any parcel owned by the owner of the |
6058 | /// current parcel. | 6235 | /// current parcel. |
6236 | /// AGENT_LIST_EXCLUDENPC ignore NPCs (bit mask) | ||
6059 | /// </summary> | 6237 | /// </summary> |
6060 | public LSL_List llGetAgentList(LSL_Integer scope, LSL_List options) | 6238 | public LSL_List llGetAgentList(LSL_Integer scope, LSL_List options) |
6061 | { | 6239 | { |
6062 | m_host.AddScriptLPS(1); | 6240 | // do our bit masks part |
6241 | bool noNPC = (scope & ScriptBaseClass.AGENT_LIST_EXCLUDENPC) !=0; | ||
6242 | |||
6243 | // remove bit masks part | ||
6244 | scope &= ~ ScriptBaseClass.AGENT_LIST_EXCLUDENPC; | ||
6063 | 6245 | ||
6064 | // the constants are 1, 2 and 4 so bits are being set, but you | 6246 | // the constants are 1, 2 and 4 so bits are being set, but you |
6065 | // get an error "INVALID_SCOPE" if it is anything but 1, 2 and 4 | 6247 | // get an error "INVALID_SCOPE" if it is anything but 1, 2 and 4 |
@@ -6101,8 +6283,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6101 | World.ForEachRootScenePresence( | 6283 | World.ForEachRootScenePresence( |
6102 | delegate (ScenePresence ssp) | 6284 | delegate (ScenePresence ssp) |
6103 | { | 6285 | { |
6286 | if(noNPC && ssp.IsNPC) | ||
6287 | return; | ||
6288 | |||
6104 | // Gods are not listed in SL | 6289 | // Gods are not listed in SL |
6105 | if (!ssp.IsDeleted && ssp.GodLevel == 0.0 && !ssp.IsChildAgent) | 6290 | if (!ssp.IsDeleted && !ssp.IsViewerUIGod && !ssp.IsChildAgent) |
6106 | { | 6291 | { |
6107 | if (!regionWide) | 6292 | if (!regionWide) |
6108 | { | 6293 | { |
@@ -6133,19 +6318,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6133 | 6318 | ||
6134 | public void llAdjustSoundVolume(double volume) | 6319 | public void llAdjustSoundVolume(double volume) |
6135 | { | 6320 | { |
6136 | m_host.AddScriptLPS(1); | ||
6137 | m_host.AdjustSoundGain(volume); | 6321 | m_host.AdjustSoundGain(volume); |
6138 | } | 6322 | } |
6139 | 6323 | ||
6140 | public void llSetSoundRadius(double radius) | 6324 | public void llSetSoundRadius(double radius) |
6141 | { | 6325 | { |
6142 | m_host.AddScriptLPS(1); | ||
6143 | m_host.SoundRadius = radius; | 6326 | m_host.SoundRadius = radius; |
6144 | } | 6327 | } |
6145 | 6328 | ||
6146 | public LSL_String llKey2Name(string id) | 6329 | public LSL_String llKey2Name(string id) |
6147 | { | 6330 | { |
6148 | m_host.AddScriptLPS(1); | ||
6149 | UUID key = new UUID(); | 6331 | UUID key = new UUID(); |
6150 | if (UUID.TryParse(id,out key)) | 6332 | if (UUID.TryParse(id,out key)) |
6151 | { | 6333 | { |
@@ -6169,20 +6351,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6169 | 6351 | ||
6170 | public void llSetTextureAnim(int mode, int face, int sizex, int sizey, double start, double length, double rate) | 6352 | public void llSetTextureAnim(int mode, int face, int sizex, int sizey, double start, double length, double rate) |
6171 | { | 6353 | { |
6172 | m_host.AddScriptLPS(1); | ||
6173 | |||
6174 | SetTextureAnim(m_host, mode, face, sizex, sizey, start, length, rate); | 6354 | SetTextureAnim(m_host, mode, face, sizex, sizey, start, length, rate); |
6175 | } | 6355 | } |
6176 | 6356 | ||
6177 | public void llSetLinkTextureAnim(int linknumber, int mode, int face, int sizex, int sizey, double start, double length, double rate) | 6357 | public void llSetLinkTextureAnim(int linknumber, int mode, int face, int sizex, int sizey, double start, double length, double rate) |
6178 | { | 6358 | { |
6179 | m_host.AddScriptLPS(1); | ||
6180 | |||
6181 | List<SceneObjectPart> parts = GetLinkParts(linknumber); | 6359 | List<SceneObjectPart> parts = GetLinkParts(linknumber); |
6182 | 6360 | ||
6183 | foreach (SceneObjectPart part in parts) | 6361 | try |
6362 | { | ||
6363 | foreach (SceneObjectPart part in parts) | ||
6364 | { | ||
6365 | SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); | ||
6366 | } | ||
6367 | } | ||
6368 | finally | ||
6184 | { | 6369 | { |
6185 | SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); | ||
6186 | } | 6370 | } |
6187 | } | 6371 | } |
6188 | 6372 | ||
@@ -6211,7 +6395,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6211 | public void llTriggerSoundLimited(string sound, double volume, LSL_Vector top_north_east, | 6395 | public void llTriggerSoundLimited(string sound, double volume, LSL_Vector top_north_east, |
6212 | LSL_Vector bottom_south_west) | 6396 | LSL_Vector bottom_south_west) |
6213 | { | 6397 | { |
6214 | m_host.AddScriptLPS(1); | ||
6215 | if (m_SoundModule != null) | 6398 | if (m_SoundModule != null) |
6216 | { | 6399 | { |
6217 | m_SoundModule.TriggerSoundLimited(m_host.UUID, | 6400 | m_SoundModule.TriggerSoundLimited(m_host.UUID, |
@@ -6222,7 +6405,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6222 | 6405 | ||
6223 | public void llEjectFromLand(string pest) | 6406 | public void llEjectFromLand(string pest) |
6224 | { | 6407 | { |
6225 | m_host.AddScriptLPS(1); | ||
6226 | UUID agentID = new UUID(); | 6408 | UUID agentID = new UUID(); |
6227 | if (UUID.TryParse(pest, out agentID)) | 6409 | if (UUID.TryParse(pest, out agentID)) |
6228 | { | 6410 | { |
@@ -6236,15 +6418,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6236 | 6418 | ||
6237 | if (m_host.OwnerID == land.LandData.OwnerID) | 6419 | if (m_host.OwnerID == land.LandData.OwnerID) |
6238 | { | 6420 | { |
6239 | World.TeleportClientHome(agentID, presence.ControllingClient); | 6421 | Vector3 p = World.GetNearestAllowedPosition(presence, land); |
6422 | presence.TeleportOnEject(p); | ||
6423 | presence.ControllingClient.SendAlertMessage("You have been ejected from this land"); | ||
6240 | } | 6424 | } |
6241 | } | 6425 | } |
6242 | } | 6426 | } |
6243 | } | 6427 | } |
6244 | 6428 | ||
6429 | public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers) | ||
6430 | { | ||
6431 | return ParseString2List(str, separators, in_spacers, false); | ||
6432 | } | ||
6433 | |||
6245 | public LSL_Integer llOverMyLand(string id) | 6434 | public LSL_Integer llOverMyLand(string id) |
6246 | { | 6435 | { |
6247 | m_host.AddScriptLPS(1); | ||
6248 | UUID key = new UUID(); | 6436 | UUID key = new UUID(); |
6249 | if (UUID.TryParse(id, out key)) | 6437 | if (UUID.TryParse(id, out key)) |
6250 | { | 6438 | { |
@@ -6271,7 +6459,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6271 | 6459 | ||
6272 | public LSL_String llGetLandOwnerAt(LSL_Vector pos) | 6460 | public LSL_String llGetLandOwnerAt(LSL_Vector pos) |
6273 | { | 6461 | { |
6274 | m_host.AddScriptLPS(1); | ||
6275 | ILandObject land = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); | 6462 | ILandObject land = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); |
6276 | if (land == null) | 6463 | if (land == null) |
6277 | return UUID.Zero.ToString(); | 6464 | return UUID.Zero.ToString(); |
@@ -6285,7 +6472,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6285 | /// </summary> | 6472 | /// </summary> |
6286 | public LSL_Vector llGetAgentSize(string id) | 6473 | public LSL_Vector llGetAgentSize(string id) |
6287 | { | 6474 | { |
6288 | m_host.AddScriptLPS(1); | ||
6289 | ScenePresence avatar = World.GetScenePresence((UUID)id); | 6475 | ScenePresence avatar = World.GetScenePresence((UUID)id); |
6290 | LSL_Vector agentSize; | 6476 | LSL_Vector agentSize; |
6291 | if (avatar == null || avatar.IsChildAgent) // Fail if not in the same region | 6477 | if (avatar == null || avatar.IsChildAgent) // Fail if not in the same region |
@@ -6294,32 +6480,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6294 | } | 6480 | } |
6295 | else | 6481 | else |
6296 | { | 6482 | { |
6297 | agentSize = GetAgentSize(avatar); | 6483 | // agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight); |
6484 | Vector3 s = avatar.Appearance.AvatarSize; | ||
6485 | agentSize = new LSL_Vector(s.X, s.Y, s.Z); | ||
6298 | } | 6486 | } |
6299 | |||
6300 | return agentSize; | 6487 | return agentSize; |
6301 | } | 6488 | } |
6302 | 6489 | ||
6303 | public LSL_Integer llSameGroup(string agent) | 6490 | public LSL_Integer llSameGroup(string id) |
6304 | { | 6491 | { |
6305 | m_host.AddScriptLPS(1); | 6492 | UUID uuid = new UUID(); |
6306 | UUID agentId = new UUID(); | 6493 | if (!UUID.TryParse(id, out uuid)) |
6307 | if (!UUID.TryParse(agent, out agentId)) | ||
6308 | return new LSL_Integer(0); | 6494 | return new LSL_Integer(0); |
6309 | ScenePresence presence = World.GetScenePresence(agentId); | 6495 | |
6310 | if (presence == null || presence.IsChildAgent) // Return flase for child agents | 6496 | // Check if it's a group key |
6311 | return new LSL_Integer(0); | 6497 | if (uuid == m_host.ParentGroup.RootPart.GroupID) |
6312 | IClientAPI client = presence.ControllingClient; | ||
6313 | if (m_host.GroupID == client.ActiveGroupId) | ||
6314 | return new LSL_Integer(1); | 6498 | return new LSL_Integer(1); |
6315 | else | 6499 | |
6500 | // Handle object case | ||
6501 | SceneObjectPart part = World.GetSceneObjectPart(uuid); | ||
6502 | if (part != null) | ||
6503 | { | ||
6504 | |||
6505 | if(part.ParentGroup.IsAttachment) | ||
6506 | { | ||
6507 | uuid = part.ParentGroup.AttachedAvatar; | ||
6508 | } | ||
6509 | else | ||
6510 | { | ||
6511 | // This will handle both deed and non-deed and also the no | ||
6512 | // group case | ||
6513 | if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID) | ||
6514 | return new LSL_Integer(1); | ||
6515 | |||
6516 | return new LSL_Integer(0); | ||
6517 | } | ||
6518 | } | ||
6519 | |||
6520 | // Handle the case where id names an avatar | ||
6521 | ScenePresence presence = World.GetScenePresence(uuid); | ||
6522 | if (presence != null) | ||
6523 | { | ||
6524 | if (presence.IsChildAgent) | ||
6525 | return new LSL_Integer(0); | ||
6526 | |||
6527 | IClientAPI client = presence.ControllingClient; | ||
6528 | if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId) | ||
6529 | return new LSL_Integer(1); | ||
6530 | |||
6316 | return new LSL_Integer(0); | 6531 | return new LSL_Integer(0); |
6532 | } | ||
6533 | |||
6534 | return new LSL_Integer(0); | ||
6317 | } | 6535 | } |
6318 | 6536 | ||
6319 | public void llUnSit(string id) | 6537 | public void llUnSit(string id) |
6320 | { | 6538 | { |
6321 | m_host.AddScriptLPS(1); | ||
6322 | |||
6323 | UUID key = new UUID(); | 6539 | UUID key = new UUID(); |
6324 | if (UUID.TryParse(id, out key)) | 6540 | if (UUID.TryParse(id, out key)) |
6325 | { | 6541 | { |
@@ -6359,8 +6575,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6359 | 6575 | ||
6360 | public LSL_Vector llGroundSlope(LSL_Vector offset) | 6576 | public LSL_Vector llGroundSlope(LSL_Vector offset) |
6361 | { | 6577 | { |
6362 | m_host.AddScriptLPS(1); | ||
6363 | |||
6364 | //Get the slope normal. This gives us the equation of the plane tangent to the slope. | 6578 | //Get the slope normal. This gives us the equation of the plane tangent to the slope. |
6365 | LSL_Vector vsn = llGroundNormal(offset); | 6579 | LSL_Vector vsn = llGroundNormal(offset); |
6366 | 6580 | ||
@@ -6380,7 +6594,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6380 | 6594 | ||
6381 | public LSL_Vector llGroundNormal(LSL_Vector offset) | 6595 | public LSL_Vector llGroundNormal(LSL_Vector offset) |
6382 | { | 6596 | { |
6383 | m_host.AddScriptLPS(1); | ||
6384 | Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset; | 6597 | Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset; |
6385 | // Clamp to valid position | 6598 | // Clamp to valid position |
6386 | if (pos.X < 0) | 6599 | if (pos.X < 0) |
@@ -6430,27 +6643,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6430 | 6643 | ||
6431 | public LSL_Vector llGroundContour(LSL_Vector offset) | 6644 | public LSL_Vector llGroundContour(LSL_Vector offset) |
6432 | { | 6645 | { |
6433 | m_host.AddScriptLPS(1); | ||
6434 | LSL_Vector x = llGroundSlope(offset); | 6646 | LSL_Vector x = llGroundSlope(offset); |
6435 | return new LSL_Vector(-x.y, x.x, 0.0); | 6647 | return new LSL_Vector(-x.y, x.x, 0.0); |
6436 | } | 6648 | } |
6437 | 6649 | ||
6438 | public LSL_Integer llGetAttached() | 6650 | public LSL_Integer llGetAttached() |
6439 | { | 6651 | { |
6440 | m_host.AddScriptLPS(1); | ||
6441 | return m_host.ParentGroup.AttachmentPoint; | 6652 | return m_host.ParentGroup.AttachmentPoint; |
6442 | } | 6653 | } |
6443 | 6654 | ||
6655 | public LSL_List llGetAttachedList(string id) | ||
6656 | { | ||
6657 | ScenePresence av = World.GetScenePresence((UUID)id); | ||
6658 | |||
6659 | if (av == null || av.IsDeleted) | ||
6660 | return new LSL_List("NOT_FOUND"); | ||
6661 | |||
6662 | if (av.IsChildAgent || av.IsInTransit) | ||
6663 | return new LSL_List("NOT_ON_REGION"); | ||
6664 | |||
6665 | LSL_List AttachmentsList = new LSL_List(); | ||
6666 | List<SceneObjectGroup> Attachments; | ||
6667 | |||
6668 | Attachments = av.GetAttachments(); | ||
6669 | |||
6670 | foreach (SceneObjectGroup Attachment in Attachments) | ||
6671 | { | ||
6672 | if(Attachment.HasPrivateAttachmentPoint) | ||
6673 | continue; | ||
6674 | AttachmentsList.Add(new LSL_Key(Attachment.UUID.ToString())); | ||
6675 | } | ||
6676 | |||
6677 | return AttachmentsList; | ||
6678 | } | ||
6679 | |||
6444 | public virtual LSL_Integer llGetFreeMemory() | 6680 | public virtual LSL_Integer llGetFreeMemory() |
6445 | { | 6681 | { |
6446 | m_host.AddScriptLPS(1); | ||
6447 | // Make scripts designed for Mono happy | 6682 | // Make scripts designed for Mono happy |
6448 | return 65536; | 6683 | return 65536; |
6449 | } | 6684 | } |
6450 | 6685 | ||
6451 | public LSL_Integer llGetFreeURLs() | 6686 | public LSL_Integer llGetFreeURLs() |
6452 | { | 6687 | { |
6453 | m_host.AddScriptLPS(1); | ||
6454 | if (m_UrlModule != null) | 6688 | if (m_UrlModule != null) |
6455 | return new LSL_Integer(m_UrlModule.GetFreeUrls()); | 6689 | return new LSL_Integer(m_UrlModule.GetFreeUrls()); |
6456 | return new LSL_Integer(0); | 6690 | return new LSL_Integer(0); |
@@ -6459,13 +6693,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6459 | 6693 | ||
6460 | public LSL_String llGetRegionName() | 6694 | public LSL_String llGetRegionName() |
6461 | { | 6695 | { |
6462 | m_host.AddScriptLPS(1); | ||
6463 | return World.RegionInfo.RegionName; | 6696 | return World.RegionInfo.RegionName; |
6464 | } | 6697 | } |
6465 | 6698 | ||
6466 | public LSL_Float llGetRegionTimeDilation() | 6699 | public LSL_Float llGetRegionTimeDilation() |
6467 | { | 6700 | { |
6468 | m_host.AddScriptLPS(1); | ||
6469 | return (double)World.TimeDilation; | 6701 | return (double)World.TimeDilation; |
6470 | } | 6702 | } |
6471 | 6703 | ||
@@ -6474,7 +6706,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6474 | /// </summary> | 6706 | /// </summary> |
6475 | public LSL_Float llGetRegionFPS() | 6707 | public LSL_Float llGetRegionFPS() |
6476 | { | 6708 | { |
6477 | m_host.AddScriptLPS(1); | ||
6478 | return World.StatsReporter.LastReportedSimFPS; | 6709 | return World.StatsReporter.LastReportedSimFPS; |
6479 | } | 6710 | } |
6480 | 6711 | ||
@@ -6552,8 +6783,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6552 | 6783 | ||
6553 | public void llLinkParticleSystem(int linknumber, LSL_List rules) | 6784 | public void llLinkParticleSystem(int linknumber, LSL_List rules) |
6554 | { | 6785 | { |
6555 | m_host.AddScriptLPS(1); | ||
6556 | |||
6557 | List<SceneObjectPart> parts = GetLinkParts(linknumber); | 6786 | List<SceneObjectPart> parts = GetLinkParts(linknumber); |
6558 | 6787 | ||
6559 | foreach (SceneObjectPart part in parts) | 6788 | foreach (SceneObjectPart part in parts) |
@@ -6564,7 +6793,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6564 | 6793 | ||
6565 | public void llParticleSystem(LSL_List rules) | 6794 | public void llParticleSystem(LSL_List rules) |
6566 | { | 6795 | { |
6567 | m_host.AddScriptLPS(1); | ||
6568 | SetParticleSystem(m_host, rules, "llParticleSystem"); | 6796 | SetParticleSystem(m_host, rules, "llParticleSystem"); |
6569 | } | 6797 | } |
6570 | 6798 | ||
@@ -6981,7 +7209,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
6981 | 7209 | ||
6982 | public void llGroundRepel(double height, int water, double tau) | 7210 | public void llGroundRepel(double height, int water, double tau) |
6983 | { | 7211 | { |
6984 | m_host.AddScriptLPS(1); | ||
6985 | if (m_host.PhysActor != null) | 7212 | if (m_host.PhysActor != null) |
6986 | { | 7213 | { |
6987 | float ground = (float)llGround(new LSL_Types.Vector3(0, 0, 0)); | 7214 | float ground = (float)llGround(new LSL_Types.Vector3(0, 0, 0)); |
@@ -7006,8 +7233,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7006 | 7233 | ||
7007 | public void llGiveInventoryList(string destination, string category, LSL_List inventory) | 7234 | public void llGiveInventoryList(string destination, string category, LSL_List inventory) |
7008 | { | 7235 | { |
7009 | m_host.AddScriptLPS(1); | ||
7010 | |||
7011 | UUID destID; | 7236 | UUID destID; |
7012 | if (!UUID.TryParse(destination, out destID)) | 7237 | if (!UUID.TryParse(destination, out destID)) |
7013 | return; | 7238 | return; |
@@ -7061,8 +7286,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7061 | 7286 | ||
7062 | public void llSetVehicleType(int type) | 7287 | public void llSetVehicleType(int type) |
7063 | { | 7288 | { |
7064 | m_host.AddScriptLPS(1); | ||
7065 | |||
7066 | if (!m_host.ParentGroup.IsDeleted) | 7289 | if (!m_host.ParentGroup.IsDeleted) |
7067 | { | 7290 | { |
7068 | m_host.ParentGroup.RootPart.SetVehicleType(type); | 7291 | m_host.ParentGroup.RootPart.SetVehicleType(type); |
@@ -7073,8 +7296,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7073 | //CFK 9/28: so these are not complete yet. | 7296 | //CFK 9/28: so these are not complete yet. |
7074 | public void llSetVehicleFloatParam(int param, LSL_Float value) | 7297 | public void llSetVehicleFloatParam(int param, LSL_Float value) |
7075 | { | 7298 | { |
7076 | m_host.AddScriptLPS(1); | ||
7077 | |||
7078 | if (!m_host.ParentGroup.IsDeleted) | 7299 | if (!m_host.ParentGroup.IsDeleted) |
7079 | { | 7300 | { |
7080 | m_host.ParentGroup.RootPart.SetVehicleFloatParam(param, (float)value); | 7301 | m_host.ParentGroup.RootPart.SetVehicleFloatParam(param, (float)value); |
@@ -7085,8 +7306,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7085 | //CFK 9/28: so these are not complete yet. | 7306 | //CFK 9/28: so these are not complete yet. |
7086 | public void llSetVehicleVectorParam(int param, LSL_Vector vec) | 7307 | public void llSetVehicleVectorParam(int param, LSL_Vector vec) |
7087 | { | 7308 | { |
7088 | m_host.AddScriptLPS(1); | ||
7089 | |||
7090 | if (!m_host.ParentGroup.IsDeleted) | 7309 | if (!m_host.ParentGroup.IsDeleted) |
7091 | { | 7310 | { |
7092 | m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, vec); | 7311 | m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, vec); |
@@ -7097,8 +7316,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7097 | //CFK 9/28: so these are not complete yet. | 7316 | //CFK 9/28: so these are not complete yet. |
7098 | public void llSetVehicleRotationParam(int param, LSL_Rotation rot) | 7317 | public void llSetVehicleRotationParam(int param, LSL_Rotation rot) |
7099 | { | 7318 | { |
7100 | m_host.AddScriptLPS(1); | ||
7101 | |||
7102 | if (!m_host.ParentGroup.IsDeleted) | 7319 | if (!m_host.ParentGroup.IsDeleted) |
7103 | { | 7320 | { |
7104 | m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, rot); | 7321 | m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, rot); |
@@ -7107,8 +7324,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7107 | 7324 | ||
7108 | public void llSetVehicleFlags(int flags) | 7325 | public void llSetVehicleFlags(int flags) |
7109 | { | 7326 | { |
7110 | m_host.AddScriptLPS(1); | ||
7111 | |||
7112 | if (!m_host.ParentGroup.IsDeleted) | 7327 | if (!m_host.ParentGroup.IsDeleted) |
7113 | { | 7328 | { |
7114 | m_host.ParentGroup.RootPart.SetVehicleFlags(flags, false); | 7329 | m_host.ParentGroup.RootPart.SetVehicleFlags(flags, false); |
@@ -7117,8 +7332,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7117 | 7332 | ||
7118 | public void llRemoveVehicleFlags(int flags) | 7333 | public void llRemoveVehicleFlags(int flags) |
7119 | { | 7334 | { |
7120 | m_host.AddScriptLPS(1); | ||
7121 | |||
7122 | if (!m_host.ParentGroup.IsDeleted) | 7335 | if (!m_host.ParentGroup.IsDeleted) |
7123 | { | 7336 | { |
7124 | m_host.ParentGroup.RootPart.SetVehicleFlags(flags, true); | 7337 | m_host.ParentGroup.RootPart.SetVehicleFlags(flags, true); |
@@ -7127,6 +7340,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7127 | 7340 | ||
7128 | protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) | 7341 | protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) |
7129 | { | 7342 | { |
7343 | // LSL quaternions can normalize to 0, normal Quaternions can't. | ||
7344 | if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0) | ||
7345 | rot.s = 1; // ZERO_ROTATION = 0,0,0,1 | ||
7346 | |||
7130 | part.SitTargetPosition = offset; | 7347 | part.SitTargetPosition = offset; |
7131 | part.SitTargetOrientation = rot; | 7348 | part.SitTargetOrientation = rot; |
7132 | part.ParentGroup.HasGroupChanged = true; | 7349 | part.ParentGroup.HasGroupChanged = true; |
@@ -7134,13 +7351,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7134 | 7351 | ||
7135 | public void llSitTarget(LSL_Vector offset, LSL_Rotation rot) | 7352 | public void llSitTarget(LSL_Vector offset, LSL_Rotation rot) |
7136 | { | 7353 | { |
7137 | m_host.AddScriptLPS(1); | ||
7138 | SitTarget(m_host, offset, rot); | 7354 | SitTarget(m_host, offset, rot); |
7139 | } | 7355 | } |
7140 | 7356 | ||
7141 | public void llLinkSitTarget(LSL_Integer link, LSL_Vector offset, LSL_Rotation rot) | 7357 | public void llLinkSitTarget(LSL_Integer link, LSL_Vector offset, LSL_Rotation rot) |
7142 | { | 7358 | { |
7143 | m_host.AddScriptLPS(1); | ||
7144 | if (link == ScriptBaseClass.LINK_ROOT) | 7359 | if (link == ScriptBaseClass.LINK_ROOT) |
7145 | SitTarget(m_host.ParentGroup.RootPart, offset, rot); | 7360 | SitTarget(m_host.ParentGroup.RootPart, offset, rot); |
7146 | else if (link == ScriptBaseClass.LINK_THIS) | 7361 | else if (link == ScriptBaseClass.LINK_THIS) |
@@ -7157,31 +7372,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7157 | 7372 | ||
7158 | public LSL_String llAvatarOnSitTarget() | 7373 | public LSL_String llAvatarOnSitTarget() |
7159 | { | 7374 | { |
7160 | m_host.AddScriptLPS(1); | ||
7161 | return m_host.SitTargetAvatar.ToString(); | 7375 | return m_host.SitTargetAvatar.ToString(); |
7162 | } | 7376 | } |
7163 | 7377 | ||
7164 | // http://wiki.secondlife.com/wiki/LlAvatarOnLinkSitTarget | 7378 | // http://wiki.secondlife.com/wiki/LlAvatarOnLinkSitTarget |
7165 | public LSL_String llAvatarOnLinkSitTarget(int linknum) | 7379 | public LSL_String llAvatarOnLinkSitTarget(int linknum) |
7166 | { | 7380 | { |
7167 | m_host.AddScriptLPS(1); | ||
7168 | if(linknum == ScriptBaseClass.LINK_SET || | 7381 | if(linknum == ScriptBaseClass.LINK_SET || |
7169 | linknum == ScriptBaseClass.LINK_ALL_CHILDREN || | 7382 | linknum == ScriptBaseClass.LINK_ALL_CHILDREN || |
7170 | linknum == ScriptBaseClass.LINK_ALL_OTHERS) return UUID.Zero.ToString(); | 7383 | linknum == ScriptBaseClass.LINK_ALL_OTHERS || |
7384 | linknum == 0) | ||
7385 | return UUID.Zero.ToString(); | ||
7171 | 7386 | ||
7172 | List<SceneObjectPart> parts = GetLinkParts(linknum); | 7387 | List<SceneObjectPart> parts = GetLinkParts(linknum); |
7173 | if (parts.Count == 0) return UUID.Zero.ToString(); | 7388 | if (parts.Count == 0) |
7389 | return UUID.Zero.ToString(); | ||
7174 | return parts[0].SitTargetAvatar.ToString(); | 7390 | return parts[0].SitTargetAvatar.ToString(); |
7175 | } | 7391 | } |
7176 | 7392 | ||
7177 | 7393 | ||
7178 | public void llAddToLandPassList(string avatar, double hours) | 7394 | public void llAddToLandPassList(string avatar, double hours) |
7179 | { | 7395 | { |
7180 | m_host.AddScriptLPS(1); | ||
7181 | UUID key; | 7396 | UUID key; |
7182 | ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); | 7397 | ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); |
7183 | 7398 | ||
7184 | if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) | 7399 | if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManagePasses, false)) |
7185 | { | 7400 | { |
7186 | int expires = 0; | 7401 | int expires = 0; |
7187 | if (hours != 0) | 7402 | if (hours != 0) |
@@ -7218,19 +7433,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7218 | 7433 | ||
7219 | public void llSetTouchText(string text) | 7434 | public void llSetTouchText(string text) |
7220 | { | 7435 | { |
7221 | m_host.AddScriptLPS(1); | ||
7222 | m_host.TouchName = text; | 7436 | m_host.TouchName = text; |
7223 | } | 7437 | } |
7224 | 7438 | ||
7225 | public void llSetSitText(string text) | 7439 | public void llSetSitText(string text) |
7226 | { | 7440 | { |
7227 | m_host.AddScriptLPS(1); | ||
7228 | m_host.SitName = text; | 7441 | m_host.SitName = text; |
7229 | } | 7442 | } |
7230 | 7443 | ||
7231 | public void llSetCameraEyeOffset(LSL_Vector offset) | 7444 | public void llSetCameraEyeOffset(LSL_Vector offset) |
7232 | { | 7445 | { |
7233 | m_host.AddScriptLPS(1); | ||
7234 | m_host.SetCameraEyeOffset(offset); | 7446 | m_host.SetCameraEyeOffset(offset); |
7235 | 7447 | ||
7236 | if (m_host.ParentGroup.RootPart.GetCameraEyeOffset() == Vector3.Zero) | 7448 | if (m_host.ParentGroup.RootPart.GetCameraEyeOffset() == Vector3.Zero) |
@@ -7239,7 +7451,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7239 | 7451 | ||
7240 | public void llSetCameraAtOffset(LSL_Vector offset) | 7452 | public void llSetCameraAtOffset(LSL_Vector offset) |
7241 | { | 7453 | { |
7242 | m_host.AddScriptLPS(1); | ||
7243 | m_host.SetCameraAtOffset(offset); | 7454 | m_host.SetCameraAtOffset(offset); |
7244 | 7455 | ||
7245 | if (m_host.ParentGroup.RootPart.GetCameraAtOffset() == Vector3.Zero) | 7456 | if (m_host.ParentGroup.RootPart.GetCameraAtOffset() == Vector3.Zero) |
@@ -7248,8 +7459,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7248 | 7459 | ||
7249 | public void llSetLinkCamera(LSL_Integer link, LSL_Vector eye, LSL_Vector at) | 7460 | public void llSetLinkCamera(LSL_Integer link, LSL_Vector eye, LSL_Vector at) |
7250 | { | 7461 | { |
7251 | m_host.AddScriptLPS(1); | ||
7252 | |||
7253 | if (link == ScriptBaseClass.LINK_SET || | 7462 | if (link == ScriptBaseClass.LINK_SET || |
7254 | link == ScriptBaseClass.LINK_ALL_CHILDREN || | 7463 | link == ScriptBaseClass.LINK_ALL_CHILDREN || |
7255 | link == ScriptBaseClass.LINK_ALL_OTHERS) return; | 7464 | link == ScriptBaseClass.LINK_ALL_OTHERS) return; |
@@ -7278,7 +7487,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7278 | 7487 | ||
7279 | public LSL_String llDumpList2String(LSL_List src, string seperator) | 7488 | public LSL_String llDumpList2String(LSL_List src, string seperator) |
7280 | { | 7489 | { |
7281 | m_host.AddScriptLPS(1); | ||
7282 | if (src.Length == 0) | 7490 | if (src.Length == 0) |
7283 | { | 7491 | { |
7284 | return String.Empty; | 7492 | return String.Empty; |
@@ -7294,8 +7502,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7294 | 7502 | ||
7295 | public LSL_Integer llScriptDanger(LSL_Vector pos) | 7503 | public LSL_Integer llScriptDanger(LSL_Vector pos) |
7296 | { | 7504 | { |
7297 | m_host.AddScriptLPS(1); | 7505 | bool result = World.LSLScriptDanger(m_host, pos); |
7298 | bool result = World.ScriptDanger(m_host.LocalId, pos); | ||
7299 | if (result) | 7506 | if (result) |
7300 | { | 7507 | { |
7301 | return 1; | 7508 | return 1; |
@@ -7304,7 +7511,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7304 | { | 7511 | { |
7305 | return 0; | 7512 | return 0; |
7306 | } | 7513 | } |
7307 | |||
7308 | } | 7514 | } |
7309 | 7515 | ||
7310 | public void llDialog(string avatar, string message, LSL_List buttons, int chat_channel) | 7516 | public void llDialog(string avatar, string message, LSL_List buttons, int chat_channel) |
@@ -7314,35 +7520,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7314 | if (dm == null) | 7520 | if (dm == null) |
7315 | return; | 7521 | return; |
7316 | 7522 | ||
7317 | m_host.AddScriptLPS(1); | ||
7318 | UUID av = new UUID(); | 7523 | UUID av = new UUID(); |
7319 | if (!UUID.TryParse(avatar,out av)) | 7524 | if (!UUID.TryParse(avatar,out av)) |
7320 | { | 7525 | { |
7321 | Error("llDialog", "First parameter must be a key"); | 7526 | Error("llDialog", "First parameter must be a key"); |
7322 | return; | 7527 | return; |
7323 | } | 7528 | } |
7324 | if (buttons.Length < 1) | 7529 | |
7530 | int length = buttons.Length; | ||
7531 | if (length < 1) | ||
7325 | { | 7532 | { |
7326 | Error("llDialog", "At least 1 button must be shown"); | 7533 | Error("llDialog", "At least 1 button must be shown"); |
7327 | return; | 7534 | return; |
7328 | } | 7535 | } |
7329 | if (buttons.Length > 12) | 7536 | if (length > 12) |
7330 | { | 7537 | { |
7331 | Error("llDialog", "No more than 12 buttons can be shown"); | 7538 | Error("llDialog", "No more than 12 buttons can be shown"); |
7332 | return; | 7539 | return; |
7333 | } | 7540 | } |
7334 | string[] buts = new string[buttons.Length]; | 7541 | |
7335 | for (int i = 0; i < buttons.Length; i++) | 7542 | if (message == string.Empty) |
7543 | { | ||
7544 | Error("llDialog", "Empty message"); | ||
7545 | } | ||
7546 | else if (Encoding.UTF8.GetByteCount(message) > 512) | ||
7547 | { | ||
7548 | Error("llDialog", "Message longer than 512 bytes"); | ||
7549 | } | ||
7550 | |||
7551 | string[] buts = new string[length]; | ||
7552 | for (int i = 0; i < length; i++) | ||
7336 | { | 7553 | { |
7337 | if (buttons.Data[i].ToString() == String.Empty) | 7554 | if (buttons.Data[i].ToString() == String.Empty) |
7338 | { | 7555 | { |
7339 | Error("llDialog", "Button label cannot be blank"); | 7556 | Error("llDialog", "Button label cannot be blank."); |
7340 | return; | 7557 | return; |
7341 | } | 7558 | } |
7342 | if (buttons.Data[i].ToString().Length > 24) | 7559 | if (buttons.Data[i].ToString().Length > 24) |
7343 | { | 7560 | { |
7344 | Error("llDialog", "Button label cannot be longer than 24 characters"); | 7561 | Error("llDialog", "Button label should not be longer than 24 characters."); |
7345 | return; | ||
7346 | } | 7562 | } |
7347 | buts[i] = buttons.Data[i].ToString(); | 7563 | buts[i] = buttons.Data[i].ToString(); |
7348 | } | 7564 | } |
@@ -7354,28 +7570,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7354 | 7570 | ||
7355 | public void llVolumeDetect(int detect) | 7571 | public void llVolumeDetect(int detect) |
7356 | { | 7572 | { |
7357 | m_host.AddScriptLPS(1); | ||
7358 | |||
7359 | if (!m_host.ParentGroup.IsDeleted) | 7573 | if (!m_host.ParentGroup.IsDeleted) |
7360 | m_host.ParentGroup.ScriptSetVolumeDetect(detect != 0); | 7574 | m_host.ParentGroup.ScriptSetVolumeDetect(detect != 0); |
7361 | } | 7575 | } |
7362 | 7576 | ||
7363 | public void llRemoteLoadScript(string target, string name, int running, int start_param) | 7577 | public void llRemoteLoadScript(string target, string name, int running, int start_param) |
7364 | { | 7578 | { |
7365 | m_host.AddScriptLPS(1); | ||
7366 | Deprecated("llRemoteLoadScript", "Use llRemoteLoadScriptPin instead"); | 7579 | Deprecated("llRemoteLoadScript", "Use llRemoteLoadScriptPin instead"); |
7367 | } | 7580 | } |
7368 | 7581 | ||
7369 | public void llSetRemoteScriptAccessPin(int pin) | 7582 | public void llSetRemoteScriptAccessPin(int pin) |
7370 | { | 7583 | { |
7371 | m_host.AddScriptLPS(1); | ||
7372 | m_host.ScriptAccessPin = pin; | 7584 | m_host.ScriptAccessPin = pin; |
7373 | } | 7585 | } |
7374 | 7586 | ||
7375 | public void llRemoteLoadScriptPin(string target, string name, int pin, int running, int start_param) | 7587 | public void llRemoteLoadScriptPin(string target, string name, int pin, int running, int start_param) |
7376 | { | 7588 | { |
7377 | m_host.AddScriptLPS(1); | ||
7378 | |||
7379 | UUID destId = UUID.Zero; | 7589 | UUID destId = UUID.Zero; |
7380 | 7590 | ||
7381 | if (!UUID.TryParse(target, out destId)) | 7591 | if (!UUID.TryParse(target, out destId)) |
@@ -7400,13 +7610,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7400 | return; | 7610 | return; |
7401 | } | 7611 | } |
7402 | 7612 | ||
7403 | // the rest of the permission checks are done in RezScript, so check the pin there as well | 7613 | SceneObjectPart dest = World.GetSceneObjectPart(destId); |
7404 | World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); | 7614 | if (dest != null) |
7615 | { | ||
7616 | if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID) | ||
7617 | { | ||
7618 | // the rest of the permission checks are done in RezScript, so check the pin there as well | ||
7619 | World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); | ||
7620 | |||
7621 | if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0) | ||
7622 | m_host.Inventory.RemoveInventoryItem(item.ItemID); | ||
7623 | } | ||
7624 | } | ||
7405 | } | 7625 | } |
7406 | 7626 | ||
7407 | public void llOpenRemoteDataChannel() | 7627 | public void llOpenRemoteDataChannel() |
7408 | { | 7628 | { |
7409 | m_host.AddScriptLPS(1); | ||
7410 | IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); | 7629 | IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); |
7411 | if (xmlrpcMod != null && xmlrpcMod.IsEnabled()) | 7630 | if (xmlrpcMod != null && xmlrpcMod.IsEnabled()) |
7412 | { | 7631 | { |
@@ -7436,7 +7655,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7436 | 7655 | ||
7437 | public LSL_String llSendRemoteData(string channel, string dest, int idata, string sdata) | 7656 | public LSL_String llSendRemoteData(string channel, string dest, int idata, string sdata) |
7438 | { | 7657 | { |
7439 | m_host.AddScriptLPS(1); | ||
7440 | IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); | 7658 | IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); |
7441 | if (xmlrpcMod == null) | 7659 | if (xmlrpcMod == null) |
7442 | return ""; | 7660 | return ""; |
@@ -7445,7 +7663,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7445 | 7663 | ||
7446 | public void llRemoteDataReply(string channel, string message_id, string sdata, int idata) | 7664 | public void llRemoteDataReply(string channel, string message_id, string sdata, int idata) |
7447 | { | 7665 | { |
7448 | m_host.AddScriptLPS(1); | ||
7449 | IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); | 7666 | IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); |
7450 | if (xmlrpcMod != null) | 7667 | if (xmlrpcMod != null) |
7451 | xmlrpcMod.RemoteDataReply(channel, message_id, sdata, idata); | 7668 | xmlrpcMod.RemoteDataReply(channel, message_id, sdata, idata); |
@@ -7453,8 +7670,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7453 | 7670 | ||
7454 | public void llCloseRemoteDataChannel(string channel) | 7671 | public void llCloseRemoteDataChannel(string channel) |
7455 | { | 7672 | { |
7456 | m_host.AddScriptLPS(1); | ||
7457 | |||
7458 | IXmlRpcRouter xmlRpcRouter = m_ScriptEngine.World.RequestModuleInterface<IXmlRpcRouter>(); | 7673 | IXmlRpcRouter xmlRpcRouter = m_ScriptEngine.World.RequestModuleInterface<IXmlRpcRouter>(); |
7459 | if (xmlRpcRouter != null) | 7674 | if (xmlRpcRouter != null) |
7460 | { | 7675 | { |
@@ -7468,20 +7683,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7468 | 7683 | ||
7469 | public LSL_String llMD5String(string src, int nonce) | 7684 | public LSL_String llMD5String(string src, int nonce) |
7470 | { | 7685 | { |
7471 | m_host.AddScriptLPS(1); | 7686 | return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8); |
7472 | return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); | ||
7473 | } | 7687 | } |
7474 | 7688 | ||
7475 | public LSL_String llSHA1String(string src) | 7689 | public LSL_String llSHA1String(string src) |
7476 | { | 7690 | { |
7477 | m_host.AddScriptLPS(1); | 7691 | return Util.SHA1Hash(src, Encoding.UTF8).ToLower(); |
7478 | return Util.SHA1Hash(src).ToLower(); | ||
7479 | } | 7692 | } |
7480 | 7693 | ||
7481 | protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) | 7694 | protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) |
7482 | { | 7695 | { |
7483 | float tempFloat; // Use in float expressions below to avoid byte cast precision issues. | 7696 | float tempFloat; // Use in float expressions below to avoid byte cast precision issues. |
7484 | ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); | 7697 | ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); |
7698 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | ||
7699 | return shapeBlock; | ||
7485 | 7700 | ||
7486 | if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && | 7701 | if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && |
7487 | holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && | 7702 | holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && |
@@ -7586,6 +7801,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7586 | // Prim type box, cylinder and prism. | 7801 | // Prim type box, cylinder and prism. |
7587 | protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve) | 7802 | protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve) |
7588 | { | 7803 | { |
7804 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | ||
7805 | return; | ||
7806 | |||
7589 | float tempFloat; // Use in float expressions below to avoid byte cast precision issues. | 7807 | float tempFloat; // Use in float expressions below to avoid byte cast precision issues. |
7590 | ObjectShapePacket.ObjectDataBlock shapeBlock; | 7808 | ObjectShapePacket.ObjectDataBlock shapeBlock; |
7591 | 7809 | ||
@@ -7639,6 +7857,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7639 | // Prim type sphere. | 7857 | // Prim type sphere. |
7640 | protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) | 7858 | protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) |
7641 | { | 7859 | { |
7860 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | ||
7861 | return; | ||
7862 | |||
7642 | ObjectShapePacket.ObjectDataBlock shapeBlock; | 7863 | ObjectShapePacket.ObjectDataBlock shapeBlock; |
7643 | 7864 | ||
7644 | shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); | 7865 | shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); |
@@ -7685,6 +7906,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7685 | // Prim type torus, tube and ring. | 7906 | // Prim type torus, tube and ring. |
7686 | protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve) | 7907 | protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve) |
7687 | { | 7908 | { |
7909 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | ||
7910 | return; | ||
7911 | |||
7688 | float tempFloat; // Use in float expressions below to avoid byte cast precision issues. | 7912 | float tempFloat; // Use in float expressions below to avoid byte cast precision issues. |
7689 | ObjectShapePacket.ObjectDataBlock shapeBlock; | 7913 | ObjectShapePacket.ObjectDataBlock shapeBlock; |
7690 | 7914 | ||
@@ -7820,6 +8044,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7820 | // Prim type sculpt. | 8044 | // Prim type sculpt. |
7821 | protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) | 8045 | protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) |
7822 | { | 8046 | { |
8047 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | ||
8048 | return; | ||
8049 | |||
7823 | ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); | 8050 | ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); |
7824 | UUID sculptId; | 8051 | UUID sculptId; |
7825 | 8052 | ||
@@ -7842,7 +8069,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7842 | type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) | 8069 | type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) |
7843 | { | 8070 | { |
7844 | // default | 8071 | // default |
7845 | type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; | 8072 | type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; |
7846 | } | 8073 | } |
7847 | 8074 | ||
7848 | part.Shape.SetSculptProperties((byte)type, sculptId); | 8075 | part.Shape.SetSculptProperties((byte)type, sculptId); |
@@ -7852,28 +8079,64 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7852 | 8079 | ||
7853 | public void llSetPrimitiveParams(LSL_List rules) | 8080 | public void llSetPrimitiveParams(LSL_List rules) |
7854 | { | 8081 | { |
7855 | m_host.AddScriptLPS(1); | ||
7856 | |||
7857 | SetLinkPrimParams(ScriptBaseClass.LINK_THIS, rules, "llSetPrimitiveParams"); | 8082 | SetLinkPrimParams(ScriptBaseClass.LINK_THIS, rules, "llSetPrimitiveParams"); |
7858 | } | 8083 | } |
7859 | 8084 | ||
7860 | public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) | 8085 | public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) |
7861 | { | 8086 | { |
7862 | m_host.AddScriptLPS(1); | ||
7863 | |||
7864 | SetLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); | 8087 | SetLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); |
7865 | } | 8088 | } |
7866 | 8089 | ||
7867 | public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) | 8090 | public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) |
7868 | { | 8091 | { |
7869 | m_host.AddScriptLPS(1); | ||
7870 | |||
7871 | SetLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); | 8092 | SetLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); |
7872 | } | 8093 | } |
7873 | 8094 | ||
7874 | protected void SetLinkPrimParams(int linknumber, LSL_List rules, string originFunc) | 8095 | private void SetLinkPrimParams(int linknumber, LSL_List rules, string originFunc) |
7875 | { | 8096 | { |
7876 | SetEntityParams(GetLinkEntities(linknumber), rules, originFunc); | 8097 | List<object> parts = new List<object>(); |
8098 | List<SceneObjectPart> prims = GetLinkParts(linknumber); | ||
8099 | List<ScenePresence> avatars = GetLinkAvatars(linknumber); | ||
8100 | foreach (SceneObjectPart p in prims) | ||
8101 | parts.Add(p); | ||
8102 | foreach (ScenePresence p in avatars) | ||
8103 | parts.Add(p); | ||
8104 | |||
8105 | LSL_List remaining = new LSL_List(); | ||
8106 | uint rulesParsed = 0; | ||
8107 | |||
8108 | if (parts.Count > 0) | ||
8109 | { | ||
8110 | foreach (object part in parts) | ||
8111 | { | ||
8112 | if (part is SceneObjectPart) | ||
8113 | remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed); | ||
8114 | else | ||
8115 | remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed); | ||
8116 | } | ||
8117 | |||
8118 | while (remaining.Length > 2) | ||
8119 | { | ||
8120 | linknumber = remaining.GetLSLIntegerItem(0); | ||
8121 | rules = remaining.GetSublist(1, -1); | ||
8122 | parts.Clear(); | ||
8123 | prims = GetLinkParts(linknumber); | ||
8124 | avatars = GetLinkAvatars(linknumber); | ||
8125 | foreach (SceneObjectPart p in prims) | ||
8126 | parts.Add(p); | ||
8127 | foreach (ScenePresence p in avatars) | ||
8128 | parts.Add(p); | ||
8129 | |||
8130 | remaining = new LSL_List(); | ||
8131 | foreach (object part in parts) | ||
8132 | { | ||
8133 | if (part is SceneObjectPart) | ||
8134 | remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed); | ||
8135 | else | ||
8136 | remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed); | ||
8137 | } | ||
8138 | } | ||
8139 | } | ||
7877 | } | 8140 | } |
7878 | 8141 | ||
7879 | protected void SetEntityParams(List<ISceneEntity> entities, LSL_List rules, string originFunc) | 8142 | protected void SetEntityParams(List<ISceneEntity> entities, LSL_List rules, string originFunc) |
@@ -8052,11 +8315,81 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8052 | } | 8315 | } |
8053 | } | 8316 | } |
8054 | 8317 | ||
8318 | public LSL_List llGetPhysicsMaterial() | ||
8319 | { | ||
8320 | LSL_List result = new LSL_List(); | ||
8321 | |||
8322 | result.Add(new LSL_Float(m_host.GravityModifier)); | ||
8323 | result.Add(new LSL_Float(m_host.Restitution)); | ||
8324 | result.Add(new LSL_Float(m_host.Friction)); | ||
8325 | result.Add(new LSL_Float(m_host.Density)); | ||
8326 | |||
8327 | return result; | ||
8328 | } | ||
8329 | |||
8330 | private void SetPhysicsMaterial(SceneObjectPart part, int material_bits, | ||
8331 | float material_density, float material_friction, | ||
8332 | float material_restitution, float material_gravity_modifier) | ||
8333 | { | ||
8334 | ExtraPhysicsData physdata = new ExtraPhysicsData(); | ||
8335 | physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType; | ||
8336 | physdata.Density = part.Density; | ||
8337 | physdata.Friction = part.Friction; | ||
8338 | physdata.Bounce = part.Restitution; | ||
8339 | physdata.GravitationModifier = part.GravityModifier; | ||
8340 | |||
8341 | if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0) | ||
8342 | physdata.Density = material_density; | ||
8343 | if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0) | ||
8344 | physdata.Friction = material_friction; | ||
8345 | if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0) | ||
8346 | physdata.Bounce = material_restitution; | ||
8347 | if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0) | ||
8348 | physdata.GravitationModifier = material_gravity_modifier; | ||
8349 | |||
8350 | part.UpdateExtraPhysics(physdata); | ||
8351 | } | ||
8352 | |||
8353 | public void llSetPhysicsMaterial(int material_bits, | ||
8354 | LSL_Float material_gravity_modifier, LSL_Float material_restitution, | ||
8355 | LSL_Float material_friction, LSL_Float material_density) | ||
8356 | { | ||
8357 | SetPhysicsMaterial(m_host, material_bits, (float)material_density, (float)material_friction, (float)material_restitution, (float)material_gravity_modifier); | ||
8358 | } | ||
8359 | |||
8360 | // vector up using libomv (c&p from sop ) | ||
8361 | // vector up rotated by r | ||
8362 | private Vector3 Zrot(Quaternion r) | ||
8363 | { | ||
8364 | double x, y, z, m; | ||
8365 | |||
8366 | m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W; | ||
8367 | if (Math.Abs(1.0 - m) > 0.000001) | ||
8368 | { | ||
8369 | m = 1.0 / Math.Sqrt(m); | ||
8370 | r.X *= (float)m; | ||
8371 | r.Y *= (float)m; | ||
8372 | r.Z *= (float)m; | ||
8373 | r.W *= (float)m; | ||
8374 | } | ||
8375 | |||
8376 | x = 2 * (r.X * r.Z + r.Y * r.W); | ||
8377 | y = 2 * (-r.X * r.W + r.Y * r.Z); | ||
8378 | z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W; | ||
8379 | |||
8380 | return new Vector3((float)x, (float)y, (float)z); | ||
8381 | } | ||
8382 | |||
8055 | protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) | 8383 | protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) |
8056 | { | 8384 | { |
8385 | if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) | ||
8386 | return new LSL_List(); | ||
8387 | |||
8057 | int idx = 0; | 8388 | int idx = 0; |
8058 | int idxStart = 0; | 8389 | int idxStart = 0; |
8059 | 8390 | ||
8391 | SceneObjectGroup parentgrp = part.ParentGroup; | ||
8392 | |||
8060 | bool positionChanged = false; | 8393 | bool positionChanged = false; |
8061 | LSL_Vector currentPosition = GetPartLocalPos(part); | 8394 | LSL_Vector currentPosition = GetPartLocalPos(part); |
8062 | 8395 | ||
@@ -8092,8 +8425,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8092 | Error(originFunc, string.Format("Error running rule #{0} -> PRIM_POS_LOCAL: arg #{1} - parameter 1 must be vector", rulesParsed, idx - idxStart - 1)); | 8425 | Error(originFunc, string.Format("Error running rule #{0} -> PRIM_POS_LOCAL: arg #{1} - parameter 1 must be vector", rulesParsed, idx - idxStart - 1)); |
8093 | return new LSL_List(); | 8426 | return new LSL_List(); |
8094 | } | 8427 | } |
8428 | if (part.IsRoot && !part.ParentGroup.IsAttachment) | ||
8429 | currentPosition = GetSetPosTarget(part, v, currentPosition, true); | ||
8430 | else | ||
8431 | currentPosition = GetSetPosTarget(part, v, currentPosition, false); | ||
8095 | positionChanged = true; | 8432 | positionChanged = true; |
8096 | currentPosition = GetSetPosTarget(part, v, currentPosition); | ||
8097 | 8433 | ||
8098 | break; | 8434 | break; |
8099 | case ScriptBaseClass.PRIM_SIZE: | 8435 | case ScriptBaseClass.PRIM_SIZE: |
@@ -8118,7 +8454,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8118 | return new LSL_List(); | 8454 | return new LSL_List(); |
8119 | } | 8455 | } |
8120 | // try to let this work as in SL... | 8456 | // try to let this work as in SL... |
8121 | if (part.ParentID == 0) | 8457 | if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart)) |
8122 | { | 8458 | { |
8123 | // special case: If we are root, rotate complete SOG to new rotation | 8459 | // special case: If we are root, rotate complete SOG to new rotation |
8124 | SetRot(part, q); | 8460 | SetRot(part, q); |
@@ -9119,7 +9455,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9119 | 9455 | ||
9120 | break; | 9456 | break; |
9121 | 9457 | ||
9122 | case ScriptBaseClass.PRIM_TEMP_ON_REZ: | 9458 | case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL: |
9459 | if (remain < 5) | ||
9460 | return new LSL_List(); | ||
9461 | |||
9462 | int material_bits = rules.GetLSLIntegerItem(idx++); | ||
9463 | float material_density = (float)rules.GetLSLFloatItem(idx++); | ||
9464 | float material_friction = (float)rules.GetLSLFloatItem(idx++); | ||
9465 | float material_restitution = (float)rules.GetLSLFloatItem(idx++); | ||
9466 | float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++); | ||
9467 | |||
9468 | SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier); | ||
9469 | |||
9470 | break; | ||
9471 | |||
9472 | case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: | ||
9123 | if (remain < 1) | 9473 | if (remain < 1) |
9124 | return new LSL_List(); | 9474 | return new LSL_List(); |
9125 | string temp = rules.Data[idx++].ToString(); | 9475 | string temp = rules.Data[idx++].ToString(); |
@@ -9290,6 +9640,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9290 | part.UpdateSlice((float)slice.x, (float)slice.y); | 9640 | part.UpdateSlice((float)slice.x, (float)slice.y); |
9291 | break; | 9641 | break; |
9292 | 9642 | ||
9643 | case ScriptBaseClass.PRIM_SIT_TARGET: | ||
9644 | if (remain < 3) | ||
9645 | return new LSL_List(); | ||
9646 | |||
9647 | int active; | ||
9648 | try | ||
9649 | { | ||
9650 | active = rules.GetLSLIntegerItem(idx++); | ||
9651 | } | ||
9652 | catch(InvalidCastException) | ||
9653 | { | ||
9654 | Error(originFunc, string.Format("Error running rule #{0} -> PRIM_SIT_TARGET: arg #{1} - parameter 1 must be integer", rulesParsed, idx - idxStart - 1)); | ||
9655 | return new LSL_List(); | ||
9656 | } | ||
9657 | LSL_Vector offset; | ||
9658 | try | ||
9659 | { | ||
9660 | offset = rules.GetVector3Item(idx++); | ||
9661 | } | ||
9662 | catch(InvalidCastException) | ||
9663 | { | ||
9664 | Error(originFunc, string.Format("Error running rule #{0} -> PRIM_SIT_TARGET: arg #{1} - parameter 2 must be vector", rulesParsed, idx - idxStart - 1)); | ||
9665 | return new LSL_List(); | ||
9666 | } | ||
9667 | LSL_Rotation sitrot; | ||
9668 | try | ||
9669 | { | ||
9670 | sitrot = rules.GetQuaternionItem(idx++); | ||
9671 | } | ||
9672 | catch(InvalidCastException) | ||
9673 | { | ||
9674 | Error(originFunc, string.Format("Error running rule #{0} -> PRIM_SIT_TARGET: arg #{1} - parameter 3 must be rotation", rulesParsed, idx - idxStart - 1)); | ||
9675 | return new LSL_List(); | ||
9676 | } | ||
9677 | |||
9678 | // not SL compatible since we don't have a independent flag to control active target but use the values of offset and rotation | ||
9679 | if(active == 1) | ||
9680 | { | ||
9681 | if(offset.x == 0 && offset.y == 0 && offset.z == 0 && sitrot.s == 1.0) | ||
9682 | offset.z = 1e-5f; // hack | ||
9683 | SitTarget(part,offset,sitrot); | ||
9684 | } | ||
9685 | else if(active == 0) | ||
9686 | SitTarget(part, Vector3.Zero , Quaternion.Identity); | ||
9687 | |||
9688 | break; | ||
9689 | |||
9293 | case ScriptBaseClass.PRIM_LINK_TARGET: | 9690 | case ScriptBaseClass.PRIM_LINK_TARGET: |
9294 | if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. | 9691 | if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. |
9295 | return new LSL_List(); | 9692 | return new LSL_List(); |
@@ -9313,14 +9710,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9313 | if (part.ParentGroup.RootPart == part) | 9710 | if (part.ParentGroup.RootPart == part) |
9314 | { | 9711 | { |
9315 | SceneObjectGroup parent = part.ParentGroup; | 9712 | SceneObjectGroup parent = part.ParentGroup; |
9316 | parent.UpdateGroupPosition(currentPosition); | 9713 | // Util.FireAndForget(delegate(object x) { |
9714 | parent.UpdateGroupPosition(currentPosition); | ||
9715 | // }); | ||
9317 | } | 9716 | } |
9318 | else | 9717 | else |
9319 | { | 9718 | { |
9320 | part.OffsetPosition = currentPosition; | 9719 | part.OffsetPosition = currentPosition; |
9321 | SceneObjectGroup parent = part.ParentGroup; | 9720 | // SceneObjectGroup parent = part.ParentGroup; |
9322 | parent.HasGroupChanged = true; | 9721 | // parent.HasGroupChanged = true; |
9323 | parent.ScheduleGroupForTerseUpdate(); | 9722 | // parent.ScheduleGroupForTerseUpdate(); |
9723 | part.ScheduleTerseUpdate(); | ||
9324 | } | 9724 | } |
9325 | } | 9725 | } |
9326 | } | 9726 | } |
@@ -9368,7 +9768,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9368 | } | 9768 | } |
9369 | break; | 9769 | break; |
9370 | 9770 | ||
9371 | case ScriptBaseClass.PRIM_ROTATION: | 9771 | case ScriptBaseClass.PRIM_ROTATION: |
9372 | if (remain < 1) | 9772 | if (remain < 1) |
9373 | return new LSL_List(); | 9773 | return new LSL_List(); |
9374 | 9774 | ||
@@ -9387,7 +9787,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9387 | SceneObjectPart parentPart = sp.ParentPart; | 9787 | SceneObjectPart parentPart = sp.ParentPart; |
9388 | 9788 | ||
9389 | if (parentPart != null) | 9789 | if (parentPart != null) |
9390 | sp.Rotation = m_host.GetWorldRotation() * inRot; | 9790 | sp.Rotation = m_host.GetWorldRotation() * inRot; |
9391 | 9791 | ||
9392 | break; | 9792 | break; |
9393 | 9793 | ||
@@ -9431,7 +9831,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9431 | catch (InvalidCastException e) | 9831 | catch (InvalidCastException e) |
9432 | { | 9832 | { |
9433 | Error( | 9833 | Error( |
9434 | originFunc, | 9834 | originFunc, |
9435 | string.Format("Error running rule #{0}: arg #{1} - ", rulesParsed, idx - idxStart) + e.Message); | 9835 | string.Format("Error running rule #{0}: arg #{1} - ", rulesParsed, idx - idxStart) + e.Message); |
9436 | } | 9836 | } |
9437 | 9837 | ||
@@ -9440,7 +9840,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9440 | 9840 | ||
9441 | public LSL_String llStringToBase64(string str) | 9841 | public LSL_String llStringToBase64(string str) |
9442 | { | 9842 | { |
9443 | m_host.AddScriptLPS(1); | ||
9444 | try | 9843 | try |
9445 | { | 9844 | { |
9446 | byte[] encData_byte; | 9845 | byte[] encData_byte; |
@@ -9457,7 +9856,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9457 | 9856 | ||
9458 | public LSL_String llBase64ToString(string str) | 9857 | public LSL_String llBase64ToString(string str) |
9459 | { | 9858 | { |
9460 | m_host.AddScriptLPS(1); | ||
9461 | try | 9859 | try |
9462 | { | 9860 | { |
9463 | byte[] b = Convert.FromBase64String(str); | 9861 | byte[] b = Convert.FromBase64String(str); |
@@ -9472,33 +9870,120 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9472 | 9870 | ||
9473 | public LSL_String llXorBase64Strings(string str1, string str2) | 9871 | public LSL_String llXorBase64Strings(string str1, string str2) |
9474 | { | 9872 | { |
9475 | m_host.AddScriptLPS(1); | 9873 | int padding = 0; |
9476 | Deprecated("llXorBase64Strings", "Use llXorBase64 instead"); | 9874 | |
9477 | return String.Empty; | 9875 | string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
9876 | |||
9877 | if (str1 == String.Empty) | ||
9878 | return String.Empty; | ||
9879 | if (str2 == String.Empty) | ||
9880 | return str1; | ||
9881 | |||
9882 | int len = str2.Length; | ||
9883 | if ((len % 4) != 0) // LL is EVIL!!!! | ||
9884 | { | ||
9885 | while (str2.EndsWith("=")) | ||
9886 | str2 = str2.Substring(0, str2.Length - 1); | ||
9887 | |||
9888 | len = str2.Length; | ||
9889 | int mod = len % 4; | ||
9890 | |||
9891 | if (mod == 1) | ||
9892 | str2 = str2.Substring(0, str2.Length - 1); | ||
9893 | else if (mod == 2) | ||
9894 | str2 += "=="; | ||
9895 | else if (mod == 3) | ||
9896 | str2 += "="; | ||
9897 | } | ||
9898 | |||
9899 | byte[] data1; | ||
9900 | byte[] data2; | ||
9901 | try | ||
9902 | { | ||
9903 | data1 = Convert.FromBase64String(str1); | ||
9904 | data2 = Convert.FromBase64String(str2); | ||
9905 | } | ||
9906 | catch (Exception) | ||
9907 | { | ||
9908 | return new LSL_String(String.Empty); | ||
9909 | } | ||
9910 | |||
9911 | // For cases where the decoded length of s2 is greater | ||
9912 | // than the decoded length of s1, simply perform a normal | ||
9913 | // decode and XOR | ||
9914 | // | ||
9915 | /* | ||
9916 | if (data2.Length >= data1.Length) | ||
9917 | { | ||
9918 | for (int pos = 0 ; pos < data1.Length ; pos++ ) | ||
9919 | data1[pos] ^= data2[pos]; | ||
9920 | |||
9921 | return Convert.ToBase64String(data1); | ||
9922 | } | ||
9923 | */ | ||
9924 | |||
9925 | // Remove padding | ||
9926 | while (str1.EndsWith("=")) | ||
9927 | { | ||
9928 | str1 = str1.Substring(0, str1.Length - 1); | ||
9929 | padding++; | ||
9930 | } | ||
9931 | while (str2.EndsWith("=")) | ||
9932 | str2 = str2.Substring(0, str2.Length - 1); | ||
9933 | |||
9934 | byte[] d1 = new byte[str1.Length]; | ||
9935 | byte[] d2 = new byte[str2.Length]; | ||
9936 | |||
9937 | for (int i = 0 ; i < str1.Length ; i++) | ||
9938 | { | ||
9939 | int idx = b64.IndexOf(str1.Substring(i, 1)); | ||
9940 | if (idx == -1) | ||
9941 | idx = 0; | ||
9942 | d1[i] = (byte)idx; | ||
9943 | } | ||
9944 | |||
9945 | for (int i = 0 ; i < str2.Length ; i++) | ||
9946 | { | ||
9947 | int idx = b64.IndexOf(str2.Substring(i, 1)); | ||
9948 | if (idx == -1) | ||
9949 | idx = 0; | ||
9950 | d2[i] = (byte)idx; | ||
9951 | } | ||
9952 | |||
9953 | string output = String.Empty; | ||
9954 | |||
9955 | for (int pos = 0 ; pos < d1.Length ; pos++) | ||
9956 | output += b64[d1[pos] ^ d2[pos % d2.Length]]; | ||
9957 | |||
9958 | // Here's a funny thing: LL blithely violate the base64 | ||
9959 | // standard pretty much everywhere. Here, padding is | ||
9960 | // added only if the first input string had it, rather | ||
9961 | // than when the data actually needs it. This can result | ||
9962 | // in invalid base64 being returned. Go figure. | ||
9963 | |||
9964 | while (padding-- > 0) | ||
9965 | output += "="; | ||
9966 | |||
9967 | return output; | ||
9478 | } | 9968 | } |
9479 | 9969 | ||
9480 | public void llRemoteDataSetRegion() | 9970 | public void llRemoteDataSetRegion() |
9481 | { | 9971 | { |
9482 | m_host.AddScriptLPS(1); | ||
9483 | Deprecated("llRemoteDataSetRegion", "Use llOpenRemoteDataChannel instead"); | 9972 | Deprecated("llRemoteDataSetRegion", "Use llOpenRemoteDataChannel instead"); |
9484 | } | 9973 | } |
9485 | 9974 | ||
9486 | public LSL_Float llLog10(double val) | 9975 | public LSL_Float llLog10(double val) |
9487 | { | 9976 | { |
9488 | m_host.AddScriptLPS(1); | ||
9489 | return (double)Math.Log10(val); | 9977 | return (double)Math.Log10(val); |
9490 | } | 9978 | } |
9491 | 9979 | ||
9492 | public LSL_Float llLog(double val) | 9980 | public LSL_Float llLog(double val) |
9493 | { | 9981 | { |
9494 | m_host.AddScriptLPS(1); | ||
9495 | return (double)Math.Log(val); | 9982 | return (double)Math.Log(val); |
9496 | } | 9983 | } |
9497 | 9984 | ||
9498 | public LSL_List llGetAnimationList(string id) | 9985 | public LSL_List llGetAnimationList(string id) |
9499 | { | 9986 | { |
9500 | m_host.AddScriptLPS(1); | ||
9501 | |||
9502 | LSL_List l = new LSL_List(); | 9987 | LSL_List l = new LSL_List(); |
9503 | ScenePresence av = World.GetScenePresence((UUID)id); | 9988 | ScenePresence av = World.GetScenePresence((UUID)id); |
9504 | if (av == null || av.IsChildAgent) // only if in the region | 9989 | if (av == null || av.IsChildAgent) // only if in the region |
@@ -9512,8 +9997,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9512 | 9997 | ||
9513 | public void llSetParcelMusicURL(string url) | 9998 | public void llSetParcelMusicURL(string url) |
9514 | { | 9999 | { |
9515 | m_host.AddScriptLPS(1); | ||
9516 | |||
9517 | ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); | 10000 | ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); |
9518 | 10001 | ||
9519 | if (land.LandData.OwnerID != m_host.OwnerID) | 10002 | if (land.LandData.OwnerID != m_host.OwnerID) |
@@ -9524,8 +10007,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9524 | 10007 | ||
9525 | public LSL_String llGetParcelMusicURL() | 10008 | public LSL_String llGetParcelMusicURL() |
9526 | { | 10009 | { |
9527 | m_host.AddScriptLPS(1); | ||
9528 | |||
9529 | ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); | 10010 | ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); |
9530 | 10011 | ||
9531 | if (land.LandData.OwnerID != m_host.OwnerID) | 10012 | if (land.LandData.OwnerID != m_host.OwnerID) |
@@ -9536,8 +10017,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9536 | 10017 | ||
9537 | public LSL_Vector llGetRootPosition() | 10018 | public LSL_Vector llGetRootPosition() |
9538 | { | 10019 | { |
9539 | m_host.AddScriptLPS(1); | ||
9540 | |||
9541 | return new LSL_Vector(m_host.ParentGroup.AbsolutePosition); | 10020 | return new LSL_Vector(m_host.ParentGroup.AbsolutePosition); |
9542 | } | 10021 | } |
9543 | 10022 | ||
@@ -9552,7 +10031,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9552 | /// </summary> | 10031 | /// </summary> |
9553 | public LSL_Rotation llGetRootRotation() | 10032 | public LSL_Rotation llGetRootRotation() |
9554 | { | 10033 | { |
9555 | m_host.AddScriptLPS(1); | ||
9556 | Quaternion q; | 10034 | Quaternion q; |
9557 | if (m_host.ParentGroup.AttachmentPoint != 0) | 10035 | if (m_host.ParentGroup.AttachmentPoint != 0) |
9558 | { | 10036 | { |
@@ -9578,26 +10056,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9578 | 10056 | ||
9579 | public void llSetObjectDesc(string desc) | 10057 | public void llSetObjectDesc(string desc) |
9580 | { | 10058 | { |
9581 | m_host.AddScriptLPS(1); | ||
9582 | m_host.Description = desc!=null?desc:String.Empty; | 10059 | m_host.Description = desc!=null?desc:String.Empty; |
9583 | } | 10060 | } |
9584 | 10061 | ||
9585 | public LSL_String llGetCreator() | 10062 | public LSL_String llGetCreator() |
9586 | { | 10063 | { |
9587 | m_host.AddScriptLPS(1); | ||
9588 | return m_host.CreatorID.ToString(); | 10064 | return m_host.CreatorID.ToString(); |
9589 | } | 10065 | } |
9590 | 10066 | ||
9591 | public LSL_String llGetTimestamp() | 10067 | public LSL_String llGetTimestamp() |
9592 | { | 10068 | { |
9593 | m_host.AddScriptLPS(1); | ||
9594 | return DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ"); | 10069 | return DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ"); |
9595 | } | 10070 | } |
9596 | 10071 | ||
9597 | public LSL_Integer llGetNumberOfPrims() | 10072 | public LSL_Integer llGetNumberOfPrims() |
9598 | { | 10073 | { |
9599 | m_host.AddScriptLPS(1); | ||
9600 | |||
9601 | return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); | 10074 | return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); |
9602 | } | 10075 | } |
9603 | 10076 | ||
@@ -9614,189 +10087,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9614 | /// </summary> | 10087 | /// </summary> |
9615 | public LSL_List llGetBoundingBox(string obj) | 10088 | public LSL_List llGetBoundingBox(string obj) |
9616 | { | 10089 | { |
9617 | m_host.AddScriptLPS(1); | ||
9618 | |||
9619 | // Get target avatar if non-seated avatar or attachment, or prim and object | ||
9620 | UUID objID = UUID.Zero; | 10090 | UUID objID = UUID.Zero; |
9621 | UUID.TryParse(obj, out objID); | ||
9622 | ScenePresence agent = World.GetScenePresence(objID); | ||
9623 | if (agent != null) | ||
9624 | { | ||
9625 | if (agent.ParentPart != null) | ||
9626 | { | ||
9627 | objID = agent.ParentPart.UUID; | ||
9628 | agent = null; | ||
9629 | } | ||
9630 | } | ||
9631 | SceneObjectGroup group = null; | ||
9632 | SceneObjectPart target = World.GetSceneObjectPart(objID); | ||
9633 | if (target != null) | ||
9634 | { | ||
9635 | group = target.ParentGroup; | ||
9636 | if (group.IsAttachment) { | ||
9637 | objID = group.AttachedAvatar; | ||
9638 | agent = World.GetScenePresence(objID); | ||
9639 | group = null; | ||
9640 | target = null; | ||
9641 | } | ||
9642 | } | ||
9643 | |||
9644 | // Initialize but break if no target | ||
9645 | LSL_List result = new LSL_List(); | 10091 | LSL_List result = new LSL_List(); |
9646 | int groupCount = 0; | 10092 | |
9647 | int partCount = 0; | 10093 | // If the ID is not valid, return null result |
9648 | int vertexCount = 0; | 10094 | if (!UUID.TryParse(obj, out objID)) |
9649 | if (target == null && agent == null) | ||
9650 | { | 10095 | { |
9651 | result.Add(new LSL_Vector()); | 10096 | result.Add(new LSL_Vector()); |
9652 | result.Add(new LSL_Vector()); | 10097 | result.Add(new LSL_Vector()); |
9653 | if (m_addStatsInGetBoundingBox) | ||
9654 | result.Add(new LSL_Vector((float)groupCount, (float)partCount, (float)vertexCount)); | ||
9655 | return result; | 10098 | return result; |
9656 | } | 10099 | } |
9657 | Vector3 minPosition = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); | ||
9658 | Vector3 maxPosition = new Vector3(float.MinValue, float.MinValue, float.MinValue); | ||
9659 | 10100 | ||
9660 | // Try to get a mesher | 10101 | // Check if this is an attached prim. If so, replace |
9661 | IRendering primMesher = null; | 10102 | // the UUID with the avatar UUID and report it's bounding box |
9662 | List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); | 10103 | SceneObjectPart part = World.GetSceneObjectPart(objID); |
9663 | if (renderers.Count > 0) | 10104 | if (part != null && part.ParentGroup.IsAttachment) |
9664 | primMesher = RenderingLoader.LoadRenderer(renderers[0]); | 10105 | objID = part.ParentGroup.AttachedAvatar; |
9665 | 10106 | ||
9666 | // Get bounding box of just avatar, seated or not | 10107 | // Find out if this is an avatar ID. If so, return it's box |
9667 | if (agent != null) | 10108 | ScenePresence presence = World.GetScenePresence(objID); |
9668 | { | 10109 | if (presence != null) |
9669 | bool hasParent = false; | ||
9670 | Vector3 lower; | ||
9671 | Vector3 upper; | ||
9672 | BoundingBoxOfScenePresence(agent, out lower, out upper); | ||
9673 | Vector3 offset = Vector3.Zero; | ||
9674 | |||
9675 | // Since local bounding box unrotated and untilted, keep it simple | ||
9676 | AddBoundingBoxOfSimpleBox(lower, upper, offset, agent.Rotation, hasParent, ref minPosition, ref maxPosition, ref vertexCount); | ||
9677 | partCount++; | ||
9678 | groupCount++; | ||
9679 | |||
9680 | // Return lower and upper bounding box corners | ||
9681 | result.Add(new LSL_Vector(minPosition)); | ||
9682 | result.Add(new LSL_Vector(maxPosition)); | ||
9683 | if (m_addStatsInGetBoundingBox) | ||
9684 | result.Add(new LSL_Vector((float)groupCount, (float)partCount, (float)vertexCount)); | ||
9685 | return result; | ||
9686 | } | ||
9687 | // Get bounding box of object including seated avatars | ||
9688 | else if (group != null) | ||
9689 | { | 10110 | { |
9690 | // Merge bounding boxes of all parts (prims and mesh) | 10111 | // As per LSL Wiki, there is no difference between sitting |
9691 | foreach (SceneObjectPart part in group.Parts) | 10112 | // and standing avatar since server 1.36 |
9692 | { | 10113 | LSL_Vector lower; |
9693 | bool hasParent = (!part.IsRoot); | 10114 | LSL_Vector upper; |
9694 | // When requested or if no mesher, keep it simple | ||
9695 | if (m_useSimpleBoxesInGetBoundingBox || primMesher == null) | ||
9696 | { | ||
9697 | AddBoundingBoxOfSimpleBox(part.Scale * -0.5f, part.Scale * 0.5f, part.OffsetPosition, part.RotationOffset, hasParent, ref minPosition, ref maxPosition, ref vertexCount); | ||
9698 | } | ||
9699 | // Do the full mounty | ||
9700 | else | ||
9701 | { | ||
9702 | Primitive omvPrim = part.Shape.ToOmvPrimitive(part.OffsetPosition, part.RotationOffset); | ||
9703 | byte[] sculptAsset = null; | ||
9704 | if (omvPrim.Sculpt != null) | ||
9705 | sculptAsset = World.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString()); | ||
9706 | |||
9707 | // When part is mesh | ||
9708 | // Quirk: Only imports as incompletely populated faceted mesh object, so needs an own handler. | ||
9709 | if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type == SculptType.Mesh && sculptAsset != null) | ||
9710 | { | ||
9711 | AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset); | ||
9712 | FacetedMesh mesh = null; | ||
9713 | FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, DetailLevel.Highest, out mesh); | ||
9714 | meshAsset = null; | ||
9715 | if (mesh != null) | ||
9716 | { | ||
9717 | AddBoundingBoxOfFacetedMesh(mesh, omvPrim, hasParent, ref minPosition, ref maxPosition, ref vertexCount); | ||
9718 | mesh = null; | ||
9719 | } | ||
9720 | } | ||
9721 | |||
9722 | // When part is sculpt | ||
9723 | // Quirk: Generated sculpt mesh is about 2.8% smaller in X and Y than visual sculpt. | ||
9724 | else if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type != SculptType.Mesh && sculptAsset != null) | ||
9725 | { | ||
9726 | IJ2KDecoder imgDecoder = World.RequestModuleInterface<IJ2KDecoder>(); | ||
9727 | if (imgDecoder != null) | ||
9728 | { | ||
9729 | Image sculpt = imgDecoder.DecodeToImage(sculptAsset); | ||
9730 | if (sculpt != null) | ||
9731 | { | ||
9732 | SimpleMesh mesh = primMesher.GenerateSimpleSculptMesh(omvPrim, (Bitmap)sculpt, DetailLevel.Medium); | ||
9733 | sculpt.Dispose(); | ||
9734 | if (mesh != null) | ||
9735 | { | ||
9736 | AddBoundingBoxOfSimpleMesh(mesh, omvPrim, hasParent, ref minPosition, ref maxPosition, ref vertexCount); | ||
9737 | mesh = null; | ||
9738 | } | ||
9739 | } | ||
9740 | } | ||
9741 | } | ||
9742 | 10115 | ||
9743 | // When part is prim | 10116 | Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f; |
9744 | else if (omvPrim.Sculpt == null) | ||
9745 | { | ||
9746 | SimpleMesh mesh = primMesher.GenerateSimpleMesh(omvPrim, DetailLevel.Medium); | ||
9747 | if (mesh != null) | ||
9748 | { | ||
9749 | AddBoundingBoxOfSimpleMesh(mesh, omvPrim, hasParent, ref minPosition, ref maxPosition, ref vertexCount); | ||
9750 | mesh = null; | ||
9751 | } | ||
9752 | } | ||
9753 | 10117 | ||
9754 | // When all else fails, try fallback to simple box | 10118 | if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID |
9755 | else | 10119 | == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) |
9756 | { | 10120 | /* |
9757 | AddBoundingBoxOfSimpleBox(part.Scale * -0.5f, part.Scale * 0.5f, part.OffsetPosition, part.RotationOffset, hasParent, ref minPosition, ref maxPosition, ref vertexCount); | 10121 | { |
9758 | } | 10122 | // This is for ground sitting avatars |
9759 | } | 10123 | float height = presence.Appearance.AvatarHeight / 2.66666667f; |
9760 | partCount++; | 10124 | lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f); |
10125 | upper = new LSL_Vector(0.3375f, 0.45f, 0.0f); | ||
10126 | } | ||
10127 | else | ||
10128 | { | ||
10129 | // This is for standing/flying avatars | ||
10130 | float height = presence.Appearance.AvatarHeight / 2.0f; | ||
10131 | lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f); | ||
10132 | upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f); | ||
9761 | } | 10133 | } |
9762 | } | ||
9763 | |||
9764 | // Merge bounding boxes of seated avatars | ||
9765 | foreach (ScenePresence sp in group.GetSittingAvatars()) | ||
9766 | { | ||
9767 | Vector3 lower; | ||
9768 | Vector3 upper; | ||
9769 | BoundingBoxOfScenePresence(sp, out lower, out upper); | ||
9770 | Vector3 offset = sp.OffsetPosition; | ||
9771 | 10134 | ||
9772 | bool hasParent = true; | 10135 | // Adjust to the documented error offsets (see LSL Wiki) |
9773 | // When requested or if no mesher, keep it simple | 10136 | lower += new LSL_Vector(0.05f, 0.05f, 0.05f); |
9774 | if (m_useSimpleBoxesInGetBoundingBox || primMesher == null) | 10137 | upper -= new LSL_Vector(0.05f, 0.05f, 0.05f); |
10138 | */ | ||
9775 | { | 10139 | { |
9776 | AddBoundingBoxOfSimpleBox(lower, upper, offset, sp.Rotation, hasParent, ref minPosition, ref maxPosition, ref vertexCount); | 10140 | // This is for ground sitting avatars TODO! |
10141 | lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f); | ||
10142 | upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f); | ||
9777 | } | 10143 | } |
9778 | // Do the full mounty | ||
9779 | else | 10144 | else |
9780 | { | 10145 | { |
9781 | // Prim shapes don't do center offsets, so add it here. | 10146 | // This is for standing/flying avatars |
9782 | offset = offset + (lower + upper) * 0.5f * sp.Rotation; | 10147 | lower = new LSL_Vector(-box.X, -box.Y, -box.Z); |
9783 | Primitive omvPrim = MakeOpenMetaversePrim(upper - lower, offset, sp.Rotation, ScriptBaseClass.PRIM_TYPE_SPHERE); | 10148 | upper = new LSL_Vector(box.X, box.Y, box.Z); |
9784 | SimpleMesh mesh = primMesher.GenerateSimpleMesh(omvPrim, DetailLevel.Medium); | ||
9785 | AddBoundingBoxOfSimpleMesh(mesh, omvPrim, hasParent, ref minPosition, ref maxPosition, ref vertexCount); | ||
9786 | mesh = null; | ||
9787 | } | 10149 | } |
9788 | partCount++; | 10150 | |
10151 | if (lower.x > upper.x) | ||
10152 | lower.x = upper.x; | ||
10153 | if (lower.y > upper.y) | ||
10154 | lower.y = upper.y; | ||
10155 | if (lower.z > upper.z) | ||
10156 | lower.z = upper.z; | ||
10157 | |||
10158 | result.Add(lower); | ||
10159 | result.Add(upper); | ||
10160 | return result; | ||
9789 | } | 10161 | } |
9790 | 10162 | ||
9791 | groupCount++; | 10163 | part = World.GetSceneObjectPart(objID); |
10164 | // Currently only works for single prims without a sitting avatar | ||
10165 | if (part != null) | ||
10166 | { | ||
10167 | float minX; | ||
10168 | float maxX; | ||
10169 | float minY; | ||
10170 | float maxY; | ||
10171 | float minZ; | ||
10172 | float maxZ; | ||
9792 | 10173 | ||
9793 | // Return lower and upper bounding box corners | 10174 | // This BBox is in sim coordinates, with the offset being |
9794 | result.Add(new LSL_Vector(minPosition)); | 10175 | // a contained point. |
9795 | result.Add(new LSL_Vector(maxPosition)); | 10176 | Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup }, |
9796 | if (m_addStatsInGetBoundingBox) | 10177 | out minX, out maxX, out minY, out maxY, out minZ, out maxZ); |
9797 | result.Add(new LSL_Vector((float)groupCount, (float)partCount, (float)vertexCount)); | 10178 | |
10179 | minX -= offsets[0].X; | ||
10180 | maxX -= offsets[0].X; | ||
10181 | minY -= offsets[0].Y; | ||
10182 | maxY -= offsets[0].Y; | ||
10183 | minZ -= offsets[0].Z; | ||
10184 | maxZ -= offsets[0].Z; | ||
10185 | |||
10186 | LSL_Vector lower; | ||
10187 | LSL_Vector upper; | ||
10188 | |||
10189 | // Adjust to the documented error offsets (see LSL Wiki) | ||
10190 | lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f); | ||
10191 | upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f); | ||
10192 | |||
10193 | if (lower.x > upper.x) | ||
10194 | lower.x = upper.x; | ||
10195 | if (lower.y > upper.y) | ||
10196 | lower.y = upper.y; | ||
10197 | if (lower.z > upper.z) | ||
10198 | lower.z = upper.z; | ||
10199 | |||
10200 | result.Add(lower); | ||
10201 | result.Add(upper); | ||
10202 | return result; | ||
10203 | } | ||
9798 | 10204 | ||
9799 | primMesher = null; | 10205 | // Not found so return empty values |
10206 | result.Add(new LSL_Vector()); | ||
10207 | result.Add(new LSL_Vector()); | ||
9800 | return result; | 10208 | return result; |
9801 | } | 10209 | } |
9802 | 10210 | ||
@@ -9836,430 +10244,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9836 | } | 10244 | } |
9837 | } | 10245 | } |
9838 | 10246 | ||
9839 | /// <summary> | ||
9840 | /// Helper to approximate a part with a simple box. | ||
9841 | /// </summary> | ||
9842 | private void AddBoundingBoxOfSimpleBox(Vector3 corner1, Vector3 corner2, Vector3 offset, Quaternion rotation, bool hasParent, ref Vector3 lower, ref Vector3 upper, ref int count) | ||
9843 | { | ||
9844 | // Parse the 8 box corners | ||
9845 | for (int i = 0; i < 8; i++) | ||
9846 | { | ||
9847 | // Calculate each box corner | ||
9848 | Vector3 position = corner1; | ||
9849 | if ((i & 1) != 0) | ||
9850 | position.X = corner2.X; | ||
9851 | if ((i & 2) != 0) | ||
9852 | position.Y = corner2.Y; | ||
9853 | if ((i & 4) != 0) | ||
9854 | position.Z = corner2.Z; | ||
9855 | // Rotate part unless part is root | ||
9856 | if (hasParent) | ||
9857 | position = position * rotation; | ||
9858 | position = position + offset; | ||
9859 | // Adjust lower and upper bounding box corners if needed | ||
9860 | lower = Vector3.Min(lower, position); | ||
9861 | upper = Vector3.Max(upper, position); | ||
9862 | count++; | ||
9863 | } | ||
9864 | } | ||
9865 | 10247 | ||
9866 | /// <summary> | ||
9867 | /// Helper to parse a meshed prim and needed especially | ||
9868 | /// for accuracy with tortured prims and sculpts. | ||
9869 | /// </summary> | ||
9870 | private void AddBoundingBoxOfSimpleMesh(SimpleMesh mesh, Primitive prim, bool hasParent, ref Vector3 lower, ref Vector3 upper, ref int count) | ||
9871 | { | ||
9872 | // Quirk: A meshed box contains 10 instead of the 8 necessary vertices. | ||
9873 | if (mesh != null) | ||
9874 | { | ||
9875 | // Parse each vertex in mesh | ||
9876 | foreach (Vertex vertex in mesh.Vertices) | ||
9877 | { | ||
9878 | Vector3 position = vertex.Position; | ||
9879 | position = position * prim.Scale; | ||
9880 | // Rotate part unless part is root | ||
9881 | if (hasParent) | ||
9882 | position = position * prim.Rotation; | ||
9883 | position = position + prim.Position; | ||
9884 | // Adjust lower and upper bounding box corners if needed | ||
9885 | lower = Vector3.Min(lower, position); | ||
9886 | upper = Vector3.Max(upper, position); | ||
9887 | count++; | ||
9888 | } | ||
9889 | } | ||
9890 | } | ||
9891 | |||
9892 | /// <summary> | ||
9893 | /// Helper to parse mesh because no method exists | ||
9894 | /// to parse mesh assets to SimpleMesh. | ||
9895 | /// </summary> | ||
9896 | private void AddBoundingBoxOfFacetedMesh(FacetedMesh mesh, Primitive prim, bool hasParent, ref Vector3 lower, ref Vector3 upper, ref int count) | ||
9897 | { | ||
9898 | if (mesh != null) | ||
9899 | { | ||
9900 | // Parse each face in mesh | ||
9901 | // since vertex array isn't populated. | ||
9902 | // This parses each unique vertex 3-6 times. | ||
9903 | foreach (Face face in mesh.Faces) | ||
9904 | { | ||
9905 | // Parse each vertex in face | ||
9906 | foreach (Vertex vertex in face.Vertices) | ||
9907 | { | ||
9908 | Vector3 position = vertex.Position; | ||
9909 | position = position * prim.Scale; | ||
9910 | // Rotate part unless part is root | ||
9911 | if (hasParent) | ||
9912 | position = position * prim.Rotation; | ||
9913 | position = position + prim.Position; | ||
9914 | // Adjust lower and upper bounding box corners if needed | ||
9915 | lower = Vector3.Min(lower, position); | ||
9916 | upper = Vector3.Max(upper, position); | ||
9917 | count++; | ||
9918 | } | ||
9919 | } | ||
9920 | } | ||
9921 | } | ||
9922 | |||
9923 | /// <summary> | ||
9924 | /// Helper to make up an OpenMetaverse prim | ||
9925 | /// needed to create mesh from parts. | ||
9926 | /// </summary> | ||
9927 | private Primitive MakeOpenMetaversePrim(Vector3 scale, Vector3 position, Quaternion rotation, int primType) | ||
9928 | { | ||
9929 | // Initialize and set common parameters | ||
9930 | Primitive prim = new OpenMetaverse.Primitive(); | ||
9931 | prim.Scale = scale; | ||
9932 | prim.Position = position; | ||
9933 | prim.Rotation = rotation; | ||
9934 | prim.PrimData.PathShearX = 0.0f; | ||
9935 | prim.PrimData.PathShearY = 0.0f; | ||
9936 | prim.PrimData.PathBegin = 0.0f; | ||
9937 | prim.PrimData.PathEnd = 1.0f; | ||
9938 | prim.PrimData.PathScaleX = 1.0f; | ||
9939 | prim.PrimData.PathScaleY = 1.0f; | ||
9940 | prim.PrimData.PathTaperX = 0.0f; | ||
9941 | prim.PrimData.PathTaperY = 0.0f; | ||
9942 | prim.PrimData.PathTwistBegin = 0.0f; | ||
9943 | prim.PrimData.PathTwist = 0.0f; | ||
9944 | prim.PrimData.ProfileBegin = 0.0f; | ||
9945 | prim.PrimData.ProfileEnd = 1.0f; | ||
9946 | prim.PrimData.ProfileHollow = 0.0f; | ||
9947 | prim.PrimData.ProfileCurve = (ProfileCurve)1; | ||
9948 | prim.PrimData.ProfileHole = (HoleType)0; | ||
9949 | prim.PrimData.PathCurve = (PathCurve)16; | ||
9950 | prim.PrimData.PathRadiusOffset = 0.0f; | ||
9951 | prim.PrimData.PathRevolutions = 1.0f; | ||
9952 | prim.PrimData.PathSkew = 0.0f; | ||
9953 | prim.PrimData.PCode = OpenMetaverse.PCode.Prim; | ||
9954 | prim.PrimData.State = (byte)0; | ||
9955 | |||
9956 | // Set type specific parameters | ||
9957 | switch (primType) | ||
9958 | { | ||
9959 | // Set specific parameters for box | ||
9960 | case ScriptBaseClass.PRIM_TYPE_BOX: | ||
9961 | prim.PrimData.PathScaleY = 1.0f; | ||
9962 | prim.PrimData.ProfileCurve = (ProfileCurve)1; | ||
9963 | prim.PrimData.PathCurve = (PathCurve)16; | ||
9964 | break; | ||
9965 | // Set specific parameters for cylinder | ||
9966 | case ScriptBaseClass.PRIM_TYPE_CYLINDER: | ||
9967 | prim.PrimData.PathScaleY = 1.0f; | ||
9968 | prim.PrimData.ProfileCurve = (ProfileCurve)0; | ||
9969 | prim.PrimData.PathCurve = (PathCurve)16; | ||
9970 | break; | ||
9971 | // Set specific parameters for prism | ||
9972 | case ScriptBaseClass.PRIM_TYPE_PRISM: | ||
9973 | prim.PrimData.PathScaleY = 1.0f; | ||
9974 | prim.PrimData.ProfileCurve = (ProfileCurve)3; | ||
9975 | prim.PrimData.PathCurve = (PathCurve)16; | ||
9976 | break; | ||
9977 | // Set specific parameters for sphere | ||
9978 | case ScriptBaseClass.PRIM_TYPE_SPHERE: | ||
9979 | prim.PrimData.PathScaleY = 1.0f; | ||
9980 | prim.PrimData.ProfileCurve = (ProfileCurve)5; | ||
9981 | prim.PrimData.PathCurve = (PathCurve)32; | ||
9982 | break; | ||
9983 | // Set specific parameters for torus | ||
9984 | case ScriptBaseClass.PRIM_TYPE_TORUS: | ||
9985 | prim.PrimData.PathScaleY = 0.5f; | ||
9986 | prim.PrimData.ProfileCurve = (ProfileCurve)0; | ||
9987 | prim.PrimData.PathCurve = (PathCurve)32; | ||
9988 | break; | ||
9989 | // Set specific parameters for tube | ||
9990 | case ScriptBaseClass.PRIM_TYPE_TUBE: | ||
9991 | prim.PrimData.PathScaleY = 0.5f; | ||
9992 | prim.PrimData.ProfileCurve = (ProfileCurve)1; | ||
9993 | prim.PrimData.PathCurve = (PathCurve)32; | ||
9994 | break; | ||
9995 | // Set specific parameters for ring | ||
9996 | case ScriptBaseClass.PRIM_TYPE_RING: | ||
9997 | prim.PrimData.PathScaleY = 0.5f; | ||
9998 | prim.PrimData.ProfileCurve = (ProfileCurve)3; | ||
9999 | prim.PrimData.PathCurve = (PathCurve)32; | ||
10000 | break; | ||
10001 | // Set specific parameters for sculpt | ||
10002 | case ScriptBaseClass.PRIM_TYPE_SCULPT: | ||
10003 | prim.PrimData.PathScaleY = 1.0f; | ||
10004 | prim.PrimData.ProfileCurve = (ProfileCurve)5; | ||
10005 | prim.PrimData.PathCurve = (PathCurve)32; | ||
10006 | break; | ||
10007 | // Default to specific parameters for box | ||
10008 | default: | ||
10009 | prim.PrimData.PathScaleY = 1.0f; | ||
10010 | prim.PrimData.ProfileCurve = (ProfileCurve)1; | ||
10011 | prim.PrimData.PathCurve = (PathCurve)16; | ||
10012 | break; | ||
10013 | } | ||
10014 | |||
10015 | return prim; | ||
10016 | } | ||
10017 | |||
10018 | /// <summary> | ||
10019 | /// Implementation of llGetGeometricCenter according to SL 2015-04-30. | ||
10020 | /// http://wiki.secondlife.com/wiki/LlGetGeometricCenter | ||
10021 | /// Returns the average position offset of all linked parts, | ||
10022 | /// including the root prim and seated avatars, | ||
10023 | /// relative to the root prim in local coordinates. | ||
10024 | /// </summary> | ||
10025 | public LSL_Vector llGetGeometricCenter() | 10248 | public LSL_Vector llGetGeometricCenter() |
10026 | { | 10249 | { |
10027 | // Subtract whatever position the root prim has to make it zero | 10250 | return new LSL_Vector(m_host.GetGeometricCenter()); |
10028 | Vector3 offset = m_host.ParentGroup.RootPart.OffsetPosition * -1.0f; | ||
10029 | |||
10030 | // Add all prim/part position offsets | ||
10031 | foreach (SceneObjectPart part in m_host.ParentGroup.Parts) | ||
10032 | offset = offset + part.OffsetPosition; | ||
10033 | // Add all avatar/scene presence position offsets | ||
10034 | foreach (ScenePresence sp in m_host.ParentGroup.GetSittingAvatars()) | ||
10035 | offset = offset + sp.OffsetPosition; | ||
10036 | |||
10037 | // Calculate and return the average offset | ||
10038 | offset = offset / (float)(m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount()); | ||
10039 | return new LSL_Vector(offset); | ||
10040 | } | 10251 | } |
10041 | 10252 | ||
10042 | public LSL_List GetEntityParams(ISceneEntity entity, LSL_List rules) | 10253 | public LSL_List llGetPrimitiveParams(LSL_List rules) |
10043 | { | 10254 | { |
10044 | LSL_List result = new LSL_List(); | 10255 | LSL_List result = new LSL_List(); |
10045 | LSL_List remaining; | ||
10046 | 10256 | ||
10047 | while (true) | 10257 | LSL_List remaining = GetPrimParams(m_host, rules, ref result); |
10048 | { | ||
10049 | // m_log.DebugFormat( | ||
10050 | // "[LSL API]: GetEntityParams has {0} rules with scene entity named {1}", | ||
10051 | // rules.Length, entity != null ? entity.Name : "NULL"); | ||
10052 | |||
10053 | if (entity == null) | ||
10054 | return result; | ||
10055 | |||
10056 | if (entity is SceneObjectPart) | ||
10057 | remaining = GetPrimParams((SceneObjectPart)entity, rules, ref result); | ||
10058 | else | ||
10059 | remaining = GetAgentParams((ScenePresence)entity, rules, ref result); | ||
10060 | |||
10061 | if (remaining == null || remaining.Length < 2) | ||
10062 | return result; | ||
10063 | 10258 | ||
10259 | while ((object)remaining != null && remaining.Length > 2) | ||
10260 | { | ||
10064 | int linknumber = remaining.GetLSLIntegerItem(0); | 10261 | int linknumber = remaining.GetLSLIntegerItem(0); |
10065 | rules = remaining.GetSublist(1, -1); | 10262 | rules = remaining.GetSublist(1, -1); |
10066 | entity = GetLinkEntity(m_host, linknumber); | 10263 | List<SceneObjectPart> parts = GetLinkParts(linknumber); |
10067 | } | ||
10068 | } | ||
10069 | 10264 | ||
10070 | public LSL_List llGetPrimitiveParams(LSL_List rules) | 10265 | foreach (SceneObjectPart part in parts) |
10071 | { | 10266 | remaining = GetPrimParams(part, rules, ref result); |
10072 | m_host.AddScriptLPS(1); | 10267 | } |
10073 | 10268 | ||
10074 | return GetEntityParams(m_host, rules); | 10269 | return result; |
10075 | } | 10270 | } |
10076 | 10271 | ||
10077 | public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) | 10272 | public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) |
10078 | { | 10273 | { |
10079 | m_host.AddScriptLPS(1); | 10274 | // acording to SL wiki this must indicate a single link number or link_root or link_this. |
10275 | // keep other options as before | ||
10080 | 10276 | ||
10081 | return GetEntityParams(GetLinkEntity(m_host, linknumber), rules); | 10277 | List<SceneObjectPart> parts; |
10082 | } | 10278 | List<ScenePresence> avatars; |
10083 | 10279 | ||
10084 | public LSL_Vector GetAgentSize(ScenePresence sp) | 10280 | LSL_List res = new LSL_List(); |
10085 | { | 10281 | LSL_List remaining = new LSL_List(); |
10086 | return new LSL_Vector(0.45, 0.6, sp.Appearance.AvatarHeight); | ||
10087 | } | ||
10088 | 10282 | ||
10089 | /// <summary> | 10283 | while (rules.Length > 0) |
10090 | /// Gets params for a seated avatar in a linkset. | ||
10091 | /// </summary> | ||
10092 | /// <returns></returns> | ||
10093 | /// <param name='sp'></param> | ||
10094 | /// <param name='rules'></param> | ||
10095 | /// <param name='res'></param> | ||
10096 | public LSL_List GetAgentParams(ScenePresence sp, LSL_List rules, ref LSL_List res) | ||
10097 | { | ||
10098 | int idx = 0; | ||
10099 | while (idx < rules.Length) | ||
10100 | { | 10284 | { |
10101 | int code = (int)rules.GetLSLIntegerItem(idx++); | 10285 | parts = GetLinkParts(linknumber); |
10102 | int remain = rules.Length-idx; | 10286 | avatars = GetLinkAvatars(linknumber); |
10103 | 10287 | ||
10104 | switch (code) | 10288 | remaining = new LSL_List(); |
10289 | foreach (SceneObjectPart part in parts) | ||
10105 | { | 10290 | { |
10106 | case (int)ScriptBaseClass.PRIM_MATERIAL: | 10291 | remaining = GetPrimParams(part, rules, ref res); |
10107 | res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MATERIAL_FLESH)); | 10292 | } |
10108 | break; | 10293 | foreach (ScenePresence avatar in avatars) |
10109 | 10294 | { | |
10110 | case (int)ScriptBaseClass.PRIM_PHYSICS: | 10295 | remaining = GetPrimParams(avatar, rules, ref res); |
10111 | res.Add(ScriptBaseClass.FALSE); | 10296 | } |
10112 | break; | ||
10113 | |||
10114 | case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: | ||
10115 | res.Add(ScriptBaseClass.FALSE); | ||
10116 | break; | ||
10117 | |||
10118 | case (int)ScriptBaseClass.PRIM_PHANTOM: | ||
10119 | res.Add(ScriptBaseClass.FALSE); | ||
10120 | break; | ||
10121 | |||
10122 | case (int)ScriptBaseClass.PRIM_POSITION: | ||
10123 | res.Add(new LSL_Vector(sp.AbsolutePosition)); | ||
10124 | break; | ||
10125 | |||
10126 | case (int)ScriptBaseClass.PRIM_SIZE: | ||
10127 | res.Add(GetAgentSize(sp)); | ||
10128 | break; | ||
10129 | |||
10130 | case (int)ScriptBaseClass.PRIM_ROTATION: | ||
10131 | res.Add(sp.GetWorldRotation()); | ||
10132 | break; | ||
10133 | |||
10134 | case (int)ScriptBaseClass.PRIM_TYPE: | ||
10135 | res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX)); | ||
10136 | res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT)); | ||
10137 | res.Add(new LSL_Vector(0, 1, 0)); | ||
10138 | res.Add(new LSL_Float(0)); | ||
10139 | res.Add(new LSL_Vector(0, 0, 0)); | ||
10140 | res.Add(new LSL_Vector(1, 1, 0)); | ||
10141 | res.Add(new LSL_Vector(0, 0, 0)); | ||
10142 | break; | ||
10143 | |||
10144 | case (int)ScriptBaseClass.PRIM_TEXTURE: | ||
10145 | if (remain < 1) | ||
10146 | return new LSL_List(); | ||
10147 | |||
10148 | int face = (int)rules.GetLSLIntegerItem(idx++); | ||
10149 | if (face > 21) | ||
10150 | break; | ||
10151 | |||
10152 | res.Add(new LSL_String("")); | ||
10153 | res.Add(ScriptBaseClass.ZERO_VECTOR); | ||
10154 | res.Add(ScriptBaseClass.ZERO_VECTOR); | ||
10155 | res.Add(new LSL_Float(0)); | ||
10156 | break; | ||
10157 | |||
10158 | case (int)ScriptBaseClass.PRIM_COLOR: | ||
10159 | if (remain < 1) | ||
10160 | return new LSL_List(); | ||
10161 | |||
10162 | face = (int)rules.GetLSLIntegerItem(idx++); | ||
10163 | if (face > 21) | ||
10164 | break; | ||
10165 | |||
10166 | res.Add(ScriptBaseClass.ZERO_VECTOR); | ||
10167 | res.Add(new LSL_Float(0)); | ||
10168 | break; | ||
10169 | |||
10170 | case (int)ScriptBaseClass.PRIM_BUMP_SHINY: | ||
10171 | if (remain < 1) | ||
10172 | return new LSL_List(); | ||
10173 | |||
10174 | face = (int)rules.GetLSLIntegerItem(idx++); | ||
10175 | if (face > 21) | ||
10176 | break; | ||
10177 | |||
10178 | res.Add(ScriptBaseClass.PRIM_SHINY_NONE); | ||
10179 | res.Add(ScriptBaseClass.PRIM_BUMP_NONE); | ||
10180 | break; | ||
10181 | |||
10182 | case (int)ScriptBaseClass.PRIM_FULLBRIGHT: | ||
10183 | if (remain < 1) | ||
10184 | return new LSL_List(); | ||
10185 | |||
10186 | face = (int)rules.GetLSLIntegerItem(idx++); | ||
10187 | if (face > 21) | ||
10188 | break; | ||
10189 | |||
10190 | res.Add(ScriptBaseClass.FALSE); | ||
10191 | break; | ||
10192 | |||
10193 | case (int)ScriptBaseClass.PRIM_FLEXIBLE: | ||
10194 | res.Add(ScriptBaseClass.FALSE); | ||
10195 | res.Add(new LSL_Integer(0)); | ||
10196 | res.Add(new LSL_Float(0)); | ||
10197 | res.Add(new LSL_Float(0)); | ||
10198 | res.Add(new LSL_Float(0)); | ||
10199 | res.Add(new LSL_Float(0)); | ||
10200 | res.Add(ScriptBaseClass.ZERO_VECTOR); | ||
10201 | break; | ||
10202 | |||
10203 | case (int)ScriptBaseClass.PRIM_TEXGEN: | ||
10204 | if (remain < 1) | ||
10205 | return new LSL_List(); | ||
10206 | |||
10207 | face = (int)rules.GetLSLIntegerItem(idx++); | ||
10208 | if (face > 21) | ||
10209 | break; | ||
10210 | |||
10211 | res.Add(ScriptBaseClass.PRIM_TEXGEN_DEFAULT); | ||
10212 | break; | ||
10213 | |||
10214 | case (int)ScriptBaseClass.PRIM_POINT_LIGHT: | ||
10215 | res.Add(ScriptBaseClass.FALSE); | ||
10216 | res.Add(ScriptBaseClass.ZERO_VECTOR); | ||
10217 | res.Add(ScriptBaseClass.ZERO_VECTOR); | ||
10218 | break; | ||
10219 | |||
10220 | case (int)ScriptBaseClass.PRIM_GLOW: | ||
10221 | if (remain < 1) | ||
10222 | return new LSL_List(); | ||
10223 | |||
10224 | face = (int)rules.GetLSLIntegerItem(idx++); | ||
10225 | if (face > 21) | ||
10226 | break; | ||
10227 | |||
10228 | res.Add(new LSL_Float(0)); | ||
10229 | break; | ||
10230 | |||
10231 | case (int)ScriptBaseClass.PRIM_TEXT: | ||
10232 | res.Add(new LSL_String("")); | ||
10233 | res.Add(ScriptBaseClass.ZERO_VECTOR); | ||
10234 | res.Add(new LSL_Float(1)); | ||
10235 | break; | ||
10236 | |||
10237 | case (int)ScriptBaseClass.PRIM_ROT_LOCAL: | ||
10238 | res.Add(new LSL_Rotation(sp.Rotation)); | ||
10239 | break; | ||
10240 | |||
10241 | case (int)ScriptBaseClass.PRIM_POS_LOCAL: | ||
10242 | res.Add(new LSL_Vector(sp.OffsetPosition)); | ||
10243 | break; | ||
10244 | |||
10245 | case (int)ScriptBaseClass.PRIM_SLICE: | ||
10246 | res.Add(new LSL_Vector(0, 1, 0)); | ||
10247 | break; | ||
10248 | |||
10249 | case (int)ScriptBaseClass.PRIM_LINK_TARGET: | ||
10250 | if(remain < 3) | ||
10251 | return new LSL_List(); | ||
10252 | 10297 | ||
10253 | return rules.GetSublist(idx, -1); | 10298 | if (remaining.Length > 0) |
10299 | { | ||
10300 | linknumber = remaining.GetLSLIntegerItem(0); | ||
10301 | rules = remaining.GetSublist(1, -1); | ||
10254 | } | 10302 | } |
10303 | else | ||
10304 | break; | ||
10255 | } | 10305 | } |
10256 | 10306 | ||
10257 | return new LSL_List(); | 10307 | return res; |
10258 | } | 10308 | } |
10259 | 10309 | ||
10260 | public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res) | 10310 | public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res) |
10261 | { | 10311 | { |
10262 | int idx = 0; | 10312 | int idx = 0; |
10313 | int face; | ||
10314 | Primitive.TextureEntry tex; | ||
10315 | int nsides = GetNumberOfSides(part); | ||
10316 | |||
10263 | while (idx < rules.Length) | 10317 | while (idx < rules.Length) |
10264 | { | 10318 | { |
10265 | int code = (int)rules.GetLSLIntegerItem(idx++); | 10319 | int code = (int)rules.GetLSLIntegerItem(idx++); |
@@ -10293,19 +10347,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
10293 | break; | 10347 | break; |
10294 | 10348 | ||
10295 | case (int)ScriptBaseClass.PRIM_POSITION: | 10349 | case (int)ScriptBaseClass.PRIM_POSITION: |
10296 | LSL_Vector v = new LSL_Vector(part.AbsolutePosition); | 10350 | LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, |
10297 | 10351 | part.AbsolutePosition.Y, | |
10298 | // For some reason, the part.AbsolutePosition.* values do not change if the | 10352 | part.AbsolutePosition.Z); |
10299 | // linkset is rotated; they always reflect the child prim's world position | ||
10300 | // as though the linkset is unrotated. This is incompatible behavior with SL's | ||
10301 | // implementation, so will break scripts imported from there (not to mention it | ||
10302 | // makes it more difficult to determine a child prim's actual inworld position). | ||
10303 | if (!part.IsRoot) | ||
10304 | { | ||
10305 | LSL_Vector rootPos = new LSL_Vector(m_host.ParentGroup.AbsolutePosition); | ||
10306 | v = ((v - rootPos) * llGetRootRotation()) + rootPos; | ||
10307 | } | ||
10308 | |||
10309 | res.Add(v); | 10353 | res.Add(v); |
10310 | break; | 10354 | break; |
10311 | 10355 | ||
@@ -10410,11 +10454,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
10410 | if (remain < 1) | 10454 | if (remain < 1) |
10411 | return new LSL_List(); | 10455 | return new LSL_List(); |
10412 | 10456 | ||
10413 | int face = (int)rules.GetLSLIntegerItem(idx++); | 10457 | face = (int)rules.GetLSLIntegerItem(idx++); |
10414 | Primitive.TextureEntry tex = part.Shape.Textures; | 10458 | tex = part.Shape.Textures; |
10459 | |||
10415 | if (face == ScriptBaseClass.ALL_SIDES) | 10460 | if (face == ScriptBaseClass.ALL_SIDES) |
10416 | { | 10461 | { |
10417 | for (face = 0 ; face < GetNumberOfSides(part); face++) | 10462 | for (face = 0; face < nsides; face++) |
10418 | { | 10463 | { |
10419 | Primitive.TextureEntryFace texface = tex.GetFace((uint)face); | 10464 | Primitive.TextureEntryFace texface = tex.GetFace((uint)face); |
10420 | 10465 | ||
@@ -10430,7 +10475,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
10430 | } | 10475 | } |
10431 | else | 10476 | else |
10432 | { | 10477 | { |
10433 | if (face >= 0 && face < GetNumberOfSides(part)) | 10478 | if (face >= 0 && face < nsides) |
10434 | { | 10479 | { |
10435 | Primitive.TextureEntryFace texface = tex.GetFace((uint)face); | 10480 | Primitive.TextureEntryFace texface = tex.GetFace((uint)face); |
10436 | 10481 | ||
@@ -10450,13 +10495,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
10450 | if (remain < 1) | 10495 | if (remain < 1) |
10451 | return new LSL_List(); | 10496 | return new LSL_List(); |
10452 | 10497 | ||
10453 | face=(int)rules.GetLSLIntegerItem(idx++); | 10498 | face = (int)rules.GetLSLIntegerItem(idx++); |
10454 | |||
10455 | tex = part.Shape.Textures; | 10499 | tex = part.Shape.Textures; |
10456 | Color4 texcolor; | 10500 | Color4 texcolor; |
10501 | |||
10457 | if (face == ScriptBaseClass.ALL_SIDES) | 10502 | if (face == ScriptBaseClass.ALL_SIDES) |
10458 | { | 10503 | { |
10459 | for (face = 0 ; face < GetNumberOfSides(part); face++) | 10504 | for (face = 0; face < nsides; face++) |
10460 | { | 10505 | { |
10461 | texcolor = tex.GetFace((uint)face).RGBA; | 10506 | texcolor = tex.GetFace((uint)face).RGBA; |
10462 | res.Add(new LSL_Vector(texcolor.R, | 10507 | res.Add(new LSL_Vector(texcolor.R, |
@@ -10476,61 +10521,100 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
10476 | break; | 10521 | break; |
10477 | 10522 | ||
10478 | case (int)ScriptBaseClass.PRIM_BUMP_SHINY: | 10523 | case (int)ScriptBaseClass.PRIM_BUMP_SHINY: |
10524 | { | ||
10479 | if (remain < 1) | 10525 | if (remain < 1) |
10480 | return new LSL_List(); | 10526 | return new LSL_List(); |
10481 | 10527 | ||
10482 | face=(int)rules.GetLSLIntegerItem(idx++); | 10528 | face = (int)rules.GetLSLIntegerItem(idx++); |
10483 | |||
10484 | tex = part.Shape.Textures; | 10529 | tex = part.Shape.Textures; |
10530 | int shiny; | ||
10485 | if (face == ScriptBaseClass.ALL_SIDES) | 10531 | if (face == ScriptBaseClass.ALL_SIDES) |
10486 | { | 10532 | { |
10487 | for (face = 0; face < GetNumberOfSides(part); face++) | 10533 | for (face = 0; face < nsides; face++) |
10488 | { | 10534 | { |
10489 | Primitive.TextureEntryFace texface = tex.GetFace((uint)face); | 10535 | Shininess shinyness = tex.GetFace((uint)face).Shiny; |
10490 | // Convert Shininess to PRIM_SHINY_* | 10536 | if (shinyness == Shininess.High) |
10491 | res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); | 10537 | { |
10492 | // PRIM_BUMP_* | 10538 | shiny = ScriptBaseClass.PRIM_SHINY_HIGH; |
10493 | res.Add(new LSL_Integer((int)texface.Bump)); | 10539 | } |
10540 | else if (shinyness == Shininess.Medium) | ||
10541 | { | ||
10542 | shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM; | ||
10543 | } | ||
10544 | else if (shinyness == Shininess.Low) | ||
10545 | { | ||
10546 | shiny = ScriptBaseClass.PRIM_SHINY_LOW; | ||
10547 | } | ||
10548 | else | ||
10549 | { | ||
10550 | shiny = ScriptBaseClass.PRIM_SHINY_NONE; | ||
10551 | } | ||
10552 | res.Add(new LSL_Integer(shiny)); | ||
10553 | res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump)); | ||
10494 | } | 10554 | } |
10495 | } | 10555 | } |
10496 | else | 10556 | else |
10497 | { | 10557 | { |
10498 | if (face >= 0 && face < GetNumberOfSides(part)) | 10558 | Shininess shinyness = tex.GetFace((uint)face).Shiny; |
10559 | if (shinyness == Shininess.High) | ||
10499 | { | 10560 | { |
10500 | Primitive.TextureEntryFace texface = tex.GetFace((uint)face); | 10561 | shiny = ScriptBaseClass.PRIM_SHINY_HIGH; |
10501 | // Convert Shininess to PRIM_SHINY_* | 10562 | } |
10502 | res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); | 10563 | else if (shinyness == Shininess.Medium) |
10503 | // PRIM_BUMP_* | 10564 | { |
10504 | res.Add(new LSL_Integer((int)texface.Bump)); | 10565 | shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM; |
10566 | } | ||
10567 | else if (shinyness == Shininess.Low) | ||
10568 | { | ||
10569 | shiny = ScriptBaseClass.PRIM_SHINY_LOW; | ||
10505 | } | 10570 | } |
10571 | else | ||
10572 | { | ||
10573 | shiny = ScriptBaseClass.PRIM_SHINY_NONE; | ||
10574 | } | ||
10575 | res.Add(new LSL_Integer(shiny)); | ||
10576 | res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump)); | ||
10506 | } | 10577 | } |
10507 | break; | 10578 | break; |
10508 | 10579 | } | |
10509 | case (int)ScriptBaseClass.PRIM_FULLBRIGHT: | 10580 | case (int)ScriptBaseClass.PRIM_FULLBRIGHT: |
10581 | { | ||
10510 | if (remain < 1) | 10582 | if (remain < 1) |
10511 | return new LSL_List(); | 10583 | return new LSL_List(); |
10512 | 10584 | ||
10513 | face = (int)rules.GetLSLIntegerItem(idx++); | 10585 | face = (int)rules.GetLSLIntegerItem(idx++); |
10514 | 10586 | ||
10515 | tex = part.Shape.Textures; | 10587 | tex = part.Shape.Textures; |
10588 | int fullbright; | ||
10516 | if (face == ScriptBaseClass.ALL_SIDES) | 10589 | if (face == ScriptBaseClass.ALL_SIDES) |
10517 | { | 10590 | { |
10518 | for (face = 0; face < GetNumberOfSides(part); face++) | 10591 | for (face = 0; face < nsides; face++) |
10519 | { | 10592 | { |
10520 | Primitive.TextureEntryFace texface = tex.GetFace((uint)face); | 10593 | if (tex.GetFace((uint)face).Fullbright == true) |
10521 | res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); | 10594 | { |
10595 | fullbright = ScriptBaseClass.TRUE; | ||
10596 | } | ||
10597 | else | ||
10598 | { | ||
10599 | fullbright = ScriptBaseClass.FALSE; | ||
10600 | } | ||
10601 | res.Add(new LSL_Integer(fullbright)); | ||
10522 | } | 10602 | } |
10523 | } | 10603 | } |
10524 | else | 10604 | else |
10525 | { | 10605 | { |
10526 | if (face >= 0 && face < GetNumberOfSides(part)) | 10606 | if (tex.GetFace((uint)face).Fullbright == true) |
10527 | { | 10607 | { |
10528 | Primitive.TextureEntryFace texface = tex.GetFace((uint)face); | 10608 | fullbright = ScriptBaseClass.TRUE; |
10529 | res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); | 10609 | } |
10610 | else | ||
10611 | { | ||
10612 | fullbright = ScriptBaseClass.FALSE; | ||
10530 | } | 10613 | } |
10614 | res.Add(new LSL_Integer(fullbright)); | ||
10531 | } | 10615 | } |
10532 | break; | 10616 | break; |
10533 | 10617 | } | |
10534 | case (int)ScriptBaseClass.PRIM_FLEXIBLE: | 10618 | case (int)ScriptBaseClass.PRIM_FLEXIBLE: |
10535 | PrimitiveBaseShape shape = part.Shape; | 10619 | PrimitiveBaseShape shape = part.Shape; |
10536 | 10620 | ||
@@ -10549,27 +10633,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
10549 | break; | 10633 | break; |
10550 | 10634 | ||
10551 | case (int)ScriptBaseClass.PRIM_TEXGEN: | 10635 | case (int)ScriptBaseClass.PRIM_TEXGEN: |
10636 | // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) | ||
10552 | if (remain < 1) | 10637 | if (remain < 1) |
10553 | return new LSL_List(); | 10638 | return new LSL_List(); |
10554 | 10639 | ||
10555 | face=(int)rules.GetLSLIntegerItem(idx++); | 10640 | face = (int)rules.GetLSLIntegerItem(idx++); |
10556 | 10641 | ||
10557 | tex = part.Shape.Textures; | 10642 | tex = part.Shape.Textures; |
10558 | if (face == ScriptBaseClass.ALL_SIDES) | 10643 | if (face == ScriptBaseClass.ALL_SIDES) |
10559 | { | 10644 | { |
10560 | for (face = 0; face < GetNumberOfSides(part); face++) | 10645 | for (face = 0; face < nsides; face++) |
10561 | { | 10646 | { |
10562 | MappingType texgen = tex.GetFace((uint)face).TexMapType; | 10647 | if (tex.GetFace((uint)face).TexMapType == MappingType.Planar) |
10563 | // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. | 10648 | { |
10564 | res.Add(new LSL_Integer((uint)texgen >> 1)); | 10649 | res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR)); |
10650 | } | ||
10651 | else | ||
10652 | { | ||
10653 | res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT)); | ||
10654 | } | ||
10565 | } | 10655 | } |
10566 | } | 10656 | } |
10567 | else | 10657 | else |
10568 | { | 10658 | { |
10569 | if (face >= 0 && face < GetNumberOfSides(part)) | 10659 | if (tex.GetFace((uint)face).TexMapType == MappingType.Planar) |
10570 | { | 10660 | { |
10571 | MappingType texgen = tex.GetFace((uint)face).TexMapType; | 10661 | res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR)); |
10572 | res.Add(new LSL_Integer((uint)texgen >> 1)); | 10662 | } |
10663 | else | ||
10664 | { | ||
10665 | res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT)); | ||
10573 | } | 10666 | } |
10574 | } | 10667 | } |
10575 | break; | 10668 | break; |
@@ -10593,24 +10686,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
10593 | if (remain < 1) | 10686 | if (remain < 1) |
10594 | return new LSL_List(); | 10687 | return new LSL_List(); |
10595 | 10688 | ||
10596 | face=(int)rules.GetLSLIntegerItem(idx++); | 10689 | face = (int)rules.GetLSLIntegerItem(idx++); |
10597 | 10690 | ||
10598 | tex = part.Shape.Textures; | 10691 | tex = part.Shape.Textures; |
10692 | float primglow; | ||
10599 | if (face == ScriptBaseClass.ALL_SIDES) | 10693 | if (face == ScriptBaseClass.ALL_SIDES) |
10600 | { | 10694 | { |
10601 | for (face = 0; face < GetNumberOfSides(part); face++) | 10695 | for (face = 0; face < nsides; face++) |
10602 | { | 10696 | { |
10603 | Primitive.TextureEntryFace texface = tex.GetFace((uint)face); | 10697 | primglow = tex.GetFace((uint)face).Glow; |
10604 | res.Add(new LSL_Float(texface.Glow)); | 10698 | res.Add(new LSL_Float(primglow)); |
10605 | } | 10699 | } |
10606 | } | 10700 | } |
10607 | else | 10701 | else |
10608 | { | 10702 | { |
10609 | if (face >= 0 && face < GetNumberOfSides(part)) | 10703 | primglow = tex.GetFace((uint)face).Glow; |
10610 | { | 10704 | res.Add(new LSL_Float(primglow)); |
10611 | Primitive.TextureEntryFace texface = tex.GetFace((uint)face); | ||
10612 | res.Add(new LSL_Float(texface.Glow)); | ||
10613 | } | ||
10614 | } | 10705 | } |
10615 | break; | 10706 | break; |
10616 | 10707 | ||
@@ -10620,17 +10711,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
10620 | res.Add(new LSL_Vector(textColor.R, | 10711 | res.Add(new LSL_Vector(textColor.R, |
10621 | textColor.G, | 10712 | textColor.G, |
10622 | textColor.B)); | 10713 | textColor.B)); |
10623 | res.Add(new LSL_Float(1.0 - textColor.A)); | 10714 | res.Add(new LSL_Float(textColor.A)); |
10624 | break; | 10715 | break; |
10716 | |||
10625 | case (int)ScriptBaseClass.PRIM_NAME: | 10717 | case (int)ScriptBaseClass.PRIM_NAME: |
10626 | res.Add(new LSL_String(part.Name)); | 10718 | res.Add(new LSL_String(part.Name)); |
10627 | break; | 10719 | break; |
10720 | |||
10628 | case (int)ScriptBaseClass.PRIM_DESC: | 10721 | case (int)ScriptBaseClass.PRIM_DESC: |
10629 | res.Add(new LSL_String(part.Description)); | 10722 | res.Add(new LSL_String(part.Description)); |
10630 | break; | 10723 | break; |
10631 | case (int)ScriptBaseClass.PRIM_ROT_LOCAL: | 10724 | case (int)ScriptBaseClass.PRIM_ROT_LOCAL: |
10632 | res.Add(new LSL_Rotation(part.RotationOffset)); | 10725 | res.Add(new LSL_Rotation(part.RotationOffset)); |
10633 | break; | 10726 | break; |
10727 | |||
10634 | case (int)ScriptBaseClass.PRIM_POS_LOCAL: | 10728 | case (int)ScriptBaseClass.PRIM_POS_LOCAL: |
10635 | res.Add(new LSL_Vector(GetPartLocalPos(part))); | 10729 | res.Add(new LSL_Vector(GetPartLocalPos(part))); |
10636 | break; | 10730 | break; |
@@ -10643,6 +10737,71 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
10643 | 0 | 10737 | 0 |
10644 | )); | 10738 | )); |
10645 | break; | 10739 | break; |
10740 | |||
10741 | case (int)ScriptBaseClass.PRIM_OMEGA: | ||
10742 | // this may return values diferent from SL since we don't handle set the same way | ||
10743 | float gain = 1.0f; // we don't use gain and don't store it | ||
10744 | Vector3 axis = part.AngularVelocity; | ||
10745 | float spin = axis.Length(); | ||
10746 | if(spin < 1.0e-6) | ||
10747 | { | ||
10748 | axis = Vector3.Zero; | ||
10749 | gain = 0.0f; | ||
10750 | spin = 0.0f; | ||
10751 | } | ||
10752 | else | ||
10753 | { | ||
10754 | axis = axis * (1.0f/spin); | ||
10755 | } | ||
10756 | |||
10757 | res.Add(new LSL_Vector(axis.X, | ||
10758 | axis.Y, | ||
10759 | axis.Z)); | ||
10760 | res.Add(new LSL_Float(spin)); | ||
10761 | res.Add(new LSL_Float(gain)); | ||
10762 | break; | ||
10763 | |||
10764 | case (int)ScriptBaseClass.PRIM_SIT_TARGET: | ||
10765 | if(part.IsSitTargetSet) | ||
10766 | { | ||
10767 | res.Add(new LSL_Integer(1)); | ||
10768 | res.Add(new LSL_Vector(part.SitTargetPosition)); | ||
10769 | res.Add(new LSL_Rotation(part.SitTargetOrientation)); | ||
10770 | } | ||
10771 | else | ||
10772 | { | ||
10773 | res.Add(new LSL_Integer(0)); | ||
10774 | res.Add(new LSL_Vector(Vector3.Zero)); | ||
10775 | res.Add(new LSL_Rotation(Quaternion.Identity)); | ||
10776 | } | ||
10777 | break; | ||
10778 | |||
10779 | case (int)ScriptBaseClass.PRIM_NORMAL: | ||
10780 | case (int)ScriptBaseClass.PRIM_SPECULAR: | ||
10781 | case (int)ScriptBaseClass.PRIM_ALPHA_MODE: | ||
10782 | if (remain < 1) | ||
10783 | return new LSL_List(); | ||
10784 | |||
10785 | face = (int)rules.GetLSLIntegerItem(idx++); | ||
10786 | tex = part.Shape.Textures; | ||
10787 | if (face == ScriptBaseClass.ALL_SIDES) | ||
10788 | { | ||
10789 | for (face = 0; face < nsides; face++) | ||
10790 | { | ||
10791 | Primitive.TextureEntryFace texface = tex.GetFace((uint)face); | ||
10792 | getLSLFaceMaterial(ref res, code, part, texface); | ||
10793 | } | ||
10794 | } | ||
10795 | else | ||
10796 | { | ||
10797 | if (face >= 0 && face < nsides) | ||
10798 | { | ||
10799 | Primitive.TextureEntryFace texface = tex.GetFace((uint)face); | ||
10800 | getLSLFaceMaterial(ref res, code, part, texface); | ||
10801 | } | ||
10802 | } | ||
10803 | break; | ||
10804 | |||
10646 | case (int)ScriptBaseClass.PRIM_LINK_TARGET: | 10805 | case (int)ScriptBaseClass.PRIM_LINK_TARGET: |
10647 | 10806 | ||
10648 | // TODO: Should be issuing a runtime script warning in this case. | 10807 | // TODO: Should be issuing a runtime script warning in this case. |
@@ -10656,15 +10815,116 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
10656 | return new LSL_List(); | 10815 | return new LSL_List(); |
10657 | } | 10816 | } |
10658 | 10817 | ||
10818 | /* | ||
10819 | private string filterTextureUUIDbyRights(UUID origID, SceneObjectPart part, bool checkTaskInventory, bool returnInvName) | ||
10820 | { | ||
10821 | if(checkTaskInventory) | ||
10822 | { | ||
10823 | lock (part.TaskInventory) | ||
10824 | { | ||
10825 | foreach (KeyValuePair<UUID, TaskInventoryItem> inv in part.TaskInventory) | ||
10826 | { | ||
10827 | if (inv.Value.AssetID == origID) | ||
10828 | { | ||
10829 | if(inv.Value.InvType == (int)InventoryType.Texture) | ||
10830 | { | ||
10831 | if(returnInvName) | ||
10832 | return inv.Value.Name; | ||
10833 | else | ||
10834 | return origID.ToString(); | ||
10835 | } | ||
10836 | else | ||
10837 | return UUID.Zero.ToString(); | ||
10838 | } | ||
10839 | } | ||
10840 | } | ||
10841 | } | ||
10842 | |||
10843 | if(World.Permissions.CanEditObject(m_host.ParentGroup.UUID, m_host.ParentGroup.RootPart.OwnerID)) | ||
10844 | return origID.ToString(); | ||
10845 | |||
10846 | return UUID.Zero.ToString(); | ||
10847 | } | ||
10848 | */ | ||
10849 | private void getLSLFaceMaterial(ref LSL_List res, int code, SceneObjectPart part, Primitive.TextureEntryFace texface) | ||
10850 | { | ||
10851 | UUID matID = texface.MaterialID; | ||
10852 | if(matID != UUID.Zero) | ||
10853 | { | ||
10854 | AssetBase MatAsset = World.AssetService.Get(matID.ToString()); | ||
10855 | if(MatAsset != null) | ||
10856 | { | ||
10857 | Byte[] data = MatAsset.Data; | ||
10858 | OSDMap osdmat = (OSDMap)OSDParser.DeserializeLLSDXml(data); | ||
10859 | if(osdmat != null && osdmat.ContainsKey("NormMap")) | ||
10860 | { | ||
10861 | string mapIDstr; | ||
10862 | FaceMaterial mat = new FaceMaterial(matID, osdmat); | ||
10863 | if(code == ScriptBaseClass.PRIM_NORMAL) | ||
10864 | { | ||
10865 | // mapIDstr = filterTextureUUIDbyRights(mat.NormalMapID, part, true, false); | ||
10866 | mapIDstr = mat.NormalMapID.ToString(); | ||
10867 | res.Add(new LSL_String(mapIDstr)); | ||
10868 | res.Add(new LSL_Vector(mat.NormalRepeatX, mat.NormalRepeatY, 0)); | ||
10869 | res.Add(new LSL_Vector(mat.NormalOffsetX, mat.NormalOffsetY, 0)); | ||
10870 | res.Add(new LSL_Float(mat.NormalRotation)); | ||
10871 | } | ||
10872 | else if(code == ScriptBaseClass.PRIM_SPECULAR ) | ||
10873 | { | ||
10874 | // mapIDstr = filterTextureUUIDbyRights(mat.SpecularMapID, part, true, false); | ||
10875 | const float colorScale = 1.0f/255f; | ||
10876 | mapIDstr = mat.SpecularMapID.ToString(); | ||
10877 | res.Add(new LSL_String(mapIDstr)); | ||
10878 | res.Add(new LSL_Vector(mat.SpecularRepeatX, mat.SpecularRepeatY, 0)); | ||
10879 | res.Add(new LSL_Vector(mat.SpecularOffsetX, mat.SpecularOffsetY, 0)); | ||
10880 | res.Add(new LSL_Float(mat.SpecularRotation)); | ||
10881 | res.Add(new LSL_Vector(mat.SpecularLightColor.R * colorScale, | ||
10882 | mat.SpecularLightColor.G * colorScale, | ||
10883 | mat.SpecularLightColor.B * colorScale)); | ||
10884 | res.Add(new LSL_Integer(mat.SpecularLightExponent)); | ||
10885 | res.Add(new LSL_Integer(mat.EnvironmentIntensity)); | ||
10886 | } | ||
10887 | else if(code == ScriptBaseClass.PRIM_ALPHA_MODE) | ||
10888 | { | ||
10889 | res.Add(new LSL_Integer(mat.DiffuseAlphaMode)); | ||
10890 | res.Add(new LSL_Integer(mat.AlphaMaskCutoff)); | ||
10891 | } | ||
10892 | return; | ||
10893 | } | ||
10894 | } | ||
10895 | matID = UUID.Zero; | ||
10896 | } | ||
10897 | if(matID == UUID.Zero) | ||
10898 | { | ||
10899 | if(code == (int)ScriptBaseClass.PRIM_NORMAL || code == (int)ScriptBaseClass.PRIM_SPECULAR ) | ||
10900 | { | ||
10901 | res.Add(new LSL_String(UUID.Zero.ToString())); | ||
10902 | res.Add(new LSL_Vector(1.0, 1.0, 0)); | ||
10903 | res.Add(new LSL_Vector(0, 0, 0)); | ||
10904 | res.Add(new LSL_Float(0)); | ||
10905 | |||
10906 | if(code == (int)ScriptBaseClass.PRIM_SPECULAR) | ||
10907 | { | ||
10908 | res.Add(new LSL_Vector(1.0, 1.0, 1.0)); | ||
10909 | res.Add(new LSL_Integer(51)); | ||
10910 | res.Add(new LSL_Integer(0)); | ||
10911 | } | ||
10912 | } | ||
10913 | else if(code == (int)ScriptBaseClass.PRIM_ALPHA_MODE) | ||
10914 | { | ||
10915 | res.Add(new LSL_Integer(1)); | ||
10916 | res.Add(new LSL_Integer(0)); | ||
10917 | } | ||
10918 | } | ||
10919 | } | ||
10920 | |||
10659 | public LSL_List llGetPrimMediaParams(int face, LSL_List rules) | 10921 | public LSL_List llGetPrimMediaParams(int face, LSL_List rules) |
10660 | { | 10922 | { |
10661 | m_host.AddScriptLPS(1); | ||
10662 | return GetPrimMediaParams(m_host, face, rules); | 10923 | return GetPrimMediaParams(m_host, face, rules); |
10663 | } | 10924 | } |
10664 | 10925 | ||
10665 | public LSL_List llGetLinkMedia(LSL_Integer link, LSL_Integer face, LSL_List rules) | 10926 | public LSL_List llGetLinkMedia(LSL_Integer link, LSL_Integer face, LSL_List rules) |
10666 | { | 10927 | { |
10667 | m_host.AddScriptLPS(1); | ||
10668 | if (link == ScriptBaseClass.LINK_ROOT) | 10928 | if (link == ScriptBaseClass.LINK_ROOT) |
10669 | return GetPrimMediaParams(m_host.ParentGroup.RootPart, face, rules); | 10929 | return GetPrimMediaParams(m_host.ParentGroup.RootPart, face, rules); |
10670 | else if (link == ScriptBaseClass.LINK_THIS) | 10930 | else if (link == ScriptBaseClass.LINK_THIS) |
@@ -10783,13 +11043,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
10783 | 11043 | ||
10784 | public LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules) | 11044 | public LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules) |
10785 | { | 11045 | { |
10786 | m_host.AddScriptLPS(1); | ||
10787 | return SetPrimMediaParams(m_host, face, rules); | 11046 | return SetPrimMediaParams(m_host, face, rules); |
10788 | } | 11047 | } |
10789 | 11048 | ||
10790 | public LSL_Integer llSetLinkMedia(LSL_Integer link, LSL_Integer face, LSL_List rules) | 11049 | public LSL_Integer llSetLinkMedia(LSL_Integer link, LSL_Integer face, LSL_List rules) |
10791 | { | 11050 | { |
10792 | m_host.AddScriptLPS(1); | ||
10793 | if (link == ScriptBaseClass.LINK_ROOT) | 11051 | if (link == ScriptBaseClass.LINK_ROOT) |
10794 | return SetPrimMediaParams(m_host.ParentGroup.RootPart, face, rules); | 11052 | return SetPrimMediaParams(m_host.ParentGroup.RootPart, face, rules); |
10795 | else if (link == ScriptBaseClass.LINK_THIS) | 11053 | else if (link == ScriptBaseClass.LINK_THIS) |
@@ -10907,13 +11165,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
10907 | 11165 | ||
10908 | public LSL_Integer llClearPrimMedia(LSL_Integer face) | 11166 | public LSL_Integer llClearPrimMedia(LSL_Integer face) |
10909 | { | 11167 | { |
10910 | m_host.AddScriptLPS(1); | ||
10911 | return ClearPrimMedia(m_host, face); | 11168 | return ClearPrimMedia(m_host, face); |
10912 | } | 11169 | } |
10913 | 11170 | ||
10914 | public LSL_Integer llClearLinkMedia(LSL_Integer link, LSL_Integer face) | 11171 | public LSL_Integer llClearLinkMedia(LSL_Integer link, LSL_Integer face) |
10915 | { | 11172 | { |
10916 | m_host.AddScriptLPS(1); | ||
10917 | if (link == ScriptBaseClass.LINK_ROOT) | 11173 | if (link == ScriptBaseClass.LINK_ROOT) |
10918 | return ClearPrimMedia(m_host.ParentGroup.RootPart, face); | 11174 | return ClearPrimMedia(m_host.ParentGroup.RootPart, face); |
10919 | else if (link == ScriptBaseClass.LINK_THIS) | 11175 | else if (link == ScriptBaseClass.LINK_THIS) |
@@ -11078,8 +11334,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11078 | 11334 | ||
11079 | char[] imdt = new char[8]; | 11335 | char[] imdt = new char[8]; |
11080 | 11336 | ||
11081 | m_host.AddScriptLPS(1); | ||
11082 | |||
11083 | // Manually unroll the loop | 11337 | // Manually unroll the loop |
11084 | 11338 | ||
11085 | imdt[7] = '='; | 11339 | imdt[7] = '='; |
@@ -11140,8 +11394,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11140 | int number = 0; | 11394 | int number = 0; |
11141 | int digit; | 11395 | int digit; |
11142 | 11396 | ||
11143 | m_host.AddScriptLPS(1); | ||
11144 | |||
11145 | // Require a well-fromed base64 string | 11397 | // Require a well-fromed base64 string |
11146 | 11398 | ||
11147 | if (str.Length > 8) | 11399 | if (str.Length > 8) |
@@ -11197,14 +11449,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11197 | 11449 | ||
11198 | public LSL_Float llGetGMTclock() | 11450 | public LSL_Float llGetGMTclock() |
11199 | { | 11451 | { |
11200 | m_host.AddScriptLPS(1); | ||
11201 | return DateTime.UtcNow.TimeOfDay.TotalSeconds; | 11452 | return DateTime.UtcNow.TimeOfDay.TotalSeconds; |
11202 | } | 11453 | } |
11203 | 11454 | ||
11204 | public LSL_String llGetHTTPHeader(LSL_Key request_id, string header) | 11455 | public LSL_String llGetHTTPHeader(LSL_Key request_id, string header) |
11205 | { | 11456 | { |
11206 | m_host.AddScriptLPS(1); | ||
11207 | |||
11208 | if (m_UrlModule != null) | 11457 | if (m_UrlModule != null) |
11209 | return m_UrlModule.GetHttpHeader(new UUID(request_id), header); | 11458 | return m_UrlModule.GetHttpHeader(new UUID(request_id), header); |
11210 | return String.Empty; | 11459 | return String.Empty; |
@@ -11213,7 +11462,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11213 | 11462 | ||
11214 | public LSL_String llGetSimulatorHostname() | 11463 | public LSL_String llGetSimulatorHostname() |
11215 | { | 11464 | { |
11216 | m_host.AddScriptLPS(1); | ||
11217 | IUrlModule UrlModule = World.RequestModuleInterface<IUrlModule>(); | 11465 | IUrlModule UrlModule = World.RequestModuleInterface<IUrlModule>(); |
11218 | return UrlModule.ExternalHostNameForLSL; | 11466 | return UrlModule.ExternalHostNameForLSL; |
11219 | } | 11467 | } |
@@ -11237,8 +11485,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11237 | // The function returns an ordered list | 11485 | // The function returns an ordered list |
11238 | // representing the tokens found in the supplied | 11486 | // representing the tokens found in the supplied |
11239 | // sources string. If two successive tokenizers | 11487 | // sources string. If two successive tokenizers |
11240 | // are encountered, then a NULL entry is added | 11488 | // are encountered, then a null-string entry is |
11241 | // to the list. | 11489 | // added to the list. |
11242 | // | 11490 | // |
11243 | // It is a precondition that the source and | 11491 | // It is a precondition that the source and |
11244 | // toekizer lisst are non-null. If they are null, | 11492 | // toekizer lisst are non-null. If they are null, |
@@ -11246,7 +11494,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11246 | // while their lengths are being determined. | 11494 | // while their lengths are being determined. |
11247 | // | 11495 | // |
11248 | // A small amount of working memoryis required | 11496 | // A small amount of working memoryis required |
11249 | // of approximately 8*#tokenizers. | 11497 | // of approximately 8*#tokenizers + 8*srcstrlen. |
11250 | // | 11498 | // |
11251 | // There are many ways in which this function | 11499 | // There are many ways in which this function |
11252 | // can be implemented, this implementation is | 11500 | // can be implemented, this implementation is |
@@ -11262,161 +11510,126 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11262 | // and eliminates redundant tokenizers as soon | 11510 | // and eliminates redundant tokenizers as soon |
11263 | // as is possible. | 11511 | // as is possible. |
11264 | // | 11512 | // |
11265 | // The implementation tries to avoid any copying | 11513 | // The implementation tries to minimize temporary |
11266 | // of arrays or other objects. | 11514 | // garbage generation. |
11267 | // </remarks> | 11515 | // </remarks> |
11268 | 11516 | ||
11269 | private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) | 11517 | public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers) |
11270 | { | 11518 | { |
11271 | int beginning = 0; | 11519 | return ParseString2List(src, separators, spacers, true); |
11272 | int srclen = src.Length; | 11520 | } |
11273 | int seplen = separators.Length; | ||
11274 | object[] separray = separators.Data; | ||
11275 | int spclen = spacers.Length; | ||
11276 | object[] spcarray = spacers.Data; | ||
11277 | int mlen = seplen+spclen; | ||
11278 | |||
11279 | int[] offset = new int[mlen+1]; | ||
11280 | bool[] active = new bool[mlen]; | ||
11281 | |||
11282 | int best; | ||
11283 | int j; | ||
11284 | |||
11285 | // Initial capacity reduces resize cost | ||
11286 | |||
11287 | LSL_List tokens = new LSL_List(); | ||
11288 | 11521 | ||
11289 | // All entries are initially valid | 11522 | private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls) |
11523 | { | ||
11524 | int srclen = src.Length; | ||
11525 | int seplen = separators.Length; | ||
11526 | object[] separray = separators.Data; | ||
11527 | int spclen = spacers.Length; | ||
11528 | object[] spcarray = spacers.Data; | ||
11529 | int dellen = 0; | ||
11530 | string[] delarray = new string[seplen+spclen]; | ||
11290 | 11531 | ||
11291 | for (int i = 0; i < mlen; i++) | 11532 | int outlen = 0; |
11292 | active[i] = true; | 11533 | string[] outarray = new string[srclen*2+1]; |
11293 | 11534 | ||
11294 | offset[mlen] = srclen; | 11535 | int i, j; |
11536 | string d; | ||
11295 | 11537 | ||
11296 | while (beginning < srclen) | 11538 | /* |
11539 | * Convert separator and spacer lists to C# strings. | ||
11540 | * Also filter out null strings so we don't hang. | ||
11541 | */ | ||
11542 | for (i = 0; i < seplen; i ++) | ||
11297 | { | 11543 | { |
11544 | d = separray[i].ToString(); | ||
11545 | if (d.Length > 0) | ||
11546 | { | ||
11547 | delarray[dellen++] = d; | ||
11548 | } | ||
11549 | } | ||
11550 | seplen = dellen; | ||
11298 | 11551 | ||
11299 | best = mlen; // as bad as it gets | 11552 | for (i = 0; i < spclen; i ++) |
11553 | { | ||
11554 | d = spcarray[i].ToString(); | ||
11555 | if (d.Length > 0) | ||
11556 | { | ||
11557 | delarray[dellen++] = d; | ||
11558 | } | ||
11559 | } | ||
11300 | 11560 | ||
11301 | // Scan for separators | 11561 | /* |
11562 | * Scan through source string from beginning to end. | ||
11563 | */ | ||
11564 | for (i = 0;;) | ||
11565 | { | ||
11302 | 11566 | ||
11303 | for (j = 0; j < seplen; j++) | 11567 | /* |
11568 | * Find earliest delimeter in src starting at i (if any). | ||
11569 | */ | ||
11570 | int earliestDel = -1; | ||
11571 | int earliestSrc = srclen; | ||
11572 | string earliestStr = null; | ||
11573 | for (j = 0; j < dellen; j ++) | ||
11304 | { | 11574 | { |
11305 | if (separray[j].ToString() == String.Empty) | 11575 | d = delarray[j]; |
11306 | active[j] = false; | 11576 | if (d != null) |
11307 | |||
11308 | if (active[j]) | ||
11309 | { | 11577 | { |
11310 | // scan all of the markers | 11578 | int index = src.IndexOf(d, i); |
11311 | if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) | 11579 | if (index < 0) |
11312 | { | 11580 | { |
11313 | // not present at all | 11581 | delarray[j] = null; // delim nowhere in src, don't check it anymore |
11314 | active[j] = false; | ||
11315 | } | 11582 | } |
11316 | else | 11583 | else if (index < earliestSrc) |
11317 | { | 11584 | { |
11318 | // present and correct | 11585 | earliestSrc = index; // where delimeter starts in source string |
11319 | if (offset[j] < offset[best]) | 11586 | earliestDel = j; // where delimeter is in delarray[] |
11320 | { | 11587 | earliestStr = d; // the delimeter string from delarray[] |
11321 | // closest so far | 11588 | if (index == i) break; // can't do any better than found at beg of string |
11322 | best = j; | ||
11323 | if (offset[best] == beginning) | ||
11324 | break; | ||
11325 | } | ||
11326 | } | 11589 | } |
11327 | } | 11590 | } |
11328 | } | 11591 | } |
11329 | 11592 | ||
11330 | // Scan for spacers | 11593 | /* |
11331 | 11594 | * Output source string starting at i through start of earliest delimeter. | |
11332 | if (offset[best] != beginning) | 11595 | */ |
11596 | if (keepNulls || (earliestSrc > i)) | ||
11333 | { | 11597 | { |
11334 | for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) | 11598 | outarray[outlen++] = src.Substring(i, earliestSrc - i); |
11335 | { | ||
11336 | if (spcarray[j-seplen].ToString() == String.Empty) | ||
11337 | active[j] = false; | ||
11338 | |||
11339 | if (active[j]) | ||
11340 | { | ||
11341 | // scan all of the markers | ||
11342 | if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1) | ||
11343 | { | ||
11344 | // not present at all | ||
11345 | active[j] = false; | ||
11346 | } | ||
11347 | else | ||
11348 | { | ||
11349 | // present and correct | ||
11350 | if (offset[j] < offset[best]) | ||
11351 | { | ||
11352 | // closest so far | ||
11353 | best = j; | ||
11354 | } | ||
11355 | } | ||
11356 | } | ||
11357 | } | ||
11358 | } | 11599 | } |
11359 | 11600 | ||
11360 | // This is the normal exit from the scanning loop | 11601 | /* |
11602 | * If no delimeter found at or after i, we're done scanning. | ||
11603 | */ | ||
11604 | if (earliestDel < 0) break; | ||
11361 | 11605 | ||
11362 | if (best == mlen) | 11606 | /* |
11607 | * If delimeter was a spacer, output the spacer. | ||
11608 | */ | ||
11609 | if (earliestDel >= seplen) | ||
11363 | { | 11610 | { |
11364 | // no markers were found on this pass | 11611 | outarray[outlen++] = earliestStr; |
11365 | // so we're pretty much done | ||
11366 | if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0)) | ||
11367 | tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning))); | ||
11368 | break; | ||
11369 | } | 11612 | } |
11370 | 11613 | ||
11371 | // Otherwise we just add the newly delimited token | 11614 | /* |
11372 | // and recalculate where the search should continue. | 11615 | * Look at rest of src string following delimeter. |
11373 | if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) | 11616 | */ |
11374 | tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); | 11617 | i = earliestSrc + earliestStr.Length; |
11375 | |||
11376 | if (best < seplen) | ||
11377 | { | ||
11378 | beginning = offset[best] + (separray[best].ToString()).Length; | ||
11379 | } | ||
11380 | else | ||
11381 | { | ||
11382 | beginning = offset[best] + (spcarray[best - seplen].ToString()).Length; | ||
11383 | string str = spcarray[best - seplen].ToString(); | ||
11384 | if ((keepNulls) || ((!keepNulls) && (str.Length > 0))) | ||
11385 | tokens.Add(new LSL_String(str)); | ||
11386 | } | ||
11387 | } | 11618 | } |
11388 | 11619 | ||
11389 | // This an awkward an not very intuitive boundary case. If the | 11620 | /* |
11390 | // last substring is a tokenizer, then there is an implied trailing | 11621 | * Make up an exact-sized output array suitable for an LSL_List object. |
11391 | // null list entry. Hopefully the single comparison will not be too | 11622 | */ |
11392 | // arduous. Alternatively the 'break' could be replced with a return | 11623 | object[] outlist = new object[outlen]; |
11393 | // but that's shabby programming. | 11624 | for (i = 0; i < outlen; i ++) |
11394 | |||
11395 | if ((beginning == srclen) && (keepNulls)) | ||
11396 | { | 11625 | { |
11397 | if (srclen != 0) | 11626 | outlist[i] = new LSL_String(outarray[i]); |
11398 | tokens.Add(new LSL_String("")); | ||
11399 | } | 11627 | } |
11400 | 11628 | return new LSL_List(outlist); | |
11401 | return tokens; | ||
11402 | } | ||
11403 | |||
11404 | public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers) | ||
11405 | { | ||
11406 | m_host.AddScriptLPS(1); | ||
11407 | return this.ParseString(src, separators, spacers, false); | ||
11408 | } | ||
11409 | |||
11410 | public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers) | ||
11411 | { | ||
11412 | m_host.AddScriptLPS(1); | ||
11413 | return this.ParseString(src, separators, spacers, true); | ||
11414 | } | 11629 | } |
11415 | 11630 | ||
11416 | public LSL_Integer llGetObjectPermMask(int mask) | 11631 | public LSL_Integer llGetObjectPermMask(int mask) |
11417 | { | 11632 | { |
11418 | m_host.AddScriptLPS(1); | ||
11419 | |||
11420 | int permmask = 0; | 11633 | int permmask = 0; |
11421 | 11634 | ||
11422 | if (mask == ScriptBaseClass.MASK_BASE)//0 | 11635 | if (mask == ScriptBaseClass.MASK_BASE)//0 |
@@ -11449,11 +11662,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11449 | 11662 | ||
11450 | public void llSetObjectPermMask(int mask, int value) | 11663 | public void llSetObjectPermMask(int mask, int value) |
11451 | { | 11664 | { |
11452 | m_host.AddScriptLPS(1); | ||
11453 | |||
11454 | if (m_ScriptEngine.Config.GetBoolean("AllowGodFunctions", false)) | 11665 | if (m_ScriptEngine.Config.GetBoolean("AllowGodFunctions", false)) |
11455 | { | 11666 | { |
11456 | if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID)) | 11667 | if (World.Permissions.IsAdministrator(m_host.OwnerID)) |
11457 | { | 11668 | { |
11458 | if (mask == ScriptBaseClass.MASK_BASE)//0 | 11669 | if (mask == ScriptBaseClass.MASK_BASE)//0 |
11459 | { | 11670 | { |
@@ -11485,8 +11696,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11485 | 11696 | ||
11486 | public LSL_Integer llGetInventoryPermMask(string itemName, int mask) | 11697 | public LSL_Integer llGetInventoryPermMask(string itemName, int mask) |
11487 | { | 11698 | { |
11488 | m_host.AddScriptLPS(1); | ||
11489 | |||
11490 | TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName); | 11699 | TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName); |
11491 | 11700 | ||
11492 | if (item == null) | 11701 | if (item == null) |
@@ -11511,11 +11720,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11511 | 11720 | ||
11512 | public void llSetInventoryPermMask(string itemName, int mask, int value) | 11721 | public void llSetInventoryPermMask(string itemName, int mask, int value) |
11513 | { | 11722 | { |
11514 | m_host.AddScriptLPS(1); | ||
11515 | |||
11516 | if (m_ScriptEngine.Config.GetBoolean("AllowGodFunctions", false)) | 11723 | if (m_ScriptEngine.Config.GetBoolean("AllowGodFunctions", false)) |
11517 | { | 11724 | { |
11518 | if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID)) | 11725 | if (World.Permissions.IsAdministrator(m_host.OwnerID)) |
11519 | { | 11726 | { |
11520 | TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName); | 11727 | TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName); |
11521 | 11728 | ||
@@ -11546,8 +11753,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11546 | 11753 | ||
11547 | public LSL_String llGetInventoryCreator(string itemName) | 11754 | public LSL_String llGetInventoryCreator(string itemName) |
11548 | { | 11755 | { |
11549 | m_host.AddScriptLPS(1); | ||
11550 | |||
11551 | TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName); | 11756 | TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName); |
11552 | 11757 | ||
11553 | if (item == null) | 11758 | if (item == null) |
@@ -11562,8 +11767,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11562 | 11767 | ||
11563 | public void llOwnerSay(string msg) | 11768 | public void llOwnerSay(string msg) |
11564 | { | 11769 | { |
11565 | m_host.AddScriptLPS(1); | ||
11566 | |||
11567 | World.SimChatBroadcast(Utils.StringToBytes(msg), ChatTypeEnum.Owner, 0, | 11770 | World.SimChatBroadcast(Utils.StringToBytes(msg), ChatTypeEnum.Owner, 0, |
11568 | m_host.AbsolutePosition, m_host.Name, m_host.UUID, false); | 11771 | m_host.AbsolutePosition, m_host.Name, m_host.UUID, false); |
11569 | // IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); | 11772 | // IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); |
@@ -11572,9 +11775,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11572 | 11775 | ||
11573 | public LSL_String llRequestSecureURL() | 11776 | public LSL_String llRequestSecureURL() |
11574 | { | 11777 | { |
11575 | m_host.AddScriptLPS(1); | ||
11576 | if (m_UrlModule != null) | 11778 | if (m_UrlModule != null) |
11577 | return m_UrlModule.RequestSecureURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID).ToString(); | 11779 | return m_UrlModule.RequestSecureURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID, null).ToString(); |
11578 | return UUID.Zero.ToString(); | 11780 | return UUID.Zero.ToString(); |
11579 | } | 11781 | } |
11580 | 11782 | ||
@@ -11584,8 +11786,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11584 | 11786 | ||
11585 | try | 11787 | try |
11586 | { | 11788 | { |
11587 | m_host.AddScriptLPS(1); | ||
11588 | |||
11589 | string reply = String.Empty; | 11789 | string reply = String.Empty; |
11590 | 11790 | ||
11591 | GridRegion info; | 11791 | GridRegion info; |
@@ -11660,11 +11860,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11660 | break; | 11860 | break; |
11661 | case ScriptBaseClass.DATA_SIM_RELEASE: | 11861 | case ScriptBaseClass.DATA_SIM_RELEASE: |
11662 | if (ossl != null) | 11862 | if (ossl != null) |
11663 | { | 11863 | ossl.CheckThreatLevel(ThreatLevel.High, "llRequestSimulatorData"); |
11664 | //// TODO - double check this. | ||
11665 | if (!ossl.CheckThreatLevel(ThreatLevel.High, "llRequestSimulatorData")) | ||
11666 | return UUID.Zero.ToString(); // Raise no event | ||
11667 | } | ||
11668 | reply = "OpenSim"; | 11864 | reply = "OpenSim"; |
11669 | break; | 11865 | break; |
11670 | default: | 11866 | default: |
@@ -11689,50 +11885,47 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11689 | 11885 | ||
11690 | public LSL_String llRequestURL() | 11886 | public LSL_String llRequestURL() |
11691 | { | 11887 | { |
11692 | m_host.AddScriptLPS(1); | ||
11693 | |||
11694 | if (m_UrlModule != null) | 11888 | if (m_UrlModule != null) |
11695 | return m_UrlModule.RequestURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID).ToString(); | 11889 | return m_UrlModule.RequestURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID, null).ToString(); |
11696 | return UUID.Zero.ToString(); | 11890 | return UUID.Zero.ToString(); |
11697 | } | 11891 | } |
11698 | 11892 | ||
11699 | public void llForceMouselook(int mouselook) | 11893 | public void llForceMouselook(int mouselook) |
11700 | { | 11894 | { |
11701 | m_host.AddScriptLPS(1); | ||
11702 | m_host.SetForceMouselook(mouselook != 0); | 11895 | m_host.SetForceMouselook(mouselook != 0); |
11703 | } | 11896 | } |
11704 | 11897 | ||
11705 | public LSL_Float llGetObjectMass(string id) | 11898 | public LSL_Float llGetObjectMass(string id) |
11706 | { | 11899 | { |
11707 | m_host.AddScriptLPS(1); | ||
11708 | UUID key = new UUID(); | 11900 | UUID key = new UUID(); |
11709 | if (UUID.TryParse(id, out key)) | 11901 | if (UUID.TryParse(id, out key)) |
11710 | { | 11902 | { |
11711 | try | 11903 | // return total object mass |
11712 | { | 11904 | SceneObjectPart part = World.GetSceneObjectPart(key); |
11713 | SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); | 11905 | if (part != null) |
11714 | if (obj != null) | 11906 | return part.ParentGroup.GetMass(); |
11715 | return (double)obj.GetMass(); | 11907 | |
11716 | // the object is null so the key is for an avatar | 11908 | // the object is null so the key is for an avatar |
11717 | ScenePresence avatar = World.GetScenePresence(key); | 11909 | ScenePresence avatar = World.GetScenePresence(key); |
11718 | if (avatar != null) | 11910 | if (avatar != null) |
11719 | if (avatar.IsChildAgent) | ||
11720 | // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass | ||
11721 | // child agents have a mass of 1.0 | ||
11722 | return 1; | ||
11723 | else | ||
11724 | return (double)avatar.GetMass(); | ||
11725 | } | ||
11726 | catch (KeyNotFoundException) | ||
11727 | { | 11911 | { |
11728 | return 0; // The Object/Agent not in the region so just return zero | 11912 | if (avatar.IsChildAgent) |
11913 | { | ||
11914 | // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass | ||
11915 | // child agents have a mass of 1.0 | ||
11916 | return 1; | ||
11917 | } | ||
11918 | else | ||
11919 | { | ||
11920 | return (double)avatar.GetMass(); | ||
11921 | } | ||
11729 | } | 11922 | } |
11730 | } | 11923 | } |
11731 | return 0; | 11924 | return 0; |
11732 | } | 11925 | } |
11733 | 11926 | ||
11734 | /// <summary> | 11927 | /// <summary> |
11735 | /// illListReplaceList removes the sub-list defined by the inclusive indices | 11928 | /// llListReplaceList removes the sub-list defined by the inclusive indices |
11736 | /// start and end and inserts the src list in its place. The inclusive | 11929 | /// start and end and inserts the src list in its place. The inclusive |
11737 | /// nature of the indices means that at least one element must be deleted | 11930 | /// nature of the indices means that at least one element must be deleted |
11738 | /// if the indices are within the bounds of the existing list. I.e. 2,2 | 11931 | /// if the indices are within the bounds of the existing list. I.e. 2,2 |
@@ -11747,8 +11940,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11747 | { | 11940 | { |
11748 | LSL_List pref; | 11941 | LSL_List pref; |
11749 | 11942 | ||
11750 | m_host.AddScriptLPS(1); | ||
11751 | |||
11752 | // Note that although we have normalized, both | 11943 | // Note that although we have normalized, both |
11753 | // indices could still be negative. | 11944 | // indices could still be negative. |
11754 | if (start < 0) | 11945 | if (start < 0) |
@@ -11789,16 +11980,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11789 | // based upon end. Note that if end exceeds the upper | 11980 | // based upon end. Note that if end exceeds the upper |
11790 | // bound in this case, the entire destination list | 11981 | // bound in this case, the entire destination list |
11791 | // is removed. | 11982 | // is removed. |
11792 | else | 11983 | else if (start == 0) |
11793 | { | 11984 | { |
11794 | if (end + 1 < dest.Length) | 11985 | if (end + 1 < dest.Length) |
11795 | { | ||
11796 | return src + dest.GetSublist(end + 1, -1); | 11986 | return src + dest.GetSublist(end + 1, -1); |
11797 | } | ||
11798 | else | 11987 | else |
11799 | { | ||
11800 | return src; | 11988 | return src; |
11801 | } | 11989 | } |
11990 | else // Start < 0 | ||
11991 | { | ||
11992 | if (end + 1 < dest.Length) | ||
11993 | return dest.GetSublist(end + 1, -1); | ||
11994 | else | ||
11995 | return new LSL_List(); | ||
11802 | } | 11996 | } |
11803 | } | 11997 | } |
11804 | // Finally, if start > end, we strip away a prefix and | 11998 | // Finally, if start > end, we strip away a prefix and |
@@ -11815,8 +12009,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11815 | 12009 | ||
11816 | public void llLoadURL(string avatar_id, string message, string url) | 12010 | public void llLoadURL(string avatar_id, string message, string url) |
11817 | { | 12011 | { |
11818 | m_host.AddScriptLPS(1); | ||
11819 | |||
11820 | IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); | 12012 | IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); |
11821 | if (null != dm) | 12013 | if (null != dm) |
11822 | dm.SendUrlToUser( | 12014 | dm.SendUrlToUser( |
@@ -11828,12 +12020,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
11828 | // TODO: Not implemented yet (missing in libomv?): | 12020 | // TODO: Not implemented yet (missing in libomv?): |
11829 | // PARCEL_MEDIA_COMMAND_LOOP_SET float loop Use this to get or set the parcel's media loop duration. (1.19.1 RC0 or later) | 12021 | // PARCEL_MEDIA_COMMAND_LOOP_SET float loop Use this to get or set the parcel's media loop duration. (1.19.1 RC0 or later) |
11830 | 12022 | ||
11831 | m_host.AddScriptLPS(1); | ||
11832 | |||
11833 | // according to the docs, this command only works if script owner and land owner are the same | 12023 | // according to the docs, this command only works if script owner and land owner are the same |
11834 | // lets add estate owners and gods, too, and use the generic permission check. | 12024 | // lets add estate owners and gods, too, and use the generic permission check. |
11835 | ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition); | 12025 | ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition); |
11836 | if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return; | 12026 | if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia, false)) return; |
11837 | 12027 | ||
11838 | bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? | 12028 | bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? |
11839 | byte loop = 0; | 12029 | byte loop = 0; |
@@ -12051,23 +12241,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12051 | if (sp.currentParcelUUID == landData.GlobalID) | 12241 | if (sp.currentParcelUUID == landData.GlobalID) |
12052 | { | 12242 | { |
12053 | sp.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this? | 12243 | sp.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this? |
12054 | (ParcelMediaCommandEnum)commandToSend, | 12244 | (ParcelMediaCommandEnum)commandToSend, time); |
12055 | time); | ||
12056 | } | 12245 | } |
12057 | }); | 12246 | }); |
12058 | } | 12247 | } |
12059 | else if (!presence.IsChildAgent) | 12248 | else if (!presence.IsChildAgent) |
12060 | { | 12249 | { |
12061 | presence.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this? | 12250 | presence.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this? |
12062 | (ParcelMediaCommandEnum)commandToSend, | 12251 | (ParcelMediaCommandEnum)commandToSend, time); |
12063 | time); | ||
12064 | } | 12252 | } |
12065 | } | 12253 | } |
12066 | } | 12254 | } |
12067 | 12255 | ||
12068 | public LSL_List llParcelMediaQuery(LSL_List aList) | 12256 | public LSL_List llParcelMediaQuery(LSL_List aList) |
12069 | { | 12257 | { |
12070 | m_host.AddScriptLPS(1); | ||
12071 | LSL_List list = new LSL_List(); | 12258 | LSL_List list = new LSL_List(); |
12072 | //TO DO: make the implementation for the missing commands | 12259 | //TO DO: make the implementation for the missing commands |
12073 | //PARCEL_MEDIA_COMMAND_LOOP_SET float loop Use this to get or set the parcel's media loop duration. (1.19.1 RC0 or later) | 12260 | //PARCEL_MEDIA_COMMAND_LOOP_SET float loop Use this to get or set the parcel's media loop duration. (1.19.1 RC0 or later) |
@@ -12076,7 +12263,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12076 | 12263 | ||
12077 | if (aList.Data[i] != null) | 12264 | if (aList.Data[i] != null) |
12078 | { | 12265 | { |
12079 | switch ((ParcelMediaCommandEnum) aList.Data[i]) | 12266 | switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString())) |
12080 | { | 12267 | { |
12081 | case ParcelMediaCommandEnum.Url: | 12268 | case ParcelMediaCommandEnum.Url: |
12082 | list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); | 12269 | list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); |
@@ -12107,7 +12294,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12107 | 12294 | ||
12108 | public LSL_Integer llModPow(int a, int b, int c) | 12295 | public LSL_Integer llModPow(int a, int b, int c) |
12109 | { | 12296 | { |
12110 | m_host.AddScriptLPS(1); | ||
12111 | Int64 tmp = 0; | 12297 | Int64 tmp = 0; |
12112 | Math.DivRem(Convert.ToInt64(Math.Pow(a, b)), c, out tmp); | 12298 | Math.DivRem(Convert.ToInt64(Math.Pow(a, b)), c, out tmp); |
12113 | return Convert.ToInt32(tmp); | 12299 | return Convert.ToInt32(tmp); |
@@ -12115,8 +12301,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12115 | 12301 | ||
12116 | public LSL_Integer llGetInventoryType(string name) | 12302 | public LSL_Integer llGetInventoryType(string name) |
12117 | { | 12303 | { |
12118 | m_host.AddScriptLPS(1); | ||
12119 | |||
12120 | TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); | 12304 | TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); |
12121 | 12305 | ||
12122 | if (item == null) | 12306 | if (item == null) |
@@ -12127,26 +12311,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12127 | 12311 | ||
12128 | public void llSetPayPrice(int price, LSL_List quick_pay_buttons) | 12312 | public void llSetPayPrice(int price, LSL_List quick_pay_buttons) |
12129 | { | 12313 | { |
12130 | m_host.AddScriptLPS(1); | ||
12131 | |||
12132 | if (quick_pay_buttons.Data.Length < 4) | 12314 | if (quick_pay_buttons.Data.Length < 4) |
12133 | { | 12315 | { |
12134 | Error("llSetPayPrice", "List must have at least 4 elements"); | 12316 | int x; |
12135 | return; | 12317 | for (x=quick_pay_buttons.Data.Length; x<= 4; x++) |
12318 | { | ||
12319 | quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE); | ||
12320 | } | ||
12136 | } | 12321 | } |
12137 | m_host.ParentGroup.RootPart.PayPrice[0]=price; | 12322 | int[] nPrice = new int[5]; |
12138 | 12323 | nPrice[0] = price; | |
12139 | m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; | 12324 | nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0); |
12140 | m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; | 12325 | nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1); |
12141 | m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; | 12326 | nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2); |
12142 | m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; | 12327 | nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3); |
12328 | m_host.ParentGroup.RootPart.PayPrice = nPrice; | ||
12143 | m_host.ParentGroup.HasGroupChanged = true; | 12329 | m_host.ParentGroup.HasGroupChanged = true; |
12144 | } | 12330 | } |
12145 | 12331 | ||
12146 | public LSL_Vector llGetCameraPos() | 12332 | public LSL_Vector llGetCameraPos() |
12147 | { | 12333 | { |
12148 | m_host.AddScriptLPS(1); | ||
12149 | |||
12150 | if (m_item.PermsGranter == UUID.Zero) | 12334 | if (m_item.PermsGranter == UUID.Zero) |
12151 | return Vector3.Zero; | 12335 | return Vector3.Zero; |
12152 | 12336 | ||
@@ -12156,7 +12340,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12156 | return Vector3.Zero; | 12340 | return Vector3.Zero; |
12157 | } | 12341 | } |
12158 | 12342 | ||
12159 | ScenePresence presence = World.GetScenePresence(m_host.OwnerID); | 12343 | // ScenePresence presence = World.GetScenePresence(m_host.OwnerID); |
12344 | ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); | ||
12160 | if (presence != null) | 12345 | if (presence != null) |
12161 | { | 12346 | { |
12162 | LSL_Vector pos = new LSL_Vector(presence.CameraPosition); | 12347 | LSL_Vector pos = new LSL_Vector(presence.CameraPosition); |
@@ -12168,8 +12353,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12168 | 12353 | ||
12169 | public LSL_Rotation llGetCameraRot() | 12354 | public LSL_Rotation llGetCameraRot() |
12170 | { | 12355 | { |
12171 | m_host.AddScriptLPS(1); | ||
12172 | |||
12173 | if (m_item.PermsGranter == UUID.Zero) | 12356 | if (m_item.PermsGranter == UUID.Zero) |
12174 | return Quaternion.Identity; | 12357 | return Quaternion.Identity; |
12175 | 12358 | ||
@@ -12179,7 +12362,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12179 | return Quaternion.Identity; | 12362 | return Quaternion.Identity; |
12180 | } | 12363 | } |
12181 | 12364 | ||
12182 | ScenePresence presence = World.GetScenePresence(m_host.OwnerID); | 12365 | // ScenePresence presence = World.GetScenePresence(m_host.OwnerID); |
12366 | ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); | ||
12183 | if (presence != null) | 12367 | if (presence != null) |
12184 | { | 12368 | { |
12185 | return new LSL_Rotation(presence.CameraRotation); | 12369 | return new LSL_Rotation(presence.CameraRotation); |
@@ -12190,19 +12374,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12190 | 12374 | ||
12191 | public void llSetPrimURL(string url) | 12375 | public void llSetPrimURL(string url) |
12192 | { | 12376 | { |
12193 | m_host.AddScriptLPS(1); | ||
12194 | Deprecated("llSetPrimURL", "Use llSetPrimMediaParams instead"); | 12377 | Deprecated("llSetPrimURL", "Use llSetPrimMediaParams instead"); |
12195 | } | 12378 | } |
12196 | 12379 | ||
12197 | public void llRefreshPrimURL() | 12380 | public void llRefreshPrimURL() |
12198 | { | 12381 | { |
12199 | m_host.AddScriptLPS(1); | ||
12200 | Deprecated("llRefreshPrimURL"); | 12382 | Deprecated("llRefreshPrimURL"); |
12201 | } | 12383 | } |
12202 | 12384 | ||
12203 | public LSL_String llEscapeURL(string url) | 12385 | public LSL_String llEscapeURL(string url) |
12204 | { | 12386 | { |
12205 | m_host.AddScriptLPS(1); | ||
12206 | try | 12387 | try |
12207 | { | 12388 | { |
12208 | return Uri.EscapeDataString(url); | 12389 | return Uri.EscapeDataString(url); |
@@ -12215,7 +12396,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12215 | 12396 | ||
12216 | public LSL_String llUnescapeURL(string url) | 12397 | public LSL_String llUnescapeURL(string url) |
12217 | { | 12398 | { |
12218 | m_host.AddScriptLPS(1); | ||
12219 | try | 12399 | try |
12220 | { | 12400 | { |
12221 | return Uri.UnescapeDataString(url); | 12401 | return Uri.UnescapeDataString(url); |
@@ -12228,9 +12408,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12228 | 12408 | ||
12229 | public void llMapDestination(string simname, LSL_Vector pos, LSL_Vector lookAt) | 12409 | public void llMapDestination(string simname, LSL_Vector pos, LSL_Vector lookAt) |
12230 | { | 12410 | { |
12231 | m_host.AddScriptLPS(1); | ||
12232 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); | 12411 | DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); |
12233 | if (detectedParams == null) return; // only works on the first detected avatar | 12412 | if (detectedParams == null) |
12413 | { | ||
12414 | if (m_host.ParentGroup.IsAttachment == true) | ||
12415 | { | ||
12416 | detectedParams = new DetectParams(); | ||
12417 | detectedParams.Key = m_host.OwnerID; | ||
12418 | } | ||
12419 | else | ||
12420 | { | ||
12421 | return; | ||
12422 | } | ||
12423 | } | ||
12234 | 12424 | ||
12235 | ScenePresence avatar = World.GetScenePresence(detectedParams.Key); | 12425 | ScenePresence avatar = World.GetScenePresence(detectedParams.Key); |
12236 | if (avatar != null) | 12426 | if (avatar != null) |
@@ -12242,10 +12432,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12242 | 12432 | ||
12243 | public void llAddToLandBanList(string avatar, double hours) | 12433 | public void llAddToLandBanList(string avatar, double hours) |
12244 | { | 12434 | { |
12245 | m_host.AddScriptLPS(1); | ||
12246 | UUID key; | 12435 | UUID key; |
12247 | ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); | 12436 | ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); |
12248 | if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) | 12437 | if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned, false)) |
12249 | { | 12438 | { |
12250 | int expires = 0; | 12439 | int expires = 0; |
12251 | if (hours != 0) | 12440 | if (hours != 0) |
@@ -12282,10 +12471,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12282 | 12471 | ||
12283 | public void llRemoveFromLandPassList(string avatar) | 12472 | public void llRemoveFromLandPassList(string avatar) |
12284 | { | 12473 | { |
12285 | m_host.AddScriptLPS(1); | ||
12286 | UUID key; | 12474 | UUID key; |
12287 | ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); | 12475 | ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); |
12288 | if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed)) | 12476 | if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManagePasses, false)) |
12289 | { | 12477 | { |
12290 | if (UUID.TryParse(avatar, out key)) | 12478 | if (UUID.TryParse(avatar, out key)) |
12291 | { | 12479 | { |
@@ -12308,10 +12496,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12308 | 12496 | ||
12309 | public void llRemoveFromLandBanList(string avatar) | 12497 | public void llRemoveFromLandBanList(string avatar) |
12310 | { | 12498 | { |
12311 | m_host.AddScriptLPS(1); | ||
12312 | UUID key; | 12499 | UUID key; |
12313 | ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); | 12500 | ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); |
12314 | if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) | 12501 | if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned, false)) |
12315 | { | 12502 | { |
12316 | if (UUID.TryParse(avatar, out key)) | 12503 | if (UUID.TryParse(avatar, out key)) |
12317 | { | 12504 | { |
@@ -12334,8 +12521,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12334 | 12521 | ||
12335 | public void llSetCameraParams(LSL_List rules) | 12522 | public void llSetCameraParams(LSL_List rules) |
12336 | { | 12523 | { |
12337 | m_host.AddScriptLPS(1); | ||
12338 | |||
12339 | // the object we are in | 12524 | // the object we are in |
12340 | UUID objectID = m_host.ParentUUID; | 12525 | UUID objectID = m_host.ParentUUID; |
12341 | if (objectID == UUID.Zero) | 12526 | if (objectID == UUID.Zero) |
@@ -12461,8 +12646,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12461 | 12646 | ||
12462 | public void llClearCameraParams() | 12647 | public void llClearCameraParams() |
12463 | { | 12648 | { |
12464 | m_host.AddScriptLPS(1); | ||
12465 | |||
12466 | // the object we are in | 12649 | // the object we are in |
12467 | UUID objectID = m_host.ParentUUID; | 12650 | UUID objectID = m_host.ParentUUID; |
12468 | if (objectID == UUID.Zero) | 12651 | if (objectID == UUID.Zero) |
@@ -12488,7 +12671,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12488 | 12671 | ||
12489 | public LSL_Float llListStatistics(int operation, LSL_List src) | 12672 | public LSL_Float llListStatistics(int operation, LSL_List src) |
12490 | { | 12673 | { |
12491 | m_host.AddScriptLPS(1); | ||
12492 | switch (operation) | 12674 | switch (operation) |
12493 | { | 12675 | { |
12494 | case ScriptBaseClass.LIST_STAT_RANGE: | 12676 | case ScriptBaseClass.LIST_STAT_RANGE: |
@@ -12520,19 +12702,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12520 | 12702 | ||
12521 | public LSL_Integer llGetUnixTime() | 12703 | public LSL_Integer llGetUnixTime() |
12522 | { | 12704 | { |
12523 | m_host.AddScriptLPS(1); | ||
12524 | return Util.UnixTimeSinceEpoch(); | 12705 | return Util.UnixTimeSinceEpoch(); |
12525 | } | 12706 | } |
12526 | 12707 | ||
12527 | public LSL_Integer llGetParcelFlags(LSL_Vector pos) | 12708 | public LSL_Integer llGetParcelFlags(LSL_Vector pos) |
12528 | { | 12709 | { |
12529 | m_host.AddScriptLPS(1); | ||
12530 | return (int)World.LandChannel.GetLandObject((float)pos.x, (float)pos.y).LandData.Flags; | 12710 | return (int)World.LandChannel.GetLandObject((float)pos.x, (float)pos.y).LandData.Flags; |
12531 | } | 12711 | } |
12532 | 12712 | ||
12533 | public LSL_Integer llGetRegionFlags() | 12713 | public LSL_Integer llGetRegionFlags() |
12534 | { | 12714 | { |
12535 | m_host.AddScriptLPS(1); | ||
12536 | IEstateModule estate = World.RequestModuleInterface<IEstateModule>(); | 12715 | IEstateModule estate = World.RequestModuleInterface<IEstateModule>(); |
12537 | if (estate == null) | 12716 | if (estate == null) |
12538 | return 67108864; | 12717 | return 67108864; |
@@ -12541,20 +12720,64 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12541 | 12720 | ||
12542 | public LSL_String llXorBase64StringsCorrect(string str1, string str2) | 12721 | public LSL_String llXorBase64StringsCorrect(string str1, string str2) |
12543 | { | 12722 | { |
12544 | m_host.AddScriptLPS(1); | 12723 | if (str1 == String.Empty) |
12545 | string ret = String.Empty; | 12724 | return String.Empty; |
12546 | string src1 = llBase64ToString(str1); | 12725 | if (str2 == String.Empty) |
12547 | string src2 = llBase64ToString(str2); | 12726 | return str1; |
12548 | int c = 0; | 12727 | |
12549 | for (int i = 0; i < src1.Length; i++) | 12728 | int len = str2.Length; |
12729 | if ((len % 4) != 0) // LL is EVIL!!!! | ||
12550 | { | 12730 | { |
12551 | ret += (char) (src1[i] ^ src2[c]); | 12731 | while (str2.EndsWith("=")) |
12732 | str2 = str2.Substring(0, str2.Length - 1); | ||
12733 | |||
12734 | len = str2.Length; | ||
12735 | int mod = len % 4; | ||
12736 | |||
12737 | if (mod == 1) | ||
12738 | str2 = str2.Substring(0, str2.Length - 1); | ||
12739 | else if (mod == 2) | ||
12740 | str2 += "=="; | ||
12741 | else if (mod == 3) | ||
12742 | str2 += "="; | ||
12743 | } | ||
12552 | 12744 | ||
12553 | c++; | 12745 | byte[] data1; |
12554 | if (c >= src2.Length) | 12746 | byte[] data2; |
12555 | c = 0; | 12747 | try |
12748 | { | ||
12749 | data1 = Convert.FromBase64String(str1); | ||
12750 | data2 = Convert.FromBase64String(str2); | ||
12751 | } | ||
12752 | catch (Exception) | ||
12753 | { | ||
12754 | return new LSL_String(String.Empty); | ||
12556 | } | 12755 | } |
12557 | return llStringToBase64(ret); | 12756 | |
12757 | byte[] d2 = new Byte[data1.Length]; | ||
12758 | int pos = 0; | ||
12759 | |||
12760 | if (data1.Length <= data2.Length) | ||
12761 | { | ||
12762 | Array.Copy(data2, 0, d2, 0, data1.Length); | ||
12763 | } | ||
12764 | else | ||
12765 | { | ||
12766 | while (pos < data1.Length) | ||
12767 | { | ||
12768 | len = data1.Length - pos; | ||
12769 | if (len > data2.Length) | ||
12770 | len = data2.Length; | ||
12771 | |||
12772 | Array.Copy(data2, 0, d2, pos, len); | ||
12773 | pos += len; | ||
12774 | } | ||
12775 | } | ||
12776 | |||
12777 | for (pos = 0 ; pos < data1.Length ; pos++ ) | ||
12778 | data1[pos] ^= d2[pos]; | ||
12779 | |||
12780 | return Convert.ToBase64String(data1); | ||
12558 | } | 12781 | } |
12559 | 12782 | ||
12560 | public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) | 12783 | public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) |
@@ -12564,12 +12787,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12564 | // parameter flags support are implemented in ScriptsHttpRequests.cs | 12787 | // parameter flags support are implemented in ScriptsHttpRequests.cs |
12565 | // in StartHttpRequest | 12788 | // in StartHttpRequest |
12566 | 12789 | ||
12567 | m_host.AddScriptLPS(1); | ||
12568 | IHttpRequestModule httpScriptMod = | 12790 | IHttpRequestModule httpScriptMod = |
12569 | m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>(); | 12791 | m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>(); |
12570 | List<string> param = new List<string>(); | 12792 | List<string> param = new List<string>(); |
12571 | bool ok; | 12793 | bool ok; |
12572 | Int32 flag; | 12794 | Int32 flag; |
12795 | int nCustomHeaders = 0; | ||
12573 | 12796 | ||
12574 | for (int i = 0; i < parameters.Data.Length; i += 2) | 12797 | for (int i = 0; i < parameters.Data.Length; i += 2) |
12575 | { | 12798 | { |
@@ -12596,6 +12819,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12596 | //Second Life documentation for llHTTPRequest. | 12819 | //Second Life documentation for llHTTPRequest. |
12597 | for (int count = 1; count <= 8; ++count) | 12820 | for (int count = 1; count <= 8; ++count) |
12598 | { | 12821 | { |
12822 | if(nCustomHeaders >= 8) | ||
12823 | { | ||
12824 | Error("llHTTPRequest", "Max number of custom headers is 8, excess ignored"); | ||
12825 | break; | ||
12826 | } | ||
12827 | |||
12599 | //Enough parameters remaining for (another) header? | 12828 | //Enough parameters remaining for (another) header? |
12600 | if (parameters.Data.Length - i < 2) | 12829 | if (parameters.Data.Length - i < 2) |
12601 | { | 12830 | { |
@@ -12610,15 +12839,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12610 | 12839 | ||
12611 | param.Add(parameters.Data[i].ToString()); | 12840 | param.Add(parameters.Data[i].ToString()); |
12612 | param.Add(parameters.Data[i+1].ToString()); | 12841 | param.Add(parameters.Data[i+1].ToString()); |
12842 | nCustomHeaders++; | ||
12613 | 12843 | ||
12614 | //Have we reached the end of the list of headers? | 12844 | //Have we reached the end of the list of headers? |
12615 | //End is marked by a string with a single digit. | 12845 | //End is marked by a string with a single digit. |
12616 | if (i+2 >= parameters.Data.Length || | 12846 | if (i + 2 >= parameters.Data.Length || |
12617 | Char.IsDigit(parameters.Data[i].ToString()[0])) | 12847 | Char.IsDigit(parameters.Data[i + 2].ToString()[0])) |
12618 | { | 12848 | { |
12619 | break; | 12849 | break; |
12620 | } | 12850 | } |
12621 | |||
12622 | i += 2; | 12851 | i += 2; |
12623 | } | 12852 | } |
12624 | } | 12853 | } |
@@ -12658,16 +12887,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12658 | if (userAgent != null) | 12887 | if (userAgent != null) |
12659 | httpHeaders["User-Agent"] = userAgent; | 12888 | httpHeaders["User-Agent"] = userAgent; |
12660 | 12889 | ||
12890 | // See if the URL contains any header hacks | ||
12891 | string[] urlParts = url.Split(new char[] {'\n'}); | ||
12892 | if (urlParts.Length > 1) | ||
12893 | { | ||
12894 | // Iterate the passed headers and parse them | ||
12895 | for (int i = 1 ; i < urlParts.Length ; i++ ) | ||
12896 | { | ||
12897 | // The rest of those would be added to the body in SL. | ||
12898 | // Let's not do that. | ||
12899 | if (urlParts[i] == String.Empty) | ||
12900 | break; | ||
12901 | |||
12902 | // See if this could be a valid header | ||
12903 | string[] headerParts = urlParts[i].Split(new char[] {':'}, 2); | ||
12904 | if (headerParts.Length != 2) | ||
12905 | continue; | ||
12906 | |||
12907 | string headerName = headerParts[0].Trim(); | ||
12908 | string headerValue = headerParts[1].Trim(); | ||
12909 | |||
12910 | // Filter out headers that could be used to abuse | ||
12911 | // another system or cloak the request | ||
12912 | if (headerName.ToLower() == "x-secondlife-shard" || | ||
12913 | headerName.ToLower() == "x-secondlife-object-name" || | ||
12914 | headerName.ToLower() == "x-secondlife-object-key" || | ||
12915 | headerName.ToLower() == "x-secondlife-region" || | ||
12916 | headerName.ToLower() == "x-secondlife-local-position" || | ||
12917 | headerName.ToLower() == "x-secondlife-local-velocity" || | ||
12918 | headerName.ToLower() == "x-secondlife-local-rotation" || | ||
12919 | headerName.ToLower() == "x-secondlife-owner-name" || | ||
12920 | headerName.ToLower() == "x-secondlife-owner-key" || | ||
12921 | headerName.ToLower() == "connection" || | ||
12922 | headerName.ToLower() == "content-length" || | ||
12923 | headerName.ToLower() == "from" || | ||
12924 | headerName.ToLower() == "host" || | ||
12925 | headerName.ToLower() == "proxy-authorization" || | ||
12926 | headerName.ToLower() == "referer" || | ||
12927 | headerName.ToLower() == "trailer" || | ||
12928 | headerName.ToLower() == "transfer-encoding" || | ||
12929 | headerName.ToLower() == "via" || | ||
12930 | headerName.ToLower() == "authorization") | ||
12931 | continue; | ||
12932 | |||
12933 | httpHeaders[headerName] = headerValue; | ||
12934 | } | ||
12935 | |||
12936 | // Finally, strip any protocol specifier from the URL | ||
12937 | url = urlParts[0].Trim(); | ||
12938 | int idx = url.IndexOf(" HTTP/"); | ||
12939 | if (idx != -1) | ||
12940 | url = url.Substring(0, idx); | ||
12941 | } | ||
12942 | |||
12661 | string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; | 12943 | string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; |
12662 | Regex r = new Regex(authregex); | 12944 | Regex r = new Regex(authregex); |
12663 | int[] gnums = r.GetGroupNumbers(); | 12945 | int[] gnums = r.GetGroupNumbers(); |
12664 | Match m = r.Match(url); | 12946 | Match m = r.Match(url); |
12665 | if (m.Success) { | 12947 | if (m.Success) |
12666 | for (int i = 1; i < gnums.Length; i++) { | 12948 | { |
12949 | for (int i = 1; i < gnums.Length; i++) | ||
12950 | { | ||
12667 | //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; | 12951 | //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; |
12668 | //CaptureCollection cc = g.Captures; | 12952 | //CaptureCollection cc = g.Captures; |
12669 | } | 12953 | } |
12670 | if (m.Groups.Count == 5) { | 12954 | if (m.Groups.Count == 5) |
12955 | { | ||
12671 | httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); | 12956 | httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); |
12672 | url = m.Groups[1].ToString() + m.Groups[4].ToString(); | 12957 | url = m.Groups[1].ToString() + m.Groups[4].ToString(); |
12673 | } | 12958 | } |
@@ -12692,15 +12977,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12692 | // Partial implementation: support for parameter flags needed | 12977 | // Partial implementation: support for parameter flags needed |
12693 | // see http://wiki.secondlife.com/wiki/llHTTPResponse | 12978 | // see http://wiki.secondlife.com/wiki/llHTTPResponse |
12694 | 12979 | ||
12695 | m_host.AddScriptLPS(1); | ||
12696 | |||
12697 | if (m_UrlModule != null) | 12980 | if (m_UrlModule != null) |
12698 | m_UrlModule.HttpResponse(new UUID(id), status,body); | 12981 | m_UrlModule.HttpResponse(new UUID(id), status,body); |
12699 | } | 12982 | } |
12700 | 12983 | ||
12701 | public void llResetLandBanList() | 12984 | public void llResetLandBanList() |
12702 | { | 12985 | { |
12703 | m_host.AddScriptLPS(1); | ||
12704 | LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData; | 12986 | LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData; |
12705 | if (land.OwnerID == m_host.OwnerID) | 12987 | if (land.OwnerID == m_host.OwnerID) |
12706 | { | 12988 | { |
@@ -12716,7 +12998,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12716 | 12998 | ||
12717 | public void llResetLandPassList() | 12999 | public void llResetLandPassList() |
12718 | { | 13000 | { |
12719 | m_host.AddScriptLPS(1); | ||
12720 | LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData; | 13001 | LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData; |
12721 | if (land.OwnerID == m_host.OwnerID) | 13002 | if (land.OwnerID == m_host.OwnerID) |
12722 | { | 13003 | { |
@@ -12732,8 +13013,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12732 | 13013 | ||
12733 | public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide) | 13014 | public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide) |
12734 | { | 13015 | { |
12735 | m_host.AddScriptLPS(1); | ||
12736 | |||
12737 | ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); | 13016 | ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); |
12738 | 13017 | ||
12739 | if (lo == null) | 13018 | if (lo == null) |
@@ -12774,7 +13053,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12774 | 13053 | ||
12775 | public LSL_List llGetParcelPrimOwners(LSL_Vector pos) | 13054 | public LSL_List llGetParcelPrimOwners(LSL_Vector pos) |
12776 | { | 13055 | { |
12777 | m_host.AddScriptLPS(1); | ||
12778 | LandObject land = (LandObject)World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); | 13056 | LandObject land = (LandObject)World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); |
12779 | LSL_List ret = new LSL_List(); | 13057 | LSL_List ret = new LSL_List(); |
12780 | if (land != null) | 13058 | if (land != null) |
@@ -12790,7 +13068,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12790 | 13068 | ||
12791 | public LSL_Integer llGetObjectPrimCount(string object_id) | 13069 | public LSL_Integer llGetObjectPrimCount(string object_id) |
12792 | { | 13070 | { |
12793 | m_host.AddScriptLPS(1); | ||
12794 | SceneObjectPart part = World.GetSceneObjectPart(new UUID(object_id)); | 13071 | SceneObjectPart part = World.GetSceneObjectPart(new UUID(object_id)); |
12795 | if (part == null) | 13072 | if (part == null) |
12796 | { | 13073 | { |
@@ -12804,8 +13081,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12804 | 13081 | ||
12805 | public LSL_Integer llGetParcelMaxPrims(LSL_Vector pos, int sim_wide) | 13082 | public LSL_Integer llGetParcelMaxPrims(LSL_Vector pos, int sim_wide) |
12806 | { | 13083 | { |
12807 | m_host.AddScriptLPS(1); | ||
12808 | |||
12809 | ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); | 13084 | ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); |
12810 | 13085 | ||
12811 | if (lo == null) | 13086 | if (lo == null) |
@@ -12819,7 +13094,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12819 | 13094 | ||
12820 | public LSL_List llGetParcelDetails(LSL_Vector pos, LSL_List param) | 13095 | public LSL_List llGetParcelDetails(LSL_Vector pos, LSL_List param) |
12821 | { | 13096 | { |
12822 | m_host.AddScriptLPS(1); | ||
12823 | LandData land = World.GetLandData(pos); | 13097 | LandData land = World.GetLandData(pos); |
12824 | if (land == null) | 13098 | if (land == null) |
12825 | { | 13099 | { |
@@ -12858,7 +13132,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12858 | 13132 | ||
12859 | public LSL_String llStringTrim(string src, int type) | 13133 | public LSL_String llStringTrim(string src, int type) |
12860 | { | 13134 | { |
12861 | m_host.AddScriptLPS(1); | ||
12862 | if (type == (int)ScriptBaseClass.STRING_TRIM_HEAD) { return src.TrimStart(); } | 13135 | if (type == (int)ScriptBaseClass.STRING_TRIM_HEAD) { return src.TrimStart(); } |
12863 | if (type == (int)ScriptBaseClass.STRING_TRIM_TAIL) { return src.TrimEnd(); } | 13136 | if (type == (int)ScriptBaseClass.STRING_TRIM_TAIL) { return src.TrimEnd(); } |
12864 | if (type == (int)ScriptBaseClass.STRING_TRIM) { return src.Trim(); } | 13137 | if (type == (int)ScriptBaseClass.STRING_TRIM) { return src.Trim(); } |
@@ -12867,10 +13140,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12867 | 13140 | ||
12868 | public LSL_List llGetObjectDetails(string id, LSL_List args) | 13141 | public LSL_List llGetObjectDetails(string id, LSL_List args) |
12869 | { | 13142 | { |
12870 | m_host.AddScriptLPS(1); | ||
12871 | |||
12872 | LSL_List ret = new LSL_List(); | 13143 | LSL_List ret = new LSL_List(); |
12873 | UUID key = new UUID(); | 13144 | UUID key = new UUID(); |
13145 | |||
13146 | |||
12874 | if (UUID.TryParse(id, out key)) | 13147 | if (UUID.TryParse(id, out key)) |
12875 | { | 13148 | { |
12876 | ScenePresence av = World.GetScenePresence(key); | 13149 | ScenePresence av = World.GetScenePresence(key); |
@@ -12888,13 +13161,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12888 | ret.Add(new LSL_String("")); | 13161 | ret.Add(new LSL_String("")); |
12889 | break; | 13162 | break; |
12890 | case ScriptBaseClass.OBJECT_POS: | 13163 | case ScriptBaseClass.OBJECT_POS: |
12891 | ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); | 13164 | Vector3 avpos; |
13165 | |||
13166 | if (av.ParentID != 0 && av.ParentPart != null && | ||
13167 | av.ParentPart.ParentGroup != null && av.ParentPart.ParentGroup.RootPart != null ) | ||
13168 | { | ||
13169 | avpos = av.OffsetPosition; | ||
13170 | |||
13171 | if(!av.LegacySitOffsets) | ||
13172 | { | ||
13173 | Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f); | ||
13174 | avpos -= sitOffset; | ||
13175 | } | ||
13176 | |||
13177 | SceneObjectPart sitRoot = av.ParentPart.ParentGroup.RootPart; | ||
13178 | avpos = sitRoot.GetWorldPosition() + avpos * sitRoot.GetWorldRotation(); | ||
13179 | } | ||
13180 | else | ||
13181 | avpos = av.AbsolutePosition; | ||
13182 | |||
13183 | ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z)); | ||
12892 | break; | 13184 | break; |
12893 | case ScriptBaseClass.OBJECT_ROT: | 13185 | case ScriptBaseClass.OBJECT_ROT: |
12894 | ret.Add(new LSL_Rotation(av.GetWorldRotation())); | 13186 | Quaternion avrot = av.GetWorldRotation(); |
13187 | ret.Add(new LSL_Rotation(avrot)); | ||
12895 | break; | 13188 | break; |
12896 | case ScriptBaseClass.OBJECT_VELOCITY: | 13189 | case ScriptBaseClass.OBJECT_VELOCITY: |
12897 | ret.Add(new LSL_Vector(av.GetWorldVelocity())); | 13190 | Vector3 avvel = av.GetWorldVelocity(); |
13191 | ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z)); | ||
12898 | break; | 13192 | break; |
12899 | case ScriptBaseClass.OBJECT_OWNER: | 13193 | case ScriptBaseClass.OBJECT_OWNER: |
12900 | ret.Add(new LSL_String(id)); | 13194 | ret.Add(new LSL_String(id)); |
@@ -12976,6 +13270,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12976 | case ScriptBaseClass.OBJECT_LAST_OWNER_ID: | 13270 | case ScriptBaseClass.OBJECT_LAST_OWNER_ID: |
12977 | ret.Add(new LSL_Key(ScriptBaseClass.NULL_KEY)); | 13271 | ret.Add(new LSL_Key(ScriptBaseClass.NULL_KEY)); |
12978 | break; | 13272 | break; |
13273 | case ScriptBaseClass.OBJECT_CLICK_ACTION: | ||
13274 | ret.Add(new LSL_Integer(0)); | ||
13275 | break; | ||
13276 | case ScriptBaseClass.OBJECT_OMEGA: | ||
13277 | ret.Add(new LSL_Vector(Vector3.Zero)); | ||
13278 | break; | ||
13279 | case ScriptBaseClass.OBJECT_PRIM_COUNT: | ||
13280 | List<SceneObjectGroup> Attachments = av.GetAttachments(); | ||
13281 | int count = 0; | ||
13282 | try | ||
13283 | { | ||
13284 | foreach (SceneObjectGroup Attachment in Attachments) | ||
13285 | count += Attachment.PrimCount; | ||
13286 | } catch { }; | ||
13287 | ret.Add(new LSL_Integer(count)); | ||
13288 | break; | ||
13289 | case ScriptBaseClass.OBJECT_TOTAL_INVENTORY_COUNT: | ||
13290 | List<SceneObjectGroup> invAttachments = av.GetAttachments(); | ||
13291 | int invcount = 0; | ||
13292 | try | ||
13293 | { | ||
13294 | foreach (SceneObjectGroup Attachment in invAttachments) | ||
13295 | { | ||
13296 | SceneObjectPart[] parts = Attachment.Parts; | ||
13297 | int nparts = parts.Count(); | ||
13298 | for(int i = 0; i < nparts; i++) | ||
13299 | invcount += parts[i].Inventory.Count; | ||
13300 | } | ||
13301 | } catch { }; | ||
13302 | ret.Add(new LSL_Integer(invcount)); | ||
13303 | break; | ||
13304 | case ScriptBaseClass.OBJECT_REZZER_KEY: | ||
13305 | ret.Add(new LSL_Key(id)); | ||
13306 | break; | ||
13307 | case ScriptBaseClass.OBJECT_GROUP_TAG: | ||
13308 | ret.Add(new LSL_String(av.Grouptitle)); | ||
13309 | break; | ||
13310 | case ScriptBaseClass.OBJECT_TEMP_ATTACHED: | ||
13311 | ret.Add(new LSL_Integer(0)); | ||
13312 | break; | ||
12979 | default: | 13313 | default: |
12980 | // Invalid or unhandled constant. | 13314 | // Invalid or unhandled constant. |
12981 | ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); | 13315 | ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); |
@@ -13000,7 +13334,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13000 | ret.Add(new LSL_String(obj.Description)); | 13334 | ret.Add(new LSL_String(obj.Description)); |
13001 | break; | 13335 | break; |
13002 | case ScriptBaseClass.OBJECT_POS: | 13336 | case ScriptBaseClass.OBJECT_POS: |
13003 | ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); | 13337 | Vector3 opos = obj.AbsolutePosition; |
13338 | ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z)); | ||
13004 | break; | 13339 | break; |
13005 | case ScriptBaseClass.OBJECT_ROT: | 13340 | case ScriptBaseClass.OBJECT_ROT: |
13006 | Quaternion rot = Quaternion.Identity; | 13341 | Quaternion rot = Quaternion.Identity; |
@@ -13036,7 +13371,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13036 | } | 13371 | } |
13037 | else | 13372 | else |
13038 | { | 13373 | { |
13039 | vel = obj.Velocity; | 13374 | vel = obj.Velocity; |
13040 | } | 13375 | } |
13041 | 13376 | ||
13042 | ret.Add(vel); | 13377 | ret.Add(vel); |
@@ -13073,9 +13408,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13073 | // The value returned in SL for normal prims is prim count | 13408 | // The value returned in SL for normal prims is prim count |
13074 | ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); | 13409 | ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); |
13075 | break; | 13410 | break; |
13076 | // The following 3 costs I have intentionaly coded to return zero. They are part of | 13411 | |
13077 | // "Land Impact" calculations. These calculations are probably not applicable | 13412 | // costs below may need to be diferent for root parts, need to check |
13078 | // to OpenSim and are not yet complete in SL | ||
13079 | case ScriptBaseClass.OBJECT_SERVER_COST: | 13413 | case ScriptBaseClass.OBJECT_SERVER_COST: |
13080 | // The linden calculation is here | 13414 | // The linden calculation is here |
13081 | // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight | 13415 | // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight |
@@ -13083,16 +13417,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13083 | ret.Add(new LSL_Float(0)); | 13417 | ret.Add(new LSL_Float(0)); |
13084 | break; | 13418 | break; |
13085 | case ScriptBaseClass.OBJECT_STREAMING_COST: | 13419 | case ScriptBaseClass.OBJECT_STREAMING_COST: |
13086 | // The linden calculation is here | 13420 | // The value returned in SL for normal prims is prim count * 0.06 |
13087 | // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost | 13421 | ret.Add(new LSL_Float(obj.StreamingCost)); |
13088 | // The value returned in SL for normal prims looks like the prim count * 0.06 | ||
13089 | ret.Add(new LSL_Float(0)); | ||
13090 | break; | 13422 | break; |
13091 | case ScriptBaseClass.OBJECT_PHYSICS_COST: | 13423 | case ScriptBaseClass.OBJECT_PHYSICS_COST: |
13092 | // The linden calculation is here | 13424 | // The value returned in SL for normal prims is prim count |
13093 | // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics | 13425 | ret.Add(new LSL_Float(obj.PhysicsCost)); |
13094 | // The value returned in SL for normal prims looks like the prim count | ||
13095 | ret.Add(new LSL_Float(0)); | ||
13096 | break; | 13426 | break; |
13097 | case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding | 13427 | case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding |
13098 | ret.Add(new LSL_Float(0)); | 13428 | ret.Add(new LSL_Float(0)); |
@@ -13152,6 +13482,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13152 | case ScriptBaseClass.OBJECT_LAST_OWNER_ID: | 13482 | case ScriptBaseClass.OBJECT_LAST_OWNER_ID: |
13153 | ret.Add(new LSL_Key(obj.ParentGroup.LastOwnerID.ToString())); | 13483 | ret.Add(new LSL_Key(obj.ParentGroup.LastOwnerID.ToString())); |
13154 | break; | 13484 | break; |
13485 | case ScriptBaseClass.OBJECT_CLICK_ACTION: | ||
13486 | ret.Add(new LSL_Integer(obj.ClickAction)); | ||
13487 | break; | ||
13488 | case ScriptBaseClass.OBJECT_OMEGA: | ||
13489 | ret.Add(new LSL_Vector(obj.AngularVelocity)); | ||
13490 | break; | ||
13491 | case ScriptBaseClass.OBJECT_PRIM_COUNT: | ||
13492 | ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); | ||
13493 | break; | ||
13494 | case ScriptBaseClass.OBJECT_TOTAL_INVENTORY_COUNT: | ||
13495 | SceneObjectPart[] parts = obj.ParentGroup.Parts; | ||
13496 | int nparts = parts.Count(); | ||
13497 | int count = 0; | ||
13498 | for(int i = 0; i < nparts; i++) | ||
13499 | count += parts[i].Inventory.Count; | ||
13500 | ret.Add(new LSL_Integer(count)); | ||
13501 | break; | ||
13502 | case ScriptBaseClass.OBJECT_REZZER_KEY: | ||
13503 | ret.Add(new LSL_Key(obj.ParentGroup.RezzerID.ToString())); | ||
13504 | break; | ||
13505 | case ScriptBaseClass.OBJECT_GROUP_TAG: | ||
13506 | ret.Add(new LSL_String(String.Empty)); | ||
13507 | break; | ||
13508 | case ScriptBaseClass.OBJECT_TEMP_ATTACHED: | ||
13509 | if (obj.ParentGroup.AttachmentPoint != 0 && obj.ParentGroup.FromItemID == UUID.Zero) | ||
13510 | { | ||
13511 | ret.Add(new LSL_Integer(1)); | ||
13512 | } | ||
13513 | else | ||
13514 | { | ||
13515 | ret.Add(new LSL_Integer(0)); | ||
13516 | } | ||
13517 | break; | ||
13155 | default: | 13518 | default: |
13156 | // Invalid or unhandled constant. | 13519 | // Invalid or unhandled constant. |
13157 | ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); | 13520 | ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); |
@@ -13257,8 +13620,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13257 | 13620 | ||
13258 | public LSL_String llGetNumberOfNotecardLines(string name) | 13621 | public LSL_String llGetNumberOfNotecardLines(string name) |
13259 | { | 13622 | { |
13260 | m_host.AddScriptLPS(1); | ||
13261 | |||
13262 | UUID assetID = UUID.Zero; | 13623 | UUID assetID = UUID.Zero; |
13263 | 13624 | ||
13264 | if (!UUID.TryParse(name, out assetID)) | 13625 | if (!UUID.TryParse(name, out assetID)) |
@@ -13306,8 +13667,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13306 | 13667 | ||
13307 | public LSL_String llGetNotecardLine(string name, int line) | 13668 | public LSL_String llGetNotecardLine(string name, int line) |
13308 | { | 13669 | { |
13309 | m_host.AddScriptLPS(1); | ||
13310 | |||
13311 | UUID assetID = UUID.Zero; | 13670 | UUID assetID = UUID.Zero; |
13312 | 13671 | ||
13313 | if (!UUID.TryParse(name, out assetID)) | 13672 | if (!UUID.TryParse(name, out assetID)) |
@@ -13371,12 +13730,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13371 | 13730 | ||
13372 | public LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules) | 13731 | public LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules) |
13373 | { | 13732 | { |
13374 | SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); | 13733 | SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); |
13734 | |||
13735 | LSL_List result = new LSL_List(); | ||
13375 | 13736 | ||
13376 | if (obj != null && obj.OwnerID == m_host.OwnerID) | 13737 | if (obj != null && obj.OwnerID == m_host.OwnerID) |
13377 | return GetEntityParams(obj, rules); | 13738 | { |
13739 | LSL_List remaining = GetPrimParams(obj, rules, ref result); | ||
13378 | 13740 | ||
13379 | return new LSL_List(); | 13741 | while (remaining.Length > 2) |
13742 | { | ||
13743 | int linknumber = remaining.GetLSLIntegerItem(0); | ||
13744 | rules = remaining.GetSublist(1, -1); | ||
13745 | List<SceneObjectPart> parts = GetLinkParts(linknumber); | ||
13746 | |||
13747 | foreach (SceneObjectPart part in parts) | ||
13748 | remaining = GetPrimParams(part, rules, ref result); | ||
13749 | } | ||
13750 | } | ||
13751 | |||
13752 | return result; | ||
13380 | } | 13753 | } |
13381 | 13754 | ||
13382 | public void print(string str) | 13755 | public void print(string str) |
@@ -13390,6 +13763,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13390 | } | 13763 | } |
13391 | } | 13764 | } |
13392 | 13765 | ||
13766 | public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link) | ||
13767 | { | ||
13768 | List<SceneObjectPart> parts = GetLinkParts(link); | ||
13769 | if (parts.Count < 1) | ||
13770 | return 0; | ||
13771 | |||
13772 | return GetNumberOfSides(parts[0]); | ||
13773 | } | ||
13774 | |||
13393 | private string Name2Username(string name) | 13775 | private string Name2Username(string name) |
13394 | { | 13776 | { |
13395 | string[] parts = name.Split(new char[] {' '}); | 13777 | string[] parts = name.Split(new char[] {' '}); |
@@ -13432,7 +13814,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13432 | 13814 | ||
13433 | return rq.ToString(); | 13815 | return rq.ToString(); |
13434 | } | 13816 | } |
13435 | 13817 | /* | |
13818 | private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args) | ||
13819 | { | ||
13820 | m_SayShoutCount = 0; | ||
13821 | } | ||
13822 | */ | ||
13436 | private struct Tri | 13823 | private struct Tri |
13437 | { | 13824 | { |
13438 | public Vector3 p1; | 13825 | public Vector3 p1; |
@@ -13453,18 +13840,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13453 | return false; | 13840 | return false; |
13454 | } | 13841 | } |
13455 | 13842 | ||
13456 | private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd) | 13843 | private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd, bool skipPhys) |
13457 | { | 13844 | { |
13458 | List<ContactResult> contacts = new List<ContactResult>(); | 13845 | List<ContactResult> contacts = new List<ContactResult>(); |
13459 | 13846 | ||
13460 | Vector3 ab = rayEnd - rayStart; | 13847 | Vector3 ab = rayEnd - rayStart; |
13848 | float ablen = ab.Length(); | ||
13461 | 13849 | ||
13462 | World.ForEachScenePresence(delegate(ScenePresence sp) | 13850 | World.ForEachScenePresence(delegate(ScenePresence sp) |
13463 | { | 13851 | { |
13852 | if(skipPhys && sp.PhysicsActor != null) | ||
13853 | return; | ||
13854 | |||
13464 | Vector3 ac = sp.AbsolutePosition - rayStart; | 13855 | Vector3 ac = sp.AbsolutePosition - rayStart; |
13465 | // Vector3 bc = sp.AbsolutePosition - rayEnd; | ||
13466 | 13856 | ||
13467 | double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); | 13857 | double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / ablen); |
13468 | 13858 | ||
13469 | if (d > 1.5) | 13859 | if (d > 1.5) |
13470 | return; | 13860 | return; |
@@ -13581,9 +13971,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13581 | 13971 | ||
13582 | ContactResult result = new ContactResult (); | 13972 | ContactResult result = new ContactResult (); |
13583 | result.ConsumerID = group.LocalId; | 13973 | result.ConsumerID = group.LocalId; |
13584 | result.Depth = intersection.distance; | 13974 | // result.Depth = intersection.distance; |
13585 | result.Normal = intersection.normal; | 13975 | result.Normal = intersection.normal; |
13586 | result.Pos = intersection.ipoint; | 13976 | result.Pos = intersection.ipoint; |
13977 | result.Depth = Vector3.Mag(rayStart - result.Pos); | ||
13587 | 13978 | ||
13588 | contacts.Add(result); | 13979 | contacts.Add(result); |
13589 | }); | 13980 | }); |
@@ -13716,6 +14107,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13716 | 14107 | ||
13717 | return contacts[0]; | 14108 | return contacts[0]; |
13718 | } | 14109 | } |
14110 | /* | ||
14111 | // not done: | ||
14112 | private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght) | ||
14113 | { | ||
14114 | ContactResult[] contacts = null; | ||
14115 | World.ForEachSOG(delegate(SceneObjectGroup group) | ||
14116 | { | ||
14117 | if (m_host.ParentGroup == group) | ||
14118 | return; | ||
14119 | |||
14120 | if (group.IsAttachment) | ||
14121 | return; | ||
14122 | |||
14123 | if(group.RootPart.PhysActor != null) | ||
14124 | return; | ||
14125 | |||
14126 | contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght); | ||
14127 | }); | ||
14128 | return contacts; | ||
14129 | } | ||
14130 | */ | ||
13719 | 14131 | ||
13720 | public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) | 14132 | public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) |
13721 | { | 14133 | { |
@@ -13725,13 +14137,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13725 | 14137 | ||
13726 | LSL_List list = new LSL_List(); | 14138 | LSL_List list = new LSL_List(); |
13727 | 14139 | ||
13728 | m_host.AddScriptLPS(1); | ||
13729 | |||
13730 | Vector3 rayStart = start; | 14140 | Vector3 rayStart = start; |
13731 | Vector3 rayEnd = end; | 14141 | Vector3 rayEnd = end; |
13732 | Vector3 dir = rayEnd - rayStart; | 14142 | Vector3 dir = rayEnd - rayStart; |
13733 | 14143 | ||
13734 | float dist = Vector3.Mag(dir); | 14144 | float dist = dir.Length(); |
13735 | 14145 | ||
13736 | int count = 1; | 14146 | int count = 1; |
13737 | bool detectPhantom = false; | 14147 | bool detectPhantom = false; |
@@ -13760,17 +14170,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13760 | bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); | 14170 | bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); |
13761 | bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); | 14171 | bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); |
13762 | 14172 | ||
13763 | |||
13764 | if (World.SupportsRayCastFiltered()) | 14173 | if (World.SupportsRayCastFiltered()) |
13765 | { | 14174 | { |
13766 | if (dist == 0) | 14175 | if (dist == 0) |
13767 | return list; | 14176 | return list; |
13768 | 14177 | ||
13769 | RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull; | 14178 | RayFilterFlags rayfilter = RayFilterFlags.BackFaceCull; |
13770 | if (checkTerrain) | 14179 | if (checkTerrain) |
13771 | rayfilter |= RayFilterFlags.land; | 14180 | rayfilter |= RayFilterFlags.land; |
13772 | // if (checkAgents) | 14181 | if (checkAgents) |
13773 | // rayfilter |= RayFilterFlags.agent; | 14182 | rayfilter |= RayFilterFlags.agent; |
13774 | if (checkPhysical) | 14183 | if (checkPhysical) |
13775 | rayfilter |= RayFilterFlags.physical; | 14184 | rayfilter |= RayFilterFlags.physical; |
13776 | if (checkNonPhysical) | 14185 | if (checkNonPhysical) |
@@ -13796,16 +14205,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13796 | 14205 | ||
13797 | if (physresults == null) | 14206 | if (physresults == null) |
13798 | { | 14207 | { |
13799 | list.Add(new LSL_Integer(-3)); // timeout error | 14208 | // list.Add(new LSL_Integer(-3)); // timeout error |
13800 | return list; | 14209 | // return list; |
14210 | results = new List<ContactResult>(); | ||
13801 | } | 14211 | } |
13802 | 14212 | else | |
13803 | results = (List<ContactResult>)physresults; | 14213 | results = (List<ContactResult>)physresults; |
13804 | 14214 | ||
13805 | // for now physics doesn't detect sitted avatars so do it outside physics | 14215 | // for now physics doesn't detect sitted avatars so do it outside physics |
13806 | if (checkAgents) | 14216 | if (checkAgents) |
13807 | { | 14217 | { |
13808 | ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); | 14218 | ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd, true); |
13809 | foreach (ContactResult r in agentHits) | 14219 | foreach (ContactResult r in agentHits) |
13810 | results.Add(r); | 14220 | results.Add(r); |
13811 | } | 14221 | } |
@@ -13821,12 +14231,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13821 | foreach (ContactResult r in objectHits) | 14231 | foreach (ContactResult r in objectHits) |
13822 | results.Add(r); | 14232 | results.Add(r); |
13823 | } | 14233 | } |
14234 | // Double check this because of current ODE distance problems | ||
14235 | if (checkTerrain && dist > 60) | ||
14236 | { | ||
14237 | bool skipGroundCheck = false; | ||
14238 | |||
14239 | foreach (ContactResult c in results) | ||
14240 | { | ||
14241 | if (c.ConsumerID == 0) // Physics gave us a ground collision | ||
14242 | skipGroundCheck = true; | ||
14243 | } | ||
14244 | |||
14245 | if (!skipGroundCheck) | ||
14246 | { | ||
14247 | float tmp = dir.X * dir.X + dir.Y * dir.Y; | ||
14248 | if(tmp > 2500) | ||
14249 | { | ||
14250 | ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); | ||
14251 | if (groundContact != null) | ||
14252 | results.Add((ContactResult)groundContact); | ||
14253 | } | ||
14254 | } | ||
14255 | } | ||
13824 | } | 14256 | } |
13825 | else | 14257 | else |
13826 | { | 14258 | { |
13827 | if (checkAgents) | 14259 | if (checkAgents) |
13828 | { | 14260 | { |
13829 | ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); | 14261 | ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd, false); |
13830 | foreach (ContactResult r in agentHits) | 14262 | foreach (ContactResult r in agentHits) |
13831 | results.Add(r); | 14263 | results.Add(r); |
13832 | } | 14264 | } |
@@ -13841,13 +14273,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13841 | results.Add(objectHits[iter]); | 14273 | results.Add(objectHits[iter]); |
13842 | } | 14274 | } |
13843 | } | 14275 | } |
13844 | } | ||
13845 | 14276 | ||
13846 | if (checkTerrain) | 14277 | if (checkTerrain) |
13847 | { | 14278 | { |
13848 | ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); | 14279 | ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); |
13849 | if (groundContact != null) | 14280 | if (groundContact != null) |
13850 | results.Add((ContactResult)groundContact); | 14281 | results.Add((ContactResult)groundContact); |
14282 | } | ||
13851 | } | 14283 | } |
13852 | 14284 | ||
13853 | results.Sort(delegate(ContactResult a, ContactResult b) | 14285 | results.Sort(delegate(ContactResult a, ContactResult b) |
@@ -13908,10 +14340,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13908 | } | 14340 | } |
13909 | 14341 | ||
13910 | list.Add(new LSL_Integer(values)); | 14342 | list.Add(new LSL_Integer(values)); |
13911 | |||
13912 | return list; | 14343 | return list; |
13913 | } | 14344 | } |
13914 | 14345 | ||
14346 | |||
13915 | /// <summary> | 14347 | /// <summary> |
13916 | /// Implementation of llCastRay similar to SL 2015-04-21. | 14348 | /// Implementation of llCastRay similar to SL 2015-04-21. |
13917 | /// http://wiki.secondlife.com/wiki/LlCastRay | 14349 | /// http://wiki.secondlife.com/wiki/LlCastRay |
@@ -13924,7 +14356,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13924 | /// </summary> | 14356 | /// </summary> |
13925 | public LSL_List llCastRayV3(LSL_Vector start, LSL_Vector end, LSL_List options) | 14357 | public LSL_List llCastRayV3(LSL_Vector start, LSL_Vector end, LSL_List options) |
13926 | { | 14358 | { |
13927 | m_host.AddScriptLPS(1); | ||
13928 | LSL_List result = new LSL_List(); | 14359 | LSL_List result = new LSL_List(); |
13929 | 14360 | ||
13930 | // Prepare throttle data | 14361 | // Prepare throttle data |
@@ -13935,7 +14366,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13935 | UUID userId = UUID.Zero; | 14366 | UUID userId = UUID.Zero; |
13936 | int msAvailable = 0; | 14367 | int msAvailable = 0; |
13937 | // Throttle per owner when attachment or "vehicle" (sat upon) | 14368 | // Throttle per owner when attachment or "vehicle" (sat upon) |
13938 | if (m_host.ParentGroup.IsAttachment || m_host.ParentGroup.GetSittingAvatars().Count > 0) | 14369 | if (m_host.ParentGroup.IsAttachment || m_host.ParentGroup.GetSittingAvatarsCount() > 0) |
13939 | { | 14370 | { |
13940 | userId = m_host.OwnerID; | 14371 | userId = m_host.OwnerID; |
13941 | msAvailable = m_msPerAvatarInCastRay; | 14372 | msAvailable = m_msPerAvatarInCastRay; |
@@ -13968,13 +14399,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13968 | msAvailable -= m_castRayCalls[i].UsedMs; | 14399 | msAvailable -= m_castRayCalls[i].UsedMs; |
13969 | } | 14400 | } |
13970 | } | 14401 | } |
13971 | } | ||
13972 | 14402 | ||
13973 | // Return failure if not enough available time | 14403 | // Return failure if not enough available time |
13974 | if (msAvailable < m_msMinInCastRay) | 14404 | if (msAvailable < m_msMinInCastRay) |
13975 | { | 14405 | { |
13976 | result.Add(new LSL_Integer(ScriptBaseClass.RCERR_CAST_TIME_EXCEEDED)); | 14406 | result.Add(new LSL_Integer(ScriptBaseClass.RCERR_CAST_TIME_EXCEEDED)); |
13977 | return result; | 14407 | return result; |
14408 | } | ||
13978 | } | 14409 | } |
13979 | 14410 | ||
13980 | // Initialize | 14411 | // Initialize |
@@ -13987,7 +14418,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13987 | int rejectTypes = 0; | 14418 | int rejectTypes = 0; |
13988 | int dataFlags = 0; | 14419 | int dataFlags = 0; |
13989 | int maxHits = 1; | 14420 | int maxHits = 1; |
13990 | bool detectPhantom = false; | 14421 | bool notdetectPhantom = true; |
13991 | for (int i = 0; i < options.Length; i += 2) | 14422 | for (int i = 0; i < options.Length; i += 2) |
13992 | { | 14423 | { |
13993 | if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) | 14424 | if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) |
@@ -13997,7 +14428,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13997 | else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) | 14428 | else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) |
13998 | maxHits = options.GetLSLIntegerItem(i + 1); | 14429 | maxHits = options.GetLSLIntegerItem(i + 1); |
13999 | else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) | 14430 | else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) |
14000 | detectPhantom = (options.GetLSLIntegerItem(i + 1) != 0); | 14431 | notdetectPhantom = (options.GetLSLIntegerItem(i + 1) == 0); |
14001 | } | 14432 | } |
14002 | if (maxHits > m_maxHitsInCastRay) | 14433 | if (maxHits > m_maxHitsInCastRay) |
14003 | maxHits = m_maxHitsInCastRay; | 14434 | maxHits = m_maxHitsInCastRay; |
@@ -14027,157 +14458,153 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14027 | World.ForEachSOG( | 14458 | World.ForEachSOG( |
14028 | delegate(SceneObjectGroup group) | 14459 | delegate(SceneObjectGroup group) |
14029 | { | 14460 | { |
14461 | if(group.IsDeleted || group.RootPart == null) | ||
14462 | return; | ||
14030 | // Check group filters unless part filters are configured | 14463 | // Check group filters unless part filters are configured |
14031 | bool isPhysical = (group.RootPart != null && group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical); | 14464 | bool isPhysical = (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical); |
14032 | bool isNonphysical = !isPhysical; | 14465 | bool isNonphysical = !isPhysical; |
14033 | bool isPhantom = group.IsPhantom || group.IsVolumeDetect; | 14466 | bool isPhantom = group.IsPhantom || group.IsVolumeDetect; |
14034 | bool isAttachment = group.IsAttachment; | 14467 | bool isAttachment = group.IsAttachment; |
14035 | bool doGroup = true; | ||
14036 | if (isPhysical && rejectPhysical) | 14468 | if (isPhysical && rejectPhysical) |
14037 | doGroup = false; | 14469 | return; |
14038 | if (isNonphysical && rejectNonphysical) | 14470 | if (isNonphysical && rejectNonphysical) |
14039 | doGroup = false; | 14471 | return; |
14040 | if (isPhantom && detectPhantom) | 14472 | if (isPhantom && notdetectPhantom) |
14041 | doGroup = true; | 14473 | return; |
14042 | if (m_filterPartsInCastRay) | ||
14043 | doGroup = true; | ||
14044 | if (isAttachment && !m_doAttachmentsInCastRay) | 14474 | if (isAttachment && !m_doAttachmentsInCastRay) |
14045 | doGroup = false; | 14475 | return; |
14476 | |||
14046 | // Parse object/group if passed filters | 14477 | // Parse object/group if passed filters |
14047 | if (doGroup) | 14478 | // Iterate over all prims/parts in object/group |
14479 | foreach(SceneObjectPart part in group.Parts) | ||
14048 | { | 14480 | { |
14049 | // Iterate over all prims/parts in object/group | 14481 | // ignore PhysicsShapeType.None as physics engines do |
14050 | foreach(SceneObjectPart part in group.Parts) | 14482 | // or we will get into trouble in future |
14483 | if(part.PhysicsShapeType == (byte)PhysicsShapeType.None) | ||
14484 | continue; | ||
14485 | isPhysical = (part.PhysActor != null && part.PhysActor.IsPhysical); | ||
14486 | isNonphysical = !isPhysical; | ||
14487 | isPhantom = ((part.Flags & PrimFlags.Phantom) != 0) || | ||
14488 | (part.VolumeDetectActive); | ||
14489 | |||
14490 | if (isPhysical && rejectPhysical) | ||
14491 | continue; | ||
14492 | if (isNonphysical && rejectNonphysical) | ||
14493 | continue; | ||
14494 | if (isPhantom && notdetectPhantom) | ||
14495 | continue; | ||
14496 | |||
14497 | // Parse prim/part and project ray if passed filters | ||
14498 | Vector3 scalePart = part.Scale; | ||
14499 | Vector3 posPart = part.GetWorldPosition(); | ||
14500 | Quaternion rotPart = part.GetWorldRotation(); | ||
14501 | Quaternion rotPartInv = Quaternion.Inverse(rotPart); | ||
14502 | Vector3 pos1RayProj = ((pos1Ray - posPart) * rotPartInv) / scalePart; | ||
14503 | Vector3 pos2RayProj = ((pos2Ray - posPart) * rotPartInv) / scalePart; | ||
14504 | |||
14505 | // Filter parts by shape bounding boxes | ||
14506 | Vector3 shapeBoxMax = new Vector3(0.5f, 0.5f, 0.5f); | ||
14507 | if (!part.Shape.SculptEntry) | ||
14508 | shapeBoxMax = shapeBoxMax * (new Vector3(m_primSafetyCoeffX, m_primSafetyCoeffY, m_primSafetyCoeffZ)); | ||
14509 | shapeBoxMax = shapeBoxMax + (new Vector3(tol, tol, tol)); | ||
14510 | if (RayIntersectsShapeBox(pos1RayProj, pos2RayProj, shapeBoxMax)) | ||
14051 | { | 14511 | { |
14052 | // Check part filters if configured | 14512 | // Prepare data needed to check for ray hits |
14053 | if (m_filterPartsInCastRay) | 14513 | RayTrans rayTrans = new RayTrans(); |
14054 | { | 14514 | rayTrans.PartId = part.UUID; |
14055 | isPhysical = (part.PhysActor != null && part.PhysActor.IsPhysical); | 14515 | rayTrans.GroupId = part.ParentGroup.UUID; |
14056 | isNonphysical = !isPhysical; | 14516 | rayTrans.Link = group.PrimCount > 1 ? part.LinkNum : 0; |
14057 | isPhantom = ((part.Flags & PrimFlags.Phantom) != 0) || (part.VolumeDetectActive); | 14517 | rayTrans.ScalePart = scalePart; |
14058 | bool doPart = true; | 14518 | rayTrans.PositionPart = posPart; |
14059 | if (isPhysical && rejectPhysical) | 14519 | rayTrans.RotationPart = rotPart; |
14060 | doPart = false; | 14520 | rayTrans.ShapeNeedsEnds = true; |
14061 | if (isNonphysical && rejectNonphysical) | 14521 | rayTrans.Position1Ray = pos1Ray; |
14062 | doPart = false; | 14522 | rayTrans.Position1RayProj = pos1RayProj; |
14063 | if (isPhantom && detectPhantom) | 14523 | rayTrans.VectorRayProj = pos2RayProj - pos1RayProj; |
14064 | doPart = true; | 14524 | |
14065 | if (!doPart) | 14525 | // Get detail level depending on type |
14066 | continue; | 14526 | int lod = 0; |
14067 | } | 14527 | // Mesh detail level |
14068 | 14528 | if (part.Shape.SculptEntry && part.Shape.SculptType == (byte)SculptType.Mesh) | |
14069 | // Parse prim/part and project ray if passed filters | 14529 | lod = (int)m_meshLodInCastRay; |
14070 | Vector3 scalePart = part.Scale; | 14530 | // Sculpt detail level |
14071 | Vector3 posPart = part.GetWorldPosition(); | 14531 | else if (part.Shape.SculptEntry && part.Shape.SculptType == (byte)SculptType.Mesh) |
14072 | Quaternion rotPart = part.GetWorldRotation(); | 14532 | lod = (int)m_sculptLodInCastRay; |
14073 | Quaternion rotPartInv = Quaternion.Inverse(rotPart); | 14533 | // Shape detail level |
14074 | Vector3 pos1RayProj = ((pos1Ray - posPart) * rotPartInv) / scalePart; | 14534 | else if (!part.Shape.SculptEntry) |
14075 | Vector3 pos2RayProj = ((pos2Ray - posPart) * rotPartInv) / scalePart; | 14535 | lod = (int)m_primLodInCastRay; |
14076 | 14536 | ||
14077 | // Filter parts by shape bounding boxes | 14537 | // Try to get cached mesh if configured |
14078 | Vector3 shapeBoxMax = new Vector3(0.5f, 0.5f, 0.5f); | 14538 | ulong meshKey = 0; |
14079 | if (!part.Shape.SculptEntry) | 14539 | FacetedMesh mesh = null; |
14080 | shapeBoxMax = shapeBoxMax * (new Vector3(m_primSafetyCoeffX, m_primSafetyCoeffY, m_primSafetyCoeffZ)); | 14540 | if (m_useMeshCacheInCastRay) |
14081 | shapeBoxMax = shapeBoxMax + (new Vector3(tol, tol, tol)); | 14541 | { |
14082 | if (RayIntersectsShapeBox(pos1RayProj, pos2RayProj, shapeBoxMax)) | 14542 | meshKey = part.Shape.GetMeshKey(Vector3.One, (float)(4 << lod)); |
14083 | { | 14543 | lock (m_cachedMeshes) |
14084 | // Prepare data needed to check for ray hits | ||
14085 | RayTrans rayTrans = new RayTrans(); | ||
14086 | rayTrans.PartId = part.UUID; | ||
14087 | rayTrans.GroupId = part.ParentGroup.UUID; | ||
14088 | rayTrans.Link = group.PrimCount > 1 ? part.LinkNum : 0; | ||
14089 | rayTrans.ScalePart = scalePart; | ||
14090 | rayTrans.PositionPart = posPart; | ||
14091 | rayTrans.RotationPart = rotPart; | ||
14092 | rayTrans.ShapeNeedsEnds = true; | ||
14093 | rayTrans.Position1Ray = pos1Ray; | ||
14094 | rayTrans.Position1RayProj = pos1RayProj; | ||
14095 | rayTrans.VectorRayProj = pos2RayProj - pos1RayProj; | ||
14096 | |||
14097 | // Get detail level depending on type | ||
14098 | int lod = 0; | ||
14099 | // Mesh detail level | ||
14100 | if (part.Shape.SculptEntry && part.Shape.SculptType == (byte)SculptType.Mesh) | ||
14101 | lod = (int)m_meshLodInCastRay; | ||
14102 | // Sculpt detail level | ||
14103 | else if (part.Shape.SculptEntry && part.Shape.SculptType == (byte)SculptType.Mesh) | ||
14104 | lod = (int)m_sculptLodInCastRay; | ||
14105 | // Shape detail level | ||
14106 | else if (!part.Shape.SculptEntry) | ||
14107 | lod = (int)m_primLodInCastRay; | ||
14108 | |||
14109 | // Try to get cached mesh if configured | ||
14110 | ulong meshKey = 0; | ||
14111 | FacetedMesh mesh = null; | ||
14112 | if (m_useMeshCacheInCastRay) | ||
14113 | { | 14544 | { |
14114 | meshKey = part.Shape.GetMeshKey(Vector3.One, (float)(4 << lod)); | 14545 | m_cachedMeshes.TryGetValue(meshKey, out mesh); |
14115 | lock (m_cachedMeshes) | ||
14116 | { | ||
14117 | m_cachedMeshes.TryGetValue(meshKey, out mesh); | ||
14118 | } | ||
14119 | } | 14546 | } |
14547 | } | ||
14120 | 14548 | ||
14121 | // Create mesh if no cached mesh | 14549 | // Create mesh if no cached mesh |
14122 | if (mesh == null) | 14550 | if (mesh == null) |
14551 | { | ||
14552 | // Make an OMV prim to be able to mesh part | ||
14553 | Primitive omvPrim = part.Shape.ToOmvPrimitive(posPart, rotPart); | ||
14554 | byte[] sculptAsset = null; | ||
14555 | if (omvPrim.Sculpt != null) | ||
14556 | sculptAsset = World.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString()); | ||
14557 | |||
14558 | // When part is mesh, get mesh | ||
14559 | if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type == SculptType.Mesh && sculptAsset != null) | ||
14123 | { | 14560 | { |
14124 | // Make an OMV prim to be able to mesh part | 14561 | AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset); |
14125 | Primitive omvPrim = part.Shape.ToOmvPrimitive(posPart, rotPart); | 14562 | FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, m_meshLodInCastRay, out mesh); |
14126 | byte[] sculptAsset = null; | 14563 | meshAsset = null; |
14127 | if (omvPrim.Sculpt != null) | 14564 | } |
14128 | sculptAsset = World.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString()); | ||
14129 | |||
14130 | // When part is mesh, get mesh | ||
14131 | if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type == SculptType.Mesh && sculptAsset != null) | ||
14132 | { | ||
14133 | AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset); | ||
14134 | FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, m_meshLodInCastRay, out mesh); | ||
14135 | meshAsset = null; | ||
14136 | } | ||
14137 | 14565 | ||
14138 | // When part is sculpt, create mesh | 14566 | // When part is sculpt, create mesh |
14139 | // Quirk: Generated sculpt mesh is about 2.8% smaller in X and Y than visual sculpt. | 14567 | // Quirk: Generated sculpt mesh is about 2.8% smaller in X and Y than visual sculpt. |
14140 | else if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type != SculptType.Mesh && sculptAsset != null) | 14568 | else if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type != SculptType.Mesh && sculptAsset != null) |
14569 | { | ||
14570 | IJ2KDecoder imgDecoder = World.RequestModuleInterface<IJ2KDecoder>(); | ||
14571 | if (imgDecoder != null) | ||
14141 | { | 14572 | { |
14142 | IJ2KDecoder imgDecoder = World.RequestModuleInterface<IJ2KDecoder>(); | 14573 | Image sculpt = imgDecoder.DecodeToImage(sculptAsset); |
14143 | if (imgDecoder != null) | 14574 | if (sculpt != null) |
14144 | { | 14575 | { |
14145 | Image sculpt = imgDecoder.DecodeToImage(sculptAsset); | 14576 | mesh = primMesher.GenerateFacetedSculptMesh(omvPrim, (Bitmap)sculpt, m_sculptLodInCastRay); |
14146 | if (sculpt != null) | 14577 | sculpt.Dispose(); |
14147 | { | ||
14148 | mesh = primMesher.GenerateFacetedSculptMesh(omvPrim, (Bitmap)sculpt, m_sculptLodInCastRay); | ||
14149 | sculpt.Dispose(); | ||
14150 | } | ||
14151 | } | 14578 | } |
14152 | } | ||
14153 | |||
14154 | // When part is shape, create mesh | ||
14155 | else if (omvPrim.Sculpt == null) | ||
14156 | { | ||
14157 | if ( | ||
14158 | omvPrim.PrimData.PathBegin == 0.0 && omvPrim.PrimData.PathEnd == 1.0 && | ||
14159 | omvPrim.PrimData.PathTaperX == 0.0 && omvPrim.PrimData.PathTaperY == 0.0 && | ||
14160 | omvPrim.PrimData.PathSkew == 0.0 && | ||
14161 | omvPrim.PrimData.PathTwist - omvPrim.PrimData.PathTwistBegin == 0.0 | ||
14162 | ) | ||
14163 | rayTrans.ShapeNeedsEnds = false; | ||
14164 | mesh = primMesher.GenerateFacetedMesh(omvPrim, m_primLodInCastRay); | ||
14165 | } | 14579 | } |
14580 | } | ||
14581 | |||
14582 | // When part is shape, create mesh | ||
14583 | else if (omvPrim.Sculpt == null) | ||
14584 | { | ||
14585 | if ( | ||
14586 | omvPrim.PrimData.PathBegin == 0.0 && omvPrim.PrimData.PathEnd == 1.0 && | ||
14587 | omvPrim.PrimData.PathTaperX == 0.0 && omvPrim.PrimData.PathTaperY == 0.0 && | ||
14588 | omvPrim.PrimData.PathSkew == 0.0 && | ||
14589 | omvPrim.PrimData.PathTwist - omvPrim.PrimData.PathTwistBegin == 0.0 | ||
14590 | ) | ||
14591 | rayTrans.ShapeNeedsEnds = false; | ||
14592 | mesh = primMesher.GenerateFacetedMesh(omvPrim, m_primLodInCastRay); | ||
14593 | } | ||
14166 | 14594 | ||
14167 | // Cache mesh if configured | 14595 | // Cache mesh if configured |
14168 | if (m_useMeshCacheInCastRay && mesh != null) | 14596 | if (m_useMeshCacheInCastRay && mesh != null) |
14597 | { | ||
14598 | lock(m_cachedMeshes) | ||
14169 | { | 14599 | { |
14170 | lock(m_cachedMeshes) | 14600 | if (!m_cachedMeshes.ContainsKey(meshKey)) |
14171 | { | 14601 | m_cachedMeshes.Add(meshKey, mesh); |
14172 | if (!m_cachedMeshes.ContainsKey(meshKey)) | ||
14173 | m_cachedMeshes.Add(meshKey, mesh); | ||
14174 | } | ||
14175 | } | 14602 | } |
14176 | } | 14603 | } |
14177 | // Check mesh for ray hits | ||
14178 | AddRayInFacetedMesh(mesh, rayTrans, ref rayHits); | ||
14179 | mesh = null; | ||
14180 | } | 14604 | } |
14605 | // Check mesh for ray hits | ||
14606 | AddRayInFacetedMesh(mesh, rayTrans, ref rayHits); | ||
14607 | mesh = null; | ||
14181 | } | 14608 | } |
14182 | } | 14609 | } |
14183 | } | 14610 | } |
@@ -14362,13 +14789,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14362 | 14789 | ||
14363 | // Add to throttle data | 14790 | // Add to throttle data |
14364 | stopWatch.Stop(); | 14791 | stopWatch.Stop(); |
14365 | CastRayCall castRayCall = new CastRayCall(); | ||
14366 | castRayCall.RegionId = regionId; | ||
14367 | castRayCall.UserId = userId; | ||
14368 | castRayCall.CalledMs = calledMs; | ||
14369 | castRayCall.UsedMs = (int)stopWatch.ElapsedMilliseconds; | ||
14370 | lock (m_castRayCalls) | 14792 | lock (m_castRayCalls) |
14371 | { | 14793 | { |
14794 | CastRayCall castRayCall = new CastRayCall(); | ||
14795 | castRayCall.RegionId = regionId; | ||
14796 | castRayCall.UserId = userId; | ||
14797 | castRayCall.CalledMs = calledMs; | ||
14798 | castRayCall.UsedMs = (int)stopWatch.ElapsedMilliseconds; | ||
14372 | m_castRayCalls.Add(castRayCall); | 14799 | m_castRayCalls.Add(castRayCall); |
14373 | } | 14800 | } |
14374 | 14801 | ||
@@ -14780,7 +15207,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14780 | 15207 | ||
14781 | public LSL_Integer llManageEstateAccess(int action, string avatar) | 15208 | public LSL_Integer llManageEstateAccess(int action, string avatar) |
14782 | { | 15209 | { |
14783 | m_host.AddScriptLPS(1); | ||
14784 | EstateSettings estate = World.RegionInfo.EstateSettings; | 15210 | EstateSettings estate = World.RegionInfo.EstateSettings; |
14785 | bool isAccount = false; | 15211 | bool isAccount = false; |
14786 | bool isGroup = false; | 15212 | bool isGroup = false; |
@@ -14813,7 +15239,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14813 | case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: | 15239 | case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: |
14814 | if (!isAccount) return 0; | 15240 | if (!isAccount) return 0; |
14815 | if (estate.HasAccess(id)) return 1; | 15241 | if (estate.HasAccess(id)) return 1; |
14816 | if (estate.IsBanned(id)) | 15242 | if (estate.IsBanned(id, World.GetUserFlags(id))) |
14817 | estate.RemoveBan(id); | 15243 | estate.RemoveBan(id); |
14818 | estate.AddEstateUser(id); | 15244 | estate.AddEstateUser(id); |
14819 | break; | 15245 | break; |
@@ -14832,14 +15258,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14832 | break; | 15258 | break; |
14833 | case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: | 15259 | case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: |
14834 | if (!isAccount) return 0; | 15260 | if (!isAccount) return 0; |
14835 | if (estate.IsBanned(id)) return 1; | 15261 | if (estate.IsBanned(id, World.GetUserFlags(id))) return 1; |
14836 | EstateBan ban = new EstateBan(); | 15262 | EstateBan ban = new EstateBan(); |
14837 | ban.EstateID = estate.EstateID; | 15263 | ban.EstateID = estate.EstateID; |
14838 | ban.BannedUserID = id; | 15264 | ban.BannedUserID = id; |
14839 | estate.AddBan(ban); | 15265 | estate.AddBan(ban); |
14840 | break; | 15266 | break; |
14841 | case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: | 15267 | case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: |
14842 | if (!isAccount || !estate.IsBanned(id)) return 0; | 15268 | if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0; |
14843 | estate.RemoveBan(id); | 15269 | estate.RemoveBan(id); |
14844 | break; | 15270 | break; |
14845 | default: return 0; | 15271 | default: return 0; |
@@ -14849,35 +15275,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14849 | 15275 | ||
14850 | public LSL_Integer llGetMemoryLimit() | 15276 | public LSL_Integer llGetMemoryLimit() |
14851 | { | 15277 | { |
14852 | m_host.AddScriptLPS(1); | ||
14853 | // The value returned for Mono scripts in SL | 15278 | // The value returned for Mono scripts in SL |
14854 | return 65536; | 15279 | return 65536; |
14855 | } | 15280 | } |
14856 | 15281 | ||
14857 | public LSL_Integer llSetMemoryLimit(LSL_Integer limit) | 15282 | public LSL_Integer llSetMemoryLimit(LSL_Integer limit) |
14858 | { | 15283 | { |
14859 | m_host.AddScriptLPS(1); | ||
14860 | // Treat as an LSO script | 15284 | // Treat as an LSO script |
14861 | return ScriptBaseClass.FALSE; | 15285 | return ScriptBaseClass.FALSE; |
14862 | } | 15286 | } |
14863 | 15287 | ||
14864 | public LSL_Integer llGetSPMaxMemory() | 15288 | public LSL_Integer llGetSPMaxMemory() |
14865 | { | 15289 | { |
14866 | m_host.AddScriptLPS(1); | ||
14867 | // The value returned for Mono scripts in SL | 15290 | // The value returned for Mono scripts in SL |
14868 | return 65536; | 15291 | return 65536; |
14869 | } | 15292 | } |
14870 | 15293 | ||
14871 | public virtual LSL_Integer llGetUsedMemory() | 15294 | public virtual LSL_Integer llGetUsedMemory() |
14872 | { | 15295 | { |
14873 | m_host.AddScriptLPS(1); | ||
14874 | // The value returned for Mono scripts in SL | 15296 | // The value returned for Mono scripts in SL |
14875 | return 65536; | 15297 | return 65536; |
14876 | } | 15298 | } |
14877 | 15299 | ||
14878 | public void llScriptProfiler(LSL_Integer flags) | 15300 | public void llScriptProfiler(LSL_Integer flags) |
14879 | { | 15301 | { |
14880 | m_host.AddScriptLPS(1); | ||
14881 | // This does nothing for LSO scripts in SL | 15302 | // This does nothing for LSO scripts in SL |
14882 | } | 15303 | } |
14883 | 15304 | ||
@@ -14889,22 +15310,66 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14889 | 15310 | ||
14890 | public void llSetSoundQueueing(int queue) | 15311 | public void llSetSoundQueueing(int queue) |
14891 | { | 15312 | { |
14892 | m_host.AddScriptLPS(1); | ||
14893 | |||
14894 | if (m_SoundModule != null) | 15313 | if (m_SoundModule != null) |
14895 | m_SoundModule.SetSoundQueueing(m_host.UUID, queue == ScriptBaseClass.TRUE.value); | 15314 | m_SoundModule.SetSoundQueueing(m_host.UUID, queue == ScriptBaseClass.TRUE.value); |
14896 | } | 15315 | } |
14897 | 15316 | ||
14898 | public void llCollisionSprite(string impact_sprite) | 15317 | public void llCollisionSprite(string impact_sprite) |
14899 | { | 15318 | { |
14900 | m_host.AddScriptLPS(1); | 15319 | // Viewer 2.0 broke this and it's likely LL has no intention |
14901 | NotImplemented("llCollisionSprite"); | 15320 | // of fixing it. Therefore, letting this be a NOP seems appropriate. |
14902 | } | 15321 | } |
14903 | 15322 | ||
14904 | public void llGodLikeRezObject(string inventory, LSL_Vector pos) | 15323 | public void llGodLikeRezObject(string inventory, LSL_Vector pos) |
14905 | { | 15324 | { |
14906 | m_host.AddScriptLPS(1); | 15325 | if (!World.Permissions.IsGod(m_host.OwnerID)) |
14907 | NotImplemented("llGodLikeRezObject"); | 15326 | NotImplemented("llGodLikeRezObject"); |
15327 | |||
15328 | AssetBase rezAsset = World.AssetService.Get(inventory); | ||
15329 | if (rezAsset == null) | ||
15330 | { | ||
15331 | llSay(0, "Asset not found"); | ||
15332 | return; | ||
15333 | } | ||
15334 | |||
15335 | SceneObjectGroup group = null; | ||
15336 | |||
15337 | try | ||
15338 | { | ||
15339 | string xmlData = Utils.BytesToString(rezAsset.Data); | ||
15340 | group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | ||
15341 | } | ||
15342 | catch | ||
15343 | { | ||
15344 | llSay(0, "Asset not found"); | ||
15345 | return; | ||
15346 | } | ||
15347 | |||
15348 | if (group == null) | ||
15349 | { | ||
15350 | llSay(0, "Asset not found"); | ||
15351 | return; | ||
15352 | } | ||
15353 | |||
15354 | group.RootPart.AttachedPos = group.AbsolutePosition; | ||
15355 | |||
15356 | group.ResetIDs(); | ||
15357 | |||
15358 | Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z); | ||
15359 | World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero); | ||
15360 | group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3); | ||
15361 | group.ScheduleGroupForFullUpdate(); | ||
15362 | |||
15363 | // objects rezzed with this method are die_at_edge by default. | ||
15364 | group.RootPart.SetDieAtEdge(true); | ||
15365 | |||
15366 | group.ResumeScripts(); | ||
15367 | |||
15368 | m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams( | ||
15369 | "object_rez", new Object[] { | ||
15370 | new LSL_String( | ||
15371 | group.RootPart.UUID.ToString()) }, | ||
15372 | new DetectParams[0])); | ||
14908 | } | 15373 | } |
14909 | 15374 | ||
14910 | public LSL_String llTransferLindenDollars(string destination, int amount) | 15375 | public LSL_String llTransferLindenDollars(string destination, int amount) |
@@ -14918,6 +15383,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14918 | 15383 | ||
14919 | try | 15384 | try |
14920 | { | 15385 | { |
15386 | if (amount <= 0) | ||
15387 | { | ||
15388 | replydata = "INVALID_AMOUNT"; | ||
15389 | return; | ||
15390 | } | ||
15391 | |||
14921 | TaskInventoryItem item = m_item; | 15392 | TaskInventoryItem item = m_item; |
14922 | if (item == null) | 15393 | if (item == null) |
14923 | { | 15394 | { |
@@ -14925,7 +15396,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14925 | return; | 15396 | return; |
14926 | } | 15397 | } |
14927 | 15398 | ||
14928 | m_host.AddScriptLPS(1); | 15399 | if (m_host.OwnerID == m_host.GroupID) |
15400 | { | ||
15401 | replydata = "GROUP_OWNED"; | ||
15402 | return; | ||
15403 | } | ||
14929 | 15404 | ||
14930 | if (item.PermsGranter == UUID.Zero) | 15405 | if (item.PermsGranter == UUID.Zero) |
14931 | { | 15406 | { |
@@ -14947,6 +15422,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14947 | return; | 15422 | return; |
14948 | } | 15423 | } |
14949 | 15424 | ||
15425 | UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, toID); | ||
15426 | if (account == null) | ||
15427 | { | ||
15428 | replydata = "LINDENDOLLAR_ENTITYDOESNOTEXIST"; | ||
15429 | return; | ||
15430 | } | ||
15431 | |||
14950 | IMoneyModule money = World.RequestModuleInterface<IMoneyModule>(); | 15432 | IMoneyModule money = World.RequestModuleInterface<IMoneyModule>(); |
14951 | 15433 | ||
14952 | if (money == null) | 15434 | if (money == null) |
@@ -14955,8 +15437,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14955 | return; | 15437 | return; |
14956 | } | 15438 | } |
14957 | 15439 | ||
14958 | bool result = money.ObjectGiveMoney( | 15440 | string reason; |
14959 | m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); | 15441 | bool result = money.ObjectGiveMoney( m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn, out reason); |
14960 | 15442 | ||
14961 | if (result) | 15443 | if (result) |
14962 | { | 15444 | { |
@@ -14964,7 +15446,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14964 | return; | 15446 | return; |
14965 | } | 15447 | } |
14966 | 15448 | ||
14967 | replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS"; | 15449 | replydata = reason; |
14968 | } | 15450 | } |
14969 | finally | 15451 | finally |
14970 | { | 15452 | { |
@@ -14981,6 +15463,1366 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
14981 | } | 15463 | } |
14982 | 15464 | ||
14983 | #endregion | 15465 | #endregion |
15466 | |||
15467 | |||
15468 | protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed) | ||
15469 | { | ||
15470 | //This is a special version of SetPrimParams to deal with avatars which are sitting on the linkset. | ||
15471 | |||
15472 | int idx = 0; | ||
15473 | int idxStart = 0; | ||
15474 | |||
15475 | bool positionChanged = false; | ||
15476 | try | ||
15477 | { | ||
15478 | while (idx < rules.Length) | ||
15479 | { | ||
15480 | ++rulesParsed; | ||
15481 | int code = rules.GetLSLIntegerItem(idx++); | ||
15482 | |||
15483 | int remain = rules.Length - idx; | ||
15484 | idxStart = idx; | ||
15485 | |||
15486 | switch (code) | ||
15487 | { | ||
15488 | case (int)ScriptBaseClass.PRIM_POSITION: | ||
15489 | case (int)ScriptBaseClass.PRIM_POS_LOCAL: | ||
15490 | { | ||
15491 | if (remain < 1) | ||
15492 | return new LSL_List(); | ||
15493 | |||
15494 | LSL_Vector v; | ||
15495 | v = rules.GetVector3Item(idx++); | ||
15496 | |||
15497 | if(!av.LegacySitOffsets) | ||
15498 | { | ||
15499 | LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f); | ||
15500 | |||
15501 | v = v + 2 * sitOffset; | ||
15502 | } | ||
15503 | |||
15504 | av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z); | ||
15505 | positionChanged = true; | ||
15506 | } | ||
15507 | break; | ||
15508 | |||
15509 | case (int)ScriptBaseClass.PRIM_ROTATION: | ||
15510 | { | ||
15511 | if (remain < 1) | ||
15512 | return new LSL_List(); | ||
15513 | |||
15514 | Quaternion r; | ||
15515 | r = rules.GetQuaternionItem(idx++); | ||
15516 | |||
15517 | av.Rotation = m_host.GetWorldRotation() * r; | ||
15518 | positionChanged = true; | ||
15519 | } | ||
15520 | break; | ||
15521 | |||
15522 | case (int)ScriptBaseClass.PRIM_ROT_LOCAL: | ||
15523 | { | ||
15524 | if (remain < 1) | ||
15525 | return new LSL_List(); | ||
15526 | |||
15527 | LSL_Rotation r; | ||
15528 | r = rules.GetQuaternionItem(idx++); | ||
15529 | |||
15530 | av.Rotation = r; | ||
15531 | positionChanged = true; | ||
15532 | } | ||
15533 | break; | ||
15534 | |||
15535 | // parse rest doing nothing but number of parameters error check | ||
15536 | case (int)ScriptBaseClass.PRIM_SIZE: | ||
15537 | case (int)ScriptBaseClass.PRIM_MATERIAL: | ||
15538 | case (int)ScriptBaseClass.PRIM_PHANTOM: | ||
15539 | case (int)ScriptBaseClass.PRIM_PHYSICS: | ||
15540 | case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE: | ||
15541 | case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: | ||
15542 | case (int)ScriptBaseClass.PRIM_NAME: | ||
15543 | case (int)ScriptBaseClass.PRIM_DESC: | ||
15544 | if (remain < 1) | ||
15545 | return new LSL_List(); | ||
15546 | idx++; | ||
15547 | break; | ||
15548 | |||
15549 | case (int)ScriptBaseClass.PRIM_GLOW: | ||
15550 | case (int)ScriptBaseClass.PRIM_FULLBRIGHT: | ||
15551 | case (int)ScriptBaseClass.PRIM_TEXGEN: | ||
15552 | if (remain < 2) | ||
15553 | return new LSL_List(); | ||
15554 | idx += 2; | ||
15555 | break; | ||
15556 | |||
15557 | case (int)ScriptBaseClass.PRIM_TYPE: | ||
15558 | if (remain < 3) | ||
15559 | return new LSL_List(); | ||
15560 | code = (int)rules.GetLSLIntegerItem(idx++); | ||
15561 | remain = rules.Length - idx; | ||
15562 | switch (code) | ||
15563 | { | ||
15564 | case (int)ScriptBaseClass.PRIM_TYPE_BOX: | ||
15565 | case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER: | ||
15566 | case (int)ScriptBaseClass.PRIM_TYPE_PRISM: | ||
15567 | if (remain < 6) | ||
15568 | return new LSL_List(); | ||
15569 | idx += 6; | ||
15570 | break; | ||
15571 | |||
15572 | case (int)ScriptBaseClass.PRIM_TYPE_SPHERE: | ||
15573 | if (remain < 5) | ||
15574 | return new LSL_List(); | ||
15575 | idx += 5; | ||
15576 | break; | ||
15577 | |||
15578 | case (int)ScriptBaseClass.PRIM_TYPE_TORUS: | ||
15579 | case (int)ScriptBaseClass.PRIM_TYPE_TUBE: | ||
15580 | case (int)ScriptBaseClass.PRIM_TYPE_RING: | ||
15581 | if (remain < 11) | ||
15582 | return new LSL_List(); | ||
15583 | idx += 11; | ||
15584 | break; | ||
15585 | |||
15586 | case (int)ScriptBaseClass.PRIM_TYPE_SCULPT: | ||
15587 | if (remain < 2) | ||
15588 | return new LSL_List(); | ||
15589 | idx += 2; | ||
15590 | break; | ||
15591 | } | ||
15592 | break; | ||
15593 | |||
15594 | case (int)ScriptBaseClass.PRIM_COLOR: | ||
15595 | case (int)ScriptBaseClass.PRIM_TEXT: | ||
15596 | case (int)ScriptBaseClass.PRIM_BUMP_SHINY: | ||
15597 | case (int)ScriptBaseClass.PRIM_OMEGA: | ||
15598 | case (int)ScriptBaseClass.PRIM_SIT_TARGET: | ||
15599 | if (remain < 3) | ||
15600 | return new LSL_List(); | ||
15601 | idx += 3; | ||
15602 | break; | ||
15603 | |||
15604 | case (int)ScriptBaseClass.PRIM_TEXTURE: | ||
15605 | case (int)ScriptBaseClass.PRIM_POINT_LIGHT: | ||
15606 | case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL: | ||
15607 | if (remain < 5) | ||
15608 | return new LSL_List(); | ||
15609 | idx += 5; | ||
15610 | break; | ||
15611 | |||
15612 | case (int)ScriptBaseClass.PRIM_FLEXIBLE: | ||
15613 | if (remain < 7) | ||
15614 | return new LSL_List(); | ||
15615 | |||
15616 | idx += 7; | ||
15617 | break; | ||
15618 | |||
15619 | case (int)ScriptBaseClass.PRIM_LINK_TARGET: | ||
15620 | if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. | ||
15621 | return new LSL_List(); | ||
15622 | |||
15623 | return rules.GetSublist(idx, -1); | ||
15624 | } | ||
15625 | } | ||
15626 | } | ||
15627 | catch (InvalidCastException e) | ||
15628 | { | ||
15629 | Error(originFunc,string.Format( | ||
15630 | " error running rule #{0}: arg #{1} {2}", | ||
15631 | rulesParsed, idx - idxStart, e.Message)); | ||
15632 | } | ||
15633 | finally | ||
15634 | { | ||
15635 | if (positionChanged) | ||
15636 | av.SendTerseUpdateToAllClients(); | ||
15637 | } | ||
15638 | return new LSL_List(); | ||
15639 | } | ||
15640 | |||
15641 | public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res) | ||
15642 | { | ||
15643 | // avatars case | ||
15644 | // replies as SL wiki | ||
15645 | |||
15646 | // SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed | ||
15647 | SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone?? | ||
15648 | |||
15649 | int idx = 0; | ||
15650 | while (idx < rules.Length) | ||
15651 | { | ||
15652 | int code = (int)rules.GetLSLIntegerItem(idx++); | ||
15653 | int remain = rules.Length - idx; | ||
15654 | |||
15655 | switch (code) | ||
15656 | { | ||
15657 | case (int)ScriptBaseClass.PRIM_MATERIAL: | ||
15658 | res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh)); | ||
15659 | break; | ||
15660 | |||
15661 | case (int)ScriptBaseClass.PRIM_PHYSICS: | ||
15662 | res.Add(new LSL_Integer(0)); | ||
15663 | break; | ||
15664 | |||
15665 | case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: | ||
15666 | res.Add(new LSL_Integer(0)); | ||
15667 | break; | ||
15668 | |||
15669 | case (int)ScriptBaseClass.PRIM_PHANTOM: | ||
15670 | res.Add(new LSL_Integer(0)); | ||
15671 | break; | ||
15672 | |||
15673 | case (int)ScriptBaseClass.PRIM_POSITION: | ||
15674 | Vector3 pos; | ||
15675 | |||
15676 | if (sitPart.ParentGroup.RootPart != null) | ||
15677 | { | ||
15678 | pos = avatar.OffsetPosition; | ||
15679 | |||
15680 | if(!avatar.LegacySitOffsets) | ||
15681 | { | ||
15682 | Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f); | ||
15683 | pos -= sitOffset; | ||
15684 | } | ||
15685 | |||
15686 | SceneObjectPart sitroot = sitPart.ParentGroup.RootPart; | ||
15687 | pos = sitroot.AbsolutePosition + pos * sitroot.GetWorldRotation(); | ||
15688 | } | ||
15689 | else | ||
15690 | pos = avatar.AbsolutePosition; | ||
15691 | |||
15692 | res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z)); | ||
15693 | break; | ||
15694 | |||
15695 | case (int)ScriptBaseClass.PRIM_SIZE: | ||
15696 | Vector3 s = avatar.Appearance.AvatarSize; | ||
15697 | res.Add(new LSL_Vector(s.X, s.Y, s.Z)); | ||
15698 | |||
15699 | break; | ||
15700 | |||
15701 | case (int)ScriptBaseClass.PRIM_ROTATION: | ||
15702 | res.Add(new LSL_Rotation(avatar.GetWorldRotation())); | ||
15703 | break; | ||
15704 | |||
15705 | case (int)ScriptBaseClass.PRIM_TYPE: | ||
15706 | res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX)); | ||
15707 | res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT)); | ||
15708 | res.Add(new LSL_Vector(0f,1.0f,0f)); | ||
15709 | res.Add(new LSL_Float(0.0f)); | ||
15710 | res.Add(new LSL_Vector(0, 0, 0)); | ||
15711 | res.Add(new LSL_Vector(1.0f,1.0f,0f)); | ||
15712 | res.Add(new LSL_Vector(0, 0, 0)); | ||
15713 | break; | ||
15714 | |||
15715 | case (int)ScriptBaseClass.PRIM_TEXTURE: | ||
15716 | if (remain < 1) | ||
15717 | return new LSL_List(); | ||
15718 | |||
15719 | int face = (int)rules.GetLSLIntegerItem(idx++); | ||
15720 | if (face == ScriptBaseClass.ALL_SIDES) | ||
15721 | { | ||
15722 | for (face = 0; face < 21; face++) | ||
15723 | { | ||
15724 | res.Add(new LSL_String("")); | ||
15725 | res.Add(new LSL_Vector(0,0,0)); | ||
15726 | res.Add(new LSL_Vector(0,0,0)); | ||
15727 | res.Add(new LSL_Float(0.0)); | ||
15728 | } | ||
15729 | } | ||
15730 | else | ||
15731 | { | ||
15732 | if (face >= 0 && face < 21) | ||
15733 | { | ||
15734 | res.Add(new LSL_String("")); | ||
15735 | res.Add(new LSL_Vector(0,0,0)); | ||
15736 | res.Add(new LSL_Vector(0,0,0)); | ||
15737 | res.Add(new LSL_Float(0.0)); | ||
15738 | } | ||
15739 | } | ||
15740 | break; | ||
15741 | |||
15742 | case (int)ScriptBaseClass.PRIM_COLOR: | ||
15743 | if (remain < 1) | ||
15744 | return new LSL_List(); | ||
15745 | |||
15746 | face = (int)rules.GetLSLIntegerItem(idx++); | ||
15747 | |||
15748 | if (face == ScriptBaseClass.ALL_SIDES) | ||
15749 | { | ||
15750 | for (face = 0; face < 21; face++) | ||
15751 | { | ||
15752 | res.Add(new LSL_Vector(0,0,0)); | ||
15753 | res.Add(new LSL_Float(0)); | ||
15754 | } | ||
15755 | } | ||
15756 | else | ||
15757 | { | ||
15758 | res.Add(new LSL_Vector(0,0,0)); | ||
15759 | res.Add(new LSL_Float(0)); | ||
15760 | } | ||
15761 | break; | ||
15762 | |||
15763 | case (int)ScriptBaseClass.PRIM_BUMP_SHINY: | ||
15764 | if (remain < 1) | ||
15765 | return new LSL_List(); | ||
15766 | face = (int)rules.GetLSLIntegerItem(idx++); | ||
15767 | |||
15768 | if (face == ScriptBaseClass.ALL_SIDES) | ||
15769 | { | ||
15770 | for (face = 0; face < 21; face++) | ||
15771 | { | ||
15772 | res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE)); | ||
15773 | res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE)); | ||
15774 | } | ||
15775 | } | ||
15776 | else | ||
15777 | { | ||
15778 | res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE)); | ||
15779 | res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE)); | ||
15780 | } | ||
15781 | break; | ||
15782 | |||
15783 | case (int)ScriptBaseClass.PRIM_FULLBRIGHT: | ||
15784 | if (remain < 1) | ||
15785 | return new LSL_List(); | ||
15786 | face = (int)rules.GetLSLIntegerItem(idx++); | ||
15787 | |||
15788 | if (face == ScriptBaseClass.ALL_SIDES) | ||
15789 | { | ||
15790 | for (face = 0; face < 21; face++) | ||
15791 | { | ||
15792 | res.Add(new LSL_Integer(ScriptBaseClass.FALSE)); | ||
15793 | } | ||
15794 | } | ||
15795 | else | ||
15796 | { | ||
15797 | res.Add(new LSL_Integer(ScriptBaseClass.FALSE)); | ||
15798 | } | ||
15799 | break; | ||
15800 | |||
15801 | case (int)ScriptBaseClass.PRIM_FLEXIBLE: | ||
15802 | res.Add(new LSL_Integer(0)); | ||
15803 | res.Add(new LSL_Integer(0));// softness | ||
15804 | res.Add(new LSL_Float(0.0f)); // gravity | ||
15805 | res.Add(new LSL_Float(0.0f)); // friction | ||
15806 | res.Add(new LSL_Float(0.0f)); // wind | ||
15807 | res.Add(new LSL_Float(0.0f)); // tension | ||
15808 | res.Add(new LSL_Vector(0f,0f,0f)); | ||
15809 | break; | ||
15810 | |||
15811 | case (int)ScriptBaseClass.PRIM_TEXGEN: | ||
15812 | // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) | ||
15813 | if (remain < 1) | ||
15814 | return new LSL_List(); | ||
15815 | face = (int)rules.GetLSLIntegerItem(idx++); | ||
15816 | |||
15817 | if (face == ScriptBaseClass.ALL_SIDES) | ||
15818 | { | ||
15819 | for (face = 0; face < 21; face++) | ||
15820 | { | ||
15821 | res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT)); | ||
15822 | } | ||
15823 | } | ||
15824 | else | ||
15825 | { | ||
15826 | res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT)); | ||
15827 | } | ||
15828 | break; | ||
15829 | |||
15830 | case (int)ScriptBaseClass.PRIM_POINT_LIGHT: | ||
15831 | res.Add(new LSL_Integer(0)); | ||
15832 | res.Add(new LSL_Vector(0f,0f,0f)); | ||
15833 | res.Add(new LSL_Float(0f)); // intensity | ||
15834 | res.Add(new LSL_Float(0f)); // radius | ||
15835 | res.Add(new LSL_Float(0f)); // falloff | ||
15836 | break; | ||
15837 | |||
15838 | case (int)ScriptBaseClass.PRIM_GLOW: | ||
15839 | if (remain < 1) | ||
15840 | return new LSL_List(); | ||
15841 | face = (int)rules.GetLSLIntegerItem(idx++); | ||
15842 | |||
15843 | if (face == ScriptBaseClass.ALL_SIDES) | ||
15844 | { | ||
15845 | for (face = 0; face < 21; face++) | ||
15846 | { | ||
15847 | res.Add(new LSL_Float(0f)); | ||
15848 | } | ||
15849 | } | ||
15850 | else | ||
15851 | { | ||
15852 | res.Add(new LSL_Float(0f)); | ||
15853 | } | ||
15854 | break; | ||
15855 | |||
15856 | case (int)ScriptBaseClass.PRIM_TEXT: | ||
15857 | res.Add(new LSL_String("")); | ||
15858 | res.Add(new LSL_Vector(0f,0f,0f)); | ||
15859 | res.Add(new LSL_Float(1.0f)); | ||
15860 | break; | ||
15861 | |||
15862 | case (int)ScriptBaseClass.PRIM_NAME: | ||
15863 | res.Add(new LSL_String(avatar.Name)); | ||
15864 | break; | ||
15865 | |||
15866 | case (int)ScriptBaseClass.PRIM_DESC: | ||
15867 | res.Add(new LSL_String("")); | ||
15868 | break; | ||
15869 | |||
15870 | case (int)ScriptBaseClass.PRIM_ROT_LOCAL: | ||
15871 | Quaternion lrot = avatar.Rotation; | ||
15872 | res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W)); | ||
15873 | break; | ||
15874 | |||
15875 | case (int)ScriptBaseClass.PRIM_POS_LOCAL: | ||
15876 | Vector3 lpos = avatar.OffsetPosition; | ||
15877 | |||
15878 | if(!avatar.LegacySitOffsets) | ||
15879 | { | ||
15880 | Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f); | ||
15881 | lpos -= lsitOffset; | ||
15882 | } | ||
15883 | |||
15884 | res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z)); | ||
15885 | break; | ||
15886 | |||
15887 | case (int)ScriptBaseClass.PRIM_LINK_TARGET: | ||
15888 | if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. | ||
15889 | return new LSL_List(); | ||
15890 | |||
15891 | return rules.GetSublist(idx, -1); | ||
15892 | } | ||
15893 | } | ||
15894 | |||
15895 | return new LSL_List(); | ||
15896 | } | ||
15897 | |||
15898 | public void llSetAnimationOverride(LSL_String animState, LSL_String anim) | ||
15899 | { | ||
15900 | string state = String.Empty; | ||
15901 | |||
15902 | foreach (KeyValuePair<string, string> kvp in MovementAnimationsForLSL) | ||
15903 | { | ||
15904 | if (kvp.Value.ToLower() == ((string)animState).ToLower()) | ||
15905 | { | ||
15906 | state = kvp.Key; | ||
15907 | break; | ||
15908 | } | ||
15909 | } | ||
15910 | |||
15911 | if (state == String.Empty) | ||
15912 | { | ||
15913 | llShout(ScriptBaseClass.DEBUG_CHANNEL, "Invalid animation state " + animState); | ||
15914 | return; | ||
15915 | } | ||
15916 | |||
15917 | if (m_item.PermsGranter == UUID.Zero) | ||
15918 | { | ||
15919 | llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations"); | ||
15920 | return; | ||
15921 | } | ||
15922 | |||
15923 | if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_OVERRIDE_ANIMATIONS) == 0) | ||
15924 | { | ||
15925 | llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations"); | ||
15926 | return; | ||
15927 | } | ||
15928 | |||
15929 | ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); | ||
15930 | |||
15931 | if (presence == null) | ||
15932 | return; | ||
15933 | |||
15934 | UUID animID; | ||
15935 | |||
15936 | animID = ScriptUtils.GetAssetIdFromItemName(m_host, anim, (int)AssetType.Animation); | ||
15937 | |||
15938 | if (animID == UUID.Zero) | ||
15939 | { | ||
15940 | String animupper = ((string)anim).ToUpperInvariant(); | ||
15941 | DefaultAvatarAnimations.AnimsUUID.TryGetValue(animupper, out animID); | ||
15942 | } | ||
15943 | |||
15944 | if (animID == UUID.Zero) | ||
15945 | { | ||
15946 | llShout(ScriptBaseClass.DEBUG_CHANNEL, "Animation not found"); | ||
15947 | return; | ||
15948 | } | ||
15949 | |||
15950 | presence.SetAnimationOverride(state, animID); | ||
15951 | } | ||
15952 | |||
15953 | public void llResetAnimationOverride(LSL_String animState) | ||
15954 | { | ||
15955 | ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); | ||
15956 | if (presence == null) | ||
15957 | return; | ||
15958 | |||
15959 | if (m_item.PermsGranter == UUID.Zero) | ||
15960 | { | ||
15961 | llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations"); | ||
15962 | return; | ||
15963 | } | ||
15964 | |||
15965 | if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_OVERRIDE_ANIMATIONS) == 0) | ||
15966 | { | ||
15967 | llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations"); | ||
15968 | return; | ||
15969 | } | ||
15970 | |||
15971 | if (animState == "ALL") | ||
15972 | { | ||
15973 | presence.SetAnimationOverride("ALL", UUID.Zero); | ||
15974 | return; | ||
15975 | } | ||
15976 | |||
15977 | string state = String.Empty; | ||
15978 | |||
15979 | foreach (KeyValuePair<string, string> kvp in MovementAnimationsForLSL) | ||
15980 | { | ||
15981 | if (kvp.Value.ToLower() == ((string)animState).ToLower()) | ||
15982 | { | ||
15983 | state = kvp.Key; | ||
15984 | break; | ||
15985 | } | ||
15986 | } | ||
15987 | |||
15988 | if (state == String.Empty) | ||
15989 | { | ||
15990 | return; | ||
15991 | } | ||
15992 | |||
15993 | presence.SetAnimationOverride(state, UUID.Zero); | ||
15994 | } | ||
15995 | |||
15996 | public LSL_String llGetAnimationOverride(LSL_String animState) | ||
15997 | { | ||
15998 | ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); | ||
15999 | if (presence == null) | ||
16000 | return String.Empty; | ||
16001 | |||
16002 | if (m_item.PermsGranter == UUID.Zero) | ||
16003 | { | ||
16004 | llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations"); | ||
16005 | return String.Empty; | ||
16006 | } | ||
16007 | |||
16008 | if ((m_item.PermsMask & (ScriptBaseClass.PERMISSION_OVERRIDE_ANIMATIONS | ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION)) == 0) | ||
16009 | { | ||
16010 | llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations"); | ||
16011 | return String.Empty; | ||
16012 | } | ||
16013 | |||
16014 | string state = String.Empty; | ||
16015 | |||
16016 | foreach (KeyValuePair<string, string> kvp in MovementAnimationsForLSL) | ||
16017 | { | ||
16018 | if (kvp.Value.ToLower() == ((string)animState).ToLower()) | ||
16019 | { | ||
16020 | state = kvp.Key; | ||
16021 | break; | ||
16022 | } | ||
16023 | } | ||
16024 | |||
16025 | if (state == String.Empty) | ||
16026 | { | ||
16027 | return String.Empty; | ||
16028 | } | ||
16029 | |||
16030 | UUID animID = presence.GetAnimationOverride(state); | ||
16031 | if (animID == UUID.Zero) | ||
16032 | return animState; | ||
16033 | |||
16034 | foreach (KeyValuePair<string, UUID> kvp in DefaultAvatarAnimations.AnimsUUID) | ||
16035 | { | ||
16036 | if (kvp.Value == animID) | ||
16037 | return kvp.Key.ToLower(); | ||
16038 | } | ||
16039 | |||
16040 | foreach (TaskInventoryItem item in m_host.Inventory.GetInventoryItems()) | ||
16041 | { | ||
16042 | if (item.AssetID == animID) | ||
16043 | return item.Name; | ||
16044 | } | ||
16045 | |||
16046 | return String.Empty; | ||
16047 | } | ||
16048 | |||
16049 | public LSL_List llJson2List(LSL_String json) | ||
16050 | { | ||
16051 | if(String.IsNullOrEmpty(json)) | ||
16052 | return new LSL_List(); | ||
16053 | if(json == "[]") | ||
16054 | return new LSL_List(); | ||
16055 | if(json == "{}") | ||
16056 | return new LSL_List(); | ||
16057 | char first = ((string)json)[0]; | ||
16058 | |||
16059 | if(first != '[' && first !='{') | ||
16060 | { | ||
16061 | // we already have a single element | ||
16062 | LSL_List l = new LSL_List(); | ||
16063 | l.Add(json); | ||
16064 | return l; | ||
16065 | } | ||
16066 | |||
16067 | LitJson.JsonData jsdata; | ||
16068 | try | ||
16069 | { | ||
16070 | jsdata = LitJson.JsonMapper.ToObject(json); | ||
16071 | } | ||
16072 | catch (Exception e) | ||
16073 | { | ||
16074 | string m = e.Message; // debug point | ||
16075 | return json; | ||
16076 | } | ||
16077 | try | ||
16078 | { | ||
16079 | return JsonParseTop(jsdata); | ||
16080 | } | ||
16081 | catch (Exception e) | ||
16082 | { | ||
16083 | string m = e.Message; // debug point | ||
16084 | return (LSL_String)ScriptBaseClass.JSON_INVALID; | ||
16085 | } | ||
16086 | } | ||
16087 | |||
16088 | private LSL_List JsonParseTop(LitJson.JsonData elem) | ||
16089 | { | ||
16090 | LSL_List retl = new LSL_List(); | ||
16091 | if(elem == null) | ||
16092 | retl.Add((LSL_String)ScriptBaseClass.JSON_NULL); | ||
16093 | |||
16094 | LitJson.JsonType elemType = elem.GetJsonType(); | ||
16095 | switch (elemType) | ||
16096 | { | ||
16097 | case LitJson.JsonType.Int: | ||
16098 | retl.Add(new LSL_Integer((int)elem)); | ||
16099 | return retl; | ||
16100 | case LitJson.JsonType.Boolean: | ||
16101 | retl.Add((LSL_String)((bool)elem ? ScriptBaseClass.JSON_TRUE : ScriptBaseClass.JSON_FALSE)); | ||
16102 | return retl; | ||
16103 | case LitJson.JsonType.Double: | ||
16104 | retl.Add(new LSL_Float((double)elem)); | ||
16105 | return retl; | ||
16106 | case LitJson.JsonType.None: | ||
16107 | retl.Add((LSL_String)ScriptBaseClass.JSON_NULL); | ||
16108 | return retl; | ||
16109 | case LitJson.JsonType.String: | ||
16110 | retl.Add(new LSL_String((string)elem)); | ||
16111 | return retl; | ||
16112 | case LitJson.JsonType.Array: | ||
16113 | foreach (LitJson.JsonData subelem in elem) | ||
16114 | retl.Add(JsonParseTopNodes(subelem)); | ||
16115 | return retl; | ||
16116 | case LitJson.JsonType.Object: | ||
16117 | IDictionaryEnumerator e = ((IOrderedDictionary)elem).GetEnumerator(); | ||
16118 | while (e.MoveNext()) | ||
16119 | { | ||
16120 | retl.Add(new LSL_String((string)e.Key)); | ||
16121 | retl.Add(JsonParseTopNodes((LitJson.JsonData)e.Value)); | ||
16122 | } | ||
16123 | return retl; | ||
16124 | default: | ||
16125 | throw new Exception(ScriptBaseClass.JSON_INVALID); | ||
16126 | } | ||
16127 | } | ||
16128 | |||
16129 | private object JsonParseTopNodes(LitJson.JsonData elem) | ||
16130 | { | ||
16131 | if(elem == null) | ||
16132 | return ((LSL_String)ScriptBaseClass.JSON_NULL); | ||
16133 | |||
16134 | LitJson.JsonType elemType = elem.GetJsonType(); | ||
16135 | switch (elemType) | ||
16136 | { | ||
16137 | case LitJson.JsonType.Int: | ||
16138 | return (new LSL_Integer((int)elem)); | ||
16139 | case LitJson.JsonType.Boolean: | ||
16140 | return ((bool)elem ? (LSL_String)ScriptBaseClass.JSON_TRUE : (LSL_String)ScriptBaseClass.JSON_FALSE); | ||
16141 | case LitJson.JsonType.Double: | ||
16142 | return (new LSL_Float((double)elem)); | ||
16143 | case LitJson.JsonType.None: | ||
16144 | return ((LSL_String)ScriptBaseClass.JSON_NULL); | ||
16145 | case LitJson.JsonType.String: | ||
16146 | return (new LSL_String((string)elem)); | ||
16147 | case LitJson.JsonType.Array: | ||
16148 | case LitJson.JsonType.Object: | ||
16149 | string s = LitJson.JsonMapper.ToJson(elem); | ||
16150 | return (LSL_String)s; | ||
16151 | default: | ||
16152 | throw new Exception(ScriptBaseClass.JSON_INVALID); | ||
16153 | } | ||
16154 | } | ||
16155 | |||
16156 | public LSL_String llList2Json(LSL_String type, LSL_List values) | ||
16157 | { | ||
16158 | try | ||
16159 | { | ||
16160 | StringBuilder sb = new StringBuilder(); | ||
16161 | if (type == ScriptBaseClass.JSON_ARRAY) | ||
16162 | { | ||
16163 | sb.Append("["); | ||
16164 | int i= 0; | ||
16165 | foreach (object o in values.Data) | ||
16166 | { | ||
16167 | sb.Append(ListToJson(o)); | ||
16168 | if((i++) < values.Data.Length - 1) | ||
16169 | sb.Append(","); | ||
16170 | } | ||
16171 | sb.Append("]"); | ||
16172 | return (LSL_String)sb.ToString();; | ||
16173 | } | ||
16174 | else if (type == ScriptBaseClass.JSON_OBJECT) | ||
16175 | { | ||
16176 | sb.Append("{"); | ||
16177 | for (int i = 0; i < values.Data.Length; i += 2) | ||
16178 | { | ||
16179 | if (!(values.Data[i] is LSL_String)) | ||
16180 | return ScriptBaseClass.JSON_INVALID; | ||
16181 | string key = ((LSL_String)values.Data[i]).m_string; | ||
16182 | key = EscapeForJSON(key, true); | ||
16183 | sb.Append(key); | ||
16184 | sb.Append(":"); | ||
16185 | sb.Append(ListToJson(values.Data[i+1])); | ||
16186 | if(i < values.Data.Length - 2) | ||
16187 | sb.Append(","); | ||
16188 | } | ||
16189 | sb.Append("}"); | ||
16190 | return (LSL_String)sb.ToString(); | ||
16191 | } | ||
16192 | return ScriptBaseClass.JSON_INVALID; | ||
16193 | } | ||
16194 | catch | ||
16195 | { | ||
16196 | return ScriptBaseClass.JSON_INVALID; | ||
16197 | } | ||
16198 | } | ||
16199 | |||
16200 | private string ListToJson(object o) | ||
16201 | { | ||
16202 | if (o is LSL_Float || o is double) | ||
16203 | { | ||
16204 | double float_val; | ||
16205 | if (o is double) | ||
16206 | float_val = ((double)o); | ||
16207 | else | ||
16208 | float_val = ((LSL_Float)o).value; | ||
16209 | |||
16210 | if(double.IsInfinity(float_val)) | ||
16211 | return "\"Inf\""; | ||
16212 | if(double.IsNaN(float_val)) | ||
16213 | return "\"NaN\""; | ||
16214 | |||
16215 | return ((LSL_Float)float_val).ToString(); | ||
16216 | } | ||
16217 | if (o is LSL_Integer || o is int) | ||
16218 | { | ||
16219 | int i; | ||
16220 | if (o is int) | ||
16221 | i = ((int)o); | ||
16222 | else | ||
16223 | i = ((LSL_Integer)o).value; | ||
16224 | return i.ToString(); | ||
16225 | } | ||
16226 | if (o is LSL_Rotation) | ||
16227 | { | ||
16228 | StringBuilder sb = new StringBuilder(128); | ||
16229 | sb.Append("\""); | ||
16230 | LSL_Rotation r = (LSL_Rotation)o; | ||
16231 | sb.Append(r.ToString()); | ||
16232 | sb.Append("\""); | ||
16233 | return sb.ToString(); | ||
16234 | } | ||
16235 | if (o is LSL_Vector) | ||
16236 | { | ||
16237 | StringBuilder sb = new StringBuilder(128); | ||
16238 | sb.Append("\""); | ||
16239 | LSL_Vector v = (LSL_Vector)o; | ||
16240 | sb.Append(v.ToString()); | ||
16241 | sb.Append("\""); | ||
16242 | return sb.ToString(); | ||
16243 | } | ||
16244 | if (o is LSL_String || o is string) | ||
16245 | { | ||
16246 | string str; | ||
16247 | if (o is string) | ||
16248 | str = ((string)o); | ||
16249 | else | ||
16250 | str = ((LSL_String)o).m_string; | ||
16251 | |||
16252 | if(str == ScriptBaseClass.JSON_TRUE || str == "true") | ||
16253 | return "true"; | ||
16254 | if(str == ScriptBaseClass.JSON_FALSE ||str == "false") | ||
16255 | return "false"; | ||
16256 | if(str == ScriptBaseClass.JSON_NULL || str == "null") | ||
16257 | return "null"; | ||
16258 | str.Trim(); | ||
16259 | if (str[0] == '{') | ||
16260 | return str; | ||
16261 | if (str[0] == '[') | ||
16262 | return str; | ||
16263 | return EscapeForJSON(str, true); | ||
16264 | } | ||
16265 | throw new IndexOutOfRangeException(); | ||
16266 | } | ||
16267 | |||
16268 | private string EscapeForJSON(string s, bool AddOuter) | ||
16269 | { | ||
16270 | int i; | ||
16271 | char c; | ||
16272 | String t; | ||
16273 | int len = s.Length; | ||
16274 | |||
16275 | StringBuilder sb = new StringBuilder(len + 64); | ||
16276 | if(AddOuter) | ||
16277 | sb.Append("\""); | ||
16278 | |||
16279 | for (i = 0; i < len; i++) | ||
16280 | { | ||
16281 | c = s[i]; | ||
16282 | switch (c) | ||
16283 | { | ||
16284 | case '\\': | ||
16285 | case '"': | ||
16286 | case '/': | ||
16287 | sb.Append('\\'); | ||
16288 | sb.Append(c); | ||
16289 | break; | ||
16290 | case '\b': | ||
16291 | sb.Append("\\b"); | ||
16292 | break; | ||
16293 | case '\t': | ||
16294 | sb.Append("\\t"); | ||
16295 | break; | ||
16296 | case '\n': | ||
16297 | sb.Append("\\n"); | ||
16298 | break; | ||
16299 | case '\f': | ||
16300 | sb.Append("\\f"); | ||
16301 | break; | ||
16302 | case '\r': | ||
16303 | sb.Append("\\r"); | ||
16304 | break; | ||
16305 | default: | ||
16306 | if (c < ' ') | ||
16307 | { | ||
16308 | t = "000" + String.Format("X", c); | ||
16309 | sb.Append("\\u" + t.Substring(t.Length - 4)); | ||
16310 | } | ||
16311 | else | ||
16312 | { | ||
16313 | sb.Append(c); | ||
16314 | } | ||
16315 | break; | ||
16316 | } | ||
16317 | } | ||
16318 | if(AddOuter) | ||
16319 | sb.Append("\""); | ||
16320 | return sb.ToString(); | ||
16321 | } | ||
16322 | |||
16323 | public LSL_String llJsonSetValue(LSL_String json, LSL_List specifiers, LSL_String value) | ||
16324 | { | ||
16325 | bool noSpecifiers = specifiers.Length == 0; | ||
16326 | LitJson.JsonData workData; | ||
16327 | try | ||
16328 | { | ||
16329 | if(noSpecifiers) | ||
16330 | specifiers.Add(new LSL_Integer(0)); | ||
16331 | |||
16332 | if(!String.IsNullOrEmpty(json)) | ||
16333 | workData = LitJson.JsonMapper.ToObject(json); | ||
16334 | else | ||
16335 | { | ||
16336 | workData = new LitJson.JsonData(); | ||
16337 | workData.SetJsonType(LitJson.JsonType.Array); | ||
16338 | } | ||
16339 | } | ||
16340 | catch (Exception e) | ||
16341 | { | ||
16342 | string m = e.Message; // debug point | ||
16343 | return ScriptBaseClass.JSON_INVALID; | ||
16344 | } | ||
16345 | try | ||
16346 | { | ||
16347 | LitJson.JsonData replace = JsonSetSpecific(workData, specifiers, 0, value); | ||
16348 | if(replace != null) | ||
16349 | workData = replace; | ||
16350 | } | ||
16351 | catch (Exception e) | ||
16352 | { | ||
16353 | string m = e.Message; // debug point | ||
16354 | return ScriptBaseClass.JSON_INVALID; | ||
16355 | } | ||
16356 | |||
16357 | try | ||
16358 | { | ||
16359 | string r = LitJson.JsonMapper.ToJson(workData); | ||
16360 | if(noSpecifiers) | ||
16361 | r = r.Substring(1,r.Length -2); // strip leading and trailing brakets | ||
16362 | return r; | ||
16363 | } | ||
16364 | catch (Exception e) | ||
16365 | { | ||
16366 | string m = e.Message; // debug point | ||
16367 | } | ||
16368 | return ScriptBaseClass.JSON_INVALID; | ||
16369 | } | ||
16370 | |||
16371 | private LitJson.JsonData JsonSetSpecific(LitJson.JsonData elem, LSL_List specifiers, int level, LSL_String val) | ||
16372 | { | ||
16373 | object spec = specifiers.Data[level]; | ||
16374 | if(spec is LSL_String) | ||
16375 | spec = ((LSL_String)spec).m_string; | ||
16376 | else if (spec is LSL_Integer) | ||
16377 | spec = ((LSL_Integer)spec).value; | ||
16378 | |||
16379 | if(!(spec is string || spec is int)) | ||
16380 | throw new IndexOutOfRangeException(); | ||
16381 | |||
16382 | int speclen = specifiers.Data.Length - 1; | ||
16383 | |||
16384 | bool hasvalue = false; | ||
16385 | LitJson.JsonData value = null; | ||
16386 | |||
16387 | LitJson.JsonType elemType = elem.GetJsonType(); | ||
16388 | if (elemType == LitJson.JsonType.Array) | ||
16389 | { | ||
16390 | if (spec is int) | ||
16391 | { | ||
16392 | int v = (int)spec; | ||
16393 | int c = elem.Count; | ||
16394 | if(v < 0 || (v != 0 && v > c)) | ||
16395 | throw new IndexOutOfRangeException(); | ||
16396 | if(v == c) | ||
16397 | elem.Add(JsonBuildRestOfSpec(specifiers, level + 1, val)); | ||
16398 | else | ||
16399 | { | ||
16400 | hasvalue = true; | ||
16401 | value = elem[v]; | ||
16402 | } | ||
16403 | } | ||
16404 | else if (spec is string) | ||
16405 | { | ||
16406 | if((string)spec == ScriptBaseClass.JSON_APPEND) | ||
16407 | elem.Add(JsonBuildRestOfSpec(specifiers, level + 1, val)); | ||
16408 | else if(elem.Count < 2) | ||
16409 | { | ||
16410 | // our initial guess of array was wrong | ||
16411 | LitJson.JsonData newdata = new LitJson.JsonData(); | ||
16412 | newdata.SetJsonType(LitJson.JsonType.Object); | ||
16413 | IOrderedDictionary no = newdata as IOrderedDictionary; | ||
16414 | no.Add((string)spec,JsonBuildRestOfSpec(specifiers, level + 1, val)); | ||
16415 | return newdata; | ||
16416 | } | ||
16417 | } | ||
16418 | } | ||
16419 | else if (elemType == LitJson.JsonType.Object) | ||
16420 | { | ||
16421 | if (spec is string) | ||
16422 | { | ||
16423 | IOrderedDictionary e = elem as IOrderedDictionary; | ||
16424 | string key = (string)spec; | ||
16425 | if(e.Contains(key)) | ||
16426 | { | ||
16427 | hasvalue = true; | ||
16428 | value = (LitJson.JsonData)e[key]; | ||
16429 | } | ||
16430 | else | ||
16431 | e.Add(key, JsonBuildRestOfSpec(specifiers, level + 1, val)); | ||
16432 | } | ||
16433 | else if(spec is int && (int)spec == 0) | ||
16434 | { | ||
16435 | //we are replacing a object by a array | ||
16436 | LitJson.JsonData newData = new LitJson.JsonData(); | ||
16437 | newData.SetJsonType(LitJson.JsonType.Array); | ||
16438 | newData.Add(JsonBuildRestOfSpec(specifiers, level + 1, val)); | ||
16439 | return newData; | ||
16440 | } | ||
16441 | } | ||
16442 | else | ||
16443 | { | ||
16444 | LitJson.JsonData newData = JsonBuildRestOfSpec(specifiers, level, val); | ||
16445 | return newData; | ||
16446 | } | ||
16447 | |||
16448 | if (hasvalue) | ||
16449 | { | ||
16450 | if (level < speclen) | ||
16451 | { | ||
16452 | LitJson.JsonData replace = JsonSetSpecific(value, specifiers, level + 1, val); | ||
16453 | if(replace != null) | ||
16454 | { | ||
16455 | if(elemType == LitJson.JsonType.Array) | ||
16456 | { | ||
16457 | if(spec is int) | ||
16458 | elem[(int)spec] = replace; | ||
16459 | else if( spec is string) | ||
16460 | { | ||
16461 | LitJson.JsonData newdata = new LitJson.JsonData(); | ||
16462 | newdata.SetJsonType(LitJson.JsonType.Object); | ||
16463 | IOrderedDictionary no = newdata as IOrderedDictionary; | ||
16464 | no.Add((string)spec, replace); | ||
16465 | return newdata; | ||
16466 | } | ||
16467 | } | ||
16468 | else if(elemType == LitJson.JsonType.Object) | ||
16469 | { | ||
16470 | if(spec is string) | ||
16471 | elem[(string)spec] = replace; | ||
16472 | else if(spec is int && (int)spec == 0) | ||
16473 | { | ||
16474 | LitJson.JsonData newdata = new LitJson.JsonData(); | ||
16475 | newdata.SetJsonType(LitJson.JsonType.Array); | ||
16476 | newdata.Add(replace); | ||
16477 | return newdata; | ||
16478 | } | ||
16479 | } | ||
16480 | } | ||
16481 | return null; | ||
16482 | } | ||
16483 | else if(speclen == level) | ||
16484 | { | ||
16485 | if(val == ScriptBaseClass.JSON_DELETE) | ||
16486 | { | ||
16487 | if(elemType == LitJson.JsonType.Array) | ||
16488 | { | ||
16489 | if(spec is int) | ||
16490 | { | ||
16491 | IList el = elem as IList; | ||
16492 | el.RemoveAt((int)spec); | ||
16493 | } | ||
16494 | } | ||
16495 | else if(elemType == LitJson.JsonType.Object) | ||
16496 | { | ||
16497 | if(spec is string) | ||
16498 | { | ||
16499 | IOrderedDictionary eo = elem as IOrderedDictionary; | ||
16500 | eo.Remove((string) spec); | ||
16501 | } | ||
16502 | } | ||
16503 | return null; | ||
16504 | } | ||
16505 | |||
16506 | LitJson.JsonData newval = null; | ||
16507 | float num; | ||
16508 | if(val == null || val == ScriptBaseClass.JSON_NULL || val == "null") | ||
16509 | newval = null; | ||
16510 | else if(val == ScriptBaseClass.JSON_TRUE || val == "true") | ||
16511 | newval = new LitJson.JsonData(true); | ||
16512 | else if(val == ScriptBaseClass.JSON_FALSE || val == "false") | ||
16513 | newval = new LitJson.JsonData(false); | ||
16514 | else if(float.TryParse(val, out num)) | ||
16515 | { | ||
16516 | // assuming we are at en.us already | ||
16517 | if(num - (int)num == 0.0f && !val.Contains(".")) | ||
16518 | newval = new LitJson.JsonData((int)num); | ||
16519 | else | ||
16520 | { | ||
16521 | num = (float)Math.Round(num,6); | ||
16522 | newval = new LitJson.JsonData((double)num); | ||
16523 | } | ||
16524 | } | ||
16525 | else | ||
16526 | { | ||
16527 | string str = val.m_string; | ||
16528 | newval = new LitJson.JsonData(str); | ||
16529 | } | ||
16530 | |||
16531 | if(elemType == LitJson.JsonType.Array) | ||
16532 | { | ||
16533 | if(spec is int) | ||
16534 | elem[(int)spec] = newval; | ||
16535 | else if( spec is string) | ||
16536 | { | ||
16537 | LitJson.JsonData newdata = new LitJson.JsonData(); | ||
16538 | newdata.SetJsonType(LitJson.JsonType.Object); | ||
16539 | IOrderedDictionary no = newdata as IOrderedDictionary; | ||
16540 | no.Add((string)spec,newval); | ||
16541 | return newdata; | ||
16542 | } | ||
16543 | } | ||
16544 | else if(elemType == LitJson.JsonType.Object) | ||
16545 | { | ||
16546 | if(spec is string) | ||
16547 | elem[(string)spec] = newval; | ||
16548 | else if(spec is int && (int)spec == 0) | ||
16549 | { | ||
16550 | LitJson.JsonData newdata = new LitJson.JsonData(); | ||
16551 | newdata.SetJsonType(LitJson.JsonType.Array); | ||
16552 | newdata.Add(newval); | ||
16553 | return newdata; | ||
16554 | } | ||
16555 | } | ||
16556 | } | ||
16557 | } | ||
16558 | if(val == ScriptBaseClass.JSON_DELETE) | ||
16559 | throw new IndexOutOfRangeException(); | ||
16560 | return null; | ||
16561 | } | ||
16562 | |||
16563 | private LitJson.JsonData JsonBuildRestOfSpec(LSL_List specifiers, int level, LSL_String val) | ||
16564 | { | ||
16565 | object spec = level >= specifiers.Data.Length ? null : specifiers.Data[level]; | ||
16566 | // 20131224 not used object specNext = i+1 >= specifiers.Data.Length ? null : specifiers.Data[i+1]; | ||
16567 | |||
16568 | float num; | ||
16569 | if (spec == null) | ||
16570 | { | ||
16571 | if(val == null || val == ScriptBaseClass.JSON_NULL || val == "null") | ||
16572 | return null; | ||
16573 | if(val == ScriptBaseClass.JSON_DELETE) | ||
16574 | throw new IndexOutOfRangeException(); | ||
16575 | if(val == ScriptBaseClass.JSON_TRUE || val == "true") | ||
16576 | return new LitJson.JsonData(true); | ||
16577 | if(val == ScriptBaseClass.JSON_FALSE || val == "false") | ||
16578 | return new LitJson.JsonData(false); | ||
16579 | if(val == null || val == ScriptBaseClass.JSON_NULL || val == "null") | ||
16580 | return null; | ||
16581 | if(float.TryParse(val, out num)) | ||
16582 | { | ||
16583 | // assuming we are at en.us already | ||
16584 | if(num - (int)num == 0.0f && !val.Contains(".")) | ||
16585 | return new LitJson.JsonData((int)num); | ||
16586 | else | ||
16587 | { | ||
16588 | num = (float)Math.Round(num,6); | ||
16589 | return new LitJson.JsonData(num); | ||
16590 | } | ||
16591 | } | ||
16592 | else | ||
16593 | { | ||
16594 | string str = val.m_string; | ||
16595 | return new LitJson.JsonData(str); | ||
16596 | } | ||
16597 | throw new IndexOutOfRangeException(); | ||
16598 | } | ||
16599 | |||
16600 | if(spec is LSL_String) | ||
16601 | spec = ((LSL_String)spec).m_string; | ||
16602 | else if (spec is LSL_Integer) | ||
16603 | spec = ((LSL_Integer)spec).value; | ||
16604 | |||
16605 | if (spec is int || | ||
16606 | (spec is string && ((string)spec) == ScriptBaseClass.JSON_APPEND) ) | ||
16607 | { | ||
16608 | if(spec is int && (int)spec != 0) | ||
16609 | throw new IndexOutOfRangeException(); | ||
16610 | LitJson.JsonData newdata = new LitJson.JsonData(); | ||
16611 | newdata.SetJsonType(LitJson.JsonType.Array); | ||
16612 | newdata.Add(JsonBuildRestOfSpec(specifiers, level + 1, val)); | ||
16613 | return newdata; | ||
16614 | } | ||
16615 | else if (spec is string) | ||
16616 | { | ||
16617 | LitJson.JsonData newdata = new LitJson.JsonData(); | ||
16618 | newdata.SetJsonType(LitJson.JsonType.Object); | ||
16619 | IOrderedDictionary no = newdata as IOrderedDictionary; | ||
16620 | no.Add((string)spec,JsonBuildRestOfSpec(specifiers, level + 1, val)); | ||
16621 | return newdata; | ||
16622 | } | ||
16623 | throw new IndexOutOfRangeException(); | ||
16624 | } | ||
16625 | |||
16626 | private bool JsonFind(LitJson.JsonData elem, LSL_List specifiers, int level, out LitJson.JsonData value) | ||
16627 | { | ||
16628 | value = null; | ||
16629 | if(elem == null) | ||
16630 | return false; | ||
16631 | |||
16632 | object spec; | ||
16633 | spec = specifiers.Data[level]; | ||
16634 | |||
16635 | bool haveVal = false; | ||
16636 | LitJson.JsonData next = null; | ||
16637 | |||
16638 | if (elem.GetJsonType() == LitJson.JsonType.Array) | ||
16639 | { | ||
16640 | if (spec is LSL_Integer) | ||
16641 | { | ||
16642 | int indx = (LSL_Integer)spec; | ||
16643 | if(indx >= 0 && indx < elem.Count) | ||
16644 | { | ||
16645 | haveVal = true; | ||
16646 | next = (LitJson.JsonData)elem[indx]; | ||
16647 | } | ||
16648 | } | ||
16649 | } | ||
16650 | else if (elem.GetJsonType() == LitJson.JsonType.Object) | ||
16651 | { | ||
16652 | if (spec is LSL_String) | ||
16653 | { | ||
16654 | IOrderedDictionary e = elem as IOrderedDictionary; | ||
16655 | string key = (LSL_String)spec; | ||
16656 | if(e.Contains(key)) | ||
16657 | { | ||
16658 | haveVal = true; | ||
16659 | next = (LitJson.JsonData)e[key]; | ||
16660 | } | ||
16661 | } | ||
16662 | } | ||
16663 | |||
16664 | if (haveVal) | ||
16665 | { | ||
16666 | if(level == specifiers.Data.Length - 1) | ||
16667 | { | ||
16668 | value = next; | ||
16669 | return true; | ||
16670 | } | ||
16671 | |||
16672 | level++; | ||
16673 | if(next == null) | ||
16674 | return false; | ||
16675 | |||
16676 | LitJson.JsonType nextType = next.GetJsonType(); | ||
16677 | if(nextType != LitJson.JsonType.Object && nextType != LitJson.JsonType.Array) | ||
16678 | return false; | ||
16679 | |||
16680 | return JsonFind(next, specifiers, level, out value); | ||
16681 | } | ||
16682 | return false; | ||
16683 | } | ||
16684 | |||
16685 | public LSL_String llJsonGetValue(LSL_String json, LSL_List specifiers) | ||
16686 | { | ||
16687 | if(String.IsNullOrWhiteSpace(json)) | ||
16688 | return ScriptBaseClass.JSON_INVALID; | ||
16689 | |||
16690 | if(specifiers.Length > 0 && (json == "{}" || json == "[]")) | ||
16691 | return ScriptBaseClass.JSON_INVALID; | ||
16692 | |||
16693 | char first = ((string)json)[0]; | ||
16694 | if((first != '[' && first !='{')) | ||
16695 | { | ||
16696 | if(specifiers.Length > 0) | ||
16697 | return ScriptBaseClass.JSON_INVALID; | ||
16698 | json = "[" + json + "]"; // could handle single element case.. but easier like this | ||
16699 | specifiers.Add((LSL_Integer)0); | ||
16700 | } | ||
16701 | |||
16702 | LitJson.JsonData jsonData; | ||
16703 | try | ||
16704 | { | ||
16705 | jsonData = LitJson.JsonMapper.ToObject(json); | ||
16706 | } | ||
16707 | catch (Exception e) | ||
16708 | { | ||
16709 | string m = e.Message; // debug point | ||
16710 | return ScriptBaseClass.JSON_INVALID; | ||
16711 | } | ||
16712 | |||
16713 | LitJson.JsonData elem = null; | ||
16714 | if(specifiers.Length == 0) | ||
16715 | elem = jsonData; | ||
16716 | else | ||
16717 | { | ||
16718 | if(!JsonFind(jsonData, specifiers, 0, out elem)) | ||
16719 | return ScriptBaseClass.JSON_INVALID; | ||
16720 | } | ||
16721 | return JsonElementToString(elem); | ||
16722 | } | ||
16723 | |||
16724 | private LSL_String JsonElementToString(LitJson.JsonData elem) | ||
16725 | { | ||
16726 | if(elem == null) | ||
16727 | return ScriptBaseClass.JSON_NULL; | ||
16728 | |||
16729 | LitJson.JsonType elemType = elem.GetJsonType(); | ||
16730 | switch(elemType) | ||
16731 | { | ||
16732 | case LitJson.JsonType.Array: | ||
16733 | return new LSL_String(LitJson.JsonMapper.ToJson(elem)); | ||
16734 | case LitJson.JsonType.Boolean: | ||
16735 | return new LSL_String((bool)elem ? ScriptBaseClass.JSON_TRUE : ScriptBaseClass.JSON_FALSE); | ||
16736 | case LitJson.JsonType.Double: | ||
16737 | double d= (double)elem; | ||
16738 | string sd = String.Format(Culture.FormatProvider, "{0:0.0#####}",d); | ||
16739 | return new LSL_String(sd); | ||
16740 | case LitJson.JsonType.Int: | ||
16741 | int i = (int)elem; | ||
16742 | return new LSL_String(i.ToString()); | ||
16743 | case LitJson.JsonType.Long: | ||
16744 | long l = (long)elem; | ||
16745 | return new LSL_String(l.ToString()); | ||
16746 | case LitJson.JsonType.Object: | ||
16747 | return new LSL_String(LitJson.JsonMapper.ToJson(elem)); | ||
16748 | case LitJson.JsonType.String: | ||
16749 | string s = (string)elem; | ||
16750 | return new LSL_String(s); | ||
16751 | case LitJson.JsonType.None: | ||
16752 | return ScriptBaseClass.JSON_NULL; | ||
16753 | default: | ||
16754 | return ScriptBaseClass.JSON_INVALID; | ||
16755 | } | ||
16756 | } | ||
16757 | |||
16758 | public LSL_String llJsonValueType(LSL_String json, LSL_List specifiers) | ||
16759 | { | ||
16760 | if(String.IsNullOrWhiteSpace(json)) | ||
16761 | return ScriptBaseClass.JSON_INVALID; | ||
16762 | |||
16763 | if(specifiers.Length > 0 && (json == "{}" || json == "[]")) | ||
16764 | return ScriptBaseClass.JSON_INVALID; | ||
16765 | |||
16766 | char first = ((string)json)[0]; | ||
16767 | if((first != '[' && first !='{')) | ||
16768 | { | ||
16769 | if(specifiers.Length > 0) | ||
16770 | return ScriptBaseClass.JSON_INVALID; | ||
16771 | json = "[" + json + "]"; // could handle single element case.. but easier like this | ||
16772 | specifiers.Add((LSL_Integer)0); | ||
16773 | } | ||
16774 | |||
16775 | LitJson.JsonData jsonData; | ||
16776 | try | ||
16777 | { | ||
16778 | jsonData = LitJson.JsonMapper.ToObject(json); | ||
16779 | } | ||
16780 | catch (Exception e) | ||
16781 | { | ||
16782 | string m = e.Message; // debug point | ||
16783 | return ScriptBaseClass.JSON_INVALID; | ||
16784 | } | ||
16785 | |||
16786 | LitJson.JsonData elem = null; | ||
16787 | if(specifiers.Length == 0) | ||
16788 | elem = jsonData; | ||
16789 | else | ||
16790 | { | ||
16791 | if(!JsonFind(jsonData, specifiers, 0, out elem)) | ||
16792 | return ScriptBaseClass.JSON_INVALID; | ||
16793 | } | ||
16794 | |||
16795 | if(elem == null) | ||
16796 | return ScriptBaseClass.JSON_NULL; | ||
16797 | |||
16798 | LitJson.JsonType elemType = elem.GetJsonType(); | ||
16799 | switch(elemType) | ||
16800 | { | ||
16801 | case LitJson.JsonType.Array: | ||
16802 | return ScriptBaseClass.JSON_ARRAY; | ||
16803 | case LitJson.JsonType.Boolean: | ||
16804 | return (bool)elem ? ScriptBaseClass.JSON_TRUE : ScriptBaseClass.JSON_FALSE; | ||
16805 | case LitJson.JsonType.Double: | ||
16806 | case LitJson.JsonType.Int: | ||
16807 | case LitJson.JsonType.Long: | ||
16808 | return ScriptBaseClass.JSON_NUMBER; | ||
16809 | case LitJson.JsonType.Object: | ||
16810 | return ScriptBaseClass.JSON_OBJECT; | ||
16811 | case LitJson.JsonType.String: | ||
16812 | string s = (string)elem; | ||
16813 | if(s == ScriptBaseClass.JSON_NULL) | ||
16814 | return ScriptBaseClass.JSON_NULL; | ||
16815 | if(s == ScriptBaseClass.JSON_TRUE) | ||
16816 | return ScriptBaseClass.JSON_TRUE; | ||
16817 | if(s == ScriptBaseClass.JSON_FALSE) | ||
16818 | return ScriptBaseClass.JSON_FALSE; | ||
16819 | return ScriptBaseClass.JSON_STRING; | ||
16820 | case LitJson.JsonType.None: | ||
16821 | return ScriptBaseClass.JSON_NULL; | ||
16822 | default: | ||
16823 | return ScriptBaseClass.JSON_INVALID; | ||
16824 | } | ||
16825 | } | ||
14984 | } | 16826 | } |
14985 | 16827 | ||
14986 | public class NotecardCache | 16828 | public class NotecardCache |