diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XEngine')
-rw-r--r-- | OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 1076 |
1 files changed, 28 insertions, 1048 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index cfe0599..c5bcfd5 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | |||
@@ -46,6 +46,7 @@ using OpenSim.Region.ScriptEngine.Shared; | |||
46 | using OpenSim.Region.ScriptEngine.Shared.Api; | 46 | using OpenSim.Region.ScriptEngine.Shared.Api; |
47 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | 47 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; |
48 | using OpenSim.Region.ScriptEngine.Shared.CodeTools; | 48 | using OpenSim.Region.ScriptEngine.Shared.CodeTools; |
49 | using OpenSim.Region.ScriptEngine.Shared.Instance; | ||
49 | using OpenSim.Region.ScriptEngine.Interfaces; | 50 | using OpenSim.Region.ScriptEngine.Interfaces; |
50 | 51 | ||
51 | namespace OpenSim.Region.ScriptEngine.XEngine | 52 | namespace OpenSim.Region.ScriptEngine.XEngine |
@@ -67,7 +68,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
67 | #pragma warning restore 414 | 68 | #pragma warning restore 414 |
68 | private int m_EventLimit; | 69 | private int m_EventLimit; |
69 | private bool m_KillTimedOutScripts; | 70 | private bool m_KillTimedOutScripts; |
70 | public AsyncCommandManager m_AsyncCommands; | 71 | private AsyncCommandManager m_AsyncCommands; |
71 | bool m_firstStart = true; | 72 | bool m_firstStart = true; |
72 | 73 | ||
73 | private static List<XEngine> m_ScriptEngines = | 74 | private static List<XEngine> m_ScriptEngines = |
@@ -80,8 +81,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
80 | 81 | ||
81 | // Maps the LLUUID above to the script instance | 82 | // Maps the LLUUID above to the script instance |
82 | 83 | ||
83 | private Dictionary<LLUUID, XScriptInstance> m_Scripts = | 84 | private Dictionary<LLUUID, IScriptInstance> m_Scripts = |
84 | new Dictionary<LLUUID, XScriptInstance>(); | 85 | new Dictionary<LLUUID, IScriptInstance>(); |
85 | 86 | ||
86 | // Maps the asset ID to the assembly | 87 | // Maps the asset ID to the assembly |
87 | 88 | ||
@@ -254,15 +255,15 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
254 | 255 | ||
255 | // m_log.Debug("[XEngine] Backing up script states"); | 256 | // m_log.Debug("[XEngine] Backing up script states"); |
256 | 257 | ||
257 | List<XScriptInstance> instances = new List<XScriptInstance>(); | 258 | List<IScriptInstance> instances = new List<IScriptInstance>(); |
258 | 259 | ||
259 | lock (m_Scripts) | 260 | lock (m_Scripts) |
260 | { | 261 | { |
261 | foreach (XScriptInstance instance in m_Scripts.Values) | 262 | foreach (IScriptInstance instance in m_Scripts.Values) |
262 | instances.Add(instance); | 263 | instances.Add(instance); |
263 | } | 264 | } |
264 | 265 | ||
265 | foreach (XScriptInstance i in instances) | 266 | foreach (IScriptInstance i in instances) |
266 | { | 267 | { |
267 | string assembly = String.Empty; | 268 | string assembly = String.Empty; |
268 | 269 | ||
@@ -289,7 +290,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
289 | object[] parms = (object[])p; | 290 | object[] parms = (object[])p; |
290 | int sleepTime = (int)parms[0]; | 291 | int sleepTime = (int)parms[0]; |
291 | 292 | ||
292 | foreach (XScriptInstance inst in m_Scripts.Values) | 293 | foreach (IScriptInstance inst in m_Scripts.Values) |
293 | { | 294 | { |
294 | if (inst.EventTime() > m_EventLimit) | 295 | if (inst.EventTime() > m_EventLimit) |
295 | { | 296 | { |
@@ -502,12 +503,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
502 | } | 503 | } |
503 | m_DomainScripts[appDomain].Add(itemID); | 504 | m_DomainScripts[appDomain].Add(itemID); |
504 | 505 | ||
505 | XScriptInstance instance = new XScriptInstance(this,localID, | 506 | ScriptInstance instance = new ScriptInstance(this,localID, |
506 | part.UUID, itemID, assetID, assembly, | 507 | part.UUID, itemID, assetID, assembly, |
507 | m_AppDomains[appDomain], | 508 | m_AppDomains[appDomain], |
508 | part.ParentGroup.RootPart.Name, | 509 | part.ParentGroup.RootPart.Name, |
509 | item.Name, startParam, postOnRez, | 510 | item.Name, startParam, postOnRez, |
510 | XScriptInstance.StateSource.NewRez); | 511 | StateSource.NewRez); |
511 | 512 | ||
512 | m_log.DebugFormat("[XEngine] Loaded script {0}.{1}", | 513 | m_log.DebugFormat("[XEngine] Loaded script {0}.{1}", |
513 | part.ParentGroup.RootPart.Name, item.Name); | 514 | part.ParentGroup.RootPart.Name, item.Name); |
@@ -539,7 +540,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
539 | 540 | ||
540 | m_AsyncCommands.RemoveScript(localID, itemID); | 541 | m_AsyncCommands.RemoveScript(localID, itemID); |
541 | 542 | ||
542 | XScriptInstance instance=m_Scripts[itemID]; | 543 | IScriptInstance instance=m_Scripts[itemID]; |
543 | m_Scripts.Remove(itemID); | 544 | m_Scripts.Remove(itemID); |
544 | 545 | ||
545 | instance.ClearQueue(); | 546 | instance.ClearQueue(); |
@@ -599,7 +600,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
599 | { | 600 | { |
600 | List<LLUUID> assetIDList = new List<LLUUID>(m_Assemblies.Keys); | 601 | List<LLUUID> assetIDList = new List<LLUUID>(m_Assemblies.Keys); |
601 | 602 | ||
602 | foreach (XScriptInstance i in m_Scripts.Values) | 603 | foreach (IScriptInstance i in m_Scripts.Values) |
603 | { | 604 | { |
604 | if (assetIDList.Contains(i.AssetID)) | 605 | if (assetIDList.Contains(i.AssetID)) |
605 | assetIDList.Remove(i.AssetID); | 606 | assetIDList.Remove(i.AssetID); |
@@ -676,7 +677,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
676 | CultureInfo USCulture = new CultureInfo("en-US"); | 677 | CultureInfo USCulture = new CultureInfo("en-US"); |
677 | Thread.CurrentThread.CurrentCulture = USCulture; | 678 | Thread.CurrentThread.CurrentCulture = USCulture; |
678 | 679 | ||
679 | XScriptInstance instance = (XScriptInstance) parms; | 680 | IScriptInstance instance = (ScriptInstance) parms; |
680 | 681 | ||
681 | return instance.EventProcessor(); | 682 | return instance.EventProcessor(); |
682 | } | 683 | } |
@@ -695,7 +696,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
695 | { | 696 | { |
696 | if (m_Scripts.ContainsKey(itemID)) | 697 | if (m_Scripts.ContainsKey(itemID)) |
697 | { | 698 | { |
698 | XScriptInstance instance = m_Scripts[itemID]; | 699 | IScriptInstance instance = m_Scripts[itemID]; |
699 | if (instance != null) | 700 | if (instance != null) |
700 | { | 701 | { |
701 | instance.PostEvent(p); | 702 | instance.PostEvent(p); |
@@ -713,7 +714,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
713 | { | 714 | { |
714 | if (m_Scripts.ContainsKey(itemID)) | 715 | if (m_Scripts.ContainsKey(itemID)) |
715 | { | 716 | { |
716 | XScriptInstance instance = m_Scripts[itemID]; | 717 | IScriptInstance instance = m_Scripts[itemID]; |
717 | if (instance != null) | 718 | if (instance != null) |
718 | instance.PostEvent(p); | 719 | instance.PostEvent(p); |
719 | return true; | 720 | return true; |
@@ -747,9 +748,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
747 | return null; | 748 | return null; |
748 | } | 749 | } |
749 | 750 | ||
750 | private XScriptInstance GetInstance(LLUUID itemID) | 751 | private IScriptInstance GetInstance(LLUUID itemID) |
751 | { | 752 | { |
752 | XScriptInstance instance; | 753 | IScriptInstance instance; |
753 | lock (m_Scripts) | 754 | lock (m_Scripts) |
754 | { | 755 | { |
755 | if (!m_Scripts.ContainsKey(itemID)) | 756 | if (!m_Scripts.ContainsKey(itemID)) |
@@ -761,7 +762,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
761 | 762 | ||
762 | public void SetScriptState(LLUUID itemID, bool running) | 763 | public void SetScriptState(LLUUID itemID, bool running) |
763 | { | 764 | { |
764 | XScriptInstance instance = GetInstance(itemID); | 765 | IScriptInstance instance = GetInstance(itemID); |
765 | if (instance != null) | 766 | if (instance != null) |
766 | { | 767 | { |
767 | if (running) | 768 | if (running) |
@@ -773,7 +774,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
773 | 774 | ||
774 | public bool GetScriptState(LLUUID itemID) | 775 | public bool GetScriptState(LLUUID itemID) |
775 | { | 776 | { |
776 | XScriptInstance instance = GetInstance(itemID); | 777 | IScriptInstance instance = GetInstance(itemID); |
777 | if (instance != null) | 778 | if (instance != null) |
778 | return instance.Running; | 779 | return instance.Running; |
779 | return false; | 780 | return false; |
@@ -781,35 +782,35 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
781 | 782 | ||
782 | public void ApiResetScript(LLUUID itemID) | 783 | public void ApiResetScript(LLUUID itemID) |
783 | { | 784 | { |
784 | XScriptInstance instance = GetInstance(itemID); | 785 | IScriptInstance instance = GetInstance(itemID); |
785 | if (instance != null) | 786 | if (instance != null) |
786 | instance.ApiResetScript(); | 787 | instance.ApiResetScript(); |
787 | } | 788 | } |
788 | 789 | ||
789 | public void ResetScript(LLUUID itemID) | 790 | public void ResetScript(LLUUID itemID) |
790 | { | 791 | { |
791 | XScriptInstance instance = GetInstance(itemID); | 792 | IScriptInstance instance = GetInstance(itemID); |
792 | if (instance != null) | 793 | if (instance != null) |
793 | instance.ResetScript(); | 794 | instance.ResetScript(); |
794 | } | 795 | } |
795 | 796 | ||
796 | public void StartScript(LLUUID itemID) | 797 | public void StartScript(LLUUID itemID) |
797 | { | 798 | { |
798 | XScriptInstance instance = GetInstance(itemID); | 799 | IScriptInstance instance = GetInstance(itemID); |
799 | if (instance != null) | 800 | if (instance != null) |
800 | instance.Start(); | 801 | instance.Start(); |
801 | } | 802 | } |
802 | 803 | ||
803 | public void StopScript(LLUUID itemID) | 804 | public void StopScript(LLUUID itemID) |
804 | { | 805 | { |
805 | XScriptInstance instance = GetInstance(itemID); | 806 | IScriptInstance instance = GetInstance(itemID); |
806 | if (instance != null) | 807 | if (instance != null) |
807 | instance.Stop(0); | 808 | instance.Stop(0); |
808 | } | 809 | } |
809 | 810 | ||
810 | public DetectParams GetDetectParams(LLUUID itemID, int idx) | 811 | public DetectParams GetDetectParams(LLUUID itemID, int idx) |
811 | { | 812 | { |
812 | XScriptInstance instance = GetInstance(itemID); | 813 | IScriptInstance instance = GetInstance(itemID); |
813 | if (instance != null) | 814 | if (instance != null) |
814 | return instance.GetDetectParams(idx); | 815 | return instance.GetDetectParams(idx); |
815 | return null; | 816 | return null; |
@@ -817,7 +818,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
817 | 818 | ||
818 | public LLUUID GetDetectID(LLUUID itemID, int idx) | 819 | public LLUUID GetDetectID(LLUUID itemID, int idx) |
819 | { | 820 | { |
820 | XScriptInstance instance = GetInstance(itemID); | 821 | IScriptInstance instance = GetInstance(itemID); |
821 | if (instance != null) | 822 | if (instance != null) |
822 | return instance.GetDetectID(idx); | 823 | return instance.GetDetectID(idx); |
823 | return LLUUID.Zero; | 824 | return LLUUID.Zero; |
@@ -825,14 +826,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
825 | 826 | ||
826 | public void SetState(LLUUID itemID, string newState) | 827 | public void SetState(LLUUID itemID, string newState) |
827 | { | 828 | { |
828 | XScriptInstance instance = GetInstance(itemID); | 829 | IScriptInstance instance = GetInstance(itemID); |
829 | if (instance == null) | 830 | if (instance == null) |
830 | return; | 831 | return; |
831 | instance.SetState(newState); | 832 | instance.SetState(newState); |
832 | } | 833 | } |
833 | public string GetState(LLUUID itemID) | 834 | public string GetState(LLUUID itemID) |
834 | { | 835 | { |
835 | XScriptInstance instance = GetInstance(itemID); | 836 | IScriptInstance instance = GetInstance(itemID); |
836 | if (instance == null) | 837 | if (instance == null) |
837 | return "default"; | 838 | return "default"; |
838 | return instance.State; | 839 | return instance.State; |
@@ -840,7 +841,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
840 | 841 | ||
841 | public int GetStartParameter(LLUUID itemID) | 842 | public int GetStartParameter(LLUUID itemID) |
842 | { | 843 | { |
843 | XScriptInstance instance = GetInstance(itemID); | 844 | IScriptInstance instance = GetInstance(itemID); |
844 | if (instance == null) | 845 | if (instance == null) |
845 | return 0; | 846 | return 0; |
846 | return instance.StartParam; | 847 | return instance.StartParam; |
@@ -851,1025 +852,4 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
851 | return GetScriptState(itemID); | 852 | return GetScriptState(itemID); |
852 | } | 853 | } |
853 | } | 854 | } |
854 | |||
855 | public class XScriptInstance | ||
856 | { | ||
857 | private XEngine m_Engine; | ||
858 | private IWorkItemResult m_CurrentResult=null; | ||
859 | private Queue m_EventQueue = new Queue(32); | ||
860 | private bool m_RunEvents = false; | ||
861 | private LLUUID m_ItemID; | ||
862 | private uint m_LocalID; | ||
863 | private LLUUID m_ObjectID; | ||
864 | private LLUUID m_AssetID; | ||
865 | private IScript m_Script; | ||
866 | private LLUUID m_AppDomain; | ||
867 | private DetectParams[] m_DetectParams; | ||
868 | private bool m_TimerQueued; | ||
869 | private DateTime m_EventStart; | ||
870 | private bool m_InEvent; | ||
871 | private string m_PrimName; | ||
872 | private string m_ScriptName; | ||
873 | private string m_Assembly; | ||
874 | private int m_StartParam = 0; | ||
875 | private string m_CurrentEvent = String.Empty; | ||
876 | private bool m_InSelfDelete = false; | ||
877 | |||
878 | private Dictionary<string,IScriptApi> m_Apis = new Dictionary<string,IScriptApi>(); | ||
879 | |||
880 | public enum StateSource | ||
881 | { | ||
882 | NewRez = 0, | ||
883 | PrimCrossing = 1, | ||
884 | AttachmentCrossing = 2 | ||
885 | } | ||
886 | |||
887 | // Script state | ||
888 | private string m_State="default"; | ||
889 | |||
890 | public Object[] PluginData = new Object[0]; | ||
891 | |||
892 | public bool Running | ||
893 | { | ||
894 | get { return m_RunEvents; } | ||
895 | set { m_RunEvents = value; } | ||
896 | } | ||
897 | |||
898 | public string State | ||
899 | { | ||
900 | get { return m_State; } | ||
901 | set { m_State = value; } | ||
902 | } | ||
903 | |||
904 | public XEngine Engine | ||
905 | { | ||
906 | get { return m_Engine; } | ||
907 | } | ||
908 | |||
909 | public LLUUID AppDomain | ||
910 | { | ||
911 | get { return m_AppDomain; } | ||
912 | set { m_AppDomain = value; } | ||
913 | } | ||
914 | |||
915 | public string PrimName | ||
916 | { | ||
917 | get { return m_PrimName; } | ||
918 | } | ||
919 | |||
920 | public string ScriptName | ||
921 | { | ||
922 | get { return m_ScriptName; } | ||
923 | } | ||
924 | |||
925 | public LLUUID ItemID | ||
926 | { | ||
927 | get { return m_ItemID; } | ||
928 | } | ||
929 | |||
930 | public LLUUID ObjectID | ||
931 | { | ||
932 | get { return m_ObjectID; } | ||
933 | } | ||
934 | |||
935 | public uint LocalID | ||
936 | { | ||
937 | get { return m_LocalID; } | ||
938 | } | ||
939 | |||
940 | public LLUUID AssetID | ||
941 | { | ||
942 | get { return m_AssetID; } | ||
943 | } | ||
944 | |||
945 | public Queue EventQueue | ||
946 | { | ||
947 | get { return m_EventQueue; } | ||
948 | } | ||
949 | |||
950 | public void ClearQueue() | ||
951 | { | ||
952 | m_TimerQueued = false; | ||
953 | m_EventQueue.Clear(); | ||
954 | } | ||
955 | |||
956 | public int StartParam | ||
957 | { | ||
958 | get { return m_StartParam; } | ||
959 | set { m_StartParam = value; } | ||
960 | } | ||
961 | |||
962 | public XScriptInstance(XEngine engine, uint localID, LLUUID objectID, | ||
963 | LLUUID itemID, LLUUID assetID, string assembly, AppDomain dom, | ||
964 | string primName, string scriptName, int startParam, | ||
965 | bool postOnRez, StateSource stateSource) | ||
966 | { | ||
967 | m_Engine = engine; | ||
968 | |||
969 | m_LocalID = localID; | ||
970 | m_ObjectID = objectID; | ||
971 | m_ItemID = itemID; | ||
972 | m_AssetID = assetID; | ||
973 | m_PrimName = primName; | ||
974 | m_ScriptName = scriptName; | ||
975 | m_Assembly = assembly; | ||
976 | m_StartParam = startParam; | ||
977 | |||
978 | ApiManager am = new ApiManager(); | ||
979 | |||
980 | SceneObjectPart part=engine.World.GetSceneObjectPart(localID); | ||
981 | if (part == null) | ||
982 | { | ||
983 | engine.Log.Error("[XEngine] SceneObjectPart unavailable. Script NOT started."); | ||
984 | return; | ||
985 | } | ||
986 | |||
987 | foreach (string api in am.GetApis()) | ||
988 | { | ||
989 | m_Apis[api] = am.CreateApi(api); | ||
990 | m_Apis[api].Initialize(engine, part, localID, itemID); | ||
991 | } | ||
992 | |||
993 | try | ||
994 | { | ||
995 | m_Script = (IScript)dom.CreateInstanceAndUnwrap( | ||
996 | Path.GetFileNameWithoutExtension(assembly), | ||
997 | "SecondLife.Script"); | ||
998 | } | ||
999 | catch (Exception e) | ||
1000 | { | ||
1001 | m_Engine.Log.ErrorFormat("[XEngine] Error loading assembly {0}\n"+e.ToString(), assembly); | ||
1002 | } | ||
1003 | |||
1004 | try | ||
1005 | { | ||
1006 | foreach (KeyValuePair<string,IScriptApi> kv in m_Apis) | ||
1007 | { | ||
1008 | m_Script.InitApi(kv.Key, kv.Value); | ||
1009 | } | ||
1010 | |||
1011 | // m_Engine.Log.Debug("[XEngine] Script instance created"); | ||
1012 | |||
1013 | part.SetScriptEvents(m_ItemID, | ||
1014 | (int)m_Script.GetStateEventFlags(State)); | ||
1015 | } | ||
1016 | catch (Exception e) | ||
1017 | { | ||
1018 | m_Engine.Log.Error("[XEngine] Error loading script instance\n"+e.ToString()); | ||
1019 | return; | ||
1020 | } | ||
1021 | |||
1022 | string savedState = Path.Combine(Path.GetDirectoryName(assembly), | ||
1023 | m_ItemID.ToString() + ".state"); | ||
1024 | if (File.Exists(savedState)) | ||
1025 | { | ||
1026 | string xml = String.Empty; | ||
1027 | |||
1028 | try | ||
1029 | { | ||
1030 | FileInfo fi = new FileInfo(savedState); | ||
1031 | int size=(int)fi.Length; | ||
1032 | if (size < 512000) | ||
1033 | { | ||
1034 | using (FileStream fs = File.Open(savedState, | ||
1035 | FileMode.Open, FileAccess.Read, FileShare.None)) | ||
1036 | { | ||
1037 | System.Text.ASCIIEncoding enc = | ||
1038 | new System.Text.ASCIIEncoding(); | ||
1039 | |||
1040 | Byte[] data = new Byte[size]; | ||
1041 | fs.Read(data, 0, size); | ||
1042 | |||
1043 | xml = enc.GetString(data); | ||
1044 | |||
1045 | ScriptSerializer.Deserialize(xml, this); | ||
1046 | |||
1047 | m_Engine.m_AsyncCommands.CreateFromData( | ||
1048 | m_LocalID, m_ItemID, m_ObjectID, | ||
1049 | PluginData); | ||
1050 | |||
1051 | m_Engine.Log.DebugFormat("[XEngine] Successfully retrieved state for script {0}.{1}", m_PrimName, m_ScriptName); | ||
1052 | |||
1053 | if (m_RunEvents) | ||
1054 | { | ||
1055 | m_RunEvents = false; | ||
1056 | Start(); | ||
1057 | if (postOnRez) | ||
1058 | PostEvent(new EventParams("on_rez", | ||
1059 | new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0])); | ||
1060 | } | ||
1061 | |||
1062 | // we get new rez events on sim restart, too | ||
1063 | // but if there is state, then we fire the change | ||
1064 | // event | ||
1065 | if (stateSource == StateSource.NewRez) | ||
1066 | { | ||
1067 | // m_Engine.Log.Debug("[XEngine] Posted changed(CHANGED_REGION_RESTART) to script"); | ||
1068 | PostEvent(new EventParams("changed", | ||
1069 | new Object[] {new LSL_Types.LSLInteger(256)}, new DetectParams[0])); | ||
1070 | } | ||
1071 | } | ||
1072 | } | ||
1073 | else | ||
1074 | { | ||
1075 | m_Engine.Log.Error("[XEngine] Unable to load script state: Memory limit exceeded"); | ||
1076 | Start(); | ||
1077 | PostEvent(new EventParams("state_entry", | ||
1078 | new Object[0], new DetectParams[0])); | ||
1079 | if (postOnRez) | ||
1080 | PostEvent(new EventParams("on_rez", | ||
1081 | new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0])); | ||
1082 | |||
1083 | } | ||
1084 | } | ||
1085 | catch (Exception e) | ||
1086 | { | ||
1087 | m_Engine.Log.ErrorFormat("[XEngine] Unable to load script state from xml: {0}\n"+e.ToString(), xml); | ||
1088 | Start(); | ||
1089 | PostEvent(new EventParams("state_entry", | ||
1090 | new Object[0], new DetectParams[0])); | ||
1091 | if (postOnRez) | ||
1092 | PostEvent(new EventParams("on_rez", | ||
1093 | new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0])); | ||
1094 | } | ||
1095 | } | ||
1096 | else | ||
1097 | { | ||
1098 | // m_Engine.Log.ErrorFormat("[XEngine] Unable to load script state, file not found"); | ||
1099 | Start(); | ||
1100 | PostEvent(new EventParams("state_entry", | ||
1101 | new Object[0], new DetectParams[0])); | ||
1102 | |||
1103 | if (postOnRez) | ||
1104 | PostEvent(new EventParams("on_rez", | ||
1105 | new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0])); | ||
1106 | } | ||
1107 | } | ||
1108 | |||
1109 | public void RemoveState() | ||
1110 | { | ||
1111 | string savedState = Path.Combine(Path.GetDirectoryName(m_Assembly), | ||
1112 | m_ItemID.ToString() + ".state"); | ||
1113 | |||
1114 | try | ||
1115 | { | ||
1116 | File.Delete(savedState); | ||
1117 | } | ||
1118 | catch(Exception) | ||
1119 | { | ||
1120 | } | ||
1121 | } | ||
1122 | |||
1123 | public void VarDump(Dictionary<string, object> vars) | ||
1124 | { | ||
1125 | Console.WriteLine("Variable dump for script {0}", m_ItemID.ToString()); | ||
1126 | foreach (KeyValuePair<string, object> v in vars) | ||
1127 | { | ||
1128 | Console.WriteLine("Variable: {0} = '{1}'", v. Key, | ||
1129 | v.Value.ToString()); | ||
1130 | } | ||
1131 | } | ||
1132 | |||
1133 | public void Start() | ||
1134 | { | ||
1135 | lock (m_EventQueue) | ||
1136 | { | ||
1137 | if (Running) | ||
1138 | return; | ||
1139 | |||
1140 | m_RunEvents = true; | ||
1141 | |||
1142 | if (m_EventQueue.Count > 0) | ||
1143 | { | ||
1144 | if (m_CurrentResult == null) | ||
1145 | m_CurrentResult = m_Engine.QueueEventHandler(this); | ||
1146 | else | ||
1147 | m_Engine.Log.Error("[XEngine] Tried to start a script that was already queued"); | ||
1148 | } | ||
1149 | } | ||
1150 | } | ||
1151 | |||
1152 | public bool Stop(int timeout) | ||
1153 | { | ||
1154 | IWorkItemResult result; | ||
1155 | |||
1156 | lock (m_EventQueue) | ||
1157 | { | ||
1158 | if (!Running) | ||
1159 | return true; | ||
1160 | |||
1161 | if (m_CurrentResult == null) | ||
1162 | { | ||
1163 | m_RunEvents = false; | ||
1164 | return true; | ||
1165 | } | ||
1166 | |||
1167 | if (m_CurrentResult.Cancel()) | ||
1168 | { | ||
1169 | m_CurrentResult = null; | ||
1170 | m_RunEvents = false; | ||
1171 | return true; | ||
1172 | } | ||
1173 | |||
1174 | result = m_CurrentResult; | ||
1175 | m_RunEvents = false; | ||
1176 | } | ||
1177 | |||
1178 | if (SmartThreadPool.WaitAll(new IWorkItemResult[] {result}, new TimeSpan((long)timeout * 100000), false)) | ||
1179 | { | ||
1180 | return true; | ||
1181 | } | ||
1182 | |||
1183 | lock (m_EventQueue) | ||
1184 | { | ||
1185 | result = m_CurrentResult; | ||
1186 | } | ||
1187 | |||
1188 | if (result == null) | ||
1189 | return true; | ||
1190 | |||
1191 | if (!m_InSelfDelete) | ||
1192 | result.Abort(); | ||
1193 | |||
1194 | lock (m_EventQueue) | ||
1195 | { | ||
1196 | m_CurrentResult = null; | ||
1197 | } | ||
1198 | |||
1199 | return true; | ||
1200 | } | ||
1201 | |||
1202 | public void SetState(string state) | ||
1203 | { | ||
1204 | PostEvent(new EventParams("state_exit", new Object[0], | ||
1205 | new DetectParams[0])); | ||
1206 | PostEvent(new EventParams("state", new Object[] { state }, | ||
1207 | new DetectParams[0])); | ||
1208 | PostEvent(new EventParams("state_entry", new Object[0], | ||
1209 | new DetectParams[0])); | ||
1210 | } | ||
1211 | |||
1212 | public void PostEvent(EventParams data) | ||
1213 | { | ||
1214 | // m_Engine.Log.DebugFormat("[XEngine] Posted event {2} in state {3} to {0}.{1}", | ||
1215 | // m_PrimName, m_ScriptName, data.EventName, m_State); | ||
1216 | |||
1217 | if (!Running) | ||
1218 | return; | ||
1219 | |||
1220 | lock (m_EventQueue) | ||
1221 | { | ||
1222 | if (m_EventQueue.Count >= m_Engine.MaxScriptQueue) | ||
1223 | return; | ||
1224 | |||
1225 | m_EventQueue.Enqueue(data); | ||
1226 | if (data.EventName == "timer") | ||
1227 | { | ||
1228 | if (m_TimerQueued) | ||
1229 | return; | ||
1230 | m_TimerQueued = true; | ||
1231 | } | ||
1232 | |||
1233 | if (!m_RunEvents) | ||
1234 | return; | ||
1235 | |||
1236 | if (m_CurrentResult == null) | ||
1237 | { | ||
1238 | m_CurrentResult = m_Engine.QueueEventHandler(this); | ||
1239 | } | ||
1240 | } | ||
1241 | } | ||
1242 | |||
1243 | public object EventProcessor() | ||
1244 | { | ||
1245 | EventParams data = null; | ||
1246 | |||
1247 | lock (m_EventQueue) | ||
1248 | { | ||
1249 | data = (EventParams) m_EventQueue.Dequeue(); | ||
1250 | if (data == null) // Shouldn't happen | ||
1251 | { | ||
1252 | m_CurrentResult = null; | ||
1253 | return 0; | ||
1254 | } | ||
1255 | if (data.EventName == "timer") | ||
1256 | m_TimerQueued = false; | ||
1257 | } | ||
1258 | |||
1259 | m_DetectParams = data.DetectParams; | ||
1260 | |||
1261 | if (data.EventName == "state") // Hardcoded state change | ||
1262 | { | ||
1263 | // m_Engine.Log.DebugFormat("[XEngine] Script {0}.{1} state set to {2}", | ||
1264 | // m_PrimName, m_ScriptName, data.Params[0].ToString()); | ||
1265 | m_State=data.Params[0].ToString(); | ||
1266 | m_Engine.m_AsyncCommands.RemoveScript( | ||
1267 | m_LocalID, m_ItemID); | ||
1268 | |||
1269 | SceneObjectPart part = m_Engine.World.GetSceneObjectPart( | ||
1270 | m_LocalID); | ||
1271 | if (part != null) | ||
1272 | { | ||
1273 | part.SetScriptEvents(m_ItemID, | ||
1274 | (int)m_Script.GetStateEventFlags(State)); | ||
1275 | } | ||
1276 | } | ||
1277 | else | ||
1278 | { | ||
1279 | SceneObjectPart part = m_Engine.World.GetSceneObjectPart( | ||
1280 | m_LocalID); | ||
1281 | // m_Engine.Log.DebugFormat("[XEngine] Delivered event {2} in state {3} to {0}.{1}", | ||
1282 | // m_PrimName, m_ScriptName, data.EventName, m_State); | ||
1283 | |||
1284 | try | ||
1285 | { | ||
1286 | m_CurrentEvent = data.EventName; | ||
1287 | m_EventStart = DateTime.Now; | ||
1288 | m_InEvent = true; | ||
1289 | |||
1290 | m_Script.ExecuteEvent(State, data.EventName, data.Params); | ||
1291 | |||
1292 | m_InEvent = false; | ||
1293 | m_CurrentEvent = String.Empty; | ||
1294 | } | ||
1295 | catch (Exception e) | ||
1296 | { | ||
1297 | m_InEvent = false; | ||
1298 | m_CurrentEvent = String.Empty; | ||
1299 | |||
1300 | if (!(e is TargetInvocationException) || (!(e.InnerException is EventAbortException) && (!(e.InnerException is SelfDeleteException)))) | ||
1301 | { | ||
1302 | if (e is System.Threading.ThreadAbortException) | ||
1303 | { | ||
1304 | lock (m_EventQueue) | ||
1305 | { | ||
1306 | if ((m_EventQueue.Count > 0) && m_RunEvents) | ||
1307 | { | ||
1308 | m_CurrentResult=m_Engine.QueueEventHandler(this); | ||
1309 | } | ||
1310 | else | ||
1311 | { | ||
1312 | m_CurrentResult = null; | ||
1313 | } | ||
1314 | } | ||
1315 | |||
1316 | m_DetectParams = null; | ||
1317 | |||
1318 | return 0; | ||
1319 | } | ||
1320 | |||
1321 | try | ||
1322 | { | ||
1323 | // DISPLAY ERROR INWORLD | ||
1324 | string text = "Runtime error:\n" + e.ToString(); | ||
1325 | if (text.Length > 1400) | ||
1326 | text = text.Substring(0, 1400); | ||
1327 | m_Engine.World.SimChat(Helpers.StringToField(text), | ||
1328 | ChatTypeEnum.DebugChannel, 2147483647, | ||
1329 | part.AbsolutePosition, | ||
1330 | part.Name, part.UUID, false); | ||
1331 | } | ||
1332 | catch (Exception e2) // LEGIT: User Scripting | ||
1333 | { | ||
1334 | m_Engine.Log.Error("[XEngine]: "+ | ||
1335 | "Error displaying error in-world: " + | ||
1336 | e2.ToString()); | ||
1337 | m_Engine.Log.Error("[XEngine]: " + | ||
1338 | "Errormessage: Error compiling script:\r\n" + | ||
1339 | e.ToString()); | ||
1340 | } | ||
1341 | } | ||
1342 | else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) | ||
1343 | { | ||
1344 | m_InSelfDelete = true; | ||
1345 | if (part != null && part.ParentGroup != null) | ||
1346 | m_Engine.World.DeleteSceneObject(part.ParentGroup); | ||
1347 | } | ||
1348 | } | ||
1349 | } | ||
1350 | |||
1351 | lock (m_EventQueue) | ||
1352 | { | ||
1353 | if ((m_EventQueue.Count > 0) && m_RunEvents) | ||
1354 | { | ||
1355 | m_CurrentResult = m_Engine.QueueEventHandler(this); | ||
1356 | } | ||
1357 | else | ||
1358 | { | ||
1359 | m_CurrentResult = null; | ||
1360 | } | ||
1361 | } | ||
1362 | |||
1363 | m_DetectParams = null; | ||
1364 | |||
1365 | return 0; | ||
1366 | } | ||
1367 | |||
1368 | public int EventTime() | ||
1369 | { | ||
1370 | if (!m_InEvent) | ||
1371 | return 0; | ||
1372 | |||
1373 | return (DateTime.Now - m_EventStart).Seconds; | ||
1374 | } | ||
1375 | |||
1376 | public void ResetScript() | ||
1377 | { | ||
1378 | bool running = Running; | ||
1379 | |||
1380 | RemoveState(); | ||
1381 | |||
1382 | Stop(0); | ||
1383 | SceneObjectPart part=m_Engine.World.GetSceneObjectPart(m_LocalID); | ||
1384 | part.GetInventoryItem(m_ItemID).PermsMask = 0; | ||
1385 | part.GetInventoryItem(m_ItemID).PermsGranter = LLUUID.Zero; | ||
1386 | m_Engine.m_AsyncCommands.RemoveScript(m_LocalID, m_ItemID); | ||
1387 | m_EventQueue.Clear(); | ||
1388 | m_Script.ResetVars(); | ||
1389 | m_State = "default"; | ||
1390 | if (running) | ||
1391 | Start(); | ||
1392 | PostEvent(new EventParams("state_entry", | ||
1393 | new Object[0], new DetectParams[0])); | ||
1394 | } | ||
1395 | |||
1396 | public void ApiResetScript() | ||
1397 | { | ||
1398 | // bool running = Running; | ||
1399 | |||
1400 | RemoveState(); | ||
1401 | |||
1402 | m_Script.ResetVars(); | ||
1403 | SceneObjectPart part=m_Engine.World.GetSceneObjectPart(m_LocalID); | ||
1404 | part.GetInventoryItem(m_ItemID).PermsMask = 0; | ||
1405 | part.GetInventoryItem(m_ItemID).PermsGranter = LLUUID.Zero; | ||
1406 | m_Engine.m_AsyncCommands.RemoveScript(m_LocalID, m_ItemID); | ||
1407 | if (m_CurrentEvent != "state_entry") | ||
1408 | { | ||
1409 | PostEvent(new EventParams("state_entry", | ||
1410 | new Object[0], new DetectParams[0])); | ||
1411 | } | ||
1412 | } | ||
1413 | |||
1414 | public Dictionary<string, object> GetVars() | ||
1415 | { | ||
1416 | return m_Script.GetVars(); | ||
1417 | } | ||
1418 | |||
1419 | public void SetVars(Dictionary<string, object> vars) | ||
1420 | { | ||
1421 | m_Script.SetVars(vars); | ||
1422 | } | ||
1423 | |||
1424 | public DetectParams GetDetectParams(int idx) | ||
1425 | { | ||
1426 | if (idx < 0 || idx >= m_DetectParams.Length) | ||
1427 | return null; | ||
1428 | |||
1429 | return m_DetectParams[idx]; | ||
1430 | } | ||
1431 | |||
1432 | public LLUUID GetDetectID(int idx) | ||
1433 | { | ||
1434 | if (idx < 0 || idx >= m_DetectParams.Length) | ||
1435 | return LLUUID.Zero; | ||
1436 | |||
1437 | return m_DetectParams[idx].Key; | ||
1438 | } | ||
1439 | |||
1440 | public void SaveState(string assembly) | ||
1441 | { | ||
1442 | PluginData = | ||
1443 | m_Engine.m_AsyncCommands.GetSerializationData( | ||
1444 | m_ItemID); | ||
1445 | |||
1446 | string xml = ScriptSerializer.Serialize(this); | ||
1447 | |||
1448 | try | ||
1449 | { | ||
1450 | FileStream fs = File.Create(Path.Combine(Path.GetDirectoryName(assembly), m_ItemID.ToString() + ".state")); | ||
1451 | System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); | ||
1452 | Byte[] buf = enc.GetBytes(xml); | ||
1453 | fs.Write(buf, 0, buf.Length); | ||
1454 | fs.Close(); | ||
1455 | } | ||
1456 | catch(Exception e) | ||
1457 | { | ||
1458 | Console.WriteLine("Unable to save xml\n"+e.ToString()); | ||
1459 | } | ||
1460 | if (!File.Exists(Path.Combine(Path.GetDirectoryName(assembly), m_ItemID.ToString() + ".state"))) | ||
1461 | { | ||
1462 | throw new Exception("Completed persistence save, but no file was created"); | ||
1463 | } | ||
1464 | } | ||
1465 | } | ||
1466 | |||
1467 | public class ScriptSerializer | ||
1468 | { | ||
1469 | public static string Serialize(XScriptInstance instance) | ||
1470 | { | ||
1471 | bool running = instance.Running; | ||
1472 | |||
1473 | if (running) | ||
1474 | instance.Stop(50); | ||
1475 | |||
1476 | XmlDocument xmldoc = new XmlDocument(); | ||
1477 | |||
1478 | XmlNode xmlnode = xmldoc.CreateNode(XmlNodeType.XmlDeclaration, | ||
1479 | "", ""); | ||
1480 | xmldoc.AppendChild(xmlnode); | ||
1481 | |||
1482 | XmlElement rootElement = xmldoc.CreateElement("", "ScriptState", | ||
1483 | ""); | ||
1484 | xmldoc.AppendChild(rootElement); | ||
1485 | |||
1486 | XmlElement state = xmldoc.CreateElement("", "State", ""); | ||
1487 | state.AppendChild(xmldoc.CreateTextNode(instance.State)); | ||
1488 | |||
1489 | rootElement.AppendChild(state); | ||
1490 | |||
1491 | XmlElement run = xmldoc.CreateElement("", "Running", ""); | ||
1492 | run.AppendChild(xmldoc.CreateTextNode( | ||
1493 | running.ToString())); | ||
1494 | |||
1495 | rootElement.AppendChild(run); | ||
1496 | |||
1497 | Dictionary<string, Object> vars = instance.GetVars(); | ||
1498 | |||
1499 | XmlElement variables = xmldoc.CreateElement("", "Variables", ""); | ||
1500 | |||
1501 | foreach (KeyValuePair<string, Object> var in vars) | ||
1502 | WriteTypedValue(xmldoc, variables, "Variable", var.Key, | ||
1503 | var.Value); | ||
1504 | |||
1505 | rootElement.AppendChild(variables); | ||
1506 | |||
1507 | XmlElement queue = xmldoc.CreateElement("", "Queue", ""); | ||
1508 | |||
1509 | int count = instance.EventQueue.Count; | ||
1510 | |||
1511 | while (count > 0) | ||
1512 | { | ||
1513 | EventParams ep = (EventParams)instance.EventQueue.Dequeue(); | ||
1514 | instance.EventQueue.Enqueue(ep); | ||
1515 | count--; | ||
1516 | |||
1517 | XmlElement item = xmldoc.CreateElement("", "Item", ""); | ||
1518 | XmlAttribute itemEvent = xmldoc.CreateAttribute("", "event", | ||
1519 | ""); | ||
1520 | itemEvent.Value = ep.EventName; | ||
1521 | item.Attributes.Append(itemEvent); | ||
1522 | |||
1523 | XmlElement parms = xmldoc.CreateElement("", "Params", ""); | ||
1524 | |||
1525 | foreach (Object o in ep.Params) | ||
1526 | WriteTypedValue(xmldoc, parms, "Param", String.Empty, o); | ||
1527 | |||
1528 | item.AppendChild(parms); | ||
1529 | |||
1530 | XmlElement detect = xmldoc.CreateElement("", "Detected", ""); | ||
1531 | |||
1532 | foreach (DetectParams det in ep.DetectParams) | ||
1533 | { | ||
1534 | XmlElement objectElem = xmldoc.CreateElement("", "Object", | ||
1535 | ""); | ||
1536 | XmlAttribute pos = xmldoc.CreateAttribute("", "pos", ""); | ||
1537 | pos.Value = det.OffsetPos.ToString(); | ||
1538 | objectElem.Attributes.Append(pos); | ||
1539 | |||
1540 | XmlAttribute d_linkNum = xmldoc.CreateAttribute("", | ||
1541 | "linkNum", ""); | ||
1542 | d_linkNum.Value = det.LinkNum.ToString(); | ||
1543 | objectElem.Attributes.Append(d_linkNum); | ||
1544 | |||
1545 | XmlAttribute d_group = xmldoc.CreateAttribute("", | ||
1546 | "group", ""); | ||
1547 | d_group.Value = det.Group.ToString(); | ||
1548 | objectElem.Attributes.Append(d_group); | ||
1549 | |||
1550 | XmlAttribute d_name = xmldoc.CreateAttribute("", | ||
1551 | "name", ""); | ||
1552 | d_name.Value = det.Name.ToString(); | ||
1553 | objectElem.Attributes.Append(d_name); | ||
1554 | |||
1555 | XmlAttribute d_owner = xmldoc.CreateAttribute("", | ||
1556 | "owner", ""); | ||
1557 | d_owner.Value = det.Owner.ToString(); | ||
1558 | objectElem.Attributes.Append(d_owner); | ||
1559 | |||
1560 | XmlAttribute d_position = xmldoc.CreateAttribute("", | ||
1561 | "position", ""); | ||
1562 | d_position.Value = det.Position.ToString(); | ||
1563 | objectElem.Attributes.Append(d_position); | ||
1564 | |||
1565 | XmlAttribute d_rotation = xmldoc.CreateAttribute("", | ||
1566 | "rotation", ""); | ||
1567 | d_rotation.Value = det.Rotation.ToString(); | ||
1568 | objectElem.Attributes.Append(d_rotation); | ||
1569 | |||
1570 | XmlAttribute d_type = xmldoc.CreateAttribute("", | ||
1571 | "type", ""); | ||
1572 | d_type.Value = det.Type.ToString(); | ||
1573 | objectElem.Attributes.Append(d_type); | ||
1574 | |||
1575 | XmlAttribute d_velocity = xmldoc.CreateAttribute("", | ||
1576 | "velocity", ""); | ||
1577 | d_velocity.Value = det.Velocity.ToString(); | ||
1578 | objectElem.Attributes.Append(d_velocity); | ||
1579 | |||
1580 | objectElem.AppendChild( | ||
1581 | xmldoc.CreateTextNode(det.Key.ToString())); | ||
1582 | |||
1583 | detect.AppendChild(objectElem); | ||
1584 | } | ||
1585 | |||
1586 | item.AppendChild(detect); | ||
1587 | |||
1588 | queue.AppendChild(item); | ||
1589 | } | ||
1590 | |||
1591 | rootElement.AppendChild(queue); | ||
1592 | |||
1593 | XmlNode plugins = xmldoc.CreateElement("", "Plugins", ""); | ||
1594 | DumpList(xmldoc, plugins, | ||
1595 | new LSL_Types.list(instance.PluginData)); | ||
1596 | |||
1597 | rootElement.AppendChild(plugins); | ||
1598 | |||
1599 | if (running) | ||
1600 | instance.Start(); | ||
1601 | |||
1602 | return xmldoc.InnerXml; | ||
1603 | } | ||
1604 | |||
1605 | public static void Deserialize(string xml, XScriptInstance instance) | ||
1606 | { | ||
1607 | XmlDocument doc = new XmlDocument(); | ||
1608 | |||
1609 | Dictionary<string, object> vars = instance.GetVars(); | ||
1610 | |||
1611 | instance.PluginData = new Object[0]; | ||
1612 | |||
1613 | doc.LoadXml(xml); | ||
1614 | |||
1615 | XmlNodeList rootL = doc.GetElementsByTagName("ScriptState"); | ||
1616 | if (rootL.Count != 1) | ||
1617 | { | ||
1618 | return; | ||
1619 | } | ||
1620 | XmlNode rootNode = rootL[0]; | ||
1621 | |||
1622 | if (rootNode != null) | ||
1623 | { | ||
1624 | object varValue; | ||
1625 | XmlNodeList partL = rootNode.ChildNodes; | ||
1626 | |||
1627 | foreach (XmlNode part in partL) | ||
1628 | { | ||
1629 | switch (part.Name) | ||
1630 | { | ||
1631 | case "State": | ||
1632 | instance.State=part.InnerText; | ||
1633 | break; | ||
1634 | case "Running": | ||
1635 | instance.Running=bool.Parse(part.InnerText); | ||
1636 | break; | ||
1637 | case "Variables": | ||
1638 | XmlNodeList varL = part.ChildNodes; | ||
1639 | foreach (XmlNode var in varL) | ||
1640 | { | ||
1641 | string varName; | ||
1642 | varValue=ReadTypedValue(var, out varName); | ||
1643 | |||
1644 | if (vars.ContainsKey(varName)) | ||
1645 | vars[varName] = varValue; | ||
1646 | } | ||
1647 | instance.SetVars(vars); | ||
1648 | break; | ||
1649 | case "Queue": | ||
1650 | XmlNodeList itemL = part.ChildNodes; | ||
1651 | foreach (XmlNode item in itemL) | ||
1652 | { | ||
1653 | List<Object> parms = new List<Object>(); | ||
1654 | List<DetectParams> detected = | ||
1655 | new List<DetectParams>(); | ||
1656 | |||
1657 | string eventName = | ||
1658 | item.Attributes.GetNamedItem("event").Value; | ||
1659 | XmlNodeList eventL = item.ChildNodes; | ||
1660 | foreach (XmlNode evt in eventL) | ||
1661 | { | ||
1662 | switch (evt.Name) | ||
1663 | { | ||
1664 | case "Params": | ||
1665 | XmlNodeList prms = evt.ChildNodes; | ||
1666 | foreach (XmlNode pm in prms) | ||
1667 | parms.Add(ReadTypedValue(pm)); | ||
1668 | |||
1669 | break; | ||
1670 | case "Detected": | ||
1671 | XmlNodeList detL = evt.ChildNodes; | ||
1672 | foreach (XmlNode det in detL) | ||
1673 | { | ||
1674 | string vect = | ||
1675 | det.Attributes.GetNamedItem( | ||
1676 | "pos").Value; | ||
1677 | LSL_Types.Vector3 v = | ||
1678 | new LSL_Types.Vector3(vect); | ||
1679 | |||
1680 | int d_linkNum=0; | ||
1681 | LLUUID d_group = LLUUID.Zero; | ||
1682 | string d_name = String.Empty; | ||
1683 | LLUUID d_owner = LLUUID.Zero; | ||
1684 | LSL_Types.Vector3 d_position = | ||
1685 | new LSL_Types.Vector3(); | ||
1686 | LSL_Types.Quaternion d_rotation = | ||
1687 | new LSL_Types.Quaternion(); | ||
1688 | int d_type = 0; | ||
1689 | LSL_Types.Vector3 d_velocity = | ||
1690 | new LSL_Types.Vector3(); | ||
1691 | |||
1692 | try | ||
1693 | { | ||
1694 | string tmp; | ||
1695 | |||
1696 | tmp = det.Attributes.GetNamedItem( | ||
1697 | "linkNum").Value; | ||
1698 | int.TryParse(tmp, out d_linkNum); | ||
1699 | |||
1700 | tmp = det.Attributes.GetNamedItem( | ||
1701 | "group").Value; | ||
1702 | LLUUID.TryParse(tmp, out d_group); | ||
1703 | |||
1704 | d_name = det.Attributes.GetNamedItem( | ||
1705 | "name").Value; | ||
1706 | |||
1707 | tmp = det.Attributes.GetNamedItem( | ||
1708 | "owner").Value; | ||
1709 | LLUUID.TryParse(tmp, out d_owner); | ||
1710 | |||
1711 | tmp = det.Attributes.GetNamedItem( | ||
1712 | "position").Value; | ||
1713 | d_position = | ||
1714 | new LSL_Types.Vector3(tmp); | ||
1715 | |||
1716 | tmp = det.Attributes.GetNamedItem( | ||
1717 | "rotation").Value; | ||
1718 | d_rotation = | ||
1719 | new LSL_Types.Quaternion(tmp); | ||
1720 | |||
1721 | tmp = det.Attributes.GetNamedItem( | ||
1722 | "type").Value; | ||
1723 | int.TryParse(tmp, out d_type); | ||
1724 | |||
1725 | tmp = det.Attributes.GetNamedItem( | ||
1726 | "velocity").Value; | ||
1727 | d_velocity = | ||
1728 | new LSL_Types.Vector3(tmp); | ||
1729 | |||
1730 | } | ||
1731 | catch (Exception) // Old version XML | ||
1732 | { | ||
1733 | } | ||
1734 | |||
1735 | LLUUID uuid = new LLUUID(); | ||
1736 | LLUUID.TryParse(det.InnerText, | ||
1737 | out uuid); | ||
1738 | |||
1739 | DetectParams d = new DetectParams(); | ||
1740 | d.Key = uuid; | ||
1741 | d.OffsetPos = v; | ||
1742 | d.LinkNum = d_linkNum; | ||
1743 | d.Group = d_group; | ||
1744 | d.Name = d_name; | ||
1745 | d.Owner = d_owner; | ||
1746 | d.Position = d_position; | ||
1747 | d.Rotation = d_rotation; | ||
1748 | d.Type = d_type; | ||
1749 | d.Velocity = d_velocity; | ||
1750 | |||
1751 | detected.Add(d); | ||
1752 | } | ||
1753 | break; | ||
1754 | } | ||
1755 | } | ||
1756 | EventParams ep = new EventParams( | ||
1757 | eventName, parms.ToArray(), | ||
1758 | detected.ToArray()); | ||
1759 | instance.EventQueue.Enqueue(ep); | ||
1760 | } | ||
1761 | break; | ||
1762 | case "Plugins": | ||
1763 | instance.PluginData = ReadList(part).Data; | ||
1764 | break; | ||
1765 | } | ||
1766 | } | ||
1767 | } | ||
1768 | } | ||
1769 | |||
1770 | private static void DumpList(XmlDocument doc, XmlNode parent, | ||
1771 | LSL_Types.list l) | ||
1772 | { | ||
1773 | foreach (Object o in l.Data) | ||
1774 | WriteTypedValue(doc, parent, "ListItem", "", o); | ||
1775 | } | ||
1776 | |||
1777 | private static LSL_Types.list ReadList(XmlNode parent) | ||
1778 | { | ||
1779 | List<Object> olist = new List<Object>(); | ||
1780 | |||
1781 | XmlNodeList itemL = parent.ChildNodes; | ||
1782 | foreach (XmlNode item in itemL) | ||
1783 | olist.Add(ReadTypedValue(item)); | ||
1784 | |||
1785 | return new LSL_Types.list(olist.ToArray()); | ||
1786 | } | ||
1787 | |||
1788 | private static void WriteTypedValue(XmlDocument doc, XmlNode parent, | ||
1789 | string tag, string name, object value) | ||
1790 | { | ||
1791 | Type t=value.GetType(); | ||
1792 | XmlAttribute typ = doc.CreateAttribute("", "type", ""); | ||
1793 | XmlNode n = doc.CreateElement("", tag, ""); | ||
1794 | |||
1795 | if (value is LSL_Types.list) | ||
1796 | { | ||
1797 | typ.Value = "list"; | ||
1798 | n.Attributes.Append(typ); | ||
1799 | |||
1800 | DumpList(doc, n, (LSL_Types.list) value); | ||
1801 | |||
1802 | if (name != String.Empty) | ||
1803 | { | ||
1804 | XmlAttribute nam = doc.CreateAttribute("", "name", ""); | ||
1805 | nam.Value = name; | ||
1806 | n.Attributes.Append(nam); | ||
1807 | } | ||
1808 | |||
1809 | parent.AppendChild(n); | ||
1810 | return; | ||
1811 | } | ||
1812 | |||
1813 | n.AppendChild(doc.CreateTextNode(value.ToString())); | ||
1814 | |||
1815 | typ.Value = t.ToString(); | ||
1816 | n.Attributes.Append(typ); | ||
1817 | if (name != String.Empty) | ||
1818 | { | ||
1819 | XmlAttribute nam = doc.CreateAttribute("", "name", ""); | ||
1820 | nam.Value = name; | ||
1821 | n.Attributes.Append(nam); | ||
1822 | } | ||
1823 | |||
1824 | parent.AppendChild(n); | ||
1825 | } | ||
1826 | |||
1827 | private static object ReadTypedValue(XmlNode tag, out string name) | ||
1828 | { | ||
1829 | name = tag.Attributes.GetNamedItem("name").Value; | ||
1830 | |||
1831 | return ReadTypedValue(tag); | ||
1832 | } | ||
1833 | |||
1834 | private static object ReadTypedValue(XmlNode tag) | ||
1835 | { | ||
1836 | Object varValue; | ||
1837 | string assembly; | ||
1838 | |||
1839 | string itemType = tag.Attributes.GetNamedItem("type").Value; | ||
1840 | |||
1841 | if (itemType == "list") | ||
1842 | return ReadList(tag); | ||
1843 | |||
1844 | if (itemType == "libsecondlife.LLUUID") | ||
1845 | { | ||
1846 | LLUUID val = new LLUUID(); | ||
1847 | LLUUID.TryParse(tag.InnerText, out val); | ||
1848 | |||
1849 | return val; | ||
1850 | } | ||
1851 | |||
1852 | Type itemT = Type.GetType(itemType); | ||
1853 | if (itemT == null) | ||
1854 | { | ||
1855 | Object[] args = | ||
1856 | new Object[] { tag.InnerText }; | ||
1857 | |||
1858 | assembly = itemType+", OpenSim.Region.ScriptEngine.Shared"; | ||
1859 | itemT = Type.GetType(assembly); | ||
1860 | if (itemT == null) | ||
1861 | return null; | ||
1862 | |||
1863 | varValue = Activator.CreateInstance(itemT, args); | ||
1864 | |||
1865 | if (varValue == null) | ||
1866 | return null; | ||
1867 | } | ||
1868 | else | ||
1869 | { | ||
1870 | varValue = Convert.ChangeType(tag.InnerText, itemT); | ||
1871 | } | ||
1872 | return varValue; | ||
1873 | } | ||
1874 | } | ||
1875 | } | 855 | } |