Crossfire Server, Trunk
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 <fcntl.h>
62 #include <stdarg.h>
63 #include <node.h>
64 #include <svnversion.h>
65 
67 
68 #define PYTHON_DEBUG /* give us some general infos out */
69 #define PYTHON_CACHE_SIZE 16 /* number of python scripts to store the bytecode of at a time */
70 
74 typedef struct {
76  PyCodeObject *code;
77  time_t cached_time,
80 
81 #define MAX_COMMANDS 1024
83 
86 
87 static PyObject *CFPythonError;
88 
90 static void set_exception(const char *fmt, ...) {
91  char buf[1024];
92  va_list arg;
93 
94  va_start(arg, fmt);
95  vsnprintf(buf, sizeof(buf), fmt, arg);
96  va_end(arg);
97 
98  PyErr_SetString(PyExc_ValueError, buf);
99 }
100 
102 
104 
105 static PyObject *shared_data = NULL;
106 
107 static PyObject *private_data = NULL;
108 
109 static CFPContext *popContext(void);
110 static void freeContext(CFPContext *context);
111 static int do_script(CFPContext *context);
112 
113 static PyObject *registerGEvent(PyObject *self, PyObject *args) {
114  int eventcode;
115  (void)self;
116 
117  if (!PyArg_ParseTuple(args, "i", &eventcode))
118  return NULL;
119 
121 
122  Py_INCREF(Py_None);
123  return Py_None;
124 }
125 
126 static PyObject *unregisterGEvent(PyObject *self, PyObject *args) {
127  int eventcode;
128  (void)self;
129 
130  if (!PyArg_ParseTuple(args, "i", &eventcode))
131  return NULL;
132 
134 
135  Py_INCREF(Py_None);
136  return Py_None;
137 }
138 
139 static PyObject *createCFObject(PyObject *self, PyObject *args) {
140  object *op;
141  (void)self;
142  (void)args;
143 
144  op = cf_create_object();
145 
146  return Crossfire_Object_wrap(op);
147 }
148 
149 static PyObject *createCFObjectByName(PyObject *self, PyObject *args) {
150  char *obname;
151  object *op;
152  (void)self;
153 
154  if (!PyArg_ParseTuple(args, "s", &obname))
155  return NULL;
156 
157  op = cf_create_object_by_name(obname);
158 
159  return Crossfire_Object_wrap(op);
160 }
161 
162 static PyObject *getCFPythonVersion(PyObject *self, PyObject *args) {
163  int i = 2044;
164  (void)self;
165  (void)args;
166 
167  return Py_BuildValue("i", i);
168 }
169 
170 static PyObject *getReturnValue(PyObject *self, PyObject *args) {
171  (void)self;
172  (void)args;
173  return Py_BuildValue("i", current_context->returnvalue);
174 }
175 
176 static PyObject *setReturnValue(PyObject *self, PyObject *args) {
177  int i;
178  (void)self;
179 
180  if (!PyArg_ParseTuple(args, "i", &i))
181  return NULL;
183  Py_INCREF(Py_None);
184  return Py_None;
185 }
186 
187 static PyObject *matchString(PyObject *self, PyObject *args) {
188  char *premiere;
189  char *seconde;
190  const char *result;
191  (void)self;
192 
193  if (!PyArg_ParseTuple(args, "ss", &premiere, &seconde))
194  return NULL;
195 
196  result = cf_re_cmp(premiere, seconde);
197  if (result != NULL)
198  return Py_BuildValue("i", 1);
199  else
200  return Py_BuildValue("i", 0);
201 }
202 
203 static PyObject *findPlayer(PyObject *self, PyObject *args) {
204  player *foundpl;
205  char *txt;
206  (void)self;
207 
208  if (!PyArg_ParseTuple(args, "s", &txt))
209  return NULL;
210 
211  foundpl = cf_player_find(txt);
212 
213  if (foundpl != NULL)
214  return Py_BuildValue("O", Crossfire_Object_wrap(foundpl->ob));
215  else {
216  Py_INCREF(Py_None);
217  return Py_None;
218  }
219 }
220 
221 static PyObject *readyMap(PyObject *self, PyObject *args) {
222  char *mapname;
223  mapstruct *map;
224  int flags = 0;
225  (void)self;
226 
227  if (!PyArg_ParseTuple(args, "s|i", &mapname, &flags))
228  return NULL;
229 
231 
232  return Crossfire_Map_wrap(map);
233 }
234 
235 static PyObject *createMap(PyObject *self, PyObject *args) {
236  int sizex, sizey;
237  mapstruct *map;
238  (void)self;
239 
240  if (!PyArg_ParseTuple(args, "ii", &sizex, &sizey))
241  return NULL;
242 
243  map = cf_get_empty_map(sizex, sizey);
244 
245  return Crossfire_Map_wrap(map);
246 }
247 
248 static PyObject *getMapDirectory(PyObject *self, PyObject *args) {
249  (void)self;
250  (void)args;
251  return Py_BuildValue("s", cf_get_directory(0));
252 }
253 
254 static PyObject *getUniqueDirectory(PyObject *self, PyObject *args) {
255  (void)self;
256  (void)args;
257  return Py_BuildValue("s", cf_get_directory(1));
258 }
259 
260 static PyObject *getTempDirectory(PyObject *self, PyObject *args) {
261  (void)self;
262  (void)args;
263  return Py_BuildValue("s", cf_get_directory(2));
264 }
265 
266 static PyObject *getConfigDirectory(PyObject *self, PyObject *args) {
267  (void)self;
268  (void)args;
269  return Py_BuildValue("s", cf_get_directory(3));
270 }
271 
272 static PyObject *getLocalDirectory(PyObject *self, PyObject *args) {
273  (void)self;
274  (void)args;
275  return Py_BuildValue("s", cf_get_directory(4));
276 }
277 
278 static PyObject *getPlayerDirectory(PyObject *self, PyObject *args) {
279  (void)self;
280  (void)args;
281  return Py_BuildValue("s", cf_get_directory(5));
282 }
283 
284 static PyObject *getDataDirectory(PyObject *self, PyObject *args) {
285  (void)self;
286  (void)args;
287  return Py_BuildValue("s", cf_get_directory(6));
288 }
289 
290 static PyObject *getWhoAmI(PyObject *self, PyObject *args) {
291  (void)self;
292  (void)args;
293  if (!current_context->who) {
294  Py_INCREF(Py_None);
295  return Py_None;
296  }
297  Py_INCREF(current_context->who);
298  return current_context->who;
299 }
300 
301 static PyObject *getWhoIsActivator(PyObject *self, PyObject *args) {
302  (void)self;
303  (void)args;
304  if (!current_context->activator) {
305  Py_INCREF(Py_None);
306  return Py_None;
307  }
308  Py_INCREF(current_context->activator);
309  return current_context->activator;
310 }
311 
312 static PyObject *getWhoIsThird(PyObject *self, PyObject *args) {
313  (void)self;
314  (void)args;
315  if (!current_context->third) {
316  Py_INCREF(Py_None);
317  return Py_None;
318  }
319  Py_INCREF(current_context->third);
320  return current_context->third;
321 }
322 
323 static PyObject *getWhatIsMessage(PyObject *self, PyObject *args) {
324  (void)self;
325  (void)args;
326  if (*current_context->message == '\0')
327  return Py_BuildValue("");
328  else
329  return Py_BuildValue("s", current_context->message);
330 }
331 
332 static PyObject *getScriptName(PyObject *self, PyObject *args) {
333  (void)self;
334  (void)args;
335  return Py_BuildValue("s", current_context->script);
336 }
337 
338 static PyObject *getScriptParameters(PyObject *self, PyObject *args) {
339  (void)self;
340  (void)args;
341  if (!*current_context->options) {
342  Py_INCREF(Py_None);
343  return Py_None;
344  }
345  return Py_BuildValue("s", current_context->options);
346 }
347 
348 static PyObject *getEvent(PyObject *self, PyObject *args) {
349  (void)self;
350  (void)args;
351  if (!current_context->event) {
352  Py_INCREF(Py_None);
353  return Py_None;
354  }
355  Py_INCREF(current_context->event);
356  return current_context->event;
357 }
358 
359 static PyObject *getPrivateDictionary(PyObject *self, PyObject *args) {
360  PyObject *data;
361  (void)self;
362  (void)args;
363 
364  data = PyDict_GetItemString(private_data, current_context->script);
365  if (!data) {
366  data = PyDict_New();
367  PyDict_SetItemString(private_data, current_context->script, data);
368  Py_DECREF(data);
369  }
370  Py_INCREF(data);
371  return data;
372 }
373 
374 static PyObject *getSharedDictionary(PyObject *self, PyObject *args) {
375  (void)self;
376  (void)args;
377  Py_INCREF(shared_data);
378  return shared_data;
379 }
380 
381 static PyObject *getArchetypes(PyObject *self, PyObject *args) {
382  PyObject *list;
383  archetype *arch;
384  (void)self;
385  (void)args;
386 
387  list = PyList_New(0);
389  while (arch) {
390  PyList_Append(list, Crossfire_Archetype_wrap(arch));
392  }
393  return list;
394 }
395 
396 static PyObject *getPlayers(PyObject *self, PyObject *args) {
397  PyObject *list;
398  object *pl;
399  (void)self;
400  (void)args;
401 
402  list = PyList_New(0);
404  while (pl) {
405  PyList_Append(list, Crossfire_Object_wrap(pl));
407  }
408  return list;
409 }
410 
411 static PyObject *getMaps(PyObject *self, PyObject *args) {
412  PyObject *list;
413  mapstruct *map;
414  (void)self;
415  (void)args;
416 
417  list = PyList_New(0);
418  map = cf_map_get_first();
419  while (map) {
420  PyList_Append(list, Crossfire_Map_wrap(map));
422  }
423  return list;
424 }
425 
426 static PyObject *getParties(PyObject *self, PyObject *args) {
427  PyObject *list;
428  partylist *party;
429  (void)self;
430  (void)args;
431 
432  list = PyList_New(0);
433  party = cf_party_get_first();
434  while (party) {
435  PyList_Append(list, Crossfire_Party_wrap(party));
436  party = cf_party_get_next(party);
437  }
438  return list;
439 }
440 
441 static PyObject *getRegions(PyObject *self, PyObject *args) {
442  PyObject *list;
443  region *reg;
444  (void)self;
445  (void)args;
446 
447  list = PyList_New(0);
448  reg = cf_region_get_first();
449  while (reg) {
450  PyList_Append(list, Crossfire_Region_wrap(reg));
451  reg = cf_region_get_next(reg);
452  }
453  return list;
454 }
455 
456 static PyObject *getFriendlyList(PyObject *self, PyObject *args) {
457  PyObject *list;
458  object *ob;
459  (void)self;
460  (void)args;
461 
462  list = PyList_New(0);
464  while (ob) {
465  PyList_Append(list, Crossfire_Object_wrap(ob));
467  }
468  return list;
469 }
470 
471 static void python_command_function(object *op, const char *params, const char *script) {
472  char buf[1024], path[1024];
473  CFPContext *context;
474 
475  snprintf(buf, sizeof(buf), "%s.py", cf_get_maps_directory(script, path, sizeof(path)));
476 
477  context = malloc(sizeof(CFPContext));
478  context->message[0] = 0;
479 
480  context->who = Crossfire_Object_wrap(op);
481  context->activator = NULL;
482  context->third = NULL;
483  context->fix = 0;
484  /* We are not running from an event, so set it to NULL to avoid segfaults. */
485  context->event = NULL;
486  snprintf(context->script, sizeof(context->script), "%s", buf);
487  if (params)
488  snprintf(context->options, sizeof(context->options), "%s", params);
489  else
490  context->options[0] = 0;
491  context->returnvalue = 1; /* Default is "command successful" */
492 
493  if (!do_script(context)) {
494  freeContext(context);
495  return;
496  }
497 
498  context = popContext();
499  freeContext(context);
500 }
501 
502 static PyObject *registerCommand(PyObject *self, PyObject *args) {
503  char *cmdname;
504  char *scriptname;
505  double cmdspeed;
507  (void)self;
508 
509  if (!PyArg_ParseTuple(args, "ssd|d", &cmdname, &scriptname, &cmdspeed, &type))
510  return NULL;
511 
512  if (cmdspeed < 0) {
513  set_exception("speed must not be negative");
514  return NULL;
515  }
516 
517  for (index = 0; index < MAX_COMMANDS; index++) {
518  if (registered_commands[index] == 0) {
519  break;
520  }
521  }
522  if (index == MAX_COMMANDS) {
523  set_exception("too many registered commands");
524  return NULL;
525  }
526 
528  if (registered_commands[index] == 0) {
529  set_exception("failed to register command (overriding an existing one with a different type?)");
530  return NULL;
531  }
532 
533  Py_INCREF(Py_None);
534  return Py_None;
535 }
536 
537 static PyObject *getTime(PyObject *self, PyObject *args) {
538  PyObject *list;
539  timeofday_t tod;
540  (void)self;
541  (void)args;
542 
543  cf_get_time(&tod);
544 
545  list = PyList_New(0);
546  PyList_Append(list, Py_BuildValue("i", tod.year));
547  PyList_Append(list, Py_BuildValue("i", tod.month));
548  PyList_Append(list, Py_BuildValue("i", tod.day));
549  PyList_Append(list, Py_BuildValue("i", tod.hour));
550  PyList_Append(list, Py_BuildValue("i", tod.minute));
551  PyList_Append(list, Py_BuildValue("i", tod.dayofweek));
552  PyList_Append(list, Py_BuildValue("i", tod.weekofmonth));
553  PyList_Append(list, Py_BuildValue("i", tod.season));
554  PyList_Append(list, Py_BuildValue("i", tod.periodofday));
555 
556  return list;
557 }
558 
559 static PyObject *destroyTimer(PyObject *self, PyObject *args) {
560  int id;
561  (void)self;
562 
563  if (!PyArg_ParseTuple(args, "i", &id))
564  return NULL;
565  return Py_BuildValue("i", cf_timer_destroy(id));
566 }
567 
568 static PyObject *getMapHasBeenLoaded(PyObject *self, PyObject *args) {
569  char *name;
570  (void)self;
571 
572  if (!PyArg_ParseTuple(args, "s", &name))
573  return NULL;
575 }
576 
577 static PyObject *findFace(PyObject *self, PyObject *args) {
578  char *name;
579  (void)self;
580 
581  if (!PyArg_ParseTuple(args, "s", &name))
582  return NULL;
583  return Py_BuildValue("i", cf_find_face(name, 0));
584 }
585 
586 static PyObject *log_message(PyObject *self, PyObject *args) {
587  LogLevel level;
588  int intLevel;
589  char *message;
590  (void)self;
591 
592  if (!PyArg_ParseTuple(args, "is", &intLevel, &message))
593  return NULL;
594 
595  switch (intLevel) {
596  case llevError:
597  level = llevError;
598  break;
599 
600  case llevInfo:
601  level = llevInfo;
602  break;
603 
604  case llevDebug:
605  level = llevDebug;
606  break;
607 
608  case llevMonster:
609  level = llevMonster;
610  break;
611 
612  default:
613  return NULL;
614  }
615  if ((message != NULL) && (message[strlen(message)] == '\n'))
616  cf_log(level, "CFPython: %s", message);
617  else
618  cf_log(level, "CFPython: %s\n", message);
619  Py_INCREF(Py_None);
620  return Py_None;
621 }
622 
623 static PyObject *findAnimation(PyObject *self, PyObject *args) {
624  char *name;
625  (void)self;
626 
627  if (!PyArg_ParseTuple(args, "s", &name))
628  return NULL;
629  return Py_BuildValue("i", cf_find_animation(name));
630 }
631 
632 static PyObject *getSeasonName(PyObject *self, PyObject *args) {
633  int i;
634  (void)self;
635 
636  if (!PyArg_ParseTuple(args, "i", &i))
637  return NULL;
638  return Py_BuildValue("s", cf_get_season_name(i));
639 }
640 
641 static PyObject *getMonthName(PyObject *self, PyObject *args) {
642  int i;
643  (void)self;
644 
645  if (!PyArg_ParseTuple(args, "i", &i))
646  return NULL;
647  return Py_BuildValue("s", cf_get_month_name(i));
648 }
649 
650 static PyObject *getWeekdayName(PyObject *self, PyObject *args) {
651  int i;
652  (void)self;
653 
654  if (!PyArg_ParseTuple(args, "i", &i))
655  return NULL;
656  return Py_BuildValue("s", cf_get_weekday_name(i));
657 }
658 
659 static PyObject *getPeriodofdayName(PyObject *self, PyObject *args) {
660  int i;
661  (void)self;
662 
663  if (!PyArg_ParseTuple(args, "i", &i))
664  return NULL;
665  return Py_BuildValue("s", cf_get_periodofday_name(i));
666 }
667 
668 static PyObject *addReply(PyObject *self, PyObject *args) {
669  char *word, *reply;
670  talk_info *talk;
671  (void)self;
672 
673  if (current_context->talk == NULL) {
674  set_exception("not in a dialog context");
675  return NULL;
676  }
677  talk = current_context->talk;
678 
679  if (!PyArg_ParseTuple(args, "ss", &word, &reply)) {
680  return NULL;
681  }
682 
683  if (talk->replies_count == MAX_REPLIES) {
684  set_exception("too many replies");
685  return NULL;
686  }
687 
688  talk->replies_words[talk->replies_count] = cf_add_string(word);
689  talk->replies[talk->replies_count] = cf_add_string(reply);
690  talk->replies_count++;
691  Py_INCREF(Py_None);
692  return Py_None;
693 
694 }
695 
696 static PyObject *setPlayerMessage(PyObject *self, PyObject *args) {
697  char *message;
698  int type = rt_reply;
699  (void)self;
700 
701  if (current_context->talk == NULL) {
702  set_exception("not in a dialog context");
703  return NULL;
704  }
705 
706  if (!PyArg_ParseTuple(args, "s|i", &message, &type)) {
707  return NULL;
708  }
709 
710  if (current_context->talk->message != NULL)
714 
715  Py_INCREF(Py_None);
716  return Py_None;
717 }
718 
719 static PyObject *npcSay(PyObject *self, PyObject *args) {
720  Crossfire_Object *npc = NULL;
721  char *message, buf[2048];
722  (void)self;
723 
724  if (!PyArg_ParseTuple(args, "O!s", &Crossfire_ObjectType, &npc, &message))
725  return NULL;
726 
727  if (current_context->talk == NULL) {
728  set_exception("not in a dialog context");
729  return NULL;
730  }
731 
733  set_exception("too many NPCs");
734  return NULL;
735  }
736 
737  if (strlen(message) >= sizeof(buf) - 1)
738  cf_log(llevError, "warning, too long message in npcSay, will be truncated");
740  snprintf(buf, sizeof(buf), "%s says: %s", npc->obj->name, message);
741 
744 
745  Py_INCREF(Py_None);
746  return Py_None;
747 }
748 
749 static PyObject *costStringFromValue(PyObject *self, PyObject *args) {
750  uint64_t value;
751  char buf[2048];
752  int largest_coin = 0;
753  (void)self;
754 
755  if (!PyArg_ParseTuple(args, "L|i", &value, &largest_coin))
756  return NULL;
757 
758  cf_cost_string_from_value(value, largest_coin, buf, sizeof(buf));
759  return Py_BuildValue("s", buf);
760 }
761 
762 PyMethodDef CFPythonMethods[] = {
763  { "WhoAmI", getWhoAmI, METH_NOARGS, NULL },
764  { "WhoIsActivator", getWhoIsActivator, METH_NOARGS, NULL },
765  { "WhoIsOther", getWhoIsThird, METH_NOARGS, NULL },
766  { "WhatIsMessage", getWhatIsMessage, METH_NOARGS, NULL },
767  { "ScriptName", getScriptName, METH_NOARGS, NULL },
768  { "ScriptParameters", getScriptParameters, METH_NOARGS, NULL },
769  { "WhatIsEvent", getEvent, METH_NOARGS, NULL },
770  { "MapDirectory", getMapDirectory, METH_NOARGS, NULL },
771  { "UniqueDirectory", getUniqueDirectory, METH_NOARGS, NULL },
772  { "TempDirectory", getTempDirectory, METH_NOARGS, NULL },
773  { "ConfigDirectory", getConfigDirectory, METH_NOARGS, NULL },
774  { "LocalDirectory", getLocalDirectory, METH_NOARGS, NULL },
775  { "PlayerDirectory", getPlayerDirectory, METH_NOARGS, NULL },
776  { "DataDirectory", getDataDirectory, METH_NOARGS, NULL },
777  { "ReadyMap", readyMap, METH_VARARGS, NULL },
778  { "CreateMap", createMap, METH_VARARGS, NULL },
779  { "FindPlayer", findPlayer, METH_VARARGS, NULL },
780  { "MatchString", matchString, METH_VARARGS, NULL },
781  { "GetReturnValue", getReturnValue, METH_NOARGS, NULL },
782  { "SetReturnValue", setReturnValue, METH_VARARGS, NULL },
783  { "PluginVersion", getCFPythonVersion, METH_NOARGS, NULL },
784  { "CreateObject", createCFObject, METH_NOARGS, NULL },
785  { "CreateObjectByName", createCFObjectByName, METH_VARARGS, NULL },
786  { "GetPrivateDictionary", getPrivateDictionary, METH_NOARGS, NULL },
787  { "GetSharedDictionary", getSharedDictionary, METH_NOARGS, NULL },
788  { "GetPlayers", getPlayers, METH_NOARGS, NULL },
789  { "GetArchetypes", getArchetypes, METH_NOARGS, NULL },
790  { "GetMaps", getMaps, METH_NOARGS, NULL },
791  { "GetParties", getParties, METH_NOARGS, NULL },
792  { "GetRegions", getRegions, METH_NOARGS, NULL },
793  { "GetFriendlyList", getFriendlyList, METH_NOARGS, NULL },
794  { "RegisterCommand", registerCommand, METH_VARARGS, NULL },
795  { "RegisterGlobalEvent", registerGEvent, METH_VARARGS, NULL },
796  { "UnregisterGlobalEvent", unregisterGEvent, METH_VARARGS, NULL },
797  { "GetTime", getTime, METH_NOARGS, NULL },
798  { "DestroyTimer", destroyTimer, METH_VARARGS, NULL },
799  { "MapHasBeenLoaded", getMapHasBeenLoaded, METH_VARARGS, NULL },
800  { "Log", log_message, METH_VARARGS, NULL },
801  { "FindFace", findFace, METH_VARARGS, NULL },
802  { "FindAnimation", findAnimation, METH_VARARGS, NULL },
803  { "GetSeasonName", getSeasonName, METH_VARARGS, NULL },
804  { "GetMonthName", getMonthName, METH_VARARGS, NULL },
805  { "GetWeekdayName", getWeekdayName, METH_VARARGS, NULL },
806  { "GetPeriodofdayName", getPeriodofdayName, METH_VARARGS, NULL },
807  { "AddReply", addReply, METH_VARARGS, NULL },
808  { "SetPlayerMessage", setPlayerMessage, METH_VARARGS, NULL },
809  { "NPCSay", npcSay, METH_VARARGS, NULL },
810  { "CostStringFromValue", costStringFromValue, METH_VARARGS, NULL },
811  { NULL, NULL, 0, NULL }
812 };
813 
814 static void initContextStack(void) {
815  current_context = NULL;
816  context_stack = NULL;
817 }
818 
819 static void pushContext(CFPContext *context) {
820  if (current_context == NULL) {
821  context_stack = context;
822  context->down = NULL;
823  } else {
824  context->down = current_context;
825  }
826  current_context = context;
827 }
828 
829 static CFPContext *popContext(void) {
830  CFPContext *oldcontext;
831 
832  if (current_context != NULL) {
833  oldcontext = current_context;
835  return oldcontext;
836  }
837  else
838  return NULL;
839 }
840 
841 static void freeContext(CFPContext *context) {
842  Py_XDECREF(context->event);
843  Py_XDECREF(context->third);
844  Py_XDECREF(context->who);
845  Py_XDECREF(context->activator);
846  free(context);
847 }
848 
852 static PyObject* cfpython_openpyfile(char *filename) {
853  PyObject *scriptfile;
854  int fd;
855  fd = open(filename, O_RDONLY);
856  if (fd == -1)
857  return NULL;
858  scriptfile = PyFile_FromFd(fd, filename, "r", -1, NULL, NULL, NULL, 1);
859  return scriptfile;
860 }
861 
866 static FILE* cfpython_pyfile_asfile(PyObject* obj) {
867  return fdopen(PyObject_AsFileDescriptor(obj), "r");
868 }
869 
874 static PyObject *catcher = NULL;
875 
882 static void log_python_error(void) {
883 
884  PyErr_Print();
885 
886  if (catcher != NULL) {
887  PyObject *output = PyObject_GetAttrString(catcher, "value"); //get the stdout and stderr from our catchOutErr object
888  PyObject* empty = PyUnicode_FromString("");
889 
890  cf_log_plain(llevError, PyUnicode_AsUTF8(output));
891  Py_DECREF(output);
892 
893  PyObject_SetAttrString(catcher, "value", empty);
894  Py_DECREF(empty);
895  }
896 
897  return;
898 }
899 
900 
902 static PyCodeObject *compilePython(char *filename) {
903  PyObject *scriptfile = NULL;
904  sstring sh_path;
905  struct stat stat_buf;
906  struct _node *n;
907  int i;
908  pycode_cache_entry *replace = NULL, *run = NULL;
909 
910  if (stat(filename, &stat_buf)) {
911  cf_log(llevDebug, "cfpython - The Script file %s can't be stat:ed\n", filename);
912  return NULL;
913  }
914 
915  sh_path = cf_add_string(filename);
916 
917  /* Search through cache. Three cases:
918  * 1) script in cache, but older than file -> replace cached
919  * 2) script in cache and up to date -> use cached
920  * 3) script not in cache, cache not full -> add to end of cache
921  * 4) script not in cache, cache full -> replace least recently used
922  */
923  for (i = 0; i < PYTHON_CACHE_SIZE; i++) {
924  if (pycode_cache[i].file == NULL) { /* script not in cache, cache not full */
925  replace = &pycode_cache[i]; /* add to end of cache */
926  break;
927  } else if (pycode_cache[i].file == sh_path) {
928  /* script in cache */
929  if (pycode_cache[i].code == NULL || (pycode_cache[i].cached_time < stat_buf.st_mtime)) {
930  /* cache older than file, replace cached */
931  replace = &pycode_cache[i];
932  } else {
933  /* cache uptodate, use cached*/
934  replace = NULL;
935  run = &pycode_cache[i];
936  }
937  break;
938  } else if (replace == NULL || pycode_cache[i].used_time < replace->used_time)
939  /* if we haven't found it yet, set replace to the oldest cache */
940  replace = &pycode_cache[i];
941  }
942 
943  /* replace a specific cache index with the file */
944  if (replace) {
945  Py_XDECREF(replace->code); /* safe to call on NULL */
946  replace->code = NULL;
947 
948  /* Need to replace path string? */
949  if (replace->file != sh_path) {
950  if (replace->file) {
951  cf_free_string(replace->file);
952  }
953  replace->file = cf_add_string(sh_path);
954  }
955 
956  /* Load, parse and compile. Note: because Pyhon may have been built with a
957  * different library than Crossfire, the FILE* it uses may be incompatible.
958  * Therefore we use PyFile to open the file, then convert to FILE* and get
959  * Python's own structure. Messy, but can't be helped... */
960  if (!(scriptfile = cfpython_openpyfile(filename))) {
961  cf_log(llevDebug, "cfpython - The Script file %s can't be opened\n", filename);
962  cf_free_string(sh_path);
963  return NULL;
964  } else {
965  /* Note: FILE* being opaque, it works, but the actual structure may be different! */
966  FILE* pyfile = cfpython_pyfile_asfile(scriptfile);
967  if ((n = PyParser_SimpleParseFile(pyfile, filename, Py_file_input))) {
968  replace->code = PyNode_Compile(n, filename);
969  PyNode_Free(n);
970  }
971 
972  if (PyErr_Occurred())
974  else
975  replace->cached_time = stat_buf.st_mtime;
976  run = replace;
977  }
978  }
979 
980  cf_free_string(sh_path);
981 
982  if (scriptfile) {
983  Py_DECREF(scriptfile);
984  }
985 
986  assert(run != NULL);
987  run->used_time = time(NULL);
988  return run->code;
989 }
990 
991 static int do_script(CFPContext *context) {
992  PyCodeObject *pycode;
993  PyObject *dict;
994  PyObject *ret;
995 #if 0
996  PyObject *list;
997  int item;
998 #endif
999 
1000  pycode = compilePython(context->script);
1001  if (pycode) {
1002  pushContext(context);
1003  dict = PyDict_New();
1004  PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins());
1005  ret = PyEval_EvalCode((PyObject *)pycode, dict, NULL);
1006  if (PyErr_Occurred()) {
1007  log_python_error();
1008  }
1009  Py_XDECREF(ret);
1010 #if 0
1011  printf("cfpython - %d items in heap\n", PyDict_Size(dict));
1012  list = PyDict_Values(dict);
1013  for (item = PyList_Size(list)-1; item >= 0; item--) {
1014  dict = PyList_GET_ITEM(list, item);
1015  ret = PyObject_Str(dict);
1016  printf(" ref %s = %d\n", PyString_AsString(ret), dict->ob_refcnt);
1017  Py_XDECREF(ret);
1018  }
1019  Py_DECREF(list);
1020 #endif
1021  Py_DECREF(dict);
1022  return 1;
1023  } else
1024  return 0;
1025 }
1026 
1034 static void addConstants(PyObject *module, const char *name, const CFConstant *constants) {
1035  int i = 0;
1036  char tmp[1024];
1037  PyObject *new;
1038  PyObject *dict;
1039 
1040  snprintf(tmp, sizeof(tmp), "Crossfire_%s", name);
1041 
1042  new = PyModule_New(tmp);
1043  dict = PyDict_New();
1044 
1045  while (constants[i].name != NULL) {
1046  PyModule_AddIntConstant(new, (char *)constants[i].name, constants[i].value);
1047  PyDict_SetItem(dict, PyLong_FromLong(constants[i].value), PyUnicode_FromString(constants[i].name));
1048  i++;
1049  }
1050  PyDict_SetItemString(PyModule_GetDict(module), name, new);
1051 
1052  snprintf(tmp, sizeof(tmp), "%sName", name);
1053  PyDict_SetItemString(PyModule_GetDict(module), tmp, dict);
1054  Py_DECREF(dict);
1055 }
1056 
1066 static void addSimpleConstants(PyObject *module, const char *name, const CFConstant *constants) {
1067  int i = 0;
1068  char tmp[1024];
1069  PyObject *new;
1070 
1071  snprintf(tmp, sizeof(tmp), "Crossfire_%s", name);
1072 
1073  new = PyModule_New(tmp);
1074 
1075  while (constants[i].name != NULL) {
1076  PyModule_AddIntConstant(new, (char *)constants[i].name, constants[i].value);
1077  i++;
1078  }
1079  PyDict_SetItemString(PyModule_GetDict(module), name, new);
1080 }
1081 
1083  { "NORTH", 1 },
1084  { "NORTHEAST", 2 },
1085  { "EAST", 3 },
1086  { "SOUTHEAST", 4 },
1087  { "SOUTH", 5 },
1088  { "SOUTHWEST", 6 },
1089  { "WEST", 7 },
1090  { "NORTHWEST", 8 },
1091  { NULL, 0 }
1092 };
1093 
1094 const CFConstant cstType[] = {
1095  { "PLAYER", PLAYER },
1096  { "TRANSPORT", TRANSPORT },
1097  { "ROD", ROD },
1098  { "TREASURE", TREASURE },
1099  { "POTION", POTION },
1100  { "FOOD", FOOD },
1101  { "POISON", POISON },
1102  { "BOOK", BOOK },
1103  { "CLOCK", CLOCK },
1104  { "DRAGON_FOCUS", DRAGON_FOCUS },
1105  { "ARROW", ARROW },
1106  { "BOW", BOW },
1107  { "WEAPON", WEAPON },
1108  { "ARMOUR", ARMOUR },
1109  { "PEDESTAL", PEDESTAL },
1110  { "ALTAR", ALTAR },
1111  { "LOCKED_DOOR", LOCKED_DOOR },
1112  { "SPECIAL_KEY", SPECIAL_KEY },
1113  { "MAP", MAP },
1114  { "DOOR", DOOR },
1115  { "KEY", KEY },
1116  { "TIMED_GATE", TIMED_GATE },
1117  { "TRIGGER", TRIGGER },
1118  { "GRIMREAPER", GRIMREAPER },
1119  { "MAGIC_EAR", MAGIC_EAR },
1120  { "TRIGGER_BUTTON", TRIGGER_BUTTON },
1121  { "TRIGGER_ALTAR", TRIGGER_ALTAR },
1122  { "TRIGGER_PEDESTAL", TRIGGER_PEDESTAL },
1123  { "SHIELD", SHIELD },
1124  { "HELMET", HELMET },
1125  { "MONEY", MONEY },
1126  { "CLASS", CLASS },
1127  { "AMULET", AMULET },
1128  { "PLAYERMOVER", PLAYERMOVER },
1129  { "TELEPORTER", TELEPORTER },
1130  { "CREATOR", CREATOR },
1131  { "SKILL", SKILL },
1132  { "EARTHWALL", EARTHWALL },
1133  { "GOLEM", GOLEM },
1134  { "THROWN_OBJ", THROWN_OBJ },
1135  { "BLINDNESS", BLINDNESS },
1136  { "GOD", GOD },
1137  { "DETECTOR", DETECTOR },
1138  { "TRIGGER_MARKER", TRIGGER_MARKER },
1139  { "DEAD_OBJECT", DEAD_OBJECT },
1140  { "DRINK", DRINK },
1141  { "MARKER", MARKER },
1142  { "HOLY_ALTAR", HOLY_ALTAR },
1143  { "PLAYER_CHANGER", PLAYER_CHANGER },
1144  { "BATTLEGROUND", BATTLEGROUND },
1145  { "PEACEMAKER", PEACEMAKER },
1146  { "GEM", GEM },
1147  { "FIREWALL", FIREWALL },
1148  { "CHECK_INV", CHECK_INV },
1149  { "MOOD_FLOOR", MOOD_FLOOR },
1150  { "EXIT", EXIT },
1151  { "ENCOUNTER", ENCOUNTER },
1152  { "SHOP_FLOOR", SHOP_FLOOR },
1153  { "SHOP_MAT", SHOP_MAT },
1154  { "RING", RING },
1155  { "FLOOR", FLOOR },
1156  { "FLESH", FLESH },
1157  { "INORGANIC", INORGANIC },
1158  { "SKILL_TOOL", SKILL_TOOL },
1159  { "LIGHTER", LIGHTER },
1160  { "WALL", WALL },
1161  { "MISC_OBJECT", MISC_OBJECT },
1162  { "MONSTER", MONSTER },
1163  { "LAMP", LAMP },
1164  { "DUPLICATOR", DUPLICATOR },
1165  { "SPELLBOOK", SPELLBOOK },
1166  { "CLOAK", CLOAK },
1167  { "SPINNER", SPINNER },
1168  { "GATE", GATE },
1169  { "BUTTON", BUTTON },
1170  { "CF_HANDLE", CF_HANDLE },
1171  { "HOLE", HOLE },
1172  { "TRAPDOOR", TRAPDOOR },
1173  { "SIGN", SIGN },
1174  { "BOOTS", BOOTS },
1175  { "GLOVES", GLOVES },
1176  { "SPELL", SPELL },
1177  { "SPELL_EFFECT", SPELL_EFFECT },
1178  { "CONVERTER", CONVERTER },
1179  { "BRACERS", BRACERS },
1180  { "POISONING", POISONING },
1181  { "SAVEBED", SAVEBED },
1182  { "WAND", WAND },
1183  { "SCROLL", SCROLL },
1184  { "DIRECTOR", DIRECTOR },
1185  { "GIRDLE", GIRDLE },
1186  { "FORCE", FORCE },
1187  { "POTION_RESIST_EFFECT", POTION_RESIST_EFFECT },
1188  { "EVENT_CONNECTOR", EVENT_CONNECTOR },
1189  { "CLOSE_CON", CLOSE_CON },
1190  { "CONTAINER", CONTAINER },
1191  { "ARMOUR_IMPROVER", ARMOUR_IMPROVER },
1192  { "WEAPON_IMPROVER", WEAPON_IMPROVER },
1193  { "SKILLSCROLL", SKILLSCROLL },
1194  { "DEEP_SWAMP", DEEP_SWAMP },
1195  { "IDENTIFY_ALTAR", IDENTIFY_ALTAR },
1196  { "SHOP_INVENTORY", SHOP_INVENTORY },
1197  { "RUNE", RUNE },
1198  { "TRAP", TRAP },
1199  { "POWER_CRYSTAL", POWER_CRYSTAL },
1200  { "CORPSE", CORPSE },
1201  { "DISEASE", DISEASE },
1202  { "SYMPTOM", SYMPTOM },
1203  { "BUILDER", BUILDER },
1204  { "MATERIAL", MATERIAL },
1205  { "MIMIC", MIMIC },
1206  { "LIGHTABLE", LIGHTABLE },
1207  { NULL, 0 }
1208 };
1209 
1210 const CFConstant cstMove[] = {
1211  { "WALK", MOVE_WALK },
1212  { "FLY_LOW", MOVE_FLY_LOW },
1213  { "FLY_HIGH", MOVE_FLY_HIGH },
1214  { "FLYING", MOVE_FLYING },
1215  { "SWIM", MOVE_SWIM },
1216  { "BOAT", MOVE_BOAT },
1217  { "ALL", MOVE_ALL },
1218  { NULL, 0 }
1219 };
1220 
1222  { "NDI_BLACK", NDI_BLACK },
1223  { "NDI_WHITE", NDI_WHITE },
1224  { "NDI_NAVY", NDI_NAVY },
1225  { "NDI_RED", NDI_RED },
1226  { "NDI_ORANGE", NDI_ORANGE },
1227  { "NDI_BLUE", NDI_BLUE },
1228  { "NDI_DK_ORANGE", NDI_DK_ORANGE },
1229  { "NDI_GREEN", NDI_GREEN },
1230  { "NDI_LT_GREEN", NDI_LT_GREEN },
1231  { "NDI_GREY", NDI_GREY },
1232  { "NDI_BROWN", NDI_BROWN },
1233  { "NDI_GOLD", NDI_GOLD },
1234  { "NDI_TAN", NDI_TAN },
1235  { "NDI_UNIQUE", NDI_UNIQUE },
1236  { "NDI_ALL", NDI_ALL },
1237  { "NDI_ALL_DMS", NDI_ALL_DMS },
1238  { NULL, 0 }
1239 };
1240 
1242  { "PHYSICAL", AT_PHYSICAL },
1243  { "MAGIC", AT_MAGIC },
1244  { "FIRE", AT_FIRE },
1245  { "ELECTRICITY", AT_ELECTRICITY },
1246  { "COLD", AT_COLD },
1247  { "CONFUSION", AT_CONFUSION },
1248  { "ACID", AT_ACID },
1249  { "DRAIN", AT_DRAIN },
1250  { "WEAPONMAGIC", AT_WEAPONMAGIC },
1251  { "GHOSTHIT", AT_GHOSTHIT },
1252  { "POISON", AT_POISON },
1253  { "SLOW", AT_SLOW },
1254  { "PARALYZE", AT_PARALYZE },
1255  { "TURN_UNDEAD", AT_TURN_UNDEAD },
1256  { "FEAR", AT_FEAR },
1257  { "CANCELLATION", AT_CANCELLATION },
1258  { "DEPLETE", AT_DEPLETE },
1259  { "DEATH", AT_DEATH },
1260  { "CHAOS", AT_CHAOS },
1261  { "COUNTERSPELL", AT_COUNTERSPELL },
1262  { "GODPOWER", AT_GODPOWER },
1263  { "HOLYWORD", AT_HOLYWORD },
1264  { "BLIND", AT_BLIND },
1265  { "INTERNAL", AT_INTERNAL },
1266  { "LIFE_STEALING", AT_LIFE_STEALING },
1267  { "DISEASE", AT_DISEASE },
1268  { NULL, 0 }
1269 };
1270 
1272  { "PHYSICAL", ATNR_PHYSICAL },
1273  { "MAGIC", ATNR_MAGIC },
1274  { "FIRE", ATNR_FIRE },
1275  { "ELECTRICITY", ATNR_ELECTRICITY },
1276  { "COLD", ATNR_COLD },
1277  { "CONFUSION", ATNR_CONFUSION },
1278  { "ACID", ATNR_ACID },
1279  { "DRAIN", ATNR_DRAIN },
1280  { "WEAPONMAGIC", ATNR_WEAPONMAGIC },
1281  { "GHOSTHIT", ATNR_GHOSTHIT },
1282  { "POISON", ATNR_POISON },
1283  { "SLOW", ATNR_SLOW },
1284  { "PARALYZE", ATNR_PARALYZE },
1285  { "TURN_UNDEAD", ATNR_TURN_UNDEAD },
1286  { "FEAR", ATNR_FEAR },
1287  { "CANCELLATION", ATNR_CANCELLATION },
1288  { "DEPLETE", ATNR_DEPLETE },
1289  { "DEATH", ATNR_DEATH },
1290  { "CHAOS", ATNR_CHAOS },
1291  { "COUNTERSPELL", ATNR_COUNTERSPELL },
1292  { "GODPOWER", ATNR_GODPOWER },
1293  { "HOLYWORD", ATNR_HOLYWORD },
1294  { "BLIND", ATNR_BLIND },
1295  { "INTERNAL", ATNR_INTERNAL },
1296  { "LIFE_STEALING", ATNR_LIFE_STEALING },
1297  { "DISEASE", ATNR_DISEASE },
1298  { NULL, 0 }
1299 };
1300 
1303  { "APPLY", EVENT_APPLY },
1304  { "ATTACK", EVENT_ATTACKED },
1305  { "ATTACKS", EVENT_ATTACKS },
1306  { "BOUGHT", EVENT_BOUGHT },
1307  { "CLOSE", EVENT_CLOSE },
1308  { "DEATH", EVENT_DEATH },
1309  { "DESTROY", EVENT_DESTROY },
1310  { "DROP", EVENT_DROP },
1311  { "PICKUP", EVENT_PICKUP },
1312  { "SAY", EVENT_SAY },
1313  { "SELLING", EVENT_SELLING },
1314  { "STOP", EVENT_STOP },
1315  { "TIME", EVENT_TIME },
1316  { "THROW", EVENT_THROW },
1317  { "TRIGGER", EVENT_TRIGGER },
1318  { "TIMER", EVENT_TIMER },
1319  { "USER", EVENT_USER },
1320 
1322  { "BORN", EVENT_BORN },
1323  { "CLOCK", EVENT_CLOCK },
1324  { "CRASH", EVENT_CRASH },
1325  { "GKILL", EVENT_GKILL },
1326  { "KICK", EVENT_KICK },
1327  { "LOGIN", EVENT_LOGIN },
1328  { "LOGOUT", EVENT_LOGOUT },
1329  { "MAPENTER", EVENT_MAPENTER },
1330  { "MAPLEAVE", EVENT_MAPLEAVE },
1331  { "MAPLOAD", EVENT_MAPLOAD },
1332  { "MAPRESET", EVENT_MAPRESET },
1333  { "MAPUNLOAD", EVENT_MAPUNLOAD },
1334  { "MUZZLE", EVENT_MUZZLE },
1335  { "PLAYER_DEATH", EVENT_PLAYER_DEATH },
1336  { "REMOVE", EVENT_REMOVE },
1337  { "SHOUT", EVENT_SHOUT },
1338  { "TELL", EVENT_TELL },
1339  { NULL, 0 }
1340 };
1341 
1342 const CFConstant cstTime[] = {
1343  { "HOURS_PER_DAY", HOURS_PER_DAY },
1344  { "DAYS_PER_WEEK", DAYS_PER_WEEK },
1345  { "WEEKS_PER_MONTH", WEEKS_PER_MONTH },
1346  { "MONTHS_PER_YEAR", MONTHS_PER_YEAR },
1347  { "SEASONS_PER_YEAR", SEASONS_PER_YEAR },
1348  { "PERIODS_PER_DAY", PERIODS_PER_DAY },
1349  { NULL, 0 }
1350 };
1351 
1353  { "SAY", rt_say },
1354  { "REPLY", rt_reply },
1355  { "QUESTION", rt_question },
1356  { NULL, 0 }
1357 };
1358 
1360  { "DISTATT", DISTATT },
1361  { "RUNATT", RUNATT },
1362  { "HITRUN", HITRUN },
1363  { "WAITATT", WAITATT },
1364  { "RUSH", RUSH },
1365  { "ALLRUN", ALLRUN },
1366  { "DISTHIT", DISTHIT },
1367  { "WAIT2", WAIT2 },
1368  { "PETMOVE", PETMOVE },
1369  { "CIRCLE1", CIRCLE1 },
1370  { "CIRCLE2", CIRCLE2 },
1371  { "PACEH", PACEH },
1372  { "PACEH2", PACEH2 },
1373  { "RANDO", RANDO },
1374  { "RANDO2", RANDO2 },
1375  { "PACEV", PACEV },
1376  { "PACEV2", PACEV2 },
1377  { NULL, 0 }
1378 };
1379 
1380 static void initConstants(PyObject *module) {
1381  addConstants(module, "Direction", cstDirection);
1382  addConstants(module, "Type", cstType);
1383  addConstants(module, "Move", cstMove);
1384  addConstants(module, "MessageFlag", cstMessageFlag);
1385  addConstants(module, "AttackType", cstAttackType);
1386  addConstants(module, "AttackTypeNumber", cstAttackTypeNumber);
1387  addConstants(module, "EventType", cstEventType);
1388  addSimpleConstants(module, "Time", cstTime);
1389  addSimpleConstants(module, "ReplyType", cstReplyTypes);
1390  addSimpleConstants(module, "AttackMovement", cstAttackMovement);
1391 }
1392 
1393 /*
1394  * Set up the main module and handle misc plugin loading stuff and such.
1395  */
1396 
1401 static void cfpython_init_types(PyObject* m) {
1402  PyObject *d = PyModule_GetDict(m);
1403 
1404  Crossfire_ObjectType.tp_new = PyType_GenericNew;
1405  Crossfire_MapType.tp_new = PyType_GenericNew;
1406  Crossfire_PlayerType.tp_new = PyType_GenericNew;
1407  Crossfire_ArchetypeType.tp_new = PyType_GenericNew;
1408  Crossfire_PartyType.tp_new = PyType_GenericNew;
1409  Crossfire_RegionType.tp_new = PyType_GenericNew;
1410  PyType_Ready(&Crossfire_ObjectType);
1411  PyType_Ready(&Crossfire_MapType);
1412  PyType_Ready(&Crossfire_PlayerType);
1413  PyType_Ready(&Crossfire_ArchetypeType);
1414  PyType_Ready(&Crossfire_PartyType);
1415  PyType_Ready(&Crossfire_RegionType);
1416 
1417  Py_INCREF(&Crossfire_ObjectType);
1418  Py_INCREF(&Crossfire_MapType);
1419  Py_INCREF(&Crossfire_PlayerType);
1420  Py_INCREF(&Crossfire_ArchetypeType);
1421  Py_INCREF(&Crossfire_PartyType);
1422  Py_INCREF(&Crossfire_RegionType);
1423 
1424  PyModule_AddObject(m, "Object", (PyObject *)&Crossfire_ObjectType);
1425  PyModule_AddObject(m, "Map", (PyObject *)&Crossfire_MapType);
1426  PyModule_AddObject(m, "Player", (PyObject *)&Crossfire_PlayerType);
1427  PyModule_AddObject(m, "Archetype", (PyObject *)&Crossfire_ArchetypeType);
1428  PyModule_AddObject(m, "Party", (PyObject *)&Crossfire_PartyType);
1429  PyModule_AddObject(m, "Region", (PyObject *)&Crossfire_RegionType);
1430 
1431  PyModule_AddObject(m, "LogError", Py_BuildValue("i", llevError));
1432  PyModule_AddObject(m, "LogInfo", Py_BuildValue("i", llevInfo));
1433  PyModule_AddObject(m, "LogDebug", Py_BuildValue("i", llevDebug));
1434  PyModule_AddObject(m, "LogMonster", Py_BuildValue("i", llevMonster));
1435 
1436  CFPythonError = PyErr_NewException("Crossfire.error", NULL, NULL);
1437  PyDict_SetItemString(d, "error", CFPythonError);
1438 }
1439 
1440 extern PyObject* PyInit_cjson(void);
1441 
1442 static PyModuleDef CrossfireModule = {
1443  PyModuleDef_HEAD_INIT,
1444  "Crossfire", /* m_name */
1445  NULL, /* m_doc */
1446  -1, /* m_size */
1447  CFPythonMethods, /* m_methods */
1448  NULL, /* m_reload */
1449  NULL, /* m_traverse */
1450  NULL, /* m_clear */
1451  NULL /* m_free */
1452 };
1453 
1454 static PyObject* PyInit_Crossfire(void)
1455 {
1456  PyObject *m = PyModule_Create(&CrossfireModule);
1457  Py_INCREF(m);
1458  return m;
1459 }
1460 
1461 CF_PLUGIN int initPlugin(const char *iversion, f_plug_api gethooksptr) {
1462  PyObject *m;
1463  /* Python code to redirect stdouts/stderr. */
1464  const char *stdOutErr =
1465 "import sys\n\
1466 class CatchOutErr:\n\
1467  def __init__(self):\n\
1468  self.value = ''\n\
1469  def write(self, txt):\n\
1470  self.value += txt\n\
1471 catchOutErr = CatchOutErr()\n\
1472 sys.stdout = catchOutErr\n\
1473 sys.stderr = catchOutErr\n\
1474 ";
1475  (void)iversion;
1476 
1477  for (int c = 0; c < MAX_COMMANDS; c++) {
1478  registered_commands[c] = 0;
1479  }
1480 
1481  cf_init_plugin(gethooksptr);
1482  cf_log(llevDebug, "CFPython 2.0a init\n");
1483 
1486 
1487  PyImport_AppendInittab("Crossfire", &PyInit_Crossfire);
1488  PyImport_AppendInittab("cjson", &PyInit_cjson);
1489 
1490  Py_Initialize();
1491 
1492  m = PyImport_ImportModule("Crossfire");
1493 
1495 
1496  initConstants(m);
1497  private_data = PyDict_New();
1498  shared_data = PyDict_New();
1499 
1500  /* Redirect Python's stderr to a special object so it can be put to
1501  * the Crossfire log. */
1502  m = PyImport_AddModule("__main__");
1503  PyRun_SimpleString(stdOutErr);
1504  catcher = PyObject_GetAttrString(m, "catchOutErr");
1505 
1506  return 0;
1507 }
1508 
1510  va_list args;
1511  const char *propname;
1512  int size;
1513  char *buf;
1514 
1515  va_start(args, type);
1516  propname = va_arg(args, const char *);
1517  if (!strcmp(propname, "Identification")) {
1518  buf = va_arg(args, char *);
1519  size = va_arg(args, int);
1520  va_end(args);
1521  snprintf(buf, size, PLUGIN_NAME);
1522  return NULL;
1523  } else if (!strcmp(propname, "FullName")) {
1524  buf = va_arg(args, char *);
1525  size = va_arg(args, int);
1526  va_end(args);
1527  snprintf(buf, size, PLUGIN_VERSION);
1528  return NULL;
1529  }
1530  va_end(args);
1531  return NULL;
1532 }
1533 
1534 static int GECodes[] = {
1535  EVENT_BORN,
1536  EVENT_CLOCK,
1538  EVENT_GKILL,
1539  EVENT_LOGIN,
1540  EVENT_LOGOUT,
1544  EVENT_REMOVE,
1545  EVENT_SHOUT,
1546  EVENT_TELL,
1547  EVENT_MUZZLE,
1548  EVENT_KICK,
1550  EVENT_MAPLOAD,
1551  0
1552 };
1553 
1554 static const char* GEPaths[] = {
1555  "born",
1556  "clock",
1557  "death",
1558  "gkill",
1559  "login",
1560  "logout",
1561  "mapenter",
1562  "mapleave",
1563  "mapreset",
1564  "remove",
1565  "shout",
1566  "tell",
1567  "muzzle",
1568  "kick",
1569  "mapunload",
1570  "mapload",
1571  NULL
1572 };
1573 
1575  PyObject *scriptfile;
1576  char path[1024];
1577  int i;
1578 
1579  cf_log(llevDebug, "CFPython 2.0a post init\n");
1580  initContextStack();
1581  for (i = 0; GECodes[i] != 0; i++)
1583 
1584  scriptfile = cfpython_openpyfile(cf_get_maps_directory("python/events/python_init.py", path, sizeof(path)));
1585  if (scriptfile != NULL) {
1586  FILE* pyfile = cfpython_pyfile_asfile(scriptfile);
1587  PyRun_SimpleFile(pyfile, cf_get_maps_directory("python/events/python_init.py", path, sizeof(path)));
1588  Py_DECREF(scriptfile);
1589  }
1590 
1591  for (i = 0; i < PYTHON_CACHE_SIZE; i++) {
1592  pycode_cache[i].code = NULL;
1593  pycode_cache[i].file = NULL;
1594  pycode_cache[i].cached_time = 0;
1595  pycode_cache[i].used_time = 0;
1596  }
1597 
1598  return 0;
1599 }
1600 
1601 static const char *getGlobalEventPath(int code) {
1602  for (int i = 0; GECodes[i] != 0; i++) {
1603  if (GECodes[i] == code)
1604  return GEPaths[i];
1605  }
1606  return "";
1607 }
1608 
1610  va_list args;
1611  int rv = 0;
1612  CFPContext *context;
1613  char *buf;
1614  player *pl;
1615  object *op;
1616  context = malloc(sizeof(CFPContext));
1617 
1618  va_start(args, type);
1619  context->event_code = va_arg(args, int);
1620 
1621  context->message[0] = 0;
1622 
1623  context->who = NULL;
1624  context->activator = NULL;
1625  context->third = NULL;
1626  context->event = NULL;
1627  context->talk = NULL;
1628  rv = context->returnvalue = 0;
1629  cf_get_maps_directory("python/events/python_event.py", context->script, sizeof(context->script));
1630  snprintf(context->options, sizeof(context->options), "%s", getGlobalEventPath(context->event_code));
1631  switch (context->event_code) {
1632  case EVENT_CRASH:
1633  cf_log(llevDebug, "Unimplemented for now\n");
1634  break;
1635 
1636  case EVENT_BORN:
1637  op = va_arg(args, object *);
1638  context->activator = Crossfire_Object_wrap(op);
1639  break;
1640 
1641  case EVENT_PLAYER_DEATH:
1642  op = va_arg(args, object *);
1643  context->who = Crossfire_Object_wrap(op);
1644  op = va_arg(args, object *);
1645  context->activator = Crossfire_Object_wrap(op);
1646  break;
1647 
1648  case EVENT_GKILL:
1649  op = va_arg(args, object *);
1650  object* hitter = va_arg(args, object *);
1651  context->who = Crossfire_Object_wrap(op);
1653  break;
1654 
1655  case EVENT_LOGIN:
1656  pl = va_arg(args, player *);
1657  context->activator = Crossfire_Object_wrap(pl->ob);
1658  buf = va_arg(args, char *);
1659  if (buf != NULL)
1660  snprintf(context->message, sizeof(context->message), "%s", buf);
1661  break;
1662 
1663  case EVENT_LOGOUT:
1664  pl = va_arg(args, player *);
1665  context->activator = Crossfire_Object_wrap(pl->ob);
1666  buf = va_arg(args, char *);
1667  if (buf != NULL)
1668  snprintf(context->message, sizeof(context->message), "%s", buf);
1669  break;
1670 
1671  case EVENT_REMOVE:
1672  op = va_arg(args, object *);
1673  context->activator = Crossfire_Object_wrap(op);
1674  break;
1675 
1676  case EVENT_SHOUT:
1677  op = va_arg(args, object *);
1678  context->activator = Crossfire_Object_wrap(op);
1679  buf = va_arg(args, char *);
1680  if (buf != NULL)
1681  snprintf(context->message, sizeof(context->message), "%s", buf);
1682  break;
1683 
1684  case EVENT_MUZZLE:
1685  op = va_arg(args, object *);
1686  context->activator = Crossfire_Object_wrap(op);
1687  buf = va_arg(args, char *);
1688  if (buf != NULL)
1689  snprintf(context->message, sizeof(context->message), "%s", buf);
1690  break;
1691 
1692  case EVENT_KICK:
1693  op = va_arg(args, object *);
1694  context->activator = Crossfire_Object_wrap(op);
1695  buf = va_arg(args, char *);
1696  if (buf != NULL)
1697  snprintf(context->message, sizeof(context->message), "%s", buf);
1698  break;
1699 
1700  case EVENT_MAPENTER:
1701  op = va_arg(args, object *);
1702  context->activator = Crossfire_Object_wrap(op);
1703  context->who = Crossfire_Map_wrap(va_arg(args, mapstruct *));
1704  break;
1705 
1706  case EVENT_MAPLEAVE:
1707  op = va_arg(args, object *);
1708  context->activator = Crossfire_Object_wrap(op);
1709  context->who = Crossfire_Map_wrap(va_arg(args, mapstruct *));
1710  break;
1711 
1712  case EVENT_CLOCK:
1713  break;
1714 
1715  case EVENT_MAPRESET:
1716  context->who = Crossfire_Map_wrap(va_arg(args, mapstruct *));
1717  break;
1718 
1719  case EVENT_TELL:
1720  op = va_arg(args, object *);
1721  buf = va_arg(args, char *);
1722  context->activator = Crossfire_Object_wrap(op);
1723  if (buf != NULL)
1724  snprintf(context->message, sizeof(context->message), "%s", buf);
1725  op = va_arg(args, object *);
1726  context->third = Crossfire_Object_wrap(op);
1727  break;
1728 
1729  case EVENT_MAPUNLOAD:
1730  context->who = Crossfire_Map_wrap(va_arg(args, mapstruct *));
1731  break;
1732 
1733  case EVENT_MAPLOAD:
1734  context->who = Crossfire_Map_wrap(va_arg(args, mapstruct *));
1735  break;
1736  }
1737  va_end(args);
1738  context->returnvalue = 0;
1739 
1740  if (context->event_code == EVENT_CLOCK) {
1741  // Ignore EVENT_CLOCK. It is not being used in maps, but nevertheless
1742  // runs python_init.py several times per second even while idling.
1743  freeContext(context);
1744  return rv;
1745  }
1746 
1747  if (!do_script(context)) {
1748  freeContext(context);
1749  return rv;
1750  }
1751 
1752  context = popContext();
1753  rv = context->returnvalue;
1754 
1755  /* Invalidate freed map wrapper. */
1756  if (context->event_code == EVENT_MAPUNLOAD)
1758 
1759  freeContext(context);
1760 
1761  return rv;
1762 }
1763 
1764 CF_PLUGIN int eventListener(int *type, ...) {
1765  int rv = 0;
1766  va_list args;
1767  char *buf;
1768  CFPContext *context;
1769  object *event;
1770 
1771  context = malloc(sizeof(CFPContext));
1772 
1773  context->message[0] = 0;
1774 
1775  va_start(args, type);
1776 
1777  context->who = Crossfire_Object_wrap(va_arg(args, object *));
1778  context->activator = Crossfire_Object_wrap(va_arg(args, object *));
1779  context->third = Crossfire_Object_wrap(va_arg(args, object *));
1780  buf = va_arg(args, char *);
1781  if (buf != NULL)
1782  snprintf(context->message, sizeof(context->message), "%s", buf);
1783  context->fix = va_arg(args, int);
1784  event = va_arg(args, object *);
1785  context->talk = va_arg(args, talk_info *);
1786  context->event_code = event->subtype;
1787  context->event = Crossfire_Object_wrap(event);
1788  cf_get_maps_directory(event->slaying, context->script, sizeof(context->script));
1789  snprintf(context->options, sizeof(context->options), "%s", event->name);
1790  context->returnvalue = 0;
1791 
1792  va_end(args);
1793 
1794  if (!do_script(context)) {
1795  freeContext(context);
1796  return rv;
1797  }
1798 
1799  context = popContext();
1800  rv = context->returnvalue;
1801  freeContext(context);
1802  return rv;
1803 }
1804 
1806  int i;
1807 
1808  cf_log(llevDebug, "CFPython 2.0a closing\n");
1809 
1810  for (int c = 0; c < MAX_COMMANDS; c++) {
1811  if (registered_commands[c]) {
1813  }
1814  }
1815 
1816  for (i = 0; i < PYTHON_CACHE_SIZE; i++) {
1817  Py_XDECREF(pycode_cache[i].code);
1818  if (pycode_cache[i].file != NULL)
1820  }
1821 
1822  Py_Finalize();
1823 
1824  return 0;
1825 }
cf_cost_string_from_value
void cf_cost_string_from_value(uint64_t cost, int largest_coin, char *buffer, int length)
Definition: plugin_common.c:984
compilePython
static PyCodeObject * compilePython(char *filename)
Definition: cfpython.c:902
CLASS
@ CLASS
Definition: object.h:138
getPlayerDirectory
static PyObject * getPlayerDirectory(PyObject *self, PyObject *args)
Definition: cfpython.c:278
CrossfireModule
static PyModuleDef CrossfireModule
Definition: cfpython.c:1442
findAnimation
static PyObject * findAnimation(PyObject *self, PyObject *args)
Definition: cfpython.c:623
TRIGGER
@ TRIGGER
Definition: object.h:129
_timeofday::month
int month
Definition: tod.h:40
_cfpcontext::message
char message[1024]
Definition: cfpython.h:94
MIMIC
@ MIMIC
Definition: object.h:249
getWhatIsMessage
static PyObject * getWhatIsMessage(PyObject *self, PyObject *args)
Definition: cfpython.c:323
PLAYER
@ PLAYER
Definition: object.h:107
cf_log
void cf_log(LogLevel logLevel, const char *format,...)
Definition: plugin_common.c:1512
ATNR_PARALYZE
#define ATNR_PARALYZE
Definition: attack.h:61
_cfpcontext::third
PyObject * third
Definition: cfpython.h:92
pycode_cache_entry::used_time
time_t used_time
Definition: cfpython.c:78
DAYS_PER_WEEK
#define DAYS_PER_WEEK
Definition: tod.h:16
ATNR_CANCELLATION
#define ATNR_CANCELLATION
Definition: attack.h:64
CF_HANDLE
@ CF_HANDLE
Definition: object.h:208
cf_get_weekday_name
const char * cf_get_weekday_name(int index)
Definition: plugin_common.c:1564
cf_add_string
sstring cf_add_string(const char *str)
Definition: plugin_common.c:1157
talk_info::replies
sstring replies[MAX_REPLIES]
Definition: dialog.h:58
MAP
@ MAP
Definition: object.h:125
cf_map_get_first
mapstruct * cf_map_get_first(void)
Definition: plugin_common.c:965
getFriendlyList
static PyObject * getFriendlyList(PyObject *self, PyObject *args)
Definition: cfpython.c:456
Crossfire_Map_wrap
PyObject * Crossfire_Map_wrap(mapstruct *what)
Definition: cfpython_map.c:439
cf_get_directory
const char * cf_get_directory(int id)
Definition: plugin_common.c:1120
AT_POISON
#define AT_POISON
Definition: attack.h:86
ATNR_INTERNAL
#define ATNR_INTERNAL
Definition: attack.h:72
AT_MAGIC
#define AT_MAGIC
Definition: attack.h:77
MONSTER
@ MONSTER
Definition: object.h:200
BOW
@ BOW
Definition: object.h:118
BRACERS
@ BRACERS
Definition: object.h:217
cstAttackType
const CFConstant cstAttackType[]
Definition: cfpython.c:1241
CLOSE_CON
@ CLOSE_CON
Definition: object.h:229
WAITATT
#define WAITATT
Definition: define.h:495
llevError
@ llevError
Definition: logger.h:11
eventListener
CF_PLUGIN int eventListener(int *type,...)
Definition: cfpython.c:1764
ARMOUR_IMPROVER
@ ARMOUR_IMPROVER
Definition: object.h:232
EVENT_CONNECTOR
@ EVENT_CONNECTOR
Definition: object.h:227
MOVE_ALL
#define MOVE_ALL
Definition: define.h:398
SYMPTOM
@ SYMPTOM
Definition: object.h:245
WAND
@ WAND
Definition: object.h:220
do_script
static int do_script(CFPContext *context)
Definition: cfpython.c:991
cf_get_season_name
const char * cf_get_season_name(int index)
Definition: plugin_common.c:1546
ALLRUN
#define ALLRUN
Definition: define.h:497
getMaps
static PyObject * getMaps(PyObject *self, PyObject *args)
Definition: cfpython.c:411
talk_info::replies_words
sstring replies_words[MAX_REPLIES]
Definition: dialog.h:57
talk_info::npc_msg_count
int npc_msg_count
Definition: dialog.h:59
FLESH
@ FLESH
Definition: object.h:187
ENCOUNTER
@ ENCOUNTER
Definition: object.h:182
closePlugin
CF_PLUGIN int closePlugin(void)
Definition: cfpython.c:1805
GLOVES
@ GLOVES
Definition: object.h:213
findFace
static PyObject * findFace(PyObject *self, PyObject *args)
Definition: cfpython.c:577
GIRDLE
@ GIRDLE
Definition: object.h:223
ATNR_ACID
#define ATNR_ACID
Definition: attack.h:55
BUTTON
@ BUTTON
Definition: object.h:207
_cfpcontext::event_code
int event_code
Definition: cfpython.h:96
cf_archetype_get_first
archetype * cf_archetype_get_first(void)
Definition: plugin_common.c:1676
RUNATT
#define RUNATT
Definition: define.h:493
AT_ELECTRICITY
#define AT_ELECTRICITY
Definition: attack.h:79
MAX_COMMANDS
#define MAX_COMMANDS
Definition: cfpython.c:81
archininventory.arch
arch
DIALOGCHECK MINARGS 1 MAXARGS 1
Definition: archininventory.py:16
PACEV2
#define PACEV2
Definition: define.h:526
Crossfire_Region_wrap
PyObject * Crossfire_Region_wrap(region *what)
Definition: cfpython_region.c:72
cf_object_get_object_property
object * cf_object_get_object_property(object *op, int propcode)
Definition: plugin_common.c:355
TRIGGER_PEDESTAL
@ TRIGGER_PEDESTAL
Definition: object.h:134
CFAPI_MAP_PROP_NEXT
#define CFAPI_MAP_PROP_NEXT
Definition: plugin.h:264
_timeofday::day
int day
Definition: tod.h:41
NDI_GREEN
#define NDI_GREEN
Definition: newclient.h:249
KEY
@ KEY
Definition: object.h:127
CFBank.open
def open()
Definition: CFBank.py:70
getWhoAmI
static PyObject * getWhoAmI(PyObject *self, PyObject *args)
Definition: cfpython.c:290
Crossfire_Object
Definition: cfpython_object.h:32
c
static event_registration c
Definition: citylife.cpp:425
AT_PHYSICAL
#define AT_PHYSICAL
Definition: attack.h:76
getMonthName
static PyObject * getMonthName(PyObject *self, PyObject *args)
Definition: cfpython.c:641
SHOP_FLOOR
@ SHOP_FLOOR
Definition: object.h:183
GEM
@ GEM
Definition: object.h:167
getWeekdayName
static PyObject * getWeekdayName(PyObject *self, PyObject *args)
Definition: cfpython.c:650
pl
Definition: player.h:92
cf_create_object_by_name
object * cf_create_object_by_name(const char *name)
Definition: plugin_common.c:1083
HITRUN
#define HITRUN
Definition: define.h:494
HOURS_PER_DAY
#define HOURS_PER_DAY
Definition: tod.h:15
TRAP
@ TRAP
Definition: object.h:241
addReply
static PyObject * addReply(PyObject *self, PyObject *args)
Definition: cfpython.c:668
ARMOUR
@ ARMOUR
Definition: object.h:120
guildoracle.list
list
Definition: guildoracle.py:87
SVN_REV
#define SVN_REV
Definition: svnversion.h:2
WEAPON
@ WEAPON
Definition: object.h:119
TIMED_GATE
@ TIMED_GATE
Definition: object.h:128
guildjoin.ob
ob
Definition: guildjoin.py:42
Crossfire_Object_wrap
PyObject * Crossfire_Object_wrap(object *what)
Definition: cfpython_object.c:1608
EVENT_TIMER
#define EVENT_TIMER
Definition: events.h:34
say.reply
string reply
Definition: say.py:77
python_event.path
path
Definition: python_event.py:11
initPlugin
CF_PLUGIN int initPlugin(const char *iversion, f_plug_api gethooksptr)
Definition: cfpython.c:1461
cf_timer_destroy
int cf_timer_destroy(int id)
Definition: plugin_common.c:1610
_timeofday::year
int year
Definition: tod.h:39
ATNR_SLOW
#define ATNR_SLOW
Definition: attack.h:60
AMULET
@ AMULET
Definition: object.h:139
CHECK_INV
@ CHECK_INV
Definition: object.h:169
current_context
CFPContext * current_context
Definition: cfpython.c:103
getCFPythonVersion
static PyObject * getCFPythonVersion(PyObject *self, PyObject *args)
Definition: cfpython.c:162
mad_mage_user.file
file
Definition: mad_mage_user.py:15
getParties
static PyObject * getParties(PyObject *self, PyObject *args)
Definition: cfpython.c:426
pl::ob
object * ob
Definition: player.h:162
ATNR_GODPOWER
#define ATNR_GODPOWER
Definition: attack.h:69
getScriptName
static PyObject * getScriptName(PyObject *self, PyObject *args)
Definition: cfpython.c:332
TREASURE
@ TREASURE
Definition: object.h:110
cf_region_get_next
region * cf_region_get_next(region *reg)
Definition: plugin_common.c:1900
EVENT_MAPLOAD
#define EVENT_MAPLOAD
Definition: events.h:47
NDI_ALL_DMS
#define NDI_ALL_DMS
Definition: newclient.h:264
SKILL
@ SKILL
Definition: object.h:143
RUNE
@ RUNE
Definition: object.h:240
ATNR_DISEASE
#define ATNR_DISEASE
Definition: attack.h:74
Ice.tmp
int tmp
Definition: Ice.py:207
AT_INTERNAL
#define AT_INTERNAL
Definition: attack.h:99
NDI_RED
#define NDI_RED
Definition: newclient.h:245
CREATOR
@ CREATOR
Definition: object.h:142
EVENT_LOGOUT
#define EVENT_LOGOUT
Definition: events.h:44
registered_commands
static command_registration registered_commands[MAX_COMMANDS]
Definition: cfpython.c:82
NDI_NAVY
#define NDI_NAVY
Definition: newclient.h:244
RANDO
#define RANDO
Definition: define.h:520
COMMAND_TYPE_NORMAL
#define COMMAND_TYPE_NORMAL
Definition: commands.h:35
_cfpcontext::returnvalue
int returnvalue
Definition: cfpython.h:99
llevMonster
@ llevMonster
Definition: logger.h:14
EVENT_SAY
#define EVENT_SAY
Definition: events.h:28
_timeofday::periodofday
int periodofday
Definition: tod.h:47
TRANSPORT
@ TRANSPORT
Definition: object.h:108
ATNR_PHYSICAL
#define ATNR_PHYSICAL
Definition: attack.h:49
POTION_RESIST_EFFECT
@ POTION_RESIST_EFFECT
Definition: object.h:225
FLOOR
@ FLOOR
Definition: object.h:186
_cfpcontext::event
PyObject * event
Definition: cfpython.h:93
setPlayerMessage
static PyObject * setPlayerMessage(PyObject *self, PyObject *args)
Definition: cfpython.c:696
SIGN
@ SIGN
Definition: object.h:211
flags
static const flag_definition flags[]
Definition: gridarta-types-convert.c:101
cf_party_get_next
partylist * cf_party_get_next(partylist *party)
Definition: plugin_common.c:1804
ATNR_TURN_UNDEAD
#define ATNR_TURN_UNDEAD
Definition: attack.h:62
TRIGGER_BUTTON
@ TRIGGER_BUTTON
Definition: object.h:132
npc_dialog.filename
filename
Definition: npc_dialog.py:99
Handle_Map_Unload_Hook
void Handle_Map_Unload_Hook(Crossfire_Map *map)
Definition: cfpython_map.c:434
NDI_BLUE
#define NDI_BLUE
Definition: newclient.h:247
talk_info::message_type
int message_type
Definition: dialog.h:55
_timeofday::dayofweek
int dayofweek
Definition: tod.h:42
POWER_CRYSTAL
@ POWER_CRYSTAL
Definition: object.h:242
WEEKS_PER_MONTH
#define WEEKS_PER_MONTH
Definition: tod.h:17
AT_LIFE_STEALING
#define AT_LIFE_STEALING
Definition: attack.h:100
_timeofday
Definition: tod.h:38
PACEH
#define PACEH
Definition: define.h:514
POISONING
@ POISONING
Definition: object.h:218
AT_DEATH
#define AT_DEATH
Definition: attack.h:93
PyInit_Crossfire
static PyObject * PyInit_Crossfire(void)
Definition: cfpython.c:1454
ATNR_CONFUSION
#define ATNR_CONFUSION
Definition: attack.h:54
ATNR_HOLYWORD
#define ATNR_HOLYWORD
Definition: attack.h:70
NDI_ORANGE
#define NDI_ORANGE
Definition: newclient.h:246
talk_info::message
sstring message
Definition: dialog.h:54
talk_info::replies_count
int replies_count
Definition: dialog.h:56
archt
Definition: object.h:468
obj
Definition: object.h:275
createCFObject
static PyObject * createCFObject(PyObject *self, PyObject *args)
Definition: cfpython.c:139
TRIGGER_MARKER
@ TRIGGER_MARKER
Definition: object.h:153
Crossfire_PlayerType
PyTypeObject Crossfire_PlayerType
getMapHasBeenLoaded
static PyObject * getMapHasBeenLoaded(PyObject *self, PyObject *args)
Definition: cfpython.c:568
ATNR_BLIND
#define ATNR_BLIND
Definition: attack.h:71
m
static event_registration m
Definition: citylife.cpp:425
AT_CHAOS
#define AT_CHAOS
Definition: attack.h:94
CLOAK
@ CLOAK
Definition: object.h:204
costStringFromValue
static PyObject * costStringFromValue(PyObject *self, PyObject *args)
Definition: cfpython.c:749
pycode_cache_entry::cached_time
time_t cached_time
Definition: cfpython.c:77
_timeofday::season
int season
Definition: tod.h:46
GECodes
static int GECodes[]
Definition: cfpython.c:1534
getEvent
static PyObject * getEvent(PyObject *self, PyObject *args)
Definition: cfpython.c:348
unregisterGEvent
static PyObject * unregisterGEvent(PyObject *self, PyObject *args)
Definition: cfpython.c:126
EVENT_LOGIN
#define EVENT_LOGIN
Definition: events.h:43
HELMET
@ HELMET
Definition: object.h:136
getConfigDirectory
static PyObject * getConfigDirectory(PyObject *self, PyObject *args)
Definition: cfpython.c:266
disinfect.map
map
Definition: disinfect.py:4
POISON
@ POISON
Definition: object.h:113
getPluginProperty
CF_PLUGIN void * getPluginProperty(int *type,...)
Definition: cfpython.c:1509
initContextStack
static void initContextStack(void)
Definition: cfpython.c:814
cf_log_plain
void cf_log_plain(LogLevel logLevel, const char *message)
Definition: plugin_common.c:1532
EVENT_STOP
#define EVENT_STOP
Definition: events.h:30
cf_party_get_first
partylist * cf_party_get_first(void)
Definition: plugin_common.c:1773
EVENT_CLOCK
#define EVENT_CLOCK
Definition: events.h:39
DEEP_SWAMP
@ DEEP_SWAMP
Definition: object.h:236
make_face_from_files.args
args
Definition: make_face_from_files.py:31
shared_data
static PyObject * shared_data
Definition: cfpython.c:105
MARKER
@ MARKER
Definition: object.h:158
cstEventType
const CFConstant cstEventType[]
Definition: cfpython.c:1301
matchString
static PyObject * matchString(PyObject *self, PyObject *args)
Definition: cfpython.c:187
EVENT_PICKUP
#define EVENT_PICKUP
Definition: events.h:27
EVENT_CRASH
#define EVENT_CRASH
Definition: events.h:40
SAVEBED
@ SAVEBED
Definition: object.h:219
EVENT_SELLING
#define EVENT_SELLING
Definition: events.h:29
AT_COLD
#define AT_COLD
Definition: attack.h:80
init_map_assoc_table
void init_map_assoc_table(void)
Definition: cfpython_map.c:37
CF_PLUGIN
#define CF_PLUGIN
Definition: plugin_common.h:38
pushContext
static void pushContext(CFPContext *context)
Definition: cfpython.c:819
SEASONS_PER_YEAR
#define SEASONS_PER_YEAR
Definition: tod.h:19
LIGHTABLE
@ LIGHTABLE
Definition: object.h:250
POTION
@ POTION
Definition: object.h:111
_cfpcontext::down
struct _cfpcontext * down
Definition: cfpython.h:89
MOVE_WALK
#define MOVE_WALK
Definition: define.h:392
cf_find_face
int cf_find_face(const char *name, int error)
Definition: plugin_common.c:1500
BUILDER
@ BUILDER
Definition: object.h:246
EVENT_DROP
#define EVENT_DROP
Definition: events.h:26
_cfpcontext::who
PyObject * who
Definition: cfpython.h:90
EVENT_TRIGGER
#define EVENT_TRIGGER
Definition: events.h:33
f_plug_api
void(* f_plug_api)(int *type,...)
Definition: plugin.h:81
createCFObjectByName
static PyObject * createCFObjectByName(PyObject *self, PyObject *args)
Definition: cfpython.c:149
EVENT_MAPENTER
#define EVENT_MAPENTER
Definition: events.h:45
freeContext
static void freeContext(CFPContext *context)
Definition: cfpython.c:841
cf_system_unregister_global_event
void cf_system_unregister_global_event(int event, const char *name)
Definition: plugin_common.c:1099
cf_get_month_name
const char * cf_get_month_name(int index)
Definition: plugin_common.c:1555
cf_init_plugin
int cf_init_plugin(f_plug_api getHooks)
Definition: plugin_common.c:141
ROD
@ ROD
Definition: object.h:109
CONTAINER
@ CONTAINER
Definition: object.h:231
INORGANIC
@ INORGANIC
Definition: object.h:188
_timeofday::weekofmonth
int weekofmonth
Definition: tod.h:45
python_command_function
static void python_command_function(object *op, const char *params, const char *script)
Definition: cfpython.c:471
cf_get_empty_map
mapstruct * cf_get_empty_map(int sizex, int sizey)
Definition: plugin_common.c:938
LOCKED_DOOR
@ LOCKED_DOOR
Definition: object.h:123
PLAYERMOVER
@ PLAYERMOVER
Definition: object.h:140
PLUGIN_NAME
#define PLUGIN_NAME
Definition: cfanim.h:32
cf_region_get_first
region * cf_region_get_first(void)
Definition: plugin_common.c:1868
cstTime
const CFConstant cstTime[]
Definition: cfpython.c:1342
EVENT_MAPRESET
#define EVENT_MAPRESET
Definition: events.h:48
cfpython.h
pycode_cache_entry::code
PyCodeObject * code
Definition: cfpython.c:76
getWhoIsThird
static PyObject * getWhoIsThird(PyObject *self, PyObject *args)
Definition: cfpython.c:312
SPECIAL_KEY
@ SPECIAL_KEY
Definition: object.h:124
MOVE_FLYING
#define MOVE_FLYING
Definition: define.h:395
HOLE
@ HOLE
Definition: object.h:209
cfpython_init_types
static void cfpython_init_types(PyObject *m)
Definition: cfpython.c:1401
PEACEMAKER
@ PEACEMAKER
Definition: object.h:164
MAX_NPC
#define MAX_NPC
Definition: dialog.h:46
CIRCLE2
#define CIRCLE2
Definition: define.h:513
getRegions
static PyObject * getRegions(PyObject *self, PyObject *args)
Definition: cfpython.c:441
readyMap
static PyObject * readyMap(PyObject *self, PyObject *args)
Definition: cfpython.c:221
EVENT_BORN
#define EVENT_BORN
Definition: events.h:38
guild_questpoints_apply.mapname
mapname
Definition: guild_questpoints_apply.py:8
CONVERTER
@ CONVERTER
Definition: object.h:216
EVENT_MAPUNLOAD
#define EVENT_MAPUNLOAD
Definition: events.h:49
SKILLSCROLL
@ SKILLSCROLL
Definition: object.h:234
ATNR_DRAIN
#define ATNR_DRAIN
Definition: attack.h:56
navar-midane_time.data
data
Definition: navar-midane_time.py:11
NDI_GOLD
#define NDI_GOLD
Definition: newclient.h:254
DRAGON_FOCUS
@ DRAGON_FOCUS
Definition: object.h:116
rt_say
@ rt_say
Definition: dialog.h:10
LAMP
@ LAMP
Definition: object.h:201
cstMove
const CFConstant cstMove[]
Definition: cfpython.c:1210
cfpython_openpyfile
static PyObject * cfpython_openpyfile(char *filename)
Definition: cfpython.c:852
GOLEM
@ GOLEM
Definition: object.h:145
sstring
const typedef char * sstring
Definition: global.h:40
ATNR_COUNTERSPELL
#define ATNR_COUNTERSPELL
Definition: attack.h:68
set_exception
static void set_exception(const char *fmt,...)
Definition: cfpython.c:90
postInitPlugin
CF_PLUGIN int postInitPlugin(void)
Definition: cfpython.c:1574
EVENT_USER
#define EVENT_USER
Definition: events.h:35
MOOD_FLOOR
@ MOOD_FLOOR
Definition: object.h:170
ATNR_POISON
#define ATNR_POISON
Definition: attack.h:59
ARROW
@ ARROW
Definition: object.h:117
EVENT_THROW
#define EVENT_THROW
Definition: events.h:32
ATNR_DEATH
#define ATNR_DEATH
Definition: attack.h:66
rt_reply
@ rt_reply
Definition: dialog.h:11
PACEV
#define PACEV
Definition: define.h:524
mapdef
Definition: map.h:324
BOOK
@ BOOK
Definition: object.h:114
SvnRevPlugin
CF_PLUGIN char SvnRevPlugin[]
Definition: cfpython.c:66
RING
@ RING
Definition: object.h:185
EVENT_SHOUT
#define EVENT_SHOUT
Definition: events.h:53
BLINDNESS
@ BLINDNESS
Definition: object.h:147
replace
Definition: replace.py:1
nlohmann::detail::void
j template void())
Definition: json.hpp:4099
cf_map_get_map_property
mapstruct * cf_map_get_map_property(mapstruct *map, int propcode)
Definition: plugin_common.c:269
NDI_BLACK
#define NDI_BLACK
Definition: newclient.h:242
getLocalDirectory
static PyObject * getLocalDirectory(PyObject *self, PyObject *args)
Definition: cfpython.c:272
cstType
const CFConstant cstType[]
Definition: cfpython.c:1094
party_struct
Definition: party.h:10
CLOCK
@ CLOCK
Definition: object.h:115
cf_free_string
void cf_free_string(sstring str)
Definition: plugin_common.c:1172
log_python_error
static void log_python_error(void)
Definition: cfpython.c:882
SHOP_MAT
@ SHOP_MAT
Definition: object.h:184
EVENT_BOUGHT
#define EVENT_BOUGHT
Definition: events.h:22
cstMessageFlag
const CFConstant cstMessageFlag[]
Definition: cfpython.c:1221
_cfpcontext::script
char script[1024]
Definition: cfpython.h:97
getReturnValue
static PyObject * getReturnValue(PyObject *self, PyObject *args)
Definition: cfpython.c:170
MOVE_FLY_LOW
#define MOVE_FLY_LOW
Definition: define.h:393
EVENT_PLAYER_DEATH
#define EVENT_PLAYER_DEATH
Definition: events.h:51
ATNR_FIRE
#define ATNR_FIRE
Definition: attack.h:51
_cfpcontext::talk
struct talk_info * talk
Definition: cfpython.h:101
cf_system_register_command_extra
command_registration cf_system_register_command_extra(const char *name, const char *extra, command_function_extra func, uint8_t command_type, float time)
Definition: plugin_common.c:2093
EXIT
@ EXIT
Definition: object.h:181
cfpython_globalEventListener
CF_PLUGIN int cfpython_globalEventListener(int *type,...)
Definition: cfpython.c:1609
MAGIC_EAR
@ MAGIC_EAR
Definition: object.h:131
MONTHS_PER_YEAR
#define MONTHS_PER_YEAR
Definition: tod.h:18
PLUGIN_VERSION
#define PLUGIN_VERSION
Definition: cfanim.h:33
createMap
static PyObject * createMap(PyObject *self, PyObject *args)
Definition: cfpython.c:235
diamondslots.message
string message
Definition: diamondslots.py:57
cf_system_register_global_event
void cf_system_register_global_event(int event, const char *name, f_plug_event hook)
Definition: plugin_common.c:1092
log_message
static PyObject * log_message(PyObject *self, PyObject *args)
Definition: cfpython.c:586
GEPaths
static const char * GEPaths[]
Definition: cfpython.c:1554
llevInfo
@ llevInfo
Definition: logger.h:12
autojail.dict
dict
Definition: autojail.py:7
pycode_cache_entry::file
sstring file
Definition: cfpython.c:75
NDI_UNIQUE
#define NDI_UNIQUE
Definition: newclient.h:262
EVENT_MUZZLE
#define EVENT_MUZZLE
Definition: events.h:50
addSimpleConstants
static void addSimpleConstants(PyObject *module, const char *name, const CFConstant *constants)
Definition: cfpython.c:1066
cf_find_animation
int cf_find_animation(const char *txt)
Definition: plugin_common.c:1488
registerGEvent
static PyObject * registerGEvent(PyObject *self, PyObject *args)
Definition: cfpython.c:113
AT_BLIND
#define AT_BLIND
Definition: attack.h:98
CFPythonError
static PyObject * CFPythonError
Definition: cfpython.c:87
EVENT_TELL
#define EVENT_TELL
Definition: events.h:54
ATNR_CHAOS
#define ATNR_CHAOS
Definition: attack.h:67
EVENT_DEATH
#define EVENT_DEATH
Definition: events.h:24
_cfpcontext::fix
int fix
Definition: cfpython.h:95
getSharedDictionary
static PyObject * getSharedDictionary(PyObject *self, PyObject *args)
Definition: cfpython.c:374
BATTLEGROUND
@ BATTLEGROUND
Definition: object.h:163
Crossfire_PartyType
PyTypeObject Crossfire_PartyType
getSeasonName
static PyObject * getSeasonName(PyObject *self, PyObject *args)
Definition: cfpython.c:632
cf_archetype_get_next
archetype * cf_archetype_get_next(archetype *arch)
Definition: plugin_common.c:1709
AT_SLOW
#define AT_SLOW
Definition: attack.h:87
CFConstant
Definition: cfpython.h:104
MAX_REPLIES
#define MAX_REPLIES
Definition: dialog.h:44
AT_TURN_UNDEAD
#define AT_TURN_UNDEAD
Definition: attack.h:89
cf_get_periodofday_name
const char * cf_get_periodofday_name(int index)
Definition: plugin_common.c:1573
cfpython_pyfile_asfile
static FILE * cfpython_pyfile_asfile(PyObject *obj)
Definition: cfpython.c:866
GRIMREAPER
@ GRIMREAPER
Definition: object.h:130
ATNR_DEPLETE
#define ATNR_DEPLETE
Definition: attack.h:65
item
Definition: item.py:1
popContext
static CFPContext * popContext(void)
Definition: cfpython.c:829
getArchetypes
static PyObject * getArchetypes(PyObject *self, PyObject *args)
Definition: cfpython.c:381
EARTHWALL
@ EARTHWALL
Definition: object.h:144
Crossfire_Archetype_wrap
PyObject * Crossfire_Archetype_wrap(archetype *what)
Definition: cfpython_archetype.c:62
DUPLICATOR
@ DUPLICATOR
Definition: object.h:202
DISEASE
@ DISEASE
Definition: object.h:244
FIREWALL
@ FIREWALL
Definition: object.h:168
TRIGGER_ALTAR
@ TRIGGER_ALTAR
Definition: object.h:133
PLAYER_CHANGER
@ PLAYER_CHANGER
Definition: object.h:162
npcSay
static PyObject * npcSay(PyObject *self, PyObject *args)
Definition: cfpython.c:719
LIGHTER
@ LIGHTER
Definition: object.h:190
rt_question
@ rt_question
Definition: dialog.h:12
PERIODS_PER_DAY
#define PERIODS_PER_DAY
Definition: tod.h:20
give.op
op
Definition: give.py:33
NDI_ALL
#define NDI_ALL
Definition: newclient.h:263
_cfpcontext::activator
PyObject * activator
Definition: cfpython.h:91
autojail.value
value
Definition: autojail.py:6
AT_DEPLETE
#define AT_DEPLETE
Definition: attack.h:92
getWhoIsActivator
static PyObject * getWhoIsActivator(PyObject *self, PyObject *args)
Definition: cfpython.c:301
Crossfire_ArchetypeType
PyTypeObject Crossfire_ArchetypeType
cf_map_has_been_loaded
mapstruct * cf_map_has_been_loaded(const char *name)
Definition: plugin_common.c:951
cstAttackTypeNumber
const CFConstant cstAttackTypeNumber[]
Definition: cfpython.c:1271
MATERIAL
@ MATERIAL
Definition: object.h:248
EVENT_TIME
#define EVENT_TIME
Definition: events.h:31
getPlayers
static PyObject * getPlayers(PyObject *self, PyObject *args)
Definition: cfpython.c:396
cf_re_cmp
const char * cf_re_cmp(const char *str, const char *regexp)
Definition: plugin_common.c:1133
destroyTimer
static PyObject * destroyTimer(PyObject *self, PyObject *args)
Definition: cfpython.c:559
EVENT_MAPLEAVE
#define EVENT_MAPLEAVE
Definition: events.h:46
initConstants
static void initConstants(PyObject *module)
Definition: cfpython.c:1380
Crossfire_Party_wrap
PyObject * Crossfire_Party_wrap(partylist *what)
Definition: cfpython_party.c:61
SPINNER
@ SPINNER
Definition: object.h:205
AT_WEAPONMAGIC
#define AT_WEAPONMAGIC
Definition: attack.h:84
SPELL_EFFECT
@ SPELL_EFFECT
Definition: object.h:215
SKILL_TOOL
@ SKILL_TOOL
Definition: object.h:189
ATNR_MAGIC
#define ATNR_MAGIC
Definition: attack.h:50
roll-o-matic.params
params
Definition: roll-o-matic.py:193
SHOP_INVENTORY
@ SHOP_INVENTORY
Definition: object.h:238
catcher
static PyObject * catcher
Definition: cfpython.c:874
context_stack
CFPContext * context_stack
Definition: cfpython.c:101
NDI_WHITE
#define NDI_WHITE
Definition: newclient.h:243
PEDESTAL
@ PEDESTAL
Definition: object.h:121
cf_create_object
object * cf_create_object(void)
Definition: plugin_common.c:1071
cf_get_maps_directory
char * cf_get_maps_directory(const char *name, char *buf, int size)
Definition: plugin_common.c:1059
npc_dialog.index
int index
Definition: npc_dialog.py:102
NDI_BROWN
#define NDI_BROWN
Definition: newclient.h:253
buf
StringBuffer * buf
Definition: readable.c:1606
talk_info
Definition: dialog.h:51
NDI_TAN
#define NDI_TAN
Definition: newclient.h:255
EVENT_REMOVE
#define EVENT_REMOVE
Definition: events.h:52
NDI_DK_ORANGE
#define NDI_DK_ORANGE
Definition: newclient.h:248
cstAttackMovement
const CFConstant cstAttackMovement[]
Definition: cfpython.c:1359
pycode_cache_entry
Definition: cfpython.c:74
registerCommand
static PyObject * registerCommand(PyObject *self, PyObject *args)
Definition: cfpython.c:502
DEAD_OBJECT
@ DEAD_OBJECT
Definition: object.h:156
getGlobalEventPath
static const char * getGlobalEventPath(int code)
Definition: cfpython.c:1601
ATNR_WEAPONMAGIC
#define ATNR_WEAPONMAGIC
Definition: attack.h:57
DIRECTOR
@ DIRECTOR
Definition: object.h:222
CORPSE
@ CORPSE
Definition: object.h:243
talk_info::npc_msgs
sstring npc_msgs[MAX_NPC]
Definition: dialog.h:60
npc_dialog.npc
npc
Definition: npc_dialog.py:95
Crossfire_RegionType
PyTypeObject Crossfire_RegionType
cf_player_find
player * cf_player_find(const char *plname)
Definition: plugin_common.c:815
cstDirection
const CFConstant cstDirection[]
Definition: cfpython.c:1082
replace
void replace(const char *src, const char *key, const char *replacement, char *result, size_t resultsize)
Definition: utils.c:354
cf_friendlylist_get_next
object * cf_friendlylist_get_next(object *ob)
Definition: plugin_common.c:2026
_cfpcontext
Definition: cfpython.h:88
AT_COUNTERSPELL
#define AT_COUNTERSPELL
Definition: attack.h:95
getScriptParameters
static PyObject * getScriptParameters(PyObject *self, PyObject *args)
Definition: cfpython.c:338
AT_DISEASE
#define AT_DISEASE
Definition: attack.h:102
AT_ACID
#define AT_ACID
Definition: attack.h:82
cf_system_unregister_command
void cf_system_unregister_command(command_registration command)
Definition: plugin_common.c:2101
AT_FEAR
#define AT_FEAR
Definition: attack.h:90
FOOD
@ FOOD
Definition: object.h:112
AT_GODPOWER
#define AT_GODPOWER
Definition: attack.h:96
findPlayer
static PyObject * findPlayer(PyObject *self, PyObject *args)
Definition: cfpython.c:203
pycode_cache
static pycode_cache_entry pycode_cache[PYTHON_CACHE_SIZE]
Definition: cfpython.c:85
MOVE_BOAT
#define MOVE_BOAT
Definition: define.h:397
MOVE_FLY_HIGH
#define MOVE_FLY_HIGH
Definition: define.h:394
EVENT_ATTACKED
#define EVENT_ATTACKED
Definition: events.h:20
PYTHON_CACHE_SIZE
#define PYTHON_CACHE_SIZE
Definition: cfpython.c:69
ALTAR
@ ALTAR
Definition: object.h:122
animate.event
event
DIALOGCHECK MINARGS 1 MAXARGS 2
Definition: animate.py:17
DOOR
@ DOOR
Definition: object.h:126
getPrivateDictionary
static PyObject * getPrivateDictionary(PyObject *self, PyObject *args)
Definition: cfpython.c:359
EVENT_CLOSE
#define EVENT_CLOSE
Definition: events.h:23
command_registration
uint64_t command_registration
Definition: commands.h:32
AT_CONFUSION
#define AT_CONFUSION
Definition: attack.h:81
cf_map_get_map
mapstruct * cf_map_get_map(const char *name, int flags)
Definition: plugin_common.c:925
WAIT2
#define WAIT2
Definition: define.h:499
level
int level
Definition: readable.c:1604
PyInit_cjson
PyObject * PyInit_cjson(void)
Definition: cjson.c:1185
DRINK
@ DRINK
Definition: object.h:157
ATNR_GHOSTHIT
#define ATNR_GHOSTHIT
Definition: attack.h:58
WALL
@ WALL
Definition: object.h:191
setReturnValue
static PyObject * setReturnValue(PyObject *self, PyObject *args)
Definition: cfpython.c:176
ATNR_COLD
#define ATNR_COLD
Definition: attack.h:53
WEAPON_IMPROVER
@ WEAPON_IMPROVER
Definition: object.h:233
SCROLL
@ SCROLL
Definition: object.h:221
AT_CANCELLATION
#define AT_CANCELLATION
Definition: attack.h:91
getTempDirectory
static PyObject * getTempDirectory(PyObject *self, PyObject *args)
Definition: cfpython.c:260
CFPythonMethods
PyMethodDef CFPythonMethods[]
Definition: cfpython.c:762
DISTHIT
#define DISTHIT
Definition: define.h:498
RUSH
#define RUSH
Definition: define.h:496
PETMOVE
#define PETMOVE
Definition: define.h:501
say.item
dictionary item
Definition: say.py:149
death_message.hitter
hitter
Definition: death_message.py:33
LogLevel
LogLevel
Definition: logger.h:10
MOVE_SWIM
#define MOVE_SWIM
Definition: define.h:396
getMapDirectory
static PyObject * getMapDirectory(PyObject *self, PyObject *args)
Definition: cfpython.c:248
DISTATT
#define DISTATT
Definition: define.h:491
cf_friendlylist_get_first
object * cf_friendlylist_get_first(void)
Definition: plugin_common.c:2010
addConstants
static void addConstants(PyObject *module, const char *name, const CFConstant *constants)
Definition: cfpython.c:1034
_timeofday::minute
int minute
Definition: tod.h:44
EVENT_ATTACKS
#define EVENT_ATTACKS
Definition: events.h:21
svnversion.h
BOOTS
@ BOOTS
Definition: object.h:212
cstReplyTypes
const CFConstant cstReplyTypes[]
Definition: cfpython.c:1352
getDataDirectory
static PyObject * getDataDirectory(PyObject *self, PyObject *args)
Definition: cfpython.c:284
AT_PARALYZE
#define AT_PARALYZE
Definition: attack.h:88
ATNR_ELECTRICITY
#define ATNR_ELECTRICITY
Definition: attack.h:52
AT_HOLYWORD
#define AT_HOLYWORD
Definition: attack.h:97
IDENTIFY_ALTAR
@ IDENTIFY_ALTAR
Definition: object.h:237
SPELL
@ SPELL
Definition: object.h:214
AT_GHOSTHIT
#define AT_GHOSTHIT
Definition: attack.h:85
EVENT_DESTROY
#define EVENT_DESTROY
Definition: events.h:25
EVENT_GKILL
#define EVENT_GKILL
Definition: events.h:41
SHIELD
@ SHIELD
Definition: object.h:135
CIRCLE1
#define CIRCLE1
Definition: define.h:509
TELEPORTER
@ TELEPORTER
Definition: object.h:141
altar_valkyrie.pl
pl
Definition: altar_valkyrie.py:28
ATNR_LIFE_STEALING
#define ATNR_LIFE_STEALING
Definition: attack.h:73
PACEH2
#define PACEH2
Definition: define.h:516
Crossfire_Map
Definition: cfpython_map.h:32
private_data
static PyObject * private_data
Definition: cfpython.c:107
THROWN_OBJ
@ THROWN_OBJ
Definition: object.h:146
NDI_GREY
#define NDI_GREY
Definition: newclient.h:252
SPELLBOOK
@ SPELLBOOK
Definition: object.h:203
Crossfire_ObjectType
PyTypeObject Crossfire_ObjectType
getPeriodofdayName
static PyObject * getPeriodofdayName(PyObject *self, PyObject *args)
Definition: cfpython.c:659
init_object_assoc_table
void init_object_assoc_table(void)
Definition: cfpython_object.c:60
EVENT_KICK
#define EVENT_KICK
Definition: events.h:42
getTime
static PyObject * getTime(PyObject *self, PyObject *args)
Definition: cfpython.c:537
FORCE
@ FORCE
Definition: object.h:224
HOLY_ALTAR
@ HOLY_ALTAR
Definition: object.h:161
TRAPDOOR
@ TRAPDOOR
Definition: object.h:210
AT_DRAIN
#define AT_DRAIN
Definition: attack.h:83
DETECTOR
@ DETECTOR
Definition: object.h:149
getUniqueDirectory
static PyObject * getUniqueDirectory(PyObject *self, PyObject *args)
Definition: cfpython.c:254
NDI_LT_GREEN
#define NDI_LT_GREEN
Definition: newclient.h:250
CFAPI_PLAYER_PROP_NEXT
#define CFAPI_PLAYER_PROP_NEXT
Definition: plugin.h:240
_cfpcontext::options
char options[1024]
Definition: cfpython.h:98
cf_get_time
void cf_get_time(timeofday_t *tod)
Definition: plugin_common.c:1539
GOD
@ GOD
Definition: object.h:148
_timeofday::hour
int hour
Definition: tod.h:43
llevDebug
@ llevDebug
Definition: logger.h:13
MISC_OBJECT
@ MISC_OBJECT
Definition: object.h:193
MONEY
@ MONEY
Definition: object.h:137
RANDO2
#define RANDO2
Definition: define.h:523
is_valid_types_gen.type
list type
Definition: is_valid_types_gen.py:25
GATE
@ GATE
Definition: object.h:206
give.name
name
Definition: give.py:27
EVENT_APPLY
#define EVENT_APPLY
Definition: events.h:19
ATNR_FEAR
#define ATNR_FEAR
Definition: attack.h:63
Crossfire_MapType
PyTypeObject Crossfire_MapType
AT_FIRE
#define AT_FIRE
Definition: attack.h:78
level
Definition: level.py:1
diamondslots.id
id
Definition: diamondslots.py:53
regiondef
Definition: map.h:275