void extenderDoMenu(SOCKET_DATA *sock, OLC_EXTENDER *ext, void *data) { LIST *keys = hashCollect(ext->opt_hash); char *key = NULL; OLC_EXT_DATA *edata = NULL; // display each menu item alphabetically listSortWith(keys, strcasecmp); LIST_ITERATOR *key_i = newListIterator(keys); ITERATE_LIST(key, key_i) { // display the menu option send_to_socket(sock, "{g%s) ", key); // then display the information edata = hashGet(ext->opt_hash, key); if(edata->type == OLCEXT_C) edata->menu(sock, data); else if(ext->borrow_py != NULL) { PyObject *ret = PyObject_CallFunction(edata->pymenu, "OO", socketGetPyFormBorrowed(sock), ext->borrow_py(data)); if(ret == NULL) log_pyerr("Error running Python OLC exention menu function: %s", key); Py_XDECREF(ret); } } deleteListIterator(key_i);
// // Try running a script on the initiator bool try_reset_script(RESET_DATA *reset, void *initiator, int initiator_type, const char *locale) { PyObject *pyme = NULL; PyObject *dict = NULL; if(initiator_type == INITIATOR_ROOM) pyme = roomGetPyFormBorrowed(initiator); else if(initiator_type == INITIATOR_THEN_OBJ) pyme = objGetPyFormBorrowed(initiator); else if(initiator_type == INITIATOR_THEN_MOB) pyme = charGetPyFormBorrowed(initiator); else return FALSE; // build our dictionary and add ourself to it as 'me' dict = restricted_script_dict(); PyDict_SetItemString(dict, "me", pyme); // run the script run_script(dict, resetGetArg(reset), locale); // check to see if we had an error if(!last_script_ok()) log_pyerr("Reset script in locale %s terminated with an error:\r\n%s", locale, resetGetArg(reset)); // garbage collection and return our outcome Py_DECREF(dict); return last_script_ok(); }
//***************************************************************************** // local functions //***************************************************************************** void PyEvent_on_complete(void *owner, PyObject *tuple, const char *arg) { PyObject *PyOwner = NULL; PyObject *efunc = NULL; PyObject *edata = NULL; char *otype = NULL; // make sure we parse everything before we call the function if(PyArg_ParseTuple(tuple, "sOO", &otype, &efunc, &edata)) { if(!strcasecmp(otype, "char")) PyOwner = charGetPyFormBorrowed(owner); else if(!strcasecmp(otype, "room")) PyOwner = roomGetPyFormBorrowed(owner); else if(!strcasecmp(otype, "obj")) PyOwner = objGetPyFormBorrowed(owner); else PyOwner = Py_None; PyObject *ret = PyObject_CallFunction(efunc, "OOs", PyOwner, edata, arg); if(ret == NULL) log_pyerr("Error finishing Python event"); Py_XDECREF(ret); } // decrease the reference on our function and data, as well as our owner Py_XDECREF(tuple); }
PyObject *eval_script(PyObject *dict, const char *statement,const char *locale){ listPush(locale_stack, strdupsafe(locale)); // run the statement PyObject *retval = PyRun_String(statement, Py_eval_input, dict, dict); // did we encounter an error? if(retval == NULL) log_pyerr("eval_script terminated with an error:\r\n%s", statement); free(listPop(locale_stack)); return retval; }
PyObject *run_script_forcode(PyObject *dict, const char *script, const char *locale) { // try compiling the code PyObject *retval = Py_CompileString(script, "<string>", Py_file_input); // try running the code if(retval != NULL) run_code(retval, dict, locale); // did we end up with an error? if(retval == NULL || !last_script_ok()) log_pyerr("Script terminated with an error:\r\n%s", script); // return our code object return retval; }
void input_handler() { LIST_ITERATOR *sock_i = newListIterator(socket_list); SOCKET_DATA *sock = NULL; ITERATE_LIST(sock, sock_i) { // Close sockects we are unable to read from, or if we have no handler // to take in input if ((FD_ISSET(sock->control, &rFd) && !read_from_socket(sock)) || listSize(sock->input_handlers) == 0) { close_socket(sock, FALSE); continue; } /* Ok, check for a new command */ next_cmd_from_buffer(sock); // are we idling? if(!sock->cmd_read) sock->idle += 1.0 / PULSES_PER_SECOND; /* Is there a new command pending ? */ else if (sock->cmd_read) { sock->idle = 0.0; IH_PAIR *pair = listGet(sock->input_handlers, 0); if(pair->python == FALSE) { void (* handler)(SOCKET_DATA *, char *) = pair->handler; char *cmddup = strdup(bufferString(sock->next_command)); handler(sock, cmddup); free(cmddup); } else { PyObject *arglist = Py_BuildValue("Os", socketGetPyFormBorrowed(sock), bufferString(sock->next_command)); PyObject *retval = PyEval_CallObject(pair->handler, arglist); // check for an error: if(retval == NULL) log_pyerr("Error with a Python input handler"); // garbage collection Py_XDECREF(retval); Py_XDECREF(arglist); } // append our last command to the command history. History buffer is // 100 commands, so pop off the earliest command if we're going over listPut(sock->command_hist, strdup(bufferString(sock->next_command))); if(listSize(sock->command_hist) > 100) free(listRemoveNum(sock->command_hist, 100)); bufferClear(sock->next_command); // we save whether or not we read a command until our next call to // input_handler(), at which time it is reset to FALSE if we didn't read // sock->cmd_read = FALSE; } #ifdef MODULE_ALIAS // ACK!! this is so yucky, but I can't think of a better way to do it... // if this command was put in place by an alias, decrement the alias_queue // counter by one. This counter is in place mainly so aliases do not end // up calling eachother and making us get stuck in an infinite loop. if(sock->player) { int alias_queue = charGetAliasesQueued(sock->player); if(alias_queue > 0) charSetAliasesQueued(sock->player, --alias_queue); } #endif } deleteListIterator(sock_i); }