diff options
-rw-r--r-- | OpenSim/Region/ScriptEngine/DotNetEngine/EventManager.cs | 479 |
1 files changed, 479 insertions, 0 deletions
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/EventManager.cs new file mode 100644 index 0000000..934d981 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/EventManager.cs | |||
@@ -0,0 +1,479 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSim Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using OpenMetaverse; | ||
31 | using OpenSim.Framework; | ||
32 | using OpenSim.Region.Environment.Modules.Avatar.Currency.SampleMoney; | ||
33 | using OpenSim.Region.Environment; | ||
34 | using OpenSim.Region.Interfaces; | ||
35 | using OpenSim.Region; | ||
36 | using OpenSim.Region.Environment.Scenes; | ||
37 | using OpenSim.Region.Environment.Interfaces; | ||
38 | using OpenSim.Region.ScriptEngine.Shared; | ||
39 | |||
40 | namespace OpenSim.Region.ScriptEngine.DotNetEngine | ||
41 | { | ||
42 | /// <summary> | ||
43 | /// Prepares events so they can be directly executed upon a script by EventQueueManager, then queues it. | ||
44 | /// </summary> | ||
45 | [Serializable] | ||
46 | public class EventManager : iScriptEngineFunctionModule | ||
47 | { | ||
48 | // | ||
49 | // Class is instanced in "ScriptEngine" and Uses "EventQueueManager" that is also instanced in "ScriptEngine". | ||
50 | // This class needs a bit of explaining: | ||
51 | // | ||
52 | // This class it the link between an event inside OpenSim and the corresponding event in a user script being executed. | ||
53 | // | ||
54 | // For example when an user touches an object then the "myScriptEngine.World.EventManager.OnObjectGrab" event is fired inside OpenSim. | ||
55 | // We hook up to this event and queue a touch_start in EventQueueManager with the proper LSL parameters. | ||
56 | // It will then be delivered to the script by EventQueueManager. | ||
57 | // | ||
58 | // You can check debug C# dump of an LSL script if you need to verify what exact parameters are needed. | ||
59 | // | ||
60 | |||
61 | |||
62 | private ScriptEngine myScriptEngine; | ||
63 | //public IScriptHost TEMP_OBJECT_ID; | ||
64 | public EventManager(ScriptEngine _ScriptEngine, bool performHookUp) | ||
65 | { | ||
66 | myScriptEngine = _ScriptEngine; | ||
67 | ReadConfig(); | ||
68 | |||
69 | if (performHookUp) | ||
70 | { | ||
71 | myScriptEngine.World.EventManager.OnRezScript += OnRezScript; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | public void HookUpEvents() | ||
76 | { | ||
77 | // Hook up to events from OpenSim | ||
78 | // We may not want to do it because someone is controlling us and will deliver events to us | ||
79 | |||
80 | myScriptEngine.Log.Info("[" + myScriptEngine.ScriptEngineName + "]: Hooking up to server events"); | ||
81 | myScriptEngine.World.EventManager.OnObjectGrab += touch_start; | ||
82 | myScriptEngine.World.EventManager.OnObjectDeGrab += touch_end; | ||
83 | myScriptEngine.World.EventManager.OnRemoveScript += OnRemoveScript; | ||
84 | myScriptEngine.World.EventManager.OnScriptChangedEvent += changed; | ||
85 | myScriptEngine.World.EventManager.OnScriptAtTargetEvent += at_target; | ||
86 | myScriptEngine.World.EventManager.OnScriptNotAtTargetEvent += not_at_target; | ||
87 | myScriptEngine.World.EventManager.OnScriptControlEvent += control; | ||
88 | myScriptEngine.World.EventManager.OnScriptColliderStart += collision_start; | ||
89 | myScriptEngine.World.EventManager.OnScriptColliding += collision; | ||
90 | myScriptEngine.World.EventManager.OnScriptCollidingEnd += collision_end; | ||
91 | |||
92 | // TODO: HOOK ALL EVENTS UP TO SERVER! | ||
93 | IMoneyModule money=myScriptEngine.World.RequestModuleInterface<IMoneyModule>(); | ||
94 | if (money != null) | ||
95 | { | ||
96 | money.OnObjectPaid+=HandleObjectPaid; | ||
97 | } | ||
98 | |||
99 | } | ||
100 | |||
101 | public void ReadConfig() | ||
102 | { | ||
103 | } | ||
104 | |||
105 | private void HandleObjectPaid(UUID objectID, UUID agentID, int amount) | ||
106 | { | ||
107 | SceneObjectPart part=myScriptEngine.World.GetSceneObjectPart(objectID); | ||
108 | if (part != null) | ||
109 | { | ||
110 | money(part.LocalId, agentID, amount); | ||
111 | } | ||
112 | } | ||
113 | |||
114 | public void changed(uint localID, uint change) | ||
115 | { | ||
116 | // Add to queue for all scripts in localID, Object pass change. | ||
117 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
118 | "changed",new object[] { new LSL_Types.LSLInteger(change) }, | ||
119 | new DetectParams[0])); | ||
120 | } | ||
121 | |||
122 | public void state_entry(uint localID) | ||
123 | { | ||
124 | // Add to queue for all scripts in ObjectID object | ||
125 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
126 | "state_entry",new object[] { }, | ||
127 | new DetectParams[0])); | ||
128 | } | ||
129 | |||
130 | public void touch_start(uint localID, uint originalID, Vector3 offsetPos, | ||
131 | IClientAPI remoteClient) | ||
132 | { | ||
133 | // Add to queue for all scripts in ObjectID object | ||
134 | DetectParams[] det = new DetectParams[1]; | ||
135 | det[0] = new DetectParams(); | ||
136 | det[0].Key = remoteClient.AgentId; | ||
137 | det[0].Populate(myScriptEngine.World); | ||
138 | |||
139 | if (originalID == 0) | ||
140 | { | ||
141 | SceneObjectPart part = myScriptEngine.World.GetSceneObjectPart(localID); | ||
142 | if (part == null) | ||
143 | return; | ||
144 | |||
145 | det[0].LinkNum = part.LinkNum; | ||
146 | } | ||
147 | else | ||
148 | { | ||
149 | SceneObjectPart originalPart = myScriptEngine.World.GetSceneObjectPart(originalID); | ||
150 | det[0].LinkNum = originalPart.LinkNum; | ||
151 | } | ||
152 | |||
153 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
154 | "touch_start", new Object[] { new LSL_Types.LSLInteger(1) }, | ||
155 | det)); | ||
156 | } | ||
157 | |||
158 | public void touch(uint localID, uint originalID, Vector3 offsetPos, | ||
159 | IClientAPI remoteClient) | ||
160 | { | ||
161 | // Add to queue for all scripts in ObjectID object | ||
162 | DetectParams[] det = new DetectParams[1]; | ||
163 | det[0] = new DetectParams(); | ||
164 | det[0].Key = remoteClient.AgentId; | ||
165 | det[0].Populate(myScriptEngine.World); | ||
166 | det[0].OffsetPos = new LSL_Types.Vector3(offsetPos.X, | ||
167 | offsetPos.Y, | ||
168 | offsetPos.Z); | ||
169 | |||
170 | if (originalID == 0) | ||
171 | { | ||
172 | SceneObjectPart part = myScriptEngine.World.GetSceneObjectPart(localID); | ||
173 | if (part == null) | ||
174 | return; | ||
175 | |||
176 | det[0].LinkNum = part.LinkNum; | ||
177 | } | ||
178 | else | ||
179 | { | ||
180 | SceneObjectPart originalPart = myScriptEngine.World.GetSceneObjectPart(originalID); | ||
181 | det[0].LinkNum = originalPart.LinkNum; | ||
182 | } | ||
183 | |||
184 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
185 | "touch", new Object[] { new LSL_Types.LSLInteger(1) }, | ||
186 | det)); | ||
187 | } | ||
188 | |||
189 | public void touch_end(uint localID, uint originalID, IClientAPI remoteClient) | ||
190 | { | ||
191 | // Add to queue for all scripts in ObjectID object | ||
192 | DetectParams[] det = new DetectParams[1]; | ||
193 | det[0] = new DetectParams(); | ||
194 | det[0].Key = remoteClient.AgentId; | ||
195 | det[0].Populate(myScriptEngine.World); | ||
196 | |||
197 | if (originalID == 0) | ||
198 | { | ||
199 | SceneObjectPart part = myScriptEngine.World.GetSceneObjectPart(localID); | ||
200 | if (part == null) | ||
201 | return; | ||
202 | |||
203 | det[0].LinkNum = part.LinkNum; | ||
204 | } | ||
205 | else | ||
206 | { | ||
207 | SceneObjectPart originalPart = myScriptEngine.World.GetSceneObjectPart(originalID); | ||
208 | det[0].LinkNum = originalPart.LinkNum; | ||
209 | } | ||
210 | |||
211 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
212 | "touch_end", new Object[] { new LSL_Types.LSLInteger(1) }, | ||
213 | det)); | ||
214 | } | ||
215 | |||
216 | public void OnRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine) | ||
217 | { | ||
218 | List<IScriptModule> engines = new List<IScriptModule>(myScriptEngine.World.RequestModuleInterfaces<IScriptModule>()); | ||
219 | |||
220 | List<string> names = new List<string>(); | ||
221 | foreach (IScriptModule m in engines) | ||
222 | names.Add(m.ScriptEngineName); | ||
223 | |||
224 | int lineEnd = script.IndexOf('\n'); | ||
225 | |||
226 | if (lineEnd != 1) | ||
227 | { | ||
228 | string firstline = script.Substring(0, lineEnd).Trim(); | ||
229 | |||
230 | int colon = firstline.IndexOf(':'); | ||
231 | if (firstline.Length > 2 && firstline.Substring(0, 2) == "//" && colon != -1) | ||
232 | { | ||
233 | string engineName = firstline.Substring(2, colon-2); | ||
234 | |||
235 | if (names.Contains(engineName)) | ||
236 | { | ||
237 | engine = engineName; | ||
238 | script = "//" + script.Substring(script.IndexOf(':')+1); | ||
239 | } | ||
240 | } | ||
241 | } | ||
242 | |||
243 | if (engine != myScriptEngine.ScriptEngineName) | ||
244 | return; | ||
245 | |||
246 | myScriptEngine.Log.Debug("OnRezScript localID: " + localID + " LLUID: " + itemID.ToString() + " Size: " + | ||
247 | script.Length); | ||
248 | myScriptEngine.m_ScriptManager.StartScript(localID, itemID, script, startParam, postOnRez); | ||
249 | } | ||
250 | |||
251 | public void OnRemoveScript(uint localID, UUID itemID) | ||
252 | { | ||
253 | myScriptEngine.Log.Debug("OnRemoveScript localID: " + localID + " LLUID: " + itemID.ToString()); | ||
254 | myScriptEngine.m_ScriptManager.StopScript( | ||
255 | localID, | ||
256 | itemID | ||
257 | ); | ||
258 | } | ||
259 | |||
260 | public void money(uint localID, UUID agentID, int amount) | ||
261 | { | ||
262 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
263 | "money", new object[] { | ||
264 | new LSL_Types.LSLString(agentID.ToString()), | ||
265 | new LSL_Types.LSLInteger(amount) }, | ||
266 | new DetectParams[0])); | ||
267 | } | ||
268 | |||
269 | // TODO: Replace placeholders below | ||
270 | // NOTE! THE PARAMETERS FOR THESE FUNCTIONS ARE NOT CORRECT! | ||
271 | // These needs to be hooked up to OpenSim during init of this class | ||
272 | // then queued in EventQueueManager. | ||
273 | // When queued in EventQueueManager they need to be LSL compatible (name and params) | ||
274 | |||
275 | public void state_exit(uint localID) | ||
276 | { | ||
277 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
278 | "state_exit", new object[] { }, | ||
279 | new DetectParams[0])); | ||
280 | } | ||
281 | |||
282 | public void collision_start(uint localID, ColliderArgs col) | ||
283 | { | ||
284 | // Add to queue for all scripts in ObjectID object | ||
285 | List<DetectParams> det = new List<DetectParams>(); | ||
286 | |||
287 | foreach (DetectedObject detobj in col.Colliders) | ||
288 | { | ||
289 | DetectParams d = new DetectParams(); | ||
290 | d.Key =detobj.keyUUID; | ||
291 | d.Populate(myScriptEngine.World); | ||
292 | det.Add(d); | ||
293 | } | ||
294 | |||
295 | if (det.Count > 0) | ||
296 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
297 | "collision_start", | ||
298 | new Object[] { new LSL_Types.LSLInteger(det.Count) }, | ||
299 | det.ToArray())); | ||
300 | } | ||
301 | |||
302 | public void collision(uint localID, ColliderArgs col) | ||
303 | { | ||
304 | // Add to queue for all scripts in ObjectID object | ||
305 | List<DetectParams> det = new List<DetectParams>(); | ||
306 | |||
307 | foreach (DetectedObject detobj in col.Colliders) | ||
308 | { | ||
309 | DetectParams d = new DetectParams(); | ||
310 | d.Key =detobj.keyUUID; | ||
311 | d.Populate(myScriptEngine.World); | ||
312 | det.Add(d); | ||
313 | } | ||
314 | |||
315 | if (det.Count > 0) | ||
316 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
317 | "collision", new Object[] { new LSL_Types.LSLInteger(det.Count) }, | ||
318 | det.ToArray())); | ||
319 | } | ||
320 | |||
321 | public void collision_end(uint localID, ColliderArgs col) | ||
322 | { | ||
323 | // Add to queue for all scripts in ObjectID object | ||
324 | List<DetectParams> det = new List<DetectParams>(); | ||
325 | |||
326 | foreach (DetectedObject detobj in col.Colliders) | ||
327 | { | ||
328 | DetectParams d = new DetectParams(); | ||
329 | d.Key =detobj.keyUUID; | ||
330 | d.Populate(myScriptEngine.World); | ||
331 | det.Add(d); | ||
332 | } | ||
333 | |||
334 | if (det.Count > 0) | ||
335 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
336 | "collision_end", | ||
337 | new Object[] { new LSL_Types.LSLInteger(det.Count) }, | ||
338 | det.ToArray())); | ||
339 | } | ||
340 | |||
341 | public void land_collision_start(uint localID, UUID itemID) | ||
342 | { | ||
343 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
344 | "land_collision_start", | ||
345 | new object[0], | ||
346 | new DetectParams[0])); | ||
347 | } | ||
348 | |||
349 | public void land_collision(uint localID, UUID itemID) | ||
350 | { | ||
351 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
352 | "land_collision", | ||
353 | new object[0], | ||
354 | new DetectParams[0])); | ||
355 | } | ||
356 | |||
357 | public void land_collision_end(uint localID, UUID itemID) | ||
358 | { | ||
359 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
360 | "land_collision_end", | ||
361 | new object[0], | ||
362 | new DetectParams[0])); | ||
363 | } | ||
364 | |||
365 | // Handled by long commands | ||
366 | public void timer(uint localID, UUID itemID) | ||
367 | { | ||
368 | } | ||
369 | |||
370 | public void listen(uint localID, UUID itemID) | ||
371 | { | ||
372 | } | ||
373 | |||
374 | public void control(uint localID, UUID itemID, UUID agentID, uint held, uint change) | ||
375 | { | ||
376 | if ((change == 0) && (myScriptEngine.m_EventQueueManager.CheckEeventQueueForEvent(localID,"control"))) return; | ||
377 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
378 | "control",new object[] { | ||
379 | new LSL_Types.LSLString(agentID.ToString()), | ||
380 | new LSL_Types.LSLInteger(held), | ||
381 | new LSL_Types.LSLInteger(change)}, | ||
382 | new DetectParams[0])); | ||
383 | } | ||
384 | |||
385 | public void email(uint localID, UUID itemID, string timeSent, | ||
386 | string address, string subject, string message, int numLeft) | ||
387 | { | ||
388 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
389 | "email",new object[] { | ||
390 | new LSL_Types.LSLString(timeSent), | ||
391 | new LSL_Types.LSLString(address), | ||
392 | new LSL_Types.LSLString(subject), | ||
393 | new LSL_Types.LSLString(message), | ||
394 | new LSL_Types.LSLInteger(numLeft)}, | ||
395 | new DetectParams[0])); | ||
396 | } | ||
397 | |||
398 | public void at_target(uint localID, uint handle, Vector3 targetpos, | ||
399 | Vector3 atpos) | ||
400 | { | ||
401 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
402 | "at_target", new object[] { | ||
403 | new LSL_Types.LSLInteger(handle), | ||
404 | new LSL_Types.Vector3(targetpos.X,targetpos.Y,targetpos.Z), | ||
405 | new LSL_Types.Vector3(atpos.X,atpos.Y,atpos.Z) }, | ||
406 | new DetectParams[0])); | ||
407 | } | ||
408 | |||
409 | public void not_at_target(uint localID) | ||
410 | { | ||
411 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
412 | "not_at_target",new object[0], | ||
413 | new DetectParams[0])); | ||
414 | } | ||
415 | |||
416 | public void at_rot_target(uint localID, UUID itemID) | ||
417 | { | ||
418 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
419 | "at_rot_target",new object[0], | ||
420 | new DetectParams[0])); | ||
421 | } | ||
422 | |||
423 | public void not_at_rot_target(uint localID, UUID itemID) | ||
424 | { | ||
425 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
426 | "not_at_rot_target",new object[0], | ||
427 | new DetectParams[0])); | ||
428 | } | ||
429 | |||
430 | public void attach(uint localID, UUID itemID) | ||
431 | { | ||
432 | } | ||
433 | |||
434 | public void dataserver(uint localID, UUID itemID) | ||
435 | { | ||
436 | } | ||
437 | |||
438 | public void link_message(uint localID, UUID itemID) | ||
439 | { | ||
440 | } | ||
441 | |||
442 | public void moving_start(uint localID, UUID itemID) | ||
443 | { | ||
444 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
445 | "moving_start",new object[0], | ||
446 | new DetectParams[0])); | ||
447 | } | ||
448 | |||
449 | public void moving_end(uint localID, UUID itemID) | ||
450 | { | ||
451 | myScriptEngine.PostObjectEvent(localID, new EventParams( | ||
452 | "moving_end",new object[0], | ||
453 | new DetectParams[0])); | ||
454 | } | ||
455 | |||
456 | public void object_rez(uint localID, UUID itemID) | ||
457 | { | ||
458 | } | ||
459 | |||
460 | public void remote_data(uint localID, UUID itemID) | ||
461 | { | ||
462 | } | ||
463 | |||
464 | // Handled by long commands | ||
465 | public void http_response(uint localID, UUID itemID) | ||
466 | { | ||
467 | } | ||
468 | |||
469 | /// <summary> | ||
470 | /// If set to true then threads and stuff should try to make a graceful exit | ||
471 | /// </summary> | ||
472 | public bool PleaseShutdown | ||
473 | { | ||
474 | get { return _PleaseShutdown; } | ||
475 | set { _PleaseShutdown = value; } | ||
476 | } | ||
477 | private bool _PleaseShutdown = false; | ||
478 | } | ||
479 | } | ||