diff --git a/direct/src/p3d/AppRunner.py b/direct/src/p3d/AppRunner.py index 6cabdfa4e5..5ede54c820 100644 --- a/direct/src/p3d/AppRunner.py +++ b/direct/src/p3d/AppRunner.py @@ -342,10 +342,11 @@ class AppRunner(DirectObject): # Now set up Python to import this stuff. VFSImporter.register() - sys.path = [ self.multifileRoot ] + sys.path + sys.path.append(self.multifileRoot) + print "sys.path is: %s" % (sys.path) # Put our root directory on the model-path, too. - getModelPath().prependDirectory(self.multifileRoot) + getModelPath().appendDirectory(self.multifileRoot) # Replace the builtin open and file symbols so user code will get # our versions by default, which can open and read files out of diff --git a/direct/src/p3d/FileSpec.py b/direct/src/p3d/FileSpec.py index 65142d871a..30cf82087f 100644 --- a/direct/src/p3d/FileSpec.py +++ b/direct/src/p3d/FileSpec.py @@ -119,7 +119,9 @@ class FileSpec: # The hash is OK after all. Change the file's timestamp back # to what we expect it to be, so we can quick-verify it # successfully next time. + os.chmod(pathname.toOsSpecific(), 0644) os.utime(pathname.toOsSpecific(), (st.st_atime, self.timestamp)) + os.chmod(pathname.toOsSpecific(), 0444) return True diff --git a/direct/src/p3d/PackageInfo.py b/direct/src/p3d/PackageInfo.py index b61e2e4ab9..a1d035b691 100644 --- a/direct/src/p3d/PackageInfo.py +++ b/direct/src/p3d/PackageInfo.py @@ -621,12 +621,12 @@ class PackageInfo: if not foundOnPath: # Not already here; add it. - sys.path.insert(0, root) + sys.path.append(root) # Put it on the model-path, too. We do this indiscriminantly, # because the Panda3D runtime won't be adding things to the # model-path, so it shouldn't be already there. - getModelPath().prependDirectory(self.packageDir) + getModelPath().appendDirectory(self.packageDir) # Set the environment variable to reference the package root. envvar = '%s_ROOT' % (self.packageName.upper()) diff --git a/direct/src/p3d/Packager.py b/direct/src/p3d/Packager.py index c740cd46cb..205950336d 100644 --- a/direct/src/p3d/Packager.py +++ b/direct/src/p3d/Packager.py @@ -1480,6 +1480,8 @@ class Packager: # hosted. self.host = PandaSystem.getPackageHostUrl() self.hostDescriptiveName = None + self.hostMirrors = [] + self.altHosts = {} # A search list for previously-built local packages. self.installSearch = ConfigVariableSearchPath('pdef-path') @@ -1641,6 +1643,21 @@ class Packager: # file. self.contents = {} + def setHost(self, host, descriptiveName = None, mirrors = []): + """ Specifies the URL that will ultimately host these + contents. """ + + self.host = host + self.hostDescriptiveName = descriptiveName + self.hostMirrors = mirrors + + def addAltHost(self, keyword, host, descriptiveName = None, mirrors = []): + """ Adds an alternate host from which an alternate version of + these contents may be downloaded, if specified on the HTML + page. """ + + self.altHosts[keyword] = (host, descriptiveName, mirrors) + def addWindowsSearchPath(self, searchPath, varname): """ Expands $varname, interpreting as a Windows-style search path, and adds its contents to the indicated DSearchPath. """ @@ -2587,8 +2604,12 @@ class Packager: doc.InsertEndChild(decl) xcontents = TiXmlElement('contents') - if self.hostDescriptiveName: - xcontents.SetAttribute('descriptive_name', self.hostDescriptiveName) + + xhost = self.makeHostXml('host', self.host, self.hostDescriptiveName, self.hostMirrors) + xcontents.InsertEndChild(xhost) + for keyword, (host, descriptiveName, mirrors) in self.altHosts.items(): + xhost = self.makeHostXml('alt_host', host, descriptiveName, mirrors) + xcontents.InsertEndChild(xhost) contents = self.contents.items() contents.sort() @@ -2598,6 +2619,22 @@ class Packager: doc.InsertEndChild(xcontents) doc.SaveFile() + + def makeHostXml(self, element, host, descriptiveName, mirrors): + """ Constructs the or entry for the + indicated host and its mirrors. """ + + xhost = TiXmlElement(element) + xhost.SetAttribute('url', host) + if descriptiveName: + xhost.SetAttribute('descriptive_name', descriptiveName) + + for mirror in mirrors: + xmirror = TiXmlElement('mirror') + xmirror.SetAttribute('url', mirror) + xhost.InsertEndChild(xmirror) + + return xhost # The following class and function definitions represent a few sneaky diff --git a/direct/src/p3d/packp3d.py b/direct/src/p3d/packp3d.py index 56078107f7..481f990d57 100755 --- a/direct/src/p3d/packp3d.py +++ b/direct/src/p3d/packp3d.py @@ -143,6 +143,7 @@ def makePackedApp(args): packager.installDir = appDir getModelPath().appendDirectory(root) + packager.allowPythonDev = allowPythonDev try: packager.setup() @@ -156,8 +157,6 @@ def makePackedApp(args): if autoStart: packager.do_config(auto_start = True) - if allowPythonDev: - packager.do_config(allow_python_dev = True) packager.do_dir(root) packager.do_mainModule(mainModule) diff --git a/direct/src/p3d/panda3d.pdef b/direct/src/p3d/panda3d.pdef index 88d36e0c52..d1d7c53145 100755 --- a/direct/src/p3d/panda3d.pdef +++ b/direct/src/p3d/panda3d.pdef @@ -202,7 +202,8 @@ class packp3d(p3d): # the targeted runtime. config(display_name = "Panda3D Application Packer", - hidden = True, platform_specific = False) + hidden = True, platform_specific = False, + keep_user_env = True) require('panda3d', 'egg') mainModule('direct.p3d.packp3d') @@ -214,7 +215,8 @@ class ppackage(p3d): # more packages or p3d applications. config(display_name = "Panda3D General Package Utility", - hidden = True, platform_specific = False) + hidden = True, platform_specific = False, + keep_user_env = True) require('panda3d', 'egg') mainModule('direct.p3d.ppackage') diff --git a/direct/src/plugin/mkdir_complete.cxx b/direct/src/plugin/mkdir_complete.cxx index 65eaa3ecd5..44d4a54e26 100755 --- a/direct/src/plugin/mkdir_complete.cxx +++ b/direct/src/plugin/mkdir_complete.cxx @@ -17,6 +17,7 @@ #ifdef _WIN32 #include +#include // chmod() #else #include #include // for mkdir() @@ -125,6 +126,10 @@ mkdir_complete(const string &dirname, ostream &logfile) { bool mkfile_complete(const string &filename, ostream &logfile) { // Make sure we delete any previously-existing file first. +#ifdef _WIN32 + // Windows can't delete a file if it's read-only. Weird. + chmod(filename.c_str(), 0644); +#endif unlink(filename.c_str()); #ifdef _WIN32 diff --git a/direct/src/plugin/p3dInstance.cxx b/direct/src/plugin/p3dInstance.cxx index 64ac465186..160eaea268 100644 --- a/direct/src/plugin/p3dInstance.cxx +++ b/direct/src/plugin/p3dInstance.cxx @@ -312,10 +312,13 @@ set_p3d_filename(const string &p3d_filename) { //////////////////////////////////////////////////////////////////// void P3DInstance:: set_wparams(const P3DWindowParams &wparams) { - nout << "set_wparams\n"; _got_wparams = true; _wparams = wparams; + nout << "set_wparams: " << wparams.get_window_type() + << " " << wparams.get_win_width() << " " << wparams.get_win_height() + << "\n"; + if (_hidden || _wparams.get_win_width() == 0 || _wparams.get_win_height() == 0) { // If we're a hidden app, or if the window has no size, then it is // really a hidden window, regardless of what type it claims to @@ -1211,6 +1214,11 @@ scan_app_desc_file(TiXmlDocument *doc) { _allow_python_dev = (allow_python_dev != 0); } + int keep_user_env = 0; + if (xconfig->QueryIntAttribute("keep_user_env", &keep_user_env) == TIXML_SUCCESS) { + _keep_user_env = (keep_user_env != 0); + } + int auto_start = 0; if (xconfig->QueryIntAttribute("auto_start", &auto_start) == TIXML_SUCCESS) { _auto_start = (auto_start != 0); diff --git a/direct/src/plugin/p3dInstance.h b/direct/src/plugin/p3dInstance.h index 9c30f3bbe3..ddec17a44f 100644 --- a/direct/src/plugin/p3dInstance.h +++ b/direct/src/plugin/p3dInstance.h @@ -223,6 +223,7 @@ private: string _log_basename; bool _hidden; bool _allow_python_dev; + bool _keep_user_env; bool _auto_start; bool _auth_button_approved; diff --git a/direct/src/plugin/p3dPackage.cxx b/direct/src/plugin/p3dPackage.cxx index c7736ecdfe..7693bcf027 100755 --- a/direct/src/plugin/p3dPackage.cxx +++ b/direct/src/plugin/p3dPackage.cxx @@ -24,6 +24,10 @@ #include #include +#ifdef _WIN32 +#include // chmod() +#endif + // The relative breakdown of the full install process. Each phase is // worth this fraction of the total movement of the progress bar. static const double download_portion = 0.9; @@ -365,10 +369,8 @@ desc_file_download_finished(bool success) { return; } -#ifndef _WIN32 // Now that we've downloaded the desc file, make it read-only. chmod(_desc_file_pathname.c_str(), 0444); -#endif if (_package_solo) { // No need to load it: the desc file *is* the package. @@ -459,6 +461,11 @@ got_desc_file(TiXmlDocument *doc, bool freshly_downloaded) { string filename = (*ci); nout << "Removing " << filename << "\n"; string pathname = _package_dir + "/" + filename; + +#ifdef _WIN32 + // Windows can't delete a file if it's read-only. + chmod(pathname.c_str(), 0644); +#endif unlink(pathname.c_str()); } @@ -723,12 +730,13 @@ uncompress_archive() { return; } -#ifndef _WIN32 // Now that we've verified the archive, make it read-only. chmod(target_pathname.c_str(), 0444); -#endif // Now we can safely remove the compressed archive. +#ifdef _WIN32 + chmod(source_pathname.c_str(), 0644); +#endif unlink(source_pathname.c_str()); // All done uncompressing. @@ -844,9 +852,16 @@ start_download(P3DPackage::DownloadType dtype, const string &url, assert(_active_download == NULL); if (!allow_partial) { +#ifdef _WIN32 + // Windows can't delete a file if it's read-only. + chmod(pathname.c_str(), 0644); +#endif unlink(pathname.c_str()); + } else { + // Make sure the file is writable. + chmod(pathname.c_str(), 0644); } - + Download *download = new Download(this, dtype); download->set_url(url); download->set_filename(pathname); diff --git a/direct/src/plugin/p3dSession.cxx b/direct/src/plugin/p3dSession.cxx index 27f1ca1b6d..6e73c5a8e4 100644 --- a/direct/src/plugin/p3dSession.cxx +++ b/direct/src/plugin/p3dSession.cxx @@ -662,11 +662,13 @@ start_p3dpython(P3DInstance *inst) { _python_root_dir = inst->_panda3d->get_package_dir(); - // Change the current directory to the standard start directory, but - // only if the runtime environment told us the original current - // directory isn't meaningful. - _use_start_dir = !inst_mgr->get_trusted_environment(); - if (_use_start_dir) { + // If we're not to be preserving the user's current directory, then + // we'll need to change to the standard start directory. + _keep_user_env = false; + if (inst_mgr->get_trusted_environment() && inst->_keep_user_env) { + _keep_user_env = true; + } + if (!_keep_user_env) { mkdir_complete(_start_dir, nout); } @@ -759,13 +761,17 @@ start_p3dpython(P3DInstance *inst) { // Populate the new process' environment. _env = string(); - if (!inst_mgr->get_trusted_environment()) { + if (!_keep_user_env) { + // Reconstruct an environment just for running the process. + // Completely replace most of the existing environment variables + // with our own. + // These are the enviroment variables we forward from the current // environment, if they are set. const char *keep[] = { "TMP", "TEMP", "HOME", "USER", #ifdef _WIN32 - "SYSTEMROOT", "USERPROFILE", "COMSPEC", "PANDA_ROOT", + "SYSTEMROOT", "USERPROFILE", "COMSPEC", #endif #ifdef HAVE_X11 "DISPLAY", @@ -783,8 +789,9 @@ start_p3dpython(P3DInstance *inst) { } } else { - // In a trusted environment, we forward *all* environment - // variables, except those defined specifically below. + // In a trusted environment, when the application asks us to, we + // forward *all* environment variables, except those defined + // specifically below. const char *dont_keep[] = { "PATH", "LD_LIBRARY_PATH", "DYLD_LIBRARY_PATH", "PYTHONPATH", "PYTHONHOME", "PRC_PATH", "PANDA_PRC_PATH", @@ -1214,10 +1221,10 @@ win_create_process() { startup_info.wShowWindow = SW_HIDE; startup_info.dwFlags |= STARTF_USESHOWWINDOW; - // If _use_start_dir is false, meaning not to change the current - // directory, then pass NULL in to CreateProcess(). + // If _keep_user_env, meaning not to change the current directory, + // then pass NULL in to CreateProcess(). const char *start_dir_cstr = NULL; - if (_use_start_dir) { + if (!_keep_user_env) { start_dir_cstr = _start_dir.c_str(); } diff --git a/direct/src/plugin/p3dSession.h b/direct/src/plugin/p3dSession.h index d09631a689..0433150ce6 100644 --- a/direct/src/plugin/p3dSession.h +++ b/direct/src/plugin/p3dSession.h @@ -90,7 +90,7 @@ private: string _log_pathname; string _python_root_dir; string _start_dir; - bool _use_start_dir; + bool _keep_user_env; // This information is passed to create_process(), or to // p3dpython_thread_run().