/Aurora/AuroraDotNetEngine/EventManager.cs
C# | 1096 lines | 854 code | 115 blank | 127 comment | 206 complexity | 1ac814aedd96c3964977b1323e7ededd MD5 | raw file
1/* 2 * Copyright (c) Contributors, http://aurora-sim.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 Aurora-Sim 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 Aurora.Framework; 29using Aurora.Framework.ClientInterfaces; 30using Aurora.Framework.ConsoleFramework; 31using Aurora.Framework.Modules; 32using Aurora.Framework.PresenceInfo; 33using Aurora.Framework.SceneInfo; 34using Aurora.Framework.SceneInfo.Entities; 35using Aurora.Framework.Utilities; 36using OpenMetaverse; 37using System; 38using System.Collections.Generic; 39using System.Linq; 40 41namespace Aurora.ScriptEngine.AuroraDotNetEngine 42{ 43 /// <summary> 44 /// Prepares events so they can be directly executed upon a script by EventQueueManager, then queues it. 45 /// </summary> 46 public class EventManager 47 { 48 // 49 // This class it the link between an event inside OpenSim and 50 // the corresponding event in a user script being executed. 51 // 52 // For example when an user touches an object then the 53 // "scene.EventManager.OnObjectGrab" event is fired 54 // inside OpenSim. 55 // We hook up to this event and queue a touch_start in 56 // the event queue with the proper LSL parameters. 57 // 58 // You can check debug C# dump of an LSL script if you need to 59 // verify what exact parameters are needed. 60 // 61 62 private readonly Dictionary<uint, Dictionary<UUID, DetectParams>> CoalescedTouchEvents = 63 new Dictionary<uint, Dictionary<UUID, DetectParams>>(); 64 65 private readonly ScriptEngine m_scriptEngine; 66 67 public EventManager(ScriptEngine _ScriptEngine) 68 { 69 m_scriptEngine = _ScriptEngine; 70 } 71 72 public void HookUpRegionEvents(IScene Scene) 73 { 74 //MainConsole.Instance.Info("[" + myScriptEngine.ScriptEngineName + 75 // "]: Hooking up to server events"); 76 77 Scene.EventManager.OnObjectGrab += 78 touch_start; 79 Scene.EventManager.OnObjectGrabbing += 80 touch; 81 Scene.EventManager.OnObjectDeGrab += 82 touch_end; 83 Scene.EventManager.OnScriptChangedEvent += 84 changed; 85 Scene.EventManager.OnScriptAtTargetEvent += 86 at_target; 87 Scene.EventManager.OnScriptNotAtTargetEvent += 88 not_at_target; 89 Scene.EventManager.OnScriptAtRotTargetEvent += 90 at_rot_target; 91 Scene.EventManager.OnScriptNotAtRotTargetEvent += 92 not_at_rot_target; 93 Scene.EventManager.OnScriptControlEvent += 94 control; 95 Scene.EventManager.OnScriptColliderStart += 96 collision_start; 97 Scene.EventManager.OnScriptColliding += 98 collision; 99 Scene.EventManager.OnScriptCollidingEnd += 100 collision_end; 101 Scene.EventManager.OnScriptLandColliderStart += 102 land_collision_start; 103 Scene.EventManager.OnScriptLandColliding += 104 land_collision; 105 Scene.EventManager.OnScriptLandColliderEnd += 106 land_collision_end; 107 Scene.EventManager.OnAttach += attach; 108 Scene.EventManager.OnScriptMovingStartEvent += moving_start; 109 Scene.EventManager.OnScriptMovingEndEvent += moving_end; 110 111 Scene.EventManager.OnRezScripts += rez_scripts; 112 113 114 IMoneyModule money = 115 Scene.RequestModuleInterface<IMoneyModule>(); 116 if (money != null) 117 { 118 money.OnObjectPaid += HandleObjectPaid; 119 money.OnPostObjectPaid += HandlePostObjectPaid; 120 } 121 } 122 123 //private void HandleObjectPaid(UUID objectID, UUID agentID, int amount) 124 private bool HandleObjectPaid(UUID objectID, UUID agentID, int amount) 125 { 126 //bool ret = false; 127 //ISceneChildEntity part = m_scriptEngine.findPrim(objectID); 128 129 //if (part == null) 130 // return; 131 132 //MainConsole.Instance.Debug("Paid: " + objectID + " from " + agentID + ", amount " + amount); 133 //if (part.ParentGroup != null) 134 // part = part.ParentGroup.RootPart; 135 136 //if (part != null) 137 //{ 138 // money(part.LocalId, agentID, amount); 139 //} 140 //if (part != null) 141 //{ 142 // MainConsole.Instance.Debug("Paid: " + objectID + " from " + agentID + ", amount " + amount); 143 // if (part.ParentEntity != null) part = part.ParentEntity.RootChild; 144 // if (part != null) 145 // { 146 // ret = money(part.LocalId, agentID, amount); 147 // } 148 //} 149 //return ret; 150 return true; 151 } 152 153 private bool HandlePostObjectPaid(uint localID, ulong regionHandle, UUID agentID, int amount) 154 { 155 return money(localID, agentID, amount); 156 } 157 158 public void changed(ISceneChildEntity part, uint change) 159 { 160 ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); 161 162 if (datas == null || datas.Length == 0) 163 { 164 datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.RootChild.UUID); 165 if (datas == null || datas.Length == 0) 166 return; 167 } 168 string functionName = "changed"; 169 object[] param = new Object[] {new LSL_Types.LSLInteger(change)}; 170 171 foreach (ScriptData ID in datas) 172 { 173 m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart, 174 param); 175 } 176 } 177 178 /// <summary> 179 /// Handles piping the proper stuff to The script engine for touching 180 /// Including DetectedParams 181 /// </summary> 182 /// <param name="part"></param> 183 /// <param name="child"></param> 184 /// <param name="offsetPos"></param> 185 /// <param name="remoteClient"></param> 186 /// <param name="surfaceArgs"></param> 187 public void touch_start(ISceneChildEntity part, ISceneChildEntity child, Vector3 offsetPos, 188 IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs) 189 { 190 // Add to queue for all scripts in ObjectID object 191 Dictionary<UUID, DetectParams> det = new Dictionary<UUID, DetectParams>(); 192 if (!CoalescedTouchEvents.TryGetValue(part.LocalId, out det)) 193 det = new Dictionary<UUID, DetectParams>(); 194 195 DetectParams detparam = new DetectParams {Key = remoteClient.AgentId}; 196 197 detparam.Populate(part.ParentEntity.Scene); 198 detparam.LinkNum = child.LinkNum; 199 200 if (surfaceArgs != null) 201 { 202 detparam.SurfaceTouchArgs = surfaceArgs; 203 } 204 205 det[remoteClient.AgentId] = detparam; 206 CoalescedTouchEvents[part.LocalId] = det; 207 208 ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); 209 210 if (datas == null || datas.Length == 0) 211 return; 212 213 string functionName = "touch_start"; 214 object[] param = new Object[] {new LSL_Types.LSLInteger(det.Count)}; 215 216 foreach (ScriptData ID in datas) 217 { 218 m_scriptEngine.AddToScriptQueue(ID, functionName, new List<DetectParams>(det.Values).ToArray(), 219 EventPriority.FirstStart, param); 220 } 221 } 222 223 public void touch(ISceneChildEntity part, ISceneChildEntity child, Vector3 offsetPos, 224 IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs) 225 { 226 Dictionary<UUID, DetectParams> det = new Dictionary<UUID, DetectParams>(); 227 if (!CoalescedTouchEvents.TryGetValue(part.LocalId, out det)) 228 det = new Dictionary<UUID, DetectParams>(); 229 230 // Add to queue for all scripts in ObjectID object 231 DetectParams detparam = new DetectParams(); 232 detparam = new DetectParams 233 { 234 Key = remoteClient.AgentId, 235 OffsetPos = new LSL_Types.Vector3(offsetPos.X, 236 offsetPos.Y, 237 offsetPos.Z) 238 }; 239 240 detparam.Populate(part.ParentEntity.Scene); 241 detparam.LinkNum = child.LinkNum; 242 243 if (surfaceArgs != null) 244 detparam.SurfaceTouchArgs = surfaceArgs; 245 246 det[remoteClient.AgentId] = detparam; 247 CoalescedTouchEvents[part.LocalId] = det; 248 249 ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); 250 251 if (datas == null || datas.Length == 0) 252 return; 253 254 string functionName = "touch"; 255 object[] param = new Object[] {new LSL_Types.LSLInteger(det.Count)}; 256 257 foreach (ScriptData ID in datas) 258 { 259 m_scriptEngine.AddToScriptQueue(ID, functionName, new List<DetectParams>(det.Values).ToArray(), 260 EventPriority.FirstStart, param); 261 } 262 } 263 264 public void touch_end(ISceneChildEntity part, ISceneChildEntity child, IClientAPI remoteClient, 265 SurfaceTouchEventArgs surfaceArgs) 266 { 267 Dictionary<UUID, DetectParams> det = new Dictionary<UUID, DetectParams>(); 268 if (!CoalescedTouchEvents.TryGetValue(part.LocalId, out det)) 269 det = new Dictionary<UUID, DetectParams>(); 270 271 // Add to queue for all scripts in ObjectID object 272 DetectParams detparam = new DetectParams(); 273 detparam = new DetectParams {Key = remoteClient.AgentId}; 274 275 detparam.Populate(part.ParentEntity.Scene); 276 detparam.LinkNum = child.LinkNum; 277 278 if (surfaceArgs != null) 279 detparam.SurfaceTouchArgs = surfaceArgs; 280 281 det[remoteClient.AgentId] = detparam; 282 CoalescedTouchEvents[part.LocalId] = det; 283 284 ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); 285 286 if (datas == null || datas.Length == 0) 287 return; 288 289 string functionName = "touch_end"; 290 object[] param = new Object[] {new LSL_Types.LSLInteger(det.Count)}; 291 292 foreach (ScriptData ID in datas) 293 { 294 m_scriptEngine.AddToScriptQueue(ID, functionName, new List<DetectParams>(det.Values).ToArray(), 295 EventPriority.FirstStart, param); 296 } 297 //Remove us from the det param list 298 det.Remove(remoteClient.AgentId); 299 CoalescedTouchEvents[part.LocalId] = det; 300 } 301 302 //public void money(uint localID, UUID agentID, int amount) 303 public bool money(uint localID, UUID agentID, int amount) 304 { 305 bool ret = false; 306 ISceneChildEntity part = m_scriptEngine.findPrim(localID); 307 if (part == null) return ret; 308 309 ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); 310 311 if (datas == null || datas.Length == 0) 312 { 313 datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.UUID); 314 if (datas == null || datas.Length == 0) return ret; 315 } 316 string functionName = "money"; 317 object[] param = new object[] 318 { 319 new LSL_Types.LSLString(agentID.ToString()), 320 new LSL_Types.LSLInteger(amount) 321 }; 322 323 foreach (ScriptData ID in datas) 324 { 325 m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart, 326 param); 327 ret = true; 328 } 329 return ret; 330 } 331 332 public void collision_start(ISceneChildEntity part, ColliderArgs col) 333 { 334 // Add to queue for all scripts in ObjectID object 335 List<DetectParams> det = new List<DetectParams>(); 336 337#if (!ISWIN) 338 foreach (DetectedObject detobj in col.Colliders) 339 { 340 DetectParams d = new DetectParams { Key = detobj.keyUUID }; 341 d.Populate(part.ParentEntity.Scene); 342 d.LinkNum = part.LinkNum; 343 det.Add(d); 344 } 345#else 346 foreach (DetectParams d in col.Colliders.Select(detobj => new DetectParams {Key = detobj.keyUUID})) 347 { 348 d.Populate(part.ParentEntity.Scene); 349 d.LinkNum = part.LinkNum; 350 det.Add(d); 351 } 352#endif 353 354 if (det.Count > 0) 355 { 356 ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); 357 358 if (datas == null || datas.Length == 0) 359 { 360 //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID); 361 //if (datas == null || datas.Length == 0) 362 return; 363 } 364 string functionName = "collision_start"; 365 object[] param = new Object[] {new LSL_Types.LSLInteger(det.Count)}; 366 367 foreach (ScriptData ID in datas) 368 { 369 m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), EventPriority.FirstStart, param); 370 } 371 } 372 } 373 374 public void collision(ISceneChildEntity part, ColliderArgs col) 375 { 376 // Add to queue for all scripts in ObjectID object 377 List<DetectParams> det = new List<DetectParams>(); 378 379#if (!ISWIN) 380 foreach (DetectedObject detobj in col.Colliders) 381 { 382 DetectParams d = new DetectParams { Key = detobj.keyUUID }; 383 d.Populate(part.ParentEntity.Scene); 384 d.LinkNum = part.LinkNum; 385 det.Add(d); 386 } 387#else 388 foreach (DetectParams d in col.Colliders.Select(detobj => new DetectParams {Key = detobj.keyUUID})) 389 { 390 d.Populate(part.ParentEntity.Scene); 391 d.LinkNum = part.LinkNum; 392 det.Add(d); 393 } 394#endif 395 396 if (det.Count > 0) 397 { 398 ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); 399 400 if (datas == null || datas.Length == 0) 401 { 402 //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID); 403 //if (datas == null || datas.Length == 0) 404 return; 405 } 406 string functionName = "collision"; 407 object[] param = new Object[] {new LSL_Types.LSLInteger(det.Count)}; 408 409 foreach (ScriptData ID in datas) 410 { 411 m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), EventPriority.FirstStart, param); 412 } 413 } 414 } 415 416 public void collision_end(ISceneChildEntity part, ColliderArgs col) 417 { 418 // Add to queue for all scripts in ObjectID object 419 List<DetectParams> det = new List<DetectParams>(); 420 421#if (!ISWIN) 422 foreach (DetectedObject detobj in col.Colliders) 423 { 424 DetectParams d = new DetectParams { Key = detobj.keyUUID }; 425 d.Populate(part.ParentEntity.Scene); 426 d.LinkNum = part.LinkNum; 427 det.Add(d); 428 } 429#else 430 foreach (DetectParams d in col.Colliders.Select(detobj => new DetectParams {Key = detobj.keyUUID})) 431 { 432 d.Populate(part.ParentEntity.Scene); 433 d.LinkNum = part.LinkNum; 434 det.Add(d); 435 } 436#endif 437 438 if (det.Count > 0) 439 { 440 ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); 441 442 if (datas == null || datas.Length == 0) 443 { 444 //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID); 445 //if (datas == null || datas.Length == 0) 446 return; 447 } 448 string functionName = "collision_end"; 449 object[] param = new Object[] {new LSL_Types.LSLInteger(det.Count)}; 450 451 foreach (ScriptData ID in datas) 452 { 453 m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), EventPriority.FirstStart, param); 454 } 455 } 456 } 457 458 public void land_collision_start(ISceneChildEntity part, ColliderArgs col) 459 { 460 List<DetectParams> det = new List<DetectParams>(); 461 462#if (!ISWIN) 463 foreach (DetectedObject detobj in col.Colliders) 464 { 465 DetectParams d = new DetectParams 466 { 467 Position = 468 new LSL_Types.Vector3(detobj.posVector.X, detobj.posVector.Y, 469 detobj.posVector.Z), 470 Key = detobj.keyUUID 471 }; 472 d.Populate(part.ParentEntity.Scene); 473 d.LinkNum = part.LinkNum; 474 det.Add(d); 475 } 476#else 477 foreach (DetectParams d in col.Colliders.Select(detobj => new DetectParams 478 { 479 Position = 480 new LSL_Types.Vector3( 481 detobj.posVector.X, 482 detobj.posVector.Y, 483 detobj.posVector.Z), 484 Key = detobj.keyUUID 485 })) 486 { 487 d.Populate(part.ParentEntity.Scene); 488 d.LinkNum = part.LinkNum; 489 det.Add(d); 490 } 491#endif 492 if (det.Count != 0) 493 { 494 ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); 495 496 if (datas == null || datas.Length == 0) 497 { 498 //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID); 499 //if (datas == null || datas.Length == 0) 500 return; 501 } 502 string functionName = "land_collision_start"; 503 object[] param = new Object[] {new LSL_Types.Vector3(det[0].Position)}; 504 505 foreach (ScriptData ID in datas) 506 { 507 m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), EventPriority.FirstStart, param); 508 } 509 } 510 } 511 512 public void land_collision(ISceneChildEntity part, ColliderArgs col) 513 { 514 List<DetectParams> det = new List<DetectParams>(); 515 516#if (!ISWIN) 517 foreach (DetectedObject detobj in col.Colliders) 518 { 519 DetectParams d = new DetectParams 520 { 521 Position = new LSL_Types.Vector3(detobj.posVector.X, detobj.posVector.Y, detobj.posVector.Z), 522 Key = detobj.keyUUID 523 }; 524 d.Populate(part.ParentEntity.Scene); 525 d.LinkNum = part.LinkNum; 526 det.Add(d); 527 } 528#else 529 foreach (DetectParams d in col.Colliders.Select(detobj => new DetectParams 530 { 531 Position = 532 new LSL_Types.Vector3( 533 detobj.posVector.X, 534 detobj.posVector.Y, 535 detobj.posVector.Z), 536 Key = detobj.keyUUID 537 })) 538 { 539 d.Populate(part.ParentEntity.Scene); 540 d.LinkNum = part.LinkNum; 541 det.Add(d); 542 } 543#endif 544 if (det.Count != 0) 545 { 546 ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); 547 548 if (datas == null || datas.Length == 0) 549 { 550 //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID); 551 //if (datas == null || datas.Length == 0) 552 return; 553 } 554 string functionName = "land_collision"; 555 object[] param = new Object[] {new LSL_Types.Vector3(det[0].Position)}; 556 557 foreach (ScriptData ID in datas) 558 { 559 m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), EventPriority.FirstStart, param); 560 } 561 } 562 } 563 564 public void land_collision_end(ISceneChildEntity part, ColliderArgs col) 565 { 566 List<DetectParams> det = new List<DetectParams>(); 567 568#if (!ISWIN) 569 foreach (DetectedObject detobj in col.Colliders) 570 { 571 DetectParams d = new DetectParams 572 { 573 Position = new LSL_Types.Vector3(detobj.posVector.X, detobj.posVector.Y, detobj.posVector.Z), 574 Key = detobj.keyUUID 575 }; 576 d.Populate(part.ParentEntity.Scene); 577 d.LinkNum = part.LinkNum; 578 det.Add(d); 579 } 580#else 581 foreach (DetectParams d in col.Colliders.Select(detobj => new DetectParams 582 { 583 Position = 584 new LSL_Types.Vector3( 585 detobj.posVector.X, 586 detobj.posVector.Y, 587 detobj.posVector.Z), 588 Key = detobj.keyUUID 589 })) 590 { 591 d.Populate(part.ParentEntity.Scene); 592 d.LinkNum = part.LinkNum; 593 det.Add(d); 594 } 595#endif 596 if (det.Count != 0) 597 { 598 ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); 599 600 if (datas == null || datas.Length == 0) 601 { 602 //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID); 603 //if (datas == null || datas.Length == 0) 604 return; 605 } 606 string functionName = "land_collision_end"; 607 object[] param = new Object[] {new LSL_Types.Vector3(det[0].Position)}; 608 609 foreach (ScriptData ID in datas) 610 { 611 m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), EventPriority.FirstStart, param); 612 } 613 } 614 } 615 616 public void control(ISceneChildEntity part, UUID itemID, UUID agentID, uint held, uint change) 617 { 618 if (part == null) 619 return; 620 ScriptData ID = ScriptEngine.ScriptProtection.GetScript(part.UUID, itemID); 621 622 if (ID == null) 623 return; 624 625 string functionName = "control"; 626 object[] param = new object[] 627 { 628 new LSL_Types.LSLString(agentID.ToString()), 629 new LSL_Types.LSLInteger(held), 630 new LSL_Types.LSLInteger(change) 631 }; 632 633 m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart, param); 634 } 635 636 public void email(uint localID, UUID itemID, string timeSent, 637 string address, string subject, string message, int numLeft) 638 { 639 ISceneChildEntity part = m_scriptEngine.findPrim(localID); 640 if (part == null) 641 return; 642 ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); 643 644 if (datas == null || datas.Length == 0) 645 { 646 datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.UUID); 647 if (datas == null || datas.Length == 0) 648 return; 649 } 650 string functionName = "email"; 651 object[] param = new object[] 652 { 653 new LSL_Types.LSLString(timeSent), 654 new LSL_Types.LSLString(address), 655 new LSL_Types.LSLString(subject), 656 new LSL_Types.LSLString(message), 657 new LSL_Types.LSLInteger(numLeft) 658 }; 659 660 foreach (ScriptData ID in datas) 661 { 662 m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart, 663 param); 664 } 665 } 666 667 public void at_target(uint localID, uint handle, Vector3 targetpos, 668 Vector3 atpos) 669 { 670 ISceneChildEntity part = m_scriptEngine.findPrim(localID); 671 if (part == null) 672 return; 673 ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); 674 675 if (datas == null || datas.Length == 0) 676 { 677 datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.UUID); 678 if (datas == null || datas.Length == 0) 679 return; 680 } 681 string functionName = "at_target"; 682 object[] param = new object[] 683 { 684 new LSL_Types.LSLInteger(handle), 685 new LSL_Types.Vector3(targetpos.X, targetpos.Y, targetpos.Z), 686 new LSL_Types.Vector3(atpos.X, atpos.Y, atpos.Z) 687 }; 688 689 foreach (ScriptData ID in datas) 690 { 691 m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart, 692 param); 693 } 694 } 695 696 public void not_at_target(uint localID) 697 { 698 ISceneChildEntity part = m_scriptEngine.findPrim(localID); 699 if (part == null) 700 return; 701 ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); 702 703 if (datas == null || datas.Length == 0) 704 { 705 datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.UUID); 706 if (datas == null || datas.Length == 0) 707 return; 708 } 709 string functionName = "not_at_target"; 710 object[] param = new object[0]; 711 712 foreach (ScriptData ID in datas) 713 { 714 m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart, 715 param); 716 } 717 } 718 719 public void at_rot_target(uint localID, uint handle, Quaternion targetrot, 720 Quaternion atrot) 721 { 722 ISceneChildEntity part = m_scriptEngine.findPrim(localID); 723 if (part == null) 724 return; 725 ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); 726 727 if (datas == null || datas.Length == 0) 728 { 729 datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.UUID); 730 if (datas == null || datas.Length == 0) 731 return; 732 } 733 string functionName = "at_rot_target"; 734 object[] param = new object[] 735 { 736 new LSL_Types.LSLInteger(handle), 737 new LSL_Types.Quaternion(targetrot.X, targetrot.Y, targetrot.Z, targetrot.W), 738 new LSL_Types.Quaternion(atrot.X, atrot.Y, atrot.Z, atrot.W) 739 }; 740 741 foreach (ScriptData ID in datas) 742 { 743 m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart, 744 param); 745 } 746 } 747 748 public void not_at_rot_target(uint localID) 749 { 750 ISceneChildEntity part = m_scriptEngine.findPrim(localID); 751 if (part == null) 752 return; 753 ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); 754 755 if (datas == null || datas.Length == 0) 756 { 757 datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.UUID); 758 if (datas == null || datas.Length == 0) 759 return; 760 } 761 string functionName = "not_at_rot_target"; 762 object[] param = new object[0]; 763 764 foreach (ScriptData ID in datas) 765 { 766 m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart, 767 param); 768 } 769 } 770 771 public void attach(uint localID, UUID itemID, UUID avatar) 772 { 773 ISceneChildEntity part = m_scriptEngine.findPrim(localID); 774 if (part == null) 775 return; 776 ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); 777 778 if (datas == null || datas.Length == 0) 779 { 780 datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.UUID); 781 if (datas == null || datas.Length == 0) 782 return; 783 } 784 string functionName = "attach"; 785 object[] param = new object[] 786 { 787 new LSL_Types.LSLString(avatar.ToString()) 788 }; 789 790 foreach (ScriptData ID in datas) 791 { 792 m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart, 793 param); 794 } 795 } 796 797 public void moving_start(ISceneChildEntity part) 798 { 799 ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); 800 801 if (datas == null || datas.Length == 0) 802 { 803 datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.RootChild.UUID); 804 if (datas == null || datas.Length == 0) 805 return; 806 } 807 string functionName = "moving_start"; 808 object[] param = new object[0]; 809 810 foreach (ScriptData ID in datas) 811 { 812 m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart, 813 param); 814 } 815 } 816 817 public void moving_end(ISceneChildEntity part) 818 { 819 ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); 820 821 if (datas == null || datas.Length == 0) 822 { 823 datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.RootChild.UUID); 824 if (datas == null || datas.Length == 0) 825 return; 826 } 827 string functionName = "moving_end"; 828 object[] param = new object[0]; 829 830 foreach (ScriptData ID in datas) 831 { 832 m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart, 833 param); 834 } 835 } 836 837 /// <summary> 838 /// Start multiple scripts in the object 839 /// </summary> 840 /// <param name="part"></param> 841 /// <param name="items"></param> 842 /// <param name="startParam"></param> 843 /// <param name="postOnRez"></param> 844 /// <param name="stateSource"></param> 845 /// <param name="rezzedFrom"></param> 846 /// <param name="clearStateSaves"></param> 847 public void rez_scripts(ISceneChildEntity part, TaskInventoryItem[] items, 848 int startParam, bool postOnRez, StateSource stateSource, UUID rezzedFrom, 849 bool clearStateSaves) 850 { 851#if (!ISWIN) 852 List<LUStruct> ItemsToStart = new List<LUStruct>(); 853 foreach (TaskInventoryItem item in items) 854 { 855 LUStruct itemToQueue = m_scriptEngine.StartScript(part, item.ItemID, startParam, postOnRez, stateSource, rezzedFrom, clearStateSaves); 856 if (itemToQueue.Action != LUType.Unknown) ItemsToStart.Add(itemToQueue); 857 } 858#else 859 List<LUStruct> ItemsToStart = 860 items.Select( 861 item => 862 m_scriptEngine.StartScript(part, item.ItemID, startParam, postOnRez, stateSource, rezzedFrom, 863 clearStateSaves)) 864 .Where(itemToQueue => itemToQueue.Action != LUType.Unknown) 865 .ToList(); 866#endif 867 if (ItemsToStart.Count != 0) 868 m_scriptEngine.MaintenanceThread.AddScriptChange(ItemsToStart.ToArray(), LoadPriority.FirstStart); 869 } 870 871 /// <summary> 872 /// This checks the minimum amount of time between script firings as well as control events, making sure that events do NOT fire after scripts reset, close or restart, etc 873 /// </summary> 874 /// <param name="ID"></param> 875 /// <param name="FunctionName"></param> 876 /// <param name="param"></param> 877 /// <returns></returns> 878 public bool CheckIfEventShouldFire(ScriptData ID, string FunctionName, object[] param) 879 { 880 lock (ID.ScriptEventLock) 881 { 882 if (ID.Loading) 883 { 884 //If the script is loading, enqueue all events 885 return true; 886 } 887 //This will happen if the script doesn't compile correctly 888 if (ID.Script == null) 889 { 890 MainConsole.Instance.Info("[AuroraDotNetEngine]: Could not load script from item '" + 891 ID.InventoryItem.Name + 892 "' to fire event " + FunctionName); 893 return false; 894 } 895 scriptEvents eventType = (scriptEvents) Enum.Parse(typeof (scriptEvents), FunctionName); 896 897 // this must be done even if there is no event method 898 899 if (eventType == scriptEvents.touch_start) 900 ID.RemoveTouchEvents = false; 901 else if (eventType == scriptEvents.collision_start) 902 ID.RemoveCollisionEvents = false; 903 else if (eventType == scriptEvents.land_collision_start) 904 ID.RemoveLandCollisionEvents = false; 905 906 if (eventType == scriptEvents.state_entry) 907 ID.ResetEvents(); 908 909 if ((ID.Script.GetStateEventFlags(ID.State) & (long) eventType) == 0) 910 return false; //If the script doesn't contain the state, don't even bother queueing it 911 912 //Make sure we can execute events at position 913 if (!m_scriptEngine.PipeEventsForScript(ID.Part)) 914 return false; 915 916 switch (eventType) 917 { 918 case scriptEvents.timer: 919 if (ID.TimerInQueue) 920 return false; 921 ID.TimerInQueue = true; 922 break; 923 case scriptEvents.sensor: 924 if (ID.SensorInQueue) 925 return false; 926 ID.SensorInQueue = true; 927 break; 928 case scriptEvents.no_sensor: 929 if (ID.NoSensorInQueue) 930 return false; 931 ID.NoSensorInQueue = true; 932 break; 933 case scriptEvents.at_target: 934 if (ID.AtTargetInQueue) 935 return false; 936 ID.AtTargetInQueue = true; 937 break; 938 case scriptEvents.not_at_target: 939 if (ID.NotAtTargetInQueue) 940 return false; 941 ID.NotAtTargetInQueue = true; 942 break; 943 case scriptEvents.at_rot_target: 944 if (ID.AtRotTargetInQueue) 945 return false; 946 ID.AtRotTargetInQueue = true; 947 break; 948 case scriptEvents.not_at_rot_target: 949 if (ID.NotAtRotTargetInQueue) 950 return false; 951 ID.NotAtRotTargetInQueue = true; 952 break; 953 case scriptEvents.control: 954 int held = ((LSL_Types.LSLInteger) param[1]).value; 955 // int changed = ((LSL_Types.LSLInteger)data.Params[2]).value; 956 957 // If the last message was a 0 (nothing held) 958 // and this one is also nothing held, drop it 959 // 960 if (ID.LastControlLevel == held && held == 0) 961 return true; 962 963 // If there is one or more queued, then queue 964 // only changed ones, else queue unconditionally 965 // 966 if (ID.ControlEventsInQueue > 0) 967 { 968 if (ID.LastControlLevel == held) 969 return false; 970 } 971 break; 972 case scriptEvents.collision: 973 if (ID.CollisionInQueue || ID.RemoveCollisionEvents) 974 return false; 975 ID.CollisionInQueue = true; 976 break; 977 case scriptEvents.moving_start: 978 if (ID.MovingInQueue) //Block all other moving_starts until moving_end is called 979 return false; 980 ID.MovingInQueue = true; 981 break; 982 case scriptEvents.moving_end: 983 if (!ID.MovingInQueue) //If we get a moving_end after we have sent one event, don't fire another 984 return false; 985 break; 986 case scriptEvents.collision_end: 987 if (ID.RemoveCollisionEvents) 988 return false; 989 break; 990 case scriptEvents.touch: 991 if (ID.TouchInQueue || ID.RemoveTouchEvents) 992 return false; 993 ID.TouchInQueue = true; 994 break; 995 case scriptEvents.touch_end: 996 if (ID.RemoveTouchEvents) 997 return false; 998 break; 999 case scriptEvents.land_collision: 1000 if (ID.LandCollisionInQueue || ID.RemoveLandCollisionEvents) 1001 return false; 1002 ID.LandCollisionInQueue = true; 1003 break; 1004 case scriptEvents.land_collision_end: 1005 if (ID.RemoveLandCollisionEvents) 1006 return false; 1007 break; 1008 case scriptEvents.changed: 1009 Changed changed; 1010 if (param[0] is Changed) 1011 changed = (Changed) param[0]; 1012 else 1013 changed = (Changed) (((LSL_Types.LSLInteger) param[0]).value); 1014 if (ID.ChangedInQueue.Contains(changed)) 1015 return false; 1016 ID.ChangedInQueue.Add(changed); 1017 break; 1018 } 1019 } 1020 return true; 1021 } 1022 1023 /// <summary> 1024 /// This removes the event from the queue and allows it to be fired again 1025 /// </summary> 1026 /// <param name="QIS"></param> 1027 public void EventComplete(QueueItemStruct QIS) 1028 { 1029 lock (QIS.ID.ScriptEventLock) 1030 { 1031 scriptEvents eventType = (scriptEvents) Enum.Parse(typeof (scriptEvents), QIS.functionName); 1032 switch (eventType) 1033 { 1034 case scriptEvents.timer: 1035 QIS.ID.TimerInQueue = false; 1036 break; 1037 case scriptEvents.control: 1038 if (QIS.ID.ControlEventsInQueue > 0) 1039 QIS.ID.ControlEventsInQueue--; 1040 break; 1041 case scriptEvents.collision: 1042 QIS.ID.CollisionInQueue = false; 1043 break; 1044 case scriptEvents.collision_end: 1045 QIS.ID.CollisionInQueue = false; 1046 break; 1047 case scriptEvents.moving_end: 1048 QIS.ID.MovingInQueue = false; 1049 break; 1050 case scriptEvents.touch: 1051 QIS.ID.TouchInQueue = false; 1052 break; 1053 case scriptEvents.touch_end: 1054 QIS.ID.TouchInQueue = false; 1055 break; 1056 case scriptEvents.land_collision: 1057 QIS.ID.LandCollisionInQueue = false; 1058 break; 1059 case scriptEvents.land_collision_end: 1060 QIS.ID.LandCollisionInQueue = false; 1061 break; 1062 case scriptEvents.sensor: 1063 QIS.ID.SensorInQueue = false; 1064 break; 1065 case scriptEvents.no_sensor: 1066 QIS.ID.NoSensorInQueue = false; 1067 break; 1068 case scriptEvents.at_target: 1069 QIS.ID.AtTargetInQueue = false; 1070 break; 1071 case scriptEvents.not_at_target: 1072 QIS.ID.NotAtTargetInQueue = false; 1073 break; 1074 case scriptEvents.at_rot_target: 1075 QIS.ID.AtRotTargetInQueue = false; 1076 break; 1077 case scriptEvents.not_at_rot_target: 1078 QIS.ID.NotAtRotTargetInQueue = false; 1079 break; 1080 case scriptEvents.changed: 1081 Changed changed; 1082 if (QIS.param[0] is Changed) 1083 { 1084 changed = (Changed) QIS.param[0]; 1085 } 1086 else 1087 { 1088 changed = (Changed) (((LSL_Types.LSLInteger) QIS.param[0]).value); 1089 } 1090 QIS.ID.ChangedInQueue.Remove(changed); 1091 break; 1092 } 1093 } 1094 } 1095 } 1096}