Crossfire Server, Branches 1.12  R18729
cfpython.c
Go to the documentation of this file.
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 #include <node.h>
63 
64 #define PYTHON_DEBUG /* give us some general infos out */
65 #define PYTHON_CACHE_SIZE 16 /* number of python scripts to store the bytecode of at a time */
66 
67 typedef struct {
69  PyCodeObject *code;
70  time_t cached_time, used_time;
72 
74 
76 
77 static void set_exception(const char *fmt, ...);
78 static PyObject *createCFObject(PyObject *self, PyObject *args);
79 static PyObject *createCFObjectByName(PyObject *self, PyObject *args);
80 static PyObject *getCFPythonVersion(PyObject *self, PyObject *args);
81 static PyObject *getReturnValue(PyObject *self, PyObject *args);
82 static PyObject *setReturnValue(PyObject *self, PyObject *args);
83 static PyObject *matchString(PyObject *self, PyObject *args);
84 static PyObject *findPlayer(PyObject *self, PyObject *args);
85 static PyObject *readyMap(PyObject *self, PyObject *args);
86 static PyObject *createMap(PyObject *self, PyObject *args);
87 static PyObject *getMapDirectory(PyObject *self, PyObject *args);
88 static PyObject *getUniqueDirectory(PyObject *self, PyObject *args);
89 static PyObject *getTempDirectory(PyObject *self, PyObject *args);
90 static PyObject *getConfigDirectory(PyObject *self, PyObject *args);
91 static PyObject *getLocalDirectory(PyObject *self, PyObject *args);
92 static PyObject *getPlayerDirectory(PyObject *self, PyObject *args);
93 static PyObject *getDataDirectory(PyObject *self, PyObject *args);
94 static PyObject *getWhoAmI(PyObject *self, PyObject *args);
95 static PyObject *getWhoIsActivator(PyObject *self, PyObject *args);
96 static PyObject *getWhoIsThird(PyObject *self, PyObject *args);
97 static PyObject *getWhatIsMessage(PyObject *self, PyObject *args);
98 static PyObject *getScriptName(PyObject *self, PyObject *args);
99 static PyObject *getScriptParameters(PyObject *self, PyObject *args);
100 static PyObject *getEvent(PyObject *self, PyObject *args);
101 static PyObject *getPrivateDictionary(PyObject *self, PyObject *args);
102 static PyObject *getSharedDictionary(PyObject *self, PyObject *args);
103 static PyObject *getArchetypes(PyObject *self, PyObject *args);
104 static PyObject *getPlayers(PyObject *self, PyObject *args);
105 static PyObject *getMaps(PyObject *self, PyObject *args);
106 static PyObject *getParties(PyObject *self, PyObject *args);
107 static PyObject *getRegions(PyObject *self, PyObject *args);
108 static PyObject *getFriendlyList(PyObject *self, PyObject *args);
109 static PyObject *registerCommand(PyObject *self, PyObject *args);
110 static PyObject *registerGEvent(PyObject *self, PyObject *args);
111 static PyObject *unregisterGEvent(PyObject *self, PyObject *args);
112 static PyObject *CFPythonError;
113 static PyObject *getTime(PyObject *self, PyObject *args);
114 static PyObject *destroyTimer(PyObject *self, PyObject *args);
115 static PyObject *getMapHasBeenLoaded(PyObject *self, PyObject *args);
116 static PyObject *findAnimation(PyObject *self, PyObject *args);
117 static PyObject *log_message(PyObject *self, PyObject *args);
118 static PyObject *findFace(PyObject *self, PyObject *args);
119 static PyObject *getSeasonName(PyObject *self, PyObject *args);
120 static PyObject *getMonthName(PyObject *self, PyObject *args);
121 static PyObject *getWeekdayName(PyObject *self, PyObject *args);
122 static PyObject *getPeriodofdayName(PyObject *self, PyObject *args);
123 
125 static void set_exception(const char *fmt, ...) {
126  char buf[1024];
127  va_list arg;
128 
129  va_start(arg, fmt);
130  vsnprintf(buf, sizeof(buf), fmt, arg);
131  va_end(arg);
132 
133  PyErr_SetString(PyExc_ValueError, buf);
134 }
135 
136 static PyMethodDef CFPythonMethods[] = {
137  { "WhoAmI", getWhoAmI, METH_NOARGS, NULL },
138  { "WhoIsActivator", getWhoIsActivator, METH_NOARGS, NULL },
139  { "WhoIsOther", getWhoIsThird, METH_NOARGS, NULL },
140  { "WhatIsMessage", getWhatIsMessage, METH_NOARGS, NULL },
141  { "ScriptName", getScriptName, METH_NOARGS, NULL },
142  { "ScriptParameters", getScriptParameters, METH_NOARGS, NULL },
143  { "WhatIsEvent", getEvent, METH_NOARGS, NULL },
144  { "MapDirectory", getMapDirectory, METH_NOARGS, NULL },
145  { "UniqueDirectory", getUniqueDirectory, METH_NOARGS, NULL },
146  { "TempDirectory", getTempDirectory, METH_NOARGS, NULL },
147  { "ConfigDirectory", getConfigDirectory, METH_NOARGS, NULL },
148  { "LocalDirectory", getLocalDirectory, METH_NOARGS, NULL },
149  { "PlayerDirectory", getPlayerDirectory, METH_NOARGS, NULL },
150  { "DataDirectory", getDataDirectory, METH_NOARGS, NULL },
151  { "ReadyMap", readyMap, METH_VARARGS, NULL },
152  { "CreateMap", createMap, METH_VARARGS, NULL },
153  { "FindPlayer", findPlayer, METH_VARARGS, NULL },
154  { "MatchString", matchString, METH_VARARGS, NULL },
155  { "GetReturnValue", getReturnValue, METH_NOARGS, NULL },
156  { "SetReturnValue", setReturnValue, METH_VARARGS, NULL },
157  { "PluginVersion", getCFPythonVersion, METH_NOARGS, NULL },
158  { "CreateObject", createCFObject, METH_NOARGS, NULL },
159  { "CreateObjectByName", createCFObjectByName, METH_VARARGS, NULL },
160  { "GetPrivateDictionary", getPrivateDictionary, METH_NOARGS, NULL },
161  { "GetSharedDictionary", getSharedDictionary, METH_NOARGS, NULL },
162  { "GetPlayers", getPlayers, METH_NOARGS, NULL },
163  { "GetArchetypes", getArchetypes, METH_NOARGS, NULL },
164  { "GetMaps", getMaps, METH_NOARGS, NULL },
165  { "GetParties", getParties, METH_NOARGS, NULL },
166  { "GetRegions", getRegions, METH_NOARGS, NULL },
167  { "GetFriendlyList", getFriendlyList, METH_NOARGS, NULL },
168  { "RegisterCommand", registerCommand, METH_VARARGS, NULL },
169  { "RegisterGlobalEvent", registerGEvent, METH_VARARGS, NULL },
170  { "UnregisterGlobalEvent", unregisterGEvent, METH_VARARGS, NULL },
171  { "GetTime", getTime, METH_NOARGS, NULL },
172  { "DestroyTimer", destroyTimer, METH_VARARGS, NULL },
173  { "MapHasBeenLoaded", getMapHasBeenLoaded, METH_VARARGS, NULL },
174  { "Log", log_message, METH_VARARGS, NULL },
175  { "FindFace", findFace, METH_VARARGS, NULL },
176  { "FindAnimation", findAnimation, METH_VARARGS, NULL },
177  { "GetSeasonName", getSeasonName, METH_VARARGS, NULL },
178  { "GetMonthName", getMonthName, METH_VARARGS, NULL },
179  { "GetWeekdayName", getWeekdayName, METH_VARARGS, NULL },
180  { "GetPeriodofdayName", getPeriodofdayName, METH_VARARGS, NULL },
181  { NULL, NULL, 0, NULL }
182 };
183 
185 
187 
188 static int current_command = -999;
189 
190 static PyObject *shared_data = NULL;
191 
192 static PyObject *private_data = NULL;
193 
194 static PyObject *registerGEvent(PyObject *self, PyObject *args) {
195  int eventcode;
196 
197  if (!PyArg_ParseTuple(args, "i", &eventcode))
198  return NULL;
199 
201 
202  Py_INCREF(Py_None);
203  return Py_None;
204 }
205 
206 static PyObject *unregisterGEvent(PyObject *self, PyObject *args) {
207  int eventcode;
208 
209  if (!PyArg_ParseTuple(args, "i", &eventcode))
210  return NULL;
211 
213 
214  Py_INCREF(Py_None);
215  return Py_None;
216 }
217 
218 static PyObject *createCFObject(PyObject *self, PyObject *args) {
219  object *op;
220 
221  op = cf_create_object();
222 
223  return Crossfire_Object_wrap(op);
224 }
225 
226 static PyObject *createCFObjectByName(PyObject *self, PyObject *args) {
227  char *obname;
228  object *op;
229 
230  if (!PyArg_ParseTuple(args, "s", &obname))
231  return NULL;
232 
233  op = cf_create_object_by_name(obname);
234 
235  return Crossfire_Object_wrap(op);
236 }
237 
238 static PyObject *getCFPythonVersion(PyObject *self, PyObject *args) {
239  int i = 2044;
240 
241  return Py_BuildValue("i", i);
242 }
243 
244 static PyObject *getReturnValue(PyObject *self, PyObject *args) {
245  return Py_BuildValue("i", current_context->returnvalue);
246 }
247 
248 static PyObject *setReturnValue(PyObject *self, PyObject *args) {
249  int i;
250 
251  if (!PyArg_ParseTuple(args, "i", &i))
252  return NULL;
253  current_context->returnvalue = i;
254  Py_INCREF(Py_None);
255  return Py_None;
256 }
257 
258 static PyObject *matchString(PyObject *self, PyObject *args) {
259  char *premiere;
260  char *seconde;
261  const char *result;
262 
263  if (!PyArg_ParseTuple(args, "ss", &premiere, &seconde))
264  return NULL;
265 
266  result = cf_re_cmp(premiere, seconde);
267  if (result != NULL)
268  return Py_BuildValue("i", 1);
269  else
270  return Py_BuildValue("i", 0);
271 }
272 
273 static PyObject *findPlayer(PyObject *self, PyObject *args) {
274  player *foundpl;
275  char *txt;
276 
277  if (!PyArg_ParseTuple(args, "s", &txt))
278  return NULL;
279 
280  foundpl = cf_player_find(txt);
281 
282  if (foundpl != NULL)
283  return Py_BuildValue("O", Crossfire_Object_wrap(foundpl->ob));
284  else {
285  Py_INCREF(Py_None);
286  return Py_None;
287  }
288 }
289 
290 static PyObject *readyMap(PyObject *self, PyObject *args) {
291  char *mapname;
292  mapstruct *map;
293  int flags = 0;
294 
295  if (!PyArg_ParseTuple(args, "s|i", &mapname, &flags))
296  return NULL;
297 
298  map = cf_map_get_map(mapname, flags);
299 
300  return Crossfire_Map_wrap(map);
301 }
302 
303 static PyObject *createMap(PyObject *self, PyObject *args) {
304  int sizex, sizey;
305  mapstruct *map;
306 
307  if (!PyArg_ParseTuple(args, "ii", &sizex, &sizey))
308  return NULL;
309 
310  map = cf_get_empty_map(sizex, sizey);
311 
312  return Crossfire_Map_wrap(map);
313 }
314 
315 static PyObject *getMapDirectory(PyObject *self, PyObject *args) {
316  return Py_BuildValue("s", cf_get_directory(0));
317 }
318 
319 static PyObject *getUniqueDirectory(PyObject *self, PyObject *args) {
320  return Py_BuildValue("s", cf_get_directory(1));
321 }
322 
323 static PyObject *getTempDirectory(PyObject *self, PyObject *args) {
324  return Py_BuildValue("s", cf_get_directory(2));
325 }
326 
327 static PyObject *getConfigDirectory(PyObject *self, PyObject *args) {
328  return Py_BuildValue("s", cf_get_directory(3));
329 }
330 
331 static PyObject *getLocalDirectory(PyObject *self, PyObject *args) {
332  return Py_BuildValue("s", cf_get_directory(4));
333 }
334 
335 static PyObject *getPlayerDirectory(PyObject *self, PyObject *args) {
336  return Py_BuildValue("s", cf_get_directory(5));
337 }
338 
339 static PyObject *getDataDirectory(PyObject *self, PyObject *args) {
340  return Py_BuildValue("s", cf_get_directory(6));
341 }
342 
343 static PyObject *getWhoAmI(PyObject *self, PyObject *args) {
344  if (!current_context->who) {
345  Py_INCREF(Py_None);
346  return Py_None;
347  }
348  Py_INCREF(current_context->who);
349  return current_context->who;
350 }
351 
352 static PyObject *getWhoIsActivator(PyObject *self, PyObject *args) {
353  if (!current_context->activator) {
354  Py_INCREF(Py_None);
355  return Py_None;
356  }
357  Py_INCREF(current_context->activator);
358  return current_context->activator;
359 }
360 
361 static PyObject *getWhoIsThird(PyObject *self, PyObject *args) {
362  if (!current_context->third) {
363  Py_INCREF(Py_None);
364  return Py_None;
365  }
366  Py_INCREF(current_context->third);
367  return current_context->third;
368 }
369 
370 static PyObject *getWhatIsMessage(PyObject *self, PyObject *args) {
371  if (current_context->message == NULL)
372  return Py_BuildValue("");
373  else
374  return Py_BuildValue("s", current_context->message);
375 }
376 
377 static PyObject *getScriptName(PyObject *self, PyObject *args) {
378  return Py_BuildValue("s", current_context->script);
379 }
380 
381 static PyObject *getScriptParameters(PyObject *self, PyObject *args) {
382  if (!current_context->options) {
383  Py_INCREF(Py_None);
384  return Py_None;
385  }
386  return Py_BuildValue("s", current_context->options);
387 }
388 
389 static PyObject *getEvent(PyObject *self, PyObject *args) {
390  if (!current_context->event) {
391  Py_INCREF(Py_None);
392  return Py_None;
393  }
394  Py_INCREF(current_context->event);
395  return current_context->event;
396 }
397 
398 static PyObject *getPrivateDictionary(PyObject *self, PyObject *args) {
399  PyObject *data;
400 
401  data = PyDict_GetItemString(private_data, current_context->script);
402  if (!data) {
403  data = PyDict_New();
404  PyDict_SetItemString(private_data, current_context->script, data);
405  Py_DECREF(data);
406  }
407  Py_INCREF(data);
408  return data;
409 }
410 
411 static PyObject *getSharedDictionary(PyObject *self, PyObject *args) {
412  Py_INCREF(shared_data);
413  return shared_data;
414 }
415 
416 static PyObject *getArchetypes(PyObject *self, PyObject *args) {
417  PyObject *list;
418  archetype *arch;
419 
420  list = PyList_New(0);
421  arch = cf_archetype_get_first();
422  while (arch) {
423  PyList_Append(list, Crossfire_Archetype_wrap(arch));
424  arch = cf_archetype_get_next(arch);
425  }
426  return list;
427 }
428 
429 static PyObject *getPlayers(PyObject *self, PyObject *args) {
430  PyObject *list;
431  object *pl;
432 
433  list = PyList_New(0);
435  while (pl) {
436  PyList_Append(list, Crossfire_Object_wrap(pl));
438  }
439  return list;
440 }
441 
442 static PyObject *getMaps(PyObject *self, PyObject *args) {
443  PyObject *list;
444  mapstruct *map;
445 
446  list = PyList_New(0);
447  map = cf_map_get_first();
448  while (map) {
449  PyList_Append(list, Crossfire_Map_wrap(map));
451  }
452  return list;
453 }
454 
455 static PyObject *getParties(PyObject *self, PyObject *args) {
456  PyObject *list;
457  partylist *party;
458 
459  list = PyList_New(0);
460  party = cf_party_get_first();
461  while (party) {
462  PyList_Append(list, Crossfire_Party_wrap(party));
463  party = cf_party_get_next(party);
464  }
465  return list;
466 }
467 
468 static PyObject *getRegions(PyObject *self, PyObject *args) {
469  PyObject *list;
470  region *reg;
471 
472  list = PyList_New(0);
473  reg = cf_region_get_first();
474  while (reg) {
475  PyList_Append(list, Crossfire_Region_wrap(reg));
476  reg = cf_region_get_next(reg);
477  }
478  return list;
479 }
480 
481 static PyObject *getFriendlyList(PyObject *self, PyObject *args) {
482  PyObject *list;
483  object *ob;
484 
485  list = PyList_New(0);
487  while (ob) {
488  PyList_Append(list, Crossfire_Object_wrap(ob));
489  ob = cf_friendlylist_get_next(ob);
490  }
491  return list;
492 }
493 
494 static PyObject *registerCommand(PyObject *self, PyObject *args) {
495  char *cmdname;
496  char *scriptname;
497  double cmdspeed;
498  int i;
499 
500  if (!PyArg_ParseTuple(args, "ssd", &cmdname, &scriptname, &cmdspeed))
501  return NULL;
502 
503  if (cmdspeed < 0) {
504  set_exception("speed must not be negative");
505  return NULL;
506  }
507 
508  for (i = 0; i < NR_CUSTOM_CMD; i++) {
509  if (CustomCommand[i].name != NULL) {
510  if (!strcmp(CustomCommand[i].name, cmdname)) {
511  set_exception("command '%s' is already registered", cmdname);
512  return NULL;
513  }
514  }
515  }
516  for (i = 0; i < NR_CUSTOM_CMD; i++) {
517  if (CustomCommand[i].name == NULL) {
518  CustomCommand[i].name = cf_strdup_local(cmdname);
519  CustomCommand[i].script = cf_strdup_local(scriptname);
520  CustomCommand[i].speed = cmdspeed;
521  break;
522  }
523  }
524 
525  Py_INCREF(Py_None);
526  return Py_None;
527 }
528 
529 static PyObject *getTime(PyObject *self, PyObject *args) {
530  PyObject *list;
531  timeofday_t tod;
532 
533  cf_get_time(&tod);
534 
535  list = PyList_New(0);
536  PyList_Append(list, Py_BuildValue("i", tod.year));
537  PyList_Append(list, Py_BuildValue("i", tod.month));
538  PyList_Append(list, Py_BuildValue("i", tod.day));
539  PyList_Append(list, Py_BuildValue("i", tod.hour));
540  PyList_Append(list, Py_BuildValue("i", tod.minute));
541  PyList_Append(list, Py_BuildValue("i", tod.dayofweek));
542  PyList_Append(list, Py_BuildValue("i", tod.weekofmonth));
543  PyList_Append(list, Py_BuildValue("i", tod.season));
544  PyList_Append(list, Py_BuildValue("i", tod.periodofday));
545 
546  return list;
547 }
548 
549 static PyObject *destroyTimer(PyObject *self, PyObject *args) {
550  int id;
551 
552  if (!PyArg_ParseTuple(args, "i", &id))
553  return NULL;
554  return Py_BuildValue("i", cf_timer_destroy(id));
555 }
556 
557 static PyObject *getMapHasBeenLoaded(PyObject *self, PyObject *args) {
558  char *name;
559 
560  if (!PyArg_ParseTuple(args, "s", &name))
561  return NULL;
563 }
564 
565 static PyObject *findFace(PyObject *self, PyObject *args) {
566  char *name;
567 
568  if (!PyArg_ParseTuple(args, "s", &name))
569  return NULL;
570  return Py_BuildValue("i", cf_find_face(name, 0));
571 }
572 
573 static PyObject *log_message(PyObject *self, PyObject *args) {
574  LogLevel level;
575  int intLevel;
576  char *message;
577 
578  if (!PyArg_ParseTuple(args, "is", &intLevel, &message))
579  return NULL;
580 
581  switch (intLevel) {
582  case llevError:
583  level = llevError;
584  break;
585 
586  case llevInfo:
587  level = llevInfo;
588  break;
589 
590  case llevDebug:
591  level = llevDebug;
592  break;
593 
594  case llevMonster:
595  level = llevMonster;
596  break;
597 
598  default:
599  return NULL;
600  }
601  if ((message != NULL) && (message[strlen(message)] == '\n'))
602  cf_log(level, "CFPython: %s", message);
603  else
604  cf_log(level, "CFPython: %s\n", message);
605  Py_INCREF(Py_None);
606  return Py_None;
607 }
608 
609 static PyObject *findAnimation(PyObject *self, PyObject *args) {
610  char *name;
611 
612  if (!PyArg_ParseTuple(args, "s", &name))
613  return NULL;
614  return Py_BuildValue("i", cf_find_animation(name));
615 }
616 
617 static PyObject *getSeasonName(PyObject *self, PyObject *args) {
618  int i;
619 
620  if (!PyArg_ParseTuple(args, "i", &i))
621  return NULL;
622  return Py_BuildValue("s", cf_get_season_name(i));
623 }
624 
625 static PyObject *getMonthName(PyObject *self, PyObject *args) {
626  int i;
627 
628  if (!PyArg_ParseTuple(args, "i", &i))
629  return NULL;
630  return Py_BuildValue("s", cf_get_month_name(i));
631 }
632 
633 static PyObject *getWeekdayName(PyObject *self, PyObject *args) {
634  int i;
635 
636  if (!PyArg_ParseTuple(args, "i", &i))
637  return NULL;
638  return Py_BuildValue("s", cf_get_weekday_name(i));
639 }
640 
641 static PyObject *getPeriodofdayName(PyObject *self, PyObject *args) {
642  int i;
643 
644  if (!PyArg_ParseTuple(args, "i", &i))
645  return NULL;
646  return Py_BuildValue("s", cf_get_periodofday_name(i));
647 }
648 
649 static void initContextStack(void) {
650  current_context = NULL;
651  context_stack = NULL;
652 }
653 
654 static void pushContext(CFPContext *context) {
655  if (current_context == NULL) {
656  context_stack = context;
657  context->down = NULL;
658  } else {
659  context->down = current_context;
660  }
661  current_context = context;
662 }
663 
664 static CFPContext *popContext(void) {
665  CFPContext *oldcontext;
666 
667  if (current_context != NULL) {
668  oldcontext = current_context;
669  current_context = current_context->down;
670  return oldcontext;
671  }
672  else
673  return NULL;
674 }
675 
676 static void freeContext(CFPContext *context) {
677  Py_XDECREF(context->event);
678  Py_XDECREF(context->third);
679  Py_XDECREF(context->who);
680  Py_XDECREF(context->activator);
681  free(context);
682 }
683 
685 static PyCodeObject *compilePython(char *filename) {
686  PyObject *scriptfile;
687  sstring sh_path;
688  struct stat stat_buf;
689  struct _node *n;
690  int i;
691  pycode_cache_entry *replace = NULL, *run = NULL;
692 
693  if (!(scriptfile = PyFile_FromString(filename, "r"))) {
694  cf_log(llevDebug, "cfpython - The Script file %s can't be opened\n", filename);
695  return NULL;
696  }
697  if (stat(filename, &stat_buf)) {
698  cf_log(llevDebug, "cfpython - The Script file %s can't be stat:ed\n", filename);
699  if (scriptfile) {
700  Py_DECREF(scriptfile);
701  }
702  return NULL;
703  }
704 
705  sh_path = cf_add_string(filename);
706 
707  /* Search through cache. Three cases:
708  * 1) script in cache, but older than file -> replace cached
709  * 2) script in cache and up to date -> use cached
710  * 3) script not in cache, cache not full -> add to end of cache
711  * 4) script not in cache, cache full -> replace least recently used
712  */
713  for (i = 0; i < PYTHON_CACHE_SIZE; i++) {
714  if (pycode_cache[i].file == NULL) { /* script not in cache, cache not full */
715  replace = &pycode_cache[i]; /* add to end of cache */
716  break;
717  } else if (pycode_cache[i].file == sh_path) {
718  /* script in cache */
719  if (pycode_cache[i].code == NULL || (pycode_cache[i].cached_time < stat_buf.st_mtime)) {
720  /* cache older than file, replace cached */
721  replace = &pycode_cache[i];
722  } else {
723  /* cache uptodate, use cached*/
724  replace = NULL;
725  run = &pycode_cache[i];
726  }
727  break;
728  } else if (replace == NULL || pycode_cache[i].used_time < replace->used_time)
729  /* if we haven't found it yet, set replace to the oldest cache */
730  replace = &pycode_cache[i];
731  }
732 
733  /* replace a specific cache index with the file */
734  if (replace) {
735  Py_XDECREF(replace->code); /* safe to call on NULL */
736  replace->code = NULL;
737 
738  /* Need to replace path string? */
739  if (replace->file != sh_path) {
740  if (replace->file) {
741  cf_free_string(replace->file);
742  }
743  replace->file = cf_add_string(sh_path);
744  }
745 
746  /* Load, parse and compile */
747  if (!scriptfile && !(scriptfile = PyFile_FromString(filename, "r"))) {
748  cf_log(llevDebug, "cfpython - The Script file %s can't be opened\n", filename);
749  replace->code = NULL;
750  return NULL;
751  } else {
752  if ((n = PyParser_SimpleParseFile(PyFile_AsFile(scriptfile), filename, Py_file_input))) {
753  replace->code = PyNode_Compile(n, filename);
754  PyNode_Free(n);
755  }
756 
757  if (PyErr_Occurred())
758  PyErr_Print();
759  else
760  replace->cached_time = stat_buf.st_mtime;
761  run = replace;
762  }
763  }
764 
765  cf_free_string(sh_path);
766 
767  if (scriptfile) {
768  Py_DECREF(scriptfile);
769  }
770 
771  if (run)
772  return run->code;
773  else
774  return NULL;
775 }
776 
777 static int do_script(CFPContext *context, int silent) {
778  PyCodeObject *pycode;
779  PyObject *dict;
780  PyObject *ret;
781 #if 0
782  PyObject *list;
783  int item;
784 #endif
785 
786  pycode = compilePython(context->script);
787  if (pycode) {
788  pushContext(context);
789  dict = PyDict_New();
790  PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins());
791  ret = PyEval_EvalCode(pycode, dict, NULL);
792  if (PyErr_Occurred()) {
793  PyErr_Print();
794  }
795  Py_XDECREF(ret);
796 #if 0
797  printf("cfpython - %d items in heap\n", PyDict_Size(dict));
798  list = PyDict_Values(dict);
799  for (item = PyList_Size(list)-1; item >= 0; item--) {
800  dict = PyList_GET_ITEM(list, item);
801  ret = PyObject_Str(dict);
802  printf(" ref %s = %d\n", PyString_AsString(ret), dict->ob_refcnt);
803  Py_XDECREF(ret);
804  }
805  Py_DECREF(list);
806 #endif
807  Py_DECREF(dict);
808  return 1;
809  } else
810  return 0;
811 }
812 
813 typedef struct {
814  const char *name;
815  const int value;
816 } CFConstant;
817 
818 static void addConstants(PyObject *module, const char *name, const CFConstant *constants) {
819  int i = 0;
820  char tmp[1024];
821  PyObject *new;
822  PyObject *dict;
823 
824  strncpy(tmp, "Crossfire_", sizeof(tmp));
825  strncat(tmp, name, sizeof(tmp)-strlen(tmp));
826 
827  new = Py_InitModule(tmp, NULL);
828  dict = PyDict_New();
829 
830  while (constants[i].name != NULL) {
831  PyModule_AddIntConstant(new, (char *)constants[i].name, constants[i].value);
832  PyDict_SetItem(dict, PyInt_FromLong(constants[i].value), PyString_FromString(constants[i].name));
833  i++;
834  }
835  PyDict_SetItemString(PyModule_GetDict(module), name, new);
836  /* This cause assert() in debug builds if enabled. */
837 #if 0
838  Py_DECREF(new);
839 #endif
840 
841  strncpy(tmp, name, sizeof(tmp));
842  strncat(tmp, "Name", sizeof(tmp)-strlen(tmp));
843  PyDict_SetItemString(PyModule_GetDict(module), tmp, dict);
844  Py_DECREF(dict);
845 }
852 static void addSimpleConstants(PyObject *module, const char *name, const CFConstant *constants) {
853  int i = 0;
854  char tmp[1024];
855  PyObject *new;
856 
857  strncpy(tmp, "Crossfire_", sizeof(tmp));
858  strncat(tmp, name, sizeof(tmp)-strlen(tmp));
859 
860  new = Py_InitModule(tmp, NULL);
861 
862  while (constants[i].name != NULL) {
863  PyModule_AddIntConstant(new, (char *)constants[i].name, constants[i].value);
864  i++;
865  }
866  PyDict_SetItemString(PyModule_GetDict(module), name, new);
867  /* This cause assert() in debug builds if enabled. */
868 #if 0
869  Py_DECREF(new);
870 #endif
871 }
872 
873 static void initConstants(PyObject *module) {
874  static const CFConstant cstDirection[] = {
875  { "NORTH", 1 },
876  { "NORTHEAST", 2 },
877  { "EAST", 3 },
878  { "SOUTHEAST", 4 },
879  { "SOUTH", 5 },
880  { "SOUTHWEST", 6 },
881  { "WEST", 7 },
882  { "NORTHWEST", 8 },
883  { NULL, 0 }
884  };
885 
886  static const CFConstant cstType[] = {
887  { "PLAYER", PLAYER },
888  { "TRANSPORT", TRANSPORT },
889  { "ROD", ROD },
890  { "TREASURE", TREASURE },
891  { "POTION", POTION },
892  { "FOOD", FOOD },
893  { "POISON", POISON },
894  { "BOOK", BOOK },
895  { "CLOCK", CLOCK },
896  { "ARROW", ARROW },
897  { "BOW", BOW },
898  { "WEAPON", WEAPON },
899  { "ARMOUR", ARMOUR },
900  { "PEDESTAL", PEDESTAL },
901  { "ALTAR", ALTAR },
902  { "LOCKED_DOOR", LOCKED_DOOR },
903  { "SPECIAL_KEY", SPECIAL_KEY },
904  { "MAP", MAP },
905  { "DOOR", DOOR },
906  { "KEY", KEY },
907  { "TIMED_GATE", TIMED_GATE },
908  { "TRIGGER", TRIGGER },
909  { "GRIMREAPER", GRIMREAPER },
910  { "MAGIC_EAR", MAGIC_EAR },
911  { "TRIGGER_BUTTON", TRIGGER_BUTTON },
912  { "TRIGGER_ALTAR", TRIGGER_ALTAR },
913  { "TRIGGER_PEDESTAL", TRIGGER_PEDESTAL },
914  { "SHIELD", SHIELD },
915  { "HELMET", HELMET },
916  { "HORN", HORN },
917  { "MONEY", MONEY },
918  { "CLASS", CLASS },
919  { "AMULET", AMULET },
920  { "PLAYERMOVER", PLAYERMOVER },
921  { "TELEPORTER", TELEPORTER },
922  { "CREATOR", CREATOR },
923  { "SKILL", SKILL },
924  { "EXPERIENCE", EXPERIENCE },
925  { "EARTHWALL", EARTHWALL },
926  { "GOLEM", GOLEM },
927  { "THROWN_OBJ", THROWN_OBJ },
928  { "BLINDNESS", BLINDNESS },
929  { "GOD", GOD },
930  { "DETECTOR", DETECTOR },
931  { "TRIGGER_MARKER", TRIGGER_MARKER },
932  { "DEAD_OBJECT", DEAD_OBJECT },
933  { "DRINK", DRINK },
934  { "MARKER", MARKER },
935  { "HOLY_ALTAR", HOLY_ALTAR },
936  { "PLAYER_CHANGER", PLAYER_CHANGER },
937  { "BATTLEGROUND", BATTLEGROUND },
938  { "PEACEMAKER", PEACEMAKER },
939  { "GEM", GEM },
940  { "FIREWALL", FIREWALL },
941  { "CHECK_INV", CHECK_INV },
942  { "MOOD_FLOOR", MOOD_FLOOR },
943  { "EXIT", EXIT },
944  { "ENCOUNTER", ENCOUNTER },
945  { "SHOP_FLOOR", SHOP_FLOOR },
946  { "SHOP_MAT", SHOP_MAT },
947  { "RING", RING },
948  { "FLOOR", FLOOR },
949  { "FLESH", FLESH },
950  { "INORGANIC", INORGANIC },
951  { "SKILL_TOOL", SKILL_TOOL },
952  { "LIGHTER", LIGHTER },
953  { "WALL", WALL },
954  { "MISC_OBJECT", MISC_OBJECT },
955  { "MONSTER", MONSTER },
956  { "LAMP", LAMP },
957  { "DUPLICATOR", DUPLICATOR },
958  { "SPELLBOOK", SPELLBOOK },
959  { "CLOAK", CLOAK },
960  { "SPINNER", SPINNER },
961  { "GATE", GATE },
962  { "BUTTON", BUTTON },
963  { "CF_HANDLE", CF_HANDLE },
964  { "HOLE", HOLE },
965  { "TRAPDOOR", TRAPDOOR },
966  { "SIGN", SIGN },
967  { "BOOTS", BOOTS },
968  { "GLOVES", GLOVES },
969  { "SPELL", SPELL },
970  { "SPELL_EFFECT", SPELL_EFFECT },
971  { "CONVERTER", CONVERTER },
972  { "BRACERS", BRACERS },
973  { "POISONING", POISONING },
974  { "SAVEBED", SAVEBED },
975  { "WAND", WAND },
976  { "SCROLL", SCROLL },
977  { "DIRECTOR", DIRECTOR },
978  { "GIRDLE", GIRDLE },
979  { "FORCE", FORCE },
980  { "POTION_EFFECT", POTION_EFFECT },
981  { "EVENT_CONNECTOR", EVENT_CONNECTOR },
982  { "CLOSE_CON", CLOSE_CON },
983  { "CONTAINER", CONTAINER },
984  { "ARMOUR_IMPROVER", ARMOUR_IMPROVER },
985  { "WEAPON_IMPROVER", WEAPON_IMPROVER },
986  { "SKILLSCROLL", SKILLSCROLL },
987  { "DEEP_SWAMP", DEEP_SWAMP },
988  { "IDENTIFY_ALTAR", IDENTIFY_ALTAR },
989  { "SHOP_INVENTORY", SHOP_INVENTORY },
990  { "RUNE", RUNE },
991  { "TRAP", TRAP },
992  { "POWER_CRYSTAL", POWER_CRYSTAL },
993  { "CORPSE", CORPSE },
994  { "DISEASE", DISEASE },
995  { "SYMPTOM", SYMPTOM },
996  { "BUILDER", BUILDER },
997  { "MATERIAL", MATERIAL },
998  { NULL, 0 }
999  };
1000 
1001  static const CFConstant cstMove[] = {
1002  { "WALK", MOVE_WALK },
1003  { "FLY_LOW", MOVE_FLY_LOW },
1004  { "FLY_HIGH", MOVE_FLY_HIGH },
1005  { "FLYING", MOVE_FLYING },
1006  { "SWIM", MOVE_SWIM },
1007  { "BOAT", MOVE_BOAT },
1008  { "ALL", MOVE_ALL },
1009  { NULL, 0 }
1010  };
1011 
1012  static const CFConstant cstMessageFlag[] = {
1013  { "NDI_BLACK", NDI_BLACK },
1014  { "NDI_WHITE", NDI_WHITE },
1015  { "NDI_NAVY", NDI_NAVY },
1016  { "NDI_RED", NDI_RED },
1017  { "NDI_ORANGE", NDI_ORANGE },
1018  { "NDI_BLUE", NDI_BLUE },
1019  { "NDI_DK_ORANGE", NDI_DK_ORANGE },
1020  { "NDI_GREEN", NDI_GREEN },
1021  { "NDI_LT_GREEN", NDI_LT_GREEN },
1022  { "NDI_GREY", NDI_GREY },
1023  { "NDI_BROWN", NDI_BROWN },
1024  { "NDI_GOLD", NDI_GOLD },
1025  { "NDI_TAN", NDI_TAN },
1026  { "NDI_UNIQUE", NDI_UNIQUE },
1027  { "NDI_ALL", NDI_ALL },
1028  { NULL, 0 }
1029  };
1030 
1031  static const CFConstant cstCostFlag[] = {
1032  { "TRUE", F_TRUE },
1033  { "BUY", F_BUY },
1034  { "SELL", F_SELL },
1035  { "NOBARGAIN", F_NO_BARGAIN },
1036  { "IDENTIFIED", F_IDENTIFIED },
1037  { "NOTCURSED", F_NOT_CURSED },
1038  { NULL, 0 }
1039  };
1040 
1041  static const CFConstant cstAttackType[] = {
1042  { "PHYSICAL", AT_PHYSICAL },
1043  { "MAGIC", AT_MAGIC },
1044  { "FIRE", AT_FIRE },
1045  { "ELECTRICITY", AT_ELECTRICITY },
1046  { "COLD", AT_COLD },
1047  { "CONFUSION", AT_CONFUSION },
1048  { "ACID", AT_ACID },
1049  { "DRAIN", AT_DRAIN },
1050  { "WEAPONMAGIC", AT_WEAPONMAGIC },
1051  { "GHOSTHIT", AT_GHOSTHIT },
1052  { "POISON", AT_POISON },
1053  { "SLOW", AT_SLOW },
1054  { "PARALYZE", AT_PARALYZE },
1055  { "TURN_UNDEAD", AT_TURN_UNDEAD },
1056  { "FEAR", AT_FEAR },
1057  { "CANCELLATION", AT_CANCELLATION },
1058  { "DEPLETE", AT_DEPLETE },
1059  { "DEATH", AT_DEATH },
1060  { "CHAOS", AT_CHAOS },
1061  { "COUNTERSPELL", AT_COUNTERSPELL },
1062  { "GODPOWER", AT_GODPOWER },
1063  { "HOLYWORD", AT_HOLYWORD },
1064  { "BLIND", AT_BLIND },
1065  { "INTERNAL", AT_INTERNAL },
1066  { "LIFE_STEALING", AT_LIFE_STEALING },
1067  { "DISEASE", AT_DISEASE },
1068  { NULL, 0 }
1069  };
1070 
1071  static const CFConstant cstAttackTypeNumber[] = {
1072  { "PHYSICAL", ATNR_PHYSICAL },
1073  { "MAGIC", ATNR_MAGIC },
1074  { "FIRE", ATNR_FIRE },
1075  { "ELECTRICITY", ATNR_ELECTRICITY },
1076  { "COLD", ATNR_COLD },
1077  { "CONFUSION", ATNR_CONFUSION },
1078  { "ACID", ATNR_ACID },
1079  { "DRAIN", ATNR_DRAIN },
1080  { "WEAPONMAGIC", ATNR_WEAPONMAGIC },
1081  { "GHOSTHIT", ATNR_GHOSTHIT },
1082  { "POISON", ATNR_POISON },
1083  { "SLOW", ATNR_SLOW },
1084  { "PARALYZE", ATNR_PARALYZE },
1085  { "TURN_UNDEAD", ATNR_TURN_UNDEAD },
1086  { "FEAR", ATNR_FEAR },
1087  { "CANCELLATION", ATNR_CANCELLATION },
1088  { "DEPLETE", ATNR_DEPLETE },
1089  { "DEATH", ATNR_DEATH },
1090  { "CHAOS", ATNR_CHAOS },
1091  { "COUNTERSPELL", ATNR_COUNTERSPELL },
1092  { "GODPOWER", ATNR_GODPOWER },
1093  { "HOLYWORD", ATNR_HOLYWORD },
1094  { "BLIND", ATNR_BLIND },
1095  { "INTERNAL", ATNR_INTERNAL },
1096  { "LIFE_STEALING", ATNR_LIFE_STEALING },
1097  { "DISEASE", ATNR_DISEASE },
1098  { NULL, 0 }
1099  };
1100 
1101  static const CFConstant cstEventType[] = {
1102  { "APPLY", EVENT_APPLY },
1103  { "ATTACK", EVENT_ATTACK },
1104  { "DEATH", EVENT_DEATH },
1105  { "DROP", EVENT_DROP },
1106  { "PICKUP", EVENT_PICKUP },
1107  { "SAY", EVENT_SAY },
1108  { "STOP", EVENT_STOP },
1109  { "TIME", EVENT_TIME },
1110  { "THROW", EVENT_THROW },
1111  { "TRIGGER", EVENT_TRIGGER },
1112  { "CLOSE", EVENT_CLOSE },
1113  { "TIMER", EVENT_TIMER },
1114  { "DESTROY", EVENT_DESTROY },
1115  { "BORN", EVENT_BORN },
1116  { "CLOCK", EVENT_CLOCK },
1117  { "CRASH", EVENT_CRASH },
1118  { "PLAYER_DEATH", EVENT_PLAYER_DEATH },
1119  { "GKILL", EVENT_GKILL },
1120  { "LOGIN", EVENT_LOGIN },
1121  { "LOGOUT", EVENT_LOGOUT },
1122  { "MAPENTER", EVENT_MAPENTER },
1123  { "MAPLEAVE", EVENT_MAPLEAVE },
1124  { "MAPRESET", EVENT_MAPRESET },
1125  { "REMOVE", EVENT_REMOVE },
1126  { "SHOUT", EVENT_SHOUT },
1127  { "TELL", EVENT_TELL },
1128  { "MUZZLE", EVENT_MUZZLE },
1129  { "KICK", EVENT_KICK },
1130  { "MAPUNLOAD", EVENT_MAPUNLOAD },
1131  { "MAPLOAD", EVENT_MAPLOAD },
1132  { "USER", EVENT_USER },
1133  { NULL, 0 }
1134  };
1135 
1136  static const CFConstant cstTime[] = {
1137  { "HOURS_PER_DAY", HOURS_PER_DAY },
1138  { "DAYS_PER_WEEK", DAYS_PER_WEEK },
1139  { "WEEKS_PER_MONTH", WEEKS_PER_MONTH },
1140  { "MONTHS_PER_YEAR", MONTHS_PER_YEAR },
1141  { "SEASONS_PER_YEAR", SEASONS_PER_YEAR },
1142  { "PERIODS_PER_DAY", PERIODS_PER_DAY },
1143  { NULL, 0 }
1144  };
1145 
1146  addConstants(module, "Direction", cstDirection);
1147  addConstants(module, "Type", cstType);
1148  addConstants(module, "Move", cstMove);
1149  addConstants(module, "MessageFlag", cstMessageFlag);
1150  addConstants(module, "CostFlag", cstCostFlag);
1151  addConstants(module, "AttackType", cstAttackType);
1152  addConstants(module, "AttackTypeNumber", cstAttackTypeNumber);
1153  addConstants(module, "EventType", cstEventType);
1154  addSimpleConstants(module, "Time", cstTime);
1155 }
1156 
1157 extern PyMODINIT_FUNC initcjson(void);
1158 
1159 CF_PLUGIN int initPlugin(const char *iversion, f_plug_api gethooksptr) {
1160  PyObject *m, *d;
1161  int i;
1162 
1163  cf_init_plugin(gethooksptr);
1164  cf_log(llevDebug, "CFPython 2.0a init\n");
1165 
1168 
1169 #ifdef IS_PY26
1170  Py_Py3kWarningFlag++;
1171 #endif
1172 
1173  Py_Initialize();
1174  Crossfire_ObjectType.tp_new = PyType_GenericNew;
1175  Crossfire_MapType.tp_new = PyType_GenericNew;
1176  Crossfire_PlayerType.tp_new = PyType_GenericNew;
1177  Crossfire_ArchetypeType.tp_new = PyType_GenericNew;
1178  Crossfire_PartyType.tp_new = PyType_GenericNew;
1179  Crossfire_RegionType.tp_new = PyType_GenericNew;
1180  PyType_Ready(&Crossfire_ObjectType);
1181  PyType_Ready(&Crossfire_MapType);
1182  PyType_Ready(&Crossfire_PlayerType);
1183  PyType_Ready(&Crossfire_ArchetypeType);
1184  PyType_Ready(&Crossfire_PartyType);
1185  PyType_Ready(&Crossfire_RegionType);
1186 
1187  m = Py_InitModule("Crossfire", CFPythonMethods);
1188  d = PyModule_GetDict(m);
1189  Py_INCREF(&Crossfire_ObjectType);
1190  Py_INCREF(&Crossfire_MapType);
1191  Py_INCREF(&Crossfire_PlayerType);
1192  Py_INCREF(&Crossfire_ArchetypeType);
1193  Py_INCREF(&Crossfire_PartyType);
1194  Py_INCREF(&Crossfire_RegionType);
1195 
1196  PyModule_AddObject(m, "Object", (PyObject *)&Crossfire_ObjectType);
1197  PyModule_AddObject(m, "Map", (PyObject *)&Crossfire_MapType);
1198  PyModule_AddObject(m, "Player", (PyObject *)&Crossfire_PlayerType);
1199  PyModule_AddObject(m, "Archetype", (PyObject *)&Crossfire_ArchetypeType);
1200  PyModule_AddObject(m, "Party", (PyObject *)&Crossfire_PartyType);
1201  PyModule_AddObject(m, "Region", (PyObject *)&Crossfire_RegionType);
1202 
1203  PyModule_AddObject(m, "LogError", Py_BuildValue("i", llevError));
1204  PyModule_AddObject(m, "LogInfo", Py_BuildValue("i", llevInfo));
1205  PyModule_AddObject(m, "LogDebug", Py_BuildValue("i", llevDebug));
1206  PyModule_AddObject(m, "LogMonster", Py_BuildValue("i", llevMonster));
1207 
1208  CFPythonError = PyErr_NewException("Crossfire.error", NULL, NULL);
1209  PyDict_SetItemString(d, "error", CFPythonError);
1210  for (i = 0; i < NR_CUSTOM_CMD; i++) {
1211  CustomCommand[i].name = NULL;
1212  CustomCommand[i].script = NULL;
1213  CustomCommand[i].speed = 0.0;
1214  }
1215  initConstants(m);
1216  private_data = PyDict_New();
1217  shared_data = PyDict_New();
1218 
1219  /* add cjson module*/
1220  initcjson();
1221  return 0;
1222 }
1223 
1224 CF_PLUGIN void *getPluginProperty(int *type, ...) {
1225  va_list args;
1226  const char *propname;
1227  int i, size;
1228  command_array_struct *rtn_cmd;
1229  char *buf;
1230 
1231  va_start(args, type);
1232  propname = va_arg(args, const char *);
1233 
1234  if (!strcmp(propname, "command?")) {
1235  const char *cmdname;
1236  cmdname = va_arg(args, const char *);
1237  rtn_cmd = va_arg(args, command_array_struct *);
1238  va_end(args);
1239 
1240  for (i = 0; i < NR_CUSTOM_CMD; i++) {
1241  if (CustomCommand[i].name != NULL) {
1242  if (!strcmp(CustomCommand[i].name, cmdname)) {
1243  rtn_cmd->name = CustomCommand[i].name;
1244  rtn_cmd->time = (float)CustomCommand[i].speed;
1245  rtn_cmd->func = cfpython_runPluginCommand;
1246  current_command = i;
1247  return rtn_cmd;
1248  }
1249  }
1250  }
1251  return NULL;
1252  } else if (!strcmp(propname, "Identification")) {
1253  buf = va_arg(args, char *);
1254  size = va_arg(args, int);
1255  va_end(args);
1256  snprintf(buf, size, PLUGIN_NAME);
1257  return NULL;
1258  } else if (!strcmp(propname, "FullName")) {
1259  buf = va_arg(args, char *);
1260  size = va_arg(args, int);
1261  va_end(args);
1262  snprintf(buf, size, PLUGIN_VERSION);
1263  return NULL;
1264  }
1265  va_end(args);
1266  return NULL;
1267 }
1268 
1269 CF_PLUGIN int cfpython_runPluginCommand(object *op, char *params) {
1270  char buf[1024], path[1024];
1271  CFPContext *context;
1272  static int rv = 0;
1273 
1274  rv = 0;
1275 
1276  if (current_command < 0) {
1277  cf_log(llevError, "Illegal call of cfpython_runPluginCommand, call find_plugin_command first.\n");
1278  return 1;
1279  }
1280  snprintf(buf, sizeof(buf), "%s.py", cf_get_maps_directory(CustomCommand[current_command].script, path, sizeof(path)));
1281 
1282  context = malloc(sizeof(CFPContext));
1283  context->message[0] = 0;
1284 
1285  context->who = Crossfire_Object_wrap(op);
1286  context->activator = NULL;
1287  context->third = NULL;
1288  context->fix = 0;
1289  snprintf(context->script, sizeof(context->script), "%s", buf);
1290  if (params)
1291  snprintf(context->options, sizeof(context->options), "%s", params);
1292  else
1293  context->options[0] = 0;
1294  context->returnvalue = 1; /* Default is "command successful" */
1295 
1296  current_command = -999;
1297  if (!do_script(context, 0)) {
1298  freeContext(context);
1299  return rv;
1300  }
1301 
1302  context = popContext();
1303  rv = context->returnvalue;
1304  freeContext(context);
1305 /* printf("Execution complete"); */
1306  return rv;
1307 }
1308 
1310  PyObject *scriptfile;
1311  char path[1024];
1312 
1313  cf_log(llevDebug, "CFPython 2.0a post init\n");
1314  initContextStack();
1317  /*registerGlobalEvent(NULL, EVENT_CRASH, PLUGIN_NAME, cfpython_globalEventListener);*/
1332 
1333  scriptfile = PyFile_FromString(cf_get_maps_directory("python/events/python_init.py", path, sizeof(path)), "r");
1334  if (scriptfile != NULL) {
1335  PyRun_SimpleFile(PyFile_AsFile(scriptfile), cf_get_maps_directory("python/events/python_init.py", path, sizeof(path)));
1336  Py_DECREF(scriptfile);
1337  }
1338 
1339  return 0;
1340 }
1341 
1343  va_list args;
1344  static int rv = 0;
1345  CFPContext *context;
1346  char *buf;
1347  player *pl;
1348  object *op;
1349  context = malloc(sizeof(CFPContext));
1350 
1351  rv = 0;
1352 
1353  va_start(args, type);
1354  context->event_code = va_arg(args, int);
1355 
1356  context->message[0] = 0;
1357 
1358  context->who = NULL;
1359  context->activator = NULL;
1360  context->third = NULL;
1361  context->event = NULL;
1362  rv = context->returnvalue = 0;
1363  cf_get_maps_directory("python/events/python_event.py", context->script, sizeof(context->script));
1364  strcpy(context->options, "");
1365  switch (context->event_code) {
1366  case EVENT_CRASH:
1367  cf_log(llevDebug, "Unimplemented for now\n");
1368  break;
1369 
1370  case EVENT_BORN:
1371  op = va_arg(args, object *);
1372  context->activator = Crossfire_Object_wrap(op);
1373  snprintf(context->options, sizeof(context->options), "born");
1374  break;
1375 
1376  case EVENT_PLAYER_DEATH:
1377  op = va_arg(args, object *);
1378  context->who = Crossfire_Object_wrap(op);
1379  snprintf(context->options, sizeof(context->options), "death");
1380  break;
1381 
1382  case EVENT_GKILL:
1383  op = va_arg(args, object *);
1384  context->who = Crossfire_Object_wrap(op);
1385  context->activator = Crossfire_Object_wrap(op);
1386  snprintf(context->options, sizeof(context->options), "gkill");
1387  break;
1388 
1389  case EVENT_LOGIN:
1390  pl = va_arg(args, player *);
1391  context->activator = Crossfire_Object_wrap(pl->ob);
1392  buf = va_arg(args, char *);
1393  if (buf != NULL)
1394  snprintf(context->message, sizeof(context->message), "%s", buf);
1395  snprintf(context->options, sizeof(context->options), "login");
1396  break;
1397 
1398  case EVENT_LOGOUT:
1399  pl = va_arg(args, player *);
1400  context->activator = Crossfire_Object_wrap(pl->ob);
1401  buf = va_arg(args, char *);
1402  if (buf != NULL)
1403  snprintf(context->message, sizeof(context->message), "%s", buf);
1404  snprintf(context->options, sizeof(context->options), "logout");
1405  break;
1406 
1407  case EVENT_REMOVE:
1408  op = va_arg(args, object *);
1409  context->activator = Crossfire_Object_wrap(op);
1410  snprintf(context->options, sizeof(context->options), "remove");
1411  break;
1412 
1413  case EVENT_SHOUT:
1414  op = va_arg(args, object *);
1415  context->activator = Crossfire_Object_wrap(op);
1416  buf = va_arg(args, char *);
1417  if (buf != NULL)
1418  snprintf(context->message, sizeof(context->message), "%s", buf);
1419  snprintf(context->options, sizeof(context->options), "shout");
1420  break;
1421 
1422  case EVENT_MUZZLE:
1423  op = va_arg(args, object *);
1424  context->activator = Crossfire_Object_wrap(op);
1425  buf = va_arg(args, char *);
1426  if (buf != NULL)
1427  snprintf(context->message, sizeof(context->message), "%s", buf);
1428  snprintf(context->options, sizeof(context->options), "muzzle");
1429  break;
1430 
1431  case EVENT_KICK:
1432  op = va_arg(args, object *);
1433  context->activator = Crossfire_Object_wrap(op);
1434  buf = va_arg(args, char *);
1435  if (buf != NULL)
1436  snprintf(context->message, sizeof(context->message), "%s", buf);
1437  snprintf(context->options, sizeof(context->options), "kick");
1438  break;
1439 
1440  case EVENT_MAPENTER:
1441  op = va_arg(args, object *);
1442  context->activator = Crossfire_Object_wrap(op);
1443  context->who = Crossfire_Map_wrap(va_arg(args, mapstruct *));
1444  snprintf(context->options, sizeof(context->options), "mapenter");
1445  break;
1446 
1447  case EVENT_MAPLEAVE:
1448  op = va_arg(args, object *);
1449  context->activator = Crossfire_Object_wrap(op);
1450  context->who = Crossfire_Map_wrap(va_arg(args, mapstruct *));
1451  snprintf(context->options, sizeof(context->options), "mapleave");
1452  break;
1453 
1454  case EVENT_CLOCK:
1455  snprintf(context->options, sizeof(context->options), "clock");
1456  break;
1457 
1458  case EVENT_MAPRESET:
1459  context->who = Crossfire_Map_wrap(va_arg(args, mapstruct *));
1460  snprintf(context->options, sizeof(context->options), "mapreset");
1461  break;
1462 
1463  case EVENT_TELL:
1464  op = va_arg(args, object *);
1465  buf = va_arg(args, char *);
1466  context->activator = Crossfire_Object_wrap(op);
1467  if (buf != NULL)
1468  snprintf(context->message, sizeof(context->message), "%s", buf);
1469  op = va_arg(args, object *);
1470  context->third = Crossfire_Object_wrap(op);
1471  snprintf(context->options, sizeof(context->options), "tell");
1472  break;
1473 
1474  case EVENT_MAPUNLOAD:
1475  context->who = Crossfire_Map_wrap(va_arg(args, mapstruct *));
1476  snprintf(context->options, sizeof(context->options), "mapunload");
1477  break;
1478 
1479  case EVENT_MAPLOAD:
1480  context->who = Crossfire_Map_wrap(va_arg(args, mapstruct *));
1481  snprintf(context->options, sizeof(context->options), "mapload");
1482  break;
1483  }
1484  va_end(args);
1485  context->returnvalue = 0;
1486 
1487  if (!do_script(context, 1)) {
1488  freeContext(context);
1489  return &rv;
1490  }
1491 
1492  context = popContext();
1493  rv = context->returnvalue;
1494 
1495  /* Invalidate freed map wrapper. */
1496  if (context->event_code == EVENT_MAPUNLOAD)
1498 
1499  freeContext(context);
1500 
1501  return &rv;
1502 }
1503 
1504 CF_PLUGIN void *eventListener(int *type, ...) {
1505  static int rv = 0;
1506  va_list args;
1507  char *buf;
1508  CFPContext *context;
1509  object *event;
1510 
1511  rv = 0;
1512 
1513  context = malloc(sizeof(CFPContext));
1514 
1515  context->message[0] = 0;
1516 
1517  va_start(args, type);
1518 
1519  context->who = Crossfire_Object_wrap(va_arg(args, object *));
1520  context->activator = Crossfire_Object_wrap(va_arg(args, object *));
1521  context->third = Crossfire_Object_wrap(va_arg(args, object *));
1522  buf = va_arg(args, char *);
1523  if (buf != NULL)
1524  snprintf(context->message, sizeof(context->message), "%s", buf);
1525  context->fix = va_arg(args, int);
1526  event = va_arg(args, object *);
1527  context->event_code = event->subtype;
1528  context->event = Crossfire_Object_wrap(event);
1529  cf_get_maps_directory(event->slaying, context->script, sizeof(context->script));
1530  snprintf(context->options, sizeof(context->options), "%s", event->name);
1531  context->returnvalue = 0;
1532 
1533  va_end(args);
1534 
1535  if (!do_script(context, 0)) {
1536  freeContext(context);
1537  return &rv;
1538  }
1539 
1540  context = popContext();
1541  rv = context->returnvalue;
1542  freeContext(context);
1543  return &rv;
1544 }
1545 
1547  cf_log(llevDebug, "CFPython 2.0a closing\n");
1548  Py_Finalize();
1549  return 0;
1550 }
#define DAYS_PER_WEEK
Definition: tod.h:42
static PyObject * log_message(PyObject *self, PyObject *args)
Definition: cfpython.c:573
CF_PLUGIN int cfpython_runPluginCommand(object *op, char *params)
Definition: cfpython.c:1269
#define AT_HOLYWORD
Definition: attack.h:125
#define SKILLSCROLL
Definition: define.h:313
#define FOOD
Definition: define.h:118
#define RING
Definition: define.h:232
Definition: player.h:146
static PyObject * getSeasonName(PyObject *self, PyObject *args)
Definition: cfpython.c:617
#define MOVE_WALK
Definition: define.h:700
#define DISEASE
Definition: define.h:331
#define CHECK_INV
Definition: define.h:206
CFPContext * current_context
Definition: cfpython.c:186
static PyObject * private_data
Definition: cfpython.c:192
PyObject * third
Definition: cfpython.h:120
#define BUTTON
Definition: define.h:274
#define EVENT_REMOVE
Definition: plugin.h:89
#define DEAD_OBJECT
Definition: define.h:186
#define AT_ELECTRICITY
Definition: attack.h:107
#define AT_COUNTERSPELL
Definition: attack.h:123
#define EVENT_SHOUT
Definition: plugin.h:90
#define TRAPDOOR
Definition: define.h:277
PyObject * Crossfire_Party_wrap(partylist *what)
#define AT_DEPLETE
Definition: attack.h:120
#define TELEPORTER
Definition: define.h:155
#define AT_GHOSTHIT
Definition: attack.h:113
object * cf_create_object(void)
void cf_get_time(timeofday_t *tod)
int event_code
Definition: cfpython.h:124
#define ATNR_TURN_UNDEAD
Definition: attack.h:90
#define EARTHWALL
Definition: define.h:167
static PyObject * findAnimation(PyObject *self, PyObject *args)
Definition: cfpython.c:609
void cf_free_string(sstring str)
const char * cf_get_month_name(int index)
PyObject * Crossfire_Region_wrap(region *what)
#define CLOSE_CON
Definition: define.h:303
#define EVENT_KICK
Definition: plugin.h:93
PyObject * Crossfire_Map_wrap(mapstruct *what)
Definition: cfpython_map.c:336
static void addConstants(PyObject *module, const char *name, const CFConstant *constants)
Definition: cfpython.c:818
#define NDI_ALL
Definition: newclient.h:220
#define EVENT_DEATH
Definition: plugin.h:64
#define F_SELL
Definition: define.h:776
#define ENCOUNTER
Definition: define.h:229
#define TRAP
Definition: define.h:326
#define WAND
Definition: define.h:291
#define NDI_WHITE
Definition: newclient.h:196
static void initContextStack(void)
Definition: cfpython.c:649
#define MISC_OBJECT
Definition: define.h:248
static PyObject * getPlayers(PyObject *self, PyObject *args)
Definition: cfpython.c:429
static void initConstants(PyObject *module)
Definition: cfpython.c:873
#define AT_INTERNAL
Definition: attack.h:127
mapstruct * cf_get_empty_map(int sizex, int sizey)
#define EVENT_DESTROY
Definition: plugin.h:74
#define CORPSE
Definition: define.h:329
#define EVENT_LOGIN
Definition: plugin.h:84
PyObject * activator
Definition: cfpython.h:119
#define NDI_ORANGE
Definition: newclient.h:199
static PyObject * findPlayer(PyObject *self, PyObject *args)
Definition: cfpython.c:273
static PyObject * createCFObjectByName(PyObject *self, PyObject *args)
Definition: cfpython.c:226
static PyObject * registerGEvent(PyObject *self, PyObject *args)
Definition: cfpython.c:194
#define MONEY
Definition: define.h:148
#define LIGHTER
Definition: define.h:237
PyTypeObject Crossfire_MapType
static PyObject * getSharedDictionary(PyObject *self, PyObject *args)
Definition: cfpython.c:411
#define NDI_BROWN
Definition: newclient.h:207
#define ATNR_DEPLETE
Definition: attack.h:93
#define DOOR
Definition: define.h:135
CF_PLUGIN int postInitPlugin(void)
Definition: cfpython.c:1309
const int value
Definition: cfpython.c:815
#define AT_CANCELLATION
Definition: attack.h:119
static PyObject * getPeriodofdayName(PyObject *self, PyObject *args)
Definition: cfpython.c:641
int minute
Definition: tod.h:67
partylist * cf_party_get_first(void)
#define MAP
Definition: define.h:134
#define EVENT_MAPLEAVE
Definition: plugin.h:87
#define NDI_BLUE
Definition: newclient.h:200
region * cf_region_get_first(void)
char options[1024]
Definition: cfpython.h:126
#define ATNR_SLOW
Definition: attack.h:88
#define POTION
Definition: define.h:117
#define EVENT_LOGOUT
Definition: plugin.h:85
const char * slaying
Definition: object.h:172
static PyObject * readyMap(PyObject *self, PyObject *args)
Definition: cfpython.c:290
void *(* f_plug_api)(int *type,...)
Definition: plugin.h:121
#define SCROLL
Definition: define.h:293
#define AT_COLD
Definition: attack.h:108
#define EXPERIENCE
Definition: define.h:158
static PyObject * CFPythonError
Definition: cfpython.c:112
#define RUNE
Definition: define.h:325
char message[1024]
Definition: cfpython.h:122
mapstruct * cf_map_get_map_property(mapstruct *map, int propcode)
void init_map_assoc_table(void)
Definition: cfpython_map.c:38
archetype * cf_archetype_get_next(archetype *arch)
#define BOOTS
Definition: define.h:281
int cf_timer_destroy(int id)
#define EVENT_TIMER
Definition: plugin.h:73
static PyObject * getMaps(PyObject *self, PyObject *args)
Definition: cfpython.c:442
region * cf_region_get_next(region *reg)
#define GOLEM
Definition: define.h:168
static PyObject * getWhoAmI(PyObject *self, PyObject *args)
Definition: cfpython.c:343
static PyObject * createCFObject(PyObject *self, PyObject *args)
Definition: cfpython.c:218
#define CLOAK
Definition: define.h:268
#define GIRDLE
Definition: define.h:295
#define F_TRUE
Definition: define.h:777
#define PEACEMAKER
Definition: define.h:197
#define AT_BLIND
Definition: attack.h:126
const char * name
Definition: cfpython.c:814
PyTypeObject Crossfire_PlayerType
#define NDI_BLACK
Definition: newclient.h:195
#define EVENT_TELL
Definition: plugin.h:91
player * cf_player_find(const char *plname)
#define EVENT_CRASH
Definition: plugin.h:81
void cf_system_register_global_event(int event, const char *name, f_plug_api hook)
static int do_script(CFPContext *context, int silent)
Definition: cfpython.c:777
#define CFAPI_MAP_PROP_NEXT
Definition: plugin.h:299
sstring cf_add_string(const char *str)
#define F_BUY
Definition: define.h:775
#define ARMOUR
Definition: define.h:128
#define PERIODS_PER_DAY
Definition: tod.h:46
static PyMethodDef CFPythonMethods[]
Definition: cfpython.c:136
#define ATNR_CONFUSION
Definition: attack.h:82
Definition: object.h:321
#define NDI_DK_ORANGE
Definition: newclient.h:201
#define F_NOT_CURSED
Definition: define.h:780
static pycode_cache_entry pycode_cache[PYTHON_CACHE_SIZE]
Definition: cfpython.c:75
static PyObject * getPrivateDictionary(PyObject *self, PyObject *args)
Definition: cfpython.c:398
#define PLAYER
Definition: define.h:113
#define POTION_EFFECT
Definition: define.h:297
int periodofday
Definition: tod.h:70
#define MAGIC_EAR
Definition: define.h:141
const char * cf_get_weekday_name(int index)
int year
Definition: tod.h:62
int cf_find_animation(const char *txt)
partylist * cf_party_get_next(partylist *party)
void cf_log(LogLevel logLevel, const char *format,...)
#define NDI_NAVY
Definition: newclient.h:197
#define SPECIAL_KEY
Definition: define.h:133
static PyObject * findFace(PyObject *self, PyObject *args)
Definition: cfpython.c:565
#define AT_TURN_UNDEAD
Definition: attack.h:117
PyCodeObject * code
Definition: cfpython.c:69
#define POISONING
Definition: define.h:287
#define MOVE_ALL
Definition: define.h:706
#define AT_LIFE_STEALING
Definition: attack.h:128
#define AMULET
Definition: define.h:153
#define AT_CHAOS
Definition: attack.h:122
#define SPINNER
Definition: define.h:272
const char * cf_get_season_name(int index)
static PyObject * getDataDirectory(PyObject *self, PyObject *args)
Definition: cfpython.c:339
char * cf_strdup_local(const char *str)
object * cf_friendlylist_get_first(void)
#define ATNR_WEAPONMAGIC
Definition: attack.h:85
#define NR_CUSTOM_CMD
Definition: cfpython.h:145
#define NDI_RED
Definition: newclient.h:198
static void set_exception(const char *fmt,...)
Definition: cfpython.c:125
#define AT_GODPOWER
Definition: attack.h:124
#define POISON
Definition: define.h:119
static PyObject * destroyTimer(PyObject *self, PyObject *args)
Definition: cfpython.c:549
#define EVENT_MAPENTER
Definition: plugin.h:86
#define F_IDENTIFIED
Definition: define.h:779
static PyObject * getScriptParameters(PyObject *self, PyObject *args)
Definition: cfpython.c:381
#define SHOP_FLOOR
Definition: define.h:230
#define SYMPTOM
Definition: define.h:332
#define CREATOR
Definition: define.h:156
char script[1024]
Definition: cfpython.h:125
#define ATNR_CANCELLATION
Definition: attack.h:92
int cf_init_plugin(f_plug_api getHooks)
CF_PLUGIN int initPlugin(const char *iversion, f_plug_api gethooksptr)
Definition: cfpython.c:1159
#define TRANSPORT
Definition: define.h:114
static void addSimpleConstants(PyObject *module, const char *name, const CFConstant *constants)
Definition: cfpython.c:852
static PyObject * getCFPythonVersion(PyObject *self, PyObject *args)
Definition: cfpython.c:238
double speed
Definition: cfpython.h:141
#define EVENT_STOP
Definition: plugin.h:68
#define AT_DISEASE
Definition: attack.h:130
static PyObject * getLocalDirectory(PyObject *self, PyObject *args)
Definition: cfpython.c:331
time_t cached_time
Definition: cfpython.c:70
#define WEAPON_IMPROVER
Definition: define.h:308
#define ATNR_PARALYZE
Definition: attack.h:89
#define MOVE_SWIM
Definition: define.h:704
static PyObject * getConfigDirectory(PyObject *self, PyObject *args)
Definition: cfpython.c:327
void Handle_Map_Unload_Hook(Crossfire_Map *map)
Definition: cfpython_map.c:331
#define MOVE_FLY_LOW
Definition: define.h:701
#define WALL
Definition: define.h:244
Definition: map.h:297
#define KEY
Definition: define.h:136
PyMODINIT_FUNC initcjson(void)
Definition: cjson.c:1108
#define ATNR_LIFE_STEALING
Definition: attack.h:101
#define ATNR_DEATH
Definition: attack.h:94
static PyObject * getEvent(PyObject *self, PyObject *args)
Definition: cfpython.c:389
static PyObject * getReturnValue(PyObject *self, PyObject *args)
Definition: cfpython.c:244
#define HORN
Definition: define.h:147
mapstruct * cf_map_get_map(const char *name, int flags)
#define EVENT_CLOSE
Definition: plugin.h:72
#define MOOD_FLOOR
Definition: define.h:207
static PyObject * createMap(PyObject *self, PyObject *args)
Definition: cfpython.c:303
#define MOVE_FLYING
Definition: define.h:703
int month
Definition: tod.h:63
static PyObject * getArchetypes(PyObject *self, PyObject *args)
Definition: cfpython.c:416
PyObject * event
Definition: cfpython.h:121
#define GRIMREAPER
Definition: define.h:140
#define ATNR_BLIND
Definition: attack.h:99
#define PLUGIN_NAME
Definition: cfanim.h:32
#define NDI_GREEN
Definition: newclient.h:202
const char * name
Definition: object.h:167
#define SPELL
Definition: define.h:283
#define EVENT_PICKUP
Definition: plugin.h:66
#define ATNR_INTERNAL
Definition: attack.h:100
#define ATNR_FEAR
Definition: attack.h:91
#define FLESH
Definition: define.h:234
static PythonCmd CustomCommand[NR_CUSTOM_CMD]
Definition: cfpython.c:73
#define PEDESTAL
Definition: define.h:129
#define DEEP_SWAMP
Definition: define.h:316
CF_PLUGIN void * getPluginProperty(int *type,...)
Definition: cfpython.c:1224
#define BATTLEGROUND
Definition: define.h:195
int weekofmonth
Definition: tod.h:68
static int current_command
Definition: cfpython.c:188
PyObject * Crossfire_Object_wrap(object *what)
static PyObject * getTime(PyObject *self, PyObject *args)
Definition: cfpython.c:529
int day
Definition: tod.h:64
#define ATNR_MAGIC
Definition: attack.h:78
int dayofweek
Definition: tod.h:65
#define BLINDNESS
Definition: define.h:171
#define GOD
Definition: define.h:172
#define LOCKED_DOOR
Definition: define.h:132
#define SHOP_MAT
Definition: define.h:231
#define WEAPON
Definition: define.h:127
#define AT_FIRE
Definition: attack.h:106
CF_PLUGIN int closePlugin(void)
Definition: cfpython.c:1546
#define ATNR_HOLYWORD
Definition: attack.h:98
void cf_system_unregister_global_event(int event, const char *name)
#define MARKER
Definition: define.h:188
#define NDI_LT_GREEN
Definition: newclient.h:203
#define TRIGGER_MARKER
Definition: define.h:181
time_t used_time
Definition: cfpython.c:70
#define ATNR_PHYSICAL
Definition: attack.h:77
#define TRIGGER_PEDESTAL
Definition: define.h:144
static PyObject * getParties(PyObject *self, PyObject *args)
Definition: cfpython.c:455
const char * name
Definition: commands.h:59
char * cf_get_maps_directory(const char *name, char *buf, int size)
#define EVENT_SAY
Definition: plugin.h:67
static PyObject * getWeekdayName(PyObject *self, PyObject *args)
Definition: cfpython.c:633
#define ATNR_ELECTRICITY
Definition: attack.h:80
#define ATNR_POISON
Definition: attack.h:87
#define AT_PHYSICAL
Definition: attack.h:104
CF_PLUGIN void * eventListener(int *type,...)
Definition: cfpython.c:1504
char * script
Definition: cfpython.h:140
#define TRIGGER
Definition: define.h:139
object * cf_friendlylist_get_next(object *ob)
#define TRIGGER_BUTTON
Definition: define.h:142
#define EVENT_MAPLOAD
Definition: plugin.h:95
#define GEM
Definition: define.h:202
#define EXIT
Definition: define.h:228
#define EVENT_THROW
Definition: plugin.h:70
PyTypeObject Crossfire_PartyType
#define GLOVES
Definition: define.h:282
static PyObject * getRegions(PyObject *self, PyObject *args)
Definition: cfpython.c:468
LogLevel
Definition: logger.h:37
#define EVENT_MAPUNLOAD
Definition: plugin.h:94
int cf_find_face(const char *name, int error)
static PyObject * matchString(PyObject *self, PyObject *args)
Definition: cfpython.c:258
static PyObject * shared_data
Definition: cfpython.c:190
#define ATNR_COUNTERSPELL
Definition: attack.h:96
#define BUILDER
Definition: define.h:334
#define BOOK
Definition: define.h:120
PyObject * who
Definition: cfpython.h:118
#define BRACERS
Definition: define.h:286
#define ATNR_DRAIN
Definition: attack.h:84
#define DUPLICATOR
Definition: define.h:264
#define ATNR_GHOSTHIT
Definition: attack.h:86
#define EVENT_MAPRESET
Definition: plugin.h:88
#define SIGN
Definition: define.h:280
#define SHOP_INVENTORY
Definition: define.h:319
#define EVENT_DROP
Definition: plugin.h:65
#define CLASS
Definition: define.h:149
#define LAMP
Definition: define.h:263
#define AT_DRAIN
Definition: attack.h:111
static const flag_definition flags[]
#define TIMED_GATE
Definition: define.h:138
#define EVENT_GKILL
Definition: plugin.h:83
#define EVENT_TIME
Definition: plugin.h:69
#define THROWN_OBJ
Definition: define.h:170
#define FLOOR
Definition: define.h:233
object * ob
Definition: player.h:207
const char * cf_re_cmp(const char *str, const char *regexp)
object * cf_object_get_object_property(object *op, int propcode)
const char * sstring
Definition: global.h:84
#define TRIGGER_ALTAR
Definition: define.h:143
#define EVENT_CLOCK
Definition: plugin.h:80
#define CFAPI_PLAYER_PROP_NEXT
Definition: plugin.h:281
#define SHIELD
Definition: define.h:145
archetype * cf_archetype_get_first(void)
int snprintf(char *dest, int max, const char *format,...)
Definition: porting.c:498
#define AT_POISON
Definition: attack.h:114
#define FORCE
Definition: define.h:296
#define SAVEBED
Definition: define.h:288
command_function func
Definition: commands.h:60
#define vsnprintf
Definition: win32.h:72
void replace(const char *src, const char *key, const char *replacement, char *result, size_t resultsize)
Definition: utils.c:444
#define INORGANIC
Definition: define.h:235
#define ALTAR
Definition: define.h:130
static PyObject * getWhoIsThird(PyObject *self, PyObject *args)
Definition: cfpython.c:361
#define CONTAINER
Definition: define.h:306
#define CF_PLUGIN
Definition: plugin_common.h:35
#define PYTHON_CACHE_SIZE
Definition: cfpython.c:65
#define FIREWALL
Definition: define.h:204
static PyCodeObject * compilePython(char *filename)
Definition: cfpython.c:685
sstring file
Definition: cfpython.c:68
#define EVENT_APPLY
Definition: plugin.h:62
#define DETECTOR
Definition: define.h:174
#define HOURS_PER_DAY
Definition: tod.h:41
#define AT_FEAR
Definition: attack.h:118
#define ATNR_GODPOWER
Definition: attack.h:97
#define AT_SLOW
Definition: attack.h:115
#define PLAYERMOVER
Definition: define.h:154
Definition: tod.h:61
#define SKILL
Definition: define.h:157
#define CF_HANDLE
Definition: define.h:275
static PyObject * getMapHasBeenLoaded(PyObject *self, PyObject *args)
Definition: cfpython.c:557
#define ARMOUR_IMPROVER
Definition: define.h:307
static PyObject * registerCommand(PyObject *self, PyObject *args)
Definition: cfpython.c:494
PyTypeObject Crossfire_ArchetypeType
#define CLOCK
Definition: define.h:121
#define SPELL_EFFECT
Definition: define.h:284
#define WEEKS_PER_MONTH
Definition: tod.h:43
mapstruct * cf_map_has_been_loaded(const char *name)
int hour
Definition: tod.h:66
static CFPContext * popContext(void)
Definition: cfpython.c:664
const char * cf_get_directory(int id)
mapstruct * cf_map_get_first(void)
#define MONSTER
Definition: define.h:261
#define NDI_GREY
Definition: newclient.h:206
static PyObject * getTempDirectory(PyObject *self, PyObject *args)
Definition: cfpython.c:323
#define AT_MAGIC
Definition: attack.h:105
#define BOW
Definition: define.h:126
PyTypeObject Crossfire_ObjectType
void init_object_assoc_table(void)
#define EVENT_CONNECTOR
Definition: define.h:300
#define DRINK
Definition: define.h:187
static void pushContext(CFPContext *context)
Definition: cfpython.c:654
struct _cfpcontext * down
Definition: cfpython.h:117
static PyObject * getWhatIsMessage(PyObject *self, PyObject *args)
Definition: cfpython.c:370
#define TREASURE
Definition: define.h:116
static PyObject * getWhoIsActivator(PyObject *self, PyObject *args)
Definition: cfpython.c:352
#define EVENT_PLAYER_DEATH
Definition: plugin.h:82
#define NDI_UNIQUE
Definition: newclient.h:219
#define HELMET
Definition: define.h:146
PyObject * Crossfire_Archetype_wrap(archetype *what)
static PyObject * getMonthName(PyObject *self, PyObject *args)
Definition: cfpython.c:625
#define MOVE_FLY_HIGH
Definition: define.h:702
int returnvalue
Definition: cfpython.h:127
#define SPELLBOOK
Definition: define.h:266
#define DIRECTOR
Definition: define.h:294
#define ARROW
Definition: define.h:125
static PyObject * getPlayerDirectory(PyObject *self, PyObject *args)
Definition: cfpython.c:335
#define ROD
Definition: define.h:115
#define IDENTIFY_ALTAR
Definition: define.h:317
#define NDI_TAN
Definition: newclient.h:209
#define HOLE
Definition: define.h:276
#define SKILL_TOOL
Definition: define.h:236
#define EVENT_ATTACK
Definition: plugin.h:63
static PyObject * setReturnValue(PyObject *self, PyObject *args)
Definition: cfpython.c:248
#define ATNR_COLD
Definition: attack.h:81
#define MONTHS_PER_YEAR
Definition: tod.h:44
Definition: map.h:346
#define F_NO_BARGAIN
Definition: define.h:778
const char * cf_get_periodofday_name(int index)
#define AT_CONFUSION
Definition: attack.h:109
static void freeContext(CFPContext *context)
Definition: cfpython.c:676
PyTypeObject Crossfire_RegionType
#define MOVE_BOAT
Definition: define.h:705
static PyObject * unregisterGEvent(PyObject *self, PyObject *args)
Definition: cfpython.c:206
Definition: cfpython.c:67
#define HOLY_ALTAR
Definition: define.h:193
#define MATERIAL
Definition: define.h:337
#define NDI_GOLD
Definition: newclient.h:208
#define AT_ACID
Definition: attack.h:110
#define ATNR_CHAOS
Definition: attack.h:95
#define ATNR_ACID
Definition: attack.h:83
#define GATE
Definition: define.h:273
#define AT_DEATH
Definition: attack.h:121
object * cf_create_object_by_name(const char *name)
#define PLAYER_CHANGER
Definition: define.h:194
#define CONVERTER
Definition: define.h:285
#define AT_WEAPONMAGIC
Definition: attack.h:112
#define EVENT_BORN
Definition: plugin.h:79
#define SEASONS_PER_YEAR
Definition: tod.h:45
CFPContext * context_stack
Definition: cfpython.c:184
#define EVENT_TRIGGER
Definition: plugin.h:71
static PyObject * getFriendlyList(PyObject *self, PyObject *args)
Definition: cfpython.c:481
#define EVENT_USER
Definition: plugin.h:75
int season
Definition: tod.h:69
#define AT_PARALYZE
Definition: attack.h:116
static PyObject * getMapDirectory(PyObject *self, PyObject *args)
Definition: cfpython.c:315
#define POWER_CRYSTAL
Definition: define.h:328
static PyObject * getUniqueDirectory(PyObject *self, PyObject *args)
Definition: cfpython.c:319
CF_PLUGIN void * cfpython_globalEventListener(int *type,...)
Definition: cfpython.c:1342
#define EVENT_MUZZLE
Definition: plugin.h:92
#define ATNR_FIRE
Definition: attack.h:79
#define ATNR_DISEASE
Definition: attack.h:102
static PyObject * getScriptName(PyObject *self, PyObject *args)
Definition: cfpython.c:377
#define PLUGIN_VERSION
Definition: cfanim.h:33