Go to the documentation of this file.
72 #define PYTHON_CACHE_SIZE 256
77 struct pycode_cache_entry {
84 #define MAX_COMMANDS 1024
98 vsnprintf(
buf,
sizeof(
buf), fmt, arg);
101 PyErr_SetString(PyExc_ValueError,
buf);
120 if (!PyArg_ParseTuple(
args,
"i", &eventcode))
133 if (!PyArg_ParseTuple(
args,
"i", &eventcode))
157 if (!PyArg_ParseTuple(
args,
"s", &obname))
170 return Py_BuildValue(
"i", i);
183 if (!PyArg_ParseTuple(
args,
"i", &i))
196 if (!PyArg_ParseTuple(
args,
"ss", &premiere, &seconde))
201 return Py_BuildValue(
"i", 1);
203 return Py_BuildValue(
"i", 0);
211 if (!PyArg_ParseTuple(
args,
"s", &txt))
243 if (!PyArg_ParseTuple(
args,
"ii", &sizex, &sizey))
330 return Py_BuildValue(
"");
386 std::vector<archetype *> archs;
391 list = PyList_New(0);
392 for (
auto arch : archs) {
406 list = PyList_New(0);
415 std::vector<mapstruct *>
maps;
421 list = PyList_New(0);
430 std::vector<partylist *> parties;
435 list = PyList_New(0);
436 for (
auto party : parties) {
449 list = PyList_New(0);
463 list = PyList_New(0);
481 context->
third = NULL;
483 context->
event = NULL;
507 if (!PyArg_ParseTuple(
args,
"ssd|i", &cmdname, &scriptname, &cmdspeed, &
type))
532 set_exception(
"failed to register command (overriding an existing one with a different type?)");
548 list = PyList_New(0);
549 PyList_Append(
list, Py_BuildValue(
"i", tod.
year));
550 PyList_Append(
list, Py_BuildValue(
"i", tod.
month));
551 PyList_Append(
list, Py_BuildValue(
"i", tod.
day));
552 PyList_Append(
list, Py_BuildValue(
"i", tod.
hour));
553 PyList_Append(
list, Py_BuildValue(
"i", tod.
minute));
556 PyList_Append(
list, Py_BuildValue(
"i", tod.
season));
566 if (!PyArg_ParseTuple(
args,
"i", &
id))
575 if (!PyArg_ParseTuple(
args,
"s", &
name))
584 if (!PyArg_ParseTuple(
args,
"s", &
name))
595 if (!PyArg_ParseTuple(
args,
"is", &intLevel, &
message))
630 if (!PyArg_ParseTuple(
args,
"s", &
name))
639 if (!PyArg_ParseTuple(
args,
"i", &i))
648 if (!PyArg_ParseTuple(
args,
"i", &i))
657 if (!PyArg_ParseTuple(
args,
"i", &i))
666 if (!PyArg_ParseTuple(
args,
"i", &i))
682 if (!PyArg_ParseTuple(
args,
"ss", &word, &
reply)) {
741 cf_log(
llevError,
"CFPython: warning, too long message in npcSay, will be truncated");
755 int largest_coin = 0;
758 if (!PyArg_ParseTuple(
args,
"L|i", &
value, &largest_coin))
762 return Py_BuildValue(
"s",
buf);
766 {
"WhoAmI",
getWhoAmI, METH_NOARGS, NULL },
772 {
"WhatIsEvent",
getEvent, METH_NOARGS, NULL },
780 {
"ReadyMap",
readyMap, METH_VARARGS, NULL },
781 {
"CreateMap",
createMap, METH_VARARGS, NULL },
782 {
"FindPlayer",
findPlayer, METH_VARARGS, NULL },
783 {
"MatchString",
matchString, METH_VARARGS, NULL },
791 {
"GetPlayers",
getPlayers, METH_NOARGS, NULL },
793 {
"GetMaps",
getMaps, METH_NOARGS, NULL },
794 {
"GetParties",
getParties, METH_NOARGS, NULL },
795 {
"GetRegions",
getRegions, METH_NOARGS, NULL },
800 {
"GetTime",
getTime, METH_NOARGS, NULL },
804 {
"FindFace",
findFace, METH_VARARGS, NULL },
810 {
"AddReply",
addReply, METH_VARARGS, NULL },
812 {
"NPCSay",
npcSay, METH_VARARGS, NULL },
814 { NULL, NULL, 0, NULL }
825 context->
down = NULL;
845 Py_XDECREF(context->
event);
846 Py_XDECREF(context->
third);
847 Py_XDECREF(context->
who);
856 PyObject *scriptfile;
861 scriptfile = PyFile_FromFd(fd,
filename,
"r", -1, NULL, NULL, NULL, 1);
870 return fdopen(PyObject_AsFileDescriptor(
obj),
"r");
879 #if defined(IS_PY3K9) || defined(IS_PY3K10)
884 static PyObject *io_module = NULL;
898 PyObject *output = PyObject_GetAttrString(
catcher,
"value");
899 PyObject*
empty = PyUnicode_FromString(
"");
914 PyObject *scriptfile = NULL;
916 struct stat stat_buf;
959 if (
replace->file != sh_path) {
965 #if defined (IS_PY3K9) || defined(IS_PY3K10)
977 io_module = PyImport_ImportModule(
"io");
978 scriptfile = PyObject_CallMethod(io_module,
"open",
"ss",
filename,
"rb");
984 PyObject *source_bytes = PyObject_CallMethod(scriptfile,
"read",
"");
985 (
void)PyObject_CallMethod(scriptfile,
"close",
"");
986 PyObject *code = Py_CompileString(PyBytes_AsString(source_bytes),
filename, Py_file_input);
988 replace->code = (PyCodeObject *)code;
990 if (PyErr_Occurred())
993 replace->cached_time = stat_buf.st_mtime;
1008 if ((n = PyParser_SimpleParseFile(pyfile,
filename, Py_file_input))) {
1012 if (PyErr_Occurred())
1015 replace->cached_time = stat_buf.st_mtime;
1024 Py_DECREF(scriptfile);
1027 assert(run != NULL);
1028 run->used_time = time(NULL);
1033 PyCodeObject *pycode;
1044 dict = PyDict_New();
1045 PyDict_SetItemString(
dict,
"__builtins__", PyEval_GetBuiltins());
1046 ret = PyEval_EvalCode((PyObject *)pycode,
dict, NULL);
1047 if (PyErr_Occurred()) {
1070 snprintf(
tmp,
sizeof(
tmp),
"Crossfire_%s",
name);
1072 cst = PyModule_New(
tmp);
1073 dict = PyDict_New();
1075 while (constants[i].
name != NULL) {
1076 PyModule_AddIntConstant(cst, (
char *)constants[i].
name, constants[i].
value);
1077 PyDict_SetItem(
dict, PyLong_FromLong(constants[i].
value), PyUnicode_FromString(constants[i].
name));
1080 PyDict_SetItemString(PyModule_GetDict(module),
name, cst);
1083 PyDict_SetItemString(PyModule_GetDict(module),
tmp,
dict);
1101 snprintf(
tmp,
sizeof(
tmp),
"Crossfire_%s",
name);
1103 cst = PyModule_New(
tmp);
1105 while (constants[i].
name != NULL) {
1106 PyModule_AddIntConstant(cst, (
char *)constants[i].
name, constants[i].
value);
1109 PyDict_SetItemString(PyModule_GetDict(module),
name, cst);
1433 PyObject *d = PyModule_GetDict(
m);
1462 PyModule_AddObject(
m,
"LogError", Py_BuildValue(
"i",
llevError));
1463 PyModule_AddObject(
m,
"LogInfo", Py_BuildValue(
"i",
llevInfo));
1464 PyModule_AddObject(
m,
"LogDebug", Py_BuildValue(
"i",
llevDebug));
1465 PyModule_AddObject(
m,
"LogMonster", Py_BuildValue(
"i",
llevMonster));
1467 CFPythonError = PyErr_NewException(
"Crossfire.error", NULL, NULL);
1474 PyModuleDef_HEAD_INIT,
1496 const char *stdOutErr =
1498 class CatchOutErr:\n\
1499 def __init__(self):\n\
1501 def write(self, txt):\n\
1502 self.value += txt\n\
1503 catchOutErr = CatchOutErr()\n\
1504 sys.stdout = catchOutErr\n\
1505 sys.stderr = catchOutErr\n\
1521 m = PyImport_ImportModule(
"Crossfire");
1531 m = PyImport_AddModule(
"__main__");
1532 PyRun_SimpleString(stdOutErr);
1533 catcher = PyObject_GetAttrString(
m,
"catchOutErr");
1539 const char *propname;
1544 propname = va_arg(
args,
const char *);
1545 if (!strcmp(propname,
"Identification")) {
1547 size = va_arg(
args,
int);
1551 }
else if (!strcmp(propname,
"FullName")) {
1553 size = va_arg(
args,
int);
1611 for (
int e = 0; eventFiles[e] != NULL; e++) {
1612 free(eventFiles[e]);
1623 char **eventFiles = NULL;
1626 int allocated = 0,
current = 0;
1636 eventFiles =
static_cast<char **
>(calloc(1,
sizeof(eventFiles[0])));
1637 eventFiles[0] = NULL;
1641 while ((d =
readdir(dp)) != NULL) {
1644 if (S_ISDIR(sb.st_mode)) {
1647 if (strcmp(d->d_name + strlen(d->d_name) - 3,
".py")) {
1653 eventFiles =
static_cast<char **
>(realloc(eventFiles,
sizeof(
char *) * (allocated + 1)));
1654 for (
int i =
current; i < allocated + 1; i++) {
1655 eventFiles[i] = NULL;
1666 PyObject *scriptfile;
1672 for (i = 0;
GECodes[i] != 0; i++)
1676 if (scriptfile != NULL) {
1679 Py_DECREF(scriptfile);
1693 for (
int i = 0;
GECodes[i] != 0; i++) {
1722 op = va_arg(
args,
object *);
1727 op = va_arg(
args,
object *);
1729 op = va_arg(
args,
object *);
1735 op = va_arg(
args,
object *);
1759 op = va_arg(
args,
object *);
1764 op = va_arg(
args,
object *);
1772 op = va_arg(
args,
object *);
1780 op = va_arg(
args,
object *);
1788 op = va_arg(
args,
object *);
1794 op = va_arg(
args,
object *);
1807 op = va_arg(
args,
object *);
1812 op = va_arg(
args,
object *);
1839 (*copy) = (*context);
1841 Py_XINCREF(copy->
event);
1842 Py_XINCREF(copy->
third);
1843 Py_XINCREF(copy->
who);
1888 event = va_arg(
args,
object *);
void cf_cost_string_from_value(uint64_t cost, int largest_coin, char *buffer, int length)
static PyObject * findPlayer(PyObject *self, PyObject *args)
static PyObject * getMonthName(PyObject *self, PyObject *args)
void cf_log(LogLevel logLevel, const char *format,...)
const CFConstant cstMove[]
#define ATNR_CANCELLATION
static PyObject * getCFPythonVersion(PyObject *self, PyObject *args)
static PyObject * shared_data
const char * cf_get_weekday_name(int index)
sstring cf_add_string(const char *str)
sstring replies[MAX_REPLIES]
static PyObject * getSeasonName(PyObject *self, PyObject *args)
const char * cf_get_directory(int id)
static PyObject * getLocalDirectory(PyObject *self, PyObject *args)
static std::unordered_map< std::string, mapzone * > maps
const char * cf_get_season_name(int index)
sstring replies_words[MAX_REPLIES]
static PyCodeObject * compilePython(char *filename)
arch
DIALOGCHECK MINARGS 1 MAXARGS 1
static event_registration c
CF_PLUGIN int postInitPlugin(void)
CF_PLUGIN int eventListener(int *type,...)
object * cf_create_object_by_name(const char *name)
static PyObject * setPlayerMessage(PyObject *self, PyObject *args)
static PyObject * CFPythonError
static CFPContext * popContext(void)
static PyObject * getPrivateDictionary(PyObject *self, PyObject *args)
int cf_timer_destroy(int id)
#define CFAPI_SYSTEM_ARCHETYPES
static PyObject * getConfigDirectory(PyObject *self, PyObject *args)
int initPlugin(const char *iversion, f_plug_api gethooksptr)
PyObject * Crossfire_Party_wrap(partylist *what)
static const flag_definition flags[]
static PyObject * createCFObject(PyObject *self, PyObject *args)
static PyObject * registerCommand(PyObject *self, PyObject *args)
static pycode_cache_entry pycode_cache[PYTHON_CACHE_SIZE]
static void pushContext(CFPContext *context)
#define COMMAND_TYPE_NORMAL
#define CFAPI_SYSTEM_PLAYERS
static char ** getEventFiles(CFPContext *context)
static std::vector< std::pair< object *, tag_t > > friends
void Handle_Map_Unload_Hook(Crossfire_Map *map)
CFPContext * current_context
PyObject * Crossfire_Object_wrap(object *what)
const CFConstant cstMessageFlag[]
void cf_system_get_region_vector(int property, std::vector< region * > *list)
static PyObject * getDataDirectory(PyObject *self, PyObject *args)
PyTypeObject Crossfire_PlayerType
static event_registration m
CF_PLUGIN void * getPluginProperty(int *type,...)
DIR * opendir(const char *)
static PyObject * setReturnValue(PyObject *self, PyObject *args)
void cf_log_plain(LogLevel logLevel, const char *message)
static PyObject * getArchetypes(PyObject *self, PyObject *args)
static PyObject * getMapHasBeenLoaded(PyObject *self, PyObject *args)
static const char * GEPaths[]
static PyObject * getMapDirectory(PyObject *self, PyObject *args)
int cf_find_face(const char *name, int error)
static PyObject * findFace(PyObject *self, PyObject *args)
void(* f_plug_api)(int *type,...)
const CFConstant cstDirection[]
static PyObject * npcSay(PyObject *self, PyObject *args)
void cf_system_unregister_global_event(int event, const char *name)
const char * cf_get_month_name(int index)
int cf_init_plugin(f_plug_api getHooks)
struct dirent * readdir(DIR *)
mapstruct * cf_get_empty_map(int sizex, int sizey)
static PyObject * unregisterGEvent(PyObject *self, PyObject *args)
static void addSimpleConstants(PyObject *module, const char *name, const CFConstant *constants)
static PyObject * costStringFromValue(PyObject *self, PyObject *args)
CF_PLUGIN char SvnRevPlugin[]
static int do_script(CFPContext *context)
static PyObject * getSharedDictionary(PyObject *self, PyObject *args)
static PyObject * createMap(PyObject *self, PyObject *args)
static void set_exception(const char *fmt,...)
static PyObject * catcher
PyObject * Crossfire_Archetype_wrap(archetype *what)
static PyObject * getFriendlyList(PyObject *self, PyObject *args)
static command_registration registered_commands[MAX_COMMANDS]
#define ATNR_COUNTERSPELL
CF_PLUGIN int closePlugin(void)
static PyObject * getPlayers(PyObject *self, PyObject *args)
#define CFAPI_SYSTEM_MAPS
PyObject * Crossfire_Region_wrap(region *what)
#define CFAPI_SYSTEM_REGIONS
static PyObject * getUniqueDirectory(PyObject *self, PyObject *args)
static PyObject * matchString(PyObject *self, PyObject *args)
void cf_free_string(sstring str)
const CFConstant cstTime[]
#define COMMAND_TYPE_WIZARD
static PyObject * destroyTimer(PyObject *self, PyObject *args)
#define EVENT_PLAYER_DEATH
static FILE * cfpython_pyfile_asfile(PyObject *obj)
const CFConstant cstType[]
command_registration cf_system_register_command_extra(const char *name, const char *extra, command_function_extra func, uint8_t command_type, float time)
static PyObject * getPlayerDirectory(PyObject *self, PyObject *args)
static PyObject * getWeekdayName(PyObject *self, PyObject *args)
static PyObject * getMaps(PyObject *self, PyObject *args)
const CFConstant cstReplyTypes[]
void cf_system_get_object_vector(int property, std::vector< object * > *list)
void replace(const char *src, const char *key, const char *replacement, char *result, size_t resultsize)
void cf_system_register_global_event(int event, const char *name, f_plug_event hook)
static PyObject * cfpython_openpyfile(char *filename)
static PyObject * getTempDirectory(PyObject *self, PyObject *args)
int cf_find_animation(const char *txt)
static PyObject * getReturnValue(PyObject *self, PyObject *args)
PyMethodDef CFPythonMethods[]
PyTypeObject Crossfire_PartyType
#define CFAPI_SYSTEM_FRIENDLY_LIST
std::vector< archetype * > players
const char * cf_get_periodofday_name(int index)
static PyObject * getWhatIsMessage(PyObject *self, PyObject *args)
static PyObject * getScriptName(PyObject *self, PyObject *args)
static PyModuleDef CrossfireModule
static void python_command_function(object *op, const char *params, const char *script)
static const char * getGlobalEventPath(int code)
void cf_system_get_map_vector(int property, std::vector< mapstruct * > *list)
static PyObject * createCFObjectByName(PyObject *self, PyObject *args)
const CFConstant cstAttackType[]
const typedef char * sstring
const CFConstant cstAttackTypeNumber[]
PyTypeObject Crossfire_ArchetypeType
mapstruct * cf_map_has_been_loaded(const char *name)
const char * cf_re_cmp(const char *str, const char *regexp)
static PyObject * getRegions(PyObject *self, PyObject *args)
static PyObject * readyMap(PyObject *self, PyObject *args)
static PyObject * getParties(PyObject *self, PyObject *args)
object * cf_create_object(void)
char * cf_get_maps_directory(const char *name, char *buf, int size)
static void freeEventFiles(char **eventFiles)
static void cfpython_init_types(PyObject *m)
static std::unordered_map< std::string, Region * > regions
static PyObject * addReply(PyObject *self, PyObject *args)
static void initConstants(PyObject *module)
static PyObject * getWhoIsThird(PyObject *self, PyObject *args)
static PyObject * getScriptParameters(PyObject *self, PyObject *args)
sstring npc_msgs[MAX_NPC]
PyTypeObject Crossfire_RegionType
void cf_system_get_archetype_vector(int property, std::vector< archetype * > *list)
player * cf_player_find(const char *plname)
void cf_system_unregister_command(command_registration command)
#define PYTHON_CACHE_SIZE
#define CFAPI_SYSTEM_PARTIES
CFPContext * context_stack
event
DIALOGCHECK MINARGS 1 MAXARGS 2
uint64_t command_registration
mapstruct * cf_map_get_map(const char *name, int flags)
void cf_system_get_party_vector(int property, std::vector< partylist * > *list)
static PyObject * registerGEvent(PyObject *self, PyObject *args)
const CFConstant cstAttackMovement[]
static PyObject * log_message(PyObject *self, PyObject *args)
static PyObject * getWhoAmI(PyObject *self, PyObject *args)
static void log_python_error(void)
static PyObject * getTime(PyObject *self, PyObject *args)
static void addConstants(PyObject *module, const char *name, const CFConstant *constants)
PyObject * Crossfire_Map_wrap(mapstruct *what)
static PyObject * private_data
#define ATNR_LIFE_STEALING
PyTypeObject Crossfire_ObjectType
static PyObject * getPeriodofdayName(PyObject *self, PyObject *args)
const CFConstant cstEventType[]
PyObject * PyInit_cjson(void)
CF_PLUGIN int cfpython_globalEventListener(int *type,...)
static PyObject * getWhoIsActivator(PyObject *self, PyObject *args)
static PyObject * PyInit_Crossfire(void)
static void initContextStack(void)
void cf_get_time(timeofday_t *tod)
static PyObject * findAnimation(PyObject *self, PyObject *args)
static PyObject * getEvent(PyObject *self, PyObject *args)
static void freeContext(CFPContext *context)
PyTypeObject Crossfire_MapType