synched with trunk at revision 36569

This commit is contained in:
Nick Samarin
2011-05-16 20:30:59 +00:00
2918 changed files with 120495 additions and 74841 deletions

View File

@@ -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)
{