aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Common/ScriptEngineBase')
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AppDomainManager.cs476
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/Common.cs114
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventManager.cs518
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs726
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/LSLLongCmdHandler.cs588
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs262
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs694
7 files changed, 1689 insertions, 1689 deletions
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AppDomainManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AppDomainManager.cs
index df00d4e..68ad88d 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AppDomainManager.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AppDomainManager.cs
@@ -1,239 +1,239 @@
1/* 1/*
2* Copyright (c) Contributors, http://opensimulator.org/ 2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders. 3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4* 4*
5* Redistribution and use in source and binary forms, with or without 5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met: 6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright 7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer. 8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright 9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the 10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution. 11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the 12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products 13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission. 14* derived from this software without specific prior written permission.
15* 15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY 16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 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 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 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 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. 25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26* 26*
27*/ 27*/
28 28
29 29
30using System; 30using System;
31using System.Collections; 31using System.Collections;
32using System.Collections.Generic; 32using System.Collections.Generic;
33using System.Reflection; 33using System.Reflection;
34using OpenSim.Region.ScriptEngine.Common; 34using OpenSim.Region.ScriptEngine.Common;
35 35
36namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase 36namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
37{ 37{
38 public class AppDomainManager 38 public class AppDomainManager
39 { 39 {
40 40
41 // 41 //
42 // This class does AppDomain handling and loading/unloading of scripts in it. 42 // This class does AppDomain handling and loading/unloading of scripts in it.
43 // It is instanced in "ScriptEngine" and controlled from "ScriptManager" 43 // It is instanced in "ScriptEngine" and controlled from "ScriptManager"
44 // 44 //
45 // 1. Create a new AppDomain if old one is full (or doesn't exist) 45 // 1. Create a new AppDomain if old one is full (or doesn't exist)
46 // 2. Load scripts into AppDomain 46 // 2. Load scripts into AppDomain
47 // 3. Unload scripts from AppDomain (stopping them and marking them as inactive) 47 // 3. Unload scripts from AppDomain (stopping them and marking them as inactive)
48 // 4. Unload AppDomain completely when all scripts in it has stopped 48 // 4. Unload AppDomain completely when all scripts in it has stopped
49 // 49 //
50 50
51 51
52 private int maxScriptsPerAppDomain = 1; 52 private int maxScriptsPerAppDomain = 1;
53 53
54 /// <summary> 54 /// <summary>
55 /// Internal list of all AppDomains 55 /// Internal list of all AppDomains
56 /// </summary> 56 /// </summary>
57 private List<AppDomainStructure> appDomains = new List<AppDomainStructure>(); 57 private List<AppDomainStructure> appDomains = new List<AppDomainStructure>();
58 58
59 /// <summary> 59 /// <summary>
60 /// Structure to keep track of data around AppDomain 60 /// Structure to keep track of data around AppDomain
61 /// </summary> 61 /// </summary>
62 private class AppDomainStructure 62 private class AppDomainStructure
63 { 63 {
64 /// <summary> 64 /// <summary>
65 /// The AppDomain itself 65 /// The AppDomain itself
66 /// </summary> 66 /// </summary>
67 public AppDomain CurrentAppDomain; 67 public AppDomain CurrentAppDomain;
68 68
69 /// <summary> 69 /// <summary>
70 /// Number of scripts loaded into AppDomain 70 /// Number of scripts loaded into AppDomain
71 /// </summary> 71 /// </summary>
72 public int ScriptsLoaded; 72 public int ScriptsLoaded;
73 73
74 /// <summary> 74 /// <summary>
75 /// Number of dead scripts 75 /// Number of dead scripts
76 /// </summary> 76 /// </summary>
77 public int ScriptsWaitingUnload; 77 public int ScriptsWaitingUnload;
78 } 78 }
79 79
80 /// <summary> 80 /// <summary>
81 /// Current AppDomain 81 /// Current AppDomain
82 /// </summary> 82 /// </summary>
83 private AppDomainStructure currentAD; 83 private AppDomainStructure currentAD;
84 84
85 private object getLock = new object(); // Mutex 85 private object getLock = new object(); // Mutex
86 private object freeLock = new object(); // Mutex 86 private object freeLock = new object(); // Mutex
87 87
88 //private ScriptEngine m_scriptEngine; 88 //private ScriptEngine m_scriptEngine;
89 //public AppDomainManager(ScriptEngine scriptEngine) 89 //public AppDomainManager(ScriptEngine scriptEngine)
90 public AppDomainManager() 90 public AppDomainManager()
91 { 91 {
92 //m_scriptEngine = scriptEngine; 92 //m_scriptEngine = scriptEngine;
93 } 93 }
94 94
95 /// <summary> 95 /// <summary>
96 /// Find a free AppDomain, creating one if necessary 96 /// Find a free AppDomain, creating one if necessary
97 /// </summary> 97 /// </summary>
98 /// <returns>Free AppDomain</returns> 98 /// <returns>Free AppDomain</returns>
99 private AppDomainStructure GetFreeAppDomain() 99 private AppDomainStructure GetFreeAppDomain()
100 { 100 {
101 Console.WriteLine("Finding free AppDomain"); 101 Console.WriteLine("Finding free AppDomain");
102 lock (getLock) 102 lock (getLock)
103 { 103 {
104 // Current full? 104 // Current full?
105 if (currentAD != null && currentAD.ScriptsLoaded >= maxScriptsPerAppDomain) 105 if (currentAD != null && currentAD.ScriptsLoaded >= maxScriptsPerAppDomain)
106 { 106 {
107 // Add it to AppDomains list and empty current 107 // Add it to AppDomains list and empty current
108 appDomains.Add(currentAD); 108 appDomains.Add(currentAD);
109 currentAD = null; 109 currentAD = null;
110 } 110 }
111 // No current 111 // No current
112 if (currentAD == null) 112 if (currentAD == null)
113 { 113 {
114 // Create a new current AppDomain 114 // Create a new current AppDomain
115 currentAD = new AppDomainStructure(); 115 currentAD = new AppDomainStructure();
116 currentAD.CurrentAppDomain = PrepareNewAppDomain(); 116 currentAD.CurrentAppDomain = PrepareNewAppDomain();
117 } 117 }
118 118
119 Console.WriteLine("Scripts loaded in this Appdomain: " + currentAD.ScriptsLoaded); 119 Console.WriteLine("Scripts loaded in this Appdomain: " + currentAD.ScriptsLoaded);
120 return currentAD; 120 return currentAD;
121 } // lock 121 } // lock
122 } 122 }
123 123
124 private int AppDomainNameCount; 124 private int AppDomainNameCount;
125 125
126 /// <summary> 126 /// <summary>
127 /// Create and prepare a new AppDomain for scripts 127 /// Create and prepare a new AppDomain for scripts
128 /// </summary> 128 /// </summary>
129 /// <returns>The new AppDomain</returns> 129 /// <returns>The new AppDomain</returns>
130 private AppDomain PrepareNewAppDomain() 130 private AppDomain PrepareNewAppDomain()
131 { 131 {
132 // Create and prepare a new AppDomain 132 // Create and prepare a new AppDomain
133 AppDomainNameCount++; 133 AppDomainNameCount++;
134 // TODO: Currently security match current appdomain 134 // TODO: Currently security match current appdomain
135 135
136 // Construct and initialize settings for a second AppDomain. 136 // Construct and initialize settings for a second AppDomain.
137 AppDomainSetup ads = new AppDomainSetup(); 137 AppDomainSetup ads = new AppDomainSetup();
138 ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory; 138 ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
139 ads.DisallowBindingRedirects = false; 139 ads.DisallowBindingRedirects = false;
140 ads.DisallowCodeDownload = true; 140 ads.DisallowCodeDownload = true;
141 ads.LoaderOptimization = LoaderOptimization.MultiDomain; // Sounds good ;) 141 ads.LoaderOptimization = LoaderOptimization.MultiDomain; // Sounds good ;)
142 ads.ShadowCopyFiles = "true"; // Enabled shadowing 142 ads.ShadowCopyFiles = "true"; // Enabled shadowing
143 ads.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; 143 ads.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
144 144
145 AppDomain AD = AppDomain.CreateDomain("ScriptAppDomain_" + AppDomainNameCount, null, ads); 145 AppDomain AD = AppDomain.CreateDomain("ScriptAppDomain_" + AppDomainNameCount, null, ads);
146 Console.WriteLine("Loading: " + 146 Console.WriteLine("Loading: " +
147 AssemblyName.GetAssemblyName("OpenSim.Region.ScriptEngine.Common.dll").ToString()); 147 AssemblyName.GetAssemblyName("OpenSim.Region.ScriptEngine.Common.dll").ToString());
148 AD.Load(AssemblyName.GetAssemblyName("OpenSim.Region.ScriptEngine.Common.dll")); 148 AD.Load(AssemblyName.GetAssemblyName("OpenSim.Region.ScriptEngine.Common.dll"));
149 149
150 // Return the new AppDomain 150 // Return the new AppDomain
151 return AD; 151 return AD;
152 } 152 }
153 153
154 /// <summary> 154 /// <summary>
155 /// Unload appdomains that are full and have only dead scripts 155 /// Unload appdomains that are full and have only dead scripts
156 /// </summary> 156 /// </summary>
157 private void UnloadAppDomains() 157 private void UnloadAppDomains()
158 { 158 {
159 lock (freeLock) 159 lock (freeLock)
160 { 160 {
161 // Go through all 161 // Go through all
162 foreach (AppDomainStructure ads in new ArrayList(appDomains)) 162 foreach (AppDomainStructure ads in new ArrayList(appDomains))
163 { 163 {
164 // Don't process current AppDomain 164 // Don't process current AppDomain
165 if (ads.CurrentAppDomain != currentAD.CurrentAppDomain) 165 if (ads.CurrentAppDomain != currentAD.CurrentAppDomain)
166 { 166 {
167 // Not current AppDomain 167 // Not current AppDomain
168 // Is number of unloaded bigger or equal to number of loaded? 168 // Is number of unloaded bigger or equal to number of loaded?
169 if (ads.ScriptsLoaded <= ads.ScriptsWaitingUnload) 169 if (ads.ScriptsLoaded <= ads.ScriptsWaitingUnload)
170 { 170 {
171 Console.WriteLine("Found empty AppDomain, unloading"); 171 Console.WriteLine("Found empty AppDomain, unloading");
172 // Remove from internal list 172 // Remove from internal list
173 appDomains.Remove(ads); 173 appDomains.Remove(ads);
174#if DEBUG 174#if DEBUG
175 long m = GC.GetTotalMemory(true); 175 long m = GC.GetTotalMemory(true);
176#endif 176#endif
177 // Unload 177 // Unload
178 AppDomain.Unload(ads.CurrentAppDomain); 178 AppDomain.Unload(ads.CurrentAppDomain);
179#if DEBUG 179#if DEBUG
180 Console.WriteLine("AppDomain unload freed " + (m - GC.GetTotalMemory(true)) + 180 Console.WriteLine("AppDomain unload freed " + (m - GC.GetTotalMemory(true)) +
181 " bytes of memory"); 181 " bytes of memory");
182#endif 182#endif
183 } 183 }
184 } 184 }
185 } // foreach 185 } // foreach
186 } // lock 186 } // lock
187 } 187 }
188 188
189 189
190 public IScript LoadScript(string FileName) 190 public IScript LoadScript(string FileName)
191 { 191 {
192 // Find next available AppDomain to put it in 192 // Find next available AppDomain to put it in
193 AppDomainStructure FreeAppDomain = GetFreeAppDomain(); 193 AppDomainStructure FreeAppDomain = GetFreeAppDomain();
194 194
195 Console.WriteLine("Loading into AppDomain: " + FileName); 195 Console.WriteLine("Loading into AppDomain: " + FileName);
196 IScript mbrt = 196 IScript mbrt =
197 (IScript) 197 (IScript)
198 FreeAppDomain.CurrentAppDomain.CreateInstanceFromAndUnwrap(FileName, "SecondLife.Script"); 198 FreeAppDomain.CurrentAppDomain.CreateInstanceFromAndUnwrap(FileName, "SecondLife.Script");
199 //Console.WriteLine("ScriptEngine AppDomainManager: is proxy={0}", RemotingServices.IsTransparentProxy(mbrt)); 199 //Console.WriteLine("ScriptEngine AppDomainManager: is proxy={0}", RemotingServices.IsTransparentProxy(mbrt));
200 FreeAppDomain.ScriptsLoaded++; 200 FreeAppDomain.ScriptsLoaded++;
201 201
202 return mbrt; 202 return mbrt;
203 } 203 }
204 204
205 205
206 /// <summary> 206 /// <summary>
207 /// Increase "dead script" counter for an AppDomain 207 /// Increase "dead script" counter for an AppDomain
208 /// </summary> 208 /// </summary>
209 /// <param name="ad"></param> 209 /// <param name="ad"></param>
210 //[Obsolete("Needs fixing, needs a real purpose in life!!!")] 210 //[Obsolete("Needs fixing, needs a real purpose in life!!!")]
211 public void StopScript(AppDomain ad) 211 public void StopScript(AppDomain ad)
212 { 212 {
213 lock (freeLock) 213 lock (freeLock)
214 { 214 {
215 Console.WriteLine("Stopping script in AppDomain"); 215 Console.WriteLine("Stopping script in AppDomain");
216 // Check if it is current AppDomain 216 // Check if it is current AppDomain
217 if (currentAD.CurrentAppDomain == ad) 217 if (currentAD.CurrentAppDomain == ad)
218 { 218 {
219 // Yes - increase 219 // Yes - increase
220 currentAD.ScriptsWaitingUnload++; 220 currentAD.ScriptsWaitingUnload++;
221 return; 221 return;
222 } 222 }
223 223
224 // Lopp through all AppDomains 224 // Lopp through all AppDomains
225 foreach (AppDomainStructure ads in new ArrayList(appDomains)) 225 foreach (AppDomainStructure ads in new ArrayList(appDomains))
226 { 226 {
227 if (ads.CurrentAppDomain == ad) 227 if (ads.CurrentAppDomain == ad)
228 { 228 {
229 // Found it 229 // Found it
230 ads.ScriptsWaitingUnload++; 230 ads.ScriptsWaitingUnload++;
231 break; 231 break;
232 } 232 }
233 } // foreach 233 } // foreach
234 } // lock 234 } // lock
235 235
236 UnloadAppDomains(); // Outsite lock, has its own GetLock 236 UnloadAppDomains(); // Outsite lock, has its own GetLock
237 } 237 }
238 } 238 }
239} \ No newline at end of file 239} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/Common.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/Common.cs
index b2eea38..bce26ff 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/Common.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/Common.cs
@@ -1,58 +1,58 @@
1/* 1/*
2* Copyright (c) Contributors, http://opensimulator.org/ 2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders. 3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4* 4*
5* Redistribution and use in source and binary forms, with or without 5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met: 6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright 7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer. 8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright 9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the 10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution. 11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the 12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products 13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission. 14* derived from this software without specific prior written permission.
15* 15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY 16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 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 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 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 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. 25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26* 26*
27*/ 27*/
28 28
29 29
30namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase 30namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
31{ 31{
32 public static class Common 32 public static class Common
33 { 33 {
34 public static bool debug = true; 34 public static bool debug = true;
35 public static ScriptEngine mySE; 35 public static ScriptEngine mySE;
36 36
37 // This class just contains some static log stuff used for debugging. 37 // This class just contains some static log stuff used for debugging.
38 38
39 //public delegate void SendToDebugEventDelegate(string Message); 39 //public delegate void SendToDebugEventDelegate(string Message);
40 //public delegate void SendToLogEventDelegate(string Message); 40 //public delegate void SendToLogEventDelegate(string Message);
41 //static public event SendToDebugEventDelegate SendToDebugEvent; 41 //static public event SendToDebugEventDelegate SendToDebugEvent;
42 //static public event SendToLogEventDelegate SendToLogEvent; 42 //static public event SendToLogEventDelegate SendToLogEvent;
43 43
44 public static void SendToDebug(string Message) 44 public static void SendToDebug(string Message)
45 { 45 {
46 //if (Debug == true) 46 //if (Debug == true)
47 mySE.Log.Verbose("ScriptEngine", "Debug: " + Message); 47 mySE.Log.Verbose("ScriptEngine", "Debug: " + Message);
48 //SendToDebugEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + Message); 48 //SendToDebugEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + Message);
49 } 49 }
50 50
51 public static void SendToLog(string Message) 51 public static void SendToLog(string Message)
52 { 52 {
53 //if (Debug == true) 53 //if (Debug == true)
54 mySE.Log.Verbose("ScriptEngine", "LOG: " + Message); 54 mySE.Log.Verbose("ScriptEngine", "LOG: " + Message);
55 //SendToLogEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + Message); 55 //SendToLogEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + Message);
56 } 56 }
57 } 57 }
58} \ No newline at end of file 58} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventManager.cs
index 07476ac..6df8343 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventManager.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventManager.cs
@@ -1,260 +1,260 @@
1/* 1/*
2* Copyright (c) Contributors, http://opensimulator.org/ 2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders. 3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4* 4*
5* Redistribution and use in source and binary forms, with or without 5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met: 6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright 7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer. 8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright 9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the 10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution. 11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the 12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products 13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission. 14* derived from this software without specific prior written permission.
15* 15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY 16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 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 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 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 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. 25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26* 26*
27*/ 27*/
28 28
29 29
30using System; 30using System;
31using libsecondlife; 31using libsecondlife;
32using OpenSim.Framework; 32using OpenSim.Framework;
33 33
34namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase 34namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
35{ 35{
36 /// <summary> 36 /// <summary>
37 /// Prepares events so they can be directly executed upon a script by EventQueueManager, then queues it. 37 /// Prepares events so they can be directly executed upon a script by EventQueueManager, then queues it.
38 /// </summary> 38 /// </summary>
39 [Serializable] 39 [Serializable]
40 public class EventManager : OpenSim.Region.ScriptEngine.Common.ScriptServerInterfaces.RemoteEvents 40 public class EventManager : OpenSim.Region.ScriptEngine.Common.ScriptServerInterfaces.RemoteEvents
41 { 41 {
42 42
43 // 43 //
44 // Class is instanced in "ScriptEngine" and Uses "EventQueueManager" that is also instanced in "ScriptEngine". 44 // Class is instanced in "ScriptEngine" and Uses "EventQueueManager" that is also instanced in "ScriptEngine".
45 // This class needs a bit of explaining: 45 // This class needs a bit of explaining:
46 // 46 //
47 // This class it the link between an event inside OpenSim and the corresponding event in a user script being executed. 47 // This class it the link between an event inside OpenSim and the corresponding event in a user script being executed.
48 // 48 //
49 // For example when an user touches an object then the "myScriptEngine.World.EventManager.OnObjectGrab" event is fired inside OpenSim. 49 // For example when an user touches an object then the "myScriptEngine.World.EventManager.OnObjectGrab" event is fired inside OpenSim.
50 // We hook up to this event and queue a touch_start in EventQueueManager with the proper LSL parameters. 50 // We hook up to this event and queue a touch_start in EventQueueManager with the proper LSL parameters.
51 // It will then be delivered to the script by EventQueueManager. 51 // It will then be delivered to the script by EventQueueManager.
52 // 52 //
53 // You can check debug C# dump of an LSL script if you need to verify what exact parameters are needed. 53 // You can check debug C# dump of an LSL script if you need to verify what exact parameters are needed.
54 // 54 //
55 55
56 56
57 private ScriptEngine myScriptEngine; 57 private ScriptEngine myScriptEngine;
58 //public IScriptHost TEMP_OBJECT_ID; 58 //public IScriptHost TEMP_OBJECT_ID;
59 public EventManager(ScriptEngine _ScriptEngine, bool performHookUp) 59 public EventManager(ScriptEngine _ScriptEngine, bool performHookUp)
60 { 60 {
61 myScriptEngine = _ScriptEngine; 61 myScriptEngine = _ScriptEngine;
62 62
63 // Hook up to events from OpenSim 63 // Hook up to events from OpenSim
64 // We may not want to do it because someone is controlling us and will deliver events to us 64 // We may not want to do it because someone is controlling us and will deliver events to us
65 if (performHookUp) 65 if (performHookUp)
66 { 66 {
67 myScriptEngine.Log.Verbose("ScriptEngine", "Hooking up to server events"); 67 myScriptEngine.Log.Verbose("ScriptEngine", "Hooking up to server events");
68 myScriptEngine.World.EventManager.OnObjectGrab += touch_start; 68 myScriptEngine.World.EventManager.OnObjectGrab += touch_start;
69 myScriptEngine.World.EventManager.OnRezScript += OnRezScript; 69 myScriptEngine.World.EventManager.OnRezScript += OnRezScript;
70 myScriptEngine.World.EventManager.OnRemoveScript += OnRemoveScript; 70 myScriptEngine.World.EventManager.OnRemoveScript += OnRemoveScript;
71 // TODO: HOOK ALL EVENTS UP TO SERVER! 71 // TODO: HOOK ALL EVENTS UP TO SERVER!
72 } 72 }
73 } 73 }
74 74
75 public void touch_start(uint localID, LLVector3 offsetPos, IClientAPI remoteClient) 75 public void touch_start(uint localID, LLVector3 offsetPos, IClientAPI remoteClient)
76 { 76 {
77 // Add to queue for all scripts in ObjectID object 77 // Add to queue for all scripts in ObjectID object
78 myScriptEngine.m_EventQueueManager.AddToObjectQueue(localID, "touch_start", new object[] {(int) 1}); 78 myScriptEngine.m_EventQueueManager.AddToObjectQueue(localID, "touch_start", new object[] {(int) 1});
79 } 79 }
80 80
81 public void OnRezScript(uint localID, LLUUID itemID, string script) 81 public void OnRezScript(uint localID, LLUUID itemID, string script)
82 { 82 {
83 Console.WriteLine("OnRezScript localID: " + localID + " LLUID: " + itemID.ToString() + " Size: " + 83 Console.WriteLine("OnRezScript localID: " + localID + " LLUID: " + itemID.ToString() + " Size: " +
84 script.Length); 84 script.Length);
85 myScriptEngine.m_ScriptManager.StartScript(localID, itemID, script); 85 myScriptEngine.m_ScriptManager.StartScript(localID, itemID, script);
86 } 86 }
87 87
88 public void OnRemoveScript(uint localID, LLUUID itemID) 88 public void OnRemoveScript(uint localID, LLUUID itemID)
89 { 89 {
90 Console.WriteLine("OnRemoveScript localID: " + localID + " LLUID: " + itemID.ToString()); 90 Console.WriteLine("OnRemoveScript localID: " + localID + " LLUID: " + itemID.ToString());
91 myScriptEngine.m_ScriptManager.StopScript( 91 myScriptEngine.m_ScriptManager.StopScript(
92 localID, 92 localID,
93 itemID 93 itemID
94 ); 94 );
95 } 95 }
96 96
97 // TODO: Replace placeholders below 97 // TODO: Replace placeholders below
98 // NOTE! THE PARAMETERS FOR THESE FUNCTIONS ARE NOT CORRECT! 98 // NOTE! THE PARAMETERS FOR THESE FUNCTIONS ARE NOT CORRECT!
99 // These needs to be hooked up to OpenSim during init of this class 99 // These needs to be hooked up to OpenSim during init of this class
100 // then queued in EventQueueManager. 100 // then queued in EventQueueManager.
101 // When queued in EventQueueManager they need to be LSL compatible (name and params) 101 // When queued in EventQueueManager they need to be LSL compatible (name and params)
102 102
103 public void state_exit(uint localID, LLUUID itemID) 103 public void state_exit(uint localID, LLUUID itemID)
104 { 104 {
105 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "state_exit"); 105 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "state_exit");
106 } 106 }
107 107
108 public void touch(uint localID, LLUUID itemID) 108 public void touch(uint localID, LLUUID itemID)
109 { 109 {
110 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "touch"); 110 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "touch");
111 } 111 }
112 112
113 public void touch_end(uint localID, LLUUID itemID) 113 public void touch_end(uint localID, LLUUID itemID)
114 { 114 {
115 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "touch_end"); 115 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "touch_end");
116 } 116 }
117 117
118 public void collision_start(uint localID, LLUUID itemID) 118 public void collision_start(uint localID, LLUUID itemID)
119 { 119 {
120 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "collision_start"); 120 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "collision_start");
121 } 121 }
122 122
123 public void collision(uint localID, LLUUID itemID) 123 public void collision(uint localID, LLUUID itemID)
124 { 124 {
125 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "collision"); 125 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "collision");
126 } 126 }
127 127
128 public void collision_end(uint localID, LLUUID itemID) 128 public void collision_end(uint localID, LLUUID itemID)
129 { 129 {
130 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "collision_end"); 130 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "collision_end");
131 } 131 }
132 132
133 public void land_collision_start(uint localID, LLUUID itemID) 133 public void land_collision_start(uint localID, LLUUID itemID)
134 { 134 {
135 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "land_collision_start"); 135 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "land_collision_start");
136 } 136 }
137 137
138 public void land_collision(uint localID, LLUUID itemID) 138 public void land_collision(uint localID, LLUUID itemID)
139 { 139 {
140 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "land_collision"); 140 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "land_collision");
141 } 141 }
142 142
143 public void land_collision_end(uint localID, LLUUID itemID) 143 public void land_collision_end(uint localID, LLUUID itemID)
144 { 144 {
145 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "land_collision_end"); 145 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "land_collision_end");
146 } 146 }
147 147
148 // Handled by long commands 148 // Handled by long commands
149 public void timer(uint localID, LLUUID itemID) 149 public void timer(uint localID, LLUUID itemID)
150 { 150 {
151 //myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, ""); 151 //myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "");
152 } 152 }
153 153
154 public void listen(uint localID, LLUUID itemID) 154 public void listen(uint localID, LLUUID itemID)
155 { 155 {
156 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "listen"); 156 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "listen");
157 } 157 }
158 158
159 public void on_rez(uint localID, LLUUID itemID) 159 public void on_rez(uint localID, LLUUID itemID)
160 { 160 {
161 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "on_rez"); 161 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "on_rez");
162 } 162 }
163 163
164 public void sensor(uint localID, LLUUID itemID) 164 public void sensor(uint localID, LLUUID itemID)
165 { 165 {
166 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "sensor"); 166 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "sensor");
167 } 167 }
168 168
169 public void no_sensor(uint localID, LLUUID itemID) 169 public void no_sensor(uint localID, LLUUID itemID)
170 { 170 {
171 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "no_sensor"); 171 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "no_sensor");
172 } 172 }
173 173
174 public void control(uint localID, LLUUID itemID) 174 public void control(uint localID, LLUUID itemID)
175 { 175 {
176 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "control"); 176 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "control");
177 } 177 }
178 178
179 public void money(uint localID, LLUUID itemID) 179 public void money(uint localID, LLUUID itemID)
180 { 180 {
181 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "money"); 181 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "money");
182 } 182 }
183 183
184 public void email(uint localID, LLUUID itemID) 184 public void email(uint localID, LLUUID itemID)
185 { 185 {
186 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "email"); 186 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "email");
187 } 187 }
188 188
189 public void at_target(uint localID, LLUUID itemID) 189 public void at_target(uint localID, LLUUID itemID)
190 { 190 {
191 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "at_target"); 191 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "at_target");
192 } 192 }
193 193
194 public void not_at_target(uint localID, LLUUID itemID) 194 public void not_at_target(uint localID, LLUUID itemID)
195 { 195 {
196 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "not_at_target"); 196 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "not_at_target");
197 } 197 }
198 198
199 public void at_rot_target(uint localID, LLUUID itemID) 199 public void at_rot_target(uint localID, LLUUID itemID)
200 { 200 {
201 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "at_rot_target"); 201 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "at_rot_target");
202 } 202 }
203 203
204 public void not_at_rot_target(uint localID, LLUUID itemID) 204 public void not_at_rot_target(uint localID, LLUUID itemID)
205 { 205 {
206 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "not_at_rot_target"); 206 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "not_at_rot_target");
207 } 207 }
208 208
209 public void run_time_permissions(uint localID, LLUUID itemID) 209 public void run_time_permissions(uint localID, LLUUID itemID)
210 { 210 {
211 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "run_time_permissions"); 211 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "run_time_permissions");
212 } 212 }
213 213
214 public void changed(uint localID, LLUUID itemID) 214 public void changed(uint localID, LLUUID itemID)
215 { 215 {
216 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "changed"); 216 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "changed");
217 } 217 }
218 218
219 public void attach(uint localID, LLUUID itemID) 219 public void attach(uint localID, LLUUID itemID)
220 { 220 {
221 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "attach"); 221 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "attach");
222 } 222 }
223 223
224 public void dataserver(uint localID, LLUUID itemID) 224 public void dataserver(uint localID, LLUUID itemID)
225 { 225 {
226 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "dataserver"); 226 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "dataserver");
227 } 227 }
228 228
229 public void link_message(uint localID, LLUUID itemID) 229 public void link_message(uint localID, LLUUID itemID)
230 { 230 {
231 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "link_message"); 231 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "link_message");
232 } 232 }
233 233
234 public void moving_start(uint localID, LLUUID itemID) 234 public void moving_start(uint localID, LLUUID itemID)
235 { 235 {
236 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "moving_start"); 236 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "moving_start");
237 } 237 }
238 238
239 public void moving_end(uint localID, LLUUID itemID) 239 public void moving_end(uint localID, LLUUID itemID)
240 { 240 {
241 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "moving_end"); 241 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "moving_end");
242 } 242 }
243 243
244 public void object_rez(uint localID, LLUUID itemID) 244 public void object_rez(uint localID, LLUUID itemID)
245 { 245 {
246 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "object_rez"); 246 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "object_rez");
247 } 247 }
248 248
249 public void remote_data(uint localID, LLUUID itemID) 249 public void remote_data(uint localID, LLUUID itemID)
250 { 250 {
251 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "remote_data"); 251 myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "remote_data");
252 } 252 }
253 253
254 // Handled by long commands 254 // Handled by long commands
255 public void http_response(uint localID, LLUUID itemID) 255 public void http_response(uint localID, LLUUID itemID)
256 { 256 {
257 // myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "http_response"); 257 // myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "http_response");
258 } 258 }
259 } 259 }
260} \ No newline at end of file 260} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs
index ad9ff45..8081e2c 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs
@@ -1,364 +1,364 @@
1/* 1/*
2* Copyright (c) Contributors, http://opensimulator.org/ 2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders. 3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4* 4*
5* Redistribution and use in source and binary forms, with or without 5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met: 6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright 7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer. 8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright 9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the 10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution. 11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the 12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products 13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission. 14* derived from this software without specific prior written permission.
15* 15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY 16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 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 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 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 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. 25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26* 26*
27*/ 27*/
28 28
29 29
30using System; 30using System;
31using System.Collections; 31using System.Collections;
32using System.Collections.Generic; 32using System.Collections.Generic;
33using System.Threading; 33using System.Threading;
34using libsecondlife; 34using libsecondlife;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.Environment.Scenes.Scripting; 36using OpenSim.Region.Environment.Scenes.Scripting;
37 37
38namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase 38namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
39{ 39{
40 /// <summary> 40 /// <summary>
41 /// EventQueueManager handles event queues 41 /// EventQueueManager handles event queues
42 /// Events are queued and executed in separate thread 42 /// Events are queued and executed in separate thread
43 /// </summary> 43 /// </summary>
44 [Serializable] 44 [Serializable]
45 public class EventQueueManager 45 public class EventQueueManager
46 { 46 {
47 47
48 // 48 //
49 // Class is instanced in "ScriptEngine" and used by "EventManager" also instanced in "ScriptEngine". 49 // Class is instanced in "ScriptEngine" and used by "EventManager" also instanced in "ScriptEngine".
50 // 50 //
51 // Class purpose is to queue and execute functions that are received by "EventManager": 51 // Class purpose is to queue and execute functions that are received by "EventManager":
52 // - allowing "EventManager" to release its event thread immediately, thus not interrupting server execution. 52 // - allowing "EventManager" to release its event thread immediately, thus not interrupting server execution.
53 // - allowing us to prioritize and control execution of script functions. 53 // - allowing us to prioritize and control execution of script functions.
54 // Class can use multiple threads for simultaneous execution. Mutexes are used for thread safety. 54 // Class can use multiple threads for simultaneous execution. Mutexes are used for thread safety.
55 // 55 //
56 // 1. Hold an execution queue for scripts 56 // 1. Hold an execution queue for scripts
57 // 2. Use threads to process queue, each thread executes one script function on each pass. 57 // 2. Use threads to process queue, each thread executes one script function on each pass.
58 // 3. Catch any script error and process it 58 // 3. Catch any script error and process it
59 // 59 //
60 // 60 //
61 // Notes: 61 // Notes:
62 // * Current execution load balancing is optimized for 1 thread, and can cause unfair execute balancing between scripts. 62 // * Current execution load balancing is optimized for 1 thread, and can cause unfair execute balancing between scripts.
63 // Not noticeable unless server is under high load. 63 // Not noticeable unless server is under high load.
64 // * This class contains the number of threads used for script executions. Since we are not microthreading scripts yet, 64 // * This class contains the number of threads used for script executions. Since we are not microthreading scripts yet,
65 // increase number of threads to allow more concurrent script executions in OpenSim. 65 // increase number of threads to allow more concurrent script executions in OpenSim.
66 // 66 //
67 67
68 68
69 /// <summary> 69 /// <summary>
70 /// List of threads processing event queue 70 /// List of threads processing event queue
71 /// </summary> 71 /// </summary>
72 private List<Thread> eventQueueThreads = new List<Thread>(); 72 private List<Thread> eventQueueThreads = new List<Thread>();
73 73
74 private object queueLock = new object(); // Mutex lock object 74 private object queueLock = new object(); // Mutex lock object
75 75
76 /// <summary> 76 /// <summary>
77 /// How many ms to sleep if queue is empty 77 /// How many ms to sleep if queue is empty
78 /// </summary> 78 /// </summary>
79 private int nothingToDoSleepms = 50; 79 private int nothingToDoSleepms = 50;
80 80
81 /// <summary> 81 /// <summary>
82 /// How many threads to process queue with 82 /// How many threads to process queue with
83 /// </summary> 83 /// </summary>
84 private int numberOfThreads = 2; 84 private int numberOfThreads = 2;
85 85
86 /// <summary> 86 /// <summary>
87 /// Queue containing events waiting to be executed 87 /// Queue containing events waiting to be executed
88 /// </summary> 88 /// </summary>
89 private Queue<QueueItemStruct> eventQueue = new Queue<QueueItemStruct>(); 89 private Queue<QueueItemStruct> eventQueue = new Queue<QueueItemStruct>();
90 90
91 /// <summary> 91 /// <summary>
92 /// Queue item structure 92 /// Queue item structure
93 /// </summary> 93 /// </summary>
94 private struct QueueItemStruct 94 private struct QueueItemStruct
95 { 95 {
96 public uint localID; 96 public uint localID;
97 public LLUUID itemID; 97 public LLUUID itemID;
98 public string functionName; 98 public string functionName;
99 public object[] param; 99 public object[] param;
100 } 100 }
101 101
102 /// <summary> 102 /// <summary>
103 /// List of localID locks for mutex processing of script events 103 /// List of localID locks for mutex processing of script events
104 /// </summary> 104 /// </summary>
105 private List<uint> objectLocks = new List<uint>(); 105 private List<uint> objectLocks = new List<uint>();
106 106
107 private object tryLockLock = new object(); // Mutex lock object 107 private object tryLockLock = new object(); // Mutex lock object
108 108
109 private ScriptEngine m_ScriptEngine; 109 private ScriptEngine m_ScriptEngine;
110 110
111 public EventQueueManager(ScriptEngine _ScriptEngine) 111 public EventQueueManager(ScriptEngine _ScriptEngine)
112 { 112 {
113 m_ScriptEngine = _ScriptEngine; 113 m_ScriptEngine = _ScriptEngine;
114 114
115 // 115 //
116 // Start event queue processing threads (worker threads) 116 // Start event queue processing threads (worker threads)
117 // 117 //
118 for (int ThreadCount = 0; ThreadCount <= numberOfThreads; ThreadCount++) 118 for (int ThreadCount = 0; ThreadCount <= numberOfThreads; ThreadCount++)
119 { 119 {
120 Thread EventQueueThread = new Thread(EventQueueThreadLoop); 120 Thread EventQueueThread = new Thread(EventQueueThreadLoop);
121 eventQueueThreads.Add(EventQueueThread); 121 eventQueueThreads.Add(EventQueueThread);
122 EventQueueThread.IsBackground = true; 122 EventQueueThread.IsBackground = true;
123 EventQueueThread.Priority = ThreadPriority.BelowNormal; 123 EventQueueThread.Priority = ThreadPriority.BelowNormal;
124 EventQueueThread.Name = "EventQueueManagerThread_" + ThreadCount; 124 EventQueueThread.Name = "EventQueueManagerThread_" + ThreadCount;
125 EventQueueThread.Start(); 125 EventQueueThread.Start();
126 } 126 }
127 } 127 }
128 128
129 ~EventQueueManager() 129 ~EventQueueManager()
130 { 130 {
131 // Kill worker threads 131 // Kill worker threads
132 foreach (Thread EventQueueThread in new ArrayList(eventQueueThreads)) 132 foreach (Thread EventQueueThread in new ArrayList(eventQueueThreads))
133 { 133 {
134 if (EventQueueThread != null && EventQueueThread.IsAlive == true) 134 if (EventQueueThread != null && EventQueueThread.IsAlive == true)
135 { 135 {
136 try 136 try
137 { 137 {
138 EventQueueThread.Abort(); 138 EventQueueThread.Abort();
139 EventQueueThread.Join(); 139 EventQueueThread.Join();
140 } 140 }
141 catch (Exception) 141 catch (Exception)
142 { 142 {
143 //myScriptEngine.Log.Verbose("ScriptEngine", "EventQueueManager Exception killing worker thread: " + e.ToString()); 143 //myScriptEngine.Log.Verbose("ScriptEngine", "EventQueueManager Exception killing worker thread: " + e.ToString());
144 } 144 }
145 } 145 }
146 } 146 }
147 eventQueueThreads.Clear(); 147 eventQueueThreads.Clear();
148 // Todo: Clean up our queues 148 // Todo: Clean up our queues
149 eventQueue.Clear(); 149 eventQueue.Clear();
150 } 150 }
151 151
152 /// <summary> 152 /// <summary>
153 /// Queue processing thread loop 153 /// Queue processing thread loop
154 /// </summary> 154 /// </summary>
155 private void EventQueueThreadLoop() 155 private void EventQueueThreadLoop()
156 { 156 {
157 //myScriptEngine.m_logger.Verbose("ScriptEngine", "EventQueueManager Worker thread spawned"); 157 //myScriptEngine.m_logger.Verbose("ScriptEngine", "EventQueueManager Worker thread spawned");
158 try 158 try
159 { 159 {
160 QueueItemStruct BlankQIS = new QueueItemStruct(); 160 QueueItemStruct BlankQIS = new QueueItemStruct();
161 while (true) 161 while (true)
162 { 162 {
163 try 163 try
164 { 164 {
165 QueueItemStruct QIS = BlankQIS; 165 QueueItemStruct QIS = BlankQIS;
166 bool GotItem = false; 166 bool GotItem = false;
167 167
168 if (eventQueue.Count == 0) 168 if (eventQueue.Count == 0)
169 { 169 {
170 // Nothing to do? Sleep a bit waiting for something to do 170 // Nothing to do? Sleep a bit waiting for something to do
171 Thread.Sleep(nothingToDoSleepms); 171 Thread.Sleep(nothingToDoSleepms);
172 } 172 }
173 else 173 else
174 { 174 {
175 // Something in queue, process 175 // Something in queue, process
176 //myScriptEngine.m_logger.Verbose("ScriptEngine", "Processing event for localID: " + QIS.localID + ", itemID: " + QIS.itemID + ", FunctionName: " + QIS.FunctionName); 176 //myScriptEngine.m_logger.Verbose("ScriptEngine", "Processing event for localID: " + QIS.localID + ", itemID: " + QIS.itemID + ", FunctionName: " + QIS.FunctionName);
177 177
178 // OBJECT BASED LOCK - TWO THREADS WORKING ON SAME OBJECT IS NOT GOOD 178 // OBJECT BASED LOCK - TWO THREADS WORKING ON SAME OBJECT IS NOT GOOD
179 lock (queueLock) 179 lock (queueLock)
180 { 180 {
181 GotItem = false; 181 GotItem = false;
182 for (int qc = 0; qc < eventQueue.Count; qc++) 182 for (int qc = 0; qc < eventQueue.Count; qc++)
183 { 183 {
184 // Get queue item 184 // Get queue item
185 QIS = eventQueue.Dequeue(); 185 QIS = eventQueue.Dequeue();
186 186
187 // Check if object is being processed by someone else 187 // Check if object is being processed by someone else
188 if (TryLock(QIS.localID) == false) 188 if (TryLock(QIS.localID) == false)
189 { 189 {
190 // Object is already being processed, requeue it 190 // Object is already being processed, requeue it
191 eventQueue.Enqueue(QIS); 191 eventQueue.Enqueue(QIS);
192 } 192 }
193 else 193 else
194 { 194 {
195 // We have lock on an object and can process it 195 // We have lock on an object and can process it
196 GotItem = true; 196 GotItem = true;
197 break; 197 break;
198 } 198 }
199 } // go through queue 199 } // go through queue
200 } // lock 200 } // lock
201 201
202 if (GotItem == true) 202 if (GotItem == true)
203 { 203 {
204 // Execute function 204 // Execute function
205 try 205 try
206 { 206 {
207#if DEBUG 207#if DEBUG
208 m_ScriptEngine.Log.Debug("ScriptEngine", "Executing event:\r\n" 208 m_ScriptEngine.Log.Debug("ScriptEngine", "Executing event:\r\n"
209 + "QIS.localID: " + QIS.localID 209 + "QIS.localID: " + QIS.localID
210 + ", QIS.itemID: " + QIS.itemID 210 + ", QIS.itemID: " + QIS.itemID
211 + ", QIS.functionName: " + QIS.functionName); 211 + ", QIS.functionName: " + QIS.functionName);
212#endif 212#endif
213 m_ScriptEngine.m_ScriptManager.ExecuteEvent(QIS.localID, QIS.itemID, 213 m_ScriptEngine.m_ScriptManager.ExecuteEvent(QIS.localID, QIS.itemID,
214 QIS.functionName, QIS.param); 214 QIS.functionName, QIS.param);
215 } 215 }
216 catch (Exception e) 216 catch (Exception e)
217 { 217 {
218 // DISPLAY ERROR INWORLD 218 // DISPLAY ERROR INWORLD
219 string text = "Error executing script function \"" + QIS.functionName + "\":\r\n"; 219 string text = "Error executing script function \"" + QIS.functionName + "\":\r\n";
220 //if (e.InnerException != null) 220 //if (e.InnerException != null)
221 //{ 221 //{
222 // Send inner exception 222 // Send inner exception
223 text += e.InnerException.Message.ToString(); 223 text += e.InnerException.Message.ToString();
224 //} 224 //}
225 //else 225 //else
226 //{ 226 //{
227 text += "\r\n"; 227 text += "\r\n";
228 // Send normal 228 // Send normal
229 text += e.Message.ToString(); 229 text += e.Message.ToString();
230 //} 230 //}
231 try 231 try
232 { 232 {
233 if (text.Length > 1500) 233 if (text.Length > 1500)
234 text = text.Substring(0, 1500); 234 text = text.Substring(0, 1500);
235 IScriptHost m_host = m_ScriptEngine.World.GetSceneObjectPart(QIS.localID); 235 IScriptHost m_host = m_ScriptEngine.World.GetSceneObjectPart(QIS.localID);
236 //if (m_host != null) 236 //if (m_host != null)
237 //{ 237 //{
238 m_ScriptEngine.World.SimChat(Helpers.StringToField(text), ChatTypeEnum.Say, 0, 238 m_ScriptEngine.World.SimChat(Helpers.StringToField(text), ChatTypeEnum.Say, 0,
239 m_host.AbsolutePosition, m_host.Name, m_host.UUID); 239 m_host.AbsolutePosition, m_host.Name, m_host.UUID);
240 } 240 }
241 catch 241 catch
242 { 242 {
243 //} 243 //}
244 //else 244 //else
245 //{ 245 //{
246 // T oconsole 246 // T oconsole
247 m_ScriptEngine.Log.Error("ScriptEngine", 247 m_ScriptEngine.Log.Error("ScriptEngine",
248 "Unable to send text in-world:\r\n" + text); 248 "Unable to send text in-world:\r\n" + text);
249 } 249 }
250 } 250 }
251 finally 251 finally
252 { 252 {
253 ReleaseLock(QIS.localID); 253 ReleaseLock(QIS.localID);
254 } 254 }
255 } 255 }
256 } // Something in queue 256 } // Something in queue
257 } 257 }
258 catch (ThreadAbortException tae) 258 catch (ThreadAbortException tae)
259 { 259 {
260 throw tae; 260 throw tae;
261 } 261 }
262 catch (Exception e) 262 catch (Exception e)
263 { 263 {
264 m_ScriptEngine.Log.Error("ScriptEngine", "Exception in EventQueueThreadLoop: " + e.ToString()); 264 m_ScriptEngine.Log.Error("ScriptEngine", "Exception in EventQueueThreadLoop: " + e.ToString());
265 } 265 }
266 } // while 266 } // while
267 } // try 267 } // try
268 catch (ThreadAbortException) 268 catch (ThreadAbortException)
269 { 269 {
270 //myScriptEngine.Log.Verbose("ScriptEngine", "EventQueueManager Worker thread killed: " + tae.Message); 270 //myScriptEngine.Log.Verbose("ScriptEngine", "EventQueueManager Worker thread killed: " + tae.Message);
271 } 271 }
272 } 272 }
273 273
274 /// <summary> 274 /// <summary>
275 /// Try to get a mutex lock on localID 275 /// Try to get a mutex lock on localID
276 /// </summary> 276 /// </summary>
277 /// <param name="localID"></param> 277 /// <param name="localID"></param>
278 /// <returns></returns> 278 /// <returns></returns>
279 private bool TryLock(uint localID) 279 private bool TryLock(uint localID)
280 { 280 {
281 lock (tryLockLock) 281 lock (tryLockLock)
282 { 282 {
283 if (objectLocks.Contains(localID) == true) 283 if (objectLocks.Contains(localID) == true)
284 { 284 {
285 return false; 285 return false;
286 } 286 }
287 else 287 else
288 { 288 {
289 objectLocks.Add(localID); 289 objectLocks.Add(localID);
290 return true; 290 return true;
291 } 291 }
292 } 292 }
293 } 293 }
294 294
295 /// <summary> 295 /// <summary>
296 /// Release mutex lock on localID 296 /// Release mutex lock on localID
297 /// </summary> 297 /// </summary>
298 /// <param name="localID"></param> 298 /// <param name="localID"></param>
299 private void ReleaseLock(uint localID) 299 private void ReleaseLock(uint localID)
300 { 300 {
301 lock (tryLockLock) 301 lock (tryLockLock)
302 { 302 {
303 if (objectLocks.Contains(localID) == true) 303 if (objectLocks.Contains(localID) == true)
304 { 304 {
305 objectLocks.Remove(localID); 305 objectLocks.Remove(localID);
306 } 306 }
307 } 307 }
308 } 308 }
309 309
310 310
311 /// <summary> 311 /// <summary>
312 /// Add event to event execution queue 312 /// Add event to event execution queue
313 /// </summary> 313 /// </summary>
314 /// <param name="localID"></param> 314 /// <param name="localID"></param>
315 /// <param name="FunctionName">Name of the function, will be state + "_event_" + FunctionName</param> 315 /// <param name="FunctionName">Name of the function, will be state + "_event_" + FunctionName</param>
316 /// <param name="param">Array of parameters to match event mask</param> 316 /// <param name="param">Array of parameters to match event mask</param>
317 public void AddToObjectQueue(uint localID, string FunctionName, params object[] param) 317 public void AddToObjectQueue(uint localID, string FunctionName, params object[] param)
318 { 318 {
319 // Determine all scripts in Object and add to their queue 319 // Determine all scripts in Object and add to their queue
320 //myScriptEngine.m_logger.Verbose("ScriptEngine", "EventQueueManager Adding localID: " + localID + ", FunctionName: " + FunctionName); 320 //myScriptEngine.m_logger.Verbose("ScriptEngine", "EventQueueManager Adding localID: " + localID + ", FunctionName: " + FunctionName);
321 321
322 322
323 // Do we have any scripts in this object at all? If not, return 323 // Do we have any scripts in this object at all? If not, return
324 if (m_ScriptEngine.m_ScriptManager.Scripts.ContainsKey(localID) == false) 324 if (m_ScriptEngine.m_ScriptManager.Scripts.ContainsKey(localID) == false)
325 { 325 {
326 //Console.WriteLine("Event \"" + FunctionName + "\" for localID: " + localID + ". No scripts found on this localID."); 326 //Console.WriteLine("Event \"" + FunctionName + "\" for localID: " + localID + ". No scripts found on this localID.");
327 return; 327 return;
328 } 328 }
329 329
330 Dictionary<LLUUID, IScript>.KeyCollection scriptKeys = 330 Dictionary<LLUUID, IScript>.KeyCollection scriptKeys =
331 m_ScriptEngine.m_ScriptManager.GetScriptKeys(localID); 331 m_ScriptEngine.m_ScriptManager.GetScriptKeys(localID);
332 332
333 foreach (LLUUID itemID in scriptKeys) 333 foreach (LLUUID itemID in scriptKeys)
334 { 334 {
335 // Add to each script in that object 335 // Add to each script in that object
336 // TODO: Some scripts may not subscribe to this event. Should we NOT add it? Does it matter? 336 // TODO: Some scripts may not subscribe to this event. Should we NOT add it? Does it matter?
337 AddToScriptQueue(localID, itemID, FunctionName, param); 337 AddToScriptQueue(localID, itemID, FunctionName, param);
338 } 338 }
339 } 339 }
340 340
341 /// <summary> 341 /// <summary>
342 /// Add event to event execution queue 342 /// Add event to event execution queue
343 /// </summary> 343 /// </summary>
344 /// <param name="localID"></param> 344 /// <param name="localID"></param>
345 /// <param name="itemID"></param> 345 /// <param name="itemID"></param>
346 /// <param name="FunctionName">Name of the function, will be state + "_event_" + FunctionName</param> 346 /// <param name="FunctionName">Name of the function, will be state + "_event_" + FunctionName</param>
347 /// <param name="param">Array of parameters to match event mask</param> 347 /// <param name="param">Array of parameters to match event mask</param>
348 public void AddToScriptQueue(uint localID, LLUUID itemID, string FunctionName, params object[] param) 348 public void AddToScriptQueue(uint localID, LLUUID itemID, string FunctionName, params object[] param)
349 { 349 {
350 lock (queueLock) 350 lock (queueLock)
351 { 351 {
352 // Create a structure and add data 352 // Create a structure and add data
353 QueueItemStruct QIS = new QueueItemStruct(); 353 QueueItemStruct QIS = new QueueItemStruct();
354 QIS.localID = localID; 354 QIS.localID = localID;
355 QIS.itemID = itemID; 355 QIS.itemID = itemID;
356 QIS.functionName = FunctionName; 356 QIS.functionName = FunctionName;
357 QIS.param = param; 357 QIS.param = param;
358 358
359 // Add it to queue 359 // Add it to queue
360 eventQueue.Enqueue(QIS); 360 eventQueue.Enqueue(QIS);
361 } 361 }
362 } 362 }
363 } 363 }
364} \ No newline at end of file 364} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/LSLLongCmdHandler.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/LSLLongCmdHandler.cs
index 94241eb..635c32a 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/LSLLongCmdHandler.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/LSLLongCmdHandler.cs
@@ -1,295 +1,295 @@
1/* 1/*
2* Copyright (c) Contributors, http://opensimulator.org/ 2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders. 3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4* 4*
5* Redistribution and use in source and binary forms, with or without 5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met: 6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright 7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer. 8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright 9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the 10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution. 11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the 12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products 13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission. 14* derived from this software without specific prior written permission.
15* 15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY 16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 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 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 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 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. 25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26* 26*
27*/ 27*/
28 28
29using System; 29using System;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Threading; 31using System.Threading;
32using libsecondlife; 32using libsecondlife;
33using OpenSim.Region.Environment.Interfaces; 33using OpenSim.Region.Environment.Interfaces;
34using OpenSim.Region.Environment.Modules; 34using OpenSim.Region.Environment.Modules;
35 35
36namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase 36namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
37{ 37{
38 /// <summary> 38 /// <summary>
39 /// Handles LSL commands that takes long time and returns an event, for example timers, HTTP requests, etc. 39 /// Handles LSL commands that takes long time and returns an event, for example timers, HTTP requests, etc.
40 /// </summary> 40 /// </summary>
41 public class LSLLongCmdHandler 41 public class LSLLongCmdHandler
42 { 42 {
43 private Thread cmdHandlerThread; 43 private Thread cmdHandlerThread;
44 private int cmdHandlerThreadCycleSleepms = 100; 44 private int cmdHandlerThreadCycleSleepms = 100;
45 45
46 private ScriptEngine m_ScriptEngine; 46 private ScriptEngine m_ScriptEngine;
47 47
48 public LSLLongCmdHandler(ScriptEngine _ScriptEngine) 48 public LSLLongCmdHandler(ScriptEngine _ScriptEngine)
49 { 49 {
50 m_ScriptEngine = _ScriptEngine; 50 m_ScriptEngine = _ScriptEngine;
51 51
52 // Start the thread that will be doing the work 52 // Start the thread that will be doing the work
53 cmdHandlerThread = new Thread(CmdHandlerThreadLoop); 53 cmdHandlerThread = new Thread(CmdHandlerThreadLoop);
54 cmdHandlerThread.Name = "CmdHandlerThread"; 54 cmdHandlerThread.Name = "CmdHandlerThread";
55 cmdHandlerThread.Priority = ThreadPriority.BelowNormal; 55 cmdHandlerThread.Priority = ThreadPriority.BelowNormal;
56 cmdHandlerThread.IsBackground = true; 56 cmdHandlerThread.IsBackground = true;
57 cmdHandlerThread.Start(); 57 cmdHandlerThread.Start();
58 } 58 }
59 59
60 ~LSLLongCmdHandler() 60 ~LSLLongCmdHandler()
61 { 61 {
62 // Shut down thread 62 // Shut down thread
63 try 63 try
64 { 64 {
65 if (cmdHandlerThread != null) 65 if (cmdHandlerThread != null)
66 { 66 {
67 if (cmdHandlerThread.IsAlive == true) 67 if (cmdHandlerThread.IsAlive == true)
68 { 68 {
69 cmdHandlerThread.Abort(); 69 cmdHandlerThread.Abort();
70 cmdHandlerThread.Join(); 70 cmdHandlerThread.Join();
71 } 71 }
72 } 72 }
73 } 73 }
74 catch 74 catch
75 { 75 {
76 } 76 }
77 } 77 }
78 78
79 private void CmdHandlerThreadLoop() 79 private void CmdHandlerThreadLoop()
80 { 80 {
81 while (true) 81 while (true)
82 { 82 {
83 // Check timers 83 // Check timers
84 CheckTimerEvents(); 84 CheckTimerEvents();
85 Thread.Sleep(25); 85 Thread.Sleep(25);
86 // Check HttpRequests 86 // Check HttpRequests
87 CheckHttpRequests(); 87 CheckHttpRequests();
88 Thread.Sleep(25); 88 Thread.Sleep(25);
89 // Check XMLRPCRequests 89 // Check XMLRPCRequests
90 CheckXMLRPCRequests(); 90 CheckXMLRPCRequests();
91 Thread.Sleep(25); 91 Thread.Sleep(25);
92 // Check Listeners 92 // Check Listeners
93 CheckListeners(); 93 CheckListeners();
94 Thread.Sleep(25); 94 Thread.Sleep(25);
95 95
96 // Sleep before next cycle 96 // Sleep before next cycle
97 //Thread.Sleep(cmdHandlerThreadCycleSleepms); 97 //Thread.Sleep(cmdHandlerThreadCycleSleepms);
98 } 98 }
99 } 99 }
100 100
101 /// <summary> 101 /// <summary>
102 /// Remove a specific script (and all its pending commands) 102 /// Remove a specific script (and all its pending commands)
103 /// </summary> 103 /// </summary>
104 /// <param name="m_localID"></param> 104 /// <param name="m_localID"></param>
105 /// <param name="m_itemID"></param> 105 /// <param name="m_itemID"></param>
106 public void RemoveScript(uint localID, LLUUID itemID) 106 public void RemoveScript(uint localID, LLUUID itemID)
107 { 107 {
108 // Remove a specific script 108 // Remove a specific script
109 109
110 // Remove from: Timers 110 // Remove from: Timers
111 UnSetTimerEvents(localID, itemID); 111 UnSetTimerEvents(localID, itemID);
112 // Remove from: HttpRequest 112 // Remove from: HttpRequest
113 IHttpRequests iHttpReq = 113 IHttpRequests iHttpReq =
114 m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>(); 114 m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>();
115 iHttpReq.StopHttpRequest(localID, itemID); 115 iHttpReq.StopHttpRequest(localID, itemID);
116 } 116 }
117 117
118 #region TIMER 118 #region TIMER
119 119
120 // 120 //
121 // TIMER 121 // TIMER
122 // 122 //
123 private class TimerClass 123 private class TimerClass
124 { 124 {
125 public uint localID; 125 public uint localID;
126 public LLUUID itemID; 126 public LLUUID itemID;
127 public double interval; 127 public double interval;
128 public DateTime next; 128 public DateTime next;
129 } 129 }
130 130
131 private List<TimerClass> Timers = new List<TimerClass>(); 131 private List<TimerClass> Timers = new List<TimerClass>();
132 private object TimerListLock = new object(); 132 private object TimerListLock = new object();
133 133
134 public void SetTimerEvent(uint m_localID, LLUUID m_itemID, double sec) 134 public void SetTimerEvent(uint m_localID, LLUUID m_itemID, double sec)
135 { 135 {
136 Console.WriteLine("SetTimerEvent"); 136 Console.WriteLine("SetTimerEvent");
137 137
138 // Always remove first, in case this is a re-set 138 // Always remove first, in case this is a re-set
139 UnSetTimerEvents(m_localID, m_itemID); 139 UnSetTimerEvents(m_localID, m_itemID);
140 if (sec == 0) // Disabling timer 140 if (sec == 0) // Disabling timer
141 return; 141 return;
142 142
143 // Add to timer 143 // Add to timer
144 TimerClass ts = new TimerClass(); 144 TimerClass ts = new TimerClass();
145 ts.localID = m_localID; 145 ts.localID = m_localID;
146 ts.itemID = m_itemID; 146 ts.itemID = m_itemID;
147 ts.interval = sec; 147 ts.interval = sec;
148 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); 148 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
149 lock (TimerListLock) 149 lock (TimerListLock)
150 { 150 {
151 Timers.Add(ts); 151 Timers.Add(ts);
152 } 152 }
153 } 153 }
154 154
155 public void UnSetTimerEvents(uint m_localID, LLUUID m_itemID) 155 public void UnSetTimerEvents(uint m_localID, LLUUID m_itemID)
156 { 156 {
157 // Remove from timer 157 // Remove from timer
158 lock (TimerListLock) 158 lock (TimerListLock)
159 { 159 {
160 List<TimerClass> NewTimers = new List<TimerClass>(); 160 List<TimerClass> NewTimers = new List<TimerClass>();
161 foreach (TimerClass ts in Timers) 161 foreach (TimerClass ts in Timers)
162 { 162 {
163 if (ts.localID != m_localID && ts.itemID != m_itemID) 163 if (ts.localID != m_localID && ts.itemID != m_itemID)
164 { 164 {
165 NewTimers.Add(ts); 165 NewTimers.Add(ts);
166 } 166 }
167 } 167 }
168 Timers.Clear(); 168 Timers.Clear();
169 Timers = NewTimers; 169 Timers = NewTimers;
170 } 170 }
171 } 171 }
172 172
173 public void CheckTimerEvents() 173 public void CheckTimerEvents()
174 { 174 {
175 // Nothing to do here? 175 // Nothing to do here?
176 if (Timers.Count == 0) 176 if (Timers.Count == 0)
177 return; 177 return;
178 178
179 lock (TimerListLock) 179 lock (TimerListLock)
180 { 180 {
181 // Go through all timers 181 // Go through all timers
182 foreach (TimerClass ts in Timers) 182 foreach (TimerClass ts in Timers)
183 { 183 {
184 // Time has passed? 184 // Time has passed?
185 if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime()) 185 if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime())
186 { 186 {
187 // Add it to queue 187 // Add it to queue
188 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "timer", 188 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "timer",
189 new object[] {}); 189 new object[] {});
190 // set next interval 190 // set next interval
191 191
192 192
193 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); 193 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
194 } 194 }
195 } 195 }
196 } // lock 196 } // lock
197 } 197 }
198 198
199 #endregion 199 #endregion
200 200
201 #region HTTP REQUEST 201 #region HTTP REQUEST
202 202
203 public void CheckHttpRequests() 203 public void CheckHttpRequests()
204 { 204 {
205 if (m_ScriptEngine.World == null) 205 if (m_ScriptEngine.World == null)
206 return; 206 return;
207 207
208 IHttpRequests iHttpReq = 208 IHttpRequests iHttpReq =
209 m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>(); 209 m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>();
210 210
211 HttpRequestClass httpInfo = null; 211 HttpRequestClass httpInfo = null;
212 212
213 if (iHttpReq != null) 213 if (iHttpReq != null)
214 httpInfo = iHttpReq.GetNextCompletedRequest(); 214 httpInfo = iHttpReq.GetNextCompletedRequest();
215 215
216 while (httpInfo != null) 216 while (httpInfo != null)
217 { 217 {
218 //Console.WriteLine("PICKED HTTP REQ:" + httpInfo.response_body + httpInfo.status); 218 //Console.WriteLine("PICKED HTTP REQ:" + httpInfo.response_body + httpInfo.status);
219 219
220 // Deliver data to prim's remote_data handler 220 // Deliver data to prim's remote_data handler
221 // 221 //
222 // TODO: Returning null for metadata, since the lsl function 222 // TODO: Returning null for metadata, since the lsl function
223 // only returns the byte for HTTP_BODY_TRUNCATED, which is not 223 // only returns the byte for HTTP_BODY_TRUNCATED, which is not
224 // implemented here yet anyway. Should be fixed if/when maxsize 224 // implemented here yet anyway. Should be fixed if/when maxsize
225 // is supported 225 // is supported
226 226
227 object[] resobj = new object[] 227 object[] resobj = new object[]
228 { 228 {
229 httpInfo.reqID.ToString(), httpInfo.status, null, httpInfo.response_body 229 httpInfo.reqID.ToString(), httpInfo.status, null, httpInfo.response_body
230 }; 230 };
231 231
232 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( 232 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
233 httpInfo.localID, httpInfo.itemID, "http_response", resobj 233 httpInfo.localID, httpInfo.itemID, "http_response", resobj
234 ); 234 );
235 235
236 httpInfo.Stop(); 236 httpInfo.Stop();
237 httpInfo = null; 237 httpInfo = null;
238 238
239 httpInfo = iHttpReq.GetNextCompletedRequest(); 239 httpInfo = iHttpReq.GetNextCompletedRequest();
240 } 240 }
241 } 241 }
242 242
243 #endregion 243 #endregion
244 244
245 public void CheckXMLRPCRequests() 245 public void CheckXMLRPCRequests()
246 { 246 {
247 if (m_ScriptEngine.World == null) 247 if (m_ScriptEngine.World == null)
248 return; 248 return;
249 249
250 IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); 250 IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
251 251
252 if (xmlrpc != null) 252 if (xmlrpc != null)
253 { 253 {
254 while (xmlrpc.hasRequests()) 254 while (xmlrpc.hasRequests())
255 { 255 {
256 RPCRequestInfo rInfo = xmlrpc.GetNextRequest(); 256 RPCRequestInfo rInfo = xmlrpc.GetNextRequest();
257 //Console.WriteLine("PICKED REQUEST"); 257 //Console.WriteLine("PICKED REQUEST");
258 258
259 //Deliver data to prim's remote_data handler 259 //Deliver data to prim's remote_data handler
260 object[] resobj = new object[] 260 object[] resobj = new object[]
261 { 261 {
262 2, rInfo.GetChannelKey().ToString(), rInfo.GetMessageID().ToString(), "", 262 2, rInfo.GetChannelKey().ToString(), rInfo.GetMessageID().ToString(), "",
263 rInfo.GetIntValue(), 263 rInfo.GetIntValue(),
264 rInfo.GetStrVal() 264 rInfo.GetStrVal()
265 }; 265 };
266 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( 266 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
267 rInfo.GetLocalID(), rInfo.GetItemID(), "remote_data", resobj 267 rInfo.GetLocalID(), rInfo.GetItemID(), "remote_data", resobj
268 ); 268 );
269 } 269 }
270 } 270 }
271 } 271 }
272 272
273 public void CheckListeners() 273 public void CheckListeners()
274 { 274 {
275 if (m_ScriptEngine.World == null) 275 if (m_ScriptEngine.World == null)
276 return; 276 return;
277 IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 277 IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
278 278
279 while (comms.HasMessages()) 279 while (comms.HasMessages())
280 { 280 {
281 ListenerInfo lInfo = comms.GetNextMessage(); 281 ListenerInfo lInfo = comms.GetNextMessage();
282 282
283 //Deliver data to prim's listen handler 283 //Deliver data to prim's listen handler
284 object[] resobj = new object[] 284 object[] resobj = new object[]
285 { 285 {
286 lInfo.GetChannel(), lInfo.GetName(), lInfo.GetID().ToString(), lInfo.GetMessage() 286 lInfo.GetChannel(), lInfo.GetName(), lInfo.GetID().ToString(), lInfo.GetMessage()
287 }; 287 };
288 288
289 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( 289 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
290 lInfo.GetLocalID(), lInfo.GetItemID(), "listen", resobj 290 lInfo.GetLocalID(), lInfo.GetItemID(), "listen", resobj
291 ); 291 );
292 } 292 }
293 } 293 }
294 } 294 }
295} \ No newline at end of file 295} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs
index 39d0bc3..da0baba 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs
@@ -1,132 +1,132 @@
1/* 1/*
2* Copyright (c) Contributors, http://opensimulator.org/ 2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders. 3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4* 4*
5* Redistribution and use in source and binary forms, with or without 5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met: 6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright 7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer. 8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright 9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the 10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution. 11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the 12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products 13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission. 14* derived from this software without specific prior written permission.
15* 15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY 16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 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 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 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 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. 25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26* 26*
27*/ 27*/
28 28
29 29
30using System; 30using System;
31using Nini.Config; 31using Nini.Config;
32using OpenSim.Framework.Console; 32using OpenSim.Framework.Console;
33using OpenSim.Region.Environment.Interfaces; 33using OpenSim.Region.Environment.Interfaces;
34using OpenSim.Region.Environment.Scenes; 34using OpenSim.Region.Environment.Scenes;
35using OpenSim.Region.ScriptEngine.Common; 35using OpenSim.Region.ScriptEngine.Common;
36using OpenSim.Region.ScriptEngine.Common.ScriptEngineBase; 36using OpenSim.Region.ScriptEngine.Common.ScriptEngineBase;
37 37
38namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase 38namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
39{ 39{
40 /// <summary> 40 /// <summary>
41 /// This is the root object for ScriptEngine. Objects access each other trough this class. 41 /// This is the root object for ScriptEngine. Objects access each other trough this class.
42 /// </summary> 42 /// </summary>
43 /// 43 ///
44 [Serializable] 44 [Serializable]
45 public abstract class ScriptEngine : IRegionModule, OpenSim.Region.ScriptEngine.Common.ScriptServerInterfaces.ScriptEngine 45 public abstract class ScriptEngine : IRegionModule, OpenSim.Region.ScriptEngine.Common.ScriptServerInterfaces.ScriptEngine
46 { 46 {
47 public Scene World; 47 public Scene World;
48 public EventManager m_EventManager; // Handles and queues incoming events from OpenSim 48 public EventManager m_EventManager; // Handles and queues incoming events from OpenSim
49 public EventQueueManager m_EventQueueManager; // Executes events 49 public EventQueueManager m_EventQueueManager; // Executes events
50 public ScriptManager m_ScriptManager; // Load, unload and execute scripts 50 public ScriptManager m_ScriptManager; // Load, unload and execute scripts
51 public AppDomainManager m_AppDomainManager; 51 public AppDomainManager m_AppDomainManager;
52 public LSLLongCmdHandler m_LSLLongCmdHandler; 52 public LSLLongCmdHandler m_LSLLongCmdHandler;
53 53
54 public ScriptManager GetScriptManager() 54 public ScriptManager GetScriptManager()
55 { 55 {
56 return _GetScriptManager(); 56 return _GetScriptManager();
57 } 57 }
58 public abstract ScriptManager _GetScriptManager(); 58 public abstract ScriptManager _GetScriptManager();
59 59
60 private LogBase m_log; 60 private LogBase m_log;
61 61
62 public ScriptEngine() 62 public ScriptEngine()
63 { 63 {
64 //Common.SendToDebug("ScriptEngine Object Initialized"); 64 //Common.SendToDebug("ScriptEngine Object Initialized");
65 Common.mySE = this; 65 Common.mySE = this;
66 } 66 }
67 67
68 public LogBase Log 68 public LogBase Log
69 { 69 {
70 get { return m_log; } 70 get { return m_log; }
71 } 71 }
72 72
73 public void InitializeEngine(Scene Sceneworld, LogBase logger, bool HookUpToServer, ScriptManager newScriptManager) 73 public void InitializeEngine(Scene Sceneworld, LogBase logger, bool HookUpToServer, ScriptManager newScriptManager)
74 { 74 {
75 World = Sceneworld; 75 World = Sceneworld;
76 m_log = logger; 76 m_log = logger;
77 77
78 Log.Verbose("ScriptEngine", "DotNet & LSL ScriptEngine initializing"); 78 Log.Verbose("ScriptEngine", "DotNet & LSL ScriptEngine initializing");
79 79
80 //m_logger.Status("ScriptEngine", "InitializeEngine"); 80 //m_logger.Status("ScriptEngine", "InitializeEngine");
81 81
82 // Create all objects we'll be using 82 // Create all objects we'll be using
83 m_EventQueueManager = new EventQueueManager(this); 83 m_EventQueueManager = new EventQueueManager(this);
84 m_EventManager = new EventManager(this, HookUpToServer); 84 m_EventManager = new EventManager(this, HookUpToServer);
85 m_ScriptManager = newScriptManager; 85 m_ScriptManager = newScriptManager;
86 //m_ScriptManager = new ScriptManager(this); 86 //m_ScriptManager = new ScriptManager(this);
87 m_AppDomainManager = new AppDomainManager(); 87 m_AppDomainManager = new AppDomainManager();
88 m_LSLLongCmdHandler = new LSLLongCmdHandler(this); 88 m_LSLLongCmdHandler = new LSLLongCmdHandler(this);
89 89
90 // Should we iterate the region for scripts that needs starting? 90 // Should we iterate the region for scripts that needs starting?
91 // Or can we assume we are loaded before anything else so we can use proper events? 91 // Or can we assume we are loaded before anything else so we can use proper events?
92 } 92 }
93 93
94 public void Shutdown() 94 public void Shutdown()
95 { 95 {
96 // We are shutting down 96 // We are shutting down
97 } 97 }
98 98
99 ScriptServerInterfaces.RemoteEvents ScriptServerInterfaces.ScriptEngine.EventManager() 99 ScriptServerInterfaces.RemoteEvents ScriptServerInterfaces.ScriptEngine.EventManager()
100 { 100 {
101 return this.m_EventManager; 101 return this.m_EventManager;
102 } 102 }
103 103
104 104
105 #region IRegionModule 105 #region IRegionModule
106 106
107 public abstract void Initialise(Scene scene, IConfigSource config); 107 public abstract void Initialise(Scene scene, IConfigSource config);
108 108
109 public void PostInitialise() 109 public void PostInitialise()
110 { 110 {
111 } 111 }
112 112
113 public void Close() 113 public void Close()
114 { 114 {
115 } 115 }
116 116
117 public string Name 117 public string Name
118 { 118 {
119 get { return "DotNetEngine"; } 119 get { return "DotNetEngine"; }
120 } 120 }
121 121
122 public bool IsSharedModule 122 public bool IsSharedModule
123 { 123 {
124 get { return false; } 124 get { return false; }
125 } 125 }
126 126
127 127
128 128
129 #endregion 129 #endregion
130 130
131 } 131 }
132} \ No newline at end of file 132} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs
index e98ff81..8f74620 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs
@@ -1,348 +1,348 @@
1/* 1/*
2* Copyright (c) Contributors, http://opensimulator.org/ 2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders. 3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4* 4*
5* Redistribution and use in source and binary forms, with or without 5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met: 6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright 7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer. 8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright 9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the 10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution. 11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the 12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products 13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission. 14* derived from this software without specific prior written permission.
15* 15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY 16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 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 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 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 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. 25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26* 26*
27*/ 27*/
28 28
29 29
30using System; 30using System;
31using System.Collections.Generic; 31using System.Collections.Generic;
32using System.IO; 32using System.IO;
33using System.Reflection; 33using System.Reflection;
34using System.Runtime.Serialization.Formatters.Binary; 34using System.Runtime.Serialization.Formatters.Binary;
35using System.Threading; 35using System.Threading;
36using libsecondlife; 36using libsecondlife;
37using OpenSim.Framework; 37using OpenSim.Framework;
38using OpenSim.Region.Environment.Scenes; 38using OpenSim.Region.Environment.Scenes;
39using OpenSim.Region.ScriptEngine.Common; 39using OpenSim.Region.ScriptEngine.Common;
40 40
41namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase 41namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
42{ 42{
43 /// <summary> 43 /// <summary>
44 /// Loads scripts 44 /// Loads scripts
45 /// Compiles them if necessary 45 /// Compiles them if necessary
46 /// Execute functions for EventQueueManager (Sends them to script on other AppDomain for execution) 46 /// Execute functions for EventQueueManager (Sends them to script on other AppDomain for execution)
47 /// </summary> 47 /// </summary>
48 /// 48 ///
49 49
50 // This class is as close as you get to the script without being inside script class. It handles all the dirty work for other classes. 50 // This class is as close as you get to the script without being inside script class. It handles all the dirty work for other classes.
51 // * Keeps track of running scripts 51 // * Keeps track of running scripts
52 // * Compiles script if necessary (through "Compiler") 52 // * Compiles script if necessary (through "Compiler")
53 // * Loads script (through "AppDomainManager" called from for example "EventQueueManager") 53 // * Loads script (through "AppDomainManager" called from for example "EventQueueManager")
54 // * Executes functions inside script (called from for example "EventQueueManager" class) 54 // * Executes functions inside script (called from for example "EventQueueManager" class)
55 // * Unloads script (through "AppDomainManager" called from for example "EventQueueManager") 55 // * Unloads script (through "AppDomainManager" called from for example "EventQueueManager")
56 // * Dedicated load/unload thread, and queues loading/unloading. 56 // * Dedicated load/unload thread, and queues loading/unloading.
57 // This so that scripts starting or stopping will not slow down other theads or whole system. 57 // This so that scripts starting or stopping will not slow down other theads or whole system.
58 // 58 //
59 [Serializable] 59 [Serializable]
60 public abstract class ScriptManager 60 public abstract class ScriptManager
61 { 61 {
62 #region Declares 62 #region Declares
63 63
64 private Thread scriptLoadUnloadThread; 64 private Thread scriptLoadUnloadThread;
65 private int scriptLoadUnloadThread_IdleSleepms = 100; 65 private int scriptLoadUnloadThread_IdleSleepms = 100;
66 private Queue<LUStruct> LUQueue = new Queue<LUStruct>(); 66 private Queue<LUStruct> LUQueue = new Queue<LUStruct>();
67 67
68 68
69 // Load/Unload structure 69 // Load/Unload structure
70 private struct LUStruct 70 private struct LUStruct
71 { 71 {
72 public uint localID; 72 public uint localID;
73 public LLUUID itemID; 73 public LLUUID itemID;
74 public string script; 74 public string script;
75 public LUType Action; 75 public LUType Action;
76 } 76 }
77 77
78 private enum LUType 78 private enum LUType
79 { 79 {
80 Unknown = 0, 80 Unknown = 0,
81 Load = 1, 81 Load = 1,
82 Unload = 2 82 Unload = 2
83 } 83 }
84 84
85 // Object<string, Script<string, script>> 85 // Object<string, Script<string, script>>
86 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 86 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
87 // Instead use RuntimeTypeHandle, RuntimeFieldHandle and RunTimeHandle (IntPtr) instead! 87 // Instead use RuntimeTypeHandle, RuntimeFieldHandle and RunTimeHandle (IntPtr) instead!
88 public Dictionary<uint, Dictionary<LLUUID, IScript>> Scripts = 88 public Dictionary<uint, Dictionary<LLUUID, IScript>> Scripts =
89 new Dictionary<uint, Dictionary<LLUUID, IScript>>(); 89 new Dictionary<uint, Dictionary<LLUUID, IScript>>();
90 90
91 public Scene World 91 public Scene World
92 { 92 {
93 get { return m_scriptEngine.World; } 93 get { return m_scriptEngine.World; }
94 } 94 }
95 95
96 #endregion 96 #endregion
97 97
98 #region Object init/shutdown 98 #region Object init/shutdown
99 99
100 public ScriptEngineBase.ScriptEngine m_scriptEngine; 100 public ScriptEngineBase.ScriptEngine m_scriptEngine;
101 101
102 public ScriptManager(ScriptEngineBase.ScriptEngine scriptEngine) 102 public ScriptManager(ScriptEngineBase.ScriptEngine scriptEngine)
103 { 103 {
104 m_scriptEngine = scriptEngine; 104 m_scriptEngine = scriptEngine;
105 AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); 105 AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
106 scriptLoadUnloadThread = new Thread(ScriptLoadUnloadThreadLoop); 106 scriptLoadUnloadThread = new Thread(ScriptLoadUnloadThreadLoop);
107 scriptLoadUnloadThread.Name = "ScriptLoadUnloadThread"; 107 scriptLoadUnloadThread.Name = "ScriptLoadUnloadThread";
108 scriptLoadUnloadThread.IsBackground = true; 108 scriptLoadUnloadThread.IsBackground = true;
109 scriptLoadUnloadThread.Priority = ThreadPriority.BelowNormal; 109 scriptLoadUnloadThread.Priority = ThreadPriority.BelowNormal;
110 scriptLoadUnloadThread.Start(); 110 scriptLoadUnloadThread.Start();
111 } 111 }
112 112
113 ~ScriptManager() 113 ~ScriptManager()
114 { 114 {
115 // Abort load/unload thread 115 // Abort load/unload thread
116 try 116 try
117 { 117 {
118 if (scriptLoadUnloadThread != null) 118 if (scriptLoadUnloadThread != null)
119 { 119 {
120 if (scriptLoadUnloadThread.IsAlive == true) 120 if (scriptLoadUnloadThread.IsAlive == true)
121 { 121 {
122 scriptLoadUnloadThread.Abort(); 122 scriptLoadUnloadThread.Abort();
123 scriptLoadUnloadThread.Join(); 123 scriptLoadUnloadThread.Join();
124 } 124 }
125 } 125 }
126 } 126 }
127 catch 127 catch
128 { 128 {
129 } 129 }
130 } 130 }
131 131
132 #endregion 132 #endregion
133 133
134 #region Load / Unload scripts (Thread loop) 134 #region Load / Unload scripts (Thread loop)
135 135
136 private void ScriptLoadUnloadThreadLoop() 136 private void ScriptLoadUnloadThreadLoop()
137 { 137 {
138 try 138 try
139 { 139 {
140 while (true) 140 while (true)
141 { 141 {
142 if (LUQueue.Count == 0) 142 if (LUQueue.Count == 0)
143 Thread.Sleep(scriptLoadUnloadThread_IdleSleepms); 143 Thread.Sleep(scriptLoadUnloadThread_IdleSleepms);
144 if (LUQueue.Count > 0) 144 if (LUQueue.Count > 0)
145 { 145 {
146 LUStruct item = LUQueue.Dequeue(); 146 LUStruct item = LUQueue.Dequeue();
147 lock (startStopLock) // Lock so we have only 1 thread working on loading/unloading of scripts 147 lock (startStopLock) // Lock so we have only 1 thread working on loading/unloading of scripts
148 { 148 {
149 if (item.Action == LUType.Unload) 149 if (item.Action == LUType.Unload)
150 { 150 {
151 _StopScript(item.localID, item.itemID); 151 _StopScript(item.localID, item.itemID);
152 } 152 }
153 if (item.Action == LUType.Load) 153 if (item.Action == LUType.Load)
154 { 154 {
155 _StartScript(item.localID, item.itemID, item.script); 155 _StartScript(item.localID, item.itemID, item.script);
156 } 156 }
157 } 157 }
158 } 158 }
159 } 159 }
160 } 160 }
161 catch (ThreadAbortException tae) 161 catch (ThreadAbortException tae)
162 { 162 {
163 string a = tae.ToString(); 163 string a = tae.ToString();
164 a = ""; 164 a = "";
165 // Expected 165 // Expected
166 } 166 }
167 } 167 }
168 168
169 #endregion 169 #endregion
170 170
171 #region Helper functions 171 #region Helper functions
172 172
173 private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 173 private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
174 { 174 {
175 //Console.WriteLine("ScriptManager.CurrentDomain_AssemblyResolve: " + args.Name); 175 //Console.WriteLine("ScriptManager.CurrentDomain_AssemblyResolve: " + args.Name);
176 return Assembly.GetExecutingAssembly().FullName == args.Name ? Assembly.GetExecutingAssembly() : null; 176 return Assembly.GetExecutingAssembly().FullName == args.Name ? Assembly.GetExecutingAssembly() : null;
177 } 177 }
178 178
179 #endregion 179 #endregion
180 180
181 181
182 182
183 #region Start/Stop/Reset script 183 #region Start/Stop/Reset script
184 184
185 private readonly Object startStopLock = new Object(); 185 private readonly Object startStopLock = new Object();
186 186
187 /// <summary> 187 /// <summary>
188 /// Fetches, loads and hooks up a script to an objects events 188 /// Fetches, loads and hooks up a script to an objects events
189 /// </summary> 189 /// </summary>
190 /// <param name="itemID"></param> 190 /// <param name="itemID"></param>
191 /// <param name="localID"></param> 191 /// <param name="localID"></param>
192 public void StartScript(uint localID, LLUUID itemID, string Script) 192 public void StartScript(uint localID, LLUUID itemID, string Script)
193 { 193 {
194 LUStruct ls = new LUStruct(); 194 LUStruct ls = new LUStruct();
195 ls.localID = localID; 195 ls.localID = localID;
196 ls.itemID = itemID; 196 ls.itemID = itemID;
197 ls.script = Script; 197 ls.script = Script;
198 ls.Action = LUType.Load; 198 ls.Action = LUType.Load;
199 LUQueue.Enqueue(ls); 199 LUQueue.Enqueue(ls);
200 } 200 }
201 201
202 /// <summary> 202 /// <summary>
203 /// Disables and unloads a script 203 /// Disables and unloads a script
204 /// </summary> 204 /// </summary>
205 /// <param name="localID"></param> 205 /// <param name="localID"></param>
206 /// <param name="itemID"></param> 206 /// <param name="itemID"></param>
207 public void StopScript(uint localID, LLUUID itemID) 207 public void StopScript(uint localID, LLUUID itemID)
208 { 208 {
209 LUStruct ls = new LUStruct(); 209 LUStruct ls = new LUStruct();
210 ls.localID = localID; 210 ls.localID = localID;
211 ls.itemID = itemID; 211 ls.itemID = itemID;
212 ls.Action = LUType.Unload; 212 ls.Action = LUType.Unload;
213 LUQueue.Enqueue(ls); 213 LUQueue.Enqueue(ls);
214 } 214 }
215 215
216 // Create a new instance of the compiler (reuse) 216 // Create a new instance of the compiler (reuse)
217 //private Compiler.LSL.Compiler LSLCompiler = new Compiler.LSL.Compiler(); 217 //private Compiler.LSL.Compiler LSLCompiler = new Compiler.LSL.Compiler();
218 218
219 public abstract void _StartScript(uint localID, LLUUID itemID, string Script); 219 public abstract void _StartScript(uint localID, LLUUID itemID, string Script);
220 220
221 public abstract void _StopScript(uint localID, LLUUID itemID); 221 public abstract void _StopScript(uint localID, LLUUID itemID);
222 222
223 223
224 #endregion 224 #endregion
225 225
226 #region Perform event execution in script 226 #region Perform event execution in script
227 227
228 /// <summary> 228 /// <summary>
229 /// Execute a LL-event-function in Script 229 /// Execute a LL-event-function in Script
230 /// </summary> 230 /// </summary>
231 /// <param name="localID">Object the script is located in</param> 231 /// <param name="localID">Object the script is located in</param>
232 /// <param name="itemID">Script ID</param> 232 /// <param name="itemID">Script ID</param>
233 /// <param name="FunctionName">Name of function</param> 233 /// <param name="FunctionName">Name of function</param>
234 /// <param name="args">Arguments to pass to function</param> 234 /// <param name="args">Arguments to pass to function</param>
235 internal void ExecuteEvent(uint localID, LLUUID itemID, string FunctionName, object[] args) 235 internal void ExecuteEvent(uint localID, LLUUID itemID, string FunctionName, object[] args)
236 { 236 {
237#if DEBUG 237#if DEBUG
238 Console.WriteLine("ScriptEngine: Inside ExecuteEvent for event " + FunctionName); 238 Console.WriteLine("ScriptEngine: Inside ExecuteEvent for event " + FunctionName);
239#endif 239#endif
240 // Execute a function in the script 240 // Execute a function in the script
241 //m_scriptEngine.Log.Verbose("ScriptEngine", "Executing Function localID: " + localID + ", itemID: " + itemID + ", FunctionName: " + FunctionName); 241 //m_scriptEngine.Log.Verbose("ScriptEngine", "Executing Function localID: " + localID + ", itemID: " + itemID + ", FunctionName: " + FunctionName);
242 //ScriptBaseInterface Script = (ScriptBaseInterface)GetScript(localID, itemID); 242 //ScriptBaseInterface Script = (ScriptBaseInterface)GetScript(localID, itemID);
243 IScript Script = GetScript(localID, itemID); 243 IScript Script = GetScript(localID, itemID);
244 if (Script == null) 244 if (Script == null)
245 return; 245 return;
246#if DEBUG 246#if DEBUG
247 Console.WriteLine("ScriptEngine: Executing event: " + FunctionName); 247 Console.WriteLine("ScriptEngine: Executing event: " + FunctionName);
248#endif 248#endif
249 // Must be done in correct AppDomain, so leaving it up to the script itself 249 // Must be done in correct AppDomain, so leaving it up to the script itself
250 Script.Exec.ExecuteEvent(FunctionName, args); 250 Script.Exec.ExecuteEvent(FunctionName, args);
251 } 251 }
252 252
253 #endregion 253 #endregion
254 254
255 #region Internal functions to keep track of script 255 #region Internal functions to keep track of script
256 256
257 public Dictionary<LLUUID, IScript>.KeyCollection GetScriptKeys(uint localID) 257 public Dictionary<LLUUID, IScript>.KeyCollection GetScriptKeys(uint localID)
258 { 258 {
259 if (Scripts.ContainsKey(localID) == false) 259 if (Scripts.ContainsKey(localID) == false)
260 return null; 260 return null;
261 261
262 Dictionary<LLUUID, IScript> Obj; 262 Dictionary<LLUUID, IScript> Obj;
263 Scripts.TryGetValue(localID, out Obj); 263 Scripts.TryGetValue(localID, out Obj);
264 264
265 return Obj.Keys; 265 return Obj.Keys;
266 } 266 }
267 267
268 public IScript GetScript(uint localID, LLUUID itemID) 268 public IScript GetScript(uint localID, LLUUID itemID)
269 { 269 {
270 if (Scripts.ContainsKey(localID) == false) 270 if (Scripts.ContainsKey(localID) == false)
271 return null; 271 return null;
272 272
273 Dictionary<LLUUID, IScript> Obj; 273 Dictionary<LLUUID, IScript> Obj;
274 Scripts.TryGetValue(localID, out Obj); 274 Scripts.TryGetValue(localID, out Obj);
275 if (Obj.ContainsKey(itemID) == false) 275 if (Obj.ContainsKey(itemID) == false)
276 return null; 276 return null;
277 277
278 // Get script 278 // Get script
279 IScript Script; 279 IScript Script;
280 Obj.TryGetValue(itemID, out Script); 280 Obj.TryGetValue(itemID, out Script);
281 281
282 return Script; 282 return Script;
283 } 283 }
284 284
285 public void SetScript(uint localID, LLUUID itemID, IScript Script) 285 public void SetScript(uint localID, LLUUID itemID, IScript Script)
286 { 286 {
287 // Create object if it doesn't exist 287 // Create object if it doesn't exist
288 if (Scripts.ContainsKey(localID) == false) 288 if (Scripts.ContainsKey(localID) == false)
289 { 289 {
290 Scripts.Add(localID, new Dictionary<LLUUID, IScript>()); 290 Scripts.Add(localID, new Dictionary<LLUUID, IScript>());
291 } 291 }
292 292
293 // Delete script if it exists 293 // Delete script if it exists
294 Dictionary<LLUUID, IScript> Obj; 294 Dictionary<LLUUID, IScript> Obj;
295 Scripts.TryGetValue(localID, out Obj); 295 Scripts.TryGetValue(localID, out Obj);
296 if (Obj.ContainsKey(itemID) == true) 296 if (Obj.ContainsKey(itemID) == true)
297 Obj.Remove(itemID); 297 Obj.Remove(itemID);
298 298
299 // Add to object 299 // Add to object
300 Obj.Add(itemID, Script); 300 Obj.Add(itemID, Script);
301 } 301 }
302 302
303 public void RemoveScript(uint localID, LLUUID itemID) 303 public void RemoveScript(uint localID, LLUUID itemID)
304 { 304 {
305 // Don't have that object? 305 // Don't have that object?
306 if (Scripts.ContainsKey(localID) == false) 306 if (Scripts.ContainsKey(localID) == false)
307 return; 307 return;
308 308
309 // Delete script if it exists 309 // Delete script if it exists
310 Dictionary<LLUUID, IScript> Obj; 310 Dictionary<LLUUID, IScript> Obj;
311 Scripts.TryGetValue(localID, out Obj); 311 Scripts.TryGetValue(localID, out Obj);
312 if (Obj.ContainsKey(itemID) == true) 312 if (Obj.ContainsKey(itemID) == true)
313 Obj.Remove(itemID); 313 Obj.Remove(itemID);
314 } 314 }
315 315
316 #endregion 316 #endregion
317 317
318 318
319 public void ResetScript(uint localID, LLUUID itemID) 319 public void ResetScript(uint localID, LLUUID itemID)
320 { 320 {
321 string script = GetScript(localID, itemID).Source; 321 string script = GetScript(localID, itemID).Source;
322 StopScript(localID, itemID); 322 StopScript(localID, itemID);
323 StartScript(localID, itemID, script); 323 StartScript(localID, itemID, script);
324 } 324 }
325 325
326 326
327 #region Script serialization/deserialization 327 #region Script serialization/deserialization
328 328
329 public void GetSerializedScript(uint localID, LLUUID itemID) 329 public void GetSerializedScript(uint localID, LLUUID itemID)
330 { 330 {
331 // Serialize the script and return it 331 // Serialize the script and return it
332 // Should not be a problem 332 // Should not be a problem
333 FileStream fs = File.Create("SERIALIZED_SCRIPT_" + itemID); 333 FileStream fs = File.Create("SERIALIZED_SCRIPT_" + itemID);
334 BinaryFormatter b = new BinaryFormatter(); 334 BinaryFormatter b = new BinaryFormatter();
335 b.Serialize(fs, GetScript(localID, itemID)); 335 b.Serialize(fs, GetScript(localID, itemID));
336 fs.Close(); 336 fs.Close();
337 } 337 }
338 338
339 public void PutSerializedScript(uint localID, LLUUID itemID) 339 public void PutSerializedScript(uint localID, LLUUID itemID)
340 { 340 {
341 // Deserialize the script and inject it into an AppDomain 341 // Deserialize the script and inject it into an AppDomain
342 342
343 // How to inject into an AppDomain? 343 // How to inject into an AppDomain?
344 } 344 }
345 345
346 #endregion 346 #endregion
347 } 347 }
348} \ No newline at end of file 348} \ No newline at end of file