ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/plugins/cfpython/cfpython.C
Revision: 1.1
Committed: Sun Aug 13 17:16:02 2006 UTC (17 years, 10 months ago) by elmex
Content type: text/plain
Branch: MAIN
Log Message:
Made server compile with C++.
Removed cfanim plugin and crossedit.
C++ here we come.

File Contents

# User Rev Content
1 elmex 1.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_BORN, PLUGIN_NAME, globalEventListener);
844     /*registerGlobalEvent(NULL, EVENT_CLOCK, PLUGIN_NAME, globalEventListener);*/
845     /*registerGlobalEvent(NULL, EVENT_CRASH, PLUGIN_NAME, globalEventListener);*/
846     registerGlobalEvent(NULL, EVENT_PLAYER_DEATH, PLUGIN_NAME, globalEventListener);
847     registerGlobalEvent(NULL, EVENT_GKILL, PLUGIN_NAME, globalEventListener);
848     registerGlobalEvent(NULL, EVENT_LOGIN, PLUGIN_NAME, globalEventListener);
849     registerGlobalEvent(NULL, EVENT_LOGOUT, PLUGIN_NAME, globalEventListener);
850     registerGlobalEvent(NULL, EVENT_MAPENTER, PLUGIN_NAME, globalEventListener);
851     registerGlobalEvent(NULL, EVENT_MAPLEAVE, PLUGIN_NAME, globalEventListener);
852     registerGlobalEvent(NULL, EVENT_MAPRESET, PLUGIN_NAME, globalEventListener);
853     registerGlobalEvent(NULL, EVENT_REMOVE, PLUGIN_NAME, globalEventListener);
854     registerGlobalEvent(NULL, EVENT_SHOUT, PLUGIN_NAME, globalEventListener);
855     registerGlobalEvent(NULL, EVENT_TELL, PLUGIN_NAME, globalEventListener);
856     registerGlobalEvent(NULL, EVENT_MUZZLE, PLUGIN_NAME, globalEventListener);
857     registerGlobalEvent(NULL, EVENT_KICK, PLUGIN_NAME, globalEventListener);
858    
859     scriptfile = fopen(cf_get_maps_directory("python/events/python_init.py"), "r");
860     if (scriptfile != NULL) {
861     PyRun_SimpleFile(scriptfile, cf_get_maps_directory("python/events/python_init.py"));
862     fclose(scriptfile);
863     }
864    
865     return 0;
866     }
867    
868     extern "C" CF_PLUGIN void* globalEventListener(int* type, ...)
869     {
870     va_list args;
871     static int rv = 0;
872     CFPContext* context;
873     Crossfire_Player* cfpl;
874     Crossfire_Object* cfob;
875     char* buf;
876     player* pl;
877     object* op;
878     context = (CFPContext*) malloc(sizeof(CFPContext));
879    
880     rv = 0;
881    
882     va_start(args, type);
883     context->event_code = va_arg(args, int);
884    
885     context->message[0] = 0;
886    
887     context->who = NULL;
888     context->activator = NULL;
889     context->third = NULL;
890     rv = context->returnvalue = 0;
891     snprintf(context->script, sizeof(context->script), "%s", cf_get_maps_directory("python/events/python_event.py"));
892     strcpy(context->options, "");
893     switch(context->event_code) {
894     case EVENT_CRASH:
895     printf( "Unimplemented for now\n");
896     break;
897     case EVENT_BORN:
898     op = va_arg(args, object*);
899     context->activator = Crossfire_Object_wrap(op);
900     snprintf(context->options, sizeof(context->options), "born");
901     cfob = (Crossfire_Object*)context->activator;
902     break;
903     case EVENT_PLAYER_DEATH:
904     op = va_arg(args, object*);
905     context->who = Crossfire_Object_wrap(op);
906     snprintf(context->options, sizeof(context->options), "death");
907     cfob = (Crossfire_Object*)context->who;
908     break;
909     case EVENT_GKILL:
910     op = va_arg(args, object*);
911     context->who = Crossfire_Object_wrap(op);
912     context->activator = Crossfire_Object_wrap(op);
913     snprintf(context->options, sizeof(context->options), "gkill");
914     cfob = (Crossfire_Object*)context->who;
915     break;
916     case EVENT_LOGIN:
917     pl = va_arg(args, player*);
918     context->activator = Crossfire_Object_wrap(pl->ob);
919     buf = va_arg(args, char*);
920     if (buf != NULL)
921     snprintf(context->message, sizeof(context->message), "%s", buf);
922     snprintf(context->options, sizeof(context->options), "login");
923     cfpl = (Crossfire_Player*)context->activator;
924     break;
925     case EVENT_LOGOUT:
926     pl = va_arg(args, player*);
927     context->activator = Crossfire_Object_wrap(pl->ob);
928     buf = va_arg(args, char*);
929     if (buf != NULL)
930     snprintf(context->message, sizeof(context->message), "%s", buf);
931     snprintf(context->options, sizeof(context->options), "logout");
932     cfpl = (Crossfire_Player*)context->activator;
933     break;
934     case EVENT_REMOVE:
935     op = va_arg(args, object*);
936     context->activator = Crossfire_Object_wrap(op);
937     snprintf(context->options, sizeof(context->options), "remove");
938     cfob = (Crossfire_Object*)context->activator;
939     break;
940     case EVENT_SHOUT:
941     op = va_arg(args, object*);
942     context->activator = Crossfire_Object_wrap(op);
943     buf = va_arg(args, char*);
944     if (buf != NULL)
945     snprintf(context->message, sizeof(context->message), "%s", buf);
946     snprintf(context->options, sizeof(context->options), "shout");
947     cfob = (Crossfire_Object*)context->activator;
948     break;
949     case EVENT_MUZZLE:
950     op = va_arg(args, object*);
951     context->activator = Crossfire_Object_wrap(op);
952     buf = va_arg(args, char*);
953     if (buf != NULL)
954     snprintf(context->message, sizeof(context->message), "%s", buf);
955     snprintf(context->options, sizeof(context->options), "muzzle");
956     cfob = (Crossfire_Object*)context->activator;
957     break;
958     case EVENT_KICK:
959     op = va_arg(args, object*);
960     context->activator = Crossfire_Object_wrap(op);
961     buf = va_arg(args, char*);
962     if (buf != NULL)
963     snprintf(context->message, sizeof(context->message), "%s", buf);
964     snprintf(context->options, sizeof(context->options), "kick");
965     cfob = (Crossfire_Object*)context->activator;
966     break;
967     case EVENT_MAPENTER:
968     op = va_arg(args, object*);
969     context->activator = Crossfire_Object_wrap(op);
970     snprintf(context->options, sizeof(context->options), "mapenter");
971     cfob = (Crossfire_Object*)context->activator;
972     break;
973     case EVENT_MAPLEAVE:
974     op = va_arg(args, object*);
975     context->activator = Crossfire_Object_wrap(op);
976     snprintf(context->options, sizeof(context->options), "mapleave");
977     cfob = (Crossfire_Object*)context->activator;
978     break;
979     case EVENT_CLOCK:
980     snprintf(context->options, sizeof(context->options), "clock");
981     break;
982     case EVENT_MAPRESET:
983     buf = va_arg(args, char*);
984     if (buf != NULL)
985     snprintf(context->message, sizeof(context->message), "%s", buf);
986     snprintf(context->options, sizeof(context->options), "mapreset");
987     break;
988     case EVENT_TELL:
989     snprintf(context->options, sizeof(context->options), "tell");
990     break;
991     }
992     va_end(args);
993     context->returnvalue = 0;
994    
995     if (!do_script(context, 1)) {
996     freeContext(context);
997     return &rv;
998     }
999    
1000     context = popContext();
1001     rv = context->returnvalue;
1002     freeContext(context);
1003    
1004     return &rv;
1005     }
1006    
1007     extern "C" CF_PLUGIN void* eventListener(int* type, ...)
1008     {
1009     static int rv = 0;
1010     va_list args;
1011     char* buf;
1012     CFPContext* context;
1013    
1014     rv = 0;
1015    
1016     context = (CFPContext*) malloc(sizeof(CFPContext));
1017    
1018     context->message[0] = 0;
1019    
1020     va_start(args, type);
1021    
1022     context->who = Crossfire_Object_wrap(va_arg(args, object*));
1023     context->event_code = va_arg(args, int);
1024     context->activator = Crossfire_Object_wrap(va_arg(args, object*));
1025     context->third = Crossfire_Object_wrap(va_arg(args, object*));
1026     buf = va_arg(args, char*);
1027     if (buf != NULL)
1028     snprintf(context->message, sizeof(context->message), "%s", buf);
1029     context->fix = va_arg(args, int);
1030     snprintf(context->script, sizeof(context->script), "%s", cf_get_maps_directory(va_arg(args, char*)));
1031     snprintf(context->options, sizeof(context->options), "%s", va_arg(args, char*));
1032     context->returnvalue = 0;
1033    
1034     va_end(args);
1035    
1036     if (!do_script(context, 0)) {
1037     freeContext(context);
1038     return &rv;
1039     }
1040    
1041     context = popContext();
1042     rv = context->returnvalue;
1043     freeContext(context);
1044     return &rv;
1045     }
1046    
1047     extern "C" CF_PLUGIN int closePlugin()
1048     {
1049     printf("CFPython 2.0a closing\n");
1050     Py_Finalize();
1051     return 0;
1052     }