PageRenderTime 59ms CodeModel.GetById 23ms app.highlight 27ms RepoModel.GetById 0ms app.codeStats 1ms

/Aurora/AuroraDotNetEngine/EventManager.cs

https://bitbucket.org/VirtualReality/software-testing
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}