aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/Api/Implementation
diff options
context:
space:
mode:
authoronefang2019-05-19 21:24:15 +1000
committeronefang2019-05-19 21:24:15 +1000
commit5e4d6cab00cb29cd088ab7b62ab13aff103b64cb (patch)
treea9fbc62df9eb2d1d9ba2698d8552eae71eca20d8 /OpenSim/Region/ScriptEngine/Shared/Api/Implementation
parentAdd a build script. (diff)
downloadopensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.zip
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.gz
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.bz2
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.xz
Dump OpenSim 0.9.0.1 into it's own branch.
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Api/Implementation')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs123
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs129
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs5948
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs18
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs84
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs2053
-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, 6027 insertions, 2434 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..3509968
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,129 @@
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 m_host.AddScriptLPS(1);
97 if(!m_CMFunctionsEnabled)
98 return String.Empty;
99 if(World.UserAccountService == null)
100 return String.Empty;
101 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
102 if (detectedParams == null)
103 return String.Empty;
104 UUID key = detectedParams.Key;
105 if(key == UUID.Zero)
106 return String.Empty;
107 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, key);
108 return account.UserCountry;
109 }
110
111 public string cmGetAgentCountry(LSL_Key key)
112 {
113 if(! m_CMFunctionsEnabled)
114 return "";
115 if(World.UserAccountService == null)
116 return String.Empty;
117 if (!World.Permissions.IsGod(m_host.OwnerID))
118 return String.Empty;
119
120 UUID uuid;
121
122 if (!UUID.TryParse(key, out uuid))
123 return String.Empty;
124
125 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
126 return account.UserCountry;
127 }
128 }
129}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 1399880..bac1468 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,30 +103,87 @@ 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;
108 109
109 protected bool throwErrorOnNotImplemented = false; 110 protected bool throwErrorOnNotImplemented = false;
110 protected AsyncCommandManager AsyncCommands = null; 111 protected AsyncCommandManager AsyncCommands = null;
112 protected float m_ScriptDelayFactor = 1.0f;
111 protected float m_ScriptDistanceFactor = 1.0f; 113 protected float m_ScriptDistanceFactor = 1.0f;
112 protected float m_MinTimerInterval = 0.5f; 114 protected float m_MinTimerInterval = 0.5f;
113 protected float m_recoilScaleFactor = 0.0f; 115 protected float m_recoilScaleFactor = 0.0f;
114 116
115 protected DateTime m_timer = DateTime.Now; 117 protected double m_timer = Util.GetTimeStampMS();
116 protected bool m_waitingForScriptAnswer = false; 118 protected bool m_waitingForScriptAnswer = false;
117 protected bool m_automaticLinkPermission = false; 119 protected bool m_automaticLinkPermission = false;
118 protected IMessageTransferModule m_TransferModule = null; 120 protected IMessageTransferModule m_TransferModule = null;
119 protected int m_notecardLineReadCharsMax = 255; 121 protected int m_notecardLineReadCharsMax = 255;
120 protected int m_scriptConsoleChannel = 0; 122 protected int m_scriptConsoleChannel = 0;
121 protected bool m_scriptConsoleChannelEnabled = false; 123 protected bool m_scriptConsoleChannelEnabled = false;
124 protected bool m_debuggerSafe = false;
122 protected IUrlModule m_UrlModule = null; 125 protected IUrlModule m_UrlModule = null;
126
123 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 127 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>();
124 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 128 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
129 protected int m_sleepMsOnSetTexture = 200;
130 protected int m_sleepMsOnSetLinkTexture = 200;
131 protected int m_sleepMsOnScaleTexture = 200;
132 protected int m_sleepMsOnOffsetTexture = 200;
133 protected int m_sleepMsOnRotateTexture = 200;
134 protected int m_sleepMsOnSetPos = 200;
135 protected int m_sleepMsOnSetRot = 200;
136 protected int m_sleepMsOnSetLocalRot = 200;
137 protected int m_sleepMsOnPreloadSound = 1000;
138 protected int m_sleepMsOnMakeExplosion = 100;
139 protected int m_sleepMsOnMakeFountain = 100;
140 protected int m_sleepMsOnMakeSmoke = 100;
141 protected int m_sleepMsOnMakeFire = 100;
142 protected int m_sleepMsOnRezAtRoot = 100;
143 protected int m_sleepMsOnInstantMessage = 2000;
144 protected int m_sleepMsOnEmail = 20000;
145 protected int m_sleepMsOnCreateLink = 1000;
146 protected int m_sleepMsOnGiveInventory = 3000;
147 protected int m_sleepMsOnRequestAgentData = 100;
148 protected int m_sleepMsOnRequestInventoryData = 1000;
149 protected int m_sleepMsOnSetDamage = 5000;
150 protected int m_sleepMsOnTextBox = 1000;
151 protected int m_sleepMsOnAdjustSoundVolume = 100;
152 protected int m_sleepMsOnEjectFromLand = 5000;
153 protected int m_sleepMsOnAddToLandPassList = 100;
154 protected int m_sleepMsOnDialog = 1000;
155 protected int m_sleepMsOnRemoteLoadScript = 3000;
156 protected int m_sleepMsOnRemoteLoadScriptPin = 3000;
157 protected int m_sleepMsOnOpenRemoteDataChannel = 1000;
158 protected int m_sleepMsOnSendRemoteData = 3000;
159 protected int m_sleepMsOnRemoteDataReply = 3000;
160 protected int m_sleepMsOnCloseRemoteDataChannel = 1000;
161 protected int m_sleepMsOnSetPrimitiveParams = 200;
162 protected int m_sleepMsOnSetLinkPrimitiveParams = 200;
163 protected int m_sleepMsOnXorBase64Strings = 300;
164 protected int m_sleepMsOnSetParcelMusicURL = 2000;
165 protected int m_sleepMsOnGetPrimMediaParams = 1000;
166 protected int m_sleepMsOnGetLinkMedia = 1000;
167 protected int m_sleepMsOnSetPrimMediaParams = 1000;
168 protected int m_sleepMsOnSetLinkMedia = 1000;
169 protected int m_sleepMsOnClearPrimMedia = 1000;
170 protected int m_sleepMsOnClearLinkMedia = 1000;
171 protected int m_sleepMsOnRequestSimulatorData = 1000;
172 protected int m_sleepMsOnLoadURL = 10000;
173 protected int m_sleepMsOnParcelMediaCommandList = 2000;
174 protected int m_sleepMsOnParcelMediaQuery = 2000;
175 protected int m_sleepMsOnModPow = 1000;
176 protected int m_sleepMsOnSetPrimURL = 2000;
177 protected int m_sleepMsOnRefreshPrimURL = 20000;
178 protected int m_sleepMsOnMapDestination = 1000;
179 protected int m_sleepMsOnAddToLandBanList = 100;
180 protected int m_sleepMsOnRemoveFromLandPassList = 100;
181 protected int m_sleepMsOnRemoveFromLandBanList = 100;
182 protected int m_sleepMsOnResetLandBanList = 100;
183 protected int m_sleepMsOnResetLandPassList = 100;
184 protected int m_sleepMsOnGetParcelPrimOwners = 2000;
185 protected int m_sleepMsOnGetNumberOfNotecardLines = 100;
186 protected int m_sleepMsOnGetNotecardLine = 100;
125 protected string m_internalObjectHost = "lsl.opensim.local"; 187 protected string m_internalObjectHost = "lsl.opensim.local";
126 protected bool m_restrictEmail = false; 188 protected bool m_restrictEmail = false;
127 protected ISoundModule m_SoundModule = null; 189 protected ISoundModule m_SoundModule = null;
@@ -172,7 +234,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
172 protected int m_maxHitsPerPrimInCastRay = 16; 234 protected int m_maxHitsPerPrimInCastRay = 16;
173 protected int m_maxHitsPerObjectInCastRay = 16; 235 protected int m_maxHitsPerObjectInCastRay = 16;
174 protected bool m_detectExitsInCastRay = false; 236 protected bool m_detectExitsInCastRay = false;
175 protected bool m_filterPartsInCastRay = false;
176 protected bool m_doAttachmentsInCastRay = false; 237 protected bool m_doAttachmentsInCastRay = false;
177 protected int m_msThrottleInCastRay = 200; 238 protected int m_msThrottleInCastRay = 200;
178 protected int m_msPerRegionInCastRay = 40; 239 protected int m_msPerRegionInCastRay = 40;
@@ -183,6 +244,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
183 protected bool m_useMeshCacheInCastRay = true; 244 protected bool m_useMeshCacheInCastRay = true;
184 protected static Dictionary<ulong, FacetedMesh> m_cachedMeshes = new Dictionary<ulong, FacetedMesh>(); 245 protected static Dictionary<ulong, FacetedMesh> m_cachedMeshes = new Dictionary<ulong, FacetedMesh>();
185 246
247// protected Timer m_ShoutSayTimer;
248 protected int m_SayShoutCount = 0;
249 DateTime m_lastSayShoutCheck;
250
251 private Dictionary<string, string> MovementAnimationsForLSL =
252 new Dictionary<string, string> {
253 {"CROUCH", "Crouching"},
254 {"CROUCHWALK", "CrouchWalking"},
255 {"FALLDOWN", "Falling Down"},
256 {"FLY", "Flying"},
257 {"FLYSLOW", "FlyingSlow"},
258 {"HOVER", "Hovering"},
259 {"HOVER_UP", "Hovering Up"},
260 {"HOVER_DOWN", "Hovering Down"},
261 {"JUMP", "Jumping"},
262 {"LAND", "Landing"},
263 {"PREJUMP", "PreJumping"},
264 {"RUN", "Running"},
265 {"SIT","Sitting"},
266 {"SITGROUND","Sitting on Ground"},
267 {"STAND", "Standing"},
268 {"STANDUP", "Standing Up"},
269 {"STRIDE","Striding"},
270 {"SOFT_LAND", "Soft Landing"},
271 {"TURNLEFT", "Turning Left"},
272 {"TURNRIGHT", "Turning Right"},
273 {"WALK", "Walking"}
274 };
275
186 //An array of HTTP/1.1 headers that are not allowed to be used 276 //An array of HTTP/1.1 headers that are not allowed to be used
187 //as custom headers by llHTTPRequest. 277 //as custom headers by llHTTPRequest.
188 private string[] HttpStandardHeaders = 278 private string[] HttpStandardHeaders =
@@ -203,9 +293,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
203 public void Initialize( 293 public void Initialize(
204 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item) 294 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item)
205 { 295 {
296 m_lastSayShoutCheck = DateTime.UtcNow;
297
206 m_ScriptEngine = scriptEngine; 298 m_ScriptEngine = scriptEngine;
207 m_host = host; 299 m_host = host;
208 m_item = item; 300 m_item = item;
301 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
209 302
210 LoadConfig(); 303 LoadConfig();
211 304
@@ -228,6 +321,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
228 321
229 if (seConfig != null) 322 if (seConfig != null)
230 { 323 {
324 m_ScriptDelayFactor =
325 seConfig.GetFloat("ScriptDelayFactor", m_ScriptDelayFactor);
231 m_ScriptDistanceFactor = 326 m_ScriptDistanceFactor =
232 seConfig.GetFloat("ScriptDistanceLimitFactor", m_ScriptDistanceFactor); 327 seConfig.GetFloat("ScriptDistanceLimitFactor", m_ScriptDistanceFactor);
233 m_MinTimerInterval = 328 m_MinTimerInterval =
@@ -296,7 +391,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
296 m_maxHitsPerPrimInCastRay = lslConfig.GetInt("MaxHitsPerPrimInLlCastRay", m_maxHitsPerPrimInCastRay); 391 m_maxHitsPerPrimInCastRay = lslConfig.GetInt("MaxHitsPerPrimInLlCastRay", m_maxHitsPerPrimInCastRay);
297 m_maxHitsPerObjectInCastRay = lslConfig.GetInt("MaxHitsPerObjectInLlCastRay", m_maxHitsPerObjectInCastRay); 392 m_maxHitsPerObjectInCastRay = lslConfig.GetInt("MaxHitsPerObjectInLlCastRay", m_maxHitsPerObjectInCastRay);
298 m_detectExitsInCastRay = lslConfig.GetBoolean("DetectExitHitsInLlCastRay", m_detectExitsInCastRay); 393 m_detectExitsInCastRay = lslConfig.GetBoolean("DetectExitHitsInLlCastRay", m_detectExitsInCastRay);
299 m_filterPartsInCastRay = lslConfig.GetBoolean("FilterPartsInLlCastRay", m_filterPartsInCastRay);
300 m_doAttachmentsInCastRay = lslConfig.GetBoolean("DoAttachmentsInLlCastRay", m_doAttachmentsInCastRay); 394 m_doAttachmentsInCastRay = lslConfig.GetBoolean("DoAttachmentsInLlCastRay", m_doAttachmentsInCastRay);
301 m_msThrottleInCastRay = lslConfig.GetInt("ThrottleTimeInMsInLlCastRay", m_msThrottleInCastRay); 395 m_msThrottleInCastRay = lslConfig.GetInt("ThrottleTimeInMsInLlCastRay", m_msThrottleInCastRay);
302 m_msPerRegionInCastRay = lslConfig.GetInt("AvailableTimeInMsPerRegionInLlCastRay", m_msPerRegionInCastRay); 396 m_msPerRegionInCastRay = lslConfig.GetInt("AvailableTimeInMsPerRegionInLlCastRay", m_msPerRegionInCastRay);
@@ -307,7 +401,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
307 } 401 }
308 402
309 IConfig smtpConfig = seConfigSource.Configs["SMTP"]; 403 IConfig smtpConfig = seConfigSource.Configs["SMTP"];
310 if (smtpConfig != null) 404 if (smtpConfig != null)
311 { 405 {
312 // there's an smtp config, so load in the snooze time. 406 // there's an smtp config, so load in the snooze time.
313 EMAIL_PAUSE_TIME = smtpConfig.GetInt("email_pause_time", EMAIL_PAUSE_TIME); 407 EMAIL_PAUSE_TIME = smtpConfig.GetInt("email_pause_time", EMAIL_PAUSE_TIME);
@@ -315,6 +409,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
315 m_internalObjectHost = smtpConfig.GetString("internal_object_host", m_internalObjectHost); 409 m_internalObjectHost = smtpConfig.GetString("internal_object_host", m_internalObjectHost);
316 } 410 }
317 } 411 }
412 m_sleepMsOnEmail = EMAIL_PAUSE_TIME * 1000;
318 } 413 }
319 414
320 public override Object InitializeLifetimeService() 415 public override Object InitializeLifetimeService()
@@ -330,6 +425,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
330 return lease; 425 return lease;
331 } 426 }
332 427
428 protected SceneObjectPart MonitoringObject()
429 {
430 UUID m = m_host.ParentGroup.MonitoringObject;
431 if (m == UUID.Zero)
432 return null;
433
434 SceneObjectPart p = m_ScriptEngine.World.GetSceneObjectPart(m);
435 if (p == null)
436 m_host.ParentGroup.MonitoringObject = UUID.Zero;
437
438 return p;
439 }
440
441 protected virtual void ScriptSleep(int delay)
442 {
443 delay = (int)((float)delay * m_ScriptDelayFactor);
444 if (delay == 0)
445 return;
446
447 Sleep(delay);
448 }
449
333 protected virtual void Sleep(int delay) 450 protected virtual void Sleep(int delay)
334 { 451 {
335 if (m_item == null) // Some unit tests don't set this 452 if (m_item == null) // Some unit tests don't set this
@@ -351,6 +468,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
351 get { return m_ScriptEngine.World; } 468 get { return m_ScriptEngine.World; }
352 } 469 }
353 470
471 [DebuggerNonUserCode]
354 public void state(string newState) 472 public void state(string newState)
355 { 473 {
356 m_ScriptEngine.SetState(m_item.ItemID, newState); 474 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -360,6 +478,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
360 /// Reset the named script. The script must be present 478 /// Reset the named script. The script must be present
361 /// in the same prim. 479 /// in the same prim.
362 /// </summary> 480 /// </summary>
481 [DebuggerNonUserCode]
363 public void llResetScript() 482 public void llResetScript()
364 { 483 {
365 m_host.AddScriptLPS(1); 484 m_host.AddScriptLPS(1);
@@ -376,12 +495,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
376 { 495 {
377 UUID item; 496 UUID item;
378 497
379 m_host.AddScriptLPS(1); 498 if ((item = GetScriptByName(name)) == UUID.Zero)
380 499 {
381 if ((item = GetScriptByName(name)) != UUID.Zero) 500 m_host.AddScriptLPS(1);
382 m_ScriptEngine.ResetScript(item);
383 else
384 Error("llResetOtherScript", "Can't find script '" + name + "'"); 501 Error("llResetOtherScript", "Can't find script '" + name + "'");
502 return;
503 }
504 if(item == m_item.ItemID)
505 llResetScript();
506 else
507 {
508 m_host.AddScriptLPS(1);
509 m_ScriptEngine.ResetScript(item);
510 }
385 } 511 }
386 512
387 public LSL_Integer llGetScriptState(string name) 513 public LSL_Integer llGetScriptState(string name)
@@ -414,7 +540,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
414 540
415 if ((item = GetScriptByName(name)) != UUID.Zero) 541 if ((item = GetScriptByName(name)) != UUID.Zero)
416 { 542 {
417 m_ScriptEngine.SetScriptState(item, run == 0 ? false : true); 543 m_ScriptEngine.SetScriptState(item, run == 0 ? false : true, item == m_item.ItemID);
418 } 544 }
419 else 545 else
420 { 546 {
@@ -422,6 +548,58 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
422 } 548 }
423 } 549 }
424 550
551 public List<ScenePresence> GetLinkAvatars(int linkType)
552 {
553 List<ScenePresence> ret = new List<ScenePresence>();
554 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
555 return ret;
556
557 // List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
558 // this needs check
559 List<ScenePresence> avs = m_host.ParentGroup.GetSittingAvatars();
560 switch (linkType)
561 {
562 case ScriptBaseClass.LINK_SET:
563 return avs;
564
565 case ScriptBaseClass.LINK_ROOT:
566 return ret;
567
568 case ScriptBaseClass.LINK_ALL_OTHERS:
569 return avs;
570
571 case ScriptBaseClass.LINK_ALL_CHILDREN:
572 return avs;
573
574 case ScriptBaseClass.LINK_THIS:
575 return ret;
576
577 default:
578 if (linkType < 0)
579 return ret;
580
581 int partCount = m_host.ParentGroup.GetPartCount();
582
583 if (linkType <= partCount)
584 {
585 return ret;
586 }
587 else
588 {
589 linkType = linkType - partCount;
590 if (linkType > avs.Count)
591 {
592 return ret;
593 }
594 else
595 {
596 ret.Add(avs[linkType-1]);
597 return ret;
598 }
599 }
600 }
601 }
602
425 /// <summary> 603 /// <summary>
426 /// Get a given link entity from a linkset (linked objects and any sitting avatars). 604 /// Get a given link entity from a linkset (linked objects and any sitting avatars).
427 /// </summary> 605 /// </summary>
@@ -501,7 +679,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
501 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 679 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
502 { 680 {
503 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 681 List<SceneObjectPart> ret = new List<SceneObjectPart>();
504 ret.Add(part); 682 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
683 return ret;
505 684
506 switch (linkType) 685 switch (linkType)
507 { 686 {
@@ -509,7 +688,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
509 return new List<SceneObjectPart>(part.ParentGroup.Parts); 688 return new List<SceneObjectPart>(part.ParentGroup.Parts);
510 689
511 case ScriptBaseClass.LINK_ROOT: 690 case ScriptBaseClass.LINK_ROOT:
512 ret = new List<SceneObjectPart>();
513 ret.Add(part.ParentGroup.RootPart); 691 ret.Add(part.ParentGroup.RootPart);
514 return ret; 692 return ret;
515 693
@@ -529,16 +707,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
529 return ret; 707 return ret;
530 708
531 case ScriptBaseClass.LINK_THIS: 709 case ScriptBaseClass.LINK_THIS:
710 ret.Add(part);
532 return ret; 711 return ret;
533 712
534 default: 713 default:
535 if (linkType < 0) 714 if (linkType < 0)
536 return new List<SceneObjectPart>(); 715 return ret;
537 716
538 SceneObjectPart target = part.ParentGroup.GetLinkNumPart(linkType); 717 SceneObjectPart target = part.ParentGroup.GetLinkNumPart(linkType);
539 if (target == null) 718 if (target == null)
540 return new List<SceneObjectPart>(); 719 return ret;
541 ret = new List<SceneObjectPart>();
542 ret.Add(target); 720 ret.Add(target);
543 return ret; 721 return ret;
544 } 722 }
@@ -648,8 +826,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
648 public LSL_Float llFrand(double mag) 826 public LSL_Float llFrand(double mag)
649 { 827 {
650 m_host.AddScriptLPS(1); 828 m_host.AddScriptLPS(1);
651 829 lock (Util.RandomClass)
652 return Util.RandomClass.NextDouble() * mag; 830 {
831 return Util.RandomClass.NextDouble() * mag;
832 }
653 } 833 }
654 834
655 public LSL_Integer llFloor(double f) 835 public LSL_Integer llFloor(double f)
@@ -700,31 +880,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
700 880
701 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 881 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
702 882
703 /// <summary> 883 // Utility function for llRot2Euler
704 /// Convert an LSL rotation to a Euler vector. 884
705 /// </summary> 885 public LSL_Vector llRot2Euler(LSL_Rotation q1)
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 { 886 {
714 m_host.AddScriptLPS(1); 887 m_host.AddScriptLPS(1);
888 LSL_Vector eul = new LSL_Vector();
715 889
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. 890 double sqw = q1.s*q1.s;
717 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 891 double sqx = q1.x*q1.x;
718 if (m == 0.0) return new LSL_Vector(); 892 double sqy = q1.z*q1.z;
719 double x = Math.Atan2(-v.y, v.z); 893 double sqz = q1.y*q1.y;
720 double sin = v.x / m; 894 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
721 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 895 double test = q1.x*q1.z + q1.y*q1.s;
722 double y = Math.Asin(sin); 896 if (test > 0.4999*unit) { // singularity at north pole
723 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation 897 eul.z = 2 * Math.Atan2(q1.x,q1.s);
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))); 898 eul.y = Math.PI/2;
725 double z = Math.Atan2(v.y, v.x); 899 eul.x = 0;
726 900 return eul;
727 return new LSL_Vector(x, y, z); 901 }
902 if (test < -0.4999*unit) { // singularity at south pole
903 eul.z = -2 * Math.Atan2(q1.x,q1.s);
904 eul.y = -Math.PI/2;
905 eul.x = 0;
906 return eul;
907 }
908 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
909 eul.y = Math.Asin(2*test/unit);
910 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
911 return eul;
728 } 912 }
729 913
730 /* From wiki: 914 /* From wiki:
@@ -777,18 +961,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
777 m_host.AddScriptLPS(1); 961 m_host.AddScriptLPS(1);
778 962
779 double x,y,z,s; 963 double x,y,z,s;
780 964 v.x *= 0.5;
781 double c1 = Math.Cos(v.x * 0.5); 965 v.y *= 0.5;
782 double c2 = Math.Cos(v.y * 0.5); 966 v.z *= 0.5;
783 double c3 = Math.Cos(v.z * 0.5); 967 double c1 = Math.Cos(v.x);
784 double s1 = Math.Sin(v.x * 0.5); 968 double c2 = Math.Cos(v.y);
785 double s2 = Math.Sin(v.y * 0.5); 969 double c1c2 = c1 * c2;
786 double s3 = Math.Sin(v.z * 0.5); 970 double s1 = Math.Sin(v.x);
787 971 double s2 = Math.Sin(v.y);
788 x = s1 * c2 * c3 + c1 * s2 * s3; 972 double s1s2 = s1 * s2;
789 y = c1 * s2 * c3 - s1 * c2 * s3; 973 double c1s2 = c1 * s2;
790 z = s1 * s2 * c3 + c1 * c2 * s3; 974 double s1c2 = s1 * c2;
791 s = c1 * c2 * c3 - s1 * s2 * s3; 975 double c3 = Math.Cos(v.z);
976 double s3 = Math.Sin(v.z);
977
978 x = s1c2 * c3 + c1s2 * s3;
979 y = c1s2 * c3 - s1c2 * s3;
980 z = s1s2 * c3 + c1c2 * s3;
981 s = c1c2 * c3 - s1s2 * s3;
792 982
793 return new LSL_Rotation(x, y, z, s); 983 return new LSL_Rotation(x, y, z, s);
794 } 984 }
@@ -926,75 +1116,74 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
926 { 1116 {
927 //A and B should both be normalized 1117 //A and B should both be normalized
928 m_host.AddScriptLPS(1); 1118 m_host.AddScriptLPS(1);
929 LSL_Rotation rotBetween; 1119 /* This method is more accurate than the SL one, and thus causes problems
930 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 1120 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
931 // continue calculation. 1121
932 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 1122 double dotProduct = LSL_Vector.Dot(a, b);
1123 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
1124 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
1125 double angle = Math.Acos(dotProduct / magProduct);
1126 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
1127 double s = Math.Sin(angle / 2);
1128
1129 double x = axis.x * s;
1130 double y = axis.y * s;
1131 double z = axis.z * s;
1132 double w = Math.Cos(angle / 2);
1133
1134 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
1135 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
1136
1137 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
1138 */
1139
1140 // This method mimics the 180 errors found in SL
1141 // See www.euclideanspace.com... angleBetween
1142 LSL_Vector vec_a = a;
1143 LSL_Vector vec_b = b;
1144
1145 // Eliminate zero length
1146 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
1147 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
1148 if (vec_a_mag < 0.00001 ||
1149 vec_b_mag < 0.00001)
933 { 1150 {
934 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 1151 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
935 } 1152 }
936 else 1153
1154 // Normalize
1155 vec_a = llVecNorm(vec_a);
1156 vec_b = llVecNorm(vec_b);
1157
1158 // Calculate axis and rotation angle
1159 LSL_Vector axis = vec_a % vec_b;
1160 LSL_Float cos_theta = vec_a * vec_b;
1161
1162 // Check if parallel
1163 if (cos_theta > 0.99999)
937 { 1164 {
938 a = LSL_Vector.Norm(a); 1165 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
939 b = LSL_Vector.Norm(b); 1166 }
940 double dotProduct = LSL_Vector.Dot(a, b); 1167
941 // There are two degenerate cases possible. These are for vectors 180 or 1168 // Check if anti-parallel
942 // 0 degrees apart. These have to be detected and handled individually. 1169 else if (cos_theta < -0.99999)
943 // 1170 {
944 // Check for vectors 180 degrees apart. 1171 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. 1172 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
946 if (dotProduct < -0.9999999f) 1173 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
947 { 1174 }
948 // First assume X axis is orthogonal to the vectors. 1175 else // other rotation
949 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 1176 {
950 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 1177 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 1178 axis = llVecNorm(axis);
952 // a rotation in an undesired direction. 1179 double x, y, z, s, t;
953 if (LSL_Vector.Mag(orthoVector) > 0.0001) 1180 s = Math.Cos(theta);
954 { 1181 t = Math.Sin(theta);
955 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 1182 x = axis.x * t;
956 } 1183 y = axis.y * t;
957 // If the magnitude of the vector was near zero, then assume the X axis is not 1184 z = axis.z * t;
958 // orthogonal and use the Z axis instead. 1185 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 } 1186 }
997 return rotBetween;
998 } 1187 }
999 1188
1000 public void llWhisper(int channelID, string text) 1189 public void llWhisper(int channelID, string text)
@@ -1012,10 +1201,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1012 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 1201 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
1013 } 1202 }
1014 1203
1204 private void CheckSayShoutTime()
1205 {
1206 DateTime now = DateTime.UtcNow;
1207 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
1208 {
1209 m_lastSayShoutCheck = now;
1210 m_SayShoutCount = 0;
1211 }
1212 else
1213 m_SayShoutCount++;
1214 }
1215
1015 public void llSay(int channelID, string text) 1216 public void llSay(int channelID, string text)
1016 { 1217 {
1017 m_host.AddScriptLPS(1); 1218 m_host.AddScriptLPS(1);
1018 1219
1220 if (channelID == 0)
1221// m_SayShoutCount++;
1222 CheckSayShoutTime();
1223
1224 if (m_SayShoutCount >= 11)
1225 ScriptSleep(2000);
1226
1019 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 1227 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
1020 { 1228 {
1021 Console.WriteLine(text); 1229 Console.WriteLine(text);
@@ -1038,6 +1246,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1038 { 1246 {
1039 m_host.AddScriptLPS(1); 1247 m_host.AddScriptLPS(1);
1040 1248
1249 if (channelID == 0)
1250// m_SayShoutCount++;
1251 CheckSayShoutTime();
1252
1253 if (m_SayShoutCount >= 11)
1254 ScriptSleep(2000);
1255
1041 if (text.Length > 1023) 1256 if (text.Length > 1023)
1042 text = text.Substring(0, 1023); 1257 text = text.Substring(0, 1023);
1043 1258
@@ -1062,8 +1277,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1062 1277
1063 m_host.AddScriptLPS(1); 1278 m_host.AddScriptLPS(1);
1064 1279
1065 World.SimChat(Utils.StringToBytes(text), 1280 // debug channel is also sent to avatars
1066 ChatTypeEnum.Region, channelID, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, false); 1281 if (channelID == ScriptBaseClass.DEBUG_CHANNEL)
1282 {
1283 World.SimChat(Utils.StringToBytes(text),
1284 ChatTypeEnum.Shout, channelID, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true);
1285
1286 }
1067 1287
1068 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 1288 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
1069 if (wComm != null) 1289 if (wComm != null)
@@ -1078,16 +1298,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1078 m_host.AddScriptLPS(1); 1298 m_host.AddScriptLPS(1);
1079 1299
1080 if (channel == ScriptBaseClass.DEBUG_CHANNEL) 1300 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
1081 {
1082 return; 1301 return;
1083 }
1084 1302
1085 UUID TargetID; 1303 UUID TargetID;
1086 UUID.TryParse(target, out TargetID); 1304 UUID.TryParse(target, out TargetID);
1087 1305
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>(); 1306 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
1092 if (wComm != null) 1307 if (wComm != null)
1093 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 1308 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg);
@@ -1346,10 +1561,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1346 return detectedParams.TouchUV; 1561 return detectedParams.TouchUV;
1347 } 1562 }
1348 1563
1564 [DebuggerNonUserCode]
1349 public virtual void llDie() 1565 public virtual void llDie()
1350 { 1566 {
1351 m_host.AddScriptLPS(1); 1567 m_host.AddScriptLPS(1);
1352 throw new SelfDeleteException(); 1568 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1353 } 1569 }
1354 1570
1355 public LSL_Float llGround(LSL_Vector offset) 1571 public LSL_Float llGround(LSL_Vector offset)
@@ -1420,6 +1636,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1420 1636
1421 public void llSetStatus(int status, int value) 1637 public void llSetStatus(int status, int value)
1422 { 1638 {
1639 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1640 return;
1423 m_host.AddScriptLPS(1); 1641 m_host.AddScriptLPS(1);
1424 1642
1425 int statusrotationaxis = 0; 1643 int statusrotationaxis = 0;
@@ -1431,18 +1649,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1431 SceneObjectGroup group = m_host.ParentGroup; 1649 SceneObjectGroup group = m_host.ParentGroup;
1432 bool allow = true; 1650 bool allow = true;
1433 1651
1652 int maxprims = World.m_linksetPhysCapacity;
1653 bool checkShape = (maxprims > 0 && group.PrimCount > maxprims);
1654
1434 foreach (SceneObjectPart part in group.Parts) 1655 foreach (SceneObjectPart part in group.Parts)
1435 { 1656 {
1657 if (part.PhysicsShapeType == (byte)PhysicsShapeType.None)
1658 continue;
1659
1436 if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys) 1660 if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys)
1437 { 1661 {
1438 allow = false; 1662 allow = false;
1439 break; 1663 break;
1440 } 1664 }
1665 if (checkShape)
1666 {
1667 if (--maxprims < 0)
1668 {
1669 allow = false;
1670 break;
1671 }
1672 }
1441 } 1673 }
1442 1674
1443 if (!allow) 1675 if (!allow)
1444 return; 1676 return;
1445 1677
1678 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1679 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1680 return;
1681
1446 m_host.ScriptSetPhysicsStatus(true); 1682 m_host.ScriptSetPhysicsStatus(true);
1447 } 1683 }
1448 else 1684 else
@@ -1586,6 +1822,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1586 return 0; 1822 return 0;
1587 } 1823 }
1588 1824
1825 public LSL_Integer llScaleByFactor(double scaling_factor)
1826 {
1827 m_host.AddScriptLPS(1);
1828 SceneObjectGroup group = m_host.ParentGroup;
1829
1830 if(scaling_factor < 1e-6)
1831 return ScriptBaseClass.FALSE;
1832 if(scaling_factor > 1e6)
1833 return ScriptBaseClass.FALSE;
1834
1835 if (group == null || group.IsDeleted || group.inTransit)
1836 return ScriptBaseClass.FALSE;
1837
1838 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
1839 return ScriptBaseClass.FALSE;
1840
1841 if (group.RootPart.KeyframeMotion != null)
1842 return ScriptBaseClass.FALSE;
1843
1844 if(group.GroupResize(scaling_factor))
1845 return ScriptBaseClass.TRUE;
1846 else
1847 return ScriptBaseClass.FALSE;
1848 }
1849
1850 public LSL_Float llGetMaxScaleFactor()
1851 {
1852 m_host.AddScriptLPS(1);
1853 SceneObjectGroup group = m_host.ParentGroup;
1854
1855 if (group == null || group.IsDeleted || group.inTransit)
1856 return 1.0f;
1857
1858 return (LSL_Float)group.GetMaxGroupResizeScale();
1859 }
1860
1861 public LSL_Float llGetMinScaleFactor()
1862 {
1863 m_host.AddScriptLPS(1);
1864 SceneObjectGroup group = m_host.ParentGroup;
1865
1866 if (group == null || group.IsDeleted || group.inTransit)
1867 return 1.0f;
1868
1869 return (LSL_Float)group.GetMinGroupResizeScale();
1870 }
1871
1589 public void llSetScale(LSL_Vector scale) 1872 public void llSetScale(LSL_Vector scale)
1590 { 1873 {
1591 m_host.AddScriptLPS(1); 1874 m_host.AddScriptLPS(1);
@@ -1641,6 +1924,50 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1641 { 1924 {
1642 m_host.AddScriptLPS(1); 1925 m_host.AddScriptLPS(1);
1643 1926
1927 SetColor(m_host, color, face);
1928 }
1929
1930 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1931 {
1932 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1933 return;
1934
1935 Primitive.TextureEntry tex = part.Shape.Textures;
1936 int nsides = GetNumberOfSides(part);
1937 Color4 texcolor;
1938
1939 if (face >= 0 && face < nsides)
1940 {
1941 texcolor = tex.CreateFace((uint)face).RGBA;
1942 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1943 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1944 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1945 tex.FaceTextures[face].RGBA = texcolor;
1946 part.UpdateTextureEntry(tex.GetBytes());
1947 return;
1948 }
1949 else if (face == ScriptBaseClass.ALL_SIDES)
1950 {
1951 for (uint i = 0; i < nsides; i++)
1952 {
1953 if (tex.FaceTextures[i] != null)
1954 {
1955 texcolor = tex.FaceTextures[i].RGBA;
1956 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1957 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1958 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1959 tex.FaceTextures[i].RGBA = texcolor;
1960 }
1961 texcolor = tex.DefaultTexture.RGBA;
1962 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1963 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1964 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1965 tex.DefaultTexture.RGBA = texcolor;
1966 }
1967 part.UpdateTextureEntry(tex.GetBytes());
1968 return;
1969 }
1970
1644 if (face == ScriptBaseClass.ALL_SIDES) 1971 if (face == ScriptBaseClass.ALL_SIDES)
1645 face = SceneObjectPart.ALL_SIDES; 1972 face = SceneObjectPart.ALL_SIDES;
1646 1973
@@ -1714,15 +2041,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1714 } 2041 }
1715 } 2042 }
1716 2043
2044/*
2045 public void llSetContentType(LSL_Key id, LSL_Integer content_type)
2046 {
2047 if (m_UrlModule != null)
2048 {
2049 string type = "text.plain";
2050 if (content_type == (int)ScriptBaseClass.CONTENT_TYPE_HTML)
2051 type = "text/html";
2052
2053 m_UrlModule.HttpContentType(new UUID(id),type);
2054 }
2055 }
2056*/
1717 public void SetTexGen(SceneObjectPart part, int face,int style) 2057 public void SetTexGen(SceneObjectPart part, int face,int style)
1718 { 2058 {
2059 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2060 return;
2061
1719 Primitive.TextureEntry tex = part.Shape.Textures; 2062 Primitive.TextureEntry tex = part.Shape.Textures;
1720 MappingType textype; 2063 MappingType textype;
1721 textype = MappingType.Default; 2064 textype = MappingType.Default;
1722 if (style == (int)ScriptBaseClass.PRIM_TEXGEN_PLANAR) 2065 if (style == (int)ScriptBaseClass.PRIM_TEXGEN_PLANAR)
1723 textype = MappingType.Planar; 2066 textype = MappingType.Planar;
1724 2067
1725 if (face >= 0 && face < GetNumberOfSides(part)) 2068 int nsides = GetNumberOfSides(part);
2069
2070 if (face >= 0 && face < nsides)
1726 { 2071 {
1727 tex.CreateFace((uint) face); 2072 tex.CreateFace((uint) face);
1728 tex.FaceTextures[face].TexMapType = textype; 2073 tex.FaceTextures[face].TexMapType = textype;
@@ -1731,7 +2076,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1731 } 2076 }
1732 else if (face == ScriptBaseClass.ALL_SIDES) 2077 else if (face == ScriptBaseClass.ALL_SIDES)
1733 { 2078 {
1734 for (uint i = 0; i < GetNumberOfSides(part); i++) 2079 for (uint i = 0; i < nsides; i++)
1735 { 2080 {
1736 if (tex.FaceTextures[i] != null) 2081 if (tex.FaceTextures[i] != null)
1737 { 2082 {
@@ -1746,8 +2091,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1746 2091
1747 public void SetGlow(SceneObjectPart part, int face, float glow) 2092 public void SetGlow(SceneObjectPart part, int face, float glow)
1748 { 2093 {
2094 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2095 return;
2096
1749 Primitive.TextureEntry tex = part.Shape.Textures; 2097 Primitive.TextureEntry tex = part.Shape.Textures;
1750 if (face >= 0 && face < GetNumberOfSides(part)) 2098 int nsides = GetNumberOfSides(part);
2099
2100 if (face >= 0 && face < nsides)
1751 { 2101 {
1752 tex.CreateFace((uint) face); 2102 tex.CreateFace((uint) face);
1753 tex.FaceTextures[face].Glow = glow; 2103 tex.FaceTextures[face].Glow = glow;
@@ -1756,7 +2106,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1756 } 2106 }
1757 else if (face == ScriptBaseClass.ALL_SIDES) 2107 else if (face == ScriptBaseClass.ALL_SIDES)
1758 { 2108 {
1759 for (uint i = 0; i < GetNumberOfSides(part); i++) 2109 for (uint i = 0; i < nsides; i++)
1760 { 2110 {
1761 if (tex.FaceTextures[i] != null) 2111 if (tex.FaceTextures[i] != null)
1762 { 2112 {
@@ -1771,6 +2121,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1771 2121
1772 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 2122 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1773 { 2123 {
2124 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2125 return;
1774 2126
1775 Shininess sval = new Shininess(); 2127 Shininess sval = new Shininess();
1776 2128
@@ -1793,8 +2145,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1793 break; 2145 break;
1794 } 2146 }
1795 2147
2148 int nsides = GetNumberOfSides(part);
2149
1796 Primitive.TextureEntry tex = part.Shape.Textures; 2150 Primitive.TextureEntry tex = part.Shape.Textures;
1797 if (face >= 0 && face < GetNumberOfSides(part)) 2151 if (face >= 0 && face < nsides)
1798 { 2152 {
1799 tex.CreateFace((uint) face); 2153 tex.CreateFace((uint) face);
1800 tex.FaceTextures[face].Shiny = sval; 2154 tex.FaceTextures[face].Shiny = sval;
@@ -1804,7 +2158,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1804 } 2158 }
1805 else if (face == ScriptBaseClass.ALL_SIDES) 2159 else if (face == ScriptBaseClass.ALL_SIDES)
1806 { 2160 {
1807 for (uint i = 0; i < GetNumberOfSides(part); i++) 2161 for (uint i = 0; i < nsides; i++)
1808 { 2162 {
1809 if (tex.FaceTextures[i] != null) 2163 if (tex.FaceTextures[i] != null)
1810 { 2164 {
@@ -1821,8 +2175,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1821 2175
1822 public void SetFullBright(SceneObjectPart part, int face, bool bright) 2176 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1823 { 2177 {
2178 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2179 return;
2180
2181 int nsides = GetNumberOfSides(part);
1824 Primitive.TextureEntry tex = part.Shape.Textures; 2182 Primitive.TextureEntry tex = part.Shape.Textures;
1825 if (face >= 0 && face < GetNumberOfSides(part)) 2183 if (face >= 0 && face < nsides)
1826 { 2184 {
1827 tex.CreateFace((uint) face); 2185 tex.CreateFace((uint) face);
1828 tex.FaceTextures[face].Fullbright = bright; 2186 tex.FaceTextures[face].Fullbright = bright;
@@ -1831,7 +2189,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1831 } 2189 }
1832 else if (face == ScriptBaseClass.ALL_SIDES) 2190 else if (face == ScriptBaseClass.ALL_SIDES)
1833 { 2191 {
1834 for (uint i = 0; i < GetNumberOfSides(part); i++) 2192 for (uint i = 0; i < nsides; i++)
1835 { 2193 {
1836 if (tex.FaceTextures[i] != null) 2194 if (tex.FaceTextures[i] != null)
1837 { 2195 {
@@ -1854,15 +2212,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1854 protected LSL_Float GetAlpha(SceneObjectPart part, int face) 2212 protected LSL_Float GetAlpha(SceneObjectPart part, int face)
1855 { 2213 {
1856 Primitive.TextureEntry tex = part.Shape.Textures; 2214 Primitive.TextureEntry tex = part.Shape.Textures;
2215 int nsides = GetNumberOfSides(part);
1857 if (face == ScriptBaseClass.ALL_SIDES) 2216 if (face == ScriptBaseClass.ALL_SIDES)
1858 { 2217 {
1859 int i; 2218 int i;
1860 double sum = 0.0; 2219 double sum = 0.0;
1861 for (i = 0 ; i < GetNumberOfSides(part); i++) 2220 for (i = 0 ; i < nsides; i++)
1862 sum += (double)tex.GetFace((uint)i).RGBA.A; 2221 sum += (double)tex.GetFace((uint)i).RGBA.A;
1863 return sum; 2222 return sum;
1864 } 2223 }
1865 if (face >= 0 && face < GetNumberOfSides(part)) 2224 if (face >= 0 && face < nsides)
1866 { 2225 {
1867 return (double)tex.GetFace((uint)face).RGBA.A; 2226 return (double)tex.GetFace((uint)face).RGBA.A;
1868 } 2227 }
@@ -1881,16 +2240,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1881 m_host.AddScriptLPS(1); 2240 m_host.AddScriptLPS(1);
1882 2241
1883 List<SceneObjectPart> parts = GetLinkParts(linknumber); 2242 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1884 2243 if (parts.Count > 0)
1885 foreach (SceneObjectPart part in parts) 2244 {
1886 SetAlpha(part, alpha, face); 2245 try
2246 {
2247 foreach (SceneObjectPart part in parts)
2248 SetAlpha(part, alpha, face);
2249 }
2250 finally { }
2251 }
1887 } 2252 }
1888 2253
1889 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 2254 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1890 { 2255 {
2256 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2257 return;
2258
1891 Primitive.TextureEntry tex = part.Shape.Textures; 2259 Primitive.TextureEntry tex = part.Shape.Textures;
2260 int nsides = GetNumberOfSides(part);
1892 Color4 texcolor; 2261 Color4 texcolor;
1893 if (face >= 0 && face < GetNumberOfSides(part)) 2262
2263 if (face >= 0 && face < nsides)
1894 { 2264 {
1895 texcolor = tex.CreateFace((uint)face).RGBA; 2265 texcolor = tex.CreateFace((uint)face).RGBA;
1896 texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f); 2266 texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f);
@@ -1900,7 +2270,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1900 } 2270 }
1901 else if (face == ScriptBaseClass.ALL_SIDES) 2271 else if (face == ScriptBaseClass.ALL_SIDES)
1902 { 2272 {
1903 for (int i = 0; i < GetNumberOfSides(part); i++) 2273 for (int i = 0; i < nsides; i++)
1904 { 2274 {
1905 if (tex.FaceTextures[i] != null) 2275 if (tex.FaceTextures[i] != null)
1906 { 2276 {
@@ -1940,7 +2310,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1940 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 2310 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1941 float wind, float tension, LSL_Vector Force) 2311 float wind, float tension, LSL_Vector Force)
1942 { 2312 {
1943 if (part == null) 2313 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1944 return; 2314 return;
1945 2315
1946 if (flexi) 2316 if (flexi)
@@ -1981,7 +2351,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1981 /// <param name="falloff"></param> 2351 /// <param name="falloff"></param>
1982 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 2352 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1983 { 2353 {
1984 if (part == null) 2354 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1985 return; 2355 return;
1986 2356
1987 if (light) 2357 if (light)
@@ -2014,11 +2384,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2014 Primitive.TextureEntry tex = part.Shape.Textures; 2384 Primitive.TextureEntry tex = part.Shape.Textures;
2015 Color4 texcolor; 2385 Color4 texcolor;
2016 LSL_Vector rgb = new LSL_Vector(); 2386 LSL_Vector rgb = new LSL_Vector();
2387 int nsides = GetNumberOfSides(part);
2388
2017 if (face == ScriptBaseClass.ALL_SIDES) 2389 if (face == ScriptBaseClass.ALL_SIDES)
2018 { 2390 {
2019 int i; 2391 int i;
2020 2392 for (i = 0; i < nsides; i++)
2021 for (i = 0 ; i < GetNumberOfSides(part); i++)
2022 { 2393 {
2023 texcolor = tex.GetFace((uint)i).RGBA; 2394 texcolor = tex.GetFace((uint)i).RGBA;
2024 rgb.x += texcolor.R; 2395 rgb.x += texcolor.R;
@@ -2026,14 +2397,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2026 rgb.z += texcolor.B; 2397 rgb.z += texcolor.B;
2027 } 2398 }
2028 2399
2029 rgb.x /= (float)GetNumberOfSides(part); 2400 float invnsides = 1.0f / (float)nsides;
2030 rgb.y /= (float)GetNumberOfSides(part); 2401
2031 rgb.z /= (float)GetNumberOfSides(part); 2402 rgb.x *= invnsides;
2403 rgb.y *= invnsides;
2404 rgb.z *= invnsides;
2032 2405
2033 return rgb; 2406 return rgb;
2034 } 2407 }
2035 2408 if (face >= 0 && face < nsides)
2036 if (face >= 0 && face < GetNumberOfSides(part))
2037 { 2409 {
2038 texcolor = tex.GetFace((uint)face).RGBA; 2410 texcolor = tex.GetFace((uint)face).RGBA;
2039 rgb.x = texcolor.R; 2411 rgb.x = texcolor.R;
@@ -2052,6 +2424,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2052 { 2424 {
2053 m_host.AddScriptLPS(1); 2425 m_host.AddScriptLPS(1);
2054 SetTexture(m_host, texture, face); 2426 SetTexture(m_host, texture, face);
2427 ScriptSleep(m_sleepMsOnSetTexture);
2055 } 2428 }
2056 2429
2057 public void llSetLinkTexture(int linknumber, string texture, int face) 2430 public void llSetLinkTexture(int linknumber, string texture, int face)
@@ -2059,13 +2432,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2059 m_host.AddScriptLPS(1); 2432 m_host.AddScriptLPS(1);
2060 2433
2061 List<SceneObjectPart> parts = GetLinkParts(linknumber); 2434 List<SceneObjectPart> parts = GetLinkParts(linknumber);
2062 2435 if (parts.Count > 0)
2063 foreach (SceneObjectPart part in parts) 2436 {
2064 SetTexture(part, texture, face); 2437 try
2438 {
2439 foreach (SceneObjectPart part in parts)
2440 SetTexture(part, texture, face);
2441 }
2442 finally { }
2443 }
2444 ScriptSleep(m_sleepMsOnSetLinkTexture);
2065 } 2445 }
2066 2446
2067 protected void SetTexture(SceneObjectPart part, string texture, int face) 2447 protected void SetTexture(SceneObjectPart part, string texture, int face)
2068 { 2448 {
2449 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2450 return;
2451
2069 UUID textureID = new UUID(); 2452 UUID textureID = new UUID();
2070 2453
2071 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); 2454 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture);
@@ -2075,9 +2458,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2075 return; 2458 return;
2076 } 2459 }
2077 2460
2461
2078 Primitive.TextureEntry tex = part.Shape.Textures; 2462 Primitive.TextureEntry tex = part.Shape.Textures;
2463 int nsides = GetNumberOfSides(part);
2079 2464
2080 if (face >= 0 && face < GetNumberOfSides(part)) 2465 if (face >= 0 && face < nsides)
2081 { 2466 {
2082 Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); 2467 Primitive.TextureEntryFace texface = tex.CreateFace((uint)face);
2083 texface.TextureID = textureID; 2468 texface.TextureID = textureID;
@@ -2087,7 +2472,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2087 } 2472 }
2088 else if (face == ScriptBaseClass.ALL_SIDES) 2473 else if (face == ScriptBaseClass.ALL_SIDES)
2089 { 2474 {
2090 for (uint i = 0; i < GetNumberOfSides(part); i++) 2475 for (uint i = 0; i < nsides; i++)
2091 { 2476 {
2092 if (tex.FaceTextures[i] != null) 2477 if (tex.FaceTextures[i] != null)
2093 { 2478 {
@@ -2105,12 +2490,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2105 m_host.AddScriptLPS(1); 2490 m_host.AddScriptLPS(1);
2106 2491
2107 ScaleTexture(m_host, u, v, face); 2492 ScaleTexture(m_host, u, v, face);
2493 ScriptSleep(m_sleepMsOnScaleTexture);
2108 } 2494 }
2109 2495
2110 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2496 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
2111 { 2497 {
2498 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2499 return;
2500
2112 Primitive.TextureEntry tex = part.Shape.Textures; 2501 Primitive.TextureEntry tex = part.Shape.Textures;
2113 if (face >= 0 && face < GetNumberOfSides(part)) 2502 int nsides = GetNumberOfSides(part);
2503
2504 if (face >= 0 && face < nsides)
2114 { 2505 {
2115 Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); 2506 Primitive.TextureEntryFace texface = tex.CreateFace((uint)face);
2116 texface.RepeatU = (float)u; 2507 texface.RepeatU = (float)u;
@@ -2121,7 +2512,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2121 } 2512 }
2122 if (face == ScriptBaseClass.ALL_SIDES) 2513 if (face == ScriptBaseClass.ALL_SIDES)
2123 { 2514 {
2124 for (int i = 0; i < GetNumberOfSides(part); i++) 2515 for (int i = 0; i < nsides; i++)
2125 { 2516 {
2126 if (tex.FaceTextures[i] != null) 2517 if (tex.FaceTextures[i] != null)
2127 { 2518 {
@@ -2140,12 +2531,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2140 { 2531 {
2141 m_host.AddScriptLPS(1); 2532 m_host.AddScriptLPS(1);
2142 OffsetTexture(m_host, u, v, face); 2533 OffsetTexture(m_host, u, v, face);
2534 ScriptSleep(m_sleepMsOnOffsetTexture);
2143 } 2535 }
2144 2536
2145 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2537 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
2146 { 2538 {
2539 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2540 return;
2541
2147 Primitive.TextureEntry tex = part.Shape.Textures; 2542 Primitive.TextureEntry tex = part.Shape.Textures;
2148 if (face >= 0 && face < GetNumberOfSides(part)) 2543 int nsides = GetNumberOfSides(part);
2544
2545 if (face >= 0 && face < nsides)
2149 { 2546 {
2150 Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); 2547 Primitive.TextureEntryFace texface = tex.CreateFace((uint)face);
2151 texface.OffsetU = (float)u; 2548 texface.OffsetU = (float)u;
@@ -2156,7 +2553,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2156 } 2553 }
2157 if (face == ScriptBaseClass.ALL_SIDES) 2554 if (face == ScriptBaseClass.ALL_SIDES)
2158 { 2555 {
2159 for (int i = 0; i < GetNumberOfSides(part); i++) 2556 for (int i = 0; i < nsides; i++)
2160 { 2557 {
2161 if (tex.FaceTextures[i] != null) 2558 if (tex.FaceTextures[i] != null)
2162 { 2559 {
@@ -2175,12 +2572,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2175 { 2572 {
2176 m_host.AddScriptLPS(1); 2573 m_host.AddScriptLPS(1);
2177 RotateTexture(m_host, rotation, face); 2574 RotateTexture(m_host, rotation, face);
2575 ScriptSleep(m_sleepMsOnRotateTexture);
2178 } 2576 }
2179 2577
2180 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2578 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
2181 { 2579 {
2580 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2581 return;
2582
2182 Primitive.TextureEntry tex = part.Shape.Textures; 2583 Primitive.TextureEntry tex = part.Shape.Textures;
2183 if (face >= 0 && face < GetNumberOfSides(part)) 2584 int nsides = GetNumberOfSides(part);
2585
2586 if (face >= 0 && face < nsides)
2184 { 2587 {
2185 Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); 2588 Primitive.TextureEntryFace texface = tex.CreateFace((uint)face);
2186 texface.Rotation = (float)rotation; 2589 texface.Rotation = (float)rotation;
@@ -2190,7 +2593,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2190 } 2593 }
2191 if (face == ScriptBaseClass.ALL_SIDES) 2594 if (face == ScriptBaseClass.ALL_SIDES)
2192 { 2595 {
2193 for (int i = 0; i < GetNumberOfSides(part); i++) 2596 for (int i = 0; i < nsides; i++)
2194 { 2597 {
2195 if (tex.FaceTextures[i] != null) 2598 if (tex.FaceTextures[i] != null)
2196 { 2599 {
@@ -2212,12 +2615,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2212 protected LSL_String GetTexture(SceneObjectPart part, int face) 2615 protected LSL_String GetTexture(SceneObjectPart part, int face)
2213 { 2616 {
2214 Primitive.TextureEntry tex = part.Shape.Textures; 2617 Primitive.TextureEntry tex = part.Shape.Textures;
2618 int nsides = GetNumberOfSides(part);
2619
2215 if (face == ScriptBaseClass.ALL_SIDES) 2620 if (face == ScriptBaseClass.ALL_SIDES)
2216 { 2621 {
2217 face = 0; 2622 face = 0;
2218 } 2623 }
2219 2624
2220 if (face >= 0 && face < GetNumberOfSides(part)) 2625 if (face >= 0 && face < nsides)
2221 { 2626 {
2222 Primitive.TextureEntryFace texface; 2627 Primitive.TextureEntryFace texface;
2223 texface = tex.GetFace((uint)face); 2628 texface = tex.GetFace((uint)face);
@@ -2248,6 +2653,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2248 m_host.AddScriptLPS(1); 2653 m_host.AddScriptLPS(1);
2249 2654
2250 SetPos(m_host, pos, true); 2655 SetPos(m_host, pos, true);
2656
2657 ScriptSleep(m_sleepMsOnSetPos);
2251 } 2658 }
2252 2659
2253 /// <summary> 2660 /// <summary>
@@ -2278,7 +2685,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2278 pos.x < -10.0 || // return FALSE if more than 10 meters into a west-adjacent region. 2685 pos.x < -10.0 || // return FALSE if more than 10 meters into a west-adjacent region.
2279 pos.x > (World.RegionInfo.RegionSizeX + 10) || // return FALSE if more than 10 meters into a east-adjacent region. 2686 pos.x > (World.RegionInfo.RegionSizeX + 10) || // return FALSE if more than 10 meters into a east-adjacent region.
2280 pos.y < -10.0 || // return FALSE if more than 10 meters into a south-adjacent region. 2687 pos.y < -10.0 || // return FALSE if more than 10 meters into a south-adjacent region.
2281 pos.y > (World.RegionInfo.RegionSizeY + 10) // return FALSE if more than 10 meters into a north-adjacent region. 2688 pos.y > (World.RegionInfo.RegionSizeY + 10) || // return FALSE if more than 10 meters into a north-adjacent region.
2689 pos.z > Constants.RegionHeight // return FALSE if altitude than 4096m
2282 ) 2690 )
2283 ) 2691 )
2284 { 2692 {
@@ -2317,7 +2725,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2317 return end; 2725 return end;
2318 } 2726 }
2319 2727
2320 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos) 2728 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos, bool adjust)
2321 { 2729 {
2322 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 2730 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2323 return fromPos; 2731 return fromPos;
@@ -2333,9 +2741,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2333 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2741 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2334 targetPos.z = ground; 2742 targetPos.z = ground;
2335 } 2743 }
2336 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); 2744 if (adjust)
2745 return SetPosAdjust(fromPos, targetPos);
2337 2746
2338 return real_vec; 2747 return targetPos;
2339 } 2748 }
2340 2749
2341 /// <summary> 2750 /// <summary>
@@ -2346,27 +2755,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2346 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2755 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2347 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2756 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2348 { 2757 {
2349 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2758 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted || part.ParentGroup.inTransit)
2759 return;
2760
2761
2350 LSL_Vector currentPos = GetPartLocalPos(part); 2762 LSL_Vector currentPos = GetPartLocalPos(part);
2763 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos, adjust);
2351 2764
2352 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2353 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2354 2765
2355 if (part.ParentGroup.RootPart == part) 2766 if (part.ParentGroup.RootPart == part)
2356 { 2767 {
2357 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2358 targetPos.z = ground;
2359 SceneObjectGroup parent = part.ParentGroup; 2768 SceneObjectGroup parent = part.ParentGroup;
2360 parent.UpdateGroupPosition(!adjust ? targetPos : 2769 if (!parent.IsAttachment && !World.Permissions.CanObjectEntry(parent, false, (Vector3)toPos))
2361 SetPosAdjust(currentPos, targetPos)); 2770 return;
2771 parent.UpdateGroupPosition((Vector3)toPos);
2362 } 2772 }
2363 else 2773 else
2364 { 2774 {
2365 part.OffsetPosition = !adjust ? targetPos : 2775 part.OffsetPosition = (Vector3)toPos;
2366 SetPosAdjust(currentPos, targetPos); 2776// SceneObjectGroup parent = part.ParentGroup;
2367 SceneObjectGroup parent = part.ParentGroup; 2777// parent.HasGroupChanged = true;
2368 parent.HasGroupChanged = true; 2778// parent.ScheduleGroupForTerseUpdate();
2369 parent.ScheduleGroupForTerseUpdate(); 2779 part.ScheduleTerseUpdate();
2370 } 2780 }
2371 } 2781 }
2372 2782
@@ -2395,13 +2805,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2395 else 2805 else
2396 { 2806 {
2397 if (part.ParentGroup.IsAttachment) 2807 if (part.ParentGroup.IsAttachment)
2398 {
2399 pos = part.AttachedPos; 2808 pos = part.AttachedPos;
2400 }
2401 else 2809 else
2402 {
2403 pos = part.AbsolutePosition; 2810 pos = part.AbsolutePosition;
2404 }
2405 } 2811 }
2406 2812
2407// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2813// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2414,7 +2820,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2414 m_host.AddScriptLPS(1); 2820 m_host.AddScriptLPS(1);
2415 2821
2416 // try to let this work as in SL... 2822 // try to let this work as in SL...
2417 if (m_host.ParentID == 0) 2823 if (m_host.ParentID == 0 || (m_host.ParentGroup != null && m_host == m_host.ParentGroup.RootPart))
2418 { 2824 {
2419 // special case: If we are root, rotate complete SOG to new rotation 2825 // special case: If we are root, rotate complete SOG to new rotation
2420 SetRot(m_host, rot); 2826 SetRot(m_host, rot);
@@ -2428,35 +2834,60 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2428 SetRot(m_host, rootPart.RotationOffset * (Quaternion)rot); 2834 SetRot(m_host, rootPart.RotationOffset * (Quaternion)rot);
2429 } 2835 }
2430 } 2836 }
2837
2838 ScriptSleep(m_sleepMsOnSetRot);
2431 } 2839 }
2432 2840
2433 public void llSetLocalRot(LSL_Rotation rot) 2841 public void llSetLocalRot(LSL_Rotation rot)
2434 { 2842 {
2435 m_host.AddScriptLPS(1); 2843 m_host.AddScriptLPS(1);
2436 SetRot(m_host, rot); 2844 SetRot(m_host, rot);
2845 ScriptSleep(m_sleepMsOnSetLocalRot);
2437 } 2846 }
2438 2847
2439 protected void SetRot(SceneObjectPart part, Quaternion rot) 2848 protected void SetRot(SceneObjectPart part, Quaternion rot)
2440 { 2849 {
2441 part.UpdateRotation(rot); 2850 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. 2851 return;
2443 2852
2444//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2853 bool isroot = (part == part.ParentGroup.RootPart);
2445// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2854 bool isphys;
2446 2855
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; 2856 PhysicsActor pa = part.PhysActor;
2455 2857
2456 if (pa != null && !pa.IsPhysical) 2858 // keep using physactor ideia of isphysical
2859 // it should be SOP ideia of that
2860 // not much of a issue with ubOde
2861 if (pa != null && pa.IsPhysical)
2862 isphys = true;
2863 else
2864 isphys = false;
2865
2866 // SL doesn't let scripts rotate root of physical linksets
2867 if (isroot && isphys)
2868 return;
2869
2870 part.UpdateRotation(rot);
2871
2872 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2873 // so do a nasty update of parts positions if is a root part rotation
2874 if (isroot && pa != null) // with if above implies non physical root part
2457 { 2875 {
2458 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2876 part.ParentGroup.ResetChildPrimPhysicsPositions();
2459 } 2877 }
2878 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2879 {
2880 // List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2881 List<ScenePresence> sittingavas = part.ParentGroup.GetSittingAvatars();
2882 if (sittingavas.Count > 0)
2883 {
2884 foreach (ScenePresence av in sittingavas)
2885 {
2886 if (isroot || part.LocalId == av.ParentID)
2887 av.SendTerseUpdateToAllClients();
2888 }
2889 }
2890 }
2460 } 2891 }
2461 2892
2462 /// <summary> 2893 /// <summary>
@@ -2473,6 +2904,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2473 2904
2474 m_host.AddScriptLPS(1); 2905 m_host.AddScriptLPS(1);
2475 Quaternion q = m_host.GetWorldRotation(); 2906 Quaternion q = m_host.GetWorldRotation();
2907
2908 if (m_host.ParentGroup != null && m_host.ParentGroup.AttachmentPoint != 0)
2909 {
2910 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2911 if (avatar != null)
2912 {
2913 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2914 q = avatar.CameraRotation * q; // Mouselook
2915 else
2916 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2917 }
2918 }
2919
2476 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2920 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2477 } 2921 }
2478 2922
@@ -2500,14 +2944,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2500 return new LSL_Rotation(q); 2944 return new LSL_Rotation(q);
2501 } 2945 }
2502 2946
2503 return new LSL_Rotation(part.GetWorldRotation()); 2947 q = part.GetWorldRotation();
2948 if (part.ParentGroup.AttachmentPoint != 0)
2949 {
2950 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2951 if (avatar != null)
2952 {
2953 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2954 q = avatar.CameraRotation * q; // Mouselook
2955 else
2956 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2957 }
2958 }
2959
2960 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2504 } 2961 }
2505 2962
2506 public LSL_Rotation llGetLocalRot() 2963 public LSL_Rotation llGetLocalRot()
2507 { 2964 {
2508 m_host.AddScriptLPS(1); 2965 return GetPartLocalRot(m_host);
2966 }
2509 2967
2510 return new LSL_Rotation(m_host.RotationOffset); 2968 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2969 {
2970 m_host.AddScriptLPS(1);
2971 Quaternion rot = part.RotationOffset;
2972 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2511 } 2973 }
2512 2974
2513 public void llSetForce(LSL_Vector force, int local) 2975 public void llSetForce(LSL_Vector force, int local)
@@ -2537,32 +2999,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2537 return force; 2999 return force;
2538 } 3000 }
2539 3001
2540 public void llSetVelocity(LSL_Vector velocity, int local) 3002 public void llSetVelocity(LSL_Vector vel, int local)
2541 { 3003 {
2542 m_host.AddScriptLPS(1); 3004 m_host.AddScriptLPS(1);
2543 3005 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2544 if (!m_host.ParentGroup.IsDeleted)
2545 {
2546 if (local != 0)
2547 velocity *= llGetRot();
2548
2549 m_host.ParentGroup.RootPart.Velocity = velocity;
2550 }
2551 } 3006 }
2552 3007
2553 public void llSetAngularVelocity(LSL_Vector angularVelocity, int local) 3008 public void llSetAngularVelocity(LSL_Vector avel, int local)
2554 { 3009 {
2555 m_host.AddScriptLPS(1); 3010 m_host.AddScriptLPS(1);
2556 3011 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2557 if (!m_host.ParentGroup.IsDeleted)
2558 {
2559 if (local != 0)
2560 angularVelocity *= llGetRot();
2561
2562 m_host.ParentGroup.RootPart.AngularVelocity = angularVelocity;
2563 }
2564 } 3012 }
2565
2566 public LSL_Integer llTarget(LSL_Vector position, double range) 3013 public LSL_Integer llTarget(LSL_Vector position, double range)
2567 { 3014 {
2568 m_host.AddScriptLPS(1); 3015 m_host.AddScriptLPS(1);
@@ -2613,16 +3060,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2613 m_host.ApplyImpulse(v, local != 0); 3060 m_host.ApplyImpulse(v, local != 0);
2614 } 3061 }
2615 3062
3063
2616 public void llApplyRotationalImpulse(LSL_Vector force, int local) 3064 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2617 { 3065 {
2618 m_host.AddScriptLPS(1); 3066 m_host.AddScriptLPS(1);
2619 m_host.ApplyAngularImpulse(force, local != 0); 3067 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2620 } 3068 }
2621 3069
2622 public void llSetTorque(LSL_Vector torque, int local) 3070 public void llSetTorque(LSL_Vector torque, int local)
2623 { 3071 {
2624 m_host.AddScriptLPS(1); 3072 m_host.AddScriptLPS(1);
2625 m_host.SetAngularImpulse(torque, local != 0); 3073 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2626 } 3074 }
2627 3075
2628 public LSL_Vector llGetTorque() 3076 public LSL_Vector llGetTorque()
@@ -2639,20 +3087,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2639 llSetTorque(torque, local); 3087 llSetTorque(torque, local);
2640 } 3088 }
2641 3089
3090
2642 public LSL_Vector llGetVel() 3091 public LSL_Vector llGetVel()
2643 { 3092 {
2644 m_host.AddScriptLPS(1); 3093 m_host.AddScriptLPS(1);
2645 3094
2646 Vector3 vel; 3095 Vector3 vel = Vector3.Zero;
2647 3096
2648 if (m_host.ParentGroup.IsAttachment) 3097 if (m_host.ParentGroup.IsAttachment)
2649 { 3098 {
2650 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 3099 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2651 vel = avatar.GetWorldVelocity(); 3100 if (avatar != null)
3101 vel = avatar.GetWorldVelocity();
2652 } 3102 }
2653 else 3103 else
2654 { 3104 {
2655 vel = m_host.Velocity; 3105 vel = m_host.ParentGroup.RootPart.Velocity;
2656 } 3106 }
2657 3107
2658 return new LSL_Vector(vel); 3108 return new LSL_Vector(vel);
@@ -2668,8 +3118,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2668 public LSL_Vector llGetOmega() 3118 public LSL_Vector llGetOmega()
2669 { 3119 {
2670 m_host.AddScriptLPS(1); 3120 m_host.AddScriptLPS(1);
2671 3121 Vector3 avel = m_host.AngularVelocity;
2672 return new LSL_Vector(m_host.AngularVelocity); 3122 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2673 } 3123 }
2674 3124
2675 public LSL_Float llGetTimeOfDay() 3125 public LSL_Float llGetTimeOfDay()
@@ -2687,22 +3137,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2687 public LSL_Float llGetTime() 3137 public LSL_Float llGetTime()
2688 { 3138 {
2689 m_host.AddScriptLPS(1); 3139 m_host.AddScriptLPS(1);
2690 TimeSpan ScriptTime = DateTime.Now - m_timer; 3140 double ScriptTime = Util.GetTimeStampMS() - m_timer;
2691 return (double)(ScriptTime.TotalMilliseconds / 1000); 3141 return (float)Math.Round((ScriptTime / 1000.0), 3);
2692 } 3142 }
2693 3143
2694 public void llResetTime() 3144 public void llResetTime()
2695 { 3145 {
2696 m_host.AddScriptLPS(1); 3146 m_host.AddScriptLPS(1);
2697 m_timer = DateTime.Now; 3147 m_timer = Util.GetTimeStampMS();
2698 } 3148 }
2699 3149
2700 public LSL_Float llGetAndResetTime() 3150 public LSL_Float llGetAndResetTime()
2701 { 3151 {
2702 m_host.AddScriptLPS(1); 3152 m_host.AddScriptLPS(1);
2703 TimeSpan ScriptTime = DateTime.Now - m_timer; 3153 double now = Util.GetTimeStampMS();
2704 m_timer = DateTime.Now; 3154 double ScriptTime = now - m_timer;
2705 return (double)(ScriptTime.TotalMilliseconds / 1000); 3155 m_timer = now;
3156 return (float)Math.Round((ScriptTime / 1000.0), 3);
2706 } 3157 }
2707 3158
2708 public void llSound(string sound, double volume, int queue, int loop) 3159 public void llSound(string sound, double volume, int queue, int loop)
@@ -2722,8 +3173,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2722 { 3173 {
2723 m_SoundModule.SendSound( 3174 m_SoundModule.SendSound(
2724 m_host.UUID, 3175 m_host.UUID,
2725 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), 3176 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound),
2726 volume, false, m_host.SoundQueueing ? (byte)SoundFlags.Queue : (byte)SoundFlags.None, 3177 volume, false, 0,
2727 0, false, false); 3178 0, false, false);
2728 } 3179 }
2729 } 3180 }
@@ -2734,7 +3185,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2734 if (m_SoundModule != null) 3185 if (m_SoundModule != null)
2735 { 3186 {
2736 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), 3187 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound),
2737 volume, 20, false); 3188 volume, 20, false,false);
2738 } 3189 }
2739 } 3190 }
2740 3191
@@ -2744,16 +3195,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2744 if (m_SoundModule != null) 3195 if (m_SoundModule != null)
2745 { 3196 {
2746 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), 3197 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound),
2747 volume, 20, true); 3198 volume, 20, true, false);
2748 } 3199 }
2749 } 3200 }
2750 3201
2751 public void llLoopSoundSlave(string sound, double volume) 3202 public void llLoopSoundSlave(string sound, double volume)
2752 { 3203 {
2753 m_host.AddScriptLPS(1); 3204 m_host.AddScriptLPS(1);
2754 lock (m_host.ParentGroup.LoopSoundSlavePrims) 3205 if (m_SoundModule != null)
2755 { 3206 {
2756 m_host.ParentGroup.LoopSoundSlavePrims.Add(m_host); 3207 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound),
3208 volume, 20, false, true);
2757 } 3209 }
2758 } 3210 }
2759 3211
@@ -2795,6 +3247,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2795 m_host.AddScriptLPS(1); 3247 m_host.AddScriptLPS(1);
2796 if (m_SoundModule != null) 3248 if (m_SoundModule != null)
2797 m_SoundModule.PreloadSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), 0); 3249 m_SoundModule.PreloadSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), 0);
3250 ScriptSleep(m_sleepMsOnPreloadSound);
2798 } 3251 }
2799 3252
2800 /// <summary> 3253 /// <summary>
@@ -3027,7 +3480,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3027 return src.ToLower(); 3480 return src.ToLower();
3028 } 3481 }
3029 3482
3030 public void llGiveMoney(string destination, int amount) 3483 public LSL_Integer llGiveMoney(string destination, int amount)
3031 { 3484 {
3032 Util.FireAndForget(x => 3485 Util.FireAndForget(x =>
3033 { 3486 {
@@ -3058,69 +3511,86 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3058 return; 3511 return;
3059 } 3512 }
3060 3513
3514 string reason;
3061 money.ObjectGiveMoney( 3515 money.ObjectGiveMoney(
3062 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3516
3517 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero, out reason);
3063 }, null, "LSL_Api.llGiveMoney"); 3518 }, null, "LSL_Api.llGiveMoney");
3519
3520 return 0;
3064 } 3521 }
3065 3522
3066 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 3523 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
3067 { 3524 {
3068 m_host.AddScriptLPS(1); 3525 m_host.AddScriptLPS(1);
3069 Deprecated("llMakeExplosion", "Use llParticleSystem instead"); 3526 Deprecated("llMakeExplosion", "Use llParticleSystem instead");
3527 ScriptSleep(m_sleepMsOnMakeExplosion);
3070 } 3528 }
3071 3529
3072 public void llMakeFountain(int particles, double scale, double vel, double lifetime, double arc, int bounce, string texture, LSL_Vector offset, double bounce_offset) 3530 public void llMakeFountain(int particles, double scale, double vel, double lifetime, double arc, int bounce, string texture, LSL_Vector offset, double bounce_offset)
3073 { 3531 {
3074 m_host.AddScriptLPS(1); 3532 m_host.AddScriptLPS(1);
3075 Deprecated("llMakeFountain", "Use llParticleSystem instead"); 3533 Deprecated("llMakeFountain", "Use llParticleSystem instead");
3534 ScriptSleep(m_sleepMsOnMakeFountain);
3076 } 3535 }
3077 3536
3078 public void llMakeSmoke(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 3537 public void llMakeSmoke(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
3079 { 3538 {
3080 m_host.AddScriptLPS(1); 3539 m_host.AddScriptLPS(1);
3081 Deprecated("llMakeSmoke", "Use llParticleSystem instead"); 3540 Deprecated("llMakeSmoke", "Use llParticleSystem instead");
3541 ScriptSleep(m_sleepMsOnMakeSmoke);
3082 } 3542 }
3083 3543
3084 public void llMakeFire(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 3544 public void llMakeFire(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
3085 { 3545 {
3086 m_host.AddScriptLPS(1); 3546 m_host.AddScriptLPS(1);
3087 Deprecated("llMakeFire", "Use llParticleSystem instead"); 3547 Deprecated("llMakeFire", "Use llParticleSystem instead");
3548 ScriptSleep(m_sleepMsOnMakeFire);
3088 } 3549 }
3089 3550
3090 public void llRezAtRoot(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param) 3551 public void llRezAtRoot(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param)
3091 { 3552 {
3553 doObjectRez(inventory, pos, vel, rot, param, true);
3554 }
3555
3556 public void doObjectRez(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param, bool atRoot)
3557 {
3092 m_host.AddScriptLPS(1); 3558 m_host.AddScriptLPS(1);
3559 if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s))
3560 return;
3093 3561
3094 Util.FireAndForget(x => 3562 float dist = (float)llVecDist(llGetPos(), pos);
3095 {
3096 if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s))
3097 return;
3098 3563
3099 float dist = (float)llVecDist(llGetPos(), pos); 3564 if (dist > m_ScriptDistanceFactor * 10.0f)
3565 return;
3100 3566
3101 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(inventory); 3567 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(inventory);
3102 3568
3103 if (item == null) 3569 if (item == null)
3104 { 3570 {
3105 Error("llRezAtRoot", "Can't find object '" + inventory + "'"); 3571 Error("llRez(AtRoot/Object)", "Can't find object '" + inventory + "'");
3106 return; 3572 return;
3107 } 3573 }
3108 3574
3109 if (item.InvType != (int)InventoryType.Object) 3575 if (item.InvType != (int)InventoryType.Object)
3110 { 3576 {
3111 Error("llRezAtRoot", "Can't create requested object; object is missing from database"); 3577 Error("llRez(AtRoot/Object)", "Can't create requested object; object is missing from database");
3112 return; 3578 return;
3113 } 3579 }
3114 3580
3115 // need the magnitude later 3581 Util.FireAndForget(x =>
3116 // float velmag = (float)Util.GetMagnitude(llvel); 3582 {
3117 3583
3118 List<SceneObjectGroup> new_groups = World.RezObject(m_host, item, pos, rot, vel, param); 3584 Quaternion wrot = rot;
3585 wrot.Normalize();
3586 List<SceneObjectGroup> new_groups = World.RezObject(m_host, item, pos, wrot, vel, param, atRoot);
3119 3587
3120 // If either of these are null, then there was an unknown error. 3588 // If either of these are null, then there was an unknown error.
3121 if (new_groups == null) 3589 if (new_groups == null)
3122 return; 3590 return;
3123 3591
3592 bool notAttachment = !m_host.ParentGroup.IsAttachment;
3593
3124 foreach (SceneObjectGroup group in new_groups) 3594 foreach (SceneObjectGroup group in new_groups)
3125 { 3595 {
3126 // objects rezzed with this method are die_at_edge by default. 3596 // objects rezzed with this method are die_at_edge by default.
@@ -3134,58 +3604,79 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3134 group.RootPart.UUID.ToString()) }, 3604 group.RootPart.UUID.ToString()) },
3135 new DetectParams[0])); 3605 new DetectParams[0]));
3136 3606
3137 float groupmass = group.GetMass(); 3607 if (notAttachment)
3608 {
3609 float groupmass = group.GetMass();
3138 3610
3139 PhysicsActor pa = group.RootPart.PhysActor; 3611 PhysicsActor pa = group.RootPart.PhysActor;
3140 3612
3141 //Recoil. 3613 //Recoil.
3142 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3614 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
3143 {
3144 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
3145 if (recoil != Vector3.Zero)
3146 { 3615 {
3147 llApplyImpulse(recoil, 0); 3616 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
3617 if (recoil != Vector3.Zero)
3618 {
3619 llApplyImpulse(recoil, 0);
3620 }
3148 } 3621 }
3149 } 3622 }
3150 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3623 }
3151 } 3624 }, null, "LSL_Api.doObjectRez");
3152 }, null, "LSL_Api.llRezAtRoot"); 3625
3626 //ScriptSleep((int)((groupmass * velmag) / 10));
3627 ScriptSleep(m_sleepMsOnRezAtRoot);
3153 } 3628 }
3154 3629
3155 public void llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param) 3630 public void llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param)
3156 { 3631 {
3157 llRezAtRoot(inventory, pos, vel, rot, param); 3632 doObjectRez(inventory, pos, vel, rot, param, false);
3158 } 3633 }
3159 3634
3160 public void llLookAt(LSL_Vector target, double strength, double damping) 3635 public void llLookAt(LSL_Vector target, double strength, double damping)
3161 { 3636 {
3162 m_host.AddScriptLPS(1); 3637 m_host.AddScriptLPS(1);
3163 // Determine where we are looking from 3638
3639 // Get the normalized vector to the target
3164 LSL_Vector from = llGetPos(); 3640 LSL_Vector from = llGetPos();
3165 3641
3166 // normalized direction to target 3642 // normalized direction to target
3167 LSL_Vector dir = llVecNorm(target - from); 3643 LSL_Vector dir = llVecNorm(target - from);
3644
3168 // use vertical to help compute left axis 3645 // use vertical to help compute left axis
3169 LSL_Vector up = new LSL_Vector(0.0, 0.0, 1.0); 3646// LSL_Vector up = new LSL_Vector(0.0, 0.0, 1.0);
3170 // find normalized left axis parallel to horizon 3647 // find normalized left axis parallel to horizon
3171 LSL_Vector left = llVecNorm(LSL_Vector.Cross(up, dir)); 3648// LSL_Vector left = llVecNorm(LSL_Vector.Cross(up, dir));
3649
3650 LSL_Vector left = new LSL_Vector(-dir.y, dir.x, 0.0f);
3651 left = llVecNorm(left);
3172 // make up orthogonal to left and dir 3652 // make up orthogonal to left and dir
3173 up = LSL_Vector.Cross(dir, left); 3653 LSL_Vector up = LSL_Vector.Cross(dir, left);
3174 3654
3175 // compute rotation based on orthogonal axes 3655 // compute rotation based on orthogonal axes
3656 // 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); 3657 LSL_Rotation rot = new LSL_Rotation(0.0, 0.707107, 0.0, 0.707107) * llAxes2Rot(dir, left, up);
3177 3658
3178 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply 3659 SceneObjectGroup sog = m_host.ParentGroup;
3179 // set the rotation of the object, copy that behavior 3660 if(sog == null || sog.IsDeleted)
3180 PhysicsActor pa = m_host.PhysActor; 3661 return;
3181 3662
3182 if (m_host.ParentGroup.IsAttachment || strength == 0 || pa == null || !pa.IsPhysical) 3663 if (!sog.UsesPhysics || sog.IsAttachment)
3183 { 3664 {
3184 llSetRot(rot); 3665 // Do nothing if either value is 0 (this has been checked in SL)
3666 if (strength <= 0.0 || damping <= 0.0)
3667 return;
3668
3669 llSetLocalRot(rot);
3185 } 3670 }
3186 else 3671 else
3187 { 3672 {
3188 m_host.StartLookAt(rot, (float)strength, (float)damping); 3673 if (strength == 0)
3674 {
3675 llSetLocalRot(rot);
3676 return;
3677 }
3678
3679 sog.StartLookAt(rot, (float)strength, (float)damping);
3189 } 3680 }
3190 } 3681 }
3191 3682
@@ -3231,22 +3722,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3231 } 3722 }
3232 else 3723 else
3233 { 3724 {
3234 if (m_host.IsRoot) 3725 // new SL always returns object mass
3235 { 3726// if (m_host.IsRoot)
3727// {
3236 return m_host.ParentGroup.GetMass(); 3728 return m_host.ParentGroup.GetMass();
3237 } 3729// }
3238 else 3730// else
3239 { 3731// {
3240 return m_host.GetMass(); 3732// return m_host.GetMass();
3241 } 3733// }
3242 } 3734 }
3243 } 3735 }
3244 3736
3245 public LSL_Float llGetMassMKS() 3737 public LSL_Float llGetMassMKS()
3246 { 3738 {
3247 // this is what the wiki says it does! 3739 return 100f * llGetMass();
3248 // http://wiki.secondlife.com/wiki/LlGetMassMKS
3249 return llGetMass() * 100.0;
3250 } 3740 }
3251 3741
3252 public void llCollisionFilter(string name, string id, int accept) 3742 public void llCollisionFilter(string name, string id, int accept)
@@ -3296,7 +3786,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3296 { 3786 {
3297 // Unregister controls from Presence 3787 // Unregister controls from Presence
3298 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3788 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3299 // Remove Take Control permission. 3789 // Remove Take Control permission.
3300 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3790 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3301 } 3791 }
3302 } 3792 }
@@ -3355,9 +3845,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3355 { 3845 {
3356 m_host.AddScriptLPS(1); 3846 m_host.AddScriptLPS(1);
3357 3847
3358// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3359// return;
3360
3361 if (m_item.PermsGranter != m_host.OwnerID) 3848 if (m_item.PermsGranter != m_host.OwnerID)
3362 return; 3849 return;
3363 3850
@@ -3401,6 +3888,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3401 public void llInstantMessage(string user, string message) 3888 public void llInstantMessage(string user, string message)
3402 { 3889 {
3403 m_host.AddScriptLPS(1); 3890 m_host.AddScriptLPS(1);
3891 UUID result;
3892 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3893 {
3894 Error("llInstantMessage","An invalid key was passed to llInstantMessage");
3895 ScriptSleep(2000);
3896 return;
3897 }
3404 3898
3405 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3899 // 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, 3900 // InstantMessageModule.OnInstantMessage searches through a list of scenes for a client matching the toAgent,
@@ -3411,31 +3905,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3411 3905
3412 // TODO: figure out values for client, fromSession, and imSessionID 3906 // 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()); 3907 // client.SendInstantMessage(m_host.UUID, fromSession, message, user, imSessionID, m_host.Name, AgentManager.InstantMessageDialog.MessageFromAgent, (uint)Util.UnixTimeSinceEpoch());
3908 UUID friendTransactionID = UUID.Random();
3909
3910 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3414 3911
3415 GridInstantMessage msg = new GridInstantMessage(); 3912 GridInstantMessage msg = new GridInstantMessage();
3416 msg.fromAgentID = new Guid(m_host.OwnerID.ToString()); // fromAgentID.Guid; 3913 msg.fromAgentID = new Guid(m_host.OwnerID.ToString()); // fromAgentID.Guid;
3417 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3914 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 3915 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); 3916 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3420// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3917 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
3421 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3918
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) 3919 if (message != null && message.Length > 1024)
3432 msg.message = message.Substring(0, 1024); 3920 msg.message = message.Substring(0, 1024);
3433 else 3921 else
3434 msg.message = message; 3922 msg.message = message;
3435 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3923 msg.dialog = (byte)19; // MessageFromObject
3436 msg.fromGroup = false;// fromGroup; 3924 msg.fromGroup = false;// fromGroup;
3437 msg.offline = (byte)0; //offline; 3925 msg.offline = (byte)0; //offline;
3438 msg.ParentEstateID = 0; //ParentEstateID; 3926 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3439 msg.Position = new Vector3(m_host.AbsolutePosition); 3927 msg.Position = new Vector3(m_host.AbsolutePosition);
3440 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3928 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid;
3441 3929
@@ -3452,6 +3940,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3452 { 3940 {
3453 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 3941 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
3454 } 3942 }
3943
3944 ScriptSleep(m_sleepMsOnInstantMessage);
3455 } 3945 }
3456 3946
3457 public void llEmail(string address, string subject, string message) 3947 public void llEmail(string address, string subject, string message)
@@ -3489,6 +3979,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3489 } 3979 }
3490 3980
3491 emailModule.SendEmail(m_host.UUID, address, subject, message); 3981 emailModule.SendEmail(m_host.UUID, address, subject, message);
3982 ScriptSleep(m_sleepMsOnEmail);
3492 } 3983 }
3493 3984
3494 public void llGetNextEmail(string address, string subject) 3985 public void llGetNextEmail(string address, string subject)
@@ -3551,25 +4042,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3551 { 4042 {
3552 m_host.AddScriptLPS(1); 4043 m_host.AddScriptLPS(1);
3553 4044
3554 if (m_host.PhysActor != null) 4045 PIDHoverType hoverType = PIDHoverType.Ground;
4046 if (water != 0)
3555 { 4047 {
3556 PIDHoverType hoverType = PIDHoverType.Ground; 4048 hoverType = PIDHoverType.GroundAndWater;
3557 if (water != 0)
3558 {
3559 hoverType = PIDHoverType.GroundAndWater;
3560 }
3561
3562 m_host.SetHoverHeight((float)height, hoverType, (float)tau);
3563 } 4049 }
4050 m_host.SetHoverHeight((float)height, hoverType, (float)tau);
3564 } 4051 }
3565 4052
3566 public void llStopHover() 4053 public void llStopHover()
3567 { 4054 {
3568 m_host.AddScriptLPS(1); 4055 m_host.AddScriptLPS(1);
3569 if (m_host.PhysActor != null) 4056 m_host.SetHoverHeight(0f, PIDHoverType.Ground, 0f);
3570 {
3571 m_host.SetHoverHeight(0f, PIDHoverType.Ground, 0f);
3572 }
3573 } 4057 }
3574 4058
3575 public void llMinEventDelay(double delay) 4059 public void llMinEventDelay(double delay)
@@ -3598,15 +4082,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3598 4082
3599 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply 4083 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
3600 // set the rotation of the object, copy that behavior 4084 // set the rotation of the object, copy that behavior
3601 PhysicsActor pa = m_host.PhysActor; 4085 SceneObjectGroup sog = m_host.ParentGroup;
4086 if(sog == null || sog.IsDeleted)
4087 return;
3602 4088
3603 if (strength == 0 || pa == null || !pa.IsPhysical) 4089 if (strength == 0 || !sog.UsesPhysics || sog.IsAttachment)
3604 { 4090 {
3605 llSetLocalRot(target); 4091 llSetLocalRot(target);
3606 } 4092 }
3607 else 4093 else
3608 { 4094 {
3609 m_host.RotLookAt(target, (float)strength, (float)damping); 4095 sog.RotLookAt(target, (float)strength, (float)damping);
3610 } 4096 }
3611 } 4097 }
3612 4098
@@ -3735,7 +4221,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3735 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 4221 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3736 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 4222 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3737 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 4223 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3738 ScriptBaseClass.PERMISSION_ATTACH; 4224 ScriptBaseClass.PERMISSION_ATTACH |
4225 ScriptBaseClass.PERMISSION_OVERRIDE_ANIMATIONS;
3739 } 4226 }
3740 else 4227 else
3741 { 4228 {
@@ -3752,15 +4239,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3752 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 4239 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3753 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 4240 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3754 } 4241 }
4242 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
4243 {
4244 implicitPerms = perm;
4245 }
3755 } 4246 }
3756 4247
3757 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 4248 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3758 { 4249 {
3759 lock (m_host.TaskInventory) 4250 m_host.TaskInventory.LockItemsForWrite(true);
3760 { 4251 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3761 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 4252 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3762 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 4253 m_host.TaskInventory.LockItemsForWrite(false);
3763 }
3764 4254
3765 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 4255 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3766 "run_time_permissions", new Object[] { 4256 "run_time_permissions", new Object[] {
@@ -3771,7 +4261,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3771 } 4261 }
3772 4262
3773 ScenePresence presence = World.GetScenePresence(agentID); 4263 ScenePresence presence = World.GetScenePresence(agentID);
3774 4264
3775 if (presence != null) 4265 if (presence != null)
3776 { 4266 {
3777 // If permissions are being requested from an NPC and were not implicitly granted above then 4267 // If permissions are being requested from an NPC and were not implicitly granted above then
@@ -3804,11 +4294,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3804 4294
3805 if (!m_waitingForScriptAnswer) 4295 if (!m_waitingForScriptAnswer)
3806 { 4296 {
3807 lock (m_host.TaskInventory) 4297 m_host.TaskInventory.LockItemsForWrite(true);
3808 { 4298 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3809 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 4299 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3810 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 4300 m_host.TaskInventory.LockItemsForWrite(false);
3811 }
3812 4301
3813 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 4302 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3814 m_waitingForScriptAnswer=true; 4303 m_waitingForScriptAnswer=true;
@@ -3837,14 +4326,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3837 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 4326 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3838 llReleaseControls(); 4327 llReleaseControls();
3839 4328
3840 lock (m_host.TaskInventory) 4329 m_host.TaskInventory.LockItemsForWrite(true);
3841 { 4330 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3842 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 4331 m_host.TaskInventory.LockItemsForWrite(false);
3843 }
3844 4332
3845 m_ScriptEngine.PostScriptEvent( 4333 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3846 m_item.ItemID, 4334 "run_time_permissions", new Object[] {
3847 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 4335 new LSL_Integer(answer) },
4336 new DetectParams[0]));
3848 } 4337 }
3849 4338
3850 public LSL_String llGetPermissionsKey() 4339 public LSL_String llGetPermissionsKey()
@@ -3883,15 +4372,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3883 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 4372 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3884 { 4373 {
3885 List<SceneObjectPart> parts = GetLinkParts(linknumber); 4374 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3886 4375 if (parts.Count > 0)
3887 foreach (SceneObjectPart part in parts) 4376 {
3888 part.SetFaceColorAlpha(face, color, null); 4377 try
4378 {
4379 foreach (SceneObjectPart part in parts)
4380 part.SetFaceColorAlpha(face, color, null);
4381 }
4382 finally { }
4383 }
3889 } 4384 }
3890 4385
3891 public void llCreateLink(string target, int parent) 4386 public void llCreateLink(string target, int parent)
3892 { 4387 {
3893 m_host.AddScriptLPS(1); 4388 m_host.AddScriptLPS(1);
3894 4389
4390 UUID targetID;
4391
4392 if (!UUID.TryParse(target, out targetID))
4393 return;
4394
3895 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 4395 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3896 && !m_automaticLinkPermission) 4396 && !m_automaticLinkPermission)
3897 { 4397 {
@@ -3907,9 +4407,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3907 UUID targetID; 4407 UUID targetID;
3908 4408
3909 if (!UUID.TryParse(target, out targetID)) 4409 if (!UUID.TryParse(target, out targetID))
3910 return; 4410 return;
3911 4411
3912 SceneObjectPart targetPart = World.GetSceneObjectPart((UUID)targetID); 4412 SceneObjectPart targetPart = World.GetSceneObjectPart((UUID)targetID);
4413 if (targetPart == null)
4414 return;
3913 4415
3914 if (targetPart.ParentGroup.AttachmentPoint != 0) 4416 if (targetPart.ParentGroup.AttachmentPoint != 0)
3915 return; // Fail silently if attached 4417 return; // Fail silently if attached
@@ -3919,24 +4421,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3919 4421
3920 SceneObjectGroup parentPrim = null, childPrim = null; 4422 SceneObjectGroup parentPrim = null, childPrim = null;
3921 4423
3922 if (targetPart != null) 4424 if (parent != 0)
3923 { 4425 {
3924 if (parent != 0) 4426 parentPrim = m_host.ParentGroup;
3925 { 4427 childPrim = targetPart.ParentGroup;
3926 parentPrim = m_host.ParentGroup; 4428 }
3927 childPrim = targetPart.ParentGroup; 4429 else
3928 } 4430 {
3929 else 4431 parentPrim = targetPart.ParentGroup;
3930 { 4432 childPrim = m_host.ParentGroup;
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 } 4433 }
3939 4434
4435 // Required for linking
4436 childPrim.RootPart.ClearUpdateSchedule();
4437 parentPrim.LinkToGroup(childPrim, true);
4438
4439
3940 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4440 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3941 parentPrim.RootPart.CreateSelected = true; 4441 parentPrim.RootPart.CreateSelected = true;
3942 parentPrim.HasGroupChanged = true; 4442 parentPrim.HasGroupChanged = true;
@@ -3949,6 +4449,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3949 4449
3950 if (client != null) 4450 if (client != null)
3951 parentPrim.SendPropertiesToClient(client); 4451 parentPrim.SendPropertiesToClient(client);
4452
4453 ScriptSleep(m_sleepMsOnCreateLink);
3952 } 4454 }
3953 4455
3954 public void llBreakLink(int linknum) 4456 public void llBreakLink(int linknum)
@@ -4005,10 +4507,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4005 // Restructuring Multiple Prims. 4507 // Restructuring Multiple Prims.
4006 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4508 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
4007 parts.Remove(parentPrim.RootPart); 4509 parts.Remove(parentPrim.RootPart);
4008 foreach (SceneObjectPart part in parts) 4510 if (parts.Count > 0)
4009 { 4511 {
4010 parentPrim.DelinkFromGroup(part.LocalId, true); 4512 try
4011 } 4513 {
4514 foreach (SceneObjectPart part in parts)
4515 {
4516 parentPrim.DelinkFromGroup(part.LocalId, true);
4517 }
4518 }
4519 finally { }
4520 }
4521
4012 parentPrim.HasGroupChanged = true; 4522 parentPrim.HasGroupChanged = true;
4013 parentPrim.ScheduleGroupForFullUpdate(); 4523 parentPrim.ScheduleGroupForFullUpdate();
4014 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4524 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -4017,12 +4527,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4017 { 4527 {
4018 SceneObjectPart newRoot = parts[0]; 4528 SceneObjectPart newRoot = parts[0];
4019 parts.Remove(newRoot); 4529 parts.Remove(newRoot);
4020 foreach (SceneObjectPart part in parts) 4530
4531 try
4021 { 4532 {
4022 // Required for linking 4533 foreach (SceneObjectPart part in parts)
4023 part.ClearUpdateSchedule(); 4534 {
4024 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4535 part.ClearUpdateSchedule();
4536 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4537 }
4025 } 4538 }
4539 finally { }
4540
4026 newRoot.ParentGroup.HasGroupChanged = true; 4541 newRoot.ParentGroup.HasGroupChanged = true;
4027 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4542 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
4028 } 4543 }
@@ -4043,13 +4558,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4043 { 4558 {
4044 m_host.AddScriptLPS(1); 4559 m_host.AddScriptLPS(1);
4045 4560
4046 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 4561 TaskInventoryItem item = m_item;
4562
4563 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4047 && !m_automaticLinkPermission) 4564 && !m_automaticLinkPermission)
4048 { 4565 {
4049 Error("llBreakAllLinks", "PERMISSION_CHANGE_LINKS permission not set"); 4566 Error("llBreakAllLinks","Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4050 return; 4567 return;
4051 } 4568 }
4052
4053 BreakAllLinks(); 4569 BreakAllLinks();
4054 } 4570 }
4055 4571
@@ -4074,13 +4590,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4074 public LSL_String llGetLinkKey(int linknum) 4590 public LSL_String llGetLinkKey(int linknum)
4075 { 4591 {
4076 m_host.AddScriptLPS(1); 4592 m_host.AddScriptLPS(1);
4593 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
4594 if (part != null)
4595 {
4596 return part.UUID.ToString();
4597 }
4598 else
4599 {
4600 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4601 {
4602 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4077 4603
4078 ISceneEntity entity = GetLinkEntity(m_host, linknum); 4604 if (linknum < 0)
4605 return UUID.Zero.ToString();
4079 4606
4080 if (entity != null) 4607 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4081 return entity.UUID.ToString(); 4608 if (avatars.Count > linknum)
4082 else 4609 {
4083 return ScriptBaseClass.NULL_KEY; 4610 return avatars[linknum].UUID.ToString();
4611 }
4612 }
4613 return UUID.Zero.ToString();
4614 }
4084 } 4615 }
4085 4616
4086 /// <summary> 4617 /// <summary>
@@ -4139,17 +4670,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4139 m_host.AddScriptLPS(1); 4670 m_host.AddScriptLPS(1);
4140 int count = 0; 4671 int count = 0;
4141 4672
4142 lock (m_host.TaskInventory) 4673 m_host.TaskInventory.LockItemsForRead(true);
4674 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4143 { 4675 {
4144 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4676 if (inv.Value.Type == type || type == -1)
4145 { 4677 {
4146 if (inv.Value.Type == type || type == -1) 4678 count = count + 1;
4147 {
4148 count = count + 1;
4149 }
4150 } 4679 }
4151 } 4680 }
4152 4681
4682 m_host.TaskInventory.LockItemsForRead(false);
4153 return count; 4683 return count;
4154 } 4684 }
4155 4685
@@ -4158,16 +4688,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4158 m_host.AddScriptLPS(1); 4688 m_host.AddScriptLPS(1);
4159 ArrayList keys = new ArrayList(); 4689 ArrayList keys = new ArrayList();
4160 4690
4161 lock (m_host.TaskInventory) 4691 m_host.TaskInventory.LockItemsForRead(true);
4692 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4162 { 4693 {
4163 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4694 if (inv.Value.Type == type || type == -1)
4164 { 4695 {
4165 if (inv.Value.Type == type || type == -1) 4696 keys.Add(inv.Value.Name);
4166 {
4167 keys.Add(inv.Value.Name);
4168 }
4169 } 4697 }
4170 } 4698 }
4699 m_host.TaskInventory.LockItemsForRead(false);
4171 4700
4172 if (keys.Count == 0) 4701 if (keys.Count == 0)
4173 { 4702 {
@@ -4237,35 +4766,49 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4237 } 4766 }
4238 } 4767 }
4239 } 4768 }
4769
4240 // destination is an avatar 4770 // destination is an avatar
4241 string message; 4771 string message;
4242 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId, out message); 4772 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId, out message);
4243 4773
4244 if (agentItem == null) 4774 if (agentItem == null)
4245 { 4775 {
4246 llSay(0, message); 4776 llSay(0, message);
4247 return; 4777 return;
4248 } 4778 }
4249 4779
4250 if (m_TransferModule != null) 4780 byte[] bucket = new byte[1];
4251 { 4781 bucket[0] = (byte)item.Type;
4252 byte[] bucket = new byte[1]; 4782 //byte[] objBytes = agentItem.ID.GetBytes();
4253 bucket[0] = (byte)item.Type; 4783 //Array.Copy(objBytes, 0, bucket, 1, 16);
4784
4785 GridInstantMessage msg = new GridInstantMessage(World,
4786 m_host.OwnerID, m_host.Name, destId,
4787 (byte)InstantMessageDialog.TaskInventoryOffered,
4788 false, item.Name+". "+m_host.Name+" is located at "+
4789 World.RegionInfo.RegionName+" "+
4790 m_host.AbsolutePosition.ToString(),
4791 agentItem.ID, true, m_host.AbsolutePosition,
4792 bucket, true);
4254 4793
4255 GridInstantMessage msg = new GridInstantMessage(World, 4794 ScenePresence sp;
4256 m_host.OwnerID, m_host.Name, destId,
4257 (byte)InstantMessageDialog.TaskInventoryOffered,
4258 false, item.Name+". "+m_host.Name+" is located at "+
4259 World.RegionInfo.RegionName+" "+
4260 m_host.AbsolutePosition.ToString(),
4261 agentItem.ID, true, m_host.AbsolutePosition,
4262 bucket, true);
4263 4795
4264 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4796 if (World.TryGetScenePresence(destId, out sp))
4797 {
4798 sp.ControllingClient.SendInstantMessage(msg);
4799 }
4800 else
4801 {
4802 if (m_TransferModule != null)
4803 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4265 } 4804 }
4805
4806 //This delay should only occur when giving inventory to avatars.
4807 ScriptSleep(m_sleepMsOnGiveInventory);
4266 } 4808 }
4267 } 4809 }
4268 4810
4811 [DebuggerNonUserCode]
4269 public void llRemoveInventory(string name) 4812 public void llRemoveInventory(string name)
4270 { 4813 {
4271 m_host.AddScriptLPS(1); 4814 m_host.AddScriptLPS(1);
@@ -4285,20 +4828,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4285 { 4828 {
4286 m_host.AddScriptLPS(1); 4829 m_host.AddScriptLPS(1);
4287 Vector3 av3 = Util.Clip(color, 0.0f, 1.0f); 4830 Vector3 av3 = Util.Clip(color, 0.0f, 1.0f);
4288 if (text.Length > 254)
4289 text = text.Remove(254);
4290
4291 byte[] data; 4831 byte[] data;
4292 do 4832 data = Util.StringToBytes256(text);
4293 { 4833 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)); 4834 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 } 4835 }
4303 4836
4304 public LSL_Float llWater(LSL_Vector offset) 4837 public LSL_Float llWater(LSL_Vector offset)
@@ -4320,14 +4853,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4320 { 4853 {
4321 m_host.AddScriptLPS(1); 4854 m_host.AddScriptLPS(1);
4322 4855
4323 UUID uuid = (UUID)id; 4856 UUID uuid;
4324 PresenceInfo pinfo = null; 4857 if (UUID.TryParse(id, out uuid))
4325 UserAccount account;
4326
4327 UserInfoCacheEntry ce;
4328
4329 lock (m_userInfoCache)
4330 { 4858 {
4859 PresenceInfo pinfo = null;
4860 UserAccount account;
4861
4862 UserInfoCacheEntry ce;
4331 if (!m_userInfoCache.TryGetValue(uuid, out ce)) 4863 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4332 { 4864 {
4333 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4865 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
@@ -4353,7 +4885,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4353 ce.time = Util.EnvironmentTickCount(); 4885 ce.time = Util.EnvironmentTickCount();
4354 ce.account = account; 4886 ce.account = account;
4355 ce.pinfo = pinfo; 4887 ce.pinfo = pinfo;
4356
4357 m_userInfoCache[uuid] = ce; 4888 m_userInfoCache[uuid] = ce;
4358 } 4889 }
4359 else 4890 else
@@ -4362,77 +4893,78 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4362 return UUID.Zero.ToString(); 4893 return UUID.Zero.ToString();
4363 4894
4364 account = ce.account; 4895 account = ce.account;
4896 pinfo = ce.pinfo;
4897 }
4365 4898
4366 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) 4899 if (Util.EnvironmentTickCount() < ce.time ||
4367 >= LlRequestAgentDataCacheTimeoutMs) 4900 (Util.EnvironmentTickCount() - ce.time) >= LlRequestAgentDataCacheTimeoutMs)
4901 {
4902 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4903 if (pinfos != null && pinfos.Length > 0)
4368 { 4904 {
4369 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4905 foreach (PresenceInfo p in pinfos)
4370 if (pinfos != null && pinfos.Length > 0)
4371 { 4906 {
4372 foreach (PresenceInfo p in pinfos) 4907 if (p.RegionID != UUID.Zero)
4373 { 4908 {
4374 if (p.RegionID != UUID.Zero) 4909 pinfo = p;
4375 {
4376 pinfo = p;
4377 }
4378 } 4910 }
4379 } 4911 }
4380 else
4381 {
4382 pinfo = null;
4383 }
4384
4385 ce.time = Util.EnvironmentTickCount();
4386 ce.pinfo = pinfo;
4387 } 4912 }
4388 else 4913 else
4389 { 4914 pinfo = null;
4390 pinfo = ce.pinfo; 4915
4391 } 4916 ce.time = Util.EnvironmentTickCount();
4917 ce.pinfo = pinfo;
4392 } 4918 }
4393 }
4394 4919
4395 string reply = String.Empty; 4920 string reply = String.Empty;
4396 4921
4397 switch (data) 4922 switch (data)
4398 { 4923 {
4399 case ScriptBaseClass.DATA_ONLINE: 4924 case ScriptBaseClass.DATA_ONLINE: // DATA_ONLINE (0|1)
4400 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4925 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4401 reply = "1"; 4926 reply = "1";
4402 else 4927 else
4403 reply = "0"; 4928 reply = "0";
4404 break; 4929 break;
4405 case ScriptBaseClass.DATA_NAME: // (First Last) 4930 case ScriptBaseClass.DATA_NAME: // DATA_NAME (First Last)
4406 reply = account.FirstName + " " + account.LastName; 4931 reply = account.FirstName + " " + account.LastName;
4407 break; 4932 break;
4408 case ScriptBaseClass.DATA_BORN: // (YYYY-MM-DD) 4933 case ScriptBaseClass.DATA_BORN: // DATA_BORN (YYYY-MM-DD)
4409 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4934 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4410 born = born.AddSeconds(account.Created); 4935 born = born.AddSeconds(account.Created);
4411 reply = born.ToString("yyyy-MM-dd"); 4936 reply = born.ToString("yyyy-MM-dd");
4412 break; 4937 break;
4413 case ScriptBaseClass.DATA_RATING: // (0,0,0,0,0,0) 4938 case ScriptBaseClass.DATA_RATING: // DATA_RATING (0,0,0,0,0,0)
4414 reply = "0,0,0,0,0,0"; 4939 reply = "0,0,0,0,0,0";
4415 break; 4940 break;
4416 case 7: // DATA_USERLEVEL (integer). This is not available in LL and so has no constant. 4941 case 7: // DATA_USERLEVEL (integer). This is not available in LL and so has no constant.
4417 reply = account.UserLevel.ToString(); 4942 reply = account.UserLevel.ToString();
4418 break; 4943 break;
4419 case ScriptBaseClass.DATA_PAYINFO: // (0|1|2|3) 4944 case ScriptBaseClass.DATA_PAYINFO: // DATA_PAYINFO (0|1|2|3)
4420 reply = "0"; 4945 reply = "0";
4421 break; 4946 break;
4422 default: 4947 default:
4423 return UUID.Zero.ToString(); // Raise no event 4948 return UUID.Zero.ToString(); // Raise no event
4424 } 4949 }
4425 4950
4426 UUID rq = UUID.Random(); 4951 UUID rq = UUID.Random();
4427 4952
4428 UUID tid = AsyncCommands. 4953 UUID tid = AsyncCommands.
4429 DataserverPlugin.RegisterRequest(m_host.LocalId, 4954 DataserverPlugin.RegisterRequest(m_host.LocalId,
4430 m_item.ItemID, rq.ToString()); 4955 m_item.ItemID, rq.ToString());
4431 4956
4432 AsyncCommands. 4957 AsyncCommands.
4433 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4958 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4434 4959
4435 return tid.ToString(); 4960 ScriptSleep(m_sleepMsOnRequestAgentData);
4961 return tid.ToString();
4962 }
4963 else
4964 {
4965 Error("llRequestAgentData","Invalid UUID passed to llRequestAgentData.");
4966 }
4967 return "";
4436 } 4968 }
4437 4969
4438 public LSL_String llRequestInventoryData(string name) 4970 public LSL_String llRequestInventoryData(string name)
@@ -4464,10 +4996,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4464 reply); 4996 reply);
4465 }); 4997 });
4466 4998
4999 ScriptSleep(m_sleepMsOnRequestInventoryData);
4467 return tid.ToString(); 5000 return tid.ToString();
4468 } 5001 }
4469 } 5002 }
4470 5003
5004 ScriptSleep(m_sleepMsOnRequestInventoryData);
4471 return String.Empty; 5005 return String.Empty;
4472 } 5006 }
4473 5007
@@ -4484,15 +5018,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4484 if (UUID.TryParse(agent, out agentId)) 5018 if (UUID.TryParse(agent, out agentId))
4485 { 5019 {
4486 ScenePresence presence = World.GetScenePresence(agentId); 5020 ScenePresence presence = World.GetScenePresence(agentId);
4487 if (presence != null) 5021 if (presence != null && presence.PresenceType != PresenceType.Npc)
4488 { 5022 {
5023 // agent must not be a god
5024 if (presence.GodController.UserLevel >= 200) return;
5025
4489 // agent must be over the owners land 5026 // agent must be over the owners land
4490 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 5027 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4491 { 5028 {
4492 World.TeleportClientHome(agentId, presence.ControllingClient); 5029 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
5030 {
5031 // They can't be teleported home for some reason
5032 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
5033 if (regionInfo != null)
5034 {
5035 World.RequestTeleportLocation(
5036 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
5037 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
5038 }
5039 }
4493 } 5040 }
4494 } 5041 }
4495 } 5042 }
5043
5044 ScriptSleep(m_sleepMsOnSetDamage);
4496 } 5045 }
4497 5046
4498 public void llTeleportAgent(string agent, string destination, LSL_Vector targetPos, LSL_Vector targetLookAt) 5047 public void llTeleportAgent(string agent, string destination, LSL_Vector targetPos, LSL_Vector targetLookAt)
@@ -4505,20 +5054,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4505 ScenePresence presence = World.GetScenePresence(agentId); 5054 ScenePresence presence = World.GetScenePresence(agentId);
4506 if (presence != null && presence.PresenceType != PresenceType.Npc) 5055 if (presence != null && presence.PresenceType != PresenceType.Npc)
4507 { 5056 {
4508 // agent must not be a god
4509 if (presence.GodLevel >= 200) return;
4510
4511 if (destination == String.Empty) 5057 if (destination == String.Empty)
4512 destination = World.RegionInfo.RegionName; 5058 destination = World.RegionInfo.RegionName;
4513 5059
4514 // agent must be over the owners land 5060 if (m_item.PermsGranter == agentId)
4515 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 5061 {
5062 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0)
5063 {
5064 DoLLTeleport(presence, destination, targetPos, targetLookAt);
5065 }
5066 }
5067
5068 // agent must be wearing the object
5069 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4516 { 5070 {
4517 DoLLTeleport(presence, destination, targetPos, targetLookAt); 5071 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4518 } 5072 }
4519 else // or must be wearing the prim 5073 else
4520 { 5074 {
4521 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) 5075 // agent must not be a god
5076 if (presence.IsViewerUIGod) return;
5077
5078 // agent must be over the owners land
5079 ILandObject agentLand = World.LandChannel.GetLandObject(presence.AbsolutePosition);
5080 ILandObject objectLand = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
5081 if (m_host.OwnerID == objectLand.LandData.OwnerID && m_host.OwnerID == agentLand.LandData.OwnerID)
4522 { 5082 {
4523 DoLLTeleport(presence, destination, targetPos, targetLookAt); 5083 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4524 } 5084 }
@@ -4536,23 +5096,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4536 5096
4537 if (UUID.TryParse(agent, out agentId)) 5097 if (UUID.TryParse(agent, out agentId))
4538 { 5098 {
5099 // This function is owner only!
5100 if (m_host.OwnerID != agentId)
5101 return;
5102
4539 ScenePresence presence = World.GetScenePresence(agentId); 5103 ScenePresence presence = World.GetScenePresence(agentId);
4540 if (presence != null && presence.PresenceType != PresenceType.Npc) 5104
5105 if (presence == null || presence.PresenceType == PresenceType.Npc)
5106 return;
5107
5108 // Can't TP sitting avatars
5109 if (presence.ParentID != 0) // Sitting
5110 return;
5111
5112 if (m_item.PermsGranter == agentId)
4541 { 5113 {
4542 // agent must not be a god 5114 // If attached using llAttachToAvatarTemp, cowardly refuse
4543 if (presence.GodLevel >= 200) return; 5115 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.ParentGroup.FromItemID == UUID.Zero)
5116 return;
4544 5117
4545 // agent must be over the owners land 5118 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 { 5119 {
4552 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) 5120 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4553 {
4554 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4555 }
4556 } 5121 }
4557 } 5122 }
4558 } 5123 }
@@ -4601,13 +5166,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4601 { 5166 {
4602 Error("llTextBox", "Empty message"); 5167 Error("llTextBox", "Empty message");
4603 } 5168 }
4604 else if (message.Length > 512) 5169 else if (Encoding.UTF8.GetByteCount(message) > 512)
4605 { 5170 {
4606 Error("llTextBox", "Message more than 512 characters"); 5171 Error("llTextBox", "Message longer than 512 bytes");
4607 } 5172 }
4608 else 5173 else
4609 { 5174 {
4610 dm.SendTextBoxToUser(av, message, chatChannel, m_host.Name, m_host.UUID, m_host.OwnerID); 5175 dm.SendTextBoxToUser(av, message, chatChannel, m_host.Name, m_host.UUID, m_host.OwnerID);
5176 ScriptSleep(m_sleepMsOnTextBox);
4611 } 5177 }
4612 } 5178 }
4613 5179
@@ -4625,9 +5191,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4625 { 5191 {
4626 m_host.AddScriptLPS(1); 5192 m_host.AddScriptLPS(1);
4627 5193
5194 if(impact_sound == "")
5195 {
5196 m_host.CollisionSoundVolume = (float)impact_volume;
5197 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
5198 m_host.CollisionSoundType = -1; // disable all sounds
5199 m_host.aggregateScriptEvents();
5200 return;
5201 }
5202
4628 // TODO: Parameter check logic required. 5203 // TODO: Parameter check logic required.
4629 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound); 5204 UUID soundId = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound);
4630 m_host.CollisionSoundVolume = (float)impact_volume; 5205 if(soundId != UUID.Zero)
5206 {
5207 m_host.CollisionSound = soundId;
5208 m_host.CollisionSoundVolume = (float)impact_volume;
5209 m_host.CollisionSoundType = 1;
5210 }
5211 else
5212 m_host.CollisionSoundType = -1;
5213
5214 m_host.aggregateScriptEvents();
4631 } 5215 }
4632 5216
4633 public LSL_String llGetAnimation(string id) 5217 public LSL_String llGetAnimation(string id)
@@ -4641,14 +5225,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4641 5225
4642 if (m_host.RegionHandle == presence.RegionHandle) 5226 if (m_host.RegionHandle == presence.RegionHandle)
4643 { 5227 {
4644 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4645
4646 if (presence != null) 5228 if (presence != null)
4647 { 5229 {
4648 AnimationSet currentAnims = presence.Animator.Animations; 5230// if (presence.SitGround)
4649 string currentAnimationState = String.Empty; 5231// return "Sitting on Ground";
4650 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 5232// if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4651 return currentAnimationState; 5233// return "Sitting";
5234
5235 string movementAnimation = presence.Animator.CurrentMovementAnimation;
5236 string lslMovementAnimation;
5237
5238 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
5239 return lslMovementAnimation;
4652 } 5240 }
4653 } 5241 }
4654 5242
@@ -4712,7 +5300,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4712 return; 5300 return;
4713 5301
4714 // Pushee is in GodMode this pushing object isn't owned by them 5302 // Pushee is in GodMode this pushing object isn't owned by them
4715 if (avatar.GodLevel > 0 && m_host.OwnerID != targetID) 5303 if (avatar.IsViewerUIGod && m_host.OwnerID != targetID)
4716 return; 5304 return;
4717 5305
4718 pusheeav = avatar; 5306 pusheeav = avatar;
@@ -4796,7 +5384,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4796 { 5384 {
4797 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 5385 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4798 float distance_term = distance * distance * distance; // Script Energy 5386 float distance_term = distance * distance * distance; // Script Energy
4799 float pusher_mass = m_host.GetMass(); 5387 // use total object mass and not part
5388 float pusher_mass = m_host.ParentGroup.GetMass();
4800 5389
4801 float PUSH_ATTENUATION_DISTANCE = 17f; 5390 float PUSH_ATTENUATION_DISTANCE = 17f;
4802 float PUSH_ATTENUATION_SCALE = 5f; 5391 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4831,7 +5420,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4831 { 5420 {
4832 if (local != 0) 5421 if (local != 0)
4833 { 5422 {
4834 applied_linear_impulse *= m_host.GetWorldRotation(); 5423// applied_linear_impulse *= m_host.GetWorldRotation();
5424 applied_linear_impulse *= pusheeav.GetWorldRotation();
4835 } 5425 }
4836 5426
4837 pa.AddForce(applied_linear_impulse, true); 5427 pa.AddForce(applied_linear_impulse, true);
@@ -4891,20 +5481,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4891 { 5481 {
4892 m_host.AddScriptLPS(1); 5482 m_host.AddScriptLPS(1);
4893 5483
4894 return GetNumberOfSides(m_host); 5484 return m_host.GetNumberOfSides();
4895 } 5485 }
4896 5486
4897 protected int GetNumberOfSides(SceneObjectPart part) 5487 protected int GetNumberOfSides(SceneObjectPart part)
4898 { 5488 {
4899 int sides = part.GetNumberOfSides(); 5489 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 } 5490 }
4909 5491
4910 5492
@@ -4959,20 +5541,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4959 { 5541 {
4960 m_host.AddScriptLPS(1); 5542 m_host.AddScriptLPS(1);
4961 5543
4962 if (Math.Abs(rot.s) > 1) // normalization needed 5544 rot.Normalize();
4963 rot.Normalize();
4964 5545
4965 double s = Math.Sqrt(1 - rot.s * rot.s); 5546 double s = Math.Sqrt(1 - rot.s * rot.s);
4966 if (s < 0.001) 5547 if (s < 1e-8)
4967 { 5548 return new LSL_Vector(0, 0, 0);
4968 return new LSL_Vector(1, 0, 0); 5549
4969 } 5550 double invS = 1.0 / s;
4970 else 5551 if (rot.s < 0)
4971 { 5552 invS = -invS;
4972 double invS = 1.0 / s; 5553 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 } 5554 }
4977 5555
4978 5556
@@ -4981,11 +5559,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4981 { 5559 {
4982 m_host.AddScriptLPS(1); 5560 m_host.AddScriptLPS(1);
4983 5561
4984 if (Math.Abs(rot.s) > 1) // normalization needed 5562 rot.Normalize();
4985 rot.Normalize();
4986 5563
4987 double angle = 2 * Math.Acos(rot.s); 5564 double angle = 2 * Math.Acos(rot.s);
4988 if (angle > Math.PI) 5565 if (angle > Math.PI)
4989 angle = 2 * Math.PI - angle; 5566 angle = 2 * Math.PI - angle;
4990 5567
4991 return angle; 5568 return angle;
@@ -5185,43 +5762,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5185 { 5762 {
5186 m_host.AddScriptLPS(1); 5763 m_host.AddScriptLPS(1);
5187 5764
5188 if (src == null) 5765 return src.Length;
5189 {
5190 return 0;
5191 }
5192 else
5193 {
5194 return src.Length;
5195 }
5196 } 5766 }
5197 5767
5198 public LSL_Integer llList2Integer(LSL_List src, int index) 5768 public LSL_Integer llList2Integer(LSL_List src, int index)
5199 { 5769 {
5200 m_host.AddScriptLPS(1); 5770 m_host.AddScriptLPS(1);
5201 if (index < 0) 5771 if (index < 0)
5202 {
5203 index = src.Length + index; 5772 index = src.Length + index;
5204 } 5773
5205 if (index >= src.Length || index < 0) 5774 if (index >= src.Length || index < 0)
5206 {
5207 return 0; 5775 return 0;
5208 } 5776
5777 object item = src.Data[index];
5209 5778
5210 // Vectors & Rotations always return zero in SL, but 5779 // Vectors & Rotations always return zero in SL, but
5211 // keys don't always return zero, it seems to be a bit complex. 5780 // keys don't always return zero, it seems to be a bit complex.
5212 else if (src.Data[index] is LSL_Vector || 5781 if (item is LSL_Vector || item is LSL_Rotation)
5213 src.Data[index] is LSL_Rotation)
5214 {
5215 return 0; 5782 return 0;
5216 } 5783
5217 try 5784 try
5218 { 5785 {
5219 5786 if (item is LSL_Integer)
5220 if (src.Data[index] is LSL_Integer) 5787 return (LSL_Integer)item;
5221 return (LSL_Integer)src.Data[index]; 5788 else if (item is LSL_Float)
5222 else if (src.Data[index] is LSL_Float) 5789 return Convert.ToInt32(((LSL_Float)item).value);;
5223 return Convert.ToInt32(((LSL_Float)src.Data[index]).value); 5790 return new LSL_Integer(item.ToString());
5224 return new LSL_Integer(src.Data[index].ToString());
5225 } 5791 }
5226 catch (FormatException) 5792 catch (FormatException)
5227 { 5793 {
@@ -5233,38 +5799,50 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5233 { 5799 {
5234 m_host.AddScriptLPS(1); 5800 m_host.AddScriptLPS(1);
5235 if (index < 0) 5801 if (index < 0)
5236 {
5237 index = src.Length + index; 5802 index = src.Length + index;
5238 } 5803
5239 if (index >= src.Length || index < 0) 5804 if (index >= src.Length || index < 0)
5240 { 5805 return 0;
5241 return 0.0; 5806
5242 } 5807 object item = src.Data[index];
5243 5808
5244 // Vectors & Rotations always return zero in SL 5809 // Vectors & Rotations always return zero in SL
5245 else if (src.Data[index] is LSL_Vector || 5810 if(item is LSL_Vector || item is LSL_Rotation)
5246 src.Data[index] is LSL_Rotation)
5247 {
5248 return 0; 5811 return 0;
5249 } 5812
5250 // valid keys seem to get parsed as integers then converted to floats 5813 // valid keys seem to get parsed as integers then converted to floats
5251 else 5814 if (item is LSL_Key)
5252 { 5815 {
5253 UUID uuidt; 5816 UUID uuidt;
5254 if (src.Data[index] is LSL_Key && UUID.TryParse(src.Data[index].ToString(), out uuidt)) 5817 string s = item.ToString();
5255 { 5818 if(UUID.TryParse(s, out uuidt))
5256 return Convert.ToDouble(new LSL_Integer(src.Data[index].ToString()).value); 5819 return Convert.ToDouble(new LSL_Integer(s).value);
5257 } 5820// we can't do this because a string is also a LSL_Key for now :(
5821// else
5822// return 0;
5258 } 5823 }
5824
5259 try 5825 try
5260 { 5826 {
5261 if (src.Data[index] is LSL_Integer) 5827 if (item is LSL_Integer)
5262 return Convert.ToDouble(((LSL_Integer)src.Data[index]).value); 5828 return Convert.ToDouble(((LSL_Integer)item).value);
5263 else if (src.Data[index] is LSL_Float) 5829 else if (item is LSL_Float)
5264 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5830 return Convert.ToDouble(((LSL_Float)item).value);
5265 else if (src.Data[index] is LSL_String) 5831 else if (item is LSL_String)
5266 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5832 {
5267 return Convert.ToDouble(src.Data[index]); 5833 string str = ((LSL_String)item).m_string;
5834 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5835 if (m != Match.Empty)
5836 {
5837 str = m.Value;
5838 double d = 0.0;
5839 if (!Double.TryParse(str, out d))
5840 return 0.0;
5841 return d;
5842 }
5843 return 0.0;
5844 }
5845 return Convert.ToDouble(item);
5268 } 5846 }
5269 catch (FormatException) 5847 catch (FormatException)
5270 { 5848 {
@@ -5276,13 +5854,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5276 { 5854 {
5277 m_host.AddScriptLPS(1); 5855 m_host.AddScriptLPS(1);
5278 if (index < 0) 5856 if (index < 0)
5279 {
5280 index = src.Length + index; 5857 index = src.Length + index;
5281 } 5858
5282 if (index >= src.Length || index < 0) 5859 if (index >= src.Length || index < 0)
5283 {
5284 return String.Empty; 5860 return String.Empty;
5285 } 5861
5286 return src.Data[index].ToString(); 5862 return src.Data[index].ToString();
5287 } 5863 }
5288 5864
@@ -5290,14 +5866,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5290 { 5866 {
5291 m_host.AddScriptLPS(1); 5867 m_host.AddScriptLPS(1);
5292 if (index < 0) 5868 if (index < 0)
5293 {
5294 index = src.Length + index; 5869 index = src.Length + index;
5295 }
5296 5870
5297 if (index >= src.Length || index < 0) 5871 if (index >= src.Length || index < 0)
5298 { 5872 return String.Empty;
5299 return ""; 5873
5300 } 5874 object item = src.Data[index];
5301 5875
5302 // SL spits out an empty string for types other than key & string 5876 // SL spits out an empty string for types other than key & string
5303 // At the time of patching, LSL_Key is currently LSL_String, 5877 // At the time of patching, LSL_Key is currently LSL_String,
@@ -5306,31 +5880,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5306 // as it's own struct 5880 // as it's own struct
5307 // NOTE: 3rd case is needed because a NULL_KEY comes through as 5881 // NOTE: 3rd case is needed because a NULL_KEY comes through as
5308 // type 'obj' and wrongly returns "" 5882 // type 'obj' and wrongly returns ""
5309 else if (!(src.Data[index] is LSL_String || 5883 if (!(item is LSL_String ||
5310 src.Data[index] is LSL_Key || 5884 item is LSL_Key ||
5311 src.Data[index].ToString() == "00000000-0000-0000-0000-000000000000")) 5885 item.ToString() == "00000000-0000-0000-0000-000000000000"))
5312 { 5886 {
5313 return ""; 5887 return String.Empty;
5314 } 5888 }
5315 5889
5316 return src.Data[index].ToString(); 5890 return item.ToString();
5317 } 5891 }
5318 5892
5319 public LSL_Vector llList2Vector(LSL_List src, int index) 5893 public LSL_Vector llList2Vector(LSL_List src, int index)
5320 { 5894 {
5321 m_host.AddScriptLPS(1); 5895 m_host.AddScriptLPS(1);
5322 if (index < 0) 5896 if (index < 0)
5323 {
5324 index = src.Length + index; 5897 index = src.Length + index;
5325 } 5898
5326 if (index >= src.Length || index < 0) 5899 if (index >= src.Length || index < 0)
5327 {
5328 return new LSL_Vector(0, 0, 0); 5900 return new LSL_Vector(0, 0, 0);
5329 } 5901
5330 if (src.Data[index].GetType() == typeof(LSL_Vector)) 5902 object item = src.Data[index];
5331 { 5903
5332 return (LSL_Vector)src.Data[index]; 5904 if (item.GetType() == typeof(LSL_Vector))
5333 } 5905 return (LSL_Vector)item;
5334 5906
5335 // SL spits always out ZERO_VECTOR for anything other than 5907 // SL spits always out ZERO_VECTOR for anything other than
5336 // strings or vectors. Although keys always return ZERO_VECTOR, 5908 // strings or vectors. Although keys always return ZERO_VECTOR,
@@ -5338,28 +5910,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5338 // a string, a key as string and a string that by coincidence 5910 // 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 5911 // is a string, so we're going to leave that up to the
5340 // LSL_Vector constructor. 5912 // LSL_Vector constructor.
5341 else if (!(src.Data[index] is LSL_String || 5913 if(item is LSL_Vector)
5342 src.Data[index] is LSL_Vector)) 5914 return (LSL_Vector) item;
5343 { 5915
5344 return new LSL_Vector(0, 0, 0); 5916 if (item is LSL_String)
5345 } 5917 return new LSL_Vector(item.ToString());
5346 else 5918
5347 { 5919 return new LSL_Vector(0, 0, 0);
5348 return new LSL_Vector(src.Data[index].ToString());
5349 }
5350 } 5920 }
5351 5921
5352 public LSL_Rotation llList2Rot(LSL_List src, int index) 5922 public LSL_Rotation llList2Rot(LSL_List src, int index)
5353 { 5923 {
5354 m_host.AddScriptLPS(1); 5924 m_host.AddScriptLPS(1);
5355 if (index < 0) 5925 if (index < 0)
5356 {
5357 index = src.Length + index; 5926 index = src.Length + index;
5358 } 5927
5359 if (index >= src.Length || index < 0) 5928 if (index >= src.Length || index < 0)
5360 {
5361 return new LSL_Rotation(0, 0, 0, 1); 5929 return new LSL_Rotation(0, 0, 0, 1);
5362 } 5930
5931 object item = src.Data[index];
5363 5932
5364 // SL spits always out ZERO_ROTATION for anything other than 5933 // SL spits always out ZERO_ROTATION for anything other than
5365 // strings or vectors. Although keys always return ZERO_ROTATION, 5934 // strings or vectors. Although keys always return ZERO_ROTATION,
@@ -5367,19 +5936,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5367 // a string, a key as string and a string that by coincidence 5936 // 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 5937 // is a string, so we're going to leave that up to the
5369 // LSL_Rotation constructor. 5938 // LSL_Rotation constructor.
5370 else if (!(src.Data[index] is LSL_String || 5939
5371 src.Data[index] is LSL_Rotation)) 5940 if (item.GetType() == typeof(LSL_Rotation))
5372 { 5941 return (LSL_Rotation)item;
5373 return new LSL_Rotation(0, 0, 0, 1); 5942
5374 } 5943 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()); 5944 return new LSL_Rotation(src.Data[index].ToString());
5382 } 5945
5946 return new LSL_Rotation(0, 0, 0, 1);
5383 } 5947 }
5384 5948
5385 public LSL_List llList2List(LSL_List src, int start, int end) 5949 public LSL_List llList2List(LSL_List src, int start, int end)
@@ -5567,7 +6131,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5567 } 6131 }
5568 } 6132 }
5569 } 6133 }
5570 else { 6134 else
6135 {
5571 object[] array = new object[src.Length]; 6136 object[] array = new object[src.Length];
5572 Array.Copy(src.Data, 0, array, 0, src.Length); 6137 Array.Copy(src.Data, 0, array, 0, src.Length);
5573 result = new LSL_List(array); 6138 result = new LSL_List(array);
@@ -5674,7 +6239,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5674 public LSL_Integer llGetRegionAgentCount() 6239 public LSL_Integer llGetRegionAgentCount()
5675 { 6240 {
5676 m_host.AddScriptLPS(1); 6241 m_host.AddScriptLPS(1);
5677 return new LSL_Integer(World.GetRootAgentCount()); 6242
6243 int count = 0;
6244 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
6245 count++;
6246 });
6247
6248 return new LSL_Integer(count);
5678 } 6249 }
5679 6250
5680 public LSL_Vector llGetRegionCorner() 6251 public LSL_Vector llGetRegionCorner()
@@ -5742,10 +6313,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5742 IUrlModule UrlModule = World.RequestModuleInterface<IUrlModule>(); 6313 IUrlModule UrlModule = World.RequestModuleInterface<IUrlModule>();
5743 return UrlModule.ExternalHostNameForLSL; 6314 return UrlModule.ExternalHostNameForLSL;
5744 } 6315 }
6316 else if (name == "region_max_prims")
6317 {
6318 return World.RegionInfo.ObjectCapacity.ToString();
6319 }
6320 else if (name == "region_object_bonus")
6321 {
6322 return World.RegionInfo.RegionSettings.ObjectBonus.ToString();
6323 }
5745 else 6324 else
5746 { 6325 {
5747 return ""; 6326 return "";
5748 } 6327 }
6328
5749 } 6329 }
5750 6330
5751 /// <summary> 6331 /// <summary>
@@ -5821,17 +6401,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5821 { 6401 {
5822 for (int i = 0; i < length; i++) 6402 for (int i = 0; i < length; i++)
5823 { 6403 {
6404 int needle = llGetListEntryType(test, 0).value;
6405 int haystack = llGetListEntryType(src, i).value;
6406
5824 // Why this piece of insanity? This is because most script constants are C# value types (e.g. int) 6407 // 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 6408 // 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. 6409 // 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. 6410 // 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)). 6411 // However, a future better approach may be use LSL struct script constants (e.g. LSL_Integer(1)).
5829 if (src.Data[i].Equals(test.Data[0]) || test.Data[0].Equals(src.Data[i])) 6412 if ((needle == haystack) && (src.Data[i].Equals(test.Data[0]) || test.Data[0].Equals(src.Data[i])))
5830 { 6413 {
5831 int j; 6414 int j;
5832 for (j = 1; j < test.Length; j++) 6415 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]))) 6416 {
6417 needle = llGetListEntryType(test, j).value;
6418 haystack = llGetListEntryType(src, i+j).value;
6419
6420 if ((needle != haystack) || (!(src.Data[i+j].Equals(test.Data[j]) || test.Data[j].Equals(src.Data[i+j]))))
5834 break; 6421 break;
6422 }
5835 6423
5836 if (j == test.Length) 6424 if (j == test.Length)
5837 { 6425 {
@@ -5869,64 +6457,61 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5869 { 6457 {
5870 m_host.AddScriptLPS(1); 6458 m_host.AddScriptLPS(1);
5871 6459
5872 // edge will be used to pass the Region Coordinates offset 6460 if(dir.x == 0 && dir.y == 0)
5873 // we want to check for a neighboring sim 6461 return 1; // SL wiki
5874 LSL_Vector edge = new LSL_Vector(0, 0, 0); 6462
6463 float rsx = World.RegionInfo.RegionSizeX;
6464 float rsy = World.RegionInfo.RegionSizeY;
6465
6466 // can understand what sl does if position is not in region, so do something :)
6467 float px = (float)Util.Clamp(pos.x, 0.5, rsx - 0.5);
6468 float py = (float)Util.Clamp(pos.y, 0.5, rsy - 0.5);
6469
6470 float ex, ey;
5875 6471
5876 if (dir.x == 0) 6472 if (dir.x == 0)
5877 { 6473 {
5878 if (dir.y == 0) 6474 ex = px;
5879 { 6475 ey = dir.y > 0 ? rsy + 1.0f : -1.0f;
5880 // Direction vector is 0,0 so return 6476 }
5881 // false since we're staying in the sim 6477 else if(dir.y == 0)
5882 return 0; 6478 {
5883 } 6479 ex = dir.x > 0 ? rsx + 1.0f : -1.0f;
5884 else 6480 ey = py;
5885 {
5886 // Y is the only valid direction
5887 edge.y = dir.y / Math.Abs(dir.y);
5888 }
5889 } 6481 }
5890 else 6482 else
5891 { 6483 {
5892 LSL_Float mag; 6484 float dx = (float) dir.x;
5893 if (dir.x > 0) 6485 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 6486
5902 mag = Math.Abs(mag); 6487 float t1 = dx * dx + dy * dy;
6488 t1 = (float)Math.Sqrt(t1);
6489 dx /= t1;
6490 dy /= t1;
5903 6491
5904 edge.y = pos.y + (dir.y * mag); 6492 if(dx > 0)
5905 6493 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 6494 else
5912 { 6495 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 6496
5919 List<GridRegion> neighbors = World.GridService.GetNeighbours(World.RegionInfo.ScopeID, World.RegionInfo.RegionID); 6497 float t2;
6498 if(dy > 0)
6499 t2 = (rsy + 1f - py)/dy;
6500 else
6501 t2 = -(py + 1f)/dy;
5920 6502
5921 uint neighborX = World.RegionInfo.RegionLocX + (uint)dir.x; 6503 if(t1 > t2)
5922 uint neighborY = World.RegionInfo.RegionLocY + (uint)dir.y; 6504 t1 = t2;
5923 6505
5924 foreach (GridRegion sri in neighbors) 6506 ex = px + t1 * dx;
5925 { 6507 ey = py + t1 * dy;
5926 if (sri.RegionCoordX == neighborX && sri.RegionCoordY == neighborY)
5927 return 0;
5928 } 6508 }
5929 6509
6510 ex += World.RegionInfo.WorldLocX;
6511 ey += World.RegionInfo.WorldLocY;
6512
6513 if(World.GridService.GetRegionByPosition(World.RegionInfo.ScopeID, (int)ex, (int)ey) != null)
6514 return 0;
5930 return 1; 6515 return 1;
5931 } 6516 }
5932 6517
@@ -5980,6 +6565,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5980 flags |= ScriptBaseClass.AGENT_AWAY; 6565 flags |= ScriptBaseClass.AGENT_AWAY;
5981 } 6566 }
5982 6567
6568 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6569 UUID[] anims = agent.Animator.GetAnimationArray();
6570 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6571 {
6572 flags |= ScriptBaseClass.AGENT_BUSY;
6573 }
6574
5983 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6575 // 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) 6576 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5985 { 6577 {
@@ -6027,6 +6619,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6027 flags |= ScriptBaseClass.AGENT_SITTING; 6619 flags |= ScriptBaseClass.AGENT_SITTING;
6028 } 6620 }
6029 6621
6622 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6623 {
6624 flags |= ScriptBaseClass.AGENT_MALE;
6625 }
6626
6030 return flags; 6627 return flags;
6031 } 6628 }
6032 6629
@@ -6056,11 +6653,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6056 /// AGENT_LIST_PARCEL - all in the same parcel as the scripted object 6653 /// 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 6654 /// AGENT_LIST_PARCEL_OWNER - all in any parcel owned by the owner of the
6058 /// current parcel. 6655 /// current parcel.
6656 /// AGENT_LIST_EXCLUDENPC ignore NPCs (bit mask)
6059 /// </summary> 6657 /// </summary>
6060 public LSL_List llGetAgentList(LSL_Integer scope, LSL_List options) 6658 public LSL_List llGetAgentList(LSL_Integer scope, LSL_List options)
6061 { 6659 {
6062 m_host.AddScriptLPS(1); 6660 m_host.AddScriptLPS(1);
6063 6661
6662 // do our bit masks part
6663 bool noNPC = (scope & ScriptBaseClass.AGENT_LIST_EXCLUDENPC) !=0;
6664
6665 // remove bit masks part
6666 scope &= ~ ScriptBaseClass.AGENT_LIST_EXCLUDENPC;
6667
6064 // the constants are 1, 2 and 4 so bits are being set, but you 6668 // 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 6669 // get an error "INVALID_SCOPE" if it is anything but 1, 2 and 4
6066 bool regionWide = scope == ScriptBaseClass.AGENT_LIST_REGION; 6670 bool regionWide = scope == ScriptBaseClass.AGENT_LIST_REGION;
@@ -6101,8 +6705,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6101 World.ForEachRootScenePresence( 6705 World.ForEachRootScenePresence(
6102 delegate (ScenePresence ssp) 6706 delegate (ScenePresence ssp)
6103 { 6707 {
6708 if(noNPC && ssp.IsNPC)
6709 return;
6710
6104 // Gods are not listed in SL 6711 // Gods are not listed in SL
6105 if (!ssp.IsDeleted && ssp.GodLevel == 0.0 && !ssp.IsChildAgent) 6712 if (!ssp.IsDeleted && !ssp.IsViewerUIGod && !ssp.IsChildAgent)
6106 { 6713 {
6107 if (!regionWide) 6714 if (!regionWide)
6108 { 6715 {
@@ -6135,6 +6742,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6135 { 6742 {
6136 m_host.AddScriptLPS(1); 6743 m_host.AddScriptLPS(1);
6137 m_host.AdjustSoundGain(volume); 6744 m_host.AdjustSoundGain(volume);
6745 ScriptSleep(m_sleepMsOnAdjustSoundVolume);
6138 } 6746 }
6139 6747
6140 public void llSetSoundRadius(double radius) 6748 public void llSetSoundRadius(double radius)
@@ -6180,9 +6788,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6180 6788
6181 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6789 List<SceneObjectPart> parts = GetLinkParts(linknumber);
6182 6790
6183 foreach (SceneObjectPart part in parts) 6791 try
6792 {
6793 foreach (SceneObjectPart part in parts)
6794 {
6795 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6796 }
6797 }
6798 finally
6184 { 6799 {
6185 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6186 } 6800 }
6187 } 6801 }
6188 6802
@@ -6236,10 +6850,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6236 6850
6237 if (m_host.OwnerID == land.LandData.OwnerID) 6851 if (m_host.OwnerID == land.LandData.OwnerID)
6238 { 6852 {
6239 World.TeleportClientHome(agentID, presence.ControllingClient); 6853 Vector3 p = World.GetNearestAllowedPosition(presence, land);
6854 presence.TeleportOnEject(p);
6855 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
6240 } 6856 }
6241 } 6857 }
6242 } 6858 }
6859 ScriptSleep(m_sleepMsOnEjectFromLand);
6860 }
6861
6862 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6863 {
6864 return ParseString2List(str, separators, in_spacers, false);
6243 } 6865 }
6244 6866
6245 public LSL_Integer llOverMyLand(string id) 6867 public LSL_Integer llOverMyLand(string id)
@@ -6294,26 +6916,59 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6294 } 6916 }
6295 else 6917 else
6296 { 6918 {
6297 agentSize = GetAgentSize(avatar); 6919// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6920 Vector3 s = avatar.Appearance.AvatarSize;
6921 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
6298 } 6922 }
6299
6300 return agentSize; 6923 return agentSize;
6301 } 6924 }
6302 6925
6303 public LSL_Integer llSameGroup(string agent) 6926 public LSL_Integer llSameGroup(string id)
6304 { 6927 {
6305 m_host.AddScriptLPS(1); 6928 m_host.AddScriptLPS(1);
6306 UUID agentId = new UUID(); 6929 UUID uuid = new UUID();
6307 if (!UUID.TryParse(agent, out agentId)) 6930 if (!UUID.TryParse(id, out uuid))
6308 return new LSL_Integer(0);
6309 ScenePresence presence = World.GetScenePresence(agentId);
6310 if (presence == null || presence.IsChildAgent) // Return flase for child agents
6311 return new LSL_Integer(0); 6931 return new LSL_Integer(0);
6312 IClientAPI client = presence.ControllingClient; 6932
6313 if (m_host.GroupID == client.ActiveGroupId) 6933 // Check if it's a group key
6934 if (uuid == m_host.ParentGroup.RootPart.GroupID)
6314 return new LSL_Integer(1); 6935 return new LSL_Integer(1);
6315 else 6936
6937 // Handle object case
6938 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6939 if (part != null)
6940 {
6941
6942 if(part.ParentGroup.IsAttachment)
6943 {
6944 uuid = part.ParentGroup.AttachedAvatar;
6945 }
6946 else
6947 {
6948 // This will handle both deed and non-deed and also the no
6949 // group case
6950 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6951 return new LSL_Integer(1);
6952
6953 return new LSL_Integer(0);
6954 }
6955 }
6956
6957 // Handle the case where id names an avatar
6958 ScenePresence presence = World.GetScenePresence(uuid);
6959 if (presence != null)
6960 {
6961 if (presence.IsChildAgent)
6962 return new LSL_Integer(0);
6963
6964 IClientAPI client = presence.ControllingClient;
6965 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6966 return new LSL_Integer(1);
6967
6316 return new LSL_Integer(0); 6968 return new LSL_Integer(0);
6969 }
6970
6971 return new LSL_Integer(0);
6317 } 6972 }
6318 6973
6319 public void llUnSit(string id) 6974 public void llUnSit(string id)
@@ -6441,6 +7096,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6441 return m_host.ParentGroup.AttachmentPoint; 7096 return m_host.ParentGroup.AttachmentPoint;
6442 } 7097 }
6443 7098
7099 public LSL_List llGetAttachedList(string id)
7100 {
7101 m_host.AddScriptLPS(1);
7102
7103 ScenePresence av = World.GetScenePresence((UUID)id);
7104
7105 if (av == null || av.IsDeleted)
7106 return new LSL_List("NOT_FOUND");
7107
7108 if (av.IsChildAgent || av.IsInTransit)
7109 return new LSL_List("NOT_ON_REGION");
7110
7111 LSL_List AttachmentsList = new LSL_List();
7112 List<SceneObjectGroup> Attachments;
7113
7114 Attachments = av.GetAttachments();
7115
7116 foreach (SceneObjectGroup Attachment in Attachments)
7117 {
7118 if(Attachment.HasPrivateAttachmentPoint)
7119 continue;
7120 AttachmentsList.Add(new LSL_Key(Attachment.UUID.ToString()));
7121 }
7122
7123 return AttachmentsList;
7124 }
7125
6444 public virtual LSL_Integer llGetFreeMemory() 7126 public virtual LSL_Integer llGetFreeMemory()
6445 { 7127 {
6446 m_host.AddScriptLPS(1); 7128 m_host.AddScriptLPS(1);
@@ -7127,6 +7809,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7127 7809
7128 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 7810 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
7129 { 7811 {
7812 // LSL quaternions can normalize to 0, normal Quaternions can't.
7813 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7814 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7815
7130 part.SitTargetPosition = offset; 7816 part.SitTargetPosition = offset;
7131 part.SitTargetOrientation = rot; 7817 part.SitTargetOrientation = rot;
7132 part.ParentGroup.HasGroupChanged = true; 7818 part.ParentGroup.HasGroupChanged = true;
@@ -7166,11 +7852,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7166 { 7852 {
7167 m_host.AddScriptLPS(1); 7853 m_host.AddScriptLPS(1);
7168 if(linknum == ScriptBaseClass.LINK_SET || 7854 if(linknum == ScriptBaseClass.LINK_SET ||
7169 linknum == ScriptBaseClass.LINK_ALL_CHILDREN || 7855 linknum == ScriptBaseClass.LINK_ALL_CHILDREN ||
7170 linknum == ScriptBaseClass.LINK_ALL_OTHERS) return UUID.Zero.ToString(); 7856 linknum == ScriptBaseClass.LINK_ALL_OTHERS ||
7857 linknum == 0)
7858 return UUID.Zero.ToString();
7171 7859
7172 List<SceneObjectPart> parts = GetLinkParts(linknum); 7860 List<SceneObjectPart> parts = GetLinkParts(linknum);
7173 if (parts.Count == 0) return UUID.Zero.ToString(); 7861 if (parts.Count == 0)
7862 return UUID.Zero.ToString();
7174 return parts[0].SitTargetAvatar.ToString(); 7863 return parts[0].SitTargetAvatar.ToString();
7175 } 7864 }
7176 7865
@@ -7181,7 +7870,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7181 UUID key; 7870 UUID key;
7182 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 7871 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
7183 7872
7184 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 7873 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManagePasses, false))
7185 { 7874 {
7186 int expires = 0; 7875 int expires = 0;
7187 if (hours != 0) 7876 if (hours != 0)
@@ -7214,6 +7903,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7214 World.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land); 7903 World.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land);
7215 } 7904 }
7216 } 7905 }
7906 ScriptSleep(m_sleepMsOnAddToLandPassList);
7217 } 7907 }
7218 7908
7219 public void llSetTouchText(string text) 7909 public void llSetTouchText(string text)
@@ -7295,7 +7985,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7295 public LSL_Integer llScriptDanger(LSL_Vector pos) 7985 public LSL_Integer llScriptDanger(LSL_Vector pos)
7296 { 7986 {
7297 m_host.AddScriptLPS(1); 7987 m_host.AddScriptLPS(1);
7298 bool result = World.ScriptDanger(m_host.LocalId, pos); 7988 bool result = World.LSLScriptDanger(m_host, pos);
7299 if (result) 7989 if (result)
7300 { 7990 {
7301 return 1; 7991 return 1;
@@ -7304,7 +7994,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7304 { 7994 {
7305 return 0; 7995 return 0;
7306 } 7996 }
7307
7308 } 7997 }
7309 7998
7310 public void llDialog(string avatar, string message, LSL_List buttons, int chat_channel) 7999 public void llDialog(string avatar, string message, LSL_List buttons, int chat_channel)
@@ -7321,35 +8010,51 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7321 Error("llDialog", "First parameter must be a key"); 8010 Error("llDialog", "First parameter must be a key");
7322 return; 8011 return;
7323 } 8012 }
7324 if (buttons.Length < 1) 8013
8014 int length = buttons.Length;
8015 if (length < 1)
7325 { 8016 {
7326 Error("llDialog", "At least 1 button must be shown"); 8017 Error("llDialog", "At least 1 button must be shown");
7327 return; 8018 return;
7328 } 8019 }
7329 if (buttons.Length > 12) 8020 if (length > 12)
7330 { 8021 {
7331 Error("llDialog", "No more than 12 buttons can be shown"); 8022 Error("llDialog", "No more than 12 buttons can be shown");
7332 return; 8023 return;
7333 } 8024 }
7334 string[] buts = new string[buttons.Length]; 8025
7335 for (int i = 0; i < buttons.Length; i++) 8026 if (message == string.Empty)
8027 {
8028 Error("llDialog", "Empty message");
8029 }
8030 else if (Encoding.UTF8.GetByteCount(message) > 512)
8031 {
8032 Error("llDialog", "Message longer than 512 bytes");
8033 }
8034
8035 string[] buts = new string[length];
8036 for (int i = 0; i < length; i++)
7336 { 8037 {
7337 if (buttons.Data[i].ToString() == String.Empty) 8038 if (buttons.Data[i].ToString() == String.Empty)
7338 { 8039 {
7339 Error("llDialog", "Button label cannot be blank"); 8040 Error("llDialog", "Button label cannot be blank");
7340 return; 8041 return;
7341 } 8042 }
8043/*
7342 if (buttons.Data[i].ToString().Length > 24) 8044 if (buttons.Data[i].ToString().Length > 24)
7343 { 8045 {
7344 Error("llDialog", "Button label cannot be longer than 24 characters"); 8046 Error("llDialog", "Button label cannot be longer than 24 characters");
7345 return; 8047 return;
7346 } 8048 }
8049*/
7347 buts[i] = buttons.Data[i].ToString(); 8050 buts[i] = buttons.Data[i].ToString();
7348 } 8051 }
7349 8052
7350 dm.SendDialogToUser( 8053 dm.SendDialogToUser(
7351 av, m_host.Name, m_host.UUID, m_host.OwnerID, 8054 av, m_host.Name, m_host.UUID, m_host.OwnerID,
7352 message, new UUID("00000000-0000-2222-3333-100000001000"), chat_channel, buts); 8055 message, new UUID("00000000-0000-2222-3333-100000001000"), chat_channel, buts);
8056
8057 ScriptSleep(m_sleepMsOnDialog);
7353 } 8058 }
7354 8059
7355 public void llVolumeDetect(int detect) 8060 public void llVolumeDetect(int detect)
@@ -7364,6 +8069,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7364 { 8069 {
7365 m_host.AddScriptLPS(1); 8070 m_host.AddScriptLPS(1);
7366 Deprecated("llRemoteLoadScript", "Use llRemoteLoadScriptPin instead"); 8071 Deprecated("llRemoteLoadScript", "Use llRemoteLoadScriptPin instead");
8072 ScriptSleep(m_sleepMsOnRemoteLoadScript);
7367 } 8073 }
7368 8074
7369 public void llSetRemoteScriptAccessPin(int pin) 8075 public void llSetRemoteScriptAccessPin(int pin)
@@ -7400,8 +8106,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7400 return; 8106 return;
7401 } 8107 }
7402 8108
7403 // the rest of the permission checks are done in RezScript, so check the pin there as well 8109 SceneObjectPart dest = World.GetSceneObjectPart(destId);
7404 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 8110 if (dest != null)
8111 {
8112 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
8113 {
8114 // the rest of the permission checks are done in RezScript, so check the pin there as well
8115 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
8116
8117 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
8118 m_host.Inventory.RemoveInventoryItem(item.ItemID);
8119 }
8120 }
8121 // this will cause the delay even if the script pin or permissions were wrong - seems ok
8122 ScriptSleep(m_sleepMsOnRemoteLoadScriptPin);
7405 } 8123 }
7406 8124
7407 public void llOpenRemoteDataChannel() 8125 public void llOpenRemoteDataChannel()
@@ -7432,12 +8150,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7432 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams("remote_data", resobj, 8150 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams("remote_data", resobj,
7433 new DetectParams[0])); 8151 new DetectParams[0]));
7434 } 8152 }
8153 ScriptSleep(m_sleepMsOnOpenRemoteDataChannel);
7435 } 8154 }
7436 8155
7437 public LSL_String llSendRemoteData(string channel, string dest, int idata, string sdata) 8156 public LSL_String llSendRemoteData(string channel, string dest, int idata, string sdata)
7438 { 8157 {
7439 m_host.AddScriptLPS(1); 8158 m_host.AddScriptLPS(1);
7440 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); 8159 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
8160 ScriptSleep(m_sleepMsOnSendRemoteData);
7441 if (xmlrpcMod == null) 8161 if (xmlrpcMod == null)
7442 return ""; 8162 return "";
7443 return (xmlrpcMod.SendRemoteData(m_host.LocalId, m_item.ItemID, channel, dest, idata, sdata)).ToString(); 8163 return (xmlrpcMod.SendRemoteData(m_host.LocalId, m_item.ItemID, channel, dest, idata, sdata)).ToString();
@@ -7449,6 +8169,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7449 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); 8169 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
7450 if (xmlrpcMod != null) 8170 if (xmlrpcMod != null)
7451 xmlrpcMod.RemoteDataReply(channel, message_id, sdata, idata); 8171 xmlrpcMod.RemoteDataReply(channel, message_id, sdata, idata);
8172 ScriptSleep(m_sleepMsOnRemoteDataReply);
7452 } 8173 }
7453 8174
7454 public void llCloseRemoteDataChannel(string channel) 8175 public void llCloseRemoteDataChannel(string channel)
@@ -7464,24 +8185,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7464 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); 8185 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
7465 if (xmlrpcMod != null) 8186 if (xmlrpcMod != null)
7466 xmlrpcMod.CloseXMLRPCChannel((UUID)channel); 8187 xmlrpcMod.CloseXMLRPCChannel((UUID)channel);
8188 ScriptSleep(m_sleepMsOnCloseRemoteDataChannel);
7467 } 8189 }
7468 8190
7469 public LSL_String llMD5String(string src, int nonce) 8191 public LSL_String llMD5String(string src, int nonce)
7470 { 8192 {
7471 m_host.AddScriptLPS(1); 8193 m_host.AddScriptLPS(1);
7472 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 8194 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
7473 } 8195 }
7474 8196
7475 public LSL_String llSHA1String(string src) 8197 public LSL_String llSHA1String(string src)
7476 { 8198 {
7477 m_host.AddScriptLPS(1); 8199 m_host.AddScriptLPS(1);
7478 return Util.SHA1Hash(src).ToLower(); 8200 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
7479 } 8201 }
7480 8202
7481 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 8203 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
7482 { 8204 {
7483 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 8205 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7484 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 8206 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
8207 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8208 return shapeBlock;
7485 8209
7486 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 8210 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
7487 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 8211 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -7586,6 +8310,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7586 // Prim type box, cylinder and prism. 8310 // 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) 8311 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 { 8312 {
8313 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8314 return;
8315
7589 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 8316 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7590 ObjectShapePacket.ObjectDataBlock shapeBlock; 8317 ObjectShapePacket.ObjectDataBlock shapeBlock;
7591 8318
@@ -7639,6 +8366,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7639 // Prim type sphere. 8366 // 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) 8367 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7641 { 8368 {
8369 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8370 return;
8371
7642 ObjectShapePacket.ObjectDataBlock shapeBlock; 8372 ObjectShapePacket.ObjectDataBlock shapeBlock;
7643 8373
7644 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 8374 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7685,6 +8415,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7685 // Prim type torus, tube and ring. 8415 // 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) 8416 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 { 8417 {
8418 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8419 return;
8420
7688 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 8421 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7689 ObjectShapePacket.ObjectDataBlock shapeBlock; 8422 ObjectShapePacket.ObjectDataBlock shapeBlock;
7690 8423
@@ -7820,6 +8553,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7820 // Prim type sculpt. 8553 // Prim type sculpt.
7821 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 8554 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7822 { 8555 {
8556 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8557 return;
8558
7823 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 8559 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7824 UUID sculptId; 8560 UUID sculptId;
7825 8561
@@ -7842,7 +8578,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7842 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 8578 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7843 { 8579 {
7844 // default 8580 // default
7845 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 8581 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7846 } 8582 }
7847 8583
7848 part.Shape.SetSculptProperties((byte)type, sculptId); 8584 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7855,6 +8591,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7855 m_host.AddScriptLPS(1); 8591 m_host.AddScriptLPS(1);
7856 8592
7857 SetLinkPrimParams(ScriptBaseClass.LINK_THIS, rules, "llSetPrimitiveParams"); 8593 SetLinkPrimParams(ScriptBaseClass.LINK_THIS, rules, "llSetPrimitiveParams");
8594
8595 ScriptSleep(m_sleepMsOnSetPrimitiveParams);
7858 } 8596 }
7859 8597
7860 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 8598 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
@@ -7862,6 +8600,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7862 m_host.AddScriptLPS(1); 8600 m_host.AddScriptLPS(1);
7863 8601
7864 SetLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 8602 SetLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
8603
8604 ScriptSleep(m_sleepMsOnSetLinkPrimitiveParams);
7865 } 8605 }
7866 8606
7867 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 8607 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
@@ -7871,9 +8611,51 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7871 SetLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 8611 SetLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7872 } 8612 }
7873 8613
7874 protected void SetLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 8614 private void SetLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7875 { 8615 {
7876 SetEntityParams(GetLinkEntities(linknumber), rules, originFunc); 8616 List<object> parts = new List<object>();
8617 List<SceneObjectPart> prims = GetLinkParts(linknumber);
8618 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
8619 foreach (SceneObjectPart p in prims)
8620 parts.Add(p);
8621 foreach (ScenePresence p in avatars)
8622 parts.Add(p);
8623
8624 LSL_List remaining = new LSL_List();
8625 uint rulesParsed = 0;
8626
8627 if (parts.Count > 0)
8628 {
8629 foreach (object part in parts)
8630 {
8631 if (part is SceneObjectPart)
8632 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
8633 else
8634 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
8635 }
8636
8637 while (remaining.Length > 2)
8638 {
8639 linknumber = remaining.GetLSLIntegerItem(0);
8640 rules = remaining.GetSublist(1, -1);
8641 parts.Clear();
8642 prims = GetLinkParts(linknumber);
8643 avatars = GetLinkAvatars(linknumber);
8644 foreach (SceneObjectPart p in prims)
8645 parts.Add(p);
8646 foreach (ScenePresence p in avatars)
8647 parts.Add(p);
8648
8649 remaining = new LSL_List();
8650 foreach (object part in parts)
8651 {
8652 if (part is SceneObjectPart)
8653 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
8654 else
8655 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
8656 }
8657 }
8658 }
7877 } 8659 }
7878 8660
7879 protected void SetEntityParams(List<ISceneEntity> entities, LSL_List rules, string originFunc) 8661 protected void SetEntityParams(List<ISceneEntity> entities, LSL_List rules, string originFunc)
@@ -8052,11 +8834,81 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8052 } 8834 }
8053 } 8835 }
8054 8836
8837 public LSL_List llGetPhysicsMaterial()
8838 {
8839 LSL_List result = new LSL_List();
8840
8841 result.Add(new LSL_Float(m_host.GravityModifier));
8842 result.Add(new LSL_Float(m_host.Restitution));
8843 result.Add(new LSL_Float(m_host.Friction));
8844 result.Add(new LSL_Float(m_host.Density));
8845
8846 return result;
8847 }
8848
8849 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
8850 float material_density, float material_friction,
8851 float material_restitution, float material_gravity_modifier)
8852 {
8853 ExtraPhysicsData physdata = new ExtraPhysicsData();
8854 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
8855 physdata.Density = part.Density;
8856 physdata.Friction = part.Friction;
8857 physdata.Bounce = part.Restitution;
8858 physdata.GravitationModifier = part.GravityModifier;
8859
8860 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
8861 physdata.Density = material_density;
8862 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
8863 physdata.Friction = material_friction;
8864 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
8865 physdata.Bounce = material_restitution;
8866 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
8867 physdata.GravitationModifier = material_gravity_modifier;
8868
8869 part.UpdateExtraPhysics(physdata);
8870 }
8871
8872 public void llSetPhysicsMaterial(int material_bits,
8873 LSL_Float material_gravity_modifier, LSL_Float material_restitution,
8874 LSL_Float material_friction, LSL_Float material_density)
8875 {
8876 SetPhysicsMaterial(m_host, material_bits, (float)material_density, (float)material_friction, (float)material_restitution, (float)material_gravity_modifier);
8877 }
8878
8879 // vector up using libomv (c&p from sop )
8880 // vector up rotated by r
8881 private Vector3 Zrot(Quaternion r)
8882 {
8883 double x, y, z, m;
8884
8885 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
8886 if (Math.Abs(1.0 - m) > 0.000001)
8887 {
8888 m = 1.0 / Math.Sqrt(m);
8889 r.X *= (float)m;
8890 r.Y *= (float)m;
8891 r.Z *= (float)m;
8892 r.W *= (float)m;
8893 }
8894
8895 x = 2 * (r.X * r.Z + r.Y * r.W);
8896 y = 2 * (-r.X * r.W + r.Y * r.Z);
8897 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
8898
8899 return new Vector3((float)x, (float)y, (float)z);
8900 }
8901
8055 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 8902 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
8056 { 8903 {
8904 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8905 return new LSL_List();
8906
8057 int idx = 0; 8907 int idx = 0;
8058 int idxStart = 0; 8908 int idxStart = 0;
8059 8909
8910 SceneObjectGroup parentgrp = part.ParentGroup;
8911
8060 bool positionChanged = false; 8912 bool positionChanged = false;
8061 LSL_Vector currentPosition = GetPartLocalPos(part); 8913 LSL_Vector currentPosition = GetPartLocalPos(part);
8062 8914
@@ -8092,8 +8944,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)); 8944 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(); 8945 return new LSL_List();
8094 } 8946 }
8947 if (part.IsRoot && !part.ParentGroup.IsAttachment)
8948 currentPosition = GetSetPosTarget(part, v, currentPosition, true);
8949 else
8950 currentPosition = GetSetPosTarget(part, v, currentPosition, false);
8095 positionChanged = true; 8951 positionChanged = true;
8096 currentPosition = GetSetPosTarget(part, v, currentPosition);
8097 8952
8098 break; 8953 break;
8099 case ScriptBaseClass.PRIM_SIZE: 8954 case ScriptBaseClass.PRIM_SIZE:
@@ -8118,7 +8973,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8118 return new LSL_List(); 8973 return new LSL_List();
8119 } 8974 }
8120 // try to let this work as in SL... 8975 // try to let this work as in SL...
8121 if (part.ParentID == 0) 8976 if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart))
8122 { 8977 {
8123 // special case: If we are root, rotate complete SOG to new rotation 8978 // special case: If we are root, rotate complete SOG to new rotation
8124 SetRot(part, q); 8979 SetRot(part, q);
@@ -9119,7 +9974,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9119 9974
9120 break; 9975 break;
9121 9976
9122 case ScriptBaseClass.PRIM_TEMP_ON_REZ: 9977 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
9978 if (remain < 5)
9979 return new LSL_List();
9980
9981 int material_bits = rules.GetLSLIntegerItem(idx++);
9982 float material_density = (float)rules.GetLSLFloatItem(idx++);
9983 float material_friction = (float)rules.GetLSLFloatItem(idx++);
9984 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
9985 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
9986
9987 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
9988
9989 break;
9990
9991 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
9123 if (remain < 1) 9992 if (remain < 1)
9124 return new LSL_List(); 9993 return new LSL_List();
9125 string temp = rules.Data[idx++].ToString(); 9994 string temp = rules.Data[idx++].ToString();
@@ -9290,6 +10159,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9290 part.UpdateSlice((float)slice.x, (float)slice.y); 10159 part.UpdateSlice((float)slice.x, (float)slice.y);
9291 break; 10160 break;
9292 10161
10162 case ScriptBaseClass.PRIM_SIT_TARGET:
10163 if (remain < 3)
10164 return new LSL_List();
10165
10166 int active;
10167 try
10168 {
10169 active = rules.GetLSLIntegerItem(idx++);
10170 }
10171 catch(InvalidCastException)
10172 {
10173 Error(originFunc, string.Format("Error running rule #{0} -> PRIM_SIT_TARGET: arg #{1} - parameter 1 must be integer", rulesParsed, idx - idxStart - 1));
10174 return new LSL_List();
10175 }
10176 LSL_Vector offset;
10177 try
10178 {
10179 offset = rules.GetVector3Item(idx++);
10180 }
10181 catch(InvalidCastException)
10182 {
10183 Error(originFunc, string.Format("Error running rule #{0} -> PRIM_SIT_TARGET: arg #{1} - parameter 2 must be vector", rulesParsed, idx - idxStart - 1));
10184 return new LSL_List();
10185 }
10186 LSL_Rotation sitrot;
10187 try
10188 {
10189 sitrot = rules.GetQuaternionItem(idx++);
10190 }
10191 catch(InvalidCastException)
10192 {
10193 Error(originFunc, string.Format("Error running rule #{0} -> PRIM_SIT_TARGET: arg #{1} - parameter 3 must be rotation", rulesParsed, idx - idxStart - 1));
10194 return new LSL_List();
10195 }
10196
10197 // not SL compatible since we don't have a independent flag to control active target but use the values of offset and rotation
10198 if(active == 1)
10199 {
10200 if(offset.x == 0 && offset.y == 0 && offset.z == 0 && sitrot.s == 1.0)
10201 offset.z = 1e-5f; // hack
10202 SitTarget(part,offset,sitrot);
10203 }
10204 else if(active == 0)
10205 SitTarget(part, Vector3.Zero , Quaternion.Identity);
10206
10207 break;
10208
9293 case ScriptBaseClass.PRIM_LINK_TARGET: 10209 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. 10210 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(); 10211 return new LSL_List();
@@ -9313,14 +10229,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9313 if (part.ParentGroup.RootPart == part) 10229 if (part.ParentGroup.RootPart == part)
9314 { 10230 {
9315 SceneObjectGroup parent = part.ParentGroup; 10231 SceneObjectGroup parent = part.ParentGroup;
9316 parent.UpdateGroupPosition(currentPosition); 10232// Util.FireAndForget(delegate(object x) {
10233 parent.UpdateGroupPosition(currentPosition);
10234// });
9317 } 10235 }
9318 else 10236 else
9319 { 10237 {
9320 part.OffsetPosition = currentPosition; 10238 part.OffsetPosition = currentPosition;
9321 SceneObjectGroup parent = part.ParentGroup; 10239// SceneObjectGroup parent = part.ParentGroup;
9322 parent.HasGroupChanged = true; 10240// parent.HasGroupChanged = true;
9323 parent.ScheduleGroupForTerseUpdate(); 10241// parent.ScheduleGroupForTerseUpdate();
10242 part.ScheduleTerseUpdate();
9324 } 10243 }
9325 } 10244 }
9326 } 10245 }
@@ -9368,7 +10287,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9368 } 10287 }
9369 break; 10288 break;
9370 10289
9371 case ScriptBaseClass.PRIM_ROTATION: 10290 case ScriptBaseClass.PRIM_ROTATION:
9372 if (remain < 1) 10291 if (remain < 1)
9373 return new LSL_List(); 10292 return new LSL_List();
9374 10293
@@ -9387,7 +10306,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9387 SceneObjectPart parentPart = sp.ParentPart; 10306 SceneObjectPart parentPart = sp.ParentPart;
9388 10307
9389 if (parentPart != null) 10308 if (parentPart != null)
9390 sp.Rotation = m_host.GetWorldRotation() * inRot; 10309 sp.Rotation = m_host.GetWorldRotation() * inRot;
9391 10310
9392 break; 10311 break;
9393 10312
@@ -9431,7 +10350,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9431 catch (InvalidCastException e) 10350 catch (InvalidCastException e)
9432 { 10351 {
9433 Error( 10352 Error(
9434 originFunc, 10353 originFunc,
9435 string.Format("Error running rule #{0}: arg #{1} - ", rulesParsed, idx - idxStart) + e.Message); 10354 string.Format("Error running rule #{0}: arg #{1} - ", rulesParsed, idx - idxStart) + e.Message);
9436 } 10355 }
9437 10356
@@ -9472,9 +10391,104 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9472 10391
9473 public LSL_String llXorBase64Strings(string str1, string str2) 10392 public LSL_String llXorBase64Strings(string str1, string str2)
9474 { 10393 {
10394 int padding = 0;
10395
10396 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
10397
10398 ScriptSleep(300);
9475 m_host.AddScriptLPS(1); 10399 m_host.AddScriptLPS(1);
9476 Deprecated("llXorBase64Strings", "Use llXorBase64 instead"); 10400
9477 return String.Empty; 10401 if (str1 == String.Empty)
10402 return String.Empty;
10403 if (str2 == String.Empty)
10404 return str1;
10405
10406 int len = str2.Length;
10407 if ((len % 4) != 0) // LL is EVIL!!!!
10408 {
10409 while (str2.EndsWith("="))
10410 str2 = str2.Substring(0, str2.Length - 1);
10411
10412 len = str2.Length;
10413 int mod = len % 4;
10414
10415 if (mod == 1)
10416 str2 = str2.Substring(0, str2.Length - 1);
10417 else if (mod == 2)
10418 str2 += "==";
10419 else if (mod == 3)
10420 str2 += "=";
10421 }
10422
10423 byte[] data1;
10424 byte[] data2;
10425 try
10426 {
10427 data1 = Convert.FromBase64String(str1);
10428 data2 = Convert.FromBase64String(str2);
10429 }
10430 catch (Exception)
10431 {
10432 return new LSL_String(String.Empty);
10433 }
10434
10435 // For cases where the decoded length of s2 is greater
10436 // than the decoded length of s1, simply perform a normal
10437 // decode and XOR
10438 //
10439 /*
10440 if (data2.Length >= data1.Length)
10441 {
10442 for (int pos = 0 ; pos < data1.Length ; pos++ )
10443 data1[pos] ^= data2[pos];
10444
10445 return Convert.ToBase64String(data1);
10446 }
10447 */
10448
10449 // Remove padding
10450 while (str1.EndsWith("="))
10451 {
10452 str1 = str1.Substring(0, str1.Length - 1);
10453 padding++;
10454 }
10455 while (str2.EndsWith("="))
10456 str2 = str2.Substring(0, str2.Length - 1);
10457
10458 byte[] d1 = new byte[str1.Length];
10459 byte[] d2 = new byte[str2.Length];
10460
10461 for (int i = 0 ; i < str1.Length ; i++)
10462 {
10463 int idx = b64.IndexOf(str1.Substring(i, 1));
10464 if (idx == -1)
10465 idx = 0;
10466 d1[i] = (byte)idx;
10467 }
10468
10469 for (int i = 0 ; i < str2.Length ; i++)
10470 {
10471 int idx = b64.IndexOf(str2.Substring(i, 1));
10472 if (idx == -1)
10473 idx = 0;
10474 d2[i] = (byte)idx;
10475 }
10476
10477 string output = String.Empty;
10478
10479 for (int pos = 0 ; pos < d1.Length ; pos++)
10480 output += b64[d1[pos] ^ d2[pos % d2.Length]];
10481
10482 // Here's a funny thing: LL blithely violate the base64
10483 // standard pretty much everywhere. Here, padding is
10484 // added only if the first input string had it, rather
10485 // than when the data actually needs it. This can result
10486 // in invalid base64 being returned. Go figure.
10487
10488 while (padding-- > 0)
10489 output += "=";
10490
10491 return output;
9478 } 10492 }
9479 10493
9480 public void llRemoteDataSetRegion() 10494 public void llRemoteDataSetRegion()
@@ -9520,6 +10534,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9520 return; 10534 return;
9521 10535
9522 land.SetMusicUrl(url); 10536 land.SetMusicUrl(url);
10537
10538 ScriptSleep(m_sleepMsOnSetParcelMusicURL);
9523 } 10539 }
9524 10540
9525 public LSL_String llGetParcelMusicURL() 10541 public LSL_String llGetParcelMusicURL()
@@ -9615,188 +10631,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9615 public LSL_List llGetBoundingBox(string obj) 10631 public LSL_List llGetBoundingBox(string obj)
9616 { 10632 {
9617 m_host.AddScriptLPS(1); 10633 m_host.AddScriptLPS(1);
9618
9619 // Get target avatar if non-seated avatar or attachment, or prim and object
9620 UUID objID = UUID.Zero; 10634 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(); 10635 LSL_List result = new LSL_List();
9646 int groupCount = 0; 10636
9647 int partCount = 0; 10637 // If the ID is not valid, return null result
9648 int vertexCount = 0; 10638 if (!UUID.TryParse(obj, out objID))
9649 if (target == null && agent == null)
9650 { 10639 {
9651 result.Add(new LSL_Vector()); 10640 result.Add(new LSL_Vector());
9652 result.Add(new LSL_Vector()); 10641 result.Add(new LSL_Vector());
9653 if (m_addStatsInGetBoundingBox)
9654 result.Add(new LSL_Vector((float)groupCount, (float)partCount, (float)vertexCount));
9655 return result; 10642 return result;
9656 } 10643 }
9657 Vector3 minPosition = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
9658 Vector3 maxPosition = new Vector3(float.MinValue, float.MinValue, float.MinValue);
9659 10644
9660 // Try to get a mesher 10645 // Check if this is an attached prim. If so, replace
9661 IRendering primMesher = null; 10646 // the UUID with the avatar UUID and report it's bounding box
9662 List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); 10647 SceneObjectPart part = World.GetSceneObjectPart(objID);
9663 if (renderers.Count > 0) 10648 if (part != null && part.ParentGroup.IsAttachment)
9664 primMesher = RenderingLoader.LoadRenderer(renderers[0]); 10649 objID = part.ParentGroup.AttachedAvatar;
9665 10650
9666 // Get bounding box of just avatar, seated or not 10651 // Find out if this is an avatar ID. If so, return it's box
9667 if (agent != null) 10652 ScenePresence presence = World.GetScenePresence(objID);
9668 { 10653 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 { 10654 {
9690 // Merge bounding boxes of all parts (prims and mesh) 10655 // As per LSL Wiki, there is no difference between sitting
9691 foreach (SceneObjectPart part in group.Parts) 10656 // and standing avatar since server 1.36
9692 { 10657 LSL_Vector lower;
9693 bool hasParent = (!part.IsRoot); 10658 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 10659
9743 // When part is prim 10660 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 10661
9754 // When all else fails, try fallback to simple box 10662 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
9755 else 10663 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
9756 { 10664/*
9757 AddBoundingBoxOfSimpleBox(part.Scale * -0.5f, part.Scale * 0.5f, part.OffsetPosition, part.RotationOffset, hasParent, ref minPosition, ref maxPosition, ref vertexCount); 10665 {
9758 } 10666 // This is for ground sitting avatars
9759 } 10667 float height = presence.Appearance.AvatarHeight / 2.66666667f;
9760 partCount++; 10668 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
10669 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
10670 }
10671 else
10672 {
10673 // This is for standing/flying avatars
10674 float height = presence.Appearance.AvatarHeight / 2.0f;
10675 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
10676 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
9761 } 10677 }
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 10678
9772 bool hasParent = true; 10679 // Adjust to the documented error offsets (see LSL Wiki)
9773 // When requested or if no mesher, keep it simple 10680 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
9774 if (m_useSimpleBoxesInGetBoundingBox || primMesher == null) 10681 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
10682*/
9775 { 10683 {
9776 AddBoundingBoxOfSimpleBox(lower, upper, offset, sp.Rotation, hasParent, ref minPosition, ref maxPosition, ref vertexCount); 10684 // This is for ground sitting avatars TODO!
10685 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
10686 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
9777 } 10687 }
9778 // Do the full mounty
9779 else 10688 else
9780 { 10689 {
9781 // Prim shapes don't do center offsets, so add it here. 10690 // This is for standing/flying avatars
9782 offset = offset + (lower + upper) * 0.5f * sp.Rotation; 10691 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
9783 Primitive omvPrim = MakeOpenMetaversePrim(upper - lower, offset, sp.Rotation, ScriptBaseClass.PRIM_TYPE_SPHERE); 10692 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 } 10693 }
9788 partCount++; 10694
10695 if (lower.x > upper.x)
10696 lower.x = upper.x;
10697 if (lower.y > upper.y)
10698 lower.y = upper.y;
10699 if (lower.z > upper.z)
10700 lower.z = upper.z;
10701
10702 result.Add(lower);
10703 result.Add(upper);
10704 return result;
9789 } 10705 }
9790 10706
9791 groupCount++; 10707 part = World.GetSceneObjectPart(objID);
10708 // Currently only works for single prims without a sitting avatar
10709 if (part != null)
10710 {
10711 float minX;
10712 float maxX;
10713 float minY;
10714 float maxY;
10715 float minZ;
10716 float maxZ;
9792 10717
9793 // Return lower and upper bounding box corners 10718 // This BBox is in sim coordinates, with the offset being
9794 result.Add(new LSL_Vector(minPosition)); 10719 // a contained point.
9795 result.Add(new LSL_Vector(maxPosition)); 10720 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
9796 if (m_addStatsInGetBoundingBox) 10721 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
9797 result.Add(new LSL_Vector((float)groupCount, (float)partCount, (float)vertexCount)); 10722
10723 minX -= offsets[0].X;
10724 maxX -= offsets[0].X;
10725 minY -= offsets[0].Y;
10726 maxY -= offsets[0].Y;
10727 minZ -= offsets[0].Z;
10728 maxZ -= offsets[0].Z;
10729
10730 LSL_Vector lower;
10731 LSL_Vector upper;
10732
10733 // Adjust to the documented error offsets (see LSL Wiki)
10734 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
10735 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
10736
10737 if (lower.x > upper.x)
10738 lower.x = upper.x;
10739 if (lower.y > upper.y)
10740 lower.y = upper.y;
10741 if (lower.z > upper.z)
10742 lower.z = upper.z;
10743
10744 result.Add(lower);
10745 result.Add(upper);
10746 return result;
10747 }
9798 10748
9799 primMesher = null; 10749 // Not found so return empty values
10750 result.Add(new LSL_Vector());
10751 result.Add(new LSL_Vector());
9800 return result; 10752 return result;
9801 } 10753 }
9802 10754
@@ -9836,430 +10788,80 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9836 } 10788 }
9837 } 10789 }
9838 10790
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 10791
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() 10792 public LSL_Vector llGetGeometricCenter()
10026 { 10793 {
10027 // Subtract whatever position the root prim has to make it zero 10794 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 } 10795 }
10041 10796
10042 public LSL_List GetEntityParams(ISceneEntity entity, LSL_List rules) 10797 public LSL_List llGetPrimitiveParams(LSL_List rules)
10043 { 10798 {
10044 LSL_List result = new LSL_List(); 10799 m_host.AddScriptLPS(1);
10045 LSL_List remaining;
10046
10047 while (true)
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 10800
10056 if (entity is SceneObjectPart) 10801 LSL_List result = new LSL_List();
10057 remaining = GetPrimParams((SceneObjectPart)entity, rules, ref result);
10058 else
10059 remaining = GetAgentParams((ScenePresence)entity, rules, ref result);
10060 10802
10061 if (remaining == null || remaining.Length < 2) 10803 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
10062 return result;
10063 10804
10805 while ((object)remaining != null && remaining.Length > 2)
10806 {
10064 int linknumber = remaining.GetLSLIntegerItem(0); 10807 int linknumber = remaining.GetLSLIntegerItem(0);
10065 rules = remaining.GetSublist(1, -1); 10808 rules = remaining.GetSublist(1, -1);
10066 entity = GetLinkEntity(m_host, linknumber); 10809 List<SceneObjectPart> parts = GetLinkParts(linknumber);
10067 }
10068 }
10069 10810
10070 public LSL_List llGetPrimitiveParams(LSL_List rules) 10811 foreach (SceneObjectPart part in parts)
10071 { 10812 remaining = GetPrimParams(part, rules, ref result);
10072 m_host.AddScriptLPS(1); 10813 }
10073 10814
10074 return GetEntityParams(m_host, rules); 10815 return result;
10075 } 10816 }
10076 10817
10077 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) 10818 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules)
10078 { 10819 {
10079 m_host.AddScriptLPS(1); 10820 m_host.AddScriptLPS(1);
10080 10821
10081 return GetEntityParams(GetLinkEntity(m_host, linknumber), rules); 10822 // acording to SL wiki this must indicate a single link number or link_root or link_this.
10082 } 10823 // keep other options as before
10083 10824
10084 public LSL_Vector GetAgentSize(ScenePresence sp) 10825 List<SceneObjectPart> parts;
10085 { 10826 List<ScenePresence> avatars;
10086 return new LSL_Vector(0.45, 0.6, sp.Appearance.AvatarHeight);
10087 }
10088 10827
10089 /// <summary> 10828 LSL_List res = new LSL_List();
10090 /// Gets params for a seated avatar in a linkset. 10829 LSL_List remaining = new LSL_List();
10091 /// </summary> 10830
10092 /// <returns></returns> 10831 while (rules.Length > 0)
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 { 10832 {
10101 int code = (int)rules.GetLSLIntegerItem(idx++); 10833 parts = GetLinkParts(linknumber);
10102 int remain = rules.Length-idx; 10834 avatars = GetLinkAvatars(linknumber);
10103 10835
10104 switch (code) 10836 remaining = new LSL_List();
10837 foreach (SceneObjectPart part in parts)
10105 { 10838 {
10106 case (int)ScriptBaseClass.PRIM_MATERIAL: 10839 remaining = GetPrimParams(part, rules, ref res);
10107 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MATERIAL_FLESH)); 10840 }
10108 break; 10841 foreach (ScenePresence avatar in avatars)
10109 10842 {
10110 case (int)ScriptBaseClass.PRIM_PHYSICS: 10843 remaining = GetPrimParams(avatar, rules, ref res);
10111 res.Add(ScriptBaseClass.FALSE); 10844 }
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 10845
10253 return rules.GetSublist(idx, -1); 10846 if (remaining.Length > 0)
10847 {
10848 linknumber = remaining.GetLSLIntegerItem(0);
10849 rules = remaining.GetSublist(1, -1);
10254 } 10850 }
10851 else
10852 break;
10255 } 10853 }
10256 10854
10257 return new LSL_List(); 10855 return res;
10258 } 10856 }
10259 10857
10260 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res) 10858 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res)
10261 { 10859 {
10262 int idx = 0; 10860 int idx = 0;
10861 int face;
10862 Primitive.TextureEntry tex;
10863 int nsides = GetNumberOfSides(part);
10864
10263 while (idx < rules.Length) 10865 while (idx < rules.Length)
10264 { 10866 {
10265 int code = (int)rules.GetLSLIntegerItem(idx++); 10867 int code = (int)rules.GetLSLIntegerItem(idx++);
@@ -10293,19 +10895,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10293 break; 10895 break;
10294 10896
10295 case (int)ScriptBaseClass.PRIM_POSITION: 10897 case (int)ScriptBaseClass.PRIM_POSITION:
10296 LSL_Vector v = new LSL_Vector(part.AbsolutePosition); 10898 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
10297 10899 part.AbsolutePosition.Y,
10298 // For some reason, the part.AbsolutePosition.* values do not change if the 10900 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); 10901 res.Add(v);
10310 break; 10902 break;
10311 10903
@@ -10410,11 +11002,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10410 if (remain < 1) 11002 if (remain < 1)
10411 return new LSL_List(); 11003 return new LSL_List();
10412 11004
10413 int face = (int)rules.GetLSLIntegerItem(idx++); 11005 face = (int)rules.GetLSLIntegerItem(idx++);
10414 Primitive.TextureEntry tex = part.Shape.Textures; 11006 tex = part.Shape.Textures;
11007
10415 if (face == ScriptBaseClass.ALL_SIDES) 11008 if (face == ScriptBaseClass.ALL_SIDES)
10416 { 11009 {
10417 for (face = 0 ; face < GetNumberOfSides(part); face++) 11010 for (face = 0; face < nsides; face++)
10418 { 11011 {
10419 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 11012 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
10420 11013
@@ -10430,7 +11023,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10430 } 11023 }
10431 else 11024 else
10432 { 11025 {
10433 if (face >= 0 && face < GetNumberOfSides(part)) 11026 if (face >= 0 && face < nsides)
10434 { 11027 {
10435 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 11028 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
10436 11029
@@ -10450,13 +11043,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10450 if (remain < 1) 11043 if (remain < 1)
10451 return new LSL_List(); 11044 return new LSL_List();
10452 11045
10453 face=(int)rules.GetLSLIntegerItem(idx++); 11046 face = (int)rules.GetLSLIntegerItem(idx++);
10454
10455 tex = part.Shape.Textures; 11047 tex = part.Shape.Textures;
10456 Color4 texcolor; 11048 Color4 texcolor;
11049
10457 if (face == ScriptBaseClass.ALL_SIDES) 11050 if (face == ScriptBaseClass.ALL_SIDES)
10458 { 11051 {
10459 for (face = 0 ; face < GetNumberOfSides(part); face++) 11052 for (face = 0; face < nsides; face++)
10460 { 11053 {
10461 texcolor = tex.GetFace((uint)face).RGBA; 11054 texcolor = tex.GetFace((uint)face).RGBA;
10462 res.Add(new LSL_Vector(texcolor.R, 11055 res.Add(new LSL_Vector(texcolor.R,
@@ -10476,61 +11069,100 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10476 break; 11069 break;
10477 11070
10478 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 11071 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
11072 {
10479 if (remain < 1) 11073 if (remain < 1)
10480 return new LSL_List(); 11074 return new LSL_List();
10481 11075
10482 face=(int)rules.GetLSLIntegerItem(idx++); 11076 face = (int)rules.GetLSLIntegerItem(idx++);
10483
10484 tex = part.Shape.Textures; 11077 tex = part.Shape.Textures;
11078 int shiny;
10485 if (face == ScriptBaseClass.ALL_SIDES) 11079 if (face == ScriptBaseClass.ALL_SIDES)
10486 { 11080 {
10487 for (face = 0; face < GetNumberOfSides(part); face++) 11081 for (face = 0; face < nsides; face++)
10488 { 11082 {
10489 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 11083 Shininess shinyness = tex.GetFace((uint)face).Shiny;
10490 // Convert Shininess to PRIM_SHINY_* 11084 if (shinyness == Shininess.High)
10491 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 11085 {
10492 // PRIM_BUMP_* 11086 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
10493 res.Add(new LSL_Integer((int)texface.Bump)); 11087 }
11088 else if (shinyness == Shininess.Medium)
11089 {
11090 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
11091 }
11092 else if (shinyness == Shininess.Low)
11093 {
11094 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
11095 }
11096 else
11097 {
11098 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
11099 }
11100 res.Add(new LSL_Integer(shiny));
11101 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
10494 } 11102 }
10495 } 11103 }
10496 else 11104 else
10497 { 11105 {
10498 if (face >= 0 && face < GetNumberOfSides(part)) 11106 Shininess shinyness = tex.GetFace((uint)face).Shiny;
11107 if (shinyness == Shininess.High)
10499 { 11108 {
10500 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 11109 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
10501 // Convert Shininess to PRIM_SHINY_* 11110 }
10502 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 11111 else if (shinyness == Shininess.Medium)
10503 // PRIM_BUMP_* 11112 {
10504 res.Add(new LSL_Integer((int)texface.Bump)); 11113 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
11114 }
11115 else if (shinyness == Shininess.Low)
11116 {
11117 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
11118 }
11119 else
11120 {
11121 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
10505 } 11122 }
11123 res.Add(new LSL_Integer(shiny));
11124 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
10506 } 11125 }
10507 break; 11126 break;
10508 11127 }
10509 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 11128 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
11129 {
10510 if (remain < 1) 11130 if (remain < 1)
10511 return new LSL_List(); 11131 return new LSL_List();
10512 11132
10513 face = (int)rules.GetLSLIntegerItem(idx++); 11133 face = (int)rules.GetLSLIntegerItem(idx++);
10514 11134
10515 tex = part.Shape.Textures; 11135 tex = part.Shape.Textures;
11136 int fullbright;
10516 if (face == ScriptBaseClass.ALL_SIDES) 11137 if (face == ScriptBaseClass.ALL_SIDES)
10517 { 11138 {
10518 for (face = 0; face < GetNumberOfSides(part); face++) 11139 for (face = 0; face < nsides; face++)
10519 { 11140 {
10520 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 11141 if (tex.GetFace((uint)face).Fullbright == true)
10521 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 11142 {
11143 fullbright = ScriptBaseClass.TRUE;
11144 }
11145 else
11146 {
11147 fullbright = ScriptBaseClass.FALSE;
11148 }
11149 res.Add(new LSL_Integer(fullbright));
10522 } 11150 }
10523 } 11151 }
10524 else 11152 else
10525 { 11153 {
10526 if (face >= 0 && face < GetNumberOfSides(part)) 11154 if (tex.GetFace((uint)face).Fullbright == true)
10527 { 11155 {
10528 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 11156 fullbright = ScriptBaseClass.TRUE;
10529 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
10530 } 11157 }
11158 else
11159 {
11160 fullbright = ScriptBaseClass.FALSE;
11161 }
11162 res.Add(new LSL_Integer(fullbright));
10531 } 11163 }
10532 break; 11164 break;
10533 11165 }
10534 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 11166 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
10535 PrimitiveBaseShape shape = part.Shape; 11167 PrimitiveBaseShape shape = part.Shape;
10536 11168
@@ -10549,27 +11181,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10549 break; 11181 break;
10550 11182
10551 case (int)ScriptBaseClass.PRIM_TEXGEN: 11183 case (int)ScriptBaseClass.PRIM_TEXGEN:
11184 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
10552 if (remain < 1) 11185 if (remain < 1)
10553 return new LSL_List(); 11186 return new LSL_List();
10554 11187
10555 face=(int)rules.GetLSLIntegerItem(idx++); 11188 face = (int)rules.GetLSLIntegerItem(idx++);
10556 11189
10557 tex = part.Shape.Textures; 11190 tex = part.Shape.Textures;
10558 if (face == ScriptBaseClass.ALL_SIDES) 11191 if (face == ScriptBaseClass.ALL_SIDES)
10559 { 11192 {
10560 for (face = 0; face < GetNumberOfSides(part); face++) 11193 for (face = 0; face < nsides; face++)
10561 { 11194 {
10562 MappingType texgen = tex.GetFace((uint)face).TexMapType; 11195 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
10563 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 11196 {
10564 res.Add(new LSL_Integer((uint)texgen >> 1)); 11197 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
11198 }
11199 else
11200 {
11201 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
11202 }
10565 } 11203 }
10566 } 11204 }
10567 else 11205 else
10568 { 11206 {
10569 if (face >= 0 && face < GetNumberOfSides(part)) 11207 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
11208 {
11209 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
11210 }
11211 else
10570 { 11212 {
10571 MappingType texgen = tex.GetFace((uint)face).TexMapType; 11213 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
10572 res.Add(new LSL_Integer((uint)texgen >> 1));
10573 } 11214 }
10574 } 11215 }
10575 break; 11216 break;
@@ -10593,24 +11234,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10593 if (remain < 1) 11234 if (remain < 1)
10594 return new LSL_List(); 11235 return new LSL_List();
10595 11236
10596 face=(int)rules.GetLSLIntegerItem(idx++); 11237 face = (int)rules.GetLSLIntegerItem(idx++);
10597 11238
10598 tex = part.Shape.Textures; 11239 tex = part.Shape.Textures;
11240 float primglow;
10599 if (face == ScriptBaseClass.ALL_SIDES) 11241 if (face == ScriptBaseClass.ALL_SIDES)
10600 { 11242 {
10601 for (face = 0; face < GetNumberOfSides(part); face++) 11243 for (face = 0; face < nsides; face++)
10602 { 11244 {
10603 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 11245 primglow = tex.GetFace((uint)face).Glow;
10604 res.Add(new LSL_Float(texface.Glow)); 11246 res.Add(new LSL_Float(primglow));
10605 } 11247 }
10606 } 11248 }
10607 else 11249 else
10608 { 11250 {
10609 if (face >= 0 && face < GetNumberOfSides(part)) 11251 primglow = tex.GetFace((uint)face).Glow;
10610 { 11252 res.Add(new LSL_Float(primglow));
10611 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
10612 res.Add(new LSL_Float(texface.Glow));
10613 }
10614 } 11253 }
10615 break; 11254 break;
10616 11255
@@ -10620,17 +11259,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10620 res.Add(new LSL_Vector(textColor.R, 11259 res.Add(new LSL_Vector(textColor.R,
10621 textColor.G, 11260 textColor.G,
10622 textColor.B)); 11261 textColor.B));
10623 res.Add(new LSL_Float(1.0 - textColor.A)); 11262 res.Add(new LSL_Float(textColor.A));
10624 break; 11263 break;
11264
10625 case (int)ScriptBaseClass.PRIM_NAME: 11265 case (int)ScriptBaseClass.PRIM_NAME:
10626 res.Add(new LSL_String(part.Name)); 11266 res.Add(new LSL_String(part.Name));
10627 break; 11267 break;
11268
10628 case (int)ScriptBaseClass.PRIM_DESC: 11269 case (int)ScriptBaseClass.PRIM_DESC:
10629 res.Add(new LSL_String(part.Description)); 11270 res.Add(new LSL_String(part.Description));
10630 break; 11271 break;
10631 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 11272 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
10632 res.Add(new LSL_Rotation(part.RotationOffset)); 11273 res.Add(new LSL_Rotation(part.RotationOffset));
10633 break; 11274 break;
11275
10634 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 11276 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
10635 res.Add(new LSL_Vector(GetPartLocalPos(part))); 11277 res.Add(new LSL_Vector(GetPartLocalPos(part)));
10636 break; 11278 break;
@@ -10643,6 +11285,71 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10643 0 11285 0
10644 )); 11286 ));
10645 break; 11287 break;
11288
11289 case (int)ScriptBaseClass.PRIM_OMEGA:
11290 // this may return values diferent from SL since we don't handle set the same way
11291 float gain = 1.0f; // we don't use gain and don't store it
11292 Vector3 axis = part.AngularVelocity;
11293 float spin = axis.Length();
11294 if(spin < 1.0e-6)
11295 {
11296 axis = Vector3.Zero;
11297 gain = 0.0f;
11298 spin = 0.0f;
11299 }
11300 else
11301 {
11302 axis = axis * (1.0f/spin);
11303 }
11304
11305 res.Add(new LSL_Vector(axis.X,
11306 axis.Y,
11307 axis.Z));
11308 res.Add(new LSL_Float(spin));
11309 res.Add(new LSL_Float(gain));
11310 break;
11311
11312 case (int)ScriptBaseClass.PRIM_SIT_TARGET:
11313 if(part.IsSitTargetSet)
11314 {
11315 res.Add(new LSL_Integer(1));
11316 res.Add(new LSL_Vector(part.SitTargetPosition));
11317 res.Add(new LSL_Rotation(part.SitTargetOrientation));
11318 }
11319 else
11320 {
11321 res.Add(new LSL_Integer(0));
11322 res.Add(new LSL_Vector(Vector3.Zero));
11323 res.Add(new LSL_Rotation(Quaternion.Identity));
11324 }
11325 break;
11326
11327 case (int)ScriptBaseClass.PRIM_NORMAL:
11328 case (int)ScriptBaseClass.PRIM_SPECULAR:
11329 case (int)ScriptBaseClass.PRIM_ALPHA_MODE:
11330 if (remain < 1)
11331 return new LSL_List();
11332
11333 face = (int)rules.GetLSLIntegerItem(idx++);
11334 tex = part.Shape.Textures;
11335 if (face == ScriptBaseClass.ALL_SIDES)
11336 {
11337 for (face = 0; face < nsides; face++)
11338 {
11339 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
11340 getLSLFaceMaterial(ref res, code, part, texface);
11341 }
11342 }
11343 else
11344 {
11345 if (face >= 0 && face < nsides)
11346 {
11347 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
11348 getLSLFaceMaterial(ref res, code, part, texface);
11349 }
11350 }
11351 break;
11352
10646 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 11353 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
10647 11354
10648 // TODO: Should be issuing a runtime script warning in this case. 11355 // TODO: Should be issuing a runtime script warning in this case.
@@ -10656,15 +11363,120 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10656 return new LSL_List(); 11363 return new LSL_List();
10657 } 11364 }
10658 11365
11366/*
11367 private string filterTextureUUIDbyRights(UUID origID, SceneObjectPart part, bool checkTaskInventory, bool returnInvName)
11368 {
11369 if(checkTaskInventory)
11370 {
11371 lock (part.TaskInventory)
11372 {
11373 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in part.TaskInventory)
11374 {
11375 if (inv.Value.AssetID == origID)
11376 {
11377 if(inv.Value.InvType == (int)InventoryType.Texture)
11378 {
11379 if(returnInvName)
11380 return inv.Value.Name;
11381 else
11382 return origID.ToString();
11383 }
11384 else
11385 return UUID.Zero.ToString();
11386 }
11387 }
11388 }
11389 }
11390
11391 if(World.Permissions.CanEditObject(m_host.ParentGroup.UUID, m_host.ParentGroup.RootPart.OwnerID))
11392 return origID.ToString();
11393
11394 return UUID.Zero.ToString();
11395 }
11396*/
11397 private void getLSLFaceMaterial(ref LSL_List res, int code, SceneObjectPart part, Primitive.TextureEntryFace texface)
11398 {
11399 UUID matID = texface.MaterialID;
11400 if(matID != UUID.Zero)
11401 {
11402 AssetBase MatAsset = World.AssetService.Get(matID.ToString());
11403 if(MatAsset != null)
11404 {
11405 Byte[] data = MatAsset.Data;
11406 OSDMap osdmat = (OSDMap)OSDParser.DeserializeLLSDXml(data);
11407 if(osdmat != null && osdmat.ContainsKey("NormMap"))
11408 {
11409 string mapIDstr;
11410 FaceMaterial mat = new FaceMaterial(matID, osdmat);
11411 if(code == ScriptBaseClass.PRIM_NORMAL)
11412 {
11413// mapIDstr = filterTextureUUIDbyRights(mat.NormalMapID, part, true, false);
11414 mapIDstr = mat.NormalMapID.ToString();
11415 res.Add(new LSL_String(mapIDstr));
11416 res.Add(new LSL_Vector(mat.NormalRepeatX, mat.NormalRepeatY, 0));
11417 res.Add(new LSL_Vector(mat.NormalOffsetX, mat.NormalOffsetY, 0));
11418 res.Add(new LSL_Float(mat.NormalRotation));
11419 }
11420 else if(code == ScriptBaseClass.PRIM_SPECULAR )
11421 {
11422// mapIDstr = filterTextureUUIDbyRights(mat.SpecularMapID, part, true, false);
11423 const float colorScale = 1.0f/255f;
11424 mapIDstr = mat.SpecularMapID.ToString();
11425 res.Add(new LSL_String(mapIDstr));
11426 res.Add(new LSL_Vector(mat.SpecularRepeatX, mat.SpecularRepeatY, 0));
11427 res.Add(new LSL_Vector(mat.SpecularOffsetX, mat.SpecularOffsetY, 0));
11428 res.Add(new LSL_Float(mat.SpecularRotation));
11429 res.Add(new LSL_Vector(mat.SpecularLightColor.R * colorScale,
11430 mat.SpecularLightColor.G * colorScale,
11431 mat.SpecularLightColor.B * colorScale));
11432 res.Add(new LSL_Integer(mat.SpecularLightExponent));
11433 res.Add(new LSL_Integer(mat.EnvironmentIntensity));
11434 }
11435 else if(code == ScriptBaseClass.PRIM_ALPHA_MODE)
11436 {
11437 res.Add(new LSL_Integer(mat.DiffuseAlphaMode));
11438 res.Add(new LSL_Integer(mat.AlphaMaskCutoff));
11439 }
11440 return;
11441 }
11442 }
11443 matID = UUID.Zero;
11444 }
11445 if(matID == UUID.Zero)
11446 {
11447 if(code == (int)ScriptBaseClass.PRIM_NORMAL || code == (int)ScriptBaseClass.PRIM_SPECULAR )
11448 {
11449 res.Add(new LSL_String(UUID.Zero.ToString()));
11450 res.Add(new LSL_Vector(1.0, 1.0, 0));
11451 res.Add(new LSL_Vector(0, 0, 0));
11452 res.Add(new LSL_Float(0));
11453
11454 if(code == (int)ScriptBaseClass.PRIM_SPECULAR)
11455 {
11456 res.Add(new LSL_Vector(1.0, 1.0, 1.0));
11457 res.Add(new LSL_Integer(51));
11458 res.Add(new LSL_Integer(0));
11459 }
11460 }
11461 else if(code == (int)ScriptBaseClass.PRIM_ALPHA_MODE)
11462 {
11463 res.Add(new LSL_Integer(1));
11464 res.Add(new LSL_Integer(0));
11465 }
11466 }
11467 }
11468
10659 public LSL_List llGetPrimMediaParams(int face, LSL_List rules) 11469 public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
10660 { 11470 {
10661 m_host.AddScriptLPS(1); 11471 m_host.AddScriptLPS(1);
11472 ScriptSleep(m_sleepMsOnGetPrimMediaParams);
10662 return GetPrimMediaParams(m_host, face, rules); 11473 return GetPrimMediaParams(m_host, face, rules);
10663 } 11474 }
10664 11475
10665 public LSL_List llGetLinkMedia(LSL_Integer link, LSL_Integer face, LSL_List rules) 11476 public LSL_List llGetLinkMedia(LSL_Integer link, LSL_Integer face, LSL_List rules)
10666 { 11477 {
10667 m_host.AddScriptLPS(1); 11478 m_host.AddScriptLPS(1);
11479 ScriptSleep(m_sleepMsOnGetLinkMedia);
10668 if (link == ScriptBaseClass.LINK_ROOT) 11480 if (link == ScriptBaseClass.LINK_ROOT)
10669 return GetPrimMediaParams(m_host.ParentGroup.RootPart, face, rules); 11481 return GetPrimMediaParams(m_host.ParentGroup.RootPart, face, rules);
10670 else if (link == ScriptBaseClass.LINK_THIS) 11482 else if (link == ScriptBaseClass.LINK_THIS)
@@ -10784,12 +11596,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10784 public LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules) 11596 public LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules)
10785 { 11597 {
10786 m_host.AddScriptLPS(1); 11598 m_host.AddScriptLPS(1);
11599 ScriptSleep(m_sleepMsOnSetPrimMediaParams);
10787 return SetPrimMediaParams(m_host, face, rules); 11600 return SetPrimMediaParams(m_host, face, rules);
10788 } 11601 }
10789 11602
10790 public LSL_Integer llSetLinkMedia(LSL_Integer link, LSL_Integer face, LSL_List rules) 11603 public LSL_Integer llSetLinkMedia(LSL_Integer link, LSL_Integer face, LSL_List rules)
10791 { 11604 {
10792 m_host.AddScriptLPS(1); 11605 m_host.AddScriptLPS(1);
11606 ScriptSleep(m_sleepMsOnSetLinkMedia);
10793 if (link == ScriptBaseClass.LINK_ROOT) 11607 if (link == ScriptBaseClass.LINK_ROOT)
10794 return SetPrimMediaParams(m_host.ParentGroup.RootPart, face, rules); 11608 return SetPrimMediaParams(m_host.ParentGroup.RootPart, face, rules);
10795 else if (link == ScriptBaseClass.LINK_THIS) 11609 else if (link == ScriptBaseClass.LINK_THIS)
@@ -10908,12 +11722,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10908 public LSL_Integer llClearPrimMedia(LSL_Integer face) 11722 public LSL_Integer llClearPrimMedia(LSL_Integer face)
10909 { 11723 {
10910 m_host.AddScriptLPS(1); 11724 m_host.AddScriptLPS(1);
11725 ScriptSleep(m_sleepMsOnClearPrimMedia);
10911 return ClearPrimMedia(m_host, face); 11726 return ClearPrimMedia(m_host, face);
10912 } 11727 }
10913 11728
10914 public LSL_Integer llClearLinkMedia(LSL_Integer link, LSL_Integer face) 11729 public LSL_Integer llClearLinkMedia(LSL_Integer link, LSL_Integer face)
10915 { 11730 {
10916 m_host.AddScriptLPS(1); 11731 m_host.AddScriptLPS(1);
11732 ScriptSleep(m_sleepMsOnClearLinkMedia);
10917 if (link == ScriptBaseClass.LINK_ROOT) 11733 if (link == ScriptBaseClass.LINK_ROOT)
10918 return ClearPrimMedia(m_host.ParentGroup.RootPart, face); 11734 return ClearPrimMedia(m_host.ParentGroup.RootPart, face);
10919 else if (link == ScriptBaseClass.LINK_THIS) 11735 else if (link == ScriptBaseClass.LINK_THIS)
@@ -11237,8 +12053,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11237 // The function returns an ordered list 12053 // The function returns an ordered list
11238 // representing the tokens found in the supplied 12054 // representing the tokens found in the supplied
11239 // sources string. If two successive tokenizers 12055 // sources string. If two successive tokenizers
11240 // are encountered, then a NULL entry is added 12056 // are encountered, then a null-string entry is
11241 // to the list. 12057 // added to the list.
11242 // 12058 //
11243 // It is a precondition that the source and 12059 // It is a precondition that the source and
11244 // toekizer lisst are non-null. If they are null, 12060 // toekizer lisst are non-null. If they are null,
@@ -11246,7 +12062,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11246 // while their lengths are being determined. 12062 // while their lengths are being determined.
11247 // 12063 //
11248 // A small amount of working memoryis required 12064 // A small amount of working memoryis required
11249 // of approximately 8*#tokenizers. 12065 // of approximately 8*#tokenizers + 8*srcstrlen.
11250 // 12066 //
11251 // There are many ways in which this function 12067 // There are many ways in which this function
11252 // can be implemented, this implementation is 12068 // can be implemented, this implementation is
@@ -11262,155 +12078,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11262 // and eliminates redundant tokenizers as soon 12078 // and eliminates redundant tokenizers as soon
11263 // as is possible. 12079 // as is possible.
11264 // 12080 //
11265 // The implementation tries to avoid any copying 12081 // The implementation tries to minimize temporary
11266 // of arrays or other objects. 12082 // garbage generation.
11267 // </remarks> 12083 // </remarks>
11268 12084
11269 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 12085 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
11270 { 12086 {
11271 int beginning = 0; 12087 return ParseString2List(src, separators, spacers, true);
11272 int srclen = src.Length; 12088 }
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 12089
11287 LSL_List tokens = new LSL_List(); 12090 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
12091 {
12092 int srclen = src.Length;
12093 int seplen = separators.Length;
12094 object[] separray = separators.Data;
12095 int spclen = spacers.Length;
12096 object[] spcarray = spacers.Data;
12097 int dellen = 0;
12098 string[] delarray = new string[seplen+spclen];
11288 12099
11289 // All entries are initially valid 12100 int outlen = 0;
12101 string[] outarray = new string[srclen*2+1];
11290 12102
11291 for (int i = 0; i < mlen; i++) 12103 int i, j;
11292 active[i] = true; 12104 string d;
11293 12105
11294 offset[mlen] = srclen; 12106 m_host.AddScriptLPS(1);
11295 12107
11296 while (beginning < srclen) 12108 /*
12109 * Convert separator and spacer lists to C# strings.
12110 * Also filter out null strings so we don't hang.
12111 */
12112 for (i = 0; i < seplen; i ++)
11297 { 12113 {
12114 d = separray[i].ToString();
12115 if (d.Length > 0)
12116 {
12117 delarray[dellen++] = d;
12118 }
12119 }
12120 seplen = dellen;
11298 12121
11299 best = mlen; // as bad as it gets 12122 for (i = 0; i < spclen; i ++)
12123 {
12124 d = spcarray[i].ToString();
12125 if (d.Length > 0)
12126 {
12127 delarray[dellen++] = d;
12128 }
12129 }
11300 12130
11301 // Scan for separators 12131 /*
12132 * Scan through source string from beginning to end.
12133 */
12134 for (i = 0;;)
12135 {
11302 12136
11303 for (j = 0; j < seplen; j++) 12137 /*
12138 * Find earliest delimeter in src starting at i (if any).
12139 */
12140 int earliestDel = -1;
12141 int earliestSrc = srclen;
12142 string earliestStr = null;
12143 for (j = 0; j < dellen; j ++)
11304 { 12144 {
11305 if (separray[j].ToString() == String.Empty) 12145 d = delarray[j];
11306 active[j] = false; 12146 if (d != null)
11307
11308 if (active[j])
11309 { 12147 {
11310 // scan all of the markers 12148 int index = src.IndexOf(d, i);
11311 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 12149 if (index < 0)
11312 { 12150 {
11313 // not present at all 12151 delarray[j] = null; // delim nowhere in src, don't check it anymore
11314 active[j] = false;
11315 } 12152 }
11316 else 12153 else if (index < earliestSrc)
11317 { 12154 {
11318 // present and correct 12155 earliestSrc = index; // where delimeter starts in source string
11319 if (offset[j] < offset[best]) 12156 earliestDel = j; // where delimeter is in delarray[]
11320 { 12157 earliestStr = d; // the delimeter string from delarray[]
11321 // closest so far 12158 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 } 12159 }
11327 } 12160 }
11328 } 12161 }
11329 12162
11330 // Scan for spacers 12163 /*
11331 12164 * Output source string starting at i through start of earliest delimeter.
11332 if (offset[best] != beginning) 12165 */
12166 if (keepNulls || (earliestSrc > i))
11333 { 12167 {
11334 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 12168 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 } 12169 }
11359 12170
11360 // This is the normal exit from the scanning loop 12171 /*
12172 * If no delimeter found at or after i, we're done scanning.
12173 */
12174 if (earliestDel < 0) break;
11361 12175
11362 if (best == mlen) 12176 /*
12177 * If delimeter was a spacer, output the spacer.
12178 */
12179 if (earliestDel >= seplen)
11363 { 12180 {
11364 // no markers were found on this pass 12181 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 } 12182 }
11370 12183
11371 // Otherwise we just add the newly delimited token 12184 /*
11372 // and recalculate where the search should continue. 12185 * Look at rest of src string following delimeter.
11373 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 12186 */
11374 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 12187 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 } 12188 }
11388 12189
11389 // This an awkward an not very intuitive boundary case. If the 12190 /*
11390 // last substring is a tokenizer, then there is an implied trailing 12191 * 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 12192 */
11392 // arduous. Alternatively the 'break' could be replced with a return 12193 object[] outlist = new object[outlen];
11393 // but that's shabby programming. 12194 for (i = 0; i < outlen; i ++)
11394
11395 if ((beginning == srclen) && (keepNulls))
11396 { 12195 {
11397 if (srclen != 0) 12196 outlist[i] = new LSL_String(outarray[i]);
11398 tokens.Add(new LSL_String(""));
11399 } 12197 }
11400 12198 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 } 12199 }
11415 12200
11416 public LSL_Integer llGetObjectPermMask(int mask) 12201 public LSL_Integer llGetObjectPermMask(int mask)
@@ -11453,7 +12238,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11453 12238
11454 if (m_ScriptEngine.Config.GetBoolean("AllowGodFunctions", false)) 12239 if (m_ScriptEngine.Config.GetBoolean("AllowGodFunctions", false))
11455 { 12240 {
11456 if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID)) 12241 if (World.Permissions.IsAdministrator(m_host.OwnerID))
11457 { 12242 {
11458 if (mask == ScriptBaseClass.MASK_BASE)//0 12243 if (mask == ScriptBaseClass.MASK_BASE)//0
11459 { 12244 {
@@ -11515,7 +12300,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11515 12300
11516 if (m_ScriptEngine.Config.GetBoolean("AllowGodFunctions", false)) 12301 if (m_ScriptEngine.Config.GetBoolean("AllowGodFunctions", false))
11517 { 12302 {
11518 if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID)) 12303 if (World.Permissions.IsAdministrator(m_host.OwnerID))
11519 { 12304 {
11520 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName); 12305 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName);
11521 12306
@@ -11574,7 +12359,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11574 { 12359 {
11575 m_host.AddScriptLPS(1); 12360 m_host.AddScriptLPS(1);
11576 if (m_UrlModule != null) 12361 if (m_UrlModule != null)
11577 return m_UrlModule.RequestSecureURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID).ToString(); 12362 return m_UrlModule.RequestSecureURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID, null).ToString();
11578 return UUID.Zero.ToString(); 12363 return UUID.Zero.ToString();
11579 } 12364 }
11580 12365
@@ -11600,6 +12385,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11600 case ScriptBaseClass.DATA_SIM_POS: 12385 case ScriptBaseClass.DATA_SIM_POS:
11601 if (info == null) 12386 if (info == null)
11602 { 12387 {
12388 ScriptSleep(m_sleepMsOnRequestSimulatorData);
11603 return UUID.Zero.ToString(); 12389 return UUID.Zero.ToString();
11604 } 12390 }
11605 12391
@@ -11646,6 +12432,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11646 case ScriptBaseClass.DATA_SIM_RATING: 12432 case ScriptBaseClass.DATA_SIM_RATING:
11647 if (info == null) 12433 if (info == null)
11648 { 12434 {
12435 ScriptSleep(m_sleepMsOnRequestSimulatorData);
11649 return UUID.Zero.ToString(); 12436 return UUID.Zero.ToString();
11650 } 12437 }
11651 int access = info.Maturity; 12438 int access = info.Maturity;
@@ -11660,14 +12447,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11660 break; 12447 break;
11661 case ScriptBaseClass.DATA_SIM_RELEASE: 12448 case ScriptBaseClass.DATA_SIM_RELEASE:
11662 if (ossl != null) 12449 if (ossl != null)
11663 { 12450 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"; 12451 reply = "OpenSim";
11669 break; 12452 break;
11670 default: 12453 default:
12454 ScriptSleep(m_sleepMsOnRequestSimulatorData);
11671 return UUID.Zero.ToString(); // Raise no event 12455 return UUID.Zero.ToString(); // Raise no event
11672 } 12456 }
11673 UUID rq = UUID.Random(); 12457 UUID rq = UUID.Random();
@@ -11678,6 +12462,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11678 AsyncCommands. 12462 AsyncCommands.
11679 DataserverPlugin.DataserverReply(rq.ToString(), reply); 12463 DataserverPlugin.DataserverReply(rq.ToString(), reply);
11680 12464
12465 ScriptSleep(m_sleepMsOnRequestSimulatorData);
11681 return tid.ToString(); 12466 return tid.ToString();
11682 } 12467 }
11683 catch(Exception) 12468 catch(Exception)
@@ -11692,7 +12477,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11692 m_host.AddScriptLPS(1); 12477 m_host.AddScriptLPS(1);
11693 12478
11694 if (m_UrlModule != null) 12479 if (m_UrlModule != null)
11695 return m_UrlModule.RequestURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID).ToString(); 12480 return m_UrlModule.RequestURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID, null).ToString();
11696 return UUID.Zero.ToString(); 12481 return UUID.Zero.ToString();
11697 } 12482 }
11698 12483
@@ -11708,31 +12493,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11708 UUID key = new UUID(); 12493 UUID key = new UUID();
11709 if (UUID.TryParse(id, out key)) 12494 if (UUID.TryParse(id, out key))
11710 { 12495 {
11711 try 12496 // return total object mass
11712 { 12497 SceneObjectPart part = World.GetSceneObjectPart(key);
11713 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 12498 if (part != null)
11714 if (obj != null) 12499 return part.ParentGroup.GetMass();
11715 return (double)obj.GetMass(); 12500
11716 // the object is null so the key is for an avatar 12501 // the object is null so the key is for an avatar
11717 ScenePresence avatar = World.GetScenePresence(key); 12502 ScenePresence avatar = World.GetScenePresence(key);
11718 if (avatar != null) 12503 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 { 12504 {
11728 return 0; // The Object/Agent not in the region so just return zero 12505 if (avatar.IsChildAgent)
12506 {
12507 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
12508 // child agents have a mass of 1.0
12509 return 1;
12510 }
12511 else
12512 {
12513 return (double)avatar.GetMass();
12514 }
11729 } 12515 }
11730 } 12516 }
11731 return 0; 12517 return 0;
11732 } 12518 }
11733 12519
11734 /// <summary> 12520 /// <summary>
11735 /// illListReplaceList removes the sub-list defined by the inclusive indices 12521 /// llListReplaceList removes the sub-list defined by the inclusive indices
11736 /// start and end and inserts the src list in its place. The inclusive 12522 /// 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 12523 /// 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 12524 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -11789,16 +12575,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11789 // based upon end. Note that if end exceeds the upper 12575 // based upon end. Note that if end exceeds the upper
11790 // bound in this case, the entire destination list 12576 // bound in this case, the entire destination list
11791 // is removed. 12577 // is removed.
11792 else 12578 else if (start == 0)
11793 { 12579 {
11794 if (end + 1 < dest.Length) 12580 if (end + 1 < dest.Length)
11795 {
11796 return src + dest.GetSublist(end + 1, -1); 12581 return src + dest.GetSublist(end + 1, -1);
11797 }
11798 else 12582 else
11799 {
11800 return src; 12583 return src;
11801 } 12584 }
12585 else // Start < 0
12586 {
12587 if (end + 1 < dest.Length)
12588 return dest.GetSublist(end + 1, -1);
12589 else
12590 return new LSL_List();
11802 } 12591 }
11803 } 12592 }
11804 // Finally, if start > end, we strip away a prefix and 12593 // Finally, if start > end, we strip away a prefix and
@@ -11821,6 +12610,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11821 if (null != dm) 12610 if (null != dm)
11822 dm.SendUrlToUser( 12611 dm.SendUrlToUser(
11823 new UUID(avatar_id), m_host.Name, m_host.UUID, m_host.OwnerID, false, message, url); 12612 new UUID(avatar_id), m_host.Name, m_host.UUID, m_host.OwnerID, false, message, url);
12613
12614 ScriptSleep(m_sleepMsOnLoadURL);
11824 } 12615 }
11825 12616
11826 public void llParcelMediaCommandList(LSL_List commandList) 12617 public void llParcelMediaCommandList(LSL_List commandList)
@@ -11833,7 +12624,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11833 // according to the docs, this command only works if script owner and land owner are the same 12624 // 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. 12625 // lets add estate owners and gods, too, and use the generic permission check.
11835 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 12626 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
11836 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return; 12627 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia, false)) return;
11837 12628
11838 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? 12629 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)?
11839 byte loop = 0; 12630 byte loop = 0;
@@ -12051,18 +12842,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12051 if (sp.currentParcelUUID == landData.GlobalID) 12842 if (sp.currentParcelUUID == landData.GlobalID)
12052 { 12843 {
12053 sp.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this? 12844 sp.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this?
12054 (ParcelMediaCommandEnum)commandToSend, 12845 (ParcelMediaCommandEnum)commandToSend, time);
12055 time);
12056 } 12846 }
12057 }); 12847 });
12058 } 12848 }
12059 else if (!presence.IsChildAgent) 12849 else if (!presence.IsChildAgent)
12060 { 12850 {
12061 presence.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this? 12851 presence.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this?
12062 (ParcelMediaCommandEnum)commandToSend, 12852 (ParcelMediaCommandEnum)commandToSend, time);
12063 time);
12064 } 12853 }
12065 } 12854 }
12855 ScriptSleep(m_sleepMsOnParcelMediaCommandList);
12066 } 12856 }
12067 12857
12068 public LSL_List llParcelMediaQuery(LSL_List aList) 12858 public LSL_List llParcelMediaQuery(LSL_List aList)
@@ -12076,7 +12866,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12076 12866
12077 if (aList.Data[i] != null) 12867 if (aList.Data[i] != null)
12078 { 12868 {
12079 switch ((ParcelMediaCommandEnum) aList.Data[i]) 12869 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
12080 { 12870 {
12081 case ParcelMediaCommandEnum.Url: 12871 case ParcelMediaCommandEnum.Url:
12082 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 12872 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -12102,6 +12892,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12102 12892
12103 } 12893 }
12104 } 12894 }
12895 ScriptSleep(m_sleepMsOnParcelMediaQuery);
12105 return list; 12896 return list;
12106 } 12897 }
12107 12898
@@ -12110,6 +12901,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12110 m_host.AddScriptLPS(1); 12901 m_host.AddScriptLPS(1);
12111 Int64 tmp = 0; 12902 Int64 tmp = 0;
12112 Math.DivRem(Convert.ToInt64(Math.Pow(a, b)), c, out tmp); 12903 Math.DivRem(Convert.ToInt64(Math.Pow(a, b)), c, out tmp);
12904 ScriptSleep(m_sleepMsOnModPow);
12113 return Convert.ToInt32(tmp); 12905 return Convert.ToInt32(tmp);
12114 } 12906 }
12115 12907
@@ -12131,15 +12923,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12131 12923
12132 if (quick_pay_buttons.Data.Length < 4) 12924 if (quick_pay_buttons.Data.Length < 4)
12133 { 12925 {
12134 Error("llSetPayPrice", "List must have at least 4 elements"); 12926 int x;
12135 return; 12927 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
12928 {
12929 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
12930 }
12136 } 12931 }
12137 m_host.ParentGroup.RootPart.PayPrice[0]=price; 12932 int[] nPrice = new int[5];
12138 12933 nPrice[0] = price;
12139 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 12934 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
12140 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 12935 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
12141 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 12936 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
12142 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 12937 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
12938 m_host.ParentGroup.RootPart.PayPrice = nPrice;
12143 m_host.ParentGroup.HasGroupChanged = true; 12939 m_host.ParentGroup.HasGroupChanged = true;
12144 } 12940 }
12145 12941
@@ -12156,7 +12952,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12156 return Vector3.Zero; 12952 return Vector3.Zero;
12157 } 12953 }
12158 12954
12159 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 12955// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
12956 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
12160 if (presence != null) 12957 if (presence != null)
12161 { 12958 {
12162 LSL_Vector pos = new LSL_Vector(presence.CameraPosition); 12959 LSL_Vector pos = new LSL_Vector(presence.CameraPosition);
@@ -12179,7 +12976,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12179 return Quaternion.Identity; 12976 return Quaternion.Identity;
12180 } 12977 }
12181 12978
12182 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 12979// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
12980 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
12183 if (presence != null) 12981 if (presence != null)
12184 { 12982 {
12185 return new LSL_Rotation(presence.CameraRotation); 12983 return new LSL_Rotation(presence.CameraRotation);
@@ -12192,12 +12990,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12192 { 12990 {
12193 m_host.AddScriptLPS(1); 12991 m_host.AddScriptLPS(1);
12194 Deprecated("llSetPrimURL", "Use llSetPrimMediaParams instead"); 12992 Deprecated("llSetPrimURL", "Use llSetPrimMediaParams instead");
12993 ScriptSleep(m_sleepMsOnSetPrimURL);
12195 } 12994 }
12196 12995
12197 public void llRefreshPrimURL() 12996 public void llRefreshPrimURL()
12198 { 12997 {
12199 m_host.AddScriptLPS(1); 12998 m_host.AddScriptLPS(1);
12200 Deprecated("llRefreshPrimURL"); 12999 Deprecated("llRefreshPrimURL");
13000 ScriptSleep(m_sleepMsOnRefreshPrimURL);
12201 } 13001 }
12202 13002
12203 public LSL_String llEscapeURL(string url) 13003 public LSL_String llEscapeURL(string url)
@@ -12230,7 +13030,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12230 { 13030 {
12231 m_host.AddScriptLPS(1); 13031 m_host.AddScriptLPS(1);
12232 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 13032 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
12233 if (detectedParams == null) return; // only works on the first detected avatar 13033 if (detectedParams == null)
13034 {
13035 if (m_host.ParentGroup.IsAttachment == true)
13036 {
13037 detectedParams = new DetectParams();
13038 detectedParams.Key = m_host.OwnerID;
13039 }
13040 else
13041 {
13042 return;
13043 }
13044 }
12234 13045
12235 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 13046 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
12236 if (avatar != null) 13047 if (avatar != null)
@@ -12238,6 +13049,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12238 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 13049 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
12239 simname, pos, lookAt); 13050 simname, pos, lookAt);
12240 } 13051 }
13052 ScriptSleep(m_sleepMsOnMapDestination);
12241 } 13053 }
12242 13054
12243 public void llAddToLandBanList(string avatar, double hours) 13055 public void llAddToLandBanList(string avatar, double hours)
@@ -12245,7 +13057,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12245 m_host.AddScriptLPS(1); 13057 m_host.AddScriptLPS(1);
12246 UUID key; 13058 UUID key;
12247 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 13059 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
12248 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 13060 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned, false))
12249 { 13061 {
12250 int expires = 0; 13062 int expires = 0;
12251 if (hours != 0) 13063 if (hours != 0)
@@ -12278,6 +13090,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12278 World.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land); 13090 World.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land);
12279 } 13091 }
12280 } 13092 }
13093 ScriptSleep(m_sleepMsOnAddToLandBanList);
12281 } 13094 }
12282 13095
12283 public void llRemoveFromLandPassList(string avatar) 13096 public void llRemoveFromLandPassList(string avatar)
@@ -12285,7 +13098,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12285 m_host.AddScriptLPS(1); 13098 m_host.AddScriptLPS(1);
12286 UUID key; 13099 UUID key;
12287 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 13100 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
12288 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed)) 13101 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManagePasses, false))
12289 { 13102 {
12290 if (UUID.TryParse(avatar, out key)) 13103 if (UUID.TryParse(avatar, out key))
12291 { 13104 {
@@ -12304,6 +13117,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12304 } 13117 }
12305 } 13118 }
12306 } 13119 }
13120 ScriptSleep(m_sleepMsOnRemoveFromLandPassList);
12307 } 13121 }
12308 13122
12309 public void llRemoveFromLandBanList(string avatar) 13123 public void llRemoveFromLandBanList(string avatar)
@@ -12311,7 +13125,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12311 m_host.AddScriptLPS(1); 13125 m_host.AddScriptLPS(1);
12312 UUID key; 13126 UUID key;
12313 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 13127 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
12314 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 13128 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned, false))
12315 { 13129 {
12316 if (UUID.TryParse(avatar, out key)) 13130 if (UUID.TryParse(avatar, out key))
12317 { 13131 {
@@ -12330,6 +13144,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12330 } 13144 }
12331 } 13145 }
12332 } 13146 }
13147 ScriptSleep(m_sleepMsOnRemoveFromLandBanList);
12333 } 13148 }
12334 13149
12335 public void llSetCameraParams(LSL_List rules) 13150 public void llSetCameraParams(LSL_List rules)
@@ -12542,19 +13357,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12542 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 13357 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
12543 { 13358 {
12544 m_host.AddScriptLPS(1); 13359 m_host.AddScriptLPS(1);
12545 string ret = String.Empty; 13360
12546 string src1 = llBase64ToString(str1); 13361 if (str1 == String.Empty)
12547 string src2 = llBase64ToString(str2); 13362 return String.Empty;
12548 int c = 0; 13363 if (str2 == String.Empty)
12549 for (int i = 0; i < src1.Length; i++) 13364 return str1;
13365
13366 int len = str2.Length;
13367 if ((len % 4) != 0) // LL is EVIL!!!!
12550 { 13368 {
12551 ret += (char) (src1[i] ^ src2[c]); 13369 while (str2.EndsWith("="))
13370 str2 = str2.Substring(0, str2.Length - 1);
13371
13372 len = str2.Length;
13373 int mod = len % 4;
12552 13374
12553 c++; 13375 if (mod == 1)
12554 if (c >= src2.Length) 13376 str2 = str2.Substring(0, str2.Length - 1);
12555 c = 0; 13377 else if (mod == 2)
13378 str2 += "==";
13379 else if (mod == 3)
13380 str2 += "=";
12556 } 13381 }
12557 return llStringToBase64(ret); 13382
13383 byte[] data1;
13384 byte[] data2;
13385 try
13386 {
13387 data1 = Convert.FromBase64String(str1);
13388 data2 = Convert.FromBase64String(str2);
13389 }
13390 catch (Exception)
13391 {
13392 return new LSL_String(String.Empty);
13393 }
13394
13395 byte[] d2 = new Byte[data1.Length];
13396 int pos = 0;
13397
13398 if (data1.Length <= data2.Length)
13399 {
13400 Array.Copy(data2, 0, d2, 0, data1.Length);
13401 }
13402 else
13403 {
13404 while (pos < data1.Length)
13405 {
13406 len = data1.Length - pos;
13407 if (len > data2.Length)
13408 len = data2.Length;
13409
13410 Array.Copy(data2, 0, d2, pos, len);
13411 pos += len;
13412 }
13413 }
13414
13415 for (pos = 0 ; pos < data1.Length ; pos++ )
13416 data1[pos] ^= d2[pos];
13417
13418 return Convert.ToBase64String(data1);
12558 } 13419 }
12559 13420
12560 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 13421 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -12570,6 +13431,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12570 List<string> param = new List<string>(); 13431 List<string> param = new List<string>();
12571 bool ok; 13432 bool ok;
12572 Int32 flag; 13433 Int32 flag;
13434 int nCustomHeaders = 0;
12573 13435
12574 for (int i = 0; i < parameters.Data.Length; i += 2) 13436 for (int i = 0; i < parameters.Data.Length; i += 2)
12575 { 13437 {
@@ -12596,6 +13458,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12596 //Second Life documentation for llHTTPRequest. 13458 //Second Life documentation for llHTTPRequest.
12597 for (int count = 1; count <= 8; ++count) 13459 for (int count = 1; count <= 8; ++count)
12598 { 13460 {
13461 if(nCustomHeaders >= 8)
13462 {
13463 Error("llHTTPRequest", "Max number of custom headers is 8, excess ignored");
13464 break;
13465 }
13466
12599 //Enough parameters remaining for (another) header? 13467 //Enough parameters remaining for (another) header?
12600 if (parameters.Data.Length - i < 2) 13468 if (parameters.Data.Length - i < 2)
12601 { 13469 {
@@ -12610,15 +13478,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12610 13478
12611 param.Add(parameters.Data[i].ToString()); 13479 param.Add(parameters.Data[i].ToString());
12612 param.Add(parameters.Data[i+1].ToString()); 13480 param.Add(parameters.Data[i+1].ToString());
13481 nCustomHeaders++;
12613 13482
12614 //Have we reached the end of the list of headers? 13483 //Have we reached the end of the list of headers?
12615 //End is marked by a string with a single digit. 13484 //End is marked by a string with a single digit.
12616 if (i+2 >= parameters.Data.Length || 13485 if (i + 2 >= parameters.Data.Length ||
12617 Char.IsDigit(parameters.Data[i].ToString()[0])) 13486 Char.IsDigit(parameters.Data[i + 2].ToString()[0]))
12618 { 13487 {
12619 break; 13488 break;
12620 } 13489 }
12621
12622 i += 2; 13490 i += 2;
12623 } 13491 }
12624 } 13492 }
@@ -12658,16 +13526,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12658 if (userAgent != null) 13526 if (userAgent != null)
12659 httpHeaders["User-Agent"] = userAgent; 13527 httpHeaders["User-Agent"] = userAgent;
12660 13528
13529 // See if the URL contains any header hacks
13530 string[] urlParts = url.Split(new char[] {'\n'});
13531 if (urlParts.Length > 1)
13532 {
13533 // Iterate the passed headers and parse them
13534 for (int i = 1 ; i < urlParts.Length ; i++ )
13535 {
13536 // The rest of those would be added to the body in SL.
13537 // Let's not do that.
13538 if (urlParts[i] == String.Empty)
13539 break;
13540
13541 // See if this could be a valid header
13542 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
13543 if (headerParts.Length != 2)
13544 continue;
13545
13546 string headerName = headerParts[0].Trim();
13547 string headerValue = headerParts[1].Trim();
13548
13549 // Filter out headers that could be used to abuse
13550 // another system or cloak the request
13551 if (headerName.ToLower() == "x-secondlife-shard" ||
13552 headerName.ToLower() == "x-secondlife-object-name" ||
13553 headerName.ToLower() == "x-secondlife-object-key" ||
13554 headerName.ToLower() == "x-secondlife-region" ||
13555 headerName.ToLower() == "x-secondlife-local-position" ||
13556 headerName.ToLower() == "x-secondlife-local-velocity" ||
13557 headerName.ToLower() == "x-secondlife-local-rotation" ||
13558 headerName.ToLower() == "x-secondlife-owner-name" ||
13559 headerName.ToLower() == "x-secondlife-owner-key" ||
13560 headerName.ToLower() == "connection" ||
13561 headerName.ToLower() == "content-length" ||
13562 headerName.ToLower() == "from" ||
13563 headerName.ToLower() == "host" ||
13564 headerName.ToLower() == "proxy-authorization" ||
13565 headerName.ToLower() == "referer" ||
13566 headerName.ToLower() == "trailer" ||
13567 headerName.ToLower() == "transfer-encoding" ||
13568 headerName.ToLower() == "via" ||
13569 headerName.ToLower() == "authorization")
13570 continue;
13571
13572 httpHeaders[headerName] = headerValue;
13573 }
13574
13575 // Finally, strip any protocol specifier from the URL
13576 url = urlParts[0].Trim();
13577 int idx = url.IndexOf(" HTTP/");
13578 if (idx != -1)
13579 url = url.Substring(0, idx);
13580 }
13581
12661 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 13582 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
12662 Regex r = new Regex(authregex); 13583 Regex r = new Regex(authregex);
12663 int[] gnums = r.GetGroupNumbers(); 13584 int[] gnums = r.GetGroupNumbers();
12664 Match m = r.Match(url); 13585 Match m = r.Match(url);
12665 if (m.Success) { 13586 if (m.Success)
12666 for (int i = 1; i < gnums.Length; i++) { 13587 {
13588 for (int i = 1; i < gnums.Length; i++)
13589 {
12667 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 13590 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
12668 //CaptureCollection cc = g.Captures; 13591 //CaptureCollection cc = g.Captures;
12669 } 13592 }
12670 if (m.Groups.Count == 5) { 13593 if (m.Groups.Count == 5)
13594 {
12671 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 13595 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(); 13596 url = m.Groups[1].ToString() + m.Groups[4].ToString();
12673 } 13597 }
@@ -12712,6 +13636,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12712 } 13636 }
12713 } 13637 }
12714 } 13638 }
13639 ScriptSleep(m_sleepMsOnResetLandBanList);
12715 } 13640 }
12716 13641
12717 public void llResetLandPassList() 13642 public void llResetLandPassList()
@@ -12728,6 +13653,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12728 } 13653 }
12729 } 13654 }
12730 } 13655 }
13656 ScriptSleep(m_sleepMsOnResetLandPassList);
12731 } 13657 }
12732 13658
12733 public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide) 13659 public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide)
@@ -12785,6 +13711,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12785 ret.Add(new LSL_Integer(detectedParams.Value)); 13711 ret.Add(new LSL_Integer(detectedParams.Value));
12786 } 13712 }
12787 } 13713 }
13714 ScriptSleep(m_sleepMsOnGetParcelPrimOwners);
12788 return ret; 13715 return ret;
12789 } 13716 }
12790 13717
@@ -12871,6 +13798,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12871 13798
12872 LSL_List ret = new LSL_List(); 13799 LSL_List ret = new LSL_List();
12873 UUID key = new UUID(); 13800 UUID key = new UUID();
13801
13802
12874 if (UUID.TryParse(id, out key)) 13803 if (UUID.TryParse(id, out key))
12875 { 13804 {
12876 ScenePresence av = World.GetScenePresence(key); 13805 ScenePresence av = World.GetScenePresence(key);
@@ -12888,13 +13817,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12888 ret.Add(new LSL_String("")); 13817 ret.Add(new LSL_String(""));
12889 break; 13818 break;
12890 case ScriptBaseClass.OBJECT_POS: 13819 case ScriptBaseClass.OBJECT_POS:
12891 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 13820 Vector3 avpos;
13821
13822 if (av.ParentID != 0 && av.ParentPart != null &&
13823 av.ParentPart.ParentGroup != null && av.ParentPart.ParentGroup.RootPart != null )
13824 {
13825 avpos = av.OffsetPosition;
13826
13827 if(!av.LegacySitOffsets)
13828 {
13829 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
13830 avpos -= sitOffset;
13831 }
13832
13833 SceneObjectPart sitRoot = av.ParentPart.ParentGroup.RootPart;
13834 avpos = sitRoot.GetWorldPosition() + avpos * sitRoot.GetWorldRotation();
13835 }
13836 else
13837 avpos = av.AbsolutePosition;
13838
13839 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
12892 break; 13840 break;
12893 case ScriptBaseClass.OBJECT_ROT: 13841 case ScriptBaseClass.OBJECT_ROT:
12894 ret.Add(new LSL_Rotation(av.GetWorldRotation())); 13842 Quaternion avrot = av.GetWorldRotation();
13843 ret.Add(new LSL_Rotation(avrot));
12895 break; 13844 break;
12896 case ScriptBaseClass.OBJECT_VELOCITY: 13845 case ScriptBaseClass.OBJECT_VELOCITY:
12897 ret.Add(new LSL_Vector(av.GetWorldVelocity())); 13846 Vector3 avvel = av.GetWorldVelocity();
13847 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
12898 break; 13848 break;
12899 case ScriptBaseClass.OBJECT_OWNER: 13849 case ScriptBaseClass.OBJECT_OWNER:
12900 ret.Add(new LSL_String(id)); 13850 ret.Add(new LSL_String(id));
@@ -12976,6 +13926,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12976 case ScriptBaseClass.OBJECT_LAST_OWNER_ID: 13926 case ScriptBaseClass.OBJECT_LAST_OWNER_ID:
12977 ret.Add(new LSL_Key(ScriptBaseClass.NULL_KEY)); 13927 ret.Add(new LSL_Key(ScriptBaseClass.NULL_KEY));
12978 break; 13928 break;
13929 case ScriptBaseClass.OBJECT_CLICK_ACTION:
13930 ret.Add(new LSL_Integer(0));
13931 break;
13932 case ScriptBaseClass.OBJECT_OMEGA:
13933 ret.Add(new LSL_Vector(Vector3.Zero));
13934 break;
13935 case ScriptBaseClass.OBJECT_PRIM_COUNT:
13936 List<SceneObjectGroup> Attachments = av.GetAttachments();
13937 int count = 0;
13938 try
13939 {
13940 foreach (SceneObjectGroup Attachment in Attachments)
13941 count += Attachment.PrimCount;
13942 } catch { };
13943 ret.Add(new LSL_Integer(count));
13944 break;
13945 case ScriptBaseClass.OBJECT_TOTAL_INVENTORY_COUNT:
13946 List<SceneObjectGroup> invAttachments = av.GetAttachments();
13947 int invcount = 0;
13948 try
13949 {
13950 foreach (SceneObjectGroup Attachment in invAttachments)
13951 {
13952 SceneObjectPart[] parts = Attachment.Parts;
13953 int nparts = parts.Count();
13954 for(int i = 0; i < nparts; i++)
13955 invcount += parts[i].Inventory.Count;
13956 }
13957 } catch { };
13958 ret.Add(new LSL_Integer(invcount));
13959 break;
13960 case ScriptBaseClass.OBJECT_REZZER_KEY:
13961 ret.Add(new LSL_Key(id));
13962 break;
13963 case ScriptBaseClass.OBJECT_GROUP_TAG:
13964 ret.Add(new LSL_String(av.Grouptitle));
13965 break;
13966 case ScriptBaseClass.OBJECT_TEMP_ATTACHED:
13967 ret.Add(new LSL_Integer(0));
13968 break;
12979 default: 13969 default:
12980 // Invalid or unhandled constant. 13970 // Invalid or unhandled constant.
12981 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); 13971 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL));
@@ -13000,7 +13990,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13000 ret.Add(new LSL_String(obj.Description)); 13990 ret.Add(new LSL_String(obj.Description));
13001 break; 13991 break;
13002 case ScriptBaseClass.OBJECT_POS: 13992 case ScriptBaseClass.OBJECT_POS:
13003 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 13993 Vector3 opos = obj.AbsolutePosition;
13994 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
13004 break; 13995 break;
13005 case ScriptBaseClass.OBJECT_ROT: 13996 case ScriptBaseClass.OBJECT_ROT:
13006 Quaternion rot = Quaternion.Identity; 13997 Quaternion rot = Quaternion.Identity;
@@ -13036,7 +14027,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13036 } 14027 }
13037 else 14028 else
13038 { 14029 {
13039 vel = obj.Velocity; 14030 vel = obj.Velocity;
13040 } 14031 }
13041 14032
13042 ret.Add(vel); 14033 ret.Add(vel);
@@ -13073,9 +14064,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13073 // The value returned in SL for normal prims is prim count 14064 // The value returned in SL for normal prims is prim count
13074 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 14065 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
13075 break; 14066 break;
13076 // The following 3 costs I have intentionaly coded to return zero. They are part of 14067
13077 // "Land Impact" calculations. These calculations are probably not applicable 14068 // 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: 14069 case ScriptBaseClass.OBJECT_SERVER_COST:
13080 // The linden calculation is here 14070 // The linden calculation is here
13081 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 14071 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -13083,16 +14073,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13083 ret.Add(new LSL_Float(0)); 14073 ret.Add(new LSL_Float(0));
13084 break; 14074 break;
13085 case ScriptBaseClass.OBJECT_STREAMING_COST: 14075 case ScriptBaseClass.OBJECT_STREAMING_COST:
13086 // The linden calculation is here 14076 // The value returned in SL for normal prims is prim count * 0.06
13087 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 14077 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; 14078 break;
13091 case ScriptBaseClass.OBJECT_PHYSICS_COST: 14079 case ScriptBaseClass.OBJECT_PHYSICS_COST:
13092 // The linden calculation is here 14080 // The value returned in SL for normal prims is prim count
13093 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 14081 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; 14082 break;
13097 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 14083 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
13098 ret.Add(new LSL_Float(0)); 14084 ret.Add(new LSL_Float(0));
@@ -13152,6 +14138,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13152 case ScriptBaseClass.OBJECT_LAST_OWNER_ID: 14138 case ScriptBaseClass.OBJECT_LAST_OWNER_ID:
13153 ret.Add(new LSL_Key(obj.ParentGroup.LastOwnerID.ToString())); 14139 ret.Add(new LSL_Key(obj.ParentGroup.LastOwnerID.ToString()));
13154 break; 14140 break;
14141 case ScriptBaseClass.OBJECT_CLICK_ACTION:
14142 ret.Add(new LSL_Integer(obj.ClickAction));
14143 break;
14144 case ScriptBaseClass.OBJECT_OMEGA:
14145 ret.Add(new LSL_Vector(obj.AngularVelocity));
14146 break;
14147 case ScriptBaseClass.OBJECT_PRIM_COUNT:
14148 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
14149 break;
14150 case ScriptBaseClass.OBJECT_TOTAL_INVENTORY_COUNT:
14151 SceneObjectPart[] parts = obj.ParentGroup.Parts;
14152 int nparts = parts.Count();
14153 int count = 0;
14154 for(int i = 0; i < nparts; i++)
14155 count += parts[i].Inventory.Count;
14156 ret.Add(new LSL_Integer(count));
14157 break;
14158 case ScriptBaseClass.OBJECT_REZZER_KEY:
14159 ret.Add(new LSL_Key(obj.ParentGroup.RezzerID.ToString()));
14160 break;
14161 case ScriptBaseClass.OBJECT_GROUP_TAG:
14162 ret.Add(new LSL_String(String.Empty));
14163 break;
14164 case ScriptBaseClass.OBJECT_TEMP_ATTACHED:
14165 if (obj.ParentGroup.AttachmentPoint != 0 && obj.ParentGroup.FromItemID == UUID.Zero)
14166 {
14167 ret.Add(new LSL_Integer(1));
14168 }
14169 else
14170 {
14171 ret.Add(new LSL_Integer(0));
14172 }
14173 break;
13155 default: 14174 default:
13156 // Invalid or unhandled constant. 14175 // Invalid or unhandled constant.
13157 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); 14176 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL));
@@ -13286,6 +14305,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13286 { 14305 {
13287 AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(assetID).ToString()); 14306 AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(assetID).ToString());
13288 14307
14308 ScriptSleep(m_sleepMsOnGetNumberOfNotecardLines);
13289 return tid.ToString(); 14309 return tid.ToString();
13290 } 14310 }
13291 14311
@@ -13301,6 +14321,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13301 AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(id).ToString()); 14321 AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(id).ToString());
13302 }); 14322 });
13303 14323
14324 ScriptSleep(m_sleepMsOnGetNumberOfNotecardLines);
13304 return tid.ToString(); 14325 return tid.ToString();
13305 } 14326 }
13306 14327
@@ -13336,6 +14357,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13336 AsyncCommands.DataserverPlugin.DataserverReply( 14357 AsyncCommands.DataserverPlugin.DataserverReply(
13337 reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax)); 14358 reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax));
13338 14359
14360 ScriptSleep(m_sleepMsOnGetNotecardLine);
13339 return tid.ToString(); 14361 return tid.ToString();
13340 } 14362 }
13341 14363
@@ -13354,6 +14376,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13354 reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax)); 14376 reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax));
13355 }); 14377 });
13356 14378
14379 ScriptSleep(m_sleepMsOnGetNotecardLine);
13357 return tid.ToString(); 14380 return tid.ToString();
13358 } 14381 }
13359 14382
@@ -13371,12 +14394,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13371 14394
13372 public LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules) 14395 public LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules)
13373 { 14396 {
13374 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); 14397 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim));
14398
14399 LSL_List result = new LSL_List();
13375 14400
13376 if (obj != null && obj.OwnerID == m_host.OwnerID) 14401 if (obj != null && obj.OwnerID == m_host.OwnerID)
13377 return GetEntityParams(obj, rules); 14402 {
14403 LSL_List remaining = GetPrimParams(obj, rules, ref result);
13378 14404
13379 return new LSL_List(); 14405 while (remaining.Length > 2)
14406 {
14407 int linknumber = remaining.GetLSLIntegerItem(0);
14408 rules = remaining.GetSublist(1, -1);
14409 List<SceneObjectPart> parts = GetLinkParts(linknumber);
14410
14411 foreach (SceneObjectPart part in parts)
14412 remaining = GetPrimParams(part, rules, ref result);
14413 }
14414 }
14415
14416 return result;
13380 } 14417 }
13381 14418
13382 public void print(string str) 14419 public void print(string str)
@@ -13390,6 +14427,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13390 } 14427 }
13391 } 14428 }
13392 14429
14430 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
14431 {
14432 List<SceneObjectPart> parts = GetLinkParts(link);
14433 if (parts.Count < 1)
14434 return 0;
14435
14436 return GetNumberOfSides(parts[0]);
14437 }
14438
13393 private string Name2Username(string name) 14439 private string Name2Username(string name)
13394 { 14440 {
13395 string[] parts = name.Split(new char[] {' '}); 14441 string[] parts = name.Split(new char[] {' '});
@@ -13432,7 +14478,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13432 14478
13433 return rq.ToString(); 14479 return rq.ToString();
13434 } 14480 }
13435 14481/*
14482 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
14483 {
14484 m_SayShoutCount = 0;
14485 }
14486*/
13436 private struct Tri 14487 private struct Tri
13437 { 14488 {
13438 public Vector3 p1; 14489 public Vector3 p1;
@@ -13453,18 +14504,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13453 return false; 14504 return false;
13454 } 14505 }
13455 14506
13456 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd) 14507 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd, bool skipPhys)
13457 { 14508 {
13458 List<ContactResult> contacts = new List<ContactResult>(); 14509 List<ContactResult> contacts = new List<ContactResult>();
13459 14510
13460 Vector3 ab = rayEnd - rayStart; 14511 Vector3 ab = rayEnd - rayStart;
14512 float ablen = ab.Length();
13461 14513
13462 World.ForEachScenePresence(delegate(ScenePresence sp) 14514 World.ForEachScenePresence(delegate(ScenePresence sp)
13463 { 14515 {
14516 if(skipPhys && sp.PhysicsActor != null)
14517 return;
14518
13464 Vector3 ac = sp.AbsolutePosition - rayStart; 14519 Vector3 ac = sp.AbsolutePosition - rayStart;
13465// Vector3 bc = sp.AbsolutePosition - rayEnd;
13466 14520
13467 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); 14521 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / ablen);
13468 14522
13469 if (d > 1.5) 14523 if (d > 1.5)
13470 return; 14524 return;
@@ -13581,9 +14635,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13581 14635
13582 ContactResult result = new ContactResult (); 14636 ContactResult result = new ContactResult ();
13583 result.ConsumerID = group.LocalId; 14637 result.ConsumerID = group.LocalId;
13584 result.Depth = intersection.distance; 14638// result.Depth = intersection.distance;
13585 result.Normal = intersection.normal; 14639 result.Normal = intersection.normal;
13586 result.Pos = intersection.ipoint; 14640 result.Pos = intersection.ipoint;
14641 result.Depth = Vector3.Mag(rayStart - result.Pos);
13587 14642
13588 contacts.Add(result); 14643 contacts.Add(result);
13589 }); 14644 });
@@ -13716,6 +14771,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13716 14771
13717 return contacts[0]; 14772 return contacts[0];
13718 } 14773 }
14774/*
14775 // not done:
14776 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
14777 {
14778 ContactResult[] contacts = null;
14779 World.ForEachSOG(delegate(SceneObjectGroup group)
14780 {
14781 if (m_host.ParentGroup == group)
14782 return;
14783
14784 if (group.IsAttachment)
14785 return;
14786
14787 if(group.RootPart.PhysActor != null)
14788 return;
14789
14790 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
14791 });
14792 return contacts;
14793 }
14794*/
13719 14795
13720 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 14796 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
13721 { 14797 {
@@ -13731,7 +14807,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13731 Vector3 rayEnd = end; 14807 Vector3 rayEnd = end;
13732 Vector3 dir = rayEnd - rayStart; 14808 Vector3 dir = rayEnd - rayStart;
13733 14809
13734 float dist = Vector3.Mag(dir); 14810 float dist = dir.Length();
13735 14811
13736 int count = 1; 14812 int count = 1;
13737 bool detectPhantom = false; 14813 bool detectPhantom = false;
@@ -13760,17 +14836,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13760 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); 14836 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
13761 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 14837 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
13762 14838
13763
13764 if (World.SupportsRayCastFiltered()) 14839 if (World.SupportsRayCastFiltered())
13765 { 14840 {
13766 if (dist == 0) 14841 if (dist == 0)
13767 return list; 14842 return list;
13768 14843
13769 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull; 14844 RayFilterFlags rayfilter = RayFilterFlags.BackFaceCull;
13770 if (checkTerrain) 14845 if (checkTerrain)
13771 rayfilter |= RayFilterFlags.land; 14846 rayfilter |= RayFilterFlags.land;
13772// if (checkAgents) 14847 if (checkAgents)
13773// rayfilter |= RayFilterFlags.agent; 14848 rayfilter |= RayFilterFlags.agent;
13774 if (checkPhysical) 14849 if (checkPhysical)
13775 rayfilter |= RayFilterFlags.physical; 14850 rayfilter |= RayFilterFlags.physical;
13776 if (checkNonPhysical) 14851 if (checkNonPhysical)
@@ -13796,16 +14871,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13796 14871
13797 if (physresults == null) 14872 if (physresults == null)
13798 { 14873 {
13799 list.Add(new LSL_Integer(-3)); // timeout error 14874// list.Add(new LSL_Integer(-3)); // timeout error
13800 return list; 14875// return list;
14876 results = new List<ContactResult>();
13801 } 14877 }
13802 14878 else
13803 results = (List<ContactResult>)physresults; 14879 results = (List<ContactResult>)physresults;
13804 14880
13805 // for now physics doesn't detect sitted avatars so do it outside physics 14881 // for now physics doesn't detect sitted avatars so do it outside physics
13806 if (checkAgents) 14882 if (checkAgents)
13807 { 14883 {
13808 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 14884 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd, true);
13809 foreach (ContactResult r in agentHits) 14885 foreach (ContactResult r in agentHits)
13810 results.Add(r); 14886 results.Add(r);
13811 } 14887 }
@@ -13821,12 +14897,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13821 foreach (ContactResult r in objectHits) 14897 foreach (ContactResult r in objectHits)
13822 results.Add(r); 14898 results.Add(r);
13823 } 14899 }
14900 // Double check this because of current ODE distance problems
14901 if (checkTerrain && dist > 60)
14902 {
14903 bool skipGroundCheck = false;
14904
14905 foreach (ContactResult c in results)
14906 {
14907 if (c.ConsumerID == 0) // Physics gave us a ground collision
14908 skipGroundCheck = true;
14909 }
14910
14911 if (!skipGroundCheck)
14912 {
14913 float tmp = dir.X * dir.X + dir.Y * dir.Y;
14914 if(tmp > 2500)
14915 {
14916 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
14917 if (groundContact != null)
14918 results.Add((ContactResult)groundContact);
14919 }
14920 }
14921 }
13824 } 14922 }
13825 else 14923 else
13826 { 14924 {
13827 if (checkAgents) 14925 if (checkAgents)
13828 { 14926 {
13829 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 14927 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd, false);
13830 foreach (ContactResult r in agentHits) 14928 foreach (ContactResult r in agentHits)
13831 results.Add(r); 14929 results.Add(r);
13832 } 14930 }
@@ -13841,13 +14939,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13841 results.Add(objectHits[iter]); 14939 results.Add(objectHits[iter]);
13842 } 14940 }
13843 } 14941 }
13844 }
13845 14942
13846 if (checkTerrain) 14943 if (checkTerrain)
13847 { 14944 {
13848 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 14945 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
13849 if (groundContact != null) 14946 if (groundContact != null)
13850 results.Add((ContactResult)groundContact); 14947 results.Add((ContactResult)groundContact);
14948 }
13851 } 14949 }
13852 14950
13853 results.Sort(delegate(ContactResult a, ContactResult b) 14951 results.Sort(delegate(ContactResult a, ContactResult b)
@@ -13908,10 +15006,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13908 } 15006 }
13909 15007
13910 list.Add(new LSL_Integer(values)); 15008 list.Add(new LSL_Integer(values));
13911
13912 return list; 15009 return list;
13913 } 15010 }
13914 15011
15012
13915 /// <summary> 15013 /// <summary>
13916 /// Implementation of llCastRay similar to SL 2015-04-21. 15014 /// Implementation of llCastRay similar to SL 2015-04-21.
13917 /// http://wiki.secondlife.com/wiki/LlCastRay 15015 /// http://wiki.secondlife.com/wiki/LlCastRay
@@ -13935,7 +15033,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13935 UUID userId = UUID.Zero; 15033 UUID userId = UUID.Zero;
13936 int msAvailable = 0; 15034 int msAvailable = 0;
13937 // Throttle per owner when attachment or "vehicle" (sat upon) 15035 // Throttle per owner when attachment or "vehicle" (sat upon)
13938 if (m_host.ParentGroup.IsAttachment || m_host.ParentGroup.GetSittingAvatars().Count > 0) 15036 if (m_host.ParentGroup.IsAttachment || m_host.ParentGroup.GetSittingAvatarsCount() > 0)
13939 { 15037 {
13940 userId = m_host.OwnerID; 15038 userId = m_host.OwnerID;
13941 msAvailable = m_msPerAvatarInCastRay; 15039 msAvailable = m_msPerAvatarInCastRay;
@@ -13968,13 +15066,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13968 msAvailable -= m_castRayCalls[i].UsedMs; 15066 msAvailable -= m_castRayCalls[i].UsedMs;
13969 } 15067 }
13970 } 15068 }
13971 }
13972 15069
13973 // Return failure if not enough available time 15070 // Return failure if not enough available time
13974 if (msAvailable < m_msMinInCastRay) 15071 if (msAvailable < m_msMinInCastRay)
13975 { 15072 {
13976 result.Add(new LSL_Integer(ScriptBaseClass.RCERR_CAST_TIME_EXCEEDED)); 15073 result.Add(new LSL_Integer(ScriptBaseClass.RCERR_CAST_TIME_EXCEEDED));
13977 return result; 15074 return result;
15075 }
13978 } 15076 }
13979 15077
13980 // Initialize 15078 // Initialize
@@ -13987,7 +15085,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13987 int rejectTypes = 0; 15085 int rejectTypes = 0;
13988 int dataFlags = 0; 15086 int dataFlags = 0;
13989 int maxHits = 1; 15087 int maxHits = 1;
13990 bool detectPhantom = false; 15088 bool notdetectPhantom = true;
13991 for (int i = 0; i < options.Length; i += 2) 15089 for (int i = 0; i < options.Length; i += 2)
13992 { 15090 {
13993 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) 15091 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
@@ -13997,7 +15095,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13997 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) 15095 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
13998 maxHits = options.GetLSLIntegerItem(i + 1); 15096 maxHits = options.GetLSLIntegerItem(i + 1);
13999 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) 15097 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
14000 detectPhantom = (options.GetLSLIntegerItem(i + 1) != 0); 15098 notdetectPhantom = (options.GetLSLIntegerItem(i + 1) == 0);
14001 } 15099 }
14002 if (maxHits > m_maxHitsInCastRay) 15100 if (maxHits > m_maxHitsInCastRay)
14003 maxHits = m_maxHitsInCastRay; 15101 maxHits = m_maxHitsInCastRay;
@@ -14027,157 +15125,153 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14027 World.ForEachSOG( 15125 World.ForEachSOG(
14028 delegate(SceneObjectGroup group) 15126 delegate(SceneObjectGroup group)
14029 { 15127 {
15128 if(group.IsDeleted || group.RootPart == null)
15129 return;
14030 // Check group filters unless part filters are configured 15130 // Check group filters unless part filters are configured
14031 bool isPhysical = (group.RootPart != null && group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical); 15131 bool isPhysical = (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical);
14032 bool isNonphysical = !isPhysical; 15132 bool isNonphysical = !isPhysical;
14033 bool isPhantom = group.IsPhantom || group.IsVolumeDetect; 15133 bool isPhantom = group.IsPhantom || group.IsVolumeDetect;
14034 bool isAttachment = group.IsAttachment; 15134 bool isAttachment = group.IsAttachment;
14035 bool doGroup = true;
14036 if (isPhysical && rejectPhysical) 15135 if (isPhysical && rejectPhysical)
14037 doGroup = false; 15136 return;
14038 if (isNonphysical && rejectNonphysical) 15137 if (isNonphysical && rejectNonphysical)
14039 doGroup = false; 15138 return;
14040 if (isPhantom && detectPhantom) 15139 if (isPhantom && notdetectPhantom)
14041 doGroup = true; 15140 return;
14042 if (m_filterPartsInCastRay)
14043 doGroup = true;
14044 if (isAttachment && !m_doAttachmentsInCastRay) 15141 if (isAttachment && !m_doAttachmentsInCastRay)
14045 doGroup = false; 15142 return;
15143
14046 // Parse object/group if passed filters 15144 // Parse object/group if passed filters
14047 if (doGroup) 15145 // Iterate over all prims/parts in object/group
15146 foreach(SceneObjectPart part in group.Parts)
14048 { 15147 {
14049 // Iterate over all prims/parts in object/group 15148 // ignore PhysicsShapeType.None as physics engines do
14050 foreach(SceneObjectPart part in group.Parts) 15149 // or we will get into trouble in future
15150 if(part.PhysicsShapeType == (byte)PhysicsShapeType.None)
15151 continue;
15152 isPhysical = (part.PhysActor != null && part.PhysActor.IsPhysical);
15153 isNonphysical = !isPhysical;
15154 isPhantom = ((part.Flags & PrimFlags.Phantom) != 0) ||
15155 (part.VolumeDetectActive);
15156
15157 if (isPhysical && rejectPhysical)
15158 continue;
15159 if (isNonphysical && rejectNonphysical)
15160 continue;
15161 if (isPhantom && notdetectPhantom)
15162 continue;
15163
15164 // Parse prim/part and project ray if passed filters
15165 Vector3 scalePart = part.Scale;
15166 Vector3 posPart = part.GetWorldPosition();
15167 Quaternion rotPart = part.GetWorldRotation();
15168 Quaternion rotPartInv = Quaternion.Inverse(rotPart);
15169 Vector3 pos1RayProj = ((pos1Ray - posPart) * rotPartInv) / scalePart;
15170 Vector3 pos2RayProj = ((pos2Ray - posPart) * rotPartInv) / scalePart;
15171
15172 // Filter parts by shape bounding boxes
15173 Vector3 shapeBoxMax = new Vector3(0.5f, 0.5f, 0.5f);
15174 if (!part.Shape.SculptEntry)
15175 shapeBoxMax = shapeBoxMax * (new Vector3(m_primSafetyCoeffX, m_primSafetyCoeffY, m_primSafetyCoeffZ));
15176 shapeBoxMax = shapeBoxMax + (new Vector3(tol, tol, tol));
15177 if (RayIntersectsShapeBox(pos1RayProj, pos2RayProj, shapeBoxMax))
14051 { 15178 {
14052 // Check part filters if configured 15179 // Prepare data needed to check for ray hits
14053 if (m_filterPartsInCastRay) 15180 RayTrans rayTrans = new RayTrans();
14054 { 15181 rayTrans.PartId = part.UUID;
14055 isPhysical = (part.PhysActor != null && part.PhysActor.IsPhysical); 15182 rayTrans.GroupId = part.ParentGroup.UUID;
14056 isNonphysical = !isPhysical; 15183 rayTrans.Link = group.PrimCount > 1 ? part.LinkNum : 0;
14057 isPhantom = ((part.Flags & PrimFlags.Phantom) != 0) || (part.VolumeDetectActive); 15184 rayTrans.ScalePart = scalePart;
14058 bool doPart = true; 15185 rayTrans.PositionPart = posPart;
14059 if (isPhysical && rejectPhysical) 15186 rayTrans.RotationPart = rotPart;
14060 doPart = false; 15187 rayTrans.ShapeNeedsEnds = true;
14061 if (isNonphysical && rejectNonphysical) 15188 rayTrans.Position1Ray = pos1Ray;
14062 doPart = false; 15189 rayTrans.Position1RayProj = pos1RayProj;
14063 if (isPhantom && detectPhantom) 15190 rayTrans.VectorRayProj = pos2RayProj - pos1RayProj;
14064 doPart = true; 15191
14065 if (!doPart) 15192 // Get detail level depending on type
14066 continue; 15193 int lod = 0;
14067 } 15194 // Mesh detail level
14068 15195 if (part.Shape.SculptEntry && part.Shape.SculptType == (byte)SculptType.Mesh)
14069 // Parse prim/part and project ray if passed filters 15196 lod = (int)m_meshLodInCastRay;
14070 Vector3 scalePart = part.Scale; 15197 // Sculpt detail level
14071 Vector3 posPart = part.GetWorldPosition(); 15198 else if (part.Shape.SculptEntry && part.Shape.SculptType == (byte)SculptType.Mesh)
14072 Quaternion rotPart = part.GetWorldRotation(); 15199 lod = (int)m_sculptLodInCastRay;
14073 Quaternion rotPartInv = Quaternion.Inverse(rotPart); 15200 // Shape detail level
14074 Vector3 pos1RayProj = ((pos1Ray - posPart) * rotPartInv) / scalePart; 15201 else if (!part.Shape.SculptEntry)
14075 Vector3 pos2RayProj = ((pos2Ray - posPart) * rotPartInv) / scalePart; 15202 lod = (int)m_primLodInCastRay;
14076 15203
14077 // Filter parts by shape bounding boxes 15204 // Try to get cached mesh if configured
14078 Vector3 shapeBoxMax = new Vector3(0.5f, 0.5f, 0.5f); 15205 ulong meshKey = 0;
14079 if (!part.Shape.SculptEntry) 15206 FacetedMesh mesh = null;
14080 shapeBoxMax = shapeBoxMax * (new Vector3(m_primSafetyCoeffX, m_primSafetyCoeffY, m_primSafetyCoeffZ)); 15207 if (m_useMeshCacheInCastRay)
14081 shapeBoxMax = shapeBoxMax + (new Vector3(tol, tol, tol)); 15208 {
14082 if (RayIntersectsShapeBox(pos1RayProj, pos2RayProj, shapeBoxMax)) 15209 meshKey = part.Shape.GetMeshKey(Vector3.One, (float)(4 << lod));
14083 { 15210 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 { 15211 {
14114 meshKey = part.Shape.GetMeshKey(Vector3.One, (float)(4 << lod)); 15212 m_cachedMeshes.TryGetValue(meshKey, out mesh);
14115 lock (m_cachedMeshes)
14116 {
14117 m_cachedMeshes.TryGetValue(meshKey, out mesh);
14118 }
14119 } 15213 }
15214 }
14120 15215
14121 // Create mesh if no cached mesh 15216 // Create mesh if no cached mesh
14122 if (mesh == null) 15217 if (mesh == null)
15218 {
15219 // Make an OMV prim to be able to mesh part
15220 Primitive omvPrim = part.Shape.ToOmvPrimitive(posPart, rotPart);
15221 byte[] sculptAsset = null;
15222 if (omvPrim.Sculpt != null)
15223 sculptAsset = World.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString());
15224
15225 // When part is mesh, get mesh
15226 if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type == SculptType.Mesh && sculptAsset != null)
14123 { 15227 {
14124 // Make an OMV prim to be able to mesh part 15228 AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset);
14125 Primitive omvPrim = part.Shape.ToOmvPrimitive(posPart, rotPart); 15229 FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, m_meshLodInCastRay, out mesh);
14126 byte[] sculptAsset = null; 15230 meshAsset = null;
14127 if (omvPrim.Sculpt != null) 15231 }
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 15232
14138 // When part is sculpt, create mesh 15233 // When part is sculpt, create mesh
14139 // Quirk: Generated sculpt mesh is about 2.8% smaller in X and Y than visual sculpt. 15234 // 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) 15235 else if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type != SculptType.Mesh && sculptAsset != null)
15236 {
15237 IJ2KDecoder imgDecoder = World.RequestModuleInterface<IJ2KDecoder>();
15238 if (imgDecoder != null)
14141 { 15239 {
14142 IJ2KDecoder imgDecoder = World.RequestModuleInterface<IJ2KDecoder>(); 15240 Image sculpt = imgDecoder.DecodeToImage(sculptAsset);
14143 if (imgDecoder != null) 15241 if (sculpt != null)
14144 { 15242 {
14145 Image sculpt = imgDecoder.DecodeToImage(sculptAsset); 15243 mesh = primMesher.GenerateFacetedSculptMesh(omvPrim, (Bitmap)sculpt, m_sculptLodInCastRay);
14146 if (sculpt != null) 15244 sculpt.Dispose();
14147 {
14148 mesh = primMesher.GenerateFacetedSculptMesh(omvPrim, (Bitmap)sculpt, m_sculptLodInCastRay);
14149 sculpt.Dispose();
14150 }
14151 } 15245 }
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 } 15246 }
15247 }
14166 15248
14167 // Cache mesh if configured 15249 // When part is shape, create mesh
14168 if (m_useMeshCacheInCastRay && mesh != null) 15250 else if (omvPrim.Sculpt == null)
15251 {
15252 if (
15253 omvPrim.PrimData.PathBegin == 0.0 && omvPrim.PrimData.PathEnd == 1.0 &&
15254 omvPrim.PrimData.PathTaperX == 0.0 && omvPrim.PrimData.PathTaperY == 0.0 &&
15255 omvPrim.PrimData.PathSkew == 0.0 &&
15256 omvPrim.PrimData.PathTwist - omvPrim.PrimData.PathTwistBegin == 0.0
15257 )
15258 rayTrans.ShapeNeedsEnds = false;
15259 mesh = primMesher.GenerateFacetedMesh(omvPrim, m_primLodInCastRay);
15260 }
15261
15262 // Cache mesh if configured
15263 if (m_useMeshCacheInCastRay && mesh != null)
15264 {
15265 lock(m_cachedMeshes)
14169 { 15266 {
14170 lock(m_cachedMeshes) 15267 if (!m_cachedMeshes.ContainsKey(meshKey))
14171 { 15268 m_cachedMeshes.Add(meshKey, mesh);
14172 if (!m_cachedMeshes.ContainsKey(meshKey))
14173 m_cachedMeshes.Add(meshKey, mesh);
14174 }
14175 } 15269 }
14176 } 15270 }
14177 // Check mesh for ray hits
14178 AddRayInFacetedMesh(mesh, rayTrans, ref rayHits);
14179 mesh = null;
14180 } 15271 }
15272 // Check mesh for ray hits
15273 AddRayInFacetedMesh(mesh, rayTrans, ref rayHits);
15274 mesh = null;
14181 } 15275 }
14182 } 15276 }
14183 } 15277 }
@@ -14362,13 +15456,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14362 15456
14363 // Add to throttle data 15457 // Add to throttle data
14364 stopWatch.Stop(); 15458 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) 15459 lock (m_castRayCalls)
14371 { 15460 {
15461 CastRayCall castRayCall = new CastRayCall();
15462 castRayCall.RegionId = regionId;
15463 castRayCall.UserId = userId;
15464 castRayCall.CalledMs = calledMs;
15465 castRayCall.UsedMs = (int)stopWatch.ElapsedMilliseconds;
14372 m_castRayCalls.Add(castRayCall); 15466 m_castRayCalls.Add(castRayCall);
14373 } 15467 }
14374 15468
@@ -14813,7 +15907,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14813 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 15907 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
14814 if (!isAccount) return 0; 15908 if (!isAccount) return 0;
14815 if (estate.HasAccess(id)) return 1; 15909 if (estate.HasAccess(id)) return 1;
14816 if (estate.IsBanned(id)) 15910 if (estate.IsBanned(id, World.GetUserFlags(id)))
14817 estate.RemoveBan(id); 15911 estate.RemoveBan(id);
14818 estate.AddEstateUser(id); 15912 estate.AddEstateUser(id);
14819 break; 15913 break;
@@ -14832,14 +15926,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14832 break; 15926 break;
14833 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 15927 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
14834 if (!isAccount) return 0; 15928 if (!isAccount) return 0;
14835 if (estate.IsBanned(id)) return 1; 15929 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
14836 EstateBan ban = new EstateBan(); 15930 EstateBan ban = new EstateBan();
14837 ban.EstateID = estate.EstateID; 15931 ban.EstateID = estate.EstateID;
14838 ban.BannedUserID = id; 15932 ban.BannedUserID = id;
14839 estate.AddBan(ban); 15933 estate.AddBan(ban);
14840 break; 15934 break;
14841 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 15935 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
14842 if (!isAccount || !estate.IsBanned(id)) return 0; 15936 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
14843 estate.RemoveBan(id); 15937 estate.RemoveBan(id);
14844 break; 15938 break;
14845 default: return 0; 15939 default: return 0;
@@ -14898,13 +15992,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14898 public void llCollisionSprite(string impact_sprite) 15992 public void llCollisionSprite(string impact_sprite)
14899 { 15993 {
14900 m_host.AddScriptLPS(1); 15994 m_host.AddScriptLPS(1);
14901 NotImplemented("llCollisionSprite"); 15995 // Viewer 2.0 broke this and it's likely LL has no intention
15996 // of fixing it. Therefore, letting this be a NOP seems appropriate.
14902 } 15997 }
14903 15998
14904 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 15999 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
14905 { 16000 {
14906 m_host.AddScriptLPS(1); 16001 m_host.AddScriptLPS(1);
14907 NotImplemented("llGodLikeRezObject"); 16002
16003 if (!World.Permissions.IsGod(m_host.OwnerID))
16004 NotImplemented("llGodLikeRezObject");
16005
16006 AssetBase rezAsset = World.AssetService.Get(inventory);
16007 if (rezAsset == null)
16008 {
16009 llSay(0, "Asset not found");
16010 return;
16011 }
16012
16013 SceneObjectGroup group = null;
16014
16015 try
16016 {
16017 string xmlData = Utils.BytesToString(rezAsset.Data);
16018 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
16019 }
16020 catch
16021 {
16022 llSay(0, "Asset not found");
16023 return;
16024 }
16025
16026 if (group == null)
16027 {
16028 llSay(0, "Asset not found");
16029 return;
16030 }
16031
16032 group.RootPart.AttachedPos = group.AbsolutePosition;
16033
16034 group.ResetIDs();
16035
16036 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
16037 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
16038 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
16039 group.ScheduleGroupForFullUpdate();
16040
16041 // objects rezzed with this method are die_at_edge by default.
16042 group.RootPart.SetDieAtEdge(true);
16043
16044 group.ResumeScripts();
16045
16046 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
16047 "object_rez", new Object[] {
16048 new LSL_String(
16049 group.RootPart.UUID.ToString()) },
16050 new DetectParams[0]));
14908 } 16051 }
14909 16052
14910 public LSL_String llTransferLindenDollars(string destination, int amount) 16053 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -14918,6 +16061,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14918 16061
14919 try 16062 try
14920 { 16063 {
16064 if (amount <= 0)
16065 {
16066 replydata = "INVALID_AMOUNT";
16067 return;
16068 }
16069
14921 TaskInventoryItem item = m_item; 16070 TaskInventoryItem item = m_item;
14922 if (item == null) 16071 if (item == null)
14923 { 16072 {
@@ -14925,6 +16074,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14925 return; 16074 return;
14926 } 16075 }
14927 16076
16077 if (m_host.OwnerID == m_host.GroupID)
16078 {
16079 replydata = "GROUP_OWNED";
16080 return;
16081 }
16082
14928 m_host.AddScriptLPS(1); 16083 m_host.AddScriptLPS(1);
14929 16084
14930 if (item.PermsGranter == UUID.Zero) 16085 if (item.PermsGranter == UUID.Zero)
@@ -14947,6 +16102,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14947 return; 16102 return;
14948 } 16103 }
14949 16104
16105 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, toID);
16106 if (account == null)
16107 {
16108 replydata = "LINDENDOLLAR_ENTITYDOESNOTEXIST";
16109 return;
16110 }
16111
14950 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>(); 16112 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
14951 16113
14952 if (money == null) 16114 if (money == null)
@@ -14955,8 +16117,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14955 return; 16117 return;
14956 } 16118 }
14957 16119
14958 bool result = money.ObjectGiveMoney( 16120 string reason;
14959 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 16121 bool result = money.ObjectGiveMoney( m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn, out reason);
14960 16122
14961 if (result) 16123 if (result)
14962 { 16124 {
@@ -14964,7 +16126,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14964 return; 16126 return;
14965 } 16127 }
14966 16128
14967 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS"; 16129 replydata = reason;
14968 } 16130 }
14969 finally 16131 finally
14970 { 16132 {
@@ -14981,6 +16143,1366 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14981 } 16143 }
14982 16144
14983 #endregion 16145 #endregion
16146
16147
16148 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
16149 {
16150 //This is a special version of SetPrimParams to deal with avatars which are sitting on the linkset.
16151
16152 int idx = 0;
16153 int idxStart = 0;
16154
16155 bool positionChanged = false;
16156 try
16157 {
16158 while (idx < rules.Length)
16159 {
16160 ++rulesParsed;
16161 int code = rules.GetLSLIntegerItem(idx++);
16162
16163 int remain = rules.Length - idx;
16164 idxStart = idx;
16165
16166 switch (code)
16167 {
16168 case (int)ScriptBaseClass.PRIM_POSITION:
16169 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
16170 {
16171 if (remain < 1)
16172 return new LSL_List();
16173
16174 LSL_Vector v;
16175 v = rules.GetVector3Item(idx++);
16176
16177 if(!av.LegacySitOffsets)
16178 {
16179 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
16180
16181 v = v + 2 * sitOffset;
16182 }
16183
16184 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
16185 positionChanged = true;
16186 }
16187 break;
16188
16189 case (int)ScriptBaseClass.PRIM_ROTATION:
16190 {
16191 if (remain < 1)
16192 return new LSL_List();
16193
16194 Quaternion r;
16195 r = rules.GetQuaternionItem(idx++);
16196
16197 av.Rotation = m_host.GetWorldRotation() * r;
16198 positionChanged = true;
16199 }
16200 break;
16201
16202 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
16203 {
16204 if (remain < 1)
16205 return new LSL_List();
16206
16207 LSL_Rotation r;
16208 r = rules.GetQuaternionItem(idx++);
16209
16210 av.Rotation = r;
16211 positionChanged = true;
16212 }
16213 break;
16214
16215 // parse rest doing nothing but number of parameters error check
16216 case (int)ScriptBaseClass.PRIM_SIZE:
16217 case (int)ScriptBaseClass.PRIM_MATERIAL:
16218 case (int)ScriptBaseClass.PRIM_PHANTOM:
16219 case (int)ScriptBaseClass.PRIM_PHYSICS:
16220 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
16221 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
16222 case (int)ScriptBaseClass.PRIM_NAME:
16223 case (int)ScriptBaseClass.PRIM_DESC:
16224 if (remain < 1)
16225 return new LSL_List();
16226 idx++;
16227 break;
16228
16229 case (int)ScriptBaseClass.PRIM_GLOW:
16230 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
16231 case (int)ScriptBaseClass.PRIM_TEXGEN:
16232 if (remain < 2)
16233 return new LSL_List();
16234 idx += 2;
16235 break;
16236
16237 case (int)ScriptBaseClass.PRIM_TYPE:
16238 if (remain < 3)
16239 return new LSL_List();
16240 code = (int)rules.GetLSLIntegerItem(idx++);
16241 remain = rules.Length - idx;
16242 switch (code)
16243 {
16244 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
16245 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
16246 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
16247 if (remain < 6)
16248 return new LSL_List();
16249 idx += 6;
16250 break;
16251
16252 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
16253 if (remain < 5)
16254 return new LSL_List();
16255 idx += 5;
16256 break;
16257
16258 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
16259 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
16260 case (int)ScriptBaseClass.PRIM_TYPE_RING:
16261 if (remain < 11)
16262 return new LSL_List();
16263 idx += 11;
16264 break;
16265
16266 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
16267 if (remain < 2)
16268 return new LSL_List();
16269 idx += 2;
16270 break;
16271 }
16272 break;
16273
16274 case (int)ScriptBaseClass.PRIM_COLOR:
16275 case (int)ScriptBaseClass.PRIM_TEXT:
16276 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
16277 case (int)ScriptBaseClass.PRIM_OMEGA:
16278 case (int)ScriptBaseClass.PRIM_SIT_TARGET:
16279 if (remain < 3)
16280 return new LSL_List();
16281 idx += 3;
16282 break;
16283
16284 case (int)ScriptBaseClass.PRIM_TEXTURE:
16285 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
16286 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
16287 if (remain < 5)
16288 return new LSL_List();
16289 idx += 5;
16290 break;
16291
16292 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
16293 if (remain < 7)
16294 return new LSL_List();
16295
16296 idx += 7;
16297 break;
16298
16299 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
16300 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
16301 return new LSL_List();
16302
16303 return rules.GetSublist(idx, -1);
16304 }
16305 }
16306 }
16307 catch (InvalidCastException e)
16308 {
16309 Error(originFunc,string.Format(
16310 " error running rule #{0}: arg #{1} {2}",
16311 rulesParsed, idx - idxStart, e.Message));
16312 }
16313 finally
16314 {
16315 if (positionChanged)
16316 av.SendTerseUpdateToAllClients();
16317 }
16318 return new LSL_List();
16319 }
16320
16321 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
16322 {
16323 // avatars case
16324 // replies as SL wiki
16325
16326// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
16327 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
16328
16329 int idx = 0;
16330 while (idx < rules.Length)
16331 {
16332 int code = (int)rules.GetLSLIntegerItem(idx++);
16333 int remain = rules.Length - idx;
16334
16335 switch (code)
16336 {
16337 case (int)ScriptBaseClass.PRIM_MATERIAL:
16338 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
16339 break;
16340
16341 case (int)ScriptBaseClass.PRIM_PHYSICS:
16342 res.Add(new LSL_Integer(0));
16343 break;
16344
16345 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
16346 res.Add(new LSL_Integer(0));
16347 break;
16348
16349 case (int)ScriptBaseClass.PRIM_PHANTOM:
16350 res.Add(new LSL_Integer(0));
16351 break;
16352
16353 case (int)ScriptBaseClass.PRIM_POSITION:
16354 Vector3 pos;
16355
16356 if (sitPart.ParentGroup.RootPart != null)
16357 {
16358 pos = avatar.OffsetPosition;
16359
16360 if(!avatar.LegacySitOffsets)
16361 {
16362 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
16363 pos -= sitOffset;
16364 }
16365
16366 SceneObjectPart sitroot = sitPart.ParentGroup.RootPart;
16367 pos = sitroot.AbsolutePosition + pos * sitroot.GetWorldRotation();
16368 }
16369 else
16370 pos = avatar.AbsolutePosition;
16371
16372 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
16373 break;
16374
16375 case (int)ScriptBaseClass.PRIM_SIZE:
16376 Vector3 s = avatar.Appearance.AvatarSize;
16377 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
16378
16379 break;
16380
16381 case (int)ScriptBaseClass.PRIM_ROTATION:
16382 res.Add(new LSL_Rotation(avatar.GetWorldRotation()));
16383 break;
16384
16385 case (int)ScriptBaseClass.PRIM_TYPE:
16386 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
16387 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
16388 res.Add(new LSL_Vector(0f,1.0f,0f));
16389 res.Add(new LSL_Float(0.0f));
16390 res.Add(new LSL_Vector(0, 0, 0));
16391 res.Add(new LSL_Vector(1.0f,1.0f,0f));
16392 res.Add(new LSL_Vector(0, 0, 0));
16393 break;
16394
16395 case (int)ScriptBaseClass.PRIM_TEXTURE:
16396 if (remain < 1)
16397 return new LSL_List();
16398
16399 int face = (int)rules.GetLSLIntegerItem(idx++);
16400 if (face == ScriptBaseClass.ALL_SIDES)
16401 {
16402 for (face = 0; face < 21; face++)
16403 {
16404 res.Add(new LSL_String(""));
16405 res.Add(new LSL_Vector(0,0,0));
16406 res.Add(new LSL_Vector(0,0,0));
16407 res.Add(new LSL_Float(0.0));
16408 }
16409 }
16410 else
16411 {
16412 if (face >= 0 && face < 21)
16413 {
16414 res.Add(new LSL_String(""));
16415 res.Add(new LSL_Vector(0,0,0));
16416 res.Add(new LSL_Vector(0,0,0));
16417 res.Add(new LSL_Float(0.0));
16418 }
16419 }
16420 break;
16421
16422 case (int)ScriptBaseClass.PRIM_COLOR:
16423 if (remain < 1)
16424 return new LSL_List();
16425
16426 face = (int)rules.GetLSLIntegerItem(idx++);
16427
16428 if (face == ScriptBaseClass.ALL_SIDES)
16429 {
16430 for (face = 0; face < 21; face++)
16431 {
16432 res.Add(new LSL_Vector(0,0,0));
16433 res.Add(new LSL_Float(0));
16434 }
16435 }
16436 else
16437 {
16438 res.Add(new LSL_Vector(0,0,0));
16439 res.Add(new LSL_Float(0));
16440 }
16441 break;
16442
16443 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
16444 if (remain < 1)
16445 return new LSL_List();
16446 face = (int)rules.GetLSLIntegerItem(idx++);
16447
16448 if (face == ScriptBaseClass.ALL_SIDES)
16449 {
16450 for (face = 0; face < 21; face++)
16451 {
16452 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
16453 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
16454 }
16455 }
16456 else
16457 {
16458 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
16459 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
16460 }
16461 break;
16462
16463 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
16464 if (remain < 1)
16465 return new LSL_List();
16466 face = (int)rules.GetLSLIntegerItem(idx++);
16467
16468 if (face == ScriptBaseClass.ALL_SIDES)
16469 {
16470 for (face = 0; face < 21; face++)
16471 {
16472 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
16473 }
16474 }
16475 else
16476 {
16477 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
16478 }
16479 break;
16480
16481 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
16482 res.Add(new LSL_Integer(0));
16483 res.Add(new LSL_Integer(0));// softness
16484 res.Add(new LSL_Float(0.0f)); // gravity
16485 res.Add(new LSL_Float(0.0f)); // friction
16486 res.Add(new LSL_Float(0.0f)); // wind
16487 res.Add(new LSL_Float(0.0f)); // tension
16488 res.Add(new LSL_Vector(0f,0f,0f));
16489 break;
16490
16491 case (int)ScriptBaseClass.PRIM_TEXGEN:
16492 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
16493 if (remain < 1)
16494 return new LSL_List();
16495 face = (int)rules.GetLSLIntegerItem(idx++);
16496
16497 if (face == ScriptBaseClass.ALL_SIDES)
16498 {
16499 for (face = 0; face < 21; face++)
16500 {
16501 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
16502 }
16503 }
16504 else
16505 {
16506 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
16507 }
16508 break;
16509
16510 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
16511 res.Add(new LSL_Integer(0));
16512 res.Add(new LSL_Vector(0f,0f,0f));
16513 res.Add(new LSL_Float(0f)); // intensity
16514 res.Add(new LSL_Float(0f)); // radius
16515 res.Add(new LSL_Float(0f)); // falloff
16516 break;
16517
16518 case (int)ScriptBaseClass.PRIM_GLOW:
16519 if (remain < 1)
16520 return new LSL_List();
16521 face = (int)rules.GetLSLIntegerItem(idx++);
16522
16523 if (face == ScriptBaseClass.ALL_SIDES)
16524 {
16525 for (face = 0; face < 21; face++)
16526 {
16527 res.Add(new LSL_Float(0f));
16528 }
16529 }
16530 else
16531 {
16532 res.Add(new LSL_Float(0f));
16533 }
16534 break;
16535
16536 case (int)ScriptBaseClass.PRIM_TEXT:
16537 res.Add(new LSL_String(""));
16538 res.Add(new LSL_Vector(0f,0f,0f));
16539 res.Add(new LSL_Float(1.0f));
16540 break;
16541
16542 case (int)ScriptBaseClass.PRIM_NAME:
16543 res.Add(new LSL_String(avatar.Name));
16544 break;
16545
16546 case (int)ScriptBaseClass.PRIM_DESC:
16547 res.Add(new LSL_String(""));
16548 break;
16549
16550 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
16551 Quaternion lrot = avatar.Rotation;
16552 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
16553 break;
16554
16555 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
16556 Vector3 lpos = avatar.OffsetPosition;
16557
16558 if(!avatar.LegacySitOffsets)
16559 {
16560 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
16561 lpos -= lsitOffset;
16562 }
16563
16564 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
16565 break;
16566
16567 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
16568 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
16569 return new LSL_List();
16570
16571 return rules.GetSublist(idx, -1);
16572 }
16573 }
16574
16575 return new LSL_List();
16576 }
16577
16578 public void llSetAnimationOverride(LSL_String animState, LSL_String anim)
16579 {
16580 string state = String.Empty;
16581
16582 foreach (KeyValuePair<string, string> kvp in MovementAnimationsForLSL)
16583 {
16584 if (kvp.Value.ToLower() == ((string)animState).ToLower())
16585 {
16586 state = kvp.Key;
16587 break;
16588 }
16589 }
16590
16591 if (state == String.Empty)
16592 {
16593 llShout(ScriptBaseClass.DEBUG_CHANNEL, "Invalid animation state " + animState);
16594 return;
16595 }
16596
16597 if (m_item.PermsGranter == UUID.Zero)
16598 {
16599 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16600 return;
16601 }
16602
16603 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_OVERRIDE_ANIMATIONS) == 0)
16604 {
16605 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16606 return;
16607 }
16608
16609 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
16610
16611 if (presence == null)
16612 return;
16613
16614 UUID animID;
16615
16616 animID = ScriptUtils.GetAssetIdFromItemName(m_host, anim, (int)AssetType.Animation);
16617
16618 if (animID == UUID.Zero)
16619 {
16620 String animupper = ((string)anim).ToUpperInvariant();
16621 DefaultAvatarAnimations.AnimsUUID.TryGetValue(animupper, out animID);
16622 }
16623
16624 if (animID == UUID.Zero)
16625 {
16626 llShout(ScriptBaseClass.DEBUG_CHANNEL, "Animation not found");
16627 return;
16628 }
16629
16630 presence.SetAnimationOverride(state, animID);
16631 }
16632
16633 public void llResetAnimationOverride(LSL_String animState)
16634 {
16635 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
16636 if (presence == null)
16637 return;
16638
16639 if (m_item.PermsGranter == UUID.Zero)
16640 {
16641 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16642 return;
16643 }
16644
16645 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_OVERRIDE_ANIMATIONS) == 0)
16646 {
16647 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16648 return;
16649 }
16650
16651 if (animState == "ALL")
16652 {
16653 presence.SetAnimationOverride("ALL", UUID.Zero);
16654 return;
16655 }
16656
16657 string state = String.Empty;
16658
16659 foreach (KeyValuePair<string, string> kvp in MovementAnimationsForLSL)
16660 {
16661 if (kvp.Value.ToLower() == ((string)animState).ToLower())
16662 {
16663 state = kvp.Key;
16664 break;
16665 }
16666 }
16667
16668 if (state == String.Empty)
16669 {
16670 return;
16671 }
16672
16673 presence.SetAnimationOverride(state, UUID.Zero);
16674 }
16675
16676 public LSL_String llGetAnimationOverride(LSL_String animState)
16677 {
16678 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
16679 if (presence == null)
16680 return String.Empty;
16681
16682 if (m_item.PermsGranter == UUID.Zero)
16683 {
16684 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16685 return String.Empty;
16686 }
16687
16688 if ((m_item.PermsMask & (ScriptBaseClass.PERMISSION_OVERRIDE_ANIMATIONS | ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION)) == 0)
16689 {
16690 llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations");
16691 return String.Empty;
16692 }
16693
16694 string state = String.Empty;
16695
16696 foreach (KeyValuePair<string, string> kvp in MovementAnimationsForLSL)
16697 {
16698 if (kvp.Value.ToLower() == ((string)animState).ToLower())
16699 {
16700 state = kvp.Key;
16701 break;
16702 }
16703 }
16704
16705 if (state == String.Empty)
16706 {
16707 return String.Empty;
16708 }
16709
16710 UUID animID = presence.GetAnimationOverride(state);
16711 if (animID == UUID.Zero)
16712 return animState;
16713
16714 foreach (KeyValuePair<string, UUID> kvp in DefaultAvatarAnimations.AnimsUUID)
16715 {
16716 if (kvp.Value == animID)
16717 return kvp.Key.ToLower();
16718 }
16719
16720 foreach (TaskInventoryItem item in m_host.Inventory.GetInventoryItems())
16721 {
16722 if (item.AssetID == animID)
16723 return item.Name;
16724 }
16725
16726 return String.Empty;
16727 }
16728
16729 public LSL_List llJson2List(LSL_String json)
16730 {
16731 if(String.IsNullOrEmpty(json))
16732 return new LSL_List();
16733 if(json == "[]")
16734 return new LSL_List();
16735 if(json == "{}")
16736 return new LSL_List();
16737 char first = ((string)json)[0];
16738
16739 if(first != '[' && first !='{')
16740 {
16741 // we already have a single element
16742 LSL_List l = new LSL_List();
16743 l.Add(json);
16744 return l;
16745 }
16746
16747 LitJson.JsonData jsdata;
16748 try
16749 {
16750 jsdata = LitJson.JsonMapper.ToObject(json);
16751 }
16752 catch (Exception e)
16753 {
16754 string m = e.Message; // debug point
16755 return json;
16756 }
16757 try
16758 {
16759 return JsonParseTop(jsdata);
16760 }
16761 catch (Exception e)
16762 {
16763 string m = e.Message; // debug point
16764 return (LSL_String)ScriptBaseClass.JSON_INVALID;
16765 }
16766 }
16767
16768 private LSL_List JsonParseTop(LitJson.JsonData elem)
16769 {
16770 LSL_List retl = new LSL_List();
16771 if(elem == null)
16772 retl.Add((LSL_String)ScriptBaseClass.JSON_NULL);
16773
16774 LitJson.JsonType elemType = elem.GetJsonType();
16775 switch (elemType)
16776 {
16777 case LitJson.JsonType.Int:
16778 retl.Add(new LSL_Integer((int)elem));
16779 return retl;
16780 case LitJson.JsonType.Boolean:
16781 retl.Add((LSL_String)((bool)elem ? ScriptBaseClass.JSON_TRUE : ScriptBaseClass.JSON_FALSE));
16782 return retl;
16783 case LitJson.JsonType.Double:
16784 retl.Add(new LSL_Float((double)elem));
16785 return retl;
16786 case LitJson.JsonType.None:
16787 retl.Add((LSL_String)ScriptBaseClass.JSON_NULL);
16788 return retl;
16789 case LitJson.JsonType.String:
16790 retl.Add(new LSL_String((string)elem));
16791 return retl;
16792 case LitJson.JsonType.Array:
16793 foreach (LitJson.JsonData subelem in elem)
16794 retl.Add(JsonParseTopNodes(subelem));
16795 return retl;
16796 case LitJson.JsonType.Object:
16797 IDictionaryEnumerator e = ((IOrderedDictionary)elem).GetEnumerator();
16798 while (e.MoveNext())
16799 {
16800 retl.Add(new LSL_String((string)e.Key));
16801 retl.Add(JsonParseTopNodes((LitJson.JsonData)e.Value));
16802 }
16803 return retl;
16804 default:
16805 throw new Exception(ScriptBaseClass.JSON_INVALID);
16806 }
16807 }
16808
16809 private object JsonParseTopNodes(LitJson.JsonData elem)
16810 {
16811 if(elem == null)
16812 return ((LSL_String)ScriptBaseClass.JSON_NULL);
16813
16814 LitJson.JsonType elemType = elem.GetJsonType();
16815 switch (elemType)
16816 {
16817 case LitJson.JsonType.Int:
16818 return (new LSL_Integer((int)elem));
16819 case LitJson.JsonType.Boolean:
16820 return ((bool)elem ? (LSL_String)ScriptBaseClass.JSON_TRUE : (LSL_String)ScriptBaseClass.JSON_FALSE);
16821 case LitJson.JsonType.Double:
16822 return (new LSL_Float((double)elem));
16823 case LitJson.JsonType.None:
16824 return ((LSL_String)ScriptBaseClass.JSON_NULL);
16825 case LitJson.JsonType.String:
16826 return (new LSL_String((string)elem));
16827 case LitJson.JsonType.Array:
16828 case LitJson.JsonType.Object:
16829 string s = LitJson.JsonMapper.ToJson(elem);
16830 return (LSL_String)s;
16831 default:
16832 throw new Exception(ScriptBaseClass.JSON_INVALID);
16833 }
16834 }
16835
16836 public LSL_String llList2Json(LSL_String type, LSL_List values)
16837 {
16838 try
16839 {
16840 StringBuilder sb = new StringBuilder();
16841 if (type == ScriptBaseClass.JSON_ARRAY)
16842 {
16843 sb.Append("[");
16844 int i= 0;
16845 foreach (object o in values.Data)
16846 {
16847 sb.Append(ListToJson(o));
16848 if((i++) < values.Data.Length - 1)
16849 sb.Append(",");
16850 }
16851 sb.Append("]");
16852 return (LSL_String)sb.ToString();;
16853 }
16854 else if (type == ScriptBaseClass.JSON_OBJECT)
16855 {
16856 sb.Append("{");
16857 for (int i = 0; i < values.Data.Length; i += 2)
16858 {
16859 if (!(values.Data[i] is LSL_String))
16860 return ScriptBaseClass.JSON_INVALID;
16861 string key = ((LSL_String)values.Data[i]).m_string;
16862 key = EscapeForJSON(key, true);
16863 sb.Append(key);
16864 sb.Append(":");
16865 sb.Append(ListToJson(values.Data[i+1]));
16866 if(i < values.Data.Length - 2)
16867 sb.Append(",");
16868 }
16869 sb.Append("}");
16870 return (LSL_String)sb.ToString();
16871 }
16872 return ScriptBaseClass.JSON_INVALID;
16873 }
16874 catch
16875 {
16876 return ScriptBaseClass.JSON_INVALID;
16877 }
16878 }
16879
16880 private string ListToJson(object o)
16881 {
16882 if (o is LSL_Float || o is double)
16883 {
16884 double float_val;
16885 if (o is double)
16886 float_val = ((double)o);
16887 else
16888 float_val = ((LSL_Float)o).value;
16889
16890 if(double.IsInfinity(float_val))
16891 return "\"Inf\"";
16892 if(double.IsNaN(float_val))
16893 return "\"NaN\"";
16894
16895 return ((LSL_Float)float_val).ToString();
16896 }
16897 if (o is LSL_Integer || o is int)
16898 {
16899 int i;
16900 if (o is int)
16901 i = ((int)o);
16902 else
16903 i = ((LSL_Integer)o).value;
16904 return i.ToString();
16905 }
16906 if (o is LSL_Rotation)
16907 {
16908 StringBuilder sb = new StringBuilder(128);
16909 sb.Append("\"");
16910 LSL_Rotation r = (LSL_Rotation)o;
16911 sb.Append(r.ToString());
16912 sb.Append("\"");
16913 return sb.ToString();
16914 }
16915 if (o is LSL_Vector)
16916 {
16917 StringBuilder sb = new StringBuilder(128);
16918 sb.Append("\"");
16919 LSL_Vector v = (LSL_Vector)o;
16920 sb.Append(v.ToString());
16921 sb.Append("\"");
16922 return sb.ToString();
16923 }
16924 if (o is LSL_String || o is string)
16925 {
16926 string str;
16927 if (o is string)
16928 str = ((string)o);
16929 else
16930 str = ((LSL_String)o).m_string;
16931
16932 if(str == ScriptBaseClass.JSON_TRUE || str == "true")
16933 return "true";
16934 if(str == ScriptBaseClass.JSON_FALSE ||str == "false")
16935 return "false";
16936 if(str == ScriptBaseClass.JSON_NULL || str == "null")
16937 return "null";
16938 str.Trim();
16939 if (str[0] == '{')
16940 return str;
16941 if (str[0] == '[')
16942 return str;
16943 return EscapeForJSON(str, true);
16944 }
16945 throw new IndexOutOfRangeException();
16946 }
16947
16948 private string EscapeForJSON(string s, bool AddOuter)
16949 {
16950 int i;
16951 char c;
16952 String t;
16953 int len = s.Length;
16954
16955 StringBuilder sb = new StringBuilder(len + 64);
16956 if(AddOuter)
16957 sb.Append("\"");
16958
16959 for (i = 0; i < len; i++)
16960 {
16961 c = s[i];
16962 switch (c)
16963 {
16964 case '\\':
16965 case '"':
16966 case '/':
16967 sb.Append('\\');
16968 sb.Append(c);
16969 break;
16970 case '\b':
16971 sb.Append("\\b");
16972 break;
16973 case '\t':
16974 sb.Append("\\t");
16975 break;
16976 case '\n':
16977 sb.Append("\\n");
16978 break;
16979 case '\f':
16980 sb.Append("\\f");
16981 break;
16982 case '\r':
16983 sb.Append("\\r");
16984 break;
16985 default:
16986 if (c < ' ')
16987 {
16988 t = "000" + String.Format("X", c);
16989 sb.Append("\\u" + t.Substring(t.Length - 4));
16990 }
16991 else
16992 {
16993 sb.Append(c);
16994 }
16995 break;
16996 }
16997 }
16998 if(AddOuter)
16999 sb.Append("\"");
17000 return sb.ToString();
17001 }
17002
17003 public LSL_String llJsonSetValue(LSL_String json, LSL_List specifiers, LSL_String value)
17004 {
17005 bool noSpecifiers = specifiers.Length == 0;
17006 LitJson.JsonData workData;
17007 try
17008 {
17009 if(noSpecifiers)
17010 specifiers.Add(new LSL_Integer(0));
17011
17012 if(!String.IsNullOrEmpty(json))
17013 workData = LitJson.JsonMapper.ToObject(json);
17014 else
17015 {
17016 workData = new LitJson.JsonData();
17017 workData.SetJsonType(LitJson.JsonType.Array);
17018 }
17019 }
17020 catch (Exception e)
17021 {
17022 string m = e.Message; // debug point
17023 return ScriptBaseClass.JSON_INVALID;
17024 }
17025 try
17026 {
17027 LitJson.JsonData replace = JsonSetSpecific(workData, specifiers, 0, value);
17028 if(replace != null)
17029 workData = replace;
17030 }
17031 catch (Exception e)
17032 {
17033 string m = e.Message; // debug point
17034 return ScriptBaseClass.JSON_INVALID;
17035 }
17036
17037 try
17038 {
17039 string r = LitJson.JsonMapper.ToJson(workData);
17040 if(noSpecifiers)
17041 r = r.Substring(1,r.Length -2); // strip leading and trailing brakets
17042 return r;
17043 }
17044 catch (Exception e)
17045 {
17046 string m = e.Message; // debug point
17047 }
17048 return ScriptBaseClass.JSON_INVALID;
17049 }
17050
17051 private LitJson.JsonData JsonSetSpecific(LitJson.JsonData elem, LSL_List specifiers, int level, LSL_String val)
17052 {
17053 object spec = specifiers.Data[level];
17054 if(spec is LSL_String)
17055 spec = ((LSL_String)spec).m_string;
17056 else if (spec is LSL_Integer)
17057 spec = ((LSL_Integer)spec).value;
17058
17059 if(!(spec is string || spec is int))
17060 throw new IndexOutOfRangeException();
17061
17062 int speclen = specifiers.Data.Length - 1;
17063
17064 bool hasvalue = false;
17065 LitJson.JsonData value = null;
17066
17067 LitJson.JsonType elemType = elem.GetJsonType();
17068 if (elemType == LitJson.JsonType.Array)
17069 {
17070 if (spec is int)
17071 {
17072 int v = (int)spec;
17073 int c = elem.Count;
17074 if(v < 0 || (v != 0 && v > c))
17075 throw new IndexOutOfRangeException();
17076 if(v == c)
17077 elem.Add(JsonBuildRestOfSpec(specifiers, level + 1, val));
17078 else
17079 {
17080 hasvalue = true;
17081 value = elem[v];
17082 }
17083 }
17084 else if (spec is string)
17085 {
17086 if((string)spec == ScriptBaseClass.JSON_APPEND)
17087 elem.Add(JsonBuildRestOfSpec(specifiers, level + 1, val));
17088 else if(elem.Count < 2)
17089 {
17090 // our initial guess of array was wrong
17091 LitJson.JsonData newdata = new LitJson.JsonData();
17092 newdata.SetJsonType(LitJson.JsonType.Object);
17093 IOrderedDictionary no = newdata as IOrderedDictionary;
17094 no.Add((string)spec,JsonBuildRestOfSpec(specifiers, level + 1, val));
17095 return newdata;
17096 }
17097 }
17098 }
17099 else if (elemType == LitJson.JsonType.Object)
17100 {
17101 if (spec is string)
17102 {
17103 IOrderedDictionary e = elem as IOrderedDictionary;
17104 string key = (string)spec;
17105 if(e.Contains(key))
17106 {
17107 hasvalue = true;
17108 value = (LitJson.JsonData)e[key];
17109 }
17110 else
17111 e.Add(key, JsonBuildRestOfSpec(specifiers, level + 1, val));
17112 }
17113 else if(spec is int && (int)spec == 0)
17114 {
17115 //we are replacing a object by a array
17116 LitJson.JsonData newData = new LitJson.JsonData();
17117 newData.SetJsonType(LitJson.JsonType.Array);
17118 newData.Add(JsonBuildRestOfSpec(specifiers, level + 1, val));
17119 return newData;
17120 }
17121 }
17122 else
17123 {
17124 LitJson.JsonData newData = JsonBuildRestOfSpec(specifiers, level, val);
17125 return newData;
17126 }
17127
17128 if (hasvalue)
17129 {
17130 if (level < speclen)
17131 {
17132 LitJson.JsonData replace = JsonSetSpecific(value, specifiers, level + 1, val);
17133 if(replace != null)
17134 {
17135 if(elemType == LitJson.JsonType.Array)
17136 {
17137 if(spec is int)
17138 elem[(int)spec] = replace;
17139 else if( spec is string)
17140 {
17141 LitJson.JsonData newdata = new LitJson.JsonData();
17142 newdata.SetJsonType(LitJson.JsonType.Object);
17143 IOrderedDictionary no = newdata as IOrderedDictionary;
17144 no.Add((string)spec, replace);
17145 return newdata;
17146 }
17147 }
17148 else if(elemType == LitJson.JsonType.Object)
17149 {
17150 if(spec is string)
17151 elem[(string)spec] = replace;
17152 else if(spec is int && (int)spec == 0)
17153 {
17154 LitJson.JsonData newdata = new LitJson.JsonData();
17155 newdata.SetJsonType(LitJson.JsonType.Array);
17156 newdata.Add(replace);
17157 return newdata;
17158 }
17159 }
17160 }
17161 return null;
17162 }
17163 else if(speclen == level)
17164 {
17165 if(val == ScriptBaseClass.JSON_DELETE)
17166 {
17167 if(elemType == LitJson.JsonType.Array)
17168 {
17169 if(spec is int)
17170 {
17171 IList el = elem as IList;
17172 el.RemoveAt((int)spec);
17173 }
17174 }
17175 else if(elemType == LitJson.JsonType.Object)
17176 {
17177 if(spec is string)
17178 {
17179 IOrderedDictionary eo = elem as IOrderedDictionary;
17180 eo.Remove((string) spec);
17181 }
17182 }
17183 return null;
17184 }
17185
17186 LitJson.JsonData newval = null;
17187 float num;
17188 if(val == null || val == ScriptBaseClass.JSON_NULL || val == "null")
17189 newval = null;
17190 else if(val == ScriptBaseClass.JSON_TRUE || val == "true")
17191 newval = new LitJson.JsonData(true);
17192 else if(val == ScriptBaseClass.JSON_FALSE || val == "false")
17193 newval = new LitJson.JsonData(false);
17194 else if(float.TryParse(val, out num))
17195 {
17196 // assuming we are at en.us already
17197 if(num - (int)num == 0.0f && !val.Contains("."))
17198 newval = new LitJson.JsonData((int)num);
17199 else
17200 {
17201 num = (float)Math.Round(num,6);
17202 newval = new LitJson.JsonData((double)num);
17203 }
17204 }
17205 else
17206 {
17207 string str = val.m_string;
17208 newval = new LitJson.JsonData(str);
17209 }
17210
17211 if(elemType == LitJson.JsonType.Array)
17212 {
17213 if(spec is int)
17214 elem[(int)spec] = newval;
17215 else if( spec is string)
17216 {
17217 LitJson.JsonData newdata = new LitJson.JsonData();
17218 newdata.SetJsonType(LitJson.JsonType.Object);
17219 IOrderedDictionary no = newdata as IOrderedDictionary;
17220 no.Add((string)spec,newval);
17221 return newdata;
17222 }
17223 }
17224 else if(elemType == LitJson.JsonType.Object)
17225 {
17226 if(spec is string)
17227 elem[(string)spec] = newval;
17228 else if(spec is int && (int)spec == 0)
17229 {
17230 LitJson.JsonData newdata = new LitJson.JsonData();
17231 newdata.SetJsonType(LitJson.JsonType.Array);
17232 newdata.Add(newval);
17233 return newdata;
17234 }
17235 }
17236 }
17237 }
17238 if(val == ScriptBaseClass.JSON_DELETE)
17239 throw new IndexOutOfRangeException();
17240 return null;
17241 }
17242
17243 private LitJson.JsonData JsonBuildRestOfSpec(LSL_List specifiers, int level, LSL_String val)
17244 {
17245 object spec = level >= specifiers.Data.Length ? null : specifiers.Data[level];
17246 // 20131224 not used object specNext = i+1 >= specifiers.Data.Length ? null : specifiers.Data[i+1];
17247
17248 float num;
17249 if (spec == null)
17250 {
17251 if(val == null || val == ScriptBaseClass.JSON_NULL || val == "null")
17252 return null;
17253 if(val == ScriptBaseClass.JSON_DELETE)
17254 throw new IndexOutOfRangeException();
17255 if(val == ScriptBaseClass.JSON_TRUE || val == "true")
17256 return new LitJson.JsonData(true);
17257 if(val == ScriptBaseClass.JSON_FALSE || val == "false")
17258 return new LitJson.JsonData(false);
17259 if(val == null || val == ScriptBaseClass.JSON_NULL || val == "null")
17260 return null;
17261 if(float.TryParse(val, out num))
17262 {
17263 // assuming we are at en.us already
17264 if(num - (int)num == 0.0f && !val.Contains("."))
17265 return new LitJson.JsonData((int)num);
17266 else
17267 {
17268 num = (float)Math.Round(num,6);
17269 return new LitJson.JsonData(num);
17270 }
17271 }
17272 else
17273 {
17274 string str = val.m_string;
17275 return new LitJson.JsonData(str);
17276 }
17277 throw new IndexOutOfRangeException();
17278 }
17279
17280 if(spec is LSL_String)
17281 spec = ((LSL_String)spec).m_string;
17282 else if (spec is LSL_Integer)
17283 spec = ((LSL_Integer)spec).value;
17284
17285 if (spec is int ||
17286 (spec is string && ((string)spec) == ScriptBaseClass.JSON_APPEND) )
17287 {
17288 if(spec is int && (int)spec != 0)
17289 throw new IndexOutOfRangeException();
17290 LitJson.JsonData newdata = new LitJson.JsonData();
17291 newdata.SetJsonType(LitJson.JsonType.Array);
17292 newdata.Add(JsonBuildRestOfSpec(specifiers, level + 1, val));
17293 return newdata;
17294 }
17295 else if (spec is string)
17296 {
17297 LitJson.JsonData newdata = new LitJson.JsonData();
17298 newdata.SetJsonType(LitJson.JsonType.Object);
17299 IOrderedDictionary no = newdata as IOrderedDictionary;
17300 no.Add((string)spec,JsonBuildRestOfSpec(specifiers, level + 1, val));
17301 return newdata;
17302 }
17303 throw new IndexOutOfRangeException();
17304 }
17305
17306 private bool JsonFind(LitJson.JsonData elem, LSL_List specifiers, int level, out LitJson.JsonData value)
17307 {
17308 value = null;
17309 if(elem == null)
17310 return false;
17311
17312 object spec;
17313 spec = specifiers.Data[level];
17314
17315 bool haveVal = false;
17316 LitJson.JsonData next = null;
17317
17318 if (elem.GetJsonType() == LitJson.JsonType.Array)
17319 {
17320 if (spec is LSL_Integer)
17321 {
17322 int indx = (LSL_Integer)spec;
17323 if(indx >= 0 && indx < elem.Count)
17324 {
17325 haveVal = true;
17326 next = (LitJson.JsonData)elem[indx];
17327 }
17328 }
17329 }
17330 else if (elem.GetJsonType() == LitJson.JsonType.Object)
17331 {
17332 if (spec is LSL_String)
17333 {
17334 IOrderedDictionary e = elem as IOrderedDictionary;
17335 string key = (LSL_String)spec;
17336 if(e.Contains(key))
17337 {
17338 haveVal = true;
17339 next = (LitJson.JsonData)e[key];
17340 }
17341 }
17342 }
17343
17344 if (haveVal)
17345 {
17346 if(level == specifiers.Data.Length - 1)
17347 {
17348 value = next;
17349 return true;
17350 }
17351
17352 level++;
17353 if(next == null)
17354 return false;
17355
17356 LitJson.JsonType nextType = next.GetJsonType();
17357 if(nextType != LitJson.JsonType.Object && nextType != LitJson.JsonType.Array)
17358 return false;
17359
17360 return JsonFind(next, specifiers, level, out value);
17361 }
17362 return false;
17363 }
17364
17365 public LSL_String llJsonGetValue(LSL_String json, LSL_List specifiers)
17366 {
17367 if(String.IsNullOrWhiteSpace(json))
17368 return ScriptBaseClass.JSON_INVALID;
17369
17370 if(specifiers.Length > 0 && (json == "{}" || json == "[]"))
17371 return ScriptBaseClass.JSON_INVALID;
17372
17373 char first = ((string)json)[0];
17374 if((first != '[' && first !='{'))
17375 {
17376 if(specifiers.Length > 0)
17377 return ScriptBaseClass.JSON_INVALID;
17378 json = "[" + json + "]"; // could handle single element case.. but easier like this
17379 specifiers.Add((LSL_Integer)0);
17380 }
17381
17382 LitJson.JsonData jsonData;
17383 try
17384 {
17385 jsonData = LitJson.JsonMapper.ToObject(json);
17386 }
17387 catch (Exception e)
17388 {
17389 string m = e.Message; // debug point
17390 return ScriptBaseClass.JSON_INVALID;
17391 }
17392
17393 LitJson.JsonData elem = null;
17394 if(specifiers.Length == 0)
17395 elem = jsonData;
17396 else
17397 {
17398 if(!JsonFind(jsonData, specifiers, 0, out elem))
17399 return ScriptBaseClass.JSON_INVALID;
17400 }
17401 return JsonElementToString(elem);
17402 }
17403
17404 private LSL_String JsonElementToString(LitJson.JsonData elem)
17405 {
17406 if(elem == null)
17407 return ScriptBaseClass.JSON_NULL;
17408
17409 LitJson.JsonType elemType = elem.GetJsonType();
17410 switch(elemType)
17411 {
17412 case LitJson.JsonType.Array:
17413 return new LSL_String(LitJson.JsonMapper.ToJson(elem));
17414 case LitJson.JsonType.Boolean:
17415 return new LSL_String((bool)elem ? ScriptBaseClass.JSON_TRUE : ScriptBaseClass.JSON_FALSE);
17416 case LitJson.JsonType.Double:
17417 double d= (double)elem;
17418 string sd = String.Format(Culture.FormatProvider, "{0:0.0#####}",d);
17419 return new LSL_String(sd);
17420 case LitJson.JsonType.Int:
17421 int i = (int)elem;
17422 return new LSL_String(i.ToString());
17423 case LitJson.JsonType.Long:
17424 long l = (long)elem;
17425 return new LSL_String(l.ToString());
17426 case LitJson.JsonType.Object:
17427 return new LSL_String(LitJson.JsonMapper.ToJson(elem));
17428 case LitJson.JsonType.String:
17429 string s = (string)elem;
17430 return new LSL_String(s);
17431 case LitJson.JsonType.None:
17432 return ScriptBaseClass.JSON_NULL;
17433 default:
17434 return ScriptBaseClass.JSON_INVALID;
17435 }
17436 }
17437
17438 public LSL_String llJsonValueType(LSL_String json, LSL_List specifiers)
17439 {
17440 if(String.IsNullOrWhiteSpace(json))
17441 return ScriptBaseClass.JSON_INVALID;
17442
17443 if(specifiers.Length > 0 && (json == "{}" || json == "[]"))
17444 return ScriptBaseClass.JSON_INVALID;
17445
17446 char first = ((string)json)[0];
17447 if((first != '[' && first !='{'))
17448 {
17449 if(specifiers.Length > 0)
17450 return ScriptBaseClass.JSON_INVALID;
17451 json = "[" + json + "]"; // could handle single element case.. but easier like this
17452 specifiers.Add((LSL_Integer)0);
17453 }
17454
17455 LitJson.JsonData jsonData;
17456 try
17457 {
17458 jsonData = LitJson.JsonMapper.ToObject(json);
17459 }
17460 catch (Exception e)
17461 {
17462 string m = e.Message; // debug point
17463 return ScriptBaseClass.JSON_INVALID;
17464 }
17465
17466 LitJson.JsonData elem = null;
17467 if(specifiers.Length == 0)
17468 elem = jsonData;
17469 else
17470 {
17471 if(!JsonFind(jsonData, specifiers, 0, out elem))
17472 return ScriptBaseClass.JSON_INVALID;
17473 }
17474
17475 if(elem == null)
17476 return ScriptBaseClass.JSON_NULL;
17477
17478 LitJson.JsonType elemType = elem.GetJsonType();
17479 switch(elemType)
17480 {
17481 case LitJson.JsonType.Array:
17482 return ScriptBaseClass.JSON_ARRAY;
17483 case LitJson.JsonType.Boolean:
17484 return (bool)elem ? ScriptBaseClass.JSON_TRUE : ScriptBaseClass.JSON_FALSE;
17485 case LitJson.JsonType.Double:
17486 case LitJson.JsonType.Int:
17487 case LitJson.JsonType.Long:
17488 return ScriptBaseClass.JSON_NUMBER;
17489 case LitJson.JsonType.Object:
17490 return ScriptBaseClass.JSON_OBJECT;
17491 case LitJson.JsonType.String:
17492 string s = (string)elem;
17493 if(s == ScriptBaseClass.JSON_NULL)
17494 return ScriptBaseClass.JSON_NULL;
17495 if(s == ScriptBaseClass.JSON_TRUE)
17496 return ScriptBaseClass.JSON_TRUE;
17497 if(s == ScriptBaseClass.JSON_FALSE)
17498 return ScriptBaseClass.JSON_FALSE;
17499 return ScriptBaseClass.JSON_STRING;
17500 case LitJson.JsonType.None:
17501 return ScriptBaseClass.JSON_NULL;
17502 default:
17503 return ScriptBaseClass.JSON_INVALID;
17504 }
17505 }
14984 } 17506 }
14985 17507
14986 public class NotecardCache 17508 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..238fefb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
@@ -295,7 +295,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
295 idx++; 295 idx++;
296 try 296 try
297 { 297 {
298 iQ = rules.GetQuaternionItem(idx); 298 iQ = rules.GetVector4Item(idx);
299 } 299 }
300 catch (InvalidCastException) 300 catch (InvalidCastException)
301 { 301 {
@@ -319,7 +319,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
319 idx++; 319 idx++;
320 try 320 try
321 { 321 {
322 iQ = rules.GetQuaternionItem(idx); 322 iQ = rules.GetVector4Item(idx);
323 } 323 }
324 catch (InvalidCastException) 324 catch (InvalidCastException)
325 { 325 {
@@ -342,7 +342,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
342 idx++; 342 idx++;
343 try 343 try
344 { 344 {
345 iQ = rules.GetQuaternionItem(idx); 345 iQ = rules.GetVector4Item(idx);
346 } 346 }
347 catch (InvalidCastException) 347 catch (InvalidCastException)
348 { 348 {
@@ -532,7 +532,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
532 idx++; 532 idx++;
533 try 533 try
534 { 534 {
535 iQ = rules.GetQuaternionItem(idx); 535 iQ = rules.GetVector4Item(idx);
536 } 536 }
537 catch (InvalidCastException) 537 catch (InvalidCastException)
538 { 538 {
@@ -654,7 +654,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
654 break; 654 break;
655 case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: 655 case (int)ScriptBaseClass.WL_SUN_MOON_COLOR:
656 idx++; 656 idx++;
657 iQ = rules.GetQuaternionItem(idx); 657 iQ = rules.GetVector4Item(idx);
658 try 658 try
659 { 659 {
660 wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); 660 wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
@@ -721,7 +721,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
721 { 721 {
722 ScenePresence sp = World.GetScenePresence(m_host.OwnerID); 722 ScenePresence sp = World.GetScenePresence(m_host.OwnerID);
723 723
724 if (sp == null || sp.GodLevel < 200) 724 if (sp == null || !sp.IsViewerUIGod)
725 { 725 {
726 LSShoutError("lsSetWindlightScene can only be used by estate managers or owners."); 726 LSShoutError("lsSetWindlightScene can only be used by estate managers or owners.");
727 return 0; 727 return 0;
@@ -768,7 +768,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
768 { 768 {
769 ScenePresence sp = World.GetScenePresence(m_host.OwnerID); 769 ScenePresence sp = World.GetScenePresence(m_host.OwnerID);
770 770
771 if (sp == null || sp.GodLevel < 200) 771 if (sp == null || !sp.IsViewerUIGod)
772 { 772 {
773 LSShoutError("lsSetWindlightScene can only be used by estate managers or owners."); 773 LSShoutError("lsSetWindlightScene can only be used by estate managers or owners.");
774 return; 774 return;
@@ -799,7 +799,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
799 { 799 {
800 ScenePresence sp = World.GetScenePresence(m_host.OwnerID); 800 ScenePresence sp = World.GetScenePresence(m_host.OwnerID);
801 801
802 if (sp == null || sp.GodLevel < 200) 802 if (sp == null || !sp.IsViewerUIGod)
803 { 803 {
804 LSShoutError("lsSetWindlightSceneTargeted can only be used by estate managers or owners."); 804 LSShoutError("lsSetWindlightSceneTargeted can only be used by estate managers or owners.");
805 return 0; 805 return 0;
@@ -831,6 +831,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
831 } 831 }
832 832
833 return success; 833 return success;
834 } 834 }
835 } 835 }
836} 836}
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..6e28fe0 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,10 @@ 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 float m_ScriptDelayFactor = 1.0f;
143 internal float m_ScriptDistanceFactor = 1.0f;
144 internal bool m_debuggerSafe = false;
141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 145 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
142
143 protected IUrlModule m_UrlModule = null; 146 protected IUrlModule m_UrlModule = null;
144 147
145 public void Initialize( 148 public void Initialize(
@@ -148,6 +151,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
148 m_ScriptEngine = scriptEngine; 151 m_ScriptEngine = scriptEngine;
149 m_host = host; 152 m_host = host;
150 m_item = item; 153 m_item = item;
154 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
151 155
152 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 156 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
153 157
@@ -157,6 +161,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
157 // m_log.Warn("[OSSL] OSSL FUNCTIONS ENABLED"); 161 // m_log.Warn("[OSSL] OSSL FUNCTIONS ENABLED");
158 } 162 }
159 163
164 m_ScriptDelayFactor =
165 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
166 m_ScriptDistanceFactor =
167 m_ScriptEngine.Config.GetFloat("ScriptDistanceLimitFactor", 1.0f);
168
160 string risk = m_ScriptEngine.Config.GetString("OSFunctionThreatLevel", "VeryLow"); 169 string risk = m_ScriptEngine.Config.GetString("OSFunctionThreatLevel", "VeryLow");
161 switch (risk) 170 switch (risk)
162 { 171 {
@@ -187,7 +196,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
187 default: 196 default:
188 break; 197 break;
189 } 198 }
190 } 199 }
191 200
192 public override Object InitializeLifetimeService() 201 public override Object InitializeLifetimeService()
193 { 202 {
@@ -209,7 +218,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
209 218
210 internal void OSSLError(string msg) 219 internal void OSSLError(string msg)
211 { 220 {
212 OSSLShoutError("OSSL Runtime Error: " + msg); 221 if (m_debuggerSafe)
222 {
223 OSSLShoutError(msg);
224 }
225 else
226 {
227 throw new ScriptException("OSSL Runtime Error: " + msg);
228 }
213 } 229 }
214 230
215 /// <summary> 231 /// <summary>
@@ -244,22 +260,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
244 wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); 260 wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message);
245 } 261 }
246 262
247 // Returns of the function is allowed. Throws a script exception if not allowed. 263 // Returns if OSSL is enabled. Throws a script exception if OSSL is not allowed..
248 public bool CheckThreatLevel(ThreatLevel level, string function) 264 // for safe funtions always active
265 public void CheckThreatLevel()
249 { 266 {
267 m_host.AddScriptLPS(1);
250 if (!m_OSFunctionsEnabled) 268 if (!m_OSFunctionsEnabled)
251 { 269 OSSLError(String.Format("{0} permission denied. All OS functions are disabled.")); // throws
252 OSSLError(String.Format("{0} permission denied. All OS functions are disabled.", function)); 270 }
253 return false; 271
254 } 272 // Returns if the function is allowed. Throws a script exception if not allowed.
273 public void CheckThreatLevel(ThreatLevel level, string function)
274 {
275 m_host.AddScriptLPS(1);
276 if (!m_OSFunctionsEnabled)
277 OSSLError(String.Format("{0} permission denied. All OS functions are disabled.", function)); // throws
255 278
256 string reasonWhyNot = CheckThreatLevelTest(level, function); 279 string reasonWhyNot = CheckThreatLevelTest(level, function);
257 if (!String.IsNullOrEmpty(reasonWhyNot)) 280 if (!String.IsNullOrEmpty(reasonWhyNot))
258 { 281 {
259 OSSLError(reasonWhyNot); 282 OSSLError(reasonWhyNot);
260 return false;
261 } 283 }
262 return true;
263 } 284 }
264 285
265 // Check to see if function is allowed. Returns an empty string if function permitted 286 // Check to see if function is allowed. Returns an empty string if function permitted
@@ -299,7 +320,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
299 foreach (string id in ids) 320 foreach (string id in ids)
300 { 321 {
301 string current = id.Trim(); 322 string current = id.Trim();
302 if (current.ToUpper() == "PARCEL_GROUP_MEMBER" || current.ToUpper() == "PARCEL_OWNER" || current.ToUpper() == "ESTATE_MANAGER" || current.ToUpper() == "ESTATE_OWNER") 323 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 { 324 {
304 if (!perms.AllowedOwnerClasses.Contains(current)) 325 if (!perms.AllowedOwnerClasses.Contains(current))
305 perms.AllowedOwnerClasses.Add(current.ToUpper()); 326 perms.AllowedOwnerClasses.Add(current.ToUpper());
@@ -404,6 +425,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
404 } 425 }
405 } 426 }
406 427
428
429 //Only grid gods may use the function
430 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("GRID_GOD"))
431 {
432 if (World.Permissions.IsGridGod(ownerID))
433 {
434 return String.Empty;
435 }
436 }
437
438 //Any god may use the function
439 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("GOD"))
440 {
441 if (World.Permissions.IsAdministrator(ownerID))
442 {
443 return String.Empty;
444 }
445 }
446
447 //Only active gods may use the function
448 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("ACTIVE_GOD"))
449 {
450 ScenePresence sp = World.GetScenePresence(ownerID);
451 if (sp != null && !sp.IsDeleted && sp.IsGod)
452 {
453 return String.Empty;
454 }
455 }
456
407 if (!m_FunctionPerms[function].AllowedCreators.Contains(m_item.CreatorID)) 457 if (!m_FunctionPerms[function].AllowedCreators.Contains(m_item.CreatorID))
408 return( 458 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.", 459 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 +475,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
425 OSSLShoutError(string.Format("Use of function {0} is deprecated. Use {1} instead.", function, replacement)); 475 OSSLShoutError(string.Format("Use of function {0} is deprecated. Use {1} instead.", function, replacement));
426 } 476 }
427 477
478 protected void ScriptSleep(int delay)
479 {
480 delay = (int)((float)delay * m_ScriptDelayFactor);
481 if (delay == 0)
482 return;
483 System.Threading.Thread.Sleep(delay);
484 }
485
428 public LSL_Integer osSetTerrainHeight(int x, int y, double val) 486 public LSL_Integer osSetTerrainHeight(int x, int y, double val)
429 { 487 {
430 if (!CheckThreatLevel(ThreatLevel.High, "osSetTerrainHeight")) return 0; 488 CheckThreatLevel(ThreatLevel.High, "osSetTerrainHeight");
431 489
432 return SetTerrainHeight(x, y, val); 490 return SetTerrainHeight(x, y, val);
433 } 491 }
434 492
435 public LSL_Integer osTerrainSetHeight(int x, int y, double val) 493 public LSL_Integer osTerrainSetHeight(int x, int y, double val)
436 { 494 {
437 if (!CheckThreatLevel(ThreatLevel.High, "osTerrainSetHeight")) return 0; 495 CheckThreatLevel(ThreatLevel.High, "osTerrainSetHeight");
438 OSSLDeprecated("osTerrainSetHeight", "osSetTerrainHeight"); 496 OSSLDeprecated("osTerrainSetHeight", "osSetTerrainHeight");
439 497
440 return SetTerrainHeight(x, y, val); 498 return SetTerrainHeight(x, y, val);
@@ -442,8 +500,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
442 500
443 private LSL_Integer SetTerrainHeight(int x, int y, double val) 501 private LSL_Integer SetTerrainHeight(int x, int y, double val)
444 { 502 {
445 m_host.AddScriptLPS(1);
446
447 if (x > (World.RegionInfo.RegionSizeX - 1) || x < 0 || y > (World.RegionInfo.RegionSizeY - 1) || y < 0) 503 if (x > (World.RegionInfo.RegionSizeX - 1) || x < 0 || y > (World.RegionInfo.RegionSizeY - 1) || y < 0)
448 OSSLError("osSetTerrainHeight: Coordinate out of bounds"); 504 OSSLError("osSetTerrainHeight: Coordinate out of bounds");
449 505
@@ -460,18 +516,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
460 516
461 public LSL_Float osGetTerrainHeight(int x, int y) 517 public LSL_Float osGetTerrainHeight(int x, int y)
462 { 518 {
519 CheckThreatLevel();
463 return GetTerrainHeight(x, y); 520 return GetTerrainHeight(x, y);
464 } 521 }
465 522
466 public LSL_Float osTerrainGetHeight(int x, int y) 523 public LSL_Float osTerrainGetHeight(int x, int y)
467 { 524 {
525 CheckThreatLevel();
468 OSSLDeprecated("osTerrainGetHeight", "osGetTerrainHeight"); 526 OSSLDeprecated("osTerrainGetHeight", "osGetTerrainHeight");
469 return GetTerrainHeight(x, y); 527 return GetTerrainHeight(x, y);
470 } 528 }
471 529
472 private LSL_Float GetTerrainHeight(int x, int y) 530 private LSL_Float GetTerrainHeight(int x, int y)
473 { 531 {
474 m_host.AddScriptLPS(1);
475 if (x > (World.RegionInfo.RegionSizeX - 1) || x < 0 || y > (World.RegionInfo.RegionSizeY - 1) || y < 0) 532 if (x > (World.RegionInfo.RegionSizeX - 1) || x < 0 || y > (World.RegionInfo.RegionSizeY - 1) || y < 0)
476 OSSLError("osGetTerrainHeight: Coordinate out of bounds"); 533 OSSLError("osGetTerrainHeight: Coordinate out of bounds");
477 534
@@ -480,8 +537,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
480 537
481 public void osTerrainFlush() 538 public void osTerrainFlush()
482 { 539 {
483 if (!CheckThreatLevel(ThreatLevel.VeryLow, "osTerrainFlush")) return; 540 CheckThreatLevel(ThreatLevel.VeryLow, "osTerrainFlush");
484 m_host.AddScriptLPS(1);
485 541
486 ITerrainModule terrainModule = World.RequestModuleInterface<ITerrainModule>(); 542 ITerrainModule terrainModule = World.RequestModuleInterface<ITerrainModule>();
487 if (terrainModule != null) terrainModule.TaintTerrain(); 543 if (terrainModule != null) terrainModule.TaintTerrain();
@@ -495,31 +551,40 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
495 // The underlying functionality is fixed, since the security 551 // The underlying functionality is fixed, since the security
496 // as such is sound 552 // as such is sound
497 // 553 //
498 if (!CheckThreatLevel(ThreatLevel.High, "osRegionRestart")) return 0; 554 CheckThreatLevel(ThreatLevel.High, "osRegionRestart");
499 555
500 IRestartModule restartModule = World.RequestModuleInterface<IRestartModule>(); 556 IRestartModule restartModule = World.RequestModuleInterface<IRestartModule>();
501 m_host.AddScriptLPS(1);
502 if (World.Permissions.CanIssueEstateCommand(m_host.OwnerID, false) && (restartModule != null)) 557 if (World.Permissions.CanIssueEstateCommand(m_host.OwnerID, false) && (restartModule != null))
503 { 558 {
504 if (seconds < 15) 559 if (seconds < 15)
505 { 560 {
506 restartModule.AbortRestart("Restart aborted"); 561 restartModule.AbortRestart("Region restart has been aborted\n");
507 return 1; 562 return 1;
508 } 563 }
509 564
510 List<int> times = new List<int>(); 565 RegionRestart(seconds, String.Empty);
511 while (seconds > 0) 566 return 1;
567 }
568 else
569 {
570 return 0;
571 }
572 }
573
574 public int osRegionRestart(double seconds, string msg)
575 {
576 CheckThreatLevel(ThreatLevel.High, "osRegionRestart");
577
578 IRestartModule restartModule = World.RequestModuleInterface<IRestartModule>();
579 if (World.Permissions.CanIssueEstateCommand(m_host.OwnerID, false) && (restartModule != null))
580 {
581 if (seconds < 15)
512 { 582 {
513 times.Add((int)seconds); 583 restartModule.AbortRestart("Region restart has been aborted\n");
514 if (seconds > 300) 584 return 1;
515 seconds -= 120;
516 else if (seconds > 30)
517 seconds -= 30;
518 else
519 seconds -= 15;
520 } 585 }
521 586
522 restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), true); 587 RegionRestart(seconds, msg);
523 return 1; 588 return 1;
524 } 589 }
525 else 590 else
@@ -528,15 +593,38 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
528 } 593 }
529 } 594 }
530 595
596 private void RegionRestart(double seconds, string msg)
597 {
598 IRestartModule restartModule = World.RequestModuleInterface<IRestartModule>();
599
600 List<int> times = new List<int>();
601 while (seconds > 0)
602 {
603 times.Add((int)seconds);
604 if (seconds > 300)
605 seconds -= 120;
606 else if (seconds > 120)
607 seconds -= 60;
608 else if (seconds > 60)
609 seconds -= 30;
610 else
611 seconds -= 15;
612 }
613
614 if (msg == String.Empty)
615 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);
616
617 else
618 restartModule.ScheduleRestart(UUID.Zero, msg + "\n\nTime remaining: {0}.\n", times.ToArray(), true);
619 }
620
531 public void osRegionNotice(string msg) 621 public void osRegionNotice(string msg)
532 { 622 {
533 // This implementation provides absolutely no security 623 // This implementation provides absolutely no security
534 // It's high griefing potential makes this classification 624 // It's high griefing potential makes this classification
535 // necessary 625 // necessary
536 // 626 //
537 if (!CheckThreatLevel(ThreatLevel.VeryHigh, "osRegionNotice")) return; 627 CheckThreatLevel(ThreatLevel.VeryHigh, "osRegionNotice");
538
539 m_host.AddScriptLPS(1);
540 628
541 IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); 629 IDialogModule dm = World.RequestModuleInterface<IDialogModule>();
542 630
@@ -549,9 +637,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
549 // This function has no security. It can be used to destroy 637 // This function has no security. It can be used to destroy
550 // arbitrary builds the user would normally have no rights to 638 // arbitrary builds the user would normally have no rights to
551 // 639 //
552 if (!CheckThreatLevel(ThreatLevel.VeryHigh, "osSetRot")) return; 640 CheckThreatLevel(ThreatLevel.VeryHigh, "osSetRot");
553 641
554 m_host.AddScriptLPS(1);
555 if (World.Entities.ContainsKey(target)) 642 if (World.Entities.ContainsKey(target))
556 { 643 {
557 EntityBase entity; 644 EntityBase entity;
@@ -572,13 +659,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
572 public string osSetDynamicTextureURL(string dynamicID, string contentType, string url, string extraParams, 659 public string osSetDynamicTextureURL(string dynamicID, string contentType, string url, string extraParams,
573 int timer) 660 int timer)
574 { 661 {
575 m_host.AddScriptLPS(1); 662 // This may be upgraded depending on the griefing or DOS
663 // potential, or guarded with a delay
664 //
665 CheckThreatLevel(ThreatLevel.VeryLow, "osSetDynamicTextureURL");
666
576 if (dynamicID == String.Empty) 667 if (dynamicID == String.Empty)
577 { 668 {
578 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>(); 669 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>();
579 UUID createdTexture = 670 UUID createdTexture =
580 textureManager.AddDynamicTextureURL(World.RegionInfo.RegionID, m_host.UUID, contentType, url, 671 textureManager.AddDynamicTextureURL(World.RegionInfo.RegionID, m_host.UUID, contentType, url,
581 extraParams, timer); 672 extraParams);
582 return createdTexture.ToString(); 673 return createdTexture.ToString();
583 } 674 }
584 else 675 else
@@ -592,13 +683,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
592 public string osSetDynamicTextureURLBlend(string dynamicID, string contentType, string url, string extraParams, 683 public string osSetDynamicTextureURLBlend(string dynamicID, string contentType, string url, string extraParams,
593 int timer, int alpha) 684 int timer, int alpha)
594 { 685 {
595 m_host.AddScriptLPS(1); 686 CheckThreatLevel(ThreatLevel.VeryLow, "osSetDynamicTextureURLBlend");
687
596 if (dynamicID == String.Empty) 688 if (dynamicID == String.Empty)
597 { 689 {
598 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>(); 690 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>();
599 UUID createdTexture = 691 UUID createdTexture =
600 textureManager.AddDynamicTextureURL(World.RegionInfo.RegionID, m_host.UUID, contentType, url, 692 textureManager.AddDynamicTextureURL(World.RegionInfo.RegionID, m_host.UUID, contentType, url,
601 extraParams, timer, true, (byte) alpha); 693 extraParams, true, (byte) alpha);
602 return createdTexture.ToString(); 694 return createdTexture.ToString();
603 } 695 }
604 else 696 else
@@ -612,13 +704,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
612 public string osSetDynamicTextureURLBlendFace(string dynamicID, string contentType, string url, string extraParams, 704 public string osSetDynamicTextureURLBlendFace(string dynamicID, string contentType, string url, string extraParams,
613 bool blend, int disp, int timer, int alpha, int face) 705 bool blend, int disp, int timer, int alpha, int face)
614 { 706 {
615 m_host.AddScriptLPS(1); 707 CheckThreatLevel(ThreatLevel.VeryLow, "osSetDynamicTextureURLBlendFace");
708
616 if (dynamicID == String.Empty) 709 if (dynamicID == String.Empty)
617 { 710 {
618 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>(); 711 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>();
619 UUID createdTexture = 712 UUID createdTexture =
620 textureManager.AddDynamicTextureURL(World.RegionInfo.RegionID, m_host.UUID, contentType, url, 713 textureManager.AddDynamicTextureURL(World.RegionInfo.RegionID, m_host.UUID, contentType, url,
621 extraParams, timer, blend, disp, (byte) alpha, face); 714 extraParams, blend, disp, (byte) alpha, face);
622 return createdTexture.ToString(); 715 return createdTexture.ToString();
623 } 716 }
624 else 717 else
@@ -632,7 +725,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
632 public string osSetDynamicTextureData(string dynamicID, string contentType, string data, string extraParams, 725 public string osSetDynamicTextureData(string dynamicID, string contentType, string data, string extraParams,
633 int timer) 726 int timer)
634 { 727 {
635 m_host.AddScriptLPS(1); 728 return osSetDynamicTextureDataFace(dynamicID, contentType, data, extraParams, timer, -1);
729 }
730
731 public string osSetDynamicTextureDataFace(string dynamicID, string contentType, string data, string extraParams,
732 int timer, int face)
733 {
734 CheckThreatLevel(ThreatLevel.VeryLow, "osSetDynamicTextureData");
735
636 if (dynamicID == String.Empty) 736 if (dynamicID == String.Empty)
637 { 737 {
638 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>(); 738 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>();
@@ -644,7 +744,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
644 } 744 }
645 UUID createdTexture = 745 UUID createdTexture =
646 textureManager.AddDynamicTextureData(World.RegionInfo.RegionID, m_host.UUID, contentType, data, 746 textureManager.AddDynamicTextureData(World.RegionInfo.RegionID, m_host.UUID, contentType, data,
647 extraParams, timer); 747 extraParams, false, 3, 255, face);
748
648 return createdTexture.ToString(); 749 return createdTexture.ToString();
649 } 750 }
650 } 751 }
@@ -659,7 +760,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
659 public string osSetDynamicTextureDataBlend(string dynamicID, string contentType, string data, string extraParams, 760 public string osSetDynamicTextureDataBlend(string dynamicID, string contentType, string data, string extraParams,
660 int timer, int alpha) 761 int timer, int alpha)
661 { 762 {
662 m_host.AddScriptLPS(1); 763 CheckThreatLevel(ThreatLevel.VeryLow, "osSetDynamicTextureDataBlend");
764
663 if (dynamicID == String.Empty) 765 if (dynamicID == String.Empty)
664 { 766 {
665 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>(); 767 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>();
@@ -671,7 +773,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
671 } 773 }
672 UUID createdTexture = 774 UUID createdTexture =
673 textureManager.AddDynamicTextureData(World.RegionInfo.RegionID, m_host.UUID, contentType, data, 775 textureManager.AddDynamicTextureData(World.RegionInfo.RegionID, m_host.UUID, contentType, data,
674 extraParams, timer, true, (byte) alpha); 776 extraParams, true, (byte) alpha);
675 return createdTexture.ToString(); 777 return createdTexture.ToString();
676 } 778 }
677 } 779 }
@@ -686,7 +788,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
686 public string osSetDynamicTextureDataBlendFace(string dynamicID, string contentType, string data, string extraParams, 788 public string osSetDynamicTextureDataBlendFace(string dynamicID, string contentType, string data, string extraParams,
687 bool blend, int disp, int timer, int alpha, int face) 789 bool blend, int disp, int timer, int alpha, int face)
688 { 790 {
689 m_host.AddScriptLPS(1); 791 CheckThreatLevel(ThreatLevel.VeryLow , "osSetDynamicTextureDataBlendFace");
792
690 if (dynamicID == String.Empty) 793 if (dynamicID == String.Empty)
691 { 794 {
692 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>(); 795 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>();
@@ -698,7 +801,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
698 } 801 }
699 UUID createdTexture = 802 UUID createdTexture =
700 textureManager.AddDynamicTextureData(World.RegionInfo.RegionID, m_host.UUID, contentType, data, 803 textureManager.AddDynamicTextureData(World.RegionInfo.RegionID, m_host.UUID, contentType, data,
701 extraParams, timer, blend, disp, (byte) alpha, face); 804 extraParams, blend, disp, (byte) alpha, face);
702 return createdTexture.ToString(); 805 return createdTexture.ToString();
703 } 806 }
704 } 807 }
@@ -712,9 +815,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
712 815
713 public bool osConsoleCommand(string command) 816 public bool osConsoleCommand(string command)
714 { 817 {
715 if (!CheckThreatLevel(ThreatLevel.Severe, "osConsoleCommand")) return false; 818 CheckThreatLevel(ThreatLevel.Severe, "osConsoleCommand");
716
717 m_host.AddScriptLPS(1);
718 819
719 // For safety, we add another permission check here, and don't rely only on the standard OSSL permissions 820 // 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)) 821 if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID))
@@ -728,123 +829,183 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
728 829
729 public void osSetPrimFloatOnWater(int floatYN) 830 public void osSetPrimFloatOnWater(int floatYN)
730 { 831 {
731 if (!CheckThreatLevel(ThreatLevel.VeryLow, "osSetPrimFloatOnWater")) return; 832 CheckThreatLevel(ThreatLevel.VeryLow, "osSetPrimFloatOnWater");
732
733 m_host.AddScriptLPS(1);
734 833
735 m_host.ParentGroup.RootPart.SetFloatOnWater(floatYN); 834 m_host.ParentGroup.RootPart.SetFloatOnWater(floatYN);
736 } 835 }
737 836
837 private bool checkAllowAgentTPbyLandOwner(UUID agentId, Vector3 pos)
838 {
839 UUID hostOwner = m_host.OwnerID;
840
841 if(hostOwner == agentId)
842 return true;
843
844 if (m_item.PermsGranter == agentId)
845 {
846 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0)
847 return true;
848 }
849
850 ILandObject land = World.LandChannel.GetLandObject(pos);
851 if(land == null)
852 return true;
853
854 LandData landdata = land.LandData;
855 if(landdata == null)
856 return true;
857
858 if(landdata.OwnerID == hostOwner)
859 return true;
860
861 EstateSettings es = World.RegionInfo.EstateSettings;
862 if(es != null && es.IsEstateManagerOrOwner(hostOwner))
863 return true;
864
865 if(!landdata.IsGroupOwned)
866 return false;
867
868 UUID landGroup = landdata.GroupID;
869 if(landGroup == UUID.Zero)
870 return false;
871
872 if(landGroup == m_host.GroupID)
873 return true;
874
875 return false;
876 }
877
738 // Teleport functions 878 // Teleport functions
739 public void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) 879 public void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
740 { 880 {
741 // High because there is no security check. High griefer potential 881 // High because there is no security check. High griefer potential
742 // 882 //
743 if (!CheckThreatLevel(ThreatLevel.High, "osTeleportAgent")) return; 883 CheckThreatLevel(ThreatLevel.Severe, "osTeleportAgent");
744 884
745 TeleportAgent(agent, regionName, position, lookat, false); 885 TeleportAgent(agent, regionName, position, lookat);
746 } 886 }
747 887
748 private void TeleportAgent(string agent, string regionName, 888 private void TeleportAgent(string agent, string regionName,
749 LSL_Types.Vector3 position, LSL_Types.Vector3 lookat, bool relaxRestrictions) 889 LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
750 { 890 {
751 m_host.AddScriptLPS(1); 891 if(String.IsNullOrEmpty(regionName))
752 UUID agentId = new UUID(); 892 regionName = World.RegionInfo.RegionName;
893
894 UUID agentId;
753 if (UUID.TryParse(agent, out agentId)) 895 if (UUID.TryParse(agent, out agentId))
754 { 896 {
755 ScenePresence presence = World.GetScenePresence(agentId); 897 ScenePresence presence = World.GetScenePresence(agentId);
756 if (presence != null) 898 if (presence == null || presence.IsDeleted || presence.IsInTransit)
899 return;
900
901 Vector3 pos = presence.AbsolutePosition;
902 if(!checkAllowAgentTPbyLandOwner(agentId, pos))
757 { 903 {
758 // For osTeleportAgent, agent must be over owners land to avoid abuse 904 ScriptSleep(500);
759 // For osTeleportOwner, this restriction isn't necessary 905 return;
760 906 }
761 // commented out because its redundant and uneeded please remove eventually.
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 907
908 if(regionName == World.RegionInfo.RegionName)
909 {
910 // should be faster than going to threadpool
911 World.RequestTeleportLocation(presence.ControllingClient, regionName, position,
912 lookat, (uint)TPFlags.ViaLocation);
913 ScriptSleep(500);
914 }
915 else
916 {
917 // We will launch the teleport on a new thread so that when the script threads are terminated
918 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
919 Util.FireAndForget(
920 o => World.RequestTeleportLocation(
921 presence.ControllingClient, regionName, position,
922 lookat, (uint)TPFlags.ViaLocation),
923 null, "OSSL_Api.TeleportAgentByRegionCoords");
924 ScriptSleep(5000);
777 } 925 }
778 } 926 }
779 } 927 }
780 928
781 public void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) 929 public void osTeleportAgent(string agent, int regionGridX, int regionGridY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
782 { 930 {
783 // High because there is no security check. High griefer potential 931 // High because there is no security check. High griefer potential
784 // 932 //
785 if (!CheckThreatLevel(ThreatLevel.High, "osTeleportAgent")) return; 933 CheckThreatLevel(ThreatLevel.Severe, "osTeleportAgent");
786 934
787 TeleportAgent(agent, regionX, regionY, position, lookat, false); 935 TeleportAgent(agent, regionGridX, regionGridY, position, lookat);
788 } 936 }
789 937
790 private void TeleportAgent(string agent, int regionX, int regionY, 938 private void TeleportAgent(string agent, int regionGridX, int regionGridY,
791 LSL_Types.Vector3 position, LSL_Types.Vector3 lookat, bool relaxRestrictions) 939 LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
792 { 940 {
793 // ulong regionHandle = Util.UIntsToLong(((uint)regionX * (uint)Constants.RegionSize), ((uint)regionY * (uint)Constants.RegionSize)); 941 ulong regionHandle = Util.RegionGridLocToHandle((uint)regionGridX, (uint)regionGridY);
794 ulong regionHandle = Util.RegionLocToHandle((uint)regionX, (uint)regionY);
795 942
796 m_host.AddScriptLPS(1); 943 UUID agentId;
797 UUID agentId = new UUID();
798 if (UUID.TryParse(agent, out agentId)) 944 if (UUID.TryParse(agent, out agentId))
799 { 945 {
800 ScenePresence presence = World.GetScenePresence(agentId); 946 ScenePresence presence = World.GetScenePresence(agentId);
801 if (presence != null) 947 if (presence == null || presence.IsDeleted || presence.IsInTransit)
802 { 948 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 949
950 Vector3 pos = presence.AbsolutePosition;
951 if(!checkAllowAgentTPbyLandOwner(agentId, pos))
952 {
953 ScriptSleep(500);
954 return;
822 } 955 }
956
957 Util.FireAndForget(
958 o => World.RequestTeleportLocation(
959 presence.ControllingClient, regionHandle,
960 position, lookat, (uint)TPFlags.ViaLocation),
961 null, "OSSL_Api.TeleportAgentByRegionName");
962
963 ScriptSleep(5000);
823 } 964 }
824 } 965 }
825 966
826 public void osTeleportAgent(string agent, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) 967 public void osTeleportAgent(string agent, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
827 { 968 {
828 // High because there is no security check. High griefer potential 969 UUID agentId;
829 // 970 if (UUID.TryParse(agent, out agentId))
830 if (!CheckThreatLevel(ThreatLevel.High, "osTeleportAgent")) return; 971 {
972 ScenePresence presence = World.GetScenePresence(agentId);
973 if (presence == null || presence.IsDeleted || presence.IsInTransit)
974 return;
831 975
832 osTeleportAgent(agent, World.RegionInfo.RegionName, position, lookat); 976 Vector3 pos = presence.AbsolutePosition;
977 if(!checkAllowAgentTPbyLandOwner(agentId, pos))
978 {
979 ScriptSleep(500);
980 return;
981 }
982
983 World.RequestTeleportLocation(presence.ControllingClient, World.RegionInfo.RegionName, position,
984 lookat, (uint)TPFlags.ViaLocation);
985 ScriptSleep(500);
986 }
833 } 987 }
834 988
835 public void osTeleportOwner(string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) 989 public void osTeleportOwner(string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
836 { 990 {
837 TeleportAgent(m_host.OwnerID.ToString(), regionName, position, lookat, true); 991 // Threat level None because this is what can already be done with the World Map in the viewer
992 CheckThreatLevel(ThreatLevel.None, "osTeleportOwner");
993
994 TeleportAgent(m_host.OwnerID.ToString(), regionName, position, lookat);
838 } 995 }
839 996
840 public void osTeleportOwner(LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) 997 public void osTeleportOwner(int regionGridX, int regionGridY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
841 { 998 {
842 osTeleportOwner(World.RegionInfo.RegionName, position, lookat); 999 CheckThreatLevel(ThreatLevel.None, "osTeleportOwner");
1000
1001 TeleportAgent(m_host.OwnerID.ToString(), regionGridX, regionGridY, position, lookat);
843 } 1002 }
844 1003
845 public void osTeleportOwner(int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) 1004 public void osTeleportOwner(LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
846 { 1005 {
847 TeleportAgent(m_host.OwnerID.ToString(), regionX, regionY, position, lookat, true); 1006 CheckThreatLevel(ThreatLevel.None, "osTeleportOwner");
1007
1008 osTeleportAgent(m_host.OwnerID.ToString(), position, lookat);
848 } 1009 }
849 1010
850 ///<summary> 1011 ///<summary>
@@ -856,9 +1017,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
856 /// <param name="avatar"></param> 1017 /// <param name="avatar"></param>
857 public void osForceOtherSit(string avatar) 1018 public void osForceOtherSit(string avatar)
858 { 1019 {
859 if (!CheckThreatLevel(ThreatLevel.VeryHigh, "osForceOtherSit")) return; 1020 CheckThreatLevel(ThreatLevel.VeryHigh, "osForceOtherSit");
860
861 m_host.AddScriptLPS(1);
862 1021
863 ForceSit(avatar, m_host.UUID); 1022 ForceSit(avatar, m_host.UUID);
864 } 1023 }
@@ -871,9 +1030,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
871 /// <param name="target"></param> 1030 /// <param name="target"></param>
872 public void osForceOtherSit(string avatar, string target) 1031 public void osForceOtherSit(string avatar, string target)
873 { 1032 {
874 if (!CheckThreatLevel(ThreatLevel.VeryHigh, "osForceOtherSit")) return; 1033 CheckThreatLevel(ThreatLevel.VeryHigh, "osForceOtherSit");
875
876 m_host.AddScriptLPS(1);
877 1034
878 UUID targetID = new UUID(target); 1035 UUID targetID = new UUID(target);
879 1036
@@ -882,7 +1039,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
882 1039
883 public void ForceSit(string avatar, UUID targetID) 1040 public void ForceSit(string avatar, UUID targetID)
884 { 1041 {
885 UUID agentID; 1042 UUID agentID;
886 1043
887 if (!UUID.TryParse(avatar, out agentID)) 1044 if (!UUID.TryParse(avatar, out agentID))
888 return; 1045 return;
@@ -900,21 +1057,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
900 part.SitTargetPosition); 1057 part.SitTargetPosition);
901 } 1058 }
902 1059
903 // Functions that get information from the agent itself. 1060 // Get a list of all the avatars/agents in the region
904 // 1061 public LSL_List osGetAgents()
905 // osGetAgentIP - this is used to determine the IP address of 1062 {
906 //the client. This is needed to help configure other in world 1063 // threat level is None as we could get this information with an
907 //resources based on the IP address of the clients connected. 1064 // in-world script as well, just not as efficient
908 //I think High is a good risk level for this, as it is an 1065 CheckThreatLevel(ThreatLevel.None, "osGetAgents");
909 //information leak. 1066
910 // Severe is even better coz privacy is important. 1067 LSL_List result = new LSL_List();
1068 World.ForEachRootScenePresence(delegate(ScenePresence sp)
1069 {
1070 result.Add(new LSL_String(sp.Name));
1071 });
1072 return result;
1073 }
1074
911 public string osGetAgentIP(string agent) 1075 public string osGetAgentIP(string agent)
912 { 1076 {
913 if (!CheckThreatLevel(ThreatLevel.Severe, "osGetAgentIP")) return ""; 1077 CheckThreatLevel(ThreatLevel.Severe, "osGetAgentIP");
1078 if(!(World.Permissions.IsGod(m_host.OwnerID))) // user god always needed
1079 return "";
914 1080
915 UUID avatarID = (UUID)agent; 1081 UUID avatarID = (UUID)agent;
916 1082
917 m_host.AddScriptLPS(1);
918 if (World.Entities.ContainsKey((UUID)agent) && World.Entities[avatarID] is ScenePresence) 1083 if (World.Entities.ContainsKey((UUID)agent) && World.Entities[avatarID] is ScenePresence)
919 { 1084 {
920 ScenePresence target = (ScenePresence)World.Entities[avatarID]; 1085 ScenePresence target = (ScenePresence)World.Entities[avatarID];
@@ -925,61 +1090,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
925 return ""; 1090 return "";
926 } 1091 }
927 1092
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 1093 // Adam's super super custom animation functions
942 public void osAvatarPlayAnimation(string avatar, string animation) 1094 public void osAvatarPlayAnimation(string avatar, string animation)
943 { 1095 {
944 if (!CheckThreatLevel(ThreatLevel.VeryHigh, "osAvatarPlayAnimation")) return; 1096 CheckThreatLevel(ThreatLevel.VeryHigh, "osAvatarPlayAnimation");
945 1097
946 AvatarPlayAnimation(avatar, animation); 1098 AvatarPlayAnimation(avatar, animation);
947 } 1099 }
948 1100
949 private void AvatarPlayAnimation(string avatar, string animation) 1101 private void AvatarPlayAnimation(string avatar, string animation)
950 { 1102 {
951 UUID avatarID = (UUID)avatar; 1103 UUID avatarID;
1104 if(!UUID.TryParse(avatar, out avatarID))
1105 return;
952 1106
953 m_host.AddScriptLPS(1); 1107 ScenePresence target = World.GetScenePresence(avatarID);
954 if (World.Entities.ContainsKey((UUID)avatar) && World.Entities[avatarID] is ScenePresence) 1108 if (target == null)
1109 return;
1110
1111 UUID animID = UUID.Zero;
1112 m_host.TaskInventory.LockItemsForRead(true);
1113 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
955 { 1114 {
956 ScenePresence target = (ScenePresence)World.Entities[avatarID]; 1115 if (inv.Value.Type == (int)AssetType.Animation)
957 if (target != null)
958 { 1116 {
959 UUID animID=UUID.Zero; 1117 if (inv.Value.Name == animation)
960 lock (m_host.TaskInventory) 1118 {
961 { 1119 animID = inv.Value.AssetID;
962 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 1120 break;
963 { 1121 }
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 } 1122 }
977 } 1123 }
1124 m_host.TaskInventory.LockItemsForRead(false);
1125
1126 if (animID == UUID.Zero)
1127 target.Animator.AddAnimation(animation, m_host.UUID);
1128 else
1129 target.Animator.AddAnimation(animID, m_host.UUID);
978 } 1130 }
979 1131
980 public void osAvatarStopAnimation(string avatar, string animation) 1132 public void osAvatarStopAnimation(string avatar, string animation)
981 { 1133 {
982 if (!CheckThreatLevel(ThreatLevel.VeryHigh, "osAvatarStopAnimation")) return; 1134 CheckThreatLevel(ThreatLevel.VeryHigh, "osAvatarStopAnimation");
983 1135
984 AvatarStopAnimation(avatar, animation); 1136 AvatarStopAnimation(avatar, animation);
985 } 1137 }
@@ -988,8 +1140,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
988 { 1140 {
989 UUID avatarID = (UUID)avatar; 1141 UUID avatarID = (UUID)avatar;
990 1142
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 1143 // 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 1144 // 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 1145 // these functions call that common code. However, this does mean navigating the brain-dead requirement
@@ -1010,6 +1160,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1010 animID = UUID.Zero; 1160 animID = UUID.Zero;
1011 } 1161 }
1012 1162
1163
1013 if (animID == UUID.Zero) 1164 if (animID == UUID.Zero)
1014 target.Animator.RemoveAnimation(animation); 1165 target.Animator.RemoveAnimation(animation);
1015 else 1166 else
@@ -1019,58 +1170,106 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1019 } 1170 }
1020 1171
1021 //Texture draw functions 1172 //Texture draw functions
1173
1174 public string osDrawResetTransform(string drawList)
1175 {
1176 CheckThreatLevel();
1177
1178 drawList += "ResetTransf;";
1179 return drawList;
1180 }
1181
1182 public string osDrawRotationTransform(string drawList, LSL_Float x)
1183 {
1184 CheckThreatLevel();
1185
1186 drawList += "RotTransf " + x + ";";
1187 return drawList;
1188 }
1189
1190 public string osDrawScaleTransform(string drawList, LSL_Float x, LSL_Float y)
1191 {
1192 CheckThreatLevel();
1193
1194 drawList += "ScaleTransf " + x + "," + y + ";";
1195 return drawList;
1196 }
1197
1198 public string osDrawTranslationTransform(string drawList, LSL_Float x, LSL_Float y)
1199 {
1200 CheckThreatLevel();
1201
1202 drawList += "TransTransf " + x + "," + y + ";";
1203 return drawList;
1204 }
1205
1022 public string osMovePen(string drawList, int x, int y) 1206 public string osMovePen(string drawList, int x, int y)
1023 { 1207 {
1024 m_host.AddScriptLPS(1); 1208 CheckThreatLevel();
1209
1025 drawList += "MoveTo " + x + "," + y + ";"; 1210 drawList += "MoveTo " + x + "," + y + ";";
1026 return drawList; 1211 return drawList;
1027 } 1212 }
1028 1213
1029 public string osDrawLine(string drawList, int startX, int startY, int endX, int endY) 1214 public string osDrawLine(string drawList, int startX, int startY, int endX, int endY)
1030 { 1215 {
1031 m_host.AddScriptLPS(1); 1216 CheckThreatLevel();
1217
1032 drawList += "MoveTo "+ startX+","+ startY +"; LineTo "+endX +","+endY +"; "; 1218 drawList += "MoveTo "+ startX+","+ startY +"; LineTo "+endX +","+endY +"; ";
1033 return drawList; 1219 return drawList;
1034 } 1220 }
1035 1221
1036 public string osDrawLine(string drawList, int endX, int endY) 1222 public string osDrawLine(string drawList, int endX, int endY)
1037 { 1223 {
1038 m_host.AddScriptLPS(1); 1224 CheckThreatLevel();
1225
1039 drawList += "LineTo " + endX + "," + endY + "; "; 1226 drawList += "LineTo " + endX + "," + endY + "; ";
1040 return drawList; 1227 return drawList;
1041 } 1228 }
1042 1229
1043 public string osDrawText(string drawList, string text) 1230 public string osDrawText(string drawList, string text)
1044 { 1231 {
1045 m_host.AddScriptLPS(1); 1232 CheckThreatLevel(ThreatLevel.None, "osDrawText");
1233
1046 drawList += "Text " + text + "; "; 1234 drawList += "Text " + text + "; ";
1047 return drawList; 1235 return drawList;
1048 } 1236 }
1049 1237
1050 public string osDrawEllipse(string drawList, int width, int height) 1238 public string osDrawEllipse(string drawList, int width, int height)
1051 { 1239 {
1052 m_host.AddScriptLPS(1); 1240 CheckThreatLevel();
1241
1053 drawList += "Ellipse " + width + "," + height + "; "; 1242 drawList += "Ellipse " + width + "," + height + "; ";
1054 return drawList; 1243 return drawList;
1055 } 1244 }
1056 1245
1246 public string osDrawFilledEllipse(string drawList, int width, int height)
1247 {
1248 CheckThreatLevel();
1249
1250 drawList += "FillEllipse " + width + "," + height + "; ";
1251 return drawList;
1252 }
1253
1057 public string osDrawRectangle(string drawList, int width, int height) 1254 public string osDrawRectangle(string drawList, int width, int height)
1058 { 1255 {
1059 m_host.AddScriptLPS(1); 1256 CheckThreatLevel();
1257
1060 drawList += "Rectangle " + width + "," + height + "; "; 1258 drawList += "Rectangle " + width + "," + height + "; ";
1061 return drawList; 1259 return drawList;
1062 } 1260 }
1063 1261
1064 public string osDrawFilledRectangle(string drawList, int width, int height) 1262 public string osDrawFilledRectangle(string drawList, int width, int height)
1065 { 1263 {
1066 m_host.AddScriptLPS(1); 1264 CheckThreatLevel();
1265
1067 drawList += "FillRectangle " + width + "," + height + "; "; 1266 drawList += "FillRectangle " + width + "," + height + "; ";
1068 return drawList; 1267 return drawList;
1069 } 1268 }
1070 1269
1071 public string osDrawFilledPolygon(string drawList, LSL_List x, LSL_List y) 1270 public string osDrawFilledPolygon(string drawList, LSL_List x, LSL_List y)
1072 { 1271 {
1073 m_host.AddScriptLPS(1); 1272 CheckThreatLevel();
1074 1273
1075 if (x.Length != y.Length || x.Length < 3) 1274 if (x.Length != y.Length || x.Length < 3)
1076 { 1275 {
@@ -1087,7 +1286,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1087 1286
1088 public string osDrawPolygon(string drawList, LSL_List x, LSL_List y) 1287 public string osDrawPolygon(string drawList, LSL_List x, LSL_List y)
1089 { 1288 {
1090 m_host.AddScriptLPS(1); 1289 CheckThreatLevel();
1091 1290
1092 if (x.Length != y.Length || x.Length < 3) 1291 if (x.Length != y.Length || x.Length < 3)
1093 { 1292 {
@@ -1104,28 +1303,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1104 1303
1105 public string osSetFontSize(string drawList, int fontSize) 1304 public string osSetFontSize(string drawList, int fontSize)
1106 { 1305 {
1107 m_host.AddScriptLPS(1); 1306 CheckThreatLevel();
1307
1108 drawList += "FontSize "+ fontSize +"; "; 1308 drawList += "FontSize "+ fontSize +"; ";
1109 return drawList; 1309 return drawList;
1110 } 1310 }
1111 1311
1112 public string osSetFontName(string drawList, string fontName) 1312 public string osSetFontName(string drawList, string fontName)
1113 { 1313 {
1114 m_host.AddScriptLPS(1); 1314 CheckThreatLevel();
1315
1115 drawList += "FontName "+ fontName +"; "; 1316 drawList += "FontName "+ fontName +"; ";
1116 return drawList; 1317 return drawList;
1117 } 1318 }
1118 1319
1119 public string osSetPenSize(string drawList, int penSize) 1320 public string osSetPenSize(string drawList, int penSize)
1120 { 1321 {
1121 m_host.AddScriptLPS(1); 1322 CheckThreatLevel();
1323
1122 drawList += "PenSize " + penSize + "; "; 1324 drawList += "PenSize " + penSize + "; ";
1123 return drawList; 1325 return drawList;
1124 } 1326 }
1125 1327
1126 public string osSetPenColor(string drawList, string color) 1328 public string osSetPenColor(string drawList, string color)
1127 { 1329 {
1128 m_host.AddScriptLPS(1); 1330 CheckThreatLevel();
1331
1129 drawList += "PenColor " + color + "; "; 1332 drawList += "PenColor " + color + "; ";
1130 return drawList; 1333 return drawList;
1131 } 1334 }
@@ -1133,30 +1336,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1133 // Deprecated 1336 // Deprecated
1134 public string osSetPenColour(string drawList, string colour) 1337 public string osSetPenColour(string drawList, string colour)
1135 { 1338 {
1339 CheckThreatLevel();
1136 OSSLDeprecated("osSetPenColour", "osSetPenColor"); 1340 OSSLDeprecated("osSetPenColour", "osSetPenColor");
1137 1341
1138 m_host.AddScriptLPS(1);
1139 drawList += "PenColour " + colour + "; "; 1342 drawList += "PenColour " + colour + "; ";
1140 return drawList; 1343 return drawList;
1141 } 1344 }
1142 1345
1143 public string osSetPenCap(string drawList, string direction, string type) 1346 public string osSetPenCap(string drawList, string direction, string type)
1144 { 1347 {
1145 m_host.AddScriptLPS(1); 1348 CheckThreatLevel();
1349
1146 drawList += "PenCap " + direction + "," + type + "; "; 1350 drawList += "PenCap " + direction + "," + type + "; ";
1147 return drawList; 1351 return drawList;
1148 } 1352 }
1149 1353
1150 public string osDrawImage(string drawList, int width, int height, string imageUrl) 1354 public string osDrawImage(string drawList, int width, int height, string imageUrl)
1151 { 1355 {
1152 m_host.AddScriptLPS(1); 1356 CheckThreatLevel();
1357
1153 drawList +="Image " +width + "," + height+ ","+ imageUrl +"; " ; 1358 drawList +="Image " +width + "," + height+ ","+ imageUrl +"; " ;
1154 return drawList; 1359 return drawList;
1155 } 1360 }
1156 1361
1157 public LSL_Vector osGetDrawStringSize(string contentType, string text, string fontName, int fontSize) 1362 public LSL_Vector osGetDrawStringSize(string contentType, string text, string fontName, int fontSize)
1158 { 1363 {
1159 m_host.AddScriptLPS(1); 1364 CheckThreatLevel();
1160 1365
1161 LSL_Vector vec = new LSL_Vector(0,0,0); 1366 LSL_Vector vec = new LSL_Vector(0,0,0);
1162 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>(); 1367 IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>();
@@ -1178,17 +1383,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1178 // It was probably added as a crutch or debugging aid, and 1383 // It was probably added as a crutch or debugging aid, and
1179 // should be removed 1384 // should be removed
1180 // 1385 //
1181 if (!CheckThreatLevel(ThreatLevel.High, "osSetStateEvents")) return; 1386 CheckThreatLevel(ThreatLevel.High, "osSetStateEvents");
1182 m_host.AddScriptLPS(1);
1183 1387
1184 m_host.SetScriptEvents(m_item.ItemID, events); 1388 m_host.SetScriptEvents(m_item.ItemID, events);
1185 } 1389 }
1186 1390
1187 public void osSetRegionWaterHeight(double height) 1391 public void osSetRegionWaterHeight(double height)
1188 { 1392 {
1189 if (!CheckThreatLevel(ThreatLevel.High, "osSetRegionWaterHeight")) return; 1393 CheckThreatLevel(ThreatLevel.High, "osSetRegionWaterHeight");
1190
1191 m_host.AddScriptLPS(1);
1192 1394
1193 World.EventManager.TriggerRequestChangeWaterHeight((float)height); 1395 World.EventManager.TriggerRequestChangeWaterHeight((float)height);
1194 } 1396 }
@@ -1201,9 +1403,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> 1403 /// <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) 1404 public void osSetRegionSunSettings(bool useEstateSun, bool sunFixed, double sunHour)
1203 { 1405 {
1204 if (!CheckThreatLevel(ThreatLevel.High, "osSetRegionSunSettings")) return; 1406 CheckThreatLevel(ThreatLevel.High, "osSetRegionSunSettings");
1205
1206 m_host.AddScriptLPS(1);
1207 1407
1208 while (sunHour > 24.0) 1408 while (sunHour > 24.0)
1209 sunHour -= 24.0; 1409 sunHour -= 24.0;
@@ -1226,9 +1426,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> 1426 /// <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) 1427 public void osSetEstateSunSettings(bool sunFixed, double sunHour)
1228 { 1428 {
1229 if (!CheckThreatLevel(ThreatLevel.High, "osSetEstateSunSettings")) return; 1429 CheckThreatLevel(ThreatLevel.High, "osSetEstateSunSettings");
1230
1231 m_host.AddScriptLPS(1);
1232 1430
1233 while (sunHour > 24.0) 1431 while (sunHour > 24.0)
1234 sunHour -= 24.0; 1432 sunHour -= 24.0;
@@ -1250,7 +1448,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1250 /// <returns></returns> 1448 /// <returns></returns>
1251 public double osGetCurrentSunHour() 1449 public double osGetCurrentSunHour()
1252 { 1450 {
1253 m_host.AddScriptLPS(1); 1451 CheckThreatLevel();
1254 1452
1255 // Must adjust for the fact that Region Sun Settings are still LL offset 1453 // Must adjust for the fact that Region Sun Settings are still LL offset
1256 double sunHour = World.RegionInfo.RegionSettings.SunPosition - 6; 1454 double sunHour = World.RegionInfo.RegionSettings.SunPosition - 6;
@@ -1267,19 +1465,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1267 1465
1268 public double osSunGetParam(string param) 1466 public double osSunGetParam(string param)
1269 { 1467 {
1468 CheckThreatLevel(ThreatLevel.None, "osSunGetParam");
1270 OSSLDeprecated("osSunGetParam", "osGetSunParam"); 1469 OSSLDeprecated("osSunGetParam", "osGetSunParam");
1271 return GetSunParam(param); 1470 return GetSunParam(param);
1272 } 1471 }
1273 1472
1274 public double osGetSunParam(string param) 1473 public double osGetSunParam(string param)
1275 { 1474 {
1475 CheckThreatLevel();
1276 return GetSunParam(param); 1476 return GetSunParam(param);
1277 } 1477 }
1278 1478
1279 private double GetSunParam(string param) 1479 private double GetSunParam(string param)
1280 { 1480 {
1281 m_host.AddScriptLPS(1);
1282
1283 double value = 0.0; 1481 double value = 0.0;
1284 1482
1285 ISunModule module = World.RequestModuleInterface<ISunModule>(); 1483 ISunModule module = World.RequestModuleInterface<ISunModule>();
@@ -1293,21 +1491,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1293 1491
1294 public void osSunSetParam(string param, double value) 1492 public void osSunSetParam(string param, double value)
1295 { 1493 {
1296//// if (!CheckThreatLevel(ThreatLevel.None, "osSunSetParam")) return; 1494 CheckThreatLevel(ThreatLevel.None, "osSunSetParam");
1297 OSSLDeprecated("osSunSetParam", "osSetSunParam"); 1495 OSSLDeprecated("osSunSetParam", "osSetSunParam");
1298 SetSunParam(param, value); 1496 SetSunParam(param, value);
1299 } 1497 }
1300 1498
1301 public void osSetSunParam(string param, double value) 1499 public void osSetSunParam(string param, double value)
1302 { 1500 {
1303//// if (!CheckThreatLevel(ThreatLevel.None, "osSetSunParam")) return; 1501 CheckThreatLevel(ThreatLevel.None, "osSetSunParam");
1304 SetSunParam(param, value); 1502 SetSunParam(param, value);
1305 } 1503 }
1306 1504
1307 private void SetSunParam(string param, double value) 1505 private void SetSunParam(string param, double value)
1308 { 1506 {
1309 m_host.AddScriptLPS(1);
1310
1311 ISunModule module = World.RequestModuleInterface<ISunModule>(); 1507 ISunModule module = World.RequestModuleInterface<ISunModule>();
1312 if (module != null) 1508 if (module != null)
1313 { 1509 {
@@ -1317,7 +1513,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1317 1513
1318 public string osWindActiveModelPluginName() 1514 public string osWindActiveModelPluginName()
1319 { 1515 {
1320 m_host.AddScriptLPS(1); 1516 CheckThreatLevel(ThreatLevel.None, "osWindActiveModelPluginName");
1321 1517
1322 IWindModule module = World.RequestModuleInterface<IWindModule>(); 1518 IWindModule module = World.RequestModuleInterface<IWindModule>();
1323 if (module != null) 1519 if (module != null)
@@ -1330,8 +1526,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1330 1526
1331 public void osSetWindParam(string plugin, string param, LSL_Float value) 1527 public void osSetWindParam(string plugin, string param, LSL_Float value)
1332 { 1528 {
1333 if (!CheckThreatLevel(ThreatLevel.VeryLow, "osSetWindParam")) return; 1529 CheckThreatLevel(ThreatLevel.VeryLow, "osSetWindParam");
1334 m_host.AddScriptLPS(1);
1335 1530
1336 IWindModule module = World.RequestModuleInterface<IWindModule>(); 1531 IWindModule module = World.RequestModuleInterface<IWindModule>();
1337 if (module != null) 1532 if (module != null)
@@ -1346,7 +1541,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1346 1541
1347 public LSL_Float osGetWindParam(string plugin, string param) 1542 public LSL_Float osGetWindParam(string plugin, string param)
1348 { 1543 {
1349 m_host.AddScriptLPS(1); 1544 CheckThreatLevel(ThreatLevel.VeryLow, "osGetWindParam");
1350 1545
1351 IWindModule module = World.RequestModuleInterface<IWindModule>(); 1546 IWindModule module = World.RequestModuleInterface<IWindModule>();
1352 if (module != null) 1547 if (module != null)
@@ -1360,8 +1555,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1360 // Routines for creating and managing parcels programmatically 1555 // Routines for creating and managing parcels programmatically
1361 public void osParcelJoin(LSL_Vector pos1, LSL_Vector pos2) 1556 public void osParcelJoin(LSL_Vector pos1, LSL_Vector pos2)
1362 { 1557 {
1363 if (!CheckThreatLevel(ThreatLevel.High, "osParcelJoin")) return; 1558 CheckThreatLevel(ThreatLevel.High, "osParcelJoin");
1364 m_host.AddScriptLPS(1);
1365 1559
1366 int startx = (int)(pos1.x < pos2.x ? pos1.x : pos2.x); 1560 int startx = (int)(pos1.x < pos2.x ? pos1.x : pos2.x);
1367 int starty = (int)(pos1.y < pos2.y ? pos1.y : pos2.y); 1561 int starty = (int)(pos1.y < pos2.y ? pos1.y : pos2.y);
@@ -1373,8 +1567,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1373 1567
1374 public void osParcelSubdivide(LSL_Vector pos1, LSL_Vector pos2) 1568 public void osParcelSubdivide(LSL_Vector pos1, LSL_Vector pos2)
1375 { 1569 {
1376 if (!CheckThreatLevel(ThreatLevel.High, "osParcelSubdivide")) return; 1570 CheckThreatLevel(ThreatLevel.High, "osParcelSubdivide");
1377 m_host.AddScriptLPS(1);
1378 1571
1379 int startx = (int)(pos1.x < pos2.x ? pos1.x : pos2.x); 1572 int startx = (int)(pos1.x < pos2.x ? pos1.x : pos2.x);
1380 int starty = (int)(pos1.y < pos2.y ? pos1.y : pos2.y); 1573 int starty = (int)(pos1.y < pos2.y ? pos1.y : pos2.y);
@@ -1387,7 +1580,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1387 public void osParcelSetDetails(LSL_Vector pos, LSL_List rules) 1580 public void osParcelSetDetails(LSL_Vector pos, LSL_List rules)
1388 { 1581 {
1389 const string functionName = "osParcelSetDetails"; 1582 const string functionName = "osParcelSetDetails";
1390 if (!CheckThreatLevel(ThreatLevel.High, functionName)) return; 1583 CheckThreatLevel(ThreatLevel.High, functionName);
1391 OSSLDeprecated(functionName, "osSetParcelDetails"); 1584 OSSLDeprecated(functionName, "osSetParcelDetails");
1392 SetParcelDetails(pos, rules, functionName); 1585 SetParcelDetails(pos, rules, functionName);
1393 } 1586 }
@@ -1395,14 +1588,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1395 public void osSetParcelDetails(LSL_Vector pos, LSL_List rules) 1588 public void osSetParcelDetails(LSL_Vector pos, LSL_List rules)
1396 { 1589 {
1397 const string functionName = "osSetParcelDetails"; 1590 const string functionName = "osSetParcelDetails";
1398 if (!CheckThreatLevel(ThreatLevel.High, functionName)) return; 1591 CheckThreatLevel(ThreatLevel.High, functionName);
1399 SetParcelDetails(pos, rules, functionName); 1592 SetParcelDetails(pos, rules, functionName);
1400 } 1593 }
1401 1594
1402 private void SetParcelDetails(LSL_Vector pos, LSL_List rules, string functionName) 1595 private void SetParcelDetails(LSL_Vector pos, LSL_List rules, string functionName)
1403 { 1596 {
1404 m_host.AddScriptLPS(1);
1405
1406 // Get a reference to the land data and make sure the owner of the script 1597 // Get a reference to the land data and make sure the owner of the script
1407 // can modify it 1598 // can modify it
1408 1599
@@ -1413,15 +1604,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1413 return; 1604 return;
1414 } 1605 }
1415 1606
1416 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, startLandObject, GroupPowers.LandOptions)) 1607 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, startLandObject, GroupPowers.LandOptions, false))
1417 { 1608 {
1418 OSSLShoutError("You do not have permission to modify the parcel"); 1609 OSSLShoutError("script owner does not have permission to modify the parcel");
1419 return; 1610 return;
1420 } 1611 }
1421 1612
1422 // Create a new land data object we can modify 1613 // Create a new land data object we can modify
1423 LandData newLand = startLandObject.LandData.Copy(); 1614 LandData newLand = startLandObject.LandData.Copy();
1424 UUID uuid; 1615 UUID uuid;
1616 EstateSettings es = World.RegionInfo.EstateSettings;
1617
1618 bool changed = false;
1619 bool changedSeeAvs = false;
1620 bool changedoverlay = false;
1621 bool changedneedupdate = false;
1425 1622
1426 // Process the rules, not sure what the impact would be of changing owner or group 1623 // Process the rules, not sure what the impact would be of changing owner or group
1427 for (int idx = 0; idx < rules.Length;) 1624 for (int idx = 0; idx < rules.Length;)
@@ -1431,35 +1628,151 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1431 switch (code) 1628 switch (code)
1432 { 1629 {
1433 case ScriptBaseClass.PARCEL_DETAILS_NAME: 1630 case ScriptBaseClass.PARCEL_DETAILS_NAME:
1434 newLand.Name = arg; 1631 if(newLand.Name != arg)
1632 {
1633 newLand.Name = arg;
1634 changed = true;
1635 }
1435 break; 1636 break;
1436 1637
1437 case ScriptBaseClass.PARCEL_DETAILS_DESC: 1638 case ScriptBaseClass.PARCEL_DETAILS_DESC:
1438 newLand.Description = arg; 1639 if(newLand.Description != arg)
1640 {
1641 newLand.Description = arg;
1642 changed = true;
1643 }
1439 break; 1644 break;
1440 1645
1441 case ScriptBaseClass.PARCEL_DETAILS_OWNER: 1646 case ScriptBaseClass.PARCEL_DETAILS_OWNER:
1442 if (!CheckThreatLevel(ThreatLevel.VeryHigh, functionName)) return; 1647 if(es != null && !es.IsEstateManagerOrOwner(m_host.OwnerID))
1443 if (UUID.TryParse(arg, out uuid)) 1648 {
1444 newLand.OwnerID = uuid; 1649 OSSLError("script owner does not have permission to modify the parcel owner");
1650 }
1651 else
1652 {
1653 if (UUID.TryParse(arg, out uuid))
1654 {
1655 if(newLand.OwnerID != uuid)
1656 {
1657 changed = true;
1658 newLand.OwnerID = uuid;
1659 newLand.GroupID = UUID.Zero;
1660 }
1661 }
1662 }
1445 break; 1663 break;
1446 1664
1447 case ScriptBaseClass.PARCEL_DETAILS_GROUP: 1665 case ScriptBaseClass.PARCEL_DETAILS_GROUP:
1448 if (!CheckThreatLevel(ThreatLevel.VeryHigh, functionName)) return; 1666 if(m_host.OwnerID == newLand.OwnerID || es == null || es.IsEstateManagerOrOwner(m_host.OwnerID))
1449 if (UUID.TryParse(arg, out uuid)) 1667 {
1450 newLand.GroupID = uuid; 1668 if (UUID.TryParse(arg, out uuid))
1669 {
1670 if(newLand.GroupID != uuid)
1671 {
1672 if(uuid == UUID.Zero)
1673 {
1674 changed = true;
1675 newLand.GroupID = uuid;
1676 }
1677 else
1678 {
1679 IGroupsModule groupsModule = m_ScriptEngine.World.RequestModuleInterface<IGroupsModule>();
1680 GroupMembershipData member = null;
1681 if (groupsModule != null)
1682 member = groupsModule.GetMembershipData(uuid, newLand.OwnerID);
1683 if (member == null)
1684 OSSLError(string.Format("land owner is not member of the new group for parcel"));
1685 else
1686 {
1687 changed = true;
1688 newLand.GroupID = uuid;
1689 }
1690 }
1691 }
1692 }
1693 }
1694 else
1695 {
1696 OSSLError("script owner does not have permission to modify the parcel group");
1697 }
1451 break; 1698 break;
1452 1699
1453 case ScriptBaseClass.PARCEL_DETAILS_CLAIMDATE: 1700 case ScriptBaseClass.PARCEL_DETAILS_CLAIMDATE:
1454 if (!CheckThreatLevel(ThreatLevel.VeryHigh, functionName)) return; 1701 if(es != null && !es.IsEstateManagerOrOwner(m_host.OwnerID))
1455 newLand.ClaimDate = Convert.ToInt32(arg); 1702 {
1456 if (newLand.ClaimDate == 0) 1703 OSSLError("script owner does not have permission to modify the parcel CLAIM DATE");
1457 newLand.ClaimDate = Util.UnixTimeSinceEpoch(); 1704 }
1705 else
1706 {
1707 int date = Convert.ToInt32(arg);
1708 if (date == 0)
1709 date = Util.UnixTimeSinceEpoch();
1710 if(newLand.ClaimDate != date)
1711 {
1712 changed = true;
1713 newLand.ClaimDate = date;
1714 }
1715 }
1458 break; 1716 break;
1459 }
1460 }
1461 1717
1462 World.LandChannel.UpdateLandObject(newLand.LocalID,newLand); 1718 case ScriptBaseClass.PARCEL_DETAILS_SEE_AVATARS:
1719 bool newavs = (Convert.ToInt32(arg) != 0);
1720 if(newLand.SeeAVs != newavs)
1721 {
1722 changed = true;
1723 changedSeeAvs = true;
1724 changedoverlay = true;
1725 changedneedupdate = true;
1726 newLand.SeeAVs = newavs;
1727 }
1728 break;
1729
1730 case ScriptBaseClass.PARCEL_DETAILS_ANY_AVATAR_SOUNDS:
1731 bool newavsounds = (Convert.ToInt32(arg) != 0);
1732 if(newLand.AnyAVSounds != newavsounds)
1733 {
1734 changed = true;
1735 newLand.AnyAVSounds = newavsounds;
1736 }
1737 break;
1738
1739 case ScriptBaseClass.PARCEL_DETAILS_GROUP_SOUNDS:
1740 bool newgrpsounds = (Convert.ToInt32(arg) != 0);
1741 if(newLand.GroupAVSounds != newgrpsounds)
1742 {
1743 changed = true;
1744 newLand.GroupAVSounds = newgrpsounds;
1745 }
1746 break;
1747 }
1748 }
1749 if(changed)
1750 {
1751 World.LandChannel.UpdateLandObject(newLand.LocalID, newLand);
1752
1753 if(changedneedupdate)
1754 {
1755 UUID parcelID= newLand.GlobalID;
1756 World.ForEachRootScenePresence(delegate (ScenePresence avatar)
1757 {
1758 if (avatar == null || avatar.IsDeleted || avatar.IsInTransit)
1759 return;
1760
1761 if(changedSeeAvs && avatar.currentParcelUUID == parcelID )
1762 avatar.currentParcelUUID = parcelID; // force parcel flags review
1763
1764 if(avatar.ControllingClient == null)
1765 return;
1766
1767 // this will be needed for some things like damage etc
1768// if(avatar.currentParcelUUID == parcelID)
1769// startLandObject.SendLandUpdateToClient(avatar.ControllingClient);
1770
1771 if(changedoverlay && !avatar.IsNPC)
1772 World.LandChannel.SendParcelsOverlay(avatar.ControllingClient);
1773 });
1774 }
1775 }
1463 } 1776 }
1464 1777
1465 public double osList2Double(LSL_Types.list src, int index) 1778 public double osList2Double(LSL_Types.list src, int index)
@@ -1469,7 +1782,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1469 // is not allowed to contain any. 1782 // is not allowed to contain any.
1470 // This really should be removed. 1783 // This really should be removed.
1471 // 1784 //
1472 m_host.AddScriptLPS(1); 1785 CheckThreatLevel();
1786
1473 if (index < 0) 1787 if (index < 0)
1474 { 1788 {
1475 index = src.Length + index; 1789 index = src.Length + index;
@@ -1485,9 +1799,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1485 { 1799 {
1486 // What actually is the difference to the LL function? 1800 // What actually is the difference to the LL function?
1487 // 1801 //
1488 if (!CheckThreatLevel(ThreatLevel.VeryLow, "osSetParcelMediaURL")) return; 1802 CheckThreatLevel(ThreatLevel.VeryLow, "osSetParcelMediaURL");
1489
1490 m_host.AddScriptLPS(1);
1491 1803
1492 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 1804 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
1493 1805
@@ -1501,9 +1813,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1501 { 1813 {
1502 // What actually is the difference to the LL function? 1814 // What actually is the difference to the LL function?
1503 // 1815 //
1504 if (!CheckThreatLevel(ThreatLevel.VeryLow, "osSetParcelSIPAddress")) return; 1816 CheckThreatLevel(ThreatLevel.VeryLow, "osSetParcelSIPAddress");
1505
1506 m_host.AddScriptLPS(1);
1507 1817
1508 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 1818 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
1509 1819
@@ -1529,9 +1839,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1529 // that trigger engine-specific failures. 1839 // that trigger engine-specific failures.
1530 // Besides, public grid users aren't supposed to know. 1840 // Besides, public grid users aren't supposed to know.
1531 // 1841 //
1532 // On the other hand, what other script engines are there? 1842 CheckThreatLevel(ThreatLevel.High, "osGetScriptEngineName");
1533 //
1534 m_host.AddScriptLPS(1);
1535 1843
1536 int scriptEngineNameIndex = 0; 1844 int scriptEngineNameIndex = 0;
1537 1845
@@ -1557,7 +1865,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1557 1865
1558 public LSL_Integer osCheckODE() 1866 public LSL_Integer osCheckODE()
1559 { 1867 {
1560 m_host.AddScriptLPS(1); 1868 CheckThreatLevel();
1869
1561 LSL_Integer ret = 0; // false 1870 LSL_Integer ret = 0; // false
1562 if (m_ScriptEngine.World.PhysicsScene != null) 1871 if (m_ScriptEngine.World.PhysicsScene != null)
1563 { 1872 {
@@ -1580,22 +1889,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1580 // about the physics engine, this function returns an empty string if 1889 // 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 1890 // the user does not have permission to see it. This as opposed to
1582 // throwing an exception. 1891 // throwing an exception.
1892
1583 m_host.AddScriptLPS(1); 1893 m_host.AddScriptLPS(1);
1584 string ret = String.Empty; 1894 string ret = String.Empty;
1895 if (String.IsNullOrEmpty(CheckThreatLevelTest(ThreatLevel.High, "osGetPhysicsEngineType")))
1896 {
1897 if (m_ScriptEngine.World.PhysicsScene != null)
1898 {
1899 ret = m_ScriptEngine.World.PhysicsScene.EngineType;
1900 // An old physics engine might have an uninitialized engine type
1901 if (ret == null)
1902 ret = "unknown";
1903 }
1904 }
1905
1906 return ret;
1907 }
1908
1909 public string osGetPhysicsEngineName()
1910 {
1911 CheckThreatLevel();
1912
1913 string ret = "NoEngine";
1585 if (m_ScriptEngine.World.PhysicsScene != null) 1914 if (m_ScriptEngine.World.PhysicsScene != null)
1586 { 1915 {
1587 ret = m_ScriptEngine.World.PhysicsScene.EngineType; 1916 ret = m_ScriptEngine.World.PhysicsScene.EngineName;
1588 // An old physics engine might have an uninitialized engine type 1917 // An old physics engine might have an uninitialized engine type
1589 if (ret == null) 1918 if (ret == null)
1590 ret = "unknown"; 1919 ret = "UnknownEngine";
1591 } 1920 }
1592
1593 return ret; 1921 return ret;
1594 } 1922 }
1595 1923
1596 public string osGetSimulatorVersion() 1924 public string osGetSimulatorVersion()
1597 { 1925 {
1598 m_host.AddScriptLPS(1); 1926 // High because it can be used to target attacks to known weaknesses
1927 // This would allow a new class of griefer scripts that don't even
1928 // require their user to know what they are doing (see script
1929 // kiddie)
1930 //
1931 CheckThreatLevel(ThreatLevel.High,"osGetSimulatorVersion");
1599 1932
1600 return m_ScriptEngine.World.GetSimulatorVersion(); 1933 return m_ScriptEngine.World.GetSimulatorVersion();
1601 } 1934 }
@@ -1639,7 +1972,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1639 1972
1640 public Object osParseJSONNew(string JSON) 1973 public Object osParseJSONNew(string JSON)
1641 { 1974 {
1642 m_host.AddScriptLPS(1); 1975 CheckThreatLevel(ThreatLevel.None, "osParseJSONNew");
1643 1976
1644 try 1977 try
1645 { 1978 {
@@ -1648,14 +1981,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1648 } 1981 }
1649 catch(Exception e) 1982 catch(Exception e)
1650 { 1983 {
1651 OSSLError("osParseJSONNew: Problems decoding JSON string " + JSON + " : " + e.Message); 1984 OSSLError("osParseJSONNew: Problems decoding JSON string " + JSON + " : " + e.Message) ;
1652 return null; 1985 return null;
1653 } 1986 }
1654 } 1987 }
1655 1988
1656 public Hashtable osParseJSON(string JSON) 1989 public Hashtable osParseJSON(string JSON)
1657 { 1990 {
1658 m_host.AddScriptLPS(1); 1991 CheckThreatLevel(ThreatLevel.None, "osParseJSON");
1659 1992
1660 Object decoded = osParseJSONNew(JSON); 1993 Object decoded = osParseJSONNew(JSON);
1661 1994
@@ -1686,7 +2019,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1686 /// <param name="message"></param> 2019 /// <param name="message"></param>
1687 public void osMessageObject(LSL_Key objectUUID, string message) 2020 public void osMessageObject(LSL_Key objectUUID, string message)
1688 { 2021 {
1689 m_host.AddScriptLPS(1); 2022 CheckThreatLevel(ThreatLevel.Low, "osMessageObject");
1690 2023
1691 UUID objUUID; 2024 UUID objUUID;
1692 if (!UUID.TryParse(objectUUID, out objUUID)) // prior to patching, a thrown exception regarding invalid GUID format would be shouted instead. 2025 if (!UUID.TryParse(objectUUID, out objUUID)) // prior to patching, a thrown exception regarding invalid GUID format would be shouted instead.
@@ -1715,6 +2048,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1715 "dataserver", resobj, new DetectParams[0])); 2048 "dataserver", resobj, new DetectParams[0]));
1716 } 2049 }
1717 2050
2051
2052 /// <summary>
2053 /// Similar to llDie but given an object UUID
2054 /// </summary>
2055 /// <param name="objectUUID"></param>
2056
2057 public void osDie(LSL_Key objectUUID)
2058 {
2059// CheckThreatLevel(ThreatLevel.VeryHigh, "osDie");
2060 // if this is restricted to objects rezzed by this host level can be reduced
2061
2062 CheckThreatLevel(ThreatLevel.Low, "osDie");
2063
2064 UUID objUUID;
2065 if (!UUID.TryParse(objectUUID, out objUUID))
2066 {
2067 OSSLShoutError("osDie() cannot delete objects with invalid UUIDs");
2068 return;
2069 }
2070
2071 // harakiri check
2072 if(objUUID == UUID.Zero)
2073 {
2074 if (!m_host.ParentGroup.IsAttachment)
2075 throw new SelfDeleteException();
2076 return;
2077 }
2078
2079 SceneObjectGroup sceneOG = World.GetSceneObjectGroup(objUUID);
2080
2081 if (sceneOG == null || sceneOG.IsDeleted)
2082 return;
2083
2084 if(sceneOG.IsAttachment)
2085 return;
2086
2087 if (sceneOG.OwnerID != m_host.OwnerID)
2088 return;
2089
2090 // harakiri check
2091 if(sceneOG.UUID == m_host.ParentGroup.UUID)
2092 throw new SelfDeleteException();
2093
2094 // restrict to objects rezzed by host
2095 if(sceneOG.RezzerID == m_host.ParentGroup.UUID)
2096 World.DeleteSceneObject(sceneOG, false);
2097 }
2098
1718 /// <summary> 2099 /// <summary>
1719 /// Write a notecard directly to the prim's inventory. 2100 /// Write a notecard directly to the prim's inventory.
1720 /// </summary> 2101 /// </summary>
@@ -1727,7 +2108,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1727 /// <param name="contents">The contents of the notecard.</param> 2108 /// <param name="contents">The contents of the notecard.</param>
1728 public void osMakeNotecard(string notecardName, LSL_Types.list contents) 2109 public void osMakeNotecard(string notecardName, LSL_Types.list contents)
1729 { 2110 {
1730 m_host.AddScriptLPS(1); 2111 CheckThreatLevel(ThreatLevel.High, "osMakeNotecard");
1731 2112
1732 StringBuilder notecardData = new StringBuilder(); 2113 StringBuilder notecardData = new StringBuilder();
1733 2114
@@ -1778,8 +2159,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1778 taskItem.ResetIDs(m_host.UUID); 2159 taskItem.ResetIDs(m_host.UUID);
1779 taskItem.ParentID = m_host.UUID; 2160 taskItem.ParentID = m_host.UUID;
1780 taskItem.CreationDate = (uint)Util.UnixTimeSinceEpoch(); 2161 taskItem.CreationDate = (uint)Util.UnixTimeSinceEpoch();
1781 taskItem.Name = asset.Name; 2162 taskItem.Name = name;
1782 taskItem.Description = asset.Description; 2163 taskItem.Description = description;
1783 taskItem.Type = (int)AssetType.Notecard; 2164 taskItem.Type = (int)AssetType.Notecard;
1784 taskItem.InvType = (int)InventoryType.Notecard; 2165 taskItem.InvType = (int)InventoryType.Notecard;
1785 taskItem.OwnerID = m_host.OwnerID; 2166 taskItem.OwnerID = m_host.OwnerID;
@@ -1799,6 +2180,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1799 m_host.Inventory.AddInventoryItemExclusive(taskItem, false); 2180 m_host.Inventory.AddInventoryItemExclusive(taskItem, false);
1800 else 2181 else
1801 m_host.Inventory.AddInventoryItem(taskItem, false); 2182 m_host.Inventory.AddInventoryItem(taskItem, false);
2183 m_host.ParentGroup.InvalidateDeepEffectivePerms();
1802 2184
1803 return taskItem; 2185 return taskItem;
1804 } 2186 }
@@ -1843,15 +2225,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1843 { 2225 {
1844 UUID assetID = UUID.Zero; 2226 UUID assetID = UUID.Zero;
1845 2227
1846 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 2228 bool notecardNameIsUUID = UUID.TryParse(notecardNameOrUuid, out assetID);
2229
2230 if (!notecardNameIsUUID)
1847 { 2231 {
1848 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 2232 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1849 {
1850 if (item.Type == 7 && item.Name == notecardNameOrUuid)
1851 {
1852 assetID = item.AssetID;
1853 }
1854 }
1855 } 2233 }
1856 2234
1857 if (assetID == UUID.Zero) 2235 if (assetID == UUID.Zero)
@@ -1862,13 +2240,43 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1862 AssetBase a = World.AssetService.Get(assetID.ToString()); 2240 AssetBase a = World.AssetService.Get(assetID.ToString());
1863 2241
1864 if (a == null) 2242 if (a == null)
1865 return UUID.Zero; 2243 {
2244 // Whoops, it's still possible here that the notecard name was properly
2245 // formatted like a UUID but isn't an asset UUID so lets look it up by name after all
2246 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
2247 if (assetID == UUID.Zero)
2248 return UUID.Zero;
2249
2250 if (!NotecardCache.IsCached(assetID))
2251 {
2252 a = World.AssetService.Get(assetID.ToString());
2253
2254 if (a == null)
2255 {
2256 return UUID.Zero;
2257 }
2258 }
2259 }
1866 2260
1867 NotecardCache.Cache(assetID, a.Data); 2261 NotecardCache.Cache(assetID, a.Data);
1868 }; 2262 };
1869 2263
1870 return assetID; 2264 return assetID;
1871 } 2265 }
2266 protected UUID SearchTaskInventoryForAssetId(string name)
2267 {
2268 UUID assetId = UUID.Zero;
2269 m_host.TaskInventory.LockItemsForRead(true);
2270 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
2271 {
2272 if (item.Type == 7 && item.Name == name)
2273 {
2274 assetId = item.AssetID;
2275 }
2276 }
2277 m_host.TaskInventory.LockItemsForRead(false);
2278 return assetId;
2279 }
1872 2280
1873 /// <summary> 2281 /// <summary>
1874 /// Directly get an entire notecard at once. 2282 /// Directly get an entire notecard at once.
@@ -1885,7 +2293,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1885 /// <returns>Notecard line</returns> 2293 /// <returns>Notecard line</returns>
1886 public string osGetNotecardLine(string name, int line) 2294 public string osGetNotecardLine(string name, int line)
1887 { 2295 {
1888 m_host.AddScriptLPS(1); 2296 CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNotecardLine");
1889 2297
1890 UUID assetID = CacheNotecard(name); 2298 UUID assetID = CacheNotecard(name);
1891 2299
@@ -1912,7 +2320,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1912 /// <returns>Notecard text</returns> 2320 /// <returns>Notecard text</returns>
1913 public string osGetNotecard(string name) 2321 public string osGetNotecard(string name)
1914 { 2322 {
1915 m_host.AddScriptLPS(1); 2323 CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNotecard");
1916 2324
1917 string text = LoadNotecard(name); 2325 string text = LoadNotecard(name);
1918 2326
@@ -1941,7 +2349,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1941 /// <returns></returns> 2349 /// <returns></returns>
1942 public int osGetNumberOfNotecardLines(string name) 2350 public int osGetNumberOfNotecardLines(string name)
1943 { 2351 {
1944 m_host.AddScriptLPS(1); 2352 CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNumberOfNotecardLines");
1945 2353
1946 UUID assetID = CacheNotecard(name); 2354 UUID assetID = CacheNotecard(name);
1947 2355
@@ -1956,8 +2364,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1956 2364
1957 public string osAvatarName2Key(string firstname, string lastname) 2365 public string osAvatarName2Key(string firstname, string lastname)
1958 { 2366 {
1959 if (!CheckThreatLevel(ThreatLevel.Low, "osAvatarName2Key")) return string.Empty; 2367 CheckThreatLevel(ThreatLevel.Low, "osAvatarName2Key");
1960 m_host.AddScriptLPS(1);
1961 2368
1962 IUserManagement userManager = World.RequestModuleInterface<IUserManagement>(); 2369 IUserManagement userManager = World.RequestModuleInterface<IUserManagement>();
1963 if (userManager == null) 2370 if (userManager == null)
@@ -2008,7 +2415,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2008 2415
2009 public string osKey2Name(string id) 2416 public string osKey2Name(string id)
2010 { 2417 {
2011 m_host.AddScriptLPS(1); 2418 CheckThreatLevel(ThreatLevel.Low, "osKey2Name");
2012 2419
2013 UUID key = new UUID(); 2420 UUID key = new UUID();
2014 2421
@@ -2117,8 +2524,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2117 /// <returns></returns> 2524 /// <returns></returns>
2118 public string osGetGridNick() 2525 public string osGetGridNick()
2119 { 2526 {
2120//// if (!CheckThreatLevel(ThreatLevel.None, "osGetGridNick")) return ""; 2527 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridNick");
2121 m_host.AddScriptLPS(1);
2122 2528
2123 string nick = String.Empty; 2529 string nick = String.Empty;
2124 IConfigSource config = m_ScriptEngine.ConfigSource; 2530 IConfigSource config = m_ScriptEngine.ConfigSource;
@@ -2134,8 +2540,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2134 2540
2135 public string osGetGridName() 2541 public string osGetGridName()
2136 { 2542 {
2137//// if (!CheckThreatLevel(ThreatLevel.None, "osGetGridName")) return ""; 2543 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridName");
2138 m_host.AddScriptLPS(1);
2139 2544
2140 string name = String.Empty; 2545 string name = String.Empty;
2141 IConfigSource config = m_ScriptEngine.ConfigSource; 2546 IConfigSource config = m_ScriptEngine.ConfigSource;
@@ -2151,8 +2556,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2151 2556
2152 public string osGetGridLoginURI() 2557 public string osGetGridLoginURI()
2153 { 2558 {
2154 if (!CheckThreatLevel(ThreatLevel.Moderate, "osGetGridLoginURI")) return ""; 2559 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridLoginURI");
2155 m_host.AddScriptLPS(1);
2156 2560
2157 string loginURI = String.Empty; 2561 string loginURI = String.Empty;
2158 IConfigSource config = m_ScriptEngine.ConfigSource; 2562 IConfigSource config = m_ScriptEngine.ConfigSource;
@@ -2168,11 +2572,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2168 2572
2169 public string osGetGridHomeURI() 2573 public string osGetGridHomeURI()
2170 { 2574 {
2171 if (!CheckThreatLevel(ThreatLevel.Moderate, "osGetGridHomeURI")) return ""; 2575 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridHomeURI");
2172 m_host.AddScriptLPS(1);
2173 2576
2174 IConfigSource config = m_ScriptEngine.ConfigSource; 2577 IConfigSource config = m_ScriptEngine.ConfigSource;
2175 string HomeURI = Util.GetConfigVarFromSections<string>(config, "HomeURI", 2578 string HomeURI = Util.GetConfigVarFromSections<string>(config, "HomeURI",
2176 new string[] { "Startup", "Hypergrid" }, String.Empty); 2579 new string[] { "Startup", "Hypergrid" }, String.Empty);
2177 2580
2178 if (!string.IsNullOrEmpty(HomeURI)) 2581 if (!string.IsNullOrEmpty(HomeURI))
@@ -2190,8 +2593,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2190 2593
2191 public string osGetGridGatekeeperURI() 2594 public string osGetGridGatekeeperURI()
2192 { 2595 {
2193 if (!CheckThreatLevel(ThreatLevel.Moderate, "osGetGridGatekeeperURI")) return ""; 2596 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridGatekeeperURI");
2194 m_host.AddScriptLPS(1);
2195 2597
2196 IConfigSource config = m_ScriptEngine.ConfigSource; 2598 IConfigSource config = m_ScriptEngine.ConfigSource;
2197 string gatekeeperURI = Util.GetConfigVarFromSections<string>(config, "GatekeeperURI", 2599 string gatekeeperURI = Util.GetConfigVarFromSections<string>(config, "GatekeeperURI",
@@ -2209,8 +2611,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2209 2611
2210 public string osGetGridCustom(string key) 2612 public string osGetGridCustom(string key)
2211 { 2613 {
2212 if (!CheckThreatLevel(ThreatLevel.Moderate, "osGetGridCustom")) return String.Empty; 2614 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridCustom");
2213 m_host.AddScriptLPS(1);
2214 2615
2215 string retval = String.Empty; 2616 string retval = String.Empty;
2216 IConfigSource config = m_ScriptEngine.ConfigSource; 2617 IConfigSource config = m_ScriptEngine.ConfigSource;
@@ -2226,8 +2627,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2226 2627
2227 public string osGetAvatarHomeURI(string uuid) 2628 public string osGetAvatarHomeURI(string uuid)
2228 { 2629 {
2229 if (!CheckThreatLevel(ThreatLevel.Moderate, "osGetAvatarHomeURI")) return ""; 2630 CheckThreatLevel(ThreatLevel.Low, "osGetAvatarHomeURI");
2230 m_host.AddScriptLPS(1);
2231 2631
2232 IUserManagement userManager = m_ScriptEngine.World.RequestModuleInterface<IUserManagement>(); 2632 IUserManagement userManager = m_ScriptEngine.World.RequestModuleInterface<IUserManagement>();
2233 string returnValue = ""; 2633 string returnValue = "";
@@ -2259,14 +2659,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2259 2659
2260 public LSL_String osFormatString(string str, LSL_List strings) 2660 public LSL_String osFormatString(string str, LSL_List strings)
2261 { 2661 {
2262 m_host.AddScriptLPS(1); 2662 CheckThreatLevel(ThreatLevel.VeryLow, "osFormatString");
2263 2663
2264 return String.Format(str, strings.Data); 2664 return String.Format(str, strings.Data);
2265 } 2665 }
2266 2666
2267 public LSL_List osMatchString(string src, string pattern, int start) 2667 public LSL_List osMatchString(string src, string pattern, int start)
2268 { 2668 {
2269 m_host.AddScriptLPS(1); 2669 CheckThreatLevel(ThreatLevel.VeryLow, "osMatchString");
2270 2670
2271 LSL_List result = new LSL_List(); 2671 LSL_List result = new LSL_List();
2272 2672
@@ -2307,7 +2707,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2307 2707
2308 public LSL_String osReplaceString(string src, string pattern, string replace, int count, int start) 2708 public LSL_String osReplaceString(string src, string pattern, string replace, int count, int start)
2309 { 2709 {
2310 m_host.AddScriptLPS(1); 2710 CheckThreatLevel(ThreatLevel.VeryLow, "osReplaceString");
2311 2711
2312 // Normalize indices (if negative). 2712 // Normalize indices (if negative).
2313 // After normlaization they may still be 2713 // After normlaization they may still be
@@ -2331,24 +2731,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2331 2731
2332 public string osLoadedCreationDate() 2732 public string osLoadedCreationDate()
2333 { 2733 {
2334 if (!CheckThreatLevel(ThreatLevel.Low, "osLoadedCreationDate")) return ""; 2734 CheckThreatLevel(ThreatLevel.Low, "osLoadedCreationDate");
2335 m_host.AddScriptLPS(1);
2336 2735
2337 return World.RegionInfo.RegionSettings.LoadedCreationDate; 2736 return World.RegionInfo.RegionSettings.LoadedCreationDate;
2338 } 2737 }
2339 2738
2340 public string osLoadedCreationTime() 2739 public string osLoadedCreationTime()
2341 { 2740 {
2342 if (!CheckThreatLevel(ThreatLevel.Low, "osLoadedCreationTime")) return ""; 2741 CheckThreatLevel(ThreatLevel.Low, "osLoadedCreationTime");
2343 m_host.AddScriptLPS(1);
2344 2742
2345 return World.RegionInfo.RegionSettings.LoadedCreationTime; 2743 return World.RegionInfo.RegionSettings.LoadedCreationTime;
2346 } 2744 }
2347 2745
2348 public string osLoadedCreationID() 2746 public string osLoadedCreationID()
2349 { 2747 {
2350 if (!CheckThreatLevel(ThreatLevel.Low, "osLoadedCreationID")) return ""; 2748 CheckThreatLevel(ThreatLevel.Low, "osLoadedCreationID");
2351 m_host.AddScriptLPS(1);
2352 2749
2353 return World.RegionInfo.RegionSettings.LoadedCreationID; 2750 return World.RegionInfo.RegionSettings.LoadedCreationID;
2354 } 2751 }
@@ -2368,8 +2765,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2368 /// <returns></returns> 2765 /// <returns></returns>
2369 public LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules) 2766 public LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules)
2370 { 2767 {
2371 if (!CheckThreatLevel(ThreatLevel.High, "osGetLinkPrimitiveParams")) return new LSL_List(); 2768 CheckThreatLevel(ThreatLevel.High, "osGetLinkPrimitiveParams");
2372 m_host.AddScriptLPS(1); 2769
2373 InitLSL(); 2770 InitLSL();
2374 // One needs to cast m_LSL_Api because we're using functions not 2771 // One needs to cast m_LSL_Api because we're using functions not
2375 // on the ILSL_Api interface. 2772 // on the ILSL_Api interface.
@@ -2396,9 +2793,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2396 2793
2397 public void osForceCreateLink(string target, int parent) 2794 public void osForceCreateLink(string target, int parent)
2398 { 2795 {
2399 if (!CheckThreatLevel(ThreatLevel.VeryLow, "osForceCreateLink")) return; 2796 CheckThreatLevel(ThreatLevel.VeryLow, "osForceCreateLink");
2400
2401 m_host.AddScriptLPS(1);
2402 2797
2403 InitLSL(); 2798 InitLSL();
2404 ((LSL_Api)m_LSL_Api).CreateLink(target, parent); 2799 ((LSL_Api)m_LSL_Api).CreateLink(target, parent);
@@ -2406,9 +2801,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2406 2801
2407 public void osForceBreakLink(int linknum) 2802 public void osForceBreakLink(int linknum)
2408 { 2803 {
2409 if (!CheckThreatLevel(ThreatLevel.VeryLow, "osForceBreakLink")) return; 2804 CheckThreatLevel(ThreatLevel.VeryLow, "osForceBreakLink");
2410
2411 m_host.AddScriptLPS(1);
2412 2805
2413 InitLSL(); 2806 InitLSL();
2414 ((LSL_Api)m_LSL_Api).BreakLink(linknum); 2807 ((LSL_Api)m_LSL_Api).BreakLink(linknum);
@@ -2416,9 +2809,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2416 2809
2417 public void osForceBreakAllLinks() 2810 public void osForceBreakAllLinks()
2418 { 2811 {
2419 if (!CheckThreatLevel(ThreatLevel.VeryLow, "osForceBreakAllLinks")) return; 2812 CheckThreatLevel(ThreatLevel.VeryLow, "osForceBreakAllLinks");
2420
2421 m_host.AddScriptLPS(1);
2422 2813
2423 InitLSL(); 2814 InitLSL();
2424 ((LSL_Api)m_LSL_Api).BreakAllLinks(); 2815 ((LSL_Api)m_LSL_Api).BreakAllLinks();
@@ -2426,7 +2817,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2426 2817
2427 public LSL_Integer osIsNpc(LSL_Key npc) 2818 public LSL_Integer osIsNpc(LSL_Key npc)
2428 { 2819 {
2429 m_host.AddScriptLPS(1); 2820 CheckThreatLevel();
2430 2821
2431 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2822 INPCModule module = World.RequestModuleInterface<INPCModule>();
2432 if (module != null) 2823 if (module != null)
@@ -2442,31 +2833,99 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2442 2833
2443 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard) 2834 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard)
2444 { 2835 {
2445 if (!CheckThreatLevel(ThreatLevel.High, "osNpcCreate")) return new LSL_Key(ScriptBaseClass.NULL_KEY); 2836 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2446 m_host.AddScriptLPS(1); 2837
2838 // have to get the npc module also here to set the default Not Owned
2839 INPCModule module = World.RequestModuleInterface<INPCModule>();
2840 if(module == null)
2841 return new LSL_Key(UUID.Zero.ToString());
2842
2843 bool owned = (module.NPCOptionFlags & NPCOptionsFlags.AllowNotOwned) == 0;
2447 2844
2448 return NpcCreate(firstname, lastname, position, notecard, false, false); 2845 return NpcCreate(firstname, lastname, position, notecard, owned, false, false);
2449 } 2846 }
2450 2847
2451 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2848 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
2452 { 2849 {
2453 if (!CheckThreatLevel(ThreatLevel.High, "osNpcCreate")) return new LSL_Key(ScriptBaseClass.NULL_KEY); 2850 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2454 m_host.AddScriptLPS(1);
2455 2851
2456 return NpcCreate( 2852 return NpcCreate(
2457 firstname, lastname, position, notecard, 2853 firstname, lastname, position, notecard,
2458 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2854 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2459 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2855 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0,
2856 (options & ScriptBaseClass.OS_NPC_OBJECT_GROUP) != 0);
2460 } 2857 }
2461 2858
2462 private LSL_Key NpcCreate( 2859 private LSL_Key NpcCreate(
2463 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2860 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent, bool hostGroupID)
2464 { 2861 {
2862 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2863 {
2864 OSSLError("no permission to rez NPC at requested location");
2865 return new LSL_Key(UUID.Zero.ToString());
2866 }
2867
2465 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2868 INPCModule module = World.RequestModuleInterface<INPCModule>();
2466 if (module != null) 2869 if(module == null)
2870 {
2871 OSSLError("NPC module not enabled");
2872 return new LSL_Key(UUID.Zero.ToString());
2873 }
2874
2875 string groupTitle = String.Empty;
2876 UUID groupID = UUID.Zero;
2877
2878 AvatarAppearance appearance = null;
2879
2880 // check creation options
2881 NPCOptionsFlags createFlags = module.NPCOptionFlags;
2882
2883 if((createFlags & NPCOptionsFlags.AllowNotOwned) == 0 && !owned)
2884 {
2885 OSSLError("Not owned NPCs disabled");
2886 owned = true; // we should get here...
2887 }
2888
2889 if((createFlags & NPCOptionsFlags.AllowSenseAsAvatar) == 0 && senseAsAgent)
2467 { 2890 {
2468 AvatarAppearance appearance = null; 2891 OSSLError("NPC allow sense as Avatar disabled");
2892 senseAsAgent = false;
2893 }
2469 2894
2895 if(hostGroupID && m_host.GroupID != UUID.Zero)
2896 {
2897 IGroupsModule groupsModule = m_ScriptEngine.World.RequestModuleInterface<IGroupsModule>();
2898 if (groupsModule != null)
2899 {
2900 GroupMembershipData member = groupsModule.GetMembershipData(m_host.GroupID, m_host.OwnerID);
2901 if (member == null)
2902 {
2903 OSSLError(string.Format("osNpcCreate: the object owner is not member of the object group"));
2904 return new LSL_Key(UUID.Zero.ToString());
2905 }
2906
2907 groupID = m_host.GroupID;
2908
2909 if((createFlags & NPCOptionsFlags.NoNPCGroup) != 0)
2910 {
2911 GroupRecord grprec = groupsModule.GetGroupRecord(m_host.GroupID);
2912 if(grprec != null && grprec.GroupName != "")
2913 groupTitle = grprec.GroupName;
2914 }
2915 }
2916 }
2917
2918 if((createFlags & NPCOptionsFlags.NoNPCGroup) == 0)
2919 {
2920 if (firstname != String.Empty || lastname != String.Empty)
2921 {
2922 if (firstname != "Shown outfit:")
2923 groupTitle = "- NPC -";
2924 }
2925 }
2926
2927 if((createFlags & NPCOptionsFlags.AllowCloneOtherAvatars) != 0)
2928 {
2470 UUID id; 2929 UUID id;
2471 if (UUID.TryParse(notecard, out id)) 2930 if (UUID.TryParse(notecard, out id))
2472 { 2931 {
@@ -2474,38 +2933,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2474 if (clonePresence != null) 2933 if (clonePresence != null)
2475 appearance = clonePresence.Appearance; 2934 appearance = clonePresence.Appearance;
2476 } 2935 }
2936 }
2477 2937
2478 if (appearance == null) 2938 if (appearance == null)
2479 { 2939 {
2480 string appearanceSerialized = LoadNotecard(notecard); 2940 string appearanceSerialized = LoadNotecard(notecard);
2481 2941
2482 if (appearanceSerialized != null) 2942 if (appearanceSerialized != null)
2943 {
2944 try
2483 { 2945 {
2484 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2946 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2485 appearance = new AvatarAppearance(); 2947 appearance = new AvatarAppearance();
2486 appearance.Unpack(appearanceOsd); 2948 appearance.Unpack(appearanceOsd);
2487 } 2949 }
2488 else 2950 catch
2489 { 2951 {
2490 OSSLError(string.Format("osNpcCreate: Notecard reference '{0}' not found.", notecard)); 2952 OSSLError(string.Format("osNpcCreate: Error processing notcard '{0}'", notecard));
2953 return new LSL_Key(UUID.Zero.ToString());
2491 } 2954 }
2492 } 2955 }
2956 else
2957 {
2958 OSSLError(string.Format("osNpcCreate: Notecard reference '{0}' not found.", notecard));
2959 }
2960 }
2493 2961
2494 UUID ownerID = UUID.Zero; 2962 UUID ownerID = UUID.Zero;
2495 if (owned) 2963 if (owned)
2496 ownerID = m_host.OwnerID; 2964 ownerID = m_host.OwnerID;
2497 UUID x = module.CreateNPC(firstname, 2965 UUID x = module.CreateNPC(firstname,
2498 lastname, 2966 lastname,
2499 position, 2967 position,
2500 ownerID, 2968 UUID.Random(),
2501 senseAsAgent, 2969 ownerID,
2502 World, 2970 groupTitle,
2503 appearance); 2971 groupID,
2972 senseAsAgent,
2973 World,
2974 appearance);
2504 2975
2505 return new LSL_Key(x.ToString()); 2976 ScenePresence sp;
2977 if (World.TryGetScenePresence(x, out sp))
2978 {
2979 sp.SendAvatarDataToAllAgents();
2506 } 2980 }
2507 2981 return new LSL_Key(x.ToString());
2508 return new LSL_Key(UUID.Zero.ToString());
2509 } 2982 }
2510 2983
2511 /// <summary> 2984 /// <summary>
@@ -2516,8 +2989,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2516 /// <returns>The asset ID of the notecard saved.</returns> 2989 /// <returns>The asset ID of the notecard saved.</returns>
2517 public LSL_Key osNpcSaveAppearance(LSL_Key npc, string notecard) 2990 public LSL_Key osNpcSaveAppearance(LSL_Key npc, string notecard)
2518 { 2991 {
2519 if (!CheckThreatLevel(ThreatLevel.High, "osNpcSaveAppearance")) return new LSL_Key(ScriptBaseClass.NULL_KEY); 2992 CheckThreatLevel(ThreatLevel.High, "osNpcSaveAppearance");
2520 m_host.AddScriptLPS(1);
2521 2993
2522 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 2994 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2523 2995
@@ -2538,8 +3010,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2538 3010
2539 public void osNpcLoadAppearance(LSL_Key npc, string notecard) 3011 public void osNpcLoadAppearance(LSL_Key npc, string notecard)
2540 { 3012 {
2541 if (!CheckThreatLevel(ThreatLevel.High, "osNpcLoadAppearance")) return; 3013 CheckThreatLevel(ThreatLevel.High, "osNpcLoadAppearance");
2542 m_host.AddScriptLPS(1);
2543 3014
2544 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 3015 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2545 3016
@@ -2570,7 +3041,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2570 3041
2571 public LSL_Key osNpcGetOwner(LSL_Key npc) 3042 public LSL_Key osNpcGetOwner(LSL_Key npc)
2572 { 3043 {
2573 m_host.AddScriptLPS(1); 3044 CheckThreatLevel(ThreatLevel.None, "osNpcGetOwner");
2574 3045
2575 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 3046 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2576 if (npcModule != null) 3047 if (npcModule != null)
@@ -2591,7 +3062,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2591 3062
2592 public LSL_Vector osNpcGetPos(LSL_Key npc) 3063 public LSL_Vector osNpcGetPos(LSL_Key npc)
2593 { 3064 {
2594 m_host.AddScriptLPS(1); 3065 CheckThreatLevel(ThreatLevel.High, "osNpcGetPos");
2595 3066
2596 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 3067 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2597 if (npcModule != null) 3068 if (npcModule != null)
@@ -2614,8 +3085,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2614 3085
2615 public void osNpcMoveTo(LSL_Key npc, LSL_Vector pos) 3086 public void osNpcMoveTo(LSL_Key npc, LSL_Vector pos)
2616 { 3087 {
2617 if (!CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo")) return; 3088 CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo");
2618 m_host.AddScriptLPS(1);
2619 3089
2620 INPCModule module = World.RequestModuleInterface<INPCModule>(); 3090 INPCModule module = World.RequestModuleInterface<INPCModule>();
2621 if (module != null) 3091 if (module != null)
@@ -2633,8 +3103,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2633 3103
2634 public void osNpcMoveToTarget(LSL_Key npc, LSL_Vector target, int options) 3104 public void osNpcMoveToTarget(LSL_Key npc, LSL_Vector target, int options)
2635 { 3105 {
2636 if (!CheckThreatLevel(ThreatLevel.High, "osNpcMoveToTarget")) return; 3106 CheckThreatLevel(ThreatLevel.High, "osNpcMoveToTarget");
2637 m_host.AddScriptLPS(1);
2638 3107
2639 INPCModule module = World.RequestModuleInterface<INPCModule>(); 3108 INPCModule module = World.RequestModuleInterface<INPCModule>();
2640 if (module != null) 3109 if (module != null)
@@ -2658,7 +3127,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2658 3127
2659 public LSL_Rotation osNpcGetRot(LSL_Key npc) 3128 public LSL_Rotation osNpcGetRot(LSL_Key npc)
2660 { 3129 {
2661 m_host.AddScriptLPS(1); 3130 CheckThreatLevel(ThreatLevel.High, "osNpcGetRot");
2662 3131
2663 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 3132 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2664 if (npcModule != null) 3133 if (npcModule != null)
@@ -2681,8 +3150,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2681 3150
2682 public void osNpcSetRot(LSL_Key npc, LSL_Rotation rotation) 3151 public void osNpcSetRot(LSL_Key npc, LSL_Rotation rotation)
2683 { 3152 {
2684 if (!CheckThreatLevel(ThreatLevel.High, "osNpcSetRot")) return; 3153 CheckThreatLevel(ThreatLevel.High, "osNpcSetRot");
2685 m_host.AddScriptLPS(1);
2686 3154
2687 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 3155 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2688 if (npcModule != null) 3156 if (npcModule != null)
@@ -2703,8 +3171,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2703 3171
2704 public void osNpcStopMoveToTarget(LSL_Key npc) 3172 public void osNpcStopMoveToTarget(LSL_Key npc)
2705 { 3173 {
2706 if (!CheckThreatLevel(ThreatLevel.High, "osNpcStopMoveToTarget")) return; 3174 CheckThreatLevel(ThreatLevel.High, "osNpcStopMoveToTarget");
2707 m_host.AddScriptLPS(1);
2708 3175
2709 INPCModule module = World.RequestModuleInterface<INPCModule>(); 3176 INPCModule module = World.RequestModuleInterface<INPCModule>();
2710 if (module != null) 3177 if (module != null)
@@ -2718,6 +3185,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2718 } 3185 }
2719 } 3186 }
2720 3187
3188 public void osNpcSetProfileAbout(LSL_Key npc, string about)
3189 {
3190 CheckThreatLevel(ThreatLevel.Low, "osNpcSetProfileAbout");
3191
3192 INPCModule module = World.RequestModuleInterface<INPCModule>();
3193 if (module != null)
3194 {
3195 UUID npcId = new UUID(npc.m_string);
3196
3197 if (!module.CheckPermissions(npcId, m_host.OwnerID))
3198 return;
3199
3200 ScenePresence sp = World.GetScenePresence(npcId);
3201 if (sp != null)
3202 ((INPC)(sp.ControllingClient)).profileAbout = about;
3203 }
3204 }
3205
3206 public void osNpcSetProfileImage(LSL_Key npc, string image)
3207 {
3208 CheckThreatLevel(ThreatLevel.Low, "osNpcSetProfileImage");
3209
3210 INPCModule module = World.RequestModuleInterface<INPCModule>();
3211 if (module != null)
3212 {
3213 UUID npcId = new UUID(npc.m_string);
3214
3215 if (!module.CheckPermissions(npcId, m_host.OwnerID))
3216 return;
3217
3218 UUID ImageID = new UUID();
3219
3220 ImageID = ScriptUtils.GetAssetIdFromItemName(m_host, image, (int)AssetType.Texture);
3221
3222 if (ImageID == null || ImageID == UUID.Zero)
3223 {
3224 if (!UUID.TryParse(image, out ImageID))
3225 return;
3226 }
3227
3228 ScenePresence sp = World.GetScenePresence(npcId);
3229 if (sp != null)
3230 ((INPC)(sp.ControllingClient)).profileImage = ImageID;
3231 }
3232 }
3233
2721 public void osNpcSay(LSL_Key npc, string message) 3234 public void osNpcSay(LSL_Key npc, string message)
2722 { 3235 {
2723 osNpcSay(npc, 0, message); 3236 osNpcSay(npc, 0, message);
@@ -2725,8 +3238,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2725 3238
2726 public void osNpcSay(LSL_Key npc, int channel, string message) 3239 public void osNpcSay(LSL_Key npc, int channel, string message)
2727 { 3240 {
2728 if (!CheckThreatLevel(ThreatLevel.High, "osNpcSay")) return; 3241 CheckThreatLevel(ThreatLevel.High, "osNpcSay");
2729 m_host.AddScriptLPS(1);
2730 3242
2731 INPCModule module = World.RequestModuleInterface<INPCModule>(); 3243 INPCModule module = World.RequestModuleInterface<INPCModule>();
2732 if (module != null) 3244 if (module != null)
@@ -2742,8 +3254,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2742 3254
2743 public void osNpcShout(LSL_Key npc, int channel, string message) 3255 public void osNpcShout(LSL_Key npc, int channel, string message)
2744 { 3256 {
2745 if (!CheckThreatLevel(ThreatLevel.High, "osNpcShout")) return; 3257 CheckThreatLevel(ThreatLevel.High, "osNpcShout");
2746 m_host.AddScriptLPS(1);
2747 3258
2748 INPCModule module = World.RequestModuleInterface<INPCModule>(); 3259 INPCModule module = World.RequestModuleInterface<INPCModule>();
2749 if (module != null) 3260 if (module != null)
@@ -2759,8 +3270,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2759 3270
2760 public void osNpcSit(LSL_Key npc, LSL_Key target, int options) 3271 public void osNpcSit(LSL_Key npc, LSL_Key target, int options)
2761 { 3272 {
2762 if (!CheckThreatLevel(ThreatLevel.High, "osNpcSit")) return; 3273 CheckThreatLevel(ThreatLevel.High, "osNpcSit");
2763 m_host.AddScriptLPS(1);
2764 3274
2765 INPCModule module = World.RequestModuleInterface<INPCModule>(); 3275 INPCModule module = World.RequestModuleInterface<INPCModule>();
2766 if (module != null) 3276 if (module != null)
@@ -2776,8 +3286,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2776 3286
2777 public void osNpcStand(LSL_Key npc) 3287 public void osNpcStand(LSL_Key npc)
2778 { 3288 {
2779 if (!CheckThreatLevel(ThreatLevel.High, "osNpcStand")) return; 3289 CheckThreatLevel(ThreatLevel.High, "osNpcStand");
2780 m_host.AddScriptLPS(1);
2781 3290
2782 INPCModule module = World.RequestModuleInterface<INPCModule>(); 3291 INPCModule module = World.RequestModuleInterface<INPCModule>();
2783 if (module != null) 3292 if (module != null)
@@ -2793,25 +3302,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2793 3302
2794 public void osNpcRemove(LSL_Key npc) 3303 public void osNpcRemove(LSL_Key npc)
2795 { 3304 {
2796 if (!CheckThreatLevel(ThreatLevel.High, "osNpcRemove")) return; 3305 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2797 m_host.AddScriptLPS(1);
2798 3306
2799 INPCModule module = World.RequestModuleInterface<INPCModule>(); 3307 try
2800 if (module != null)
2801 { 3308 {
2802 UUID npcId = new UUID(npc.m_string); 3309 INPCModule module = World.RequestModuleInterface<INPCModule>();
3310 if (module != null)
3311 {
3312 UUID npcId = new UUID(npc.m_string);
2803 3313
2804 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 3314 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2805 return; 3315 return;
2806 3316
2807 module.DeleteNPC(npcId, World); 3317 module.DeleteNPC(npcId, World);
3318 }
2808 } 3319 }
3320 catch { }
2809 } 3321 }
2810 3322
2811 public void osNpcPlayAnimation(LSL_Key npc, string animation) 3323 public void osNpcPlayAnimation(LSL_Key npc, string animation)
2812 { 3324 {
2813 if (!CheckThreatLevel(ThreatLevel.High, "osNpcPlayAnimation")) return; 3325 CheckThreatLevel(ThreatLevel.High, "osNpcPlayAnimation");
2814 m_host.AddScriptLPS(1);
2815 3326
2816 INPCModule module = World.RequestModuleInterface<INPCModule>(); 3327 INPCModule module = World.RequestModuleInterface<INPCModule>();
2817 if (module != null) 3328 if (module != null)
@@ -2825,8 +3336,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2825 3336
2826 public void osNpcStopAnimation(LSL_Key npc, string animation) 3337 public void osNpcStopAnimation(LSL_Key npc, string animation)
2827 { 3338 {
2828 if (!CheckThreatLevel(ThreatLevel.High, "osNpcStopAnimation")) return; 3339 CheckThreatLevel(ThreatLevel.High, "osNpcStopAnimation");
2829 m_host.AddScriptLPS(1);
2830 3340
2831 INPCModule module = World.RequestModuleInterface<INPCModule>(); 3341 INPCModule module = World.RequestModuleInterface<INPCModule>();
2832 if (module != null) 3342 if (module != null)
@@ -2840,8 +3350,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2840 3350
2841 public void osNpcWhisper(LSL_Key npc, int channel, string message) 3351 public void osNpcWhisper(LSL_Key npc, int channel, string message)
2842 { 3352 {
2843 if (!CheckThreatLevel(ThreatLevel.High, "osNpcWhisper")) return; 3353 CheckThreatLevel(ThreatLevel.High, "osNpcWhisper");
2844 m_host.AddScriptLPS(1);
2845 3354
2846 INPCModule module = World.RequestModuleInterface<INPCModule>(); 3355 INPCModule module = World.RequestModuleInterface<INPCModule>();
2847 if (module != null) 3356 if (module != null)
@@ -2857,8 +3366,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2857 3366
2858 public void osNpcTouch(LSL_Key npcLSL_Key, LSL_Key object_key, LSL_Integer link_num) 3367 public void osNpcTouch(LSL_Key npcLSL_Key, LSL_Key object_key, LSL_Integer link_num)
2859 { 3368 {
2860 if (!CheckThreatLevel(ThreatLevel.High, "osNpcTouch")) return; 3369 CheckThreatLevel(ThreatLevel.High, "osNpcTouch");
2861 m_host.AddScriptLPS(1);
2862 3370
2863 INPCModule module = World.RequestModuleInterface<INPCModule>(); 3371 INPCModule module = World.RequestModuleInterface<INPCModule>();
2864 int linkNum = link_num.value; 3372 int linkNum = link_num.value;
@@ -2902,16 +3410,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2902 /// <returns>The asset ID of the notecard saved.</returns> 3410 /// <returns>The asset ID of the notecard saved.</returns>
2903 public LSL_Key osOwnerSaveAppearance(string notecard) 3411 public LSL_Key osOwnerSaveAppearance(string notecard)
2904 { 3412 {
2905 if (!CheckThreatLevel(ThreatLevel.Moderate, "osOwnerSaveAppearance")) return new LSL_Key(ScriptBaseClass.NULL_KEY); 3413 CheckThreatLevel(ThreatLevel.High, "osOwnerSaveAppearance");
2906 m_host.AddScriptLPS(1);
2907 3414
2908 return SaveAppearanceToNotecard(m_host.OwnerID, notecard); 3415 return SaveAppearanceToNotecard(m_host.OwnerID, notecard);
2909 } 3416 }
2910 3417
2911 public LSL_Key osAgentSaveAppearance(LSL_Key avatarId, string notecard) 3418 public LSL_Key osAgentSaveAppearance(LSL_Key avatarId, string notecard)
2912 { 3419 {
2913 if (!CheckThreatLevel(ThreatLevel.High, "osAgentSaveAppearance")) return new LSL_Key(ScriptBaseClass.NULL_KEY); 3420 CheckThreatLevel(ThreatLevel.VeryHigh, "osAgentSaveAppearance");
2914 m_host.AddScriptLPS(1);
2915 3421
2916 return SaveAppearanceToNotecard(avatarId, notecard); 3422 return SaveAppearanceToNotecard(avatarId, notecard);
2917 } 3423 }
@@ -2923,7 +3429,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2923 if (appearanceModule != null) 3429 if (appearanceModule != null)
2924 { 3430 {
2925 appearanceModule.SaveBakedTextures(sp.UUID); 3431 appearanceModule.SaveBakedTextures(sp.UUID);
2926 OSDMap appearancePacked = sp.Appearance.Pack(); 3432 EntityTransferContext ctx = new EntityTransferContext();
3433 OSDMap appearancePacked = sp.Appearance.Pack(ctx);
2927 3434
2928 TaskInventoryItem item 3435 TaskInventoryItem item
2929 = SaveNotecard(notecard, "Avatar Appearance", Util.GetFormattedXml(appearancePacked as OSD), true); 3436 = SaveNotecard(notecard, "Avatar Appearance", Util.GetFormattedXml(appearancePacked as OSD), true);
@@ -2962,7 +3469,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2962 /// <returns>"male" or "female" or "unknown"</returns> 3469 /// <returns>"male" or "female" or "unknown"</returns>
2963 public LSL_String osGetGender(LSL_Key rawAvatarId) 3470 public LSL_String osGetGender(LSL_Key rawAvatarId)
2964 { 3471 {
2965 m_host.AddScriptLPS(1); 3472 CheckThreatLevel(ThreatLevel.None, "osGetGender");
2966 3473
2967 UUID avatarId; 3474 UUID avatarId;
2968 if (!UUID.TryParse(rawAvatarId, out avatarId)) 3475 if (!UUID.TryParse(rawAvatarId, out avatarId))
@@ -3005,7 +3512,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3005 /// <returns></returns> 3512 /// <returns></returns>
3006 public LSL_Key osGetMapTexture() 3513 public LSL_Key osGetMapTexture()
3007 { 3514 {
3008 m_host.AddScriptLPS(1); 3515 CheckThreatLevel();
3009 3516
3010 return m_ScriptEngine.World.RegionInfo.RegionSettings.TerrainImageID.ToString(); 3517 return m_ScriptEngine.World.RegionInfo.RegionSettings.TerrainImageID.ToString();
3011 } 3518 }
@@ -3017,7 +3524,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3017 /// <returns></returns> 3524 /// <returns></returns>
3018 public LSL_Key osGetRegionMapTexture(string regionName) 3525 public LSL_Key osGetRegionMapTexture(string regionName)
3019 { 3526 {
3020 m_host.AddScriptLPS(1); 3527 CheckThreatLevel(ThreatLevel.High, "osGetRegionMapTexture");
3021 3528
3022 Scene scene = m_ScriptEngine.World; 3529 Scene scene = m_ScriptEngine.World;
3023 UUID key = UUID.Zero; 3530 UUID key = UUID.Zero;
@@ -3033,6 +3540,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3033 if (region != null) 3540 if (region != null)
3034 key = region.TerrainImage; 3541 key = region.TerrainImage;
3035 3542
3543 ScriptSleep(1000);
3544
3036 return key.ToString(); 3545 return key.ToString();
3037 } 3546 }
3038 3547
@@ -3045,7 +3554,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3045 /// <returns>List of floats</returns> 3554 /// <returns>List of floats</returns>
3046 public LSL_List osGetRegionStats() 3555 public LSL_List osGetRegionStats()
3047 { 3556 {
3048 m_host.AddScriptLPS(1); 3557 CheckThreatLevel(ThreatLevel.Moderate, "osGetRegionStats");
3558
3049 LSL_List ret = new LSL_List(); 3559 LSL_List ret = new LSL_List();
3050 float[] stats = World.StatsReporter.LastReportedSimStats; 3560 float[] stats = World.StatsReporter.LastReportedSimStats;
3051 3561
@@ -3058,32 +3568,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3058 3568
3059 public LSL_Vector osGetRegionSize() 3569 public LSL_Vector osGetRegionSize()
3060 { 3570 {
3061 m_host.AddScriptLPS(1); 3571 CheckThreatLevel();
3062 3572
3063 bool isMegaregion; 3573 Scene scene = m_ScriptEngine.World;
3064 IRegionCombinerModule rcMod = World.RequestModuleInterface<IRegionCombinerModule>(); 3574 RegionInfo reg = World.RegionInfo;
3065 if (rcMod != null) 3575// GridRegion region = scene.GridService.GetRegionByUUID(UUID.Zero, World.RegionInfo.RegionID);
3066 isMegaregion = rcMod.IsRootForMegaregion(World.RegionInfo.RegionID); 3576// return new LSL_Vector((float)region.RegionSizeX, (float)region.RegionSizeY, (float)Constants.RegionHeight);
3067 else 3577 return new LSL_Vector((float)reg.RegionSizeX, (float)reg.RegionSizeY, 0.0f);
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 } 3578 }
3082 3579
3083 public int osGetSimulatorMemory() 3580 public int osGetSimulatorMemory()
3084 { 3581 {
3085 if (!CheckThreatLevel(ThreatLevel.Moderate, "osGetSimulatorMemory")) return 0; 3582 CheckThreatLevel(ThreatLevel.Moderate, "osGetSimulatorMemory");
3086 m_host.AddScriptLPS(1); 3583
3087 long pws = System.Diagnostics.Process.GetCurrentProcess().WorkingSet64; 3584 long pws = System.Diagnostics.Process.GetCurrentProcess().WorkingSet64;
3088 3585
3089 if (pws > Int32.MaxValue) 3586 if (pws > Int32.MaxValue)
@@ -3094,10 +3591,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3094 return (int)pws; 3591 return (int)pws;
3095 } 3592 }
3096 3593
3594 public int osGetSimulatorMemoryKB()
3595 {
3596 CheckThreatLevel(ThreatLevel.Moderate, "osGetSimulatorMemoryKB");
3597
3598 long pws = System.Diagnostics.Process.GetCurrentProcess().WorkingSet64;
3599
3600 if((pws & 0x3FFL) != 0)
3601 pws += 0x400L;
3602 pws >>= 10;
3603
3604 if (pws > Int32.MaxValue)
3605 return Int32.MaxValue;
3606
3607 return (int)pws;
3608 }
3609
3097 public void osSetSpeed(string UUID, LSL_Float SpeedModifier) 3610 public void osSetSpeed(string UUID, LSL_Float SpeedModifier)
3098 { 3611 {
3099 if (!CheckThreatLevel(ThreatLevel.Moderate, "osSetSpeed")) return; 3612 CheckThreatLevel(ThreatLevel.Moderate, "osSetSpeed");
3100 m_host.AddScriptLPS(1); 3613
3101 ScenePresence avatar = World.GetScenePresence(new UUID(UUID)); 3614 ScenePresence avatar = World.GetScenePresence(new UUID(UUID));
3102 3615
3103 if (avatar != null) 3616 if (avatar != null)
@@ -3106,8 +3619,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3106 3619
3107 public void osKickAvatar(string FirstName, string SurName, string alert) 3620 public void osKickAvatar(string FirstName, string SurName, string alert)
3108 { 3621 {
3109 if (!CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar")) return; 3622 CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar");
3110 m_host.AddScriptLPS(1);
3111 3623
3112 World.ForEachRootScenePresence(delegate(ScenePresence sp) 3624 World.ForEachRootScenePresence(delegate(ScenePresence sp)
3113 { 3625 {
@@ -3125,23 +3637,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3125 3637
3126 public LSL_Float osGetHealth(string avatar) 3638 public LSL_Float osGetHealth(string avatar)
3127 { 3639 {
3128 m_host.AddScriptLPS(1); 3640 CheckThreatLevel(ThreatLevel.None, "osGetHealth");
3129 3641
3130 LSL_Float health = new LSL_Float(-1); 3642 LSL_Float health = new LSL_Float(-1);
3131 ScenePresence presence = World.GetScenePresence(new UUID(avatar)); 3643 ScenePresence presence = World.GetScenePresence(new UUID(avatar));
3132 if (presence != null) health = presence.Health; 3644 if (presence != null)
3645 health = presence.Health;
3133 return health; 3646 return health;
3134 } 3647 }
3135 3648
3136 public void osCauseDamage(string avatar, double damage) 3649 public void osCauseDamage(string avatar, double damage)
3137 { 3650 {
3138 if (!CheckThreatLevel(ThreatLevel.High, "osCauseDamage")) return; 3651 CheckThreatLevel(ThreatLevel.High, "osCauseDamage");
3139 m_host.AddScriptLPS(1);
3140 3652
3141 UUID avatarId = new UUID(avatar); 3653 UUID avatarId = new UUID(avatar);
3142 Vector3 pos = m_host.GetWorldPosition(); 3654 Vector3 pos = m_host.GetWorldPosition();
3143 3655
3144 ScenePresence presence = World.GetScenePresence(avatarId); 3656 ScenePresence presence = World.GetScenePresence(avatarId);
3145 if (presence != null) 3657 if (presence != null)
3146 { 3658 {
3147 LandData land = World.GetLandData(pos); 3659 LandData land = World.GetLandData(pos);
@@ -3163,13 +3675,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3163 3675
3164 public void osCauseHealing(string avatar, double healing) 3676 public void osCauseHealing(string avatar, double healing)
3165 { 3677 {
3166 if (!CheckThreatLevel(ThreatLevel.High, "osCauseHealing")) return; 3678 CheckThreatLevel(ThreatLevel.High, "osCauseHealing");
3167 m_host.AddScriptLPS(1);
3168 3679
3169 UUID avatarId = new UUID(avatar); 3680 UUID avatarId = new UUID(avatar);
3170 ScenePresence presence = World.GetScenePresence(avatarId); 3681 ScenePresence presence = World.GetScenePresence(avatarId);
3171 3682
3172 if (presence != null && World.ScriptDanger(m_host.LocalId, m_host.GetWorldPosition())) 3683 if (presence != null)
3173 { 3684 {
3174 float health = presence.Health; 3685 float health = presence.Health;
3175 health += (float)healing; 3686 health += (float)healing;
@@ -3181,31 +3692,67 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3181 } 3692 }
3182 } 3693 }
3183 3694
3695 public void osSetHealth(string avatar, double health)
3696 {
3697 CheckThreatLevel(ThreatLevel.High, "osSetHealth");
3698
3699 UUID avatarId = new UUID(avatar);
3700 ScenePresence presence = World.GetScenePresence(avatarId);
3701
3702 if (presence != null)
3703 {
3704 if (health > 100.0)
3705 health = 100.0;
3706 else if (health < 1.0)
3707 health = 1.0;
3708
3709 presence.setHealthWithUpdate((float)health);
3710 }
3711 }
3712
3713 public void osSetHealRate(string avatar, double healrate)
3714 {
3715 CheckThreatLevel(ThreatLevel.High, "osSetHealRate");
3716
3717 UUID avatarId = new UUID(avatar);
3718 ScenePresence presence = World.GetScenePresence(avatarId);
3719
3720 if (presence != null)
3721 presence.HealRate = (float)healrate;
3722 }
3723
3724 public LSL_Float osGetHealRate(string avatar)
3725 {
3726 CheckThreatLevel(ThreatLevel.None, "osGetHealRate");
3727
3728 LSL_Float rate = new LSL_Float(0);
3729 ScenePresence presence = World.GetScenePresence(new UUID(avatar));
3730 if (presence != null)
3731 rate = presence.HealRate;
3732 return rate;
3733 }
3734
3184 public LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules) 3735 public LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules)
3185 { 3736 {
3186 if (!CheckThreatLevel(ThreatLevel.High, "osGetPrimitiveParams")) return new LSL_List(); 3737 CheckThreatLevel(ThreatLevel.High, "osGetPrimitiveParams");
3187 m_host.AddScriptLPS(1);
3188 InitLSL();
3189 3738
3739 InitLSL();
3190 return m_LSL_Api.GetPrimitiveParamsEx(prim, rules); 3740 return m_LSL_Api.GetPrimitiveParamsEx(prim, rules);
3191 } 3741 }
3192 3742
3193 public void osSetPrimitiveParams(LSL_Key prim, LSL_List rules) 3743 public void osSetPrimitiveParams(LSL_Key prim, LSL_List rules)
3194 { 3744 {
3195 if (!CheckThreatLevel(ThreatLevel.High, "osSetPrimitiveParams")) return; 3745 CheckThreatLevel(ThreatLevel.High, "osSetPrimitiveParams");
3196 m_host.AddScriptLPS(1);
3197 InitLSL();
3198 3746
3747 InitLSL();
3199 m_LSL_Api.SetPrimitiveParamsEx(prim, rules, "osSetPrimitiveParams"); 3748 m_LSL_Api.SetPrimitiveParamsEx(prim, rules, "osSetPrimitiveParams");
3200 } 3749 }
3201 3750
3202 /// <summary> 3751 /// <summary>
3203 /// Set parameters for light projection in host prim 3752 /// Set parameters for light projection in host prim
3204 /// </summary> 3753 /// </summary>
3205 public void osSetProjectionParams(bool projection, LSL_Key texture, double fov, double focus, double amb) 3754 public void osSetProjectionParams(bool projection, LSL_Key texture, double fov, double focus, double amb)
3206 { 3755 {
3207 if (!CheckThreatLevel(ThreatLevel.High, "osSetProjectionParams")) return;
3208
3209 osSetProjectionParams(UUID.Zero.ToString(), projection, texture, fov, focus, amb); 3756 osSetProjectionParams(UUID.Zero.ToString(), projection, texture, fov, focus, amb);
3210 } 3757 }
3211 3758
@@ -3214,8 +3761,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3214 /// </summary> 3761 /// </summary>
3215 public void osSetProjectionParams(LSL_Key prim, bool projection, LSL_Key texture, double fov, double focus, double amb) 3762 public void osSetProjectionParams(LSL_Key prim, bool projection, LSL_Key texture, double fov, double focus, double amb)
3216 { 3763 {
3217 if (!CheckThreatLevel(ThreatLevel.High, "osSetProjectionParams")) return; 3764 CheckThreatLevel(ThreatLevel.High, "osSetProjectionParams");
3218 m_host.AddScriptLPS(1);
3219 3765
3220 SceneObjectPart obj = null; 3766 SceneObjectPart obj = null;
3221 if (prim == UUID.Zero.ToString()) 3767 if (prim == UUID.Zero.ToString())
@@ -3245,12 +3791,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3245 /// <returns>Strided list of the UUID, position and name of each avatar in the region</returns> 3791 /// <returns>Strided list of the UUID, position and name of each avatar in the region</returns>
3246 public LSL_List osGetAvatarList() 3792 public LSL_List osGetAvatarList()
3247 { 3793 {
3248 m_host.AddScriptLPS(1); 3794 CheckThreatLevel(ThreatLevel.None, "osGetAvatarList");
3249 3795
3250 LSL_List result = new LSL_List(); 3796 LSL_List result = new LSL_List();
3251 World.ForEachRootScenePresence(delegate (ScenePresence avatar) 3797 World.ForEachRootScenePresence(delegate (ScenePresence avatar)
3252 { 3798 {
3253 if (avatar != null && avatar.UUID != m_host.OwnerID) 3799 if (avatar != null && !avatar.IsDeleted && avatar.UUID != m_host.OwnerID )
3800 {
3801 result.Add(new LSL_String(avatar.UUID.ToString()));
3802 result.Add(new LSL_Vector(avatar.AbsolutePosition));
3803 result.Add(new LSL_String(avatar.Name));
3804 }
3805 });
3806
3807 return result;
3808 }
3809
3810 public LSL_List osGetNPCList()
3811 {
3812 CheckThreatLevel(ThreatLevel.None, "osGetNPCList");
3813
3814 LSL_List result = new LSL_List();
3815 World.ForEachRootScenePresence(delegate (ScenePresence avatar)
3816 {
3817 // npcs are not childagents but that is now.
3818 if (avatar != null && avatar.IsNPC && !avatar.IsDeleted && !avatar.IsChildAgent && !avatar.IsInTransit)
3254 { 3819 {
3255 result.Add(new LSL_String(avatar.UUID.ToString())); 3820 result.Add(new LSL_String(avatar.UUID.ToString()));
3256 result.Add(new LSL_Vector(avatar.AbsolutePosition)); 3821 result.Add(new LSL_Vector(avatar.AbsolutePosition));
@@ -3268,7 +3833,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3268 /// <returns></returns> 3833 /// <returns></returns>
3269 public LSL_String osUnixTimeToTimestamp(long time) 3834 public LSL_String osUnixTimeToTimestamp(long time)
3270 { 3835 {
3271 m_host.AddScriptLPS(1); 3836 CheckThreatLevel(ThreatLevel.VeryLow, "osUnixTimeToTimestamp");
3272 3837
3273 long baseTicks = 621355968000000000; 3838 long baseTicks = 621355968000000000;
3274 long tickResolution = 10000000; 3839 long tickResolution = 10000000;
@@ -3282,10 +3847,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3282 /// Get the description from an inventory item 3847 /// Get the description from an inventory item
3283 /// </summary> 3848 /// </summary>
3284 /// <param name="inventoryName"></param> 3849 /// <param name="inventoryName"></param>
3285 /// <returns>Item description</returns> 3850 /// <returns>Item description</returns>
3286 public LSL_String osGetInventoryDesc(string item) 3851 public LSL_String osGetInventoryDesc(string item)
3287 { 3852 {
3288 m_host.AddScriptLPS(1); 3853 CheckThreatLevel();
3289 3854
3290 lock (m_host.TaskInventory) 3855 lock (m_host.TaskInventory)
3291 { 3856 {
@@ -3308,8 +3873,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3308 /// <returns></returns> 3873 /// <returns></returns>
3309 public LSL_Integer osInviteToGroup(LSL_Key agentId) 3874 public LSL_Integer osInviteToGroup(LSL_Key agentId)
3310 { 3875 {
3311 if (!CheckThreatLevel(ThreatLevel.VeryLow, "osInviteToGroup")) return ScriptBaseClass.FALSE; 3876 CheckThreatLevel(ThreatLevel.VeryLow, "osInviteToGroup");
3312 m_host.AddScriptLPS(1);
3313 3877
3314 UUID agent = new UUID(agentId); 3878 UUID agent = new UUID(agentId);
3315 3879
@@ -3343,8 +3907,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3343 /// <returns></returns> 3907 /// <returns></returns>
3344 public LSL_Integer osEjectFromGroup(LSL_Key agentId) 3908 public LSL_Integer osEjectFromGroup(LSL_Key agentId)
3345 { 3909 {
3346 if (!CheckThreatLevel(ThreatLevel.VeryLow, "osEjectFromGroup")) return ScriptBaseClass.FALSE; 3910 CheckThreatLevel(ThreatLevel.VeryLow, "osEjectFromGroup");
3347 m_host.AddScriptLPS(1);
3348 3911
3349 UUID agent = new UUID(agentId); 3912 UUID agent = new UUID(agentId);
3350 3913
@@ -3378,9 +3941,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3378 /// <returns></returns> 3941 /// <returns></returns>
3379 public void osSetTerrainTexture(int level, LSL_Key texture) 3942 public void osSetTerrainTexture(int level, LSL_Key texture)
3380 { 3943 {
3381 if (!CheckThreatLevel(ThreatLevel.High, "osSetTerrainTexture")) return; 3944 CheckThreatLevel(ThreatLevel.High, "osSetTerrainTexture");
3382 3945
3383 m_host.AddScriptLPS(1);
3384 //Check to make sure that the script's owner is the estate manager/master 3946 //Check to make sure that the script's owner is the estate manager/master
3385 //World.Permissions.GenericEstatePermission( 3947 //World.Permissions.GenericEstatePermission(
3386 if (World.Permissions.IsGod(m_host.OwnerID)) 3948 if (World.Permissions.IsGod(m_host.OwnerID))
@@ -3408,9 +3970,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3408 /// <returns></returns> 3970 /// <returns></returns>
3409 public void osSetTerrainTextureHeight(int corner, double low, double high) 3971 public void osSetTerrainTextureHeight(int corner, double low, double high)
3410 { 3972 {
3411 if (!CheckThreatLevel(ThreatLevel.High, "osSetTerrainTextureHeight")) return; 3973 CheckThreatLevel(ThreatLevel.High, "osSetTerrainTextureHeight");
3412 3974
3413 m_host.AddScriptLPS(1);
3414 //Check to make sure that the script's owner is the estate manager/master 3975 //Check to make sure that the script's owner is the estate manager/master
3415 //World.Permissions.GenericEstatePermission( 3976 //World.Permissions.GenericEstatePermission(
3416 if (World.Permissions.IsGod(m_host.OwnerID)) 3977 if (World.Permissions.IsGod(m_host.OwnerID))
@@ -3429,9 +3990,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3429 3990
3430 public void osForceAttachToAvatar(int attachmentPoint) 3991 public void osForceAttachToAvatar(int attachmentPoint)
3431 { 3992 {
3432 if (!CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatar")) return; 3993 CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatar");
3433
3434 m_host.AddScriptLPS(1);
3435 3994
3436 InitLSL(); 3995 InitLSL();
3437 ((LSL_Api)m_LSL_Api).AttachToAvatar(attachmentPoint); 3996 ((LSL_Api)m_LSL_Api).AttachToAvatar(attachmentPoint);
@@ -3439,18 +3998,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3439 3998
3440 public void osForceAttachToAvatarFromInventory(string itemName, int attachmentPoint) 3999 public void osForceAttachToAvatarFromInventory(string itemName, int attachmentPoint)
3441 { 4000 {
3442 if (!CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatarFromInventory")) return; 4001 CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatarFromInventory");
3443
3444 m_host.AddScriptLPS(1);
3445 4002
3446 ForceAttachToAvatarFromInventory(m_host.OwnerID, itemName, attachmentPoint); 4003 ForceAttachToAvatarFromInventory(m_host.OwnerID, itemName, attachmentPoint);
3447 } 4004 }
3448 4005
3449 public void osForceAttachToOtherAvatarFromInventory(string rawAvatarId, string itemName, int attachmentPoint) 4006 public void osForceAttachToOtherAvatarFromInventory(string rawAvatarId, string itemName, int attachmentPoint)
3450 { 4007 {
3451 if (!CheckThreatLevel(ThreatLevel.Severe, "osForceAttachToOtherAvatarFromInventory")) return; 4008 CheckThreatLevel(ThreatLevel.VeryHigh, "osForceAttachToOtherAvatarFromInventory");
3452
3453 m_host.AddScriptLPS(1);
3454 4009
3455 UUID avatarId; 4010 UUID avatarId;
3456 4011
@@ -3480,7 +4035,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3480 if (item.InvType != (int)InventoryType.Object) 4035 if (item.InvType != (int)InventoryType.Object)
3481 { 4036 {
3482 // FIXME: Temporary null check for regression tests since they dont' have the infrastructure to set 4037 // FIXME: Temporary null check for regression tests since they dont' have the infrastructure to set
3483 // up the api reference. 4038 // up the api reference.
3484 if (m_LSL_Api != null) 4039 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)); 4040 ((LSL_Api)m_LSL_Api).llSay(0, string.Format("Unable to attach, item '{0}' is not an object.", itemName));
3486 4041
@@ -3509,9 +4064,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3509 4064
3510 public void osForceDetachFromAvatar() 4065 public void osForceDetachFromAvatar()
3511 { 4066 {
3512 if (!CheckThreatLevel(ThreatLevel.High, "osForceDetachFromAvatar")) return; 4067 CheckThreatLevel(ThreatLevel.High, "osForceDetachFromAvatar");
3513
3514 m_host.AddScriptLPS(1);
3515 4068
3516 InitLSL(); 4069 InitLSL();
3517 ((LSL_Api)m_LSL_Api).DetachFromAvatar(); 4070 ((LSL_Api)m_LSL_Api).DetachFromAvatar();
@@ -3519,9 +4072,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3519 4072
3520 public LSL_List osGetNumberOfAttachments(LSL_Key avatar, LSL_List attachmentPoints) 4073 public LSL_List osGetNumberOfAttachments(LSL_Key avatar, LSL_List attachmentPoints)
3521 { 4074 {
3522 if (!CheckThreatLevel(ThreatLevel.Moderate, "osGetNumberOfAttachments")) return new LSL_List(); 4075 CheckThreatLevel(ThreatLevel.Moderate, "osGetNumberOfAttachments");
3523
3524 m_host.AddScriptLPS(1);
3525 4076
3526 UUID targetUUID; 4077 UUID targetUUID;
3527 ScenePresence target; 4078 ScenePresence target;
@@ -3555,15 +4106,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3555 4106
3556 public void osMessageAttachments(LSL_Key avatar, string message, LSL_List attachmentPoints, int options) 4107 public void osMessageAttachments(LSL_Key avatar, string message, LSL_List attachmentPoints, int options)
3557 { 4108 {
3558 if (!CheckThreatLevel(ThreatLevel.Moderate, "osMessageAttachments")) return; 4109 CheckThreatLevel(ThreatLevel.Moderate, "osMessageAttachments");
3559 m_host.AddScriptLPS(1);
3560 4110
3561 UUID targetUUID; 4111 UUID targetUUID;
4112 if(!UUID.TryParse(avatar.ToString(), out targetUUID))
4113 return;
4114
4115 if(targetUUID == UUID.Zero)
4116 return;
4117
3562 ScenePresence target; 4118 ScenePresence target;
4119 if(!World.TryGetScenePresence(targetUUID, out target))
4120 return;
3563 4121
3564 if (attachmentPoints.Length >= 1 && UUID.TryParse(avatar.ToString(), out targetUUID) && World.TryGetScenePresence(targetUUID, out target)) 4122 if(target.IsDeleted || target.IsInTransit)
4123 return;
4124
4125 List<int> aps = new List<int>();
4126 if(attachmentPoints.Length != 0)
3565 { 4127 {
3566 List<int> aps = new List<int>();
3567 foreach (object point in attachmentPoints.Data) 4128 foreach (object point in attachmentPoints.Data)
3568 { 4129 {
3569 int ipoint; 4130 int ipoint;
@@ -3572,115 +4133,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3572 aps.Add(ipoint); 4133 aps.Add(ipoint);
3573 } 4134 }
3574 } 4135 }
4136 // parsing failed
4137 if(aps.Count != attachmentPoints.Length)
4138 return;
4139 }
3575 4140
3576 List<SceneObjectGroup> attachments = new List<SceneObjectGroup>(); 4141 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 4142
3581 if (msgAll && invertPoints) 4143 bool msgAll;
3582 { 4144 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 4145
3600 // if we have no attachments at this point, exit now 4146 if(aps.Count == 0)
3601 if (attachments.Count == 0) 4147 {
3602 { 4148 if(!invertPoints)
3603 return; 4149 return;
3604 } 4150 msgAll = true;
4151 invertPoints = false;
4152 }
4153 else
4154 msgAll = aps.Contains(ScriptBaseClass.OS_ATTACH_MSG_ALL);
3605 4155
3606 List<SceneObjectGroup> ignoreThese = new List<SceneObjectGroup>(); 4156 if (msgAll && invertPoints)
4157 return;
3607 4158
3608 if (invertPoints) 4159 if (msgAll || invertPoints)
4160 {
4161 attachments = target.GetAttachments();
4162 }
4163 else
4164 {
4165 foreach (int point in aps)
3609 { 4166 {
3610 foreach (SceneObjectGroup attachment in attachments) 4167 if (point > 0)
3611 { 4168 {
3612 if (aps.Contains((int)attachment.AttachmentPoint)) 4169 attachments.AddRange(target.GetAttachments((uint)point));
3613 {
3614 ignoreThese.Add(attachment);
3615 }
3616 } 4170 }
3617 } 4171 }
4172 }
3618 4173
3619 foreach (SceneObjectGroup attachment in ignoreThese) 4174 // if we have no attachments at this point, exit now
3620 { 4175 if (attachments.Count == 0)
3621 attachments.Remove(attachment); 4176 {
3622 } 4177 return;
3623 ignoreThese.Clear(); 4178 }
3624
3625 // if inverting removed all attachments to check, exit now
3626 if (attachments.Count < 1)
3627 {
3628 return;
3629 }
3630 4179
3631 if ((options & ScriptBaseClass.OS_ATTACH_MSG_OBJECT_CREATOR) != 0) 4180 bool optionObjCreator = (options &
3632 { 4181 ScriptBaseClass.OS_ATTACH_MSG_OBJECT_CREATOR) != 0;
3633 foreach (SceneObjectGroup attachment in attachments) 4182 bool optionScriptCreator = (options &
3634 { 4183 ScriptBaseClass.OS_ATTACH_MSG_SCRIPT_CREATOR) != 0;
3635 if (attachment.RootPart.CreatorID != m_host.CreatorID)
3636 {
3637 ignoreThese.Add(attachment);
3638 }
3639 }
3640 4184
3641 foreach (SceneObjectGroup attachment in ignoreThese) 4185 UUID hostCreatorID = m_host.CreatorID;
3642 { 4186 UUID itemCreatorID = m_item.CreatorID;
3643 attachments.Remove(attachment);
3644 }
3645 ignoreThese.Clear();
3646 4187
3647 // if filtering by same object creator removed all 4188 foreach (SceneObjectGroup sog in attachments)
3648 // attachments to check, exit now 4189 {
3649 if (attachments.Count == 0) 4190 if(sog.IsDeleted || sog.inTransit)
3650 { 4191 continue;
3651 return;
3652 }
3653 }
3654 4192
3655 if ((options & ScriptBaseClass.OS_ATTACH_MSG_SCRIPT_CREATOR) != 0) 4193 if (invertPoints && aps.Contains((int)sog.AttachmentPoint))
3656 { 4194 continue;
3657 foreach (SceneObjectGroup attachment in attachments)
3658 {
3659 if (attachment.RootPart.CreatorID != m_item.CreatorID)
3660 {
3661 ignoreThese.Add(attachment);
3662 }
3663 }
3664 4195
3665 foreach (SceneObjectGroup attachment in ignoreThese) 4196 UUID CreatorID = sog.RootPart.CreatorID;
3666 { 4197 if (optionObjCreator && CreatorID != hostCreatorID)
3667 attachments.Remove(attachment); 4198 continue;
3668 }
3669 ignoreThese.Clear();
3670 4199
3671 // if filtering by object creator must match originating 4200 if (optionScriptCreator && CreatorID != itemCreatorID)
3672 // script creator removed all attachments to check, 4201 continue;
3673 // exit now
3674 if (attachments.Count == 0)
3675 {
3676 return;
3677 }
3678 }
3679 4202
3680 foreach (SceneObjectGroup attachment in attachments) 4203 SceneObjectPart[] parts = sog.Parts;
3681 { 4204 foreach(SceneObjectPart p in parts)
3682 MessageObject(attachment.RootPart.UUID, message); 4205 MessageObject(p.UUID, message);
3683 }
3684 } 4206 }
3685 } 4207 }
3686 4208
@@ -3693,7 +4215,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3693 /// <returns>1 if thing is a valid UUID, 0 otherwise</returns> 4215 /// <returns>1 if thing is a valid UUID, 0 otherwise</returns>
3694 public LSL_Integer osIsUUID(string thing) 4216 public LSL_Integer osIsUUID(string thing)
3695 { 4217 {
3696 m_host.AddScriptLPS(1); 4218 CheckThreatLevel();
3697 4219
3698 UUID test; 4220 UUID test;
3699 return UUID.TryParse(thing, out test) ? 1 : 0; 4221 return UUID.TryParse(thing, out test) ? 1 : 0;
@@ -3707,7 +4229,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3707 /// <returns></returns> 4229 /// <returns></returns>
3708 public LSL_Float osMin(double a, double b) 4230 public LSL_Float osMin(double a, double b)
3709 { 4231 {
3710 m_host.AddScriptLPS(1); 4232 CheckThreatLevel();
3711 4233
3712 return Math.Min(a, b); 4234 return Math.Min(a, b);
3713 } 4235 }
@@ -3720,16 +4242,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3720 /// <returns></returns> 4242 /// <returns></returns>
3721 public LSL_Float osMax(double a, double b) 4243 public LSL_Float osMax(double a, double b)
3722 { 4244 {
3723 m_host.AddScriptLPS(1); 4245 CheckThreatLevel();
3724 4246
3725 return Math.Max(a, b); 4247 return Math.Max(a, b);
3726 } 4248 }
3727 4249
3728 public LSL_Key osGetRezzingObject() 4250 public LSL_Key osGetRezzingObject()
3729 { 4251 {
3730 m_host.AddScriptLPS(1); 4252 CheckThreatLevel(ThreatLevel.None, "osGetRezzingObject");
3731 4253
3732 return new LSL_Key(m_host.ParentGroup.FromPartID.ToString()); 4254 UUID rezID = m_host.ParentGroup.RezzerID;
4255 if(rezID == UUID.Zero || m_host.ParentGroup.Scene.GetScenePresence(rezID) != null)
4256 return new LSL_Key(UUID.Zero.ToString());
4257 return new LSL_Key(rezID.ToString());
3733 } 4258 }
3734 4259
3735 /// <summary> 4260 /// <summary>
@@ -3738,7 +4263,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3738 /// <returns></returns> 4263 /// <returns></returns>
3739 public void osSetContentType(LSL_Key id, string type) 4264 public void osSetContentType(LSL_Key id, string type)
3740 { 4265 {
3741 if (!CheckThreatLevel(ThreatLevel.High, "osSetContentType")) return; 4266 CheckThreatLevel(ThreatLevel.High, "osSetContentType");
3742 4267
3743 if (m_UrlModule != null) 4268 if (m_UrlModule != null)
3744 m_UrlModule.HttpContentType(new UUID(id),type); 4269 m_UrlModule.HttpContentType(new UUID(id),type);
@@ -3750,7 +4275,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3750 /// <returns>boolean indicating whether an error was shouted.</returns> 4275 /// <returns>boolean indicating whether an error was shouted.</returns>
3751 protected bool ShoutErrorOnLackingOwnerPerms(int perms, string errorPrefix) 4276 protected bool ShoutErrorOnLackingOwnerPerms(int perms, string errorPrefix)
3752 { 4277 {
3753 m_host.AddScriptLPS(1);
3754 bool fail = false; 4278 bool fail = false;
3755 if (m_item.PermsGranter != m_host.OwnerID) 4279 if (m_item.PermsGranter != m_host.OwnerID)
3756 { 4280 {
@@ -3800,39 +4324,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3800 4324
3801 public void osDropAttachment() 4325 public void osDropAttachment()
3802 { 4326 {
3803 if (!CheckThreatLevel(ThreatLevel.Low, "osDropAttachment")) return; 4327 CheckThreatLevel(ThreatLevel.Moderate, "osDropAttachment");
3804 m_host.AddScriptLPS(1);
3805 4328
3806 DropAttachment(true); 4329 DropAttachment(true);
3807 } 4330 }
3808 4331
3809 public void osForceDropAttachment() 4332 public void osForceDropAttachment()
3810 { 4333 {
3811 if (!CheckThreatLevel(ThreatLevel.High, "osForceDropAttachment")) return; 4334 CheckThreatLevel(ThreatLevel.High, "osForceDropAttachment");
3812 m_host.AddScriptLPS(1);
3813 4335
3814 DropAttachment(false); 4336 DropAttachment(false);
3815 } 4337 }
3816 4338
3817 public void osDropAttachmentAt(LSL_Vector pos, LSL_Rotation rot) 4339 public void osDropAttachmentAt(LSL_Vector pos, LSL_Rotation rot)
3818 { 4340 {
3819 if (!CheckThreatLevel(ThreatLevel.Low, "osDropAttachmentAt")) return; 4341 CheckThreatLevel(ThreatLevel.Moderate, "osDropAttachmentAt");
3820 m_host.AddScriptLPS(1);
3821 4342
3822 DropAttachmentAt(true, pos, rot); 4343 DropAttachmentAt(true, pos, rot);
3823 } 4344 }
3824 4345
3825 public void osForceDropAttachmentAt(LSL_Vector pos, LSL_Rotation rot) 4346 public void osForceDropAttachmentAt(LSL_Vector pos, LSL_Rotation rot)
3826 { 4347 {
3827 if (!CheckThreatLevel(ThreatLevel.High, "osForceDropAttachmentAt")) return; 4348 CheckThreatLevel(ThreatLevel.High, "osForceDropAttachmentAt");
3828 m_host.AddScriptLPS(1);
3829 4349
3830 DropAttachmentAt(false, pos, rot); 4350 DropAttachmentAt(false, pos, rot);
3831 } 4351 }
3832 4352
3833 public LSL_Integer osListenRegex(int channelID, string name, string ID, string msg, int regexBitfield) 4353 public LSL_Integer osListenRegex(int channelID, string name, string ID, string msg, int regexBitfield)
3834 { 4354 {
3835 m_host.AddScriptLPS(1); 4355 CheckThreatLevel(ThreatLevel.Low, "osListenRegex");
4356
3836 UUID keyID; 4357 UUID keyID;
3837 UUID.TryParse(ID, out keyID); 4358 UUID.TryParse(ID, out keyID);
3838 4359
@@ -3879,7 +4400,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3879 4400
3880 public LSL_Integer osRegexIsMatch(string input, string pattern) 4401 public LSL_Integer osRegexIsMatch(string input, string pattern)
3881 { 4402 {
3882 m_host.AddScriptLPS(1); 4403 CheckThreatLevel(ThreatLevel.Low, "osRegexIsMatch");
4404
3883 try 4405 try
3884 { 4406 {
3885 return Regex.IsMatch(input, pattern) ? 1 : 0; 4407 return Regex.IsMatch(input, pattern) ? 1 : 0;
@@ -3890,5 +4412,392 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3890 return 0; 4412 return 0;
3891 } 4413 }
3892 } 4414 }
4415
4416 public LSL_String osRequestURL(LSL_List options)
4417 {
4418 CheckThreatLevel(ThreatLevel.Moderate, "osRequestSecureURL");
4419
4420 Hashtable opts = new Hashtable();
4421 for (int i = 0 ; i < options.Length ; i++)
4422 {
4423 object opt = options.Data[i];
4424 if (opt.ToString() == "allowXss")
4425 opts["allowXss"] = true;
4426 }
4427
4428 if (m_UrlModule != null)
4429 return m_UrlModule.RequestURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID, opts).ToString();
4430 return UUID.Zero.ToString();
4431 }
4432
4433 public LSL_String osRequestSecureURL(LSL_List options)
4434 {
4435 CheckThreatLevel(ThreatLevel.Moderate, "osRequestSecureURL");
4436
4437 Hashtable opts = new Hashtable();
4438 for (int i = 0 ; i < options.Length ; i++)
4439 {
4440 object opt = options.Data[i];
4441 if (opt.ToString() == "allowXss")
4442 opts["allowXss"] = true;
4443 }
4444
4445 if (m_UrlModule != null)
4446 return m_UrlModule.RequestSecureURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID, opts).ToString();
4447 return UUID.Zero.ToString();
4448 }
4449
4450 public void osCollisionSound(string impact_sound, double impact_volume)
4451 {
4452 CheckThreatLevel();
4453
4454 if(impact_sound == "")
4455 {
4456 m_host.CollisionSoundVolume = (float)impact_volume;
4457 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4458 if(impact_volume == 0.0)
4459 m_host.CollisionSoundType = -1; // disable all sounds
4460 else if(impact_volume == 1.0f)
4461 m_host.CollisionSoundType = 0; // full return to default sounds
4462 else
4463 m_host.CollisionSoundType = 2; // default sounds with volume
4464 m_host.aggregateScriptEvents();
4465 return;
4466 }
4467 // TODO: Parameter check logic required.
4468 UUID soundId = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound);
4469 if(soundId != UUID.Zero)
4470 {
4471 m_host.CollisionSound = soundId;
4472 m_host.CollisionSoundVolume = (float)impact_volume;
4473 m_host.CollisionSoundType = 1;
4474 }
4475 else
4476 m_host.CollisionSoundType = -1;
4477
4478 m_host.aggregateScriptEvents();
4479 }
4480
4481 // still not very usefull, detector is lost on rez, restarts, etc
4482 public void osVolumeDetect(int detect)
4483 {
4484 CheckThreatLevel();
4485
4486 if (m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted || m_host.ParentGroup.IsAttachment)
4487 return;
4488
4489 m_host.ScriptSetVolumeDetect(detect != 0);
4490 }
4491
4492 /// <summary>
4493 /// Get inertial data
4494 /// </summary>
4495 /// <remarks>
4496 /// </remarks>
4497 /// <returns>
4498 /// a LSL list with contents:
4499 /// LSL_Float mass, the total mass of a linkset
4500 /// LSL_Vector CenterOfMass, center mass relative to root prim
4501 /// LSL_Vector Inertia, elements of diagonal of inertia Ixx,Iyy,Izz divided by total mass
4502 /// LSL_Vector aux, elements of upper triagle of inertia Ixy (= Iyx), Ixz (= Izx), Iyz(= Izy) divided by total mass
4503 /// </returns>
4504 public LSL_List osGetInertiaData()
4505 {
4506 CheckThreatLevel();
4507
4508 LSL_List result = new LSL_List();
4509 float TotalMass;
4510 Vector3 CenterOfMass;
4511 Vector3 Inertia;
4512 Vector4 aux;
4513
4514 SceneObjectGroup sog = m_host.ParentGroup;
4515 if(sog== null || sog.IsDeleted)
4516 return result;
4517
4518 sog.GetInertiaData(out TotalMass, out CenterOfMass, out Inertia, out aux );
4519 if(TotalMass > 0)
4520 {
4521 float t = 1.0f/TotalMass;
4522 Inertia.X *= t;
4523 Inertia.Y *= t;
4524 Inertia.Z *= t;
4525
4526 aux.X *= t;
4527 aux.Y *= t;
4528 aux.Z *= t;
4529 }
4530
4531 result.Add(new LSL_Float(TotalMass));
4532 result.Add(new LSL_Vector(CenterOfMass.X, CenterOfMass.Y, CenterOfMass.Z));
4533 result.Add(new LSL_Vector(Inertia.X, Inertia.Y, Inertia.Z));
4534 result.Add(new LSL_Vector(aux.X, aux.Y, aux.Z));
4535 return result;
4536 }
4537
4538 /// <summary>
4539 /// set inertial data
4540 /// replaces the automatic calculation of mass, center of mass and inertia
4541 ///
4542 /// </summary>
4543 /// <param name="Mass">total mass of linkset</param>
4544 /// <param name="centerOfMass">location of center of mass relative to root prim in local coords</param>
4545 /// <param name="principalInertiaScaled">moment of inertia relative to principal axis and center of mass,Ixx, Iyy, Izz divided by mass</param>
4546 /// <param name="lslrot">rotation of the inertia, relative to local axis</param>
4547 /// <remarks>
4548 /// the inertia argument is is inertia divided by mass, so corresponds only to the geometric distribution of mass and both can be changed independently.
4549 /// </remarks>
4550
4551 public void osSetInertia(LSL_Float mass, LSL_Vector centerOfMass, LSL_Vector principalInertiaScaled, LSL_Rotation lslrot)
4552 {
4553 CheckThreatLevel();
4554
4555 SceneObjectGroup sog = m_host.ParentGroup;
4556 if(sog== null || sog.IsDeleted)
4557 return;
4558
4559 if(mass < 0 || principalInertiaScaled.x < 0 || principalInertiaScaled.y < 0 || principalInertiaScaled.z < 0)
4560 return;
4561
4562 // need more checks
4563
4564 Vector3 CenterOfMass = new Vector3((float)centerOfMass.x,(float)centerOfMass.y,(float)centerOfMass.z);
4565 Vector3 Inertia;
4566 float m = (float)mass;
4567
4568 Inertia.X = m * (float)principalInertiaScaled.x;
4569 Inertia.Y = m * (float)principalInertiaScaled.y;
4570 Inertia.Z = m * (float)principalInertiaScaled.z;
4571
4572 Vector4 rot = new Vector4((float)lslrot.x, (float)lslrot.y, (float)lslrot.y, (float)lslrot.s);
4573 rot.Normalize();
4574
4575 sog.SetInertiaData(m, CenterOfMass, Inertia, rot );
4576 }
4577
4578 /// <summary>
4579 /// set inertial data as a sphere
4580 /// replaces the automatic calculation of mass, center of mass and inertia
4581 ///
4582 /// </summary>
4583 /// <param name="Mass">total mass of linkset</param>
4584 /// <param name="boxsize">size of the Box</param>
4585 /// <param name="centerOfMass">location of center of mass relative to root prim in local coords</param>
4586 /// <param name="lslrot">rotation of the box, and so inertia, relative to local axis</param>
4587 /// <remarks>
4588 /// </remarks>
4589 public void osSetInertiaAsBox(LSL_Float mass, LSL_Vector boxSize, LSL_Vector centerOfMass, LSL_Rotation lslrot)
4590 {
4591 CheckThreatLevel();
4592
4593 SceneObjectGroup sog = m_host.ParentGroup;
4594 if(sog== null || sog.IsDeleted)
4595 return;
4596
4597 if(mass < 0)
4598 return;
4599
4600 // need more checks
4601
4602 Vector3 CenterOfMass = new Vector3((float)centerOfMass.x,(float)centerOfMass.y,(float)centerOfMass.z);
4603 Vector3 Inertia;
4604 float lx = (float)boxSize.x;
4605 float ly = (float)boxSize.y;
4606 float lz = (float)boxSize.z;
4607 float m = (float)mass;
4608 float t = m / 12.0f;
4609
4610 Inertia.X = t * (ly*ly + lz*lz);
4611 Inertia.Y = t * (lx*lx + lz*lz);
4612 Inertia.Z = t * (lx*lx + ly*ly);
4613
4614 Vector4 rot = new Vector4((float)lslrot.x, (float)lslrot.y, (float)lslrot.z, (float)lslrot.s);
4615 rot.Normalize();
4616
4617 sog.SetInertiaData(m, CenterOfMass, Inertia, rot );
4618 }
4619
4620 /// <summary>
4621 /// set inertial data as a sphere
4622 /// replaces the automatic calculation of mass, center of mass and inertia
4623 ///
4624 /// </summary>
4625 /// <param name="Mass">total mass of linkset</param>
4626 /// <param name="radius">radius of the sphere</param>
4627 /// <param name="centerOfMass">location of center of mass relative to root prim in local coords</param>
4628 /// <remarks>
4629 /// </remarks>
4630 public void osSetInertiaAsSphere(LSL_Float mass, LSL_Float radius, LSL_Vector centerOfMass)
4631 {
4632 CheckThreatLevel();
4633
4634 SceneObjectGroup sog = m_host.ParentGroup;
4635 if(sog== null || sog.IsDeleted)
4636 return;
4637
4638 if(mass < 0)
4639 return;
4640
4641 // need more checks
4642
4643 Vector3 CenterOfMass = new Vector3((float)centerOfMass.x,(float)centerOfMass.y,(float)centerOfMass.z);
4644 Vector3 Inertia;
4645 float r = (float)radius;
4646 float m = (float)mass;
4647 float t = 0.4f * m * r * r;
4648
4649 Inertia.X = t;
4650 Inertia.Y = t;
4651 Inertia.Z = t;
4652
4653 sog.SetInertiaData(m, CenterOfMass, Inertia, new Vector4(0f, 0f, 0f,1.0f));
4654 }
4655
4656 /// <summary>
4657 /// set inertial data as a cylinder
4658 /// replaces the automatic calculation of mass, center of mass and inertia
4659 ///
4660 /// </summary>
4661 /// <param name="Mass">total mass of linkset</param>
4662 /// <param name="radius">radius of the cylinder</param>
4663 /// <param name="lenght">lenght of the cylinder</param>
4664 /// <param name="centerOfMass">location of center of mass relative to root prim in local coords</param>
4665 /// <param name="lslrot">rotation of the cylinder, and so inertia, relative to local axis</param>
4666 /// <remarks>
4667 /// cylinder axis aligned with Z axis. For other orientations provide the rotation.
4668 /// </remarks>
4669 public void osSetInertiaAsCylinder(LSL_Float mass, LSL_Float radius, LSL_Float lenght, LSL_Vector centerOfMass, LSL_Rotation lslrot)
4670 {
4671 CheckThreatLevel();
4672
4673 SceneObjectGroup sog = m_host.ParentGroup;
4674 if(sog== null || sog.IsDeleted)
4675 return;
4676
4677 if(mass < 0)
4678 return;
4679
4680 // need more checks
4681
4682 Vector3 CenterOfMass = new Vector3((float)centerOfMass.x,(float)centerOfMass.y,(float)centerOfMass.z);
4683 Vector3 Inertia;
4684 float m = (float)mass;
4685 float r = (float)radius;
4686 r *= r;
4687 Inertia.Z = 0.5f * m * r;
4688 float t = (float)lenght;
4689 t *= t;
4690 t += 3.0f * r;
4691 t *= 8.333333e-2f * m;
4692
4693 Inertia.X = t;
4694 Inertia.Y = t;
4695
4696 Vector4 rot = new Vector4((float)lslrot.x, (float)lslrot.y, (float)lslrot.z, (float)lslrot.s);
4697 rot.Normalize();
4698
4699 sog.SetInertiaData(m, CenterOfMass, Inertia, rot);
4700 }
4701
4702 /// <summary>
4703 /// removes inertial data manual override
4704 /// default automatic calculation is used again
4705 ///
4706 /// </summary>
4707 public void osClearInertia()
4708 {
4709 CheckThreatLevel();
4710
4711 SceneObjectGroup sog = m_host.ParentGroup;
4712 if(sog== null || sog.IsDeleted)
4713 return;
4714
4715 sog.SetInertiaData(-1, Vector3.Zero, Vector3.Zero, Vector4.Zero );
4716 }
4717
4718 private bool checkAllowObjectTPbyLandOwner(Vector3 pos)
4719 {
4720 ILandObject land = World.LandChannel.GetLandObject(pos);
4721 if(land == null)
4722 return true;
4723
4724 LandData landdata = land.LandData;
4725 if(landdata == null)
4726 return true;
4727
4728 UUID hostOwner = m_host.OwnerID;
4729 if(landdata.OwnerID == hostOwner)
4730 return true;
4731
4732 EstateSettings es = World.RegionInfo.EstateSettings;
4733 if(es != null && es.IsEstateManagerOrOwner(hostOwner))
4734 return true;
4735
4736 if(!landdata.IsGroupOwned)
4737 return false;
4738
4739 UUID landGroup = landdata.GroupID;
4740 if(landGroup == UUID.Zero)
4741 return false;
4742
4743 if(landGroup == m_host.GroupID)
4744 return true;
4745
4746 return false;
4747 }
4748
4749 /// <summary>
4750 /// teleports a object (full linkset)
4751 /// </summary>
4752 /// <param name="objectUUID">the id of the linkset to teleport</param>
4753 /// <param name="targetPos">target position</param>
4754 /// <param name="rotation"> a rotation to apply</param>
4755 /// <param name="flags">several flags/param>
4756 /// <remarks>
4757 /// only does teleport local to region
4758 /// if object has scripts, owner must have rights to run scripts on target location
4759 /// object owner must have rights to enter ojects on target location
4760 /// target location parcel must have enought free prims capacity for the linkset prims
4761 /// all avatars siting on the object must have access to target location
4762 /// has a cool down time. retries before expire reset it
4763 /// fail conditions are silent ignored
4764 /// </remarks>
4765 public LSL_Integer osTeleportObject(LSL_Key objectUUID, LSL_Vector targetPos, LSL_Rotation rotation, LSL_Integer flags)
4766 {
4767 CheckThreatLevel(ThreatLevel.Severe, "osTeleportObject");
4768
4769 UUID objUUID;
4770 if (!UUID.TryParse(objectUUID, out objUUID))
4771 {
4772 OSSLShoutError("osTeleportObject() invalid object Key");
4773 return -1;
4774 }
4775
4776 SceneObjectGroup sog = World.GetSceneObjectGroup(objUUID);
4777 if(sog== null || sog.IsDeleted || sog.inTransit)
4778 return -1;
4779
4780 if(sog.OwnerID != m_host.OwnerID)
4781 {
4782 Vector3 pos = sog.AbsolutePosition;
4783 if(!checkAllowObjectTPbyLandOwner(pos))
4784 return -1;
4785 }
4786
4787 UUID myid = m_host.ParentGroup.UUID;
4788
4789 return sog.TeleportObject(myid, targetPos, rotation, flags);
4790 // a delay here may break vehicles
4791 }
4792
4793 public LSL_Integer osGetLinkNumber(LSL_String name)
4794 {
4795 CheckThreatLevel();
4796
4797 SceneObjectGroup sog = m_host.ParentGroup;
4798 if(sog== null || sog.IsDeleted)
4799 return -1;
4800 return sog.GetLinkNumber(name);
4801 }
3893 } 4802 }
3894} 4803}
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