]> jfr.im git - irc/evilnet/x3.git/blobdiff - src/mod-python.c
Fix for "whats the color" 8ball question formats
[irc/evilnet/x3.git] / src / mod-python.c
index 2b2397a412b104c2242abc47b243e520e166d276..b35db073c5e7a9e61868be82faa731cd49052a84 100644 (file)
  * - modpython.py calls for everything you can reg_ a handler for in x3
  * - Some kind of system for getting needed binds bound automagicaly to make it easier
  *   to run peoples' scripts and mod-python in general.
+ *   - Create a (python side) command registry that plugins register into
+ *   - In modcmd.c check that list first, before the usual (c based) command search
+ *   - If python version returns 0, go on with the built-in search, otherwise just quit (allows plugins to override)
+ *   - OR 
+ *   - Mechanism for python plugins to register themselves like x3 plugins? (*module.____) ??
+ *   - Then, same problem as other x3 modules, pain to set up commands 1st time etc, maybe solve that for all modules?
  * - An interface to reading/writing data to x3.db. Maybe generic, or attached to account or channel reg records?
+
+ * basic startup for now:
+ * configure --enable-modules=python
+ * Make install will copy modpython.py and plugins/ directory to start out with hangman example/test
+ *
+ * x3.conf: in the "moduleS" section add:
+ *   "python" {
+ *       "scripts_dir" "/home/you/x3rundirectory";
+ *       "main_module" "modpython";
+ *   };
+
+ * /msg o3 bind o3 py\ run *python.run
+ * /msg o3 bind o3 py\ reload *python.reload
+ * /msg o3 bind o3 py\ command *python.command
+
+ * example script bindings (for now)
+ * /msg o3 bind x3 hangman *modcmd.joiner
+ * /msg o3 bind x3 hangman\ start *python.command hangman start
+ * /msg o3 bind x3 hangman\ end *python.command hangman end
+ * /msg o3 bind x3 hangman\ guess *python.command hangman guess $1
  */
 
 static const struct message_entry msgtab[] = {
@@ -1194,6 +1220,60 @@ emb_service_register(UNUSED_ARG(PyObject* self_), PyObject* args) {
     return pyobj_from_service(service_register(user));
 }
 
+size_t logs_size = 0;
+static struct log_type **logs_list = NULL;
+
+PyDoc_STRVAR(emb_log_register_type__doc__,
+        "registers a log source to write event data to.");
+static PyObject* emb_log_register_type(UNUSED_ARG(PyObject *self), PyObject* args) {
+    const char* logName;
+    const char* defaultLog;
+    struct log_type* log;
+    struct log_type** newlogs;
+
+    if (!PyArg_ParseTuple(args, "ss", &logName, &defaultLog))
+        return NULL;
+
+    newlogs = realloc(logs_list, (logs_size+1)*sizeof(struct log_type*));
+    if (newlogs == NULL) {
+        PyErr_SetString(PyExc_Exception, "unable to allocate memory for log structures. aborting.");
+        return NULL;
+    }
+    logs_list = newlogs;
+
+    log = log_register_type(logName, defaultLog);
+    if (log == NULL) {
+        PyErr_SetString(PyExc_Exception, "unable to register log");
+        return NULL;
+    }
+
+    logs_list[logs_size++] = log;
+
+    return Py_BuildValue("O", PyCObject_FromVoidPtr(log, NULL));
+}
+
+PyDoc_STRVAR(emb_module_register__doc__, "registers a module");
+PyObject* emb_module_register(UNUSED_ARG(PyObject* self), PyObject* args) {
+    PyObject* pylog;
+    char const *name, *helpfile;
+    struct log_type* log;
+    struct module* mod;
+
+    if (!PyArg_ParseTuple(args, "sOs", &name, &pylog, &helpfile))
+        return NULL;
+
+    log = PyCObject_AsVoidPtr(pylog);
+
+    mod = module_register(name, log, helpfile, NULL);
+
+    if (mod == NULL) {
+        PyErr_SetString(PyExc_Exception, "unable to register module");
+        return NULL;
+    }
+
+    return Py_BuildValue("O", PyCObject_FromVoidPtr(mod, NULL));
+}
+
 static PyMethodDef EmbMethods[] = {
     /* Communication methods */
     {"dump", emb_dump, METH_VARARGS, emb_dump__doc__},
@@ -1224,6 +1304,12 @@ static PyMethodDef EmbMethods[] = {
     {"timeq_add", emb_timeq_add, METH_VARARGS, emb_timeq_add__doc__},
     {"timeq_del", emb_timeq_del, METH_VARARGS, emb_timeq_del__doc__},
 
+    /* module registration methods */
+    {"log_register_type", emb_log_register_type, METH_VARARGS,
+        emb_log_register_type__doc__},
+    {"module_register", emb_module_register, METH_VARARGS,
+        emb_module_register__doc__},
+
     /* Information gathering methods */
     {"get_user", emb_get_user, METH_VARARGS, emb_get_user__doc__},
     {"get_users", emb_get_users, METH_VARARGS, emb_get_users__doc__},
@@ -1802,6 +1888,7 @@ int python_load() {
         free(env);
     }
 
+    log_module(PY_LOG, LOG_DEBUG, "Starting Python Init from python_load");
     Py_Initialize();
     Py_InitModule("_svc", EmbMethods);
     pName = PyString_FromString(modpython_conf.main_module);
@@ -1820,6 +1907,7 @@ int python_load() {
         else {
             /* error handler class not found */
             log_module(PY_LOG, LOG_WARNING, "Failed to create handler object");
+            exit(1);
             return 0;
         }
     }
@@ -1827,6 +1915,7 @@ int python_load() {
         //PyErr_Print();
         python_log_module();
         log_module(PY_LOG, LOG_WARNING, "Failed to load modpython.py");
+        exit(1);
         return 0;
     }
     return 0;
@@ -1945,8 +2034,11 @@ static MODCMD_FUNC(cmd_command) {
     else {
         msg = "";
     }
-    char *args[] = {plugin, command, msg};
+    char *args[] = {strdup(plugin), strdup(command), strdup(msg)};
     python_call_handler("cmd_command", args, numstrargs(args), cmd->parent->bot->nick, user?user->nick:"", channel?channel->name:"");
+    free(args[0]);
+    free(args[1]);
+    free(args[2]);
     return 1;
 }
 
@@ -1960,10 +2052,10 @@ static void modpython_conf_read(void) {
     }
 
     str = database_get_data(conf_node, "scripts_dir", RECDB_QSTRING);
-    modpython_conf.scripts_dir = str ? str : "./";
+    modpython_conf.scripts_dir = strdup(str ? str : "./");
 
     str = database_get_data(conf_node, "main_module", RECDB_QSTRING);
-    modpython_conf.main_module = str ? str : "modpython";
+    modpython_conf.main_module = strdup(str ? str : "modpython");
 }
 
 int python_init(void) {
@@ -1988,7 +2080,7 @@ int python_init(void) {
 */
     modcmd_register(python_module, "reload",  cmd_reload,  1,  MODCMD_REQUIRE_AUTHED, "flags", "+oper", NULL);
     modcmd_register(python_module, "run",  cmd_run,  2,  MODCMD_REQUIRE_AUTHED, "flags", "+oper", NULL);
-    modcmd_register(python_module, "command", cmd_command, 3, MODCMD_REQUIRE_STAFF, NULL);
+    modcmd_register(python_module, "command", cmd_command, 3, MODCMD_REQUIRE_AUTHED, "flags", "+oper", NULL);
 
 //  Please help us by implementing any of the callbacks listed as TODO below. They already exist
 //  in x3, they just need handle_ bridges implemented. (see python_handle_join for an example)