aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs35
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs6
-rw-r--r--OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs79
-rw-r--r--OpenSim/Region/Framework/Interfaces/IHttpRequests.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs7
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs158
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs13
7 files changed, 216 insertions, 85 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 9d7b44b..5d72af8 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -301,10 +301,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
301 301
302 // If we're an NPC then skip all the item checks and manipulations since we don't have an 302 // If we're an NPC then skip all the item checks and manipulations since we don't have an
303 // inventory right now. 303 // inventory right now.
304 if (sp.PresenceType == PresenceType.Npc) 304 RezSingleAttachmentFromInventoryInternal(sp, sp.PresenceType == PresenceType.Npc ? UUID.Zero : attach.ItemID, attach.AssetID, p | (uint)0x80, null);
305 RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null, true);
306 else
307 RezSingleAttachmentFromInventory(sp, attach.ItemID, p | (uint)0x80, d);
308 } 305 }
309 catch (Exception e) 306 catch (Exception e)
310 { 307 {
@@ -519,26 +516,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
519 "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2} in {3}", 516 "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2} in {3}",
520 (AttachmentPoint)AttachmentPt, itemID, sp.Name, m_scene.Name); 517 (AttachmentPoint)AttachmentPt, itemID, sp.Name, m_scene.Name);
521 518
522 bool append = (AttachmentPt & 0x80) != 0; 519 // We check the attachments in the avatar appearance here rather than the objects attached to the
523 AttachmentPt &= 0x7f; 520 // ScenePresence itself so that we can ignore calls by viewer 2/3 to attach objects on startup. We are
524 521 // already doing this in ScenePresence.MakeRootAgent(). Simulator-side attaching needs to be done
525 // Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such). 522 // because pre-outfit folder viewers (most version 1 viewers) require it.
526 // This often happens during login - not sure the exact reason.
527 // For now, we will ignore the request. Unfortunately, this means that we need to dig through all the
528 // ScenePresence attachments. We can't use the data in AvatarAppearance because that's present at login
529 // before anything has actually been attached.
530 bool alreadyOn = false; 523 bool alreadyOn = false;
531 List<SceneObjectGroup> existingAttachments = sp.GetAttachments(); 524 List<AvatarAttachment> existingAttachments = sp.Appearance.GetAttachments();
532 foreach (SceneObjectGroup so in existingAttachments) 525 foreach (AvatarAttachment existingAttachment in existingAttachments)
533 { 526 {
534 if (so.FromItemID == itemID) 527 if (existingAttachment.ItemID == itemID)
535 { 528 {
536 alreadyOn = true; 529 alreadyOn = true;
537 break; 530 break;
538 } 531 }
539 } 532 }
540 533
541// if (sp.Appearance.GetAttachmentForItem(itemID) != null)
542 if (alreadyOn) 534 if (alreadyOn)
543 { 535 {
544 if (DebugLevel > 0) 536 if (DebugLevel > 0)
@@ -549,7 +541,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
549 return null; 541 return null;
550 } 542 }
551 543
552 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc, append); 544 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc);
553 } 545 }
554 546
555 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) 547 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist)
@@ -558,7 +550,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
558 return; 550 return;
559 551
560 if (DebugLevel > 0) 552 if (DebugLevel > 0)
561 m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); 553 m_log.DebugFormat(
554 "[ATTACHMENTS MODULE]: Rezzing {0} attachments from inventory for {1} in {2}",
555 rezlist.Count, sp.Name, m_scene.Name);
562 556
563 foreach (KeyValuePair<UUID, uint> rez in rezlist) 557 foreach (KeyValuePair<UUID, uint> rez in rezlist)
564 { 558 {
@@ -957,11 +951,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
957 } 951 }
958 952
959 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 953 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
960 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc, bool append) 954 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc)
961 { 955 {
962 if (m_invAccessModule == null) 956 if (m_invAccessModule == null)
963 return null; 957 return null;
964 958
959 bool append = (attachmentPt & 0x80) != 0;
960 attachmentPt &= 0x7f;
961
965 SceneObjectGroup objatt; 962 SceneObjectGroup objatt;
966 963
967 if (itemID != UUID.Zero) 964 if (itemID != UUID.Zero)
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index cfe5538..1a38619 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -130,7 +130,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
130 config.AddConfig("Modules"); 130 config.AddConfig("Modules");
131 config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); 131 config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
132 132
133 modules.Add(new AttachmentsModule()); 133 AttachmentsModule attMod = new AttachmentsModule();
134 attMod.DebugLevel = 1;
135 modules.Add(attMod);
134 modules.Add(new BasicInventoryAccessModule()); 136 modules.Add(new BasicInventoryAccessModule());
135 } 137 }
136 138
@@ -728,7 +730,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
728 public void TestRezAttachmentsOnAvatarEntrance() 730 public void TestRezAttachmentsOnAvatarEntrance()
729 { 731 {
730 TestHelpers.InMethod(); 732 TestHelpers.InMethod();
731// log4net.Config.XmlConfigurator.Configure(); 733// TestHelpers.EnableLogging();
732 734
733 Scene scene = CreateTestScene(); 735 Scene scene = CreateTestScene();
734 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); 736 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
index 0276267..2b13a8b 100644
--- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
@@ -189,6 +189,45 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
189 case (int)HttpRequestConstants.HTTP_VERIFY_CERT: 189 case (int)HttpRequestConstants.HTTP_VERIFY_CERT:
190 htc.HttpVerifyCert = (int.Parse(parms[i + 1]) != 0); 190 htc.HttpVerifyCert = (int.Parse(parms[i + 1]) != 0);
191 break; 191 break;
192
193 case (int)HttpRequestConstants.HTTP_VERBOSE_THROTTLE:
194
195 // TODO implement me
196 break;
197
198 case (int)HttpRequestConstants.HTTP_CUSTOM_HEADER:
199 //Parameters are in pairs and custom header takes
200 //arguments in pairs so adjust for header marker.
201 ++i;
202
203 //Maximum of 8 headers are allowed based on the
204 //Second Life documentation for llHTTPRequest.
205 for (int count = 1; count <= 8; ++count)
206 {
207 //Not enough parameters remaining for a header?
208 if (parms.Length - i < 2)
209 break;
210
211 //Have we reached the end of the list of headers?
212 //End is marked by a string with a single digit.
213 //We already know we have at least one parameter
214 //so it is safe to do this check at top of loop.
215 if (Char.IsDigit(parms[i][0]))
216 break;
217
218 if (htc.HttpCustomHeaders == null)
219 htc.HttpCustomHeaders = new List<string>();
220
221 htc.HttpCustomHeaders.Add(parms[i]);
222 htc.HttpCustomHeaders.Add(parms[i+1]);
223
224 i += 2;
225 }
226 break;
227
228 case (int)HttpRequestConstants.HTTP_PRAGMA_NO_CACHE:
229 htc.HttpPragmaNoCache = (int.Parse(parms[i + 1]) != 0);
230 break;
192 } 231 }
193 } 232 }
194 } 233 }
@@ -353,9 +392,12 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
353 // public const int HTTP_METHOD = 0; 392 // public const int HTTP_METHOD = 0;
354 // public const int HTTP_MIMETYPE = 1; 393 // public const int HTTP_MIMETYPE = 1;
355 // public const int HTTP_VERIFY_CERT = 3; 394 // public const int HTTP_VERIFY_CERT = 3;
395 // public const int HTTP_VERBOSE_THROTTLE = 4;
396 // public const int HTTP_CUSTOM_HEADER = 5;
397 // public const int HTTP_PRAGMA_NO_CACHE = 6;
356 private bool _finished; 398 private bool _finished;
357 public bool Finished 399 public bool Finished
358 { 400 {
359 get { return _finished; } 401 get { return _finished; }
360 } 402 }
361 // public int HttpBodyMaxLen = 2048; // not implemented 403 // public int HttpBodyMaxLen = 2048; // not implemented
@@ -367,9 +409,14 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
367 public bool HttpVerifyCert = true; 409 public bool HttpVerifyCert = true;
368 public IWorkItemResult WorkItem = null; 410 public IWorkItemResult WorkItem = null;
369 411
412 //public bool HttpVerboseThrottle = true; // not implemented
413 public List<string> HttpCustomHeaders = null;
414 public bool HttpPragmaNoCache = true;
415 private Thread httpThread;
416
370 // Request info 417 // Request info
371 private UUID _itemID; 418 private UUID _itemID;
372 public UUID ItemID 419 public UUID ItemID
373 { 420 {
374 get { return _itemID; } 421 get { return _itemID; }
375 set { _itemID = value; } 422 set { _itemID = value; }
@@ -385,7 +432,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
385 public string proxyexcepts; 432 public string proxyexcepts;
386 public string OutboundBody; 433 public string OutboundBody;
387 private UUID _reqID; 434 private UUID _reqID;
388 public UUID ReqID 435 public UUID ReqID
389 { 436 {
390 get { return _reqID; } 437 get { return _reqID; }
391 set { _reqID = value; } 438 set { _reqID = value; }
@@ -434,20 +481,34 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
434 Request.Method = HttpMethod; 481 Request.Method = HttpMethod;
435 Request.ContentType = HttpMIMEType; 482 Request.ContentType = HttpMIMEType;
436 483
437 if(!HttpVerifyCert) 484 if (!HttpVerifyCert)
438 { 485 {
439 // We could hijack Connection Group Name to identify 486 // We could hijack Connection Group Name to identify
440 // a desired security exception. But at the moment we'll use a dummy header instead. 487 // a desired security exception. But at the moment we'll use a dummy header instead.
441 Request.Headers.Add("NoVerifyCert", "true"); 488 Request.Headers.Add("NoVerifyCert", "true");
442 } 489 }
443 if (proxyurl != null && proxyurl.Length > 0) 490// else
491// {
492// Request.ConnectionGroupName="Verify";
493// }
494 if (!HttpPragmaNoCache)
495 {
496 Request.Headers.Add("Pragma", "no-cache");
497 }
498 if (HttpCustomHeaders != null)
444 { 499 {
445 if (proxyexcepts != null && proxyexcepts.Length > 0) 500 for (int i = 0; i < HttpCustomHeaders.Count; i += 2)
501 Request.Headers.Add(HttpCustomHeaders[i],
502 HttpCustomHeaders[i+1]);
503 }
504 if (proxyurl != null && proxyurl.Length > 0)
505 {
506 if (proxyexcepts != null && proxyexcepts.Length > 0)
446 { 507 {
447 string[] elist = proxyexcepts.Split(';'); 508 string[] elist = proxyexcepts.Split(';');
448 Request.Proxy = new WebProxy(proxyurl, true, elist); 509 Request.Proxy = new WebProxy(proxyurl, true, elist);
449 } 510 }
450 else 511 else
451 { 512 {
452 Request.Proxy = new WebProxy(proxyurl, true); 513 Request.Proxy = new WebProxy(proxyurl, true);
453 } 514 }
@@ -460,7 +521,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
460 Request.Headers[entry.Key] = entry.Value; 521 Request.Headers[entry.Key] = entry.Value;
461 522
462 // Encode outbound data 523 // Encode outbound data
463 if (OutboundBody.Length > 0) 524 if (OutboundBody.Length > 0)
464 { 525 {
465 byte[] data = Util.UTF8.GetBytes(OutboundBody); 526 byte[] data = Util.UTF8.GetBytes(OutboundBody);
466 527
diff --git a/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs b/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs
index de0f2a3..eb6c5ac 100644
--- a/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs
+++ b/OpenSim/Region/Framework/Interfaces/IHttpRequests.cs
@@ -36,6 +36,9 @@ namespace OpenSim.Region.Framework.Interfaces
36 HTTP_MIMETYPE = 1, 36 HTTP_MIMETYPE = 1,
37 HTTP_BODY_MAXLENGTH = 2, 37 HTTP_BODY_MAXLENGTH = 2,
38 HTTP_VERIFY_CERT = 3, 38 HTTP_VERIFY_CERT = 3,
39 HTTP_VERBOSE_THROTTLE = 4,
40 HTTP_CUSTOM_HEADER = 5,
41 HTTP_PRAGMA_NO_CACHE = 6
39 } 42 }
40 43
41 public interface IHttpRequestModule 44 public interface IHttpRequestModule
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index f01a916..0ab267a 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1100,15 +1100,12 @@ namespace OpenSim.Region.Framework.Scenes
1100 { 1100 {
1101 // Viewers which have a current outfit folder will actually rez their own attachments. However, 1101 // Viewers which have a current outfit folder will actually rez their own attachments. However,
1102 // viewers without (e.g. v1 viewers) will not, so we still need to make this call. 1102 // viewers without (e.g. v1 viewers) will not, so we still need to make this call.
1103 //
1104 // However, we leave a 5 second pause to try and avoid a clash with viewers that are rezzing
1105 // attachments themselves. This should then mean that this call ends up doing nothing.
1106 if (Scene.AttachmentsModule != null) 1103 if (Scene.AttachmentsModule != null)
1107 Util.FireAndForget( 1104 Util.FireAndForget(
1108 o => 1105 o =>
1109 { 1106 {
1110 if (PresenceType != PresenceType.Npc && Util.FireAndForgetMethod != FireAndForgetMethod.None) 1107// if (PresenceType != PresenceType.Npc && Util.FireAndForgetMethod != FireAndForgetMethod.None)
1111 System.Threading.Thread.Sleep(5000); 1108// System.Threading.Thread.Sleep(7000);
1112 1109
1113 Scene.AttachmentsModule.RezAttachments(this); 1110 Scene.AttachmentsModule.RezAttachments(this);
1114 }); 1111 });
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index f677cdf..bc35272 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -71,6 +71,7 @@ using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
71using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 71using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
72using System.Reflection; 72using System.Reflection;
73using Timer = System.Timers.Timer; 73using Timer = System.Timers.Timer;
74using System.Linq;
74using PermissionMask = OpenSim.Framework.PermissionMask; 75using PermissionMask = OpenSim.Framework.PermissionMask;
75 76
76namespace OpenSim.Region.ScriptEngine.Shared.Api 77namespace OpenSim.Region.ScriptEngine.Shared.Api
@@ -96,8 +97,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
96 /// <summary> 97 /// <summary>
97 /// Used for script sleeps when we are using co-operative script termination. 98 /// Used for script sleeps when we are using co-operative script termination.
98 /// </summary> 99 /// </summary>
99 /// <remarks>null if co-operative script termination is not active</remarks> 100 /// <remarks>null if co-operative script termination is not active</remarks>
100 WaitHandle m_coopSleepHandle; 101 WaitHandle m_coopSleepHandle;
101 102
102 /// <summary> 103 /// <summary>
103 /// The item that hosts this script 104 /// The item that hosts this script
@@ -150,6 +151,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
150 {"TURNLEFT", "Turning Left"}, 151 {"TURNLEFT", "Turning Left"},
151 {"TURNRIGHT", "Turning Right"} 152 {"TURNRIGHT", "Turning Right"}
152 }; 153 };
154 //An array of HTTP/1.1 headers that are not allowed to be used
155 //as custom headers by llHTTPRequest.
156 private string[] HttpStandardHeaders =
157 {
158 "Accept", "Accept-Charset", "Accept-Encoding", "Accept-Language",
159 "Accept-Ranges", "Age", "Allow", "Authorization", "Cache-Control",
160 "Connection", "Content-Encoding", "Content-Language",
161 "Content-Length", "Content-Location", "Content-MD5",
162 "Content-Range", "Content-Type", "Date", "ETag", "Expect",
163 "Expires", "From", "Host", "If-Match", "If-Modified-Since",
164 "If-None-Match", "If-Range", "If-Unmodified-Since", "Last-Modified",
165 "Location", "Max-Forwards", "Pragma", "Proxy-Authenticate",
166 "Proxy-Authorization", "Range", "Referer", "Retry-After", "Server",
167 "TE", "Trailer", "Transfer-Encoding", "Upgrade", "User-Agent",
168 "Vary", "Via", "Warning", "WWW-Authenticate"
169 };
153 170
154 public void Initialize( 171 public void Initialize(
155 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) 172 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
@@ -391,7 +408,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
391 /// If the linkset has more than one entity and a linknum greater than zero but equal to or less than the number 408 /// If the linkset has more than one entity and a linknum greater than zero but equal to or less than the number
392 /// of entities, then the entity which corresponds to that linknum is returned. 409 /// of entities, then the entity which corresponds to that linknum is returned.
393 /// Otherwise, if a positive linknum is given which is greater than the number of entities in the linkset, then 410 /// Otherwise, if a positive linknum is given which is greater than the number of entities in the linkset, then
394 /// null is returned. 411 /// null is returned.
395 /// </param> 412 /// </param>
396 public ISceneEntity GetLinkEntity(int linknum) 413 public ISceneEntity GetLinkEntity(int linknum)
397 { 414 {
@@ -1750,7 +1767,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1750 if (tex.FaceTextures[i] != null) 1767 if (tex.FaceTextures[i] != null)
1751 { 1768 {
1752 tex.FaceTextures[i].Shiny = sval; 1769 tex.FaceTextures[i].Shiny = sval;
1753 tex.FaceTextures[i].Bump = bump;; 1770 tex.FaceTextures[i].Bump = bump;
1754 } 1771 }
1755 tex.DefaultTexture.Shiny = sval; 1772 tex.DefaultTexture.Shiny = sval;
1756 tex.DefaultTexture.Bump = bump; 1773 tex.DefaultTexture.Bump = bump;
@@ -1873,7 +1890,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1873 texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f); 1890 texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f);
1874 tex.DefaultTexture.RGBA = texcolor; 1891 tex.DefaultTexture.RGBA = texcolor;
1875 } 1892 }
1876 1893
1877 part.UpdateTextureEntry(tex.GetBytes()); 1894 part.UpdateTextureEntry(tex.GetBytes());
1878 return; 1895 return;
1879 } 1896 }
@@ -1996,7 +2013,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1996 rgb.x = texcolor.R; 2013 rgb.x = texcolor.R;
1997 rgb.y = texcolor.G; 2014 rgb.y = texcolor.G;
1998 rgb.z = texcolor.B; 2015 rgb.z = texcolor.B;
1999 2016
2000 return rgb; 2017 return rgb;
2001 } 2018 }
2002 else 2019 else
@@ -2038,12 +2055,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2038 2055
2039 UUID textureID = new UUID(); 2056 UUID textureID = new UUID();
2040 2057
2041 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); 2058 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture);
2042 if (textureID == UUID.Zero) 2059 if (textureID == UUID.Zero)
2043 { 2060 {
2044 if (!UUID.TryParse(texture, out textureID)) 2061 if (!UUID.TryParse(texture, out textureID))
2045 return; 2062 return;
2046 } 2063 }
2047 2064
2048 Primitive.TextureEntry tex = part.Shape.Textures; 2065 Primitive.TextureEntry tex = part.Shape.Textures;
2049 2066
@@ -2249,7 +2266,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2249 // IF YOU GET REGION CROSSINGS WORKING WITH THIS FUNCTION, REPLACE THE WORKAROUND. 2266 // IF YOU GET REGION CROSSINGS WORKING WITH THIS FUNCTION, REPLACE THE WORKAROUND.
2250 // 2267 //
2251 // This workaround is to prevent silent failure of this function. 2268 // This workaround is to prevent silent failure of this function.
2252 // According to the specification on the SL Wiki, providing a position outside of the 2269 // According to the specification on the SL Wiki, providing a position outside of the
2253 if (pos.x < 0 || pos.x > Constants.RegionSize || pos.y < 0 || pos.y > Constants.RegionSize) 2270 if (pos.x < 0 || pos.x > Constants.RegionSize || pos.y < 0 || pos.y > Constants.RegionSize)
2254 { 2271 {
2255 return 0; 2272 return 0;
@@ -2484,7 +2501,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2484 { 2501 {
2485 return llGetRootRotation(); 2502 return llGetRootRotation();
2486 } 2503 }
2487 2504
2488 m_host.AddScriptLPS(1); 2505 m_host.AddScriptLPS(1);
2489 Quaternion q = m_host.GetWorldRotation(); 2506 Quaternion q = m_host.GetWorldRotation();
2490 2507
@@ -3317,7 +3334,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3317 3334
3318 if (!UUID.TryParse(id, out objectID)) 3335 if (!UUID.TryParse(id, out objectID))
3319 objectID = UUID.Zero; 3336 objectID = UUID.Zero;
3320 3337
3321 if (objectID == UUID.Zero && name == "") 3338 if (objectID == UUID.Zero && name == "")
3322 return; 3339 return;
3323 3340
@@ -3527,19 +3544,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3527 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3544 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid;
3528 3545
3529 Vector3 pos = m_host.AbsolutePosition; 3546 Vector3 pos = m_host.AbsolutePosition;
3530 msg.binaryBucket 3547 msg.binaryBucket
3531 = Util.StringToBytes256( 3548 = Util.StringToBytes256(
3532 "{0}/{1}/{2}/{3}", 3549 "{0}/{1}/{2}/{3}",
3533 World.RegionInfo.RegionName, 3550 World.RegionInfo.RegionName,
3534 (int)Math.Floor(pos.X), 3551 (int)Math.Floor(pos.X),
3535 (int)Math.Floor(pos.Y), 3552 (int)Math.Floor(pos.Y),
3536 (int)Math.Floor(pos.Z)); 3553 (int)Math.Floor(pos.Z));
3537 3554
3538 if (m_TransferModule != null) 3555 if (m_TransferModule != null)
3539 { 3556 {
3540 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 3557 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
3541 } 3558 }
3542 3559
3543 ScriptSleep(2000); 3560 ScriptSleep(2000);
3544 } 3561 }
3545 3562
@@ -3664,7 +3681,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3664 public void llRotLookAt(LSL_Rotation target, double strength, double damping) 3681 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3665 { 3682 {
3666 m_host.AddScriptLPS(1); 3683 m_host.AddScriptLPS(1);
3667 3684
3668 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply 3685 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
3669 // set the rotation of the object, copy that behavior 3686 // set the rotation of the object, copy that behavior
3670 PhysicsActor pa = m_host.PhysActor; 3687 PhysicsActor pa = m_host.PhysActor;
@@ -5458,7 +5475,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5458 // SL spits out an empty string for types other than key & string 5475 // SL spits out an empty string for types other than key & string
5459 // At the time of patching, LSL_Key is currently LSL_String, 5476 // At the time of patching, LSL_Key is currently LSL_String,
5460 // so the OR check may be a little redundant, but it's being done 5477 // so the OR check may be a little redundant, but it's being done
5461 // for completion and should LSL_Key ever be implemented 5478 // for completion and should LSL_Key ever be implemented
5462 // as it's own struct 5479 // as it's own struct
5463 else if (!(src.Data[index] is LSL_String || 5480 else if (!(src.Data[index] is LSL_String ||
5464 src.Data[index] is LSL_Key || 5481 src.Data[index] is LSL_Key ||
@@ -5595,8 +5612,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5595 { 5612 {
5596 m_host.AddScriptLPS(1); 5613 m_host.AddScriptLPS(1);
5597 5614
5598 return string.Join(", ", 5615 return string.Join(", ",
5599 (new List<object>(src.Data)).ConvertAll<string>(o => 5616 (new List<object>(src.Data)).ConvertAll<string>(o =>
5600 { 5617 {
5601 return o.ToString(); 5618 return o.ToString();
5602 }).ToArray()); 5619 }).ToArray());
@@ -6700,7 +6717,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6700 SetParticleSystem(m_host, rules); 6717 SetParticleSystem(m_host, rules);
6701 } 6718 }
6702 6719
6703 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) 6720 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6704 { 6721 {
6705 if (rules.Length == 0) 6722 if (rules.Length == 0)
6706 { 6723 {
@@ -6937,7 +6954,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6937 m_host.OwnerID, m_host.Name, destID, 6954 m_host.OwnerID, m_host.Name, destID,
6938 (byte)InstantMessageDialog.TaskInventoryOffered, 6955 (byte)InstantMessageDialog.TaskInventoryOffered,
6939 false, string.Format("'{0}'", category), 6956 false, string.Format("'{0}'", category),
6940// We won't go so far as to add a SLURL, but this is the format used by LL as of 2012-10-06 6957// We won't go so far as to add a SLURL, but this is the format used by LL as of 2012-10-06
6941// false, string.Format("'{0}' ( http://slurl.com/secondlife/{1}/{2}/{3}/{4} )", category, World.Name, (int)pos.X, (int)pos.Y, (int)pos.Z), 6958// false, string.Format("'{0}' ( http://slurl.com/secondlife/{1}/{2}/{3}/{4} )", category, World.Name, (int)pos.X, (int)pos.Y, (int)pos.Z),
6942 folderID, false, pos, 6959 folderID, false, pos,
6943 bucket, false); 6960 bucket, false);
@@ -7056,12 +7073,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7056 public LSL_String llAvatarOnLinkSitTarget(int linknum) 7073 public LSL_String llAvatarOnLinkSitTarget(int linknum)
7057 { 7074 {
7058 m_host.AddScriptLPS(1); 7075 m_host.AddScriptLPS(1);
7059 if(linknum == ScriptBaseClass.LINK_SET || 7076 if(linknum == ScriptBaseClass.LINK_SET ||
7060 linknum == ScriptBaseClass.LINK_ALL_CHILDREN || 7077 linknum == ScriptBaseClass.LINK_ALL_CHILDREN ||
7061 linknum == ScriptBaseClass.LINK_ALL_OTHERS) return UUID.Zero.ToString(); 7078 linknum == ScriptBaseClass.LINK_ALL_OTHERS) return UUID.Zero.ToString();
7062 7079
7063 List<SceneObjectPart> parts = GetLinkParts(linknum); 7080 List<SceneObjectPart> parts = GetLinkParts(linknum);
7064 if (parts.Count == 0) return UUID.Zero.ToString(); 7081 if (parts.Count == 0) return UUID.Zero.ToString();
7065 return parts[0].SitTargetAvatar.ToString(); 7082 return parts[0].SitTargetAvatar.ToString();
7066 } 7083 }
7067 7084
@@ -7451,7 +7468,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7451 hollow = 0.70f; 7468 hollow = 0.70f;
7452 } 7469 }
7453 } 7470 }
7454 // Otherwise, hollow is limited to 95%. 7471 // Otherwise, hollow is limited to 95%.
7455 else 7472 else
7456 { 7473 {
7457 if (hollow > 0.95f) 7474 if (hollow > 0.95f)
@@ -8906,16 +8923,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8906 res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0)); 8923 res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0));
8907 8924
8908 // float revolutions 8925 // float revolutions
8909 res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d); 8926 res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d);
8910 // Slightly inaccurate, because an unsigned byte is being used to represent 8927 // Slightly inaccurate, because an unsigned byte is being used to represent
8911 // the entire range of floating-point values from 1.0 through 4.0 (which is how 8928 // the entire range of floating-point values from 1.0 through 4.0 (which is how
8912 // SL does it). 8929 // SL does it).
8913 // 8930 //
8914 // Using these formulas to store and retrieve PathRevolutions, it is not 8931 // Using these formulas to store and retrieve PathRevolutions, it is not
8915 // possible to use all values between 1.00 and 4.00. For instance, you can't 8932 // possible to use all values between 1.00 and 4.00. For instance, you can't
8916 // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you 8933 // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you
8917 // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them 8934 // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them
8918 // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar 8935 // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar
8919 // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11. 8936 // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11.
8920 // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value 8937 // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value
8921 // such as 1.10. So, SL must store and retreive the actual user input rather 8938 // such as 1.10. So, SL must store and retreive the actual user input rather
@@ -9199,7 +9216,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9199 case (int)ScriptBaseClass.PRIM_DESC: 9216 case (int)ScriptBaseClass.PRIM_DESC:
9200 res.Add(new LSL_String(part.Description)); 9217 res.Add(new LSL_String(part.Description));
9201 break; 9218 break;
9202 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9219 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
9203 res.Add(new LSL_Rotation(part.RotationOffset)); 9220 res.Add(new LSL_Rotation(part.RotationOffset));
9204 break; 9221 break;
9205 9222
@@ -11127,9 +11144,60 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11127 IHttpRequestModule httpScriptMod = 11144 IHttpRequestModule httpScriptMod =
11128 m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>(); 11145 m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>();
11129 List<string> param = new List<string>(); 11146 List<string> param = new List<string>();
11130 foreach (object o in parameters.Data) 11147 bool ok;
11148 Int32 flag;
11149
11150 for (int i = 0; i < parameters.Data.Length; i += 2)
11131 { 11151 {
11132 param.Add(o.ToString()); 11152 ok = Int32.TryParse(parameters.Data[i].ToString(), out flag);
11153 if (!ok || flag < 0 ||
11154 flag > (int)HttpRequestConstants.HTTP_PRAGMA_NO_CACHE)
11155 {
11156 throw new ScriptException("Parameter " + i.ToString() + " is an invalid flag");
11157 }
11158
11159 param.Add(parameters.Data[i].ToString()); //Add parameter flag
11160
11161 if (flag != (int)HttpRequestConstants.HTTP_CUSTOM_HEADER)
11162 {
11163 param.Add(parameters.Data[i+1].ToString()); //Add parameter value
11164 }
11165 else
11166 {
11167 //Parameters are in pairs and custom header takes
11168 //arguments in pairs so adjust for header marker.
11169 ++i;
11170
11171 //Maximum of 8 headers are allowed based on the
11172 //Second Life documentation for llHTTPRequest.
11173 for (int count = 1; count <= 8; ++count)
11174 {
11175 //Enough parameters remaining for (another) header?
11176 if (parameters.Data.Length - i < 2)
11177 {
11178 //There must be at least one name/value pair for custom header
11179 if (count == 1)
11180 throw new ScriptException("Missing name/value for custom header at parameter " + i.ToString());
11181 break;
11182 }
11183
11184 if (HttpStandardHeaders.Contains(parameters.Data[i].ToString(), StringComparer.OrdinalIgnoreCase))
11185 throw new ScriptException("Name is invalid as a custom header at parameter " + i.ToString());
11186
11187 param.Add(parameters.Data[i].ToString());
11188 param.Add(parameters.Data[i+1].ToString());
11189
11190 //Have we reached the end of the list of headers?
11191 //End is marked by a string with a single digit.
11192 if (i+2 >= parameters.Data.Length ||
11193 Char.IsDigit(parameters.Data[i].ToString()[0]))
11194 {
11195 break;
11196 }
11197
11198 i += 2;
11199 }
11200 }
11133 } 11201 }
11134 11202
11135 Vector3 position = m_host.AbsolutePosition; 11203 Vector3 position = m_host.AbsolutePosition;
@@ -11295,12 +11363,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11295 public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide) 11363 public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide)
11296 { 11364 {
11297 m_host.AddScriptLPS(1); 11365 m_host.AddScriptLPS(1);
11298 11366
11299 ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); 11367 ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y);
11300 11368
11301 if (lo == null) 11369 if (lo == null)
11302 return 0; 11370 return 0;
11303 11371
11304 IPrimCounts pc = lo.PrimCounts; 11372 IPrimCounts pc = lo.PrimCounts;
11305 11373
11306 if (sim_wide != ScriptBaseClass.FALSE) 11374 if (sim_wide != ScriptBaseClass.FALSE)
@@ -11330,7 +11398,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11330 else if (category == ScriptBaseClass.PARCEL_COUNT_TEMP) 11398 else if (category == ScriptBaseClass.PARCEL_COUNT_TEMP)
11331 return 0; // counts not implemented yet 11399 return 0; // counts not implemented yet
11332 } 11400 }
11333 11401
11334 return 0; 11402 return 0;
11335 } 11403 }
11336 11404
@@ -11691,7 +11759,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11691 return ret; 11759 return ret;
11692 } 11760 }
11693 } 11761 }
11694 11762
11695 return new LSL_List(); 11763 return new LSL_List();
11696 } 11764 }
11697 11765
@@ -12071,7 +12139,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12071// Vector3 bc = group.AbsolutePosition - rayEnd; 12139// Vector3 bc = group.AbsolutePosition - rayEnd;
12072 12140
12073 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); 12141 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
12074 12142
12075 // Too far off ray, don't bother 12143 // Too far off ray, don't bother
12076 if (d > radius) 12144 if (d > radius)
12077 return; 12145 return;
@@ -12434,7 +12502,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12434 else 12502 else
12435 { 12503 {
12436 ScenePresence sp = World.GetScenePresence(result.ConsumerID); 12504 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
12437 /// It it a boy? a girl? 12505 /// It it a boy? a girl?
12438 if (sp != null) 12506 if (sp != null)
12439 itemID = sp.UUID; 12507 itemID = sp.UUID;
12440 } 12508 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index da3b31f..2f8154d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -356,6 +356,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
356 public const int HTTP_MIMETYPE = 1; 356 public const int HTTP_MIMETYPE = 1;
357 public const int HTTP_BODY_MAXLENGTH = 2; 357 public const int HTTP_BODY_MAXLENGTH = 2;
358 public const int HTTP_VERIFY_CERT = 3; 358 public const int HTTP_VERIFY_CERT = 3;
359 public const int HTTP_VERBOSE_THROTTLE = 4;
360 public const int HTTP_CUSTOM_HEADER = 5;
361 public const int HTTP_PRAGMA_NO_CACHE = 6;
359 362
360 public const int PRIM_MATERIAL = 2; 363 public const int PRIM_MATERIAL = 2;
361 public const int PRIM_PHYSICS = 3; 364 public const int PRIM_PHYSICS = 3;
@@ -636,7 +639,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
636 public const int TOUCH_INVALID_FACE = -1; 639 public const int TOUCH_INVALID_FACE = -1;
637 public static readonly vector TOUCH_INVALID_TEXCOORD = new vector(-1.0, -1.0, 0.0); 640 public static readonly vector TOUCH_INVALID_TEXCOORD = new vector(-1.0, -1.0, 0.0);
638 public static readonly vector TOUCH_INVALID_VECTOR = ZERO_VECTOR; 641 public static readonly vector TOUCH_INVALID_VECTOR = ZERO_VECTOR;
639 642
640 // constants for llGetPrimMediaParams/llSetPrimMediaParams 643 // constants for llGetPrimMediaParams/llSetPrimMediaParams
641 public const int PRIM_MEDIA_ALT_IMAGE_ENABLE = 0; 644 public const int PRIM_MEDIA_ALT_IMAGE_ENABLE = 0;
642 public const int PRIM_MEDIA_CONTROLS = 1; 645 public const int PRIM_MEDIA_CONTROLS = 1;
@@ -653,10 +656,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
653 public const int PRIM_MEDIA_WHITELIST = 12; 656 public const int PRIM_MEDIA_WHITELIST = 12;
654 public const int PRIM_MEDIA_PERMS_INTERACT = 13; 657 public const int PRIM_MEDIA_PERMS_INTERACT = 13;
655 public const int PRIM_MEDIA_PERMS_CONTROL = 14; 658 public const int PRIM_MEDIA_PERMS_CONTROL = 14;
656 659
657 public const int PRIM_MEDIA_CONTROLS_STANDARD = 0; 660 public const int PRIM_MEDIA_CONTROLS_STANDARD = 0;
658 public const int PRIM_MEDIA_CONTROLS_MINI = 1; 661 public const int PRIM_MEDIA_CONTROLS_MINI = 1;
659 662
660 public const int PRIM_MEDIA_PERM_NONE = 0; 663 public const int PRIM_MEDIA_PERM_NONE = 0;
661 public const int PRIM_MEDIA_PERM_OWNER = 1; 664 public const int PRIM_MEDIA_PERM_OWNER = 1;
662 public const int PRIM_MEDIA_PERM_GROUP = 2; 665 public const int PRIM_MEDIA_PERM_GROUP = 2;
@@ -689,7 +692,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
689 public const string TEXTURE_PLYWOOD = "89556747-24cb-43ed-920b-47caed15465f"; 692 public const string TEXTURE_PLYWOOD = "89556747-24cb-43ed-920b-47caed15465f";
690 public const string TEXTURE_TRANSPARENT = "8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"; 693 public const string TEXTURE_TRANSPARENT = "8dcd4a48-2d37-4909-9f78-f7a9eb4ef903";
691 public const string TEXTURE_MEDIA = "8b5fec65-8d8d-9dc5-cda8-8fdf2716e361"; 694 public const string TEXTURE_MEDIA = "8b5fec65-8d8d-9dc5-cda8-8fdf2716e361";
692 695
693 // Constants for osGetRegionStats 696 // Constants for osGetRegionStats
694 public const int STATS_TIME_DILATION = 0; 697 public const int STATS_TIME_DILATION = 0;
695 public const int STATS_SIM_FPS = 1; 698 public const int STATS_SIM_FPS = 1;
@@ -742,7 +745,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
742 public static readonly LSLInteger RC_GET_ROOT_KEY = 2; 745 public static readonly LSLInteger RC_GET_ROOT_KEY = 2;
743 public static readonly LSLInteger RC_GET_LINK_NUM = 4; 746 public static readonly LSLInteger RC_GET_LINK_NUM = 4;
744 747
745 public static readonly LSLInteger RCERR_UNKNOWN = -1; 748 public static readonly LSLInteger RCERR_UNKNOWN = -1;
746 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 749 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
747 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3; 750 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3;
748 751