synched with trunk at revision 36569
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
@@ -28,6 +28,11 @@
|
||||
* Initialize Python thingies.
|
||||
*/
|
||||
|
||||
/** \file gameengine/Ketsji/KX_PythonInit.cpp
|
||||
* \ingroup ketsji
|
||||
*/
|
||||
|
||||
|
||||
#include "GL/glew.h"
|
||||
|
||||
#if defined(WIN32) && !defined(FREE_WINDOWS)
|
||||
@@ -642,7 +647,7 @@ static PyObject *pyPrintExt(PyObject *,PyObject *,PyObject *)
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *gLibLoad(PyObject*, PyObject* args)
|
||||
static PyObject *gLibLoad(PyObject*, PyObject* args, PyObject* kwds)
|
||||
{
|
||||
KX_Scene *kx_scene= gp_KetsjiScene;
|
||||
char *path;
|
||||
@@ -650,20 +655,37 @@ static PyObject *gLibLoad(PyObject*, PyObject* args)
|
||||
Py_buffer py_buffer;
|
||||
py_buffer.buf = NULL;
|
||||
char *err_str= NULL;
|
||||
|
||||
short options=0;
|
||||
int load_actions=0, verbose=0;
|
||||
|
||||
static const char *kwlist[] = {"path", "group", "buffer", "load_actions", "verbose", NULL};
|
||||
|
||||
if (!PyArg_ParseTuple(args,"ss|y*:LibLoad",&path, &group, &py_buffer))
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss|y*ii:LibLoad", const_cast<char**>(kwlist),
|
||||
&path, &group, &py_buffer, &load_actions, &verbose))
|
||||
return NULL;
|
||||
|
||||
/* setup options */
|
||||
if (load_actions != 0)
|
||||
options |= KX_BlenderSceneConverter::LIB_LOAD_LOAD_ACTIONS;
|
||||
if (verbose != 0)
|
||||
options |= KX_BlenderSceneConverter::LIB_LOAD_VERBOSE;
|
||||
|
||||
if (!py_buffer.buf)
|
||||
{
|
||||
if(kx_scene->GetSceneConverter()->LinkBlendFilePath(path, group, kx_scene, &err_str)) {
|
||||
char abs_path[FILE_MAX];
|
||||
// Make the path absolute
|
||||
BLI_strncpy(abs_path, path, sizeof(abs_path));
|
||||
BLI_path_abs(abs_path, gp_GamePythonPath);
|
||||
|
||||
if(kx_scene->GetSceneConverter()->LinkBlendFilePath(abs_path, group, kx_scene, &err_str, options)) {
|
||||
Py_RETURN_TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if(kx_scene->GetSceneConverter()->LinkBlendFileMemory(py_buffer.buf, py_buffer.len, path, group, kx_scene, &err_str)) {
|
||||
if(kx_scene->GetSceneConverter()->LinkBlendFileMemory(py_buffer.buf, py_buffer.len, path, group, kx_scene, &err_str, options)) {
|
||||
PyBuffer_Release(&py_buffer);
|
||||
Py_RETURN_TRUE;
|
||||
}
|
||||
@@ -797,7 +819,7 @@ static struct PyMethodDef game_methods[] = {
|
||||
{"PrintMemInfo", (PyCFunction)pyPrintStats, METH_NOARGS, (const char *)"Print engine stastics"},
|
||||
|
||||
/* library functions */
|
||||
{"LibLoad", (PyCFunction)gLibLoad, METH_VARARGS, (const char *)""},
|
||||
{"LibLoad", (PyCFunction)gLibLoad, METH_VARARGS|METH_KEYWORDS, (const char *)""},
|
||||
{"LibNew", (PyCFunction)gLibNew, METH_VARARGS, (const char *)""},
|
||||
{"LibFree", (PyCFunction)gLibFree, METH_VARARGS, (const char *)""},
|
||||
{"LibList", (PyCFunction)gLibList, METH_VARARGS, (const char *)""},
|
||||
@@ -930,12 +952,12 @@ static PyObject* gPySetBackgroundColor(PyObject*, PyObject* value)
|
||||
|
||||
if (gp_Canvas)
|
||||
{
|
||||
gp_Rasterizer->SetBackColor(vec[0], vec[1], vec[2], vec[3]);
|
||||
gp_Rasterizer->SetBackColor((float)vec[0], (float)vec[1], (float)vec[2], (float)vec[3]);
|
||||
}
|
||||
|
||||
KX_WorldInfo *wi = gp_KetsjiScene->GetWorldInfo();
|
||||
if (wi->hasWorld())
|
||||
wi->setBackColor(vec[0], vec[1], vec[2]);
|
||||
wi->setBackColor((float)vec[0], (float)vec[1], (float)vec[2]);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
@@ -953,7 +975,7 @@ static PyObject* gPySetMistColor(PyObject*, PyObject* value)
|
||||
PyErr_SetString(PyExc_RuntimeError, "Rasterizer.setMistColor(color), Rasterizer not available");
|
||||
return NULL;
|
||||
}
|
||||
gp_Rasterizer->SetFogColor(vec[0], vec[1], vec[2]);
|
||||
gp_Rasterizer->SetFogColor((float)vec[0], (float)vec[1], (float)vec[2]);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
@@ -1018,7 +1040,7 @@ static PyObject* gPySetAmbientColor(PyObject*, PyObject* value)
|
||||
PyErr_SetString(PyExc_RuntimeError, "Rasterizer.setAmbientColor(color), Rasterizer not available");
|
||||
return NULL;
|
||||
}
|
||||
gp_Rasterizer->SetAmbientColor(vec[0], vec[1], vec[2]);
|
||||
gp_Rasterizer->SetAmbientColor((float)vec[0], (float)vec[1], (float)vec[2]);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
@@ -1407,6 +1429,7 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack
|
||||
|
||||
/* 7. Action actuator */
|
||||
KX_MACRO_addTypesToDict(d, KX_ACTIONACT_PLAY, ACT_ACTION_PLAY);
|
||||
KX_MACRO_addTypesToDict(d, KX_ACTIONACT_PINGPONG, ACT_ACTION_PINGPONG);
|
||||
KX_MACRO_addTypesToDict(d, KX_ACTIONACT_FLIPPER, ACT_ACTION_FLIPPER);
|
||||
KX_MACRO_addTypesToDict(d, KX_ACTIONACT_LOOPSTOP, ACT_ACTION_LOOP_STOP);
|
||||
KX_MACRO_addTypesToDict(d, KX_ACTIONACT_LOOPEND, ACT_ACTION_LOOP_END);
|
||||
@@ -1633,176 +1656,6 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack
|
||||
return m;
|
||||
}
|
||||
|
||||
// Python Sandbox code
|
||||
// override builtin functions import() and open()
|
||||
|
||||
|
||||
PyObject *KXpy_open(PyObject *self, PyObject *args) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Sandbox: open() function disabled!\nGame Scripts should not use this function.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyObject *KXpy_file(PyObject *self, PyObject *args) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Sandbox: file() function disabled!\nGame Scripts should not use this function.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyObject *KXpy_execfile(PyObject *self, PyObject *args) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Sandbox: execfile() function disabled!\nGame Scripts should not use this function.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyObject *KXpy_compile(PyObject *self, PyObject *args) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Sandbox: compile() function disabled!\nGame Scripts should not use this function.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyObject *KXpy_import(PyObject *self, PyObject *args)
|
||||
{
|
||||
char *name;
|
||||
int found;
|
||||
PyObject *globals = NULL;
|
||||
PyObject *locals = NULL;
|
||||
PyObject *fromlist = NULL;
|
||||
PyObject *l, *m, *n;
|
||||
int level; /* not used yet */
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s|OOOi:m_import",
|
||||
&name, &globals, &locals, &fromlist, &level))
|
||||
return NULL;
|
||||
|
||||
/* check for builtin modules */
|
||||
m = PyImport_AddModule("sys");
|
||||
l = PyObject_GetAttrString(m, "builtin_module_names");
|
||||
n = PyUnicode_FromString(name);
|
||||
|
||||
if (PySequence_Contains(l, n)) {
|
||||
return PyImport_ImportModuleEx(name, globals, locals, fromlist);
|
||||
}
|
||||
|
||||
/* quick hack for GamePython modules
|
||||
TODO: register builtin modules properly by ExtendInittab */
|
||||
if (!strcmp(name, "GameLogic") || !strcmp(name, "GameKeys") || !strcmp(name, "PhysicsConstraints") ||
|
||||
!strcmp(name, "Rasterizer") || !strcmp(name, "mathutils") || !strcmp(name, "bgl") || !strcmp(name, "geometry")) {
|
||||
return PyImport_ImportModuleEx(name, globals, locals, fromlist);
|
||||
}
|
||||
|
||||
/* Import blender texts as python modules */
|
||||
m= bpy_text_import_name(name, &found);
|
||||
if (m)
|
||||
return m;
|
||||
|
||||
if(found==0) /* if its found but could not import then it has its own error */
|
||||
PyErr_Format(PyExc_ImportError, "Import of external Module %.20s not allowed.", name);
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
PyObject *KXpy_reload(PyObject *self, PyObject *args) {
|
||||
|
||||
/* Used to be sandboxed, bettet to allow importing of internal text only */
|
||||
#if 0
|
||||
PyErr_SetString(PyExc_RuntimeError, "Sandbox: reload() function disabled!\nGame Scripts should not use this function.");
|
||||
return NULL;
|
||||
#endif
|
||||
int found;
|
||||
PyObject *module = NULL;
|
||||
PyObject *newmodule = NULL;
|
||||
|
||||
/* check for a module arg */
|
||||
if( !PyArg_ParseTuple( args, "O:bpy_reload_meth", &module ) )
|
||||
return NULL;
|
||||
|
||||
newmodule= bpy_text_reimport( module, &found );
|
||||
if (newmodule)
|
||||
return newmodule;
|
||||
|
||||
if (found==0) /* if its found but could not import then it has its own error */
|
||||
PyErr_SetString(PyExc_ImportError, "reload(module): failed to reload from blenders internal text");
|
||||
|
||||
return newmodule;
|
||||
}
|
||||
|
||||
/* override python file type functions */
|
||||
#if 0
|
||||
static int
|
||||
file_init(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
KXpy_file(NULL, NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
file_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
return KXpy_file(NULL, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
static PyMethodDef meth_open[] = {{ "open", KXpy_open, METH_VARARGS, "(disabled)"}};
|
||||
static PyMethodDef meth_reload[] = {{ "reload", KXpy_reload, METH_VARARGS, "(disabled)"}};
|
||||
static PyMethodDef meth_file[] = {{ "file", KXpy_file, METH_VARARGS, "(disabled)"}};
|
||||
static PyMethodDef meth_execfile[] = {{ "execfile", KXpy_execfile, METH_VARARGS, "(disabled)"}};
|
||||
static PyMethodDef meth_compile[] = {{ "compile", KXpy_compile, METH_VARARGS, "(disabled)"}};
|
||||
|
||||
static PyMethodDef meth_import[] = {{ "import", KXpy_import, METH_VARARGS, "our own import"}};
|
||||
|
||||
//static PyObject *g_oldopen = 0;
|
||||
//static PyObject *g_oldimport = 0;
|
||||
//static int g_security = 0;
|
||||
|
||||
static void setSandbox(TPythonSecurityLevel level)
|
||||
{
|
||||
PyObject *m = PyImport_AddModule("__builtin__");
|
||||
PyObject *d = PyModule_GetDict(m);
|
||||
PyObject *item;
|
||||
switch (level) {
|
||||
case psl_Highest:
|
||||
//if (!g_security) {
|
||||
//g_oldopen = PyDict_GetItemString(d, "open");
|
||||
|
||||
// functions we cant trust
|
||||
PyDict_SetItemString(d, "open", item=PyCFunction_New(meth_open, NULL)); Py_DECREF(item);
|
||||
PyDict_SetItemString(d, "reload", item=PyCFunction_New(meth_reload, NULL)); Py_DECREF(item);
|
||||
PyDict_SetItemString(d, "file", item=PyCFunction_New(meth_file, NULL)); Py_DECREF(item);
|
||||
PyDict_SetItemString(d, "execfile", item=PyCFunction_New(meth_execfile, NULL)); Py_DECREF(item);
|
||||
PyDict_SetItemString(d, "compile", item=PyCFunction_New(meth_compile, NULL)); Py_DECREF(item);
|
||||
|
||||
// our own import
|
||||
PyDict_SetItemString(d, "__import__", PyCFunction_New(meth_import, NULL));
|
||||
//g_security = level;
|
||||
|
||||
// Overiding file dosnt stop it being accessed if your sneaky
|
||||
// f = [ t for t in (1).__class__.__mro__[-1].__subclasses__() if t.__name__ == 'file'][0]('/some_file.txt', 'w')
|
||||
// f.write('...')
|
||||
// so overwrite the file types functions. be very careful here still, since python uses python.
|
||||
// ps - python devs frown deeply upon this.
|
||||
|
||||
/* this could mess up pythons internals, if we are serious about sandboxing
|
||||
* issues like the one above need to be solved, possibly modify __subclasses__ is safer? */
|
||||
#if 0
|
||||
PyFile_Type.tp_init = file_init;
|
||||
PyFile_Type.tp_new = file_new;
|
||||
#endif
|
||||
//}
|
||||
break;
|
||||
/*
|
||||
case psl_Lowest:
|
||||
if (g_security) {
|
||||
PyDict_SetItemString(d, "open", g_oldopen);
|
||||
PyDict_SetItemString(d, "__import__", g_oldimport);
|
||||
g_security = level;
|
||||
}
|
||||
*/
|
||||
default:
|
||||
/* Allow importing internal text, from bpy_internal_import.py */
|
||||
PyDict_SetItemString(d, "reload", item=PyCFunction_New(&bpy_reload_meth, NULL)); Py_DECREF(item);
|
||||
PyDict_SetItemString(d, "__import__", item=PyCFunction_New(&bpy_import_meth, NULL)); Py_DECREF(item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Explanation of
|
||||
*
|
||||
* - backupPySysObjects() : stores sys.path in gp_OrigPythonSysPath
|
||||
@@ -1913,8 +1766,18 @@ static void restorePySysObjects(void)
|
||||
// PyObject_Print(sys_path, stderr, 0);
|
||||
}
|
||||
|
||||
// Copied from bpy_interface.c
|
||||
static struct _inittab bge_internal_modules[]= {
|
||||
{(char *)"mathutils", BPyInit_mathutils},
|
||||
{(char *)"bgl", BPyInit_bgl},
|
||||
{(char *)"blf", BPyInit_blf},
|
||||
{(char *)"aud", AUD_initPython},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
/**
|
||||
* Python is not initialised.
|
||||
* see bpy_interface.c's BPY_python_start() which shares the same functionality in blender.
|
||||
*/
|
||||
PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecurityLevel level, Main *maggie, int argc, char** argv)
|
||||
{
|
||||
@@ -1932,6 +1795,13 @@ PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur
|
||||
#endif
|
||||
Py_NoSiteFlag=1;
|
||||
Py_FrozenFlag=1;
|
||||
|
||||
/* must run before python initializes */
|
||||
PyImport_ExtendInittab(bge_internal_modules);
|
||||
|
||||
/* find local python installation */
|
||||
PyC_SetHomePath(BLI_get_folder(BLENDER_PYTHON, NULL));
|
||||
|
||||
Py_Initialize();
|
||||
|
||||
if(argv && first_time) { /* browser plugins dont currently set this */
|
||||
@@ -1946,8 +1816,15 @@ PyObject* initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur
|
||||
PySys_SetObject("argv", py_argv);
|
||||
Py_DECREF(py_argv);
|
||||
}
|
||||
|
||||
setSandbox(level);
|
||||
|
||||
bpy_import_init(PyEval_GetBuiltins());
|
||||
|
||||
/* mathutils types are used by the BGE even if we dont import them */
|
||||
{
|
||||
PyObject *mod= PyImport_ImportModuleLevel((char *)"mathutils", NULL, NULL, NULL, 0);
|
||||
Py_DECREF(mod);
|
||||
}
|
||||
|
||||
initPyTypes();
|
||||
|
||||
bpy_import_main_set(maggie);
|
||||
@@ -1992,7 +1869,6 @@ PyObject* initGamePythonScripting(const STR_String& progname, TPythonSecurityLev
|
||||
Py_NoSiteFlag=1;
|
||||
Py_FrozenFlag=1;
|
||||
|
||||
setSandbox(level);
|
||||
initPyTypes();
|
||||
|
||||
bpy_import_main_set(maggie);
|
||||
@@ -2041,11 +1917,6 @@ void setupGamePython(KX_KetsjiEngine* ketsjiengine, KX_Scene* startscene, Main *
|
||||
|
||||
initGameKeys();
|
||||
initPythonConstraintBinding();
|
||||
initMathutils();
|
||||
initGeometry();
|
||||
initBGL();
|
||||
initBLF();
|
||||
AUD_initPython();
|
||||
initVideoTexture();
|
||||
|
||||
/* could be done a lot more nicely, but for now a quick way to get bge.* working */
|
||||
@@ -2354,26 +2225,6 @@ PyObject* initGameKeys()
|
||||
return d;
|
||||
}
|
||||
|
||||
PyObject* initMathutils()
|
||||
{
|
||||
return BPyInit_mathutils();
|
||||
}
|
||||
|
||||
PyObject* initGeometry()
|
||||
{
|
||||
return BPyInit_mathutils_geometry();
|
||||
}
|
||||
|
||||
PyObject* initBGL()
|
||||
{
|
||||
return BPyInit_bgl();
|
||||
}
|
||||
|
||||
PyObject* initBLF()
|
||||
{
|
||||
return BPyInit_blf();
|
||||
}
|
||||
|
||||
// utility function for loading and saving the globalDict
|
||||
int saveGamePythonConfig( char **marshal_buffer)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user