00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 #include <cfpython.h>
00061 #include <stdarg.h>
00062 #include <node.h>
00063
00064 #define PYTHON_DEBUG
00065 #define PYTHON_CACHE_SIZE 16
00066
00067 typedef struct {
00068 sstring file;
00069 PyCodeObject *code;
00070 time_t cached_time, used_time;
00071 } pycode_cache_entry;
00072
00073 static PythonCmd CustomCommand[NR_CUSTOM_CMD];
00074
00075 static pycode_cache_entry pycode_cache[PYTHON_CACHE_SIZE];
00076
00077 static void set_exception(const char *fmt, ...);
00078 static PyObject *createCFObject(PyObject *self, PyObject *args);
00079 static PyObject *createCFObjectByName(PyObject *self, PyObject *args);
00080 static PyObject *getCFPythonVersion(PyObject *self, PyObject *args);
00081 static PyObject *getReturnValue(PyObject *self, PyObject *args);
00082 static PyObject *setReturnValue(PyObject *self, PyObject *args);
00083 static PyObject *matchString(PyObject *self, PyObject *args);
00084 static PyObject *findPlayer(PyObject *self, PyObject *args);
00085 static PyObject *readyMap(PyObject *self, PyObject *args);
00086 static PyObject *createMap(PyObject *self, PyObject *args);
00087 static PyObject *getMapDirectory(PyObject *self, PyObject *args);
00088 static PyObject *getUniqueDirectory(PyObject *self, PyObject *args);
00089 static PyObject *getTempDirectory(PyObject *self, PyObject *args);
00090 static PyObject *getConfigDirectory(PyObject *self, PyObject *args);
00091 static PyObject *getLocalDirectory(PyObject *self, PyObject *args);
00092 static PyObject *getPlayerDirectory(PyObject *self, PyObject *args);
00093 static PyObject *getDataDirectory(PyObject *self, PyObject *args);
00094 static PyObject *getWhoAmI(PyObject *self, PyObject *args);
00095 static PyObject *getWhoIsActivator(PyObject *self, PyObject *args);
00096 static PyObject *getWhoIsThird(PyObject *self, PyObject *args);
00097 static PyObject *getWhatIsMessage(PyObject *self, PyObject *args);
00098 static PyObject *getScriptName(PyObject *self, PyObject *args);
00099 static PyObject *getScriptParameters(PyObject *self, PyObject *args);
00100 static PyObject *getEvent(PyObject *self, PyObject *args);
00101 static PyObject *getPrivateDictionary(PyObject *self, PyObject *args);
00102 static PyObject *getSharedDictionary(PyObject *self, PyObject *args);
00103 static PyObject *getArchetypes(PyObject *self, PyObject *args);
00104 static PyObject *getPlayers(PyObject *self, PyObject *args);
00105 static PyObject *getMaps(PyObject *self, PyObject *args);
00106 static PyObject *getParties(PyObject *self, PyObject *args);
00107 static PyObject *getRegions(PyObject *self, PyObject *args);
00108 static PyObject *getFriendlyList(PyObject *self, PyObject *args);
00109 static PyObject *registerCommand(PyObject *self, PyObject *args);
00110 static PyObject *registerGEvent(PyObject *self, PyObject *args);
00111 static PyObject *unregisterGEvent(PyObject *self, PyObject *args);
00112 static PyObject *CFPythonError;
00113 static PyObject *getTime(PyObject *self, PyObject *args);
00114 static PyObject *destroyTimer(PyObject *self, PyObject *args);
00115 static PyObject *getMapHasBeenLoaded(PyObject *self, PyObject *args);
00116 static PyObject *findAnimation(PyObject *self, PyObject *args);
00117 static PyObject *log_message(PyObject *self, PyObject *args);
00118 static PyObject *findFace(PyObject *self, PyObject *args);
00119 static PyObject *getSeasonName(PyObject *self, PyObject *args);
00120 static PyObject *getMonthName(PyObject *self, PyObject *args);
00121 static PyObject *getWeekdayName(PyObject *self, PyObject *args);
00122 static PyObject *getPeriodofdayName(PyObject *self, PyObject *args);
00123
00125 static void set_exception(const char *fmt, ...) {
00126 char buf[1024];
00127 va_list arg;
00128
00129 va_start(arg, fmt);
00130 vsnprintf(buf, sizeof(buf), fmt, arg);
00131 va_end(arg);
00132
00133 PyErr_SetString(PyExc_ValueError, buf);
00134 }
00135
00136 static PyMethodDef CFPythonMethods[] = {
00137 { "WhoAmI", getWhoAmI, METH_NOARGS, NULL },
00138 { "WhoIsActivator", getWhoIsActivator, METH_NOARGS, NULL },
00139 { "WhoIsOther", getWhoIsThird, METH_NOARGS, NULL },
00140 { "WhatIsMessage", getWhatIsMessage, METH_NOARGS, NULL },
00141 { "ScriptName", getScriptName, METH_NOARGS, NULL },
00142 { "ScriptParameters", getScriptParameters, METH_NOARGS, NULL },
00143 { "WhatIsEvent", getEvent, METH_NOARGS, NULL },
00144 { "MapDirectory", getMapDirectory, METH_NOARGS, NULL },
00145 { "UniqueDirectory", getUniqueDirectory, METH_NOARGS, NULL },
00146 { "TempDirectory", getTempDirectory, METH_NOARGS, NULL },
00147 { "ConfigDirectory", getConfigDirectory, METH_NOARGS, NULL },
00148 { "LocalDirectory", getLocalDirectory, METH_NOARGS, NULL },
00149 { "PlayerDirectory", getPlayerDirectory, METH_NOARGS, NULL },
00150 { "DataDirectory", getDataDirectory, METH_NOARGS, NULL },
00151 { "ReadyMap", readyMap, METH_VARARGS, NULL },
00152 { "CreateMap", createMap, METH_VARARGS, NULL },
00153 { "FindPlayer", findPlayer, METH_VARARGS, NULL },
00154 { "MatchString", matchString, METH_VARARGS, NULL },
00155 { "GetReturnValue", getReturnValue, METH_NOARGS, NULL },
00156 { "SetReturnValue", setReturnValue, METH_VARARGS, NULL },
00157 { "PluginVersion", getCFPythonVersion, METH_NOARGS, NULL },
00158 { "CreateObject", createCFObject, METH_NOARGS, NULL },
00159 { "CreateObjectByName", createCFObjectByName, METH_VARARGS, NULL },
00160 { "GetPrivateDictionary", getPrivateDictionary, METH_NOARGS, NULL },
00161 { "GetSharedDictionary", getSharedDictionary, METH_NOARGS, NULL },
00162 { "GetPlayers", getPlayers, METH_NOARGS, NULL },
00163 { "GetArchetypes", getArchetypes, METH_NOARGS, NULL },
00164 { "GetMaps", getMaps, METH_NOARGS, NULL },
00165 { "GetParties", getParties, METH_NOARGS, NULL },
00166 { "GetRegions", getRegions, METH_NOARGS, NULL },
00167 { "GetFriendlyList", getFriendlyList, METH_NOARGS, NULL },
00168 { "RegisterCommand", registerCommand, METH_VARARGS, NULL },
00169 { "RegisterGlobalEvent", registerGEvent, METH_VARARGS, NULL },
00170 { "UnregisterGlobalEvent", unregisterGEvent, METH_VARARGS, NULL },
00171 { "GetTime", getTime, METH_NOARGS, NULL },
00172 { "DestroyTimer", destroyTimer, METH_VARARGS, NULL },
00173 { "MapHasBeenLoaded", getMapHasBeenLoaded, METH_VARARGS, NULL },
00174 { "Log", log_message, METH_VARARGS, NULL },
00175 { "FindFace", findFace, METH_VARARGS, NULL },
00176 { "FindAnimation", findAnimation, METH_VARARGS, NULL },
00177 { "GetSeasonName", getSeasonName, METH_VARARGS, NULL },
00178 { "GetMonthName", getMonthName, METH_VARARGS, NULL },
00179 { "GetWeekdayName", getWeekdayName, METH_VARARGS, NULL },
00180 { "GetPeriodofdayName", getPeriodofdayName, METH_VARARGS, NULL },
00181 { NULL, NULL, 0, NULL }
00182 };
00183
00184 CFPContext *context_stack;
00185
00186 CFPContext *current_context;
00187
00188 static int current_command = -999;
00189
00190 static PyObject *shared_data = NULL;
00191
00192 static PyObject *private_data = NULL;
00193
00194 static PyObject *registerGEvent(PyObject *self, PyObject *args) {
00195 int eventcode;
00196
00197 if (!PyArg_ParseTuple(args, "i", &eventcode))
00198 return NULL;
00199
00200 cf_system_register_global_event(eventcode, PLUGIN_NAME, cfpython_globalEventListener);
00201
00202 Py_INCREF(Py_None);
00203 return Py_None;
00204 }
00205
00206 static PyObject *unregisterGEvent(PyObject *self, PyObject *args) {
00207 int eventcode;
00208
00209 if (!PyArg_ParseTuple(args, "i", &eventcode))
00210 return NULL;
00211
00212 cf_system_unregister_global_event(EVENT_TELL, PLUGIN_NAME);
00213
00214 Py_INCREF(Py_None);
00215 return Py_None;
00216 }
00217
00218 static PyObject *createCFObject(PyObject *self, PyObject *args) {
00219 object *op;
00220
00221 op = cf_create_object();
00222
00223 return Crossfire_Object_wrap(op);
00224 }
00225
00226 static PyObject *createCFObjectByName(PyObject *self, PyObject *args) {
00227 char *obname;
00228 object *op;
00229
00230 if (!PyArg_ParseTuple(args, "s", &obname))
00231 return NULL;
00232
00233 op = cf_create_object_by_name(obname);
00234
00235 return Crossfire_Object_wrap(op);
00236 }
00237
00238 static PyObject *getCFPythonVersion(PyObject *self, PyObject *args) {
00239 int i = 2044;
00240
00241 return Py_BuildValue("i", i);
00242 }
00243
00244 static PyObject *getReturnValue(PyObject *self, PyObject *args) {
00245 return Py_BuildValue("i", current_context->returnvalue);
00246 }
00247
00248 static PyObject *setReturnValue(PyObject *self, PyObject *args) {
00249 int i;
00250
00251 if (!PyArg_ParseTuple(args, "i", &i))
00252 return NULL;
00253 current_context->returnvalue = i;
00254 Py_INCREF(Py_None);
00255 return Py_None;
00256 }
00257
00258 static PyObject *matchString(PyObject *self, PyObject *args) {
00259 char *premiere;
00260 char *seconde;
00261 const char *result;
00262
00263 if (!PyArg_ParseTuple(args, "ss", &premiere, &seconde))
00264 return NULL;
00265
00266 result = cf_re_cmp(premiere, seconde);
00267 if (result != NULL)
00268 return Py_BuildValue("i", 1);
00269 else
00270 return Py_BuildValue("i", 0);
00271 }
00272
00273 static PyObject *findPlayer(PyObject *self, PyObject *args) {
00274 player *foundpl;
00275 char *txt;
00276
00277 if (!PyArg_ParseTuple(args, "s", &txt))
00278 return NULL;
00279
00280 foundpl = cf_player_find(txt);
00281
00282 if (foundpl != NULL)
00283 return Py_BuildValue("O", Crossfire_Object_wrap(foundpl->ob));
00284 else {
00285 Py_INCREF(Py_None);
00286 return Py_None;
00287 }
00288 }
00289
00290 static PyObject *readyMap(PyObject *self, PyObject *args) {
00291 char *mapname;
00292 mapstruct *map;
00293 int flags = 0;
00294
00295 if (!PyArg_ParseTuple(args, "s|i", &mapname, &flags))
00296 return NULL;
00297
00298 map = cf_map_get_map(mapname, flags);
00299
00300 return Crossfire_Map_wrap(map);
00301 }
00302
00303 static PyObject *createMap(PyObject *self, PyObject *args) {
00304 int sizex, sizey;
00305 mapstruct *map;
00306
00307 if (!PyArg_ParseTuple(args, "ii", &sizex, &sizey))
00308 return NULL;
00309
00310 map = cf_get_empty_map(sizex, sizey);
00311
00312 return Crossfire_Map_wrap(map);
00313 }
00314
00315 static PyObject *getMapDirectory(PyObject *self, PyObject *args) {
00316 return Py_BuildValue("s", cf_get_directory(0));
00317 }
00318
00319 static PyObject *getUniqueDirectory(PyObject *self, PyObject *args) {
00320 return Py_BuildValue("s", cf_get_directory(1));
00321 }
00322
00323 static PyObject *getTempDirectory(PyObject *self, PyObject *args) {
00324 return Py_BuildValue("s", cf_get_directory(2));
00325 }
00326
00327 static PyObject *getConfigDirectory(PyObject *self, PyObject *args) {
00328 return Py_BuildValue("s", cf_get_directory(3));
00329 }
00330
00331 static PyObject *getLocalDirectory(PyObject *self, PyObject *args) {
00332 return Py_BuildValue("s", cf_get_directory(4));
00333 }
00334
00335 static PyObject *getPlayerDirectory(PyObject *self, PyObject *args) {
00336 return Py_BuildValue("s", cf_get_directory(5));
00337 }
00338
00339 static PyObject *getDataDirectory(PyObject *self, PyObject *args) {
00340 return Py_BuildValue("s", cf_get_directory(6));
00341 }
00342
00343 static PyObject *getWhoAmI(PyObject *self, PyObject *args) {
00344 if (!current_context->who) {
00345 Py_INCREF(Py_None);
00346 return Py_None;
00347 }
00348 Py_INCREF(current_context->who);
00349 return current_context->who;
00350 }
00351
00352 static PyObject *getWhoIsActivator(PyObject *self, PyObject *args) {
00353 if (!current_context->activator) {
00354 Py_INCREF(Py_None);
00355 return Py_None;
00356 }
00357 Py_INCREF(current_context->activator);
00358 return current_context->activator;
00359 }
00360
00361 static PyObject *getWhoIsThird(PyObject *self, PyObject *args) {
00362 if (!current_context->third) {
00363 Py_INCREF(Py_None);
00364 return Py_None;
00365 }
00366 Py_INCREF(current_context->third);
00367 return current_context->third;
00368 }
00369
00370 static PyObject *getWhatIsMessage(PyObject *self, PyObject *args) {
00371 if (current_context->message == NULL)
00372 return Py_BuildValue("");
00373 else
00374 return Py_BuildValue("s", current_context->message);
00375 }
00376
00377 static PyObject *getScriptName(PyObject *self, PyObject *args) {
00378 return Py_BuildValue("s", current_context->script);
00379 }
00380
00381 static PyObject *getScriptParameters(PyObject *self, PyObject *args) {
00382 if (!current_context->options) {
00383 Py_INCREF(Py_None);
00384 return Py_None;
00385 }
00386 return Py_BuildValue("s", current_context->options);
00387 }
00388
00389 static PyObject *getEvent(PyObject *self, PyObject *args) {
00390 if (!current_context->event) {
00391 Py_INCREF(Py_None);
00392 return Py_None;
00393 }
00394 Py_INCREF(current_context->event);
00395 return current_context->event;
00396 }
00397
00398 static PyObject *getPrivateDictionary(PyObject *self, PyObject *args) {
00399 PyObject *data;
00400
00401 data = PyDict_GetItemString(private_data, current_context->script);
00402 if (!data) {
00403 data = PyDict_New();
00404 PyDict_SetItemString(private_data, current_context->script, data);
00405 Py_DECREF(data);
00406 }
00407 Py_INCREF(data);
00408 return data;
00409 }
00410
00411 static PyObject *getSharedDictionary(PyObject *self, PyObject *args) {
00412 Py_INCREF(shared_data);
00413 return shared_data;
00414 }
00415
00416 static PyObject *getArchetypes(PyObject *self, PyObject *args) {
00417 PyObject *list;
00418 archetype *arch;
00419
00420 list = PyList_New(0);
00421 arch = cf_archetype_get_first();
00422 while (arch) {
00423 PyList_Append(list, Crossfire_Archetype_wrap(arch));
00424 arch = cf_archetype_get_next(arch);
00425 }
00426 return list;
00427 }
00428
00429 static PyObject *getPlayers(PyObject *self, PyObject *args) {
00430 PyObject *list;
00431 object *pl;
00432
00433 list = PyList_New(0);
00434 pl = cf_object_get_object_property(NULL, CFAPI_PLAYER_PROP_NEXT);
00435 while (pl) {
00436 PyList_Append(list, Crossfire_Object_wrap(pl));
00437 pl = cf_object_get_object_property(pl, CFAPI_PLAYER_PROP_NEXT);
00438 }
00439 return list;
00440 }
00441
00442 static PyObject *getMaps(PyObject *self, PyObject *args) {
00443 PyObject *list;
00444 mapstruct *map;
00445
00446 list = PyList_New(0);
00447 map = cf_map_get_first();
00448 while (map) {
00449 PyList_Append(list, Crossfire_Map_wrap(map));
00450 map = cf_map_get_map_property(map, CFAPI_MAP_PROP_NEXT);
00451 }
00452 return list;
00453 }
00454
00455 static PyObject *getParties(PyObject *self, PyObject *args) {
00456 PyObject *list;
00457 partylist *party;
00458
00459 list = PyList_New(0);
00460 party = cf_party_get_first();
00461 while (party) {
00462 PyList_Append(list, Crossfire_Party_wrap(party));
00463 party = cf_party_get_next(party);
00464 }
00465 return list;
00466 }
00467
00468 static PyObject *getRegions(PyObject *self, PyObject *args) {
00469 PyObject *list;
00470 region *reg;
00471
00472 list = PyList_New(0);
00473 reg = cf_region_get_first();
00474 while (reg) {
00475 PyList_Append(list, Crossfire_Region_wrap(reg));
00476 reg = cf_region_get_next(reg);
00477 }
00478 return list;
00479 }
00480
00481 static PyObject *getFriendlyList(PyObject *self, PyObject *args) {
00482 PyObject *list;
00483 object *ob;
00484
00485 list = PyList_New(0);
00486 ob = cf_friendlylist_get_first();
00487 while (ob) {
00488 PyList_Append(list, Crossfire_Object_wrap(ob));
00489 ob = cf_friendlylist_get_next(ob);
00490 }
00491 return list;
00492 }
00493
00494 static PyObject *registerCommand(PyObject *self, PyObject *args) {
00495 char *cmdname;
00496 char *scriptname;
00497 double cmdspeed;
00498 int i;
00499
00500 if (!PyArg_ParseTuple(args, "ssd", &cmdname, &scriptname, &cmdspeed))
00501 return NULL;
00502
00503 if (cmdspeed < 0) {
00504 set_exception("speed must not be negative");
00505 return NULL;
00506 }
00507
00508 for (i = 0; i < NR_CUSTOM_CMD; i++) {
00509 if (CustomCommand[i].name != NULL) {
00510 if (!strcmp(CustomCommand[i].name, cmdname)) {
00511 set_exception("command '%s' is already registered", cmdname);
00512 return NULL;
00513 }
00514 }
00515 }
00516 for (i = 0; i < NR_CUSTOM_CMD; i++) {
00517 if (CustomCommand[i].name == NULL) {
00518 CustomCommand[i].name = cf_strdup_local(cmdname);
00519 CustomCommand[i].script = cf_strdup_local(scriptname);
00520 CustomCommand[i].speed = cmdspeed;
00521 break;
00522 }
00523 }
00524
00525 Py_INCREF(Py_None);
00526 return Py_None;
00527 }
00528
00529 static PyObject *getTime(PyObject *self, PyObject *args) {
00530 PyObject *list;
00531 timeofday_t tod;
00532
00533 cf_get_time(&tod);
00534
00535 list = PyList_New(0);
00536 PyList_Append(list, Py_BuildValue("i", tod.year));
00537 PyList_Append(list, Py_BuildValue("i", tod.month));
00538 PyList_Append(list, Py_BuildValue("i", tod.day));
00539 PyList_Append(list, Py_BuildValue("i", tod.hour));
00540 PyList_Append(list, Py_BuildValue("i", tod.minute));
00541 PyList_Append(list, Py_BuildValue("i", tod.dayofweek));
00542 PyList_Append(list, Py_BuildValue("i", tod.weekofmonth));
00543 PyList_Append(list, Py_BuildValue("i", tod.season));
00544 PyList_Append(list, Py_BuildValue("i", tod.periodofday));
00545
00546 return list;
00547 }
00548
00549 static PyObject *destroyTimer(PyObject *self, PyObject *args) {
00550 int id;
00551
00552 if (!PyArg_ParseTuple(args, "i", &id))
00553 return NULL;
00554 return Py_BuildValue("i", cf_timer_destroy(id));
00555 }
00556
00557 static PyObject *getMapHasBeenLoaded(PyObject *self, PyObject *args) {
00558 char *name;
00559
00560 if (!PyArg_ParseTuple(args, "s", &name))
00561 return NULL;
00562 return Crossfire_Map_wrap(cf_map_has_been_loaded(name));
00563 }
00564
00565 static PyObject *findFace(PyObject *self, PyObject *args) {
00566 char *name;
00567
00568 if (!PyArg_ParseTuple(args, "s", &name))
00569 return NULL;
00570 return Py_BuildValue("i", cf_find_face(name, 0));
00571 }
00572
00573 static PyObject *log_message(PyObject *self, PyObject *args) {
00574 LogLevel level;
00575 int intLevel;
00576 char *message;
00577
00578 if (!PyArg_ParseTuple(args, "is", &intLevel, &message))
00579 return NULL;
00580
00581 switch (intLevel) {
00582 case llevError:
00583 level = llevError;
00584 break;
00585
00586 case llevInfo:
00587 level = llevInfo;
00588 break;
00589
00590 case llevDebug:
00591 level = llevDebug;
00592 break;
00593
00594 case llevMonster:
00595 level = llevMonster;
00596 break;
00597
00598 default:
00599 return NULL;
00600 }
00601 if ((message != NULL) && (message[strlen(message)] == '\n'))
00602 cf_log(level, "CFPython: %s", message);
00603 else
00604 cf_log(level, "CFPython: %s\n", message);
00605 Py_INCREF(Py_None);
00606 return Py_None;
00607 }
00608
00609 static PyObject *findAnimation(PyObject *self, PyObject *args) {
00610 char *name;
00611
00612 if (!PyArg_ParseTuple(args, "s", &name))
00613 return NULL;
00614 return Py_BuildValue("i", cf_find_animation(name));
00615 }
00616
00617 static PyObject *getSeasonName(PyObject *self, PyObject *args) {
00618 int i;
00619
00620 if (!PyArg_ParseTuple(args, "i", &i))
00621 return NULL;
00622 return Py_BuildValue("s", cf_get_season_name(i));
00623 }
00624
00625 static PyObject *getMonthName(PyObject *self, PyObject *args) {
00626 int i;
00627
00628 if (!PyArg_ParseTuple(args, "i", &i))
00629 return NULL;
00630 return Py_BuildValue("s", cf_get_month_name(i));
00631 }
00632
00633 static PyObject *getWeekdayName(PyObject *self, PyObject *args) {
00634 int i;
00635
00636 if (!PyArg_ParseTuple(args, "i", &i))
00637 return NULL;
00638 return Py_BuildValue("s", cf_get_weekday_name(i));
00639 }
00640
00641 static PyObject *getPeriodofdayName(PyObject *self, PyObject *args) {
00642 int i;
00643
00644 if (!PyArg_ParseTuple(args, "i", &i))
00645 return NULL;
00646 return Py_BuildValue("s", cf_get_periodofday_name(i));
00647 }
00648
00649 static void initContextStack(void) {
00650 current_context = NULL;
00651 context_stack = NULL;
00652 }
00653
00654 static void pushContext(CFPContext *context) {
00655 if (current_context == NULL) {
00656 context_stack = context;
00657 context->down = NULL;
00658 } else {
00659 context->down = current_context;
00660 }
00661 current_context = context;
00662 }
00663
00664 static CFPContext *popContext(void) {
00665 CFPContext *oldcontext;
00666
00667 if (current_context != NULL) {
00668 oldcontext = current_context;
00669 current_context = current_context->down;
00670 return oldcontext;
00671 }
00672 else
00673 return NULL;
00674 }
00675
00676 static void freeContext(CFPContext *context) {
00677 Py_XDECREF(context->event);
00678 Py_XDECREF(context->third);
00679 Py_XDECREF(context->who);
00680 Py_XDECREF(context->activator);
00681 free(context);
00682 }
00683
00685 static PyCodeObject *compilePython(char *filename) {
00686 PyObject *scriptfile;
00687 sstring sh_path;
00688 struct stat stat_buf;
00689 struct _node *n;
00690 int i;
00691 pycode_cache_entry *replace = NULL, *run = NULL;
00692
00693 if (!(scriptfile = PyFile_FromString(filename, "r"))) {
00694 cf_log(llevDebug, "cfpython - The Script file %s can't be opened\n", filename);
00695 return NULL;
00696 }
00697 if (stat(filename, &stat_buf)) {
00698 cf_log(llevDebug, "cfpython - The Script file %s can't be stat:ed\n", filename);
00699 if (scriptfile) {
00700 Py_DECREF(scriptfile);
00701 }
00702 return NULL;
00703 }
00704
00705 sh_path = cf_add_string(filename);
00706
00707
00708
00709
00710
00711
00712
00713 for (i = 0; i < PYTHON_CACHE_SIZE; i++) {
00714 if (pycode_cache[i].file == NULL) {
00715 replace = &pycode_cache[i];
00716 break;
00717 } else if (pycode_cache[i].file == sh_path) {
00718
00719 if (pycode_cache[i].code == NULL || (pycode_cache[i].cached_time < stat_buf.st_mtime)) {
00720
00721 replace = &pycode_cache[i];
00722 } else {
00723
00724 replace = NULL;
00725 run = &pycode_cache[i];
00726 }
00727 break;
00728 } else if (replace == NULL || pycode_cache[i].used_time < replace->used_time)
00729
00730 replace = &pycode_cache[i];
00731 }
00732
00733
00734 if (replace) {
00735 Py_XDECREF(replace->code);
00736 replace->code = NULL;
00737
00738
00739 if (replace->file != sh_path) {
00740 if (replace->file) {
00741 cf_free_string(replace->file);
00742 }
00743 replace->file = cf_add_string(sh_path);
00744 }
00745
00746
00747 if (!scriptfile && !(scriptfile = PyFile_FromString(filename, "r"))) {
00748 cf_log(llevDebug, "cfpython - The Script file %s can't be opened\n", filename);
00749 replace->code = NULL;
00750 return NULL;
00751 } else {
00752 if ((n = PyParser_SimpleParseFile(PyFile_AsFile(scriptfile), filename, Py_file_input))) {
00753 replace->code = PyNode_Compile(n, filename);
00754 PyNode_Free(n);
00755 }
00756
00757 if (PyErr_Occurred())
00758 PyErr_Print();
00759 else
00760 replace->cached_time = stat_buf.st_mtime;
00761 run = replace;
00762 }
00763 }
00764
00765 cf_free_string(sh_path);
00766
00767 if (scriptfile) {
00768 Py_DECREF(scriptfile);
00769 }
00770
00771 if (run)
00772 return run->code;
00773 else
00774 return NULL;
00775 }
00776
00777 static int do_script(CFPContext *context, int silent) {
00778 PyCodeObject *pycode;
00779 PyObject *dict;
00780 PyObject *ret;
00781 #if 0
00782 PyObject *list;
00783 int item;
00784 #endif
00785
00786 pycode = compilePython(context->script);
00787 if (pycode) {
00788 pushContext(context);
00789 dict = PyDict_New();
00790 PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins());
00791 ret = PyEval_EvalCode(pycode, dict, NULL);
00792 if (PyErr_Occurred()) {
00793 PyErr_Print();
00794 }
00795 Py_XDECREF(ret);
00796 #if 0
00797 printf("cfpython - %d items in heap\n", PyDict_Size(dict));
00798 list = PyDict_Values(dict);
00799 for (item = PyList_Size(list)-1; item >= 0; item--) {
00800 dict = PyList_GET_ITEM(list, item);
00801 ret = PyObject_Str(dict);
00802 printf(" ref %s = %d\n", PyString_AsString(ret), dict->ob_refcnt);
00803 Py_XDECREF(ret);
00804 }
00805 Py_DECREF(list);
00806 #endif
00807 Py_DECREF(dict);
00808 return 1;
00809 } else
00810 return 0;
00811 }
00812
00813 typedef struct {
00814 const char *name;
00815 const int value;
00816 } CFConstant;
00817
00818 static void addConstants(PyObject *module, const char *name, const CFConstant *constants) {
00819 int i = 0;
00820 char tmp[1024];
00821 PyObject *new;
00822 PyObject *dict;
00823
00824 strncpy(tmp, "Crossfire_", sizeof(tmp));
00825 strncat(tmp, name, sizeof(tmp)-strlen(tmp));
00826
00827 new = Py_InitModule(tmp, NULL);
00828 dict = PyDict_New();
00829
00830 while (constants[i].name != NULL) {
00831 PyModule_AddIntConstant(new, (char *)constants[i].name, constants[i].value);
00832 PyDict_SetItem(dict, PyInt_FromLong(constants[i].value), PyString_FromString(constants[i].name));
00833 i++;
00834 }
00835 PyDict_SetItemString(PyModule_GetDict(module), name, new);
00836
00837 #if 0
00838 Py_DECREF(new);
00839 #endif
00840
00841 strncpy(tmp, name, sizeof(tmp));
00842 strncat(tmp, "Name", sizeof(tmp)-strlen(tmp));
00843 PyDict_SetItemString(PyModule_GetDict(module), tmp, dict);
00844 Py_DECREF(dict);
00845 }
00852 static void addSimpleConstants(PyObject *module, const char *name, const CFConstant *constants) {
00853 int i = 0;
00854 char tmp[1024];
00855 PyObject *new;
00856
00857 strncpy(tmp, "Crossfire_", sizeof(tmp));
00858 strncat(tmp, name, sizeof(tmp)-strlen(tmp));
00859
00860 new = Py_InitModule(tmp, NULL);
00861
00862 while (constants[i].name != NULL) {
00863 PyModule_AddIntConstant(new, (char *)constants[i].name, constants[i].value);
00864 i++;
00865 }
00866 PyDict_SetItemString(PyModule_GetDict(module), name, new);
00867
00868 #if 0
00869 Py_DECREF(new);
00870 #endif
00871 }
00872
00873 static void initConstants(PyObject *module) {
00874 static const CFConstant cstDirection[] = {
00875 { "NORTH", 1 },
00876 { "NORTHEAST", 2 },
00877 { "EAST", 3 },
00878 { "SOUTHEAST", 4 },
00879 { "SOUTH", 5 },
00880 { "SOUTHWEST", 6 },
00881 { "WEST", 7 },
00882 { "NORTHWEST", 8 },
00883 { NULL, 0 }
00884 };
00885
00886 static const CFConstant cstType[] = {
00887 { "PLAYER", PLAYER },
00888 { "TRANSPORT", TRANSPORT },
00889 { "ROD", ROD },
00890 { "TREASURE", TREASURE },
00891 { "POTION", POTION },
00892 { "FOOD", FOOD },
00893 { "POISON", POISON },
00894 { "BOOK", BOOK },
00895 { "CLOCK", CLOCK },
00896 { "ARROW", ARROW },
00897 { "BOW", BOW },
00898 { "WEAPON", WEAPON },
00899 { "ARMOUR", ARMOUR },
00900 { "PEDESTAL", PEDESTAL },
00901 { "ALTAR", ALTAR },
00902 { "LOCKED_DOOR", LOCKED_DOOR },
00903 { "SPECIAL_KEY", SPECIAL_KEY },
00904 { "MAP", MAP },
00905 { "DOOR", DOOR },
00906 { "KEY", KEY },
00907 { "TIMED_GATE", TIMED_GATE },
00908 { "TRIGGER", TRIGGER },
00909 { "GRIMREAPER", GRIMREAPER },
00910 { "MAGIC_EAR", MAGIC_EAR },
00911 { "TRIGGER_BUTTON", TRIGGER_BUTTON },
00912 { "TRIGGER_ALTAR", TRIGGER_ALTAR },
00913 { "TRIGGER_PEDESTAL", TRIGGER_PEDESTAL },
00914 { "SHIELD", SHIELD },
00915 { "HELMET", HELMET },
00916 { "HORN", HORN },
00917 { "MONEY", MONEY },
00918 { "CLASS", CLASS },
00919 { "AMULET", AMULET },
00920 { "PLAYERMOVER", PLAYERMOVER },
00921 { "TELEPORTER", TELEPORTER },
00922 { "CREATOR", CREATOR },
00923 { "SKILL", SKILL },
00924 { "EXPERIENCE", EXPERIENCE },
00925 { "EARTHWALL", EARTHWALL },
00926 { "GOLEM", GOLEM },
00927 { "THROWN_OBJ", THROWN_OBJ },
00928 { "BLINDNESS", BLINDNESS },
00929 { "GOD", GOD },
00930 { "DETECTOR", DETECTOR },
00931 { "TRIGGER_MARKER", TRIGGER_MARKER },
00932 { "DEAD_OBJECT", DEAD_OBJECT },
00933 { "DRINK", DRINK },
00934 { "MARKER", MARKER },
00935 { "HOLY_ALTAR", HOLY_ALTAR },
00936 { "PLAYER_CHANGER", PLAYER_CHANGER },
00937 { "BATTLEGROUND", BATTLEGROUND },
00938 { "PEACEMAKER", PEACEMAKER },
00939 { "GEM", GEM },
00940 { "FIREWALL", FIREWALL },
00941 { "CHECK_INV", CHECK_INV },
00942 { "MOOD_FLOOR", MOOD_FLOOR },
00943 { "EXIT", EXIT },
00944 { "ENCOUNTER", ENCOUNTER },
00945 { "SHOP_FLOOR", SHOP_FLOOR },
00946 { "SHOP_MAT", SHOP_MAT },
00947 { "RING", RING },
00948 { "FLOOR", FLOOR },
00949 { "FLESH", FLESH },
00950 { "INORGANIC", INORGANIC },
00951 { "SKILL_TOOL", SKILL_TOOL },
00952 { "LIGHTER", LIGHTER },
00953 { "WALL", WALL },
00954 { "MISC_OBJECT", MISC_OBJECT },
00955 { "MONSTER", MONSTER },
00956 { "LAMP", LAMP },
00957 { "DUPLICATOR", DUPLICATOR },
00958 { "SPELLBOOK", SPELLBOOK },
00959 { "CLOAK", CLOAK },
00960 { "SPINNER", SPINNER },
00961 { "GATE", GATE },
00962 { "BUTTON", BUTTON },
00963 { "CF_HANDLE", CF_HANDLE },
00964 { "HOLE", HOLE },
00965 { "TRAPDOOR", TRAPDOOR },
00966 { "SIGN", SIGN },
00967 { "BOOTS", BOOTS },
00968 { "GLOVES", GLOVES },
00969 { "SPELL", SPELL },
00970 { "SPELL_EFFECT", SPELL_EFFECT },
00971 { "CONVERTER", CONVERTER },
00972 { "BRACERS", BRACERS },
00973 { "POISONING", POISONING },
00974 { "SAVEBED", SAVEBED },
00975 { "WAND", WAND },
00976 { "SCROLL", SCROLL },
00977 { "DIRECTOR", DIRECTOR },
00978 { "GIRDLE", GIRDLE },
00979 { "FORCE", FORCE },
00980 { "POTION_EFFECT", POTION_EFFECT },
00981 { "EVENT_CONNECTOR", EVENT_CONNECTOR },
00982 { "CLOSE_CON", CLOSE_CON },
00983 { "CONTAINER", CONTAINER },
00984 { "ARMOUR_IMPROVER", ARMOUR_IMPROVER },
00985 { "WEAPON_IMPROVER", WEAPON_IMPROVER },
00986 { "SKILLSCROLL", SKILLSCROLL },
00987 { "DEEP_SWAMP", DEEP_SWAMP },
00988 { "IDENTIFY_ALTAR", IDENTIFY_ALTAR },
00989 { "SHOP_INVENTORY", SHOP_INVENTORY },
00990 { "RUNE", RUNE },
00991 { "TRAP", TRAP },
00992 { "POWER_CRYSTAL", POWER_CRYSTAL },
00993 { "CORPSE", CORPSE },
00994 { "DISEASE", DISEASE },
00995 { "SYMPTOM", SYMPTOM },
00996 { "BUILDER", BUILDER },
00997 { "MATERIAL", MATERIAL },
00998 { NULL, 0 }
00999 };
01000
01001 static const CFConstant cstMove[] = {
01002 { "WALK", MOVE_WALK },
01003 { "FLY_LOW", MOVE_FLY_LOW },
01004 { "FLY_HIGH", MOVE_FLY_HIGH },
01005 { "FLYING", MOVE_FLYING },
01006 { "SWIM", MOVE_SWIM },
01007 { "BOAT", MOVE_BOAT },
01008 { "ALL", MOVE_ALL },
01009 { NULL, 0 }
01010 };
01011
01012 static const CFConstant cstMessageFlag[] = {
01013 { "NDI_BLACK", NDI_BLACK },
01014 { "NDI_WHITE", NDI_WHITE },
01015 { "NDI_NAVY", NDI_NAVY },
01016 { "NDI_RED", NDI_RED },
01017 { "NDI_ORANGE", NDI_ORANGE },
01018 { "NDI_BLUE", NDI_BLUE },
01019 { "NDI_DK_ORANGE", NDI_DK_ORANGE },
01020 { "NDI_GREEN", NDI_GREEN },
01021 { "NDI_LT_GREEN", NDI_LT_GREEN },
01022 { "NDI_GREY", NDI_GREY },
01023 { "NDI_BROWN", NDI_BROWN },
01024 { "NDI_GOLD", NDI_GOLD },
01025 { "NDI_TAN", NDI_TAN },
01026 { "NDI_UNIQUE", NDI_UNIQUE },
01027 { "NDI_ALL", NDI_ALL },
01028 { NULL, 0 }
01029 };
01030
01031 static const CFConstant cstCostFlag[] = {
01032 { "TRUE", F_TRUE },
01033 { "BUY", F_BUY },
01034 { "SELL", F_SELL },
01035 { "NOBARGAIN", F_NO_BARGAIN },
01036 { "IDENTIFIED", F_IDENTIFIED },
01037 { "NOTCURSED", F_NOT_CURSED },
01038 { NULL, 0 }
01039 };
01040
01041 static const CFConstant cstAttackType[] = {
01042 { "PHYSICAL", AT_PHYSICAL },
01043 { "MAGIC", AT_MAGIC },
01044 { "FIRE", AT_FIRE },
01045 { "ELECTRICITY", AT_ELECTRICITY },
01046 { "COLD", AT_COLD },
01047 { "CONFUSION", AT_CONFUSION },
01048 { "ACID", AT_ACID },
01049 { "DRAIN", AT_DRAIN },
01050 { "WEAPONMAGIC", AT_WEAPONMAGIC },
01051 { "GHOSTHIT", AT_GHOSTHIT },
01052 { "POISON", AT_POISON },
01053 { "SLOW", AT_SLOW },
01054 { "PARALYZE", AT_PARALYZE },
01055 { "TURN_UNDEAD", AT_TURN_UNDEAD },
01056 { "FEAR", AT_FEAR },
01057 { "CANCELLATION", AT_CANCELLATION },
01058 { "DEPLETE", AT_DEPLETE },
01059 { "DEATH", AT_DEATH },
01060 { "CHAOS", AT_CHAOS },
01061 { "COUNTERSPELL", AT_COUNTERSPELL },
01062 { "GODPOWER", AT_GODPOWER },
01063 { "HOLYWORD", AT_HOLYWORD },
01064 { "BLIND", AT_BLIND },
01065 { "INTERNAL", AT_INTERNAL },
01066 { "LIFE_STEALING", AT_LIFE_STEALING },
01067 { "DISEASE", AT_DISEASE },
01068 { NULL, 0 }
01069 };
01070
01071 static const CFConstant cstAttackTypeNumber[] = {
01072 { "PHYSICAL", ATNR_PHYSICAL },
01073 { "MAGIC", ATNR_MAGIC },
01074 { "FIRE", ATNR_FIRE },
01075 { "ELECTRICITY", ATNR_ELECTRICITY },
01076 { "COLD", ATNR_COLD },
01077 { "CONFUSION", ATNR_CONFUSION },
01078 { "ACID", ATNR_ACID },
01079 { "DRAIN", ATNR_DRAIN },
01080 { "WEAPONMAGIC", ATNR_WEAPONMAGIC },
01081 { "GHOSTHIT", ATNR_GHOSTHIT },
01082 { "POISON", ATNR_POISON },
01083 { "SLOW", ATNR_SLOW },
01084 { "PARALYZE", ATNR_PARALYZE },
01085 { "TURN_UNDEAD", ATNR_TURN_UNDEAD },
01086 { "FEAR", ATNR_FEAR },
01087 { "CANCELLATION", ATNR_CANCELLATION },
01088 { "DEPLETE", ATNR_DEPLETE },
01089 { "DEATH", ATNR_DEATH },
01090 { "CHAOS", ATNR_CHAOS },
01091 { "COUNTERSPELL", ATNR_COUNTERSPELL },
01092 { "GODPOWER", ATNR_GODPOWER },
01093 { "HOLYWORD", ATNR_HOLYWORD },
01094 { "BLIND", ATNR_BLIND },
01095 { "INTERNAL", ATNR_INTERNAL },
01096 { "LIFE_STEALING", ATNR_LIFE_STEALING },
01097 { "DISEASE", ATNR_DISEASE },
01098 { NULL, 0 }
01099 };
01100
01101 static const CFConstant cstEventType[] = {
01102 { "APPLY", EVENT_APPLY },
01103 { "ATTACK", EVENT_ATTACK },
01104 { "DEATH", EVENT_DEATH },
01105 { "DROP", EVENT_DROP },
01106 { "PICKUP", EVENT_PICKUP },
01107 { "SAY", EVENT_SAY },
01108 { "STOP", EVENT_STOP },
01109 { "TIME", EVENT_TIME },
01110 { "THROW", EVENT_THROW },
01111 { "TRIGGER", EVENT_TRIGGER },
01112 { "CLOSE", EVENT_CLOSE },
01113 { "TIMER", EVENT_TIMER },
01114 { "DESTROY", EVENT_DESTROY },
01115 { "BORN", EVENT_BORN },
01116 { "CLOCK", EVENT_CLOCK },
01117 { "CRASH", EVENT_CRASH },
01118 { "PLAYER_DEATH", EVENT_PLAYER_DEATH },
01119 { "GKILL", EVENT_GKILL },
01120 { "LOGIN", EVENT_LOGIN },
01121 { "LOGOUT", EVENT_LOGOUT },
01122 { "MAPENTER", EVENT_MAPENTER },
01123 { "MAPLEAVE", EVENT_MAPLEAVE },
01124 { "MAPRESET", EVENT_MAPRESET },
01125 { "REMOVE", EVENT_REMOVE },
01126 { "SHOUT", EVENT_SHOUT },
01127 { "TELL", EVENT_TELL },
01128 { "MUZZLE", EVENT_MUZZLE },
01129 { "KICK", EVENT_KICK },
01130 { "MAPUNLOAD", EVENT_MAPUNLOAD },
01131 { "MAPLOAD", EVENT_MAPLOAD },
01132 { "USER", EVENT_USER },
01133 { NULL, 0 }
01134 };
01135
01136 static const CFConstant cstTime[] = {
01137 { "HOURS_PER_DAY", HOURS_PER_DAY },
01138 { "DAYS_PER_WEEK", DAYS_PER_WEEK },
01139 { "WEEKS_PER_MONTH", WEEKS_PER_MONTH },
01140 { "MONTHS_PER_YEAR", MONTHS_PER_YEAR },
01141 { "SEASONS_PER_YEAR", SEASONS_PER_YEAR },
01142 { "PERIODS_PER_DAY", PERIODS_PER_DAY },
01143 { NULL, 0 }
01144 };
01145
01146 addConstants(module, "Direction", cstDirection);
01147 addConstants(module, "Type", cstType);
01148 addConstants(module, "Move", cstMove);
01149 addConstants(module, "MessageFlag", cstMessageFlag);
01150 addConstants(module, "CostFlag", cstCostFlag);
01151 addConstants(module, "AttackType", cstAttackType);
01152 addConstants(module, "AttackTypeNumber", cstAttackTypeNumber);
01153 addConstants(module, "EventType", cstEventType);
01154 addSimpleConstants(module, "Time", cstTime);
01155 }
01156
01157 extern PyMODINIT_FUNC initcjson(void);
01158
01159 CF_PLUGIN int initPlugin(const char *iversion, f_plug_api gethooksptr) {
01160 PyObject *m, *d;
01161 int i;
01162
01163 cf_init_plugin(gethooksptr);
01164 cf_log(llevDebug, "CFPython 2.0a init\n");
01165
01166 init_object_assoc_table();
01167 init_map_assoc_table();
01168
01169 #ifdef IS_PY26
01170 Py_Py3kWarningFlag++;
01171 #endif
01172
01173 Py_Initialize();
01174 Crossfire_ObjectType.tp_new = PyType_GenericNew;
01175 Crossfire_MapType.tp_new = PyType_GenericNew;
01176 Crossfire_PlayerType.tp_new = PyType_GenericNew;
01177 Crossfire_ArchetypeType.tp_new = PyType_GenericNew;
01178 Crossfire_PartyType.tp_new = PyType_GenericNew;
01179 Crossfire_RegionType.tp_new = PyType_GenericNew;
01180 PyType_Ready(&Crossfire_ObjectType);
01181 PyType_Ready(&Crossfire_MapType);
01182 PyType_Ready(&Crossfire_PlayerType);
01183 PyType_Ready(&Crossfire_ArchetypeType);
01184 PyType_Ready(&Crossfire_PartyType);
01185 PyType_Ready(&Crossfire_RegionType);
01186
01187 m = Py_InitModule("Crossfire", CFPythonMethods);
01188 d = PyModule_GetDict(m);
01189 Py_INCREF(&Crossfire_ObjectType);
01190 Py_INCREF(&Crossfire_MapType);
01191 Py_INCREF(&Crossfire_PlayerType);
01192 Py_INCREF(&Crossfire_ArchetypeType);
01193 Py_INCREF(&Crossfire_PartyType);
01194 Py_INCREF(&Crossfire_RegionType);
01195
01196 PyModule_AddObject(m, "Object", (PyObject *)&Crossfire_ObjectType);
01197 PyModule_AddObject(m, "Map", (PyObject *)&Crossfire_MapType);
01198 PyModule_AddObject(m, "Player", (PyObject *)&Crossfire_PlayerType);
01199 PyModule_AddObject(m, "Archetype", (PyObject *)&Crossfire_ArchetypeType);
01200 PyModule_AddObject(m, "Party", (PyObject *)&Crossfire_PartyType);
01201 PyModule_AddObject(m, "Region", (PyObject *)&Crossfire_RegionType);
01202
01203 PyModule_AddObject(m, "LogError", Py_BuildValue("i", llevError));
01204 PyModule_AddObject(m, "LogInfo", Py_BuildValue("i", llevInfo));
01205 PyModule_AddObject(m, "LogDebug", Py_BuildValue("i", llevDebug));
01206 PyModule_AddObject(m, "LogMonster", Py_BuildValue("i", llevMonster));
01207
01208 CFPythonError = PyErr_NewException("Crossfire.error", NULL, NULL);
01209 PyDict_SetItemString(d, "error", CFPythonError);
01210 for (i = 0; i < NR_CUSTOM_CMD; i++) {
01211 CustomCommand[i].name = NULL;
01212 CustomCommand[i].script = NULL;
01213 CustomCommand[i].speed = 0.0;
01214 }
01215 initConstants(m);
01216 private_data = PyDict_New();
01217 shared_data = PyDict_New();
01218
01219
01220 initcjson();
01221 return 0;
01222 }
01223
01224 CF_PLUGIN void *getPluginProperty(int *type, ...) {
01225 va_list args;
01226 const char *propname;
01227 int i, size;
01228 command_array_struct *rtn_cmd;
01229 char *buf;
01230
01231 va_start(args, type);
01232 propname = va_arg(args, const char *);
01233
01234 if (!strcmp(propname, "command?")) {
01235 const char *cmdname;
01236 cmdname = va_arg(args, const char *);
01237 rtn_cmd = va_arg(args, command_array_struct *);
01238 va_end(args);
01239
01240 for (i = 0; i < NR_CUSTOM_CMD; i++) {
01241 if (CustomCommand[i].name != NULL) {
01242 if (!strcmp(CustomCommand[i].name, cmdname)) {
01243 rtn_cmd->name = CustomCommand[i].name;
01244 rtn_cmd->time = (float)CustomCommand[i].speed;
01245 rtn_cmd->func = cfpython_runPluginCommand;
01246 current_command = i;
01247 return rtn_cmd;
01248 }
01249 }
01250 }
01251 return NULL;
01252 } else if (!strcmp(propname, "Identification")) {
01253 buf = va_arg(args, char *);
01254 size = va_arg(args, int);
01255 va_end(args);
01256 snprintf(buf, size, PLUGIN_NAME);
01257 return NULL;
01258 } else if (!strcmp(propname, "FullName")) {
01259 buf = va_arg(args, char *);
01260 size = va_arg(args, int);
01261 va_end(args);
01262 snprintf(buf, size, PLUGIN_VERSION);
01263 return NULL;
01264 }
01265 va_end(args);
01266 return NULL;
01267 }
01268
01269 CF_PLUGIN int cfpython_runPluginCommand(object *op, char *params) {
01270 char buf[1024], path[1024];
01271 CFPContext *context;
01272 static int rv = 0;
01273
01274 rv = 0;
01275
01276 if (current_command < 0) {
01277 cf_log(llevError, "Illegal call of cfpython_runPluginCommand, call find_plugin_command first.\n");
01278 return 1;
01279 }
01280 snprintf(buf, sizeof(buf), "%s.py", cf_get_maps_directory(CustomCommand[current_command].script, path, sizeof(path)));
01281
01282 context = malloc(sizeof(CFPContext));
01283 context->message[0] = 0;
01284
01285 context->who = Crossfire_Object_wrap(op);
01286 context->activator = NULL;
01287 context->third = NULL;
01288 context->fix = 0;
01289 snprintf(context->script, sizeof(context->script), "%s", buf);
01290 if (params)
01291 snprintf(context->options, sizeof(context->options), "%s", params);
01292 else
01293 context->options[0] = 0;
01294 context->returnvalue = 1;
01295
01296 current_command = -999;
01297 if (!do_script(context, 0)) {
01298 freeContext(context);
01299 return rv;
01300 }
01301
01302 context = popContext();
01303 rv = context->returnvalue;
01304 freeContext(context);
01305
01306 return rv;
01307 }
01308
01309 CF_PLUGIN int postInitPlugin(void) {
01310 PyObject *scriptfile;
01311 char path[1024];
01312
01313 cf_log(llevDebug, "CFPython 2.0a post init\n");
01314 initContextStack();
01315 cf_system_register_global_event(EVENT_BORN, PLUGIN_NAME, cfpython_globalEventListener);
01316 cf_system_register_global_event(EVENT_CLOCK, PLUGIN_NAME, cfpython_globalEventListener);
01317
01318 cf_system_register_global_event(EVENT_PLAYER_DEATH, PLUGIN_NAME, cfpython_globalEventListener);
01319 cf_system_register_global_event(EVENT_GKILL, PLUGIN_NAME, cfpython_globalEventListener);
01320 cf_system_register_global_event(EVENT_LOGIN, PLUGIN_NAME, cfpython_globalEventListener);
01321 cf_system_register_global_event(EVENT_LOGOUT, PLUGIN_NAME, cfpython_globalEventListener);
01322 cf_system_register_global_event(EVENT_MAPENTER, PLUGIN_NAME, cfpython_globalEventListener);
01323 cf_system_register_global_event(EVENT_MAPLEAVE, PLUGIN_NAME, cfpython_globalEventListener);
01324 cf_system_register_global_event(EVENT_MAPRESET, PLUGIN_NAME, cfpython_globalEventListener);
01325 cf_system_register_global_event(EVENT_REMOVE, PLUGIN_NAME, cfpython_globalEventListener);
01326 cf_system_register_global_event(EVENT_SHOUT, PLUGIN_NAME, cfpython_globalEventListener);
01327 cf_system_register_global_event(EVENT_TELL, PLUGIN_NAME, cfpython_globalEventListener);
01328 cf_system_register_global_event(EVENT_MUZZLE, PLUGIN_NAME, cfpython_globalEventListener);
01329 cf_system_register_global_event(EVENT_KICK, PLUGIN_NAME, cfpython_globalEventListener);
01330 cf_system_register_global_event(EVENT_MAPUNLOAD, PLUGIN_NAME, cfpython_globalEventListener);
01331 cf_system_register_global_event(EVENT_MAPLOAD, PLUGIN_NAME, cfpython_globalEventListener);
01332
01333 scriptfile = PyFile_FromString(cf_get_maps_directory("python/events/python_init.py", path, sizeof(path)), "r");
01334 if (scriptfile != NULL) {
01335 PyRun_SimpleFile(PyFile_AsFile(scriptfile), cf_get_maps_directory("python/events/python_init.py", path, sizeof(path)));
01336 Py_DECREF(scriptfile);
01337 }
01338
01339 return 0;
01340 }
01341
01342 CF_PLUGIN void *cfpython_globalEventListener(int *type, ...) {
01343 va_list args;
01344 static int rv = 0;
01345 CFPContext *context;
01346 char *buf;
01347 player *pl;
01348 object *op;
01349 context = malloc(sizeof(CFPContext));
01350
01351 rv = 0;
01352
01353 va_start(args, type);
01354 context->event_code = va_arg(args, int);
01355
01356 context->message[0] = 0;
01357
01358 context->who = NULL;
01359 context->activator = NULL;
01360 context->third = NULL;
01361 context->event = NULL;
01362 rv = context->returnvalue = 0;
01363 cf_get_maps_directory("python/events/python_event.py", context->script, sizeof(context->script));
01364 strcpy(context->options, "");
01365 switch (context->event_code) {
01366 case EVENT_CRASH:
01367 cf_log(llevDebug, "Unimplemented for now\n");
01368 break;
01369
01370 case EVENT_BORN:
01371 op = va_arg(args, object *);
01372 context->activator = Crossfire_Object_wrap(op);
01373 snprintf(context->options, sizeof(context->options), "born");
01374 break;
01375
01376 case EVENT_PLAYER_DEATH:
01377 op = va_arg(args, object *);
01378 context->who = Crossfire_Object_wrap(op);
01379 snprintf(context->options, sizeof(context->options), "death");
01380 break;
01381
01382 case EVENT_GKILL:
01383 op = va_arg(args, object *);
01384 context->who = Crossfire_Object_wrap(op);
01385 context->activator = Crossfire_Object_wrap(op);
01386 snprintf(context->options, sizeof(context->options), "gkill");
01387 break;
01388
01389 case EVENT_LOGIN:
01390 pl = va_arg(args, player *);
01391 context->activator = Crossfire_Object_wrap(pl->ob);
01392 buf = va_arg(args, char *);
01393 if (buf != NULL)
01394 snprintf(context->message, sizeof(context->message), "%s", buf);
01395 snprintf(context->options, sizeof(context->options), "login");
01396 break;
01397
01398 case EVENT_LOGOUT:
01399 pl = va_arg(args, player *);
01400 context->activator = Crossfire_Object_wrap(pl->ob);
01401 buf = va_arg(args, char *);
01402 if (buf != NULL)
01403 snprintf(context->message, sizeof(context->message), "%s", buf);
01404 snprintf(context->options, sizeof(context->options), "logout");
01405 break;
01406
01407 case EVENT_REMOVE:
01408 op = va_arg(args, object *);
01409 context->activator = Crossfire_Object_wrap(op);
01410 snprintf(context->options, sizeof(context->options), "remove");
01411 break;
01412
01413 case EVENT_SHOUT:
01414 op = va_arg(args, object *);
01415 context->activator = Crossfire_Object_wrap(op);
01416 buf = va_arg(args, char *);
01417 if (buf != NULL)
01418 snprintf(context->message, sizeof(context->message), "%s", buf);
01419 snprintf(context->options, sizeof(context->options), "shout");
01420 break;
01421
01422 case EVENT_MUZZLE:
01423 op = va_arg(args, object *);
01424 context->activator = Crossfire_Object_wrap(op);
01425 buf = va_arg(args, char *);
01426 if (buf != NULL)
01427 snprintf(context->message, sizeof(context->message), "%s", buf);
01428 snprintf(context->options, sizeof(context->options), "muzzle");
01429 break;
01430
01431 case EVENT_KICK:
01432 op = va_arg(args, object *);
01433 context->activator = Crossfire_Object_wrap(op);
01434 buf = va_arg(args, char *);
01435 if (buf != NULL)
01436 snprintf(context->message, sizeof(context->message), "%s", buf);
01437 snprintf(context->options, sizeof(context->options), "kick");
01438 break;
01439
01440 case EVENT_MAPENTER:
01441 op = va_arg(args, object *);
01442 context->activator = Crossfire_Object_wrap(op);
01443 context->who = Crossfire_Map_wrap(va_arg(args, mapstruct *));
01444 snprintf(context->options, sizeof(context->options), "mapenter");
01445 break;
01446
01447 case EVENT_MAPLEAVE:
01448 op = va_arg(args, object *);
01449 context->activator = Crossfire_Object_wrap(op);
01450 context->who = Crossfire_Map_wrap(va_arg(args, mapstruct *));
01451 snprintf(context->options, sizeof(context->options), "mapleave");
01452 break;
01453
01454 case EVENT_CLOCK:
01455 snprintf(context->options, sizeof(context->options), "clock");
01456 break;
01457
01458 case EVENT_MAPRESET:
01459 context->who = Crossfire_Map_wrap(va_arg(args, mapstruct *));
01460 snprintf(context->options, sizeof(context->options), "mapreset");
01461 break;
01462
01463 case EVENT_TELL:
01464 op = va_arg(args, object *);
01465 buf = va_arg(args, char *);
01466 context->activator = Crossfire_Object_wrap(op);
01467 if (buf != NULL)
01468 snprintf(context->message, sizeof(context->message), "%s", buf);
01469 op = va_arg(args, object *);
01470 context->third = Crossfire_Object_wrap(op);
01471 snprintf(context->options, sizeof(context->options), "tell");
01472 break;
01473
01474 case EVENT_MAPUNLOAD:
01475 context->who = Crossfire_Map_wrap(va_arg(args, mapstruct *));
01476 snprintf(context->options, sizeof(context->options), "mapunload");
01477 break;
01478
01479 case EVENT_MAPLOAD:
01480 context->who = Crossfire_Map_wrap(va_arg(args, mapstruct *));
01481 snprintf(context->options, sizeof(context->options), "mapload");
01482 break;
01483 }
01484 va_end(args);
01485 context->returnvalue = 0;
01486
01487 if (!do_script(context, 1)) {
01488 freeContext(context);
01489 return &rv;
01490 }
01491
01492 context = popContext();
01493 rv = context->returnvalue;
01494
01495
01496 if (context->event_code == EVENT_MAPUNLOAD)
01497 Handle_Map_Unload_Hook((Crossfire_Map *)context->who);
01498
01499 freeContext(context);
01500
01501 return &rv;
01502 }
01503
01504 CF_PLUGIN void *eventListener(int *type, ...) {
01505 static int rv = 0;
01506 va_list args;
01507 char *buf;
01508 CFPContext *context;
01509 object *event;
01510
01511 rv = 0;
01512
01513 context = malloc(sizeof(CFPContext));
01514
01515 context->message[0] = 0;
01516
01517 va_start(args, type);
01518
01519 context->who = Crossfire_Object_wrap(va_arg(args, object *));
01520 context->activator = Crossfire_Object_wrap(va_arg(args, object *));
01521 context->third = Crossfire_Object_wrap(va_arg(args, object *));
01522 buf = va_arg(args, char *);
01523 if (buf != NULL)
01524 snprintf(context->message, sizeof(context->message), "%s", buf);
01525 context->fix = va_arg(args, int);
01526 event = va_arg(args, object *);
01527 context->event_code = event->subtype;
01528 context->event = Crossfire_Object_wrap(event);
01529 cf_get_maps_directory(event->slaying, context->script, sizeof(context->script));
01530 snprintf(context->options, sizeof(context->options), "%s", event->name);
01531 context->returnvalue = 0;
01532
01533 va_end(args);
01534
01535 if (!do_script(context, 0)) {
01536 freeContext(context);
01537 return &rv;
01538 }
01539
01540 context = popContext();
01541 rv = context->returnvalue;
01542 freeContext(context);
01543 return &rv;
01544 }
01545
01546 CF_PLUGIN int closePlugin(void) {
01547 cf_log(llevDebug, "CFPython 2.0a closing\n");
01548 Py_Finalize();
01549 return 0;
01550 }