Atrinik Server 2.5
plugins/plugin_python/include/plugin_python.h
Go to the documentation of this file.
00001 /************************************************************************
00002 *            Atrinik, a Multiplayer Online Role Playing Game            *
00003 *                                                                       *
00004 *    Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team    *
00005 *                                                                       *
00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game)     *
00007 * and Crossfire (Multiplayer game for X-windows).                       *
00008 *                                                                       *
00009 * This program is free software; you can redistribute it and/or modify  *
00010 * it under the terms of the GNU General Public License as published by  *
00011 * the Free Software Foundation; either version 2 of the License, or     *
00012 * (at your option) any later version.                                   *
00013 *                                                                       *
00014 * This program is distributed in the hope that it will be useful,       *
00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00017 * GNU General Public License for more details.                          *
00018 *                                                                       *
00019 * You should have received a copy of the GNU General Public License     *
00020 * along with this program; if not, write to the Free Software           *
00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.             *
00022 *                                                                       *
00023 * The author can be reached at admin@atrinik.org                        *
00024 ************************************************************************/
00025 
00030 #ifndef PLUGIN_PYTHON_H
00031 #define PLUGIN_PYTHON_H
00032 
00033 #include <Python.h>
00034 #include <plugin.h>
00035 #include <timers.h>
00036 
00038 #if PY_MAJOR_VERSION >= 3
00039 #   define IS_PY3K
00040 #else
00041 #   if PY_MINOR_VERSION >= 6
00042 #       define IS_PY26
00043 #   else
00044 #       define IS_PY_LEGACY
00045 #   endif
00046 #   if PY_MINOR_VERSION >= 5
00047 #       define IS_PY25
00048 #   endif
00049 #endif
00050 
00051 /* Fake some Python 2.x functions for Python 3.x. */
00052 #ifdef IS_PY3K
00053 #   define PyString_Check PyUnicode_Check
00054 #   define PyString_AsString _PyUnicode_AsString
00055 #   define PyInt_Check PyLong_Check
00056 #   define PyInt_AsLong PyLong_AsLong
00057     extern PyTypeObject PyIOBase_Type;
00058 #   define PyFile_Check(op) (PyObject_IsInstance((op), (PyObject *) &PyIOBase_Type))
00059 #   define PyString_FromFormat PyUnicode_FromFormat
00060 #else
00061 #   define PyObject_AsFileDescriptor(op) (PyFile_AsFile((op)) ? PyFile_AsFile((op))->fd : -1)
00062 #endif
00063 
00065 #define PLUGIN_NAME "Python"
00066 
00067 #define PLUGIN_VERSION "Atrinik Python Plugin 1.0"
00068 
00069 extern struct plugin_hooklist *hooks;
00070 
00077 #define AROUND_ALL 0
00078 
00079 #define AROUND_WALL 1
00080 
00081 #define AROUND_BLOCKSVIEW 2
00082 
00083 #define AROUND_PLAYER_ONLY 4
00084 
00091 #define INVENTORY_ONLY 0
00092 
00095 #define INVENTORY_CONTAINERS 1
00096 
00099 #define INVENTORY_ALL 2
00100 
00102 #undef LOG
00103 
00104 #define LOG hooks->LOG
00105 
00106 #undef FREE_AND_COPY_HASH
00107 #undef FREE_AND_CLEAR_HASH
00108 
00113 #define FREE_AND_COPY_HASH(_sv_, _nv_)   \
00114 {                                        \
00115     if (_sv_)                            \
00116     {                                    \
00117         hooks->free_string_shared(_sv_); \
00118     }                                    \
00119                                          \
00120     _sv_ = hooks->add_string(_nv_);      \
00121 }
00122 
00126 #define FREE_AND_CLEAR_HASH(_nv_)        \
00127 {                                        \
00128     if (_nv_)                            \
00129     {                                    \
00130         hooks->free_string_shared(_nv_); \
00131         _nv_ = NULL;                     \
00132     }                                    \
00133 }
00134 
00135 #undef SET_ANIMATION
00136 #define SET_ANIMATION(ob, newanim) ob->face = &(*hooks->new_faces)[(*hooks->animations)[ob->animation_id].faces[newanim]]
00137 #undef NUM_ANIMATIONS
00138 #define NUM_ANIMATIONS(ob) ((*hooks->animations)[ob->animation_id].num_animations)
00139 #undef NUM_FACINGS
00140 #define NUM_FACINGS(ob) ((*hooks->animations)[ob->animation_id].facings)
00141 
00142 extern PyObject *AtrinikError;
00143 
00145 #define RAISE(msg)                        \
00146 {                                         \
00147     PyErr_SetString(AtrinikError, (msg)); \
00148     return NULL;                          \
00149 }
00150 
00151 #define INTRAISE(msg)                        \
00152 {                                            \
00153     PyErr_SetString(PyExc_TypeError, (msg)); \
00154     return -1;                               \
00155 }
00156 
00158 typedef struct _pythoncontext
00159 {
00161     struct _pythoncontext *down;
00162 
00164     object *activator;
00165 
00167     object *who;
00168 
00170     object *other;
00171 
00173     object *event;
00174 
00176     char *text;
00177 
00179     char *options;
00180 
00182     int returnvalue;
00183 
00185     int parms[4];
00186 } PythonContext;
00187 
00188 extern PythonContext *current_context;
00189 
00191 typedef struct
00192 {
00194     const char *name;
00195 
00197     const long value;
00198 } Atrinik_Constant;
00199 
00201 typedef enum
00202 {
00204     FIELDTYPE_SHSTR,
00206     FIELDTYPE_CSTR,
00208     FIELDTYPE_CARY,
00210     FIELDTYPE_UINT8,
00212     FIELDTYPE_SINT8,
00214     FIELDTYPE_UINT16,
00216     FIELDTYPE_SINT16,
00218     FIELDTYPE_UINT32,
00220     FIELDTYPE_SINT32,
00222     FIELDTYPE_UINT64,
00224     FIELDTYPE_SINT64,
00226     FIELDTYPE_FLOAT,
00228     FIELDTYPE_OBJECT,
00230     FIELDTYPE_OBJECT2,
00232     FIELDTYPE_MAP,
00234     FIELDTYPE_OBJECTREF,
00236     FIELDTYPE_REGION,
00238     FIELDTYPE_PARTY,
00240     FIELDTYPE_ARCH,
00242     FIELDTYPE_PLAYER,
00244     FIELDTYPE_FACE,
00248     FIELDTYPE_ANIMATION,
00250     FIELDTYPE_BOOLEAN,
00252     FIELDTYPE_LIST,
00254     FIELDTYPE_KNOWN_SPELLS,
00256     FIELDTYPE_CMD_PERMISSIONS,
00258     FIELDTYPE_FACTIONS
00259 } field_type;
00260 
00266 #define FIELDFLAG_READONLY 1
00267 
00268 #define FIELDFLAG_PLAYER_READONLY 2
00269 
00270 #define FIELDFLAG_PLAYER_FIX 4
00271 
00273 PyTypeObject Atrinik_ObjectType;
00274 PyObject *wrap_object(object *what);
00275 int Atrinik_Object_init(PyObject *module);
00276 
00282 #define OBJ_ITER_TYPE_NONE 0
00283 
00284 #define OBJ_ITER_TYPE_BELOW 1
00285 
00286 #define OBJ_ITER_TYPE_ABOVE 2
00287 
00288 #define OBJ_ITER_TYPE_ONE 3
00289 
00292 typedef struct Atrinik_Object
00293 {
00294     PyObject_HEAD
00295 
00297     object *obj;
00298 
00300     struct Atrinik_Object *iter;
00301 
00303     uint8 iter_type;
00304 
00306     tag_t count;
00307 } Atrinik_Object;
00308 
00309 PyTypeObject Atrinik_MapType;
00310 PyObject *wrap_map(mapstruct *map);
00311 int Atrinik_Map_init(PyObject *module);
00312 
00314 typedef struct
00315 {
00316     PyObject_HEAD
00318     mapstruct *map;
00319 } Atrinik_Map;
00320 
00321 PyTypeObject Atrinik_PartyType;
00322 PyObject *wrap_party(party_struct *party);
00323 int Atrinik_Party_init(PyObject *module);
00324 
00326 typedef struct
00327 {
00328     PyObject_HEAD
00330     party_struct *party;
00331 } Atrinik_Party;
00332 
00333 PyTypeObject Atrinik_RegionType;
00334 PyObject *wrap_region(region *region);
00335 int Atrinik_Region_init(PyObject *module);
00336 
00338 typedef struct
00339 {
00340     PyObject_HEAD
00342     region *region;
00343 } Atrinik_Region;
00344 
00345 PyTypeObject Atrinik_PlayerType;
00346 PyObject *wrap_player(player *pl);
00347 int Atrinik_Player_init(PyObject *module);
00348 
00350 typedef struct
00351 {
00352     PyObject_HEAD
00354     player *pl;
00355 } Atrinik_Player;
00356 
00357 PyTypeObject Atrinik_ArchetypeType;
00358 PyObject *wrap_archetype(archetype *at);
00359 int Atrinik_Archetype_init(PyObject *module);
00360 
00362 typedef struct
00363 {
00364     PyObject_HEAD
00366     archetype *at;
00367 } Atrinik_Archetype;
00368 
00369 PyTypeObject Atrinik_AttrListType;
00370 PyObject *wrap_attr_list(void *ptr, size_t offset, field_type field);
00371 int Atrinik_AttrList_init(PyObject *module);
00372 
00374 typedef struct
00375 {
00376     PyObject_HEAD
00377 
00379     void *ptr;
00380 
00382     size_t offset;
00383 
00387     field_type field;
00388 
00390     unsigned PY_LONG_LONG iter;
00391 } Atrinik_AttrList;
00392 
00394 typedef struct PythonCmdStruct
00395 {
00397     char *name;
00398 
00400     char *script;
00401 
00403     double speed;
00404 } PythonCmd;
00405 
00408 typedef struct
00409 {
00412     char *name;
00413 
00416     field_type type;
00417 
00420     size_t offset;
00421 
00424     uint32 flags;
00425 
00428     uint32 extra_data;
00429 } fields_struct;
00430 
00434 #define NUM_FIELDS (sizeof(fields) / sizeof(fields[0]))
00435 
00437 #define NR_CUSTOM_CMD 1024
00438 
00439 #define OBJEXISTCHECK_INT(ob) \
00440 { \
00441     if (!(ob) || !(ob)->obj || (ob)->obj->count != (ob)->count || OBJECT_FREE((ob)->obj)) \
00442     { \
00443         PyErr_SetString(PyExc_ReferenceError, "Atrinik object no longer exists."); \
00444         return -1; \
00445     } \
00446 }
00447 
00448 #define OBJEXISTCHECK(ob) \
00449 { \
00450     if (!(ob) || !(ob)->obj || (ob)->obj->count != (ob)->count || OBJECT_FREE((ob)->obj)) \
00451     { \
00452         PyErr_SetString(PyExc_ReferenceError, "Atrinik object no longer exists."); \
00453         return NULL; \
00454     } \
00455 }
00456 
00459 #define SQUARES_AROUND_ADD(_m, _x, _y) \
00460 { \
00461     PyObject *tuple = PyTuple_New(3); \
00462 \
00463     PyTuple_SET_ITEM(tuple, 0, wrap_map((_m))); \
00464     PyTuple_SET_ITEM(tuple, 1, Py_BuildValue("i", (_x))); \
00465     PyTuple_SET_ITEM(tuple, 2, Py_BuildValue("i", (_y))); \
00466     PyList_Append(list, tuple); \
00467 }
00468 
00472 #define Py_ReturnBoolean(val) \
00473 { \
00474     if ((val)) \
00475     { \
00476         Py_INCREF(Py_True); \
00477         return Py_True; \
00478     } \
00479     else \
00480     { \
00481         Py_INCREF(Py_False); \
00482         return Py_False; \
00483     } \
00484 }
00485 
00486 int generic_field_setter(fields_struct *field, void *ptr, PyObject *value);
00487 PyObject *generic_field_getter(fields_struct *field, void *ptr);
00488 PyObject *generic_rich_compare(int op, int result);
00489 int python_call_int(PyObject *callable, PyObject *arglist);
00490 
00491 #endif