aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/Api/Implementation
diff options
context:
space:
mode:
authoronefang2019-09-11 16:36:50 +1000
committeronefang2019-09-11 16:36:50 +1000
commit50cd1ffd32f69228e566f2b0b89f86ea0d9fe489 (patch)
tree52f2ab0c04f1a5d7d6ac5dc872981b4b156447e7 /OpenSim/Region/ScriptEngine/Shared/Api/Implementation
parentRenamed branch to SledjChisl. (diff)
parentBump to release flavour, build 0. (diff)
downloadopensim-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 '')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs123
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs128
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs6280
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs84
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs1954
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs62
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs34
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs10
9 files changed, 5698 insertions, 2998 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 036cb5d..e01d2e4 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -28,9 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Reflection;
32using System.Threading; 31using System.Threading;
33using log4net;
34using OpenMetaverse; 32using OpenMetaverse;
35using OpenSim.Framework; 33using OpenSim.Framework;
36using OpenSim.Framework.Monitoring; 34using OpenSim.Framework.Monitoring;
@@ -39,6 +37,8 @@ using OpenSim.Region.ScriptEngine.Interfaces;
39using OpenSim.Region.ScriptEngine.Shared; 37using OpenSim.Region.ScriptEngine.Shared;
40using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; 38using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
41using Timer=OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer; 39using Timer=OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer;
40using System.Reflection;
41using log4net;
42 42
43namespace OpenSim.Region.ScriptEngine.Shared.Api 43namespace OpenSim.Region.ScriptEngine.Shared.Api
44{ 44{
@@ -51,7 +51,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
51 51
52 private static Thread cmdHandlerThread; 52 private static Thread cmdHandlerThread;
53 private static int cmdHandlerThreadCycleSleepms; 53 private static int cmdHandlerThreadCycleSleepms;
54 54 private static int numInstances;
55 /// <summary> 55 /// <summary>
56 /// Lock for reading/writing static components of AsyncCommandManager. 56 /// Lock for reading/writing static components of AsyncCommandManager.
57 /// </summary> 57 /// </summary>
@@ -81,64 +81,64 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
81 81
82 public Dataserver DataserverPlugin 82 public Dataserver DataserverPlugin
83 { 83 {
84 get 84 get
85 { 85 {
86 lock (staticLock) 86 lock (staticLock)
87 return m_Dataserver[m_ScriptEngine]; 87 return m_Dataserver[m_ScriptEngine];
88 } 88 }
89 } 89 }
90 90
91 public Timer TimerPlugin 91 public Timer TimerPlugin
92 { 92 {
93 get 93 get
94 { 94 {
95 lock (staticLock) 95 lock (staticLock)
96 return m_Timer[m_ScriptEngine]; 96 return m_Timer[m_ScriptEngine];
97 } 97 }
98 } 98 }
99 99
100 public HttpRequest HttpRequestPlugin 100 public HttpRequest HttpRequestPlugin
101 { 101 {
102 get 102 get
103 { 103 {
104 lock (staticLock) 104 lock (staticLock)
105 return m_HttpRequest[m_ScriptEngine]; 105 return m_HttpRequest[m_ScriptEngine];
106 } 106 }
107 } 107 }
108 108
109 public Listener ListenerPlugin 109 public Listener ListenerPlugin
110 { 110 {
111 get 111 get
112 { 112 {
113 lock (staticLock) 113 lock (staticLock)
114 return m_Listener[m_ScriptEngine]; 114 return m_Listener[m_ScriptEngine];
115 } 115 }
116 } 116 }
117 117
118 public SensorRepeat SensorRepeatPlugin 118 public SensorRepeat SensorRepeatPlugin
119 { 119 {
120 get 120 get
121 { 121 {
122 lock (staticLock) 122 lock (staticLock)
123 return m_SensorRepeat[m_ScriptEngine]; 123 return m_SensorRepeat[m_ScriptEngine];
124 } 124 }
125 } 125 }
126 126
127 public XmlRequest XmlRequestPlugin 127 public XmlRequest XmlRequestPlugin
128 { 128 {
129 get 129 get
130 { 130 {
131 lock (staticLock) 131 lock (staticLock)
132 return m_XmlRequest[m_ScriptEngine]; 132 return m_XmlRequest[m_ScriptEngine];
133 } 133 }
134 } 134 }
135 135
136 public IScriptEngine[] ScriptEngines 136 public IScriptEngine[] ScriptEngines
137 { 137 {
138 get 138 get
139 { 139 {
140 lock (staticLock) 140 lock (staticLock)
141 return m_ScriptEngines.ToArray(); 141 return m_ScriptEngines.ToArray();
142 } 142 }
143 } 143 }
144 144
@@ -172,18 +172,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
172 if (!m_XmlRequest.ContainsKey(m_ScriptEngine)) 172 if (!m_XmlRequest.ContainsKey(m_ScriptEngine))
173 m_XmlRequest[m_ScriptEngine] = new XmlRequest(this); 173 m_XmlRequest[m_ScriptEngine] = new XmlRequest(this);
174 174
175 StartThread(); 175 numInstances++;
176 } 176 if (cmdHandlerThread == null)
177 } 177 {
178 178 cmdHandlerThread = WorkManager.StartThread(
179 private static void StartThread()
180 {
181 if (cmdHandlerThread == null)
182 {
183 // Start the thread that will be doing the work
184 cmdHandlerThread
185 = WorkManager.StartThread(
186 CmdHandlerThreadLoop, "AsyncLSLCmdHandlerThread", ThreadPriority.Normal, true, true); 179 CmdHandlerThreadLoop, "AsyncLSLCmdHandlerThread", ThreadPriority.Normal, true, true);
180 }
187 } 181 }
188 } 182 }
189 183
@@ -194,25 +188,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
194 cmdHandlerThreadCycleSleepms = 100; 188 cmdHandlerThreadCycleSleepms = 100;
195 } 189 }
196 190
191/*
197 ~AsyncCommandManager() 192 ~AsyncCommandManager()
198 { 193 {
199 // Shut down thread 194 // Shut down thread
200// try
201// {
202// if (cmdHandlerThread != null)
203// {
204// if (cmdHandlerThread.IsAlive == true)
205// {
206// cmdHandlerThread.Abort();
207// //cmdHandlerThread.Join();
208// }
209// }
210// }
211// catch
212// {
213// }
214 }
215 195
196 try
197 {
198 lock (staticLock)
199 {
200 numInstances--;
201 if(numInstances > 0)
202 return;
203 if (cmdHandlerThread != null)
204 {
205 if (cmdHandlerThread.IsAlive == true)
206 {
207 cmdHandlerThread.Abort();
208 //cmdHandlerThread.Join();
209 cmdHandlerThread = null;
210 }
211 }
212 }
213 }
214 catch
215 {
216 }
217 }
218*/
216 /// <summary> 219 /// <summary>
217 /// Main loop for the manager thread 220 /// Main loop for the manager thread
218 /// </summary> 221 /// </summary>
@@ -223,11 +226,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
223 try 226 try
224 { 227 {
225 Thread.Sleep(cmdHandlerThreadCycleSleepms); 228 Thread.Sleep(cmdHandlerThreadCycleSleepms);
226 229 Watchdog.UpdateThread();
227 DoOneCmdHandlerPass(); 230 DoOneCmdHandlerPass();
228
229 Watchdog.UpdateThread(); 231 Watchdog.UpdateThread();
230 } 232 }
233 catch ( System.Threading.ThreadAbortException) { }
231 catch (Exception e) 234 catch (Exception e)
232 { 235 {
233 m_log.Error("[ASYNC COMMAND MANAGER]: Exception in command handler pass: ", e); 236 m_log.Error("[ASYNC COMMAND MANAGER]: Exception in command handler pass: ", e);
@@ -240,24 +243,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
240 lock (staticLock) 243 lock (staticLock)
241 { 244 {
242 // Check HttpRequests 245 // Check HttpRequests
243 m_HttpRequest[m_ScriptEngines[0]].CheckHttpRequests(); 246 try { m_HttpRequest[m_ScriptEngines[0]].CheckHttpRequests(); } catch {}
244 247
245 // Check XMLRPCRequests 248 // Check XMLRPCRequests
246 m_XmlRequest[m_ScriptEngines[0]].CheckXMLRPCRequests(); 249 try { m_XmlRequest[m_ScriptEngines[0]].CheckXMLRPCRequests(); } catch {}
247 250
248 foreach (IScriptEngine s in m_ScriptEngines) 251 foreach (IScriptEngine s in m_ScriptEngines)
249 { 252 {
250 // Check Listeners 253 // Check Listeners
251 m_Listener[s].CheckListeners(); 254 try { m_Listener[s].CheckListeners(); } catch {}
255
252 256
253 // Check timers 257 // Check timers
254 m_Timer[s].CheckTimerEvents(); 258 try { m_Timer[s].CheckTimerEvents(); } catch {}
255 259
256 // Check Sensors 260 // Check Sensors
257 m_SensorRepeat[s].CheckSenseRepeaterEvents(); 261 try { m_SensorRepeat[s].CheckSenseRepeaterEvents(); } catch {}
258 262
259 // Check dataserver 263 // Check dataserver
260 m_Dataserver[s].ExpireRequests(); 264 try { m_Dataserver[s].ExpireRequests(); } catch {}
261 } 265 }
262 } 266 }
263 } 267 }
@@ -269,6 +273,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
269 /// <param name="itemID"></param> 273 /// <param name="itemID"></param>
270 public static void RemoveScript(IScriptEngine engine, uint localID, UUID itemID) 274 public static void RemoveScript(IScriptEngine engine, uint localID, UUID itemID)
271 { 275 {
276 // Remove a specific script
272// m_log.DebugFormat("[ASYNC COMMAND MANAGER]: Removing facilities for script {0}", itemID); 277// m_log.DebugFormat("[ASYNC COMMAND MANAGER]: Removing facilities for script {0}", itemID);
273 278
274 lock (staticLock) 279 lock (staticLock)
@@ -282,7 +287,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
282 // Remove from: HttpRequest 287 // Remove from: HttpRequest
283 IHttpRequestModule iHttpReq = engine.World.RequestModuleInterface<IHttpRequestModule>(); 288 IHttpRequestModule iHttpReq = engine.World.RequestModuleInterface<IHttpRequestModule>();
284 if (iHttpReq != null) 289 if (iHttpReq != null)
285 iHttpReq.StopHttpRequestsForScript(itemID); 290 iHttpReq.StopHttpRequest(localID, itemID);
286 291
287 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>(); 292 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
288 if (comms != null) 293 if (comms != null)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
new file mode 100644
index 0000000..c848555
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,128 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Threading;
30using System.Reflection;
31using System.Collections;
32using System.Collections.Generic;
33using System.Runtime.Remoting.Lifetime;
34using OpenMetaverse;
35using Nini.Config;
36using OpenSim;
37using OpenSim.Framework;
38using OpenSim.Region.CoreModules.World.LightShare;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Region.ScriptEngine.Shared;
42using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
43using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
44using OpenSim.Region.ScriptEngine.Interfaces;
45using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
46using OpenSim.Services.Interfaces;
47
48using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
49using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
50using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
51using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
52using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
53using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
54using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
55
56namespace OpenSim.Region.ScriptEngine.Shared.Api
57{
58 [Serializable]
59 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
60 {
61 internal IScriptEngine m_ScriptEngine;
62 internal SceneObjectPart m_host;
63 internal TaskInventoryItem m_item;
64 internal bool m_CMFunctionsEnabled = false;
65
66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
67 {
68 m_ScriptEngine = ScriptEngine;
69 m_host = host;
70 m_item = item;
71
72 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
73 m_CMFunctionsEnabled = true;
74 }
75
76 public override Object InitializeLifetimeService()
77 {
78 ILease lease = (ILease)base.InitializeLifetimeService();
79
80 if (lease.CurrentState == LeaseState.Initial)
81 {
82 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
83// lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
84// lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
85 }
86 return lease;
87 }
88
89 public Scene World
90 {
91 get { return m_ScriptEngine.World; }
92 }
93
94 public string cmDetectedCountry(int number)
95 {
96 if(!m_CMFunctionsEnabled)
97 return String.Empty;
98 if(World.UserAccountService == null)
99 return String.Empty;
100 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
101 if (detectedParams == null)
102 return String.Empty;
103 UUID key = detectedParams.Key;
104 if(key == UUID.Zero)
105 return String.Empty;
106 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, key);
107 return account.UserCountry;
108 }
109
110 public string cmGetAgentCountry(LSL_Key key)
111 {
112 if(! m_CMFunctionsEnabled)
113 return "";
114 if(World.UserAccountService == null)
115 return String.Empty;
116 if (!World.Permissions.IsGod(m_host.OwnerID))
117 return String.Empty;
118
119 UUID uuid;
120
121 if (!UUID.TryParse(key, out uuid))
122 return String.Empty;
123
124 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
125 return account.UserCountry;
126 }
127 }
128}
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 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Collections.Specialized;
31using System.Diagnostics; 32using System.Diagnostics;
32using System.Drawing; 33using System.Drawing;
33using System.Drawing.Imaging; 34using System.Drawing.Imaging;
@@ -35,10 +36,12 @@ using System.Runtime.Remoting.Lifetime;
35using System.Text; 36using System.Text;
36using System.Threading; 37using System.Threading;
37using System.Text.RegularExpressions; 38using System.Text.RegularExpressions;
39using System.Timers;
38using Nini.Config; 40using Nini.Config;
39using log4net; 41using log4net;
40using OpenMetaverse; 42using OpenMetaverse;
41using OpenMetaverse.Assets; 43using OpenMetaverse.Assets;
44using OpenMetaverse.StructuredData; // LitJson is hidden on this
42using OpenMetaverse.Packets; 45using OpenMetaverse.Packets;
43using OpenMetaverse.Rendering; 46using OpenMetaverse.Rendering;
44using OpenSim; 47using OpenSim;
@@ -49,6 +52,7 @@ using OpenSim.Region.CoreModules.World.Land;
49using OpenSim.Region.CoreModules.World.Terrain; 52using OpenSim.Region.CoreModules.World.Terrain;
50using OpenSim.Region.Framework.Interfaces; 53using OpenSim.Region.Framework.Interfaces;
51using OpenSim.Region.Framework.Scenes; 54using OpenSim.Region.Framework.Scenes;
55using OpenSim.Region.Framework.Scenes.Serialization;
52using OpenSim.Region.Framework.Scenes.Animation; 56using OpenSim.Region.Framework.Scenes.Animation;
53using OpenSim.Region.Framework.Scenes.Scripting; 57using OpenSim.Region.Framework.Scenes.Scripting;
54using OpenSim.Region.PhysicsModules.SharedBase; 58using OpenSim.Region.PhysicsModules.SharedBase;
@@ -72,6 +76,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
72using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 76using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
73using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 77using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
74using System.Reflection; 78using System.Reflection;
79using Timer = System.Timers.Timer;
75using System.Linq; 80using System.Linq;
76using PermissionMask = OpenSim.Framework.PermissionMask; 81using 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
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
index e5e43f8..e50b7fd 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
@@ -120,7 +120,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
120 LSShoutError("LightShare functions are not enabled."); 120 LSShoutError("LightShare functions are not enabled.");
121 return new LSL_List(); 121 return new LSL_List();
122 } 122 }
123 m_host.AddScriptLPS(1);
124 RegionLightShareData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings; 123 RegionLightShareData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings;
125 124
126 LSL_List values = new LSL_List(); 125 LSL_List values = new LSL_List();
@@ -295,7 +294,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
295 idx++; 294 idx++;
296 try 295 try
297 { 296 {
298 iQ = rules.GetQuaternionItem(idx); 297 iQ = rules.GetVector4Item(idx);
299 } 298 }
300 catch (InvalidCastException) 299 catch (InvalidCastException)
301 { 300 {
@@ -319,7 +318,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
319 idx++; 318 idx++;
320 try 319 try
321 { 320 {
322 iQ = rules.GetQuaternionItem(idx); 321 iQ = rules.GetVector4Item(idx);
323 } 322 }
324 catch (InvalidCastException) 323 catch (InvalidCastException)
325 { 324 {
@@ -342,7 +341,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
342 idx++; 341 idx++;
343 try 342 try
344 { 343 {
345 iQ = rules.GetQuaternionItem(idx); 344 iQ = rules.GetVector4Item(idx);
346 } 345 }
347 catch (InvalidCastException) 346 catch (InvalidCastException)
348 { 347 {
@@ -532,7 +531,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
532 idx++; 531 idx++;
533 try 532 try
534 { 533 {
535 iQ = rules.GetQuaternionItem(idx); 534 iQ = rules.GetVector4Item(idx);
536 } 535 }
537 catch (InvalidCastException) 536 catch (InvalidCastException)
538 { 537 {
@@ -654,7 +653,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
654 break; 653 break;
655 case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: 654 case (int)ScriptBaseClass.WL_SUN_MOON_COLOR:
656 idx++; 655 idx++;
657 iQ = rules.GetQuaternionItem(idx); 656 iQ = rules.GetVector4Item(idx);
658 try 657 try
659 { 658 {
660 wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); 659 wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
@@ -721,7 +720,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
721 { 720 {
722 ScenePresence sp = World.GetScenePresence(m_host.OwnerID); 721 ScenePresence sp = World.GetScenePresence(m_host.OwnerID);
723 722
724 if (sp == null || sp.GodLevel < 200) 723 if (sp == null || !sp.IsViewerUIGod)
725 { 724 {
726 LSShoutError("lsSetWindlightScene can only be used by estate managers or owners."); 725 LSShoutError("lsSetWindlightScene can only be used by estate managers or owners.");
727 return 0; 726 return 0;
@@ -729,7 +728,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
729 } 728 }
730 729
731 int success = 0; 730 int success = 0;
732 m_host.AddScriptLPS(1);
733 731
734 if (LightShareModule.EnableWindlight) 732 if (LightShareModule.EnableWindlight)
735 { 733 {
@@ -768,7 +766,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
768 { 766 {
769 ScenePresence sp = World.GetScenePresence(m_host.OwnerID); 767 ScenePresence sp = World.GetScenePresence(m_host.OwnerID);
770 768
771 if (sp == null || sp.GodLevel < 200) 769 if (sp == null || !sp.IsViewerUIGod)
772 { 770 {
773 LSShoutError("lsSetWindlightScene can only be used by estate managers or owners."); 771 LSShoutError("lsSetWindlightScene can only be used by estate managers or owners.");
774 return; 772 return;
@@ -799,7 +797,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
799 { 797 {
800 ScenePresence sp = World.GetScenePresence(m_host.OwnerID); 798 ScenePresence sp = World.GetScenePresence(m_host.OwnerID);
801 799
802 if (sp == null || sp.GodLevel < 200) 800 if (sp == null || !sp.IsViewerUIGod)
803 { 801 {
804 LSShoutError("lsSetWindlightSceneTargeted can only be used by estate managers or owners."); 802 LSShoutError("lsSetWindlightSceneTargeted can only be used by estate managers or owners.");
805 return 0; 803 return 0;
@@ -807,7 +805,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
807 } 805 }
808 806
809 int success = 0; 807 int success = 0;
810 m_host.AddScriptLPS(1);
811 808
812 if (LightShareModule.EnableWindlight) 809 if (LightShareModule.EnableWindlight)
813 { 810 {
@@ -831,6 +828,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
831 } 828 }
832 829
833 return success; 830 return success;
834 } 831 }
835 } 832 }
836} 833}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
index 1458c95..692bec0 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
@@ -107,14 +107,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
107 /// Dumps an error message on the debug console. 107 /// Dumps an error message on the debug console.
108 /// </summary> 108 /// </summary>
109 /// <param name='message'></param> 109 /// <param name='message'></param>
110 internal void MODShoutError(string message) 110 internal void MODShoutError(string message)
111 { 111 {
112 if (message.Length > 1023) 112 if (message.Length > 1023)
113 message = message.Substring(0, 1023); 113 message = message.Substring(0, 1023);
114 114
115 World.SimChat( 115 World.SimChat(
116 Utils.StringToBytes(message), 116 Utils.StringToBytes(message),
117 ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, 117 ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL,
118 m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, false); 118 m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, false);
119 119
120 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 120 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
@@ -122,7 +122,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
122 } 122 }
123 123
124 /// <summary> 124 /// <summary>
125 /// 125 ///
126 /// </summary> 126 /// </summary>
127 /// <param name="fname">The name of the function to invoke</param> 127 /// <param name="fname">The name of the function to invoke</param>
128 /// <param name="parms">List of parameters</param> 128 /// <param name="parms">List of parameters</param>
@@ -130,13 +130,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
130 public void modInvokeN(string fname, params object[] parms) 130 public void modInvokeN(string fname, params object[] parms)
131 { 131 {
132// m_log.DebugFormat( 132// m_log.DebugFormat(
133// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type", 133// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type",
134// fname, 134// fname,
135// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())), 135// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())),
136// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); 136// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
137 137
138 Type returntype = m_comms.LookupReturnType(fname); 138 Type returntype = m_comms.LookupReturnType(fname);
139 if (returntype != typeof(string)) 139 if (returntype != typeof(void))
140 MODError(String.Format("return type mismatch for {0}",fname)); 140 MODError(String.Format("return type mismatch for {0}",fname));
141 141
142 modInvoke(fname,parms); 142 modInvoke(fname,parms);
@@ -145,9 +145,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
145 public LSL_String modInvokeS(string fname, params object[] parms) 145 public LSL_String modInvokeS(string fname, params object[] parms)
146 { 146 {
147// m_log.DebugFormat( 147// m_log.DebugFormat(
148// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type", 148// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type",
149// fname, 149// fname,
150// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())), 150// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())),
151// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); 151// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
152 152
153 Type returntype = m_comms.LookupReturnType(fname); 153 Type returntype = m_comms.LookupReturnType(fname);
@@ -161,9 +161,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
161 public LSL_Integer modInvokeI(string fname, params object[] parms) 161 public LSL_Integer modInvokeI(string fname, params object[] parms)
162 { 162 {
163// m_log.DebugFormat( 163// m_log.DebugFormat(
164// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type", 164// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type",
165// fname, 165// fname,
166// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())), 166// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())),
167// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); 167// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
168 168
169 Type returntype = m_comms.LookupReturnType(fname); 169 Type returntype = m_comms.LookupReturnType(fname);
@@ -173,13 +173,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
173 int result = (int)modInvoke(fname,parms); 173 int result = (int)modInvoke(fname,parms);
174 return new LSL_Integer(result); 174 return new LSL_Integer(result);
175 } 175 }
176 176
177 public LSL_Float modInvokeF(string fname, params object[] parms) 177 public LSL_Float modInvokeF(string fname, params object[] parms)
178 { 178 {
179// m_log.DebugFormat( 179// m_log.DebugFormat(
180// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type", 180// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type",
181// fname, 181// fname,
182// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())), 182// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())),
183// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); 183// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
184 184
185 Type returntype = m_comms.LookupReturnType(fname); 185 Type returntype = m_comms.LookupReturnType(fname);
@@ -193,9 +193,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
193 public LSL_Key modInvokeK(string fname, params object[] parms) 193 public LSL_Key modInvokeK(string fname, params object[] parms)
194 { 194 {
195// m_log.DebugFormat( 195// m_log.DebugFormat(
196// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type", 196// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type",
197// fname, 197// fname,
198// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())), 198// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())),
199// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); 199// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
200 200
201 Type returntype = m_comms.LookupReturnType(fname); 201 Type returntype = m_comms.LookupReturnType(fname);
@@ -209,9 +209,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
209 public LSL_Vector modInvokeV(string fname, params object[] parms) 209 public LSL_Vector modInvokeV(string fname, params object[] parms)
210 { 210 {
211// m_log.DebugFormat( 211// m_log.DebugFormat(
212// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type", 212// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type",
213// fname, 213// fname,
214// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())), 214// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())),
215// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); 215// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
216 216
217 Type returntype = m_comms.LookupReturnType(fname); 217 Type returntype = m_comms.LookupReturnType(fname);
@@ -225,9 +225,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
225 public LSL_Rotation modInvokeR(string fname, params object[] parms) 225 public LSL_Rotation modInvokeR(string fname, params object[] parms)
226 { 226 {
227// m_log.DebugFormat( 227// m_log.DebugFormat(
228// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type", 228// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type",
229// fname, 229// fname,
230// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())), 230// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())),
231// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); 231// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
232 232
233 Type returntype = m_comms.LookupReturnType(fname); 233 Type returntype = m_comms.LookupReturnType(fname);
@@ -241,9 +241,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
241 public LSL_List modInvokeL(string fname, params object[] parms) 241 public LSL_List modInvokeL(string fname, params object[] parms)
242 { 242 {
243// m_log.DebugFormat( 243// m_log.DebugFormat(
244// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type", 244// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type",
245// fname, 245// fname,
246// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())), 246// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())),
247// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); 247// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
248 248
249 Type returntype = m_comms.LookupReturnType(fname); 249 Type returntype = m_comms.LookupReturnType(fname);
@@ -308,27 +308,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
308 } 308 }
309 309
310// m_log.DebugFormat( 310// m_log.DebugFormat(
311// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type", 311// "[MOD API]: Invoking dynamic function {0}, args '{1}' with {2} return type",
312// fname, 312// fname,
313// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())), 313// string.Join(",", Array.ConvertAll<object, string>(parms, o => o.ToString())),
314// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); 314// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
315 315
316 Type[] signature = m_comms.LookupTypeSignature(fname); 316 Type[] signature = m_comms.LookupTypeSignature(fname);
317 if (signature.Length != parms.Length) 317 if (signature.Length != parms.Length)
318 MODError(String.Format("wrong number of parameters to function {0}",fname)); 318 MODError(String.Format("wrong number of parameters to function {0}",fname));
319 319
320 object[] convertedParms = new object[parms.Length]; 320 object[] convertedParms = new object[parms.Length];
321 for (int i = 0; i < parms.Length; i++) 321 for (int i = 0; i < parms.Length; i++)
322 convertedParms[i] = ConvertFromLSL(parms[i], signature[i], fname); 322 convertedParms[i] = ConvertFromLSL(parms[i], signature[i], fname);
323 323
324 // now call the function, the contract with the function is that it will always return 324 // now call the function, the contract with the function is that it will always return
325 // non-null but don't trust it completely 325 // non-null but don't trust it completely
326 try 326 try
327 { 327 {
328 object result = m_comms.InvokeOperation(m_host.UUID, m_item.ItemID, fname, convertedParms); 328 object result = m_comms.InvokeOperation(m_host.UUID, m_item.ItemID, fname, convertedParms);
329 if (result != null) 329 if (result != null)
330 return result; 330 return result;
331 331
332 Type returntype = m_comms.LookupReturnType(fname);
333 if (returntype == typeof(void))
334 return null;
335
332 MODError(String.Format("Invocation of {0} failed; null return value",fname)); 336 MODError(String.Format("Invocation of {0} failed; null return value",fname));
333 } 337 }
334 catch (Exception e) 338 catch (Exception e)
@@ -338,7 +342,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
338 342
339 return null; 343 return null;
340 } 344 }
341 345
342 /// <summary> 346 /// <summary>
343 /// Send a command to functions registered on an event 347 /// Send a command to functions registered on an event
344 /// </summary> 348 /// </summary>
@@ -361,8 +365,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
361 /// </summary> 365 /// </summary>
362 protected object ConvertFromLSL(object lslparm, Type type, string fname) 366 protected object ConvertFromLSL(object lslparm, Type type, string fname)
363 { 367 {
368
369 if(lslparm.GetType() == type)
370 return lslparm;
371
364 // ---------- String ---------- 372 // ---------- String ----------
365 if (lslparm is LSL_String) 373 else if (lslparm is LSL_String)
366 { 374 {
367 if (type == typeof(string)) 375 if (type == typeof(string))
368 return (string)(LSL_String)lslparm; 376 return (string)(LSL_String)lslparm;
@@ -421,7 +429,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
421 for (int i = 0; i < plist.Length; i++) 429 for (int i = 0; i < plist.Length; i++)
422 { 430 {
423 if (plist[i] is LSL_String) 431 if (plist[i] is LSL_String)
424 result[i] = (string)(LSL_String)plist[i]; 432 result[i] = (string)(LSL_String)plist[i];
425 else if (plist[i] is LSL_Integer) 433 else if (plist[i] is LSL_Integer)
426 result[i] = (int)(LSL_Integer)plist[i]; 434 result[i] = (int)(LSL_Integer)plist[i];
427 // The int check exists because of the many plain old int script constants in ScriptBase which 435 // The int check exists because of the many plain old int script constants in ScriptBase which
@@ -443,7 +451,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
443 return result; 451 return result;
444 } 452 }
445 } 453 }
446 454
447 MODError(String.Format("{0}: parameter type mismatch; expecting {1}, type(parm)={2}", fname, type.Name, lslparm.GetType())); 455 MODError(String.Format("{0}: parameter type mismatch; expecting {1}, type(parm)={2}", fname, type.Name, lslparm.GetType()));
448 return null; 456 return null;
449 } 457 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 83aa245..a8c1a8f 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -45,6 +45,7 @@ using OpenSim.Framework;
45using OpenSim.Framework.Console; 45using OpenSim.Framework.Console;
46using OpenSim.Region.Framework.Interfaces; 46using OpenSim.Region.Framework.Interfaces;
47using OpenSim.Region.Framework.Scenes; 47using OpenSim.Region.Framework.Scenes;
48using OpenSim.Region.Framework.Scenes.Scripting;
48using OpenSim.Region.ScriptEngine.Shared; 49using OpenSim.Region.ScriptEngine.Shared;
49using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; 50using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
50using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 51using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
@@ -138,8 +139,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
138 internal TaskInventoryItem m_item; 139 internal TaskInventoryItem m_item;
139 internal bool m_OSFunctionsEnabled = false; 140 internal bool m_OSFunctionsEnabled = false;
140 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 141 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
142 internal bool m_debuggerSafe = false;
141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 143 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
142
143 protected IUrlModule m_UrlModule = null; 144 protected IUrlModule m_UrlModule = null;
144 145
145 public void Initialize( 146 public void Initialize(
@@ -148,6 +149,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
148 m_ScriptEngine = scriptEngine; 149 m_ScriptEngine = scriptEngine;
149 m_host = host; 150 m_host = host;
150 m_item = item; 151 m_item = item;
152 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
151 153
152 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 154 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
153 155
@@ -187,7 +189,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
187 default: 189 default:
188 break; 190 break;
189 } 191 }
190 } 192 }
191 193
192 public override Object InitializeLifetimeService() 194 public override Object InitializeLifetimeService()
193 { 195 {
@@ -209,7 +211,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
209 211
210 internal void OSSLError(string msg) 212 internal void OSSLError(string msg)
211 { 213 {
212 OSSLShoutError("OSSL Runtime Error: " + msg); 214 if (m_debuggerSafe)
215 OSSLShoutError(msg);
216 else
217 {
218 throw new ScriptException("OSSL Runtime Error: " + msg);
219 }
213 } 220 }
214 221
215 /// <summary> 222 /// <summary>
@@ -244,28 +251,40 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
244 wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); 251 wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message);
245 } 252 }
246 253
247 // Returns of the function is allowed. Throws a script exception if not allowed. 254 // Returns if OSSL is enabled. Throws a script exception if OSSL is not allowed..
248 public bool CheckThreatLevel(ThreatLevel level, string function) 255 // for safe funtions always active
256 public void CheckThreatLevel()
249 { 257 {
250 if (!m_OSFunctionsEnabled) 258 if (!m_OSFunctionsEnabled)
251 { 259 throw new ScriptException(String.Format("{0} permission denied. All OS functions are disabled."));
252 OSSLError(String.Format("{0} permission denied. All OS functions are disabled.", function)); 260 }
253 return false; 261
254 } 262 // Returns if the function is allowed. Throws a script exception if not allowed.
263 public void CheckThreatLevel(ThreatLevel level, string function)
264 {
265 if (!m_OSFunctionsEnabled)
266 throw new ScriptException(String.Format("{0} permission denied. All OS functions are disabled.", function));
255 267
256 string reasonWhyNot = CheckThreatLevelTest(level, function); 268 string reasonWhyNot = CheckThreatLevelTest(level, function);
257 if (!String.IsNullOrEmpty(reasonWhyNot)) 269 if (!String.IsNullOrEmpty(reasonWhyNot))
258 { 270 throw new ScriptException(reasonWhyNot);
259 OSSLError(reasonWhyNot);
260 return false;
261 }
262 return true;
263 } 271 }
264 272
265 // Check to see if function is allowed. Returns an empty string if function permitted 273 // Check to see if function is allowed. Returns an empty string if function permitted
266 // or a string explaining why this function can't be used. 274 // or a string explaining why this function can't be used.
267 private string CheckThreatLevelTest(ThreatLevel level, string function) 275 private string CheckThreatLevelTest(ThreatLevel level, string function)
268 { 276 {
277 // Grid gods can do anything they damn well please.
278 if (World.Permissions.IsGridGod(m_item.OwnerID))
279 return String.Empty;
280 else
281 {
282 // So can active gods.
283 ScenePresence sp = World.GetScenePresence(m_item.OwnerID);
284 if (sp != null && !sp.IsDeleted && sp.IsGod)
285 return String.Empty;
286 }
287
269 if (!m_FunctionPerms.ContainsKey(function)) 288 if (!m_FunctionPerms.ContainsKey(function))
270 { 289 {
271 FunctionPerms perms = new FunctionPerms(); 290 FunctionPerms perms = new FunctionPerms();
@@ -299,7 +318,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
299 foreach (string id in ids) 318 foreach (string id in ids)
300 { 319 {
301 string current = id.Trim(); 320 string current = id.Trim();
302 if (current.ToUpper() == "PARCEL_GROUP_MEMBER" || current.ToUpper() == "PARCEL_OWNER" || current.ToUpper() == "ESTATE_MANAGER" || current.ToUpper() == "ESTATE_OWNER") 321 if (current.ToUpper() == "PARCEL_GROUP_MEMBER" || current.ToUpper() == "PARCEL_OWNER" || current.ToUpper() == "ESTATE_MANAGER" || current.ToUpper() == "ESTATE_OWNER" || current.ToUpper() == "ACTIVE_GOD" || current.ToUpper() == "GRID_GOD" || current.ToUpper() == "GOD")
303 { 322 {
304 if (!perms.AllowedOwnerClasses.Contains(current)) 323 if (!perms.AllowedOwnerClasses.Contains(current))
305 perms.AllowedOwnerClasses.Add(current.ToUpper()); 324 perms.AllowedOwnerClasses.Add(current.ToUpper());
@@ -404,6 +423,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
404 } 423 }
405 } 424 }
406 425
426
427 //Only grid gods may use the function
428 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("GRID_GOD"))
429 {
430 if (World.Permissions.IsGridGod(ownerID))
431 {
432 return String.Empty;
433 }
434 }
435
436 //Any god may use the function
437 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("GOD"))
438 {
439 if (World.Permissions.IsAdministrator(ownerID))
440 {
441 return String.Empty;
442 }
443 }
444
445 //Only active gods may use the function
446 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("ACTIVE_GOD"))
447 {
448 ScenePresence sp = World.GetScenePresence(ownerID);
449 if (sp != null && !sp.IsDeleted && sp.IsGod)
450 {
451 return String.Empty;
452 }
453 }
454
407 if (!m_FunctionPerms[function].AllowedCreators.Contains(m_item.CreatorID)) 455 if (!m_FunctionPerms[function].AllowedCreators.Contains(m_item.CreatorID))
408 return( 456 return(
409 String.Format("{0} permission denied. Script creator is not in the list of users allowed to execute this function and prim owner also has no permission.", 457 String.Format("{0} permission denied. Script creator is not in the list of users allowed to execute this function and prim owner also has no permission.",
@@ -425,16 +473,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
425 OSSLShoutError(string.Format("Use of function {0} is deprecated. Use {1} instead.", function, replacement)); 473 OSSLShoutError(string.Format("Use of function {0} is deprecated. Use {1} instead.", function, replacement));
426 } 474 }
427 475
476//// protected void ScriptSleep(int delay)
477//// {
478//// delay = (int)((float)delay * m_ScriptDelayFactor);
479//// if (delay == 0)
480//// return;
481//// System.Threading.Thread.Sleep(delay);
482//// }
483
428 public LSL_Integer osSetTerrainHeight(int x, int y, double val) 484 public LSL_Integer osSetTerrainHeight(int x, int y, double val)
429 { 485 {
430 if (!CheckThreatLevel(ThreatLevel.High, "osSetTerrainHeight")) return 0; 486 CheckThreatLevel(ThreatLevel.High, "osSetTerrainHeight");
431 487
432 return SetTerrainHeight(x, y, val); 488 return SetTerrainHeight(x, y, val);
433 } 489 }
434 490
435 public LSL_Integer osTerrainSetHeight(int x, int y, double val) 491 public LSL_Integer osTerrainSetHeight(int x, int y, double val)
436 { 492 {
437 if (!CheckThreatLevel(ThreatLevel.High, "osTerrainSetHeight")) return 0; 493 CheckThreatLevel(ThreatLevel.High, "osTerrainSetHeight");
438 OSSLDeprecated("osTerrainSetHeight", "osSetTerrainHeight"); 494 OSSLDeprecated("osTerrainSetHeight", "osSetTerrainHeight");
439 495
440 return SetTerrainHeight(x, y, val); 496 return SetTerrainHeight(x, y, val);
@@ -442,8 +498,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
442 498
443 private LSL_Integer SetTerrainHeight(int x, int y, double val) 499 private LSL_Integer SetTerrainHeight(int x, int y, double val)
444 { 500 {
445 m_host.AddScriptLPS(1);
446
447 if (x > (World.RegionInfo.RegionSizeX - 1) || x < 0 || y > (World.RegionInfo.RegionSizeY - 1) || y < 0) 501 if (x > (World.RegionInfo.RegionSizeX - 1) || x < 0 || y > (World.RegionInfo.RegionSizeY - 1) || y < 0)
448 OSSLError("osSetTerrainHeight: Coordinate out of bounds"); 502 OSSLError("osSetTerrainHeight: Coordinate out of bounds");
449 503
@@ -471,7 +525,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
471 525
472 private LSL_Float GetTerrainHeight(int x, int y) 526 private LSL_Float GetTerrainHeight(int x, int y)
473 { 527 {
474 m_host.AddScriptLPS(1);
475 if (x > (World.RegionInfo.RegionSizeX - 1) || x < 0 || y > (World.RegionInfo.RegionSizeY - 1) || y < 0) 528 if (x > (World.RegionInfo.RegionSizeX - 1) || x < 0 || y > (World.RegionInfo.RegionSizeY - 1) || y < 0)
476 OSSLError("osGetTerrainHeight: Coordinate out of bounds"); 529 OSSLError("osGetTerrainHeight: Coordinate out of bounds");
477 530
@@ -480,8 +533,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
480 533
481 public void osTerrainFlush() 534 public void osTerrainFlush()
482 { 535 {
483 if (!CheckThreatLevel(ThreatLevel.VeryLow, "osTerrainFlush")) return; 536 CheckThreatLevel(ThreatLevel.VeryLow, "osTerrainFlush");
484 m_host.AddScriptLPS(1);
485 537
486 ITerrainModule terrainModule = World.RequestModuleInterface<ITerrainModule>(); 538 ITerrainModule terrainModule = World.RequestModuleInterface<ITerrainModule>();
487 if (terrainModule != null) terrainModule.TaintTerrain(); 539 if (terrainModule != null) terrainModule.TaintTerrain();
@@ -495,31 +547,40 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
495 // The underlying functionality is fixed, since the security 547 // The underlying functionality is fixed, since the security
496 // as such is sound 548 // as such is sound
497 // 549 //
498 if (!CheckThreatLevel(ThreatLevel.High, "osRegionRestart")) return 0; 550 CheckThreatLevel(ThreatLevel.High, "osRegionRestart");
499 551
500 IRestartModule restartModule = World.RequestModuleInterface<IRestartModule>(); 552 IRestartModule restartModule = World.RequestModuleInterface<IRestartModule>();
501 m_host.AddScriptLPS(1);
502 if (World.Permissions.CanIssueEstateCommand(m_host.OwnerID, false) && (restartModule != null)) 553 if (World.Permissions.CanIssueEstateCommand(m_host.OwnerID, false) && (restartModule != null))
503 { 554 {
504 if (seconds < 15) 555 if (seconds < 15)
505 { 556 {
506 restartModule.AbortRestart("Restart aborted"); 557 restartModule.AbortRestart("Region restart has been aborted\n");
507 return 1; 558 return 1;
508 } 559 }
509 560
510 List<int> times = new List<int>(); 561 RegionRestart(seconds, String.Empty);
511 while (seconds > 0) 562 return 1;
563 }
564 else
565 {
566 return 0;
567 }
568 }
569
570 public int osRegionRestart(double seconds, string msg)
571 {
572 CheckThreatLevel(ThreatLevel.High, "osRegionRestart");
573
574 IRestartModule restartModule = World.RequestModuleInterface<IRestartModule>();
575 if (World.Permissions.CanIssueEstateCommand(m_host.OwnerID, false) && (restartModule != null))
576 {
577 if (seconds < 15)
512 { 578 {
513 times.Add((int)seconds); 579 restartModule.AbortRestart("Region restart has been aborted\n");
514 if (seconds > 300) 580 return 1;
515 seconds -= 120;
516 else if (seconds > 30)
517 seconds -= 30;
518 else
519 seconds -= 15;
520 } 581 }
521 582
522 restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), true); 583 RegionRestart(seconds, msg);
523 return 1; 584 return 1;
524 } 585 }
525 else 586 else
@@ -528,15 +589,38 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
528 } 589 }
529 } 590 }
530 591
592 private void RegionRestart(double seconds, string msg)
593 {
594 IRestartModule restartModule = World.RequestModuleInterface<IRestartModule>();
595
596 List<int> times = new List<int>();
597 while (seconds > 0)
598 {
599 times.Add((int)seconds);
600 if (seconds > 300)
601 seconds -= 120;
602 else if (seconds > 120)
603 seconds -= 60;
604 else if (seconds > 60)
605 seconds -= 30;
606 else
607 seconds -= 15;
608 }
609
610 if (msg == String.Empty)
611 restartModule.ScheduleRestart(UUID.Zero, "Region: " + World.RegionInfo.RegionName + " is about to restart.\n\nIf you stay here you will be logged out.\n\n\nTime remaining: {0}.\n", times.ToArray(), true);
612
613 else
614 restartModule.ScheduleRestart(UUID.Zero, msg + "\n\nTime remaining: {0}.\n", times.ToArray(), true);
615 }
616
531 public void osRegionNotice(string msg) 617 public void osRegionNotice(string msg)
532 { 618 {
533 // This implementation provides absolutely no security 619 // This implementation provides absolutely no security
534 // It's high griefing potential makes this classification 620 // It's high griefing potential makes this classification
535 // necessary 621 // necessary
536 // 622 //
537 if (!CheckThreatLevel(ThreatLevel.VeryHigh, "osRegionNotice")) return; 623 CheckThreatLevel(ThreatLevel.VeryHigh, "osRegionNotice");
538
539 m_host.AddScriptLPS(1);
540 624
541 IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); 625 IDialogModule dm = World.RequestModuleInterface<IDialogModule>();
542 626
@@ -549,9 +633,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
549 // This function has no security. It can be used to destroy 633 // This function has no security. It can be used to destroy
550 // arbitrary builds the user would normally have no rights to 634 // arbitrary builds the user would normally have no rights to
551 // 635 //
552 if (!CheckThreatLevel(ThreatLevel.VeryHigh, "osSetRot")) return; 636 CheckThreatLevel(ThreatLevel.VeryHigh, "osSetRot");
553 637
554 m_host.AddScriptLPS(1);
555 if (World.Entities.ContainsKey(target)) 638 if (World.Entities.ContainsKey(target))
556 { 639 {
557 EntityBase entity; 640 EntityBase entity;
@@ -572,13 +655,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
572 public string osSetDynamicTextureURL(string dynamicID, string contentType, string url, string extraParams, 655 public string osSetDynamicTextureURL(string dynamicID, string contentType, string url, string extraParams,
573 int timer) 656 int timer)
574 { 657 {
575 m_host.AddScriptLPS(1);
576 if (dynamicID == String.Empty) 658 if (dynamicID == String.Empty)
577 { 659 {
578 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>(); 660 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>();
579 UUID createdTexture = 661 UUID createdTexture =
580 textureManager.AddDynamicTextureURL(World.RegionInfo.RegionID, m_host.UUID, contentType, url, 662 textureManager.AddDynamicTextureURL(World.RegionInfo.RegionID, m_host.UUID, contentType, url,
581 extraParams, timer); 663 extraParams);
582 return createdTexture.ToString(); 664 return createdTexture.ToString();
583 } 665 }
584 else 666 else
@@ -592,13 +674,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
592 public string osSetDynamicTextureURLBlend(string dynamicID, string contentType, string url, string extraParams, 674 public string osSetDynamicTextureURLBlend(string dynamicID, string contentType, string url, string extraParams,
593 int timer, int alpha) 675 int timer, int alpha)
594 { 676 {
595 m_host.AddScriptLPS(1);
596 if (dynamicID == String.Empty) 677 if (dynamicID == String.Empty)
597 { 678 {
598 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>(); 679 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>();
599 UUID createdTexture = 680 UUID createdTexture =
600 textureManager.AddDynamicTextureURL(World.RegionInfo.RegionID, m_host.UUID, contentType, url, 681 textureManager.AddDynamicTextureURL(World.RegionInfo.RegionID, m_host.UUID, contentType, url,
601 extraParams, timer, true, (byte) alpha); 682 extraParams, true, (byte) alpha);
602 return createdTexture.ToString(); 683 return createdTexture.ToString();
603 } 684 }
604 else 685 else
@@ -612,13 +693,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
612 public string osSetDynamicTextureURLBlendFace(string dynamicID, string contentType, string url, string extraParams, 693 public string osSetDynamicTextureURLBlendFace(string dynamicID, string contentType, string url, string extraParams,
613 bool blend, int disp, int timer, int alpha, int face) 694 bool blend, int disp, int timer, int alpha, int face)
614 { 695 {
615 m_host.AddScriptLPS(1);
616 if (dynamicID == String.Empty) 696 if (dynamicID == String.Empty)
617 { 697 {
618 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>(); 698 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>();
619 UUID createdTexture = 699 UUID createdTexture =
620 textureManager.AddDynamicTextureURL(World.RegionInfo.RegionID, m_host.UUID, contentType, url, 700 textureManager.AddDynamicTextureURL(World.RegionInfo.RegionID, m_host.UUID, contentType, url,
621 extraParams, timer, blend, disp, (byte) alpha, face); 701 extraParams, blend, disp, (byte) alpha, face);
622 return createdTexture.ToString(); 702 return createdTexture.ToString();
623 } 703 }
624 else 704 else
@@ -632,7 +712,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
632 public string osSetDynamicTextureData(string dynamicID, string contentType, string data, string extraParams, 712 public string osSetDynamicTextureData(string dynamicID, string contentType, string data, string extraParams,
633 int timer) 713 int timer)
634 { 714 {
635 m_host.AddScriptLPS(1); 715 return osSetDynamicTextureDataFace(dynamicID, contentType, data, extraParams, timer, -1);
716 }
717
718 public string osSetDynamicTextureDataFace(string dynamicID, string contentType, string data, string extraParams,
719 int timer, int face)
720 {
636 if (dynamicID == String.Empty) 721 if (dynamicID == String.Empty)
637 { 722 {
638 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>(); 723 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>();
@@ -644,7 +729,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
644 } 729 }
645 UUID createdTexture = 730 UUID createdTexture =
646 textureManager.AddDynamicTextureData(World.RegionInfo.RegionID, m_host.UUID, contentType, data, 731 textureManager.AddDynamicTextureData(World.RegionInfo.RegionID, m_host.UUID, contentType, data,
647 extraParams, timer); 732 extraParams, false, 3, 255, face);
733
648 return createdTexture.ToString(); 734 return createdTexture.ToString();
649 } 735 }
650 } 736 }
@@ -659,7 +745,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
659 public string osSetDynamicTextureDataBlend(string dynamicID, string contentType, string data, string extraParams, 745 public string osSetDynamicTextureDataBlend(string dynamicID, string contentType, string data, string extraParams,
660 int timer, int alpha) 746 int timer, int alpha)
661 { 747 {
662 m_host.AddScriptLPS(1);
663 if (dynamicID == String.Empty) 748 if (dynamicID == String.Empty)
664 { 749 {
665 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>(); 750 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>();
@@ -671,7 +756,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
671 } 756 }
672 UUID createdTexture = 757 UUID createdTexture =
673 textureManager.AddDynamicTextureData(World.RegionInfo.RegionID, m_host.UUID, contentType, data, 758 textureManager.AddDynamicTextureData(World.RegionInfo.RegionID, m_host.UUID, contentType, data,
674 extraParams, timer, true, (byte) alpha); 759 extraParams, true, (byte) alpha);
675 return createdTexture.ToString(); 760 return createdTexture.ToString();
676 } 761 }
677 } 762 }
@@ -686,7 +771,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
686 public string osSetDynamicTextureDataBlendFace(string dynamicID, string contentType, string data, string extraParams, 771 public string osSetDynamicTextureDataBlendFace(string dynamicID, string contentType, string data, string extraParams,
687 bool blend, int disp, int timer, int alpha, int face) 772 bool blend, int disp, int timer, int alpha, int face)
688 { 773 {
689 m_host.AddScriptLPS(1);
690 if (dynamicID == String.Empty) 774 if (dynamicID == String.Empty)
691 { 775 {
692 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>(); 776 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>();
@@ -698,7 +782,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
698 } 782 }
699 UUID createdTexture = 783 UUID createdTexture =
700 textureManager.AddDynamicTextureData(World.RegionInfo.RegionID, m_host.UUID, contentType, data, 784 textureManager.AddDynamicTextureData(World.RegionInfo.RegionID, m_host.UUID, contentType, data,
701 extraParams, timer, blend, disp, (byte) alpha, face); 785 extraParams, blend, disp, (byte) alpha, face);
702 return createdTexture.ToString(); 786 return createdTexture.ToString();
703 } 787 }
704 } 788 }
@@ -712,9 +796,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
712 796
713 public bool osConsoleCommand(string command) 797 public bool osConsoleCommand(string command)
714 { 798 {
715 if (!CheckThreatLevel(ThreatLevel.Severe, "osConsoleCommand")) return false; 799 CheckThreatLevel(ThreatLevel.Severe, "osConsoleCommand");
716
717 m_host.AddScriptLPS(1);
718 800
719 // For safety, we add another permission check here, and don't rely only on the standard OSSL permissions 801 // For safety, we add another permission check here, and don't rely only on the standard OSSL permissions
720 if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID)) 802 if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID))
@@ -728,123 +810,163 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
728 810
729 public void osSetPrimFloatOnWater(int floatYN) 811 public void osSetPrimFloatOnWater(int floatYN)
730 { 812 {
731 if (!CheckThreatLevel(ThreatLevel.VeryLow, "osSetPrimFloatOnWater")) return; 813 CheckThreatLevel(ThreatLevel.VeryLow, "osSetPrimFloatOnWater");
732
733 m_host.AddScriptLPS(1);
734 814
735 m_host.ParentGroup.RootPart.SetFloatOnWater(floatYN); 815 m_host.ParentGroup.RootPart.SetFloatOnWater(floatYN);
736 } 816 }
737 817
818 private bool checkAllowAgentTPbyLandOwner(UUID agentId, Vector3 pos)
819 {
820 UUID hostOwner = m_host.OwnerID;
821
822 if(hostOwner == agentId)
823 return true;
824
825 if (m_item.PermsGranter == agentId)
826 {
827 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0)
828 return true;
829 }
830
831 ILandObject land = World.LandChannel.GetLandObject(pos);
832 if(land == null)
833 return true;
834
835 LandData landdata = land.LandData;
836 if(landdata == null)
837 return true;
838
839 if(landdata.OwnerID == hostOwner)
840 return true;
841
842 EstateSettings es = World.RegionInfo.EstateSettings;
843 if(es != null && es.IsEstateManagerOrOwner(hostOwner))
844 return true;
845
846 if(!landdata.IsGroupOwned)
847 return false;
848
849 UUID landGroup = landdata.GroupID;
850 if(landGroup == UUID.Zero)
851 return false;
852
853 if(landGroup == m_host.GroupID)
854 return true;
855
856 return false;
857 }
858
738 // Teleport functions 859 // Teleport functions
739 public void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) 860 public void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
740 { 861 {
741 // High because there is no security check. High griefer potential 862 // High because there is no security check. High griefer potential
742 // 863 //
743 if (!CheckThreatLevel(ThreatLevel.High, "osTeleportAgent")) return; 864 CheckThreatLevel(ThreatLevel.Severe, "osTeleportAgent");
744 865
745 TeleportAgent(agent, regionName, position, lookat, false); 866 TeleportAgent(agent, regionName, position, lookat);
746 } 867 }
747 868
748 private void TeleportAgent(string agent, string regionName, 869 private void TeleportAgent(string agent, string regionName,
749 LSL_Types.Vector3 position, LSL_Types.Vector3 lookat, bool relaxRestrictions) 870 LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
750 { 871 {
751 m_host.AddScriptLPS(1); 872 if(String.IsNullOrEmpty(regionName))
752 UUID agentId = new UUID(); 873 regionName = World.RegionInfo.RegionName;
874
875 UUID agentId;
753 if (UUID.TryParse(agent, out agentId)) 876 if (UUID.TryParse(agent, out agentId))
754 { 877 {
755 ScenePresence presence = World.GetScenePresence(agentId); 878 ScenePresence presence = World.GetScenePresence(agentId);
756 if (presence != null) 879 if (presence == null || presence.IsDeleted || presence.IsInTransit)
757 { 880 return;
758 // For osTeleportAgent, agent must be over owners land to avoid abuse 881
759 // For osTeleportOwner, this restriction isn't necessary 882 Vector3 pos = presence.AbsolutePosition;
760 883 if(!checkAllowAgentTPbyLandOwner(agentId, pos))
761 // commented out because its redundant and uneeded please remove eventually. 884 return;
762 // if (relaxRestrictions ||
763 // m_host.OwnerID
764 // == World.LandChannel.GetLandObject(
765 // presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
766 // {
767
768 // We will launch the teleport on a new thread so that when the script threads are terminated
769 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
770 Util.FireAndForget(
771 o => World.RequestTeleportLocation(
772 presence.ControllingClient, regionName, position,
773 lookat, (uint)TPFlags.ViaLocation),
774 null, "OSSL_Api.TeleportAgentByRegionCoords");
775 // }
776 885
886 if(regionName == World.RegionInfo.RegionName)
887 {
888 // should be faster than going to threadpool
889 World.RequestTeleportLocation(presence.ControllingClient, regionName, position,
890 lookat, (uint)(TPFlags.ViaLocation | TPFlags.ViaScript));
891 }
892 else
893 {
894 // We will launch the teleport on a new thread so that when the script threads are terminated
895 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
896 Util.FireAndForget(
897 o => World.RequestTeleportLocation(
898 presence.ControllingClient, regionName, position,
899 lookat, (uint)(TPFlags.ViaLocation | TPFlags.ViaScript)),
900 null, "OSSL_Api.TeleportAgentByRegionCoords");
777 } 901 }
778 } 902 }
779 } 903 }
780 904
781 public void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) 905 public void osTeleportAgent(string agent, int regionGridX, int regionGridY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
782 { 906 {
783 // High because there is no security check. High griefer potential 907 // High because there is no security check. High griefer potential
784 // 908 //
785 if (!CheckThreatLevel(ThreatLevel.High, "osTeleportAgent")) return; 909 CheckThreatLevel(ThreatLevel.Severe, "osTeleportAgent");
786 910
787 TeleportAgent(agent, regionX, regionY, position, lookat, false); 911 TeleportAgent(agent, regionGridX, regionGridY, position, lookat);
788 } 912 }
789 913
790 private void TeleportAgent(string agent, int regionX, int regionY, 914 private void TeleportAgent(string agent, int regionGridX, int regionGridY,
791 LSL_Types.Vector3 position, LSL_Types.Vector3 lookat, bool relaxRestrictions) 915 LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
792 { 916 {
793 // ulong regionHandle = Util.UIntsToLong(((uint)regionX * (uint)Constants.RegionSize), ((uint)regionY * (uint)Constants.RegionSize)); 917 ulong regionHandle = Util.RegionGridLocToHandle((uint)regionGridX, (uint)regionGridY);
794 ulong regionHandle = Util.RegionLocToHandle((uint)regionX, (uint)regionY);
795 918
796 m_host.AddScriptLPS(1); 919 UUID agentId;
797 UUID agentId = new UUID();
798 if (UUID.TryParse(agent, out agentId)) 920 if (UUID.TryParse(agent, out agentId))
799 { 921 {
800 ScenePresence presence = World.GetScenePresence(agentId); 922 ScenePresence presence = World.GetScenePresence(agentId);
801 if (presence != null) 923 if (presence == null || presence.IsDeleted || presence.IsInTransit)
802 { 924 return;
803 // For osTeleportAgent, agent must be over owners land to avoid abuse
804 // For osTeleportOwner, this restriction isn't necessary
805
806 // commented out because its redundant and uneeded please remove eventually.
807 // if (relaxRestrictions ||
808 // m_host.OwnerID
809 // == World.LandChannel.GetLandObject(
810 // presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
811 // {
812
813 // We will launch the teleport on a new thread so that when the script threads are terminated
814 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
815 Util.FireAndForget(
816 o => World.RequestTeleportLocation(
817 presence.ControllingClient, regionHandle,
818 position, lookat, (uint)TPFlags.ViaLocation),
819 null, "OSSL_Api.TeleportAgentByRegionName");
820 // }
821 925
822 } 926 Vector3 pos = presence.AbsolutePosition;
927 if(!checkAllowAgentTPbyLandOwner(agentId, pos))
928 return;
929
930 Util.FireAndForget(
931 o => World.RequestTeleportLocation(
932 presence.ControllingClient, regionHandle,
933 position, lookat, (uint)(TPFlags.ViaLocation | TPFlags.ViaScript)),
934 null, "OSSL_Api.TeleportAgentByRegionName");
823 } 935 }
824 } 936 }
825 937
826 public void osTeleportAgent(string agent, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) 938 public void osTeleportAgent(string agent, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
827 { 939 {
828 // High because there is no security check. High griefer potential 940 UUID agentId;
829 // 941 if (UUID.TryParse(agent, out agentId))
830 if (!CheckThreatLevel(ThreatLevel.High, "osTeleportAgent")) return; 942 {
943 ScenePresence presence = World.GetScenePresence(agentId);
944 if (presence == null || presence.IsDeleted || presence.IsInTransit)
945 return;
946
947 Vector3 pos = presence.AbsolutePosition;
948 if(!checkAllowAgentTPbyLandOwner(agentId, pos))
949 return;
831 950
832 osTeleportAgent(agent, World.RegionInfo.RegionName, position, lookat); 951 World.RequestTeleportLocation(presence.ControllingClient, World.RegionInfo.RegionName, position,
952 lookat, (uint)(TPFlags.ViaLocation | TPFlags.ViaScript));
953 }
833 } 954 }
834 955
835 public void osTeleportOwner(string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) 956 public void osTeleportOwner(string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
836 { 957 {
837 TeleportAgent(m_host.OwnerID.ToString(), regionName, position, lookat, true); 958 // Threat level None because this is what can already be done with the World Map in the viewer
959 TeleportAgent(m_host.OwnerID.ToString(), regionName, position, lookat);
838 } 960 }
839 961
840 public void osTeleportOwner(LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) 962 public void osTeleportOwner(int regionGridX, int regionGridY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
841 { 963 {
842 osTeleportOwner(World.RegionInfo.RegionName, position, lookat); 964 TeleportAgent(m_host.OwnerID.ToString(), regionGridX, regionGridY, position, lookat);
843 } 965 }
844 966
845 public void osTeleportOwner(int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) 967 public void osTeleportOwner(LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
846 { 968 {
847 TeleportAgent(m_host.OwnerID.ToString(), regionX, regionY, position, lookat, true); 969 osTeleportAgent(m_host.OwnerID.ToString(), position, lookat);
848 } 970 }
849 971
850 ///<summary> 972 ///<summary>
@@ -856,9 +978,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
856 /// <param name="avatar"></param> 978 /// <param name="avatar"></param>
857 public void osForceOtherSit(string avatar) 979 public void osForceOtherSit(string avatar)
858 { 980 {
859 if (!CheckThreatLevel(ThreatLevel.VeryHigh, "osForceOtherSit")) return; 981 CheckThreatLevel(ThreatLevel.VeryHigh, "osForceOtherSit");
860
861 m_host.AddScriptLPS(1);
862 982
863 ForceSit(avatar, m_host.UUID); 983 ForceSit(avatar, m_host.UUID);
864 } 984 }
@@ -871,9 +991,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
871 /// <param name="target"></param> 991 /// <param name="target"></param>
872 public void osForceOtherSit(string avatar, string target) 992 public void osForceOtherSit(string avatar, string target)
873 { 993 {
874 if (!CheckThreatLevel(ThreatLevel.VeryHigh, "osForceOtherSit")) return; 994 CheckThreatLevel(ThreatLevel.VeryHigh, "osForceOtherSit");
875
876 m_host.AddScriptLPS(1);
877 995
878 UUID targetID = new UUID(target); 996 UUID targetID = new UUID(target);
879 997
@@ -882,7 +1000,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
882 1000
883 public void ForceSit(string avatar, UUID targetID) 1001 public void ForceSit(string avatar, UUID targetID)
884 { 1002 {
885 UUID agentID; 1003 UUID agentID;
886 1004
887 if (!UUID.TryParse(avatar, out agentID)) 1005 if (!UUID.TryParse(avatar, out agentID))
888 return; 1006 return;
@@ -900,21 +1018,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
900 part.SitTargetPosition); 1018 part.SitTargetPosition);
901 } 1019 }
902 1020
903 // Functions that get information from the agent itself. 1021 // Get a list of all the avatars/agents in the region
904 // 1022 public LSL_List osGetAgents()
905 // osGetAgentIP - this is used to determine the IP address of 1023 {
906 //the client. This is needed to help configure other in world 1024 // threat level is None as we could get this information with an
907 //resources based on the IP address of the clients connected. 1025 // in-world script as well, just not as efficient
908 //I think High is a good risk level for this, as it is an 1026 LSL_List result = new LSL_List();
909 //information leak. 1027 World.ForEachRootScenePresence(delegate(ScenePresence sp)
910 // Severe is even better coz privacy is important. 1028 {
1029 result.Add(new LSL_String(sp.Name));
1030 });
1031 return result;
1032 }
1033
911 public string osGetAgentIP(string agent) 1034 public string osGetAgentIP(string agent)
912 { 1035 {
913 if (!CheckThreatLevel(ThreatLevel.Severe, "osGetAgentIP")) return ""; 1036 CheckThreatLevel(ThreatLevel.Severe, "osGetAgentIP");
1037 if(!(World.Permissions.IsGod(m_host.OwnerID))) // user god always needed
1038 return "";
914 1039
915 UUID avatarID = (UUID)agent; 1040 UUID avatarID = (UUID)agent;
916 1041
917 m_host.AddScriptLPS(1);
918 if (World.Entities.ContainsKey((UUID)agent) && World.Entities[avatarID] is ScenePresence) 1042 if (World.Entities.ContainsKey((UUID)agent) && World.Entities[avatarID] is ScenePresence)
919 { 1043 {
920 ScenePresence target = (ScenePresence)World.Entities[avatarID]; 1044 ScenePresence target = (ScenePresence)World.Entities[avatarID];
@@ -925,61 +1049,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
925 return ""; 1049 return "";
926 } 1050 }
927 1051
928 // Get a list of all the avatars/agents in the region
929 public LSL_List osGetAgents()
930 {
931 m_host.AddScriptLPS(1);
932
933 LSL_List result = new LSL_List();
934 World.ForEachRootScenePresence(delegate(ScenePresence sp)
935 {
936 result.Add(new LSL_String(sp.Name));
937 });
938 return result;
939 }
940
941 // Adam's super super custom animation functions 1052 // Adam's super super custom animation functions
942 public void osAvatarPlayAnimation(string avatar, string animation) 1053 public void osAvatarPlayAnimation(string avatar, string animation)
943 { 1054 {
944 if (!CheckThreatLevel(ThreatLevel.VeryHigh, "osAvatarPlayAnimation")) return; 1055 CheckThreatLevel(ThreatLevel.VeryHigh, "osAvatarPlayAnimation");
945 1056
946 AvatarPlayAnimation(avatar, animation); 1057 AvatarPlayAnimation(avatar, animation);
947 } 1058 }
948 1059
949 private void AvatarPlayAnimation(string avatar, string animation) 1060 private void AvatarPlayAnimation(string avatar, string animation)
950 { 1061 {
951 UUID avatarID = (UUID)avatar; 1062 UUID avatarID;
1063 if(!UUID.TryParse(avatar, out avatarID))
1064 return;
1065
1066 ScenePresence target = World.GetScenePresence(avatarID);
1067 if (target == null)
1068 return;
952 1069
953 m_host.AddScriptLPS(1); 1070 UUID animID = UUID.Zero;
954 if (World.Entities.ContainsKey((UUID)avatar) && World.Entities[avatarID] is ScenePresence) 1071 m_host.TaskInventory.LockItemsForRead(true);
1072 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
955 { 1073 {
956 ScenePresence target = (ScenePresence)World.Entities[avatarID]; 1074 if (inv.Value.Type == (int)AssetType.Animation)
957 if (target != null)
958 { 1075 {
959 UUID animID=UUID.Zero; 1076 if (inv.Value.Name == animation)
960 lock (m_host.TaskInventory) 1077 {
961 { 1078 animID = inv.Value.AssetID;
962 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 1079 break;
963 { 1080 }
964 if (inv.Value.Name == animation)
965 {
966 if (inv.Value.Type == (int)AssetType.Animation)
967 animID = inv.Value.AssetID;
968 continue;
969 }
970 }
971 }
972 if (animID == UUID.Zero)
973 target.Animator.AddAnimation(animation, m_host.UUID);
974 else
975 target.Animator.AddAnimation(animID, m_host.UUID);
976 } 1081 }
977 } 1082 }
1083 m_host.TaskInventory.LockItemsForRead(false);
1084
1085 if (animID == UUID.Zero)
1086 target.Animator.AddAnimation(animation, m_host.UUID);
1087 else
1088 target.Animator.AddAnimation(animID, m_host.UUID);
978 } 1089 }
979 1090
980 public void osAvatarStopAnimation(string avatar, string animation) 1091 public void osAvatarStopAnimation(string avatar, string animation)
981 { 1092 {
982 if (!CheckThreatLevel(ThreatLevel.VeryHigh, "osAvatarStopAnimation")) return; 1093 CheckThreatLevel(ThreatLevel.VeryHigh, "osAvatarStopAnimation");
983 1094
984 AvatarStopAnimation(avatar, animation); 1095 AvatarStopAnimation(avatar, animation);
985 } 1096 }
@@ -988,8 +1099,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
988 { 1099 {
989 UUID avatarID = (UUID)avatar; 1100 UUID avatarID = (UUID)avatar;
990 1101
991 m_host.AddScriptLPS(1);
992
993 // FIXME: What we really want to do here is factor out the similar code in llStopAnimation() to a common 1102 // FIXME: What we really want to do here is factor out the similar code in llStopAnimation() to a common
994 // method (though see that doesn't do the is animation check, which is probably a bug) and have both 1103 // method (though see that doesn't do the is animation check, which is probably a bug) and have both
995 // these functions call that common code. However, this does mean navigating the brain-dead requirement 1104 // these functions call that common code. However, this does mean navigating the brain-dead requirement
@@ -1010,6 +1119,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1010 animID = UUID.Zero; 1119 animID = UUID.Zero;
1011 } 1120 }
1012 1121
1122
1013 if (animID == UUID.Zero) 1123 if (animID == UUID.Zero)
1014 target.Animator.RemoveAnimation(animation); 1124 target.Animator.RemoveAnimation(animation);
1015 else 1125 else
@@ -1019,59 +1129,81 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1019 } 1129 }
1020 1130
1021 //Texture draw functions 1131 //Texture draw functions
1132
1133 public string osDrawResetTransform(string drawList)
1134 {
1135 drawList += "ResetTransf;";
1136 return drawList;
1137 }
1138
1139 public string osDrawRotationTransform(string drawList, LSL_Float x)
1140 {
1141 drawList += "RotTransf " + x + ";";
1142 return drawList;
1143 }
1144
1145 public string osDrawScaleTransform(string drawList, LSL_Float x, LSL_Float y)
1146 {
1147 drawList += "ScaleTransf " + x + "," + y + ";";
1148 return drawList;
1149 }
1150
1151 public string osDrawTranslationTransform(string drawList, LSL_Float x, LSL_Float y)
1152 {
1153 drawList += "TransTransf " + x + "," + y + ";";
1154 return drawList;
1155 }
1156
1022 public string osMovePen(string drawList, int x, int y) 1157 public string osMovePen(string drawList, int x, int y)
1023 { 1158 {
1024 m_host.AddScriptLPS(1);
1025 drawList += "MoveTo " + x + "," + y + ";"; 1159 drawList += "MoveTo " + x + "," + y + ";";
1026 return drawList; 1160 return drawList;
1027 } 1161 }
1028 1162
1029 public string osDrawLine(string drawList, int startX, int startY, int endX, int endY) 1163 public string osDrawLine(string drawList, int startX, int startY, int endX, int endY)
1030 { 1164 {
1031 m_host.AddScriptLPS(1);
1032 drawList += "MoveTo "+ startX+","+ startY +"; LineTo "+endX +","+endY +"; "; 1165 drawList += "MoveTo "+ startX+","+ startY +"; LineTo "+endX +","+endY +"; ";
1033 return drawList; 1166 return drawList;
1034 } 1167 }
1035 1168
1036 public string osDrawLine(string drawList, int endX, int endY) 1169 public string osDrawLine(string drawList, int endX, int endY)
1037 { 1170 {
1038 m_host.AddScriptLPS(1);
1039 drawList += "LineTo " + endX + "," + endY + "; "; 1171 drawList += "LineTo " + endX + "," + endY + "; ";
1040 return drawList; 1172 return drawList;
1041 } 1173 }
1042 1174
1043 public string osDrawText(string drawList, string text) 1175 public string osDrawText(string drawList, string text)
1044 { 1176 {
1045 m_host.AddScriptLPS(1);
1046 drawList += "Text " + text + "; "; 1177 drawList += "Text " + text + "; ";
1047 return drawList; 1178 return drawList;
1048 } 1179 }
1049 1180
1050 public string osDrawEllipse(string drawList, int width, int height) 1181 public string osDrawEllipse(string drawList, int width, int height)
1051 { 1182 {
1052 m_host.AddScriptLPS(1);
1053 drawList += "Ellipse " + width + "," + height + "; "; 1183 drawList += "Ellipse " + width + "," + height + "; ";
1054 return drawList; 1184 return drawList;
1055 } 1185 }
1056 1186
1187 public string osDrawFilledEllipse(string drawList, int width, int height)
1188 {
1189 drawList += "FillEllipse " + width + "," + height + "; ";
1190 return drawList;
1191 }
1192
1057 public string osDrawRectangle(string drawList, int width, int height) 1193 public string osDrawRectangle(string drawList, int width, int height)
1058 { 1194 {
1059 m_host.AddScriptLPS(1);
1060 drawList += "Rectangle " + width + "," + height + "; "; 1195 drawList += "Rectangle " + width + "," + height + "; ";
1061 return drawList; 1196 return drawList;
1062 } 1197 }
1063 1198
1064 public string osDrawFilledRectangle(string drawList, int width, int height) 1199 public string osDrawFilledRectangle(string drawList, int width, int height)
1065 { 1200 {
1066 m_host.AddScriptLPS(1);
1067 drawList += "FillRectangle " + width + "," + height + "; "; 1201 drawList += "FillRectangle " + width + "," + height + "; ";
1068 return drawList; 1202 return drawList;
1069 } 1203 }
1070 1204
1071 public string osDrawFilledPolygon(string drawList, LSL_List x, LSL_List y) 1205 public string osDrawFilledPolygon(string drawList, LSL_List x, LSL_List y)
1072 { 1206 {
1073 m_host.AddScriptLPS(1);
1074
1075 if (x.Length != y.Length || x.Length < 3) 1207 if (x.Length != y.Length || x.Length < 3)
1076 { 1208 {
1077 return ""; 1209 return "";
@@ -1087,8 +1219,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1087 1219
1088 public string osDrawPolygon(string drawList, LSL_List x, LSL_List y) 1220 public string osDrawPolygon(string drawList, LSL_List x, LSL_List y)
1089 { 1221 {
1090 m_host.AddScriptLPS(1);
1091
1092 if (x.Length != y.Length || x.Length < 3) 1222 if (x.Length != y.Length || x.Length < 3)
1093 { 1223 {
1094 return ""; 1224 return "";
@@ -1104,28 +1234,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1104 1234
1105 public string osSetFontSize(string drawList, int fontSize) 1235 public string osSetFontSize(string drawList, int fontSize)
1106 { 1236 {
1107 m_host.AddScriptLPS(1);
1108 drawList += "FontSize "+ fontSize +"; "; 1237 drawList += "FontSize "+ fontSize +"; ";
1109 return drawList; 1238 return drawList;
1110 } 1239 }
1111 1240
1112 public string osSetFontName(string drawList, string fontName) 1241 public string osSetFontName(string drawList, string fontName)
1113 { 1242 {
1114 m_host.AddScriptLPS(1);
1115 drawList += "FontName "+ fontName +"; "; 1243 drawList += "FontName "+ fontName +"; ";
1116 return drawList; 1244 return drawList;
1117 } 1245 }
1118 1246
1119 public string osSetPenSize(string drawList, int penSize) 1247 public string osSetPenSize(string drawList, int penSize)
1120 { 1248 {
1121 m_host.AddScriptLPS(1);
1122 drawList += "PenSize " + penSize + "; "; 1249 drawList += "PenSize " + penSize + "; ";
1123 return drawList; 1250 return drawList;
1124 } 1251 }
1125 1252
1126 public string osSetPenColor(string drawList, string color) 1253 public string osSetPenColor(string drawList, string color)
1127 { 1254 {
1128 m_host.AddScriptLPS(1);
1129 drawList += "PenColor " + color + "; "; 1255 drawList += "PenColor " + color + "; ";
1130 return drawList; 1256 return drawList;
1131 } 1257 }
@@ -1135,29 +1261,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1135 { 1261 {
1136 OSSLDeprecated("osSetPenColour", "osSetPenColor"); 1262 OSSLDeprecated("osSetPenColour", "osSetPenColor");
1137 1263
1138 m_host.AddScriptLPS(1);
1139 drawList += "PenColour " + colour + "; "; 1264 drawList += "PenColour " + colour + "; ";
1140 return drawList; 1265 return drawList;
1141 } 1266 }
1142 1267
1143 public string osSetPenCap(string drawList, string direction, string type) 1268 public string osSetPenCap(string drawList, string direction, string type)
1144 { 1269 {
1145 m_host.AddScriptLPS(1);
1146 drawList += "PenCap " + direction + "," + type + "; "; 1270 drawList += "PenCap " + direction + "," + type + "; ";
1147 return drawList; 1271 return drawList;
1148 } 1272 }
1149 1273
1150 public string osDrawImage(string drawList, int width, int height, string imageUrl) 1274 public string osDrawImage(string drawList, int width, int height, string imageUrl)
1151 { 1275 {
1152 m_host.AddScriptLPS(1);
1153 drawList +="Image " +width + "," + height+ ","+ imageUrl +"; " ; 1276 drawList +="Image " +width + "," + height+ ","+ imageUrl +"; " ;
1154 return drawList; 1277 return drawList;
1155 } 1278 }
1156 1279
1157 public LSL_Vector osGetDrawStringSize(string contentType, string text, string fontName, int fontSize) 1280 public LSL_Vector osGetDrawStringSize(string contentType, string text, string fontName, int fontSize)
1158 { 1281 {
1159 m_host.AddScriptLPS(1);
1160
1161 LSL_Vector vec = new LSL_Vector(0,0,0); 1282 LSL_Vector vec = new LSL_Vector(0,0,0);
1162 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>(); 1283 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>();
1163 if (textureManager != null) 1284 if (textureManager != null)
@@ -1178,17 +1299,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1178 // It was probably added as a crutch or debugging aid, and 1299 // It was probably added as a crutch or debugging aid, and
1179 // should be removed 1300 // should be removed
1180 // 1301 //
1181 if (!CheckThreatLevel(ThreatLevel.High, "osSetStateEvents")) return; 1302 CheckThreatLevel(ThreatLevel.High, "osSetStateEvents");
1182 m_host.AddScriptLPS(1);
1183 1303
1184 m_host.SetScriptEvents(m_item.ItemID, events); 1304 m_host.SetScriptEvents(m_item.ItemID, events);
1185 } 1305 }
1186 1306
1187 public void osSetRegionWaterHeight(double height) 1307 public void osSetRegionWaterHeight(double height)
1188 { 1308 {
1189 if (!CheckThreatLevel(ThreatLevel.High, "osSetRegionWaterHeight")) return; 1309 CheckThreatLevel(ThreatLevel.High, "osSetRegionWaterHeight");
1190
1191 m_host.AddScriptLPS(1);
1192 1310
1193 World.EventManager.TriggerRequestChangeWaterHeight((float)height); 1311 World.EventManager.TriggerRequestChangeWaterHeight((float)height);
1194 } 1312 }
@@ -1201,9 +1319,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1201 /// <param name="sunHour">The "Sun Hour" that is desired, 0...24, with 0 just after SunRise</param> 1319 /// <param name="sunHour">The "Sun Hour" that is desired, 0...24, with 0 just after SunRise</param>
1202 public void osSetRegionSunSettings(bool useEstateSun, bool sunFixed, double sunHour) 1320 public void osSetRegionSunSettings(bool useEstateSun, bool sunFixed, double sunHour)
1203 { 1321 {
1204 if (!CheckThreatLevel(ThreatLevel.High, "osSetRegionSunSettings")) return; 1322 CheckThreatLevel(ThreatLevel.Nuisance, "osSetRegionSunSettings");
1205
1206 m_host.AddScriptLPS(1);
1207 1323
1208 while (sunHour > 24.0) 1324 while (sunHour > 24.0)
1209 sunHour -= 24.0; 1325 sunHour -= 24.0;
@@ -1226,9 +1342,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1226 /// <param name="sunHour">The "Sun Hour" that is desired, 0...24, with 0 just after SunRise</param> 1342 /// <param name="sunHour">The "Sun Hour" that is desired, 0...24, with 0 just after SunRise</param>
1227 public void osSetEstateSunSettings(bool sunFixed, double sunHour) 1343 public void osSetEstateSunSettings(bool sunFixed, double sunHour)
1228 { 1344 {
1229 if (!CheckThreatLevel(ThreatLevel.High, "osSetEstateSunSettings")) return; 1345 CheckThreatLevel(ThreatLevel.Nuisance, "osSetEstateSunSettings");
1230
1231 m_host.AddScriptLPS(1);
1232 1346
1233 while (sunHour > 24.0) 1347 while (sunHour > 24.0)
1234 sunHour -= 24.0; 1348 sunHour -= 24.0;
@@ -1250,8 +1364,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1250 /// <returns></returns> 1364 /// <returns></returns>
1251 public double osGetCurrentSunHour() 1365 public double osGetCurrentSunHour()
1252 { 1366 {
1253 m_host.AddScriptLPS(1);
1254
1255 // Must adjust for the fact that Region Sun Settings are still LL offset 1367 // Must adjust for the fact that Region Sun Settings are still LL offset
1256 double sunHour = World.RegionInfo.RegionSettings.SunPosition - 6; 1368 double sunHour = World.RegionInfo.RegionSettings.SunPosition - 6;
1257 1369
@@ -1278,8 +1390,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1278 1390
1279 private double GetSunParam(string param) 1391 private double GetSunParam(string param)
1280 { 1392 {
1281 m_host.AddScriptLPS(1);
1282
1283 double value = 0.0; 1393 double value = 0.0;
1284 1394
1285 ISunModule module = World.RequestModuleInterface<ISunModule>(); 1395 ISunModule module = World.RequestModuleInterface<ISunModule>();
@@ -1293,21 +1403,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1293 1403
1294 public void osSunSetParam(string param, double value) 1404 public void osSunSetParam(string param, double value)
1295 { 1405 {
1296//// if (!CheckThreatLevel(ThreatLevel.None, "osSunSetParam")) return; 1406 CheckThreatLevel(ThreatLevel.Nuisance, "osSunSetParam");
1297 OSSLDeprecated("osSunSetParam", "osSetSunParam"); 1407 OSSLDeprecated("osSunSetParam", "osSetSunParam");
1298 SetSunParam(param, value); 1408 SetSunParam(param, value);
1299 } 1409 }
1300 1410
1301 public void osSetSunParam(string param, double value) 1411 public void osSetSunParam(string param, double value)
1302 { 1412 {
1303//// if (!CheckThreatLevel(ThreatLevel.None, "osSetSunParam")) return; 1413 CheckThreatLevel(ThreatLevel.Nuisance, "osSetSunParam");
1304 SetSunParam(param, value); 1414 SetSunParam(param, value);
1305 } 1415 }
1306 1416
1307 private void SetSunParam(string param, double value) 1417 private void SetSunParam(string param, double value)
1308 { 1418 {
1309 m_host.AddScriptLPS(1);
1310
1311 ISunModule module = World.RequestModuleInterface<ISunModule>(); 1419 ISunModule module = World.RequestModuleInterface<ISunModule>();
1312 if (module != null) 1420 if (module != null)
1313 { 1421 {
@@ -1317,8 +1425,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1317 1425
1318 public string osWindActiveModelPluginName() 1426 public string osWindActiveModelPluginName()
1319 { 1427 {
1320 m_host.AddScriptLPS(1);
1321
1322 IWindModule module = World.RequestModuleInterface<IWindModule>(); 1428 IWindModule module = World.RequestModuleInterface<IWindModule>();
1323 if (module != null) 1429 if (module != null)
1324 { 1430 {
@@ -1330,8 +1436,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1330 1436
1331 public void osSetWindParam(string plugin, string param, LSL_Float value) 1437 public void osSetWindParam(string plugin, string param, LSL_Float value)
1332 { 1438 {
1333 if (!CheckThreatLevel(ThreatLevel.VeryLow, "osSetWindParam")) return; 1439 CheckThreatLevel(ThreatLevel.Nuisance, "osSetWindParam");
1334 m_host.AddScriptLPS(1);
1335 1440
1336 IWindModule module = World.RequestModuleInterface<IWindModule>(); 1441 IWindModule module = World.RequestModuleInterface<IWindModule>();
1337 if (module != null) 1442 if (module != null)
@@ -1346,8 +1451,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1346 1451
1347 public LSL_Float osGetWindParam(string plugin, string param) 1452 public LSL_Float osGetWindParam(string plugin, string param)
1348 { 1453 {
1349 m_host.AddScriptLPS(1);
1350
1351 IWindModule module = World.RequestModuleInterface<IWindModule>(); 1454 IWindModule module = World.RequestModuleInterface<IWindModule>();
1352 if (module != null) 1455 if (module != null)
1353 { 1456 {
@@ -1360,8 +1463,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1360 // Routines for creating and managing parcels programmatically 1463 // Routines for creating and managing parcels programmatically
1361 public void osParcelJoin(LSL_Vector pos1, LSL_Vector pos2) 1464 public void osParcelJoin(LSL_Vector pos1, LSL_Vector pos2)
1362 { 1465 {
1363 if (!CheckThreatLevel(ThreatLevel.High, "osParcelJoin")) return; 1466 CheckThreatLevel(ThreatLevel.High, "osParcelJoin");
1364 m_host.AddScriptLPS(1);
1365 1467
1366 int startx = (int)(pos1.x < pos2.x ? pos1.x : pos2.x); 1468 int startx = (int)(pos1.x < pos2.x ? pos1.x : pos2.x);
1367 int starty = (int)(pos1.y < pos2.y ? pos1.y : pos2.y); 1469 int starty = (int)(pos1.y < pos2.y ? pos1.y : pos2.y);
@@ -1373,8 +1475,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1373 1475
1374 public void osParcelSubdivide(LSL_Vector pos1, LSL_Vector pos2) 1476 public void osParcelSubdivide(LSL_Vector pos1, LSL_Vector pos2)
1375 { 1477 {
1376 if (!CheckThreatLevel(ThreatLevel.High, "osParcelSubdivide")) return; 1478 CheckThreatLevel(ThreatLevel.High, "osParcelSubdivide");
1377 m_host.AddScriptLPS(1);
1378 1479
1379 int startx = (int)(pos1.x < pos2.x ? pos1.x : pos2.x); 1480 int startx = (int)(pos1.x < pos2.x ? pos1.x : pos2.x);
1380 int starty = (int)(pos1.y < pos2.y ? pos1.y : pos2.y); 1481 int starty = (int)(pos1.y < pos2.y ? pos1.y : pos2.y);
@@ -1387,7 +1488,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1387 public void osParcelSetDetails(LSL_Vector pos, LSL_List rules) 1488 public void osParcelSetDetails(LSL_Vector pos, LSL_List rules)
1388 { 1489 {
1389 const string functionName = "osParcelSetDetails"; 1490 const string functionName = "osParcelSetDetails";
1390 if (!CheckThreatLevel(ThreatLevel.High, functionName)) return; 1491 CheckThreatLevel(ThreatLevel.High, functionName);
1391 OSSLDeprecated(functionName, "osSetParcelDetails"); 1492 OSSLDeprecated(functionName, "osSetParcelDetails");
1392 SetParcelDetails(pos, rules, functionName); 1493 SetParcelDetails(pos, rules, functionName);
1393 } 1494 }
@@ -1395,14 +1496,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1395 public void osSetParcelDetails(LSL_Vector pos, LSL_List rules) 1496 public void osSetParcelDetails(LSL_Vector pos, LSL_List rules)
1396 { 1497 {
1397 const string functionName = "osSetParcelDetails"; 1498 const string functionName = "osSetParcelDetails";
1398 if (!CheckThreatLevel(ThreatLevel.High, functionName)) return; 1499 CheckThreatLevel(ThreatLevel.High, functionName);
1399 SetParcelDetails(pos, rules, functionName); 1500 SetParcelDetails(pos, rules, functionName);
1400 } 1501 }
1401 1502
1402 private void SetParcelDetails(LSL_Vector pos, LSL_List rules, string functionName) 1503 private void SetParcelDetails(LSL_Vector pos, LSL_List rules, string functionName)
1403 { 1504 {
1404 m_host.AddScriptLPS(1);
1405
1406 // Get a reference to the land data and make sure the owner of the script 1505 // Get a reference to the land data and make sure the owner of the script
1407 // can modify it 1506 // can modify it
1408 1507
@@ -1413,15 +1512,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1413 return; 1512 return;
1414 } 1513 }
1415 1514
1416 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, startLandObject, GroupPowers.LandOptions)) 1515 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, startLandObject, GroupPowers.LandOptions, false))
1417 { 1516 {
1418 OSSLShoutError("You do not have permission to modify the parcel"); 1517 OSSLShoutError("script owner does not have permission to modify the parcel");
1419 return; 1518 return;
1420 } 1519 }
1421 1520
1422 // Create a new land data object we can modify 1521 // Create a new land data object we can modify
1423 LandData newLand = startLandObject.LandData.Copy(); 1522 LandData newLand = startLandObject.LandData.Copy();
1424 UUID uuid; 1523 UUID uuid;
1524 EstateSettings es = World.RegionInfo.EstateSettings;
1525
1526 bool changed = false;
1527 bool changedSeeAvs = false;
1528 bool changedoverlay = false;
1529 bool changedneedupdate = false;
1425 1530
1426 // Process the rules, not sure what the impact would be of changing owner or group 1531 // Process the rules, not sure what the impact would be of changing owner or group
1427 for (int idx = 0; idx < rules.Length;) 1532 for (int idx = 0; idx < rules.Length;)
@@ -1431,35 +1536,151 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1431 switch (code) 1536 switch (code)
1432 { 1537 {
1433 case ScriptBaseClass.PARCEL_DETAILS_NAME: 1538 case ScriptBaseClass.PARCEL_DETAILS_NAME:
1434 newLand.Name = arg; 1539 if(newLand.Name != arg)
1540 {
1541 newLand.Name = arg;
1542 changed = true;
1543 }
1435 break; 1544 break;
1436 1545
1437 case ScriptBaseClass.PARCEL_DETAILS_DESC: 1546 case ScriptBaseClass.PARCEL_DETAILS_DESC:
1438 newLand.Description = arg; 1547 if(newLand.Description != arg)
1548 {
1549 newLand.Description = arg;
1550 changed = true;
1551 }
1439 break; 1552 break;
1440 1553
1441 case ScriptBaseClass.PARCEL_DETAILS_OWNER: 1554 case ScriptBaseClass.PARCEL_DETAILS_OWNER:
1442 if (!CheckThreatLevel(ThreatLevel.VeryHigh, functionName)) return; 1555 if(es != null && !es.IsEstateManagerOrOwner(m_host.OwnerID))
1443 if (UUID.TryParse(arg, out uuid)) 1556 {
1444 newLand.OwnerID = uuid; 1557 OSSLError("script owner does not have permission to modify the parcel owner");
1558 }
1559 else
1560 {
1561 if (UUID.TryParse(arg, out uuid))
1562 {
1563 if(newLand.OwnerID != uuid)
1564 {
1565 changed = true;
1566 newLand.OwnerID = uuid;
1567 newLand.GroupID = UUID.Zero;
1568 }
1569 }
1570 }
1445 break; 1571 break;
1446 1572
1447 case ScriptBaseClass.PARCEL_DETAILS_GROUP: 1573 case ScriptBaseClass.PARCEL_DETAILS_GROUP:
1448 if (!CheckThreatLevel(ThreatLevel.VeryHigh, functionName)) return; 1574 if(m_host.OwnerID == newLand.OwnerID || es == null || es.IsEstateManagerOrOwner(m_host.OwnerID))
1449 if (UUID.TryParse(arg, out uuid)) 1575 {
1450 newLand.GroupID = uuid; 1576 if (UUID.TryParse(arg, out uuid))
1577 {
1578 if(newLand.GroupID != uuid)
1579 {
1580 if(uuid == UUID.Zero)
1581 {
1582 changed = true;
1583 newLand.GroupID = uuid;
1584 }
1585 else
1586 {
1587 IGroupsModule groupsModule = m_ScriptEngine.World.RequestModuleInterface<IGroupsModule>();
1588 GroupMembershipData member = null;
1589 if (groupsModule != null)
1590 member = groupsModule.GetMembershipData(uuid, newLand.OwnerID);
1591 if (member == null)
1592 OSSLError(string.Format("land owner is not member of the new group for parcel"));
1593 else
1594 {
1595 changed = true;
1596 newLand.GroupID = uuid;
1597 }
1598 }
1599 }
1600 }
1601 }
1602 else
1603 {
1604 OSSLError("script owner does not have permission to modify the parcel group");
1605 }
1451 break; 1606 break;
1452 1607
1453 case ScriptBaseClass.PARCEL_DETAILS_CLAIMDATE: 1608 case ScriptBaseClass.PARCEL_DETAILS_CLAIMDATE:
1454 if (!CheckThreatLevel(ThreatLevel.VeryHigh, functionName)) return; 1609 if(es != null && !es.IsEstateManagerOrOwner(m_host.OwnerID))
1455 newLand.ClaimDate = Convert.ToInt32(arg); 1610 {
1456 if (newLand.ClaimDate == 0) 1611 OSSLError("script owner does not have permission to modify the parcel CLAIM DATE");
1457 newLand.ClaimDate = Util.UnixTimeSinceEpoch(); 1612 }
1613 else
1614 {
1615 int date = Convert.ToInt32(arg);
1616 if (date == 0)
1617 date = Util.UnixTimeSinceEpoch();
1618 if(newLand.ClaimDate != date)
1619 {
1620 changed = true;
1621 newLand.ClaimDate = date;
1622 }
1623 }
1624 break;
1625
1626 case ScriptBaseClass.PARCEL_DETAILS_SEE_AVATARS:
1627 bool newavs = (Convert.ToInt32(arg) != 0);
1628 if(newLand.SeeAVs != newavs)
1629 {
1630 changed = true;
1631 changedSeeAvs = true;
1632 changedoverlay = true;
1633 changedneedupdate = true;
1634 newLand.SeeAVs = newavs;
1635 }
1458 break; 1636 break;
1459 }
1460 }
1461 1637
1462 World.LandChannel.UpdateLandObject(newLand.LocalID,newLand); 1638 case ScriptBaseClass.PARCEL_DETAILS_ANY_AVATAR_SOUNDS:
1639 bool newavsounds = (Convert.ToInt32(arg) != 0);
1640 if(newLand.AnyAVSounds != newavsounds)
1641 {
1642 changed = true;
1643 newLand.AnyAVSounds = newavsounds;
1644 }
1645 break;
1646
1647 case ScriptBaseClass.PARCEL_DETAILS_GROUP_SOUNDS:
1648 bool newgrpsounds = (Convert.ToInt32(arg) != 0);
1649 if(newLand.GroupAVSounds != newgrpsounds)
1650 {
1651 changed = true;
1652 newLand.GroupAVSounds = newgrpsounds;
1653 }
1654 break;
1655 }
1656 }
1657 if(changed)
1658 {
1659 World.LandChannel.UpdateLandObject(newLand.LocalID, newLand);
1660
1661 if(changedneedupdate)
1662 {
1663 UUID parcelID= newLand.GlobalID;
1664 World.ForEachRootScenePresence(delegate (ScenePresence avatar)
1665 {
1666 if (avatar == null || avatar.IsDeleted || avatar.IsInTransit)
1667 return;
1668
1669 if(changedSeeAvs && avatar.currentParcelUUID == parcelID )
1670 avatar.currentParcelUUID = parcelID; // force parcel flags review
1671
1672 if(avatar.ControllingClient == null)
1673 return;
1674
1675 // this will be needed for some things like damage etc
1676// if(avatar.currentParcelUUID == parcelID)
1677// startLandObject.SendLandUpdateToClient(avatar.ControllingClient);
1678
1679 if(changedoverlay && !avatar.IsNPC)
1680 World.LandChannel.SendParcelsOverlay(avatar.ControllingClient);
1681 });
1682 }
1683 }
1463 } 1684 }
1464 1685
1465 public double osList2Double(LSL_Types.list src, int index) 1686 public double osList2Double(LSL_Types.list src, int index)
@@ -1469,7 +1690,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1469 // is not allowed to contain any. 1690 // is not allowed to contain any.
1470 // This really should be removed. 1691 // This really should be removed.
1471 // 1692 //
1472 m_host.AddScriptLPS(1);
1473 if (index < 0) 1693 if (index < 0)
1474 { 1694 {
1475 index = src.Length + index; 1695 index = src.Length + index;
@@ -1485,9 +1705,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1485 { 1705 {
1486 // What actually is the difference to the LL function? 1706 // What actually is the difference to the LL function?
1487 // 1707 //
1488 if (!CheckThreatLevel(ThreatLevel.VeryLow, "osSetParcelMediaURL")) return; 1708 CheckThreatLevel(ThreatLevel.VeryLow, "osSetParcelMediaURL");
1489
1490 m_host.AddScriptLPS(1);
1491 1709
1492 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 1710 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
1493 1711
@@ -1501,9 +1719,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1501 { 1719 {
1502 // What actually is the difference to the LL function? 1720 // What actually is the difference to the LL function?
1503 // 1721 //
1504 if (!CheckThreatLevel(ThreatLevel.VeryLow, "osSetParcelSIPAddress")) return; 1722 CheckThreatLevel(ThreatLevel.VeryLow, "osSetParcelSIPAddress");
1505
1506 m_host.AddScriptLPS(1);
1507 1723
1508 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 1724 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
1509 1725
@@ -1529,9 +1745,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1529 // that trigger engine-specific failures. 1745 // that trigger engine-specific failures.
1530 // Besides, public grid users aren't supposed to know. 1746 // Besides, public grid users aren't supposed to know.
1531 // 1747 //
1532 // On the other hand, what other script engines are there? 1748 // And yet, they get to choose the engine in their scripts. Pfffft
1533 // 1749// CheckThreatLevel(ThreatLevel.High, "osGetScriptEngineName");
1534 m_host.AddScriptLPS(1);
1535 1750
1536 int scriptEngineNameIndex = 0; 1751 int scriptEngineNameIndex = 0;
1537 1752
@@ -1557,7 +1772,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1557 1772
1558 public LSL_Integer osCheckODE() 1773 public LSL_Integer osCheckODE()
1559 { 1774 {
1560 m_host.AddScriptLPS(1);
1561 LSL_Integer ret = 0; // false 1775 LSL_Integer ret = 0; // false
1562 if (m_ScriptEngine.World.PhysicsScene != null) 1776 if (m_ScriptEngine.World.PhysicsScene != null)
1563 { 1777 {
@@ -1580,22 +1794,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1580 // about the physics engine, this function returns an empty string if 1794 // about the physics engine, this function returns an empty string if
1581 // the user does not have permission to see it. This as opposed to 1795 // the user does not have permission to see it. This as opposed to
1582 // throwing an exception. 1796 // throwing an exception.
1583 m_host.AddScriptLPS(1); 1797
1584 string ret = String.Empty; 1798 string ret = String.Empty;
1799// if (String.IsNullOrEmpty(CheckThreatLevelTest(ThreatLevel.High, "osGetPhysicsEngineType")))
1800 {
1801 if (m_ScriptEngine.World.PhysicsScene != null)
1802 {
1803 ret = m_ScriptEngine.World.PhysicsScene.EngineType;
1804 // An old physics engine might have an uninitialized engine type
1805 if (ret == null)
1806 ret = "unknown";
1807 }
1808 }
1809
1810 return ret;
1811 }
1812
1813 public string osGetPhysicsEngineName()
1814 {
1815 CheckThreatLevel();
1816
1817 string ret = "NoEngine";
1585 if (m_ScriptEngine.World.PhysicsScene != null) 1818 if (m_ScriptEngine.World.PhysicsScene != null)
1586 { 1819 {
1587 ret = m_ScriptEngine.World.PhysicsScene.EngineType; 1820 ret = m_ScriptEngine.World.PhysicsScene.EngineName;
1588 // An old physics engine might have an uninitialized engine type 1821 // An old physics engine might have an uninitialized engine type
1589 if (ret == null) 1822 if (ret == null)
1590 ret = "unknown"; 1823 ret = "UnknownEngine";
1591 } 1824 }
1592
1593 return ret; 1825 return ret;
1594 } 1826 }
1595 1827
1596 public string osGetSimulatorVersion() 1828 public string osGetSimulatorVersion()
1597 { 1829 {
1598 m_host.AddScriptLPS(1); 1830 // High because it can be used to target attacks to known weaknesses
1831 // This would allow a new class of griefer scripts that don't even
1832 // require their user to know what they are doing (see script
1833 // kiddie)
1834 //
1835 // Or they could check in the About window. Pfffft
1836// CheckThreatLevel(ThreatLevel.High,"osGetSimulatorVersion");
1599 1837
1600 return m_ScriptEngine.World.GetSimulatorVersion(); 1838 return m_ScriptEngine.World.GetSimulatorVersion();
1601 } 1839 }
@@ -1639,8 +1877,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1639 1877
1640 public Object osParseJSONNew(string JSON) 1878 public Object osParseJSONNew(string JSON)
1641 { 1879 {
1642 m_host.AddScriptLPS(1);
1643
1644 try 1880 try
1645 { 1881 {
1646 OSD decoded = OSDParser.DeserializeJson(JSON); 1882 OSD decoded = OSDParser.DeserializeJson(JSON);
@@ -1648,15 +1884,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1648 } 1884 }
1649 catch(Exception e) 1885 catch(Exception e)
1650 { 1886 {
1651 OSSLError("osParseJSONNew: Problems decoding JSON string " + JSON + " : " + e.Message); 1887 OSSLError("osParseJSONNew: Problems decoding JSON string " + JSON + " : " + e.Message) ;
1652 return null; 1888 return null;
1653 } 1889 }
1654 } 1890 }
1655 1891
1656 public Hashtable osParseJSON(string JSON) 1892 public Hashtable osParseJSON(string JSON)
1657 { 1893 {
1658 m_host.AddScriptLPS(1);
1659
1660 Object decoded = osParseJSONNew(JSON); 1894 Object decoded = osParseJSONNew(JSON);
1661 1895
1662 if ( decoded is Hashtable ) { 1896 if ( decoded is Hashtable ) {
@@ -1686,8 +1920,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1686 /// <param name="message"></param> 1920 /// <param name="message"></param>
1687 public void osMessageObject(LSL_Key objectUUID, string message) 1921 public void osMessageObject(LSL_Key objectUUID, string message)
1688 { 1922 {
1689 m_host.AddScriptLPS(1);
1690
1691 UUID objUUID; 1923 UUID objUUID;
1692 if (!UUID.TryParse(objectUUID, out objUUID)) // prior to patching, a thrown exception regarding invalid GUID format would be shouted instead. 1924 if (!UUID.TryParse(objectUUID, out objUUID)) // prior to patching, a thrown exception regarding invalid GUID format would be shouted instead.
1693 { 1925 {
@@ -1715,6 +1947,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1715 "dataserver", resobj, new DetectParams[0])); 1947 "dataserver", resobj, new DetectParams[0]));
1716 } 1948 }
1717 1949
1950
1951 /// <summary>
1952 /// Similar to llDie but given an object UUID
1953 /// </summary>
1954 /// <param name="objectUUID"></param>
1955
1956 public void osDie(LSL_Key objectUUID)
1957 {
1958// CheckThreatLevel(ThreatLevel.VeryHigh, "osDie");
1959 // if this is restricted to objects rezzed by this host level can be reduced
1960
1961// CheckThreatLevel(ThreatLevel.Low, "osDie");
1962
1963 UUID objUUID;
1964 if (!UUID.TryParse(objectUUID, out objUUID))
1965 {
1966 OSSLShoutError("osDie() cannot delete objects with invalid UUIDs");
1967 return;
1968 }
1969
1970 // harakiri check
1971 if(objUUID == UUID.Zero)
1972 {
1973 if (!m_host.ParentGroup.IsAttachment)
1974 throw new SelfDeleteException();
1975 return;
1976 }
1977
1978 SceneObjectGroup sceneOG = World.GetSceneObjectGroup(objUUID);
1979
1980 if (sceneOG == null || sceneOG.IsDeleted)
1981 return;
1982
1983 if(sceneOG.IsAttachment)
1984 return;
1985
1986 if (sceneOG.OwnerID != m_host.OwnerID)
1987 return;
1988
1989 // harakiri check
1990 if(sceneOG.UUID == m_host.ParentGroup.UUID)
1991 throw new SelfDeleteException();
1992
1993 // restrict to objects rezzed by host
1994 if(sceneOG.RezzerID == m_host.ParentGroup.UUID)
1995 World.DeleteSceneObject(sceneOG, false);
1996 }
1997
1718 /// <summary> 1998 /// <summary>
1719 /// Write a notecard directly to the prim's inventory. 1999 /// Write a notecard directly to the prim's inventory.
1720 /// </summary> 2000 /// </summary>
@@ -1727,7 +2007,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1727 /// <param name="contents">The contents of the notecard.</param> 2007 /// <param name="contents">The contents of the notecard.</param>
1728 public void osMakeNotecard(string notecardName, LSL_Types.list contents) 2008 public void osMakeNotecard(string notecardName, LSL_Types.list contents)
1729 { 2009 {
1730 m_host.AddScriptLPS(1); 2010// CheckThreatLevel(ThreatLevel.High, "osMakeNotecard");
1731 2011
1732 StringBuilder notecardData = new StringBuilder(); 2012 StringBuilder notecardData = new StringBuilder();
1733 2013
@@ -1778,8 +2058,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1778 taskItem.ResetIDs(m_host.UUID); 2058 taskItem.ResetIDs(m_host.UUID);
1779 taskItem.ParentID = m_host.UUID; 2059 taskItem.ParentID = m_host.UUID;
1780 taskItem.CreationDate = (uint)Util.UnixTimeSinceEpoch(); 2060 taskItem.CreationDate = (uint)Util.UnixTimeSinceEpoch();
1781 taskItem.Name = asset.Name; 2061 taskItem.Name = name;
1782 taskItem.Description = asset.Description; 2062 taskItem.Description = description;
1783 taskItem.Type = (int)AssetType.Notecard; 2063 taskItem.Type = (int)AssetType.Notecard;
1784 taskItem.InvType = (int)InventoryType.Notecard; 2064 taskItem.InvType = (int)InventoryType.Notecard;
1785 taskItem.OwnerID = m_host.OwnerID; 2065 taskItem.OwnerID = m_host.OwnerID;
@@ -1799,6 +2079,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1799 m_host.Inventory.AddInventoryItemExclusive(taskItem, false); 2079 m_host.Inventory.AddInventoryItemExclusive(taskItem, false);
1800 else 2080 else
1801 m_host.Inventory.AddInventoryItem(taskItem, false); 2081 m_host.Inventory.AddInventoryItem(taskItem, false);
2082 m_host.ParentGroup.InvalidateDeepEffectivePerms();
1802 2083
1803 return taskItem; 2084 return taskItem;
1804 } 2085 }
@@ -1843,15 +2124,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1843 { 2124 {
1844 UUID assetID = UUID.Zero; 2125 UUID assetID = UUID.Zero;
1845 2126
1846 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 2127 bool notecardNameIsUUID = UUID.TryParse(notecardNameOrUuid, out assetID);
2128
2129 if (!notecardNameIsUUID)
1847 { 2130 {
1848 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 2131 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1849 {
1850 if (item.Type == 7 && item.Name == notecardNameOrUuid)
1851 {
1852 assetID = item.AssetID;
1853 }
1854 }
1855 } 2132 }
1856 2133
1857 if (assetID == UUID.Zero) 2134 if (assetID == UUID.Zero)
@@ -1862,13 +2139,43 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1862 AssetBase a = World.AssetService.Get(assetID.ToString()); 2139 AssetBase a = World.AssetService.Get(assetID.ToString());
1863 2140
1864 if (a == null) 2141 if (a == null)
1865 return UUID.Zero; 2142 {
2143 // Whoops, it's still possible here that the notecard name was properly
2144 // formatted like a UUID but isn't an asset UUID so lets look it up by name after all
2145 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
2146 if (assetID == UUID.Zero)
2147 return UUID.Zero;
2148
2149 if (!NotecardCache.IsCached(assetID))
2150 {
2151 a = World.AssetService.Get(assetID.ToString());
2152
2153 if (a == null)
2154 {
2155 return UUID.Zero;
2156 }
2157 }
2158 }
1866 2159
1867 NotecardCache.Cache(assetID, a.Data); 2160 NotecardCache.Cache(assetID, a.Data);
1868 }; 2161 };
1869 2162
1870 return assetID; 2163 return assetID;
1871 } 2164 }
2165 protected UUID SearchTaskInventoryForAssetId(string name)
2166 {
2167 UUID assetId = UUID.Zero;
2168 m_host.TaskInventory.LockItemsForRead(true);
2169 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
2170 {
2171 if (item.Type == 7 && item.Name == name)
2172 {
2173 assetId = item.AssetID;
2174 }
2175 }
2176 m_host.TaskInventory.LockItemsForRead(false);
2177 return assetId;
2178 }
1872 2179
1873 /// <summary> 2180 /// <summary>
1874 /// Directly get an entire notecard at once. 2181 /// Directly get an entire notecard at once.
@@ -1885,7 +2192,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1885 /// <returns>Notecard line</returns> 2192 /// <returns>Notecard line</returns>
1886 public string osGetNotecardLine(string name, int line) 2193 public string osGetNotecardLine(string name, int line)
1887 { 2194 {
1888 m_host.AddScriptLPS(1); 2195// CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNotecardLine");
1889 2196
1890 UUID assetID = CacheNotecard(name); 2197 UUID assetID = CacheNotecard(name);
1891 2198
@@ -1912,7 +2219,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1912 /// <returns>Notecard text</returns> 2219 /// <returns>Notecard text</returns>
1913 public string osGetNotecard(string name) 2220 public string osGetNotecard(string name)
1914 { 2221 {
1915 m_host.AddScriptLPS(1); 2222// CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNotecard");
1916 2223
1917 string text = LoadNotecard(name); 2224 string text = LoadNotecard(name);
1918 2225
@@ -1941,7 +2248,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1941 /// <returns></returns> 2248 /// <returns></returns>
1942 public int osGetNumberOfNotecardLines(string name) 2249 public int osGetNumberOfNotecardLines(string name)
1943 { 2250 {
1944 m_host.AddScriptLPS(1); 2251// CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNumberOfNotecardLines");
1945 2252
1946 UUID assetID = CacheNotecard(name); 2253 UUID assetID = CacheNotecard(name);
1947 2254
@@ -1956,8 +2263,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1956 2263
1957 public string osAvatarName2Key(string firstname, string lastname) 2264 public string osAvatarName2Key(string firstname, string lastname)
1958 { 2265 {
1959 if (!CheckThreatLevel(ThreatLevel.Low, "osAvatarName2Key")) return string.Empty; 2266 CheckThreatLevel(ThreatLevel.Low, "osAvatarName2Key");
1960 m_host.AddScriptLPS(1);
1961 2267
1962 IUserManagement userManager = World.RequestModuleInterface<IUserManagement>(); 2268 IUserManagement userManager = World.RequestModuleInterface<IUserManagement>();
1963 if (userManager == null) 2269 if (userManager == null)
@@ -2008,8 +2314,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2008 2314
2009 public string osKey2Name(string id) 2315 public string osKey2Name(string id)
2010 { 2316 {
2011 m_host.AddScriptLPS(1);
2012
2013 UUID key = new UUID(); 2317 UUID key = new UUID();
2014 2318
2015 if (UUID.TryParse(id, out key)) 2319 if (UUID.TryParse(id, out key))
@@ -2117,8 +2421,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2117 /// <returns></returns> 2421 /// <returns></returns>
2118 public string osGetGridNick() 2422 public string osGetGridNick()
2119 { 2423 {
2120//// if (!CheckThreatLevel(ThreatLevel.None, "osGetGridNick")) return ""; 2424// CheckThreatLevel(ThreatLevel.Moderate, "osGetGridNick");
2121 m_host.AddScriptLPS(1);
2122 2425
2123 string nick = String.Empty; 2426 string nick = String.Empty;
2124 IConfigSource config = m_ScriptEngine.ConfigSource; 2427 IConfigSource config = m_ScriptEngine.ConfigSource;
@@ -2134,8 +2437,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2134 2437
2135 public string osGetGridName() 2438 public string osGetGridName()
2136 { 2439 {
2137//// if (!CheckThreatLevel(ThreatLevel.None, "osGetGridName")) return ""; 2440// CheckThreatLevel(ThreatLevel.Moderate, "osGetGridName");
2138 m_host.AddScriptLPS(1);
2139 2441
2140 string name = String.Empty; 2442 string name = String.Empty;
2141 IConfigSource config = m_ScriptEngine.ConfigSource; 2443 IConfigSource config = m_ScriptEngine.ConfigSource;
@@ -2151,8 +2453,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2151 2453
2152 public string osGetGridLoginURI() 2454 public string osGetGridLoginURI()
2153 { 2455 {
2154 if (!CheckThreatLevel(ThreatLevel.Moderate, "osGetGridLoginURI")) return ""; 2456// CheckThreatLevel(ThreatLevel.Moderate, "osGetGridLoginURI");
2155 m_host.AddScriptLPS(1);
2156 2457
2157 string loginURI = String.Empty; 2458 string loginURI = String.Empty;
2158 IConfigSource config = m_ScriptEngine.ConfigSource; 2459 IConfigSource config = m_ScriptEngine.ConfigSource;
@@ -2168,11 +2469,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2168 2469
2169 public string osGetGridHomeURI() 2470 public string osGetGridHomeURI()
2170 { 2471 {
2171 if (!CheckThreatLevel(ThreatLevel.Moderate, "osGetGridHomeURI")) return ""; 2472// CheckThreatLevel(ThreatLevel.Moderate, "osGetGridHomeURI");
2172 m_host.AddScriptLPS(1);
2173 2473
2174 IConfigSource config = m_ScriptEngine.ConfigSource; 2474 IConfigSource config = m_ScriptEngine.ConfigSource;
2175 string HomeURI = Util.GetConfigVarFromSections<string>(config, "HomeURI", 2475 string HomeURI = Util.GetConfigVarFromSections<string>(config, "HomeURI",
2176 new string[] { "Startup", "Hypergrid" }, String.Empty); 2476 new string[] { "Startup", "Hypergrid" }, String.Empty);
2177 2477
2178 if (!string.IsNullOrEmpty(HomeURI)) 2478 if (!string.IsNullOrEmpty(HomeURI))
@@ -2190,8 +2490,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2190 2490
2191 public string osGetGridGatekeeperURI() 2491 public string osGetGridGatekeeperURI()
2192 { 2492 {
2193 if (!CheckThreatLevel(ThreatLevel.Moderate, "osGetGridGatekeeperURI")) return ""; 2493 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridGatekeeperURI");
2194 m_host.AddScriptLPS(1);
2195 2494
2196 IConfigSource config = m_ScriptEngine.ConfigSource; 2495 IConfigSource config = m_ScriptEngine.ConfigSource;
2197 string gatekeeperURI = Util.GetConfigVarFromSections<string>(config, "GatekeeperURI", 2496 string gatekeeperURI = Util.GetConfigVarFromSections<string>(config, "GatekeeperURI",
@@ -2201,16 +2500,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2201 return gatekeeperURI; 2500 return gatekeeperURI;
2202 2501
2203 // Legacy. Remove soon! 2502 // Legacy. Remove soon!
2204 if (config.Configs["GridService"] != null) 2503//// if (config.Configs["GridService"] != null)
2205 gatekeeperURI = config.Configs["GridService"].GetString("Gatekeeper", gatekeeperURI); 2504//// gatekeeperURI = config.Configs["GridService"].GetString("Gatekeeper", gatekeeperURI);
2206 2505
2207 return gatekeeperURI; 2506 return gatekeeperURI;
2208 } 2507 }
2209 2508
2210 public string osGetGridCustom(string key) 2509 public string osGetGridCustom(string key)
2211 { 2510 {
2212 if (!CheckThreatLevel(ThreatLevel.Moderate, "osGetGridCustom")) return String.Empty; 2511// CheckThreatLevel(ThreatLevel.Moderate, "osGetGridCustom");
2213 m_host.AddScriptLPS(1);
2214 2512
2215 string retval = String.Empty; 2513 string retval = String.Empty;
2216 IConfigSource config = m_ScriptEngine.ConfigSource; 2514 IConfigSource config = m_ScriptEngine.ConfigSource;
@@ -2226,8 +2524,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2226 2524
2227 public string osGetAvatarHomeURI(string uuid) 2525 public string osGetAvatarHomeURI(string uuid)
2228 { 2526 {
2229 if (!CheckThreatLevel(ThreatLevel.Moderate, "osGetAvatarHomeURI")) return ""; 2527// CheckThreatLevel(ThreatLevel.Low, "osGetAvatarHomeURI");
2230 m_host.AddScriptLPS(1);
2231 2528
2232 IUserManagement userManager = m_ScriptEngine.World.RequestModuleInterface<IUserManagement>(); 2529 IUserManagement userManager = m_ScriptEngine.World.RequestModuleInterface<IUserManagement>();
2233 string returnValue = ""; 2530 string returnValue = "";
@@ -2259,15 +2556,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2259 2556
2260 public LSL_String osFormatString(string str, LSL_List strings) 2557 public LSL_String osFormatString(string str, LSL_List strings)
2261 { 2558 {
2262 m_host.AddScriptLPS(1);
2263
2264 return String.Format(str, strings.Data); 2559 return String.Format(str, strings.Data);
2265 } 2560 }
2266 2561
2267 public LSL_List osMatchString(string src, string pattern, int start) 2562 public LSL_List osMatchString(string src, string pattern, int start)
2268 { 2563 {
2269 m_host.AddScriptLPS(1);
2270
2271 LSL_List result = new LSL_List(); 2564 LSL_List result = new LSL_List();
2272 2565
2273 // Normalize indices (if negative). 2566 // Normalize indices (if negative).
@@ -2307,8 +2600,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2307 2600
2308 public LSL_String osReplaceString(string src, string pattern, string replace, int count, int start) 2601 public LSL_String osReplaceString(string src, string pattern, string replace, int count, int start)
2309 { 2602 {
2310 m_host.AddScriptLPS(1);
2311
2312 // Normalize indices (if negative). 2603 // Normalize indices (if negative).
2313 // After normlaization they may still be 2604 // After normlaization they may still be
2314 // negative, but that is now relative to 2605 // negative, but that is now relative to
@@ -2331,25 +2622,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2331 2622
2332 public string osLoadedCreationDate() 2623 public string osLoadedCreationDate()
2333 { 2624 {
2334 if (!CheckThreatLevel(ThreatLevel.Low, "osLoadedCreationDate")) return "";
2335 m_host.AddScriptLPS(1);
2336
2337 return World.RegionInfo.RegionSettings.LoadedCreationDate; 2625 return World.RegionInfo.RegionSettings.LoadedCreationDate;
2338 } 2626 }
2339 2627
2340 public string osLoadedCreationTime() 2628 public string osLoadedCreationTime()
2341 { 2629 {
2342 if (!CheckThreatLevel(ThreatLevel.Low, "osLoadedCreationTime")) return "";
2343 m_host.AddScriptLPS(1);
2344
2345 return World.RegionInfo.RegionSettings.LoadedCreationTime; 2630 return World.RegionInfo.RegionSettings.LoadedCreationTime;
2346 } 2631 }
2347 2632
2348 public string osLoadedCreationID() 2633 public string osLoadedCreationID()
2349 { 2634 {
2350 if (!CheckThreatLevel(ThreatLevel.Low, "osLoadedCreationID")) return "";
2351 m_host.AddScriptLPS(1);
2352
2353 return World.RegionInfo.RegionSettings.LoadedCreationID; 2635 return World.RegionInfo.RegionSettings.LoadedCreationID;
2354 } 2636 }
2355 2637
@@ -2368,8 +2650,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2368 /// <returns></returns> 2650 /// <returns></returns>
2369 public LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules) 2651 public LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules)
2370 { 2652 {
2371 if (!CheckThreatLevel(ThreatLevel.High, "osGetLinkPrimitiveParams")) return new LSL_List(); 2653 CheckThreatLevel(ThreatLevel.VeryLow, "osGetLinkPrimitiveParams");
2372 m_host.AddScriptLPS(1); 2654
2373 InitLSL(); 2655 InitLSL();
2374 // One needs to cast m_LSL_Api because we're using functions not 2656 // One needs to cast m_LSL_Api because we're using functions not
2375 // on the ILSL_Api interface. 2657 // on the ILSL_Api interface.
@@ -2396,9 +2678,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2396 2678
2397 public void osForceCreateLink(string target, int parent) 2679 public void osForceCreateLink(string target, int parent)
2398 { 2680 {
2399 if (!CheckThreatLevel(ThreatLevel.VeryLow, "osForceCreateLink")) return; 2681 CheckThreatLevel(ThreatLevel.VeryLow, "osForceCreateLink");
2400
2401 m_host.AddScriptLPS(1);
2402 2682
2403 InitLSL(); 2683 InitLSL();
2404 ((LSL_Api)m_LSL_Api).CreateLink(target, parent); 2684 ((LSL_Api)m_LSL_Api).CreateLink(target, parent);
@@ -2406,9 +2686,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2406 2686
2407 public void osForceBreakLink(int linknum) 2687 public void osForceBreakLink(int linknum)
2408 { 2688 {
2409 if (!CheckThreatLevel(ThreatLevel.VeryLow, "osForceBreakLink")) return; 2689 CheckThreatLevel(ThreatLevel.VeryLow, "osForceBreakLink");
2410
2411 m_host.AddScriptLPS(1);
2412 2690
2413 InitLSL(); 2691 InitLSL();
2414 ((LSL_Api)m_LSL_Api).BreakLink(linknum); 2692 ((LSL_Api)m_LSL_Api).BreakLink(linknum);
@@ -2416,9 +2694,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2416 2694
2417 public void osForceBreakAllLinks() 2695 public void osForceBreakAllLinks()
2418 { 2696 {
2419 if (!CheckThreatLevel(ThreatLevel.VeryLow, "osForceBreakAllLinks")) return; 2697 CheckThreatLevel(ThreatLevel.VeryLow, "osForceBreakAllLinks");
2420
2421 m_host.AddScriptLPS(1);
2422 2698
2423 InitLSL(); 2699 InitLSL();
2424 ((LSL_Api)m_LSL_Api).BreakAllLinks(); 2700 ((LSL_Api)m_LSL_Api).BreakAllLinks();
@@ -2426,8 +2702,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2426 2702
2427 public LSL_Integer osIsNpc(LSL_Key npc) 2703 public LSL_Integer osIsNpc(LSL_Key npc)
2428 { 2704 {
2429 m_host.AddScriptLPS(1);
2430
2431 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2705 INPCModule module = World.RequestModuleInterface<INPCModule>();
2432 if (module != null) 2706 if (module != null)
2433 { 2707 {
@@ -2442,31 +2716,99 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2442 2716
2443 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard) 2717 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard)
2444 { 2718 {
2445 if (!CheckThreatLevel(ThreatLevel.High, "osNpcCreate")) return new LSL_Key(ScriptBaseClass.NULL_KEY); 2719 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2446 m_host.AddScriptLPS(1); 2720
2721 // have to get the npc module also here to set the default Not Owned
2722 INPCModule module = World.RequestModuleInterface<INPCModule>();
2723 if(module == null)
2724 return new LSL_Key(UUID.Zero.ToString());
2725
2726 bool owned = (module.NPCOptionFlags & NPCOptionsFlags.AllowNotOwned) == 0;
2447 2727
2448 return NpcCreate(firstname, lastname, position, notecard, false, false); 2728 return NpcCreate(firstname, lastname, position, notecard, owned, false, false);
2449 } 2729 }
2450 2730
2451 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2731 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
2452 { 2732 {
2453 if (!CheckThreatLevel(ThreatLevel.High, "osNpcCreate")) return new LSL_Key(ScriptBaseClass.NULL_KEY); 2733 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2454 m_host.AddScriptLPS(1);
2455 2734
2456 return NpcCreate( 2735 return NpcCreate(
2457 firstname, lastname, position, notecard, 2736 firstname, lastname, position, notecard,
2458 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2737 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2459 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2738 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0,
2739 (options & ScriptBaseClass.OS_NPC_OBJECT_GROUP) != 0);
2460 } 2740 }
2461 2741
2462 private LSL_Key NpcCreate( 2742 private LSL_Key NpcCreate(
2463 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2743 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent, bool hostGroupID)
2464 { 2744 {
2745 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2746 {
2747 OSSLError("no permission to rez NPC at requested location");
2748 return new LSL_Key(UUID.Zero.ToString());
2749 }
2750
2465 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2751 INPCModule module = World.RequestModuleInterface<INPCModule>();
2466 if (module != null) 2752 if(module == null)
2753 {
2754 OSSLError("NPC module not enabled");
2755 return new LSL_Key(UUID.Zero.ToString());
2756 }
2757
2758 string groupTitle = String.Empty;
2759 UUID groupID = UUID.Zero;
2760
2761 AvatarAppearance appearance = null;
2762
2763 // check creation options
2764 NPCOptionsFlags createFlags = module.NPCOptionFlags;
2765
2766 if((createFlags & NPCOptionsFlags.AllowNotOwned) == 0 && !owned)
2767 {
2768 OSSLError("Not owned NPCs disabled");
2769 owned = true; // we should get here...
2770 }
2771
2772 if((createFlags & NPCOptionsFlags.AllowSenseAsAvatar) == 0 && senseAsAgent)
2773 {
2774 OSSLError("NPC allow sense as Avatar disabled");
2775 senseAsAgent = false;
2776 }
2777
2778 if(hostGroupID && m_host.GroupID != UUID.Zero)
2467 { 2779 {
2468 AvatarAppearance appearance = null; 2780 IGroupsModule groupsModule = m_ScriptEngine.World.RequestModuleInterface<IGroupsModule>();
2781 if (groupsModule != null)
2782 {
2783 GroupMembershipData member = groupsModule.GetMembershipData(m_host.GroupID, m_host.OwnerID);
2784 if (member == null)
2785 {
2786 OSSLError(string.Format("osNpcCreate: the object owner is not member of the object group"));
2787 return new LSL_Key(UUID.Zero.ToString());
2788 }
2789
2790 groupID = m_host.GroupID;
2791
2792 if((createFlags & NPCOptionsFlags.NoNPCGroup) != 0)
2793 {
2794 GroupRecord grprec = groupsModule.GetGroupRecord(m_host.GroupID);
2795 if(grprec != null && grprec.GroupName != "")
2796 groupTitle = grprec.GroupName;
2797 }
2798 }
2799 }
2800
2801 if((createFlags & NPCOptionsFlags.NoNPCGroup) == 0)
2802 {
2803 if (firstname != String.Empty || lastname != String.Empty)
2804 {
2805 if (firstname != "Shown outfit:")
2806 groupTitle = "- NPC -";
2807 }
2808 }
2469 2809
2810 if((createFlags & NPCOptionsFlags.AllowCloneOtherAvatars) != 0)
2811 {
2470 UUID id; 2812 UUID id;
2471 if (UUID.TryParse(notecard, out id)) 2813 if (UUID.TryParse(notecard, out id))
2472 { 2814 {
@@ -2474,38 +2816,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2474 if (clonePresence != null) 2816 if (clonePresence != null)
2475 appearance = clonePresence.Appearance; 2817 appearance = clonePresence.Appearance;
2476 } 2818 }
2819 }
2477 2820
2478 if (appearance == null) 2821 if (appearance == null)
2479 { 2822 {
2480 string appearanceSerialized = LoadNotecard(notecard); 2823 string appearanceSerialized = LoadNotecard(notecard);
2481 2824
2482 if (appearanceSerialized != null) 2825 if (appearanceSerialized != null)
2826 {
2827 try
2483 { 2828 {
2484 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2829 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2485 appearance = new AvatarAppearance(); 2830 appearance = new AvatarAppearance();
2486 appearance.Unpack(appearanceOsd); 2831 appearance.Unpack(appearanceOsd);
2487 } 2832 }
2488 else 2833 catch
2489 { 2834 {
2490 OSSLError(string.Format("osNpcCreate: Notecard reference '{0}' not found.", notecard)); 2835 OSSLError(string.Format("osNpcCreate: Error processing notcard '{0}'", notecard));
2836 return new LSL_Key(UUID.Zero.ToString());
2491 } 2837 }
2492 } 2838 }
2839 else
2840 {
2841 OSSLError(string.Format("osNpcCreate: Notecard reference '{0}' not found.", notecard));
2842 }
2843 }
2493 2844
2494 UUID ownerID = UUID.Zero; 2845 UUID ownerID = UUID.Zero;
2495 if (owned) 2846 if (owned)
2496 ownerID = m_host.OwnerID; 2847 ownerID = m_host.OwnerID;
2497 UUID x = module.CreateNPC(firstname, 2848 UUID x = module.CreateNPC(firstname,
2498 lastname, 2849 lastname,
2499 position, 2850 position,
2500 ownerID, 2851 UUID.Random(),
2501 senseAsAgent, 2852 ownerID,
2502 World, 2853 groupTitle,
2503 appearance); 2854 groupID,
2855 senseAsAgent,
2856 World,
2857 appearance);
2504 2858
2505 return new LSL_Key(x.ToString()); 2859 ScenePresence sp;
2860 if (World.TryGetScenePresence(x, out sp))
2861 {
2862 sp.SendAvatarDataToAllAgents();
2506 } 2863 }
2507 2864 return new LSL_Key(x.ToString());
2508 return new LSL_Key(UUID.Zero.ToString());
2509 } 2865 }
2510 2866
2511 /// <summary> 2867 /// <summary>
@@ -2516,9 +2872,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2516 /// <returns>The asset ID of the notecard saved.</returns> 2872 /// <returns>The asset ID of the notecard saved.</returns>
2517 public LSL_Key osNpcSaveAppearance(LSL_Key npc, string notecard) 2873 public LSL_Key osNpcSaveAppearance(LSL_Key npc, string notecard)
2518 { 2874 {
2519 if (!CheckThreatLevel(ThreatLevel.High, "osNpcSaveAppearance")) return new LSL_Key(ScriptBaseClass.NULL_KEY);
2520 m_host.AddScriptLPS(1);
2521
2522 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 2875 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2523 2876
2524 if (npcModule != null) 2877 if (npcModule != null)
@@ -2538,9 +2891,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2538 2891
2539 public void osNpcLoadAppearance(LSL_Key npc, string notecard) 2892 public void osNpcLoadAppearance(LSL_Key npc, string notecard)
2540 { 2893 {
2541 if (!CheckThreatLevel(ThreatLevel.High, "osNpcLoadAppearance")) return;
2542 m_host.AddScriptLPS(1);
2543
2544 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 2894 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2545 2895
2546 if (npcModule != null) 2896 if (npcModule != null)
@@ -2570,8 +2920,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2570 2920
2571 public LSL_Key osNpcGetOwner(LSL_Key npc) 2921 public LSL_Key osNpcGetOwner(LSL_Key npc)
2572 { 2922 {
2573 m_host.AddScriptLPS(1);
2574
2575 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 2923 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2576 if (npcModule != null) 2924 if (npcModule != null)
2577 { 2925 {
@@ -2591,8 +2939,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2591 2939
2592 public LSL_Vector osNpcGetPos(LSL_Key npc) 2940 public LSL_Vector osNpcGetPos(LSL_Key npc)
2593 { 2941 {
2594 m_host.AddScriptLPS(1);
2595
2596 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 2942 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2597 if (npcModule != null) 2943 if (npcModule != null)
2598 { 2944 {
@@ -2614,9 +2960,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2614 2960
2615 public void osNpcMoveTo(LSL_Key npc, LSL_Vector pos) 2961 public void osNpcMoveTo(LSL_Key npc, LSL_Vector pos)
2616 { 2962 {
2617 if (!CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo")) return;
2618 m_host.AddScriptLPS(1);
2619
2620 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2963 INPCModule module = World.RequestModuleInterface<INPCModule>();
2621 if (module != null) 2964 if (module != null)
2622 { 2965 {
@@ -2633,9 +2976,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2633 2976
2634 public void osNpcMoveToTarget(LSL_Key npc, LSL_Vector target, int options) 2977 public void osNpcMoveToTarget(LSL_Key npc, LSL_Vector target, int options)
2635 { 2978 {
2636 if (!CheckThreatLevel(ThreatLevel.High, "osNpcMoveToTarget")) return;
2637 m_host.AddScriptLPS(1);
2638
2639 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2979 INPCModule module = World.RequestModuleInterface<INPCModule>();
2640 if (module != null) 2980 if (module != null)
2641 { 2981 {
@@ -2658,8 +2998,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2658 2998
2659 public LSL_Rotation osNpcGetRot(LSL_Key npc) 2999 public LSL_Rotation osNpcGetRot(LSL_Key npc)
2660 { 3000 {
2661 m_host.AddScriptLPS(1);
2662
2663 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 3001 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2664 if (npcModule != null) 3002 if (npcModule != null)
2665 { 3003 {
@@ -2681,9 +3019,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2681 3019
2682 public void osNpcSetRot(LSL_Key npc, LSL_Rotation rotation) 3020 public void osNpcSetRot(LSL_Key npc, LSL_Rotation rotation)
2683 { 3021 {
2684 if (!CheckThreatLevel(ThreatLevel.High, "osNpcSetRot")) return;
2685 m_host.AddScriptLPS(1);
2686
2687 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 3022 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2688 if (npcModule != null) 3023 if (npcModule != null)
2689 { 3024 {
@@ -2703,9 +3038,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2703 3038
2704 public void osNpcStopMoveToTarget(LSL_Key npc) 3039 public void osNpcStopMoveToTarget(LSL_Key npc)
2705 { 3040 {
2706 if (!CheckThreatLevel(ThreatLevel.High, "osNpcStopMoveToTarget")) return;
2707 m_host.AddScriptLPS(1);
2708
2709 INPCModule module = World.RequestModuleInterface<INPCModule>(); 3041 INPCModule module = World.RequestModuleInterface<INPCModule>();
2710 if (module != null) 3042 if (module != null)
2711 { 3043 {
@@ -2718,6 +3050,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2718 } 3050 }
2719 } 3051 }
2720 3052
3053 public void osNpcSetProfileAbout(LSL_Key npc, string about)
3054 {
3055 INPCModule module = World.RequestModuleInterface<INPCModule>();
3056 if (module != null)
3057 {
3058 UUID npcId = new UUID(npc.m_string);
3059
3060 if (!module.CheckPermissions(npcId, m_host.OwnerID))
3061 return;
3062
3063 ScenePresence sp = World.GetScenePresence(npcId);
3064 if (sp != null)
3065 ((INPC)(sp.ControllingClient)).profileAbout = about;
3066 }
3067 }
3068
3069 public void osNpcSetProfileImage(LSL_Key npc, string image)
3070 {
3071 INPCModule module = World.RequestModuleInterface<INPCModule>();
3072 if (module != null)
3073 {
3074 UUID npcId = new UUID(npc.m_string);
3075
3076 if (!module.CheckPermissions(npcId, m_host.OwnerID))
3077 return;
3078
3079 UUID ImageID = new UUID();
3080
3081 ImageID = ScriptUtils.GetAssetIdFromItemName(m_host, image, (int)AssetType.Texture);
3082
3083 if (ImageID == null || ImageID == UUID.Zero)
3084 {
3085 if (!UUID.TryParse(image, out ImageID))
3086 return;
3087 }
3088
3089 ScenePresence sp = World.GetScenePresence(npcId);
3090 if (sp != null)
3091 ((INPC)(sp.ControllingClient)).profileImage = ImageID;
3092 }
3093 }
3094
2721 public void osNpcSay(LSL_Key npc, string message) 3095 public void osNpcSay(LSL_Key npc, string message)
2722 { 3096 {
2723 osNpcSay(npc, 0, message); 3097 osNpcSay(npc, 0, message);
@@ -2725,9 +3099,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2725 3099
2726 public void osNpcSay(LSL_Key npc, int channel, string message) 3100 public void osNpcSay(LSL_Key npc, int channel, string message)
2727 { 3101 {
2728 if (!CheckThreatLevel(ThreatLevel.High, "osNpcSay")) return;
2729 m_host.AddScriptLPS(1);
2730
2731 INPCModule module = World.RequestModuleInterface<INPCModule>(); 3102 INPCModule module = World.RequestModuleInterface<INPCModule>();
2732 if (module != null) 3103 if (module != null)
2733 { 3104 {
@@ -2742,9 +3113,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2742 3113
2743 public void osNpcShout(LSL_Key npc, int channel, string message) 3114 public void osNpcShout(LSL_Key npc, int channel, string message)
2744 { 3115 {
2745 if (!CheckThreatLevel(ThreatLevel.High, "osNpcShout")) return;
2746 m_host.AddScriptLPS(1);
2747
2748 INPCModule module = World.RequestModuleInterface<INPCModule>(); 3116 INPCModule module = World.RequestModuleInterface<INPCModule>();
2749 if (module != null) 3117 if (module != null)
2750 { 3118 {
@@ -2759,9 +3127,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2759 3127
2760 public void osNpcSit(LSL_Key npc, LSL_Key target, int options) 3128 public void osNpcSit(LSL_Key npc, LSL_Key target, int options)
2761 { 3129 {
2762 if (!CheckThreatLevel(ThreatLevel.High, "osNpcSit")) return;
2763 m_host.AddScriptLPS(1);
2764
2765 INPCModule module = World.RequestModuleInterface<INPCModule>(); 3130 INPCModule module = World.RequestModuleInterface<INPCModule>();
2766 if (module != null) 3131 if (module != null)
2767 { 3132 {
@@ -2776,9 +3141,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2776 3141
2777 public void osNpcStand(LSL_Key npc) 3142 public void osNpcStand(LSL_Key npc)
2778 { 3143 {
2779 if (!CheckThreatLevel(ThreatLevel.High, "osNpcStand")) return;
2780 m_host.AddScriptLPS(1);
2781
2782 INPCModule module = World.RequestModuleInterface<INPCModule>(); 3144 INPCModule module = World.RequestModuleInterface<INPCModule>();
2783 if (module != null) 3145 if (module != null)
2784 { 3146 {
@@ -2793,26 +3155,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2793 3155
2794 public void osNpcRemove(LSL_Key npc) 3156 public void osNpcRemove(LSL_Key npc)
2795 { 3157 {
2796 if (!CheckThreatLevel(ThreatLevel.High, "osNpcRemove")) return; 3158 try
2797 m_host.AddScriptLPS(1);
2798
2799 INPCModule module = World.RequestModuleInterface<INPCModule>();
2800 if (module != null)
2801 { 3159 {
2802 UUID npcId = new UUID(npc.m_string); 3160 INPCModule module = World.RequestModuleInterface<INPCModule>();
3161 if (module != null)
3162 {
3163 UUID npcId = new UUID(npc.m_string);
2803 3164
2804 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 3165 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2805 return; 3166 return;
2806 3167
2807 module.DeleteNPC(npcId, World); 3168 module.DeleteNPC(npcId, World);
3169 }
2808 } 3170 }
3171 catch { }
2809 } 3172 }
2810 3173
2811 public void osNpcPlayAnimation(LSL_Key npc, string animation) 3174 public void osNpcPlayAnimation(LSL_Key npc, string animation)
2812 { 3175 {
2813 if (!CheckThreatLevel(ThreatLevel.High, "osNpcPlayAnimation")) return;
2814 m_host.AddScriptLPS(1);
2815
2816 INPCModule module = World.RequestModuleInterface<INPCModule>(); 3176 INPCModule module = World.RequestModuleInterface<INPCModule>();
2817 if (module != null) 3177 if (module != null)
2818 { 3178 {
@@ -2825,9 +3185,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2825 3185
2826 public void osNpcStopAnimation(LSL_Key npc, string animation) 3186 public void osNpcStopAnimation(LSL_Key npc, string animation)
2827 { 3187 {
2828 if (!CheckThreatLevel(ThreatLevel.High, "osNpcStopAnimation")) return;
2829 m_host.AddScriptLPS(1);
2830
2831 INPCModule module = World.RequestModuleInterface<INPCModule>(); 3188 INPCModule module = World.RequestModuleInterface<INPCModule>();
2832 if (module != null) 3189 if (module != null)
2833 { 3190 {
@@ -2840,9 +3197,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2840 3197
2841 public void osNpcWhisper(LSL_Key npc, int channel, string message) 3198 public void osNpcWhisper(LSL_Key npc, int channel, string message)
2842 { 3199 {
2843 if (!CheckThreatLevel(ThreatLevel.High, "osNpcWhisper")) return;
2844 m_host.AddScriptLPS(1);
2845
2846 INPCModule module = World.RequestModuleInterface<INPCModule>(); 3200 INPCModule module = World.RequestModuleInterface<INPCModule>();
2847 if (module != null) 3201 if (module != null)
2848 { 3202 {
@@ -2857,9 +3211,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2857 3211
2858 public void osNpcTouch(LSL_Key npcLSL_Key, LSL_Key object_key, LSL_Integer link_num) 3212 public void osNpcTouch(LSL_Key npcLSL_Key, LSL_Key object_key, LSL_Integer link_num)
2859 { 3213 {
2860 if (!CheckThreatLevel(ThreatLevel.High, "osNpcTouch")) return;
2861 m_host.AddScriptLPS(1);
2862
2863 INPCModule module = World.RequestModuleInterface<INPCModule>(); 3214 INPCModule module = World.RequestModuleInterface<INPCModule>();
2864 int linkNum = link_num.value; 3215 int linkNum = link_num.value;
2865 if (module != null || (linkNum < 0 && linkNum != ScriptBaseClass.LINK_THIS)) 3216 if (module != null || (linkNum < 0 && linkNum != ScriptBaseClass.LINK_THIS))
@@ -2902,16 +3253,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2902 /// <returns>The asset ID of the notecard saved.</returns> 3253 /// <returns>The asset ID of the notecard saved.</returns>
2903 public LSL_Key osOwnerSaveAppearance(string notecard) 3254 public LSL_Key osOwnerSaveAppearance(string notecard)
2904 { 3255 {
2905 if (!CheckThreatLevel(ThreatLevel.Moderate, "osOwnerSaveAppearance")) return new LSL_Key(ScriptBaseClass.NULL_KEY);
2906 m_host.AddScriptLPS(1);
2907
2908 return SaveAppearanceToNotecard(m_host.OwnerID, notecard); 3256 return SaveAppearanceToNotecard(m_host.OwnerID, notecard);
2909 } 3257 }
2910 3258
2911 public LSL_Key osAgentSaveAppearance(LSL_Key avatarId, string notecard) 3259 public LSL_Key osAgentSaveAppearance(LSL_Key avatarId, string notecard)
2912 { 3260 {
2913 if (!CheckThreatLevel(ThreatLevel.High, "osAgentSaveAppearance")) return new LSL_Key(ScriptBaseClass.NULL_KEY); 3261 CheckThreatLevel(ThreatLevel.VeryHigh, "osAgentSaveAppearance");
2914 m_host.AddScriptLPS(1);
2915 3262
2916 return SaveAppearanceToNotecard(avatarId, notecard); 3263 return SaveAppearanceToNotecard(avatarId, notecard);
2917 } 3264 }
@@ -2923,7 +3270,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2923 if (appearanceModule != null) 3270 if (appearanceModule != null)
2924 { 3271 {
2925 appearanceModule.SaveBakedTextures(sp.UUID); 3272 appearanceModule.SaveBakedTextures(sp.UUID);
2926 OSDMap appearancePacked = sp.Appearance.Pack(); 3273 EntityTransferContext ctx = new EntityTransferContext();
3274 OSDMap appearancePacked = sp.Appearance.Pack(ctx);
2927 3275
2928 TaskInventoryItem item 3276 TaskInventoryItem item
2929 = SaveNotecard(notecard, "Avatar Appearance", Util.GetFormattedXml(appearancePacked as OSD), true); 3277 = SaveNotecard(notecard, "Avatar Appearance", Util.GetFormattedXml(appearancePacked as OSD), true);
@@ -2962,8 +3310,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2962 /// <returns>"male" or "female" or "unknown"</returns> 3310 /// <returns>"male" or "female" or "unknown"</returns>
2963 public LSL_String osGetGender(LSL_Key rawAvatarId) 3311 public LSL_String osGetGender(LSL_Key rawAvatarId)
2964 { 3312 {
2965 m_host.AddScriptLPS(1);
2966
2967 UUID avatarId; 3313 UUID avatarId;
2968 if (!UUID.TryParse(rawAvatarId, out avatarId)) 3314 if (!UUID.TryParse(rawAvatarId, out avatarId))
2969 return new LSL_String("unknown"); 3315 return new LSL_String("unknown");
@@ -3005,8 +3351,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3005 /// <returns></returns> 3351 /// <returns></returns>
3006 public LSL_Key osGetMapTexture() 3352 public LSL_Key osGetMapTexture()
3007 { 3353 {
3008 m_host.AddScriptLPS(1);
3009
3010 return m_ScriptEngine.World.RegionInfo.RegionSettings.TerrainImageID.ToString(); 3354 return m_ScriptEngine.World.RegionInfo.RegionSettings.TerrainImageID.ToString();
3011 } 3355 }
3012 3356
@@ -3017,8 +3361,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3017 /// <returns></returns> 3361 /// <returns></returns>
3018 public LSL_Key osGetRegionMapTexture(string regionName) 3362 public LSL_Key osGetRegionMapTexture(string regionName)
3019 { 3363 {
3020 m_host.AddScriptLPS(1);
3021
3022 Scene scene = m_ScriptEngine.World; 3364 Scene scene = m_ScriptEngine.World;
3023 UUID key = UUID.Zero; 3365 UUID key = UUID.Zero;
3024 GridRegion region; 3366 GridRegion region;
@@ -3045,7 +3387,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3045 /// <returns>List of floats</returns> 3387 /// <returns>List of floats</returns>
3046 public LSL_List osGetRegionStats() 3388 public LSL_List osGetRegionStats()
3047 { 3389 {
3048 m_host.AddScriptLPS(1); 3390 CheckThreatLevel(ThreatLevel.Moderate, "osGetRegionStats");
3391
3049 LSL_List ret = new LSL_List(); 3392 LSL_List ret = new LSL_List();
3050 float[] stats = World.StatsReporter.LastReportedSimStats; 3393 float[] stats = World.StatsReporter.LastReportedSimStats;
3051 3394
@@ -3058,32 +3401,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3058 3401
3059 public LSL_Vector osGetRegionSize() 3402 public LSL_Vector osGetRegionSize()
3060 { 3403 {
3061 m_host.AddScriptLPS(1); 3404 Scene scene = m_ScriptEngine.World;
3062 3405 RegionInfo reg = World.RegionInfo;
3063 bool isMegaregion; 3406// GridRegion region = scene.GridService.GetRegionByUUID(UUID.Zero, World.RegionInfo.RegionID);
3064 IRegionCombinerModule rcMod = World.RequestModuleInterface<IRegionCombinerModule>(); 3407// return new LSL_Vector((float)region.RegionSizeX, (float)region.RegionSizeY, (float)Constants.RegionHeight);
3065 if (rcMod != null) 3408 return new LSL_Vector((float)reg.RegionSizeX, (float)reg.RegionSizeY, 0.0f);
3066 isMegaregion = rcMod.IsRootForMegaregion(World.RegionInfo.RegionID);
3067 else
3068 isMegaregion = false;
3069
3070 if (isMegaregion)
3071 {
3072 Vector2 size = rcMod.GetSizeOfMegaregion(World.RegionInfo.RegionID);
3073 return new LSL_Vector(size.X, size.Y, Constants.RegionHeight);
3074 }
3075 else
3076 {
3077 Scene scene = m_ScriptEngine.World;
3078 GridRegion region = scene.GridService.GetRegionByUUID(UUID.Zero, World.RegionInfo.RegionID);
3079 return new LSL_Vector((float)region.RegionSizeX, (float)region.RegionSizeX, Constants.RegionHeight);
3080 }
3081 } 3409 }
3082 3410
3083 public int osGetSimulatorMemory() 3411 public int osGetSimulatorMemory()
3084 { 3412 {
3085 if (!CheckThreatLevel(ThreatLevel.Moderate, "osGetSimulatorMemory")) return 0; 3413 CheckThreatLevel(ThreatLevel.Moderate, "osGetSimulatorMemory");
3086 m_host.AddScriptLPS(1); 3414
3087 long pws = System.Diagnostics.Process.GetCurrentProcess().WorkingSet64; 3415 long pws = System.Diagnostics.Process.GetCurrentProcess().WorkingSet64;
3088 3416
3089 if (pws > Int32.MaxValue) 3417 if (pws > Int32.MaxValue)
@@ -3094,10 +3422,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3094 return (int)pws; 3422 return (int)pws;
3095 } 3423 }
3096 3424
3425 public int osGetSimulatorMemoryKB()
3426 {
3427 CheckThreatLevel(ThreatLevel.Moderate, "osGetSimulatorMemoryKB");
3428
3429 long pws = System.Diagnostics.Process.GetCurrentProcess().WorkingSet64;
3430
3431 if((pws & 0x3FFL) != 0)
3432 pws += 0x400L;
3433 pws >>= 10;
3434
3435 if (pws > Int32.MaxValue)
3436 return Int32.MaxValue;
3437
3438 return (int)pws;
3439 }
3440
3097 public void osSetSpeed(string UUID, LSL_Float SpeedModifier) 3441 public void osSetSpeed(string UUID, LSL_Float SpeedModifier)
3098 { 3442 {
3099 if (!CheckThreatLevel(ThreatLevel.Moderate, "osSetSpeed")) return; 3443 CheckThreatLevel(ThreatLevel.Moderate, "osSetSpeed");
3100 m_host.AddScriptLPS(1); 3444
3101 ScenePresence avatar = World.GetScenePresence(new UUID(UUID)); 3445 ScenePresence avatar = World.GetScenePresence(new UUID(UUID));
3102 3446
3103 if (avatar != null) 3447 if (avatar != null)
@@ -3106,8 +3450,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3106 3450
3107 public void osKickAvatar(string FirstName, string SurName, string alert) 3451 public void osKickAvatar(string FirstName, string SurName, string alert)
3108 { 3452 {
3109 if (!CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar")) return; 3453 CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar");
3110 m_host.AddScriptLPS(1);
3111 3454
3112 World.ForEachRootScenePresence(delegate(ScenePresence sp) 3455 World.ForEachRootScenePresence(delegate(ScenePresence sp)
3113 { 3456 {
@@ -3125,23 +3468,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3125 3468
3126 public LSL_Float osGetHealth(string avatar) 3469 public LSL_Float osGetHealth(string avatar)
3127 { 3470 {
3128 m_host.AddScriptLPS(1);
3129
3130 LSL_Float health = new LSL_Float(-1); 3471 LSL_Float health = new LSL_Float(-1);
3131 ScenePresence presence = World.GetScenePresence(new UUID(avatar)); 3472 ScenePresence presence = World.GetScenePresence(new UUID(avatar));
3132 if (presence != null) health = presence.Health; 3473 if (presence != null)
3474 health = presence.Health;
3133 return health; 3475 return health;
3134 } 3476 }
3135 3477
3136 public void osCauseDamage(string avatar, double damage) 3478 public void osCauseDamage(string avatar, double damage)
3137 { 3479 {
3138 if (!CheckThreatLevel(ThreatLevel.High, "osCauseDamage")) return; 3480 CheckThreatLevel(ThreatLevel.High, "osCauseDamage");
3139 m_host.AddScriptLPS(1);
3140 3481
3141 UUID avatarId = new UUID(avatar); 3482 UUID avatarId = new UUID(avatar);
3142 Vector3 pos = m_host.GetWorldPosition(); 3483 Vector3 pos = m_host.GetWorldPosition();
3143 3484
3144 ScenePresence presence = World.GetScenePresence(avatarId); 3485 ScenePresence presence = World.GetScenePresence(avatarId);
3145 if (presence != null) 3486 if (presence != null)
3146 { 3487 {
3147 LandData land = World.GetLandData(pos); 3488 LandData land = World.GetLandData(pos);
@@ -3163,13 +3504,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3163 3504
3164 public void osCauseHealing(string avatar, double healing) 3505 public void osCauseHealing(string avatar, double healing)
3165 { 3506 {
3166 if (!CheckThreatLevel(ThreatLevel.High, "osCauseHealing")) return; 3507 CheckThreatLevel(ThreatLevel.High, "osCauseHealing");
3167 m_host.AddScriptLPS(1);
3168 3508
3169 UUID avatarId = new UUID(avatar); 3509 UUID avatarId = new UUID(avatar);
3170 ScenePresence presence = World.GetScenePresence(avatarId); 3510 ScenePresence presence = World.GetScenePresence(avatarId);
3171 3511
3172 if (presence != null && World.ScriptDanger(m_host.LocalId, m_host.GetWorldPosition())) 3512 if (presence != null)
3173 { 3513 {
3174 float health = presence.Health; 3514 float health = presence.Health;
3175 health += (float)healing; 3515 health += (float)healing;
@@ -3181,31 +3521,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3181 } 3521 }
3182 } 3522 }
3183 3523
3524 public void osSetHealth(string avatar, double health)
3525 {
3526 CheckThreatLevel(ThreatLevel.High, "osSetHealth");
3527
3528 UUID avatarId = new UUID(avatar);
3529 ScenePresence presence = World.GetScenePresence(avatarId);
3530
3531 if (presence != null)
3532 {
3533 if (health > 100.0)
3534 health = 100.0;
3535 else if (health < 1.0)
3536 health = 1.0;
3537
3538 presence.setHealthWithUpdate((float)health);
3539 }
3540 }
3541
3542 public void osSetHealRate(string avatar, double healrate)
3543 {
3544 CheckThreatLevel(ThreatLevel.High, "osSetHealRate");
3545
3546 UUID avatarId = new UUID(avatar);
3547 ScenePresence presence = World.GetScenePresence(avatarId);
3548
3549 if (presence != null)
3550 presence.HealRate = (float)healrate;
3551 }
3552
3553 public LSL_Float osGetHealRate(string avatar)
3554 {
3555 LSL_Float rate = new LSL_Float(0);
3556 ScenePresence presence = World.GetScenePresence(new UUID(avatar));
3557 if (presence != null)
3558 rate = presence.HealRate;
3559 return rate;
3560 }
3561
3184 public LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules) 3562 public LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules)
3185 { 3563 {
3186 if (!CheckThreatLevel(ThreatLevel.High, "osGetPrimitiveParams")) return new LSL_List(); 3564 CheckThreatLevel(ThreatLevel.High, "osGetPrimitiveParams");
3187 m_host.AddScriptLPS(1);
3188 InitLSL();
3189 3565
3566 InitLSL();
3190 return m_LSL_Api.GetPrimitiveParamsEx(prim, rules); 3567 return m_LSL_Api.GetPrimitiveParamsEx(prim, rules);
3191 } 3568 }
3192 3569
3193 public void osSetPrimitiveParams(LSL_Key prim, LSL_List rules) 3570 public void osSetPrimitiveParams(LSL_Key prim, LSL_List rules)
3194 { 3571 {
3195 if (!CheckThreatLevel(ThreatLevel.High, "osSetPrimitiveParams")) return; 3572 CheckThreatLevel(ThreatLevel.VeryLow, "osSetPrimitiveParams");
3196 m_host.AddScriptLPS(1);
3197 InitLSL();
3198 3573
3574 InitLSL();
3199 m_LSL_Api.SetPrimitiveParamsEx(prim, rules, "osSetPrimitiveParams"); 3575 m_LSL_Api.SetPrimitiveParamsEx(prim, rules, "osSetPrimitiveParams");
3200 } 3576 }
3201 3577
3202 /// <summary> 3578 /// <summary>
3203 /// Set parameters for light projection in host prim 3579 /// Set parameters for light projection in host prim
3204 /// </summary> 3580 /// </summary>
3205 public void osSetProjectionParams(bool projection, LSL_Key texture, double fov, double focus, double amb) 3581 public void osSetProjectionParams(bool projection, LSL_Key texture, double fov, double focus, double amb)
3206 { 3582 {
3207 if (!CheckThreatLevel(ThreatLevel.High, "osSetProjectionParams")) return;
3208
3209 osSetProjectionParams(UUID.Zero.ToString(), projection, texture, fov, focus, amb); 3583 osSetProjectionParams(UUID.Zero.ToString(), projection, texture, fov, focus, amb);
3210 } 3584 }
3211 3585
@@ -3214,8 +3588,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3214 /// </summary> 3588 /// </summary>
3215 public void osSetProjectionParams(LSL_Key prim, bool projection, LSL_Key texture, double fov, double focus, double amb) 3589 public void osSetProjectionParams(LSL_Key prim, bool projection, LSL_Key texture, double fov, double focus, double amb)
3216 { 3590 {
3217 if (!CheckThreatLevel(ThreatLevel.High, "osSetProjectionParams")) return; 3591 CheckThreatLevel(ThreatLevel.High, "osSetProjectionParams");
3218 m_host.AddScriptLPS(1);
3219 3592
3220 SceneObjectPart obj = null; 3593 SceneObjectPart obj = null;
3221 if (prim == UUID.Zero.ToString()) 3594 if (prim == UUID.Zero.ToString())
@@ -3245,12 +3618,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3245 /// <returns>Strided list of the UUID, position and name of each avatar in the region</returns> 3618 /// <returns>Strided list of the UUID, position and name of each avatar in the region</returns>
3246 public LSL_List osGetAvatarList() 3619 public LSL_List osGetAvatarList()
3247 { 3620 {
3248 m_host.AddScriptLPS(1); 3621 LSL_List result = new LSL_List();
3622 World.ForEachRootScenePresence(delegate (ScenePresence avatar)
3623 {
3624 if (avatar != null && !avatar.IsDeleted && avatar.UUID != m_host.OwnerID )
3625 {
3626 result.Add(new LSL_String(avatar.UUID.ToString()));
3627 result.Add(new LSL_Vector(avatar.AbsolutePosition));
3628 result.Add(new LSL_String(avatar.Name));
3629 }
3630 });
3631
3632 return result;
3633 }
3249 3634
3635 public LSL_List osGetNPCList()
3636 {
3250 LSL_List result = new LSL_List(); 3637 LSL_List result = new LSL_List();
3251 World.ForEachRootScenePresence(delegate (ScenePresence avatar) 3638 World.ForEachRootScenePresence(delegate (ScenePresence avatar)
3252 { 3639 {
3253 if (avatar != null && avatar.UUID != m_host.OwnerID) 3640 // npcs are not childagents but that is now.
3641 if (avatar != null && avatar.IsNPC && !avatar.IsDeleted && !avatar.IsChildAgent && !avatar.IsInTransit)
3254 { 3642 {
3255 result.Add(new LSL_String(avatar.UUID.ToString())); 3643 result.Add(new LSL_String(avatar.UUID.ToString()));
3256 result.Add(new LSL_Vector(avatar.AbsolutePosition)); 3644 result.Add(new LSL_Vector(avatar.AbsolutePosition));
@@ -3268,8 +3656,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3268 /// <returns></returns> 3656 /// <returns></returns>
3269 public LSL_String osUnixTimeToTimestamp(long time) 3657 public LSL_String osUnixTimeToTimestamp(long time)
3270 { 3658 {
3271 m_host.AddScriptLPS(1);
3272
3273 long baseTicks = 621355968000000000; 3659 long baseTicks = 621355968000000000;
3274 long tickResolution = 10000000; 3660 long tickResolution = 10000000;
3275 long epochTicks = (time * tickResolution) + baseTicks; 3661 long epochTicks = (time * tickResolution) + baseTicks;
@@ -3282,11 +3668,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3282 /// Get the description from an inventory item 3668 /// Get the description from an inventory item
3283 /// </summary> 3669 /// </summary>
3284 /// <param name="inventoryName"></param> 3670 /// <param name="inventoryName"></param>
3285 /// <returns>Item description</returns> 3671 /// <returns>Item description</returns>
3286 public LSL_String osGetInventoryDesc(string item) 3672 public LSL_String osGetInventoryDesc(string item)
3287 { 3673 {
3288 m_host.AddScriptLPS(1);
3289
3290 lock (m_host.TaskInventory) 3674 lock (m_host.TaskInventory)
3291 { 3675 {
3292 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 3676 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
@@ -3308,8 +3692,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3308 /// <returns></returns> 3692 /// <returns></returns>
3309 public LSL_Integer osInviteToGroup(LSL_Key agentId) 3693 public LSL_Integer osInviteToGroup(LSL_Key agentId)
3310 { 3694 {
3311 if (!CheckThreatLevel(ThreatLevel.VeryLow, "osInviteToGroup")) return ScriptBaseClass.FALSE; 3695 CheckThreatLevel(ThreatLevel.VeryLow, "osInviteToGroup");
3312 m_host.AddScriptLPS(1);
3313 3696
3314 UUID agent = new UUID(agentId); 3697 UUID agent = new UUID(agentId);
3315 3698
@@ -3343,8 +3726,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3343 /// <returns></returns> 3726 /// <returns></returns>
3344 public LSL_Integer osEjectFromGroup(LSL_Key agentId) 3727 public LSL_Integer osEjectFromGroup(LSL_Key agentId)
3345 { 3728 {
3346 if (!CheckThreatLevel(ThreatLevel.VeryLow, "osEjectFromGroup")) return ScriptBaseClass.FALSE; 3729 CheckThreatLevel(ThreatLevel.VeryLow, "osEjectFromGroup");
3347 m_host.AddScriptLPS(1);
3348 3730
3349 UUID agent = new UUID(agentId); 3731 UUID agent = new UUID(agentId);
3350 3732
@@ -3378,9 +3760,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3378 /// <returns></returns> 3760 /// <returns></returns>
3379 public void osSetTerrainTexture(int level, LSL_Key texture) 3761 public void osSetTerrainTexture(int level, LSL_Key texture)
3380 { 3762 {
3381 if (!CheckThreatLevel(ThreatLevel.High, "osSetTerrainTexture")) return; 3763 CheckThreatLevel(ThreatLevel.High, "osSetTerrainTexture");
3382 3764
3383 m_host.AddScriptLPS(1);
3384 //Check to make sure that the script's owner is the estate manager/master 3765 //Check to make sure that the script's owner is the estate manager/master
3385 //World.Permissions.GenericEstatePermission( 3766 //World.Permissions.GenericEstatePermission(
3386 if (World.Permissions.IsGod(m_host.OwnerID)) 3767 if (World.Permissions.IsGod(m_host.OwnerID))
@@ -3408,9 +3789,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3408 /// <returns></returns> 3789 /// <returns></returns>
3409 public void osSetTerrainTextureHeight(int corner, double low, double high) 3790 public void osSetTerrainTextureHeight(int corner, double low, double high)
3410 { 3791 {
3411 if (!CheckThreatLevel(ThreatLevel.High, "osSetTerrainTextureHeight")) return; 3792 CheckThreatLevel(ThreatLevel.High, "osSetTerrainTextureHeight");
3412 3793
3413 m_host.AddScriptLPS(1);
3414 //Check to make sure that the script's owner is the estate manager/master 3794 //Check to make sure that the script's owner is the estate manager/master
3415 //World.Permissions.GenericEstatePermission( 3795 //World.Permissions.GenericEstatePermission(
3416 if (World.Permissions.IsGod(m_host.OwnerID)) 3796 if (World.Permissions.IsGod(m_host.OwnerID))
@@ -3429,9 +3809,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3429 3809
3430 public void osForceAttachToAvatar(int attachmentPoint) 3810 public void osForceAttachToAvatar(int attachmentPoint)
3431 { 3811 {
3432 if (!CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatar")) return; 3812 CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatar");
3433
3434 m_host.AddScriptLPS(1);
3435 3813
3436 InitLSL(); 3814 InitLSL();
3437 ((LSL_Api)m_LSL_Api).AttachToAvatar(attachmentPoint); 3815 ((LSL_Api)m_LSL_Api).AttachToAvatar(attachmentPoint);
@@ -3439,18 +3817,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3439 3817
3440 public void osForceAttachToAvatarFromInventory(string itemName, int attachmentPoint) 3818 public void osForceAttachToAvatarFromInventory(string itemName, int attachmentPoint)
3441 { 3819 {
3442 if (!CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatarFromInventory")) return; 3820 CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatarFromInventory");
3443
3444 m_host.AddScriptLPS(1);
3445 3821
3446 ForceAttachToAvatarFromInventory(m_host.OwnerID, itemName, attachmentPoint); 3822 ForceAttachToAvatarFromInventory(m_host.OwnerID, itemName, attachmentPoint);
3447 } 3823 }
3448 3824
3449 public void osForceAttachToOtherAvatarFromInventory(string rawAvatarId, string itemName, int attachmentPoint) 3825 public void osForceAttachToOtherAvatarFromInventory(string rawAvatarId, string itemName, int attachmentPoint)
3450 { 3826 {
3451 if (!CheckThreatLevel(ThreatLevel.Severe, "osForceAttachToOtherAvatarFromInventory")) return; 3827 CheckThreatLevel(ThreatLevel.VeryHigh, "osForceAttachToOtherAvatarFromInventory");
3452
3453 m_host.AddScriptLPS(1);
3454 3828
3455 UUID avatarId; 3829 UUID avatarId;
3456 3830
@@ -3480,7 +3854,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3480 if (item.InvType != (int)InventoryType.Object) 3854 if (item.InvType != (int)InventoryType.Object)
3481 { 3855 {
3482 // FIXME: Temporary null check for regression tests since they dont' have the infrastructure to set 3856 // FIXME: Temporary null check for regression tests since they dont' have the infrastructure to set
3483 // up the api reference. 3857 // up the api reference.
3484 if (m_LSL_Api != null) 3858 if (m_LSL_Api != null)
3485 ((LSL_Api)m_LSL_Api).llSay(0, string.Format("Unable to attach, item '{0}' is not an object.", itemName)); 3859 ((LSL_Api)m_LSL_Api).llSay(0, string.Format("Unable to attach, item '{0}' is not an object.", itemName));
3486 3860
@@ -3509,9 +3883,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3509 3883
3510 public void osForceDetachFromAvatar() 3884 public void osForceDetachFromAvatar()
3511 { 3885 {
3512 if (!CheckThreatLevel(ThreatLevel.High, "osForceDetachFromAvatar")) return; 3886 CheckThreatLevel(ThreatLevel.VeryHigh, "osForceDetachFromAvatar");
3513
3514 m_host.AddScriptLPS(1);
3515 3887
3516 InitLSL(); 3888 InitLSL();
3517 ((LSL_Api)m_LSL_Api).DetachFromAvatar(); 3889 ((LSL_Api)m_LSL_Api).DetachFromAvatar();
@@ -3519,9 +3891,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3519 3891
3520 public LSL_List osGetNumberOfAttachments(LSL_Key avatar, LSL_List attachmentPoints) 3892 public LSL_List osGetNumberOfAttachments(LSL_Key avatar, LSL_List attachmentPoints)
3521 { 3893 {
3522 if (!CheckThreatLevel(ThreatLevel.Moderate, "osGetNumberOfAttachments")) return new LSL_List(); 3894 CheckThreatLevel(ThreatLevel.Moderate, "osGetNumberOfAttachments");
3523
3524 m_host.AddScriptLPS(1);
3525 3895
3526 UUID targetUUID; 3896 UUID targetUUID;
3527 ScenePresence target; 3897 ScenePresence target;
@@ -3555,15 +3925,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3555 3925
3556 public void osMessageAttachments(LSL_Key avatar, string message, LSL_List attachmentPoints, int options) 3926 public void osMessageAttachments(LSL_Key avatar, string message, LSL_List attachmentPoints, int options)
3557 { 3927 {
3558 if (!CheckThreatLevel(ThreatLevel.Moderate, "osMessageAttachments")) return; 3928 CheckThreatLevel(ThreatLevel.Moderate, "osMessageAttachments");
3559 m_host.AddScriptLPS(1);
3560 3929
3561 UUID targetUUID; 3930 UUID targetUUID;
3931 if(!UUID.TryParse(avatar.ToString(), out targetUUID))
3932 return;
3933
3934 if(targetUUID == UUID.Zero)
3935 return;
3936
3562 ScenePresence target; 3937 ScenePresence target;
3938 if(!World.TryGetScenePresence(targetUUID, out target))
3939 return;
3563 3940
3564 if (attachmentPoints.Length >= 1 && UUID.TryParse(avatar.ToString(), out targetUUID) && World.TryGetScenePresence(targetUUID, out target)) 3941 if(target.IsDeleted || target.IsInTransit)
3942 return;
3943
3944 List<int> aps = new List<int>();
3945 if(attachmentPoints.Length != 0)
3565 { 3946 {
3566 List<int> aps = new List<int>();
3567 foreach (object point in attachmentPoints.Data) 3947 foreach (object point in attachmentPoints.Data)
3568 { 3948 {
3569 int ipoint; 3949 int ipoint;
@@ -3572,115 +3952,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3572 aps.Add(ipoint); 3952 aps.Add(ipoint);
3573 } 3953 }
3574 } 3954 }
3955 // parsing failed
3956 if(aps.Count != attachmentPoints.Length)
3957 return;
3958 }
3575 3959
3576 List<SceneObjectGroup> attachments = new List<SceneObjectGroup>(); 3960 List<SceneObjectGroup> attachments = new List<SceneObjectGroup>();
3577
3578 bool msgAll = aps.Contains(ScriptBaseClass.OS_ATTACH_MSG_ALL);
3579 bool invertPoints = (options & ScriptBaseClass.OS_ATTACH_MSG_INVERT_POINTS) != 0;
3580 3961
3581 if (msgAll && invertPoints) 3962 bool msgAll;
3582 { 3963 bool invertPoints = (options & ScriptBaseClass.OS_ATTACH_MSG_INVERT_POINTS) != 0;
3583 return;
3584 }
3585 else if (msgAll || invertPoints)
3586 {
3587 attachments = target.GetAttachments();
3588 }
3589 else
3590 {
3591 foreach (int point in aps)
3592 {
3593 if (point > 0)
3594 {
3595 attachments.AddRange(target.GetAttachments((uint)point));
3596 }
3597 }
3598 }
3599 3964
3600 // if we have no attachments at this point, exit now 3965 if(aps.Count == 0)
3601 if (attachments.Count == 0) 3966 {
3602 { 3967 if(!invertPoints)
3603 return; 3968 return;
3604 } 3969 msgAll = true;
3970 invertPoints = false;
3971 }
3972 else
3973 msgAll = aps.Contains(ScriptBaseClass.OS_ATTACH_MSG_ALL);
3605 3974
3606 List<SceneObjectGroup> ignoreThese = new List<SceneObjectGroup>(); 3975 if (msgAll && invertPoints)
3976 return;
3607 3977
3608 if (invertPoints) 3978 if (msgAll || invertPoints)
3979 {
3980 attachments = target.GetAttachments();
3981 }
3982 else
3983 {
3984 foreach (int point in aps)
3609 { 3985 {
3610 foreach (SceneObjectGroup attachment in attachments) 3986 if (point > 0)
3611 { 3987 {
3612 if (aps.Contains((int)attachment.AttachmentPoint)) 3988 attachments.AddRange(target.GetAttachments((uint)point));
3613 {
3614 ignoreThese.Add(attachment);
3615 }
3616 } 3989 }
3617 } 3990 }
3991 }
3618 3992
3619 foreach (SceneObjectGroup attachment in ignoreThese) 3993 // if we have no attachments at this point, exit now
3620 { 3994 if (attachments.Count == 0)
3621 attachments.Remove(attachment); 3995 {
3622 } 3996 return;
3623 ignoreThese.Clear(); 3997 }
3624 3998
3625 // if inverting removed all attachments to check, exit now 3999 bool optionObjCreator = (options &
3626 if (attachments.Count < 1) 4000 ScriptBaseClass.OS_ATTACH_MSG_OBJECT_CREATOR) != 0;
3627 { 4001 bool optionScriptCreator = (options &
3628 return; 4002 ScriptBaseClass.OS_ATTACH_MSG_SCRIPT_CREATOR) != 0;
3629 }
3630 4003
3631 if ((options & ScriptBaseClass.OS_ATTACH_MSG_OBJECT_CREATOR) != 0) 4004 UUID hostCreatorID = m_host.CreatorID;
3632 { 4005 UUID itemCreatorID = m_item.CreatorID;
3633 foreach (SceneObjectGroup attachment in attachments)
3634 {
3635 if (attachment.RootPart.CreatorID != m_host.CreatorID)
3636 {
3637 ignoreThese.Add(attachment);
3638 }
3639 }
3640 4006
3641 foreach (SceneObjectGroup attachment in ignoreThese) 4007 foreach (SceneObjectGroup sog in attachments)
3642 { 4008 {
3643 attachments.Remove(attachment); 4009 if(sog.IsDeleted || sog.inTransit)
3644 } 4010 continue;
3645 ignoreThese.Clear();
3646
3647 // if filtering by same object creator removed all
3648 // attachments to check, exit now
3649 if (attachments.Count == 0)
3650 {
3651 return;
3652 }
3653 }
3654 4011
3655 if ((options & ScriptBaseClass.OS_ATTACH_MSG_SCRIPT_CREATOR) != 0) 4012 if (invertPoints && aps.Contains((int)sog.AttachmentPoint))
3656 { 4013 continue;
3657 foreach (SceneObjectGroup attachment in attachments)
3658 {
3659 if (attachment.RootPart.CreatorID != m_item.CreatorID)
3660 {
3661 ignoreThese.Add(attachment);
3662 }
3663 }
3664 4014
3665 foreach (SceneObjectGroup attachment in ignoreThese) 4015 UUID CreatorID = sog.RootPart.CreatorID;
3666 { 4016 if (optionObjCreator && CreatorID != hostCreatorID)
3667 attachments.Remove(attachment); 4017 continue;
3668 }
3669 ignoreThese.Clear();
3670 4018
3671 // if filtering by object creator must match originating 4019 if (optionScriptCreator && CreatorID != itemCreatorID)
3672 // script creator removed all attachments to check, 4020 continue;
3673 // exit now
3674 if (attachments.Count == 0)
3675 {
3676 return;
3677 }
3678 }
3679 4021
3680 foreach (SceneObjectGroup attachment in attachments) 4022 SceneObjectPart[] parts = sog.Parts;
3681 { 4023 foreach(SceneObjectPart p in parts)
3682 MessageObject(attachment.RootPart.UUID, message); 4024 MessageObject(p.UUID, message);
3683 }
3684 } 4025 }
3685 } 4026 }
3686 4027
@@ -3693,8 +4034,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3693 /// <returns>1 if thing is a valid UUID, 0 otherwise</returns> 4034 /// <returns>1 if thing is a valid UUID, 0 otherwise</returns>
3694 public LSL_Integer osIsUUID(string thing) 4035 public LSL_Integer osIsUUID(string thing)
3695 { 4036 {
3696 m_host.AddScriptLPS(1);
3697
3698 UUID test; 4037 UUID test;
3699 return UUID.TryParse(thing, out test) ? 1 : 0; 4038 return UUID.TryParse(thing, out test) ? 1 : 0;
3700 } 4039 }
@@ -3707,8 +4046,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3707 /// <returns></returns> 4046 /// <returns></returns>
3708 public LSL_Float osMin(double a, double b) 4047 public LSL_Float osMin(double a, double b)
3709 { 4048 {
3710 m_host.AddScriptLPS(1);
3711
3712 return Math.Min(a, b); 4049 return Math.Min(a, b);
3713 } 4050 }
3714 4051
@@ -3720,16 +4057,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3720 /// <returns></returns> 4057 /// <returns></returns>
3721 public LSL_Float osMax(double a, double b) 4058 public LSL_Float osMax(double a, double b)
3722 { 4059 {
3723 m_host.AddScriptLPS(1);
3724
3725 return Math.Max(a, b); 4060 return Math.Max(a, b);
3726 } 4061 }
3727 4062
3728 public LSL_Key osGetRezzingObject() 4063 public LSL_Key osGetRezzingObject()
3729 { 4064 {
3730 m_host.AddScriptLPS(1); 4065 UUID rezID = m_host.ParentGroup.RezzerID;
3731 4066 if(rezID == UUID.Zero || m_host.ParentGroup.Scene.GetScenePresence(rezID) != null)
3732 return new LSL_Key(m_host.ParentGroup.FromPartID.ToString()); 4067 return new LSL_Key(UUID.Zero.ToString());
4068 return new LSL_Key(rezID.ToString());
3733 } 4069 }
3734 4070
3735 /// <summary> 4071 /// <summary>
@@ -3738,7 +4074,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3738 /// <returns></returns> 4074 /// <returns></returns>
3739 public void osSetContentType(LSL_Key id, string type) 4075 public void osSetContentType(LSL_Key id, string type)
3740 { 4076 {
3741 if (!CheckThreatLevel(ThreatLevel.High, "osSetContentType")) return; 4077 CheckThreatLevel(ThreatLevel.High, "osSetContentType");
3742 4078
3743 if (m_UrlModule != null) 4079 if (m_UrlModule != null)
3744 m_UrlModule.HttpContentType(new UUID(id),type); 4080 m_UrlModule.HttpContentType(new UUID(id),type);
@@ -3750,7 +4086,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3750 /// <returns>boolean indicating whether an error was shouted.</returns> 4086 /// <returns>boolean indicating whether an error was shouted.</returns>
3751 protected bool ShoutErrorOnLackingOwnerPerms(int perms, string errorPrefix) 4087 protected bool ShoutErrorOnLackingOwnerPerms(int perms, string errorPrefix)
3752 { 4088 {
3753 m_host.AddScriptLPS(1);
3754 bool fail = false; 4089 bool fail = false;
3755 if (m_item.PermsGranter != m_host.OwnerID) 4090 if (m_item.PermsGranter != m_host.OwnerID)
3756 { 4091 {
@@ -3800,39 +4135,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3800 4135
3801 public void osDropAttachment() 4136 public void osDropAttachment()
3802 { 4137 {
3803 if (!CheckThreatLevel(ThreatLevel.Low, "osDropAttachment")) return; 4138 CheckThreatLevel(ThreatLevel.Moderate, "osDropAttachment");
3804 m_host.AddScriptLPS(1);
3805 4139
3806 DropAttachment(true); 4140 DropAttachment(true);
3807 } 4141 }
3808 4142
3809 public void osForceDropAttachment() 4143 public void osForceDropAttachment()
3810 { 4144 {
3811 if (!CheckThreatLevel(ThreatLevel.High, "osForceDropAttachment")) return; 4145 CheckThreatLevel(ThreatLevel.High, "osForceDropAttachment");
3812 m_host.AddScriptLPS(1);
3813 4146
3814 DropAttachment(false); 4147 DropAttachment(false);
3815 } 4148 }
3816 4149
3817 public void osDropAttachmentAt(LSL_Vector pos, LSL_Rotation rot) 4150 public void osDropAttachmentAt(LSL_Vector pos, LSL_Rotation rot)
3818 { 4151 {
3819 if (!CheckThreatLevel(ThreatLevel.Low, "osDropAttachmentAt")) return; 4152 CheckThreatLevel(ThreatLevel.Moderate, "osDropAttachmentAt");
3820 m_host.AddScriptLPS(1);
3821 4153
3822 DropAttachmentAt(true, pos, rot); 4154 DropAttachmentAt(true, pos, rot);
3823 } 4155 }
3824 4156
3825 public void osForceDropAttachmentAt(LSL_Vector pos, LSL_Rotation rot) 4157 public void osForceDropAttachmentAt(LSL_Vector pos, LSL_Rotation rot)
3826 { 4158 {
3827 if (!CheckThreatLevel(ThreatLevel.High, "osForceDropAttachmentAt")) return; 4159 CheckThreatLevel(ThreatLevel.High, "osForceDropAttachmentAt");
3828 m_host.AddScriptLPS(1);
3829 4160
3830 DropAttachmentAt(false, pos, rot); 4161 DropAttachmentAt(false, pos, rot);
3831 } 4162 }
3832 4163
3833 public LSL_Integer osListenRegex(int channelID, string name, string ID, string msg, int regexBitfield) 4164 public LSL_Integer osListenRegex(int channelID, string name, string ID, string msg, int regexBitfield)
3834 { 4165 {
3835 m_host.AddScriptLPS(1);
3836 UUID keyID; 4166 UUID keyID;
3837 UUID.TryParse(ID, out keyID); 4167 UUID.TryParse(ID, out keyID);
3838 4168
@@ -3879,7 +4209,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3879 4209
3880 public LSL_Integer osRegexIsMatch(string input, string pattern) 4210 public LSL_Integer osRegexIsMatch(string input, string pattern)
3881 { 4211 {
3882 m_host.AddScriptLPS(1);
3883 try 4212 try
3884 { 4213 {
3885 return Regex.IsMatch(input, pattern) ? 1 : 0; 4214 return Regex.IsMatch(input, pattern) ? 1 : 0;
@@ -3890,5 +4219,376 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3890 return 0; 4219 return 0;
3891 } 4220 }
3892 } 4221 }
4222
4223 public LSL_String osRequestURL(LSL_List options)
4224 {
4225 CheckThreatLevel(ThreatLevel.Moderate, "osRequestSecureURL");
4226
4227 Hashtable opts = new Hashtable();
4228 for (int i = 0 ; i < options.Length ; i++)
4229 {
4230 object opt = options.Data[i];
4231 if (opt.ToString() == "allowXss")
4232 opts["allowXss"] = true;
4233 }
4234
4235 if (m_UrlModule != null)
4236 return m_UrlModule.RequestURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID, opts).ToString();
4237 return UUID.Zero.ToString();
4238 }
4239
4240 public LSL_String osRequestSecureURL(LSL_List options)
4241 {
4242 CheckThreatLevel(ThreatLevel.Moderate, "osRequestSecureURL");
4243
4244 Hashtable opts = new Hashtable();
4245 for (int i = 0 ; i < options.Length ; i++)
4246 {
4247 object opt = options.Data[i];
4248 if (opt.ToString() == "allowXss")
4249 opts["allowXss"] = true;
4250 }
4251
4252 if (m_UrlModule != null)
4253 return m_UrlModule.RequestSecureURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID, opts).ToString();
4254 return UUID.Zero.ToString();
4255 }
4256
4257 public void osCollisionSound(string impact_sound, double impact_volume)
4258 {
4259 if(impact_sound == "")
4260 {
4261 m_host.CollisionSoundVolume = (float)impact_volume;
4262 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4263 if(impact_volume == 0.0)
4264 m_host.CollisionSoundType = -1; // disable all sounds
4265 else if(impact_volume == 1.0f)
4266 m_host.CollisionSoundType = 0; // full return to default sounds
4267 else
4268 m_host.CollisionSoundType = 2; // default sounds with volume
4269 m_host.aggregateScriptEvents();
4270 return;
4271 }
4272 // TODO: Parameter check logic required.
4273 UUID soundId = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound);
4274 if(soundId != UUID.Zero)
4275 {
4276 m_host.CollisionSound = soundId;
4277 m_host.CollisionSoundVolume = (float)impact_volume;
4278 m_host.CollisionSoundType = 1;
4279 }
4280 else
4281 m_host.CollisionSoundType = -1;
4282
4283 m_host.aggregateScriptEvents();
4284 }
4285
4286 // still not very usefull, detector is lost on rez, restarts, etc
4287 public void osVolumeDetect(int detect)
4288 {
4289 CheckThreatLevel();
4290
4291 if (m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted || m_host.ParentGroup.IsAttachment)
4292 return;
4293
4294 m_host.ScriptSetVolumeDetect(detect != 0);
4295 }
4296
4297 /// <summary>
4298 /// Get inertial data
4299 /// </summary>
4300 /// <remarks>
4301 /// </remarks>
4302 /// <returns>
4303 /// a LSL list with contents:
4304 /// LSL_Float mass, the total mass of a linkset
4305 /// LSL_Vector CenterOfMass, center mass relative to root prim
4306 /// LSL_Vector Inertia, elements of diagonal of inertia Ixx,Iyy,Izz divided by total mass
4307 /// LSL_Vector aux, elements of upper triagle of inertia Ixy (= Iyx), Ixz (= Izx), Iyz(= Izy) divided by total mass
4308 /// </returns>
4309 public LSL_List osGetInertiaData()
4310 {
4311 LSL_List result = new LSL_List();
4312 float TotalMass;
4313 Vector3 CenterOfMass;
4314 Vector3 Inertia;
4315 Vector4 aux;
4316
4317 SceneObjectGroup sog = m_host.ParentGroup;
4318 if(sog== null || sog.IsDeleted)
4319 return result;
4320
4321 sog.GetInertiaData(out TotalMass, out CenterOfMass, out Inertia, out aux );
4322 if(TotalMass > 0)
4323 {
4324 float t = 1.0f/TotalMass;
4325 Inertia.X *= t;
4326 Inertia.Y *= t;
4327 Inertia.Z *= t;
4328
4329 aux.X *= t;
4330 aux.Y *= t;
4331 aux.Z *= t;
4332 }
4333
4334 result.Add(new LSL_Float(TotalMass));
4335 result.Add(new LSL_Vector(CenterOfMass.X, CenterOfMass.Y, CenterOfMass.Z));
4336 result.Add(new LSL_Vector(Inertia.X, Inertia.Y, Inertia.Z));
4337 result.Add(new LSL_Vector(aux.X, aux.Y, aux.Z));
4338 return result;
4339 }
4340
4341 /// <summary>
4342 /// set inertial data
4343 /// replaces the automatic calculation of mass, center of mass and inertia
4344 ///
4345 /// </summary>
4346 /// <param name="Mass">total mass of linkset</param>
4347 /// <param name="centerOfMass">location of center of mass relative to root prim in local coords</param>
4348 /// <param name="principalInertiaScaled">moment of inertia relative to principal axis and center of mass,Ixx, Iyy, Izz divided by mass</param>
4349 /// <param name="lslrot">rotation of the inertia, relative to local axis</param>
4350 /// <remarks>
4351 /// the inertia argument is is inertia divided by mass, so corresponds only to the geometric distribution of mass and both can be changed independently.
4352 /// </remarks>
4353
4354 public void osSetInertia(LSL_Float mass, LSL_Vector centerOfMass, LSL_Vector principalInertiaScaled, LSL_Rotation lslrot)
4355 {
4356 SceneObjectGroup sog = m_host.ParentGroup;
4357 if(sog== null || sog.IsDeleted)
4358 return;
4359
4360 if(mass < 0 || principalInertiaScaled.x < 0 || principalInertiaScaled.y < 0 || principalInertiaScaled.z < 0)
4361 return;
4362
4363 // need more checks
4364
4365 Vector3 CenterOfMass = new Vector3((float)centerOfMass.x,(float)centerOfMass.y,(float)centerOfMass.z);
4366 Vector3 Inertia;
4367 float m = (float)mass;
4368
4369 Inertia.X = m * (float)principalInertiaScaled.x;
4370 Inertia.Y = m * (float)principalInertiaScaled.y;
4371 Inertia.Z = m * (float)principalInertiaScaled.z;
4372
4373 Vector4 rot = new Vector4((float)lslrot.x, (float)lslrot.y, (float)lslrot.y, (float)lslrot.s);
4374 rot.Normalize();
4375
4376 sog.SetInertiaData(m, CenterOfMass, Inertia, rot );
4377 }
4378
4379 /// <summary>
4380 /// set inertial data as a sphere
4381 /// replaces the automatic calculation of mass, center of mass and inertia
4382 ///
4383 /// </summary>
4384 /// <param name="Mass">total mass of linkset</param>
4385 /// <param name="boxsize">size of the Box</param>
4386 /// <param name="centerOfMass">location of center of mass relative to root prim in local coords</param>
4387 /// <param name="lslrot">rotation of the box, and so inertia, relative to local axis</param>
4388 /// <remarks>
4389 /// </remarks>
4390 public void osSetInertiaAsBox(LSL_Float mass, LSL_Vector boxSize, LSL_Vector centerOfMass, LSL_Rotation lslrot)
4391 {
4392 SceneObjectGroup sog = m_host.ParentGroup;
4393 if(sog== null || sog.IsDeleted)
4394 return;
4395
4396 if(mass < 0)
4397 return;
4398
4399 // need more checks
4400
4401 Vector3 CenterOfMass = new Vector3((float)centerOfMass.x,(float)centerOfMass.y,(float)centerOfMass.z);
4402 Vector3 Inertia;
4403 float lx = (float)boxSize.x;
4404 float ly = (float)boxSize.y;
4405 float lz = (float)boxSize.z;
4406 float m = (float)mass;
4407 float t = m / 12.0f;
4408
4409 Inertia.X = t * (ly*ly + lz*lz);
4410 Inertia.Y = t * (lx*lx + lz*lz);
4411 Inertia.Z = t * (lx*lx + ly*ly);
4412
4413 Vector4 rot = new Vector4((float)lslrot.x, (float)lslrot.y, (float)lslrot.z, (float)lslrot.s);
4414 rot.Normalize();
4415
4416 sog.SetInertiaData(m, CenterOfMass, Inertia, rot );
4417 }
4418
4419 /// <summary>
4420 /// set inertial data as a sphere
4421 /// replaces the automatic calculation of mass, center of mass and inertia
4422 ///
4423 /// </summary>
4424 /// <param name="Mass">total mass of linkset</param>
4425 /// <param name="radius">radius of the sphere</param>
4426 /// <param name="centerOfMass">location of center of mass relative to root prim in local coords</param>
4427 /// <remarks>
4428 /// </remarks>
4429 public void osSetInertiaAsSphere(LSL_Float mass, LSL_Float radius, LSL_Vector centerOfMass)
4430 {
4431 SceneObjectGroup sog = m_host.ParentGroup;
4432 if(sog== null || sog.IsDeleted)
4433 return;
4434
4435 if(mass < 0)
4436 return;
4437
4438 // need more checks
4439
4440 Vector3 CenterOfMass = new Vector3((float)centerOfMass.x,(float)centerOfMass.y,(float)centerOfMass.z);
4441 Vector3 Inertia;
4442 float r = (float)radius;
4443 float m = (float)mass;
4444 float t = 0.4f * m * r * r;
4445
4446 Inertia.X = t;
4447 Inertia.Y = t;
4448 Inertia.Z = t;
4449
4450 sog.SetInertiaData(m, CenterOfMass, Inertia, new Vector4(0f, 0f, 0f,1.0f));
4451 }
4452
4453 /// <summary>
4454 /// set inertial data as a cylinder
4455 /// replaces the automatic calculation of mass, center of mass and inertia
4456 ///
4457 /// </summary>
4458 /// <param name="Mass">total mass of linkset</param>
4459 /// <param name="radius">radius of the cylinder</param>
4460 /// <param name="lenght">lenght of the cylinder</param>
4461 /// <param name="centerOfMass">location of center of mass relative to root prim in local coords</param>
4462 /// <param name="lslrot">rotation of the cylinder, and so inertia, relative to local axis</param>
4463 /// <remarks>
4464 /// cylinder axis aligned with Z axis. For other orientations provide the rotation.
4465 /// </remarks>
4466 public void osSetInertiaAsCylinder(LSL_Float mass, LSL_Float radius, LSL_Float lenght, LSL_Vector centerOfMass, LSL_Rotation lslrot)
4467 {
4468 SceneObjectGroup sog = m_host.ParentGroup;
4469 if(sog== null || sog.IsDeleted)
4470 return;
4471
4472 if(mass < 0)
4473 return;
4474
4475 // need more checks
4476
4477 Vector3 CenterOfMass = new Vector3((float)centerOfMass.x,(float)centerOfMass.y,(float)centerOfMass.z);
4478 Vector3 Inertia;
4479 float m = (float)mass;
4480 float r = (float)radius;
4481 r *= r;
4482 Inertia.Z = 0.5f * m * r;
4483 float t = (float)lenght;
4484 t *= t;
4485 t += 3.0f * r;
4486 t *= 8.333333e-2f * m;
4487
4488 Inertia.X = t;
4489 Inertia.Y = t;
4490
4491 Vector4 rot = new Vector4((float)lslrot.x, (float)lslrot.y, (float)lslrot.z, (float)lslrot.s);
4492 rot.Normalize();
4493
4494 sog.SetInertiaData(m, CenterOfMass, Inertia, rot);
4495 }
4496
4497 /// <summary>
4498 /// removes inertial data manual override
4499 /// default automatic calculation is used again
4500 ///
4501 /// </summary>
4502 public void osClearInertia()
4503 {
4504 SceneObjectGroup sog = m_host.ParentGroup;
4505 if(sog== null || sog.IsDeleted)
4506 return;
4507
4508 sog.SetInertiaData(-1, Vector3.Zero, Vector3.Zero, Vector4.Zero );
4509 }
4510
4511 private bool checkAllowObjectTPbyLandOwner(Vector3 pos)
4512 {
4513 ILandObject land = World.LandChannel.GetLandObject(pos);
4514 if(land == null)
4515 return true;
4516
4517 LandData landdata = land.LandData;
4518 if(landdata == null)
4519 return true;
4520
4521 UUID hostOwner = m_host.OwnerID;
4522 if(landdata.OwnerID == hostOwner)
4523 return true;
4524
4525 EstateSettings es = World.RegionInfo.EstateSettings;
4526 if(es != null && es.IsEstateManagerOrOwner(hostOwner))
4527 return true;
4528
4529 if(!landdata.IsGroupOwned)
4530 return false;
4531
4532 UUID landGroup = landdata.GroupID;
4533 if(landGroup == UUID.Zero)
4534 return false;
4535
4536 if(landGroup == m_host.GroupID)
4537 return true;
4538
4539 return false;
4540 }
4541
4542 /// <summary>
4543 /// teleports a object (full linkset)
4544 /// </summary>
4545 /// <param name="objectUUID">the id of the linkset to teleport</param>
4546 /// <param name="targetPos">target position</param>
4547 /// <param name="rotation"> a rotation to apply</param>
4548 /// <param name="flags">several flags/param>
4549 /// <remarks>
4550 /// only does teleport local to region
4551 /// if object has scripts, owner must have rights to run scripts on target location
4552 /// object owner must have rights to enter ojects on target location
4553 /// target location parcel must have enought free prims capacity for the linkset prims
4554 /// all avatars siting on the object must have access to target location
4555 /// has a cool down time. retries before expire reset it
4556 /// fail conditions are silent ignored
4557 /// </remarks>
4558 public LSL_Integer osTeleportObject(LSL_Key objectUUID, LSL_Vector targetPos, LSL_Rotation rotation, LSL_Integer flags)
4559 {
4560 CheckThreatLevel(ThreatLevel.Severe, "osTeleportObject");
4561
4562 UUID objUUID;
4563 if (!UUID.TryParse(objectUUID, out objUUID))
4564 {
4565 OSSLShoutError("osTeleportObject() invalid object Key");
4566 return -1;
4567 }
4568
4569 SceneObjectGroup sog = World.GetSceneObjectGroup(objUUID);
4570 if(sog== null || sog.IsDeleted || sog.inTransit)
4571 return -1;
4572
4573 if(sog.OwnerID != m_host.OwnerID)
4574 {
4575 Vector3 pos = sog.AbsolutePosition;
4576 if(!checkAllowObjectTPbyLandOwner(pos))
4577 return -1;
4578 }
4579
4580 UUID myid = m_host.ParentGroup.UUID;
4581
4582 return sog.TeleportObject(myid, targetPos, rotation, flags);
4583 // a delay here may break vehicles
4584 }
4585
4586 public LSL_Integer osGetLinkNumber(LSL_String name)
4587 {
4588 SceneObjectGroup sog = m_host.ParentGroup;
4589 if(sog== null || sog.IsDeleted)
4590 return -1;
4591 return sog.GetLinkNumber(name);
4592 }
3893 } 4593 }
3894} 4594}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 64dc2e2..cc98bbb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -93,7 +93,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
93 private const int AGENT = 1; 93 private const int AGENT = 1;
94 private const int AGENT_BY_USERNAME = 0x10; 94 private const int AGENT_BY_USERNAME = 0x10;
95 private const int NPC = 0x20; 95 private const int NPC = 0x20;
96 private const int OS_NPC = 0x01000000;
97 private const int ACTIVE = 2; 96 private const int ACTIVE = 2;
98 private const int PASSIVE = 4; 97 private const int PASSIVE = 4;
99 private const int SCRIPTED = 8; 98 private const int SCRIPTED = 8;
@@ -161,7 +160,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
161 ts.arc = arc; 160 ts.arc = arc;
162 ts.host = host; 161 ts.host = host;
163 162
164 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); 163 ts.next = DateTime.UtcNow.AddSeconds(ts.interval);
165 164
166 AddSenseRepeater(ts); 165 AddSenseRepeater(ts);
167 } 166 }
@@ -197,14 +196,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
197 public void CheckSenseRepeaterEvents() 196 public void CheckSenseRepeaterEvents()
198 { 197 {
199 // Go through all timers 198 // Go through all timers
200 foreach (SensorInfo ts in SenseRepeaters) 199
200 List<SensorInfo> curSensors;
201 lock(SenseRepeatListLock)
202 curSensors = SenseRepeaters;
203
204 DateTime now = DateTime.UtcNow;
205 foreach (SensorInfo ts in curSensors)
201 { 206 {
202 // Time has passed? 207 // Time has passed?
203 if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime()) 208 if (ts.next < now)
204 { 209 {
205 SensorSweep(ts); 210 SensorSweep(ts);
206 // set next interval 211 // set next interval
207 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); 212 ts.next = now.AddSeconds(ts.interval);
208 } 213 }
209 } 214 }
210 } 215 }
@@ -240,7 +245,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
240 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 245 List<SensedEntity> sensedEntities = new List<SensedEntity>();
241 246
242 // Is the sensor type is AGENT and not SCRIPTED then include agents 247 // Is the sensor type is AGENT and not SCRIPTED then include agents
243 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC | OS_NPC)) != 0 && (ts.type & SCRIPTED) == 0) 248 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
244 { 249 {
245 sensedEntities.AddRange(doAgentSensor(ts)); 250 sensedEntities.AddRange(doAgentSensor(ts));
246 } 251 }
@@ -339,7 +344,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
339 float dy; 344 float dy;
340 float dz; 345 float dz;
341 346
342 Quaternion q = SensePoint.GetWorldRotation(); 347// Quaternion q = SensePoint.RotationOffset;
348 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
343 if (SensePoint.ParentGroup.IsAttachment) 349 if (SensePoint.ParentGroup.IsAttachment)
344 { 350 {
345 // In attachments, rotate the sensor cone with the 351 // In attachments, rotate the sensor cone with the
@@ -351,14 +357,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
351 // your head but the sensor will stay with your (global) 357 // your head but the sensor will stay with your (global)
352 // avatar rotation and position. 358 // avatar rotation and position.
353 // Position of a sensor in a child prim attached to an avatar 359 // Position of a sensor in a child prim attached to an avatar
354 // will be still wrong. 360 // will be still wrong.
355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 361 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
356 362
357 // Don't proceed if the avatar for this attachment has since been removed from the scene. 363 // Don't proceed if the avatar for this attachment has since been removed from the scene.
358 if (avatar == null) 364 if (avatar == null)
359 return sensedEntities; 365 return sensedEntities;
360 366
361 q = avatar.GetWorldRotation() * q; 367 fromRegionPos = avatar.AbsolutePosition;
368 q = avatar.Rotation;
362 } 369 }
363 370
364 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 371 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -402,7 +409,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
402 objtype = 0; 409 objtype = 0;
403 410
404 part = ((SceneObjectGroup)ent).RootPart; 411 part = ((SceneObjectGroup)ent).RootPart;
405 if (part.ParentGroup.AttachmentPoint != 0) // Attached so ignore 412 if (part.ParentGroup.RootPart.Shape.PCode != (byte)PCode.Tree &&
413 part.ParentGroup.RootPart.Shape.PCode != (byte)PCode.NewTree &&
414 part.ParentGroup.AttachmentPoint != 0) // Attached so ignore
406 continue; 415 continue;
407 416
408 if (part.Inventory.ContainsScripts()) 417 if (part.Inventory.ContainsScripts())
@@ -470,7 +479,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
470 479
471 SceneObjectPart SensePoint = ts.host; 480 SceneObjectPart SensePoint = ts.host;
472 Vector3 fromRegionPos = SensePoint.GetWorldPosition(); 481 Vector3 fromRegionPos = SensePoint.GetWorldPosition();
473 482
474 Quaternion q = SensePoint.GetWorldRotation(); 483 Quaternion q = SensePoint.GetWorldRotation();
475 if (SensePoint.ParentGroup.IsAttachment) 484 if (SensePoint.ParentGroup.IsAttachment)
476 { 485 {
@@ -483,14 +492,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
483 // your head but the sensor will stay with your (global) 492 // your head but the sensor will stay with your (global)
484 // avatar rotation and position. 493 // avatar rotation and position.
485 // Position of a sensor in a child prim attached to an avatar 494 // Position of a sensor in a child prim attached to an avatar
486 // will be still wrong. 495 // will be still wrong.
487 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 496 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
488 497
489 // Don't proceed if the avatar for this attachment has since been removed from the scene. 498 // Don't proceed if the avatar for this attachment has since been removed from the scene.
490 if (avatar == null) 499 if (avatar == null)
491 return sensedEntities; 500 return sensedEntities;
492 501 fromRegionPos = avatar.AbsolutePosition;
493 q = avatar.GetWorldRotation() * q; 502 q = avatar.Rotation;
494 } 503 }
495 504
496 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 505 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -499,14 +508,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
499 bool attached = (SensePoint.ParentGroup.AttachmentPoint != 0); 508 bool attached = (SensePoint.ParentGroup.AttachmentPoint != 0);
500 Vector3 toRegionPos; 509 Vector3 toRegionPos;
501 double dis; 510 double dis;
502 511
503 Action<ScenePresence> senseEntity = new Action<ScenePresence>(presence => 512 Action<ScenePresence> senseEntity = new Action<ScenePresence>(presence =>
504 { 513 {
505// m_log.DebugFormat( 514// m_log.DebugFormat(
506// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}", 515// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}",
507// presence.Name, presence.PresenceType, ts.name, ts.type); 516// presence.Name, presence.PresenceType, ts.name, ts.type);
508 517
509 if ((ts.type & NPC) == 0 && (ts.type & OS_NPC) == 0 && presence.PresenceType == PresenceType.Npc) 518 if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
510 { 519 {
511 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene); 520 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
512 if (npcData == null || !npcData.SenseAsAgent) 521 if (npcData == null || !npcData.SenseAsAgent)
@@ -537,16 +546,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
537 } 546 }
538 } 547 }
539 548
540 if (presence.IsDeleted || presence.IsChildAgent || presence.GodLevel > 0.0) 549 if (presence.IsDeleted || presence.IsChildAgent || presence.IsViewerUIGod)
541 return; 550 return;
542 551
543 // if the object the script is in is attached and the avatar is the owner 552 // if the object the script is in is attached and the avatar is the owner
544 // then this one is not wanted 553 // then this one is not wanted
545 if (attached && presence.UUID == SensePoint.OwnerID) 554 if (attached && presence.UUID == SensePoint.OwnerID)
546 return; 555 return;
547 556
548 toRegionPos = presence.AbsolutePosition; 557 toRegionPos = presence.AbsolutePosition;
549 dis = Math.Abs(Util.GetDistanceTo(toRegionPos, fromRegionPos)); 558 dis = Util.GetDistanceTo(toRegionPos, fromRegionPos);
559 if (presence.IsSatOnObject && presence.ParentPart != null &&
560 presence.ParentPart.ParentGroup != null &&
561 presence.ParentPart.ParentGroup.RootPart != null)
562 {
563 Vector3 rpos = presence.ParentPart.ParentGroup.RootPart.AbsolutePosition;
564 double dis2 = Util.GetDistanceTo(rpos, fromRegionPos);
565 if (dis > dis2)
566 dis = dis2;
567 }
550 568
551 // Disabled for now since all osNpc* methods check for appropriate ownership permission. 569 // Disabled for now since all osNpc* methods check for appropriate ownership permission.
552 // Perhaps could be re-enabled as an NPC setting at some point since being able to make NPCs not 570 // Perhaps could be re-enabled as an NPC setting at some point since being able to make NPCs not
@@ -688,7 +706,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
688 DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); 706 DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
689 707
690 AddSenseRepeater(ts); 708 AddSenseRepeater(ts);
691 709
692 idx += 6; 710 idx += 6;
693 } 711 }
694 } 712 }
@@ -704,6 +722,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
704 } 722 }
705 723
706 return retList; 724 return retList;
707 } 725 }
708 } 726 }
709} \ No newline at end of file 727}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index 0b14565..cae1c14 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -123,25 +123,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
123 if (Timers.Count == 0) 123 if (Timers.Count == 0)
124 return; 124 return;
125 125
126 Dictionary<string, TimerInfo> tvals;
126 lock (TimerListLock) 127 lock (TimerListLock)
127 { 128 {
128 // Go through all timers 129 // Go through all timers
129 Dictionary<string, TimerInfo>.ValueCollection tvals = Timers.Values; 130 tvals = new Dictionary<string, TimerInfo>(Timers);
130 foreach (TimerInfo ts in tvals) 131 }
132
133 foreach (TimerInfo ts in tvals.Values)
134 {
135 // Time has passed?
136 if (ts.next < DateTime.Now.Ticks)
131 { 137 {
132 // Time has passed? 138 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
133 if (ts.next < DateTime.Now.Ticks) 139 // Add it to queue
134 { 140 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
135 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 141 new EventParams("timer", new Object[0],
136 // Add it to queue 142 new DetectParams[0]));
137 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 143 // set next interval
138 new EventParams("timer", new Object[0], 144
139 new DetectParams[0])); 145 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
140 // set next interval 146 ts.next = DateTime.Now.Ticks + ts.interval;
141
142 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
143 ts.next = DateTime.Now.Ticks + ts.interval;
144 }
145 } 147 }
146 } 148 }
147 } 149 }
@@ -198,6 +200,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
198 } 200 }
199 201
200 return retList; 202 return retList;
201 } 203 }
202 } 204 }
203} 205}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs
index 215c087..e6676b4 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs
@@ -2,7 +2,7 @@
2using System.Runtime.CompilerServices; 2using System.Runtime.CompilerServices;
3using System.Runtime.InteropServices; 3using System.Runtime.InteropServices;
4 4
5// General Information about an assembly is controlled through the following 5// General Information about an assembly is controlled through the following
6// set of attributes. Change these attribute values to modify the information 6// set of attributes. Change these attribute values to modify the information
7// associated with an assembly. 7// associated with an assembly.
8[assembly: AssemblyTitle("OpenSim.Region.ScriptEngine.Shared.Api")] 8[assembly: AssemblyTitle("OpenSim.Region.ScriptEngine.Shared.Api")]
@@ -14,8 +14,8 @@ using System.Runtime.InteropServices;
14[assembly: AssemblyTrademark("")] 14[assembly: AssemblyTrademark("")]
15[assembly: AssemblyCulture("")] 15[assembly: AssemblyCulture("")]
16 16
17// Setting ComVisible to false makes the types in this assembly not visible 17// Setting ComVisible to false makes the types in this assembly not visible
18// to COM components. If you need to access a type in this assembly from 18// to COM components. If you need to access a type in this assembly from
19// COM, set the ComVisible attribute to true on that type. 19// COM, set the ComVisible attribute to true on that type.
20[assembly: ComVisible(false)] 20[assembly: ComVisible(false)]
21 21
@@ -25,9 +25,9 @@ using System.Runtime.InteropServices;
25// Version information for an assembly consists of the following four values: 25// Version information for an assembly consists of the following four values:
26// 26//
27// Major Version 27// Major Version
28// Minor Version 28// Minor Version
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.8.3.*")] 32[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
33 33