ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/plugins/cfpython/cfpython.C
Revision: 1.4
Committed: Thu Sep 7 20:10:29 2006 UTC (17 years, 8 months ago) by pippijn
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +0 -0 lines
State: FILE REMOVED
Log Message:
Entirely removed cfpython.

File Contents

# Content
1 /*****************************************************************************/
2 /* CFPython - A Python module for Crossfire RPG. */
3 /*****************************************************************************/
4 /* This is the third version of the Crossfire Scripting Engine. */
5 /* The first version used Guile. It was directly integrated in the server */
6 /* code, but since Guile wasn't perceived as an easy-to-learn, easy-to-use */
7 /* language by many, it was dropped in favor of Python. */
8 /* The second version, CFPython 1.0, was included as a plugin and provided */
9 /* just about the same level of functionality the current version has. But */
10 /* it used a rather counter-intuitive, procedural way of presenting things. */
11 /* */
12 /* CFPython 2.0 aims at correcting many of the design flaws crippling the */
13 /* older version. It is also the first plugin to be implemented using the */
14 /* new interface, that doesn't need awkward stuff like the horrible CFParm */
15 /* structure. For the Python writer, things should probably be easier and */
16 /* lead to more readable code: instead of writing "CFPython.getObjectXPos(ob)*/
17 /* he/she now can simply write "ob.X". */
18 /* */
19 /*****************************************************************************/
20 /* Please note that it is still very beta - some of the functions may not */
21 /* work as expected and could even cause the server to crash. */
22 /*****************************************************************************/
23 /* Version history: */
24 /* 0.1 "Ophiuchus" - Initial Alpha release */
25 /* 0.5 "Stalingrad" - Message length overflow corrected. */
26 /* 0.6 "Kharkov" - Message and Write correctly redefined. */
27 /* 0.7 "Koursk" - Setting informations implemented. */
28 /* 1.0a "Petersburg" - Last "old-fashioned" version, never submitted to CVS.*/
29 /* 2.0 "Arkangelsk" - First release of the 2.x series. */
30 /*****************************************************************************/
31 /* Version: 2.0beta8 (also known as "Alexander") */
32 /* Contact: yann.chachkoff@myrealbox.com */
33 /*****************************************************************************/
34 /* That code is placed under the GNU General Public Licence (GPL) */
35 /* (C)2001-2005 by Chachkoff Yann (Feel free to deliver your complaints) */
36 /*****************************************************************************/
37 /* CrossFire, A Multiplayer game for X-windows */
38 /* */
39 /* Copyright (C) 2000 Mark Wedel */
40 /* Copyright (C) 1992 Frank Tore Johansen */
41 /* */
42 /* This program is free software; you can redistribute it and/or modify */
43 /* it under the terms of the GNU General Public License as published by */
44 /* the Free Software Foundation; either version 2 of the License, or */
45 /* (at your option) any later version. */
46 /* */
47 /* This program is distributed in the hope that it will be useful, */
48 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
49 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
50 /* GNU General Public License for more details. */
51 /* */
52 /* You should have received a copy of the GNU General Public License */
53 /* along with this program; if not, write to the Free Software */
54 /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
55 /* */
56 /*****************************************************************************/
57
58 /* First let's include the header file needed */
59
60 #include <cfpython.h>
61 #include <stdarg.h>
62
63 #define PYTHON_DEBUG /* give us some general infos out */
64
65 f_plug_api gethook;
66 f_plug_api registerGlobalEvent;
67 f_plug_api unregisterGlobalEvent;
68 f_plug_api systemDirectory;
69 f_plug_api reCmp;
70
71 static void set_exception(const char *fmt, ...);
72 static PyObject* createCFObject(PyObject* self, PyObject* args);
73 static PyObject* createCFObjectByName(PyObject* self, PyObject* args);
74 static PyObject* getCFPythonVersion(PyObject* self, PyObject* args);
75 static PyObject* getReturnValue(PyObject* self, PyObject* args);
76 static PyObject* setReturnValue(PyObject* self, PyObject* args);
77 static PyObject* matchString(PyObject* self, PyObject* args);
78 static PyObject* findPlayer(PyObject* self, PyObject* args);
79 static PyObject* readyMap(PyObject* self, PyObject* args);
80 static PyObject* getCostFlagTrue(PyObject* self, PyObject* args);
81 static PyObject* getCostFlagBuy(PyObject* self, PyObject* args);
82 static PyObject* getCostFlagSell(PyObject* self, PyObject* args);
83 static PyObject* getCostFlagNoBargain(PyObject* self, PyObject* args);
84 static PyObject* getCostFlagIdentified(PyObject* self, PyObject* args);
85 static PyObject* getCostFlagNotCursed(PyObject* self, PyObject* args);
86 static PyObject* getDirectionNorthEast(PyObject* self, PyObject* args);
87 static PyObject* getDirectionEast(PyObject* self, PyObject* args);
88 static PyObject* getDirectionSouthEast(PyObject* self, PyObject* args);
89 static PyObject* getDirectionSouth(PyObject* self, PyObject* args);
90 static PyObject* getDirectionSouthWest(PyObject* self, PyObject* args);
91 static PyObject* getDirectionWest(PyObject* self, PyObject* args);
92 static PyObject* getDirectionNorthWest(PyObject* self, PyObject* args);
93 static PyObject* getDirectionNorth(PyObject* self, PyObject* args);
94 static PyObject* getMapDirectory(PyObject* self, PyObject* args);
95 static PyObject* getUniqueDirectory(PyObject* self, PyObject* args);
96 static PyObject* getTempDirectory(PyObject* self, PyObject* args);
97 static PyObject* getConfigDirectory(PyObject* self, PyObject* args);
98 static PyObject* getLocalDirectory(PyObject* self, PyObject* args);
99 static PyObject* getPlayerDirectory(PyObject* self, PyObject* args);
100 static PyObject* getDataDirectory(PyObject* self, PyObject* args);
101 static PyObject* getWhoAmI(PyObject* self, PyObject* args);
102 static PyObject* getWhoIsActivator(PyObject* self, PyObject* args);
103 static PyObject* getWhoIsThird(PyObject* self, PyObject* args);
104 static PyObject* getWhatIsMessage(PyObject* self, PyObject* args);
105 static PyObject* getScriptName(PyObject* self, PyObject* args);
106 static PyObject* getScriptParameters(PyObject* self, PyObject* args);
107 static PyObject* getPrivateDictionary(PyObject* self, PyObject* args);
108 static PyObject* getSharedDictionary(PyObject* self, PyObject* args);
109 static PyObject* getArchetypes(PyObject* self, PyObject* args);
110 static PyObject* getMaps(PyObject* self, PyObject* args);
111 static PyObject* getParties(PyObject* self, PyObject* args);
112 static PyObject* getRegions(PyObject* self, PyObject* args);
113 static PyObject* registerCommand(PyObject* self, PyObject* args);
114 static PyObject* registerGEvent(PyObject* self, PyObject* args);
115 static PyObject* unregisterGEvent(PyObject* self, PyObject* args);
116 static PyObject* CFPythonError;
117
118 PythonCmd CustomCommand[NR_CUSTOM_CMD];
119
120 /* Set up an Python exception object. */
121 static void set_exception(const char *fmt, ...)
122 {
123 char buf[1024];
124 va_list arg;
125
126 va_start(arg, fmt);
127 vsnprintf(buf, sizeof(buf), fmt, arg);
128 va_end(arg);
129
130 PyErr_SetString(PyExc_ValueError, buf);
131 }
132
133 static PyMethodDef CFPythonMethods[] = {
134 {"WhoAmI", getWhoAmI, METH_VARARGS},
135 {"WhoIsActivator", getWhoIsActivator, METH_VARARGS},
136 {"WhoIsOther", getWhoIsThird, METH_VARARGS},
137 {"WhatIsMessage", getWhatIsMessage, METH_VARARGS},
138 {"ScriptName", getScriptName, METH_VARARGS},
139 {"ScriptParameters", getScriptParameters, METH_VARARGS},
140 {"MapDirectory", getMapDirectory, METH_VARARGS},
141 {"UniqueDirectory", getUniqueDirectory, METH_VARARGS},
142 {"TempDirectory", getTempDirectory, METH_VARARGS},
143 {"ConfigDirectory", getConfigDirectory, METH_VARARGS},
144 {"LocalDirectory", getLocalDirectory, METH_VARARGS},
145 {"PlayerDirectory", getPlayerDirectory, METH_VARARGS},
146 {"DataDirectory", getDataDirectory, METH_VARARGS},
147 {"DirectionNorth", getDirectionNorth, METH_VARARGS},
148 {"DirectionNorthEast", getDirectionNorthEast, METH_VARARGS},
149 {"DirectionEast", getDirectionEast, METH_VARARGS},
150 {"DirectionSouthEast", getDirectionSouthEast, METH_VARARGS},
151 {"DirectionSouth", getDirectionSouth, METH_VARARGS},
152 {"DirectionSouthWest", getDirectionSouthWest, METH_VARARGS},
153 {"DirectionWest", getDirectionWest, METH_VARARGS},
154 {"DirectionNorthWest", getDirectionNorthWest, METH_VARARGS},
155 {"CostFlagTrue", getCostFlagTrue, METH_VARARGS},
156 {"CostFlagBuy", getCostFlagBuy, METH_VARARGS},
157 {"CostFlagSell", getCostFlagSell, METH_VARARGS},
158 {"CostFlagNoBargain", getCostFlagNoBargain, METH_VARARGS},
159 {"CostFlagIdentified", getCostFlagIdentified, METH_VARARGS},
160 {"CostFlagNotCursed", getCostFlagNotCursed, METH_VARARGS},
161 {"ReadyMap", readyMap, METH_VARARGS},
162 {"FindPlayer", findPlayer, METH_VARARGS},
163 {"MatchString", matchString, METH_VARARGS},
164 {"GetReturnValue", getReturnValue, METH_VARARGS},
165 {"SetReturnValue", setReturnValue, METH_VARARGS},
166 {"PluginVersion", getCFPythonVersion, METH_VARARGS},
167 {"CreateObject", createCFObject, METH_VARARGS},
168 {"CreateObjectByName", createCFObjectByName, METH_VARARGS},
169 {"GetPrivateDictionary", getPrivateDictionary, METH_VARARGS},
170 {"GetSharedDictionary", getSharedDictionary, METH_VARARGS},
171 {"GetArchetypes", getArchetypes, METH_VARARGS},
172 {"GetMaps", getMaps, METH_VARARGS},
173 {"GetParties", getParties, METH_VARARGS},
174 {"GetRegions", getRegions, METH_VARARGS},
175 {"RegisterCommand", registerCommand, METH_VARARGS},
176 {"RegisterGlobalEvent", registerGEvent, METH_VARARGS},
177 {"UnregisterGlobalEvent",unregisterGEvent, METH_VARARGS},
178 {NULL, NULL, 0}
179 };
180
181 CFPContext* context_stack;
182 CFPContext* current_context;
183 static int current_command = -999;
184 static PyObject* shared_data = NULL;
185 static PyObject* private_data = NULL;
186
187 static PyObject* registerGEvent(PyObject* self, PyObject* args)
188 {
189 int eventcode;
190 if (!PyArg_ParseTuple(args, "i", &eventcode))
191 return NULL;
192
193 registerGlobalEvent(NULL, eventcode, PLUGIN_NAME, globalEventListener);
194
195 Py_INCREF(Py_None);
196 return Py_None;
197 }
198 static PyObject* unregisterGEvent(PyObject* self, PyObject* args)
199 {
200 int eventcode;
201 if (!PyArg_ParseTuple(args, "i", &eventcode))
202 return NULL;
203
204 unregisterGlobalEvent(NULL, EVENT_TELL, PLUGIN_NAME);
205
206 Py_INCREF(Py_None);
207 return Py_None;
208 }
209
210 static PyObject* createCFObject(PyObject* self, PyObject* args)
211 {
212 object* op;
213 op = cf_create_object();
214
215 if (op == NULL) {
216 Py_INCREF(Py_None);
217 return Py_None;
218 }
219 return Crossfire_Object_wrap(op);
220 }
221 static PyObject* createCFObjectByName(PyObject* self, PyObject* args)
222 {
223 char* obname;
224 object* op;
225
226 if (!PyArg_ParseTuple(args, "s", &obname))
227 return NULL;
228
229 op = cf_create_object_by_name(obname);
230
231 if (op == NULL) {
232 Py_INCREF(Py_None);
233 return Py_None;
234 }
235 return Crossfire_Object_wrap(op);
236 }
237 static PyObject* getCFPythonVersion(PyObject* self, PyObject* args)
238 {
239 int i = 2044;
240 if (!PyArg_ParseTuple(args, "", NULL))
241 return NULL;
242 return Py_BuildValue("i", i);
243 }
244 static PyObject* getReturnValue(PyObject* self, PyObject* args)
245 {
246 if (!PyArg_ParseTuple(args, "", NULL))
247 return NULL;
248 return Py_BuildValue("i", current_context->returnvalue);
249 }
250 static PyObject* setReturnValue(PyObject* self, PyObject* args)
251 {
252 int i;
253 if (!PyArg_ParseTuple(args, "i", &i))
254 return NULL;
255 current_context->returnvalue = i;
256 Py_INCREF(Py_None);
257 return Py_None;
258 }
259 static PyObject* matchString(PyObject* self, PyObject* args)
260 {
261 char *premiere;
262 char *seconde;
263 char *result;
264 int val;
265 if (!PyArg_ParseTuple(args, "ss", &premiere, &seconde))
266 return NULL;
267
268 result = (char*) reCmp( &val, premiere, seconde );
269 if (result != NULL)
270 return Py_BuildValue("i", 1);
271 else
272 return Py_BuildValue("i", 0);
273 }
274 static PyObject* findPlayer(PyObject* self, PyObject* args)
275 {
276 player *foundpl;
277 char* txt;
278
279 if (!PyArg_ParseTuple(args, "s", &txt))
280 return NULL;
281
282 foundpl = cf_player_find(txt);
283
284 if (foundpl != NULL)
285 return Py_BuildValue("O", Crossfire_Object_wrap(foundpl->ob));
286 else {
287 Py_INCREF(Py_None);
288 return Py_None;
289 }
290 }
291 static PyObject* readyMap(PyObject* self, PyObject* args)
292 {
293 char* mapname;
294 mapstruct* map;
295
296 if (!PyArg_ParseTuple(args, "s", &mapname))
297 return NULL;
298
299 map = cf_map_get_map(mapname);
300
301 if (map == NULL) {
302 Py_INCREF(Py_None);
303 return Py_None;
304 }
305 return Crossfire_Map_wrap(map);
306 }
307 static PyObject* getCostFlagTrue(PyObject* self, PyObject* args)
308 {
309 int i = F_TRUE;
310 if (!PyArg_ParseTuple(args, "", NULL))
311 return NULL;
312 return Py_BuildValue("i", i);
313 }
314 static PyObject* getCostFlagBuy(PyObject* self, PyObject* args)
315 {
316 int i = F_BUY;
317 if (!PyArg_ParseTuple(args, "", NULL))
318 return NULL;
319 return Py_BuildValue("i", i);
320 }
321 static PyObject* getCostFlagSell(PyObject* self, PyObject* args)
322 {
323 int i = F_SELL;
324 if (!PyArg_ParseTuple(args, "", NULL))
325 return NULL;
326 return Py_BuildValue("i", i);
327 }
328 static PyObject* getCostFlagNoBargain(PyObject* self, PyObject* args)
329 {
330 int i = F_NO_BARGAIN;
331 if (!PyArg_ParseTuple(args, "", NULL))
332 return NULL;
333 return Py_BuildValue("i", i);
334 }
335 static PyObject* getCostFlagIdentified(PyObject* self, PyObject* args)
336 {
337 int i = F_IDENTIFIED;
338 if (!PyArg_ParseTuple(args, "", NULL))
339 return NULL;
340 return Py_BuildValue("i", i);
341 }
342 static PyObject* getCostFlagNotCursed(PyObject* self, PyObject* args)
343 {
344 int i = F_NOT_CURSED;
345 if (!PyArg_ParseTuple(args, "", NULL))
346 return NULL;
347 return Py_BuildValue("i", i);
348 }
349 static PyObject* getDirectionNorthEast(PyObject* self, PyObject* args)
350 {
351 int i = 2;
352 if (!PyArg_ParseTuple(args, "", NULL))
353 return NULL;
354 return Py_BuildValue("i", i);
355 }
356 static PyObject* getDirectionEast(PyObject* self, PyObject* args)
357 {
358 int i = 3;
359 if (!PyArg_ParseTuple(args, "", NULL))
360 return NULL;
361 return Py_BuildValue("i", i);
362 }
363 static PyObject* getDirectionSouthEast(PyObject* self, PyObject* args)
364 {
365 int i = 4;
366 if (!PyArg_ParseTuple(args, "", NULL))
367 return NULL;
368 return Py_BuildValue("i", i);
369 }
370 static PyObject* getDirectionSouth(PyObject* self, PyObject* args)
371 {
372 int i = 5;
373 if (!PyArg_ParseTuple(args, "", NULL))
374 return NULL;
375 return Py_BuildValue("i", i);
376 }
377 static PyObject* getDirectionSouthWest(PyObject* self, PyObject* args)
378 {
379 int i = 6;
380 if (!PyArg_ParseTuple(args, "", NULL))
381 return NULL;
382 return Py_BuildValue("i", i);
383 }
384 static PyObject* getDirectionWest(PyObject* self, PyObject* args)
385 {
386 int i = 7;
387 if (!PyArg_ParseTuple(args, "", NULL))
388 return NULL;
389 return Py_BuildValue("i", i);
390 }
391 static PyObject* getDirectionNorthWest(PyObject* self, PyObject* args)
392 {
393 int i = 8;
394 if (!PyArg_ParseTuple(args, "", NULL))
395 return NULL;
396 return Py_BuildValue("i", i);
397 }
398 static PyObject* getDirectionNorth(PyObject* self, PyObject* args)
399 {
400 int i = 1;
401 if (!PyArg_ParseTuple(args, "", NULL))
402 return NULL;
403 return Py_BuildValue("i", i);
404 }
405 static PyObject* getMapDirectory(PyObject* self, PyObject* args)
406 {
407 int rv;
408 if (!PyArg_ParseTuple(args, "", NULL))
409 return NULL;
410 return Py_BuildValue("s", systemDirectory(&rv, 0));
411 }
412 static PyObject* getUniqueDirectory(PyObject* self, PyObject* args)
413 {
414 int rv;
415 if (!PyArg_ParseTuple(args, "", NULL))
416 return NULL;
417 return Py_BuildValue("s", systemDirectory(&rv, 1));
418 }
419 static PyObject* getTempDirectory(PyObject* self, PyObject* args)
420 {
421 int rv;
422 if (!PyArg_ParseTuple(args, "", NULL))
423 return NULL;
424 return Py_BuildValue("s", systemDirectory(&rv, 2));
425 }
426 static PyObject* getConfigDirectory(PyObject* self, PyObject* args)
427 {
428 int rv;
429 if (!PyArg_ParseTuple(args, "", NULL))
430 return NULL;
431 return Py_BuildValue("s", systemDirectory(&rv, 3));
432 }
433 static PyObject* getLocalDirectory(PyObject* self, PyObject* args)
434 {
435 int rv;
436 if (!PyArg_ParseTuple(args, "", NULL))
437 return NULL;
438 return Py_BuildValue("s", systemDirectory(&rv, 4));
439 }
440 static PyObject* getPlayerDirectory(PyObject* self, PyObject* args)
441 {
442 int rv;
443 if (!PyArg_ParseTuple(args, "", NULL))
444 return NULL;
445 return Py_BuildValue("s", systemDirectory(&rv, 5));
446 }
447 static PyObject* getDataDirectory(PyObject* self, PyObject* args)
448 {
449 int rv;
450 if (!PyArg_ParseTuple(args, "", NULL))
451 return NULL;
452 return Py_BuildValue("s", systemDirectory(&rv, 6));
453 }
454 static PyObject* getWhoAmI(PyObject* self, PyObject* args)
455 {
456 if (!PyArg_ParseTuple(args, "", NULL))
457 return NULL;
458 if (!current_context->who) {
459 Py_INCREF(Py_None);
460 return Py_None;
461 }
462 Py_INCREF(current_context->who);
463 return current_context->who;
464 }
465 static PyObject* getWhoIsActivator(PyObject* self, PyObject* args)
466 {
467 if (!PyArg_ParseTuple(args, "", NULL))
468 return NULL;
469 if (!current_context->activator) {
470 Py_INCREF(Py_None);
471 return Py_None;
472 }
473 Py_INCREF(current_context->activator);
474 return current_context->activator;
475 }
476 static PyObject* getWhoIsThird(PyObject* self, PyObject* args)
477 {
478 if (!PyArg_ParseTuple(args, "", NULL))
479 return NULL;
480 if (!current_context->third) {
481 Py_INCREF(Py_None);
482 return Py_None;
483 }
484 Py_INCREF(current_context->third);
485 return current_context->third;
486 }
487 static PyObject* getWhatIsMessage(PyObject* self, PyObject* args)
488 {
489 if (!PyArg_ParseTuple(args, "", NULL))
490 return NULL;
491
492 if (current_context->message == NULL)
493 return Py_BuildValue("");
494 else
495 return Py_BuildValue("s", current_context->message);
496 }
497 static PyObject* getScriptName(PyObject* self, PyObject* args)
498 {
499 if (!PyArg_ParseTuple(args, "", NULL))
500 return NULL;
501 return Py_BuildValue("s", current_context->script);
502 }
503 static PyObject* getScriptParameters(PyObject* self, PyObject* args)
504 {
505 if (!PyArg_ParseTuple(args, "", NULL))
506 return NULL;
507 return Py_BuildValue("s", current_context->options);
508 }
509
510 static PyObject* getPrivateDictionary(PyObject* self, PyObject* args)
511 {
512 PyObject* data;
513
514 if (!PyArg_ParseTuple(args, "", NULL))
515 return NULL;
516
517 data = PyDict_GetItemString(private_data, current_context->script);
518 if (!data) {
519 data = PyDict_New();
520 PyDict_SetItemString(private_data, current_context->script, data);
521 Py_DECREF(data);
522 }
523 Py_INCREF(data);
524 return data;
525 }
526
527 static PyObject* getSharedDictionary(PyObject* self, PyObject* args)
528 {
529 if (!PyArg_ParseTuple(args, "", NULL))
530 return NULL;
531
532 Py_INCREF(shared_data);
533 return shared_data;
534 }
535
536 static PyObject* getArchetypes(PyObject* self, PyObject* args)
537 {
538 PyObject* list;
539 archetype* arch;
540
541 list = PyList_New(0);
542 arch = cf_archetype_get_first();
543 while (arch) {
544 PyList_Append(list, Crossfire_Archetype_wrap(arch));
545 arch = cf_archetype_get_next(arch);
546 }
547 return list;
548 }
549
550 static PyObject* getMaps(PyObject* self, PyObject* args)
551 {
552 PyObject* list;
553 mapstruct* map;
554
555 list = PyList_New(0);
556 map = cf_map_get_first();
557 while (map) {
558 PyList_Append(list, Crossfire_Map_wrap(map));
559 map = (mapstruct*) cf_map_get_property(map, CFAPI_MAP_PROP_NEXT);
560 }
561 return list;
562 }
563
564 static PyObject* getParties(PyObject* self, PyObject* args)
565 {
566 PyObject* list;
567 partylist* party;
568
569 list = PyList_New(0);
570 party = cf_party_get_first();
571 while (party) {
572 PyList_Append(list, Crossfire_Party_wrap(party));
573 party = cf_party_get_next(party);
574 }
575 return list;
576 }
577
578 static PyObject* getRegions(PyObject* self, PyObject* args)
579 {
580 PyObject *list;
581 region *reg;
582
583 list = PyList_New(0);
584 reg = cf_region_get_first();
585 while (reg) {
586 PyList_Append(list, Crossfire_Region_wrap(reg));
587 reg = cf_region_get_next(reg);
588 }
589 return list;
590 }
591
592 static PyObject* registerCommand(PyObject* self, PyObject* args)
593 {
594 char *cmdname;
595 char *scriptname;
596 double cmdspeed;
597 int i;
598
599 if (!PyArg_ParseTuple(args, "ssd", &cmdname, &scriptname, &cmdspeed))
600 return NULL;
601
602 if (cmdspeed < 0) {
603 set_exception("speed must not be negative");
604 return NULL;
605 }
606
607 for (i = 0; i < NR_CUSTOM_CMD; i++) {
608 if (CustomCommand[i].name != NULL) {
609 if (!strcmp(CustomCommand[i].name, cmdname)) {
610 set_exception("command '%s' is already registered", cmdname);
611 return NULL;
612 }
613 }
614 }
615 for (i = 0; i < NR_CUSTOM_CMD; i++) {
616 if (CustomCommand[i].name == NULL) {
617 CustomCommand[i].name = cf_strdup_local(cmdname);
618 CustomCommand[i].script = cf_strdup_local(scriptname);
619 CustomCommand[i].speed = cmdspeed;
620 break;
621 }
622 };
623
624 Py_INCREF(Py_None);
625 return Py_None;
626 }
627
628 void initContextStack()
629 {
630 current_context = NULL;
631 context_stack = NULL;
632 }
633
634 void pushContext(CFPContext* context)
635 {
636 if (current_context == NULL) {
637 context_stack = context;
638 context->down = NULL;
639 } else {
640 context->down = current_context;
641 }
642 current_context = context;
643 }
644
645 CFPContext* popContext()
646 {
647 CFPContext* oldcontext;
648 if (current_context != NULL) {
649 oldcontext = current_context;
650 current_context = current_context->down;
651 return oldcontext;
652 }
653 else
654 return NULL;
655 }
656
657 void freeContext(CFPContext* context)
658 {
659 Py_XDECREF(context->who);
660 Py_XDECREF(context->activator);
661 Py_XDECREF(context->third);
662 free(context);
663 }
664
665 static int do_script(CFPContext* context, int silent)
666 {
667 FILE* scriptfile;
668 PyObject* dict;
669 PyObject* ret;
670 #if 0
671 PyObject* list;
672 int item;
673 #endif
674
675 scriptfile = fopen(context->script, "r");
676 if (scriptfile == NULL) {
677 if (!silent)
678 printf( "cfpython - The Script file %s can't be opened\n", context->script);
679 return 0;
680 }
681 pushContext(context);
682 dict = PyDict_New();
683 PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins());
684 ret = PyRun_File(scriptfile, context->script, Py_file_input, dict, dict);
685 if (PyErr_Occurred()) {
686 PyErr_Print();
687 }
688 Py_XDECREF(ret);
689 #if 0
690 printf( "cfpython - %d items in heap\n", PyDict_Size(dict));
691 list = PyDict_Values(dict);
692 for (item = PyList_Size(list) - 1; item >= 0; item--) {
693 dict = PyList_GET_ITEM(list, item);
694 ret = PyObject_Str(dict);
695 printf(" ref %s = %d\n", PyString_AsString(ret), dict->ob_refcnt);
696 Py_XDECREF(ret);
697 }
698 Py_DECREF(list);
699 #endif
700 Py_DECREF(dict);
701 fclose(scriptfile);
702 return 1;
703 }
704
705 extern "C" CF_PLUGIN int initPlugin(const char* iversion, f_plug_api gethooksptr)
706 {
707 PyObject *m, *d;
708 int i;
709 gethook = gethooksptr;
710 printf("CFPython 2.0a init\n");
711
712 Py_Initialize();
713 Crossfire_ObjectType.tp_new = PyType_GenericNew;
714 Crossfire_MapType.tp_new = PyType_GenericNew;
715 Crossfire_PlayerType.tp_new = PyType_GenericNew;
716 Crossfire_ArchetypeType.tp_new = PyType_GenericNew;
717 Crossfire_PartyType.tp_new = PyType_GenericNew;
718 Crossfire_RegionType.tp_new = PyType_GenericNew;
719 PyType_Ready(&Crossfire_ObjectType);
720 PyType_Ready(&Crossfire_MapType);
721 PyType_Ready(&Crossfire_PlayerType);
722 PyType_Ready(&Crossfire_ArchetypeType);
723 PyType_Ready(&Crossfire_PartyType);
724 PyType_Ready(&Crossfire_RegionType);
725
726 m = Py_InitModule("Crossfire", CFPythonMethods);
727 d = PyModule_GetDict(m);
728 Py_INCREF(&Crossfire_ObjectType);
729 Py_INCREF(&Crossfire_MapType);
730 Py_INCREF(&Crossfire_PlayerType);
731 Py_INCREF(&Crossfire_ArchetypeType);
732 Py_INCREF(&Crossfire_PartyType);
733 Py_INCREF(&Crossfire_RegionType);
734
735 PyModule_AddObject(m, "Object", (PyObject*)&Crossfire_ObjectType);
736 PyModule_AddObject(m, "Map", (PyObject*)&Crossfire_MapType);
737 PyModule_AddObject(m, "Player", (PyObject*)&Crossfire_PlayerType);
738 PyModule_AddObject(m, "Archetype", (PyObject*)&Crossfire_ArchetypeType);
739 PyModule_AddObject(m, "Party", (PyObject*)&Crossfire_PartyType);
740 PyModule_AddObject(m, "Region", (PyObject*)&Crossfire_RegionType);
741
742 CFPythonError = PyErr_NewException("Crossfire.error", NULL, NULL);
743 PyDict_SetItemString(d, "error", CFPythonError);
744 for (i = 0; i < NR_CUSTOM_CMD; i++) {
745 CustomCommand[i].name = NULL;
746 CustomCommand[i].script = NULL;
747 CustomCommand[i].speed = 0.0;
748 }
749 private_data = PyDict_New();
750 shared_data = PyDict_New();
751 return 0;
752 }
753
754 extern "C" CF_PLUGIN void* getPluginProperty(int* type, ...)
755 {
756 va_list args;
757 const char* propname;
758 int i;
759 static CommArray_s rtn_cmd;
760
761 va_start(args, type);
762 propname = va_arg(args, const char *);
763
764 if (!strcmp(propname, "command?")) {
765 const char* cmdname;
766 cmdname = va_arg(args, const char *);
767 va_end(args);
768
769 for (i = 0; i < NR_CUSTOM_CMD; i++) {
770 if (CustomCommand[i].name != NULL) {
771 if (!strcmp(CustomCommand[i].name, cmdname)) {
772 rtn_cmd.name = CustomCommand[i].name;
773 rtn_cmd.time = (float)CustomCommand[i].speed;
774 rtn_cmd.func = runPluginCommand;
775 current_command = i;
776 return &rtn_cmd;
777 }
778 }
779 }
780 return NULL;
781 } else if (!strcmp(propname, "Identification")) {
782 va_end(args);
783 return (void*) PLUGIN_NAME;
784 } else if (!strcmp(propname, "FullName")) {
785 va_end(args);
786 return (void*) PLUGIN_VERSION;
787 }
788 return NULL;
789 }
790
791 extern "C" CF_PLUGIN int runPluginCommand(object* op, char* params)
792 {
793 char buf[1024];
794 CFPContext* context;
795 static int rv = 0;
796
797 rv = 0;
798
799 if (current_command < 0) {
800 printf("Illegal call of runPluginCommand, call find_plugin_command first.\n");
801 return 1;
802 }
803 snprintf(buf, sizeof(buf), "%s.py", cf_get_maps_directory(CustomCommand[current_command].script));
804
805 context = (CFPContext*) malloc(sizeof(CFPContext));
806 context->message[0] = 0;
807
808 context->who = Crossfire_Object_wrap(op);
809 context->activator = NULL;
810 context->third = NULL;
811 context->fix = 0;
812 snprintf(context->script, sizeof(context->script), "%s", buf);
813 snprintf(context->options, sizeof(context->options), "%s", params);
814 context->returnvalue = 1; /* Default is "command successful" */
815
816 current_command = -999;
817
818 if (!do_script(context, 0)) {
819 freeContext(context);
820 return rv;
821 }
822
823 context = popContext();
824 rv = context->returnvalue;
825 freeContext(context);
826 /* printf("Execution complete"); */
827 return rv;
828 }
829
830 extern "C" CF_PLUGIN int postInitPlugin()
831 {
832 int hooktype = 1;
833 int rtype = 0;
834 FILE* scriptfile;
835
836 printf("CFPython 2.0a post init\n");
837 registerGlobalEvent = (void* (*)(int*, ...)) gethook(&rtype, hooktype, "cfapi_system_register_global_event");
838 unregisterGlobalEvent = (void* (*)(int*, ...))gethook(&rtype, hooktype, "cfapi_system_unregister_global_event");
839 systemDirectory = (void* (*)(int*, ...))gethook(&rtype, hooktype, "cfapi_system_directory");
840 reCmp = (void* (*)(int*, ...))gethook(&rtype, hooktype, "cfapi_system_re_cmp");
841 cf_init_plugin( gethook );
842 initContextStack();
843 /*registerGlobalEvent(NULL, EVENT_CLOCK, PLUGIN_NAME, globalEventListener);*/
844 /*registerGlobalEvent(NULL, EVENT_CRASH, PLUGIN_NAME, globalEventListener);*/
845 registerGlobalEvent(NULL, EVENT_SHOUT, PLUGIN_NAME, globalEventListener);
846 registerGlobalEvent(NULL, EVENT_TELL, PLUGIN_NAME, globalEventListener);
847 registerGlobalEvent(NULL, EVENT_MUZZLE, PLUGIN_NAME, globalEventListener);
848 registerGlobalEvent(NULL, EVENT_KICK, PLUGIN_NAME, globalEventListener);
849
850 scriptfile = fopen(cf_get_maps_directory("python/events/python_init.py"), "r");
851 if (scriptfile != NULL) {
852 PyRun_SimpleFile(scriptfile, cf_get_maps_directory("python/events/python_init.py"));
853 fclose(scriptfile);
854 }
855
856 return 0;
857 }
858
859 extern "C" CF_PLUGIN void* globalEventListener(int* type, ...)
860 {
861 va_list args;
862 static int rv = 0;
863 CFPContext* context;
864 Crossfire_Player* cfpl;
865 Crossfire_Object* cfob;
866 char* buf;
867 player* pl;
868 object* op;
869 context = (CFPContext*) malloc(sizeof(CFPContext));
870
871 rv = 0;
872
873 va_start(args, type);
874 context->event_code = va_arg(args, int);
875
876 context->message[0] = 0;
877
878 context->who = NULL;
879 context->activator = NULL;
880 context->third = NULL;
881 rv = context->returnvalue = 0;
882 snprintf(context->script, sizeof(context->script), "%s", cf_get_maps_directory("python/events/python_event.py"));
883 strcpy(context->options, "");
884 switch(context->event_code) {
885 case EVENT_CRASH:
886 printf( "Unimplemented for now\n");
887 break;
888 case EVENT_SHOUT:
889 op = va_arg(args, object*);
890 context->activator = Crossfire_Object_wrap(op);
891 buf = va_arg(args, char*);
892 if (buf != NULL)
893 snprintf(context->message, sizeof(context->message), "%s", buf);
894 snprintf(context->options, sizeof(context->options), "shout");
895 cfob = (Crossfire_Object*)context->activator;
896 break;
897 case EVENT_MUZZLE:
898 op = va_arg(args, object*);
899 context->activator = Crossfire_Object_wrap(op);
900 buf = va_arg(args, char*);
901 if (buf != NULL)
902 snprintf(context->message, sizeof(context->message), "%s", buf);
903 snprintf(context->options, sizeof(context->options), "muzzle");
904 cfob = (Crossfire_Object*)context->activator;
905 break;
906 case EVENT_KICK:
907 op = va_arg(args, object*);
908 context->activator = Crossfire_Object_wrap(op);
909 buf = va_arg(args, char*);
910 if (buf != NULL)
911 snprintf(context->message, sizeof(context->message), "%s", buf);
912 snprintf(context->options, sizeof(context->options), "kick");
913 cfob = (Crossfire_Object*)context->activator;
914 break;
915 case EVENT_CLOCK:
916 snprintf(context->options, sizeof(context->options), "clock");
917 break;
918 case EVENT_TELL:
919 snprintf(context->options, sizeof(context->options), "tell");
920 break;
921 }
922 va_end(args);
923 context->returnvalue = 0;
924
925 if (!do_script(context, 1)) {
926 freeContext(context);
927 return &rv;
928 }
929
930 context = popContext();
931 rv = context->returnvalue;
932 freeContext(context);
933
934 return &rv;
935 }
936
937 extern "C" CF_PLUGIN void* eventListener(int* type, ...)
938 {
939 static int rv = 0;
940 va_list args;
941 char* buf;
942 CFPContext* context;
943
944 rv = 0;
945
946 context = (CFPContext*) malloc(sizeof(CFPContext));
947
948 context->message[0] = 0;
949
950 va_start(args, type);
951
952 context->who = Crossfire_Object_wrap(va_arg(args, object*));
953 context->event_code = va_arg(args, int);
954 context->activator = Crossfire_Object_wrap(va_arg(args, object*));
955 context->third = Crossfire_Object_wrap(va_arg(args, object*));
956 buf = va_arg(args, char*);
957 if (buf != NULL)
958 snprintf(context->message, sizeof(context->message), "%s", buf);
959 context->fix = va_arg(args, int);
960 snprintf(context->script, sizeof(context->script), "%s", cf_get_maps_directory(va_arg(args, char*)));
961 snprintf(context->options, sizeof(context->options), "%s", va_arg(args, char*));
962 context->returnvalue = 0;
963
964 va_end(args);
965
966 if (!do_script(context, 0)) {
967 freeContext(context);
968 return &rv;
969 }
970
971 context = popContext();
972 rv = context->returnvalue;
973 freeContext(context);
974 return &rv;
975 }
976
977 extern "C" CF_PLUGIN int closePlugin()
978 {
979 printf("CFPython 2.0a closing\n");
980 Py_Finalize();
981 return 0;
982 }