aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs29
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs472
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3921
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs524
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs1188
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs148
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs36
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs16
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILS_Api.cs49
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs53
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Constants.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs17
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs85
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs60
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs101
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs173
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/AssemblyResolver.cs7
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs35
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs12
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs271
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs97
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs295
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs229
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/EventManager.cs12
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs340
29 files changed, 5898 insertions, 2298 deletions
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs
index 02d1511..581a9a9 100644
--- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs
+++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs
@@ -82,6 +82,7 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
82 IConfig Config { get; } 82 IConfig Config { get; }
83 IConfigSource ConfigSource { get; } 83 IConfigSource ConfigSource { get; }
84 string ScriptEngineName { get; } 84 string ScriptEngineName { get; }
85 string ScriptEnginePath { get; }
85 IScriptApi GetApi(UUID itemID, string name); 86 IScriptApi GetApi(UUID itemID, string name);
86 } 87 }
87} 88}
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
index ae148a9..d3200d5 100644
--- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
@@ -38,10 +38,12 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
38{ 38{
39 public enum StateSource 39 public enum StateSource
40 { 40 {
41 NewRez = 0, 41 RegionStart = 0,
42 PrimCrossing = 1, 42 NewRez = 1,
43 ScriptedRez = 2, 43 PrimCrossing = 2,
44 AttachedRez = 3 44 ScriptedRez = 3,
45 AttachedRez = 4,
46 Teleporting = 5
45 } 47 }
46 48
47 public interface IScriptWorkItem 49 public interface IScriptWorkItem
@@ -56,7 +58,16 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
56 /// </summary> 58 /// </summary>
57 public interface IScriptInstance 59 public interface IScriptInstance
58 { 60 {
61 /// <summary>
62 /// Is the script currently running?
63 /// </summary>
59 bool Running { get; set; } 64 bool Running { get; set; }
65
66 /// <summary>
67 /// Is the script suspended?
68 /// </summary>
69 bool Suspended { get; set; }
70
60 bool ShuttingDown { get; set; } 71 bool ShuttingDown { get; set; }
61 string State { get; set; } 72 string State { get; set; }
62 IScriptEngine Engine { get; } 73 IScriptEngine Engine { get; }
@@ -76,11 +87,21 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
76 87
77 void Init(); 88 void Init();
78 void Start(); 89 void Start();
90
91 /// <summary>
92 /// Stop the script.
93 /// </summary>
94 /// <param name="timeout"></param>
95 /// <returns>true if the script was successfully stopped, false otherwise</returns>
79 bool Stop(int timeout); 96 bool Stop(int timeout);
97
80 void SetState(string state); 98 void SetState(string state);
81 99
82 void PostEvent(EventParams data); 100 void PostEvent(EventParams data);
83 101
102 void Suspend();
103 void Resume();
104
84 /// <summary> 105 /// <summary>
85 /// Process the next event queued for this script 106 /// Process the next event queued for this script
86 /// </summary> 107 /// </summary>
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index ee32755..61e4934 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -248,6 +248,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
248 248
249 } 249 }
250 250
251 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
252 {
253 // Remove a specific script
254
255 // Remove dataserver events
256 m_Dataserver[engine].RemoveEvents(localID, itemID);
257
258 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
259 if (comms != null)
260 comms.DeleteListener(itemID);
261
262 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
263 xmlrpc.DeleteChannels(itemID);
264 xmlrpc.CancelSRDRequests(itemID);
265
266 // Remove Sensors
267 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
268
269 }
270
251 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 271 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
252 { 272 {
253 List<Object> data = new List<Object>(); 273 List<Object> data = new List<Object>();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
index 5b180ff..489c1c6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -1,4 +1,31 @@
1using System; 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;
2using System.Reflection; 29using System.Reflection;
3using System.Collections; 30using System.Collections;
4using System.Collections.Generic; 31using System.Collections.Generic;
@@ -7,7 +34,7 @@ using OpenMetaverse;
7using Nini.Config; 34using Nini.Config;
8using OpenSim; 35using OpenSim;
9using OpenSim.Framework; 36using OpenSim.Framework;
10using OpenSim.Region.CoreModules.World.Meta7Windlight; 37using OpenSim.Region.CoreModules.World.LightShare;
11using OpenSim.Region.Framework.Interfaces; 38using OpenSim.Region.Framework.Interfaces;
12using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
13using OpenSim.Region.ScriptEngine.Shared; 40using OpenSim.Region.ScriptEngine.Shared;
@@ -15,6 +42,7 @@ using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
15using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 42using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
16using OpenSim.Region.ScriptEngine.Interfaces; 43using OpenSim.Region.ScriptEngine.Interfaces;
17using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces; 44using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
45using OpenSim.Services.Interfaces;
18 46
19using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; 47using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
20using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; 48using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
@@ -34,7 +62,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
34 internal uint m_localID; 62 internal uint m_localID;
35 internal UUID m_itemID; 63 internal UUID m_itemID;
36 internal bool m_CMFunctionsEnabled = false; 64 internal bool m_CMFunctionsEnabled = false;
37 internal IScriptModuleComms m_comms = null;
38 65
39 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
40 { 67 {
@@ -45,10 +72,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
45 72
46 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false)) 73 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
47 m_CMFunctionsEnabled = true; 74 m_CMFunctionsEnabled = true;
48
49 m_comms = m_ScriptEngine.World.RequestModuleInterface<IScriptModuleComms>();
50 if (m_comms == null)
51 m_CMFunctionsEnabled = false;
52 } 75 }
53 76
54 public override Object InitializeLifetimeService() 77 public override Object InitializeLifetimeService()
@@ -69,434 +92,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
69 get { return m_ScriptEngine.World; } 92 get { return m_ScriptEngine.World; }
70 } 93 }
71 94
72 // 95 public string cmDetectedCountry(int number)
73 //Dumps an error message on the debug console.
74 //
75
76 internal void CMShoutError(string message)
77 { 96 {
78 if (message.Length > 1023) 97 m_host.AddScriptLPS(1);
79 message = message.Substring(0, 1023); 98 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number);
80 99 if (detectedParams == null)
81 World.SimChat(Utils.StringToBytes(message), 100 return String.Empty;
82 ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true); 101 return detectedParams.Country;
83
84 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
85 wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message);
86 } 102 }
87 103
88 /// <summary> 104 public string cmGetAgentCountry(LSL_Key key)
89 /// Like osGetAgents but returns enough info for a radar
90 /// </summary>
91 /// <returns>Strided list of the UUID, position and name of each avatar in the region</returns>
92 public LSL_List cmGetAvatarList()
93 { 105 {
94 LSL_List result = new LSL_List(); 106 if (!World.Permissions.IsGod(m_host.OwnerID))
95 foreach (ScenePresence avatar in World.GetAvatars()) 107 return String.Empty;
96 {
97 if (avatar != null && avatar.UUID != m_host.OwnerID)
98 {
99 if (avatar.IsChildAgent == false)
100 {
101 if (avatar.PhysicsActor != null && avatar.PhysicsActor.Position != null)
102 {
103 result.Add(avatar.UUID);
104 result.Add(avatar.PhysicsActor.Position);
105 result.Add(avatar.Name);
106 }
107 }
108 }
109 }
110 return result;
111 }
112 108
113 /// <summary> 109 UUID uuid;
114 /// Get the current Windlight scene
115 /// </summary>
116 /// <returns>List of windlight parameters</returns>
117 public LSL_List cmGetWindlightScene(LSL_List rules)
118 {
119 if (!m_CMFunctionsEnabled)
120 {
121 CMShoutError("Careminster functions are not enabled.");
122 return new LSL_List();
123 }
124 m_host.AddScriptLPS(1);
125 RegionMeta7WindlightData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings;
126 110
127 LSL_List values = new LSL_List(); 111 if (!UUID.TryParse(key, out uuid))
128 int idx = 0; 112 return String.Empty;
129 while (idx < rules.Length)
130 {
131 uint rule = (uint)rules.GetLSLIntegerItem(idx);
132 LSL_List toadd = new LSL_List();
133
134 switch (rule)
135 {
136 case (int)ScriptBaseClass.WL_AMBIENT:
137 toadd.Add(new LSL_Rotation(wl.ambient.X, wl.ambient.Y, wl.ambient.Z, wl.ambient.W));
138 break;
139 case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION:
140 toadd.Add(new LSL_Vector(wl.bigWaveDirection.X, wl.bigWaveDirection.Y, 0.0f));
141 break;
142 case (int)ScriptBaseClass.WL_BLUE_DENSITY:
143 toadd.Add(new LSL_Rotation(wl.blueDensity.X, wl.blueDensity.Y, wl.blueDensity.Z, wl.blueDensity.W));
144 break;
145 case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER:
146 toadd.Add(new LSL_Float(wl.blurMultiplier));
147 break;
148 case (int)ScriptBaseClass.WL_CLOUD_COLOR:
149 toadd.Add(new LSL_Rotation(wl.cloudColor.X, wl.cloudColor.Y, wl.cloudColor.Z, wl.cloudColor.W));
150 break;
151 case (int)ScriptBaseClass.WL_CLOUD_COVERAGE:
152 toadd.Add(new LSL_Float(wl.cloudCoverage));
153 break;
154 case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY:
155 toadd.Add(new LSL_Vector(wl.cloudDetailXYDensity.X, wl.cloudDetailXYDensity.Y, wl.cloudDetailXYDensity.Z));
156 break;
157 case (int)ScriptBaseClass.WL_CLOUD_SCALE:
158 toadd.Add(new LSL_Float(wl.cloudScale));
159 break;
160 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X:
161 toadd.Add(new LSL_Float(wl.cloudScrollX));
162 break;
163 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK:
164 toadd.Add(new LSL_Integer(wl.cloudScrollXLock ? 1 : 0));
165 break;
166 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y:
167 toadd.Add(new LSL_Float(wl.cloudScrollY));
168 break;
169 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK:
170 toadd.Add(new LSL_Integer(wl.cloudScrollYLock ? 1 : 0));
171 break;
172 case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY:
173 toadd.Add(new LSL_Vector(wl.cloudXYDensity.X, wl.cloudXYDensity.Y, wl.cloudXYDensity.Z));
174 break;
175 case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER:
176 toadd.Add(new LSL_Float(wl.densityMultiplier));
177 break;
178 case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER:
179 toadd.Add(new LSL_Float(wl.distanceMultiplier));
180 break;
181 case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS:
182 toadd.Add(new LSL_Integer(wl.drawClassicClouds ? 1 : 0));
183 break;
184 case (int)ScriptBaseClass.WL_EAST_ANGLE:
185 toadd.Add(new LSL_Float(wl.eastAngle));
186 break;
187 case (int)ScriptBaseClass.WL_FRESNEL_OFFSET:
188 toadd.Add(new LSL_Float(wl.fresnelOffset));
189 break;
190 case (int)ScriptBaseClass.WL_FRESNEL_SCALE:
191 toadd.Add(new LSL_Float(wl.fresnelScale));
192 break;
193 case (int)ScriptBaseClass.WL_HAZE_DENSITY:
194 toadd.Add(new LSL_Float(wl.hazeDensity));
195 break;
196 case (int)ScriptBaseClass.WL_HAZE_HORIZON:
197 toadd.Add(new LSL_Float(wl.hazeHorizon));
198 break;
199 case (int)ScriptBaseClass.WL_HORIZON:
200 toadd.Add(new LSL_Rotation(wl.horizon.X, wl.horizon.Y, wl.horizon.Z, wl.horizon.W));
201 break;
202 case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION:
203 toadd.Add(new LSL_Vector(wl.littleWaveDirection.X, wl.littleWaveDirection.Y, 0.0f));
204 break;
205 case (int)ScriptBaseClass.WL_MAX_ALTITUDE:
206 toadd.Add(new LSL_Integer(wl.maxAltitude));
207 break;
208 case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE:
209 toadd.Add(new LSL_Key(wl.normalMapTexture.ToString()));
210 break;
211 case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE:
212 toadd.Add(new LSL_Vector(wl.reflectionWaveletScale.X, wl.reflectionWaveletScale.Y, wl.reflectionWaveletScale.Z));
213 break;
214 case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE:
215 toadd.Add(new LSL_Float(wl.refractScaleAbove));
216 break;
217 case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW:
218 toadd.Add(new LSL_Float(wl.refractScaleBelow));
219 break;
220 case (int)ScriptBaseClass.WL_SCENE_GAMMA:
221 toadd.Add(new LSL_Float(wl.sceneGamma));
222 break;
223 case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS:
224 toadd.Add(new LSL_Float(wl.starBrightness));
225 break;
226 case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS:
227 toadd.Add(new LSL_Float(wl.sunGlowFocus));
228 break;
229 case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE:
230 toadd.Add(new LSL_Float(wl.sunGlowSize));
231 break;
232 case (int)ScriptBaseClass.WL_SUN_MOON_COLOR:
233 toadd.Add(new LSL_Rotation(wl.sunMoonColor.X, wl.sunMoonColor.Y, wl.sunMoonColor.Z, wl.sunMoonColor.W));
234 break;
235 case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER:
236 toadd.Add(new LSL_Float(wl.underwaterFogModifier));
237 break;
238 case (int)ScriptBaseClass.WL_WATER_COLOR:
239 toadd.Add(new LSL_Vector(wl.waterColor.X, wl.waterColor.Y, wl.waterColor.Z));
240 break;
241 case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT:
242 toadd.Add(new LSL_Float(wl.waterFogDensityExponent));
243 break;
244 }
245
246 if (toadd.Length > 0)
247 {
248 values.Add(rule);
249 values.Add(toadd.Data[0]);
250 }
251 idx++;
252 }
253
254
255 return values;
256 113
114 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
115 return account.UserCountry;
257 } 116 }
258
259 private RegionMeta7WindlightData getWindlightProfileFromRules(LSL_List rules)
260 {
261 RegionMeta7WindlightData wl = (RegionMeta7WindlightData)m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.Clone();
262
263 LSL_List values = new LSL_List();
264 int idx = 0;
265 while (idx < rules.Length)
266 {
267 uint rule = (uint)rules.GetLSLIntegerItem(idx);
268 LSL_Types.Quaternion iQ;
269 LSL_Types.Vector3 iV;
270 switch (rule)
271 {
272 case (int)ScriptBaseClass.WL_SUN_MOON_POSITION:
273 idx++;
274 wl.sunMoonPosition = (float)rules.GetLSLFloatItem(idx);
275 break;
276 case (int)ScriptBaseClass.WL_AMBIENT:
277 idx++;
278 iQ = rules.GetQuaternionItem(idx);
279 wl.ambient = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
280 break;
281 case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION:
282 idx++;
283 iV = rules.GetVector3Item(idx);
284 wl.bigWaveDirection = new Vector2((float)iV.x, (float)iV.y);
285 break;
286 case (int)ScriptBaseClass.WL_BLUE_DENSITY:
287 idx++;
288 iQ = rules.GetQuaternionItem(idx);
289 wl.blueDensity = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
290 break;
291 case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER:
292 idx++;
293 wl.blurMultiplier = (float)rules.GetLSLFloatItem(idx);
294 break;
295 case (int)ScriptBaseClass.WL_CLOUD_COLOR:
296 idx++;
297 iQ = rules.GetQuaternionItem(idx);
298 wl.cloudColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
299 break;
300 case (int)ScriptBaseClass.WL_CLOUD_COVERAGE:
301 idx++;
302 wl.cloudCoverage = (float)rules.GetLSLFloatItem(idx);
303 break;
304 case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY:
305 idx++;
306 iV = rules.GetVector3Item(idx);
307 wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
308 break;
309 case (int)ScriptBaseClass.WL_CLOUD_SCALE:
310 idx++;
311 wl.cloudScale = (float)rules.GetLSLFloatItem(idx);
312 break;
313 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X:
314 idx++;
315 wl.cloudScrollX = (float)rules.GetLSLFloatItem(idx);
316 break;
317 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK:
318 idx++;
319 wl.cloudScrollXLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false;
320 break;
321 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y:
322 idx++;
323 wl.cloudScrollY = (float)rules.GetLSLFloatItem(idx);
324 break;
325 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK:
326 idx++;
327 wl.cloudScrollYLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false;
328 break;
329 case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY:
330 idx++;
331 iV = rules.GetVector3Item(idx);
332 wl.cloudXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
333 break;
334 case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER:
335 idx++;
336 wl.densityMultiplier = (float)rules.GetLSLFloatItem(idx);
337 break;
338 case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER:
339 idx++;
340 wl.distanceMultiplier = (float)rules.GetLSLFloatItem(idx);
341 break;
342 case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS:
343 idx++;
344 wl.drawClassicClouds = rules.GetLSLIntegerItem(idx).value == 1 ? true : false;
345 break;
346 case (int)ScriptBaseClass.WL_EAST_ANGLE:
347 idx++;
348 wl.eastAngle = (float)rules.GetLSLFloatItem(idx);
349 break;
350 case (int)ScriptBaseClass.WL_FRESNEL_OFFSET:
351 idx++;
352 wl.fresnelOffset = (float)rules.GetLSLFloatItem(idx);
353 break;
354 case (int)ScriptBaseClass.WL_FRESNEL_SCALE:
355 idx++;
356 wl.fresnelScale = (float)rules.GetLSLFloatItem(idx);
357 break;
358 case (int)ScriptBaseClass.WL_HAZE_DENSITY:
359 idx++;
360 wl.hazeDensity = (float)rules.GetLSLFloatItem(idx);
361 break;
362 case (int)ScriptBaseClass.WL_HAZE_HORIZON:
363 idx++;
364 wl.hazeHorizon = (float)rules.GetLSLFloatItem(idx);
365 break;
366 case (int)ScriptBaseClass.WL_HORIZON:
367 idx++;
368 iQ = rules.GetQuaternionItem(idx);
369 wl.horizon = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
370 break;
371 case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION:
372 idx++;
373 iV = rules.GetVector3Item(idx);
374 wl.littleWaveDirection = new Vector2((float)iV.x, (float)iV.y);
375 break;
376 case (int)ScriptBaseClass.WL_MAX_ALTITUDE:
377 idx++;
378 wl.maxAltitude = (ushort)rules.GetLSLIntegerItem(idx).value;
379 break;
380 case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE:
381 idx++;
382 wl.normalMapTexture = new UUID(rules.GetLSLStringItem(idx).m_string);
383 break;
384 case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE:
385 idx++;
386 iV = rules.GetVector3Item(idx);
387 wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
388 break;
389 case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE:
390 idx++;
391 wl.refractScaleAbove = (float)rules.GetLSLFloatItem(idx);
392 break;
393 case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW:
394 idx++;
395 wl.refractScaleBelow = (float)rules.GetLSLFloatItem(idx);
396 break;
397 case (int)ScriptBaseClass.WL_SCENE_GAMMA:
398 idx++;
399 wl.sceneGamma = (float)rules.GetLSLFloatItem(idx);
400 break;
401 case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS:
402 idx++;
403 wl.starBrightness = (float)rules.GetLSLFloatItem(idx);
404 break;
405 case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS:
406 idx++;
407 wl.sunGlowFocus = (float)rules.GetLSLFloatItem(idx);
408 break;
409 case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE:
410 idx++;
411 wl.sunGlowSize = (float)rules.GetLSLFloatItem(idx);
412 break;
413 case (int)ScriptBaseClass.WL_SUN_MOON_COLOR:
414 idx++;
415 iQ = rules.GetQuaternionItem(idx);
416 wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
417 break;
418 case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER:
419 idx++;
420 wl.underwaterFogModifier = (float)rules.GetLSLFloatItem(idx);
421 break;
422 case (int)ScriptBaseClass.WL_WATER_COLOR:
423 idx++;
424 iV = rules.GetVector3Item(idx);
425 wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
426 break;
427 case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT:
428 idx++;
429 wl.waterFogDensityExponent = (float)rules.GetLSLFloatItem(idx);
430 break;
431 }
432 idx++;
433 }
434 return wl;
435 }
436 /// <summary>
437 /// Set the current Windlight scene
438 /// </summary>
439 /// <param name="rules"></param>
440 /// <returns>success: true or false</returns>
441 public int cmSetWindlightScene(LSL_List rules)
442 {
443 if (!m_CMFunctionsEnabled)
444 {
445 CMShoutError("Careminster functions are not enabled.");
446 return 0;
447 }
448 if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200)
449 {
450 CMShoutError("cmSetWindlightScene can only be used by estate managers or owners.");
451 return 0;
452 }
453 int success = 0;
454 m_host.AddScriptLPS(1);
455 if (Meta7WindlightModule.EnableWindlight)
456 {
457 RegionMeta7WindlightData wl = getWindlightProfileFromRules(rules);
458 m_host.ParentGroup.Scene.StoreWindlightProfile(wl);
459 success = 1;
460 }
461 else
462 {
463 CMShoutError("Windlight module is disabled");
464 return 0;
465 }
466 return success;
467 }
468 /// <summary>
469 /// Set the current Windlight scene to a target avatar
470 /// </summary>
471 /// <param name="rules"></param>
472 /// <returns>success: true or false</returns>
473 public int cmSetWindlightSceneTargeted(LSL_List rules, LSL_Key target)
474 {
475 if (!m_CMFunctionsEnabled)
476 {
477 CMShoutError("Careminster functions are not enabled.");
478 return 0;
479 }
480 if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200)
481 {
482 CMShoutError("cmSetWindlightSceneTargeted can only be used by estate managers or owners.");
483 return 0;
484 }
485 int success = 0;
486 m_host.AddScriptLPS(1);
487 if (Meta7WindlightModule.EnableWindlight)
488 {
489 RegionMeta7WindlightData wl = getWindlightProfileFromRules(rules);
490 World.EventManager.TriggerOnSendNewWindlightProfileTargeted(wl, new UUID(target.m_string));
491 success = 1;
492 }
493 else
494 {
495 CMShoutError("Windlight module is disabled");
496 return 0;
497 }
498 return success;
499 }
500
501 } 117 }
502} 118}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 012ba90..7a56f11 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -24,7 +24,7 @@
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 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. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
@@ -33,18 +33,20 @@ using System.Runtime.Remoting.Lifetime;
33using System.Text; 33using System.Text;
34using System.Threading; 34using System.Threading;
35using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
36using Nini.Config; 37using Nini.Config;
37using log4net; 38using log4net;
38using OpenMetaverse; 39using OpenMetaverse;
39using OpenMetaverse.Packets; 40using OpenMetaverse.Packets;
40using OpenSim; 41using OpenSim;
41using OpenSim.Framework; 42using OpenSim.Framework;
42using OpenSim.Framework.Communications.Cache; 43
43using OpenSim.Region.CoreModules; 44using OpenSim.Region.CoreModules;
44using OpenSim.Region.CoreModules.World.Land; 45using OpenSim.Region.CoreModules.World.Land;
45using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
46using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
47using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
48using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
49using OpenSim.Region.Physics.Manager; 51using OpenSim.Region.Physics.Manager;
50using OpenSim.Region.ScriptEngine.Shared; 52using OpenSim.Region.ScriptEngine.Shared;
@@ -53,9 +55,9 @@ using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
53using OpenSim.Region.ScriptEngine.Interfaces; 55using OpenSim.Region.ScriptEngine.Interfaces;
54using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces; 56using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
55using OpenSim.Services.Interfaces; 57using OpenSim.Services.Interfaces;
56
57using PrimType = OpenSim.Region.Framework.Scenes.PrimType;
58using GridRegion = OpenSim.Services.Interfaces.GridRegion; 58using GridRegion = OpenSim.Services.Interfaces.GridRegion;
59using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
60using PrimType = OpenSim.Region.Framework.Scenes.PrimType;
59using AssetLandmark = OpenSim.Framework.AssetLandmark; 61using AssetLandmark = OpenSim.Framework.AssetLandmark;
60 62
61using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; 63using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
@@ -66,15 +68,24 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
66using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 68using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
67using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 69using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
68using System.Reflection; 70using System.Reflection;
71using Timer = System.Timers.Timer;
69 72
70namespace OpenSim.Region.ScriptEngine.Shared.Api 73namespace OpenSim.Region.ScriptEngine.Shared.Api
71{ 74{
75 // MUST be a ref type
76 public class UserInfoCacheEntry
77 {
78 public int time;
79 public UserAccount account;
80 public PresenceInfo pinfo;
81 }
82
72 /// <summary> 83 /// <summary>
73 /// Contains all LSL ll-functions. This class will be in Default AppDomain. 84 /// Contains all LSL ll-functions. This class will be in Default AppDomain.
74 /// </summary> 85 /// </summary>
75 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi 86 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
76 { 87 {
77 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 88// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
78 protected IScriptEngine m_ScriptEngine; 89 protected IScriptEngine m_ScriptEngine;
79 protected SceneObjectPart m_host; 90 protected SceneObjectPart m_host;
80 protected uint m_localID; 91 protected uint m_localID;
@@ -92,14 +103,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
92 protected int m_notecardLineReadCharsMax = 255; 103 protected int m_notecardLineReadCharsMax = 255;
93 protected int m_scriptConsoleChannel = 0; 104 protected int m_scriptConsoleChannel = 0;
94 protected bool m_scriptConsoleChannelEnabled = false; 105 protected bool m_scriptConsoleChannelEnabled = false;
106 protected bool m_debuggerSafe = false;
95 protected IUrlModule m_UrlModule = null; 107 protected IUrlModule m_UrlModule = null;
108 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
109 new Dictionary<UUID, UserInfoCacheEntry>();
110
111 protected Timer m_ShoutSayTimer;
112 protected int m_SayShoutCount = 0;
96 113
97 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 114 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
98 { 115 {
116 m_ShoutSayTimer = new Timer(1000);
117 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
118 m_ShoutSayTimer.AutoReset = true;
119 m_ShoutSayTimer.Start();
120
99 m_ScriptEngine = ScriptEngine; 121 m_ScriptEngine = ScriptEngine;
100 m_host = host; 122 m_host = host;
101 m_localID = localID; 123 m_localID = localID;
102 m_itemID = itemID; 124 m_itemID = itemID;
125 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
103 126
104 m_ScriptDelayFactor = 127 m_ScriptDelayFactor =
105 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 128 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
@@ -219,6 +242,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
219 } 242 }
220 } 243 }
221 244
245 public List<ScenePresence> GetLinkAvatars(int linkType)
246 {
247 List<ScenePresence> ret = new List<ScenePresence>();
248 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
249 return ret;
250
251 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
252
253 switch (linkType)
254 {
255 case ScriptBaseClass.LINK_SET:
256 return avs;
257
258 case ScriptBaseClass.LINK_ROOT:
259 return ret;
260
261 case ScriptBaseClass.LINK_ALL_OTHERS:
262 return avs;
263
264 case ScriptBaseClass.LINK_ALL_CHILDREN:
265 return avs;
266
267 case ScriptBaseClass.LINK_THIS:
268 return ret;
269
270 default:
271 if (linkType < 0)
272 return ret;
273
274 int partCount = m_host.ParentGroup.GetPartCount();
275
276 if (linkType <= partCount)
277 {
278 return ret;
279 }
280 else
281 {
282 linkType = linkType - partCount;
283 if (linkType > avs.Count)
284 {
285 return ret;
286 }
287 else
288 {
289 ret.Add(avs[linkType-1]);
290 return ret;
291 }
292 }
293 }
294 }
295
222 public List<SceneObjectPart> GetLinkParts(int linkType) 296 public List<SceneObjectPart> GetLinkParts(int linkType)
223 { 297 {
224 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 298 List<SceneObjectPart> ret = new List<SceneObjectPart>();
@@ -229,31 +303,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
229 switch (linkType) 303 switch (linkType)
230 { 304 {
231 case ScriptBaseClass.LINK_SET: 305 case ScriptBaseClass.LINK_SET:
232 if (m_host.ParentGroup != null) 306 return new List<SceneObjectPart>(m_host.ParentGroup.Parts);
233 return new List<SceneObjectPart>(m_host.ParentGroup.Children.Values);
234 return ret;
235 307
236 case ScriptBaseClass.LINK_ROOT: 308 case ScriptBaseClass.LINK_ROOT:
237 if (m_host.ParentGroup != null) 309 ret = new List<SceneObjectPart>();
238 { 310 ret.Add(m_host.ParentGroup.RootPart);
239 ret = new List<SceneObjectPart>();
240 ret.Add(m_host.ParentGroup.RootPart);
241 return ret;
242 }
243 return ret; 311 return ret;
244 312
245 case ScriptBaseClass.LINK_ALL_OTHERS: 313 case ScriptBaseClass.LINK_ALL_OTHERS:
246 if (m_host.ParentGroup == null) 314 ret = new List<SceneObjectPart>(m_host.ParentGroup.Parts);
247 return new List<SceneObjectPart>(); 315
248 ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values);
249 if (ret.Contains(m_host)) 316 if (ret.Contains(m_host))
250 ret.Remove(m_host); 317 ret.Remove(m_host);
318
251 return ret; 319 return ret;
252 320
253 case ScriptBaseClass.LINK_ALL_CHILDREN: 321 case ScriptBaseClass.LINK_ALL_CHILDREN:
254 if (m_host.ParentGroup == null) 322 ret = new List<SceneObjectPart>(m_host.ParentGroup.Parts);
255 return new List<SceneObjectPart>(); 323
256 ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values);
257 if (ret.Contains(m_host.ParentGroup.RootPart)) 324 if (ret.Contains(m_host.ParentGroup.RootPart))
258 ret.Remove(m_host.ParentGroup.RootPart); 325 ret.Remove(m_host.ParentGroup.RootPart);
259 return ret; 326 return ret;
@@ -262,15 +329,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
262 return ret; 329 return ret;
263 330
264 default: 331 default:
265 if (linkType < 0 || m_host.ParentGroup == null) 332 if (linkType < 0)
266 return new List<SceneObjectPart>(); 333 return new List<SceneObjectPart>();
334
267 SceneObjectPart target = m_host.ParentGroup.GetLinkNumPart(linkType); 335 SceneObjectPart target = m_host.ParentGroup.GetLinkNumPart(linkType);
268 if (target == null) 336 if (target == null)
269 return new List<SceneObjectPart>(); 337 return new List<SceneObjectPart>();
270 ret = new List<SceneObjectPart>(); 338 ret = new List<SceneObjectPart>();
271 ret.Add(target); 339 ret.Add(target);
272 return ret; 340 return ret;
273
274 } 341 }
275 } 342 }
276 343
@@ -370,7 +437,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
370 } 437 }
371 438
372 // convert a LSL_Rotation to a Quaternion 439 // convert a LSL_Rotation to a Quaternion
373 protected Quaternion Rot2Quaternion(LSL_Rotation r) 440 public static Quaternion Rot2Quaternion(LSL_Rotation r)
374 { 441 {
375 Quaternion q = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s); 442 Quaternion q = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
376 q.Normalize(); 443 q.Normalize();
@@ -467,7 +534,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
467 534
468 public LSL_Vector llVecNorm(LSL_Vector v) 535 public LSL_Vector llVecNorm(LSL_Vector v)
469 { 536 {
470 m_host.AddScriptLPS(1); 537 m_host.AddScriptLPS(1);
471 return LSL_Vector.Norm(v); 538 return LSL_Vector.Norm(v);
472 } 539 }
473 540
@@ -497,25 +564,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
497 return remainder; 564 return remainder;
498 } 565 }
499 566
500 // Old implementation of llRot2Euler, now normalized 567 public LSL_Vector llRot2Euler(LSL_Rotation q1)
501
502 public LSL_Vector llRot2Euler(LSL_Rotation r)
503 { 568 {
504 m_host.AddScriptLPS(1); 569 m_host.AddScriptLPS(1);
505 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 570 LSL_Vector eul = new LSL_Vector();
506 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 571
507 double m = (t.x + t.y + t.z + t.s); 572 double sqw = q1.s*q1.s;
508 if (m == 0) return new LSL_Vector(); 573 double sqx = q1.x*q1.x;
509 double n = 2 * (r.y * r.s + r.x * r.z); 574 double sqy = q1.z*q1.z;
510 double p = m * m - n * n; 575 double sqz = q1.y*q1.y;
511 if (p > 0) 576 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
512 return new LSL_Vector(NormalizeAngle(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s))), 577 double test = q1.x*q1.z + q1.y*q1.s;
513 NormalizeAngle(Math.Atan2(n, Math.Sqrt(p))), 578 if (test > 0.4999*unit) { // singularity at north pole
514 NormalizeAngle(Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s)))); 579 eul.z = 2 * Math.Atan2(q1.x,q1.s);
515 else if (n > 0) 580 eul.y = Math.PI/2;
516 return new LSL_Vector(0.0, Math.PI * 0.5, NormalizeAngle(Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z))); 581 eul.x = 0;
517 else 582 return eul;
518 return new LSL_Vector(0.0, -Math.PI * 0.5, NormalizeAngle(Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z))); 583 }
584 if (test < -0.4999*unit) { // singularity at south pole
585 eul.z = -2 * Math.Atan2(q1.x,q1.s);
586 eul.y = -Math.PI/2;
587 eul.x = 0;
588 return eul;
589 }
590 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
591 eul.y = Math.Asin(2*test/unit);
592 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
593 return eul;
519 } 594 }
520 595
521 /* From wiki: 596 /* From wiki:
@@ -740,53 +815,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
740 815
741 // This method mimics the 180 errors found in SL 816 // This method mimics the 180 errors found in SL
742 // See www.euclideanspace.com... angleBetween 817 // See www.euclideanspace.com... angleBetween
743 LSL_Vector vec_a = a; 818 LSL_Vector vec_a = a;
744 LSL_Vector vec_b = b; 819 LSL_Vector vec_b = b;
745 820
746 // Eliminate zero length 821 // Eliminate zero length
747 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a); 822 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
748 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b); 823 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
749 if (vec_a_mag < 0.00001 || 824 if (vec_a_mag < 0.00001 ||
750 vec_b_mag < 0.00001) 825 vec_b_mag < 0.00001)
751 { 826 {
752 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 827 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
753 } 828 }
754 829
755 // Normalize 830 // Normalize
756 vec_a = llVecNorm(vec_a); 831 vec_a = llVecNorm(vec_a);
757 vec_b = llVecNorm(vec_b); 832 vec_b = llVecNorm(vec_b);
758 833
759 // Calculate axis and rotation angle 834 // Calculate axis and rotation angle
760 LSL_Vector axis = vec_a % vec_b; 835 LSL_Vector axis = vec_a % vec_b;
761 LSL_Float cos_theta = vec_a * vec_b; 836 LSL_Float cos_theta = vec_a * vec_b;
762 837
763 // Check if parallel 838 // Check if parallel
764 if (cos_theta > 0.99999) 839 if (cos_theta > 0.99999)
765 { 840 {
766 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 841 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
767 } 842 }
768 843
769 // Check if anti-parallel 844 // Check if anti-parallel
770 else if (cos_theta < -0.99999) 845 else if (cos_theta < -0.99999)
771 { 846 {
772 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a); 847 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
773 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0); 848 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
774 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0); 849 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
775 } 850 }
776 else // other rotation 851 else // other rotation
777 { 852 {
778 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f; 853 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
779 axis = llVecNorm(axis); 854 axis = llVecNorm(axis);
780 double x, y, z, s, t; 855 double x, y, z, s, t;
781 s = Math.Cos(theta); 856 s = Math.Cos(theta);
782 t = Math.Sin(theta); 857 t = Math.Sin(theta);
783 x = axis.x * t; 858 x = axis.x * t;
784 y = axis.y * t; 859 y = axis.y * t;
785 z = axis.z * t; 860 z = axis.z * t;
786 return new LSL_Rotation(x,y,z,s); 861 return new LSL_Rotation(x,y,z,s);
787 } 862 }
788 } 863 }
789 864
790 public void llWhisper(int channelID, string text) 865 public void llWhisper(int channelID, string text)
791 { 866 {
792 m_host.AddScriptLPS(1); 867 m_host.AddScriptLPS(1);
@@ -806,6 +881,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
806 { 881 {
807 m_host.AddScriptLPS(1); 882 m_host.AddScriptLPS(1);
808 883
884 if (channelID == 0)
885 m_SayShoutCount++;
886
887 if (m_SayShoutCount >= 11)
888 ScriptSleep(2000);
889
809 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 890 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
810 { 891 {
811 Console.WriteLine(text); 892 Console.WriteLine(text);
@@ -828,6 +909,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
828 { 909 {
829 m_host.AddScriptLPS(1); 910 m_host.AddScriptLPS(1);
830 911
912 if (channelID == 0)
913 m_SayShoutCount++;
914
915 if (m_SayShoutCount >= 11)
916 ScriptSleep(2000);
917
831 if (text.Length > 1023) 918 if (text.Length > 1023)
832 text = text.Substring(0, 1023); 919 text = text.Substring(0, 1023);
833 920
@@ -857,6 +944,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
857 wComm.DeliverMessage(ChatTypeEnum.Region, channelID, m_host.Name, m_host.UUID, text); 944 wComm.DeliverMessage(ChatTypeEnum.Region, channelID, m_host.Name, m_host.UUID, text);
858 } 945 }
859 946
947 public void llRegionSayTo(string target, int channel, string msg)
948 {
949 string error = String.Empty;
950
951 if (msg.Length > 1023)
952 msg = msg.Substring(0, 1023);
953
954 m_host.AddScriptLPS(1);
955
956 UUID TargetID;
957 UUID.TryParse(target, out TargetID);
958
959 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
960 if (wComm != null)
961 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
962 LSLError(error);
963 }
964
860 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 965 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
861 { 966 {
862 m_host.AddScriptLPS(1); 967 m_host.AddScriptLPS(1);
@@ -912,10 +1017,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
912 public string resolveName(UUID objecUUID) 1017 public string resolveName(UUID objecUUID)
913 { 1018 {
914 // try avatar username surname 1019 // try avatar username surname
915 CachedUserInfo profile = World.CommsManager.UserProfileCacheService.GetUserDetails(objecUUID); 1020 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, objecUUID);
916 if (profile != null && profile.UserProfile != null) 1021 if (account != null)
917 { 1022 {
918 string avatarname = profile.UserProfile.FirstName + " " + profile.UserProfile.SurName; 1023 string avatarname = account.Name;
919 return avatarname; 1024 return avatarname;
920 } 1025 }
921 // try an scene object 1026 // try an scene object
@@ -1114,7 +1219,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1114 public virtual void llDie() 1219 public virtual void llDie()
1115 { 1220 {
1116 m_host.AddScriptLPS(1); 1221 m_host.AddScriptLPS(1);
1117 if (!m_host.IsAttachment) throw new SelfDeleteException(); 1222 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1118 } 1223 }
1119 1224
1120 public LSL_Float llGround(LSL_Vector offset) 1225 public LSL_Float llGround(LSL_Vector offset)
@@ -1198,10 +1303,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1198 if (value != 0) 1303 if (value != 0)
1199 { 1304 {
1200 SceneObjectGroup group = m_host.ParentGroup; 1305 SceneObjectGroup group = m_host.ParentGroup;
1201 if (group == null)
1202 return;
1203 bool allow = true; 1306 bool allow = true;
1204 foreach (SceneObjectPart part in group.Children.Values) 1307
1308 foreach (SceneObjectPart part in group.Parts)
1205 { 1309 {
1206 if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys) 1310 if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys)
1207 { 1311 {
@@ -1212,18 +1316,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1212 1316
1213 if (!allow) 1317 if (!allow)
1214 return; 1318 return;
1319
1215 m_host.ScriptSetPhysicsStatus(true); 1320 m_host.ScriptSetPhysicsStatus(true);
1216 } 1321 }
1217 else 1322 else
1323 {
1218 m_host.ScriptSetPhysicsStatus(false); 1324 m_host.ScriptSetPhysicsStatus(false);
1325 }
1219 } 1326 }
1220 1327
1221 if ((status & ScriptBaseClass.STATUS_PHANTOM) == ScriptBaseClass.STATUS_PHANTOM) 1328 if ((status & ScriptBaseClass.STATUS_PHANTOM) == ScriptBaseClass.STATUS_PHANTOM)
1222 { 1329 {
1223 if (value != 0) 1330 m_host.ParentGroup.ScriptSetPhantomStatus(value != 0);
1224 m_host.ScriptSetPhantomStatus(true);
1225 else
1226 m_host.ScriptSetPhantomStatus(false);
1227 } 1331 }
1228 1332
1229 if ((status & ScriptBaseClass.STATUS_CAST_SHADOWS) == ScriptBaseClass.STATUS_CAST_SHADOWS) 1333 if ((status & ScriptBaseClass.STATUS_CAST_SHADOWS) == ScriptBaseClass.STATUS_CAST_SHADOWS)
@@ -1365,8 +1469,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1365 protected void SetScale(SceneObjectPart part, LSL_Vector scale) 1469 protected void SetScale(SceneObjectPart part, LSL_Vector scale)
1366 { 1470 {
1367 // TODO: this needs to trigger a persistance save as well 1471 // TODO: this needs to trigger a persistance save as well
1368 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 1472 if (part == null || part.ParentGroup.IsDeleted)
1369 return; 1473 return;
1474
1370 if (scale.x < 0.01) 1475 if (scale.x < 0.01)
1371 scale.x = 0.01; 1476 scale.x = 0.01;
1372 if (scale.y < 0.01) 1477 if (scale.y < 0.01)
@@ -1409,7 +1514,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1409 { 1514 {
1410 m_host.AddScriptLPS(1); 1515 m_host.AddScriptLPS(1);
1411 m_host.ClickAction = (byte)action; 1516 m_host.ClickAction = (byte)action;
1412 if (m_host.ParentGroup != null) m_host.ParentGroup.HasGroupChanged = true; 1517 m_host.ParentGroup.HasGroupChanged = true;
1413 m_host.ScheduleFullUpdate(); 1518 m_host.ScheduleFullUpdate();
1414 return; 1519 return;
1415 } 1520 }
@@ -1435,7 +1540,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1435 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f); 1540 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1436 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f); 1541 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1437 tex.FaceTextures[face].RGBA = texcolor; 1542 tex.FaceTextures[face].RGBA = texcolor;
1438 part.UpdateTexture(tex); 1543 part.UpdateTextureEntry(tex.GetBytes());
1439 return; 1544 return;
1440 } 1545 }
1441 else if (face == ScriptBaseClass.ALL_SIDES) 1546 else if (face == ScriptBaseClass.ALL_SIDES)
@@ -1456,13 +1561,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1456 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f); 1561 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1457 tex.DefaultTexture.RGBA = texcolor; 1562 tex.DefaultTexture.RGBA = texcolor;
1458 } 1563 }
1459 part.UpdateTexture(tex); 1564 part.UpdateTextureEntry(tex.GetBytes());
1460 return; 1565 return;
1461 } 1566 }
1462 1567
1463 if (face == ScriptBaseClass.ALL_SIDES) 1568 if (face == ScriptBaseClass.ALL_SIDES)
1464 face = SceneObjectPart.ALL_SIDES; 1569 face = SceneObjectPart.ALL_SIDES;
1465 1570
1466 m_host.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 1571 m_host.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
1467 } 1572 }
1468 1573
@@ -1481,7 +1586,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1481 { 1586 {
1482 tex.CreateFace((uint) face); 1587 tex.CreateFace((uint) face);
1483 tex.FaceTextures[face].TexMapType = textype; 1588 tex.FaceTextures[face].TexMapType = textype;
1484 part.UpdateTexture(tex); 1589 part.UpdateTextureEntry(tex.GetBytes());
1485 return; 1590 return;
1486 } 1591 }
1487 else if (face == ScriptBaseClass.ALL_SIDES) 1592 else if (face == ScriptBaseClass.ALL_SIDES)
@@ -1494,7 +1599,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1494 } 1599 }
1495 tex.DefaultTexture.TexMapType = textype; 1600 tex.DefaultTexture.TexMapType = textype;
1496 } 1601 }
1497 part.UpdateTexture(tex); 1602 part.UpdateTextureEntry(tex.GetBytes());
1498 return; 1603 return;
1499 } 1604 }
1500 } 1605 }
@@ -1509,7 +1614,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1509 { 1614 {
1510 tex.CreateFace((uint) face); 1615 tex.CreateFace((uint) face);
1511 tex.FaceTextures[face].Glow = glow; 1616 tex.FaceTextures[face].Glow = glow;
1512 part.UpdateTexture(tex); 1617 part.UpdateTextureEntry(tex.GetBytes());
1513 return; 1618 return;
1514 } 1619 }
1515 else if (face == ScriptBaseClass.ALL_SIDES) 1620 else if (face == ScriptBaseClass.ALL_SIDES)
@@ -1522,7 +1627,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1522 } 1627 }
1523 tex.DefaultTexture.Glow = glow; 1628 tex.DefaultTexture.Glow = glow;
1524 } 1629 }
1525 part.UpdateTexture(tex); 1630 part.UpdateTextureEntry(tex.GetBytes());
1526 return; 1631 return;
1527 } 1632 }
1528 } 1633 }
@@ -1559,7 +1664,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1559 tex.CreateFace((uint) face); 1664 tex.CreateFace((uint) face);
1560 tex.FaceTextures[face].Shiny = sval; 1665 tex.FaceTextures[face].Shiny = sval;
1561 tex.FaceTextures[face].Bump = bump; 1666 tex.FaceTextures[face].Bump = bump;
1562 part.UpdateTexture(tex); 1667 part.UpdateTextureEntry(tex.GetBytes());
1563 return; 1668 return;
1564 } 1669 }
1565 else if (face == ScriptBaseClass.ALL_SIDES) 1670 else if (face == ScriptBaseClass.ALL_SIDES)
@@ -1574,7 +1679,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1574 tex.DefaultTexture.Shiny = sval; 1679 tex.DefaultTexture.Shiny = sval;
1575 tex.DefaultTexture.Bump = bump; 1680 tex.DefaultTexture.Bump = bump;
1576 } 1681 }
1577 part.UpdateTexture(tex); 1682 part.UpdateTextureEntry(tex.GetBytes());
1578 return; 1683 return;
1579 } 1684 }
1580 } 1685 }
@@ -1589,7 +1694,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1589 { 1694 {
1590 tex.CreateFace((uint) face); 1695 tex.CreateFace((uint) face);
1591 tex.FaceTextures[face].Fullbright = bright; 1696 tex.FaceTextures[face].Fullbright = bright;
1592 part.UpdateTexture(tex); 1697 part.UpdateTextureEntry(tex.GetBytes());
1593 return; 1698 return;
1594 } 1699 }
1595 else if (face == ScriptBaseClass.ALL_SIDES) 1700 else if (face == ScriptBaseClass.ALL_SIDES)
@@ -1602,7 +1707,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1602 } 1707 }
1603 } 1708 }
1604 tex.DefaultTexture.Fullbright = bright; 1709 tex.DefaultTexture.Fullbright = bright;
1605 part.UpdateTexture(tex); 1710 part.UpdateTextureEntry(tex.GetBytes());
1606 return; 1711 return;
1607 } 1712 }
1608 } 1713 }
@@ -1644,9 +1749,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1644 m_host.AddScriptLPS(1); 1749 m_host.AddScriptLPS(1);
1645 1750
1646 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1751 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1647 1752 if (parts.Count > 0)
1648 foreach (SceneObjectPart part in parts) 1753 {
1649 SetAlpha(part, alpha, face); 1754 try
1755 {
1756 parts[0].ParentGroup.areUpdatesSuspended = true;
1757 foreach (SceneObjectPart part in parts)
1758 SetAlpha(part, alpha, face);
1759 }
1760 finally
1761 {
1762 parts[0].ParentGroup.areUpdatesSuspended = false;
1763 }
1764 }
1650 } 1765 }
1651 1766
1652 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1767 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
@@ -1661,7 +1776,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1661 texcolor = tex.CreateFace((uint)face).RGBA; 1776 texcolor = tex.CreateFace((uint)face).RGBA;
1662 texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f); 1777 texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f);
1663 tex.FaceTextures[face].RGBA = texcolor; 1778 tex.FaceTextures[face].RGBA = texcolor;
1664 part.UpdateTexture(tex); 1779 part.UpdateTextureEntry(tex.GetBytes());
1665 return; 1780 return;
1666 } 1781 }
1667 else if (face == ScriptBaseClass.ALL_SIDES) 1782 else if (face == ScriptBaseClass.ALL_SIDES)
@@ -1675,10 +1790,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1675 tex.FaceTextures[i].RGBA = texcolor; 1790 tex.FaceTextures[i].RGBA = texcolor;
1676 } 1791 }
1677 } 1792 }
1678 texcolor = tex.DefaultTexture.RGBA; 1793
1679 texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f); 1794 // In some cases, the default texture can be null, eg when every face
1680 tex.DefaultTexture.RGBA = texcolor; 1795 // has a unique texture
1681 part.UpdateTexture(tex); 1796 if (tex.DefaultTexture != null)
1797 {
1798 texcolor = tex.DefaultTexture.RGBA;
1799 texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f);
1800 tex.DefaultTexture.RGBA = texcolor;
1801 }
1802
1803 part.UpdateTextureEntry(tex.GetBytes());
1682 return; 1804 return;
1683 } 1805 }
1684 } 1806 }
@@ -1705,7 +1827,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1705 if (flexi) 1827 if (flexi)
1706 { 1828 {
1707 part.Shape.FlexiEntry = true; // this setting flexi true isn't working, but the below parameters do 1829 part.Shape.FlexiEntry = true; // this setting flexi true isn't working, but the below parameters do
1708 // work once the prim is already flexi 1830 // work once the prim is already flexi
1709 part.Shape.FlexiSoftness = softness; 1831 part.Shape.FlexiSoftness = softness;
1710 part.Shape.FlexiGravity = gravity; 1832 part.Shape.FlexiGravity = gravity;
1711 part.Shape.FlexiDrag = friction; 1833 part.Shape.FlexiDrag = friction;
@@ -1715,10 +1837,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1715 part.Shape.FlexiForceY = (float)Force.y; 1837 part.Shape.FlexiForceY = (float)Force.y;
1716 part.Shape.FlexiForceZ = (float)Force.z; 1838 part.Shape.FlexiForceZ = (float)Force.z;
1717 part.Shape.PathCurve = 0x80; 1839 part.Shape.PathCurve = 0x80;
1840 part.ParentGroup.HasGroupChanged = true;
1841 part.ScheduleFullUpdate();
1718 } 1842 }
1719
1720 part.ParentGroup.HasGroupChanged = true;
1721 part.ScheduleFullUpdate();
1722 } 1843 }
1723 1844
1724 /// <summary> 1845 /// <summary>
@@ -1811,10 +1932,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1811 m_host.AddScriptLPS(1); 1932 m_host.AddScriptLPS(1);
1812 1933
1813 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1934 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1814 1935 if (parts.Count > 0)
1815 foreach (SceneObjectPart part in parts) 1936 {
1816 SetTexture(part, texture, face); 1937 try
1817 1938 {
1939 parts[0].ParentGroup.areUpdatesSuspended = true;
1940 foreach (SceneObjectPart part in parts)
1941 SetTexture(part, texture, face);
1942 }
1943 finally
1944 {
1945 parts[0].ParentGroup.areUpdatesSuspended = false;
1946 }
1947 }
1818 ScriptSleep(200); 1948 ScriptSleep(200);
1819 } 1949 }
1820 1950
@@ -1823,15 +1953,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1823 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 1953 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1824 return; 1954 return;
1825 1955
1826 UUID textureID=new UUID(); 1956 UUID textureID = new UUID();
1827 1957
1828 if (!UUID.TryParse(texture, out textureID)) 1958 textureID = InventoryKey(texture, (int)AssetType.Texture);
1829 { 1959 if (textureID == UUID.Zero)
1830 textureID=InventoryKey(texture, (int)AssetType.Texture); 1960 {
1831 } 1961 if (!UUID.TryParse(texture, out textureID))
1832 1962 return;
1833 if (textureID == UUID.Zero) 1963 }
1834 return;
1835 1964
1836 Primitive.TextureEntry tex = part.Shape.Textures; 1965 Primitive.TextureEntry tex = part.Shape.Textures;
1837 1966
@@ -1840,7 +1969,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1840 Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); 1969 Primitive.TextureEntryFace texface = tex.CreateFace((uint)face);
1841 texface.TextureID = textureID; 1970 texface.TextureID = textureID;
1842 tex.FaceTextures[face] = texface; 1971 tex.FaceTextures[face] = texface;
1843 part.UpdateTexture(tex); 1972 part.UpdateTextureEntry(tex.GetBytes());
1844 return; 1973 return;
1845 } 1974 }
1846 else if (face == ScriptBaseClass.ALL_SIDES) 1975 else if (face == ScriptBaseClass.ALL_SIDES)
@@ -1853,7 +1982,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1853 } 1982 }
1854 } 1983 }
1855 tex.DefaultTexture.TextureID = textureID; 1984 tex.DefaultTexture.TextureID = textureID;
1856 part.UpdateTexture(tex); 1985 part.UpdateTextureEntry(tex.GetBytes());
1857 return; 1986 return;
1858 } 1987 }
1859 } 1988 }
@@ -1878,7 +2007,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1878 texface.RepeatU = (float)u; 2007 texface.RepeatU = (float)u;
1879 texface.RepeatV = (float)v; 2008 texface.RepeatV = (float)v;
1880 tex.FaceTextures[face] = texface; 2009 tex.FaceTextures[face] = texface;
1881 part.UpdateTexture(tex); 2010 part.UpdateTextureEntry(tex.GetBytes());
1882 return; 2011 return;
1883 } 2012 }
1884 if (face == ScriptBaseClass.ALL_SIDES) 2013 if (face == ScriptBaseClass.ALL_SIDES)
@@ -1893,7 +2022,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1893 } 2022 }
1894 tex.DefaultTexture.RepeatU = (float)u; 2023 tex.DefaultTexture.RepeatU = (float)u;
1895 tex.DefaultTexture.RepeatV = (float)v; 2024 tex.DefaultTexture.RepeatV = (float)v;
1896 part.UpdateTexture(tex); 2025 part.UpdateTextureEntry(tex.GetBytes());
1897 return; 2026 return;
1898 } 2027 }
1899 } 2028 }
@@ -1917,7 +2046,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1917 texface.OffsetU = (float)u; 2046 texface.OffsetU = (float)u;
1918 texface.OffsetV = (float)v; 2047 texface.OffsetV = (float)v;
1919 tex.FaceTextures[face] = texface; 2048 tex.FaceTextures[face] = texface;
1920 part.UpdateTexture(tex); 2049 part.UpdateTextureEntry(tex.GetBytes());
1921 return; 2050 return;
1922 } 2051 }
1923 if (face == ScriptBaseClass.ALL_SIDES) 2052 if (face == ScriptBaseClass.ALL_SIDES)
@@ -1932,7 +2061,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1932 } 2061 }
1933 tex.DefaultTexture.OffsetU = (float)u; 2062 tex.DefaultTexture.OffsetU = (float)u;
1934 tex.DefaultTexture.OffsetV = (float)v; 2063 tex.DefaultTexture.OffsetV = (float)v;
1935 part.UpdateTexture(tex); 2064 part.UpdateTextureEntry(tex.GetBytes());
1936 return; 2065 return;
1937 } 2066 }
1938 } 2067 }
@@ -1955,7 +2084,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1955 Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); 2084 Primitive.TextureEntryFace texface = tex.CreateFace((uint)face);
1956 texface.Rotation = (float)rotation; 2085 texface.Rotation = (float)rotation;
1957 tex.FaceTextures[face] = texface; 2086 tex.FaceTextures[face] = texface;
1958 part.UpdateTexture(tex); 2087 part.UpdateTextureEntry(tex.GetBytes());
1959 return; 2088 return;
1960 } 2089 }
1961 if (face == ScriptBaseClass.ALL_SIDES) 2090 if (face == ScriptBaseClass.ALL_SIDES)
@@ -1968,7 +2097,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1968 } 2097 }
1969 } 2098 }
1970 tex.DefaultTexture.Rotation = (float)rotation; 2099 tex.DefaultTexture.Rotation = (float)rotation;
1971 part.UpdateTexture(tex); 2100 part.UpdateTextureEntry(tex.GetBytes());
1972 return; 2101 return;
1973 } 2102 }
1974 } 2103 }
@@ -1986,15 +2115,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1986 { 2115 {
1987 face = 0; 2116 face = 0;
1988 } 2117 }
2118
1989 if (face >= 0 && face < GetNumberOfSides(part)) 2119 if (face >= 0 && face < GetNumberOfSides(part))
1990 { 2120 {
1991 Primitive.TextureEntryFace texface; 2121 Primitive.TextureEntryFace texface;
1992 texface = tex.GetFace((uint)face); 2122 texface = tex.GetFace((uint)face);
1993 return texface.TextureID.ToString(); 2123 string texture = texface.TextureID.ToString();
2124
2125 lock (part.TaskInventory)
2126 {
2127 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in part.TaskInventory)
2128 {
2129 if (inv.Value.AssetID == texface.TextureID)
2130 {
2131 texture = inv.Value.Name.ToString();
2132 break;
2133 }
2134 }
2135 }
2136
2137 return texture;
1994 } 2138 }
1995 else 2139 else
1996 { 2140 {
1997 return String.Empty; 2141 return UUID.Zero.ToString();
1998 } 2142 }
1999 } 2143 }
2000 2144
@@ -2017,42 +2161,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2017 return end; 2161 return end;
2018 } 2162 }
2019 2163
2020 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2164 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos)
2021 { 2165 {
2022 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 2166 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2023 return; 2167 return fromPos;
2024 2168
2025 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2169 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
2026 LSL_Vector currentPos = llGetLocalPos(); 2170
2027 2171
2028 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); 2172 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2029 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); 2173 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2030 2174
2031 if (part.ParentGroup == null) 2175 if (part.ParentGroup.RootPart == part)
2032 { 2176 {
2033 if ((targetPos.z < ground) && disable_underground_movement) 2177 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2034 targetPos.z = ground; 2178 targetPos.z = ground;
2035 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos);
2036 part.UpdateOffSet(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
2037 } 2179 }
2038 else if (part.ParentGroup.RootPart == part) 2180 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos);
2181
2182 return real_vec;
2183 }
2184
2185 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
2186 {
2187 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2188 return;
2189
2190 LSL_Vector currentPos = GetPartLocalPos(part);
2191 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2192
2193 if (part.ParentGroup.RootPart == part)
2039 { 2194 {
2040 if ((targetPos.z < ground) && disable_underground_movement)
2041 targetPos.z = ground;
2042 SceneObjectGroup parent = part.ParentGroup; 2195 SceneObjectGroup parent = part.ParentGroup;
2043 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2196 parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z));
2044 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
2045 } 2197 }
2046 else 2198 else
2047 { 2199 {
2048 //it's late... i think this is right ? 2200 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2049 if (llVecDist(new LSL_Vector(0,0,0), targetPos) <= 10.0f) 2201 SceneObjectGroup parent = part.ParentGroup;
2050 { 2202 parent.HasGroupChanged = true;
2051 part.OffsetPosition = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z); 2203 parent.ScheduleGroupForTerseUpdate();
2052 SceneObjectGroup parent = part.ParentGroup;
2053 parent.HasGroupChanged = true;
2054 parent.ScheduleGroupForTerseUpdate();
2055 }
2056 } 2204 }
2057 } 2205 }
2058 2206
@@ -2066,17 +2214,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2066 public LSL_Vector llGetLocalPos() 2214 public LSL_Vector llGetLocalPos()
2067 { 2215 {
2068 m_host.AddScriptLPS(1); 2216 m_host.AddScriptLPS(1);
2069 if (m_host.ParentID != 0) 2217 return GetPartLocalPos(m_host);
2218 }
2219
2220 protected LSL_Vector GetPartLocalPos(SceneObjectPart part)
2221 {
2222 m_host.AddScriptLPS(1);
2223 if (part.ParentID == 0)
2070 { 2224 {
2071 return new LSL_Vector(m_host.OffsetPosition.X, 2225 return new LSL_Vector(part.AbsolutePosition.X,
2072 m_host.OffsetPosition.Y, 2226 part.AbsolutePosition.Y,
2073 m_host.OffsetPosition.Z); 2227 part.AbsolutePosition.Z);
2074 } 2228 }
2075 else 2229 else
2076 { 2230 {
2077 return new LSL_Vector(m_host.AbsolutePosition.X, 2231 if (m_host.IsRoot)
2078 m_host.AbsolutePosition.Y, 2232 {
2079 m_host.AbsolutePosition.Z); 2233 return new LSL_Vector(m_host.AttachedPos.X,
2234 m_host.AttachedPos.Y,
2235 m_host.AttachedPos.Z);
2236 }
2237 else
2238 {
2239 return new LSL_Vector(part.OffsetPosition.X,
2240 part.OffsetPosition.Y,
2241 part.OffsetPosition.Z);
2242 }
2080 } 2243 }
2081 } 2244 }
2082 2245
@@ -2085,22 +2248,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2085 m_host.AddScriptLPS(1); 2248 m_host.AddScriptLPS(1);
2086 2249
2087 // try to let this work as in SL... 2250 // try to let this work as in SL...
2088 if (m_host.ParentID == 0) 2251 if (m_host.LinkNum < 2)
2089 { 2252 {
2090 // special case: If we are root, rotate complete SOG to new rotation 2253 // Special case: If we are root, rotate complete SOG to new
2254 // rotation.
2255 // We are root if the link number is 0 (single prim) or 1
2256 // (root prim). ParentID may be nonzero in attachments and
2257 // using it would cause attachments and HUDs to rotate
2258 // to the wrong positions.
2091 SetRot(m_host, Rot2Quaternion(rot)); 2259 SetRot(m_host, Rot2Quaternion(rot));
2092 } 2260 }
2093 else 2261 else
2094 { 2262 {
2095 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 2263 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
2096 SceneObjectGroup group = m_host.ParentGroup; 2264 SceneObjectPart rootPart = m_host.ParentGroup.RootPart;
2097 if (group != null) // a bit paranoid, maybe 2265 if (rootPart != null) // better safe than sorry
2098 { 2266 {
2099 SceneObjectPart rootPart = group.RootPart; 2267 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot));
2100 if (rootPart != null) // again, better safe than sorry
2101 {
2102 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot));
2103 }
2104 } 2268 }
2105 } 2269 }
2106 2270
@@ -2124,7 +2288,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2124 2288
2125//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2289//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type
2126// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2290// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition;
2127 2291
2128 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line 2292 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2129 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt 2293 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2130 // It's perfectly okay when the object is not an active physical body though. 2294 // It's perfectly okay when the object is not an active physical body though.
@@ -2149,6 +2313,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2149 { 2313 {
2150 return llGetRootRotation(); 2314 return llGetRootRotation();
2151 } 2315 }
2316
2152 m_host.AddScriptLPS(1); 2317 m_host.AddScriptLPS(1);
2153 Quaternion q = m_host.GetWorldRotation(); 2318 Quaternion q = m_host.GetWorldRotation();
2154 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2319 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
@@ -2159,9 +2324,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2159 Quaternion q; 2324 Quaternion q;
2160 if (part.LinkNum == 0 || part.LinkNum == 1) // unlinked or root prim 2325 if (part.LinkNum == 0 || part.LinkNum == 1) // unlinked or root prim
2161 { 2326 {
2162 if (part.ParentGroup.RootPart.AttachmentPoint != 0) 2327 if (part.ParentGroup.AttachmentPoint != 0)
2163 { 2328 {
2164 ScenePresence avatar = World.GetScenePresence(part.AttachedAvatar); 2329 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2165 if (avatar != null) 2330 if (avatar != null)
2166 { 2331 {
2167 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 2332 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
@@ -2190,15 +2355,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2190 { 2355 {
2191 m_host.AddScriptLPS(1); 2356 m_host.AddScriptLPS(1);
2192 2357
2193 if (m_host.ParentGroup != null) 2358 if (!m_host.ParentGroup.IsDeleted)
2194 { 2359 {
2195 if (!m_host.ParentGroup.IsDeleted) 2360 if (local != 0)
2196 { 2361 force *= llGetRot();
2197 if (local != 0)
2198 force *= llGetRot();
2199 2362
2200 m_host.ParentGroup.RootPart.SetForce(new Vector3((float)force.x, (float)force.y, (float)force.z)); 2363 m_host.ParentGroup.RootPart.SetForce(new Vector3((float)force.x, (float)force.y, (float)force.z));
2201 }
2202 } 2364 }
2203 } 2365 }
2204 2366
@@ -2208,15 +2370,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2208 2370
2209 m_host.AddScriptLPS(1); 2371 m_host.AddScriptLPS(1);
2210 2372
2211 if (m_host.ParentGroup != null) 2373 if (!m_host.ParentGroup.IsDeleted)
2212 { 2374 {
2213 if (!m_host.ParentGroup.IsDeleted) 2375 Vector3 tmpForce = m_host.ParentGroup.RootPart.GetForce();
2214 { 2376 force.x = tmpForce.X;
2215 Vector3 tmpForce = m_host.ParentGroup.RootPart.GetForce(); 2377 force.y = tmpForce.Y;
2216 force.x = tmpForce.X; 2378 force.z = tmpForce.Z;
2217 force.y = tmpForce.Y;
2218 force.z = tmpForce.Z;
2219 }
2220 } 2379 }
2221 2380
2222 return force; 2381 return force;
@@ -2225,25 +2384,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2225 public LSL_Integer llTarget(LSL_Vector position, double range) 2384 public LSL_Integer llTarget(LSL_Vector position, double range)
2226 { 2385 {
2227 m_host.AddScriptLPS(1); 2386 m_host.AddScriptLPS(1);
2228 return m_host.registerTargetWaypoint(new Vector3((float)position.x, (float)position.y, (float)position.z), (float)range); 2387 return m_host.ParentGroup.registerTargetWaypoint(
2388 new Vector3((float)position.x, (float)position.y, (float)position.z), (float)range);
2229 } 2389 }
2230 2390
2231 public void llTargetRemove(int number) 2391 public void llTargetRemove(int number)
2232 { 2392 {
2233 m_host.AddScriptLPS(1); 2393 m_host.AddScriptLPS(1);
2234 m_host.unregisterTargetWaypoint(number); 2394 m_host.ParentGroup.unregisterTargetWaypoint(number);
2235 } 2395 }
2236 2396
2237 public LSL_Integer llRotTarget(LSL_Rotation rot, double error) 2397 public LSL_Integer llRotTarget(LSL_Rotation rot, double error)
2238 { 2398 {
2239 m_host.AddScriptLPS(1); 2399 m_host.AddScriptLPS(1);
2240 return m_host.registerRotTargetWaypoint(new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s), (float)error); 2400 return m_host.ParentGroup.registerRotTargetWaypoint(
2401 new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s), (float)error);
2241 } 2402 }
2242 2403
2243 public void llRotTargetRemove(int number) 2404 public void llRotTargetRemove(int number)
2244 { 2405 {
2245 m_host.AddScriptLPS(1); 2406 m_host.AddScriptLPS(1);
2246 m_host.unregisterRotTargetWaypoint(number); 2407 m_host.ParentGroup.unregisterRotTargetWaypoint(number);
2247 } 2408 }
2248 2409
2249 public void llMoveToTarget(LSL_Vector target, double tau) 2410 public void llMoveToTarget(LSL_Vector target, double tau)
@@ -2286,7 +2447,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2286 public LSL_Vector llGetTorque() 2447 public LSL_Vector llGetTorque()
2287 { 2448 {
2288 m_host.AddScriptLPS(1); 2449 m_host.AddScriptLPS(1);
2289 Vector3 torque = m_host.GetTorque(); 2450 Vector3 torque = m_host.ParentGroup.GetTorque();
2290 return new LSL_Vector(torque.X,torque.Y,torque.Z); 2451 return new LSL_Vector(torque.X,torque.Y,torque.Z);
2291 } 2452 }
2292 2453
@@ -2300,7 +2461,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2300 public LSL_Vector llGetVel() 2461 public LSL_Vector llGetVel()
2301 { 2462 {
2302 m_host.AddScriptLPS(1); 2463 m_host.AddScriptLPS(1);
2303 return new LSL_Vector(m_host.Velocity.X, m_host.Velocity.Y, m_host.Velocity.Z); 2464
2465 Vector3 vel;
2466
2467 if (m_host.ParentGroup.IsAttachment)
2468 {
2469 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2470 vel = avatar.Velocity;
2471 }
2472 else
2473 {
2474 vel = m_host.Velocity;
2475 }
2476
2477 return new LSL_Vector(vel.X, vel.Y, vel.Z);
2304 } 2478 }
2305 2479
2306 public LSL_Vector llGetAccel() 2480 public LSL_Vector llGetAccel()
@@ -2500,10 +2674,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2500 /// indices, and the tolerance for out-of-bound values, makes 2674 /// indices, and the tolerance for out-of-bound values, makes
2501 /// this more complicated than it might otherwise seem. 2675 /// this more complicated than it might otherwise seem.
2502 /// </summary> 2676 /// </summary>
2503
2504 public LSL_String llGetSubString(string src, int start, int end) 2677 public LSL_String llGetSubString(string src, int start, int end)
2505 { 2678 {
2506
2507 m_host.AddScriptLPS(1); 2679 m_host.AddScriptLPS(1);
2508 2680
2509 // Normalize indices (if negative). 2681 // Normalize indices (if negative).
@@ -2596,10 +2768,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2596 /// negative (indicating end-relative) and may be inverted, 2768 /// negative (indicating end-relative) and may be inverted,
2597 /// i.e. end < start. 2769 /// i.e. end < start.
2598 /// </summary> 2770 /// </summary>
2599
2600 public LSL_String llDeleteSubString(string src, int start, int end) 2771 public LSL_String llDeleteSubString(string src, int start, int end)
2601 { 2772 {
2602
2603 m_host.AddScriptLPS(1); 2773 m_host.AddScriptLPS(1);
2604 2774
2605 // Normalize indices (if negative). 2775 // Normalize indices (if negative).
@@ -2679,10 +2849,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2679 /// which case it is end-relative. The index may exceed either 2849 /// which case it is end-relative. The index may exceed either
2680 /// string bound, with the result being a concatenation. 2850 /// string bound, with the result being a concatenation.
2681 /// </summary> 2851 /// </summary>
2682
2683 public LSL_String llInsertString(string dest, int index, string src) 2852 public LSL_String llInsertString(string dest, int index, string src)
2684 { 2853 {
2685
2686 m_host.AddScriptLPS(1); 2854 m_host.AddScriptLPS(1);
2687 2855
2688 // Normalize indices (if negative). 2856 // Normalize indices (if negative).
@@ -2840,12 +3008,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2840 // If either of these are null, then there was an unknown error. 3008 // If either of these are null, then there was an unknown error.
2841 if (new_group == null) 3009 if (new_group == null)
2842 continue; 3010 continue;
2843 if (new_group.RootPart == null)
2844 continue;
2845 3011
2846 // objects rezzed with this method are die_at_edge by default. 3012 // objects rezzed with this method are die_at_edge by default.
2847 new_group.RootPart.SetDieAtEdge(true); 3013 new_group.RootPart.SetDieAtEdge(true);
2848 3014
3015 new_group.ResumeScripts();
3016
2849 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams( 3017 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
2850 "object_rez", new Object[] { 3018 "object_rez", new Object[] {
2851 new LSL_String( 3019 new LSL_String(
@@ -2910,8 +3078,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2910 // http://bugs.meta7.com/view.php?id=28 3078 // http://bugs.meta7.com/view.php?id=28
2911 // - Tom 3079 // - Tom
2912 3080
2913 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d)); 3081 /* And the following does not do the job either. It has to be performed inside the ODE glue-code. -.- .._.
3082 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
2914 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos())); 3083 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3084 */
3085 if (m_host.PhysActor != null && !m_host.PhysActor.IsPhysical)
3086 {
3087 // Part is non-phys, convert this to a llSetRot()
3088 Vector3 tgt = new Vector3((float)target.x, (float)target.y, (float)target.z);
3089 Vector3 dir = tgt - m_host.GroupPosition;
3090 dir.Normalize();
3091 float tzrot = (float)Math.Atan2(dir.Y, dir.X);
3092 float txy = (float)Math.Sqrt((dir.X * dir.X) + (dir.Y * dir.Y));
3093 float terot = (float)Math.Atan2(-dir.Z, txy);
3094 LSL_Vector az = new LSL_Vector(0.0f, 0.0f, tzrot);
3095 LSL_Vector ae = new LSL_Vector(0.0f, terot, 0.0f);
3096 LSL_Types.Quaternion spin = llEuler2Rot(az);
3097 LSL_Types.Quaternion rot = llEuler2Rot(ae) * spin;
3098 llSetRot(rot);
3099 }
3100 else
3101 {
3102 // Physical, send the target vector to RotLookAt method inside a 'rotation', the .w -99.9 value indicates it is really a LookAt.
3103 Quaternion q = new Quaternion((float)target.x, (float)target.y, (float)target.z, -99.9f);
3104 m_host.RotLookAt(q, (float)strength, (float)damping);
3105 }
2915 3106
2916 } 3107 }
2917 3108
@@ -3047,9 +3238,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3047 { 3238 {
3048 m_host.AddScriptLPS(1); 3239 m_host.AddScriptLPS(1);
3049 3240
3050 if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3051 return;
3052
3053 TaskInventoryItem item; 3241 TaskInventoryItem item;
3054 3242
3055 m_host.TaskInventory.LockItemsForRead(true); 3243 m_host.TaskInventory.LockItemsForRead(true);
@@ -3075,9 +3263,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3075 3263
3076 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3264 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
3077 3265
3078 m_ScriptEngine.World.AttachObject(presence.ControllingClient, 3266 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3079 grp.LocalId, (uint)attachment, Quaternion.Identity, 3267 if (attachmentsModule != null)
3080 Vector3.Zero, false); 3268 attachmentsModule.AttachObject(presence, grp, (uint)attachment, false);
3081 } 3269 }
3082 } 3270 }
3083 3271
@@ -3085,7 +3273,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3085 { 3273 {
3086 m_host.AddScriptLPS(1); 3274 m_host.AddScriptLPS(1);
3087 3275
3088 if (m_host.ParentGroup.RootPart.AttachmentPoint == 0) 3276 if (m_host.ParentGroup.AttachmentPoint == 0)
3089 return; 3277 return;
3090 3278
3091 TaskInventoryItem item; 3279 TaskInventoryItem item;
@@ -3109,14 +3297,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3109 3297
3110 if ((item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0) 3298 if ((item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0)
3111 { 3299 {
3112 SceneObjectGroup grp = m_host.ParentGroup; 3300 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3113 UUID itemID = grp.GetFromItemID(); 3301 if (attachmentsModule != null)
3302 Util.FireAndForget(DetachWrapper, m_host);
3303 }
3304 }
3114 3305
3115 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3306 private void DetachWrapper(object o)
3307 {
3308 SceneObjectPart host = (SceneObjectPart)o;
3116 3309
3117 m_ScriptEngine.World.DetachSingleAttachmentToInv(itemID, 3310 SceneObjectGroup grp = host.ParentGroup;
3118 presence.ControllingClient); 3311 UUID itemID = grp.GetFromItemID();
3119 } 3312 ScenePresence presence = World.GetScenePresence(host.OwnerID);
3313
3314 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3315 if (attachmentsModule != null)
3316 attachmentsModule.DetachSingleAttachmentToInv(presence, itemID);
3120 } 3317 }
3121 3318
3122 public void llTakeCamera(string avatar) 3319 public void llTakeCamera(string avatar)
@@ -3138,13 +3335,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3138 return m_host.OwnerID.ToString(); 3335 return m_host.OwnerID.ToString();
3139 } 3336 }
3140 3337
3141 [DebuggerNonUserCode]
3142 public void llInstantMessage(string user, string message) 3338 public void llInstantMessage(string user, string message)
3143 { 3339 {
3144 UUID result; 3340 UUID result;
3145 if (!UUID.TryParse(user, out result)) 3341 if (!UUID.TryParse(user, out result))
3146 { 3342 {
3147 throw new Exception(String.Format("An invalid key of '{0} was passed to llInstantMessage", user)); 3343 ShoutError("An invalid key was passed to llInstantMessage");
3344 ScriptSleep(2000);
3148 return; 3345 return;
3149 } 3346 }
3150 3347
@@ -3170,7 +3367,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3170 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3367 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3171// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3368// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3172// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3369// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3173 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3370// DateTime dt = DateTime.UtcNow;
3371//
3372// // Ticks from UtcNow, but make it look like local. Evil, huh?
3373// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3374//
3375// try
3376// {
3377// // Convert that to the PST timezone
3378// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3379// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3380// }
3381// catch
3382// {
3383// // No logging here, as it could be VERY spammy
3384// }
3385//
3386// // And make it look local again to fool the unix time util
3387// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3388
3389 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3390
3174 //if (client != null) 3391 //if (client != null)
3175 //{ 3392 //{
3176 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3393 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3184,18 +3401,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3184 msg.message = message.Substring(0, 1024); 3401 msg.message = message.Substring(0, 1024);
3185 else 3402 else
3186 msg.message = message; 3403 msg.message = message;
3187 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3404 msg.dialog = (byte)19; // MessageFromObject
3188 msg.fromGroup = false;// fromGroup; 3405 msg.fromGroup = false;// fromGroup;
3189 msg.offline = (byte)0; //offline; 3406 msg.offline = (byte)0; //offline;
3190 msg.ParentEstateID = 0; //ParentEstateID; 3407 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3191 msg.Position = Vector3.Zero;// new Vector3(m_host.AbsolutePosition); 3408 msg.Position = new Vector3(m_host.AbsolutePosition);
3192 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3409 msg.RegionID = World.RegionInfo.RegionID.Guid;
3193 msg.binaryBucket = new byte[0];// binaryBucket; 3410 msg.binaryBucket
3411 = Util.StringToBytes256(
3412 "{0}/{1}/{2}/{3}",
3413 World.RegionInfo.RegionName,
3414 (int)Math.Floor(m_host.AbsolutePosition.X),
3415 (int)Math.Floor(m_host.AbsolutePosition.Y),
3416 (int)Math.Floor(m_host.AbsolutePosition.Z));
3194 3417
3195 if (m_TransferModule != null) 3418 if (m_TransferModule != null)
3196 { 3419 {
3197 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 3420 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
3198 } 3421 }
3422
3199 ScriptSleep(2000); 3423 ScriptSleep(2000);
3200 } 3424 }
3201 3425
@@ -3210,7 +3434,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3210 } 3434 }
3211 3435
3212 emailModule.SendEmail(m_host.UUID, address, subject, message); 3436 emailModule.SendEmail(m_host.UUID, address, subject, message);
3213 ScriptSleep(20000); 3437 ScriptSleep(15000);
3214 } 3438 }
3215 3439
3216 public void llGetNextEmail(string address, string subject) 3440 public void llGetNextEmail(string address, string subject)
@@ -3250,12 +3474,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3250 public void llSetBuoyancy(double buoyancy) 3474 public void llSetBuoyancy(double buoyancy)
3251 { 3475 {
3252 m_host.AddScriptLPS(1); 3476 m_host.AddScriptLPS(1);
3253 if (m_host.ParentGroup != null) 3477
3478 if (!m_host.ParentGroup.IsDeleted)
3254 { 3479 {
3255 if (!m_host.ParentGroup.IsDeleted) 3480 m_host.ParentGroup.RootPart.SetBuoyancy((float)buoyancy);
3256 {
3257 m_host.ParentGroup.RootPart.SetBuoyancy((float)buoyancy);
3258 }
3259 } 3481 }
3260 } 3482 }
3261 3483
@@ -3415,38 +3637,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3415 public void llPointAt(LSL_Vector pos) 3637 public void llPointAt(LSL_Vector pos)
3416 { 3638 {
3417 m_host.AddScriptLPS(1); 3639 m_host.AddScriptLPS(1);
3418 ScenePresence Owner = World.GetScenePresence(m_host.UUID);
3419 LSL_Rotation rot = llEuler2Rot(pos);
3420 Owner.PreviousRotation = Owner.Rotation;
3421 Owner.Rotation = (new Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s));
3422 } 3640 }
3423 3641
3424 public void llStopPointAt() 3642 public void llStopPointAt()
3425 { 3643 {
3426 m_host.AddScriptLPS(1); 3644 m_host.AddScriptLPS(1);
3427 ScenePresence Owner = m_host.ParentGroup.Scene.GetScenePresence(m_host.OwnerID);
3428 Owner.Rotation = Owner.PreviousRotation;
3429 } 3645 }
3430 3646
3431 public void llTargetOmega(LSL_Vector axis, double spinrate, double gain) 3647 public void llTargetOmega(LSL_Vector axis, double spinrate, double gain)
3432 { 3648 {
3433 m_host.AddScriptLPS(1); 3649 m_host.AddScriptLPS(1);
3434 m_host.AngularVelocity = new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate)); 3650 TargetOmega(m_host, axis, spinrate, gain);
3435 m_host.ScheduleTerseUpdate();
3436 m_host.SendTerseUpdateToAllClients();
3437 m_host.ParentGroup.HasGroupChanged = true;
3438 } 3651 }
3439 3652
3440 public LSL_Integer llGetStartParameter() 3653 protected void TargetOmega(SceneObjectPart part, LSL_Vector axis, double spinrate, double gain)
3441 { 3654 {
3442 m_host.AddScriptLPS(1); 3655 part.UpdateAngularVelocity(new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate)));
3443 return m_ScriptEngine.GetStartParameter(m_itemID); 3656 }
3444 }
3445 3657
3446 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 3658 public LSL_Integer llGetStartParameter()
3447 { 3659 {
3448 m_host.AddScriptLPS(1); 3660 m_host.AddScriptLPS(1);
3449 NotImplemented("llGodLikeRezObject"); 3661 return m_ScriptEngine.GetStartParameter(m_itemID);
3450 } 3662 }
3451 3663
3452 public void llRequestPermissions(string agent, int perm) 3664 public void llRequestPermissions(string agent, int perm)
@@ -3496,12 +3708,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3496 3708
3497 m_host.AddScriptLPS(1); 3709 m_host.AddScriptLPS(1);
3498 3710
3499 if (m_host.ParentGroup.IsAttachment && (UUID)agent == m_host.ParentGroup.RootPart.AttachedAvatar) 3711 if (m_host.ParentGroup.IsAttachment && (UUID)agent == m_host.ParentGroup.AttachedAvatar)
3500 { 3712 {
3501 // When attached, certain permissions are implicit if requested from owner 3713 // When attached, certain permissions are implicit if requested from owner
3502 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3714 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3503 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3715 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3504 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3716 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3717 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3505 ScriptBaseClass.PERMISSION_ATTACH; 3718 ScriptBaseClass.PERMISSION_ATTACH;
3506 3719
3507 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3720 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
@@ -3519,27 +3732,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3519 return; 3732 return;
3520 } 3733 }
3521 } 3734 }
3522 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3735 else
3523 { 3736 {
3524 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3737 bool sitting = false;
3525 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3738 if (m_host.SitTargetAvatar == agentID)
3526 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3739 {
3527 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3740 sitting = true;
3528 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3741 }
3742 else
3743 {
3744 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3745 {
3746 if (p.SitTargetAvatar == agentID)
3747 sitting = true;
3748 }
3749 }
3529 3750
3530 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3751 if (sitting)
3531 { 3752 {
3532 m_host.TaskInventory.LockItemsForWrite(true); 3753 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3533 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3754 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3534 m_host.TaskInventory[invItemID].PermsMask = perm; 3755 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3535 m_host.TaskInventory.LockItemsForWrite(false); 3756 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3757 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3536 3758
3537 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3759 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3538 "run_time_permissions", new Object[] { 3760 {
3539 new LSL_Integer(perm) }, 3761 m_host.TaskInventory.LockItemsForWrite(true);
3540 new DetectParams[0])); 3762 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3763 m_host.TaskInventory[invItemID].PermsMask = perm;
3764 m_host.TaskInventory.LockItemsForWrite(false);
3541 3765
3542 return; 3766 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3767 "run_time_permissions", new Object[] {
3768 new LSL_Integer(perm) },
3769 new DetectParams[0]));
3770
3771 return;
3772 }
3543 } 3773 }
3544 } 3774 }
3545 3775
@@ -3648,7 +3878,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3648 { 3878 {
3649 m_host.AddScriptLPS(1); 3879 m_host.AddScriptLPS(1);
3650 3880
3651 if (m_host.ParentGroup.Children.Count > 1) 3881 if (m_host.ParentGroup.PrimCount > 1)
3652 { 3882 {
3653 return m_host.LinkNum; 3883 return m_host.LinkNum;
3654 } 3884 }
@@ -3661,15 +3891,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3661 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3891 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3662 { 3892 {
3663 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3893 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3664 3894 if (parts.Count > 0)
3665 foreach (SceneObjectPart part in parts) 3895 {
3666 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3896 try
3897 {
3898 parts[0].ParentGroup.areUpdatesSuspended = true;
3899 foreach (SceneObjectPart part in parts)
3900 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3901 }
3902 finally
3903 {
3904 parts[0].ParentGroup.areUpdatesSuspended = false;
3905 }
3906 }
3667 } 3907 }
3668 3908
3669 public void llCreateLink(string target, int parent) 3909 public void llCreateLink(string target, int parent)
3670 { 3910 {
3671 m_host.AddScriptLPS(1); 3911 m_host.AddScriptLPS(1);
3672 UUID invItemID = InventorySelf(); 3912 UUID invItemID = InventorySelf();
3913 UUID targetID;
3914
3915 if (!UUID.TryParse(target, out targetID))
3916 return;
3673 3917
3674 TaskInventoryItem item; 3918 TaskInventoryItem item;
3675 m_host.TaskInventory.LockItemsForRead(true); 3919 m_host.TaskInventory.LockItemsForRead(true);
@@ -3688,15 +3932,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3688 if (sp != null) 3932 if (sp != null)
3689 client = sp.ControllingClient; 3933 client = sp.ControllingClient;
3690 3934
3691 SceneObjectPart targetPart = World.GetSceneObjectPart((UUID)target); 3935 SceneObjectPart targetPart = World.GetSceneObjectPart((UUID)targetID);
3692 3936
3693 if (targetPart.ParentGroup.RootPart.AttachmentPoint != 0) 3937 if (targetPart.ParentGroup.AttachmentPoint != 0)
3694 return; // Fail silently if attached 3938 return; // Fail silently if attached
3939
3940 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3941 return;
3942
3695 SceneObjectGroup parentPrim = null, childPrim = null; 3943 SceneObjectGroup parentPrim = null, childPrim = null;
3696 3944
3697 if (targetPart != null) 3945 if (targetPart != null)
3698 { 3946 {
3699 if (parent != 0) { 3947 if (parent != 0)
3948 {
3700 parentPrim = m_host.ParentGroup; 3949 parentPrim = m_host.ParentGroup;
3701 childPrim = targetPart.ParentGroup; 3950 childPrim = targetPart.ParentGroup;
3702 } 3951 }
@@ -3705,20 +3954,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3705 parentPrim = targetPart.ParentGroup; 3954 parentPrim = targetPart.ParentGroup;
3706 childPrim = m_host.ParentGroup; 3955 childPrim = m_host.ParentGroup;
3707 } 3956 }
3708// byte uf = childPrim.RootPart.UpdateFlag; 3957
3709 childPrim.RootPart.UpdateFlag = 0; 3958 // Required for linking
3959 childPrim.RootPart.ClearUpdateSchedule();
3710 parentPrim.LinkToGroup(childPrim); 3960 parentPrim.LinkToGroup(childPrim);
3711// if (uf != (Byte)0)
3712// parent.RootPart.UpdateFlag = uf;
3713 } 3961 }
3714 3962
3715 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3963 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3716 parentPrim.RootPart.AddFlag(PrimFlags.CreateSelected); 3964 parentPrim.RootPart.CreateSelected = true;
3717 parentPrim.HasGroupChanged = true; 3965 parentPrim.HasGroupChanged = true;
3718 parentPrim.ScheduleGroupForFullUpdate(); 3966 parentPrim.ScheduleGroupForFullUpdate();
3719 3967
3720 if (client != null) 3968 if (client != null)
3721 parentPrim.GetProperties(client); 3969 parentPrim.SendPropertiesToClient(client);
3722 3970
3723 ScriptSleep(1000); 3971 ScriptSleep(1000);
3724 } 3972 }
@@ -3743,7 +3991,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3743 3991
3744 SceneObjectGroup parentPrim = m_host.ParentGroup; 3992 SceneObjectGroup parentPrim = m_host.ParentGroup;
3745 3993
3746 if (parentPrim.RootPart.AttachmentPoint != 0) 3994 if (parentPrim.AttachmentPoint != 0)
3747 return; // Fail silently if attached 3995 return; // Fail silently if attached
3748 SceneObjectPart childPrim = null; 3996 SceneObjectPart childPrim = null;
3749 3997
@@ -3755,7 +4003,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3755 case ScriptBaseClass.LINK_ALL_OTHERS: 4003 case ScriptBaseClass.LINK_ALL_OTHERS:
3756 case ScriptBaseClass.LINK_ALL_CHILDREN: 4004 case ScriptBaseClass.LINK_ALL_CHILDREN:
3757 case ScriptBaseClass.LINK_THIS: 4005 case ScriptBaseClass.LINK_THIS:
3758 foreach (SceneObjectPart part in parentPrim.Children.Values) 4006 foreach (SceneObjectPart part in parentPrim.Parts)
3759 { 4007 {
3760 if (part.UUID != m_host.UUID) 4008 if (part.UUID != m_host.UUID)
3761 { 4009 {
@@ -3774,12 +4022,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3774 if (linknum == ScriptBaseClass.LINK_ROOT) 4022 if (linknum == ScriptBaseClass.LINK_ROOT)
3775 { 4023 {
3776 // Restructuring Multiple Prims. 4024 // Restructuring Multiple Prims.
3777 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); 4025 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3778 parts.Remove(parentPrim.RootPart); 4026 parts.Remove(parentPrim.RootPart);
3779 foreach (SceneObjectPart part in parts) 4027 if (parts.Count > 0)
3780 { 4028 {
3781 parentPrim.DelinkFromGroup(part.LocalId, true); 4029 try
4030 {
4031 parts[0].ParentGroup.areUpdatesSuspended = true;
4032 foreach (SceneObjectPart part in parts)
4033 {
4034 parentPrim.DelinkFromGroup(part.LocalId, true);
4035 }
4036 }
4037 finally
4038 {
4039 parts[0].ParentGroup.areUpdatesSuspended = false;
4040 }
3782 } 4041 }
4042
3783 parentPrim.HasGroupChanged = true; 4043 parentPrim.HasGroupChanged = true;
3784 parentPrim.ScheduleGroupForFullUpdate(); 4044 parentPrim.ScheduleGroupForFullUpdate();
3785 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4045 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3788,11 +4048,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3788 { 4048 {
3789 SceneObjectPart newRoot = parts[0]; 4049 SceneObjectPart newRoot = parts[0];
3790 parts.Remove(newRoot); 4050 parts.Remove(newRoot);
3791 foreach (SceneObjectPart part in parts) 4051
4052 try
3792 { 4053 {
3793 part.UpdateFlag = 0; 4054 parts[0].ParentGroup.areUpdatesSuspended = true;
3794 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4055 foreach (SceneObjectPart part in parts)
4056 {
4057 part.ClearUpdateSchedule();
4058 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4059 }
3795 } 4060 }
4061 finally
4062 {
4063 parts[0].ParentGroup.areUpdatesSuspended = false;
4064 }
4065
4066
3796 newRoot.ParentGroup.HasGroupChanged = true; 4067 newRoot.ParentGroup.HasGroupChanged = true;
3797 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4068 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3798 } 4069 }
@@ -3812,11 +4083,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3812 public void llBreakAllLinks() 4083 public void llBreakAllLinks()
3813 { 4084 {
3814 m_host.AddScriptLPS(1); 4085 m_host.AddScriptLPS(1);
4086
4087 UUID invItemID = InventorySelf();
4088
4089 TaskInventoryItem item;
4090 m_host.TaskInventory.LockItemsForRead(true);
4091 item = m_host.TaskInventory[invItemID];
4092 m_host.TaskInventory.LockItemsForRead(false);
4093
4094 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4095 && !m_automaticLinkPermission)
4096 {
4097 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4098 return;
4099 }
4100
3815 SceneObjectGroup parentPrim = m_host.ParentGroup; 4101 SceneObjectGroup parentPrim = m_host.ParentGroup;
3816 if (parentPrim.RootPart.AttachmentPoint != 0) 4102 if (parentPrim.AttachmentPoint != 0)
3817 return; // Fail silently if attached 4103 return; // Fail silently if attached
3818 4104
3819 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); 4105 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3820 parts.Remove(parentPrim.RootPart); 4106 parts.Remove(parentPrim.RootPart);
3821 4107
3822 foreach (SceneObjectPart part in parts) 4108 foreach (SceneObjectPart part in parts)
@@ -3831,6 +4117,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3831 public LSL_String llGetLinkKey(int linknum) 4117 public LSL_String llGetLinkKey(int linknum)
3832 { 4118 {
3833 m_host.AddScriptLPS(1); 4119 m_host.AddScriptLPS(1);
4120 List<UUID> keytable = new List<UUID>();
4121 // parse for sitting avatare-uuids
4122 World.ForEachRootScenePresence(delegate(ScenePresence presence)
4123 {
4124 if (presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
4125 keytable.Add(presence.UUID);
4126 });
4127
4128 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
4129 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
4130 {
4131 return keytable[totalprims - linknum].ToString();
4132 }
4133
4134 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
4135 {
4136 return m_host.UUID.ToString();
4137 }
4138
3834 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4139 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3835 if (part != null) 4140 if (part != null)
3836 { 4141 {
@@ -3838,6 +4143,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3838 } 4143 }
3839 else 4144 else
3840 { 4145 {
4146 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4147 {
4148 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4149
4150 if (linknum < 0)
4151 return UUID.Zero.ToString();
4152
4153 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4154 if (avatars.Count > linknum)
4155 {
4156 return avatars[linknum].UUID.ToString();
4157 }
4158 }
3841 return UUID.Zero.ToString(); 4159 return UUID.Zero.ToString();
3842 } 4160 }
3843 } 4161 }
@@ -3874,6 +4192,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3874 public LSL_String llGetLinkName(int linknum) 4192 public LSL_String llGetLinkName(int linknum)
3875 { 4193 {
3876 m_host.AddScriptLPS(1); 4194 m_host.AddScriptLPS(1);
4195 // parse for sitting avatare-names
4196 List<String> nametable = new List<String>();
4197 World.ForEachRootScenePresence(delegate(ScenePresence presence)
4198 {
4199 if (presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
4200 nametable.Add(presence.ControllingClient.Name);
4201 });
4202
4203 int totalprims = m_host.ParentGroup.PrimCount + nametable.Count;
4204 if (totalprims > m_host.ParentGroup.PrimCount)
4205 {
4206 // sitting Avatar-Name with negativ linknum / SinglePrim
4207 if (linknum < 0 && m_host.ParentGroup.PrimCount == 1 && nametable.Count == 1)
4208 return nametable[0];
4209 // Prim-Name / SinglePrim Sitting Avatar
4210 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && nametable.Count == 1)
4211 return m_host.Name;
4212 // LinkNumber > of Real PrimSet = AvatarName
4213 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
4214 return nametable[totalprims - linknum];
4215 }
3877 4216
3878 // simplest case, this prims link number 4217 // simplest case, this prims link number
3879 if (m_host.LinkNum == linknum) 4218 if (m_host.LinkNum == linknum)
@@ -3887,6 +4226,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3887 else 4226 else
3888 return UUID.Zero.ToString(); 4227 return UUID.Zero.ToString();
3889 } 4228 }
4229
3890 // Link set 4230 // Link set
3891 SceneObjectPart part = null; 4231 SceneObjectPart part = null;
3892 if (m_host.LinkNum == 1) // this is the Root prim 4232 if (m_host.LinkNum == 1) // this is the Root prim
@@ -3994,47 +4334,69 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3994 if (!found) 4334 if (!found)
3995 { 4335 {
3996 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4336 llSay(0, String.Format("Could not find object '{0}'", inventory));
3997 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4337 return;
4338// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3998 } 4339 }
3999 4340
4000 // check if destination is an avatar 4341 // check if destination is an object
4001 if (World.GetScenePresence(destId) != null) 4342 if (World.GetSceneObjectPart(destId) != null)
4343 {
4344 // destination is an object
4345 World.MoveTaskInventoryItem(destId, m_host, objId);
4346 }
4347 else
4002 { 4348 {
4349 ScenePresence presence = World.GetScenePresence(destId);
4350
4351 if (presence == null)
4352 {
4353 UserAccount account =
4354 World.UserAccountService.GetUserAccount(
4355 World.RegionInfo.ScopeID,
4356 destId);
4357
4358 if (account == null)
4359 {
4360 llSay(0, "Can't find destination "+destId.ToString());
4361 return;
4362 }
4363 }
4364
4003 // destination is an avatar 4365 // destination is an avatar
4004 InventoryItemBase agentItem = 4366 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
4005 World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
4006 4367
4007 if (agentItem == null) 4368 if (agentItem == null)
4008 return; 4369 return;
4009 4370
4010 byte[] bucket = new byte[17]; 4371 byte[] bucket = new byte[1];
4011 bucket[0] = (byte)assetType; 4372 bucket[0] = (byte)assetType;
4012 byte[] objBytes = objId.GetBytes(); 4373 //byte[] objBytes = agentItem.ID.GetBytes();
4013 Array.Copy(objBytes, 0, bucket, 1, 16); 4374 //Array.Copy(objBytes, 0, bucket, 1, 16);
4014 4375
4015 Console.WriteLine("Giving inventory");
4016 GridInstantMessage msg = new GridInstantMessage(World, 4376 GridInstantMessage msg = new GridInstantMessage(World,
4017 m_host.UUID, m_host.Name+", an object owned by "+ 4377 m_host.OwnerID, m_host.Name, destId,
4018 resolveName(m_host.OwnerID)+",", destId, 4378 (byte)InstantMessageDialog.TaskInventoryOffered,
4019 (byte)InstantMessageDialog.InventoryOffered, 4379 false, objName+". "+m_host.Name+" is located at "+
4020 false, objName+"\n"+m_host.Name+" is located at "+
4021 World.RegionInfo.RegionName+" "+ 4380 World.RegionInfo.RegionName+" "+
4022 m_host.AbsolutePosition.ToString(), 4381 m_host.AbsolutePosition.ToString(),
4023 agentItem.ID, true, m_host.AbsolutePosition, 4382 agentItem.ID, true, m_host.AbsolutePosition,
4024 bucket); 4383 bucket);
4025 4384
4026 if (m_TransferModule != null) 4385 ScenePresence sp;
4027 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4386
4387 if (World.TryGetScenePresence(destId, out sp))
4388 {
4389 sp.ControllingClient.SendInstantMessage(msg);
4390 }
4391 else
4392 {
4393 if (m_TransferModule != null)
4394 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4395 }
4028 4396
4029 //This delay should only occur when giving inventory to avatars. 4397 //This delay should only occur when giving inventory to avatars.
4030 ScriptSleep(3000); 4398 ScriptSleep(3000);
4031 } 4399 }
4032 else
4033 {
4034 // destination is an object
4035 World.MoveTaskInventoryItem(destId, m_host, objId);
4036 }
4037
4038 } 4400 }
4039 4401
4040 [DebuggerNonUserCode] 4402 [DebuggerNonUserCode]
@@ -4042,8 +4404,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4042 { 4404 {
4043 m_host.AddScriptLPS(1); 4405 m_host.AddScriptLPS(1);
4044 4406
4045 m_host.TaskInventory.LockItemsForRead(true); 4407 List<TaskInventoryItem> inv;
4046 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4408 try
4409 {
4410 m_host.TaskInventory.LockItemsForRead(true);
4411 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4412 }
4413 finally
4414 {
4415 m_host.TaskInventory.LockItemsForRead(false);
4416 }
4417 foreach (TaskInventoryItem item in inv)
4047 { 4418 {
4048 if (item.Name == name) 4419 if (item.Name == name)
4049 { 4420 {
@@ -4051,12 +4422,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4051 throw new ScriptDeleteException(); 4422 throw new ScriptDeleteException();
4052 else 4423 else
4053 m_host.Inventory.RemoveInventoryItem(item.ItemID); 4424 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4054
4055 m_host.TaskInventory.LockItemsForRead(false);
4056 return; 4425 return;
4057 } 4426 }
4058 } 4427 }
4059 m_host.TaskInventory.LockItemsForRead(false);
4060 } 4428 }
4061 4429
4062 public void llSetText(string text, LSL_Vector color, double alpha) 4430 public void llSetText(string text, LSL_Vector color, double alpha)
@@ -4089,57 +4457,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4089 { 4457 {
4090 m_host.AddScriptLPS(1); 4458 m_host.AddScriptLPS(1);
4091 4459
4092 UUID uuid = (UUID)id; 4460 UUID uuid;
4093 4461 if (UUID.TryParse(id, out uuid))
4094 UserProfileData userProfile = 4462 {
4095 World.CommsManager.UserService.GetUserProfile(uuid); 4463 PresenceInfo pinfo = null;
4464 UserAccount account;
4096 4465
4097 UserAgentData userAgent = 4466 UserInfoCacheEntry ce;
4098 World.CommsManager.UserService.GetAgentByUUID(uuid); 4467 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4468 {
4469 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4470 if (account == null)
4471 {
4472 m_userInfoCache[uuid] = null; // Cache negative
4473 return UUID.Zero.ToString();
4474 }
4099 4475
4100 if (userProfile == null || userAgent == null)
4101 return UUID.Zero.ToString();
4102 4476
4103 string reply = String.Empty; 4477 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4478 if (pinfos != null && pinfos.Length > 0)
4479 {
4480 foreach (PresenceInfo p in pinfos)
4481 {
4482 if (p.RegionID != UUID.Zero)
4483 {
4484 pinfo = p;
4485 }
4486 }
4487 }
4104 4488
4105 switch (data) 4489 ce = new UserInfoCacheEntry();
4106 { 4490 ce.time = Util.EnvironmentTickCount();
4107 case 1: // DATA_ONLINE (0|1) 4491 ce.account = account;
4108 // TODO: implement fetching of this information 4492 ce.pinfo = pinfo;
4109 if (userProfile.CurrentAgent!=null && userProfile.CurrentAgent.AgentOnline) 4493 m_userInfoCache[uuid] = ce;
4110 reply = "1"; 4494 }
4111 else 4495 else
4112 reply = "0"; 4496 {
4113 break; 4497 if (ce == null)
4114 case 2: // DATA_NAME (First Last) 4498 return UUID.Zero.ToString();
4115 reply = userProfile.FirstName + " " + userProfile.SurName;
4116 break;
4117 case 3: // DATA_BORN (YYYY-MM-DD)
4118 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4119 born = born.AddSeconds(userProfile.Created);
4120 reply = born.ToString("yyyy-MM-dd");
4121 break;
4122 case 4: // DATA_RATING (0,0,0,0,0,0)
4123 reply = "0,0,0,0,0,0";
4124 break;
4125 case 8: // DATA_PAYINFO (0|1|2|3)
4126 reply = "0";
4127 break;
4128 default:
4129 return UUID.Zero.ToString(); // Raise no event
4130 }
4131 4499
4132 UUID rq = UUID.Random(); 4500 account = ce.account;
4501 pinfo = ce.pinfo;
4502 }
4503
4504 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4505 {
4506 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4507 if (pinfos != null && pinfos.Length > 0)
4508 {
4509 foreach (PresenceInfo p in pinfos)
4510 {
4511 if (p.RegionID != UUID.Zero)
4512 {
4513 pinfo = p;
4514 }
4515 }
4516 }
4517 else
4518 pinfo = null;
4133 4519
4134 UUID tid = AsyncCommands. 4520 ce.time = Util.EnvironmentTickCount();
4135 DataserverPlugin.RegisterRequest(m_localID, 4521 ce.pinfo = pinfo;
4136 m_itemID, rq.ToString()); 4522 }
4137 4523
4138 AsyncCommands. 4524 string reply = String.Empty;
4139 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4140 4525
4141 ScriptSleep(100); 4526 switch (data)
4142 return tid.ToString(); 4527 {
4528 case 1: // DATA_ONLINE (0|1)
4529 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4530 reply = "1";
4531 else
4532 reply = "0";
4533 break;
4534 case 2: // DATA_NAME (First Last)
4535 reply = account.FirstName + " " + account.LastName;
4536 break;
4537 case 3: // DATA_BORN (YYYY-MM-DD)
4538 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4539 born = born.AddSeconds(account.Created);
4540 reply = born.ToString("yyyy-MM-dd");
4541 break;
4542 case 4: // DATA_RATING (0,0,0,0,0,0)
4543 reply = "0,0,0,0,0,0";
4544 break;
4545 case 8: // DATA_PAYINFO (0|1|2|3)
4546 reply = "0";
4547 break;
4548 default:
4549 return UUID.Zero.ToString(); // Raise no event
4550 }
4551
4552 UUID rq = UUID.Random();
4553
4554 UUID tid = AsyncCommands.
4555 DataserverPlugin.RegisterRequest(m_localID,
4556 m_itemID, rq.ToString());
4557
4558 AsyncCommands.
4559 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4560
4561 ScriptSleep(100);
4562 return tid.ToString();
4563 }
4564 else
4565 {
4566 ShoutError("Invalid UUID passed to llRequestAgentData.");
4567 }
4568 return "";
4143 } 4569 }
4144 4570
4145 public LSL_String llRequestInventoryData(string name) 4571 public LSL_String llRequestInventoryData(string name)
@@ -4201,13 +4627,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4201 if (presence != null) 4627 if (presence != null)
4202 { 4628 {
4203 // agent must not be a god 4629 // agent must not be a god
4204 if (presence.GodLevel >= 200) return; 4630 if (presence.UserLevel >= 200) return;
4205 4631
4206 // agent must be over the owners land 4632 // agent must be over the owners land
4207 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4633 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4208 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4634 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4209 { 4635 {
4210 presence.ControllingClient.SendTeleportLocationStart();
4211 World.TeleportClientHome(agentId, presence.ControllingClient); 4636 World.TeleportClientHome(agentId, presence.ControllingClient);
4212 } 4637 }
4213 } 4638 }
@@ -4215,10 +4640,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4215 ScriptSleep(5000); 4640 ScriptSleep(5000);
4216 } 4641 }
4217 4642
4218 public void llTextBox(string avatar, string message, int chat_channel) 4643 public void llTextBox(string agent, string message, int chatChannel)
4219 { 4644 {
4645 IDialogModule dm = World.RequestModuleInterface<IDialogModule>();
4646
4647 if (dm == null)
4648 return;
4649
4220 m_host.AddScriptLPS(1); 4650 m_host.AddScriptLPS(1);
4221 NotImplemented("llTextBox"); 4651 UUID av = new UUID();
4652 if (!UUID.TryParse(agent,out av))
4653 {
4654 //LSLError("First parameter to llDialog needs to be a key");
4655 return;
4656 }
4657
4658 if (message == string.Empty)
4659 {
4660 ShoutError("Trying to use llTextBox with empty message.");
4661 }
4662 else if (message.Length > 512)
4663 {
4664 ShoutError("Trying to use llTextBox with message over 512 characters.");
4665 }
4666 else
4667 {
4668 dm.SendTextBoxToUser(av, message, chatChannel, m_host.Name, m_host.UUID, m_host.OwnerID);
4669 ScriptSleep(1000);
4670 }
4222 } 4671 }
4223 4672
4224 public void llModifyLand(int action, int brush) 4673 public void llModifyLand(int action, int brush)
@@ -4234,6 +4683,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4234 public void llCollisionSound(string impact_sound, double impact_volume) 4683 public void llCollisionSound(string impact_sound, double impact_volume)
4235 { 4684 {
4236 m_host.AddScriptLPS(1); 4685 m_host.AddScriptLPS(1);
4686
4237 // TODO: Parameter check logic required. 4687 // TODO: Parameter check logic required.
4238 UUID soundId = UUID.Zero; 4688 UUID soundId = UUID.Zero;
4239 if (!UUID.TryParse(impact_sound, out soundId)) 4689 if (!UUID.TryParse(impact_sound, out soundId))
@@ -4253,12 +4703,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4253 m_host.CollisionSoundVolume = (float)impact_volume; 4703 m_host.CollisionSoundVolume = (float)impact_volume;
4254 } 4704 }
4255 4705
4256 public void llCollisionSprite(string impact_sprite)
4257 {
4258 m_host.AddScriptLPS(1);
4259 NotImplemented("llCollisionSprite");
4260 }
4261
4262 public LSL_String llGetAnimation(string id) 4706 public LSL_String llGetAnimation(string id)
4263 { 4707 {
4264 // This should only return a value if the avatar is in the same region 4708 // This should only return a value if the avatar is in the same region
@@ -4280,7 +4724,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4280 return currentAnimationState; 4724 return currentAnimationState;
4281 } 4725 }
4282 } 4726 }
4283 4727
4284 return String.Empty; 4728 return String.Empty;
4285 } 4729 }
4286 4730
@@ -4302,7 +4746,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4302 { 4746 {
4303 partItemID = item.ItemID; 4747 partItemID = item.ItemID;
4304 int linkNumber = m_host.LinkNum; 4748 int linkNumber = m_host.LinkNum;
4305 if (m_host.ParentGroup.Children.Count == 1) 4749 if (m_host.ParentGroup.PrimCount == 1)
4306 linkNumber = 0; 4750 linkNumber = 0;
4307 4751
4308 object[] resobj = new object[] 4752 object[] resobj = new object[]
@@ -4379,7 +4823,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4379 return; 4823 return;
4380 4824
4381 // Object not pushable. Not an attachment and has no physics component 4825 // Object not pushable. Not an attachment and has no physics component
4382 if (!pusheeob.IsAttachment && pusheeob.PhysActor == null) 4826 if (!pusheeob.ParentGroup.IsAttachment && pusheeob.PhysActor == null)
4383 return; 4827 return;
4384 4828
4385 PusheePos = pusheeob.AbsolutePosition; 4829 PusheePos = pusheeob.AbsolutePosition;
@@ -4396,7 +4840,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4396 return; 4840 return;
4397 4841
4398 // Need provisions for Group Owned here 4842 // Need provisions for Group Owned here
4399 if (m_host.OwnerID == targetlandObj.LandData.OwnerID || 4843 if (m_host.OwnerID == targetlandObj.LandData.OwnerID ||
4400 targetlandObj.LandData.IsGroupOwned || m_host.OwnerID == targetID) 4844 targetlandObj.LandData.IsGroupOwned || m_host.OwnerID == targetID)
4401 { 4845 {
4402 pushAllowed = true; 4846 pushAllowed = true;
@@ -4416,8 +4860,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4416 if ((targetlandObj.LandData.Flags & (uint)ParcelFlags.RestrictPushObject) == (uint)ParcelFlags.RestrictPushObject) 4860 if ((targetlandObj.LandData.Flags & (uint)ParcelFlags.RestrictPushObject) == (uint)ParcelFlags.RestrictPushObject)
4417 { 4861 {
4418 // Need provisions for Group Owned here 4862 // Need provisions for Group Owned here
4419 if (m_host.OwnerID == targetlandObj.LandData.OwnerID || 4863 if (m_host.OwnerID == targetlandObj.LandData.OwnerID ||
4420 targetlandObj.LandData.IsGroupOwned || 4864 targetlandObj.LandData.IsGroupOwned ||
4421 m_host.OwnerID == targetID) 4865 m_host.OwnerID == targetID)
4422 { 4866 {
4423 pushAllowed = true; 4867 pushAllowed = true;
@@ -4522,6 +4966,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4522 return result; 4966 return result;
4523 } 4967 }
4524 4968
4969 public LSL_Integer llGetLinkNumberOfSides(int link)
4970 {
4971 m_host.AddScriptLPS(1);
4972
4973 SceneObjectPart linkedPart;
4974
4975 if (link == ScriptBaseClass.LINK_ROOT)
4976 linkedPart = m_host.ParentGroup.RootPart;
4977 else if (link == ScriptBaseClass.LINK_THIS)
4978 linkedPart = m_host;
4979 else
4980 linkedPart = m_host.ParentGroup.GetLinkNumPart(link);
4981
4982 return GetNumberOfSides(linkedPart);
4983 }
4984
4525 public LSL_Integer llGetNumberOfSides() 4985 public LSL_Integer llGetNumberOfSides()
4526 { 4986 {
4527 m_host.AddScriptLPS(1); 4987 m_host.AddScriptLPS(1);
@@ -4541,7 +5001,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4541 5001
4542 return sides; 5002 return sides;
4543 } 5003 }
4544 5004
4545 5005
4546 /* The new / changed functions were tested with the following LSL script: 5006 /* The new / changed functions were tested with the following LSL script:
4547 5007
@@ -4840,14 +5300,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4840 { 5300 {
4841 m_host.AddScriptLPS(1); 5301 m_host.AddScriptLPS(1);
4842 5302
4843 if (src == null) 5303 return src.Length;
4844 {
4845 return 0;
4846 }
4847 else
4848 {
4849 return src.Length;
4850 }
4851 } 5304 }
4852 5305
4853 public LSL_Integer llList2Integer(LSL_List src, int index) 5306 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4893,7 +5346,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4893 else if (src.Data[index] is LSL_Float) 5346 else if (src.Data[index] is LSL_Float)
4894 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5347 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4895 else if (src.Data[index] is LSL_String) 5348 else if (src.Data[index] is LSL_String)
4896 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5349 {
5350 string str = ((LSL_String) src.Data[index]).m_string;
5351 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5352 if (m != Match.Empty)
5353 {
5354 str = m.Value;
5355 double d = 0.0;
5356 if (!Double.TryParse(str, out d))
5357 return 0.0;
5358
5359 return d;
5360 }
5361 return 0.0;
5362 }
4897 return Convert.ToDouble(src.Data[index]); 5363 return Convert.ToDouble(src.Data[index]);
4898 } 5364 }
4899 catch (FormatException) 5365 catch (FormatException)
@@ -5082,7 +5548,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5082 case ',': 5548 case ',':
5083 if (parens == 0) 5549 if (parens == 0)
5084 { 5550 {
5085 result.Add(src.Substring(start,length).Trim()); 5551 result.Add(new LSL_String(src.Substring(start,length).Trim()));
5086 start += length+1; 5552 start += length+1;
5087 length = 0; 5553 length = 0;
5088 } 5554 }
@@ -5097,7 +5563,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5097 } 5563 }
5098 } 5564 }
5099 5565
5100 result.Add(src.Substring(start,length).Trim()); 5566 result.Add(new LSL_String(src.Substring(start,length).Trim()));
5101 5567
5102 return result; 5568 return result;
5103 } 5569 }
@@ -5166,7 +5632,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5166 } 5632 }
5167 } 5633 }
5168 } 5634 }
5169 else { 5635 else
5636 {
5170 object[] array = new object[src.Length]; 5637 object[] array = new object[src.Length];
5171 Array.Copy(src.Data, 0, array, 0, src.Length); 5638 Array.Copy(src.Data, 0, array, 0, src.Length);
5172 result = new LSL_List(array); 5639 result = new LSL_List(array);
@@ -5517,7 +5984,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5517 flags |= ScriptBaseClass.AGENT_TYPING; 5984 flags |= ScriptBaseClass.AGENT_TYPING;
5518 } 5985 }
5519 5986
5520 string agentMovementAnimation = agent.Animator.GetMovementAnimation(); 5987 string agentMovementAnimation = agent.Animator.CurrentMovementAnimation;
5521 5988
5522 if (agentMovementAnimation == "CROUCH") 5989 if (agentMovementAnimation == "CROUCH")
5523 { 5990 {
@@ -5549,7 +6016,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5549 flags |= ScriptBaseClass.AGENT_SITTING; 6016 flags |= ScriptBaseClass.AGENT_SITTING;
5550 } 6017 }
5551 6018
5552 if (agent.Animator.Animations.DefaultAnimation.AnimID 6019 if (agent.Animator.Animations.DefaultAnimation.AnimID
5553 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 6020 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
5554 { 6021 {
5555 flags |= ScriptBaseClass.AGENT_SITTING; 6022 flags |= ScriptBaseClass.AGENT_SITTING;
@@ -5575,12 +6042,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5575 ScriptSleep(100); 6042 ScriptSleep(100);
5576 } 6043 }
5577 6044
5578 public void llSetSoundQueueing(int queue)
5579 {
5580 m_host.AddScriptLPS(1);
5581 NotImplemented("llSetSoundQueueing");
5582 }
5583
5584 public void llSetSoundRadius(double radius) 6045 public void llSetSoundRadius(double radius)
5585 { 6046 {
5586 m_host.AddScriptLPS(1); 6047 m_host.AddScriptLPS(1);
@@ -5623,10 +6084,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5623 m_host.AddScriptLPS(1); 6084 m_host.AddScriptLPS(1);
5624 6085
5625 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6086 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5626 6087 if (parts.Count > 0)
5627 foreach (var part in parts)
5628 { 6088 {
5629 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6089 try
6090 {
6091 parts[0].ParentGroup.areUpdatesSuspended = true;
6092 foreach (var part in parts)
6093 {
6094 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6095 }
6096 }
6097 finally
6098 {
6099 parts[0].ParentGroup.areUpdatesSuspended = false;
6100 }
5630 } 6101 }
5631 } 6102 }
5632 6103
@@ -5682,74 +6153,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5682 6153
5683 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers) 6154 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
5684 { 6155 {
5685 m_host.AddScriptLPS(1); 6156 return ParseString2List(str, separators, in_spacers, false);
5686 LSL_List ret = new LSL_List();
5687 LSL_List spacers = new LSL_List();
5688 if (in_spacers.Length > 0 && separators.Length > 0)
5689 {
5690 for (int i = 0; i < in_spacers.Length; i++)
5691 {
5692 object s = in_spacers.Data[i];
5693 for (int j = 0; j < separators.Length; j++)
5694 {
5695 if (separators.Data[j].ToString() == s.ToString())
5696 {
5697 s = null;
5698 break;
5699 }
5700 }
5701 if (s != null)
5702 {
5703 spacers.Add(s);
5704 }
5705 }
5706 }
5707 object[] delimiters = new object[separators.Length + spacers.Length];
5708 separators.Data.CopyTo(delimiters, 0);
5709 spacers.Data.CopyTo(delimiters, separators.Length);
5710 bool dfound = false;
5711 do
5712 {
5713 dfound = false;
5714 int cindex = -1;
5715 string cdeli = "";
5716 for (int i = 0; i < delimiters.Length; i++)
5717 {
5718 int index = str.IndexOf(delimiters[i].ToString());
5719 bool found = index != -1;
5720 if (found && String.Empty != delimiters[i].ToString())
5721 {
5722 if ((cindex > index) || (cindex == -1))
5723 {
5724 cindex = index;
5725 cdeli = delimiters[i].ToString();
5726 }
5727 dfound = dfound || found;
5728 }
5729 }
5730 if (cindex != -1)
5731 {
5732 if (cindex > 0)
5733 {
5734 ret.Add(new LSL_String(str.Substring(0, cindex)));
5735 }
5736 // Cannot use spacers.Contains() because spacers may be either type String or LSLString
5737 for (int j = 0; j < spacers.Length; j++)
5738 {
5739 if (spacers.Data[j].ToString() == cdeli)
5740 {
5741 ret.Add(new LSL_String(cdeli));
5742 break;
5743 }
5744 }
5745 str = str.Substring(cindex + cdeli.Length);
5746 }
5747 } while (dfound);
5748 if (str != "")
5749 {
5750 ret.Add(new LSL_String(str));
5751 }
5752 return ret;
5753 } 6157 }
5754 6158
5755 public LSL_Integer llOverMyLand(string id) 6159 public LSL_Integer llOverMyLand(string id)
@@ -5783,7 +6187,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5783 public LSL_String llGetLandOwnerAt(LSL_Vector pos) 6187 public LSL_String llGetLandOwnerAt(LSL_Vector pos)
5784 { 6188 {
5785 m_host.AddScriptLPS(1); 6189 m_host.AddScriptLPS(1);
5786 return World.LandChannel.GetLandObject((float)pos.x, (float)pos.y).LandData.OwnerID.ToString(); 6190 ILandObject land = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y);
6191 if (land == null)
6192 return UUID.Zero.ToString();
6193 return land.LandData.OwnerID.ToString();
5787 } 6194 }
5788 6195
5789 /// <summary> 6196 /// <summary>
@@ -5813,8 +6220,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5813 UUID agentId = new UUID(); 6220 UUID agentId = new UUID();
5814 if (!UUID.TryParse(agent, out agentId)) 6221 if (!UUID.TryParse(agent, out agentId))
5815 return new LSL_Integer(0); 6222 return new LSL_Integer(0);
6223 if (agentId == m_host.GroupID)
6224 return new LSL_Integer(1);
5816 ScenePresence presence = World.GetScenePresence(agentId); 6225 ScenePresence presence = World.GetScenePresence(agentId);
5817 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6226 if (presence == null || presence.IsChildAgent) // Return false for child agents
5818 return new LSL_Integer(0); 6227 return new LSL_Integer(0);
5819 IClientAPI client = presence.ControllingClient; 6228 IClientAPI client = presence.ControllingClient;
5820 if (m_host.GroupID == client.ActiveGroupId) 6229 if (m_host.GroupID == client.ActiveGroupId)
@@ -5946,10 +6355,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5946 public LSL_Integer llGetAttached() 6355 public LSL_Integer llGetAttached()
5947 { 6356 {
5948 m_host.AddScriptLPS(1); 6357 m_host.AddScriptLPS(1);
5949 return m_host.ParentGroup.RootPart.AttachmentPoint; 6358 return m_host.ParentGroup.AttachmentPoint;
5950 } 6359 }
5951 6360
5952 public LSL_Integer llGetFreeMemory() 6361 public virtual LSL_Integer llGetFreeMemory()
5953 { 6362 {
5954 m_host.AddScriptLPS(1); 6363 m_host.AddScriptLPS(1);
5955 // Make scripts designed for LSO happy 6364 // Make scripts designed for LSO happy
@@ -5983,9 +6392,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5983 public LSL_Float llGetRegionFPS() 6392 public LSL_Float llGetRegionFPS()
5984 { 6393 {
5985 m_host.AddScriptLPS(1); 6394 m_host.AddScriptLPS(1);
5986 return World.SimulatorFPS; 6395 return World.StatsReporter.LastReportedSimFPS;
5987 } 6396 }
5988 6397
5989 6398
5990 /* particle system rules should be coming into this routine as doubles, that is 6399 /* particle system rules should be coming into this routine as doubles, that is
5991 rule[0] should be an integer from this list and rule[1] should be the arg 6400 rule[0] should be an integer from this list and rule[1] should be the arg
@@ -6008,6 +6417,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6008 PSYS_PART_MAX_AGE = 7, 6417 PSYS_PART_MAX_AGE = 7,
6009 PSYS_SRC_ACCEL = 8, 6418 PSYS_SRC_ACCEL = 8,
6010 PSYS_SRC_PATTERN = 9, 6419 PSYS_SRC_PATTERN = 9,
6420 PSYS_SRC_INNERANGLE = 10,
6421 PSYS_SRC_OUTERANGLE = 11,
6011 PSYS_SRC_TEXTURE = 12, 6422 PSYS_SRC_TEXTURE = 12,
6012 PSYS_SRC_BURST_RATE = 13, 6423 PSYS_SRC_BURST_RATE = 13,
6013 PSYS_SRC_BURST_PART_COUNT = 15, 6424 PSYS_SRC_BURST_PART_COUNT = 15,
@@ -6064,9 +6475,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6064 SetParticleSystem(m_host, rules); 6475 SetParticleSystem(m_host, rules);
6065 } 6476 }
6066 6477
6067 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6478 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6479 {
6480
6068 6481
6069
6070 if (rules.Length == 0) 6482 if (rules.Length == 0)
6071 { 6483 {
6072 part.RemoveParticleSystem(); 6484 part.RemoveParticleSystem();
@@ -6140,6 +6552,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6140 prules.Pattern = (Primitive.ParticleSystem.SourcePattern)tmpi; 6552 prules.Pattern = (Primitive.ParticleSystem.SourcePattern)tmpi;
6141 break; 6553 break;
6142 6554
6555 // PSYS_SRC_INNERANGLE and PSYS_SRC_ANGLE_BEGIN use the same variables. The
6556 // PSYS_SRC_OUTERANGLE and PSYS_SRC_ANGLE_END also use the same variable. The
6557 // client tells the difference between the two by looking at the 0x02 bit in
6558 // the PartFlags variable.
6559 case (int)ScriptBaseClass.PSYS_SRC_INNERANGLE:
6560 tempf = (float)rules.GetLSLFloatItem(i + 1);
6561 prules.InnerAngle = (float)tempf;
6562 prules.PartFlags &= 0xFFFFFFFD; // Make sure new angle format is off.
6563 break;
6564
6565 case (int)ScriptBaseClass.PSYS_SRC_OUTERANGLE:
6566 tempf = (float)rules.GetLSLFloatItem(i + 1);
6567 prules.OuterAngle = (float)tempf;
6568 prules.PartFlags &= 0xFFFFFFFD; // Make sure new angle format is off.
6569 break;
6570
6143 case (int)ScriptBaseClass.PSYS_SRC_TEXTURE: 6571 case (int)ScriptBaseClass.PSYS_SRC_TEXTURE:
6144 prules.Texture = KeyOrName(rules.GetLSLStringItem(i + 1)); 6572 prules.Texture = KeyOrName(rules.GetLSLStringItem(i + 1));
6145 break; 6573 break;
@@ -6196,21 +6624,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6196 case (int)ScriptBaseClass.PSYS_SRC_ANGLE_BEGIN: 6624 case (int)ScriptBaseClass.PSYS_SRC_ANGLE_BEGIN:
6197 tempf = (float)rules.GetLSLFloatItem(i + 1); 6625 tempf = (float)rules.GetLSLFloatItem(i + 1);
6198 prules.InnerAngle = (float)tempf; 6626 prules.InnerAngle = (float)tempf;
6627 prules.PartFlags |= 0x02; // Set new angle format.
6199 break; 6628 break;
6200 6629
6201 case (int)ScriptBaseClass.PSYS_SRC_ANGLE_END: 6630 case (int)ScriptBaseClass.PSYS_SRC_ANGLE_END:
6202 tempf = (float)rules.GetLSLFloatItem(i + 1); 6631 tempf = (float)rules.GetLSLFloatItem(i + 1);
6203 prules.OuterAngle = (float)tempf; 6632 prules.OuterAngle = (float)tempf;
6204 break; 6633 prules.PartFlags |= 0x02; // Set new angle format.
6205
6206 case (int)ScriptBaseClass.PSYS_SRC_INNERANGLE:
6207 tempf = (float)rules.GetLSLFloatItem(i + 1);
6208 prules.InnerAngle = (float)tempf;
6209 break;
6210
6211 case (int)ScriptBaseClass.PSYS_SRC_OUTERANGLE:
6212 tempf = (float)rules.GetLSLFloatItem(i + 1);
6213 prules.OuterAngle = (float)tempf;
6214 break; 6634 break;
6215 } 6635 }
6216 6636
@@ -6229,7 +6649,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6229 if (m_host.PhysActor != null) 6649 if (m_host.PhysActor != null)
6230 { 6650 {
6231 float ground = (float)llGround(new LSL_Types.Vector3(0, 0, 0)); 6651 float ground = (float)llGround(new LSL_Types.Vector3(0, 0, 0));
6232 float waterLevel = (float)llWater(new LSL_Types.Vector3(0, 0, 0)); 6652 float waterLevel = (float)llWater(new LSL_Types.Vector3(0, 0, 0));
6233 PIDHoverType hoverType = PIDHoverType.Ground; 6653 PIDHoverType hoverType = PIDHoverType.Ground;
6234 if (water != 0) 6654 if (water != 0)
6235 { 6655 {
@@ -6243,7 +6663,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6243 { 6663 {
6244 height += ground; 6664 height += ground;
6245 } 6665 }
6246 6666
6247 m_host.SetHoverHeight((float)height, hoverType, (float)tau); 6667 m_host.SetHoverHeight((float)height, hoverType, (float)tau);
6248 } 6668 }
6249 } 6669 }
@@ -6297,16 +6717,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6297 if (folderID == UUID.Zero) 6717 if (folderID == UUID.Zero)
6298 return; 6718 return;
6299 6719
6300 byte[] bucket = new byte[17]; 6720 byte[] bucket = new byte[1];
6301 bucket[0] = (byte)AssetType.Folder; 6721 bucket[0] = (byte)AssetType.Folder;
6302 byte[] objBytes = folderID.GetBytes(); 6722 //byte[] objBytes = folderID.GetBytes();
6303 Array.Copy(objBytes, 0, bucket, 1, 16); 6723 //Array.Copy(objBytes, 0, bucket, 1, 16);
6304 6724
6305 GridInstantMessage msg = new GridInstantMessage(World, 6725 GridInstantMessage msg = new GridInstantMessage(World,
6306 m_host.UUID, m_host.Name+", an object owned by "+ 6726 m_host.OwnerID, m_host.Name, destID,
6307 resolveName(m_host.OwnerID)+",", destID, 6727 (byte)InstantMessageDialog.TaskInventoryOffered,
6308 (byte)InstantMessageDialog.InventoryOffered, 6728 false, category+". "+m_host.Name+" is located at "+
6309 false, category+"\n"+m_host.Name+" is located at "+
6310 World.RegionInfo.RegionName+" "+ 6729 World.RegionInfo.RegionName+" "+
6311 m_host.AbsolutePosition.ToString(), 6730 m_host.AbsolutePosition.ToString(),
6312 folderID, true, m_host.AbsolutePosition, 6731 folderID, true, m_host.AbsolutePosition,
@@ -6319,12 +6738,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6319 public void llSetVehicleType(int type) 6738 public void llSetVehicleType(int type)
6320 { 6739 {
6321 m_host.AddScriptLPS(1); 6740 m_host.AddScriptLPS(1);
6322 if (m_host.ParentGroup != null) 6741
6742 if (!m_host.ParentGroup.IsDeleted)
6323 { 6743 {
6324 if (!m_host.ParentGroup.IsDeleted) 6744 m_host.ParentGroup.RootPart.SetVehicleType(type);
6325 {
6326 m_host.ParentGroup.RootPart.SetVehicleType(type);
6327 }
6328 } 6745 }
6329 } 6746 }
6330 6747
@@ -6334,12 +6751,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6334 { 6751 {
6335 m_host.AddScriptLPS(1); 6752 m_host.AddScriptLPS(1);
6336 6753
6337 if (m_host.ParentGroup != null) 6754 if (!m_host.ParentGroup.IsDeleted)
6338 { 6755 {
6339 if (!m_host.ParentGroup.IsDeleted) 6756 m_host.ParentGroup.RootPart.SetVehicleFloatParam(param, (float)value);
6340 {
6341 m_host.ParentGroup.RootPart.SetVehicleFloatParam(param, (float)value);
6342 }
6343 } 6757 }
6344 } 6758 }
6345 6759
@@ -6348,13 +6762,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6348 public void llSetVehicleVectorParam(int param, LSL_Vector vec) 6762 public void llSetVehicleVectorParam(int param, LSL_Vector vec)
6349 { 6763 {
6350 m_host.AddScriptLPS(1); 6764 m_host.AddScriptLPS(1);
6351 if (m_host.ParentGroup != null) 6765
6766 if (!m_host.ParentGroup.IsDeleted)
6352 { 6767 {
6353 if (!m_host.ParentGroup.IsDeleted) 6768 m_host.ParentGroup.RootPart.SetVehicleVectorParam(param,
6354 { 6769 new Vector3((float)vec.x, (float)vec.y, (float)vec.z));
6355 m_host.ParentGroup.RootPart.SetVehicleVectorParam(param,
6356 new Vector3((float)vec.x, (float)vec.y, (float)vec.z));
6357 }
6358 } 6770 }
6359 } 6771 }
6360 6772
@@ -6363,37 +6775,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6363 public void llSetVehicleRotationParam(int param, LSL_Rotation rot) 6775 public void llSetVehicleRotationParam(int param, LSL_Rotation rot)
6364 { 6776 {
6365 m_host.AddScriptLPS(1); 6777 m_host.AddScriptLPS(1);
6366 if (m_host.ParentGroup != null) 6778
6779 if (!m_host.ParentGroup.IsDeleted)
6367 { 6780 {
6368 if (!m_host.ParentGroup.IsDeleted) 6781 m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, Rot2Quaternion(rot));
6369 {
6370 m_host.ParentGroup.RootPart.SetVehicleRotationParam(param,
6371 Rot2Quaternion(rot));
6372 }
6373 } 6782 }
6374 } 6783 }
6375 6784
6376 public void llSetVehicleFlags(int flags) 6785 public void llSetVehicleFlags(int flags)
6377 { 6786 {
6378 m_host.AddScriptLPS(1); 6787 m_host.AddScriptLPS(1);
6379 if (m_host.ParentGroup != null) 6788
6789 if (!m_host.ParentGroup.IsDeleted)
6380 { 6790 {
6381 if (!m_host.ParentGroup.IsDeleted) 6791 m_host.ParentGroup.RootPart.SetVehicleFlags(flags, false);
6382 {
6383 m_host.ParentGroup.RootPart.SetVehicleFlags(flags, false);
6384 }
6385 } 6792 }
6386 } 6793 }
6387 6794
6388 public void llRemoveVehicleFlags(int flags) 6795 public void llRemoveVehicleFlags(int flags)
6389 { 6796 {
6390 m_host.AddScriptLPS(1); 6797 m_host.AddScriptLPS(1);
6391 if (m_host.ParentGroup != null) 6798
6799 if (!m_host.ParentGroup.IsDeleted)
6392 { 6800 {
6393 if (!m_host.ParentGroup.IsDeleted) 6801 m_host.ParentGroup.RootPart.SetVehicleFlags(flags, true);
6394 {
6395 m_host.ParentGroup.RootPart.SetVehicleFlags(flags, true);
6396 }
6397 } 6802 }
6398 } 6803 }
6399 6804
@@ -6412,23 +6817,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6412 public LSL_String llAvatarOnSitTarget() 6817 public LSL_String llAvatarOnSitTarget()
6413 { 6818 {
6414 m_host.AddScriptLPS(1); 6819 m_host.AddScriptLPS(1);
6415 return m_host.GetAvatarOnSitTarget().ToString(); 6820 return m_host.SitTargetAvatar.ToString();
6416 } 6821 }
6417 6822
6823 // http://wiki.secondlife.com/wiki/LlAvatarOnLinkSitTarget
6824 public LSL_String llAvatarOnLinkSitTarget(int linknum)
6825 {
6826 m_host.AddScriptLPS(1);
6827 if(linknum == ScriptBaseClass.LINK_SET ||
6828 linknum == ScriptBaseClass.LINK_ALL_CHILDREN ||
6829 linknum == ScriptBaseClass.LINK_ALL_OTHERS) return UUID.Zero.ToString();
6830
6831 List<SceneObjectPart> parts = GetLinkParts(linknum);
6832 if (parts.Count == 0) return UUID.Zero.ToString();
6833 return parts[0].SitTargetAvatar.ToString();
6834 }
6835
6836
6418 public void llAddToLandPassList(string avatar, double hours) 6837 public void llAddToLandPassList(string avatar, double hours)
6419 { 6838 {
6420 m_host.AddScriptLPS(1); 6839 m_host.AddScriptLPS(1);
6421 UUID key; 6840 UUID key;
6422 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).LandData; 6841 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
6423 if (land.OwnerID == m_host.OwnerID) 6842 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed))
6424 { 6843 {
6425 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); 6844 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
6426 if (UUID.TryParse(avatar, out key)) 6845 if (UUID.TryParse(avatar, out key))
6427 { 6846 {
6428 entry.AgentID = key; 6847 if (land.LandData.ParcelAccessList.FindIndex(
6429 entry.Flags = AccessList.Access; 6848 delegate(ParcelManager.ParcelAccessEntry e)
6430 entry.Time = DateTime.Now.AddHours(hours); 6849 {
6431 land.ParcelAccessList.Add(entry); 6850 if (e.AgentID == key && e.Flags == AccessList.Access)
6851 return true;
6852 return false;
6853 }) == -1)
6854 {
6855 entry.AgentID = key;
6856 entry.Flags = AccessList.Access;
6857 entry.Time = DateTime.Now.AddHours(hours);
6858 land.LandData.ParcelAccessList.Add(entry);
6859 }
6432 } 6860 }
6433 } 6861 }
6434 ScriptSleep(100); 6862 ScriptSleep(100);
@@ -6500,13 +6928,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6500 UUID av = new UUID(); 6928 UUID av = new UUID();
6501 if (!UUID.TryParse(avatar,out av)) 6929 if (!UUID.TryParse(avatar,out av))
6502 { 6930 {
6503 LSLError("First parameter to llDialog needs to be a key"); 6931 //LSLError("First parameter to llDialog needs to be a key");
6504 return; 6932 return;
6505 } 6933 }
6506 if (buttons.Length < 1) 6934 if (buttons.Length < 1)
6507 { 6935 {
6508 LSLError("No less than 1 button can be shown"); 6936 buttons.Add("OK");
6509 return;
6510 } 6937 }
6511 if (buttons.Length > 12) 6938 if (buttons.Length > 12)
6512 { 6939 {
@@ -6523,7 +6950,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6523 } 6950 }
6524 if (buttons.Data[i].ToString().Length > 24) 6951 if (buttons.Data[i].ToString().Length > 24)
6525 { 6952 {
6526 LSLError("button label cannot be longer than 24 characters"); 6953 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6527 return; 6954 return;
6528 } 6955 }
6529 buts[i] = buttons.Data[i].ToString(); 6956 buts[i] = buttons.Data[i].ToString();
@@ -6539,20 +6966,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6539 public void llVolumeDetect(int detect) 6966 public void llVolumeDetect(int detect)
6540 { 6967 {
6541 m_host.AddScriptLPS(1); 6968 m_host.AddScriptLPS(1);
6542 if (m_host.ParentGroup != null) 6969
6543 { 6970 if (!m_host.ParentGroup.IsDeleted)
6544 if (!m_host.ParentGroup.IsDeleted) 6971 m_host.ParentGroup.ScriptSetVolumeDetect(detect != 0);
6545 {
6546 m_host.ParentGroup.RootPart.ScriptSetVolumeDetect(detect!=0);
6547 }
6548 }
6549 } 6972 }
6550 6973
6551 /// <summary> 6974 /// <summary>
6552 /// This is a depecated function so this just replicates the result of 6975 /// This is a depecated function so this just replicates the result of
6553 /// invoking it in SL 6976 /// invoking it in SL
6554 /// </summary> 6977 /// </summary>
6555
6556 public void llRemoteLoadScript(string target, string name, int running, int start_param) 6978 public void llRemoteLoadScript(string target, string name, int running, int start_param)
6557 { 6979 {
6558 m_host.AddScriptLPS(1); 6980 m_host.AddScriptLPS(1);
@@ -6587,6 +7009,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6587 } 7009 }
6588 7010
6589 // copy the first script found with this inventory name 7011 // copy the first script found with this inventory name
7012 TaskInventoryItem scriptItem = null;
6590 m_host.TaskInventory.LockItemsForRead(true); 7013 m_host.TaskInventory.LockItemsForRead(true);
6591 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 7014 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6592 { 7015 {
@@ -6597,6 +7020,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6597 { 7020 {
6598 found = true; 7021 found = true;
6599 srcId = inv.Key; 7022 srcId = inv.Key;
7023 scriptItem = inv.Value;
6600 break; 7024 break;
6601 } 7025 }
6602 } 7026 }
@@ -6609,8 +7033,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6609 return; 7033 return;
6610 } 7034 }
6611 7035
6612 // the rest of the permission checks are done in RezScript, so check the pin there as well 7036 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6613 World.RezScript(srcId, m_host, destId, pin, running, start_param); 7037 if (dest != null)
7038 {
7039 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7040 {
7041 // the rest of the permission checks are done in RezScript, so check the pin there as well
7042 World.RezScript(srcId, m_host, destId, pin, running, start_param);
7043
7044 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7045 m_host.Inventory.RemoveInventoryItem(srcId);
7046 }
7047 }
6614 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7048 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6615 ScriptSleep(3000); 7049 ScriptSleep(3000);
6616 } 7050 }
@@ -6626,19 +7060,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6626 if (xmlRpcRouter != null) 7060 if (xmlRpcRouter != null)
6627 { 7061 {
6628 string ExternalHostName = m_ScriptEngine.World.RegionInfo.ExternalHostName; 7062 string ExternalHostName = m_ScriptEngine.World.RegionInfo.ExternalHostName;
6629 7063
6630 xmlRpcRouter.RegisterNewReceiver(m_ScriptEngine.ScriptModule, channelID, m_host.UUID, 7064 xmlRpcRouter.RegisterNewReceiver(m_ScriptEngine.ScriptModule, channelID, m_host.UUID,
6631 m_itemID, String.Format("http://{0}:{1}/", ExternalHostName, 7065 m_itemID, String.Format("http://{0}:{1}/", ExternalHostName,
6632 xmlrpcMod.Port.ToString())); 7066 xmlrpcMod.Port.ToString()));
6633 } 7067 }
6634 object[] resobj = new object[] 7068 object[] resobj = new object[]
6635 { 7069 {
6636 new LSL_Integer(1), 7070 new LSL_Integer(1),
6637 new LSL_String(channelID.ToString()), 7071 new LSL_String(channelID.ToString()),
6638 new LSL_String(UUID.Zero.ToString()), 7072 new LSL_String(UUID.Zero.ToString()),
6639 new LSL_String(String.Empty), 7073 new LSL_String(String.Empty),
6640 new LSL_Integer(0), 7074 new LSL_Integer(0),
6641 new LSL_String(String.Empty) 7075 new LSL_String(String.Empty)
6642 }; 7076 };
6643 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams("remote_data", resobj, 7077 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams("remote_data", resobj,
6644 new DetectParams[0])); 7078 new DetectParams[0]));
@@ -6673,17 +7107,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6673 public LSL_String llMD5String(string src, int nonce) 7107 public LSL_String llMD5String(string src, int nonce)
6674 { 7108 {
6675 m_host.AddScriptLPS(1); 7109 m_host.AddScriptLPS(1);
6676 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7110 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6677 } 7111 }
6678 7112
6679 public LSL_String llSHA1String(string src) 7113 public LSL_String llSHA1String(string src)
6680 { 7114 {
6681 m_host.AddScriptLPS(1); 7115 m_host.AddScriptLPS(1);
6682 return Util.SHA1Hash(src).ToLower(); 7116 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6683 } 7117 }
6684 7118
6685 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 7119 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6686 { 7120 {
7121 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6687 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7122 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6688 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 7123 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6689 return shapeBlock; 7124 return shapeBlock;
@@ -6695,7 +7130,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6695 { 7130 {
6696 holeshape = (int)ScriptBaseClass.PRIM_HOLE_DEFAULT; 7131 holeshape = (int)ScriptBaseClass.PRIM_HOLE_DEFAULT;
6697 } 7132 }
6698 shapeBlock.ProfileCurve = (byte)holeshape; 7133 shapeBlock.PathCurve = pathcurve;
7134 shapeBlock.ProfileCurve = (byte)holeshape; // Set the hole shape.
7135 shapeBlock.ProfileCurve += profileshape; // Add in the profile shape.
6699 if (cut.x < 0f) 7136 if (cut.x < 0f)
6700 { 7137 {
6701 cut.x = 0f; 7138 cut.x = 0f;
@@ -6715,6 +7152,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6715 if (cut.y - cut.x < 0.05f) 7152 if (cut.y - cut.x < 0.05f)
6716 { 7153 {
6717 cut.x = cut.y - 0.05f; 7154 cut.x = cut.y - 0.05f;
7155 if (cut.x < 0.0f)
7156 {
7157 cut.x = 0.0f;
7158 cut.y = 0.05f;
7159 }
6718 } 7160 }
6719 shapeBlock.ProfileBegin = (ushort)(50000 * cut.x); 7161 shapeBlock.ProfileBegin = (ushort)(50000 * cut.x);
6720 shapeBlock.ProfileEnd = (ushort)(50000 * (1 - cut.y)); 7162 shapeBlock.ProfileEnd = (ushort)(50000 * (1 - cut.y));
@@ -6722,9 +7164,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6722 { 7164 {
6723 hollow = 0f; 7165 hollow = 0f;
6724 } 7166 }
6725 if (hollow > 0.95) 7167 // If the prim is a Cylinder, Prism, Sphere, Torus or Ring (or not a
7168 // Box or Tube) and the hole shape is a square, hollow is limited to
7169 // a max of 70%. The viewer performs its own check on this value but
7170 // we need to do it here also so llGetPrimitiveParams can have access
7171 // to the correct value.
7172 if (profileshape != (byte)ProfileCurve.Square &&
7173 holeshape == (int)ScriptBaseClass.PRIM_HOLE_SQUARE)
6726 { 7174 {
6727 hollow = 0.95f; 7175 if (hollow > 0.70f)
7176 {
7177 hollow = 0.70f;
7178 }
7179 }
7180 // Otherwise, hollow is limited to 95%.
7181 else
7182 {
7183 if (hollow > 0.95f)
7184 {
7185 hollow = 0.95f;
7186 }
6728 } 7187 }
6729 shapeBlock.ProfileHollow = (ushort)(50000 * hollow); 7188 shapeBlock.ProfileHollow = (ushort)(50000 * hollow);
6730 if (twist.x < -1.0f) 7189 if (twist.x < -1.0f)
@@ -6743,28 +7202,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6743 { 7202 {
6744 twist.y = 1.0f; 7203 twist.y = 1.0f;
6745 } 7204 }
6746 shapeBlock.PathTwistBegin = (sbyte)(100 * twist.x); 7205 // A fairly large precision error occurs for some calculations,
6747 shapeBlock.PathTwist = (sbyte)(100 * twist.y); 7206 // if a float or double is directly cast to a byte or sbyte
7207 // variable, in both .Net and Mono. In .Net, coding
7208 // "(sbyte)(float)(some expression)" corrects the precision
7209 // errors. But this does not work for Mono. This longer coding
7210 // form of creating a tempoary float variable from the
7211 // expression first, then casting that variable to a byte or
7212 // sbyte, works for both .Net and Mono. These types of
7213 // assignments occur in SetPrimtiveBlockShapeParams and
7214 // SetPrimitiveShapeParams in support of llSetPrimitiveParams.
7215 tempFloat = (float)(100.0d * twist.x);
7216 shapeBlock.PathTwistBegin = (sbyte)tempFloat;
7217 tempFloat = (float)(100.0d * twist.y);
7218 shapeBlock.PathTwist = (sbyte)tempFloat;
6748 7219
6749 shapeBlock.ObjectLocalID = part.LocalId; 7220 shapeBlock.ObjectLocalID = part.LocalId;
6750 7221
6751 // retain pathcurve
6752 shapeBlock.PathCurve = part.Shape.PathCurve;
6753
6754 part.Shape.SculptEntry = false; 7222 part.Shape.SculptEntry = false;
6755 return shapeBlock; 7223 return shapeBlock;
6756 } 7224 }
6757 7225
6758 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 7226 // Prim type box, cylinder and prism.
7227 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)
6759 { 7228 {
6760 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 7229 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6761 return; 7230 return;
6762 7231
7232 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6763 ObjectShapePacket.ObjectDataBlock shapeBlock; 7233 ObjectShapePacket.ObjectDataBlock shapeBlock;
6764 7234
6765 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7235 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
6766
6767 shapeBlock.ProfileCurve += fudge;
6768 7236
6769 if (taper_b.x < 0f) 7237 if (taper_b.x < 0f)
6770 { 7238 {
@@ -6782,8 +7250,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6782 { 7250 {
6783 taper_b.y = 2f; 7251 taper_b.y = 2f;
6784 } 7252 }
6785 shapeBlock.PathScaleX = (byte)(100 * (2.0 - taper_b.x)); 7253 tempFloat = (float)(100.0d * (2.0d - taper_b.x));
6786 shapeBlock.PathScaleY = (byte)(100 * (2.0 - taper_b.y)); 7254 shapeBlock.PathScaleX = (byte)tempFloat;
7255 tempFloat = (float)(100.0d * (2.0d - taper_b.y));
7256 shapeBlock.PathScaleY = (byte)tempFloat;
6787 if (topshear.x < -0.5f) 7257 if (topshear.x < -0.5f)
6788 { 7258 {
6789 topshear.x = -0.5f; 7259 topshear.x = -0.5f;
@@ -6800,28 +7270,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6800 { 7270 {
6801 topshear.y = 0.5f; 7271 topshear.y = 0.5f;
6802 } 7272 }
6803 shapeBlock.PathShearX = (byte)(100 * topshear.x); 7273 tempFloat = (float)(100.0d * topshear.x);
6804 shapeBlock.PathShearY = (byte)(100 * topshear.y); 7274 shapeBlock.PathShearX = (byte)tempFloat;
7275 tempFloat = (float)(100.0d * topshear.y);
7276 shapeBlock.PathShearY = (byte)tempFloat;
6805 7277
6806 part.Shape.SculptEntry = false; 7278 part.Shape.SculptEntry = false;
6807 part.UpdateShape(shapeBlock); 7279 part.UpdateShape(shapeBlock);
6808 } 7280 }
6809 7281
6810 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 7282 // Prim type sphere.
7283 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6811 { 7284 {
6812 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 7285 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6813 return; 7286 return;
6814 7287
6815 ObjectShapePacket.ObjectDataBlock shapeBlock; 7288 ObjectShapePacket.ObjectDataBlock shapeBlock;
6816 7289
6817 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7290 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
6818 7291
6819 // profile/path swapped for a sphere 7292 // profile/path swapped for a sphere
6820 shapeBlock.PathBegin = shapeBlock.ProfileBegin; 7293 shapeBlock.PathBegin = shapeBlock.ProfileBegin;
6821 shapeBlock.PathEnd = shapeBlock.ProfileEnd; 7294 shapeBlock.PathEnd = shapeBlock.ProfileEnd;
6822 7295
6823 shapeBlock.ProfileCurve += fudge;
6824
6825 shapeBlock.PathScaleX = 100; 7296 shapeBlock.PathScaleX = 100;
6826 shapeBlock.PathScaleY = 100; 7297 shapeBlock.PathScaleY = 100;
6827 7298
@@ -6852,16 +7323,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6852 part.UpdateShape(shapeBlock); 7323 part.UpdateShape(shapeBlock);
6853 } 7324 }
6854 7325
6855 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 fudge) 7326 // Prim type torus, tube and ring.
7327 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)
6856 { 7328 {
6857 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 7329 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6858 return; 7330 return;
6859 7331
7332 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6860 ObjectShapePacket.ObjectDataBlock shapeBlock; 7333 ObjectShapePacket.ObjectDataBlock shapeBlock;
6861 7334
6862 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7335 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
6863
6864 shapeBlock.ProfileCurve += fudge;
6865 7336
6866 // profile/path swapped for a torrus, tube, ring 7337 // profile/path swapped for a torrus, tube, ring
6867 shapeBlock.PathBegin = shapeBlock.ProfileBegin; 7338 shapeBlock.PathBegin = shapeBlock.ProfileBegin;
@@ -6883,8 +7354,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6883 { 7354 {
6884 holesize.y = 0.5f; 7355 holesize.y = 0.5f;
6885 } 7356 }
6886 shapeBlock.PathScaleX = (byte)(100 * (2 - holesize.x)); 7357 tempFloat = (float)(100.0d * (2.0d - holesize.x));
6887 shapeBlock.PathScaleY = (byte)(100 * (2 - holesize.y)); 7358 shapeBlock.PathScaleX = (byte)tempFloat;
7359 tempFloat = (float)(100.0d * (2.0d - holesize.y));
7360 shapeBlock.PathScaleY = (byte)tempFloat;
6888 if (topshear.x < -0.5f) 7361 if (topshear.x < -0.5f)
6889 { 7362 {
6890 topshear.x = -0.5f; 7363 topshear.x = -0.5f;
@@ -6901,8 +7374,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6901 { 7374 {
6902 topshear.y = 0.5f; 7375 topshear.y = 0.5f;
6903 } 7376 }
6904 shapeBlock.PathShearX = (byte)(100 * topshear.x); 7377 tempFloat = (float)(100.0d * topshear.x);
6905 shapeBlock.PathShearY = (byte)(100 * topshear.y); 7378 shapeBlock.PathShearX = (byte)tempFloat;
7379 tempFloat = (float)(100.0d * topshear.y);
7380 shapeBlock.PathShearY = (byte)tempFloat;
6906 if (profilecut.x < 0f) 7381 if (profilecut.x < 0f)
6907 { 7382 {
6908 profilecut.x = 0f; 7383 profilecut.x = 0f;
@@ -6919,9 +7394,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6919 { 7394 {
6920 profilecut.y = 1f; 7395 profilecut.y = 1f;
6921 } 7396 }
6922 if (profilecut.y - cut.x < 0.05f) 7397 if (profilecut.y - profilecut.x < 0.05f)
6923 { 7398 {
6924 profilecut.x = cut.y - 0.05f; 7399 profilecut.x = profilecut.y - 0.05f;
7400 if (profilecut.x < 0.0f)
7401 {
7402 profilecut.x = 0.0f;
7403 profilecut.y = 0.05f;
7404 }
6925 } 7405 }
6926 shapeBlock.ProfileBegin = (ushort)(50000 * profilecut.x); 7406 shapeBlock.ProfileBegin = (ushort)(50000 * profilecut.x);
6927 shapeBlock.ProfileEnd = (ushort)(50000 * (1 - profilecut.y)); 7407 shapeBlock.ProfileEnd = (ushort)(50000 * (1 - profilecut.y));
@@ -6941,8 +7421,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6941 { 7421 {
6942 taper_a.y = 1f; 7422 taper_a.y = 1f;
6943 } 7423 }
6944 shapeBlock.PathTaperX = (sbyte)(100 * taper_a.x); 7424 tempFloat = (float)(100.0d * taper_a.x);
6945 shapeBlock.PathTaperY = (sbyte)(100 * taper_a.y); 7425 shapeBlock.PathTaperX = (sbyte)tempFloat;
7426 tempFloat = (float)(100.0d * taper_a.y);
7427 shapeBlock.PathTaperY = (sbyte)tempFloat;
6946 if (revolutions < 1f) 7428 if (revolutions < 1f)
6947 { 7429 {
6948 revolutions = 1f; 7430 revolutions = 1f;
@@ -6951,7 +7433,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6951 { 7433 {
6952 revolutions = 4f; 7434 revolutions = 4f;
6953 } 7435 }
6954 shapeBlock.PathRevolutions = (byte)(66.666667 * (revolutions - 1.0)); 7436 tempFloat = 66.66667f * (revolutions - 1.0f);
7437 shapeBlock.PathRevolutions = (byte)tempFloat;
6955 // limits on radiusoffset depend on revolutions and hole size (how?) seems like the maximum range is 0 to 1 7438 // limits on radiusoffset depend on revolutions and hole size (how?) seems like the maximum range is 0 to 1
6956 if (radiusoffset < 0f) 7439 if (radiusoffset < 0f)
6957 { 7440 {
@@ -6961,7 +7444,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6961 { 7444 {
6962 radiusoffset = 1f; 7445 radiusoffset = 1f;
6963 } 7446 }
6964 shapeBlock.PathRadiusOffset = (sbyte)(100 * radiusoffset); 7447 tempFloat = 100.0f * radiusoffset;
7448 shapeBlock.PathRadiusOffset = (sbyte)tempFloat;
6965 if (skew < -0.95f) 7449 if (skew < -0.95f)
6966 { 7450 {
6967 skew = -0.95f; 7451 skew = -0.95f;
@@ -6970,13 +7454,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6970 { 7454 {
6971 skew = 0.95f; 7455 skew = 0.95f;
6972 } 7456 }
6973 shapeBlock.PathSkew = (sbyte)(100 * skew); 7457 tempFloat = 100.0f * skew;
7458 shapeBlock.PathSkew = (sbyte)tempFloat;
6974 7459
6975 part.Shape.SculptEntry = false; 7460 part.Shape.SculptEntry = false;
6976 part.UpdateShape(shapeBlock); 7461 part.UpdateShape(shapeBlock);
6977 } 7462 }
6978 7463
6979 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7464 // Prim type sculpt.
7465 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
6980 { 7466 {
6981 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 7467 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6982 return; 7468 return;
@@ -6992,23 +7478,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6992 if (sculptId == UUID.Zero) 7478 if (sculptId == UUID.Zero)
6993 return; 7479 return;
6994 7480
7481 shapeBlock.PathCurve = pathcurve;
6995 shapeBlock.ObjectLocalID = part.LocalId; 7482 shapeBlock.ObjectLocalID = part.LocalId;
6996 shapeBlock.PathScaleX = 100; 7483 shapeBlock.PathScaleX = 100;
6997 shapeBlock.PathScaleY = 150; 7484 shapeBlock.PathScaleY = 150;
6998 7485
6999 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7486 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
7000 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7487 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
7001 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7488 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
7002 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7489 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
7003 { 7490 {
7004 // default 7491 // default
7005 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7492 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7006 } 7493 }
7007 7494
7008 // retain pathcurve 7495 part.Shape.SetSculptProperties((byte)type, sculptId);
7009 shapeBlock.PathCurve = part.Shape.PathCurve;
7010
7011 part.Shape.SetSculptData((byte)type, sculptId);
7012 part.Shape.SculptEntry = true; 7496 part.Shape.SculptEntry = true;
7013 part.UpdateShape(shapeBlock); 7497 part.UpdateShape(shapeBlock);
7014 } 7498 }
@@ -7017,27 +7501,51 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7017 { 7501 {
7018 m_host.AddScriptLPS(1); 7502 m_host.AddScriptLPS(1);
7019 SetPrimParams(m_host, rules); 7503 SetPrimParams(m_host, rules);
7504
7505 ScriptSleep(200);
7020 } 7506 }
7021 7507
7022 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7508 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7023 { 7509 {
7024 m_host.AddScriptLPS(1); 7510 m_host.AddScriptLPS(1);
7025 7511
7026 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7512 setLinkPrimParams(linknumber, rules);
7513 }
7027 7514
7028 foreach (SceneObjectPart part in parts) 7515 private void setLinkPrimParams(int linknumber, LSL_List rules)
7029 SetPrimParams(part, rules); 7516 {
7517 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7518 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7519 if (parts.Count>0)
7520 {
7521 try
7522 {
7523 parts[0].ParentGroup.areUpdatesSuspended = true;
7524 foreach (SceneObjectPart part in parts)
7525 SetPrimParams(part, rules);
7526 }
7527 finally
7528 {
7529 parts[0].ParentGroup.areUpdatesSuspended = false;
7530 }
7531 }
7532 if (avatars.Count > 0)
7533 {
7534 foreach (ScenePresence avatar in avatars)
7535 SetPrimParams(avatar, rules);
7536 }
7030 } 7537 }
7031 7538
7032 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7539 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7033 { 7540 {
7034 llSetLinkPrimitiveParams(linknumber, rules); 7541 llSetLinkPrimitiveParamsFast(linknumber, rules);
7542 ScriptSleep(200);
7035 } 7543 }
7036 7544
7037 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7545 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7038 { 7546 {
7039 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 7547 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7040 return; 7548 //We only support PRIM_POSITION and PRIM_ROTATION
7041 7549
7042 int idx = 0; 7550 int idx = 0;
7043 7551
@@ -7047,365 +7555,456 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7047 7555
7048 int remain = rules.Length - idx; 7556 int remain = rules.Length - idx;
7049 7557
7050 int face; 7558
7051 LSL_Vector v;
7052 7559
7053 switch (code) 7560 switch (code)
7054 { 7561 {
7055 case (int)ScriptBaseClass.PRIM_POSITION: 7562 case (int)ScriptBaseClass.PRIM_POSITION:
7056 if (remain < 1) 7563 if (remain < 1)
7057 return; 7564 return;
7058 7565 LSL_Vector v;
7059 v=rules.GetVector3Item(idx++); 7566 v = rules.GetVector3Item(idx++);
7060 SetPos(part, v); 7567 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7568 av.SendAvatarDataToAllAgents();
7061 7569
7062 break; 7570 break;
7063 case (int)ScriptBaseClass.PRIM_SIZE:
7064 if (remain < 1)
7065 return;
7066
7067 v=rules.GetVector3Item(idx++);
7068 SetScale(part, v);
7069 7571
7070 break;
7071 case (int)ScriptBaseClass.PRIM_ROTATION: 7572 case (int)ScriptBaseClass.PRIM_ROTATION:
7072 if (remain < 1) 7573 if (remain < 1)
7073 return; 7574 return;
7575 LSL_Rotation r;
7576 r = rules.GetQuaternionItem(idx++);
7577 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7578 av.SendAvatarDataToAllAgents();
7579 break;
7580 }
7581 }
7582 }
7074 7583
7075 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7584 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7076 // try to let this work as in SL... 7585 {
7077 if (part.ParentID == 0) 7586 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7078 { 7587 return;
7079 // special case: If we are root, rotate complete SOG to new rotation 7588
7080 SetRot(part, Rot2Quaternion(q)); 7589 int idx = 0;
7081 } 7590
7082 else 7591 bool positionChanged = false;
7083 { 7592 LSL_Vector currentPosition = GetPartLocalPos(part);
7084 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 7593
7085 SceneObjectGroup group = part.ParentGroup; 7594 try
7086 if (group != null) // a bit paranoid, maybe 7595 {
7596 while (idx < rules.Length)
7597 {
7598 int code = rules.GetLSLIntegerItem(idx++);
7599
7600 int remain = rules.Length - idx;
7601
7602 int face;
7603 LSL_Vector v;
7604
7605 switch (code)
7606 {
7607 case (int)ScriptBaseClass.PRIM_POSITION:
7608 if (remain < 1)
7609 return;
7610
7611 v=rules.GetVector3Item(idx++);
7612 positionChanged = true;
7613 currentPosition = GetSetPosTarget(part, v, currentPosition);
7614
7615 break;
7616 case (int)ScriptBaseClass.PRIM_SIZE:
7617 if (remain < 1)
7618 return;
7619
7620 v=rules.GetVector3Item(idx++);
7621 SetScale(part, v);
7622
7623 break;
7624 case (int)ScriptBaseClass.PRIM_ROTATION:
7625 if (remain < 1)
7626 return;
7627
7628 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7629 // try to let this work as in SL...
7630 if (part.ParentID == 0)
7087 { 7631 {
7088 SceneObjectPart rootPart = group.RootPart; 7632 // special case: If we are root, rotate complete SOG to new rotation
7089 if (rootPart != null) // again, better safe than sorry 7633 SetRot(part, Rot2Quaternion(q));
7090 { 7634 }
7091 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); 7635 else
7092 } 7636 {
7637 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
7638 SceneObjectPart rootPart = part.ParentGroup.RootPart;
7639 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q));
7093 } 7640 }
7094 }
7095 7641
7096 break; 7642 break;
7097 7643
7098 case (int)ScriptBaseClass.PRIM_TYPE: 7644 case (int)ScriptBaseClass.PRIM_TYPE:
7099 if (remain < 3) 7645 if (remain < 3)
7100 return; 7646 return;
7101 7647
7102 code = (int)rules.GetLSLIntegerItem(idx++); 7648 code = (int)rules.GetLSLIntegerItem(idx++);
7103 7649
7104 remain = rules.Length - idx; 7650 remain = rules.Length - idx;
7105 float hollow; 7651 float hollow;
7106 LSL_Vector twist; 7652 LSL_Vector twist;
7107 LSL_Vector taper_b; 7653 LSL_Vector taper_b;
7108 LSL_Vector topshear; 7654 LSL_Vector topshear;
7109 float revolutions; 7655 float revolutions;
7110 float radiusoffset; 7656 float radiusoffset;
7111 float skew; 7657 float skew;
7112 LSL_Vector holesize; 7658 LSL_Vector holesize;
7113 LSL_Vector profilecut; 7659 LSL_Vector profilecut;
7114 7660
7115 switch (code) 7661 switch (code)
7116 { 7662 {
7117 case (int)ScriptBaseClass.PRIM_TYPE_BOX: 7663 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
7118 if (remain < 6) 7664 if (remain < 6)
7119 return; 7665 return;
7120 7666
7121 face = (int)rules.GetLSLIntegerItem(idx++); 7667 face = (int)rules.GetLSLIntegerItem(idx++);
7122 v = rules.GetVector3Item(idx++); // cut 7668 v = rules.GetVector3Item(idx++); // cut
7123 hollow = (float)rules.GetLSLFloatItem(idx++); 7669 hollow = (float)rules.GetLSLFloatItem(idx++);
7124 twist = rules.GetVector3Item(idx++); 7670 twist = rules.GetVector3Item(idx++);
7125 taper_b = rules.GetVector3Item(idx++); 7671 taper_b = rules.GetVector3Item(idx++);
7126 topshear = rules.GetVector3Item(idx++); 7672 topshear = rules.GetVector3Item(idx++);
7127 7673
7128 part.Shape.PathCurve = (byte)Extrusion.Straight; 7674 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear,
7129 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear, 1); 7675 (byte)ProfileShape.Square, (byte)Extrusion.Straight);
7130 break; 7676 break;
7131 7677
7132 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER: 7678 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
7133 if (remain < 6) 7679 if (remain < 6)
7134 return; 7680 return;
7135 7681
7136 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape 7682 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
7137 v = rules.GetVector3Item(idx++); // cut 7683 v = rules.GetVector3Item(idx++); // cut
7138 hollow = (float)rules.GetLSLFloatItem(idx++); 7684 hollow = (float)rules.GetLSLFloatItem(idx++);
7139 twist = rules.GetVector3Item(idx++); 7685 twist = rules.GetVector3Item(idx++);
7140 taper_b = rules.GetVector3Item(idx++); 7686 taper_b = rules.GetVector3Item(idx++);
7141 topshear = rules.GetVector3Item(idx++); 7687 topshear = rules.GetVector3Item(idx++);
7142 part.Shape.ProfileShape = ProfileShape.Circle; 7688 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear,
7143 part.Shape.PathCurve = (byte)Extrusion.Straight; 7689 (byte)ProfileShape.Circle, (byte)Extrusion.Straight);
7144 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear, 0); 7690 break;
7145 break;
7146 7691
7147 case (int)ScriptBaseClass.PRIM_TYPE_PRISM: 7692 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
7148 if (remain < 6) 7693 if (remain < 6)
7149 return; 7694 return;
7150 7695
7151 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape 7696 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
7152 v = rules.GetVector3Item(idx++); //cut 7697 v = rules.GetVector3Item(idx++); //cut
7153 hollow = (float)rules.GetLSLFloatItem(idx++); 7698 hollow = (float)rules.GetLSLFloatItem(idx++);
7154 twist = rules.GetVector3Item(idx++); 7699 twist = rules.GetVector3Item(idx++);
7155 taper_b = rules.GetVector3Item(idx++); 7700 taper_b = rules.GetVector3Item(idx++);
7156 topshear = rules.GetVector3Item(idx++); 7701 topshear = rules.GetVector3Item(idx++);
7157 part.Shape.PathCurve = (byte)Extrusion.Straight; 7702 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear,
7158 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear, 3); 7703 (byte)ProfileShape.EquilateralTriangle, (byte)Extrusion.Straight);
7159 break; 7704 break;
7160 7705
7161 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE: 7706 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
7162 if (remain < 5) 7707 if (remain < 5)
7163 return; 7708 return;
7164 7709
7165 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape 7710 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
7166 v = rules.GetVector3Item(idx++); // cut 7711 v = rules.GetVector3Item(idx++); // cut
7167 hollow = (float)rules.GetLSLFloatItem(idx++); 7712 hollow = (float)rules.GetLSLFloatItem(idx++);
7168 twist = rules.GetVector3Item(idx++); 7713 twist = rules.GetVector3Item(idx++);
7169 taper_b = rules.GetVector3Item(idx++); // dimple 7714 taper_b = rules.GetVector3Item(idx++); // dimple
7170 part.Shape.PathCurve = (byte)Extrusion.Curve1; 7715 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b,
7171 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, 5); 7716 (byte)ProfileShape.HalfCircle, (byte)Extrusion.Curve1);
7172 break; 7717 break;
7173 7718
7174 case (int)ScriptBaseClass.PRIM_TYPE_TORUS: 7719 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
7175 if (remain < 11) 7720 if (remain < 11)
7176 return; 7721 return;
7177 7722
7178 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape 7723 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
7179 v = rules.GetVector3Item(idx++); //cut 7724 v = rules.GetVector3Item(idx++); //cut
7180 hollow = (float)rules.GetLSLFloatItem(idx++); 7725 hollow = (float)rules.GetLSLFloatItem(idx++);
7181 twist = rules.GetVector3Item(idx++); 7726 twist = rules.GetVector3Item(idx++);
7182 holesize = rules.GetVector3Item(idx++); 7727 holesize = rules.GetVector3Item(idx++);
7183 topshear = rules.GetVector3Item(idx++); 7728 topshear = rules.GetVector3Item(idx++);
7184 profilecut = rules.GetVector3Item(idx++); 7729 profilecut = rules.GetVector3Item(idx++);
7185 taper_b = rules.GetVector3Item(idx++); // taper_a 7730 taper_b = rules.GetVector3Item(idx++); // taper_a
7186 revolutions = (float)rules.GetLSLFloatItem(idx++); 7731 revolutions = (float)rules.GetLSLFloatItem(idx++);
7187 radiusoffset = (float)rules.GetLSLFloatItem(idx++); 7732 radiusoffset = (float)rules.GetLSLFloatItem(idx++);
7188 skew = (float)rules.GetLSLFloatItem(idx++); 7733 skew = (float)rules.GetLSLFloatItem(idx++);
7189 part.Shape.PathCurve = (byte)Extrusion.Curve1; 7734 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b,
7190 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b, 7735 revolutions, radiusoffset, skew, (byte)ProfileShape.Circle, (byte)Extrusion.Curve1);
7191 revolutions, radiusoffset, skew, 0); 7736 break;
7192 break;
7193 7737
7194 case (int)ScriptBaseClass.PRIM_TYPE_TUBE: 7738 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
7195 if (remain < 11) 7739 if (remain < 11)
7196 return; 7740 return;
7197 7741
7198 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape 7742 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
7199 v = rules.GetVector3Item(idx++); //cut 7743 v = rules.GetVector3Item(idx++); //cut
7200 hollow = (float)rules.GetLSLFloatItem(idx++); 7744 hollow = (float)rules.GetLSLFloatItem(idx++);
7201 twist = rules.GetVector3Item(idx++); 7745 twist = rules.GetVector3Item(idx++);
7202 holesize = rules.GetVector3Item(idx++); 7746 holesize = rules.GetVector3Item(idx++);
7203 topshear = rules.GetVector3Item(idx++); 7747 topshear = rules.GetVector3Item(idx++);
7204 profilecut = rules.GetVector3Item(idx++); 7748 profilecut = rules.GetVector3Item(idx++);
7205 taper_b = rules.GetVector3Item(idx++); // taper_a 7749 taper_b = rules.GetVector3Item(idx++); // taper_a
7206 revolutions = (float)rules.GetLSLFloatItem(idx++); 7750 revolutions = (float)rules.GetLSLFloatItem(idx++);
7207 radiusoffset = (float)rules.GetLSLFloatItem(idx++); 7751 radiusoffset = (float)rules.GetLSLFloatItem(idx++);
7208 skew = (float)rules.GetLSLFloatItem(idx++); 7752 skew = (float)rules.GetLSLFloatItem(idx++);
7209 part.Shape.PathCurve = (byte)Extrusion.Curve1; 7753 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b,
7210 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b, 7754 revolutions, radiusoffset, skew, (byte)ProfileShape.Square, (byte)Extrusion.Curve1);
7211 revolutions, radiusoffset, skew, 1); 7755 break;
7212 break;
7213 7756
7214 case (int)ScriptBaseClass.PRIM_TYPE_RING: 7757 case (int)ScriptBaseClass.PRIM_TYPE_RING:
7215 if (remain < 11) 7758 if (remain < 11)
7216 return; 7759 return;
7217 7760
7218 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape 7761 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
7219 v = rules.GetVector3Item(idx++); //cut 7762 v = rules.GetVector3Item(idx++); //cut
7220 hollow = (float)rules.GetLSLFloatItem(idx++); 7763 hollow = (float)rules.GetLSLFloatItem(idx++);
7221 twist = rules.GetVector3Item(idx++); 7764 twist = rules.GetVector3Item(idx++);
7222 holesize = rules.GetVector3Item(idx++); 7765 holesize = rules.GetVector3Item(idx++);
7223 topshear = rules.GetVector3Item(idx++); 7766 topshear = rules.GetVector3Item(idx++);
7224 profilecut = rules.GetVector3Item(idx++); 7767 profilecut = rules.GetVector3Item(idx++);
7225 taper_b = rules.GetVector3Item(idx++); // taper_a 7768 taper_b = rules.GetVector3Item(idx++); // taper_a
7226 revolutions = (float)rules.GetLSLFloatItem(idx++); 7769 revolutions = (float)rules.GetLSLFloatItem(idx++);
7227 radiusoffset = (float)rules.GetLSLFloatItem(idx++); 7770 radiusoffset = (float)rules.GetLSLFloatItem(idx++);
7228 skew = (float)rules.GetLSLFloatItem(idx++); 7771 skew = (float)rules.GetLSLFloatItem(idx++);
7229 part.Shape.PathCurve = (byte)Extrusion.Curve1; 7772 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b,
7230 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b, 7773 revolutions, radiusoffset, skew, (byte)ProfileShape.EquilateralTriangle, (byte)Extrusion.Curve1);
7231 revolutions, radiusoffset, skew, 3); 7774 break;
7232 break;
7233 7775
7234 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT: 7776 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
7235 if (remain < 2) 7777 if (remain < 2)
7236 return; 7778 return;
7237 7779
7238 string map = rules.Data[idx++].ToString(); 7780 string map = rules.Data[idx++].ToString();
7239 face = (int)rules.GetLSLIntegerItem(idx++); // type 7781 face = (int)rules.GetLSLIntegerItem(idx++); // type
7240 part.Shape.PathCurve = (byte)Extrusion.Curve1; 7782 SetPrimitiveShapeParams(part, map, face, (byte)Extrusion.Curve1);
7241 SetPrimitiveShapeParams(part, map, face); 7783 break;
7242 break; 7784 }
7243 }
7244 7785
7245 break; 7786 break;
7246 7787
7247 case (int)ScriptBaseClass.PRIM_TEXTURE: 7788 case (int)ScriptBaseClass.PRIM_TEXTURE:
7248 if (remain < 5) 7789 if (remain < 5)
7249 return; 7790 return;
7250 7791
7251 face=(int)rules.GetLSLIntegerItem(idx++); 7792 face=(int)rules.GetLSLIntegerItem(idx++);
7252 string tex=rules.Data[idx++].ToString(); 7793 string tex=rules.Data[idx++].ToString();
7253 LSL_Vector repeats=rules.GetVector3Item(idx++); 7794 LSL_Vector repeats=rules.GetVector3Item(idx++);
7254 LSL_Vector offsets=rules.GetVector3Item(idx++); 7795 LSL_Vector offsets=rules.GetVector3Item(idx++);
7255 double rotation=(double)rules.GetLSLFloatItem(idx++); 7796 double rotation=(double)rules.GetLSLFloatItem(idx++);
7256 7797
7257 SetTexture(part, tex, face); 7798 SetTexture(part, tex, face);
7258 ScaleTexture(part, repeats.x, repeats.y, face); 7799 ScaleTexture(part, repeats.x, repeats.y, face);
7259 OffsetTexture(part, offsets.x, offsets.y, face); 7800 OffsetTexture(part, offsets.x, offsets.y, face);
7260 RotateTexture(part, rotation, face); 7801 RotateTexture(part, rotation, face);
7261 7802
7262 break; 7803 break;
7263 7804
7264 case (int)ScriptBaseClass.PRIM_COLOR: 7805 case (int)ScriptBaseClass.PRIM_COLOR:
7265 if (remain < 3) 7806 if (remain < 3)
7266 return; 7807 return;
7267 7808
7268 face=(int)rules.GetLSLIntegerItem(idx++); 7809 face=(int)rules.GetLSLIntegerItem(idx++);
7269 LSL_Vector color=rules.GetVector3Item(idx++); 7810 LSL_Vector color=rules.GetVector3Item(idx++);
7270 double alpha=(double)rules.GetLSLFloatItem(idx++); 7811 double alpha=(double)rules.GetLSLFloatItem(idx++);
7271 7812
7272 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 7813 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
7273 SetAlpha(part, alpha, face); 7814 SetAlpha(part, alpha, face);
7274 7815
7275 break; 7816 break;
7276
7277 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
7278 if (remain < 7)
7279 return;
7280 7817
7281 bool flexi = rules.GetLSLIntegerItem(idx++); 7818 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
7282 int softness = rules.GetLSLIntegerItem(idx++); 7819 if (remain < 7)
7283 float gravity = (float)rules.GetLSLFloatItem(idx++); 7820 return;
7284 float friction = (float)rules.GetLSLFloatItem(idx++);
7285 float wind = (float)rules.GetLSLFloatItem(idx++);
7286 float tension = (float)rules.GetLSLFloatItem(idx++);
7287 LSL_Vector force = rules.GetVector3Item(idx++);
7288 7821
7289 SetFlexi(part, flexi, softness, gravity, friction, wind, tension, force); 7822 bool flexi = rules.GetLSLIntegerItem(idx++);
7823 int softness = rules.GetLSLIntegerItem(idx++);
7824 float gravity = (float)rules.GetLSLFloatItem(idx++);
7825 float friction = (float)rules.GetLSLFloatItem(idx++);
7826 float wind = (float)rules.GetLSLFloatItem(idx++);
7827 float tension = (float)rules.GetLSLFloatItem(idx++);
7828 LSL_Vector force = rules.GetVector3Item(idx++);
7290 7829
7291 break; 7830 SetFlexi(part, flexi, softness, gravity, friction, wind, tension, force);
7292
7293 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
7294 if (remain < 5)
7295 return;
7296 bool light = rules.GetLSLIntegerItem(idx++);
7297 LSL_Vector lightcolor = rules.GetVector3Item(idx++);
7298 float intensity = (float)rules.GetLSLFloatItem(idx++);
7299 float radius = (float)rules.GetLSLFloatItem(idx++);
7300 float falloff = (float)rules.GetLSLFloatItem(idx++);
7301 7831
7302 SetPointLight(part, light, lightcolor, intensity, radius, falloff); 7832 break;
7303 7833
7304 break; 7834 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
7305 7835 if (remain < 5)
7306 case (int)ScriptBaseClass.PRIM_GLOW: 7836 return;
7307 if (remain < 2) 7837 bool light = rules.GetLSLIntegerItem(idx++);
7308 return; 7838 LSL_Vector lightcolor = rules.GetVector3Item(idx++);
7309 face = rules.GetLSLIntegerItem(idx++); 7839 float intensity = (float)rules.GetLSLFloatItem(idx++);
7310 float glow = (float)rules.GetLSLFloatItem(idx++); 7840 float radius = (float)rules.GetLSLFloatItem(idx++);
7841 float falloff = (float)rules.GetLSLFloatItem(idx++);
7311 7842
7312 SetGlow(part, face, glow); 7843 SetPointLight(part, light, lightcolor, intensity, radius, falloff);
7313 7844
7314 break; 7845 break;
7315
7316 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7317 if (remain < 3)
7318 return;
7319 face = (int)rules.GetLSLIntegerItem(idx++);
7320 int shiny = (int)rules.GetLSLIntegerItem(idx++);
7321 Bumpiness bump = (Bumpiness)Convert.ToByte((int)rules.GetLSLIntegerItem(idx++));
7322 7846
7323 SetShiny(part, face, shiny, bump); 7847 case (int)ScriptBaseClass.PRIM_GLOW:
7848 if (remain < 2)
7849 return;
7850 face = rules.GetLSLIntegerItem(idx++);
7851 float glow = (float)rules.GetLSLFloatItem(idx++);
7324 7852
7325 break; 7853 SetGlow(part, face, glow);
7326
7327 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7328 if (remain < 2)
7329 return;
7330 face = rules.GetLSLIntegerItem(idx++);
7331 bool st = rules.GetLSLIntegerItem(idx++);
7332 SetFullBright(part, face , st);
7333 break;
7334
7335 case (int)ScriptBaseClass.PRIM_MATERIAL:
7336 if (remain < 1)
7337 return;
7338 int mat = rules.GetLSLIntegerItem(idx++);
7339 if (mat < 0 || mat > 7)
7340 return;
7341
7342 part.Material = Convert.ToByte(mat);
7343 break;
7344
7345 case (int)ScriptBaseClass.PRIM_PHANTOM:
7346 if (remain < 1)
7347 return;
7348 7854
7349 string ph = rules.Data[idx++].ToString(); 7855 break;
7350 bool phantom;
7351 7856
7352 if (ph.Equals("1")) 7857 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7353 phantom = true; 7858 if (remain < 3)
7354 else 7859 return;
7355 phantom = false; 7860 face = (int)rules.GetLSLIntegerItem(idx++);
7861 int shiny = (int)rules.GetLSLIntegerItem(idx++);
7862 Bumpiness bump = (Bumpiness)Convert.ToByte((int)rules.GetLSLIntegerItem(idx++));
7356 7863
7357 part.ScriptSetPhantomStatus(phantom); 7864 SetShiny(part, face, shiny, bump);
7358 break;
7359
7360 case (int)ScriptBaseClass.PRIM_PHYSICS:
7361 if (remain < 1)
7362 return;
7363 string phy = rules.Data[idx++].ToString();
7364 bool physics;
7365 7865
7366 if (phy.Equals("1")) 7866 break;
7367 physics = true;
7368 else
7369 physics = false;
7370 7867
7371 part.ScriptSetPhysicsStatus(physics); 7868 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7372 break; 7869 if (remain < 2)
7373 7870 return;
7374 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 7871 face = rules.GetLSLIntegerItem(idx++);
7375 if (remain < 1) 7872 bool st = rules.GetLSLIntegerItem(idx++);
7376 return; 7873 SetFullBright(part, face , st);
7377 string temp = rules.Data[idx++].ToString(); 7874 break;
7378 bool tempOnRez;
7379 7875
7380 if (temp.Equals("1")) 7876 case (int)ScriptBaseClass.PRIM_MATERIAL:
7381 tempOnRez = true; 7877 if (remain < 1)
7382 else 7878 return;
7383 tempOnRez = false; 7879 int mat = rules.GetLSLIntegerItem(idx++);
7880 if (mat < 0 || mat > 7)
7881 return;
7384 7882
7385 part.ScriptSetTemporaryStatus(tempOnRez); 7883 part.Material = Convert.ToByte(mat);
7386 break; 7884 break;
7885
7886 case (int)ScriptBaseClass.PRIM_PHANTOM:
7887 if (remain < 1)
7888 return;
7889
7890 string ph = rules.Data[idx++].ToString();
7891 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1"));
7892
7893 break;
7894
7895 case (int)ScriptBaseClass.PRIM_PHYSICS:
7896 if (remain < 1)
7897 return;
7898 string phy = rules.Data[idx++].ToString();
7899 bool physics;
7900
7901 if (phy.Equals("1"))
7902 physics = true;
7903 else
7904 physics = false;
7905
7906 part.ScriptSetPhysicsStatus(physics);
7907 break;
7908
7909 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7910 if (remain < 1)
7911 return;
7912 string temp = rules.Data[idx++].ToString();
7913
7914 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1"));
7915
7916 break;
7917
7918 case (int)ScriptBaseClass.PRIM_TEXGEN:
7919 if (remain < 2)
7920 return;
7921 //face,type
7922 face = rules.GetLSLIntegerItem(idx++);
7923 int style = rules.GetLSLIntegerItem(idx++);
7924 SetTexGen(part, face, style);
7925 break;
7926 case (int)ScriptBaseClass.PRIM_TEXT:
7927 if (remain < 3)
7928 return;
7929 string primText = rules.GetLSLStringItem(idx++);
7930 LSL_Vector primTextColor = rules.GetVector3Item(idx++);
7931 LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++);
7932 Vector3 av3 = new Vector3(Util.Clip((float)primTextColor.x, 0.0f, 1.0f),
7933 Util.Clip((float)primTextColor.y, 0.0f, 1.0f),
7934 Util.Clip((float)primTextColor.z, 0.0f, 1.0f));
7935 part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f));
7936
7937 break;
7938 case (int)ScriptBaseClass.PRIM_NAME:
7939 if (remain < 1)
7940 return;
7941 string primName = rules.GetLSLStringItem(idx++);
7942 part.Name = primName;
7943 break;
7944 case (int)ScriptBaseClass.PRIM_DESC:
7945 if (remain < 1)
7946 return;
7947 string primDesc = rules.GetLSLStringItem(idx++);
7948 part.Description = primDesc;
7949 break;
7950 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7951 if (remain < 1)
7952 return;
7953 LSL_Rotation lr = rules.GetQuaternionItem(idx++);
7954 SetRot(part, Rot2Quaternion(lr));
7955 break;
7956 case (int)ScriptBaseClass.PRIM_OMEGA:
7957 if (remain < 3)
7958 return;
7959 LSL_Vector axis = rules.GetVector3Item(idx++);
7960 LSL_Float spinrate = rules.GetLSLFloatItem(idx++);
7961 LSL_Float gain = rules.GetLSLFloatItem(idx++);
7962 TargetOmega(part, axis, (double)spinrate, (double)gain);
7963 break;
7964 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
7965 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
7966 return;
7967 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
7968 LSL_List new_rules = rules.GetSublist(idx, -1);
7969 setLinkPrimParams((int)new_linknumber, new_rules);
7387 7970
7388 case (int)ScriptBaseClass.PRIM_TEXGEN:
7389 if (remain < 2)
7390 return;
7391 //face,type
7392 face = rules.GetLSLIntegerItem(idx++);
7393 int style = rules.GetLSLIntegerItem(idx++);
7394 SetTexGen(part, face, style);
7395 break;
7396 case (int)ScriptBaseClass.PRIM_TEXT:
7397 if (remain < 3)
7398 return; 7971 return;
7399 string primText = rules.GetLSLStringItem(idx++); 7972 }
7400 LSL_Vector primTextColor = rules.GetVector3Item(idx++); 7973 }
7401 LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++); 7974 }
7402 Vector3 av3 = new Vector3(Util.Clip((float)primTextColor.x, 0.0f, 1.0f), 7975 finally
7403 Util.Clip((float)primTextColor.y, 0.0f, 1.0f), 7976 {
7404 Util.Clip((float)primTextColor.z, 0.0f, 1.0f)); 7977 if (positionChanged)
7405 part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f)); 7978 {
7979 if (part.ParentGroup.RootPart == part)
7980 {
7981 SceneObjectGroup parent = part.ParentGroup;
7982 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7983 }
7984 else
7985 {
7986 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
7987 SceneObjectGroup parent = part.ParentGroup;
7988 parent.HasGroupChanged = true;
7989 parent.ScheduleGroupForTerseUpdate();
7990 }
7991 }
7992 }
7406 7993
7407 break; 7994 if (positionChanged)
7995 {
7996 if (part.ParentGroup.RootPart == part)
7997 {
7998 SceneObjectGroup parent = part.ParentGroup;
7999 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7408 } 8000 }
8001 else
8002 {
8003 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8004 SceneObjectGroup parent = part.ParentGroup;
8005 parent.HasGroupChanged = true;
8006 parent.ScheduleGroupForTerseUpdate();
8007 }
7409 } 8008 }
7410 } 8009 }
7411 8010
@@ -7475,7 +8074,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7475 UUID[] anims; 8074 UUID[] anims;
7476 anims = av.Animator.GetAnimationArray(); 8075 anims = av.Animator.GetAnimationArray();
7477 foreach (UUID foo in anims) 8076 foreach (UUID foo in anims)
7478 l.Add(foo.ToString()); 8077 l.Add(new LSL_Key(foo.ToString()));
7479 return l; 8078 return l;
7480 } 8079 }
7481 8080
@@ -7496,7 +8095,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7496 public LSL_Vector llGetRootPosition() 8095 public LSL_Vector llGetRootPosition()
7497 { 8096 {
7498 m_host.AddScriptLPS(1); 8097 m_host.AddScriptLPS(1);
7499 return new LSL_Vector(m_host.ParentGroup.AbsolutePosition.X, m_host.ParentGroup.AbsolutePosition.Y, 8098 return new LSL_Vector(m_host.ParentGroup.AbsolutePosition.X, m_host.ParentGroup.AbsolutePosition.Y,
7500 m_host.ParentGroup.AbsolutePosition.Z); 8099 m_host.ParentGroup.AbsolutePosition.Z);
7501 } 8100 }
7502 8101
@@ -7513,9 +8112,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7513 { 8112 {
7514 m_host.AddScriptLPS(1); 8113 m_host.AddScriptLPS(1);
7515 Quaternion q; 8114 Quaternion q;
7516 if (m_host.ParentGroup.RootPart.AttachmentPoint != 0) 8115 if (m_host.ParentGroup.AttachmentPoint != 0)
7517 { 8116 {
7518 ScenePresence avatar = World.GetScenePresence(m_host.AttachedAvatar); 8117 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
7519 if (avatar != null) 8118 if (avatar != null)
7520 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 8119 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
7521 q = avatar.CameraRotation; // Mouselook 8120 q = avatar.CameraRotation; // Mouselook
@@ -7555,13 +8154,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7555 public LSL_Integer llGetNumberOfPrims() 8154 public LSL_Integer llGetNumberOfPrims()
7556 { 8155 {
7557 m_host.AddScriptLPS(1); 8156 m_host.AddScriptLPS(1);
7558 int avatarCount = 0; 8157 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7559 World.ForEachScenePresence(delegate(ScenePresence presence) 8158
7560 {
7561 if (!presence.IsChildAgent && presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7562 avatarCount++;
7563 });
7564
7565 return m_host.ParentGroup.PrimCount + avatarCount; 8159 return m_host.ParentGroup.PrimCount + avatarCount;
7566 } 8160 }
7567 8161
@@ -7577,55 +8171,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7577 m_host.AddScriptLPS(1); 8171 m_host.AddScriptLPS(1);
7578 UUID objID = UUID.Zero; 8172 UUID objID = UUID.Zero;
7579 LSL_List result = new LSL_List(); 8173 LSL_List result = new LSL_List();
8174
8175 // If the ID is not valid, return null result
7580 if (!UUID.TryParse(obj, out objID)) 8176 if (!UUID.TryParse(obj, out objID))
7581 { 8177 {
7582 result.Add(new LSL_Vector()); 8178 result.Add(new LSL_Vector());
7583 result.Add(new LSL_Vector()); 8179 result.Add(new LSL_Vector());
7584 return result; 8180 return result;
7585 } 8181 }
8182
8183 // Check if this is an attached prim. If so, replace
8184 // the UUID with the avatar UUID and report it's bounding box
8185 SceneObjectPart part = World.GetSceneObjectPart(objID);
8186 if (part != null && part.ParentGroup.IsAttachment)
8187 objID = part.ParentGroup.AttachedAvatar;
8188
8189 // Find out if this is an avatar ID. If so, return it's box
7586 ScenePresence presence = World.GetScenePresence(objID); 8190 ScenePresence presence = World.GetScenePresence(objID);
7587 if (presence != null) 8191 if (presence != null)
7588 { 8192 {
7589 if (presence.ParentID == 0) // not sat on an object 8193 // As per LSL Wiki, there is no difference between sitting
8194 // and standing avatar since server 1.36
8195 LSL_Vector lower;
8196 LSL_Vector upper;
8197 if (presence.Animator.Animations.DefaultAnimation.AnimID
8198 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7590 { 8199 {
7591 LSL_Vector lower; 8200 // This is for ground sitting avatars
7592 LSL_Vector upper; 8201 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7593 if (presence.Animator.Animations.DefaultAnimation.AnimID 8202 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7594 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8203 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7595 {
7596 // This is for ground sitting avatars
7597 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7598 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7599 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7600 }
7601 else
7602 {
7603 // This is for standing/flying avatars
7604 float height = presence.Appearance.AvatarHeight / 2.0f;
7605 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7606 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7607 }
7608 result.Add(lower);
7609 result.Add(upper);
7610 return result;
7611 } 8204 }
7612 else 8205 else
7613 { 8206 {
7614 // sitting on an object so we need the bounding box of that 8207 // This is for standing/flying avatars
7615 // which should include the avatar so set the UUID to the 8208 float height = presence.Appearance.AvatarHeight / 2.0f;
7616 // UUID of the object the avatar is sat on and allow it to fall through 8209 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7617 // to processing an object 8210 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7618 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7619 objID = p.UUID;
7620 } 8211 }
8212
8213 // Adjust to the documented error offsets (see LSL Wiki)
8214 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8215 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8216
8217 if (lower.x > upper.x)
8218 lower.x = upper.x;
8219 if (lower.y > upper.y)
8220 lower.y = upper.y;
8221 if (lower.z > upper.z)
8222 lower.z = upper.z;
8223
8224 result.Add(lower);
8225 result.Add(upper);
8226 return result;
7621 } 8227 }
7622 SceneObjectPart part = World.GetSceneObjectPart(objID); 8228
8229 part = World.GetSceneObjectPart(objID);
7623 // Currently only works for single prims without a sitting avatar 8230 // Currently only works for single prims without a sitting avatar
7624 if (part != null) 8231 if (part != null)
7625 { 8232 {
7626 Vector3 halfSize = part.Scale / 2.0f; 8233 float minX;
7627 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8234 float maxX;
7628 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8235 float minY;
8236 float maxY;
8237 float minZ;
8238 float maxZ;
8239
8240 // This BBox is in sim coordinates, with the offset being
8241 // a contained point.
8242 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8243 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8244
8245 minX -= offsets[0].X;
8246 maxX -= offsets[0].X;
8247 minY -= offsets[0].Y;
8248 maxY -= offsets[0].Y;
8249 minZ -= offsets[0].Z;
8250 maxZ -= offsets[0].Z;
8251
8252 LSL_Vector lower;
8253 LSL_Vector upper;
8254
8255 // Adjust to the documented error offsets (see LSL Wiki)
8256 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8257 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8258
8259 if (lower.x > upper.x)
8260 lower.x = upper.x;
8261 if (lower.y > upper.y)
8262 lower.y = upper.y;
8263 if (lower.z > upper.z)
8264 lower.z = upper.z;
8265
7629 result.Add(lower); 8266 result.Add(lower);
7630 result.Add(upper); 8267 result.Add(upper);
7631 return result; 8268 return result;
@@ -7705,13 +8342,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7705 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8342 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7706 part.AbsolutePosition.Y, 8343 part.AbsolutePosition.Y,
7707 part.AbsolutePosition.Z); 8344 part.AbsolutePosition.Z);
7708 // For some reason, the part.AbsolutePosition.* values do not change if the
7709 // linkset is rotated; they always reflect the child prim's world position
7710 // as though the linkset is unrotated. This is incompatible behavior with SL's
7711 // implementation, so will break scripts imported from there (not to mention it
7712 // makes it more difficult to determine a child prim's actual inworld position).
7713 if (part.ParentID != 0)
7714 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7715 res.Add(v); 8345 res.Add(v);
7716 break; 8346 break;
7717 8347
@@ -7737,7 +8367,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7737 case ScriptBaseClass.PRIM_TYPE_BOX: 8367 case ScriptBaseClass.PRIM_TYPE_BOX:
7738 case ScriptBaseClass.PRIM_TYPE_CYLINDER: 8368 case ScriptBaseClass.PRIM_TYPE_CYLINDER:
7739 case ScriptBaseClass.PRIM_TYPE_PRISM: 8369 case ScriptBaseClass.PRIM_TYPE_PRISM:
7740 res.Add(new LSL_Integer(Shape.ProfileCurve)); 8370 res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble.
7741 res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0)); 8371 res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0));
7742 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0)); 8372 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0));
7743 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0)); 8373 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0));
@@ -7746,7 +8376,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7746 break; 8376 break;
7747 8377
7748 case ScriptBaseClass.PRIM_TYPE_SPHERE: 8378 case ScriptBaseClass.PRIM_TYPE_SPHERE:
7749 res.Add(new LSL_Integer(Shape.ProfileCurve)); 8379 res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble.
7750 res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0)); 8380 res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0));
7751 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0)); 8381 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0));
7752 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0)); 8382 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0));
@@ -7762,7 +8392,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7762 case ScriptBaseClass.PRIM_TYPE_TUBE: 8392 case ScriptBaseClass.PRIM_TYPE_TUBE:
7763 case ScriptBaseClass.PRIM_TYPE_TORUS: 8393 case ScriptBaseClass.PRIM_TYPE_TORUS:
7764 // holeshape 8394 // holeshape
7765 res.Add(new LSL_Integer(Shape.ProfileCurve)); 8395 res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble.
7766 8396
7767 // cut 8397 // cut
7768 res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0)); 8398 res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0));
@@ -7786,11 +8416,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7786 res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0)); 8416 res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0));
7787 8417
7788 // float revolutions 8418 // float revolutions
7789 res.Add(new LSL_Float((Shape.PathRevolutions * 0.015) + 1.0)); // Slightly inaccurate, because an unsigned 8419 res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d);
7790 // byte is being used to represent the entire 8420 // Slightly inaccurate, because an unsigned byte is being used to represent
7791 // range of floating-point values from 1.0 8421 // the entire range of floating-point values from 1.0 through 4.0 (which is how
7792 // through 4.0 (which is how SL does it). 8422 // SL does it).
7793 8423 //
8424 // Using these formulas to store and retrieve PathRevolutions, it is not
8425 // possible to use all values between 1.00 and 4.00. For instance, you can't
8426 // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you
8427 // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them
8428 // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar
8429 // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11.
8430 // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value
8431 // such as 1.10. So, SL must store and retreive the actual user input rather
8432 // than only storing the encoded value.
8433
7794 // float radiusoffset 8434 // float radiusoffset
7795 res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0)); 8435 res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0));
7796 8436
@@ -8050,17 +8690,264 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8050 break; 8690 break;
8051 case (int)ScriptBaseClass.PRIM_TEXT: 8691 case (int)ScriptBaseClass.PRIM_TEXT:
8052 Color4 textColor = part.GetTextColor(); 8692 Color4 textColor = part.GetTextColor();
8053 res.Add(part.Text); 8693 res.Add(new LSL_String(part.Text));
8054 res.Add(new LSL_Vector(textColor.R, 8694 res.Add(new LSL_Vector(textColor.R,
8055 textColor.G, 8695 textColor.G,
8056 textColor.B)); 8696 textColor.B));
8057 res.Add(new LSL_Float(textColor.A)); 8697 res.Add(new LSL_Float(textColor.A));
8058 break; 8698 break;
8699 case (int)ScriptBaseClass.PRIM_NAME:
8700 res.Add(new LSL_String(part.Name));
8701 break;
8702 case (int)ScriptBaseClass.PRIM_DESC:
8703 res.Add(new LSL_String(part.Description));
8704 break;
8705 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8706 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8707 break;
8708 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8709 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8710 break;
8711 }
8712 }
8713 return res;
8714 }
8715
8716 public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
8717 {
8718 m_host.AddScriptLPS(1);
8719 ScriptSleep(1000);
8720
8721 // LSL Spec http://wiki.secondlife.com/wiki/LlGetPrimMediaParams says to fail silently if face is invalid
8722 // TODO: Need to correctly handle case where a face has no media (which gives back an empty list).
8723 // Assuming silently fail means give back an empty list. Ideally, need to check this.
8724 if (face < 0 || face > m_host.GetNumberOfSides() - 1)
8725 return new LSL_List();
8726
8727 return GetPrimMediaParams(face, rules);
8728 }
8729
8730 private LSL_List GetPrimMediaParams(int face, LSL_List rules)
8731 {
8732 IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>();
8733 if (null == module)
8734 throw new Exception("Media on a prim functions not available");
8735
8736 MediaEntry me = module.GetMediaEntry(m_host, face);
8737
8738 // As per http://wiki.secondlife.com/wiki/LlGetPrimMediaParams
8739 if (null == me)
8740 return new LSL_List();
8741
8742 LSL_List res = new LSL_List();
8743
8744 for (int i = 0; i < rules.Length; i++)
8745 {
8746 int code = (int)rules.GetLSLIntegerItem(i);
8747
8748 switch (code)
8749 {
8750 case ScriptBaseClass.PRIM_MEDIA_ALT_IMAGE_ENABLE:
8751 // Not implemented
8752 res.Add(new LSL_Integer(0));
8753 break;
8754
8755 case ScriptBaseClass.PRIM_MEDIA_CONTROLS:
8756 if (me.Controls == MediaControls.Standard)
8757 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MEDIA_CONTROLS_STANDARD));
8758 else
8759 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MEDIA_CONTROLS_MINI));
8760 break;
8761
8762 case ScriptBaseClass.PRIM_MEDIA_CURRENT_URL:
8763 res.Add(new LSL_String(me.CurrentURL));
8764 break;
8765
8766 case ScriptBaseClass.PRIM_MEDIA_HOME_URL:
8767 res.Add(new LSL_String(me.HomeURL));
8768 break;
8769
8770 case ScriptBaseClass.PRIM_MEDIA_AUTO_LOOP:
8771 res.Add(me.AutoLoop ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
8772 break;
8773
8774 case ScriptBaseClass.PRIM_MEDIA_AUTO_PLAY:
8775 res.Add(me.AutoPlay ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
8776 break;
8777
8778 case ScriptBaseClass.PRIM_MEDIA_AUTO_SCALE:
8779 res.Add(me.AutoScale ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
8780 break;
8781
8782 case ScriptBaseClass.PRIM_MEDIA_AUTO_ZOOM:
8783 res.Add(me.AutoZoom ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
8784 break;
8785
8786 case ScriptBaseClass.PRIM_MEDIA_FIRST_CLICK_INTERACT:
8787 res.Add(me.InteractOnFirstClick ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
8788 break;
8789
8790 case ScriptBaseClass.PRIM_MEDIA_WIDTH_PIXELS:
8791 res.Add(new LSL_Integer(me.Width));
8792 break;
8793
8794 case ScriptBaseClass.PRIM_MEDIA_HEIGHT_PIXELS:
8795 res.Add(new LSL_Integer(me.Height));
8796 break;
8797
8798 case ScriptBaseClass.PRIM_MEDIA_WHITELIST_ENABLE:
8799 res.Add(me.EnableWhiteList ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
8800 break;
8801
8802 case ScriptBaseClass.PRIM_MEDIA_WHITELIST:
8803 string[] urls = (string[])me.WhiteList.Clone();
8804
8805 for (int j = 0; j < urls.Length; j++)
8806 urls[j] = Uri.EscapeDataString(urls[j]);
8807
8808 res.Add(new LSL_String(string.Join(", ", urls)));
8809 break;
8810
8811 case ScriptBaseClass.PRIM_MEDIA_PERMS_INTERACT:
8812 res.Add(new LSL_Integer((int)me.InteractPermissions));
8813 break;
8814
8815 case ScriptBaseClass.PRIM_MEDIA_PERMS_CONTROL:
8816 res.Add(new LSL_Integer((int)me.ControlPermissions));
8817 break;
8059 } 8818 }
8060 } 8819 }
8820
8061 return res; 8821 return res;
8062 } 8822 }
8063 8823
8824 public LSL_Integer llSetPrimMediaParams(int face, LSL_List rules)
8825 {
8826 m_host.AddScriptLPS(1);
8827 ScriptSleep(1000);
8828
8829 // LSL Spec http://wiki.secondlife.com/wiki/LlSetPrimMediaParams says to fail silently if face is invalid
8830 // Assuming silently fail means sending back LSL_STATUS_OK. Ideally, need to check this.
8831 // Don't perform the media check directly
8832 if (face < 0 || face > m_host.GetNumberOfSides() - 1)
8833 return ScriptBaseClass.LSL_STATUS_OK;
8834
8835 return SetPrimMediaParams(face, rules);
8836 }
8837
8838 private LSL_Integer SetPrimMediaParams(int face, LSL_List rules)
8839 {
8840 IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>();
8841 if (null == module)
8842 throw new Exception("Media on a prim functions not available");
8843
8844 MediaEntry me = module.GetMediaEntry(m_host, face);
8845 if (null == me)
8846 me = new MediaEntry();
8847
8848 int i = 0;
8849
8850 while (i < rules.Length - 1)
8851 {
8852 int code = rules.GetLSLIntegerItem(i++);
8853
8854 switch (code)
8855 {
8856 case ScriptBaseClass.PRIM_MEDIA_ALT_IMAGE_ENABLE:
8857 me.EnableAlterntiveImage = (rules.GetLSLIntegerItem(i++) != 0 ? true : false);
8858 break;
8859
8860 case ScriptBaseClass.PRIM_MEDIA_CONTROLS:
8861 int v = rules.GetLSLIntegerItem(i++);
8862 if (ScriptBaseClass.PRIM_MEDIA_CONTROLS_STANDARD == v)
8863 me.Controls = MediaControls.Standard;
8864 else
8865 me.Controls = MediaControls.Mini;
8866 break;
8867
8868 case ScriptBaseClass.PRIM_MEDIA_CURRENT_URL:
8869 me.CurrentURL = rules.GetLSLStringItem(i++);
8870 break;
8871
8872 case ScriptBaseClass.PRIM_MEDIA_HOME_URL:
8873 me.HomeURL = rules.GetLSLStringItem(i++);
8874 break;
8875
8876 case ScriptBaseClass.PRIM_MEDIA_AUTO_LOOP:
8877 me.AutoLoop = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
8878 break;
8879
8880 case ScriptBaseClass.PRIM_MEDIA_AUTO_PLAY:
8881 me.AutoPlay = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
8882 break;
8883
8884 case ScriptBaseClass.PRIM_MEDIA_AUTO_SCALE:
8885 me.AutoScale = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
8886 break;
8887
8888 case ScriptBaseClass.PRIM_MEDIA_AUTO_ZOOM:
8889 me.AutoZoom = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
8890 break;
8891
8892 case ScriptBaseClass.PRIM_MEDIA_FIRST_CLICK_INTERACT:
8893 me.InteractOnFirstClick = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
8894 break;
8895
8896 case ScriptBaseClass.PRIM_MEDIA_WIDTH_PIXELS:
8897 me.Width = (int)rules.GetLSLIntegerItem(i++);
8898 break;
8899
8900 case ScriptBaseClass.PRIM_MEDIA_HEIGHT_PIXELS:
8901 me.Height = (int)rules.GetLSLIntegerItem(i++);
8902 break;
8903
8904 case ScriptBaseClass.PRIM_MEDIA_WHITELIST_ENABLE:
8905 me.EnableWhiteList = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
8906 break;
8907
8908 case ScriptBaseClass.PRIM_MEDIA_WHITELIST:
8909 string[] rawWhiteListUrls = rules.GetLSLStringItem(i++).ToString().Split(new char[] { ',' });
8910 List<string> whiteListUrls = new List<string>();
8911 Array.ForEach(
8912 rawWhiteListUrls, delegate(string rawUrl) { whiteListUrls.Add(rawUrl.Trim()); });
8913 me.WhiteList = whiteListUrls.ToArray();
8914 break;
8915
8916 case ScriptBaseClass.PRIM_MEDIA_PERMS_INTERACT:
8917 me.InteractPermissions = (MediaPermission)(byte)(int)rules.GetLSLIntegerItem(i++);
8918 break;
8919
8920 case ScriptBaseClass.PRIM_MEDIA_PERMS_CONTROL:
8921 me.ControlPermissions = (MediaPermission)(byte)(int)rules.GetLSLIntegerItem(i++);
8922 break;
8923 }
8924 }
8925
8926 module.SetMediaEntry(m_host, face, me);
8927
8928 return ScriptBaseClass.LSL_STATUS_OK;
8929 }
8930
8931 public LSL_Integer llClearPrimMedia(LSL_Integer face)
8932 {
8933 m_host.AddScriptLPS(1);
8934 ScriptSleep(1000);
8935
8936 // LSL Spec http://wiki.secondlife.com/wiki/LlClearPrimMedia says to fail silently if face is invalid
8937 // Assuming silently fail means sending back LSL_STATUS_OK. Ideally, need to check this.
8938 // FIXME: Don't perform the media check directly
8939 if (face < 0 || face > m_host.GetNumberOfSides() - 1)
8940 return ScriptBaseClass.LSL_STATUS_OK;
8941
8942 IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>();
8943 if (null == module)
8944 throw new Exception("Media on a prim functions not available");
8945
8946 module.ClearMediaEntry(m_host, face);
8947
8948 return ScriptBaseClass.LSL_STATUS_OK;
8949 }
8950
8064 // <remarks> 8951 // <remarks>
8065 // <para> 8952 // <para>
8066 // The .NET definition of base 64 is: 8953 // The .NET definition of base 64 is:
@@ -8320,7 +9207,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8320 public LSL_String llGetHTTPHeader(LSL_Key request_id, string header) 9207 public LSL_String llGetHTTPHeader(LSL_Key request_id, string header)
8321 { 9208 {
8322 m_host.AddScriptLPS(1); 9209 m_host.AddScriptLPS(1);
8323 9210
8324 if (m_UrlModule != null) 9211 if (m_UrlModule != null)
8325 return m_UrlModule.GetHttpHeader(new UUID(request_id), header); 9212 return m_UrlModule.GetHttpHeader(new UUID(request_id), header);
8326 return String.Empty; 9213 return String.Empty;
@@ -8352,8 +9239,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8352 // The function returns an ordered list 9239 // The function returns an ordered list
8353 // representing the tokens found in the supplied 9240 // representing the tokens found in the supplied
8354 // sources string. If two successive tokenizers 9241 // sources string. If two successive tokenizers
8355 // are encountered, then a NULL entry is added 9242 // are encountered, then a null-string entry is
8356 // to the list. 9243 // added to the list.
8357 // 9244 //
8358 // It is a precondition that the source and 9245 // It is a precondition that the source and
8359 // toekizer lisst are non-null. If they are null, 9246 // toekizer lisst are non-null. If they are null,
@@ -8361,7 +9248,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8361 // while their lengths are being determined. 9248 // while their lengths are being determined.
8362 // 9249 //
8363 // A small amount of working memoryis required 9250 // A small amount of working memoryis required
8364 // of approximately 8*#tokenizers. 9251 // of approximately 8*#tokenizers + 8*srcstrlen.
8365 // 9252 //
8366 // There are many ways in which this function 9253 // There are many ways in which this function
8367 // can be implemented, this implementation is 9254 // can be implemented, this implementation is
@@ -8377,136 +9264,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8377 // and eliminates redundant tokenizers as soon 9264 // and eliminates redundant tokenizers as soon
8378 // as is possible. 9265 // as is possible.
8379 // 9266 //
8380 // The implementation tries to avoid any copying 9267 // The implementation tries to minimize temporary
8381 // of arrays or other objects. 9268 // garbage generation.
8382 // </remarks> 9269 // </remarks>
8383 9270
8384 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers) 9271 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8385 { 9272 {
8386 int beginning = 0; 9273 return ParseString2List(src, separators, spacers, true);
8387 int srclen = src.Length; 9274 }
8388 int seplen = separators.Length;
8389 object[] separray = separators.Data;
8390 int spclen = spacers.Length;
8391 object[] spcarray = spacers.Data;
8392 int mlen = seplen+spclen;
8393
8394 int[] offset = new int[mlen+1];
8395 bool[] active = new bool[mlen];
8396 9275
8397 int best; 9276 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
8398 int j; 9277 {
9278 int srclen = src.Length;
9279 int seplen = separators.Length;
9280 object[] separray = separators.Data;
9281 int spclen = spacers.Length;
9282 object[] spcarray = spacers.Data;
9283 int dellen = 0;
9284 string[] delarray = new string[seplen+spclen];
8399 9285
8400 // Initial capacity reduces resize cost 9286 int outlen = 0;
9287 string[] outarray = new string[srclen*2+1];
8401 9288
8402 LSL_List tokens = new LSL_List(); 9289 int i, j;
9290 string d;
8403 9291
8404 m_host.AddScriptLPS(1); 9292 m_host.AddScriptLPS(1);
8405 9293
8406 // All entries are initially valid 9294 /*
8407 9295 * Convert separator and spacer lists to C# strings.
8408 for (int i = 0; i < mlen; i++) 9296 * Also filter out null strings so we don't hang.
8409 active[i] = true; 9297 */
8410 9298 for (i = 0; i < seplen; i ++)
8411 offset[mlen] = srclen;
8412
8413 while (beginning < srclen)
8414 { 9299 {
9300 d = separray[i].ToString();
9301 if (d.Length > 0)
9302 {
9303 delarray[dellen++] = d;
9304 }
9305 }
9306 seplen = dellen;
8415 9307
8416 best = mlen; // as bad as it gets 9308 for (i = 0; i < spclen; i ++)
9309 {
9310 d = spcarray[i].ToString();
9311 if (d.Length > 0)
9312 {
9313 delarray[dellen++] = d;
9314 }
9315 }
8417 9316
8418 // Scan for separators 9317 /*
9318 * Scan through source string from beginning to end.
9319 */
9320 for (i = 0;;)
9321 {
8419 9322
8420 for (j = 0; j < seplen; j++) 9323 /*
9324 * Find earliest delimeter in src starting at i (if any).
9325 */
9326 int earliestDel = -1;
9327 int earliestSrc = srclen;
9328 string earliestStr = null;
9329 for (j = 0; j < dellen; j ++)
8421 { 9330 {
8422 if (active[j]) 9331 d = delarray[j];
9332 if (d != null)
8423 { 9333 {
8424 // scan all of the markers 9334 int index = src.IndexOf(d, i);
8425 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9335 if (index < 0)
8426 { 9336 {
8427 // not present at all 9337 delarray[j] = null; // delim nowhere in src, don't check it anymore
8428 active[j] = false;
8429 } 9338 }
8430 else 9339 else if (index < earliestSrc)
8431 { 9340 {
8432 // present and correct 9341 earliestSrc = index; // where delimeter starts in source string
8433 if (offset[j] < offset[best]) 9342 earliestDel = j; // where delimeter is in delarray[]
8434 { 9343 earliestStr = d; // the delimeter string from delarray[]
8435 // closest so far 9344 if (index == i) break; // can't do any better than found at beg of string
8436 best = j;
8437 if (offset[best] == beginning)
8438 break;
8439 }
8440 } 9345 }
8441 } 9346 }
8442 } 9347 }
8443 9348
8444 // Scan for spacers 9349 /*
8445 9350 * Output source string starting at i through start of earliest delimeter.
8446 if (offset[best] != beginning) 9351 */
9352 if (keepNulls || (earliestSrc > i))
8447 { 9353 {
8448 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9354 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8449 {
8450 if (active[j])
8451 {
8452 // scan all of the markers
8453 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8454 {
8455 // not present at all
8456 active[j] = false;
8457 }
8458 else
8459 {
8460 // present and correct
8461 if (offset[j] < offset[best])
8462 {
8463 // closest so far
8464 best = j;
8465 }
8466 }
8467 }
8468 }
8469 } 9355 }
8470 9356
8471 // This is the normal exit from the scanning loop 9357 /*
9358 * If no delimeter found at or after i, we're done scanning.
9359 */
9360 if (earliestDel < 0) break;
8472 9361
8473 if (best == mlen) 9362 /*
9363 * If delimeter was a spacer, output the spacer.
9364 */
9365 if (earliestDel >= seplen)
8474 { 9366 {
8475 // no markers were found on this pass 9367 outarray[outlen++] = earliestStr;
8476 // so we're pretty much done
8477 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8478 break;
8479 } 9368 }
8480 9369
8481 // Otherwise we just add the newly delimited token 9370 /*
8482 // and recalculate where the search should continue. 9371 * Look at rest of src string following delimeter.
8483 9372 */
8484 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9373 i = earliestSrc + earliestStr.Length;
8485
8486 if (best < seplen)
8487 {
8488 beginning = offset[best] + (separray[best].ToString()).Length;
8489 }
8490 else
8491 {
8492 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8493 tokens.Add(new LSL_String(spcarray[best - seplen].ToString()));
8494 }
8495 } 9374 }
8496 9375
8497 // This an awkward an not very intuitive boundary case. If the 9376 /*
8498 // last substring is a tokenizer, then there is an implied trailing 9377 * Make up an exact-sized output array suitable for an LSL_List object.
8499 // null list entry. Hopefully the single comparison will not be too 9378 */
8500 // arduous. Alternatively the 'break' could be replced with a return 9379 object[] outlist = new object[outlen];
8501 // but that's shabby programming. 9380 for (i = 0; i < outlen; i ++)
8502
8503 if (beginning == srclen)
8504 { 9381 {
8505 if (srclen != 0) 9382 outlist[i] = new LSL_String(outarray[i]);
8506 tokens.Add(new LSL_String(""));
8507 } 9383 }
8508 9384 return new LSL_List(outlist);
8509 return tokens;
8510 } 9385 }
8511 9386
8512 public LSL_Integer llGetObjectPermMask(int mask) 9387 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8695,28 +9570,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8695 9570
8696 string reply = String.Empty; 9571 string reply = String.Empty;
8697 9572
8698 GridRegion info = m_ScriptEngine.World.GridService.GetRegionByName(m_ScriptEngine.World.RegionInfo.ScopeID, simulator); 9573 GridRegion info;
9574
9575 if (m_ScriptEngine.World.RegionInfo.RegionName == simulator)
9576 info = new GridRegion(m_ScriptEngine.World.RegionInfo);
9577 else
9578 info = m_ScriptEngine.World.GridService.GetRegionByName(m_ScriptEngine.World.RegionInfo.ScopeID, simulator);
8699 9579
8700 switch (data) 9580 switch (data)
8701 { 9581 {
8702 case 5: // DATA_SIM_POS 9582 case ScriptBaseClass.DATA_SIM_POS:
8703 if (info == null) 9583 if (info == null)
8704 { 9584 {
8705 ScriptSleep(1000); 9585 ScriptSleep(1000);
8706 return UUID.Zero.ToString(); 9586 return UUID.Zero.ToString();
8707 } 9587 }
8708 reply = new LSL_Vector( 9588 reply = new LSL_Vector(
8709 info.RegionLocX * Constants.RegionSize, 9589 info.RegionLocX,
8710 info.RegionLocY * Constants.RegionSize, 9590 info.RegionLocY,
8711 0).ToString(); 9591 0).ToString();
8712 break; 9592 break;
8713 case 6: // DATA_SIM_STATUS 9593 case ScriptBaseClass.DATA_SIM_STATUS:
8714 if (info != null) 9594 if (info != null)
8715 reply = "up"; // Duh! 9595 reply = "up"; // Duh!
8716 else 9596 else
8717 reply = "unknown"; 9597 reply = "unknown";
8718 break; 9598 break;
8719 case 7: // DATA_SIM_RATING 9599 case ScriptBaseClass.DATA_SIM_RATING:
8720 if (info == null) 9600 if (info == null)
8721 { 9601 {
8722 ScriptSleep(1000); 9602 ScriptSleep(1000);
@@ -8732,7 +9612,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8732 else 9612 else
8733 reply = "UNKNOWN"; 9613 reply = "UNKNOWN";
8734 break; 9614 break;
8735 case 128: 9615 case ScriptBaseClass.DATA_SIM_RELEASE:
8736 if (ossl != null) 9616 if (ossl != null)
8737 ossl.CheckThreatLevel(ThreatLevel.High, "llRequestSimulatorData"); 9617 ossl.CheckThreatLevel(ThreatLevel.High, "llRequestSimulatorData");
8738 reply = "OpenSim"; 9618 reply = "OpenSim";
@@ -8803,7 +9683,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8803 } 9683 }
8804 9684
8805 /// <summary> 9685 /// <summary>
8806 /// illListReplaceList removes the sub-list defined by the inclusive indices 9686 /// llListReplaceList removes the sub-list defined by the inclusive indices
8807 /// start and end and inserts the src list in its place. The inclusive 9687 /// start and end and inserts the src list in its place. The inclusive
8808 /// nature of the indices means that at least one element must be deleted 9688 /// nature of the indices means that at least one element must be deleted
8809 /// if the indices are within the bounds of the existing list. I.e. 2,2 9689 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -8860,16 +9740,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8860 // based upon end. Note that if end exceeds the upper 9740 // based upon end. Note that if end exceeds the upper
8861 // bound in this case, the entire destination list 9741 // bound in this case, the entire destination list
8862 // is removed. 9742 // is removed.
8863 else 9743 else if (start == 0)
8864 { 9744 {
8865 if (end + 1 < dest.Length) 9745 if (end + 1 < dest.Length)
8866 {
8867 return src + dest.GetSublist(end + 1, -1); 9746 return src + dest.GetSublist(end + 1, -1);
8868 }
8869 else 9747 else
8870 {
8871 return src; 9748 return src;
8872 } 9749 }
9750 else // Start < 0
9751 {
9752 if (end + 1 < dest.Length)
9753 return dest.GetSublist(end + 1, -1);
9754 else
9755 return new LSL_List();
8873 } 9756 }
8874 } 9757 }
8875 // Finally, if start > end, we strip away a prefix and 9758 // Finally, if start > end, we strip away a prefix and
@@ -8906,7 +9789,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8906 // according to the docs, this command only works if script owner and land owner are the same 9789 // according to the docs, this command only works if script owner and land owner are the same
8907 // lets add estate owners and gods, too, and use the generic permission check. 9790 // lets add estate owners and gods, too, and use the generic permission check.
8908 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 9791 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
8909 if (!World.Permissions.CanEditParcel(m_host.OwnerID, landObject)) return; 9792 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return;
8910 9793
8911 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? 9794 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)?
8912 byte loop = 0; 9795 byte loop = 0;
@@ -9078,25 +9961,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9078 // we send to all 9961 // we send to all
9079 landData.MediaID = new UUID(texture); 9962 landData.MediaID = new UUID(texture);
9080 landData.MediaAutoScale = autoAlign ? (byte)1 : (byte)0; 9963 landData.MediaAutoScale = autoAlign ? (byte)1 : (byte)0;
9081 landData.MediaSize[0] = width; 9964 landData.MediaWidth = width;
9082 landData.MediaSize[1] = height; 9965 landData.MediaHeight = height;
9083 landData.MediaType = mediaType; 9966 landData.MediaType = mediaType;
9084 9967
9085 // do that one last, it will cause a ParcelPropertiesUpdate 9968 // do that one last, it will cause a ParcelPropertiesUpdate
9086 landObject.SetMediaUrl(url); 9969 landObject.SetMediaUrl(url);
9087 9970
9088 // now send to all (non-child) agents 9971 // now send to all (non-child) agents in the parcel
9089 List<ScenePresence> agents = World.GetAvatars(); 9972 World.ForEachRootScenePresence(delegate(ScenePresence sp)
9090 foreach (ScenePresence agent in agents)
9091 { 9973 {
9092 agent.ControllingClient.SendParcelMediaUpdate(landData.MediaURL, 9974 if (sp.currentParcelUUID == landData.GlobalID)
9093 landData.MediaID, 9975 {
9094 landData.MediaAutoScale, 9976 sp.ControllingClient.SendParcelMediaUpdate(landData.MediaURL,
9095 mediaType, 9977 landData.MediaID,
9096 description, 9978 landData.MediaAutoScale,
9097 width, height, 9979 mediaType,
9098 loop); 9980 description,
9099 } 9981 width, height,
9982 loop);
9983 }
9984 });
9100 } 9985 }
9101 else if (!presence.IsChildAgent) 9986 else if (!presence.IsChildAgent)
9102 { 9987 {
@@ -9116,14 +10001,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9116 // the commandList contained a start/stop/... command, too 10001 // the commandList contained a start/stop/... command, too
9117 if (presence == null) 10002 if (presence == null)
9118 { 10003 {
9119 // send to all (non-child) agents 10004 // send to all (non-child) agents in the parcel
9120 List<ScenePresence> agents = World.GetAvatars(); 10005 World.ForEachRootScenePresence(delegate(ScenePresence sp)
9121 foreach (ScenePresence agent in agents)
9122 { 10006 {
9123 agent.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this? 10007 if (sp.currentParcelUUID == landData.GlobalID)
9124 (ParcelMediaCommandEnum)commandToSend, 10008 {
9125 time); 10009 sp.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this?
9126 } 10010 (ParcelMediaCommandEnum)commandToSend,
10011 time);
10012 }
10013 });
9127 } 10014 }
9128 else if (!presence.IsChildAgent) 10015 else if (!presence.IsChildAgent)
9129 { 10016 {
@@ -9146,7 +10033,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9146 10033
9147 if (aList.Data[i] != null) 10034 if (aList.Data[i] != null)
9148 { 10035 {
9149 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10036 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9150 { 10037 {
9151 case ParcelMediaCommandEnum.Url: 10038 case ParcelMediaCommandEnum.Url:
9152 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10039 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9161,8 +10048,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9161 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaType)); 10048 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaType));
9162 break; 10049 break;
9163 case ParcelMediaCommandEnum.Size: 10050 case ParcelMediaCommandEnum.Size:
9164 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaSize[0])); 10051 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaWidth));
9165 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaSize[1])); 10052 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaHeight));
9166 break; 10053 break;
9167 default: 10054 default:
9168 ParcelMediaCommandEnum mediaCommandEnum = ParcelMediaCommandEnum.Url; 10055 ParcelMediaCommandEnum mediaCommandEnum = ParcelMediaCommandEnum.Url;
@@ -9216,11 +10103,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9216 } 10103 }
9217 } 10104 }
9218 int[] nPrice = new int[5]; 10105 int[] nPrice = new int[5];
9219 nPrice[0]=price; 10106 nPrice[0] = price;
9220 nPrice[1] = (LSL_Integer)quick_pay_buttons.Data[0]; 10107 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9221 nPrice[2] = (LSL_Integer)quick_pay_buttons.Data[1]; 10108 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9222 nPrice[3] = (LSL_Integer)quick_pay_buttons.Data[2]; 10109 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9223 nPrice[4] = (LSL_Integer)quick_pay_buttons.Data[3]; 10110 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
9224 m_host.ParentGroup.RootPart.PayPrice = nPrice; 10111 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9225 m_host.ParentGroup.HasGroupChanged = true; 10112 m_host.ParentGroup.HasGroupChanged = true;
9226 } 10113 }
@@ -9338,8 +10225,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9338 { 10225 {
9339 m_host.AddScriptLPS(1); 10226 m_host.AddScriptLPS(1);
9340 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10227 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9341 if (detectedParams == null) return; // only works on the first detected avatar 10228 if (detectedParams == null)
9342 10229 {
10230 if (m_host.ParentGroup.IsAttachment == true)
10231 {
10232 detectedParams = new DetectParams();
10233 detectedParams.Key = m_host.OwnerID;
10234 }
10235 else
10236 {
10237 return;
10238 }
10239 }
10240
9343 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10241 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9344 if (avatar != null) 10242 if (avatar != null)
9345 { 10243 {
@@ -9347,6 +10245,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9347 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10245 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9348 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10246 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9349 } 10247 }
10248
9350 ScriptSleep(1000); 10249 ScriptSleep(1000);
9351 } 10250 }
9352 10251
@@ -9354,16 +10253,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9354 { 10253 {
9355 m_host.AddScriptLPS(1); 10254 m_host.AddScriptLPS(1);
9356 UUID key; 10255 UUID key;
9357 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).LandData; 10256 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
9358 if (land.OwnerID == m_host.OwnerID) 10257 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned))
9359 { 10258 {
9360 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); 10259 ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
9361 if (UUID.TryParse(avatar, out key)) 10260 if (UUID.TryParse(avatar, out key))
9362 { 10261 {
9363 entry.AgentID = key; 10262 if (land.LandData.ParcelAccessList.FindIndex(
9364 entry.Flags = AccessList.Ban; 10263 delegate(ParcelManager.ParcelAccessEntry e)
9365 entry.Time = DateTime.Now.AddHours(hours); 10264 {
9366 land.ParcelAccessList.Add(entry); 10265 if (e.AgentID == key && e.Flags == AccessList.Ban)
10266 return true;
10267 return false;
10268 }) == -1)
10269 {
10270 entry.AgentID = key;
10271 entry.Flags = AccessList.Ban;
10272 entry.Time = DateTime.Now.AddHours(hours);
10273 land.LandData.ParcelAccessList.Add(entry);
10274 }
9367 } 10275 }
9368 } 10276 }
9369 ScriptSleep(100); 10277 ScriptSleep(100);
@@ -9373,19 +10281,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9373 { 10281 {
9374 m_host.AddScriptLPS(1); 10282 m_host.AddScriptLPS(1);
9375 UUID key; 10283 UUID key;
9376 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).LandData; 10284 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
9377 if (land.OwnerID == m_host.OwnerID) 10285 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed))
9378 { 10286 {
9379 if (UUID.TryParse(avatar, out key)) 10287 if (UUID.TryParse(avatar, out key))
9380 { 10288 {
9381 foreach (ParcelManager.ParcelAccessEntry entry in land.ParcelAccessList) 10289 int idx = land.LandData.ParcelAccessList.FindIndex(
9382 { 10290 delegate(ParcelManager.ParcelAccessEntry e)
9383 if (entry.AgentID == key && entry.Flags == AccessList.Access) 10291 {
9384 { 10292 if (e.AgentID == key && e.Flags == AccessList.Access)
9385 land.ParcelAccessList.Remove(entry); 10293 return true;
9386 break; 10294 return false;
9387 } 10295 });
9388 } 10296
10297 if (idx != -1)
10298 land.LandData.ParcelAccessList.RemoveAt(idx);
9389 } 10299 }
9390 } 10300 }
9391 ScriptSleep(100); 10301 ScriptSleep(100);
@@ -9395,19 +10305,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9395 { 10305 {
9396 m_host.AddScriptLPS(1); 10306 m_host.AddScriptLPS(1);
9397 UUID key; 10307 UUID key;
9398 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).LandData; 10308 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
9399 if (land.OwnerID == m_host.OwnerID) 10309 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned))
9400 { 10310 {
9401 if (UUID.TryParse(avatar, out key)) 10311 if (UUID.TryParse(avatar, out key))
9402 { 10312 {
9403 foreach (ParcelManager.ParcelAccessEntry entry in land.ParcelAccessList) 10313 int idx = land.LandData.ParcelAccessList.FindIndex(
9404 { 10314 delegate(ParcelManager.ParcelAccessEntry e)
9405 if (entry.AgentID == key && entry.Flags == AccessList.Ban) 10315 {
9406 { 10316 if (e.AgentID == key && e.Flags == AccessList.Ban)
9407 land.ParcelAccessList.Remove(entry); 10317 return true;
9408 break; 10318 return false;
9409 } 10319 });
9410 } 10320
10321 if (idx != -1)
10322 land.LandData.ParcelAccessList.RemoveAt(idx);
9411 } 10323 }
9412 } 10324 }
9413 ScriptSleep(100); 10325 ScriptSleep(100);
@@ -9449,12 +10361,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9449 10361
9450 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10362 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9451 object[] data = rules.Data; 10363 object[] data = rules.Data;
9452 for (int i = 0; i < data.Length; ++i) { 10364 for (int i = 0; i < data.Length; ++i)
10365 {
9453 int type = Convert.ToInt32(data[i++].ToString()); 10366 int type = Convert.ToInt32(data[i++].ToString());
9454 if (i >= data.Length) break; // odd number of entries => ignore the last 10367 if (i >= data.Length) break; // odd number of entries => ignore the last
9455 10368
9456 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10369 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9457 switch (type) { 10370 switch (type)
10371 {
9458 case ScriptBaseClass.CAMERA_FOCUS: 10372 case ScriptBaseClass.CAMERA_FOCUS:
9459 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10373 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9460 case ScriptBaseClass.CAMERA_POSITION: 10374 case ScriptBaseClass.CAMERA_POSITION:
@@ -9569,19 +10483,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9569 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10483 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9570 { 10484 {
9571 m_host.AddScriptLPS(1); 10485 m_host.AddScriptLPS(1);
9572 string ret = String.Empty; 10486
9573 string src1 = llBase64ToString(str1); 10487 if (str1 == String.Empty)
9574 string src2 = llBase64ToString(str2); 10488 return String.Empty;
9575 int c = 0; 10489 if (str2 == String.Empty)
9576 for (int i = 0; i < src1.Length; i++) 10490 return str1;
10491
10492 int len = str2.Length;
10493 if ((len % 4) != 0) // LL is EVIL!!!!
9577 { 10494 {
9578 ret += (char) (src1[i] ^ src2[c]); 10495 while (str2.EndsWith("="))
10496 str2 = str2.Substring(0, str2.Length - 1);
10497
10498 len = str2.Length;
10499 int mod = len % 4;
10500
10501 if (mod == 1)
10502 str2 = str2.Substring(0, str2.Length - 1);
10503 else if (mod == 2)
10504 str2 += "==";
10505 else if (mod == 3)
10506 str2 += "=";
10507 }
9579 10508
9580 c++; 10509 byte[] data1;
9581 if (c >= src2.Length) 10510 byte[] data2;
9582 c = 0; 10511 try
10512 {
10513 data1 = Convert.FromBase64String(str1);
10514 data2 = Convert.FromBase64String(str2);
9583 } 10515 }
9584 return llStringToBase64(ret); 10516 catch (Exception)
10517 {
10518 return new LSL_String(String.Empty);
10519 }
10520
10521 byte[] d2 = new Byte[data1.Length];
10522 int pos = 0;
10523
10524 if (data1.Length <= data2.Length)
10525 {
10526 Array.Copy(data2, 0, d2, 0, data1.Length);
10527 }
10528 else
10529 {
10530 while (pos < data1.Length)
10531 {
10532 len = data1.Length - pos;
10533 if (len > data2.Length)
10534 len = data2.Length;
10535
10536 Array.Copy(data2, 0, d2, pos, len);
10537 pos += len;
10538 }
10539 }
10540
10541 for (pos = 0 ; pos < data1.Length ; pos++ )
10542 data1[pos] ^= d2[pos];
10543
10544 return Convert.ToBase64String(data1);
9585 } 10545 }
9586 10546
9587 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10547 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9618,8 +10578,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9618 IConfigSource config = m_ScriptEngine.ConfigSource; 10578 IConfigSource config = m_ScriptEngine.ConfigSource;
9619 if (config.Configs["Network"] != null) 10579 if (config.Configs["Network"] != null)
9620 { 10580 {
9621 shard = config.Configs["Network"].GetString(
9622 "user_server_url", "http://127.0.0.1:" + ConfigSettings.DefaultUserServerHttpPort.ToString());
9623 shard = config.Configs["Network"].GetString("shard", shard); 10581 shard = config.Configs["Network"].GetString("shard", shard);
9624 } 10582 }
9625 10583
@@ -9640,12 +10598,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9640 Regex r = new Regex(authregex); 10598 Regex r = new Regex(authregex);
9641 int[] gnums = r.GetGroupNumbers(); 10599 int[] gnums = r.GetGroupNumbers();
9642 Match m = r.Match(url); 10600 Match m = r.Match(url);
9643 if (m.Success) { 10601 if (m.Success)
9644 for (int i = 1; i < gnums.Length; i++) { 10602 {
10603 for (int i = 1; i < gnums.Length; i++)
10604 {
9645 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10605 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9646 //CaptureCollection cc = g.Captures; 10606 //CaptureCollection cc = g.Captures;
9647 } 10607 }
9648 if (m.Groups.Count == 5) { 10608 if (m.Groups.Count == 5)
10609 {
9649 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10610 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
9650 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10611 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9651 } 10612 }
@@ -9709,63 +10670,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9709 public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide) 10670 public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide)
9710 { 10671 {
9711 m_host.AddScriptLPS(1); 10672 m_host.AddScriptLPS(1);
10673
10674 ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y);
9712 10675
9713 LandData land = World.GetLandData((float)pos.x, (float)pos.y); 10676 if (lo == null)
9714
9715 if (land == null)
9716 {
9717 return 0; 10677 return 0;
9718 } 10678
10679 IPrimCounts pc = lo.PrimCounts;
9719 10680
9720 else 10681 if (sim_wide != ScriptBaseClass.FALSE)
9721 { 10682 {
9722 if (sim_wide != 0) 10683 if (category == ScriptBaseClass.PARCEL_COUNT_TOTAL)
9723 { 10684 {
9724 if (category == 0) 10685 return pc.Simulator;
9725 {
9726 return land.SimwidePrims;
9727 }
9728
9729 else
9730 {
9731 //public int simwideArea = 0;
9732 return 0;
9733 }
9734 } 10686 }
9735
9736 else 10687 else
9737 { 10688 {
9738 if (category == 0)//Total Prims 10689 // counts not implemented yet
9739 { 10690 return 0;
9740 return 0;//land.
9741 }
9742
9743 else if (category == 1)//Owner Prims
9744 {
9745 return land.OwnerPrims;
9746 }
9747
9748 else if (category == 2)//Group Prims
9749 {
9750 return land.GroupPrims;
9751 }
9752
9753 else if (category == 3)//Other Prims
9754 {
9755 return land.OtherPrims;
9756 }
9757
9758 else if (category == 4)//Selected
9759 {
9760 return land.SelectedPrims;
9761 }
9762
9763 else if (category == 5)//Temp
9764 {
9765 return 0;//land.
9766 }
9767 } 10691 }
9768 } 10692 }
10693 else
10694 {
10695 if (category == ScriptBaseClass.PARCEL_COUNT_TOTAL)
10696 return pc.Total;
10697 else if (category == ScriptBaseClass.PARCEL_COUNT_OWNER)
10698 return pc.Owner;
10699 else if (category == ScriptBaseClass.PARCEL_COUNT_GROUP)
10700 return pc.Group;
10701 else if (category == ScriptBaseClass.PARCEL_COUNT_OTHER)
10702 return pc.Others;
10703 else if (category == ScriptBaseClass.PARCEL_COUNT_SELECTED)
10704 return pc.Selected;
10705 else if (category == ScriptBaseClass.PARCEL_COUNT_TEMP)
10706 return 0; // counts not implemented yet
10707 }
10708
9769 return 0; 10709 return 0;
9770 } 10710 }
9771 10711
@@ -9778,8 +10718,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9778 { 10718 {
9779 foreach (KeyValuePair<UUID, int> detectedParams in land.GetLandObjectOwners()) 10719 foreach (KeyValuePair<UUID, int> detectedParams in land.GetLandObjectOwners())
9780 { 10720 {
9781 ret.Add(detectedParams.Key.ToString()); 10721 ret.Add(new LSL_String(detectedParams.Key.ToString()));
9782 ret.Add(detectedParams.Value); 10722 ret.Add(new LSL_Integer(detectedParams.Value));
9783 } 10723 }
9784 } 10724 }
9785 ScriptSleep(2000); 10725 ScriptSleep(2000);
@@ -9803,31 +10743,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9803 public LSL_Integer llGetParcelMaxPrims(LSL_Vector pos, int sim_wide) 10743 public LSL_Integer llGetParcelMaxPrims(LSL_Vector pos, int sim_wide)
9804 { 10744 {
9805 m_host.AddScriptLPS(1); 10745 m_host.AddScriptLPS(1);
9806 // Alondria: This currently just is utilizing the normal grid's 0.22 prims/m2 calculation
9807 // Which probably will be irrelevent in OpenSim....
9808 LandData land = World.GetLandData((float)pos.x, (float)pos.y);
9809 10746
9810 float bonusfactor = (float)World.RegionInfo.RegionSettings.ObjectBonus; 10747 ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y);
9811 10748
9812 if (land == null) 10749 if (lo == null)
9813 {
9814 return 0; 10750 return 0;
9815 }
9816 10751
9817 if (sim_wide != 0) 10752 if (sim_wide != 0)
9818 { 10753 return lo.GetSimulatorMaxPrimCount();
9819 decimal v = land.SimwideArea * (decimal)(0.22) * (decimal)bonusfactor;
9820
9821 return (int)v;
9822 }
9823
9824 else 10754 else
9825 { 10755 return lo.GetParcelMaxPrimCount();
9826 decimal v = land.Area * (decimal)(0.22) * (decimal)bonusfactor;
9827
9828 return (int)v;
9829 }
9830
9831 } 10756 }
9832 10757
9833 public LSL_List llGetParcelDetails(LSL_Vector pos, LSL_List param) 10758 public LSL_List llGetParcelDetails(LSL_Vector pos, LSL_List param)
@@ -9844,22 +10769,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9844 switch (o.ToString()) 10769 switch (o.ToString())
9845 { 10770 {
9846 case "0": 10771 case "0":
9847 ret = ret + new LSL_List(land.Name); 10772 ret.Add(new LSL_String(land.Name));
9848 break; 10773 break;
9849 case "1": 10774 case "1":
9850 ret = ret + new LSL_List(land.Description); 10775 ret.Add(new LSL_String(land.Description));
9851 break; 10776 break;
9852 case "2": 10777 case "2":
9853 ret = ret + new LSL_List(land.OwnerID.ToString()); 10778 ret.Add(new LSL_Key(land.OwnerID.ToString()));
9854 break; 10779 break;
9855 case "3": 10780 case "3":
9856 ret = ret + new LSL_List(land.GroupID.ToString()); 10781 ret.Add(new LSL_Key(land.GroupID.ToString()));
9857 break; 10782 break;
9858 case "4": 10783 case "4":
9859 ret = ret + new LSL_List(land.Area); 10784 ret.Add(new LSL_Integer(land.Area));
10785 break;
10786 case "5":
10787 ret.Add(new LSL_Key(land.GlobalID.ToString()));
9860 break; 10788 break;
9861 default: 10789 default:
9862 ret = ret + new LSL_List(0); 10790 ret.Add(new LSL_Integer(0));
9863 break; 10791 break;
9864 } 10792 }
9865 } 10793 }
@@ -9878,6 +10806,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9878 public LSL_List llGetObjectDetails(string id, LSL_List args) 10806 public LSL_List llGetObjectDetails(string id, LSL_List args)
9879 { 10807 {
9880 m_host.AddScriptLPS(1); 10808 m_host.AddScriptLPS(1);
10809
9881 LSL_List ret = new LSL_List(); 10810 LSL_List ret = new LSL_List();
9882 UUID key = new UUID(); 10811 UUID key = new UUID();
9883 if (UUID.TryParse(id, out key)) 10812 if (UUID.TryParse(id, out key))
@@ -9888,72 +10817,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9888 { 10817 {
9889 foreach (object o in args.Data) 10818 foreach (object o in args.Data)
9890 { 10819 {
9891 switch (o.ToString()) 10820 switch (int.Parse(o.ToString()))
9892 { 10821 {
9893 case "1": 10822 case ScriptBaseClass.OBJECT_NAME:
9894 ret.Add(av.Firstname + " " + av.Lastname); 10823 ret.Add(new LSL_String(av.Firstname + " " + av.Lastname));
9895 break; 10824 break;
9896 case "2": 10825 case ScriptBaseClass.OBJECT_DESC:
9897 ret.Add(""); 10826 ret.Add(new LSL_String(""));
9898 break; 10827 break;
9899 case "3": 10828 case ScriptBaseClass.OBJECT_POS:
9900 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 10829 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z));
9901 break; 10830 break;
9902 case "4": 10831 case ScriptBaseClass.OBJECT_ROT:
9903 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 10832 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W));
9904 break; 10833 break;
9905 case "5": 10834 case ScriptBaseClass.OBJECT_VELOCITY:
9906 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 10835 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z));
9907 break; 10836 break;
9908 case "6": 10837 case ScriptBaseClass.OBJECT_OWNER:
9909 ret.Add(id); 10838 ret.Add(new LSL_String(id));
9910 break; 10839 break;
9911 case "7": 10840 case ScriptBaseClass.OBJECT_GROUP:
9912 ret.Add(UUID.Zero.ToString()); 10841 ret.Add(new LSL_String(UUID.Zero.ToString()));
9913 break; 10842 break;
9914 case "8": 10843 case ScriptBaseClass.OBJECT_CREATOR:
9915 ret.Add(UUID.Zero.ToString()); 10844 ret.Add(new LSL_String(UUID.Zero.ToString()));
9916 break; 10845 break;
9917 } 10846 }
9918 } 10847 }
10848
9919 return ret; 10849 return ret;
9920 } 10850 }
10851
9921 SceneObjectPart obj = World.GetSceneObjectPart(key); 10852 SceneObjectPart obj = World.GetSceneObjectPart(key);
9922 if (obj != null) 10853 if (obj != null)
9923 { 10854 {
9924 foreach (object o in args.Data) 10855 foreach (object o in args.Data)
9925 { 10856 {
9926 switch (o.ToString()) 10857 switch (int.Parse(o.ToString()))
9927 { 10858 {
9928 case "1": 10859 case ScriptBaseClass.OBJECT_NAME:
9929 ret.Add(obj.Name); 10860 ret.Add(new LSL_String(obj.Name));
9930 break; 10861 break;
9931 case "2": 10862 case ScriptBaseClass.OBJECT_DESC:
9932 ret.Add(obj.Description); 10863 ret.Add(new LSL_String(obj.Description));
9933 break; 10864 break;
9934 case "3": 10865 case ScriptBaseClass.OBJECT_POS:
9935 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 10866 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z));
9936 break; 10867 break;
9937 case "4": 10868 case ScriptBaseClass.OBJECT_ROT:
9938 ret.Add(new LSL_Rotation(obj.RotationOffset.X, obj.RotationOffset.Y, obj.RotationOffset.Z, obj.RotationOffset.W)); 10869 ret.Add(new LSL_Rotation(obj.RotationOffset.X, obj.RotationOffset.Y, obj.RotationOffset.Z, obj.RotationOffset.W));
9939 break; 10870 break;
9940 case "5": 10871 case ScriptBaseClass.OBJECT_VELOCITY:
9941 ret.Add(new LSL_Vector(obj.Velocity.X, obj.Velocity.Y, obj.Velocity.Z)); 10872 ret.Add(new LSL_Vector(obj.Velocity.X, obj.Velocity.Y, obj.Velocity.Z));
9942 break; 10873 break;
9943 case "6": 10874 case ScriptBaseClass.OBJECT_OWNER:
9944 ret.Add(obj.OwnerID.ToString()); 10875 ret.Add(new LSL_String(obj.OwnerID.ToString()));
9945 break; 10876 break;
9946 case "7": 10877 case ScriptBaseClass.OBJECT_GROUP:
9947 ret.Add(obj.GroupID.ToString()); 10878 ret.Add(new LSL_String(obj.GroupID.ToString()));
9948 break; 10879 break;
9949 case "8": 10880 case ScriptBaseClass.OBJECT_CREATOR:
9950 ret.Add(obj.CreatorID.ToString()); 10881 ret.Add(new LSL_String(obj.CreatorID.ToString()));
9951 break; 10882 break;
9952 } 10883 }
9953 } 10884 }
10885
9954 return ret; 10886 return ret;
9955 } 10887 }
9956 } 10888 }
10889
9957 return new LSL_List(); 10890 return new LSL_List();
9958 } 10891 }
9959 10892
@@ -10131,6 +11064,413 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10131 ScriptSleep(100); 11064 ScriptSleep(100);
10132 return tid.ToString(); 11065 return tid.ToString();
10133 } 11066 }
11067
11068 public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules)
11069 {
11070 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim));
11071 if (obj == null)
11072 return;
11073
11074 if (obj.OwnerID != m_host.OwnerID)
11075 return;
11076
11077 SetPrimParams(obj, rules);
11078 }
11079
11080 public LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules)
11081 {
11082 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim));
11083 if (obj == null)
11084 return new LSL_List();
11085
11086 if (obj.OwnerID != m_host.OwnerID)
11087 return new LSL_List();
11088
11089 return GetLinkPrimitiveParams(obj, rules);
11090 }
11091
11092 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
11093 {
11094 List<SceneObjectPart> parts = GetLinkParts(link);
11095 if (parts.Count < 1)
11096 return 0;
11097
11098 return GetNumberOfSides(parts[0]);
11099 }
11100
11101 private string Name2Username(string name)
11102 {
11103 string[] parts = name.Split(new char[] {' '});
11104 if (parts.Length < 2)
11105 return name.ToLower();
11106 if (parts[1] == "Resident")
11107 return parts[0].ToLower();
11108
11109 return name.Replace(" ", ".").ToLower();
11110 }
11111
11112 public LSL_String llGetUsername(string id)
11113 {
11114 return Name2Username(llKey2Name(id));
11115 }
11116
11117 public LSL_String llRequestUsername(string id)
11118 {
11119 UUID rq = UUID.Random();
11120
11121 AsyncCommands.DataserverPlugin.RegisterRequest(m_localID, m_itemID, rq.ToString());
11122
11123 AsyncCommands.DataserverPlugin.DataserverReply(rq.ToString(), Name2Username(llKey2Name(id)));
11124
11125 return rq.ToString();
11126 }
11127
11128 public LSL_String llGetDisplayName(string id)
11129 {
11130 return llKey2Name(id);
11131 }
11132
11133 public LSL_String llRequestDisplayName(string id)
11134 {
11135 UUID rq = UUID.Random();
11136
11137 AsyncCommands.DataserverPlugin.RegisterRequest(m_localID, m_itemID, rq.ToString());
11138
11139 AsyncCommands.DataserverPlugin.DataserverReply(rq.ToString(), llKey2Name(id));
11140
11141 return rq.ToString();
11142 }
11143
11144 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11145 {
11146 m_SayShoutCount = 0;
11147 }
11148 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11149 {
11150 m_host.AddScriptLPS(1);
11151
11152 Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z);
11153 Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z);
11154 Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z);
11155
11156 int count = 0;
11157// int detectPhantom = 0;
11158 int dataFlags = 0;
11159 int rejectTypes = 0;
11160
11161 for (int i = 0; i < options.Length; i += 2)
11162 {
11163 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
11164 {
11165 count = options.GetLSLIntegerItem(i + 1);
11166 }
11167// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
11168// {
11169// detectPhantom = options.GetLSLIntegerItem(i + 1);
11170// }
11171 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
11172 {
11173 dataFlags = options.GetLSLIntegerItem(i + 1);
11174 }
11175 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
11176 {
11177 rejectTypes = options.GetLSLIntegerItem(i + 1);
11178 }
11179 }
11180
11181 LSL_List list = new LSL_List();
11182 List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count);
11183
11184 double distance = Util.GetDistanceTo(startvector, endvector);
11185
11186 if (distance == 0)
11187 distance = 0.001;
11188
11189 Vector3 posToCheck = startvector;
11190 ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
11191
11192 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
11193 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
11194 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
11195 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11196
11197 for (float i = 0; i <= distance; i += 0.1f)
11198 {
11199 posToCheck = startvector + (dir * (i / (float)distance));
11200
11201 if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z)
11202 {
11203 ContactResult result = new ContactResult();
11204 result.ConsumerID = 0;
11205 result.Depth = 0;
11206 result.Normal = Vector3.Zero;
11207 result.Pos = posToCheck;
11208 results.Add(result);
11209 checkTerrain = false;
11210 }
11211
11212 if (checkAgents)
11213 {
11214 World.ForEachRootScenePresence(delegate(ScenePresence sp)
11215 {
11216 if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X))
11217 {
11218 ContactResult result = new ContactResult ();
11219 result.ConsumerID = sp.LocalId;
11220 result.Depth = 0;
11221 result.Normal = Vector3.Zero;
11222 result.Pos = posToCheck;
11223 results.Add(result);
11224 }
11225 });
11226 }
11227 }
11228
11229 int refcount = 0;
11230 foreach (ContactResult result in results)
11231 {
11232 if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND)
11233 == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0)
11234 continue;
11235
11236 ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID);
11237
11238 if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS)
11239 entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents
11240
11241 if (entity == null)
11242 {
11243 list.Add(UUID.Zero);
11244
11245 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
11246 list.Add(0);
11247
11248 list.Add(result.Pos);
11249
11250 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
11251 list.Add(result.Normal);
11252
11253 continue; //Can't find it, so add UUID.Zero
11254 }
11255
11256 /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity &&
11257 ((ISceneChildEntity)intersection.obj).PhysActor == null)
11258 continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects
11259
11260 if (entity is SceneObjectPart)
11261 {
11262 if (((SceneObjectPart)entity).PhysActor != null && ((SceneObjectPart)entity).PhysActor.IsPhysical)
11263 {
11264 if (!checkPhysical)
11265 continue;
11266 }
11267 else
11268 {
11269 if (!checkNonPhysical)
11270 continue;
11271 }
11272 }
11273
11274 refcount++;
11275 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart)
11276 list.Add(((SceneObjectPart)entity).ParentGroup.UUID);
11277 else
11278 list.Add(entity.UUID);
11279
11280 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
11281 {
11282 if (entity is SceneObjectPart)
11283 list.Add(((SceneObjectPart)entity).LinkNum);
11284 else
11285 list.Add(0);
11286 }
11287
11288 list.Add(result.Pos);
11289
11290 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
11291 list.Add(result.Normal);
11292 }
11293
11294 list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED
11295
11296 return list;
11297 }
11298
11299 #region Not Implemented
11300 //
11301 // Listing the unimplemented lsl functions here, please move
11302 // them from this region as they are completed
11303 //
11304
11305 public void llGetEnv(LSL_String name)
11306 {
11307 m_host.AddScriptLPS(1);
11308 NotImplemented("llGetEnv");
11309 }
11310
11311 public void llGetSPMaxMemory()
11312 {
11313 m_host.AddScriptLPS(1);
11314 NotImplemented("llGetSPMaxMemory");
11315 }
11316
11317 public virtual LSL_Integer llGetUsedMemory()
11318 {
11319 m_host.AddScriptLPS(1);
11320 NotImplemented("llGetUsedMemory");
11321 return 0;
11322 }
11323
11324 public void llScriptProfiler(LSL_Integer flags)
11325 {
11326 m_host.AddScriptLPS(1);
11327 //NotImplemented("llScriptProfiler");
11328 }
11329
11330 public void llSetSoundQueueing(int queue)
11331 {
11332 m_host.AddScriptLPS(1);
11333 }
11334
11335 public void llCollisionSprite(string impact_sprite)
11336 {
11337 m_host.AddScriptLPS(1);
11338 NotImplemented("llCollisionSprite");
11339 }
11340
11341 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11342 {
11343 m_host.AddScriptLPS(1);
11344
11345 if (!World.Permissions.IsGod(m_host.OwnerID))
11346 NotImplemented("llGodLikeRezObject");
11347
11348 AssetBase rezAsset = World.AssetService.Get(inventory);
11349 if (rezAsset == null)
11350 {
11351 llSay(0, "Asset not found");
11352 return;
11353 }
11354
11355 SceneObjectGroup group = null;
11356
11357 try
11358 {
11359 string xmlData = Utils.BytesToString(rezAsset.Data);
11360 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
11361 }
11362 catch
11363 {
11364 llSay(0, "Asset not found");
11365 return;
11366 }
11367
11368 if (group == null)
11369 {
11370 llSay(0, "Asset not found");
11371 return;
11372 }
11373
11374 group.RootPart.AttachPoint = group.RootPart.Shape.State;
11375 group.RootPart.AttachOffset = group.AbsolutePosition;
11376
11377 group.ResetIDs();
11378
11379 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
11380 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
11381 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
11382 group.ScheduleGroupForFullUpdate();
11383
11384 // objects rezzed with this method are die_at_edge by default.
11385 group.RootPart.SetDieAtEdge(true);
11386
11387 group.ResumeScripts();
11388
11389 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
11390 "object_rez", new Object[] {
11391 new LSL_String(
11392 group.RootPart.UUID.ToString()) },
11393 new DetectParams[0]));
11394 }
11395
11396 public LSL_String llTransferLindenDollars(string destination, int amount)
11397 {
11398 UUID txn = UUID.Random();
11399
11400 Util.FireAndForget(delegate(object x)
11401 {
11402 int replycode = 0;
11403 string replydata = destination + "," + amount.ToString();
11404
11405 try
11406 {
11407 UUID invItemID=InventorySelf();
11408 if (invItemID == UUID.Zero)
11409 {
11410 replydata = "SERVICE_ERROR";
11411 return;
11412 }
11413
11414 m_host.AddScriptLPS(1);
11415
11416 m_host.TaskInventory.LockItemsForRead(true);
11417 TaskInventoryItem item = m_host.TaskInventory[invItemID];
11418 m_host.TaskInventory.LockItemsForRead(false);
11419
11420 if (item.PermsGranter == UUID.Zero)
11421 {
11422 replydata = "MISSING_PERMISSION_DEBIT";
11423 return;
11424 }
11425
11426 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
11427 {
11428 replydata = "MISSING_PERMISSION_DEBIT";
11429 return;
11430 }
11431
11432 UUID toID = new UUID();
11433
11434 if (!UUID.TryParse(destination, out toID))
11435 {
11436 replydata = "INVALID_AGENT";
11437 return;
11438 }
11439
11440 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
11441
11442 if (money == null)
11443 {
11444 replydata = "TRANSFERS_DISABLED";
11445 return;
11446 }
11447
11448 bool result = money.ObjectGiveMoney(
11449 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
11450
11451 if (result)
11452 {
11453 replycode = 1;
11454 return;
11455 }
11456
11457 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
11458 }
11459 finally
11460 {
11461 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
11462 "transaction_result", new Object[] {
11463 new LSL_String(txn.ToString()),
11464 new LSL_Integer(replycode),
11465 new LSL_String(replydata) },
11466 new DetectParams[0]));
11467 }
11468 });
11469
11470 return txn.ToString();
11471 }
11472
11473 #endregion
10134 } 11474 }
10135 11475
10136 public class NotecardCache 11476 public class NotecardCache
@@ -10180,9 +11520,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10180 } 11520 }
10181 } 11521 }
10182 11522
10183 public static string GetLine(UUID assetID, int line, int maxLength) 11523 /// <summary>
11524 /// Get a notecard line.
11525 /// </summary>
11526 /// <param name="assetID"></param>
11527 /// <param name="line">Lines start at index 0</param>
11528 /// <returns></returns>
11529 public static string GetLine(UUID assetID, int lineNumber)
10184 { 11530 {
10185 if (line < 0) 11531 if (lineNumber < 0)
10186 return ""; 11532 return "";
10187 11533
10188 string data; 11534 string data;
@@ -10194,17 +11540,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10194 { 11540 {
10195 m_Notecards[assetID].lastRef = DateTime.Now; 11541 m_Notecards[assetID].lastRef = DateTime.Now;
10196 11542
10197 if (line >= m_Notecards[assetID].text.Length) 11543 if (lineNumber >= m_Notecards[assetID].text.Length)
10198 return "\n\n\n"; 11544 return "\n\n\n";
10199 11545
10200 data = m_Notecards[assetID].text[line]; 11546 data = m_Notecards[assetID].text[lineNumber];
10201 if (data.Length > maxLength)
10202 data = data.Substring(0, maxLength);
10203 11547
10204 return data; 11548 return data;
10205 } 11549 }
10206 } 11550 }
10207 11551
11552 /// <summary>
11553 /// Get a notecard line.
11554 /// </summary>
11555 /// <param name="assetID"></param>
11556 /// <param name="line">Lines start at index 0</param>
11557 /// <param name="maxLength">Maximum length of the returned line. Longer lines will be truncated</para>
11558 /// <returns></returns>
11559 public static string GetLine(UUID assetID, int lineNumber, int maxLength)
11560 {
11561 string line = GetLine(assetID, lineNumber);
11562
11563 if (line.Length > maxLength)
11564 line = line.Substring(0, maxLength);
11565
11566 return line;
11567 }
11568
10208 public static void CacheCheck() 11569 public static void CacheCheck()
10209 { 11570 {
10210 foreach (UUID key in new List<UUID>(m_Notecards.Keys)) 11571 foreach (UUID key in new List<UUID>(m_Notecards.Keys))
@@ -10215,4 +11576,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10215 } 11576 }
10216 } 11577 }
10217 } 11578 }
10218} \ No newline at end of file 11579}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
new file mode 100644
index 0000000..cb0d765
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
@@ -0,0 +1,524 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using System.Collections;
31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime;
33using OpenMetaverse;
34using Nini.Config;
35using OpenSim;
36using OpenSim.Framework;
37using OpenSim.Region.CoreModules.World.LightShare;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.ScriptEngine.Shared;
41using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
42using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
43using OpenSim.Region.ScriptEngine.Interfaces;
44using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
45
46using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
47using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
48using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
49using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
50using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
51using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
52using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
53
54namespace OpenSim.Region.ScriptEngine.Shared.Api
55{
56 [Serializable]
57 public class LS_Api : MarshalByRefObject, ILS_Api, IScriptApi
58 {
59 internal IScriptEngine m_ScriptEngine;
60 internal SceneObjectPart m_host;
61 internal uint m_localID;
62 internal UUID m_itemID;
63 internal bool m_LSFunctionsEnabled = false;
64 internal IScriptModuleComms m_comms = null;
65
66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
67 {
68 m_ScriptEngine = ScriptEngine;
69 m_host = host;
70 m_localID = localID;
71 m_itemID = itemID;
72
73 if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false))
74 m_LSFunctionsEnabled = true;
75
76 m_comms = m_ScriptEngine.World.RequestModuleInterface<IScriptModuleComms>();
77 if (m_comms == null)
78 m_LSFunctionsEnabled = false;
79 }
80
81 public override Object InitializeLifetimeService()
82 {
83 ILease lease = (ILease)base.InitializeLifetimeService();
84
85 if (lease.CurrentState == LeaseState.Initial)
86 {
87 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
88 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
89 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
90 }
91 return lease;
92 }
93
94 public Scene World
95 {
96 get { return m_ScriptEngine.World; }
97 }
98
99 //
100 //Dumps an error message on the debug console.
101 //
102
103 internal void LSShoutError(string message)
104 {
105 if (message.Length > 1023)
106 message = message.Substring(0, 1023);
107
108 World.SimChat(Utils.StringToBytes(message),
109 ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true);
110
111 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
112 wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message);
113 }
114
115 /// <summary>
116 /// Get the current Windlight scene
117 /// </summary>
118 /// <returns>List of windlight parameters</returns>
119 public LSL_List lsGetWindlightScene(LSL_List rules)
120 {
121 if (!m_LSFunctionsEnabled)
122 {
123 LSShoutError("LightShare functions are not enabled.");
124 return new LSL_List();
125 }
126 m_host.AddScriptLPS(1);
127 RegionLightShareData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings;
128
129 LSL_List values = new LSL_List();
130 int idx = 0;
131 while (idx < rules.Length)
132 {
133 LSL_Integer ruleInt = rules.GetLSLIntegerItem(idx);
134 uint rule = (uint)ruleInt;
135 LSL_List toadd = new LSL_List();
136
137 switch (rule)
138 {
139 case (int)ScriptBaseClass.WL_AMBIENT:
140 toadd.Add(new LSL_Rotation(wl.ambient.X, wl.ambient.Y, wl.ambient.Z, wl.ambient.W));
141 break;
142 case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION:
143 toadd.Add(new LSL_Vector(wl.bigWaveDirection.X, wl.bigWaveDirection.Y, 0.0f));
144 break;
145 case (int)ScriptBaseClass.WL_BLUE_DENSITY:
146 toadd.Add(new LSL_Rotation(wl.blueDensity.X, wl.blueDensity.Y, wl.blueDensity.Z, wl.blueDensity.W));
147 break;
148 case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER:
149 toadd.Add(new LSL_Float(wl.blurMultiplier));
150 break;
151 case (int)ScriptBaseClass.WL_CLOUD_COLOR:
152 toadd.Add(new LSL_Rotation(wl.cloudColor.X, wl.cloudColor.Y, wl.cloudColor.Z, wl.cloudColor.W));
153 break;
154 case (int)ScriptBaseClass.WL_CLOUD_COVERAGE:
155 toadd.Add(new LSL_Float(wl.cloudCoverage));
156 break;
157 case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY:
158 toadd.Add(new LSL_Vector(wl.cloudDetailXYDensity.X, wl.cloudDetailXYDensity.Y, wl.cloudDetailXYDensity.Z));
159 break;
160 case (int)ScriptBaseClass.WL_CLOUD_SCALE:
161 toadd.Add(new LSL_Float(wl.cloudScale));
162 break;
163 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X:
164 toadd.Add(new LSL_Float(wl.cloudScrollX));
165 break;
166 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK:
167 toadd.Add(new LSL_Integer(wl.cloudScrollXLock ? 1 : 0));
168 break;
169 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y:
170 toadd.Add(new LSL_Float(wl.cloudScrollY));
171 break;
172 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK:
173 toadd.Add(new LSL_Integer(wl.cloudScrollYLock ? 1 : 0));
174 break;
175 case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY:
176 toadd.Add(new LSL_Vector(wl.cloudXYDensity.X, wl.cloudXYDensity.Y, wl.cloudXYDensity.Z));
177 break;
178 case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER:
179 toadd.Add(new LSL_Float(wl.densityMultiplier));
180 break;
181 case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER:
182 toadd.Add(new LSL_Float(wl.distanceMultiplier));
183 break;
184 case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS:
185 toadd.Add(new LSL_Integer(wl.drawClassicClouds ? 1 : 0));
186 break;
187 case (int)ScriptBaseClass.WL_EAST_ANGLE:
188 toadd.Add(new LSL_Float(wl.eastAngle));
189 break;
190 case (int)ScriptBaseClass.WL_FRESNEL_OFFSET:
191 toadd.Add(new LSL_Float(wl.fresnelOffset));
192 break;
193 case (int)ScriptBaseClass.WL_FRESNEL_SCALE:
194 toadd.Add(new LSL_Float(wl.fresnelScale));
195 break;
196 case (int)ScriptBaseClass.WL_HAZE_DENSITY:
197 toadd.Add(new LSL_Float(wl.hazeDensity));
198 break;
199 case (int)ScriptBaseClass.WL_HAZE_HORIZON:
200 toadd.Add(new LSL_Float(wl.hazeHorizon));
201 break;
202 case (int)ScriptBaseClass.WL_HORIZON:
203 toadd.Add(new LSL_Rotation(wl.horizon.X, wl.horizon.Y, wl.horizon.Z, wl.horizon.W));
204 break;
205 case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION:
206 toadd.Add(new LSL_Vector(wl.littleWaveDirection.X, wl.littleWaveDirection.Y, 0.0f));
207 break;
208 case (int)ScriptBaseClass.WL_MAX_ALTITUDE:
209 toadd.Add(new LSL_Integer(wl.maxAltitude));
210 break;
211 case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE:
212 toadd.Add(new LSL_Key(wl.normalMapTexture.ToString()));
213 break;
214 case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE:
215 toadd.Add(new LSL_Vector(wl.reflectionWaveletScale.X, wl.reflectionWaveletScale.Y, wl.reflectionWaveletScale.Z));
216 break;
217 case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE:
218 toadd.Add(new LSL_Float(wl.refractScaleAbove));
219 break;
220 case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW:
221 toadd.Add(new LSL_Float(wl.refractScaleBelow));
222 break;
223 case (int)ScriptBaseClass.WL_SCENE_GAMMA:
224 toadd.Add(new LSL_Float(wl.sceneGamma));
225 break;
226 case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS:
227 toadd.Add(new LSL_Float(wl.starBrightness));
228 break;
229 case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS:
230 toadd.Add(new LSL_Float(wl.sunGlowFocus));
231 break;
232 case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE:
233 toadd.Add(new LSL_Float(wl.sunGlowSize));
234 break;
235 case (int)ScriptBaseClass.WL_SUN_MOON_COLOR:
236 toadd.Add(new LSL_Rotation(wl.sunMoonColor.X, wl.sunMoonColor.Y, wl.sunMoonColor.Z, wl.sunMoonColor.W));
237 break;
238 case (int)ScriptBaseClass.WL_SUN_MOON_POSITION:
239 toadd.Add(new LSL_Float(wl.sunMoonPosition));
240 break;
241 case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER:
242 toadd.Add(new LSL_Float(wl.underwaterFogModifier));
243 break;
244 case (int)ScriptBaseClass.WL_WATER_COLOR:
245 toadd.Add(new LSL_Vector(wl.waterColor.X, wl.waterColor.Y, wl.waterColor.Z));
246 break;
247 case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT:
248 toadd.Add(new LSL_Float(wl.waterFogDensityExponent));
249 break;
250 }
251
252 if (toadd.Length > 0)
253 {
254 values.Add(ruleInt);
255 values.Add(toadd.Data[0]);
256 }
257 idx++;
258 }
259
260 return values;
261 }
262
263 private RegionLightShareData getWindlightProfileFromRules(LSL_List rules)
264 {
265 RegionLightShareData wl = (RegionLightShareData)m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.Clone();
266
267// LSL_List values = new LSL_List();
268 int idx = 0;
269 while (idx < rules.Length)
270 {
271 uint rule = (uint)rules.GetLSLIntegerItem(idx);
272 LSL_Types.Quaternion iQ;
273 LSL_Types.Vector3 iV;
274 switch (rule)
275 {
276 case (int)ScriptBaseClass.WL_SUN_MOON_POSITION:
277 idx++;
278 wl.sunMoonPosition = (float)rules.GetLSLFloatItem(idx);
279 break;
280 case (int)ScriptBaseClass.WL_AMBIENT:
281 idx++;
282 iQ = rules.GetQuaternionItem(idx);
283 wl.ambient = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
284 break;
285 case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION:
286 idx++;
287 iV = rules.GetVector3Item(idx);
288 wl.bigWaveDirection = new Vector2((float)iV.x, (float)iV.y);
289 break;
290 case (int)ScriptBaseClass.WL_BLUE_DENSITY:
291 idx++;
292 iQ = rules.GetQuaternionItem(idx);
293 wl.blueDensity = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
294 break;
295 case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER:
296 idx++;
297 wl.blurMultiplier = (float)rules.GetLSLFloatItem(idx);
298 break;
299 case (int)ScriptBaseClass.WL_CLOUD_COLOR:
300 idx++;
301 iQ = rules.GetQuaternionItem(idx);
302 wl.cloudColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
303 break;
304 case (int)ScriptBaseClass.WL_CLOUD_COVERAGE:
305 idx++;
306 wl.cloudCoverage = (float)rules.GetLSLFloatItem(idx);
307 break;
308 case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY:
309 idx++;
310 iV = rules.GetVector3Item(idx);
311 wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
312 break;
313 case (int)ScriptBaseClass.WL_CLOUD_SCALE:
314 idx++;
315 wl.cloudScale = (float)rules.GetLSLFloatItem(idx);
316 break;
317 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X:
318 idx++;
319 wl.cloudScrollX = (float)rules.GetLSLFloatItem(idx);
320 break;
321 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK:
322 idx++;
323 wl.cloudScrollXLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false;
324 break;
325 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y:
326 idx++;
327 wl.cloudScrollY = (float)rules.GetLSLFloatItem(idx);
328 break;
329 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK:
330 idx++;
331 wl.cloudScrollYLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false;
332 break;
333 case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY:
334 idx++;
335 iV = rules.GetVector3Item(idx);
336 wl.cloudXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
337 break;
338 case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER:
339 idx++;
340 wl.densityMultiplier = (float)rules.GetLSLFloatItem(idx);
341 break;
342 case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER:
343 idx++;
344 wl.distanceMultiplier = (float)rules.GetLSLFloatItem(idx);
345 break;
346 case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS:
347 idx++;
348 wl.drawClassicClouds = rules.GetLSLIntegerItem(idx).value == 1 ? true : false;
349 break;
350 case (int)ScriptBaseClass.WL_EAST_ANGLE:
351 idx++;
352 wl.eastAngle = (float)rules.GetLSLFloatItem(idx);
353 break;
354 case (int)ScriptBaseClass.WL_FRESNEL_OFFSET:
355 idx++;
356 wl.fresnelOffset = (float)rules.GetLSLFloatItem(idx);
357 break;
358 case (int)ScriptBaseClass.WL_FRESNEL_SCALE:
359 idx++;
360 wl.fresnelScale = (float)rules.GetLSLFloatItem(idx);
361 break;
362 case (int)ScriptBaseClass.WL_HAZE_DENSITY:
363 idx++;
364 wl.hazeDensity = (float)rules.GetLSLFloatItem(idx);
365 break;
366 case (int)ScriptBaseClass.WL_HAZE_HORIZON:
367 idx++;
368 wl.hazeHorizon = (float)rules.GetLSLFloatItem(idx);
369 break;
370 case (int)ScriptBaseClass.WL_HORIZON:
371 idx++;
372 iQ = rules.GetQuaternionItem(idx);
373 wl.horizon = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
374 break;
375 case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION:
376 idx++;
377 iV = rules.GetVector3Item(idx);
378 wl.littleWaveDirection = new Vector2((float)iV.x, (float)iV.y);
379 break;
380 case (int)ScriptBaseClass.WL_MAX_ALTITUDE:
381 idx++;
382 wl.maxAltitude = (ushort)rules.GetLSLIntegerItem(idx).value;
383 break;
384 case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE:
385 idx++;
386 wl.normalMapTexture = new UUID(rules.GetLSLStringItem(idx).m_string);
387 break;
388 case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE:
389 idx++;
390 iV = rules.GetVector3Item(idx);
391 wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
392 break;
393 case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE:
394 idx++;
395 wl.refractScaleAbove = (float)rules.GetLSLFloatItem(idx);
396 break;
397 case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW:
398 idx++;
399 wl.refractScaleBelow = (float)rules.GetLSLFloatItem(idx);
400 break;
401 case (int)ScriptBaseClass.WL_SCENE_GAMMA:
402 idx++;
403 wl.sceneGamma = (float)rules.GetLSLFloatItem(idx);
404 break;
405 case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS:
406 idx++;
407 wl.starBrightness = (float)rules.GetLSLFloatItem(idx);
408 break;
409 case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS:
410 idx++;
411 wl.sunGlowFocus = (float)rules.GetLSLFloatItem(idx);
412 break;
413 case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE:
414 idx++;
415 wl.sunGlowSize = (float)rules.GetLSLFloatItem(idx);
416 break;
417 case (int)ScriptBaseClass.WL_SUN_MOON_COLOR:
418 idx++;
419 iQ = rules.GetQuaternionItem(idx);
420 wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
421 break;
422 case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER:
423 idx++;
424 wl.underwaterFogModifier = (float)rules.GetLSLFloatItem(idx);
425 break;
426 case (int)ScriptBaseClass.WL_WATER_COLOR:
427 idx++;
428 iV = rules.GetVector3Item(idx);
429 wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
430 break;
431 case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT:
432 idx++;
433 wl.waterFogDensityExponent = (float)rules.GetLSLFloatItem(idx);
434 break;
435 }
436 idx++;
437 }
438 return wl;
439 }
440 /// <summary>
441 /// Set the current Windlight scene
442 /// </summary>
443 /// <param name="rules"></param>
444 /// <returns>success: true or false</returns>
445 public int lsSetWindlightScene(LSL_List rules)
446 {
447 if (!m_LSFunctionsEnabled)
448 {
449 LSShoutError("LightShare functions are not enabled.");
450 return 0;
451 }
452 if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200)
453 {
454 LSShoutError("lsSetWindlightScene can only be used by estate managers or owners.");
455 return 0;
456 }
457 int success = 0;
458 m_host.AddScriptLPS(1);
459 if (LightShareModule.EnableWindlight)
460 {
461 RegionLightShareData wl = getWindlightProfileFromRules(rules);
462 wl.valid = true;
463 m_host.ParentGroup.Scene.StoreWindlightProfile(wl);
464 success = 1;
465 }
466 else
467 {
468 LSShoutError("Windlight module is disabled");
469 return 0;
470 }
471 return success;
472 }
473 public void lsClearWindlightScene()
474 {
475 if (!m_LSFunctionsEnabled)
476 {
477 LSShoutError("LightShare functions are not enabled.");
478 return;
479 }
480 if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200)
481 {
482 LSShoutError("lsSetWindlightScene can only be used by estate managers or owners.");
483 return;
484 }
485
486 m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.valid = false;
487 if (m_host.ParentGroup.Scene.SimulationDataService != null)
488 m_host.ParentGroup.Scene.SimulationDataService.RemoveRegionWindlightSettings(m_host.ParentGroup.Scene.RegionInfo.RegionID);
489 }
490 /// <summary>
491 /// Set the current Windlight scene to a target avatar
492 /// </summary>
493 /// <param name="rules"></param>
494 /// <returns>success: true or false</returns>
495 public int lsSetWindlightSceneTargeted(LSL_List rules, LSL_Key target)
496 {
497 if (!m_LSFunctionsEnabled)
498 {
499 LSShoutError("LightShare functions are not enabled.");
500 return 0;
501 }
502 if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200)
503 {
504 LSShoutError("lsSetWindlightSceneTargeted can only be used by estate managers or owners.");
505 return 0;
506 }
507 int success = 0;
508 m_host.AddScriptLPS(1);
509 if (LightShareModule.EnableWindlight)
510 {
511 RegionLightShareData wl = getWindlightProfileFromRules(rules);
512 World.EventManager.TriggerOnSendNewWindlightProfileTargeted(wl, new UUID(target.m_string));
513 success = 1;
514 }
515 else
516 {
517 LSShoutError("Windlight module is disabled");
518 return 0;
519 }
520 return success;
521 }
522
523 }
524}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 1ddba1e..c0d2f38 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -28,20 +28,23 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 33using System.Runtime.Remoting.Lifetime;
32using System.Text; 34using System.Text;
33using System.Net; 35using System.Net;
34using System.Threading; 36using System.Threading;
37using System.Xml;
38using log4net;
35using OpenMetaverse; 39using OpenMetaverse;
40using OpenMetaverse.StructuredData;
36using Nini.Config; 41using Nini.Config;
37using OpenSim; 42using OpenSim;
38using OpenSim.Framework; 43using OpenSim.Framework;
39using OpenSim.Framework.Communications.Cache; 44
40using OpenSim.Framework.Console; 45using OpenSim.Framework.Console;
41using OpenSim.Region.CoreModules.Avatar.NPC;
42using OpenSim.Region.Framework.Interfaces; 46using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.Framework.Scenes; 47using OpenSim.Region.Framework.Scenes;
44using OpenSim.Region.Framework.Scenes.Hypergrid;
45using OpenSim.Region.ScriptEngine.Shared; 48using OpenSim.Region.ScriptEngine.Shared;
46using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; 49using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
47using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 50using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
@@ -106,9 +109,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
106 // modification of user data, or allows the compromise of 109 // modification of user data, or allows the compromise of
107 // sensitive data by design. 110 // sensitive data by design.
108 111
112 class FunctionPerms
113 {
114 public List<UUID> AllowedCreators;
115 public List<UUID> AllowedOwners;
116 public List<string> AllowedOwnerClasses;
117
118 public FunctionPerms()
119 {
120 AllowedCreators = new List<UUID>();
121 AllowedOwners = new List<UUID>();
122 AllowedOwnerClasses = new List<string>();
123 }
124 }
125
109 [Serializable] 126 [Serializable]
110 public class OSSL_Api : MarshalByRefObject, IOSSL_Api, IScriptApi 127 public class OSSL_Api : MarshalByRefObject, IOSSL_Api, IScriptApi
111 { 128 {
129// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
130
112 internal IScriptEngine m_ScriptEngine; 131 internal IScriptEngine m_ScriptEngine;
113 internal ILSL_Api m_LSL_Api = null; // get a reference to the LSL API so we can call methods housed there 132 internal ILSL_Api m_LSL_Api = null; // get a reference to the LSL API so we can call methods housed there
114 internal SceneObjectPart m_host; 133 internal SceneObjectPart m_host;
@@ -118,7 +137,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
118 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 137 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
119 internal float m_ScriptDelayFactor = 1.0f; 138 internal float m_ScriptDelayFactor = 1.0f;
120 internal float m_ScriptDistanceFactor = 1.0f; 139 internal float m_ScriptDistanceFactor = 1.0f;
121 internal Dictionary<string, List<UUID> > m_FunctionPerms = new Dictionary<string, List<UUID> >(); 140 internal bool m_debuggerSafe = false;
141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
122 142
123 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 143 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
124 { 144 {
@@ -126,6 +146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
126 m_host = host; 146 m_host = host;
127 m_localID = localID; 147 m_localID = localID;
128 m_itemID = itemID; 148 m_itemID = itemID;
149 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
129 150
130 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 151 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
131 m_OSFunctionsEnabled = true; 152 m_OSFunctionsEnabled = true;
@@ -184,7 +205,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
184 205
185 internal void OSSLError(string msg) 206 internal void OSSLError(string msg)
186 { 207 {
187 throw new Exception("OSSL Runtime Error: " + msg); 208 if (m_debuggerSafe)
209 {
210 OSSLShoutError(msg);
211 }
212 else
213 {
214 throw new Exception("OSSL Runtime Error: " + msg);
215 }
188 } 216 }
189 217
190 private void InitLSL() 218 private void InitLSL()
@@ -218,31 +246,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
218 246
219 if (!m_FunctionPerms.ContainsKey(function)) 247 if (!m_FunctionPerms.ContainsKey(function))
220 { 248 {
221 string perm = m_ScriptEngine.Config.GetString("Allow_" + function, ""); 249 FunctionPerms perms = new FunctionPerms();
222 if (perm == "") 250 m_FunctionPerms[function] = perms;
251
252 string ownerPerm = m_ScriptEngine.Config.GetString("Allow_" + function, "");
253 string creatorPerm = m_ScriptEngine.Config.GetString("Creators_" + function, "");
254 if (ownerPerm == "" && creatorPerm == "")
223 { 255 {
224 m_FunctionPerms[function] = null; // a null value is default 256 // Default behavior
257 perms.AllowedOwners = null;
258 perms.AllowedCreators = null;
259 perms.AllowedOwnerClasses = null;
225 } 260 }
226 else 261 else
227 { 262 {
228 bool allowed; 263 bool allowed;
229 264
230 if (bool.TryParse(perm, out allowed)) 265 if (bool.TryParse(ownerPerm, out allowed))
231 { 266 {
232 // Boolean given 267 // Boolean given
233 if (allowed) 268 if (allowed)
234 { 269 {
235 m_FunctionPerms[function] = new List<UUID>(); 270 // Allow globally
236 m_FunctionPerms[function].Add(UUID.Zero); 271 perms.AllowedOwners.Add(UUID.Zero);
237 } 272 }
238 else
239 m_FunctionPerms[function] = new List<UUID>(); // Empty list = none
240 } 273 }
241 else 274 else
242 { 275 {
243 m_FunctionPerms[function] = new List<UUID>(); 276 string[] ids = ownerPerm.Split(new char[] {','});
277 foreach (string id in ids)
278 {
279 string current = id.Trim();
280 if (current.ToUpper() == "PARCEL_GROUP_MEMBER" || current.ToUpper() == "PARCEL_OWNER" || current.ToUpper() == "ESTATE_MANAGER" || current.ToUpper() == "ESTATE_OWNER")
281 {
282 if (!perms.AllowedOwnerClasses.Contains(current))
283 perms.AllowedOwnerClasses.Add(current.ToUpper());
284 }
285 else
286 {
287 UUID uuid;
244 288
245 string[] ids = perm.Split(new char[] {','}); 289 if (UUID.TryParse(current, out uuid))
290 {
291 if (uuid != UUID.Zero)
292 perms.AllowedOwners.Add(uuid);
293 }
294 }
295 }
296
297 ids = creatorPerm.Split(new char[] {','});
246 foreach (string id in ids) 298 foreach (string id in ids)
247 { 299 {
248 string current = id.Trim(); 300 string current = id.Trim();
@@ -251,7 +303,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
251 if (UUID.TryParse(current, out uuid)) 303 if (UUID.TryParse(current, out uuid))
252 { 304 {
253 if (uuid != UUID.Zero) 305 if (uuid != UUID.Zero)
254 m_FunctionPerms[function].Add(uuid); 306 perms.AllowedCreators.Add(uuid);
255 } 307 }
256 } 308 }
257 } 309 }
@@ -267,8 +319,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
267 // 319 //
268 // To allow use by anyone, the list contains UUID.Zero 320 // To allow use by anyone, the list contains UUID.Zero
269 // 321 //
270 if (m_FunctionPerms[function] == null) // No list = true 322 if (m_FunctionPerms[function].AllowedOwners == null)
271 { 323 {
324 // Allow / disallow by threat level
272 if (level > m_MaxThreatLevel) 325 if (level > m_MaxThreatLevel)
273 OSSLError( 326 OSSLError(
274 String.Format( 327 String.Format(
@@ -277,16 +330,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
277 } 330 }
278 else 331 else
279 { 332 {
280 if (!m_FunctionPerms[function].Contains(UUID.Zero)) 333 if (!m_FunctionPerms[function].AllowedOwners.Contains(UUID.Zero))
281 { 334 {
282 if (!m_FunctionPerms[function].Contains(m_host.OwnerID)) 335 // Not anyone. Do detailed checks
336 if (m_FunctionPerms[function].AllowedOwners.Contains(m_host.OwnerID))
337 {
338 // prim owner is in the list of allowed owners
339 return;
340 }
341
342 TaskInventoryItem ti = m_host.Inventory.GetInventoryItem(m_itemID);
343 if (ti == null)
344 {
283 OSSLError( 345 OSSLError(
284 String.Format("{0} permission denied. Prim owner is not in the list of users allowed to execute this function.", 346 String.Format("{0} permission error. Can't find script in prim inventory.",
285 function)); 347 function));
348 }
349
350 UUID ownerID = ti.OwnerID;
351
352 //OSSL only may be used if objet is in the same group as the parcel
353 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("PARCEL_GROUP_MEMBER"))
354 {
355 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
356
357 if (land.LandData.GroupID == ti.GroupID && land.LandData.GroupID != UUID.Zero)
358 {
359 return;
360 }
361 }
362
363 //Only Parcelowners may use the function
364 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("PARCEL_OWNER"))
365 {
366 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
367
368 if (land.LandData.OwnerID == ownerID)
369 {
370 return;
371 }
372 }
373
374 //Only Estate Managers may use the function
375 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("ESTATE_MANAGER"))
376 {
377 //Only Estate Managers may use the function
378 if (World.RegionInfo.EstateSettings.IsEstateManager(ownerID) && World.RegionInfo.EstateSettings.EstateOwner != ownerID)
379 {
380 return;
381 }
382 }
383
384 //Only regionowners may use the function
385 if (m_FunctionPerms[function].AllowedOwnerClasses.Contains("ESTATE_OWNER"))
386 {
387 if (World.RegionInfo.EstateSettings.EstateOwner == ownerID)
388 {
389 return;
390 }
391 }
392
393 if (!m_FunctionPerms[function].AllowedCreators.Contains(ti.CreatorID))
394 OSSLError(
395 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.",
396 function));
397 if (ti.CreatorID != ownerID)
398 {
399 if ((ti.CurrentPermissions & (uint)PermissionMask.Modify) != 0)
400 OSSLError(
401 String.Format("{0} permission denied. Script permissions error.",
402 function));
403
404 }
286 } 405 }
287 } 406 }
288 } 407 }
289 408
409 internal void OSSLDeprecated(string function, string replacement)
410 {
411 OSSLShoutError(string.Format("Use of function {0} is deprecated. Use {1} instead.", function, replacement));
412 }
413
290 protected void ScriptSleep(int delay) 414 protected void ScriptSleep(int delay)
291 { 415 {
292 delay = (int)((float)delay * m_ScriptDelayFactor); 416 delay = (int)((float)delay * m_ScriptDelayFactor);
@@ -295,16 +419,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
295 System.Threading.Thread.Sleep(delay); 419 System.Threading.Thread.Sleep(delay);
296 } 420 }
297 421
298 // 422 public LSL_Integer osSetTerrainHeight(int x, int y, double val)
299 // OpenSim functions 423 {
300 // 424 CheckThreatLevel(ThreatLevel.High, "osSetTerrainHeight");
425 return SetTerrainHeight(x, y, val);
426 }
427
301 public LSL_Integer osTerrainSetHeight(int x, int y, double val) 428 public LSL_Integer osTerrainSetHeight(int x, int y, double val)
302 { 429 {
303 CheckThreatLevel(ThreatLevel.High, "osTerrainSetHeight"); 430 CheckThreatLevel(ThreatLevel.High, "osTerrainSetHeight");
431 OSSLDeprecated("osTerrainSetHeight", "osSetTerrainHeight");
432 return SetTerrainHeight(x, y, val);
433 }
304 434
435 private LSL_Integer SetTerrainHeight(int x, int y, double val)
436 {
305 m_host.AddScriptLPS(1); 437 m_host.AddScriptLPS(1);
306 if (x > ((int)Constants.RegionSize - 1) || x < 0 || y > ((int)Constants.RegionSize - 1) || y < 0) 438 if (x > ((int)Constants.RegionSize - 1) || x < 0 || y > ((int)Constants.RegionSize - 1) || y < 0)
307 OSSLError("osTerrainSetHeight: Coordinate out of bounds"); 439 OSSLError("osSetTerrainHeight: Coordinate out of bounds");
308 440
309 if (World.Permissions.CanTerraformLand(m_host.OwnerID, new Vector3(x, y, 0))) 441 if (World.Permissions.CanTerraformLand(m_host.OwnerID, new Vector3(x, y, 0)))
310 { 442 {
@@ -317,13 +449,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
317 } 449 }
318 } 450 }
319 451
452 public LSL_Float osGetTerrainHeight(int x, int y)
453 {
454 CheckThreatLevel(ThreatLevel.None, "osGetTerrainHeight");
455 return GetTerrainHeight(x, y);
456 }
457
320 public LSL_Float osTerrainGetHeight(int x, int y) 458 public LSL_Float osTerrainGetHeight(int x, int y)
321 { 459 {
322 CheckThreatLevel(ThreatLevel.None, "osTerrainGetHeight"); 460 CheckThreatLevel(ThreatLevel.None, "osTerrainGetHeight");
461 OSSLDeprecated("osTerrainGetHeight", "osGetTerrainHeight");
462 return GetTerrainHeight(x, y);
463 }
323 464
465 private LSL_Float GetTerrainHeight(int x, int y)
466 {
324 m_host.AddScriptLPS(1); 467 m_host.AddScriptLPS(1);
325 if (x > ((int)Constants.RegionSize - 1) || x < 0 || y > ((int)Constants.RegionSize - 1) || y < 0) 468 if (x > ((int)Constants.RegionSize - 1) || x < 0 || y > ((int)Constants.RegionSize - 1) || y < 0)
326 OSSLError("osTerrainGetHeight: Coordinate out of bounds"); 469 OSSLError("osGetTerrainHeight: Coordinate out of bounds");
327 470
328 return World.Heightmap[x, y]; 471 return World.Heightmap[x, y];
329 } 472 }
@@ -346,10 +489,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
346 // 489 //
347 CheckThreatLevel(ThreatLevel.High, "osRegionRestart"); 490 CheckThreatLevel(ThreatLevel.High, "osRegionRestart");
348 491
492 IRestartModule restartModule = World.RequestModuleInterface<IRestartModule>();
349 m_host.AddScriptLPS(1); 493 m_host.AddScriptLPS(1);
350 if (World.Permissions.CanIssueEstateCommand(m_host.OwnerID, false)) 494 if (World.Permissions.CanIssueEstateCommand(m_host.OwnerID, false) && (restartModule != null))
351 { 495 {
352 World.Restart((float)seconds); 496 if (seconds < 15)
497 {
498 restartModule.AbortRestart("Restart aborted");
499 return 1;
500 }
501
502 List<int> times = new List<int>();
503 while (seconds > 0)
504 {
505 times.Add((int)seconds);
506 if (seconds > 300)
507 seconds -= 120;
508 else if (seconds > 30)
509 seconds -= 30;
510 else
511 seconds -= 15;
512 }
513
514 restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), true);
353 return 1; 515 return 1;
354 } 516 }
355 else 517 else
@@ -388,7 +550,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
388 if (World.Entities.TryGetValue(target, out entity)) 550 if (World.Entities.TryGetValue(target, out entity))
389 { 551 {
390 if (entity is SceneObjectGroup) 552 if (entity is SceneObjectGroup)
391 ((SceneObjectGroup)entity).Rotation = rotation; 553 ((SceneObjectGroup)entity).UpdateGroupRotationR(rotation);
392 else if (entity is ScenePresence) 554 else if (entity is ScenePresence)
393 ((ScenePresence)entity).Rotation = rotation; 555 ((ScenePresence)entity).Rotation = rotation;
394 } 556 }
@@ -574,13 +736,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
574 CheckThreatLevel(ThreatLevel.VeryLow, "osSetPrimFloatOnWater"); 736 CheckThreatLevel(ThreatLevel.VeryLow, "osSetPrimFloatOnWater");
575 737
576 m_host.AddScriptLPS(1); 738 m_host.AddScriptLPS(1);
577 if (m_host.ParentGroup != null) 739
578 { 740 m_host.ParentGroup.RootPart.SetFloatOnWater(floatYN);
579 if (m_host.ParentGroup.RootPart != null)
580 {
581 m_host.ParentGroup.RootPart.SetFloatOnWater(floatYN);
582 }
583 }
584 } 741 }
585 742
586 // Teleport functions 743 // Teleport functions
@@ -590,6 +747,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
590 // 747 //
591 CheckThreatLevel(ThreatLevel.High, "osTeleportAgent"); 748 CheckThreatLevel(ThreatLevel.High, "osTeleportAgent");
592 749
750 TeleportAgent(agent, regionName, position, lookat, false);
751 }
752
753 private void TeleportAgent(string agent, string regionName,
754 LSL_Types.Vector3 position, LSL_Types.Vector3 lookat, bool relaxRestrictions)
755 {
593 m_host.AddScriptLPS(1); 756 m_host.AddScriptLPS(1);
594 UUID agentId = new UUID(); 757 UUID agentId = new UUID();
595 if (UUID.TryParse(agent, out agentId)) 758 if (UUID.TryParse(agent, out agentId))
@@ -597,37 +760,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
597 ScenePresence presence = World.GetScenePresence(agentId); 760 ScenePresence presence = World.GetScenePresence(agentId);
598 if (presence != null) 761 if (presence != null)
599 { 762 {
600 // agent must be over owners land to avoid abuse 763 // For osTeleportAgent, agent must be over owners land to avoid abuse
601 if (m_host.OwnerID 764 // For osTeleportOwner, this restriction isn't necessary
765 if (relaxRestrictions ||
766 m_host.OwnerID
602 == World.LandChannel.GetLandObject( 767 == World.LandChannel.GetLandObject(
603 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 768 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
604 { 769 {
605 770 // We will launch the teleport on a new thread so that when the script threads are terminated
606 // Check for hostname , attempt to make a hglink 771 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
607 // and convert the regionName to the target region 772 Util.FireAndForget(
608 if (regionName.Contains(".") && regionName.Contains(":")) 773 o => World.RequestTeleportLocation(presence.ControllingClient, regionName,
609 { 774 new Vector3((float)position.x, (float)position.y, (float)position.z),
610 // Try to link the region 775 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation));
611 IHyperlinkService hyperService = World.RequestModuleInterface<IHyperlinkService>();
612 if (hyperService != null)
613 {
614 GridRegion regInfo = hyperService.TryLinkRegion(presence.ControllingClient,
615 regionName);
616 // Get the region name
617 if (regInfo != null)
618 {
619 regionName = regInfo.RegionName;
620 }
621 else
622 {
623 // Might need to ping the client here in case of failure??
624 }
625 }
626 }
627 presence.ControllingClient.SendTeleportLocationStart();
628 World.RequestTeleportLocation(presence.ControllingClient, regionName,
629 new Vector3((float)position.x, (float)position.y, (float)position.z),
630 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation);
631 776
632 ScriptSleep(5000); 777 ScriptSleep(5000);
633 } 778 }
@@ -635,13 +780,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
635 } 780 }
636 } 781 }
637 782
638 // Teleport functions
639 public void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) 783 public void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
640 { 784 {
641 // High because there is no security check. High griefer potential 785 // High because there is no security check. High griefer potential
642 // 786 //
643 CheckThreatLevel(ThreatLevel.High, "osTeleportAgent"); 787 CheckThreatLevel(ThreatLevel.High, "osTeleportAgent");
644 788
789 TeleportAgent(agent, regionX, regionY, position, lookat, false);
790 }
791
792 private void TeleportAgent(string agent, int regionX, int regionY,
793 LSL_Types.Vector3 position, LSL_Types.Vector3 lookat, bool relaxRestrictions)
794 {
645 ulong regionHandle = Util.UIntsToLong(((uint)regionX * (uint)Constants.RegionSize), ((uint)regionY * (uint)Constants.RegionSize)); 795 ulong regionHandle = Util.UIntsToLong(((uint)regionX * (uint)Constants.RegionSize), ((uint)regionY * (uint)Constants.RegionSize));
646 796
647 m_host.AddScriptLPS(1); 797 m_host.AddScriptLPS(1);
@@ -651,15 +801,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
651 ScenePresence presence = World.GetScenePresence(agentId); 801 ScenePresence presence = World.GetScenePresence(agentId);
652 if (presence != null) 802 if (presence != null)
653 { 803 {
654 // agent must be over owners land to avoid abuse 804 // For osTeleportAgent, agent must be over owners land to avoid abuse
655 if (m_host.OwnerID 805 // For osTeleportOwner, this restriction isn't necessary
806 if (relaxRestrictions ||
807 m_host.OwnerID
656 == World.LandChannel.GetLandObject( 808 == World.LandChannel.GetLandObject(
657 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 809 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
658 { 810 {
659 presence.ControllingClient.SendTeleportLocationStart(); 811 // We will launch the teleport on a new thread so that when the script threads are terminated
660 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, 812 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
661 new Vector3((float)position.x, (float)position.y, (float)position.z), 813 Util.FireAndForget(
662 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation); 814 o => World.RequestTeleportLocation(presence.ControllingClient, regionHandle,
815 new Vector3((float)position.x, (float)position.y, (float)position.z),
816 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation));
817
663 ScriptSleep(5000); 818 ScriptSleep(5000);
664 } 819 }
665 } 820 }
@@ -671,6 +826,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
671 osTeleportAgent(agent, World.RegionInfo.RegionName, position, lookat); 826 osTeleportAgent(agent, World.RegionInfo.RegionName, position, lookat);
672 } 827 }
673 828
829 public void osTeleportOwner(string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
830 {
831 // Threat level None because this is what can already be done with the World Map in the viewer
832 CheckThreatLevel(ThreatLevel.None, "osTeleportOwner");
833
834 TeleportAgent(m_host.OwnerID.ToString(), regionName, position, lookat, true);
835 }
836
837 public void osTeleportOwner(LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
838 {
839 osTeleportOwner(World.RegionInfo.RegionName, position, lookat);
840 }
841
842 public void osTeleportOwner(int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
843 {
844 CheckThreatLevel(ThreatLevel.None, "osTeleportOwner");
845
846 TeleportAgent(m_host.OwnerID.ToString(), regionX, regionY, position, lookat, true);
847 }
848
674 // Functions that get information from the agent itself. 849 // Functions that get information from the agent itself.
675 // 850 //
676 // osGetAgentIP - this is used to determine the IP address of 851 // osGetAgentIP - this is used to determine the IP address of
@@ -707,10 +882,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
707 CheckThreatLevel(ThreatLevel.None, "osGetAgents"); 882 CheckThreatLevel(ThreatLevel.None, "osGetAgents");
708 883
709 LSL_List result = new LSL_List(); 884 LSL_List result = new LSL_List();
710 foreach (ScenePresence avatar in World.GetAvatars()) 885 World.ForEachRootScenePresence(delegate(ScenePresence sp)
711 { 886 {
712 result.Add(avatar.Name); 887 result.Add(new LSL_String(sp.Name));
713 } 888 });
714 return result; 889 return result;
715 } 890 }
716 891
@@ -759,7 +934,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
759 ScenePresence target = (ScenePresence)World.Entities[avatarID]; 934 ScenePresence target = (ScenePresence)World.Entities[avatarID];
760 if (target != null) 935 if (target != null)
761 { 936 {
762 UUID animID=UUID.Zero; 937 UUID animID = UUID.Zero;
763 m_host.TaskInventory.LockItemsForRead(true); 938 m_host.TaskInventory.LockItemsForRead(true);
764 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 939 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
765 { 940 {
@@ -865,7 +1040,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
865 1040
866 public string osDrawPolygon(string drawList, LSL_List x, LSL_List y) 1041 public string osDrawPolygon(string drawList, LSL_List x, LSL_List y)
867 { 1042 {
868 CheckThreatLevel(ThreatLevel.None, "osDrawFilledPolygon"); 1043 CheckThreatLevel(ThreatLevel.None, "osDrawPolygon");
869 1044
870 m_host.AddScriptLPS(1); 1045 m_host.AddScriptLPS(1);
871 1046
@@ -909,9 +1084,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
909 return drawList; 1084 return drawList;
910 } 1085 }
911 1086
1087 public string osSetPenColor(string drawList, string color)
1088 {
1089 CheckThreatLevel(ThreatLevel.None, "osSetPenColor");
1090
1091 m_host.AddScriptLPS(1);
1092 drawList += "PenColor " + color + "; ";
1093 return drawList;
1094 }
1095
1096 // Deprecated
912 public string osSetPenColour(string drawList, string colour) 1097 public string osSetPenColour(string drawList, string colour)
913 { 1098 {
914 CheckThreatLevel(ThreatLevel.None, "osSetPenColour"); 1099 CheckThreatLevel(ThreatLevel.None, "osSetPenColour");
1100 OSSLDeprecated("osSetPenColour", "osSetPenColor");
915 1101
916 m_host.AddScriptLPS(1); 1102 m_host.AddScriptLPS(1);
917 drawList += "PenColour " + colour + "; "; 1103 drawList += "PenColour " + colour + "; ";
@@ -920,7 +1106,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
920 1106
921 public string osSetPenCap(string drawList, string direction, string type) 1107 public string osSetPenCap(string drawList, string direction, string type)
922 { 1108 {
923 CheckThreatLevel(ThreatLevel.None, "osSetPenColour"); 1109 CheckThreatLevel(ThreatLevel.None, "osSetPenCap");
924 1110
925 m_host.AddScriptLPS(1); 1111 m_host.AddScriptLPS(1);
926 drawList += "PenCap " + direction + "," + type + "; "; 1112 drawList += "PenCap " + direction + "," + type + "; ";
@@ -1065,6 +1251,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1065 public double osSunGetParam(string param) 1251 public double osSunGetParam(string param)
1066 { 1252 {
1067 CheckThreatLevel(ThreatLevel.None, "osSunGetParam"); 1253 CheckThreatLevel(ThreatLevel.None, "osSunGetParam");
1254 OSSLDeprecated("osSunGetParam", "osGetSunParam");
1255 return GetSunParam(param);
1256 }
1257
1258 public double osGetSunParam(string param)
1259 {
1260 CheckThreatLevel(ThreatLevel.None, "osGetSunParam");
1261 return GetSunParam(param);
1262 }
1263
1264 private double GetSunParam(string param)
1265 {
1068 m_host.AddScriptLPS(1); 1266 m_host.AddScriptLPS(1);
1069 1267
1070 double value = 0.0; 1268 double value = 0.0;
@@ -1081,6 +1279,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1081 public void osSunSetParam(string param, double value) 1279 public void osSunSetParam(string param, double value)
1082 { 1280 {
1083 CheckThreatLevel(ThreatLevel.None, "osSunSetParam"); 1281 CheckThreatLevel(ThreatLevel.None, "osSunSetParam");
1282 OSSLDeprecated("osSunSetParam", "osSetSunParam");
1283 SetSunParam(param, value);
1284 }
1285
1286 public void osSetSunParam(string param, double value)
1287 {
1288 CheckThreatLevel(ThreatLevel.None, "osSetSunParam");
1289 SetSunParam(param, value);
1290 }
1291
1292 private void SetSunParam(string param, double value)
1293 {
1084 m_host.AddScriptLPS(1); 1294 m_host.AddScriptLPS(1);
1085 1295
1086 ISunModule module = World.RequestModuleInterface<ISunModule>(); 1296 ISunModule module = World.RequestModuleInterface<ISunModule>();
@@ -1088,10 +1298,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1088 { 1298 {
1089 module.SetSunParameter(param, value); 1299 module.SetSunParameter(param, value);
1090 } 1300 }
1091
1092 } 1301 }
1093 1302
1094
1095 public string osWindActiveModelPluginName() 1303 public string osWindActiveModelPluginName()
1096 { 1304 {
1097 CheckThreatLevel(ThreatLevel.None, "osWindActiveModelPluginName"); 1305 CheckThreatLevel(ThreatLevel.None, "osWindActiveModelPluginName");
@@ -1106,9 +1314,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1106 return String.Empty; 1314 return String.Empty;
1107 } 1315 }
1108 1316
1109 public void osWindParamSet(string plugin, string param, float value) 1317 public void osSetWindParam(string plugin, string param, LSL_Float value)
1110 { 1318 {
1111 CheckThreatLevel(ThreatLevel.VeryLow, "osWindParamSet"); 1319 CheckThreatLevel(ThreatLevel.VeryLow, "osSetWindParam");
1112 m_host.AddScriptLPS(1); 1320 m_host.AddScriptLPS(1);
1113 1321
1114 IWindModule module = World.RequestModuleInterface<IWindModule>(); 1322 IWindModule module = World.RequestModuleInterface<IWindModule>();
@@ -1116,15 +1324,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1116 { 1324 {
1117 try 1325 try
1118 { 1326 {
1119 module.WindParamSet(plugin, param, value); 1327 module.WindParamSet(plugin, param, (float)value);
1120 } 1328 }
1121 catch (Exception) { } 1329 catch (Exception) { }
1122 } 1330 }
1123 } 1331 }
1124 1332
1125 public float osWindParamGet(string plugin, string param) 1333 public LSL_Float osGetWindParam(string plugin, string param)
1126 { 1334 {
1127 CheckThreatLevel(ThreatLevel.VeryLow, "osWindParamGet"); 1335 CheckThreatLevel(ThreatLevel.VeryLow, "osGetWindParam");
1128 m_host.AddScriptLPS(1); 1336 m_host.AddScriptLPS(1);
1129 1337
1130 IWindModule module = World.RequestModuleInterface<IWindModule>(); 1338 IWindModule module = World.RequestModuleInterface<IWindModule>();
@@ -1136,7 +1344,110 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1136 return 0.0f; 1344 return 0.0f;
1137 } 1345 }
1138 1346
1347 // Routines for creating and managing parcels programmatically
1348 public void osParcelJoin(LSL_Vector pos1, LSL_Vector pos2)
1349 {
1350 CheckThreatLevel(ThreatLevel.High, "osParcelJoin");
1351 m_host.AddScriptLPS(1);
1352
1353 int startx = (int)(pos1.x < pos2.x ? pos1.x : pos2.x);
1354 int starty = (int)(pos1.y < pos2.y ? pos1.y : pos2.y);
1355 int endx = (int)(pos1.x > pos2.x ? pos1.x : pos2.x);
1356 int endy = (int)(pos1.y > pos2.y ? pos1.y : pos2.y);
1357
1358 World.LandChannel.Join(startx,starty,endx,endy,m_host.OwnerID);
1359 }
1139 1360
1361 public void osParcelSubdivide(LSL_Vector pos1, LSL_Vector pos2)
1362 {
1363 CheckThreatLevel(ThreatLevel.High, "osParcelSubdivide");
1364 m_host.AddScriptLPS(1);
1365
1366 int startx = (int)(pos1.x < pos2.x ? pos1.x : pos2.x);
1367 int starty = (int)(pos1.y < pos2.y ? pos1.y : pos2.y);
1368 int endx = (int)(pos1.x > pos2.x ? pos1.x : pos2.x);
1369 int endy = (int)(pos1.y > pos2.y ? pos1.y : pos2.y);
1370
1371 World.LandChannel.Subdivide(startx,starty,endx,endy,m_host.OwnerID);
1372 }
1373
1374 public void osParcelSetDetails(LSL_Vector pos, LSL_List rules)
1375 {
1376 const string functionName = "osParcelSetDetails";
1377 CheckThreatLevel(ThreatLevel.High, functionName);
1378 OSSLDeprecated(functionName, "osSetParcelDetails");
1379 SetParcelDetails(pos, rules, functionName);
1380 }
1381
1382 public void osSetParcelDetails(LSL_Vector pos, LSL_List rules)
1383 {
1384 const string functionName = "osSetParcelDetails";
1385 CheckThreatLevel(ThreatLevel.High, functionName);
1386 SetParcelDetails(pos, rules, functionName);
1387 }
1388
1389 private void SetParcelDetails(LSL_Vector pos, LSL_List rules, string functionName)
1390 {
1391 m_host.AddScriptLPS(1);
1392
1393 // Get a reference to the land data and make sure the owner of the script
1394 // can modify it
1395
1396 ILandObject startLandObject = World.LandChannel.GetLandObject((int)pos.x, (int)pos.y);
1397 if (startLandObject == null)
1398 {
1399 OSSLShoutError("There is no land at that location");
1400 return;
1401 }
1402
1403 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, startLandObject, GroupPowers.LandOptions))
1404 {
1405 OSSLShoutError("You do not have permission to modify the parcel");
1406 return;
1407 }
1408
1409 // Create a new land data object we can modify
1410 LandData newLand = startLandObject.LandData.Copy();
1411 UUID uuid;
1412
1413 // Process the rules, not sure what the impact would be of changing owner or group
1414 for (int idx = 0; idx < rules.Length;)
1415 {
1416 int code = rules.GetLSLIntegerItem(idx++);
1417 string arg = rules.GetLSLStringItem(idx++);
1418 switch (code)
1419 {
1420 case ScriptBaseClass.PARCEL_DETAILS_NAME:
1421 newLand.Name = arg;
1422 break;
1423
1424 case ScriptBaseClass.PARCEL_DETAILS_DESC:
1425 newLand.Description = arg;
1426 break;
1427
1428 case ScriptBaseClass.PARCEL_DETAILS_OWNER:
1429 CheckThreatLevel(ThreatLevel.VeryHigh, functionName);
1430 if (UUID.TryParse(arg, out uuid))
1431 newLand.OwnerID = uuid;
1432 break;
1433
1434 case ScriptBaseClass.PARCEL_DETAILS_GROUP:
1435 CheckThreatLevel(ThreatLevel.VeryHigh, functionName);
1436 if (UUID.TryParse(arg, out uuid))
1437 newLand.GroupID = uuid;
1438 break;
1439
1440 case ScriptBaseClass.PARCEL_DETAILS_CLAIMDATE:
1441 CheckThreatLevel(ThreatLevel.VeryHigh, functionName);
1442 newLand.ClaimDate = Convert.ToInt32(arg);
1443 if (newLand.ClaimDate == 0)
1444 newLand.ClaimDate = Util.UnixTimeSinceEpoch();
1445 break;
1446 }
1447 }
1448
1449 World.LandChannel.UpdateLandObject(newLand.LocalID,newLand);
1450 }
1140 1451
1141 public double osList2Double(LSL_Types.list src, int index) 1452 public double osList2Double(LSL_Types.list src, int index)
1142 { 1453 {
@@ -1180,7 +1491,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1180 { 1491 {
1181 // What actually is the difference to the LL function? 1492 // What actually is the difference to the LL function?
1182 // 1493 //
1183 CheckThreatLevel(ThreatLevel.VeryLow, "osSetParcelMediaURL"); 1494 CheckThreatLevel(ThreatLevel.VeryLow, "osSetParcelSIPAddress");
1184 1495
1185 m_host.AddScriptLPS(1); 1496 m_host.AddScriptLPS(1);
1186 1497
@@ -1201,8 +1512,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1201 voiceModule.setLandSIPAddress(SIPAddress,land.LandData.GlobalID); 1512 voiceModule.setLandSIPAddress(SIPAddress,land.LandData.GlobalID);
1202 else 1513 else
1203 OSSLError("osSetParcelSIPAddress: No voice module enabled for this land"); 1514 OSSLError("osSetParcelSIPAddress: No voice module enabled for this land");
1204
1205
1206 } 1515 }
1207 1516
1208 public string osGetScriptEngineName() 1517 public string osGetScriptEngineName()
@@ -1455,8 +1764,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1455 return jsondata; 1764 return jsondata;
1456 } 1765 }
1457 1766
1458 // send a message to to object identified by the given UUID, a script in the object must implement the dataserver function 1767 /// <summary>
1459 // the dataserver function is passed the ID of the calling function and a string message 1768 /// Send a message to to object identified by the given UUID
1769 /// </summary>
1770 /// <remarks>
1771 /// A script in the object must implement the dataserver function
1772 /// the dataserver function is passed the ID of the calling function and a string message
1773 /// </remarks>
1774 /// <param name="objectUUID"></param>
1775 /// <param name="message"></param>
1460 public void osMessageObject(LSL_Key objectUUID, string message) 1776 public void osMessageObject(LSL_Key objectUUID, string message)
1461 { 1777 {
1462 CheckThreatLevel(ThreatLevel.Low, "osMessageObject"); 1778 CheckThreatLevel(ThreatLevel.Low, "osMessageObject");
@@ -1471,34 +1787,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1471 "dataserver", resobj, new DetectParams[0])); 1787 "dataserver", resobj, new DetectParams[0]));
1472 } 1788 }
1473 1789
1474 1790 /// <summary>
1475 // This needs ThreatLevel high. It is an excellent griefer tool, 1791 /// Write a notecard directly to the prim's inventory.
1476 // In a loop, it can cause asset bloat and DOS levels of asset 1792 /// </summary>
1477 // writes. 1793 /// <remarks>
1478 // 1794 /// This needs ThreatLevel high. It is an excellent griefer tool,
1795 /// In a loop, it can cause asset bloat and DOS levels of asset
1796 /// writes.
1797 /// </remarks>
1798 /// <param name="notecardName">The name of the notecard to write.</param>
1799 /// <param name="contents">The contents of the notecard.</param>
1479 public void osMakeNotecard(string notecardName, LSL_Types.list contents) 1800 public void osMakeNotecard(string notecardName, LSL_Types.list contents)
1480 { 1801 {
1481 CheckThreatLevel(ThreatLevel.High, "osMakeNotecard"); 1802 CheckThreatLevel(ThreatLevel.High, "osMakeNotecard");
1482 m_host.AddScriptLPS(1); 1803 m_host.AddScriptLPS(1);
1483 1804
1484 // Create new asset 1805 StringBuilder notecardData = new StringBuilder();
1485 AssetBase asset = new AssetBase(UUID.Random(), notecardName, (sbyte)AssetType.Notecard);
1486 asset.Description = "Script Generated Notecard";
1487 string notecardData = String.Empty;
1488 1806
1489 for (int i = 0; i < contents.Length; i++) { 1807 for (int i = 0; i < contents.Length; i++)
1490 notecardData += contents.GetLSLStringItem(i) + "\n"; 1808 notecardData.Append((string)(contents.GetLSLStringItem(i) + "\n"));
1491 } 1809
1810 SaveNotecard(notecardName, "Script generated notecard", notecardData.ToString(), false);
1811 }
1812
1813 /// <summary>
1814 /// Save a notecard to prim inventory.
1815 /// </summary>
1816 /// <param name="name"></param>
1817 /// <param name="description">Description of notecard</param>
1818 /// <param name="notecardData"></param>
1819 /// <param name="forceSameName">
1820 /// If true, then if an item exists with the same name, it is replaced.
1821 /// If false, then a new item is created witha slightly different name (e.g. name 1)
1822 /// </param>
1823 /// <returns>Prim inventory item created.</returns>
1824 protected TaskInventoryItem SaveNotecard(string name, string description, string data, bool forceSameName)
1825 {
1826 // Create new asset
1827 AssetBase asset = new AssetBase(UUID.Random(), name, (sbyte)AssetType.Notecard, m_host.OwnerID.ToString());
1828 asset.Description = description;
1492 1829
1493 int textLength = notecardData.Length; 1830 int textLength = data.Length;
1494 notecardData = "Linden text version 2\n{\nLLEmbeddedItems version 1\n{\ncount 0\n}\nText length " 1831 data
1495 + textLength.ToString() + "\n" + notecardData + "}\n"; 1832 = "Linden text version 2\n{\nLLEmbeddedItems version 1\n{\ncount 0\n}\nText length "
1833 + textLength.ToString() + "\n" + data + "}\n";
1496 1834
1497 asset.Data = Util.UTF8.GetBytes(notecardData); 1835 asset.Data = Util.UTF8.GetBytes(data);
1498 World.AssetService.Store(asset); 1836 World.AssetService.Store(asset);
1499 1837
1500 // Create Task Entry 1838 // Create Task Entry
1501 TaskInventoryItem taskItem=new TaskInventoryItem(); 1839 TaskInventoryItem taskItem = new TaskInventoryItem();
1502 1840
1503 taskItem.ResetIDs(m_host.UUID); 1841 taskItem.ResetIDs(m_host.UUID);
1504 taskItem.ParentID = m_host.UUID; 1842 taskItem.ParentID = m_host.UUID;
@@ -1520,29 +1858,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1520 taskItem.PermsMask = 0; 1858 taskItem.PermsMask = 0;
1521 taskItem.AssetID = asset.FullID; 1859 taskItem.AssetID = asset.FullID;
1522 1860
1523 m_host.Inventory.AddInventoryItem(taskItem, false); 1861 if (forceSameName)
1862 m_host.Inventory.AddInventoryItemExclusive(taskItem, false);
1863 else
1864 m_host.Inventory.AddInventoryItem(taskItem, false);
1865
1866 return taskItem;
1524 } 1867 }
1525 1868
1869 /// <summary>
1870 /// Load the notecard data found at the given prim inventory item name or asset uuid.
1871 /// </summary>
1872 /// <param name="notecardNameOrUuid"></param>
1873 /// <returns>The text loaded. Null if no notecard was found.</returns>
1874 protected string LoadNotecard(string notecardNameOrUuid)
1875 {
1876 UUID assetID = CacheNotecard(notecardNameOrUuid);
1877 StringBuilder notecardData = new StringBuilder();
1878
1879 for (int count = 0; count < NotecardCache.GetLines(assetID); count++)
1880 {
1881 string line = NotecardCache.GetLine(assetID, count) + "\n";
1882
1883// m_log.DebugFormat("[OSSL]: From notecard {0} loading line {1}", notecardNameOrUuid, line);
1526 1884
1527 /*Instead of using the LSL Dataserver event to pull notecard data, 1885 notecardData.Append(line);
1528 this will simply read the requested line and return its data as a string. 1886 }
1529 1887
1530 Warning - due to the synchronous method this function uses to fetch assets, its use 1888 return notecardData.ToString();
1531 may be dangerous and unreliable while running in grid mode. 1889 }
1532 */
1533 public string osGetNotecardLine(string name, int line)
1534 {
1535 CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNotecardLine");
1536 m_host.AddScriptLPS(1);
1537 1890
1891 /// <summary>
1892 /// Cache a notecard's contents.
1893 /// </summary>
1894 /// <param name="notecardNameOrUuid"></param>
1895 /// <returns>
1896 /// The asset id of the notecard, which is used for retrieving the cached data.
1897 /// UUID.Zero if no asset could be found.
1898 /// </returns>
1899 protected UUID CacheNotecard(string notecardNameOrUuid)
1900 {
1538 UUID assetID = UUID.Zero; 1901 UUID assetID = UUID.Zero;
1539 1902
1540 if (!UUID.TryParse(name, out assetID)) 1903 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1541 { 1904 {
1542 m_host.TaskInventory.LockItemsForRead(true); 1905 m_host.TaskInventory.LockItemsForRead(true);
1543 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1906 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1544 { 1907 {
1545 if (item.Type == 7 && item.Name == name) 1908 if (item.Type == 7 && item.Name == notecardNameOrUuid)
1546 { 1909 {
1547 assetID = item.AssetID; 1910 assetID = item.AssetID;
1548 } 1911 }
@@ -1551,118 +1914,100 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1551 } 1914 }
1552 1915
1553 if (assetID == UUID.Zero) 1916 if (assetID == UUID.Zero)
1554 { 1917 return UUID.Zero;
1555 OSSLShoutError("Notecard '" + name + "' could not be found.");
1556 return "ERROR!";
1557 }
1558 1918
1559 if (!NotecardCache.IsCached(assetID)) 1919 if (!NotecardCache.IsCached(assetID))
1560 { 1920 {
1561 AssetBase a = World.AssetService.Get(assetID.ToString()); 1921 AssetBase a = World.AssetService.Get(assetID.ToString());
1562 if (a != null)
1563 {
1564 System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
1565 string data = enc.GetString(a.Data);
1566 NotecardCache.Cache(assetID, data);
1567 }
1568 else
1569 {
1570 OSSLShoutError("Notecard '" + name + "' could not be found.");
1571 return "ERROR!";
1572 }
1573 };
1574 1922
1575 return NotecardCache.GetLine(assetID, line, 255); 1923 if (a == null)
1924 return UUID.Zero;
1576 1925
1926 System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
1927 string data = enc.GetString(a.Data);
1928 NotecardCache.Cache(assetID, data);
1929 };
1577 1930
1931 return assetID;
1578 } 1932 }
1579 1933
1580 /*Instead of using the LSL Dataserver event to pull notecard data line by line, 1934 /// <summary>
1581 this will simply read the entire notecard and return its data as a string. 1935 /// Directly get an entire notecard at once.
1936 /// </summary>
1937 /// <remarks>
1938 /// Instead of using the LSL Dataserver event to pull notecard data
1939 /// this will simply read the entire notecard and return its data as a string.
1940 ///
1941 /// Warning - due to the synchronous method this function uses to fetch assets, its use
1942 /// may be dangerous and unreliable while running in grid mode.
1943 /// </remarks>
1944 /// <param name="name">Name of the notecard or its asset id</param>
1945 /// <param name="line">The line number to read. The first line is line 0</param>
1946 /// <returns>Notecard line</returns>
1947 public string osGetNotecardLine(string name, int line)
1948 {
1949 CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNotecardLine");
1950 m_host.AddScriptLPS(1);
1951
1952 UUID assetID = CacheNotecard(name);
1582 1953
1583 Warning - due to the synchronous method this function uses to fetch assets, its use 1954 if (assetID == UUID.Zero)
1584 may be dangerous and unreliable while running in grid mode. 1955 {
1585 */ 1956 OSSLShoutError("Notecard '" + name + "' could not be found.");
1957 return "ERROR!";
1958 }
1959
1960 return NotecardCache.GetLine(assetID, line);
1961 }
1586 1962
1963 /// <summary>
1964 /// Get an entire notecard at once.
1965 /// </summary>
1966 /// <remarks>
1967 /// Instead of using the LSL Dataserver event to pull notecard data line by line,
1968 /// this will simply read the entire notecard and return its data as a string.
1969 ///
1970 /// Warning - due to the synchronous method this function uses to fetch assets, its use
1971 /// may be dangerous and unreliable while running in grid mode.
1972 /// </remarks>
1973 /// <param name="name">Name of the notecard or its asset id</param>
1974 /// <returns>Notecard text</returns>
1587 public string osGetNotecard(string name) 1975 public string osGetNotecard(string name)
1588 { 1976 {
1589 CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNotecard"); 1977 CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNotecard");
1590 m_host.AddScriptLPS(1); 1978 m_host.AddScriptLPS(1);
1591 1979
1592 UUID assetID = UUID.Zero; 1980 string text = LoadNotecard(name);
1593 string NotecardData = "";
1594 1981
1595 if (!UUID.TryParse(name, out assetID)) 1982 if (text == null)
1596 {
1597 m_host.TaskInventory.LockItemsForRead(true);
1598 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1599 {
1600 if (item.Type == 7 && item.Name == name)
1601 {
1602 assetID = item.AssetID;
1603 }
1604 }
1605 m_host.TaskInventory.LockItemsForRead(false);
1606 }
1607
1608 if (assetID == UUID.Zero)
1609 { 1983 {
1610 OSSLShoutError("Notecard '" + name + "' could not be found."); 1984 OSSLShoutError("Notecard '" + name + "' could not be found.");
1611 return "ERROR!"; 1985 return "ERROR!";
1612 } 1986 }
1613 1987 else
1614 if (!NotecardCache.IsCached(assetID))
1615 {
1616 AssetBase a = World.AssetService.Get(assetID.ToString());
1617 if (a != null)
1618 {
1619 System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
1620 string data = enc.GetString(a.Data);
1621 NotecardCache.Cache(assetID, data);
1622 }
1623 else
1624 {
1625 OSSLShoutError("Notecard '" + name + "' could not be found.");
1626 return "ERROR!";
1627 }
1628 };
1629
1630 for (int count = 0; count < NotecardCache.GetLines(assetID); count++)
1631 { 1988 {
1632 NotecardData += NotecardCache.GetLine(assetID, count, 255) + "\n"; 1989 return text;
1633 } 1990 }
1634
1635 return NotecardData;
1636
1637
1638 } 1991 }
1639 1992
1640 /*Instead of using the LSL Dataserver event to pull notecard data, 1993 /// <summary>
1641 this will simply read the number of note card lines and return this data as an integer. 1994 /// Get the number of lines in the given notecard.
1642 1995 /// </summary>
1643 Warning - due to the synchronous method this function uses to fetch assets, its use 1996 /// <remarks>
1644 may be dangerous and unreliable while running in grid mode. 1997 /// Instead of using the LSL Dataserver event to pull notecard data,
1645 */ 1998 /// this will simply read the number of note card lines and return this data as an integer.
1646 1999 ///
2000 /// Warning - due to the synchronous method this function uses to fetch assets, its use
2001 /// may be dangerous and unreliable while running in grid mode.
2002 /// </remarks>
2003 /// <param name="name">Name of the notecard or its asset id</param>
2004 /// <returns></returns>
1647 public int osGetNumberOfNotecardLines(string name) 2005 public int osGetNumberOfNotecardLines(string name)
1648 { 2006 {
1649 CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNumberOfNotecardLines"); 2007 CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNumberOfNotecardLines");
1650 m_host.AddScriptLPS(1); 2008 m_host.AddScriptLPS(1);
1651 2009
1652 UUID assetID = UUID.Zero; 2010 UUID assetID = CacheNotecard(name);
1653
1654 if (!UUID.TryParse(name, out assetID))
1655 {
1656 m_host.TaskInventory.LockItemsForRead(true);
1657 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1658 {
1659 if (item.Type == 7 && item.Name == name)
1660 {
1661 assetID = item.AssetID;
1662 }
1663 }
1664 m_host.TaskInventory.LockItemsForRead(false);
1665 }
1666 2011
1667 if (assetID == UUID.Zero) 2012 if (assetID == UUID.Zero)
1668 { 2013 {
@@ -1670,40 +2015,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1670 return -1; 2015 return -1;
1671 } 2016 }
1672 2017
1673 if (!NotecardCache.IsCached(assetID))
1674 {
1675 AssetBase a = World.AssetService.Get(assetID.ToString());
1676 if (a != null)
1677 {
1678 System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
1679 string data = enc.GetString(a.Data);
1680 NotecardCache.Cache(assetID, data);
1681 }
1682 else
1683 {
1684 OSSLShoutError("Notecard '" + name + "' could not be found.");
1685 return -1;
1686 }
1687 };
1688
1689 return NotecardCache.GetLines(assetID); 2018 return NotecardCache.GetLines(assetID);
1690
1691
1692 } 2019 }
1693 2020
1694 public string osAvatarName2Key(string firstname, string lastname) 2021 public string osAvatarName2Key(string firstname, string lastname)
1695 { 2022 {
1696 CheckThreatLevel(ThreatLevel.Low, "osAvatarName2Key"); 2023 CheckThreatLevel(ThreatLevel.Low, "osAvatarName2Key");
1697 2024
1698 CachedUserInfo userInfo = World.CommsManager.UserProfileCacheService.GetUserDetails(firstname, lastname); 2025 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, firstname, lastname);
1699 2026 if (null == account)
1700 if (null == userInfo)
1701 { 2027 {
1702 return UUID.Zero.ToString(); 2028 return UUID.Zero.ToString();
1703 } 2029 }
1704 else 2030 else
1705 { 2031 {
1706 return userInfo.UserProfile.ID.ToString(); 2032 return account.PrincipalID.ToString();
1707 } 2033 }
1708 } 2034 }
1709 2035
@@ -1714,30 +2040,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1714 2040
1715 if (UUID.TryParse(id, out key)) 2041 if (UUID.TryParse(id, out key))
1716 { 2042 {
1717 CachedUserInfo userInfo = World.CommsManager.UserProfileCacheService.GetUserDetails(key); 2043 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, key);
1718 2044 if (null == account)
1719 if (null == userInfo)
1720 { 2045 {
1721 return ""; 2046 return "";
1722 } 2047 }
1723 else 2048 else
1724 { 2049 {
1725 return userInfo.UserProfile.Name; 2050 return account.Name;
1726 } 2051 }
1727 } 2052 }
1728 else 2053 else
1729 { 2054 {
1730 return ""; 2055 return "";
1731 } 2056 }
1732
1733 } 2057 }
1734 2058
2059 /// <summary>
2060 /// Get the nickname of this grid, as set in the [GridInfo] config section.
2061 /// </summary>
2062 /// <remarks>
1735 /// Threat level is Moderate because intentional abuse, for instance 2063 /// Threat level is Moderate because intentional abuse, for instance
1736 /// scripts that are written to be malicious only on one grid, 2064 /// scripts that are written to be malicious only on one grid,
1737 /// for instance in a HG scenario, are a distinct possibility. 2065 /// for instance in a HG scenario, are a distinct possibility.
1738 /// 2066 /// </remarks>
1739 /// Use value from the config file and return it. 2067 /// <returns></returns>
1740 ///
1741 public string osGetGridNick() 2068 public string osGetGridNick()
1742 { 2069 {
1743 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridNick"); 2070 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridNick");
@@ -1804,16 +2131,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1804 // Find matches beginning at start position 2131 // Find matches beginning at start position
1805 Regex matcher = new Regex(pattern); 2132 Regex matcher = new Regex(pattern);
1806 Match match = matcher.Match(src, start); 2133 Match match = matcher.Match(src, start);
1807 if (match.Success) 2134 while (match.Success)
1808 { 2135 {
1809 foreach (System.Text.RegularExpressions.Group g in match.Groups) 2136 foreach (System.Text.RegularExpressions.Group g in match.Groups)
1810 { 2137 {
1811 if (g.Success) 2138 if (g.Success)
1812 { 2139 {
1813 result.Add(g.Value); 2140 result.Add(new LSL_String(g.Value));
1814 result.Add(g.Index); 2141 result.Add(new LSL_Integer(g.Index));
1815 } 2142 }
1816 } 2143 }
2144
2145 match = match.NextMatch();
1817 } 2146 }
1818 2147
1819 return result; 2148 return result;
@@ -1843,12 +2172,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1843 return World.RegionInfo.RegionSettings.LoadedCreationID; 2172 return World.RegionInfo.RegionSettings.LoadedCreationID;
1844 } 2173 }
1845 2174
1846 // Threat level is 'Low' because certain users could possibly be tricked into 2175 /// <summary>
1847 // dropping an unverified script into one of their own objects, which could 2176 /// Get the primitive parameters of a linked prim.
1848 // then gather the physical construction details of the object and transmit it 2177 /// </summary>
1849 // to an unscrupulous third party, thus permitting unauthorized duplication of 2178 /// <remarks>
1850 // the object's form. 2179 /// Threat level is 'Low' because certain users could possibly be tricked into
1851 // 2180 /// dropping an unverified script into one of their own objects, which could
2181 /// then gather the physical construction details of the object and transmit it
2182 /// to an unscrupulous third party, thus permitting unauthorized duplication of
2183 /// the object's form.
2184 /// </remarks>
2185 /// <param name="linknumber"></param>
2186 /// <param name="rules"></param>
2187 /// <returns></returns>
1852 public LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules) 2188 public LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules)
1853 { 2189 {
1854 CheckThreatLevel(ThreatLevel.High, "osGetLinkPrimitiveParams"); 2190 CheckThreatLevel(ThreatLevel.High, "osGetLinkPrimitiveParams");
@@ -1863,25 +2199,121 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1863 return retVal; 2199 return retVal;
1864 } 2200 }
1865 2201
1866 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, LSL_Key cloneFrom) 2202 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard)
1867 { 2203 {
1868 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2204 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
1869 //QueueUserWorkItem
1870 2205
1871 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2206 INPCModule module = World.RequestModuleInterface<INPCModule>();
1872 if (module != null) 2207 if (module != null)
1873 { 2208 {
2209 AvatarAppearance appearance = null;
2210
2211 UUID id;
2212 if (UUID.TryParse(notecard, out id))
2213 {
2214 ScenePresence clonePresence = World.GetScenePresence(id);
2215 if (clonePresence != null)
2216 appearance = clonePresence.Appearance;
2217 }
2218
2219 if (appearance == null)
2220 {
2221 string appearanceSerialized = LoadNotecard(notecard);
2222
2223 if (appearanceSerialized != null)
2224 {
2225 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2226 appearance = new AvatarAppearance();
2227 appearance.Unpack(appearanceOsd);
2228 }
2229 }
2230
2231 if (appearance == null)
2232 return new LSL_Key(UUID.Zero.ToString());
2233
1874 UUID x = module.CreateNPC(firstname, 2234 UUID x = module.CreateNPC(firstname,
1875 lastname, 2235 lastname,
1876 new Vector3((float) position.x, (float) position.y, (float) position.z), 2236 new Vector3((float) position.x, (float) position.y, (float) position.z),
1877 World, 2237 World,appearance);
1878 new UUID(cloneFrom));
1879 2238
1880 return new LSL_Key(x.ToString()); 2239 return new LSL_Key(x.ToString());
1881 } 2240 }
2241
2242 return new LSL_Key(UUID.Zero.ToString());
2243 }
2244
2245 /// <summary>
2246 /// Save the current appearance of the NPC permanently to the named notecard.
2247 /// </summary>
2248 /// <param name="avatar"></param>
2249 /// <param name="notecard">The name of the notecard to which to save the appearance.</param>
2250 /// <returns>The asset ID of the notecard saved.</returns>
2251 public LSL_Key osNpcSaveAppearance(LSL_Key npc, string notecard)
2252 {
2253 CheckThreatLevel(ThreatLevel.High, "osNpcSaveAppearance");
2254
2255 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2256
2257 if (npcModule != null)
2258 {
2259 UUID npcId;
2260 if (!UUID.TryParse(npc.m_string, out npcId))
2261 return new LSL_Key(UUID.Zero.ToString());
2262
2263 if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene))
2264 return new LSL_Key(UUID.Zero.ToString());
2265
2266 return SaveAppearanceToNotecard(npcId, notecard);
2267 }
2268
1882 return new LSL_Key(UUID.Zero.ToString()); 2269 return new LSL_Key(UUID.Zero.ToString());
1883 } 2270 }
1884 2271
2272 public void osNpcLoadAppearance(LSL_Key npc, string notecard)
2273 {
2274 CheckThreatLevel(ThreatLevel.High, "osNpcLoadAppearance");
2275
2276 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2277
2278 if (npcModule != null)
2279 {
2280 UUID npcId;
2281 if (!UUID.TryParse(npc.m_string, out npcId))
2282 return;
2283
2284 string appearanceSerialized = LoadNotecard(notecard);
2285 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2286// OSD a = OSDParser.DeserializeLLSDXml(appearanceSerialized);
2287// Console.WriteLine("appearanceSerialized {0}", appearanceSerialized);
2288// Console.WriteLine("a.Type {0}, a.ToString() {1}", a.Type, a);
2289 AvatarAppearance appearance = new AvatarAppearance();
2290 appearance.Unpack(appearanceOsd);
2291
2292 npcModule.SetNPCAppearance(npcId, appearance, m_host.ParentGroup.Scene);
2293 }
2294 }
2295
2296 public LSL_Vector osNpcGetPos(LSL_Key npc)
2297 {
2298 CheckThreatLevel(ThreatLevel.High, "osNpcGetPos");
2299
2300 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2301 if (npcModule != null)
2302 {
2303 UUID npcId;
2304 if (!UUID.TryParse(npc.m_string, out npcId))
2305 return new LSL_Vector(0, 0, 0);
2306
2307 if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene))
2308 return new LSL_Vector(0, 0, 0);
2309
2310 Vector3 pos = World.GetScenePresence(npcId).AbsolutePosition;
2311 return new LSL_Vector(pos.X, pos.Y, pos.Z);
2312 }
2313
2314 return new LSL_Vector(0, 0, 0);
2315 }
2316
1885 public void osNpcMoveTo(LSL_Key npc, LSL_Vector position) 2317 public void osNpcMoveTo(LSL_Key npc, LSL_Vector position)
1886 { 2318 {
1887 CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo"); 2319 CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo");
@@ -1889,11 +2321,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1889 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2321 INPCModule module = World.RequestModuleInterface<INPCModule>();
1890 if (module != null) 2322 if (module != null)
1891 { 2323 {
2324 UUID npcId;
2325 if (!UUID.TryParse(npc.m_string, out npcId))
2326 return;
2327
1892 Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z); 2328 Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z);
1893 module.Autopilot(new UUID(npc.m_string), World, pos); 2329 module.MoveToTarget(npcId, World, pos, false, true);
1894 } 2330 }
1895 } 2331 }
1896 2332
2333 public void osNpcMoveToTarget(LSL_Key npc, LSL_Vector target, int options)
2334 {
2335 CheckThreatLevel(ThreatLevel.High, "osNpcMoveToTarget");
2336
2337 INPCModule module = World.RequestModuleInterface<INPCModule>();
2338 if (module != null)
2339 {
2340 UUID npcId;
2341 if (!UUID.TryParse(npc.m_string, out npcId))
2342 return;
2343
2344 Vector3 pos = new Vector3((float)target.x, (float)target.y, (float)target.z);
2345 module.MoveToTarget(
2346 new UUID(npc.m_string),
2347 World,
2348 pos,
2349 (options & ScriptBaseClass.OS_NPC_NO_FLY) != 0,
2350 (options & ScriptBaseClass.OS_NPC_LAND_AT_TARGET) != 0);
2351 }
2352 }
2353
2354 public LSL_Rotation osNpcGetRot(LSL_Key npc)
2355 {
2356 CheckThreatLevel(ThreatLevel.High, "osNpcGetRot");
2357
2358 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2359 if (npcModule != null)
2360 {
2361 UUID npcId;
2362 if (!UUID.TryParse(npc.m_string, out npcId))
2363 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W);
2364
2365 if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene))
2366 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W);
2367
2368 ScenePresence sp = World.GetScenePresence(npcId);
2369 Quaternion rot = sp.Rotation;
2370
2371 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2372 }
2373
2374 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W);
2375 }
2376
2377 public void osNpcSetRot(LSL_Key npc, LSL_Rotation rotation)
2378 {
2379 CheckThreatLevel(ThreatLevel.High, "osNpcSetRot");
2380
2381 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2382 if (npcModule != null)
2383 {
2384 UUID npcId;
2385 if (!UUID.TryParse(npc.m_string, out npcId))
2386 return;
2387
2388 if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene))
2389 return;
2390
2391 ScenePresence sp = World.GetScenePresence(npcId);
2392 sp.Rotation = LSL_Api.Rot2Quaternion(rotation);
2393 }
2394 }
2395
2396 public void osNpcStopMoveToTarget(LSL_Key npc)
2397 {
2398 CheckThreatLevel(ThreatLevel.VeryLow, "osNpcStopMoveTo");
2399
2400 INPCModule module = World.RequestModuleInterface<INPCModule>();
2401 if (module != null)
2402 module.StopMoveToTarget(new UUID(npc.m_string), World);
2403 }
2404
1897 public void osNpcSay(LSL_Key npc, string message) 2405 public void osNpcSay(LSL_Key npc, string message)
1898 { 2406 {
1899 CheckThreatLevel(ThreatLevel.High, "osNpcSay"); 2407 CheckThreatLevel(ThreatLevel.High, "osNpcSay");
@@ -1905,6 +2413,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1905 } 2413 }
1906 } 2414 }
1907 2415
2416 public void osNpcSit(LSL_Key npc, LSL_Key target, int options)
2417 {
2418 CheckThreatLevel(ThreatLevel.High, "osNpcSit");
2419
2420 INPCModule module = World.RequestModuleInterface<INPCModule>();
2421 if (module != null)
2422 {
2423 module.Sit(new UUID(npc.m_string), new UUID(target.m_string), World);
2424 }
2425 }
2426
2427 public void osNpcStand(LSL_Key npc)
2428 {
2429 CheckThreatLevel(ThreatLevel.High, "osNpcStand");
2430
2431 INPCModule module = World.RequestModuleInterface<INPCModule>();
2432 if (module != null)
2433 {
2434 module.Stand(new UUID(npc.m_string), World);
2435 }
2436 }
2437
1908 public void osNpcRemove(LSL_Key npc) 2438 public void osNpcRemove(LSL_Key npc)
1909 { 2439 {
1910 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2440 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
@@ -1915,6 +2445,64 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1915 module.DeleteNPC(new UUID(npc.m_string), World); 2445 module.DeleteNPC(new UUID(npc.m_string), World);
1916 } 2446 }
1917 } 2447 }
2448
2449 /// <summary>
2450 /// Save the current appearance of the script owner permanently to the named notecard.
2451 /// </summary>
2452 /// <param name="notecard">The name of the notecard to which to save the appearance.</param>
2453 /// <returns>The asset ID of the notecard saved.</returns>
2454 public LSL_Key osOwnerSaveAppearance(string notecard)
2455 {
2456 CheckThreatLevel(ThreatLevel.High, "osOwnerSaveAppearance");
2457
2458 return SaveAppearanceToNotecard(m_host.OwnerID, notecard);
2459 }
2460
2461 public LSL_Key osAgentSaveAppearance(LSL_Key avatarId, string notecard)
2462 {
2463 CheckThreatLevel(ThreatLevel.VeryHigh, "osAgentSaveAppearance");
2464
2465 return SaveAppearanceToNotecard(avatarId, notecard);
2466 }
2467
2468 protected LSL_Key SaveAppearanceToNotecard(ScenePresence sp, string notecard)
2469 {
2470 IAvatarFactoryModule appearanceModule = World.RequestModuleInterface<IAvatarFactoryModule>();
2471
2472 if (appearanceModule != null)
2473 {
2474 appearanceModule.SaveBakedTextures(sp.UUID);
2475 OSDMap appearancePacked = sp.Appearance.Pack();
2476
2477 TaskInventoryItem item
2478 = SaveNotecard(notecard, "Avatar Appearance", Util.GetFormattedXml(appearancePacked as OSD), true);
2479
2480 return new LSL_Key(item.AssetID.ToString());
2481 }
2482 else
2483 {
2484 return new LSL_Key(UUID.Zero.ToString());
2485 }
2486 }
2487
2488 protected LSL_Key SaveAppearanceToNotecard(UUID avatarId, string notecard)
2489 {
2490 ScenePresence sp = World.GetScenePresence(avatarId);
2491
2492 if (sp == null || sp.IsChildAgent)
2493 return new LSL_Key(UUID.Zero.ToString());
2494
2495 return SaveAppearanceToNotecard(sp, notecard);
2496 }
2497
2498 protected LSL_Key SaveAppearanceToNotecard(LSL_Key rawAvatarId, string notecard)
2499 {
2500 UUID avatarId;
2501 if (!UUID.TryParse(rawAvatarId, out avatarId))
2502 return new LSL_Key(UUID.Zero.ToString());
2503
2504 return SaveAppearanceToNotecard(avatarId, notecard);
2505 }
1918 2506
1919 /// <summary> 2507 /// <summary>
1920 /// Get current region's map texture UUID 2508 /// Get current region's map texture UUID
@@ -1965,7 +2553,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1965 CheckThreatLevel(ThreatLevel.Moderate, "osGetRegionStats"); 2553 CheckThreatLevel(ThreatLevel.Moderate, "osGetRegionStats");
1966 m_host.AddScriptLPS(1); 2554 m_host.AddScriptLPS(1);
1967 LSL_List ret = new LSL_List(); 2555 LSL_List ret = new LSL_List();
1968 float[] stats = World.SimulatorStats; 2556 float[] stats = World.StatsReporter.LastReportedSimStats;
1969 2557
1970 for (int i = 0; i < 21; i++) 2558 for (int i = 0; i < 21; i++)
1971 { 2559 {
@@ -1988,12 +2576,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1988 return (int)pws; 2576 return (int)pws;
1989 } 2577 }
1990 2578
1991 public void osSetSpeed(string UUID, float SpeedModifier) 2579 public void osSetSpeed(string UUID, LSL_Float SpeedModifier)
1992 { 2580 {
1993 CheckThreatLevel(ThreatLevel.Moderate, "osSetSpeed"); 2581 CheckThreatLevel(ThreatLevel.Moderate, "osSetSpeed");
1994 m_host.AddScriptLPS(1); 2582 m_host.AddScriptLPS(1);
1995 ScenePresence avatar = World.GetScenePresence(new UUID(UUID)); 2583 ScenePresence avatar = World.GetScenePresence(new UUID(UUID));
1996 avatar.SpeedModifier = SpeedModifier; 2584 avatar.SpeedModifier = (float)SpeedModifier;
1997 } 2585 }
1998 2586
1999 public void osKickAvatar(string FirstName,string SurName,string alert) 2587 public void osKickAvatar(string FirstName,string SurName,string alert)
@@ -2001,19 +2589,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2001 CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar"); 2589 CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar");
2002 if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID)) 2590 if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID))
2003 { 2591 {
2004 foreach (ScenePresence presence in World.GetAvatars()) 2592 World.ForEachRootScenePresence(delegate(ScenePresence sp)
2005 { 2593 {
2006 if ((presence.Firstname == FirstName) && 2594 if (sp.Firstname == FirstName && sp.Lastname == SurName)
2007 presence.Lastname == SurName)
2008 { 2595 {
2009 // kick client... 2596 // kick client...
2010 if (alert != null) 2597 if (alert != null)
2011 presence.ControllingClient.Kick(alert); 2598 sp.ControllingClient.Kick(alert);
2012 2599
2013 // ...and close on our side 2600 // ...and close on our side
2014 presence.Scene.IncomingCloseAgent(presence.UUID); 2601 sp.Scene.IncomingCloseAgent(sp.UUID);
2015 } 2602 }
2016 } 2603 });
2017 } 2604 }
2018 } 2605 }
2019 2606
@@ -2068,5 +2655,102 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2068 } 2655 }
2069 } 2656 }
2070 } 2657 }
2658
2659 public LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules)
2660 {
2661 CheckThreatLevel(ThreatLevel.High, "osGetPrimitiveParams");
2662 m_host.AddScriptLPS(1);
2663 InitLSL();
2664
2665 return m_LSL_Api.GetLinkPrimitiveParamsEx(prim, rules);
2666 }
2667
2668 public void osSetPrimitiveParams(LSL_Key prim, LSL_List rules)
2669 {
2670 CheckThreatLevel(ThreatLevel.High, "osSetPrimitiveParams");
2671 m_host.AddScriptLPS(1);
2672 InitLSL();
2673
2674 m_LSL_Api.SetPrimitiveParamsEx(prim, rules);
2675 }
2676
2677 /// <summary>
2678 /// Set parameters for light projection in host prim
2679 /// </summary>
2680 public void osSetProjectionParams(bool projection, LSL_Key texture, double fov, double focus, double amb)
2681 {
2682 CheckThreatLevel(ThreatLevel.High, "osSetProjectionParams");
2683
2684 osSetProjectionParams(UUID.Zero.ToString(), projection, texture, fov, focus, amb);
2685 }
2686
2687 /// <summary>
2688 /// Set parameters for light projection with uuid of target prim
2689 /// </summary>
2690 public void osSetProjectionParams(LSL_Key prim, bool projection, LSL_Key texture, double fov, double focus, double amb)
2691 {
2692 CheckThreatLevel(ThreatLevel.High, "osSetProjectionParams");
2693 m_host.AddScriptLPS(1);
2694
2695 SceneObjectPart obj = null;
2696 if (prim == UUID.Zero.ToString())
2697 {
2698 obj = m_host;
2699 }
2700 else
2701 {
2702 obj = World.GetSceneObjectPart(new UUID(prim));
2703 if (obj == null)
2704 return;
2705 }
2706
2707 obj.Shape.ProjectionEntry = projection;
2708 obj.Shape.ProjectionTextureUUID = new UUID(texture);
2709 obj.Shape.ProjectionFOV = (float)fov;
2710 obj.Shape.ProjectionFocus = (float)focus;
2711 obj.Shape.ProjectionAmbiance = (float)amb;
2712
2713 obj.ParentGroup.HasGroupChanged = true;
2714 obj.ScheduleFullUpdate();
2715 }
2716
2717 /// <summary>
2718 /// Like osGetAgents but returns enough info for a radar
2719 /// </summary>
2720 /// <returns>Strided list of the UUID, position and name of each avatar in the region</returns>
2721 public LSL_List osGetAvatarList()
2722 {
2723 CheckThreatLevel(ThreatLevel.None, "osGetAvatarList");
2724
2725 LSL_List result = new LSL_List();
2726 World.ForEachRootScenePresence(delegate (ScenePresence avatar)
2727 {
2728 if (avatar != null && avatar.UUID != m_host.OwnerID)
2729 {
2730 result.Add(new LSL_String(avatar.UUID.ToString()));
2731 OpenMetaverse.Vector3 ap = avatar.AbsolutePosition;
2732 result.Add(new LSL_Vector(ap.X, ap.Y, ap.Z));
2733 result.Add(new LSL_String(avatar.Name));
2734 }
2735 });
2736
2737 return result;
2738 }
2739
2740 /// <summary>
2741 /// Convert a unix time to a llGetTimestamp() like string
2742 /// </summary>
2743 /// <param name="unixTime"></param>
2744 /// <returns></returns>
2745 public LSL_String osUnixTimeToTimestamp(long time)
2746 {
2747 CheckThreatLevel(ThreatLevel.VeryLow, "osUnixTimeToTimestamp");
2748 long baseTicks = 621355968000000000;
2749 long tickResolution = 10000000;
2750 long epochTicks = (time * tickResolution) + baseTicks;
2751 DateTime date = new DateTime(epochTicks);
2752
2753 return date.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ");
2754 }
2071 } 2755 }
2072} \ No newline at end of file 2756} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index b75a2e4..4da8fe7 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -29,7 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using OpenMetaverse; 30using OpenMetaverse;
31using OpenSim.Framework; 31using OpenSim.Framework;
32using OpenSim.Framework.Communications.Cache; 32
33using OpenSim.Region.Framework.Scenes; 33using OpenSim.Region.Framework.Scenes;
34using OpenSim.Region.ScriptEngine.Shared; 34using OpenSim.Region.ScriptEngine.Shared;
35using OpenSim.Region.ScriptEngine.Shared.Api; 35using OpenSim.Region.ScriptEngine.Shared.Api;
@@ -50,6 +50,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
50 private Object SenseLock = new Object(); 50 private Object SenseLock = new Object();
51 51
52 private const int AGENT = 1; 52 private const int AGENT = 1;
53 private const int AGENT_BY_USERNAME = 0x10;
53 private const int ACTIVE = 2; 54 private const int ACTIVE = 2;
54 private const int PASSIVE = 4; 55 private const int PASSIVE = 4;
55 private const int SCRIPTED = 8; 56 private const int SCRIPTED = 8;
@@ -139,7 +140,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
139 List<SenseRepeatClass> NewSensors = new List<SenseRepeatClass>(); 140 List<SenseRepeatClass> NewSensors = new List<SenseRepeatClass>();
140 foreach (SenseRepeatClass ts in SenseRepeaters) 141 foreach (SenseRepeatClass ts in SenseRepeaters)
141 { 142 {
142 if (ts.localID != m_localID && ts.itemID != m_itemID) 143 if (ts.localID != m_localID || ts.itemID != m_itemID)
143 { 144 {
144 NewSensors.Add(ts); 145 NewSensors.Add(ts);
145 } 146 }
@@ -202,9 +203,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
202 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 203 List<SensedEntity> sensedEntities = new List<SensedEntity>();
203 204
204 // Is the sensor type is AGENT and not SCRIPTED then include agents 205 // Is the sensor type is AGENT and not SCRIPTED then include agents
205 if ((ts.type & AGENT) != 0 && (ts.type & SCRIPTED) == 0) 206 if ((ts.type & (AGENT | AGENT_BY_USERNAME)) != 0 && (ts.type & SCRIPTED) == 0)
206 { 207 {
207 sensedEntities.AddRange(doAgentSensor(ts)); 208 sensedEntities.AddRange(doAgentSensor(ts));
208 } 209 }
209 210
210 // If SCRIPTED or PASSIVE or ACTIVE check objects 211 // If SCRIPTED or PASSIVE or ACTIVE check objects
@@ -286,7 +287,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
286 } 287 }
287 else 288 else
288 { 289 {
289 Entities = m_CmdManager.m_ScriptEngine.World.GetEntities(); 290 Entities = new List<EntityBase>(m_CmdManager.m_ScriptEngine.World.GetEntities());
290 } 291 }
291 SceneObjectPart SensePoint = ts.host; 292 SceneObjectPart SensePoint = ts.host;
292 293
@@ -301,7 +302,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
301 float dy; 302 float dy;
302 float dz; 303 float dz;
303 304
304 Quaternion q = SensePoint.RotationOffset; 305// Quaternion q = SensePoint.RotationOffset;
306 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
307 if (SensePoint.ParentGroup.IsAttachment)
308 {
309 // In attachments, the sensor cone always orients with the
310 // avatar rotation. This may include a nonzero elevation if
311 // in mouselook.
312 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
313 fromRegionPos = avatar.AbsolutePosition;
314 q = avatar.Rotation;
315 }
305 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 316 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
306 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 317 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
307 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 318 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
@@ -343,7 +354,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
343 objtype = 0; 354 objtype = 0;
344 355
345 part = ((SceneObjectGroup)ent).RootPart; 356 part = ((SceneObjectGroup)ent).RootPart;
346 if (part.AttachmentPoint != 0) // Attached so ignore 357 if (part.ParentGroup.AttachmentPoint != 0) // Attached so ignore
347 continue; 358 continue;
348 359
349 if (part.Inventory.ContainsScripts()) 360 if (part.Inventory.ContainsScripts())
@@ -404,70 +415,51 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
404 415
405 private List<SensedEntity> doAgentSensor(SenseRepeatClass ts) 416 private List<SensedEntity> doAgentSensor(SenseRepeatClass ts)
406 { 417 {
407 List<ScenePresence> presences;
408 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 418 List<SensedEntity> sensedEntities = new List<SensedEntity>();
409 419
410 // If this is an avatar sense by key try to get them directly
411 // rather than getting a list to scan through
412 if (ts.keyID != UUID.Zero)
413 {
414 ScenePresence p = m_CmdManager.m_ScriptEngine.World.GetScenePresence(ts.keyID);
415 if (p == null)
416 return sensedEntities;
417 presences = new List<ScenePresence>();
418 presences.Add(p);
419 }
420 else
421 {
422 presences = new List<ScenePresence>(m_CmdManager.m_ScriptEngine.World.GetScenePresences());
423 }
424
425 // If nobody about quit fast 420 // If nobody about quit fast
426 if (presences.Count == 0) 421 if (m_CmdManager.m_ScriptEngine.World.GetRootAgentCount() == 0)
427 return sensedEntities; 422 return sensedEntities;
428 423
429 SceneObjectPart SensePoint = ts.host; 424 SceneObjectPart SensePoint = ts.host;
430
431 Vector3 fromRegionPos = SensePoint.AbsolutePosition; 425 Vector3 fromRegionPos = SensePoint.AbsolutePosition;
432 426
433 Quaternion q = SensePoint.RotationOffset; 427 Quaternion q = SensePoint.RotationOffset;
428 if (SensePoint.ParentGroup.IsAttachment)
429 {
430 // In attachments, the sensor cone always orients with the
431 // avatar rotation. This may include a nonzero elevation if
432 // in mouselook.
433 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
434 fromRegionPos = avatar.AbsolutePosition;
435 q = avatar.Rotation;
436 }
437
434 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 438 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
435 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 439 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
436 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 440 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
437 441 bool attached = (SensePoint.ParentGroup.AttachmentPoint != 0);
438 bool attached = (SensePoint.AttachmentPoint != 0);
439 bool nameSearch = (ts.name != null && ts.name != "");
440 Vector3 toRegionPos; 442 Vector3 toRegionPos;
441 double dis; 443 double dis;
442 444
443 for (int i = 0; i < presences.Count; i++) 445 Action<ScenePresence> senseEntity = new Action<ScenePresence>(delegate(ScenePresence presence)
444 { 446 {
445 ScenePresence presence = presences[i]; 447 if (presence.IsDeleted || presence.IsChildAgent || presence.GodLevel > 0.0)
446 bool keep = true; 448 return;
447 449
448 if (presence.IsDeleted) 450 // if the object the script is in is attached and the avatar is the owner
449 continue; 451 // then this one is not wanted
452 if (attached && presence.UUID == SensePoint.OwnerID)
453 return;
450 454
451 if (presence.IsChildAgent)
452 keep = false;
453 toRegionPos = presence.AbsolutePosition; 455 toRegionPos = presence.AbsolutePosition;
454
455 dis = Math.Abs(Util.GetDistanceTo(toRegionPos, fromRegionPos)); 456 dis = Math.Abs(Util.GetDistanceTo(toRegionPos, fromRegionPos));
456 457
457 // are they in range 458 // are they in range
458 if (keep && dis <= ts.range) 459 if (dis <= ts.range)
459 { 460 {
460 // if the object the script is in is attached and the avatar is the owner
461 // then this one is not wanted
462 if (attached && presence.UUID == SensePoint.OwnerID)
463 keep = false;
464
465 // check the name if needed
466 if (keep && nameSearch && ts.name != presence.Name)
467 keep = false;
468
469 // Are they in the required angle of view 461 // Are they in the required angle of view
470 if (keep && ts.arc < Math.PI) 462 if (ts.arc < Math.PI)
471 { 463 {
472 // not omni-directional. Can you see it ? 464 // not omni-directional. Can you see it ?
473 // vec forward_dir = llRot2Fwd(llGetRot()) 465 // vec forward_dir = llRot2Fwd(llGetRot())
@@ -488,26 +480,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
488 catch 480 catch
489 { 481 {
490 } 482 }
491 if (ang_obj > ts.arc) keep = false; 483 if (ang_obj <= ts.arc)
484 {
485 sensedEntities.Add(new SensedEntity(dis, presence.UUID));
486 }
487 }
488 else
489 {
490 sensedEntities.Add(new SensedEntity(dis, presence.UUID));
492 } 491 }
493 } 492 }
494 else 493 });
495 {
496 keep = false;
497 }
498
499 // Do not report gods, not even minor ones
500 if (keep && presence.GodLevel > 0.0)
501 keep = false;
502 494
503 if (keep) // add to list with distance 495 // If this is an avatar sense by key try to get them directly
496 // rather than getting a list to scan through
497 if (ts.keyID != UUID.Zero)
498 {
499 ScenePresence sp;
500 // Try direct lookup by UUID
501 if (!m_CmdManager.m_ScriptEngine.World.TryGetScenePresence(ts.keyID, out sp))
502 return sensedEntities;
503 senseEntity(sp);
504 }
505 else if (ts.name != null && ts.name != "")
506 {
507 ScenePresence sp;
508 // Try lookup by name will return if/when found
509 if (((ts.type & AGENT) != 0) && m_CmdManager.m_ScriptEngine.World.TryGetAvatarByName(ts.name, out sp))
510 senseEntity(sp);
511 if ((ts.type & AGENT_BY_USERNAME) != 0)
504 { 512 {
505 sensedEntities.Add(new SensedEntity(dis, presence.UUID)); 513 m_CmdManager.m_ScriptEngine.World.ForEachRootScenePresence(
514 delegate (ScenePresence ssp)
515 {
516 if (ssp.Lastname == "Resident")
517 {
518 if (ssp.Firstname.ToLower() == ts.name)
519 senseEntity(ssp);
520 return;
521 }
522 if (ssp.Name.Replace(" ", ".").ToLower() == ts.name)
523 senseEntity(ssp);
524 }
525 );
506 } 526 }
507 527
508 // If this is a search by name and we have just found it then no more to do 528 return sensedEntities;
509 if (nameSearch && ts.name == presence.Name) 529 }
510 return sensedEntities; 530 else
531 {
532 m_CmdManager.m_ScriptEngine.World.ForEachRootScenePresence(senseEntity);
511 } 533 }
512 return sensedEntities; 534 return sensedEntities;
513 } 535 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
index 6239726..ab215f3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -1,4 +1,31 @@
1using System.Collections; 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.Collections;
2using OpenSim.Region.ScriptEngine.Interfaces; 29using OpenSim.Region.ScriptEngine.Interfaces;
3 30
4using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
@@ -13,10 +40,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
13{ 40{
14 public interface ICM_Api 41 public interface ICM_Api
15 { 42 {
16 // Windlight Functions 43 string cmDetectedCountry(int num);
17 LSL_List cmGetWindlightScene(LSL_List rules); 44 string cmGetAgentCountry(key key);
18 int cmSetWindlightScene(LSL_List rules);
19 int cmSetWindlightSceneTargeted(LSL_List rules, key target);
20 LSL_List cmGetAvatarList();
21 } 45 }
22} 46}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 7ab04a3..e0027b2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -54,14 +54,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
54 LSL_Float llAtan2(double x, double y); 54 LSL_Float llAtan2(double x, double y);
55 void llAttachToAvatar(int attachment); 55 void llAttachToAvatar(int attachment);
56 LSL_Key llAvatarOnSitTarget(); 56 LSL_Key llAvatarOnSitTarget();
57 LSL_Key llAvatarOnLinkSitTarget(int linknum);
57 LSL_Rotation llAxes2Rot(LSL_Vector fwd, LSL_Vector left, LSL_Vector up); 58 LSL_Rotation llAxes2Rot(LSL_Vector fwd, LSL_Vector left, LSL_Vector up);
58 LSL_Rotation llAxisAngle2Rot(LSL_Vector axis, double angle); 59 LSL_Rotation llAxisAngle2Rot(LSL_Vector axis, double angle);
59 LSL_Integer llBase64ToInteger(string str); 60 LSL_Integer llBase64ToInteger(string str);
60 LSL_String llBase64ToString(string str); 61 LSL_String llBase64ToString(string str);
61 void llBreakAllLinks(); 62 void llBreakAllLinks();
62 void llBreakLink(int linknum); 63 void llBreakLink(int linknum);
64 LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options);
63 LSL_Integer llCeil(double f); 65 LSL_Integer llCeil(double f);
64 void llClearCameraParams(); 66 void llClearCameraParams();
67 LSL_Integer llClearPrimMedia(LSL_Integer face);
65 void llCloseRemoteDataChannel(string channel); 68 void llCloseRemoteDataChannel(string channel);
66 LSL_Float llCloud(LSL_Vector offset); 69 LSL_Float llCloud(LSL_Vector offset);
67 void llCollisionFilter(string name, string id, int accept); 70 void llCollisionFilter(string name, string id, int accept);
@@ -120,6 +123,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
120 LSL_Float llGetEnergy(); 123 LSL_Float llGetEnergy();
121 LSL_Vector llGetForce(); 124 LSL_Vector llGetForce();
122 LSL_Integer llGetFreeMemory(); 125 LSL_Integer llGetFreeMemory();
126 LSL_Integer llGetUsedMemory();
123 LSL_Integer llGetFreeURLs(); 127 LSL_Integer llGetFreeURLs();
124 LSL_Vector llGetGeometricCenter(); 128 LSL_Vector llGetGeometricCenter();
125 LSL_Float llGetGMTclock(); 129 LSL_Float llGetGMTclock();
@@ -162,6 +166,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
162 LSL_List llGetParcelPrimOwners(LSL_Vector pos); 166 LSL_List llGetParcelPrimOwners(LSL_Vector pos);
163 LSL_Integer llGetPermissions(); 167 LSL_Integer llGetPermissions();
164 LSL_Key llGetPermissionsKey(); 168 LSL_Key llGetPermissionsKey();
169 LSL_List llGetPrimMediaParams(int face, LSL_List rules);
165 LSL_Vector llGetPos(); 170 LSL_Vector llGetPos();
166 LSL_List llGetPrimitiveParams(LSL_List rules); 171 LSL_List llGetPrimitiveParams(LSL_List rules);
167 LSL_Integer llGetRegionAgentCount(); 172 LSL_Integer llGetRegionAgentCount();
@@ -195,6 +200,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
195 void llGiveInventory(string destination, string inventory); 200 void llGiveInventory(string destination, string inventory);
196 void llGiveInventoryList(string destination, string category, LSL_List inventory); 201 void llGiveInventoryList(string destination, string category, LSL_List inventory);
197 LSL_Integer llGiveMoney(string destination, int amount); 202 LSL_Integer llGiveMoney(string destination, int amount);
203 LSL_String llTransferLindenDollars(string destination, int amount);
198 void llGodLikeRezObject(string inventory, LSL_Vector pos); 204 void llGodLikeRezObject(string inventory, LSL_Vector pos);
199 LSL_Float llGround(LSL_Vector offset); 205 LSL_Float llGround(LSL_Vector offset);
200 LSL_Vector llGroundContour(LSL_Vector offset); 206 LSL_Vector llGroundContour(LSL_Vector offset);
@@ -207,6 +213,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
207 void llInstantMessage(string user, string message); 213 void llInstantMessage(string user, string message);
208 LSL_String llIntegerToBase64(int number); 214 LSL_String llIntegerToBase64(int number);
209 LSL_String llKey2Name(string id); 215 LSL_String llKey2Name(string id);
216 LSL_String llGetUsername(string id);
217 LSL_String llRequestUsername(string id);
218 LSL_String llGetDisplayName(string id);
219 LSL_String llRequestDisplayName(string id);
210 void llLinkParticleSystem(int linknum, LSL_List rules); 220 void llLinkParticleSystem(int linknum, LSL_List rules);
211 LSL_String llList2CSV(LSL_List src); 221 LSL_String llList2CSV(LSL_List src);
212 LSL_Float llList2Float(LSL_List src, int index); 222 LSL_Float llList2Float(LSL_List src, int index);
@@ -264,6 +274,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
264 void llPushObject(string target, LSL_Vector impulse, LSL_Vector ang_impulse, int local); 274 void llPushObject(string target, LSL_Vector impulse, LSL_Vector ang_impulse, int local);
265 void llRefreshPrimURL(); 275 void llRefreshPrimURL();
266 void llRegionSay(int channelID, string text); 276 void llRegionSay(int channelID, string text);
277 void llRegionSayTo(string target, int channelID, string text);
267 void llReleaseCamera(string avatar); 278 void llReleaseCamera(string avatar);
268 void llReleaseControls(); 279 void llReleaseControls();
269 void llReleaseURL(string url); 280 void llReleaseURL(string url);
@@ -332,6 +343,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
332 void llSetParcelMusicURL(string url); 343 void llSetParcelMusicURL(string url);
333 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 344 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
334 void llSetPos(LSL_Vector pos); 345 void llSetPos(LSL_Vector pos);
346 LSL_Integer llSetPrimMediaParams(int face, LSL_List rules);
335 void llSetPrimitiveParams(LSL_List rules); 347 void llSetPrimitiveParams(LSL_List rules);
336 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 348 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
337 void llSetPrimURL(string url); 349 void llSetPrimURL(string url);
@@ -395,5 +407,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
395 LSL_Vector llWind(LSL_Vector offset); 407 LSL_Vector llWind(LSL_Vector offset);
396 LSL_String llXorBase64Strings(string str1, string str2); 408 LSL_String llXorBase64Strings(string str1, string str2);
397 LSL_String llXorBase64StringsCorrect(string str1, string str2); 409 LSL_String llXorBase64StringsCorrect(string str1, string str2);
410 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
411
412 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
413 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
398 } 414 }
399} 415}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILS_Api.cs
new file mode 100644
index 0000000..f2df094
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILS_Api.cs
@@ -0,0 +1,49 @@
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.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces;
30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{
41 public interface ILS_Api
42 {
43 // Windlight Functions
44 LSL_List lsGetWindlightScene(LSL_List rules);
45 int lsSetWindlightScene(LSL_List rules);
46 int lsSetWindlightSceneTargeted(LSL_List rules, key target);
47 void lsClearWindlightScene();
48 }
49}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index f5921e1..a61d553 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -35,6 +35,7 @@ using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; 36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; 37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
38 39
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces 40namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{ 41{
@@ -66,8 +67,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
66 string osSetDynamicTextureDataBlendFace(string dynamicID, string contentType, string data, string extraParams, 67 string osSetDynamicTextureDataBlendFace(string dynamicID, string contentType, string data, string extraParams,
67 bool blend, int disp, int timer, int alpha, int face); 68 bool blend, int disp, int timer, int alpha, int face);
68 69
69 LSL_Float osTerrainGetHeight(int x, int y); 70 LSL_Float osGetTerrainHeight(int x, int y);
70 LSL_Integer osTerrainSetHeight(int x, int y, double val); 71 LSL_Float osTerrainGetHeight(int x, int y); // Deprecated
72 LSL_Integer osSetTerrainHeight(int x, int y, double val);
73 LSL_Integer osTerrainSetHeight(int x, int y, double val); //Deprecated
71 void osTerrainFlush(); 74 void osTerrainFlush();
72 75
73 int osRegionRestart(double seconds); 76 int osRegionRestart(double seconds);
@@ -85,6 +88,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
85 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 88 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
86 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 89 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
87 void osTeleportAgent(string agent, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 90 void osTeleportAgent(string agent, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
91 void osTeleportOwner(string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
92 void osTeleportOwner(int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
93 void osTeleportOwner(LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
88 94
89 // Animation commands 95 // Animation commands
90 void osAvatarPlayAnimation(string avatar, string animation); 96 void osAvatarPlayAnimation(string avatar, string animation);
@@ -103,7 +109,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
103 string osSetFontName(string drawList, string fontName); 109 string osSetFontName(string drawList, string fontName);
104 string osSetFontSize(string drawList, int fontSize); 110 string osSetFontSize(string drawList, int fontSize);
105 string osSetPenSize(string drawList, int penSize); 111 string osSetPenSize(string drawList, int penSize);
106 string osSetPenColour(string drawList, string colour); 112 string osSetPenColor(string drawList, string color);
113 string osSetPenColour(string drawList, string colour); // Deprecated
107 string osSetPenCap(string drawList, string direction, string type); 114 string osSetPenCap(string drawList, string direction, string type);
108 string osDrawImage(string drawList, int width, int height, string imageUrl); 115 string osDrawImage(string drawList, int width, int height, string imageUrl);
109 vector osGetDrawStringSize(string contentType, string text, string fontName, int fontSize); 116 vector osGetDrawStringSize(string contentType, string text, string fontName, int fontSize);
@@ -115,14 +122,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
115 void osSetRegionSunSettings(bool useEstateSun, bool sunFixed, double sunHour); 122 void osSetRegionSunSettings(bool useEstateSun, bool sunFixed, double sunHour);
116 void osSetEstateSunSettings(bool sunFixed, double sunHour); 123 void osSetEstateSunSettings(bool sunFixed, double sunHour);
117 double osGetCurrentSunHour(); 124 double osGetCurrentSunHour();
118 double osSunGetParam(string param); 125 double osGetSunParam(string param);
119 void osSunSetParam(string param, double value); 126 double osSunGetParam(string param); // Deprecated
127 void osSetSunParam(string param, double value);
128 void osSunSetParam(string param, double value); // Deprecated
120 129
121 // Wind Module Functions 130 // Wind Module Functions
122 string osWindActiveModelPluginName(); 131 string osWindActiveModelPluginName();
123 void osWindParamSet(string plugin, string param, float value); 132 void osSetWindParam(string plugin, string param, LSL_Float value);
124 float osWindParamGet(string plugin, string param); 133 LSL_Float osGetWindParam(string plugin, string param);
125 134
135 // Parcel commands
136 void osParcelJoin(vector pos1, vector pos2);
137 void osParcelSubdivide(vector pos1, vector pos2);
138 void osSetParcelDetails(vector pos, LSL_List rules);
139 void osParcelSetDetails(vector pos, LSL_List rules); // Deprecated
126 140
127 string osGetScriptEngineName(); 141 string osGetScriptEngineName();
128 string osGetSimulatorVersion(); 142 string osGetSimulatorVersion();
@@ -154,20 +168,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
154 168
155 LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules); 169 LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules);
156 170
157 171 key osNpcCreate(string user, string name, vector position, string notecard);
158 key osNpcCreate(string user, string name, vector position, key cloneFrom); 172 LSL_Key osNpcSaveAppearance(key npc, string notecard);
173 void osNpcLoadAppearance(key npc, string notecard);
174 vector osNpcGetPos(key npc);
159 void osNpcMoveTo(key npc, vector position); 175 void osNpcMoveTo(key npc, vector position);
176 void osNpcMoveToTarget(key npc, vector target, int options);
177 rotation osNpcGetRot(key npc);
178 void osNpcSetRot(LSL_Key npc, rotation rot);
179 void osNpcStopMoveToTarget(LSL_Key npc);
160 void osNpcSay(key npc, string message); 180 void osNpcSay(key npc, string message);
181 void osNpcSit(key npc, key target, int options);
182 void osNpcStand(LSL_Key npc);
161 void osNpcRemove(key npc); 183 void osNpcRemove(key npc);
162 184
185 LSL_Key osOwnerSaveAppearance(string notecard);
186 LSL_Key osAgentSaveAppearance(key agentId, string notecard);
187
163 key osGetMapTexture(); 188 key osGetMapTexture();
164 key osGetRegionMapTexture(string regionName); 189 key osGetRegionMapTexture(string regionName);
165 LSL_List osGetRegionStats(); 190 LSL_List osGetRegionStats();
166 191
167 int osGetSimulatorMemory(); 192 int osGetSimulatorMemory();
168 void osKickAvatar(string FirstName,string SurName,string alert); 193 void osKickAvatar(string FirstName,string SurName,string alert);
169 void osSetSpeed(string UUID, float SpeedModifier); 194 void osSetSpeed(string UUID, LSL_Float SpeedModifier);
170 void osCauseHealing(string avatar, double healing); 195 void osCauseHealing(string avatar, double healing);
171 void osCauseDamage(string avatar, double damage); 196 void osCauseDamage(string avatar, double damage);
197 LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules);
198 void osSetPrimitiveParams(LSL_Key prim, LSL_List rules);
199 void osSetProjectionParams(bool projection, LSL_Key texture, double fov, double focus, double amb);
200 void osSetProjectionParams(LSL_Key prim, bool projection, LSL_Key texture, double fov, double focus, double amb);
201
202 LSL_List osGetAvatarList();
203
204 LSL_String osUnixTimeToTimestamp(long time);
172 } 205 }
173} 206}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Constants.cs
index 522c020..f94ef4a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Constants.cs
@@ -70,7 +70,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
70 public const int WL_CLOUD_SCROLL_Y = 32; 70 public const int WL_CLOUD_SCROLL_Y = 32;
71 public const int WL_CLOUD_SCROLL_Y_LOCK = 33; 71 public const int WL_CLOUD_SCROLL_Y_LOCK = 33;
72 public const int WL_CLOUD_SCROLL_X_LOCK = 34; 72 public const int WL_CLOUD_SCROLL_X_LOCK = 34;
73 public const int WL_DRAW_CLASSIC_CLOUDS = 35; 73 public const int WL_DRAW_CLASSIC_CLOUDS = 35;
74 public const int WL_SUN_MOON_POSITION = 36; 74 public const int WL_SUN_MOON_POSITION = 36;
75 75
76 } 76 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
index aaffbe4..4132dfa 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
@@ -58,23 +58,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
58 m_CM_Functions = (ICM_Api)api; 58 m_CM_Functions = (ICM_Api)api;
59 } 59 }
60 60
61 public LSL_List cmGetWindlightScene(LSL_List rules) 61 public string cmDetectedCountry(int num)
62 { 62 {
63 return m_CM_Functions.cmGetWindlightScene(rules); 63 return m_CM_Functions.cmDetectedCountry(num);
64 } 64 }
65 65
66 public int cmSetWindlightScene(LSL_List rules) 66 public string cmGetAgentCountry(key key)
67 { 67 {
68 return m_CM_Functions.cmSetWindlightScene(rules); 68 return m_CM_Functions.cmGetAgentCountry(key);
69 }
70
71 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
72 {
73 return m_CM_Functions.cmSetWindlightSceneTargeted(rules, target);
74 }
75 public LSL_List cmGetAvatarList()
76 {
77 return m_CM_Functions.cmGetAvatarList();
78 } 69 }
79 } 70 }
80} 71}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index b3e4740..0ad3f78 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -50,6 +50,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
50 public const int STATUS_CAST_SHADOWS = 512; 50 public const int STATUS_CAST_SHADOWS = 512;
51 51
52 public const int AGENT = 1; 52 public const int AGENT = 1;
53 public const int AGENT_BY_LEGACY_NAME = 1;
54 public const int AGENT_BY_USERNAME = 0x10;
53 public const int ACTIVE = 2; 55 public const int ACTIVE = 2;
54 public const int PASSIVE = 4; 56 public const int PASSIVE = 4;
55 public const int SCRIPTED = 8; 57 public const int SCRIPTED = 8;
@@ -273,11 +275,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
273 public const int CHANGED_LINK = 32; 275 public const int CHANGED_LINK = 32;
274 public const int CHANGED_ALLOWED_DROP = 64; 276 public const int CHANGED_ALLOWED_DROP = 64;
275 public const int CHANGED_OWNER = 128; 277 public const int CHANGED_OWNER = 128;
276 public const int CHANGED_REGION_RESTART = 256; 278 public const int CHANGED_REGION = 256;
277 public const int CHANGED_REGION_START = 256; //LL Changed the constant from CHANGED_REGION_RESTART 279 public const int CHANGED_TELEPORT = 512;
278 public const int CHANGED_REGION = 512; 280 public const int CHANGED_REGION_RESTART = 1024;
279 public const int CHANGED_TELEPORT = 1024; 281 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
282 public const int CHANGED_MEDIA = 2048;
280 public const int CHANGED_ANIMATION = 16384; 283 public const int CHANGED_ANIMATION = 16384;
284 public const int CHANGED_POSITION = 32768;
281 public const int TYPE_INVALID = 0; 285 public const int TYPE_INVALID = 0;
282 public const int TYPE_INTEGER = 1; 286 public const int TYPE_INTEGER = 1;
283 public const int TYPE_FLOAT = 2; 287 public const int TYPE_FLOAT = 2;
@@ -315,6 +319,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
315 public const int PRIM_POINT_LIGHT = 23; // Huh? 319 public const int PRIM_POINT_LIGHT = 23; // Huh?
316 public const int PRIM_GLOW = 25; 320 public const int PRIM_GLOW = 25;
317 public const int PRIM_TEXT = 26; 321 public const int PRIM_TEXT = 26;
322 public const int PRIM_NAME = 27;
323 public const int PRIM_DESC = 28;
324 public const int PRIM_ROT_LOCAL = 29;
325 public const int PRIM_OMEGA = 32;
326 public const int PRIM_POS_LOCAL = 33;
327 public const int PRIM_LINK_TARGET = 34;
318 public const int PRIM_TEXGEN_DEFAULT = 0; 328 public const int PRIM_TEXGEN_DEFAULT = 0;
319 public const int PRIM_TEXGEN_PLANAR = 1; 329 public const int PRIM_TEXGEN_PLANAR = 1;
320 330
@@ -368,6 +378,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
368 public const int PRIM_SCULPT_TYPE_TORUS = 2; 378 public const int PRIM_SCULPT_TYPE_TORUS = 2;
369 public const int PRIM_SCULPT_TYPE_PLANE = 3; 379 public const int PRIM_SCULPT_TYPE_PLANE = 3;
370 public const int PRIM_SCULPT_TYPE_CYLINDER = 4; 380 public const int PRIM_SCULPT_TYPE_CYLINDER = 4;
381 public const int PRIM_SCULPT_FLAG_INVERT = 64;
382 public const int PRIM_SCULPT_FLAG_MIRROR = 128;
371 383
372 public const int MASK_BASE = 0; 384 public const int MASK_BASE = 0;
373 public const int MASK_OWNER = 1; 385 public const int MASK_OWNER = 1;
@@ -503,6 +515,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
503 public const int PARCEL_DETAILS_OWNER = 2; 515 public const int PARCEL_DETAILS_OWNER = 2;
504 public const int PARCEL_DETAILS_GROUP = 3; 516 public const int PARCEL_DETAILS_GROUP = 3;
505 public const int PARCEL_DETAILS_AREA = 4; 517 public const int PARCEL_DETAILS_AREA = 4;
518 public const int PARCEL_DETAILS_ID = 5;
519 public const int PARCEL_DETAILS_SEE_AVATARS = 6; // not implemented
520
521 //osSetParcelDetails
522 public const int PARCEL_DETAILS_CLAIMDATE = 10;
506 523
507 // constants for llSetClickAction 524 // constants for llSetClickAction
508 public const int CLICK_ACTION_NONE = 0; 525 public const int CLICK_ACTION_NONE = 0;
@@ -518,6 +535,41 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
518 public const int TOUCH_INVALID_FACE = -1; 535 public const int TOUCH_INVALID_FACE = -1;
519 public static readonly vector TOUCH_INVALID_TEXCOORD = new vector(-1.0, -1.0, 0.0); 536 public static readonly vector TOUCH_INVALID_TEXCOORD = new vector(-1.0, -1.0, 0.0);
520 public static readonly vector TOUCH_INVALID_VECTOR = ZERO_VECTOR; 537 public static readonly vector TOUCH_INVALID_VECTOR = ZERO_VECTOR;
538
539 // constants for llGetPrimMediaParams/llSetPrimMediaParams
540 public const int PRIM_MEDIA_ALT_IMAGE_ENABLE = 0;
541 public const int PRIM_MEDIA_CONTROLS = 1;
542 public const int PRIM_MEDIA_CURRENT_URL = 2;
543 public const int PRIM_MEDIA_HOME_URL = 3;
544 public const int PRIM_MEDIA_AUTO_LOOP = 4;
545 public const int PRIM_MEDIA_AUTO_PLAY = 5;
546 public const int PRIM_MEDIA_AUTO_SCALE = 6;
547 public const int PRIM_MEDIA_AUTO_ZOOM = 7;
548 public const int PRIM_MEDIA_FIRST_CLICK_INTERACT = 8;
549 public const int PRIM_MEDIA_WIDTH_PIXELS = 9;
550 public const int PRIM_MEDIA_HEIGHT_PIXELS = 10;
551 public const int PRIM_MEDIA_WHITELIST_ENABLE = 11;
552 public const int PRIM_MEDIA_WHITELIST = 12;
553 public const int PRIM_MEDIA_PERMS_INTERACT = 13;
554 public const int PRIM_MEDIA_PERMS_CONTROL = 14;
555
556 public const int PRIM_MEDIA_CONTROLS_STANDARD = 0;
557 public const int PRIM_MEDIA_CONTROLS_MINI = 1;
558
559 public const int PRIM_MEDIA_PERM_NONE = 0;
560 public const int PRIM_MEDIA_PERM_OWNER = 1;
561 public const int PRIM_MEDIA_PERM_GROUP = 2;
562 public const int PRIM_MEDIA_PERM_ANYONE = 4;
563
564 // extra constants for llSetPrimMediaParams
565 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
566 public static readonly LSLInteger LSL_STATUS_MALFORMED_PARAMS = new LSLInteger(1000);
567 public static readonly LSLInteger LSL_STATUS_TYPE_MISMATCH = new LSLInteger(1001);
568 public static readonly LSLInteger LSL_STATUS_BOUNDS_ERROR = new LSLInteger(1002);
569 public static readonly LSLInteger LSL_STATUS_NOT_FOUND = new LSLInteger(1003);
570 public static readonly LSLInteger LSL_STATUS_NOT_SUPPORTED = new LSLInteger(1004);
571 public static readonly LSLInteger LSL_STATUS_INTERNAL_ERROR = new LSLInteger(1999);
572 public static readonly LSLInteger LSL_STATUS_WHITELIST_FAILED = new LSLInteger(2001);
521 573
522 // Constants for default textures 574 // Constants for default textures
523 public const string TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f"; 575 public const string TEXTURE_BLANK = "5748decc-f629-461c-9a36-a35a221fe21f";
@@ -549,5 +601,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
549 public const int STATS_ACTIVE_SCRIPTS = 19; 601 public const int STATS_ACTIVE_SCRIPTS = 19;
550 public const int STATS_SCRIPT_LPS = 20; 602 public const int STATS_SCRIPT_LPS = 20;
551 603
604 // Constants for osNpc* functions
605 public const int OS_NPC_FLY = 0;
606 public const int OS_NPC_NO_FLY = 1;
607 public const int OS_NPC_LAND_AT_TARGET = 2;
608
609 public const int OS_NPC_SIT_NOW = 0;
610
611 public const string URL_REQUEST_GRANTED = "URL_REQUEST_GRANTED";
612 public const string URL_REQUEST_DENIED = "URL_REQUEST_DENIED";
613
614 public static readonly LSLInteger RC_REJECT_TYPES = 2;
615 public static readonly LSLInteger RC_DATA_FLAGS = 4;
616 public static readonly LSLInteger RC_MAX_HITS = 8;
617 public static readonly LSLInteger RC_DETECT_PHANTOM = 16;
618
619 public static readonly LSLInteger RC_REJECT_AGENTS = 2;
620 public static readonly LSLInteger RC_REJECT_PHYSICAL = 4;
621 public static readonly LSLInteger RC_REJECT_NONPHYSICAL = 8;
622 public static readonly LSLInteger RC_REJECT_LAND = 16;
623
624 public static readonly LSLInteger RC_GET_NORMAL = 2;
625 public static readonly LSLInteger RC_GET_ROOT_KEY = 4;
626 public static readonly LSLInteger RC_GET_LINK_NUM = 8;
627
628 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 1;
552 } 629 }
553} 630}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index e86d08c..c717589 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -130,6 +130,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
130 return m_LSL_Functions.llAvatarOnSitTarget(); 130 return m_LSL_Functions.llAvatarOnSitTarget();
131 } 131 }
132 132
133 public LSL_Key llAvatarOnLinkSitTarget(int linknum)
134 {
135 return m_LSL_Functions.llAvatarOnLinkSitTarget(linknum);
136 }
137
133 public LSL_Rotation llAxes2Rot(LSL_Vector fwd, LSL_Vector left, LSL_Vector up) 138 public LSL_Rotation llAxes2Rot(LSL_Vector fwd, LSL_Vector left, LSL_Vector up)
134 { 139 {
135 return m_LSL_Functions.llAxes2Rot(fwd, left, up); 140 return m_LSL_Functions.llAxes2Rot(fwd, left, up);
@@ -461,6 +466,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
461 return m_LSL_Functions.llGetFreeMemory(); 466 return m_LSL_Functions.llGetFreeMemory();
462 } 467 }
463 468
469 public LSL_Integer llGetUsedMemory()
470 {
471 return m_LSL_Functions.llGetUsedMemory();
472 }
473
464 public LSL_Integer llGetFreeURLs() 474 public LSL_Integer llGetFreeURLs()
465 { 475 {
466 return m_LSL_Functions.llGetFreeURLs(); 476 return m_LSL_Functions.llGetFreeURLs();
@@ -836,6 +846,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
836 return m_LSL_Functions.llGiveMoney(destination, amount); 846 return m_LSL_Functions.llGiveMoney(destination, amount);
837 } 847 }
838 848
849 public LSL_String llTransferLindenDollars(string destination, int amount)
850 {
851 return m_LSL_Functions.llTransferLindenDollars(destination, amount);
852 }
853
839 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 854 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
840 { 855 {
841 m_LSL_Functions.llGodLikeRezObject(inventory, pos); 856 m_LSL_Functions.llGodLikeRezObject(inventory, pos);
@@ -896,6 +911,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
896 return m_LSL_Functions.llKey2Name(id); 911 return m_LSL_Functions.llKey2Name(id);
897 } 912 }
898 913
914 public LSL_String llGetUsername(string id)
915 {
916 return m_LSL_Functions.llGetUsername(id);
917 }
918
919 public LSL_String llRequestUsername(string id)
920 {
921 return m_LSL_Functions.llRequestUsername(id);
922 }
923
924 public LSL_String llGetDisplayName(string id)
925 {
926 return m_LSL_Functions.llGetDisplayName(id);
927 }
928
929 public LSL_String llRequestDisplayName(string id)
930 {
931 return m_LSL_Functions.llRequestDisplayName(id);
932 }
933
899 public void llLinkParticleSystem(int linknum, LSL_List rules) 934 public void llLinkParticleSystem(int linknum, LSL_List rules)
900 { 935 {
901 m_LSL_Functions.llLinkParticleSystem(linknum, rules); 936 m_LSL_Functions.llLinkParticleSystem(linknum, rules);
@@ -1181,6 +1216,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1181 m_LSL_Functions.llRegionSay(channelID, text); 1216 m_LSL_Functions.llRegionSay(channelID, text);
1182 } 1217 }
1183 1218
1219 public void llRegionSayTo(string key, int channelID, string text)
1220 {
1221 m_LSL_Functions.llRegionSayTo(key, channelID, text);
1222 }
1223
1184 public void llReleaseCamera(string avatar) 1224 public void llReleaseCamera(string avatar)
1185 { 1225 {
1186 m_LSL_Functions.llReleaseCamera(avatar); 1226 m_LSL_Functions.llReleaseCamera(avatar);
@@ -1834,5 +1874,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1834 { 1874 {
1835 return m_LSL_Functions.llXorBase64StringsCorrect(str1, str2); 1875 return m_LSL_Functions.llXorBase64StringsCorrect(str1, str2);
1836 } 1876 }
1877
1878 public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
1879 {
1880 return m_LSL_Functions.llGetPrimMediaParams(face, rules);
1881 }
1882
1883 public LSL_Integer llSetPrimMediaParams(int face, LSL_List rules)
1884 {
1885 return m_LSL_Functions.llSetPrimMediaParams(face, rules);
1886 }
1887
1888 public LSL_Integer llClearPrimMedia(LSL_Integer face)
1889 {
1890 return m_LSL_Functions.llClearPrimMedia(face);
1891 }
1892
1893 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1894 {
1895 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1896 }
1837 } 1897 }
1838} 1898}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
new file mode 100644
index 0000000..2e27f16
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -0,0 +1,101 @@
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.Runtime.Remoting.Lifetime;
30using System.Threading;
31using System.Reflection;
32using System.Collections;
33using System.Collections.Generic;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
38using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
46
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{
49 public partial class ScriptBaseClass : MarshalByRefObject
50 {
51 public ILS_Api m_LS_Functions;
52
53 public void ApiTypeLS(IScriptApi api)
54 {
55 if (!(api is ILS_Api))
56 return;
57
58 m_LS_Functions = (ILS_Api)api;
59 }
60
61 public LSL_List lsGetWindlightScene(LSL_List rules)
62 {
63 return m_LS_Functions.lsGetWindlightScene(rules);
64 }
65
66 public int lsSetWindlightScene(LSL_List rules)
67 {
68 return m_LS_Functions.lsSetWindlightScene(rules);
69 }
70
71 public int lsSetWindlightSceneTargeted(LSL_List rules, key target)
72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 }
75
76 public void lsClearWindlightScene()
77 {
78 m_LS_Functions.lsClearWindlightScene();
79 }
80
81 public LSL_List cmGetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsGetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightScene(LSL_List rules)
87 {
88 return m_LS_Functions.lsSetWindlightScene(rules);
89 }
90
91 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
92 {
93 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
94 }
95
96 public void cmClearWindlightScene()
97 {
98 m_LS_Functions.lsClearWindlightScene();
99 }
100 }
101}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index 3870af3..9e7c8da 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -41,6 +41,7 @@ using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; 42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; 45using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; 46using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
46 47
@@ -80,11 +81,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
80 return m_OSSL_Functions.osGetCurrentSunHour(); 81 return m_OSSL_Functions.osGetCurrentSunHour();
81 } 82 }
82 83
84 public double osGetSunParam(string param)
85 {
86 return m_OSSL_Functions.osGetSunParam(param);
87 }
88 // Deprecated
83 public double osSunGetParam(string param) 89 public double osSunGetParam(string param)
84 { 90 {
85 return m_OSSL_Functions.osSunGetParam(param); 91 return m_OSSL_Functions.osSunGetParam(param);
86 } 92 }
87 93
94 public void osSetSunParam(string param, double value)
95 {
96 m_OSSL_Functions.osSetSunParam(param, value);
97 }
98 // Deprecated
88 public void osSunSetParam(string param, double value) 99 public void osSunSetParam(string param, double value)
89 { 100 {
90 m_OSSL_Functions.osSunSetParam(param, value); 101 m_OSSL_Functions.osSunSetParam(param, value);
@@ -95,16 +106,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
95 return m_OSSL_Functions.osWindActiveModelPluginName(); 106 return m_OSSL_Functions.osWindActiveModelPluginName();
96 } 107 }
97 108
98// Not yet plugged in as available OSSL functions, so commented out 109 public void osSetWindParam(string plugin, string param, LSL_Float value)
99// void osWindParamSet(string plugin, string param, float value) 110 {
100// { 111 m_OSSL_Functions.osSetWindParam(plugin, param, value);
101// m_OSSL_Functions.osWindParamSet(plugin, param, value); 112 }
102// } 113
103// 114 public LSL_Float osGetWindParam(string plugin, string param)
104// float osWindParamGet(string plugin, string param) 115 {
105// { 116 return m_OSSL_Functions.osGetWindParam(plugin, param);
106// return m_OSSL_Functions.osWindParamGet(plugin, param); 117 }
107// } 118
119 public void osParcelJoin(vector pos1, vector pos2)
120 {
121 m_OSSL_Functions.osParcelJoin(pos1,pos2);
122 }
123
124 public void osParcelSubdivide(vector pos1, vector pos2)
125 {
126 m_OSSL_Functions.osParcelSubdivide(pos1, pos2);
127 }
128
129 public void osSetParcelDetails(vector pos, LSL_List rules)
130 {
131 m_OSSL_Functions.osSetParcelDetails(pos, rules);
132 }
133 // Deprecated
134 public void osParcelSetDetails(vector pos, LSL_List rules)
135 {
136 m_OSSL_Functions.osParcelSetDetails(pos,rules);
137 }
108 138
109 public double osList2Double(LSL_Types.list src, int index) 139 public double osList2Double(LSL_Types.list src, int index)
110 { 140 {
@@ -149,11 +179,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
149 blend, disp, timer, alpha, face); 179 blend, disp, timer, alpha, face);
150 } 180 }
151 181
182 public LSL_Float osGetTerrainHeight(int x, int y)
183 {
184 return m_OSSL_Functions.osGetTerrainHeight(x, y);
185 }
186 // Deprecated
152 public LSL_Float osTerrainGetHeight(int x, int y) 187 public LSL_Float osTerrainGetHeight(int x, int y)
153 { 188 {
154 return m_OSSL_Functions.osTerrainGetHeight(x, y); 189 return m_OSSL_Functions.osTerrainGetHeight(x, y);
155 } 190 }
156 191
192 public LSL_Integer osSetTerrainHeight(int x, int y, double val)
193 {
194 return m_OSSL_Functions.osSetTerrainHeight(x, y, val);
195 }
196 // Deprecated
157 public LSL_Integer osTerrainSetHeight(int x, int y, double val) 197 public LSL_Integer osTerrainSetHeight(int x, int y, double val)
158 { 198 {
159 return m_OSSL_Functions.osTerrainSetHeight(x, y, val); 199 return m_OSSL_Functions.osTerrainSetHeight(x, y, val);
@@ -211,6 +251,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
211 m_OSSL_Functions.osTeleportAgent(agent, position, lookat); 251 m_OSSL_Functions.osTeleportAgent(agent, position, lookat);
212 } 252 }
213 253
254 public void osTeleportOwner(string regionName, vector position, vector lookat)
255 {
256 m_OSSL_Functions.osTeleportOwner(regionName, position, lookat);
257 }
258
259 public void osTeleportOwner(int regionX, int regionY, vector position, vector lookat)
260 {
261 m_OSSL_Functions.osTeleportOwner(regionX, regionY, position, lookat);
262 }
263
264 public void osTeleportOwner(vector position, vector lookat)
265 {
266 m_OSSL_Functions.osTeleportOwner(position, lookat);
267 }
268
214 // Avatar info functions 269 // Avatar info functions
215 public string osGetAgentIP(string agent) 270 public string osGetAgentIP(string agent)
216 { 271 {
@@ -302,6 +357,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
302 return m_OSSL_Functions.osSetPenCap(drawList, direction, type); 357 return m_OSSL_Functions.osSetPenCap(drawList, direction, type);
303 } 358 }
304 359
360 public string osSetPenColor(string drawList, string color)
361 {
362 return m_OSSL_Functions.osSetPenColor(drawList, color);
363 }
364 // Deprecated
305 public string osSetPenColour(string drawList, string colour) 365 public string osSetPenColour(string drawList, string colour)
306 { 366 {
307 return m_OSSL_Functions.osSetPenColour(drawList, colour); 367 return m_OSSL_Functions.osSetPenColour(drawList, colour);
@@ -423,21 +483,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
423 return m_OSSL_Functions.osNpcCreate(user, name, position, cloneFrom); 483 return m_OSSL_Functions.osNpcCreate(user, name, position, cloneFrom);
424 } 484 }
425 485
486 public key osNpcSaveAppearance(key npc, string notecard)
487 {
488 return m_OSSL_Functions.osNpcSaveAppearance(npc, notecard);
489 }
490
491 public void osNpcLoadAppearance(key npc, string notecard)
492 {
493 m_OSSL_Functions.osNpcLoadAppearance(npc, notecard);
494 }
495
496 public vector osNpcGetPos(LSL_Key npc)
497 {
498 return m_OSSL_Functions.osNpcGetPos(npc);
499 }
500
426 public void osNpcMoveTo(key npc, vector position) 501 public void osNpcMoveTo(key npc, vector position)
427 { 502 {
428 m_OSSL_Functions.osNpcMoveTo(npc, position); 503 m_OSSL_Functions.osNpcMoveTo(npc, position);
429 } 504 }
430 505
506 public void osNpcMoveToTarget(key npc, vector target, int options)
507 {
508 m_OSSL_Functions.osNpcMoveToTarget(npc, target, options);
509 }
510
511 public rotation osNpcGetRot(key npc)
512 {
513 return m_OSSL_Functions.osNpcGetRot(npc);
514 }
515
516 public void osNpcSetRot(key npc, rotation rot)
517 {
518 m_OSSL_Functions.osNpcSetRot(npc, rot);
519 }
520
521 public void osNpcStopMoveToTarget(LSL_Key npc)
522 {
523 m_OSSL_Functions.osNpcStopMoveToTarget(npc);
524 }
525
431 public void osNpcSay(key npc, string message) 526 public void osNpcSay(key npc, string message)
432 { 527 {
433 m_OSSL_Functions.osNpcSay(npc, message); 528 m_OSSL_Functions.osNpcSay(npc, message);
434 } 529 }
435 530
531 public void osNpcSit(LSL_Key npc, LSL_Key target, int options)
532 {
533 m_OSSL_Functions.osNpcSit(npc, target, options);
534 }
535
536 public void osNpcStand(LSL_Key npc)
537 {
538 m_OSSL_Functions.osNpcStand(npc);
539 }
540
436 public void osNpcRemove(key npc) 541 public void osNpcRemove(key npc)
437 { 542 {
438 m_OSSL_Functions.osNpcRemove(npc); 543 m_OSSL_Functions.osNpcRemove(npc);
439 } 544 }
440 545
546 public LSL_Key osOwnerSaveAppearance(string notecard)
547 {
548 return m_OSSL_Functions.osOwnerSaveAppearance(notecard);
549 }
550
551 public LSL_Key osAgentSaveAppearance(LSL_Key agentId, string notecard)
552 {
553 return m_OSSL_Functions.osAgentSaveAppearance(agentId, notecard);
554 }
555
441 public OSSLPrim Prim; 556 public OSSLPrim Prim;
442 557
443 [Serializable] 558 [Serializable]
@@ -647,21 +762,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
647 { 762 {
648 return m_OSSL_Functions.osGetSimulatorMemory(); 763 return m_OSSL_Functions.osGetSimulatorMemory();
649 } 764 }
765
650 public void osKickAvatar(string FirstName,string SurName,string alert) 766 public void osKickAvatar(string FirstName,string SurName,string alert)
651 { 767 {
652 m_OSSL_Functions.osKickAvatar(FirstName, SurName, alert); 768 m_OSSL_Functions.osKickAvatar(FirstName, SurName, alert);
653 } 769 }
654 public void osSetSpeed(string UUID, float SpeedModifier) 770
771 public void osSetSpeed(string UUID, LSL_Float SpeedModifier)
655 { 772 {
656 m_OSSL_Functions.osSetSpeed(UUID, SpeedModifier); 773 m_OSSL_Functions.osSetSpeed(UUID, SpeedModifier);
657 } 774 }
775
658 public void osCauseDamage(string avatar, double damage) 776 public void osCauseDamage(string avatar, double damage)
659 { 777 {
660 m_OSSL_Functions.osCauseDamage(avatar, damage); 778 m_OSSL_Functions.osCauseDamage(avatar, damage);
661 } 779 }
780
662 public void osCauseHealing(string avatar, double healing) 781 public void osCauseHealing(string avatar, double healing)
663 { 782 {
664 m_OSSL_Functions.osCauseHealing(avatar, healing); 783 m_OSSL_Functions.osCauseHealing(avatar, healing);
665 } 784 }
785
786 public LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules)
787 {
788 return m_OSSL_Functions.osGetPrimitiveParams(prim, rules);
789 }
790
791 public void osSetPrimitiveParams(LSL_Key prim, LSL_List rules)
792 {
793 m_OSSL_Functions.osSetPrimitiveParams(prim, rules);
794 }
795
796 public void osSetProjectionParams(bool projection, LSL_Key texture, double fov, double focus, double amb)
797 {
798 m_OSSL_Functions.osSetProjectionParams(projection, texture, fov, focus, amb);
799 }
800
801 public void osSetProjectionParams(LSL_Key prim, bool projection, LSL_Key texture, double fov, double focus, double amb)
802 {
803 m_OSSL_Functions.osSetProjectionParams(prim, projection, texture, fov, focus, amb);
804 }
805
806 public LSL_List osGetAvatarList()
807 {
808 return m_OSSL_Functions.osGetAvatarList();
809 }
810
811 public LSL_String osUnixTimeToTimestamp(long time)
812 {
813 return m_OSSL_Functions.osUnixTimeToTimestamp(time);
814 }
666 } 815 }
667} 816} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp
index 23138ef..f02d2d9 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp
@@ -18,10 +18,10 @@
18 </DeploymentInformation> 18 </DeploymentInformation>
19 <Contents> 19 <Contents>
20 <File name="./CM_Constants.cs" subtype="Code" buildaction="Compile" dependson="" data="" /> 20 <File name="./CM_Constants.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
21 <File name="./CM_Stub.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
22 <File name="./Executor.cs" subtype="Code" buildaction="Compile" dependson="" data="" /> 21 <File name="./Executor.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
23 <File name="./LSL_Constants.cs" subtype="Code" buildaction="Compile" dependson="" data="" /> 22 <File name="./LSL_Constants.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
24 <File name="./LSL_Stub.cs" subtype="Code" buildaction="Compile" dependson="" data="" /> 23 <File name="./LSL_Stub.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
24 <File name="./LS_Stub.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
25 <File name="./MOD_Stub.cs" subtype="Code" buildaction="Compile" dependson="" data="" /> 25 <File name="./MOD_Stub.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
26 <File name="./OSSL_Stub.cs" subtype="Code" buildaction="Compile" dependson="" data="" /> 26 <File name="./OSSL_Stub.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
27 <File name="./ScriptBase.cs" subtype="Code" buildaction="Compile" dependson="" data="" /> 27 <File name="./ScriptBase.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
diff --git a/OpenSim/Region/ScriptEngine/Shared/AssemblyResolver.cs b/OpenSim/Region/ScriptEngine/Shared/AssemblyResolver.cs
index ade1924..130e197 100644
--- a/OpenSim/Region/ScriptEngine/Shared/AssemblyResolver.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/AssemblyResolver.cs
@@ -32,7 +32,7 @@ using System.Reflection;
32namespace OpenSim.Region.ScriptEngine.Shared 32namespace OpenSim.Region.ScriptEngine.Shared
33{ 33{
34 [Serializable] 34 [Serializable]
35 public class AssemblyResolver 35 public class AssemblyResolver : MarshalByRefObject
36 { 36 {
37 public static Assembly OnAssemblyResolve(object sender, 37 public static Assembly OnAssemblyResolve(object sender,
38 ResolveEventArgs args) 38 ResolveEventArgs args)
@@ -42,9 +42,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
42 42
43 AppDomain myDomain = (AppDomain)sender; 43 AppDomain myDomain = (AppDomain)sender;
44 string dirName = myDomain.FriendlyName; 44 string dirName = myDomain.FriendlyName;
45 string ScriptEnginesPath = myDomain.SetupInformation.PrivateBinPath;
45 46
46 string[] pathList = new string[] {"bin", "ScriptEngines", 47 string[] pathList = new string[] {"bin", ScriptEnginesPath,
47 Path.Combine("ScriptEngines", dirName)}; 48 Path.Combine(ScriptEnginesPath, dirName)};
48 49
49 string assemblyName = args.Name; 50 string assemblyName = args.Name;
50 if (assemblyName.IndexOf(",") != -1) 51 if (assemblyName.IndexOf(",") != -1)
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
index 959164b..734d4d5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
@@ -72,7 +72,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
72 private Dictionary<string, enumCompileType> LanguageMapping = new Dictionary<string, enumCompileType>(StringComparer.CurrentCultureIgnoreCase); 72 private Dictionary<string, enumCompileType> LanguageMapping = new Dictionary<string, enumCompileType>(StringComparer.CurrentCultureIgnoreCase);
73 73
74 private string FilePrefix; 74 private string FilePrefix;
75 private string ScriptEnginesPath = "ScriptEngines"; 75 private string ScriptEnginesPath = null;
76 // mapping between LSL and C# line/column numbers 76 // mapping between LSL and C# line/column numbers
77 private ICodeConverter LSL_Converter; 77 private ICodeConverter LSL_Converter;
78 78
@@ -95,7 +95,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
95 95
96 public Compiler(IScriptEngine scriptEngine) 96 public Compiler(IScriptEngine scriptEngine)
97 { 97 {
98 m_scriptEngine = scriptEngine; 98 m_scriptEngine = scriptEngine;;
99 ScriptEnginesPath = scriptEngine.ScriptEnginePath;
99 ReadConfig(); 100 ReadConfig();
100 } 101 }
101 102
@@ -105,6 +106,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
105 // Get some config 106 // Get some config
106 WriteScriptSourceToDebugFile = m_scriptEngine.Config.GetBoolean("WriteScriptSourceToDebugFile", false); 107 WriteScriptSourceToDebugFile = m_scriptEngine.Config.GetBoolean("WriteScriptSourceToDebugFile", false);
107 CompileWithDebugInformation = m_scriptEngine.Config.GetBoolean("CompileWithDebugInformation", true); 108 CompileWithDebugInformation = m_scriptEngine.Config.GetBoolean("CompileWithDebugInformation", true);
109 bool DeleteScriptsOnStartup = m_scriptEngine.Config.GetBoolean("DeleteScriptsOnStartup", true);
108 110
109 // Get file prefix from scriptengine name and make it file system safe: 111 // Get file prefix from scriptengine name and make it file system safe:
110 FilePrefix = "CommonCompiler"; 112 FilePrefix = "CommonCompiler";
@@ -113,11 +115,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
113 FilePrefix = FilePrefix.Replace(c, '_'); 115 FilePrefix = FilePrefix.Replace(c, '_');
114 } 116 }
115 117
116 // First time we start? Delete old files
117 if (in_startup) 118 if (in_startup)
118 { 119 {
119 in_startup = false; 120 in_startup = false;
120 DeleteOldFiles(); 121 CreateScriptsDirectory();
122
123 // First time we start? Delete old files
124 if (DeleteScriptsOnStartup)
125 DeleteOldFiles();
121 } 126 }
122 127
123 // Map name and enum type of our supported languages 128 // Map name and enum type of our supported languages
@@ -186,11 +191,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
186 } 191 }
187 192
188 /// <summary> 193 /// <summary>
189 /// Delete old script files 194 /// Create the directory where compiled scripts are stored.
190 /// </summary> 195 /// </summary>
191 private void DeleteOldFiles() 196 private void CreateScriptsDirectory()
192 { 197 {
193 // CREATE FOLDER IF IT DOESNT EXIST
194 if (!Directory.Exists(ScriptEnginesPath)) 198 if (!Directory.Exists(ScriptEnginesPath))
195 { 199 {
196 try 200 try
@@ -217,7 +221,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
217 m_scriptEngine.World.RegionInfo.RegionID.ToString()) + "\": " + ex.ToString()); 221 m_scriptEngine.World.RegionInfo.RegionID.ToString()) + "\": " + ex.ToString());
218 } 222 }
219 } 223 }
224 }
220 225
226 /// <summary>
227 /// Delete old script files
228 /// </summary>
229 private void DeleteOldFiles()
230 {
221 foreach (string file in Directory.GetFiles(Path.Combine(ScriptEnginesPath, 231 foreach (string file in Directory.GetFiles(Path.Combine(ScriptEnginesPath,
222 m_scriptEngine.World.RegionInfo.RegionID.ToString()), FilePrefix + "_compiled*")) 232 m_scriptEngine.World.RegionInfo.RegionID.ToString()), FilePrefix + "_compiled*"))
223 { 233 {
@@ -261,13 +271,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
261 // } 271 // }
262 //} 272 //}
263 273
264 public object GetCompilerOutput(UUID assetID) 274 public string GetCompilerOutput(string assetID)
265 { 275 {
266 return Path.Combine(ScriptEnginesPath, Path.Combine( 276 return Path.Combine(ScriptEnginesPath, Path.Combine(
267 m_scriptEngine.World.RegionInfo.RegionID.ToString(), 277 m_scriptEngine.World.RegionInfo.RegionID.ToString(),
268 FilePrefix + "_compiled_" + assetID + ".dll")); 278 FilePrefix + "_compiled_" + assetID + ".dll"));
269 } 279 }
270 280
281 public string GetCompilerOutput(UUID assetID)
282 {
283 return GetCompilerOutput(assetID.ToString());
284 }
285
271 /// <summary> 286 /// <summary>
272 /// Converts script from LSL to CS and calls CompileFromCSText 287 /// Converts script from LSL to CS and calls CompileFromCSText
273 /// </summary> 288 /// </summary>
@@ -279,9 +294,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
279 linemap = null; 294 linemap = null;
280 m_warnings.Clear(); 295 m_warnings.Clear();
281 296
282 assembly = Path.Combine(ScriptEnginesPath, Path.Combine( 297 assembly = GetCompilerOutput(asset);
283 m_scriptEngine.World.RegionInfo.RegionID.ToString(),
284 FilePrefix + "_compiled_" + asset + ".dll"));
285 298
286 if (!Directory.Exists(ScriptEnginesPath)) 299 if (!Directory.Exists(ScriptEnginesPath))
287 { 300 {
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index 4855d64..7e7e278 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -35,6 +35,7 @@ using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.CoreModules; 36using OpenSim.Region.CoreModules;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces;
38 39
39namespace OpenSim.Region.ScriptEngine.Shared 40namespace OpenSim.Region.ScriptEngine.Shared
40{ 41{
@@ -95,6 +96,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
95 Type = 0; 96 Type = 0;
96 Velocity = new LSL_Types.Vector3(); 97 Velocity = new LSL_Types.Vector3();
97 initializeSurfaceTouch(); 98 initializeSurfaceTouch();
99 Country = String.Empty;
98 } 100 }
99 101
100 public UUID Key; 102 public UUID Key;
@@ -126,6 +128,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
126 private int touchFace; 128 private int touchFace;
127 public int TouchFace { get { return touchFace; } } 129 public int TouchFace { get { return touchFace; } }
128 130
131 public string Country;
132
129 // This can be done in two places including the constructor 133 // This can be done in two places including the constructor
130 // so be carefull what gets added here 134 // so be carefull what gets added here
131 private void initializeSurfaceTouch() 135 private void initializeSurfaceTouch()
@@ -173,6 +177,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
173 return; 177 return;
174 178
175 Name = presence.Firstname + " " + presence.Lastname; 179 Name = presence.Firstname + " " + presence.Lastname;
180 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
181 if (account != null)
182 Country = account.UserCountry;
183
176 Owner = Key; 184 Owner = Key;
177 Position = new LSL_Types.Vector3( 185 Position = new LSL_Types.Vector3(
178 presence.AbsolutePosition.X, 186 presence.AbsolutePosition.X,
@@ -197,7 +205,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
197 return; 205 return;
198 } 206 }
199 207
200 part=part.ParentGroup.RootPart; // We detect objects only 208 part = part.ParentGroup.RootPart; // We detect objects only
201 209
202 LinkNum = 0; // Not relevant 210 LinkNum = 0; // Not relevant
203 211
@@ -209,7 +217,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
209 else 217 else
210 Type = 0x02; // Passive 218 Type = 0x02; // Passive
211 219
212 foreach (SceneObjectPart p in part.ParentGroup.Children.Values) 220 foreach (SceneObjectPart p in part.ParentGroup.Parts)
213 { 221 {
214 if (p.Inventory.ContainsScripts()) 222 if (p.Inventory.ContainsScripts())
215 { 223 {
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index a299dba..9ff2e4d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -56,7 +56,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
56{ 56{
57 public class ScriptInstance : MarshalByRefObject, IScriptInstance 57 public class ScriptInstance : MarshalByRefObject, IScriptInstance
58 { 58 {
59 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 59 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
60 60
61 private IScriptEngine m_Engine; 61 private IScriptEngine m_Engine;
62 private IScriptWorkItem m_CurrentResult = null; 62 private IScriptWorkItem m_CurrentResult = null;
@@ -139,6 +139,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
139 set { m_RunEvents = value; } 139 set { m_RunEvents = value; }
140 } 140 }
141 141
142 public bool Suspended
143 {
144 get { return m_Suspended; }
145
146 set
147 {
148 // Need to do this inside a lock in order to avoid races with EventProcessor()
149 lock (m_Script)
150 {
151 bool wasSuspended = m_Suspended;
152 m_Suspended = value;
153
154 if (wasSuspended && !m_Suspended)
155 {
156 lock (m_EventQueue)
157 {
158 // Need to place ourselves back in a work item if there are events to process
159 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
160 m_CurrentResult = m_Engine.QueueEventHandler(this);
161 }
162 }
163 }
164 }
165 }
166 private bool m_Suspended;
167
142 public bool ShuttingDown 168 public bool ShuttingDown
143 { 169 {
144 get { return m_ShuttingDown; } 170 get { return m_ShuttingDown; }
@@ -233,7 +259,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
233 m_MaxScriptQueue = maxScriptQueue; 259 m_MaxScriptQueue = maxScriptQueue;
234 m_stateSource = stateSource; 260 m_stateSource = stateSource;
235 m_postOnRez = postOnRez; 261 m_postOnRez = postOnRez;
236 m_AttachedAvatar = part.AttachedAvatar; 262 m_AttachedAvatar = part.ParentGroup.AttachedAvatar;
237 m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID; 263 m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID;
238 264
239 if (part != null) 265 if (part != null)
@@ -270,9 +296,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
270 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 296 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
271// lease.Register(this); 297// lease.Register(this);
272 } 298 }
273 catch (Exception) 299 catch (Exception e)
274 { 300 {
275 // m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly); 301 m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly);
302 throw;
276 } 303 }
277 304
278 try 305 try
@@ -387,19 +414,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
387 PostEvent(new EventParams("attach", 414 PostEvent(new EventParams("attach",
388 new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0])); 415 new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0]));
389 } 416 }
390 else if (m_stateSource == StateSource.NewRez) 417 else if (m_stateSource == StateSource.RegionStart)
391 { 418 {
392// m_log.Debug("[Script] Posted changed(CHANGED_REGION_RESTART) to script"); 419 //m_log.Debug("[Script] Posted changed(CHANGED_REGION_RESTART) to script");
393 PostEvent(new EventParams("changed", 420 PostEvent(new EventParams("changed",
394 new Object[] {new LSL_Types.LSLInteger(256)}, new DetectParams[0])); 421 new Object[] { new LSL_Types.LSLInteger((int)Changed.REGION_RESTART) }, new DetectParams[0]));
395 } 422 }
396 else if (m_stateSource == StateSource.PrimCrossing) 423 else if (m_stateSource == StateSource.PrimCrossing || m_stateSource == StateSource.Teleporting)
397 { 424 {
398 // CHANGED_REGION 425 // CHANGED_REGION
399 PostEvent(new EventParams("changed", 426 PostEvent(new EventParams("changed",
400 new Object[] {new LSL_Types.LSLInteger(512)}, new DetectParams[0])); 427 new Object[] { new LSL_Types.LSLInteger((int)Changed.REGION) }, new DetectParams[0]));
428
429 // CHANGED_TELEPORT
430 if (m_stateSource == StateSource.Teleporting)
431 PostEvent(new EventParams("changed",
432 new Object[] { new LSL_Types.LSLInteger((int)Changed.TELEPORT) }, new DetectParams[0]));
401 } 433 }
402 } 434 }
403 else 435 else
404 { 436 {
405 Start(); 437 Start();
@@ -542,7 +574,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
542 m_CurrentResult = null; 574 m_CurrentResult = null;
543 } 575 }
544 576
545 return false; 577 return true;
546 } 578 }
547 579
548 [DebuggerNonUserCode] //Prevents the debugger from farting in this function 580 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
@@ -640,12 +672,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
640 /// <returns></returns> 672 /// <returns></returns>
641 public object EventProcessor() 673 public object EventProcessor()
642 { 674 {
675 EventParams data = null;
643 676
644 EventParams data = null; 677// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
645 678
646 lock (m_EventQueue) 679 if (Suspended)
647 { 680 return 0;
648 lock (m_Script) 681
682 lock (m_EventQueue)
649 { 683 {
650 data = (EventParams) m_EventQueue.Dequeue(); 684 data = (EventParams) m_EventQueue.Dequeue();
651 if (data == null) // Shouldn't happen 685 if (data == null) // Shouldn't happen
@@ -671,127 +705,127 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
671 if (data.EventName == "collision") 705 if (data.EventName == "collision")
672 m_CollisionInQueue = false; 706 m_CollisionInQueue = false;
673 } 707 }
674 }
675 lock(m_Script)
676 {
677
678 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this);
679
680 m_DetectParams = data.DetectParams;
681 708
682 if (data.EventName == "state") // Hardcoded state change 709 lock(m_Script)
683 {
684// m_log.DebugFormat("[Script] Script {0}.{1} state set to {2}",
685// m_PrimName, m_ScriptName, data.Params[0].ToString());
686 m_State=data.Params[0].ToString();
687 AsyncCommandManager.RemoveScript(m_Engine,
688 m_LocalID, m_ItemID);
689
690 SceneObjectPart part = m_Engine.World.GetSceneObjectPart(
691 m_LocalID);
692 if (part != null)
693 {
694 part.SetScriptEvents(m_ItemID,
695 (int)m_Script.GetStateEventFlags(State));
696 }
697 }
698 else
699 { 710 {
700 if (m_Engine.World.PipeEventsForScript(m_LocalID) || 711
701 data.EventName == "control") // Don't freeze avies! 712// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
713
714 m_DetectParams = data.DetectParams;
715
716 if (data.EventName == "state") // Hardcoded state change
702 { 717 {
718 // m_log.DebugFormat("[Script] Script {0}.{1} state set to {2}",
719 // m_PrimName, m_ScriptName, data.Params[0].ToString());
720 m_State = data.Params[0].ToString();
721 AsyncCommandManager.RemoveScript(m_Engine,
722 m_LocalID, m_ItemID);
723
703 SceneObjectPart part = m_Engine.World.GetSceneObjectPart( 724 SceneObjectPart part = m_Engine.World.GetSceneObjectPart(
704 m_LocalID); 725 m_LocalID);
705 // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}", 726 if (part != null)
706 // m_PrimName, m_ScriptName, data.EventName, m_State); 727 {
707 728 part.SetScriptEvents(m_ItemID,
708 try 729 (int)m_Script.GetStateEventFlags(State));
730 }
731 }
732 else
733 {
734 if (m_Engine.World.PipeEventsForScript(m_LocalID) ||
735 data.EventName == "control") // Don't freeze avies!
709 { 736 {
710 m_CurrentEvent = data.EventName; 737 SceneObjectPart part = m_Engine.World.GetSceneObjectPart(
711 m_EventStart = DateTime.Now; 738 m_LocalID);
712 m_InEvent = true; 739 // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}",
740 // m_PrimName, m_ScriptName, data.EventName, m_State);
713 741
714 m_Script.ExecuteEvent(State, data.EventName, data.Params); 742 try
743 {
744 m_CurrentEvent = data.EventName;
745 m_EventStart = DateTime.Now;
746 m_InEvent = true;
715 747
716 m_InEvent = false; 748 m_Script.ExecuteEvent(State, data.EventName, data.Params);
717 m_CurrentEvent = String.Empty;
718 749
719 if (m_SaveState) 750 m_InEvent = false;
720 { 751 m_CurrentEvent = String.Empty;
721 // This will be the very first event we deliver
722 // (state_entry) in default state
723 //
724 752
725 SaveState(m_Assembly); 753 if (m_SaveState)
754 {
755 // This will be the very first event we deliver
756 // (state_entry) in default state
757 //
726 758
727 m_SaveState = false; 759 SaveState(m_Assembly);
728 }
729 }
730 catch (Exception e)
731 {
732 // m_log.DebugFormat("[SCRIPT] Exception: {0}", e.Message);
733 m_InEvent = false;
734 m_CurrentEvent = String.Empty;
735 760
736 if ((!(e is TargetInvocationException) || (!(e.InnerException is SelfDeleteException) && !(e.InnerException is ScriptDeleteException))) && !(e is ThreadAbortException)) 761 m_SaveState = false;
762 }
763 }
764 catch (Exception e)
737 { 765 {
738 try 766 // m_log.DebugFormat("[SCRIPT] Exception: {0}", e.Message);
767 m_InEvent = false;
768 m_CurrentEvent = String.Empty;
769
770 if ((!(e is TargetInvocationException) || (!(e.InnerException is SelfDeleteException) && !(e.InnerException is ScriptDeleteException))) && !(e is ThreadAbortException))
739 { 771 {
740 // DISPLAY ERROR INWORLD 772 try
741 string text = FormatException(e); 773 {
742 774 // DISPLAY ERROR INWORLD
743 if (text.Length > 1000) 775 string text = FormatException(e);
744 text = text.Substring(0, 1000); 776
745 m_Engine.World.SimChat(Utils.StringToBytes(text), 777 if (text.Length > 1000)
746 ChatTypeEnum.DebugChannel, 2147483647, 778 text = text.Substring(0, 1000);
747 part.AbsolutePosition, 779 m_Engine.World.SimChat(Utils.StringToBytes(text),
748 part.Name, part.UUID, false); 780 ChatTypeEnum.DebugChannel, 2147483647,
781 part.AbsolutePosition,
782 part.Name, part.UUID, false);
783 }
784 catch (Exception)
785 {
786 }
787 // catch (Exception e2) // LEGIT: User Scripting
788 // {
789 // m_log.Error("[SCRIPT]: "+
790 // "Error displaying error in-world: " +
791 // e2.ToString());
792 // m_log.Error("[SCRIPT]: " +
793 // "Errormessage: Error compiling script:\r\n" +
794 // e.ToString());
795 // }
749 } 796 }
750 catch (Exception) 797 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException))
751 { 798 {
799 m_InSelfDelete = true;
800 if (part != null)
801 m_Engine.World.DeleteSceneObject(part.ParentGroup, false);
802 }
803 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException))
804 {
805 m_InSelfDelete = true;
806 if (part != null)
807 part.Inventory.RemoveInventoryItem(m_ItemID);
752 } 808 }
753 // catch (Exception e2) // LEGIT: User Scripting
754 // {
755 // m_log.Error("[SCRIPT]: "+
756 // "Error displaying error in-world: " +
757 // e2.ToString());
758 // m_log.Error("[SCRIPT]: " +
759 // "Errormessage: Error compiling script:\r\n" +
760 // e.ToString());
761 // }
762 }
763 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException))
764 {
765 m_InSelfDelete = true;
766 if (part != null && part.ParentGroup != null)
767 m_Engine.World.DeleteSceneObject(part.ParentGroup, false);
768 }
769 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException))
770 {
771 m_InSelfDelete = true;
772 if (part != null && part.ParentGroup != null)
773 part.Inventory.RemoveInventoryItem(m_ItemID);
774 } 809 }
775 } 810 }
776 } 811 }
777 }
778 812
779 lock (m_EventQueue) 813 lock (m_EventQueue)
780 {
781 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
782 {
783 m_CurrentResult = m_Engine.QueueEventHandler(this);
784 }
785 else
786 { 814 {
787 m_CurrentResult = null; 815 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
816 {
817 m_CurrentResult = m_Engine.QueueEventHandler(this);
818 }
819 else
820 {
821 m_CurrentResult = null;
822 }
788 } 823 }
789 }
790 824
791 m_DetectParams = null; 825 m_DetectParams = null;
792 826
793 return 0; 827 return 0;
794 } 828 }
795 } 829 }
796 830
797 public int EventTime() 831 public int EventTime()
@@ -998,7 +1032,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
998 public string GetXMLState() 1032 public string GetXMLState()
999 { 1033 {
1000 bool run = Running; 1034 bool run = Running;
1001 bool stopped = Stop(100); 1035 Stop(100);
1002 Running = run; 1036 Running = run;
1003 1037
1004 // We should not be doing this, but since we are about to 1038 // We should not be doing this, but since we are about to
@@ -1009,9 +1043,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1009 1043
1010 // Force an update of the in-memory plugin data 1044 // Force an update of the in-memory plugin data
1011 // 1045 //
1012 if (!stopped)
1013 return String.Empty;
1014
1015 PluginData = AsyncCommandManager.GetSerializationData(m_Engine, m_ItemID); 1046 PluginData = AsyncCommandManager.GetSerializationData(m_Engine, m_ItemID);
1016 1047
1017 return ScriptSerializer.Serialize(this); 1048 return ScriptSerializer.Serialize(this);
@@ -1021,5 +1052,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1021 { 1052 {
1022 get { return m_RegionID; } 1053 get { return m_RegionID; }
1023 } 1054 }
1055
1056 public void Suspend()
1057 {
1058 Suspended = true;
1059 }
1060
1061 public void Resume()
1062 {
1063 Suspended = false;
1064 }
1024 } 1065 }
1025} 1066}
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 326f327..9e6752c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -83,19 +83,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
83 83
84 public override string ToString() 84 public override string ToString()
85 { 85 {
86 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 86 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
87 return s; 87 return s;
88 } 88 }
89 89
90 public static explicit operator LSLString(Vector3 vec) 90 public static explicit operator LSLString(Vector3 vec)
91 { 91 {
92 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 92 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
93 return new LSLString(s); 93 return new LSLString(s);
94 } 94 }
95 95
96 public static explicit operator string(Vector3 vec) 96 public static explicit operator string(Vector3 vec)
97 { 97 {
98 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 98 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
99 return s; 99 return s;
100 } 100 }
101 101
@@ -257,17 +257,17 @@ namespace OpenSim.Region.ScriptEngine.Shared
257 public static double Mag(Vector3 v) 257 public static double Mag(Vector3 v)
258 { 258 {
259 return Math.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z); 259 return Math.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
260 } 260 }
261 261
262 public static Vector3 Norm(Vector3 vector) 262 public static Vector3 Norm(Vector3 vector)
263 { 263 {
264 double mag = Mag(vector); 264 double mag = Mag(vector);
265 if (mag > 0.0) 265 if (mag > 0.0)
266 { 266 {
267 double invMag = 1.0 / mag; 267 double invMag = 1.0 / mag;
268 return vector * invMag; 268 return vector * invMag;
269 } 269 }
270 return new Vector3(0, 0, 0); 270 return new Vector3(0, 0, 0);
271 } 271 }
272 272
273 #endregion 273 #endregion
@@ -342,19 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
342 342
343 public override string ToString() 343 public override string ToString()
344 { 344 {
345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
346 return st; 346 return st;
347 } 347 }
348 348
349 public static explicit operator string(Quaternion r) 349 public static explicit operator string(Quaternion r)
350 { 350 {
351 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 351 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
352 return s; 352 return s;
353 } 353 }
354 354
355 public static explicit operator LSLString(Quaternion r) 355 public static explicit operator LSLString(Quaternion r)
356 { 356 {
357 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 357 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
358 return new LSLString(s); 358 return new LSLString(s);
359 } 359 }
360 360
@@ -459,6 +459,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
459 size += 64; 459 size += 64;
460 else if (o is int) 460 else if (o is int)
461 size += 4; 461 size += 4;
462 else if (o is uint)
463 size += 4;
462 else if (o is string) 464 else if (o is string)
463 size += ((string)o).Length; 465 size += ((string)o).Length;
464 else if (o is float) 466 else if (o is float)
@@ -558,7 +560,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
558 else if (m_data[itemIndex] is Int32) 560 else if (m_data[itemIndex] is Int32)
559 return new LSLInteger((int)m_data[itemIndex]); 561 return new LSLInteger((int)m_data[itemIndex]);
560 else if (m_data[itemIndex] is LSL_Types.LSLString) 562 else if (m_data[itemIndex] is LSL_Types.LSLString)
561 return new LSLInteger((string)m_data[itemIndex]); 563 return new LSLInteger(m_data[itemIndex].ToString());
562 else 564 else
563 throw new InvalidCastException(); 565 throw new InvalidCastException();
564 } 566 }
@@ -613,24 +615,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 615
614 public static bool operator ==(list a, list b) 616 public static bool operator ==(list a, list b)
615 { 617 {
616 int la = -1; 618 int la = a.Length;
617 int lb = -1; 619 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 620
623 return la == lb; 621 return la == lb;
624 } 622 }
625 623
626 public static bool operator !=(list a, list b) 624 public static bool operator !=(list a, list b)
627 { 625 {
628 int la = -1; 626 int la = a.Length;
629 int lb = -1; 627 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 628
635 return la != lb; 629 return la != lb;
636 } 630 }
@@ -668,13 +662,13 @@ namespace OpenSim.Region.ScriptEngine.Shared
668 Object[] ret; 662 Object[] ret;
669 663
670 if (start < 0) 664 if (start < 0)
671 start=m_data.Length-start; 665 start=m_data.Length+start;
672 666
673 if (start < 0) 667 if (start < 0)
674 start=0; 668 start=0;
675 669
676 if (end < 0) 670 if (end < 0)
677 end=m_data.Length-end; 671 end=m_data.Length+end;
678 if (end < 0) 672 if (end < 0)
679 end=0; 673 end=0;
680 674
@@ -1064,7 +1058,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1064 { 1058 {
1065 list ret = new list(); 1059 list ret = new list();
1066 double entry; 1060 double entry;
1067 for (int i = 0; i < src.Data.Length - 1; i++) 1061 for (int i = 0; i < src.Data.Length; i++)
1068 { 1062 {
1069 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry)) 1063 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
1070 { 1064 {
@@ -1379,7 +1373,9 @@ namespace OpenSim.Region.ScriptEngine.Shared
1379 public struct LSLString 1373 public struct LSLString
1380 { 1374 {
1381 public string m_string; 1375 public string m_string;
1376
1382 #region Constructors 1377 #region Constructors
1378
1383 public LSLString(string s) 1379 public LSLString(string s)
1384 { 1380 {
1385 m_string = s; 1381 m_string = s;
@@ -1387,22 +1383,24 @@ namespace OpenSim.Region.ScriptEngine.Shared
1387 1383
1388 public LSLString(double d) 1384 public LSLString(double d)
1389 { 1385 {
1390 string s=String.Format(Culture.FormatProvider, "{0:0.000000}", d); 1386 string s = String.Format(Culture.FormatProvider, "{0:0.000000}", d);
1391 m_string=s; 1387 m_string = s;
1392 } 1388 }
1393 1389
1394 public LSLString(LSLFloat f) 1390 public LSLString(LSLFloat f)
1395 { 1391 {
1396 string s = String.Format(Culture.FormatProvider, "{0:0.000000}", f.value); 1392 string s = String.Format(Culture.FormatProvider, "{0:0.000000}", f.value);
1397 m_string=s; 1393 m_string = s;
1398 } 1394 }
1399 1395
1400 public LSLString(LSLInteger i) 1396 public LSLString(int i)
1401 { 1397 {
1402 string s = String.Format("{0}", i); 1398 string s = String.Format("{0}", i);
1403 m_string = s; 1399 m_string = s;
1404 } 1400 }
1405 1401
1402 public LSLString(LSLInteger i) : this(i.value) {}
1403
1406 #endregion 1404 #endregion
1407 1405
1408 #region Operators 1406 #region Operators
@@ -1469,6 +1467,11 @@ namespace OpenSim.Region.ScriptEngine.Shared
1469 { 1467 {
1470 return new LSLString(d); 1468 return new LSLString(d);
1471 } 1469 }
1470
1471 static public explicit operator LSLString(int i)
1472 {
1473 return new LSLString(i);
1474 }
1472 1475
1473 public static explicit operator LSLString(LSLFloat f) 1476 public static explicit operator LSLString(LSLFloat f)
1474 { 1477 {
@@ -1536,6 +1539,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1536 public struct LSLInteger 1539 public struct LSLInteger
1537 { 1540 {
1538 public int value; 1541 public int value;
1542 private static readonly Regex castRegex = new Regex(@"(^[ ]*0[xX][0-9A-Fa-f][0-9A-Fa-f]*)|(^[ ]*(-?|\+?)[0-9][0-9]*)");
1539 1543
1540 #region Constructors 1544 #region Constructors
1541 public LSLInteger(int i) 1545 public LSLInteger(int i)
@@ -1555,9 +1559,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
1555 1559
1556 public LSLInteger(string s) 1560 public LSLInteger(string s)
1557 { 1561 {
1558 Regex r = new Regex("(^[ ]*0[xX][0-9A-Fa-f][0-9A-Fa-f]*)|(^[ ]*-?[0-9][0-9]*)"); 1562 Match m = castRegex.Match(s);
1559 Match m = r.Match(s);
1560 string v = m.Groups[0].Value; 1563 string v = m.Groups[0].Value;
1564 // Leading plus sign is allowed, but ignored
1565 v = v.Replace("+", "");
1561 1566
1562 if (v == String.Empty) 1567 if (v == String.Empty)
1563 { 1568 {
@@ -1740,7 +1745,17 @@ namespace OpenSim.Region.ScriptEngine.Shared
1740 public override bool Equals(Object o) 1745 public override bool Equals(Object o)
1741 { 1746 {
1742 if (!(o is LSLInteger)) 1747 if (!(o is LSLInteger))
1743 return false; 1748 {
1749 if (o is int)
1750 {
1751 return value == (int)o;
1752 }
1753 else
1754 {
1755 return false;
1756 }
1757 }
1758
1744 return value == ((LSLInteger)o).value; 1759 return value == ((LSLInteger)o).value;
1745 } 1760 }
1746 1761
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
index 358ce22..0cbad41 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
@@ -27,12 +27,13 @@
27 27
28using System.Collections.Generic; 28using System.Collections.Generic;
29using NUnit.Framework; 29using NUnit.Framework;
30using OpenSim.Framework;
30using OpenSim.Tests.Common; 31using OpenSim.Tests.Common;
31using OpenSim.Region.ScriptEngine.Shared; 32using OpenSim.Region.ScriptEngine.Shared;
32using OpenSim.Tests.Common.Setup;
33using OpenSim.Region.Framework.Scenes; 33using OpenSim.Region.Framework.Scenes;
34using Nini.Config; 34using Nini.Config;
35using OpenSim.Region.ScriptEngine.Shared.Api; 35using OpenSim.Region.ScriptEngine.Shared.Api;
36using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
36using OpenMetaverse; 37using OpenMetaverse;
37using System; 38using System;
38using OpenSim.Tests.Common.Mock; 39using OpenSim.Tests.Common.Mock;
@@ -47,6 +48,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
47 { 48 {
48 49
49 private const double ANGLE_ACCURACY_IN_RADIANS = 1E-6; 50 private const double ANGLE_ACCURACY_IN_RADIANS = 1E-6;
51 private const double VECTOR_COMPONENT_ACCURACY = 0.0000005d;
52 private const float FLOAT_ACCURACY = 0.00005f;
50 private LSL_Api m_lslApi; 53 private LSL_Api m_lslApi;
51 54
52 [SetUp] 55 [SetUp]
@@ -57,8 +60,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
57 IConfig config = initConfigSource.AddConfig("XEngine"); 60 IConfig config = initConfigSource.AddConfig("XEngine");
58 config.Set("Enabled", "true"); 61 config.Set("Enabled", "true");
59 62
60 Scene scene = SceneSetupHelpers.SetupScene(); 63 Scene scene = SceneHelpers.SetupScene();
61 SceneObjectPart part = SceneSetupHelpers.AddSceneObject(scene); 64 SceneObjectPart part = SceneHelpers.AddSceneObject(scene);
62 65
63 XEngine.XEngine engine = new XEngine.XEngine(); 66 XEngine.XEngine engine = new XEngine.XEngine();
64 engine.Initialise(initConfigSource); 67 engine.Initialise(initConfigSource);
@@ -134,5 +137,291 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
134 137
135 #endregion 138 #endregion
136 139
140 [Test]
141 // llRot2Euler test.
142 public void TestllRot2Euler()
143 {
144 // 180, 90 and zero degree rotations.
145 CheckllRot2Euler(new LSL_Types.Quaternion(1.0f, 0.0f, 0.0f, 0.0f), new LSL_Types.Vector3(Math.PI, 0.0f, 0.0f));
146 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, 1.0f, 0.0f, 0.0f), new LSL_Types.Vector3(Math.PI, 0.0f, Math.PI));
147 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, 0.0f, 1.0f, 0.0f), new LSL_Types.Vector3(0.0f, 0.0f, Math.PI));
148 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, 0.0f, 0.0f, 1.0f), new LSL_Types.Vector3(0.0f, 0.0f, 0.0f));
149 CheckllRot2Euler(new LSL_Types.Quaternion(-0.5f, -0.5f, 0.5f, 0.5f), new LSL_Types.Vector3(0, -Math.PI / 2.0f, Math.PI / 2.0f));
150 CheckllRot2Euler(new LSL_Types.Quaternion(-0.707107f, 0.0f, 0.0f, -0.707107f), new LSL_Types.Vector3(Math.PI / 2.0f, 0.0f, 0.0f));
151 // A couple of messy rotations.
152 CheckllRot2Euler(new LSL_Types.Quaternion(1.0f, 5.651f, -3.1f, 67.023f), new LSL_Types.Vector3(0.037818f, 0.166447f, -0.095595f));
153 CheckllRot2Euler(new LSL_Types.Quaternion(0.719188f, -0.408934f, -0.363998f, -0.427841f), new LSL_Types.Vector3(-1.954769f, -0.174533f, 1.151917f));
154 }
155
156 private void CheckllRot2Euler(LSL_Types.Quaternion rot, LSL_Types.Vector3 eulerCheck)
157 {
158 // Call LSL function to convert quaternion rotaion to euler radians.
159 LSL_Types.Vector3 eulerCalc = m_lslApi.llRot2Euler(rot);
160 // Check upper and lower bounds of x, y and z.
161 // This type of check is performed as opposed to comparing for equal numbers, in order to allow slight
162 // differences in accuracy.
163 Assert.Greater(eulerCalc.x, eulerCheck.x - ANGLE_ACCURACY_IN_RADIANS, "TestllRot2Euler X lower bounds check fail");
164 Assert.Less(eulerCalc.x, eulerCheck.x + ANGLE_ACCURACY_IN_RADIANS, "TestllRot2Euler X upper bounds check fail");
165 Assert.Greater(eulerCalc.y, eulerCheck.y - ANGLE_ACCURACY_IN_RADIANS, "TestllRot2Euler Y lower bounds check fail");
166 Assert.Less(eulerCalc.y, eulerCheck.y + ANGLE_ACCURACY_IN_RADIANS, "TestllRot2Euler Y upper bounds check fail");
167 Assert.Greater(eulerCalc.z, eulerCheck.z - ANGLE_ACCURACY_IN_RADIANS, "TestllRot2Euler Z lower bounds check fail");
168 Assert.Less(eulerCalc.z, eulerCheck.z + ANGLE_ACCURACY_IN_RADIANS, "TestllRot2Euler Z upper bounds check fail");
169 }
170
171 [Test]
172 // llSetPrimitiveParams and llGetPrimitiveParams test.
173 public void TestllSetPrimitiveParams()
174 {
175 // Create Prim1.
176 Scene scene = SceneHelpers.SetupScene();
177 string obj1Name = "Prim1";
178 UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001");
179 SceneObjectPart part1 =
180 new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default,
181 Vector3.Zero, Quaternion.Identity,
182 Vector3.Zero) { Name = obj1Name, UUID = objUuid };
183 Assert.That(scene.AddNewSceneObject(new SceneObjectGroup(part1), false), Is.True);
184
185 // Note that prim hollow check is passed with the other prim params in order to allow the
186 // specification of a different check value from the prim param. A cylinder, prism, sphere,
187 // torus or ring, with a hole shape of square, is limited to a hollow of 70%. Test 5 below
188 // specifies a value of 95% and checks to see if 70% was properly returned.
189
190 // Test a sphere.
191 CheckllSetPrimitiveParams(
192 "test 1", // Prim test identification string
193 new LSL_Types.Vector3(6.0d, 9.9d, 9.9d), // Prim size
194 ScriptBaseClass.PRIM_TYPE_SPHERE, // Prim type
195 ScriptBaseClass.PRIM_HOLE_DEFAULT, // Prim hole type
196 new LSL_Types.Vector3(0.0d, 0.075d, 0.0d), // Prim cut
197 0.80f, // Prim hollow
198 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist
199 new LSL_Types.Vector3(0.32d, 0.76d, 0.0d), // Prim dimple
200 0.80f); // Prim hollow check
201
202 // Test a prism.
203 CheckllSetPrimitiveParams(
204 "test 2", // Prim test identification string
205 new LSL_Types.Vector3(3.5d, 3.5d, 3.5d), // Prim size
206 ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type
207 ScriptBaseClass.PRIM_HOLE_CIRCLE, // Prim hole type
208 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
209 0.90f, // Prim hollow
210 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim twist
211 new LSL_Types.Vector3(2.0d, 1.0d, 0.0d), // Prim taper
212 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
213 0.90f); // Prim hollow check
214
215 // Test a box.
216 CheckllSetPrimitiveParams(
217 "test 3", // Prim test identification string
218 new LSL_Types.Vector3(3.5d, 3.5d, 3.5d), // Prim size
219 ScriptBaseClass.PRIM_TYPE_BOX, // Prim type
220 ScriptBaseClass.PRIM_HOLE_TRIANGLE, // Prim hole type
221 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
222 0.95f, // Prim hollow
223 new LSL_Types.Vector3(1.0d, 0.0d, 0.0d), // Prim twist
224 new LSL_Types.Vector3(1.0d, 1.0d, 0.0d), // Prim taper
225 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
226 0.95f); // Prim hollow check
227
228 // Test a tube.
229 CheckllSetPrimitiveParams(
230 "test 4", // Prim test identification string
231 new LSL_Types.Vector3(4.2d, 4.2d, 4.2d), // Prim size
232 ScriptBaseClass.PRIM_TYPE_TUBE, // Prim type
233 ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type
234 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
235 0.00f, // Prim hollow
236 new LSL_Types.Vector3(1.0d, -1.0d, 0.0d), // Prim twist
237 new LSL_Types.Vector3(1.0d, 0.05d, 0.0d), // Prim hole size
238 // Expression for y selected to test precision problems during byte
239 // cast in SetPrimitiveShapeParams.
240 new LSL_Types.Vector3(0.0d, 0.35d + 0.1d, 0.0d), // Prim shear
241 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim profile cut
242 // Expression for y selected to test precision problems during sbyte
243 // cast in SetPrimitiveShapeParams.
244 new LSL_Types.Vector3(-1.0d, 0.70d + 0.1d + 0.1d, 0.0d), // Prim taper
245 1.11f, // Prim revolutions
246 0.88f, // Prim radius
247 0.95f, // Prim skew
248 0.00f); // Prim hollow check
249
250 // Test a prism.
251 CheckllSetPrimitiveParams(
252 "test 5", // Prim test identification string
253 new LSL_Types.Vector3(3.5d, 3.5d, 3.5d), // Prim size
254 ScriptBaseClass.PRIM_TYPE_PRISM, // Prim type
255 ScriptBaseClass.PRIM_HOLE_SQUARE, // Prim hole type
256 new LSL_Types.Vector3(0.0d, 1.0d, 0.0d), // Prim cut
257 0.95f, // Prim hollow
258 // Expression for x selected to test precision problems during sbyte
259 // cast in SetPrimitiveShapeBlockParams.
260 new LSL_Types.Vector3(0.7d + 0.2d, 0.0d, 0.0d), // Prim twist
261 // Expression for y selected to test precision problems during sbyte
262 // cast in SetPrimitiveShapeParams.
263 new LSL_Types.Vector3(2.0d, (1.3d + 0.1d), 0.0d), // Prim taper
264 new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), // Prim shear
265 0.70f); // Prim hollow check
266
267 // Test a sculpted prim.
268 CheckllSetPrimitiveParams(
269 "test 6", // Prim test identification string
270 new LSL_Types.Vector3(2.0d, 2.0d, 2.0d), // Prim size
271 ScriptBaseClass.PRIM_TYPE_SCULPT, // Prim type
272 "be293869-d0d9-0a69-5989-ad27f1946fd4", // Prim map
273 ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE); // Prim sculpt type
274 }
275
276 // Set prim params for a box, cylinder or prism and check results.
277 public void CheckllSetPrimitiveParams(string primTest,
278 LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
279 float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primTaper, LSL_Types.Vector3 primShear,
280 float primHollowCheck)
281 {
282 // Set the prim params.
283 m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
284 ScriptBaseClass.PRIM_TYPE, primType, primHoleType,
285 primCut, primHollow, primTwist, primTaper, primShear));
286
287 // Get params for prim to validate settings.
288 LSL_Types.list primParams =
289 m_lslApi.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE));
290
291 // Validate settings.
292 CheckllSetPrimitiveParamsVector(primSize, m_lslApi.llList2Vector(primParams, 0), primTest + " prim size");
293 Assert.AreEqual(primType, m_lslApi.llList2Integer(primParams, 1),
294 "TestllSetPrimitiveParams " + primTest + " prim type check fail");
295 Assert.AreEqual(primHoleType, m_lslApi.llList2Integer(primParams, 2),
296 "TestllSetPrimitiveParams " + primTest + " prim hole default check fail");
297 CheckllSetPrimitiveParamsVector(primCut, m_lslApi.llList2Vector(primParams, 3), primTest + " prim cut");
298 Assert.AreEqual(primHollowCheck, m_lslApi.llList2Float(primParams, 4), FLOAT_ACCURACY,
299 "TestllSetPrimitiveParams " + primTest + " prim hollow check fail");
300 CheckllSetPrimitiveParamsVector(primTwist, m_lslApi.llList2Vector(primParams, 5), primTest + " prim twist");
301 CheckllSetPrimitiveParamsVector(primTaper, m_lslApi.llList2Vector(primParams, 6), primTest + " prim taper");
302 CheckllSetPrimitiveParamsVector(primShear, m_lslApi.llList2Vector(primParams, 7), primTest + " prim shear");
303 }
304
305 // Set prim params for a sphere and check results.
306 public void CheckllSetPrimitiveParams(string primTest,
307 LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
308 float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primDimple, float primHollowCheck)
309 {
310 // Set the prim params.
311 m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
312 ScriptBaseClass.PRIM_TYPE, primType, primHoleType,
313 primCut, primHollow, primTwist, primDimple));
314
315 // Get params for prim to validate settings.
316 LSL_Types.list primParams =
317 m_lslApi.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE));
318
319 // Validate settings.
320 CheckllSetPrimitiveParamsVector(primSize, m_lslApi.llList2Vector(primParams, 0), primTest + " prim size");
321 Assert.AreEqual(primType, m_lslApi.llList2Integer(primParams, 1),
322 "TestllSetPrimitiveParams " + primTest + " prim type check fail");
323 Assert.AreEqual(primHoleType, m_lslApi.llList2Integer(primParams, 2),
324 "TestllSetPrimitiveParams " + primTest + " prim hole default check fail");
325 CheckllSetPrimitiveParamsVector(primCut, m_lslApi.llList2Vector(primParams, 3), primTest + " prim cut");
326 Assert.AreEqual(primHollowCheck, m_lslApi.llList2Float(primParams, 4), FLOAT_ACCURACY,
327 "TestllSetPrimitiveParams " + primTest + " prim hollow check fail");
328 CheckllSetPrimitiveParamsVector(primTwist, m_lslApi.llList2Vector(primParams, 5), primTest + " prim twist");
329 CheckllSetPrimitiveParamsVector(primDimple, m_lslApi.llList2Vector(primParams, 6), primTest + " prim dimple");
330 }
331
332 // Set prim params for a torus, tube or ring and check results.
333 public void CheckllSetPrimitiveParams(string primTest,
334 LSL_Types.Vector3 primSize, int primType, int primHoleType, LSL_Types.Vector3 primCut,
335 float primHollow, LSL_Types.Vector3 primTwist, LSL_Types.Vector3 primHoleSize,
336 LSL_Types.Vector3 primShear, LSL_Types.Vector3 primProfCut, LSL_Types.Vector3 primTaper,
337 float primRev, float primRadius, float primSkew, float primHollowCheck)
338 {
339 // Set the prim params.
340 m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
341 ScriptBaseClass.PRIM_TYPE, primType, primHoleType,
342 primCut, primHollow, primTwist, primHoleSize, primShear, primProfCut,
343 primTaper, primRev, primRadius, primSkew));
344
345 // Get params for prim to validate settings.
346 LSL_Types.list primParams =
347 m_lslApi.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE));
348
349 // Valdate settings.
350 CheckllSetPrimitiveParamsVector(primSize, m_lslApi.llList2Vector(primParams, 0), primTest + " prim size");
351 Assert.AreEqual(primType, m_lslApi.llList2Integer(primParams, 1),
352 "TestllSetPrimitiveParams " + primTest + " prim type check fail");
353 Assert.AreEqual(primHoleType, m_lslApi.llList2Integer(primParams, 2),
354 "TestllSetPrimitiveParams " + primTest + " prim hole default check fail");
355 CheckllSetPrimitiveParamsVector(primCut, m_lslApi.llList2Vector(primParams, 3), primTest + " prim cut");
356 Assert.AreEqual(primHollowCheck, m_lslApi.llList2Float(primParams, 4), FLOAT_ACCURACY,
357 "TestllSetPrimitiveParams " + primTest + " prim hollow check fail");
358 CheckllSetPrimitiveParamsVector(primTwist, m_lslApi.llList2Vector(primParams, 5), primTest + " prim twist");
359 CheckllSetPrimitiveParamsVector(primHoleSize, m_lslApi.llList2Vector(primParams, 6), primTest + " prim hole size");
360 CheckllSetPrimitiveParamsVector(primShear, m_lslApi.llList2Vector(primParams, 7), primTest + " prim shear");
361 CheckllSetPrimitiveParamsVector(primProfCut, m_lslApi.llList2Vector(primParams, 8), primTest + " prim profile cut");
362 CheckllSetPrimitiveParamsVector(primTaper, m_lslApi.llList2Vector(primParams, 9), primTest + " prim taper");
363 Assert.AreEqual(primRev, m_lslApi.llList2Float(primParams, 10), FLOAT_ACCURACY,
364 "TestllSetPrimitiveParams " + primTest + " prim revolutions fail");
365 Assert.AreEqual(primRadius, m_lslApi.llList2Float(primParams, 11), FLOAT_ACCURACY,
366 "TestllSetPrimitiveParams " + primTest + " prim radius fail");
367 Assert.AreEqual(primSkew, m_lslApi.llList2Float(primParams, 12), FLOAT_ACCURACY,
368 "TestllSetPrimitiveParams " + primTest + " prim skew fail");
369 }
370
371 // Set prim params for a sculpted prim and check results.
372 public void CheckllSetPrimitiveParams(string primTest,
373 LSL_Types.Vector3 primSize, int primType, string primMap, int primSculptType)
374 {
375 // Set the prim params.
376 m_lslApi.llSetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, primSize,
377 ScriptBaseClass.PRIM_TYPE, primType, primMap, primSculptType));
378
379 // Get params for prim to validate settings.
380 LSL_Types.list primParams =
381 m_lslApi.llGetPrimitiveParams(new LSL_Types.list(ScriptBaseClass.PRIM_SIZE, ScriptBaseClass.PRIM_TYPE));
382
383 // Validate settings.
384 CheckllSetPrimitiveParamsVector(primSize, m_lslApi.llList2Vector(primParams, 0), primTest + " prim size");
385 Assert.AreEqual(primType, m_lslApi.llList2Integer(primParams, 1),
386 "TestllSetPrimitiveParams " + primTest + " prim type check fail");
387 Assert.AreEqual(primMap, (string)m_lslApi.llList2String(primParams, 2),
388 "TestllSetPrimitiveParams " + primTest + " prim map check fail");
389 Assert.AreEqual(primSculptType, m_lslApi.llList2Integer(primParams, 3),
390 "TestllSetPrimitiveParams " + primTest + " prim type scuplt check fail");
391 }
392
393 public void CheckllSetPrimitiveParamsVector(LSL_Types.Vector3 vecCheck, LSL_Types.Vector3 vecReturned, string msg)
394 {
395 // Check each vector component against expected result.
396 Assert.AreEqual(vecCheck.x, vecReturned.x, VECTOR_COMPONENT_ACCURACY,
397 "TestllSetPrimitiveParams " + msg + " vector check fail on x component");
398 Assert.AreEqual(vecCheck.y, vecReturned.y, VECTOR_COMPONENT_ACCURACY,
399 "TestllSetPrimitiveParams " + msg + " vector check fail on y component");
400 Assert.AreEqual(vecCheck.z, vecReturned.z, VECTOR_COMPONENT_ACCURACY,
401 "TestllSetPrimitiveParams " + msg + " vector check fail on z component");
402 }
403
404 [Test]
405 // llVecNorm test.
406 public void TestllVecNorm()
407 {
408 // Check special case for normalizing zero vector.
409 CheckllVecNorm(new LSL_Types.Vector3(0.0d, 0.0d, 0.0d), new LSL_Types.Vector3(0.0d, 0.0d, 0.0d));
410 // Check various vectors.
411 CheckllVecNorm(new LSL_Types.Vector3(10.0d, 25.0d, 0.0d), new LSL_Types.Vector3(0.371391d, 0.928477d, 0.0d));
412 CheckllVecNorm(new LSL_Types.Vector3(1.0d, 0.0d, 0.0d), new LSL_Types.Vector3(1.0d, 0.0d, 0.0d));
413 CheckllVecNorm(new LSL_Types.Vector3(-90.0d, 55.0d, 2.0d), new LSL_Types.Vector3(-0.853128d, 0.521356d, 0.018958d));
414 CheckllVecNorm(new LSL_Types.Vector3(255.0d, 255.0d, 255.0d), new LSL_Types.Vector3(0.577350d, 0.577350d, 0.577350d));
415 }
416
417 public void CheckllVecNorm(LSL_Types.Vector3 vec, LSL_Types.Vector3 vecNormCheck)
418 {
419 // Call LSL function to normalize the vector.
420 LSL_Types.Vector3 vecNorm = m_lslApi.llVecNorm(vec);
421 // Check each vector component against expected result.
422 Assert.AreEqual(vecNorm.x, vecNormCheck.x, VECTOR_COMPONENT_ACCURACY, "TestllVecNorm vector check fail on x component");
423 Assert.AreEqual(vecNorm.y, vecNormCheck.y, VECTOR_COMPONENT_ACCURACY, "TestllVecNorm vector check fail on y component");
424 Assert.AreEqual(vecNorm.z, vecNormCheck.z, VECTOR_COMPONENT_ACCURACY, "TestllVecNorm vector check fail on z component");
425 }
137 } 426 }
138} 427}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
new file mode 100644
index 0000000..7573dff
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
@@ -0,0 +1,229 @@
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.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using log4net;
33using Nini.Config;
34using NUnit.Framework;
35using OpenMetaverse;
36using OpenMetaverse.Assets;
37using OpenMetaverse.StructuredData;
38using OpenSim.Framework;
39using OpenSim.Region.CoreModules.Avatar.AvatarFactory;
40using OpenSim.Region.OptionalModules.World.NPC;
41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Region.ScriptEngine.Shared;
43using OpenSim.Region.ScriptEngine.Shared.Api;
44using OpenSim.Services.Interfaces;
45using OpenSim.Tests.Common;
46using OpenSim.Tests.Common.Mock;
47
48namespace OpenSim.Region.ScriptEngine.Shared.Tests
49{
50 /// <summary>
51 /// Tests for OSSL_Api
52 /// </summary>
53 [TestFixture]
54 public class OSSL_ApiAppearanceTest
55 {
56 protected Scene m_scene;
57 protected XEngine.XEngine m_engine;
58
59 [SetUp]
60 public void SetUp()
61 {
62 IConfigSource initConfigSource = new IniConfigSource();
63 IConfig config = initConfigSource.AddConfig("XEngine");
64 config.Set("Enabled", "true");
65 config.Set("AllowOSFunctions", "true");
66 config.Set("OSFunctionThreatLevel", "Severe");
67 config = initConfigSource.AddConfig("NPC");
68 config.Set("Enabled", "true");
69
70 m_scene = SceneHelpers.SetupScene();
71 SceneHelpers.SetupSceneModules(m_scene, initConfigSource, new AvatarFactoryModule(), new NPCModule());
72
73 m_engine = new XEngine.XEngine();
74 m_engine.Initialise(initConfigSource);
75 m_engine.AddRegion(m_scene);
76 }
77
78 /// <summary>
79 /// Test creation of an NPC where the appearance data comes from a notecard
80 /// </summary>
81 [Test]
82 public void TestOsNpcCreateFromNotecard()
83 {
84 TestHelpers.InMethod();
85// log4net.Config.XmlConfigurator.Configure();
86
87 // Store an avatar with a different height from default in a notecard.
88 UUID userId = TestHelpers.ParseTail(0x1);
89 float newHeight = 1.9f;
90
91 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
92 sp.Appearance.AvatarHeight = newHeight;
93 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId);
94 SceneObjectPart part = so.RootPart;
95 m_scene.AddSceneObject(so);
96
97 OSSL_Api osslApi = new OSSL_Api();
98 osslApi.Initialize(m_engine, part, part.LocalId, part.UUID);
99
100 string notecardName = "appearanceNc";
101 osslApi.osOwnerSaveAppearance(notecardName);
102
103 // Try creating a bot using the appearance in the notecard.
104 string npcRaw = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), notecardName);
105 Assert.That(npcRaw, Is.Not.Null);
106
107 UUID npcId = new UUID(npcRaw);
108 ScenePresence npc = m_scene.GetScenePresence(npcId);
109 Assert.That(npc, Is.Not.Null);
110 Assert.That(npc.Appearance.AvatarHeight, Is.EqualTo(newHeight));
111 }
112
113 /// <summary>
114 /// Test creation of an NPC where the appearance data comes from an avatar already in the region.
115 /// </summary>
116 [Test]
117 public void TestOsNpcCreateFromAvatar()
118 {
119 TestHelpers.InMethod();
120// log4net.Config.XmlConfigurator.Configure();
121
122 // Store an avatar with a different height from default in a notecard.
123 UUID userId = TestHelpers.ParseTail(0x1);
124 float newHeight = 1.9f;
125
126 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
127 sp.Appearance.AvatarHeight = newHeight;
128 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId);
129 SceneObjectPart part = so.RootPart;
130 m_scene.AddSceneObject(so);
131
132 OSSL_Api osslApi = new OSSL_Api();
133 osslApi.Initialize(m_engine, part, part.LocalId, part.UUID);
134
135 string notecardName = "appearanceNc";
136 osslApi.osOwnerSaveAppearance(notecardName);
137
138 // Try creating a bot using the existing avatar's appearance
139 string npcRaw = osslApi.osNpcCreate("Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), sp.UUID.ToString());
140 Assert.That(npcRaw, Is.Not.Null);
141
142 UUID npcId = new UUID(npcRaw);
143 ScenePresence npc = m_scene.GetScenePresence(npcId);
144 Assert.That(npc, Is.Not.Null);
145 Assert.That(npc.Appearance.AvatarHeight, Is.EqualTo(newHeight));
146 }
147
148 [Test]
149 public void TestOsOwnerSaveAppearance()
150 {
151 TestHelpers.InMethod();
152// log4net.Config.XmlConfigurator.Configure();
153
154 UUID userId = TestHelpers.ParseTail(0x1);
155 float newHeight = 1.9f;
156
157 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
158 sp.Appearance.AvatarHeight = newHeight;
159 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId);
160 SceneObjectPart part = so.RootPart;
161 m_scene.AddSceneObject(so);
162
163 OSSL_Api osslApi = new OSSL_Api();
164 osslApi.Initialize(m_engine, part, part.LocalId, part.UUID);
165
166 string notecardName = "appearanceNc";
167
168 osslApi.osOwnerSaveAppearance(notecardName);
169
170 IList<TaskInventoryItem> items = part.Inventory.GetInventoryItems(notecardName);
171 Assert.That(items.Count, Is.EqualTo(1));
172
173 TaskInventoryItem ncItem = items[0];
174 Assert.That(ncItem.Name, Is.EqualTo(notecardName));
175
176 AssetBase ncAsset = m_scene.AssetService.Get(ncItem.AssetID.ToString());
177 Assert.That(ncAsset, Is.Not.Null);
178
179 AssetNotecard anc = new AssetNotecard(UUID.Zero, ncAsset.Data);
180 anc.Decode();
181 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(anc.BodyText);
182 AvatarAppearance savedAppearance = new AvatarAppearance();
183 savedAppearance.Unpack(appearanceOsd);
184
185 Assert.That(savedAppearance.AvatarHeight, Is.EqualTo(sp.Appearance.AvatarHeight));
186 }
187
188 [Test]
189 public void TestOsAgentSaveAppearance()
190 {
191 TestHelpers.InMethod();
192// log4net.Config.XmlConfigurator.Configure();
193
194 UUID ownerId = TestHelpers.ParseTail(0x1);
195 UUID nonOwnerId = TestHelpers.ParseTail(0x2);
196 float newHeight = 1.9f;
197
198 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, nonOwnerId);
199 sp.Appearance.AvatarHeight = newHeight;
200 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, ownerId);
201 SceneObjectPart part = so.RootPart;
202 m_scene.AddSceneObject(so);
203
204 OSSL_Api osslApi = new OSSL_Api();
205 osslApi.Initialize(m_engine, part, part.LocalId, part.UUID);
206
207 string notecardName = "appearanceNc";
208
209 osslApi.osAgentSaveAppearance(new LSL_Types.LSLString(nonOwnerId.ToString()), notecardName);
210
211 IList<TaskInventoryItem> items = part.Inventory.GetInventoryItems(notecardName);
212 Assert.That(items.Count, Is.EqualTo(1));
213
214 TaskInventoryItem ncItem = items[0];
215 Assert.That(ncItem.Name, Is.EqualTo(notecardName));
216
217 AssetBase ncAsset = m_scene.AssetService.Get(ncItem.AssetID.ToString());
218 Assert.That(ncAsset, Is.Not.Null);
219
220 AssetNotecard anc = new AssetNotecard(UUID.Zero, ncAsset.Data);
221 anc.Decode();
222 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(anc.BodyText);
223 AvatarAppearance savedAppearance = new AvatarAppearance();
224 savedAppearance.Unpack(appearanceOsd);
225
226 Assert.That(savedAppearance.AvatarHeight, Is.EqualTo(sp.Appearance.AvatarHeight));
227 }
228 }
229} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
index 09b79d0..5c4174e 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
@@ -97,13 +97,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
97 return; 97 return;
98 98
99 m_log.Debug("Paid: " + objectID + " from " + agentID + ", amount " + amount); 99 m_log.Debug("Paid: " + objectID + " from " + agentID + ", amount " + amount);
100 if (part.ParentGroup != null)
101 part = part.ParentGroup.RootPart;
102 100
103 if (part != null) 101 part = part.ParentGroup.RootPart;
104 { 102 money(part.LocalId, agentID, amount);
105 money(part.LocalId, agentID, amount);
106 }
107 } 103 }
108 104
109 /// <summary> 105 /// <summary>
@@ -356,9 +352,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
356 // timer: not handled here 352 // timer: not handled here
357 // listen: not handled here 353 // listen: not handled here
358 354
359 public void control(uint localID, UUID itemID, UUID agentID, uint held, uint change) 355 public void control(UUID itemID, UUID agentID, uint held, uint change)
360 { 356 {
361 myScriptEngine.PostObjectEvent(localID, new EventParams( 357 myScriptEngine.PostScriptEvent(itemID, new EventParams(
362 "control",new object[] { 358 "control",new object[] {
363 new LSL_Types.LSLString(agentID.ToString()), 359 new LSL_Types.LSLString(agentID.ToString()),
364 new LSL_Types.LSLInteger(held), 360 new LSL_Types.LSLInteger(held),
diff --git a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs
index 045abb4..b635d5c 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/Tests/XEngineTest.cs
@@ -29,7 +29,6 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using Nini.Config; 30using Nini.Config;
31using NUnit.Framework; 31using NUnit.Framework;
32using OpenSim.Tests.Common.Setup;
33using OpenSim.Tests.Common.Mock; 32using OpenSim.Tests.Common.Mock;
34using OpenSim.Region.Framework.Scenes; 33using OpenSim.Region.Framework.Scenes;
35using OpenMetaverse; 34using OpenMetaverse;
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index c8f6559..65c7416 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -42,7 +42,7 @@ using log4net;
42using Nini.Config; 42using Nini.Config;
43using Amib.Threading; 43using Amib.Threading;
44using OpenSim.Framework; 44using OpenSim.Framework;
45using OpenSim.Region.CoreModules.Framework.EventQueue; 45using OpenSim.Framework.Console;
46using OpenSim.Region.Framework.Scenes; 46using OpenSim.Region.Framework.Scenes;
47using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
48using OpenSim.Region.ScriptEngine.Shared; 48using OpenSim.Region.ScriptEngine.Shared;
@@ -89,6 +89,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
89 private IXmlRpcRouter m_XmlRpcRouter; 89 private IXmlRpcRouter m_XmlRpcRouter;
90 private int m_EventLimit; 90 private int m_EventLimit;
91 private bool m_KillTimedOutScripts; 91 private bool m_KillTimedOutScripts;
92 private string m_ScriptEnginesPath = null;
93
94 /// <summary>
95 /// Is the entire simulator in the process of shutting down?
96 /// </summary>
97 private bool m_SimulatorShuttingDown;
92 98
93 private static List<XEngine> m_ScriptEngines = 99 private static List<XEngine> m_ScriptEngines =
94 new List<XEngine>(); 100 new List<XEngine>();
@@ -224,6 +230,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine
224 get { return m_ScriptConfig; } 230 get { return m_ScriptConfig; }
225 } 231 }
226 232
233 public string ScriptEnginePath
234 {
235 get { return m_ScriptEnginesPath; }
236 }
237
227 public IConfigSource ConfigSource 238 public IConfigSource ConfigSource
228 { 239 {
229 get { return m_ConfigSource; } 240 get { return m_ConfigSource; }
@@ -281,6 +292,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
281 m_EventLimit = m_ScriptConfig.GetInt("EventLimit", 30); 292 m_EventLimit = m_ScriptConfig.GetInt("EventLimit", 30);
282 m_KillTimedOutScripts = m_ScriptConfig.GetBoolean("KillTimedOutScripts", false); 293 m_KillTimedOutScripts = m_ScriptConfig.GetBoolean("KillTimedOutScripts", false);
283 m_SaveTime = m_ScriptConfig.GetInt("SaveInterval", 120) * 1000; 294 m_SaveTime = m_ScriptConfig.GetInt("SaveInterval", 120) * 1000;
295 m_ScriptEnginesPath = m_ScriptConfig.GetString("ScriptEnginesPath", "ScriptEngines");
284 296
285 m_Prio = ThreadPriority.BelowNormal; 297 m_Prio = ThreadPriority.BelowNormal;
286 switch (priority) 298 switch (priority)
@@ -327,10 +339,185 @@ namespace OpenSim.Region.ScriptEngine.XEngine
327 OnScriptRemoved += m_XmlRpcRouter.ScriptRemoved; 339 OnScriptRemoved += m_XmlRpcRouter.ScriptRemoved;
328 OnObjectRemoved += m_XmlRpcRouter.ObjectRemoved; 340 OnObjectRemoved += m_XmlRpcRouter.ObjectRemoved;
329 } 341 }
342
343 MainConsole.Instance.Commands.AddCommand(
344 "scripts", false, "scripts show", "scripts show", "Show script information",
345 "Show information on all scripts known to the script engine", HandleShowScripts);
346
347 MainConsole.Instance.Commands.AddCommand(
348 "scripts", false, "show scripts", "show scripts", "Show script information",
349 "Synonym for scripts show command", HandleShowScripts);
350
351 MainConsole.Instance.Commands.AddCommand(
352 "scripts", false, "scripts suspend", "scripts suspend [<script-item-uuid>]", "Suspends all running scripts",
353 "Suspends all currently running scripts. This only suspends event delivery, it will not suspend a"
354 + " script that is currently processing an event.\n"
355 + "Suspended scripts will continue to accumulate events but won't process them.\n"
356 + "If a <script-item-uuid> is given then only that script will be suspended. Otherwise, all suitable scripts are suspended.",
357 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleSuspendScript));
358
359 MainConsole.Instance.Commands.AddCommand(
360 "scripts", false, "scripts resume", "scripts resume [<script-item-uuid>]", "Resumes all suspended scripts",
361 "Resumes all currently suspended scripts.\n"
362 + "Resumed scripts will process all events accumulated whilst suspended."
363 + "If a <script-item-uuid> is given then only that script will be resumed. Otherwise, all suitable scripts are resumed.",
364 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleResumeScript));
365
366 MainConsole.Instance.Commands.AddCommand(
367 "scripts", false, "scripts stop", "scripts stop [<script-item-uuid>]", "Stops all running scripts",
368 "Stops all running scripts."
369 + "If a <script-item-uuid> is given then only that script will be stopped. Otherwise, all suitable scripts are stopped.",
370 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStopScript));
371
372 MainConsole.Instance.Commands.AddCommand(
373 "scripts", false, "scripts start", "scripts start [<script-item-uuid>]", "Starts all stopped scripts",
374 "Starts all stopped scripts."
375 + "If a <script-item-uuid> is given then only that script will be started. Otherwise, all suitable scripts are started.",
376 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStartScript));
377 }
378
379 public void HandleShowScripts(string module, string[] cmdparams)
380 {
381 lock (m_Scripts)
382 {
383 MainConsole.Instance.OutputFormat(
384 "Showing {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName);
385
386 foreach (IScriptInstance instance in m_Scripts.Values)
387 {
388 SceneObjectPart sop = m_Scene.GetSceneObjectPart(instance.ObjectID);
389 string status;
390
391 if (instance.ShuttingDown)
392 {
393 status = "shutting down";
394 }
395 else if (instance.Suspended)
396 {
397 status = "suspended";
398 }
399 else if (!instance.Running)
400 {
401 status = "stopped";
402 }
403 else
404 {
405 status = "running";
406 }
407
408 MainConsole.Instance.OutputFormat(
409 "{0}.{1}, item UUID {2}, prim UUID {3} @ {4} ({5})",
410 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID,
411 sop.AbsolutePosition, status);
412 }
413 }
414 }
415
416 /// <summary>
417 /// Parse the raw item id into a script instance from the command params if it's present.
418 /// </summary>
419 /// <param name="cmdparams"></param>
420 /// <param name="instance"></param>
421 /// <returns>true if we're okay to proceed, false if not.</returns>
422 private void HandleScriptsAction(string[] cmdparams, Action<IScriptInstance> action)
423 {
424 lock (m_Scripts)
425 {
426 string rawItemId;
427 UUID itemId = UUID.Zero;
428
429 if (cmdparams.Length == 2)
430 {
431 foreach (IScriptInstance instance in m_Scripts.Values)
432 action(instance);
433
434 return;
435 }
436
437 rawItemId = cmdparams[2];
438
439 if (!UUID.TryParse(rawItemId, out itemId))
440 {
441 MainConsole.Instance.OutputFormat("Error - {0} is not a valid UUID", rawItemId);
442 return;
443 }
444
445 if (itemId != UUID.Zero)
446 {
447 IScriptInstance instance = GetInstance(itemId);
448 if (instance == null)
449 {
450 // Commented out for now since this will cause false reports on simulators with more than
451 // one scene where the current command line set region is 'root' (which causes commands to
452 // go to both regions... (sigh)
453// MainConsole.Instance.OutputFormat("Error - No item found with id {0}", itemId);
454 return;
455 }
456 else
457 {
458 action(instance);
459 return;
460 }
461 }
462 }
463 }
464
465 private void HandleSuspendScript(IScriptInstance instance)
466 {
467 if (!instance.Suspended)
468 {
469 instance.Suspend();
470
471 SceneObjectPart sop = m_Scene.GetSceneObjectPart(instance.ObjectID);
472 MainConsole.Instance.OutputFormat(
473 "Suspended {0}.{1}, item UUID {2}, prim UUID {3} @ {4}",
474 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, sop.AbsolutePosition);
475 }
476 }
477
478 private void HandleResumeScript(IScriptInstance instance)
479 {
480 if (instance.Suspended)
481 {
482 instance.Resume();
483
484 SceneObjectPart sop = m_Scene.GetSceneObjectPart(instance.ObjectID);
485 MainConsole.Instance.OutputFormat(
486 "Resumed {0}.{1}, item UUID {2}, prim UUID {3} @ {4}",
487 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, sop.AbsolutePosition);
488 }
489 }
490
491 private void HandleStartScript(IScriptInstance instance)
492 {
493 if (!instance.Running)
494 {
495 instance.Start();
496
497 SceneObjectPart sop = m_Scene.GetSceneObjectPart(instance.ObjectID);
498 MainConsole.Instance.OutputFormat(
499 "Started {0}.{1}, item UUID {2}, prim UUID {3} @ {4}",
500 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, sop.AbsolutePosition);
501 }
502 }
503
504 private void HandleStopScript(IScriptInstance instance)
505 {
506 if (instance.Running)
507 {
508 instance.Stop(0);
509
510 SceneObjectPart sop = m_Scene.GetSceneObjectPart(instance.ObjectID);
511 MainConsole.Instance.OutputFormat(
512 "Stopped {0}.{1}, item UUID {2}, prim UUID {3} @ {4}",
513 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, sop.AbsolutePosition);
514 }
330 } 515 }
331 516
332 public void RemoveRegion(Scene scene) 517 public void RemoveRegion(Scene scene)
333 { 518 {
519 if (!m_Enabled)
520 return;
334 lockScriptsForRead(true); 521 lockScriptsForRead(true);
335 foreach (IScriptInstance instance in m_Scripts.Values) 522 foreach (IScriptInstance instance in m_Scripts.Values)
336 { 523 {
@@ -355,12 +542,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
355 // Must be done explicitly because they have infinite 542 // Must be done explicitly because they have infinite
356 // lifetime 543 // lifetime
357 // 544 //
358 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 545 if (!m_SimulatorShuttingDown)
359 if (m_DomainScripts[instance.AppDomain].Count == 0)
360 { 546 {
361 m_DomainScripts.Remove(instance.AppDomain); 547 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
362 UnloadAppDomain(instance.AppDomain); 548 if (m_DomainScripts[instance.AppDomain].Count == 0)
549 {
550 m_DomainScripts.Remove(instance.AppDomain);
551 UnloadAppDomain(instance.AppDomain);
552 }
363 } 553 }
554
555 m_Scripts.Clear();
556 m_PrimObjects.Clear();
557 m_Assemblies.Clear();
558 m_DomainScripts.Clear();
364 } 559 }
365 lockScriptsForRead(false); 560 lockScriptsForRead(false);
366 lockScriptsForWrite(true); 561 lockScriptsForWrite(true);
@@ -403,12 +598,18 @@ namespace OpenSim.Region.ScriptEngine.XEngine
403 m_ThreadPool.QueueWorkItem(new WorkItemCallback(this.DoBackup), 598 m_ThreadPool.QueueWorkItem(new WorkItemCallback(this.DoBackup),
404 new Object[] { m_SaveTime }); 599 new Object[] { m_SaveTime });
405 } 600 }
601 }
406 602
603 public void StartProcessing()
604 {
407 m_ThreadPool.Start(); 605 m_ThreadPool.Start();
408 } 606 }
409 607
410 public void Close() 608 public void Close()
411 { 609 {
610 if (!m_Enabled)
611 return;
612
412 lock (m_ScriptEngines) 613 lock (m_ScriptEngines)
413 { 614 {
414 if (m_ScriptEngines.Contains(this)) 615 if (m_ScriptEngines.Contains(this))
@@ -455,11 +656,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
455 return 0; 656 return 0;
456 } 657 }
457 658
458 public object DoMaintenance(object p) 659 public void SaveAllState()
459 { 660 {
460 object[] parms = (object[])p;
461 int sleepTime = (int)parms[0];
462
463 foreach (IScriptInstance inst in m_Scripts.Values) 661 foreach (IScriptInstance inst in m_Scripts.Values)
464 { 662 {
465 if (inst.EventTime() > m_EventLimit) 663 if (inst.EventTime() > m_EventLimit)
@@ -469,6 +667,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
469 inst.Start(); 667 inst.Start();
470 } 668 }
471 } 669 }
670 }
671
672 public object DoMaintenance(object p)
673 {
674 object[] parms = (object[])p;
675 int sleepTime = (int)parms[0];
676
677 SaveAllState();
472 678
473 System.Threading.Thread.Sleep(sleepTime); 679 System.Threading.Thread.Sleep(sleepTime);
474 680
@@ -478,7 +684,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
478 return 0; 684 return 0;
479 } 685 }
480 686
481 public Type ReplaceableInterface 687 public Type ReplaceableInterface
482 { 688 {
483 get { return null; } 689 get { return null; }
484 } 690 }
@@ -632,7 +838,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
632 bool postOnRez = (bool)p[4]; 838 bool postOnRez = (bool)p[4];
633 StateSource stateSource = (StateSource)p[5]; 839 StateSource stateSource = (StateSource)p[5];
634 840
635 lock(m_CompileDict) 841 lock (m_CompileDict)
636 { 842 {
637 if (!m_CompileDict.ContainsKey(itemID)) 843 if (!m_CompileDict.ContainsKey(itemID))
638 return false; 844 return false;
@@ -648,7 +854,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
648 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); 854 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
649 if (part == null) 855 if (part == null)
650 { 856 {
651 m_log.Error("[Script] SceneObjectPart unavailable. Script NOT started."); 857 m_log.ErrorFormat("[Script]: SceneObjectPart with localID {0} unavailable. Script NOT started.", localID);
652 m_ScriptErrorMessage += "SceneObjectPart unavailable. Script NOT started.\n"; 858 m_ScriptErrorMessage += "SceneObjectPart unavailable. Script NOT started.\n";
653 m_ScriptFailCount++; 859 m_ScriptFailCount++;
654 return false; 860 return false;
@@ -769,8 +975,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
769 } 975 }
770 } 976 }
771 977
772
773
774 ScriptInstance instance = null; 978 ScriptInstance instance = null;
775 // Create the object record 979 // Create the object record
776 lockScriptsForRead(true); 980 lockScriptsForRead(true);
@@ -789,9 +993,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
789 try 993 try
790 { 994 {
791 AppDomainSetup appSetup = new AppDomainSetup(); 995 AppDomainSetup appSetup = new AppDomainSetup();
792 // appSetup.ApplicationBase = Path.Combine( 996 appSetup.PrivateBinPath = Path.Combine(
793 // "ScriptEngines", 997 m_ScriptEnginesPath,
794 // m_Scene.RegionInfo.RegionID.ToString()); 998 m_Scene.RegionInfo.RegionID.ToString());
795 999
796 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 1000 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
797 Evidence evidence = new Evidence(baseEvidence); 1001 Evidence evidence = new Evidence(baseEvidence);
@@ -840,8 +1044,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
840 item.Name, startParam, postOnRez, 1044 item.Name, startParam, postOnRez,
841 stateSource, m_MaxScriptQueue); 1045 stateSource, m_MaxScriptQueue);
842 1046
843 m_log.DebugFormat("[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}", 1047 m_log.DebugFormat(
844 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, part.ParentGroup.RootPart.AbsolutePosition.ToString()); 1048 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1049 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
1050 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
845 1051
846 if (presence != null) 1052 if (presence != null)
847 { 1053 {
@@ -892,9 +1098,19 @@ namespace OpenSim.Region.ScriptEngine.XEngine
892 m_CompileDict.Remove(itemID); 1098 m_CompileDict.Remove(itemID);
893 } 1099 }
894 1100
895 lock (m_Scripts) 1101 lockScriptsForRead(true);
1102 // Do we even have it?
1103 if (!m_Scripts.ContainsKey(itemID))
896 { 1104 {
1105 // Do we even have it?
1106 if (!m_Scripts.ContainsKey(itemID))
1107 return;
1108
897 lockScriptsForRead(false); 1109 lockScriptsForRead(false);
1110 lockScriptsForWrite(true);
1111 m_Scripts.Remove(itemID);
1112 lockScriptsForWrite(false);
1113
898 return; 1114 return;
899 } 1115 }
900 1116
@@ -948,7 +1164,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
948 1164
949 CleanAssemblies(); 1165 CleanAssemblies();
950 1166
951
952 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1167 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
953 if (handlerScriptRemoved != null) 1168 if (handlerScriptRemoved != null)
954 handlerScriptRemoved(itemID); 1169 handlerScriptRemoved(itemID);
@@ -1039,7 +1254,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1039 startInfo.IdleTimeout = idleTimeout*1000; // convert to seconds as stated in .ini 1254 startInfo.IdleTimeout = idleTimeout*1000; // convert to seconds as stated in .ini
1040 startInfo.MaxWorkerThreads = maxThreads; 1255 startInfo.MaxWorkerThreads = maxThreads;
1041 startInfo.MinWorkerThreads = minThreads; 1256 startInfo.MinWorkerThreads = minThreads;
1042 startInfo.ThreadPriority = threadPriority; 1257 startInfo.ThreadPriority = threadPriority;;
1043 startInfo.StackSize = stackSize; 1258 startInfo.StackSize = stackSize;
1044 startInfo.StartSuspended = true; 1259 startInfo.StartSuspended = true;
1045 1260
@@ -1068,7 +1283,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1068 1283
1069 IScriptInstance instance = (ScriptInstance) parms; 1284 IScriptInstance instance = (ScriptInstance) parms;
1070 1285
1071 //m_log.DebugFormat("[XENGINE]: Processing event for {0}", instance); 1286 //m_log.DebugFormat("[XEngine]: Processing event for {0}", instance);
1072 1287
1073 return instance.EventProcessor(); 1288 return instance.EventProcessor();
1074 } 1289 }
@@ -1082,26 +1297,34 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1082 public bool PostObjectEvent(uint localID, EventParams p) 1297 public bool PostObjectEvent(uint localID, EventParams p)
1083 { 1298 {
1084 bool result = false; 1299 bool result = false;
1085 1300 List<UUID> uuids = null;
1301
1086 lock (m_PrimObjects) 1302 lock (m_PrimObjects)
1087 { 1303 {
1088 if (!m_PrimObjects.ContainsKey(localID)) 1304 if (!m_PrimObjects.ContainsKey(localID))
1089 return false; 1305 return false;
1090 1306
1307 uuids = m_PrimObjects[localID];
1091 1308
1092 foreach (UUID itemID in m_PrimObjects[localID]) 1309
1310 foreach (UUID itemID in uuids)
1311 {
1312 IScriptInstance instance = null;
1313 try
1093 { 1314 {
1094 if (m_Scripts.ContainsKey(itemID)) 1315 if (m_Scripts.ContainsKey(itemID))
1095 { 1316 instance = m_Scripts[itemID];
1096 IScriptInstance instance = m_Scripts[itemID];
1097 if (instance != null)
1098 {
1099 instance.PostEvent(p);
1100 result = true;
1101 }
1102 }
1103 } 1317 }
1318 catch { /* ignore race conditions */ }
1319
1320 if (instance != null)
1321 {
1322 instance.PostEvent(p);
1323 result = true;
1324 }
1325 }
1104 } 1326 }
1327
1105 return result; 1328 return result;
1106 } 1329 }
1107 1330
@@ -1177,8 +1400,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1177 if (!(sender is System.AppDomain)) 1400 if (!(sender is System.AppDomain))
1178 return null; 1401 return null;
1179 1402
1180 string[] pathList = new string[] {"bin", "ScriptEngines", 1403 string[] pathList = new string[] {"bin", m_ScriptEnginesPath,
1181 Path.Combine("ScriptEngines", 1404 Path.Combine(m_ScriptEnginesPath,
1182 m_Scene.RegionInfo.RegionID.ToString())}; 1405 m_Scene.RegionInfo.RegionID.ToString())};
1183 1406
1184 string assemblyName = args.Name; 1407 string assemblyName = args.Name;
@@ -1302,6 +1525,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1302 1525
1303 public void OnShutdown() 1526 public void OnShutdown()
1304 { 1527 {
1528 m_SimulatorShuttingDown = true;
1529
1305 List<IScriptInstance> instances = new List<IScriptInstance>(); 1530 List<IScriptInstance> instances = new List<IScriptInstance>();
1306 1531
1307 lockScriptsForRead(true); 1532 lockScriptsForRead(true);
@@ -1346,16 +1571,22 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1346 } 1571 }
1347 else 1572 else
1348 { 1573 {
1349 eq.Enqueue(EventQueueHelper.ScriptRunningReplyEvent(objectID, itemID, GetScriptState(itemID), true), 1574 eq.Enqueue(eq.ScriptRunningEvent(objectID, itemID, GetScriptState(itemID), true),
1350 controllingClient.AgentId); 1575 controllingClient.AgentId);
1351 } 1576 }
1352 } 1577 }
1353 1578
1354 public string GetXMLState(UUID itemID) 1579 public string GetXMLState(UUID itemID)
1355 { 1580 {
1581// m_log.DebugFormat("[XEngine]: Getting XML state for {0}", itemID);
1582
1356 IScriptInstance instance = GetInstance(itemID); 1583 IScriptInstance instance = GetInstance(itemID);
1357 if (instance == null) 1584 if (instance == null)
1585 {
1586// m_log.DebugFormat("[XEngine]: Found no script for {0}, returning empty string", itemID);
1358 return ""; 1587 return "";
1588 }
1589
1359 string xml = instance.GetXMLState(); 1590 string xml = instance.GetXMLState();
1360 1591
1361 XmlDocument sdoc = new XmlDocument(); 1592 XmlDocument sdoc = new XmlDocument();
@@ -1364,7 +1595,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1364 { 1595 {
1365 sdoc.LoadXml(xml); 1596 sdoc.LoadXml(xml);
1366 } 1597 }
1367 catch (System.Xml.XmlException e) 1598 catch (System.Xml.XmlException)
1368 { 1599 {
1369 loadedState = false; 1600 loadedState = false;
1370 } 1601 }
@@ -1496,6 +1727,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1496 mapData.InnerText = map; 1727 mapData.InnerText = map;
1497 1728
1498 stateData.AppendChild(mapData); 1729 stateData.AppendChild(mapData);
1730
1731// m_log.DebugFormat("[XEngine]: Got XML state for {0}", itemID);
1732
1499 return doc.InnerXml; 1733 return doc.InnerXml;
1500 } 1734 }
1501 1735
@@ -1555,7 +1789,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1555 string fn = assemE.GetAttribute("Filename"); 1789 string fn = assemE.GetAttribute("Filename");
1556 string base64 = assemE.InnerText; 1790 string base64 = assemE.InnerText;
1557 1791
1558 string path = Path.Combine("ScriptEngines", World.RegionInfo.RegionID.ToString()); 1792 string path = Path.Combine(m_ScriptEnginesPath, World.RegionInfo.RegionID.ToString());
1559 path = Path.Combine(path, fn); 1793 path = Path.Combine(path, fn);
1560 1794
1561 if (!File.Exists(path)) 1795 if (!File.Exists(path))
@@ -1595,7 +1829,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1595 } 1829 }
1596 } 1830 }
1597 1831
1598 string statepath = Path.Combine("ScriptEngines", World.RegionInfo.RegionID.ToString()); 1832 string statepath = Path.Combine(m_ScriptEnginesPath, World.RegionInfo.RegionID.ToString());
1599 statepath = Path.Combine(statepath, itemID.ToString() + ".state"); 1833 statepath = Path.Combine(statepath, itemID.ToString() + ".state");
1600 1834
1601 try 1835 try
@@ -1621,7 +1855,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1621 { 1855 {
1622 XmlElement mapE = (XmlElement)mapL[0]; 1856 XmlElement mapE = (XmlElement)mapL[0];
1623 1857
1624 string mappath = Path.Combine("ScriptEngines", World.RegionInfo.RegionID.ToString()); 1858 string mappath = Path.Combine(m_ScriptEnginesPath, World.RegionInfo.RegionID.ToString());
1625 mappath = Path.Combine(mappath, mapE.GetAttribute("Filename")); 1859 mappath = Path.Combine(mappath, mapE.GetAttribute("Filename"));
1626 1860
1627 try 1861 try
@@ -1661,5 +1895,31 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1661 return new ArrayList(); 1895 return new ArrayList();
1662 } 1896 }
1663 } 1897 }
1898
1899 public void SuspendScript(UUID itemID)
1900 {
1901 IScriptInstance instance = GetInstance(itemID);
1902 if (instance != null)
1903 instance.Suspend();
1904 }
1905
1906 public void ResumeScript(UUID itemID)
1907 {
1908 IScriptInstance instance = GetInstance(itemID);
1909 if (instance != null)
1910 instance.Resume();
1911 }
1912
1913 public bool HasScript(UUID itemID, out bool running)
1914 {
1915 running = true;
1916
1917 IScriptInstance instance = GetInstance(itemID);
1918 if (instance == null)
1919 return false;
1920
1921 running = instance.Running;
1922 return true;
1923 }
1664 } 1924 }
1665} 1925}