aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/EventManager.cs479
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
28using System;
29using System.Collections.Generic;
30using OpenMetaverse;
31using OpenSim.Framework;
32using OpenSim.Region.Environment.Modules.Avatar.Currency.SampleMoney;
33using OpenSim.Region.Environment;
34using OpenSim.Region.Interfaces;
35using OpenSim.Region;
36using OpenSim.Region.Environment.Scenes;
37using OpenSim.Region.Environment.Interfaces;
38using OpenSim.Region.ScriptEngine.Shared;
39
40namespace 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}