diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 192 |
1 files changed, 106 insertions, 86 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index f172216..ff4d130 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | |||
@@ -30,6 +30,7 @@ using System.Collections; | |||
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Globalization; | 31 | using System.Globalization; |
32 | using System.IO; | 32 | using System.IO; |
33 | using System.Diagnostics; //for [DebuggerNonUserCode] | ||
33 | using System.Reflection; | 34 | using System.Reflection; |
34 | using System.Runtime.Remoting; | 35 | using System.Runtime.Remoting; |
35 | using System.Runtime.Remoting.Lifetime; | 36 | using System.Runtime.Remoting.Lifetime; |
@@ -157,24 +158,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
157 | 158 | ||
158 | public UUID AppDomain { get; set; } | 159 | public UUID AppDomain { get; set; } |
159 | 160 | ||
160 | /// <summary> | ||
161 | /// Scene part in which this script instance is contained. | ||
162 | /// </summary> | ||
163 | public SceneObjectPart Part { get; private set; } | ||
164 | |||
165 | public string PrimName { get; private set; } | 161 | public string PrimName { get; private set; } |
166 | 162 | ||
167 | public string ScriptName { get; private set; } | 163 | public string ScriptName { get; private set; } |
168 | 164 | ||
169 | public UUID ItemID { get; private set; } | 165 | public UUID ItemID { get; private set; } |
170 | 166 | ||
171 | public UUID ObjectID { get { return Part.UUID; } } | 167 | public UUID ObjectID { get; private set; } |
172 | 168 | ||
173 | public uint LocalID { get { return Part.LocalId; } } | 169 | public uint LocalID { get; private set; } |
174 | 170 | ||
175 | public UUID RootObjectID { get { return Part.ParentGroup.UUID; } } | 171 | public UUID RootObjectID { get; private set; } |
176 | 172 | ||
177 | public uint RootLocalID { get { return Part.ParentGroup.LocalId; } } | 173 | public uint RootLocalID { get; private set; } |
178 | 174 | ||
179 | public UUID AssetID { get; private set; } | 175 | public UUID AssetID { get; private set; } |
180 | 176 | ||
@@ -219,7 +215,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
219 | EventQueue = new Queue(32); | 215 | EventQueue = new Queue(32); |
220 | 216 | ||
221 | Engine = engine; | 217 | Engine = engine; |
222 | Part = part; | 218 | LocalID = part.LocalId; |
219 | ObjectID = part.UUID; | ||
220 | RootLocalID = part.ParentGroup.LocalId; | ||
221 | RootObjectID = part.ParentGroup.UUID; | ||
223 | ItemID = itemID; | 222 | ItemID = itemID; |
224 | AssetID = assetID; | 223 | AssetID = assetID; |
225 | PrimName = primName; | 224 | PrimName = primName; |
@@ -229,15 +228,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
229 | m_MaxScriptQueue = maxScriptQueue; | 228 | m_MaxScriptQueue = maxScriptQueue; |
230 | m_stateSource = stateSource; | 229 | m_stateSource = stateSource; |
231 | m_postOnRez = postOnRez; | 230 | m_postOnRez = postOnRez; |
232 | m_AttachedAvatar = Part.ParentGroup.AttachedAvatar; | 231 | m_AttachedAvatar = part.ParentGroup.AttachedAvatar; |
233 | m_RegionID = Part.ParentGroup.Scene.RegionInfo.RegionID; | 232 | m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID; |
234 | 233 | ||
235 | lock (Part.TaskInventory) | 234 | if (part != null) |
236 | { | 235 | { |
237 | if (Part.TaskInventory.ContainsKey(ItemID)) | 236 | part.TaskInventory.LockItemsForRead(true); |
237 | if (part.TaskInventory.ContainsKey(ItemID)) | ||
238 | { | 238 | { |
239 | ScriptTask = Part.TaskInventory[ItemID]; | 239 | ScriptTask = part.TaskInventory[ItemID]; |
240 | } | 240 | } |
241 | part.TaskInventory.LockItemsForRead(false); | ||
241 | } | 242 | } |
242 | 243 | ||
243 | ApiManager am = new ApiManager(); | 244 | ApiManager am = new ApiManager(); |
@@ -321,7 +322,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
321 | 322 | ||
322 | // m_log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", PrimName, m_ScriptName); | 323 | // m_log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", PrimName, m_ScriptName); |
323 | 324 | ||
324 | Part.SetScriptEvents(ItemID, | 325 | part.SetScriptEvents(ItemID, |
325 | (int)m_Script.GetStateEventFlags(State)); | 326 | (int)m_Script.GetStateEventFlags(State)); |
326 | 327 | ||
327 | if (!Running) | 328 | if (!Running) |
@@ -417,27 +418,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
417 | PostEvent(new EventParams("attach", | 418 | PostEvent(new EventParams("attach", |
418 | new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0])); | 419 | new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0])); |
419 | } | 420 | } |
421 | |||
420 | } | 422 | } |
421 | } | 423 | } |
422 | 424 | ||
423 | private void ReleaseControls() | 425 | private void ReleaseControls() |
424 | { | 426 | { |
425 | int permsMask; | 427 | SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); |
426 | UUID permsGranter; | 428 | |
427 | lock (Part.TaskInventory) | 429 | if (part != null) |
428 | { | 430 | { |
429 | if (!Part.TaskInventory.ContainsKey(ItemID)) | 431 | int permsMask; |
432 | UUID permsGranter; | ||
433 | part.TaskInventory.LockItemsForRead(true); | ||
434 | if (!part.TaskInventory.ContainsKey(ItemID)) | ||
435 | { | ||
436 | part.TaskInventory.LockItemsForRead(false); | ||
430 | return; | 437 | return; |
438 | } | ||
439 | permsGranter = part.TaskInventory[ItemID].PermsGranter; | ||
440 | permsMask = part.TaskInventory[ItemID].PermsMask; | ||
441 | part.TaskInventory.LockItemsForRead(false); | ||
431 | 442 | ||
432 | permsGranter = Part.TaskInventory[ItemID].PermsGranter; | 443 | if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) |
433 | permsMask = Part.TaskInventory[ItemID].PermsMask; | 444 | { |
434 | } | 445 | ScenePresence presence = Engine.World.GetScenePresence(permsGranter); |
435 | 446 | if (presence != null) | |
436 | if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) | 447 | presence.UnRegisterControlEventsToScript(LocalID, ItemID); |
437 | { | 448 | } |
438 | ScenePresence presence = Engine.World.GetScenePresence(permsGranter); | ||
439 | if (presence != null) | ||
440 | presence.UnRegisterControlEventsToScript(LocalID, ItemID); | ||
441 | } | 449 | } |
442 | } | 450 | } |
443 | 451 | ||
@@ -558,6 +566,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
558 | return true; | 566 | return true; |
559 | } | 567 | } |
560 | 568 | ||
569 | [DebuggerNonUserCode] //Prevents the debugger from farting in this function | ||
561 | public void SetState(string state) | 570 | public void SetState(string state) |
562 | { | 571 | { |
563 | if (state == State) | 572 | if (state == State) |
@@ -569,7 +578,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
569 | new DetectParams[0])); | 578 | new DetectParams[0])); |
570 | PostEvent(new EventParams("state_entry", new Object[0], | 579 | PostEvent(new EventParams("state_entry", new Object[0], |
571 | new DetectParams[0])); | 580 | new DetectParams[0])); |
572 | 581 | ||
573 | throw new EventAbortException(); | 582 | throw new EventAbortException(); |
574 | } | 583 | } |
575 | 584 | ||
@@ -659,57 +668,60 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
659 | /// <returns></returns> | 668 | /// <returns></returns> |
660 | public object EventProcessor() | 669 | public object EventProcessor() |
661 | { | 670 | { |
671 | EventParams data = null; | ||
662 | // We check here as the thread stopping this instance from running may itself hold the m_Script lock. | 672 | // We check here as the thread stopping this instance from running may itself hold the m_Script lock. |
663 | if (!Running) | 673 | if (!Running) |
664 | return 0; | 674 | return 0; |
665 | 675 | ||
666 | lock (m_Script) | ||
667 | { | ||
668 | // m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); | 676 | // m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); |
669 | 677 | ||
670 | if (Suspended) | 678 | if (Suspended) |
671 | return 0; | 679 | return 0; |
672 | |||
673 | EventParams data = null; | ||
674 | 680 | ||
675 | lock (EventQueue) | 681 | lock (EventQueue) |
682 | { | ||
683 | data = (EventParams) EventQueue.Dequeue(); | ||
684 | if (data == null) // Shouldn't happen | ||
676 | { | 685 | { |
677 | data = (EventParams)EventQueue.Dequeue(); | 686 | if (EventQueue.Count > 0 && Running && !ShuttingDown) |
678 | if (data == null) // Shouldn't happen | ||
679 | { | 687 | { |
680 | if (EventQueue.Count > 0 && Running && !ShuttingDown) | 688 | m_CurrentWorkItem = Engine.QueueEventHandler(this); |
681 | { | ||
682 | m_CurrentWorkItem = Engine.QueueEventHandler(this); | ||
683 | } | ||
684 | else | ||
685 | { | ||
686 | m_CurrentWorkItem = null; | ||
687 | } | ||
688 | return 0; | ||
689 | } | 689 | } |
690 | 690 | else | |
691 | if (data.EventName == "timer") | ||
692 | m_TimerQueued = false; | ||
693 | if (data.EventName == "control") | ||
694 | { | 691 | { |
695 | if (m_ControlEventsInQueue > 0) | 692 | m_CurrentWorkItem = null; |
696 | m_ControlEventsInQueue--; | ||
697 | } | 693 | } |
698 | if (data.EventName == "collision") | 694 | return 0; |
699 | m_CollisionInQueue = false; | 695 | } |
696 | |||
697 | if (data.EventName == "timer") | ||
698 | m_TimerQueued = false; | ||
699 | if (data.EventName == "control") | ||
700 | { | ||
701 | if (m_ControlEventsInQueue > 0) | ||
702 | m_ControlEventsInQueue--; | ||
700 | } | 703 | } |
704 | if (data.EventName == "collision") | ||
705 | m_CollisionInQueue = false; | ||
706 | } | ||
707 | |||
708 | lock(m_Script) | ||
709 | { | ||
710 | |||
711 | // m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); | ||
712 | SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); | ||
701 | 713 | ||
702 | if (DebugLevel >= 2) | 714 | if (DebugLevel >= 2) |
703 | m_log.DebugFormat( | 715 | m_log.DebugFormat( |
704 | "[SCRIPT INSTANCE]: Processing event {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", | 716 | "[SCRIPT INSTANCE]: Processing event {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", |
705 | data.EventName, | 717 | data.EventName, |
706 | ScriptName, | 718 | ScriptName, |
707 | Part.Name, | 719 | part.Name, |
708 | Part.LocalId, | 720 | part.LocalId, |
709 | Part.ParentGroup.Name, | 721 | part.ParentGroup.Name, |
710 | Part.ParentGroup.UUID, | 722 | part.ParentGroup.UUID, |
711 | Part.AbsolutePosition, | 723 | part.AbsolutePosition, |
712 | Part.ParentGroup.Scene.Name); | 724 | part.ParentGroup.Scene.Name); |
713 | 725 | ||
714 | m_DetectParams = data.DetectParams; | 726 | m_DetectParams = data.DetectParams; |
715 | 727 | ||
@@ -722,17 +734,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
722 | "[SCRIPT INSTANCE]: Changing state to {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", | 734 | "[SCRIPT INSTANCE]: Changing state to {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", |
723 | State, | 735 | State, |
724 | ScriptName, | 736 | ScriptName, |
725 | Part.Name, | 737 | part.Name, |
726 | Part.LocalId, | 738 | part.LocalId, |
727 | Part.ParentGroup.Name, | 739 | part.ParentGroup.Name, |
728 | Part.ParentGroup.UUID, | 740 | part.ParentGroup.UUID, |
729 | Part.AbsolutePosition, | 741 | part.AbsolutePosition, |
730 | Part.ParentGroup.Scene.Name); | 742 | part.ParentGroup.Scene.Name); |
731 | 743 | ||
732 | AsyncCommandManager.RemoveScript(Engine, | 744 | AsyncCommandManager.RemoveScript(Engine, |
733 | LocalID, ItemID); | 745 | LocalID, ItemID); |
734 | 746 | ||
735 | Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); | 747 | if (part != null) |
748 | { | ||
749 | part.SetScriptEvents(ItemID, | ||
750 | (int)m_Script.GetStateEventFlags(State)); | ||
751 | } | ||
736 | } | 752 | } |
737 | else | 753 | else |
738 | { | 754 | { |
@@ -791,17 +807,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
791 | text = text.Substring(0, 1000); | 807 | text = text.Substring(0, 1000); |
792 | Engine.World.SimChat(Utils.StringToBytes(text), | 808 | Engine.World.SimChat(Utils.StringToBytes(text), |
793 | ChatTypeEnum.DebugChannel, 2147483647, | 809 | ChatTypeEnum.DebugChannel, 2147483647, |
794 | Part.AbsolutePosition, | 810 | part.AbsolutePosition, |
795 | Part.Name, Part.UUID, false); | 811 | part.Name, part.UUID, false); |
796 | 812 | ||
797 | 813 | ||
798 | m_log.DebugFormat( | 814 | m_log.DebugFormat( |
799 | "[SCRIPT INSTANCE]: Runtime error in script {0}, part {1} {2} at {3} in {4}, displayed error {5}, actual exception {6}", | 815 | "[SCRIPT INSTANCE]: Runtime error in script {0}, part {1} {2} at {3} in {4}, displayed error {5}, actual exception {6}", |
800 | ScriptName, | 816 | ScriptName, |
801 | PrimName, | 817 | PrimName, |
802 | Part.UUID, | 818 | part.UUID, |
803 | Part.AbsolutePosition, | 819 | part.AbsolutePosition, |
804 | Part.ParentGroup.Scene.Name, | 820 | part.ParentGroup.Scene.Name, |
805 | text.Replace("\n", "\\n"), | 821 | text.Replace("\n", "\\n"), |
806 | e.InnerException); | 822 | e.InnerException); |
807 | } | 823 | } |
@@ -821,12 +837,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
821 | else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) | 837 | else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) |
822 | { | 838 | { |
823 | m_InSelfDelete = true; | 839 | m_InSelfDelete = true; |
824 | Engine.World.DeleteSceneObject(Part.ParentGroup, false); | 840 | if (part != null) |
841 | Engine.World.DeleteSceneObject(part.ParentGroup, false); | ||
825 | } | 842 | } |
826 | else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) | 843 | else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) |
827 | { | 844 | { |
828 | m_InSelfDelete = true; | 845 | m_InSelfDelete = true; |
829 | Part.Inventory.RemoveInventoryItem(ItemID); | 846 | if (part != null) |
847 | part.Inventory.RemoveInventoryItem(ItemID); | ||
830 | } | 848 | } |
831 | } | 849 | } |
832 | } | 850 | } |
@@ -873,14 +891,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
873 | ReleaseControls(); | 891 | ReleaseControls(); |
874 | 892 | ||
875 | Stop(timeout); | 893 | Stop(timeout); |
876 | Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; | 894 | SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); |
877 | Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; | 895 | part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; |
896 | part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; | ||
897 | part.CollisionSound = UUID.Zero; | ||
878 | AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); | 898 | AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); |
879 | EventQueue.Clear(); | 899 | EventQueue.Clear(); |
880 | m_Script.ResetVars(); | 900 | m_Script.ResetVars(); |
881 | State = "default"; | 901 | State = "default"; |
882 | 902 | ||
883 | Part.SetScriptEvents(ItemID, | 903 | part.SetScriptEvents(ItemID, |
884 | (int)m_Script.GetStateEventFlags(State)); | 904 | (int)m_Script.GetStateEventFlags(State)); |
885 | if (running) | 905 | if (running) |
886 | Start(); | 906 | Start(); |
@@ -889,6 +909,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
889 | new Object[0], new DetectParams[0])); | 909 | new Object[0], new DetectParams[0])); |
890 | } | 910 | } |
891 | 911 | ||
912 | [DebuggerNonUserCode] //Stops the VS debugger from farting in this function | ||
892 | public void ApiResetScript() | 913 | public void ApiResetScript() |
893 | { | 914 | { |
894 | // bool running = Running; | 915 | // bool running = Running; |
@@ -897,15 +918,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
897 | ReleaseControls(); | 918 | ReleaseControls(); |
898 | 919 | ||
899 | m_Script.ResetVars(); | 920 | m_Script.ResetVars(); |
900 | Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; | 921 | SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); |
901 | Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; | 922 | part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; |
923 | part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; | ||
924 | part.CollisionSound = UUID.Zero; | ||
902 | AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); | 925 | AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); |
903 | 926 | ||
904 | EventQueue.Clear(); | 927 | EventQueue.Clear(); |
905 | m_Script.ResetVars(); | 928 | m_Script.ResetVars(); |
906 | State = "default"; | 929 | State = "default"; |
907 | 930 | ||
908 | Part.SetScriptEvents(ItemID, | 931 | part.SetScriptEvents(ItemID, |
909 | (int)m_Script.GetStateEventFlags(State)); | 932 | (int)m_Script.GetStateEventFlags(State)); |
910 | 933 | ||
911 | if (m_CurrentEvent != "state_entry") | 934 | if (m_CurrentEvent != "state_entry") |
@@ -919,10 +942,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
919 | 942 | ||
920 | public Dictionary<string, object> GetVars() | 943 | public Dictionary<string, object> GetVars() |
921 | { | 944 | { |
922 | if (m_Script != null) | 945 | return m_Script.GetVars(); |
923 | return m_Script.GetVars(); | ||
924 | else | ||
925 | return new Dictionary<string, object>(); | ||
926 | } | 946 | } |
927 | 947 | ||
928 | public void SetVars(Dictionary<string, object> vars) | 948 | public void SetVars(Dictionary<string, object> vars) |