Atrinik Server  4.0
plugin_python.h
Go to the documentation of this file.
1 /*************************************************************************
2  * Atrinik, a Multiplayer Online Role Playing Game *
3  * *
4  * Copyright (C) 2009-2014 Alex Tokar and Atrinik Development Team *
5  * *
6  * Fork from Crossfire (Multiplayer game for X-windows). *
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, write to the Free Software *
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
21  * *
22  * The author can be reached at admin@atrinik.org *
23  ************************************************************************/
24 
33 #ifndef PLUGIN_PYTHON_H
34 #define PLUGIN_PYTHON_H
35 
36 #pragma GCC diagnostic push
37 #pragma GCC diagnostic ignored "-Wundef"
38 #pragma GCC diagnostic ignored "-Wredundant-decls"
39 #include <Python.h>
40 #pragma GCC diagnostic pop
41 
42 #define GLOBAL_NO_PROTOTYPES
43 #include <global.h>
44 #include <arch.h>
45 #include <plugin.h>
46 #include <plugin_hooklist.h>
47 
49 #if PY_MAJOR_VERSION >= 3
50 #define IS_PY3K
51 #else
52 #if PY_MINOR_VERSION >= 6
53 #define IS_PY26
54 #else
55 #define IS_PY_LEGACY
56 #endif
57 #if PY_MINOR_VERSION >= 5
58 #define IS_PY25
59 #endif
60 #endif
61 
62 /* Fake some Python 2.x functions for Python 3.x. */
63 #ifdef IS_PY3K
64 #define PyString_Check PyUnicode_Check
65 #define PyString_AsString _PyUnicode_AsString
66 #define PyInt_Check PyLong_Check
67 #define PyInt_AsLong PyLong_AsLong
68 extern PyTypeObject PyIOBase_Type;
69 #define PyFile_Check(op) (PyObject_IsInstance((op), (PyObject *) &PyIOBase_Type))
70 #define PyString_FromFormat PyUnicode_FromFormat
71 #else
72 #define PyObject_AsFileDescriptor(op) (PyFile_AsFile((op)) ? PyFile_AsFile((op))->fd : -1)
73 #endif
74 
76 #define PLUGIN_NAME "Python"
77 
78 #define PLUGIN_VERSION "Atrinik Python Plugin 1.0"
79 
84 typedef PyObject *(*PyMethod_NOARGS)(PyObject *self);
85 
91 typedef PyObject *(*PyMethod_VARARGS)(PyObject *self, PyObject *args);
92 
98 typedef PyObject *(*PyMethod_OBJECT)(PyObject *self, PyObject *what);
99 
105 typedef PyObject *(*PyMethod_VARARGS_KEYWORDS)(PyObject *self, PyObject *args,
106  PyObject *keywds);
107 
108 extern struct plugin_hooklist *hooks;
109 
116 #define AROUND_ALL 0
117 
118 #define AROUND_WALL 1
119 
120 #define AROUND_BLOCKSVIEW 2
121 
122 #define AROUND_PLAYER_ONLY 4
123 
130 #define INVENTORY_ONLY 0
131 
135 #define INVENTORY_CONTAINERS 1
136 
140 #define INVENTORY_ALL 2
141 
143 #undef FREE_AND_COPY_HASH
144 #undef FREE_AND_CLEAR_HASH
145 
153 #define FREE_AND_COPY_HASH(_sv_, _nv_) \
154  { \
155  if (_sv_) \
156  { \
157  hooks->free_string_shared(_sv_); \
158  } \
159  \
160  _sv_ = hooks->add_string(_nv_); \
161  }
162 
169 #define FREE_AND_CLEAR_HASH(_nv_) \
170  { \
171  if (_nv_) \
172  { \
173  hooks->free_string_shared(_nv_); \
174  _nv_ = NULL; \
175  } \
176  }
177 
178 #undef SET_ANIMATION
179 #define SET_ANIMATION(ob, newanim) ob->face = &(*hooks->new_faces)[(*hooks->animations)[ob->animation_id].faces[newanim]]
180 #undef NUM_ANIMATIONS
181 #define NUM_ANIMATIONS(ob) ((*hooks->animations)[ob->animation_id].num_animations)
182 #undef NUM_FACINGS
183 #define NUM_FACINGS(ob) ((*hooks->animations)[ob->animation_id].facings)
184 
185 #undef emalloc
186 #undef efree
187 #undef ecalloc
188 #undef erealloc
189 #undef ereallocz
190 #undef estrdup
191 #undef estrndup
192 
193 #ifndef NDEBUG
194 #define emalloc(_size) hooks->memory_emalloc(_size, __FILE__, __LINE__)
195 #define efree(_ptr) hooks->memory_efree(_ptr, __FILE__, __LINE__)
196 #define ecalloc(_nmemb, _size) \
197  hooks->memory_ecalloc(_nmemb, _size, __FILE__, __LINE__)
198 #define erealloc(_ptr, _size) \
199  hooks->memory_erealloc(_ptr, _size, __FILE__, __LINE__)
200 #define ereallocz(_ptr, _old_size, _new_size) \
201  hooks->memory_reallocz(_ptr, _old_size, _new_size, __FILE__, __LINE__)
202 #define estrdup(_s) hooks->string_estrdup(_s, __FILE__, __LINE__)
203 #define estrndup(_s, _n) hooks->string_estrndup(_s, _n, __FILE__, __LINE__)
204 #else
205 #define emalloc(_size) hooks->memory_emalloc(_size)
206 #define efree(_ptr) hooks->memory_efree(_ptr)
207 #define ecalloc(_nmemb, _size) hooks->memory_ecalloc(_nmemb, _size)
208 #define erealloc(_ptr, _size) hooks->memory_erealloc(_ptr, _size)
209 #define ereallocz(_ptr, _old_size, _new_size) \
210  hooks->memory_reallocz(_ptr, _old_size, _new_size)
211 #define estrdup(_s) hooks->string_estrdup(_s)
212 #define estrndup(_s, _n) hooks->string_estrndup(_s, _n)
213 #endif
214 
215 #define logger_print hooks->logger_print
216 #define max_time *hooks->max_time
217 
218 extern PyObject *AtrinikError;
219 
221 #define RAISE(msg) \
222  { \
223  PyErr_SetString(AtrinikError, (msg)); \
224  return NULL; \
225  }
226 
227 #define INTRAISE(msg) \
228  { \
229  PyErr_SetString(PyExc_TypeError, (msg)); \
230  return -1; \
231  }
232 
234 typedef struct _pythoncontext {
237 
239  object *activator;
240 
242  object *who;
243 
245  object *other;
246 
248  object *event;
249 
251  const char *text;
252 
254  const char *options;
255 
258 
260  int parms[4];
261 } PythonContext;
262 
264 
266 typedef struct {
268  const char *name;
269 
271  const long value;
273 
275 typedef enum {
343 } field_type;
344 
350 #define FIELDFLAG_READONLY 1
351 
352 #define FIELDFLAG_PLAYER_READONLY 2
353 
354 #define FIELDFLAG_PLAYER_FIX 4
355 
357 PyTypeObject Atrinik_ObjectType;
358 PyObject *wrap_object(object *what);
359 PyTypeObject Atrinik_ObjectIteratorType;
360 PyObject *wrap_object_iterator(object *what);
361 int Atrinik_Object_init(PyObject *module);
362 
368 #define OBJ_ITER_TYPE_NONE 0
369 
370 #define OBJ_ITER_TYPE_BELOW 1
371 
372 #define OBJ_ITER_TYPE_ABOVE 2
373 
374 #define OBJ_ITER_TYPE_ONE 3
375 
378 typedef struct Atrinik_Object {
379  PyObject_HEAD
380 
382  object *obj;
383 
385  tag_t count;
387 
389 typedef struct Atrinik_ObjectIterator {
390  PyObject_HEAD
391 
393  object *obj;
394 
396  tag_t count;
397 
399  uint8_t iter_type:7;
400 
402  uint8_t iterated:1;
404 
405 PyTypeObject Atrinik_MapType;
406 PyObject *wrap_map(mapstruct *map);
407 int Atrinik_Map_init(PyObject *module);
408 
410 typedef struct {
411  PyObject_HEAD
414 } Atrinik_Map;
415 
416 PyTypeObject Atrinik_PartyType;
417 PyObject *wrap_party(party_struct *party);
418 int Atrinik_Party_init(PyObject *module);
419 
421 typedef struct {
422  PyObject_HEAD
425 } Atrinik_Party;
426 
427 PyTypeObject Atrinik_RegionType;
428 PyObject *wrap_region(region_struct *region);
429 int Atrinik_Region_init(PyObject *module);
430 
432 typedef struct {
433  PyObject_HEAD
437 
438 PyTypeObject Atrinik_PlayerType;
439 PyObject *wrap_player(player *pl);
440 int Atrinik_Player_init(PyObject *module);
441 
443 typedef struct {
444  PyObject_HEAD
448 
449 PyTypeObject Atrinik_ArchetypeType;
450 PyObject *wrap_archetype(archetype_t *at);
451 int Atrinik_Archetype_init(PyObject *module);
452 
454 typedef struct {
455  PyObject_HEAD
459 
460 PyTypeObject Atrinik_AttrListType;
461 PyObject *wrap_attr_list(void *ptr, size_t offset, field_type field);
462 int Atrinik_AttrList_init(PyObject *module);
463 
465 typedef struct {
466  PyObject_HEAD
467 
469  void *ptr;
470 
472  size_t offset;
473 
479 
481  union {
482  void *ptr;
483  PY_LONG_LONG idx;
484  } iter;
486 
488 typedef struct python_cache_entry {
490  char *file;
491 
493  PyCodeObject *code;
494 
496  time_t cached_time;
497 
499  UT_hash_handle hh;
501 
505 typedef struct {
509  char *name;
510 
515 
519  size_t offset;
520 
524  uint32_t flags;
525 
529  uint32_t extra_data;
530 
534  char *doc;
535 } fields_struct;
536 
542 #define NUM_FIELDS (sizeof(fields) / sizeof(fields[0]))
543 
544 #define OBJEXISTCHECK_INT(ob) \
545  { \
546  if (!(ob) || !(ob)->obj || (ob)->obj->count != (ob)->count || OBJECT_FREE((ob)->obj)) \
547  { \
548  PyErr_SetString(PyExc_ReferenceError, "Atrinik object no longer exists."); \
549  return -1; \
550  } \
551  }
552 
553 #define OBJEXISTCHECK(ob) \
554  { \
555  if (!(ob) || !(ob)->obj || (ob)->obj->count != (ob)->count || OBJECT_FREE((ob)->obj)) \
556  { \
557  PyErr_SetString(PyExc_ReferenceError, "Atrinik object no longer exists."); \
558  return NULL; \
559  } \
560  }
561 
565 #define SQUARES_AROUND_ADD(_m, _x, _y) \
566  { \
567  PyObject *tuple = PyTuple_New(3); \
568 \
569  PyTuple_SET_ITEM(tuple, 0, wrap_map((_m))); \
570  PyTuple_SET_ITEM(tuple, 1, Py_BuildValue("i", (_x))); \
571  PyTuple_SET_ITEM(tuple, 2, Py_BuildValue("i", (_y))); \
572  PyList_Append(list, tuple); \
573  }
574 
579 #define Py_BuildBoolean(val) \
580  ((val) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
581 
582 
586 #define FOR_ATRINIK_ITERATOR_BEGIN() \
587  for (object *tmp = self->obj; tmp != NULL; ) {
588 
592 #define FOR_ATRINIK_ITERATOR_END() \
593  if (self->iter_type == OBJ_ITER_TYPE_BELOW) { \
594  tmp = tmp->below; \
595  } else if (self->iter_type == OBJ_ITER_TYPE_ABOVE) { \
596  tmp = tmp->above; \
597  } else { \
598  break; \
599  } \
600  }
601 
602 #define PY_CHECK_INT(val, min, max) \
603  if (val < min || val > max) { \
604  PyErr_Format(PyExc_OverflowError, \
605  "Invalid integer value for parameter '"STRINGIFY(val)"': " \
606  "%zd, must be %zd to %zd.", (Py_ssize_t) val, \
607  (Py_ssize_t) min, (Py_ssize_t) max); \
608  return NULL; \
609  }
610 
611 int generic_field_setter(fields_struct *field, void *ptr, PyObject *value);
612 PyObject *generic_field_getter(fields_struct *field, void *ptr);
613 PyObject *generic_rich_compare(int op, int result);
614 int python_call_int(PyObject *callable, PyObject *arglist);
615 
616 #endif
PyTypeObject Atrinik_PlayerType
PyObject * wrap_attr_list(void *ptr, size_t offset, field_type field)
Definition: attr_list.c:810
PyTypeObject Atrinik_ObjectType
struct Atrinik_Object Atrinik_Object
struct plugin_hooklist * hooks
Definition: plugin_arena.c:160
int Atrinik_Player_init(PyObject *module)
int Atrinik_Party_init(PyObject *module)
const char * text
uint32_t flags
const char * name
field_type field
int Atrinik_Archetype_init(PyObject *module)
int generic_field_setter(fields_struct *field, void *ptr, PyObject *value)
PyTypeObject Atrinik_ObjectIteratorType
PyObject * generic_rich_compare(int op, int result)
PyObject_HEAD archetype_t * at
PyObject * wrap_archetype(archetype_t *at)
UT_hash_handle hh
PyTypeObject Atrinik_ArchetypeType
int python_call_int(PyObject *callable, PyObject *arglist)
PyObject * wrap_object_iterator(object *what)
PyObject_HEAD object * obj
struct python_cache_entry python_cache_entry
PyCodeObject * code
int Atrinik_AttrList_init(PyObject *module)
Definition: attr_list.c:784
PyObject * AtrinikError
Definition: plugin_python.c:55
Definition: arch.h:40
uint32_t extra_data
PY_LONG_LONG idx
Index.
struct Atrinik_ObjectIterator Atrinik_ObjectIterator
PyObject_HEAD void * ptr
field_type type
PyObject * wrap_party(party_struct *party)
const char * options
int Atrinik_Region_init(PyObject *module)
char * file
field_type
static PyObject * iter(PyObject *seq)
Definition: attr_list.c:626
int Atrinik_Object_init(PyObject *module)
PyTypeObject Atrinik_PartyType
PyObject_HEAD mapstruct * map
PyObject_HEAD player * pl
PyObject * wrap_region(region_struct *region)
PyTypeObject Atrinik_RegionType
void * ptr
Pointer.
PyObject * generic_field_getter(fields_struct *field, void *ptr)
PyObject_HEAD party_struct * party
time_t cached_time
PyTypeObject Atrinik_AttrListType
Definition: attr_list.c:737
PyObject * wrap_player(player *pl)
const long value
int Atrinik_Map_init(PyObject *module)
Definition: atrinik_map.c:1086
struct _pythoncontext * down
struct _pythoncontext PythonContext
PyTypeObject Atrinik_MapType
Definition: atrinik_map.c:1040
PyObject_HEAD region_struct * region
Definition: map.h:536
PyObject * wrap_map(mapstruct *map)
Definition: atrinik_map.c:1139
PyObject_HEAD object * obj
PythonContext * current_context
Definition: plugin_python.c:60
PyObject * wrap_object(object *what)
object * activator