Browse Source

coreapi version

David Rose 15 years ago
parent
commit
edab904b87

+ 5 - 2
direct/src/p3d/PackageMerger.py

@@ -43,7 +43,9 @@ class PackageMerger:
             self.descFile.loadXml(xpackage)
 
             self.packageSeq = SeqValue()
-            self.packageSeq.loadXml(xpackage)
+            self.packageSeq.loadXml(xpackage, 'seq')
+            self.packageSetVer = SeqValue()
+            self.packageSetVer.loadXml(xpackage, 'set_ver')
 
             self.importDescFile = None
             ximport = xpackage.FirstChildElement('import')
@@ -63,7 +65,8 @@ class PackageMerger:
                 xpackage.SetAttribute('solo', '1')
 
             self.descFile.storeXml(xpackage)
-            self.packageSeq.storeXml(xpackage)
+            self.packageSeq.storeXml(xpackage, 'seq')
+            self.packageSetVer.storeXml(xpackage, 'set_ver')
 
             if self.importDescFile:
                 ximport = TiXmlElement('import')

+ 41 - 9
direct/src/p3d/Packager.py

@@ -166,8 +166,13 @@ class Packager:
         file. """
         
         def __init__(self):
+            # The "seq" value increments automatically with each publish.
             self.packageSeq = SeqValue()
 
+            # The "set_ver" value is optionally specified in the pdef
+            # file and does not change unless the user says it does.
+            self.packageSetVer = SeqValue()
+
         def getKey(self):
             """ Returns a tuple used for sorting the PackageEntry
             objects uniquely per package. """
@@ -196,7 +201,10 @@ class Packager:
             self.solo = int(solo or '0')
 
             self.packageSeq = SeqValue()
-            self.packageSeq.loadXml(xpackage)
+            self.packageSeq.loadXml(xpackage, 'seq')
+
+            self.packageSetVer = SeqValue()
+            self.packageSetVer.loadXml(xpackage, 'set_ver')
 
             self.descFile = FileSpec()
             self.descFile.loadXml(xpackage)
@@ -219,7 +227,8 @@ class Packager:
             if self.solo:
                 xpackage.SetAttribute('solo', '1')
 
-            self.packageSeq.storeXml(xpackage)
+            self.packageSeq.storeXml(xpackage, 'seq')
+            self.packageSetVer.storeXml(xpackage, 'set_ver')
             self.descFile.storeXml(xpackage)
 
             if self.importDescFile:
@@ -318,6 +327,10 @@ class Packager:
             self.signParams = []
             self.requires = []
 
+            # This may be set explicitly in the pdef file to a
+            # particular sequence value.
+            self.packageSetVer = SeqValue()
+
             # This is the set of config variables assigned to the
             # package.
             self.configs = {}
@@ -679,6 +692,7 @@ class Packager:
                             False, self.packager.installDir,
                             self.packageDesc, self.packageImportDesc)
                 pe.packageSeq = self.packageSeq
+                pe.packageSetVer = self.packageSetVer
                 
                 self.packager.contents[pe.getKey()] = pe
                 self.packager.contentsChanged = True
@@ -743,6 +757,9 @@ class Packager:
             peOrig = self.packager.contents.get(pe.getKey(), None)
             if peOrig:
                 pe.packageSeq = peOrig.packageSeq + 1
+                pe.packageSetVer = peOrig.packageSetVer
+            if self.packageSetVer:
+                pe.packageSetVer = self.packageSetVer
 
             self.packager.contents[pe.getKey()] = pe
             self.packager.contentsChanged = True
@@ -1215,7 +1232,8 @@ class Packager:
                 if package.version:
                     xrequires.SetAttribute('version', package.version)
                 xrequires.SetAttribute('host', package.host)
-                package.packageSeq.storeXml(xrequires)
+                package.packageSeq.storeXml(xrequires, 'seq')
+                package.packageSetVer.storeXml(xrequires, 'set_ver')
                 requireHosts[package.host] = True
                 xpackage.InsertEndChild(xrequires)
 
@@ -1262,6 +1280,7 @@ class Packager:
             similar historic data, between sessions. """
 
             self.packageSeq = SeqValue()
+            self.packageSetVer = SeqValue()
             self.patchVersion = None
             self.patches = []
 
@@ -1276,7 +1295,8 @@ class Packager:
             if not xpackage:
                 return
 
-            self.packageSeq.loadXml(xpackage)
+            self.packageSeq.loadXml(xpackage, 'seq')
+            self.packageSetVer.loadXml(xpackage, 'set_ver')
 
             xcompressed = xpackage.FirstChildElement('compressed_archive')
             if xcompressed:
@@ -1324,7 +1344,8 @@ class Packager:
             if self.patchVersion:
                 xpackage.SetAttribute('last_patch_version', self.patchVersion)
 
-            self.packageSeq.storeXml(xpackage)
+            self.packageSeq.storeXml(xpackage, 'seq')
+            self.packageSetVer.storeXml(xpackage, 'set_ver')
 
             self.__addConfigs(xpackage)
 
@@ -1335,7 +1356,8 @@ class Packager:
                     xrequires.SetAttribute('platform', package.platform)
                 if package.version:
                     xrequires.SetAttribute('version', package.version)
-                package.packageSeq.storeXml(xrequires)
+                package.packageSeq.storeXml(xrequires, 'seq')
+                package.packageSetVer.storeXml(xrequires, 'set_ver')
                 xrequires.SetAttribute('host', package.host)
                 xpackage.InsertEndChild(xrequires)
 
@@ -1397,7 +1419,8 @@ class Packager:
                 xpackage.SetAttribute('version', self.version)
             xpackage.SetAttribute('host', self.host)
 
-            self.packageSeq.storeXml(xpackage)
+            self.packageSeq.storeXml(xpackage, 'seq')
+            self.packageSetVer.storeXml(xpackage, 'set_ver')
 
             for package in self.requires:
                 xrequires = TiXmlElement('requires')
@@ -1406,7 +1429,8 @@ class Packager:
                     xrequires.SetAttribute('platform', package.platform)
                 if package.version:
                     xrequires.SetAttribute('version', package.version)
-                package.packageSeq.storeXml(xrequires)
+                package.packageSeq.storeXml(xrequires, 'seq')
+                package.packageSetVer.storeXml(xrequires, 'set_ver')
                 xrequires.SetAttribute('host', package.host)
                 xpackage.InsertEndChild(xrequires)
 
@@ -1422,6 +1446,7 @@ class Packager:
             False on failure. """
 
             self.packageSeq = SeqValue()
+            self.packageSetVer = SeqValue()
 
             doc = TiXmlDocument(filename.toOsSpecific())
             if not doc.LoadFile():
@@ -1435,7 +1460,8 @@ class Packager:
             self.version = xpackage.Attribute('version')
             self.host = xpackage.Attribute('host')
 
-            self.packageSeq.loadXml(xpackage)
+            self.packageSeq.loadXml(xpackage, 'seq')
+            self.packageSetVer.loadXml(xpackage, 'set_ver')
 
             self.requires = []
             xrequires = xpackage.FirstChildElement('requires')
@@ -2708,6 +2734,12 @@ class Packager:
 
         return None
 
+    def do_setVer(self, value):
+        """ Sets an explicit set_ver number for the package, as a tuple
+        of integers, or as a string of dot-separated integers. """
+
+        self.currentPackage.packageSetVer = SeqValue(value)
+
     def do_config(self, **kw):
         """ Called with any number of keyword parameters.  For each
         keyword parameter, sets the corresponding p3d config variable

+ 4 - 4
direct/src/p3d/PatchMaker.py

@@ -487,9 +487,9 @@ class PatchMaker:
                 return
 
             packageSeq = SeqValue()
-            packageSeq.loadXml(xpackage)
+            packageSeq.loadXml(xpackage, 'seq')
             packageSeq += 1
-            packageSeq.storeXml(xpackage)
+            packageSeq.storeXml(xpackage, 'seq')
 
             # Remove all of the old patch entries from the desc file
             # we read earlier.
@@ -531,7 +531,7 @@ class PatchMaker:
             if doc.LoadFile():
                 xpackage = doc.FirstChildElement('package')
                 if xpackage:
-                    packageSeq.storeXml(xpackage)
+                    packageSeq.storeXml(xpackage, 'seq')
                     doc.SaveFile()
             else:
                 print "Couldn't read %s" % (importDescFullpath)
@@ -548,7 +548,7 @@ class PatchMaker:
                 # contents.xml file, mainly for documentation purposes
                 # (the authoritative seq value is within the desc
                 # file).
-                packageSeq.storeXml(self.contentsDocPackage)
+                packageSeq.storeXml(self.contentsDocPackage, 'seq')
 
 
     # PatchMaker constructor.

+ 49 - 16
direct/src/p3d/SeqValue.py

@@ -1,3 +1,5 @@
+import types
+
 class SeqValue:
 
     """ This represents a sequence value read from a contents.xml
@@ -9,44 +11,75 @@ class SeqValue:
     the series; or it may be compared with another SeqValue, which
     compares all of the integers componentwise. """
 
-    def __init__(self, *value):
+    def __init__(self, value = None):
+        self.value = ()
+        if value is not None:
+            self.set(value)
+
+    def set(self, value):
+        """ Sets the seq from the indicated value of unspecified
+        type. """
+        if isinstance(value, types.TupleType):
+            self.setFromTuple(value)
+        elif isinstance(value, types.StringTypes):
+            self.setFromString(value)
+        else:
+            raise TypeError, 'Invalid sequence type: %s' % (value,)
+
+    def setFromTuple(self, value):
+        """ Sets the seq from the indicated tuple of integers. """
+        assert isinstance(value, types.TupleType)
         self.value = value
-        if not self.value:
-            self.value = (0,)
 
-    def loadXml(self, xelement):
+    def setFromString(self, value):
+        """ Sets the seq from the indicated string of dot-separated
+        integers.  Raises ValueError on error. """
+        assert isinstance(value, types.StringTypes)
+        
+        self.value = ()
+        if value:
+            value = value.split('.')
+            value = map(int, value)
+            self.value = tuple(value)
+
+    def loadXml(self, xelement, attribute = 'seq'):
         """ Reads the seq from the indicated XML element.  Returns
         true if loaded, false if not given or if there was an
         error. """
 
-        self.value = (0,)
-        value = xelement.Attribute('seq')
+        self.value = ()
+        value = xelement.Attribute(attribute)
         if value:
-            value = value.split('.')
             try:
-                value = map(int, value)
+                self.setFromString(value)
             except ValueError:
-                value = None
-        if value:
-            self.value = tuple(value)
+                return False
             return True
+
         return False
 
 
-    def storeXml(self, xelement):
+    def storeXml(self, xelement, attribute = 'seq'):
         """ Adds the seq to the indicated XML element. """
-        value = '.'.join(map(str, self.value))
-        xelement.SetAttribute('seq', value)
+        if self.value:
+            value = '.'.join(map(str, self.value))
+            xelement.SetAttribute(attribute, value)
 
     def __add__(self, inc):
         """ Increments the seq value, returning the new value. """
-        value = self.value[:-1] + (self.value[-1] + inc,)
-        return SeqValue(*value)
+        if not self.value:
+            value = (1,)
+        else:
+            value = self.value[:-1] + (self.value[-1] + inc,)
+        return SeqValue(value)
 
     def __cmp__(self, other):
         """ Compares to another seq value. """
         return cmp(self.value, other.value)
 
+    def __bool__(self):
+        return bool(self.value)
+
     def __str__(self):
         return 'SeqValue%s' % (repr(self.value))
     

+ 2 - 1
direct/src/p3d/coreapi.pdef

@@ -1,4 +1,4 @@
-from pandac.PandaModules import getModelPath, Filename, ConfigVariableFilename, DSearchPath, ExecutionEnvironment
+from pandac.PandaModules import getModelPath, Filename, ConfigVariableFilename, DSearchPath, ExecutionEnvironment, PandaSystem
 
 # This file defines a number of standard "packages" that correspond to
 # a Panda3D distribution.  These packages are built by passing this
@@ -22,6 +22,7 @@ from pandac.PandaModules import getModelPath, Filename, ConfigVariableFilename,
 class coreapi(solo):
     # The special "coreapi" package.  As a "solo", this is just a
     # single .dll (or dylib, or whatever).
+    setVer(PandaSystem.getP3dCoreapiVersionString())
     file('p3d_plugin.dll')
 
 class images(package):

+ 3 - 2
direct/src/plugin/p3dInstance.cxx

@@ -199,8 +199,8 @@ P3DInstance(P3D_request_ready_func *func,
     stream << "c";
   }
   
-// The plugin version as a single number, with three digits reserved
-// for each component.
+  // The plugin version as a single number, with three digits reserved
+  // for each component.
   int numeric_version = 
     inst_mgr->get_plugin_major_version() * 1000000 + 
     inst_mgr->get_plugin_minor_version() * 1000 + 
@@ -221,6 +221,7 @@ P3DInstance(P3D_request_ready_func *func,
   time_t timestamp = inst_mgr->get_coreapi_timestamp();
   _panda_script_object->set_int_property("coreapiTimestamp", (int)timestamp);
   _panda_script_object->set_string_property("coreapiTimestampString", ctime(&timestamp));
+  _panda_script_object->set_string_property("coreapiVersionString", inst_mgr->get_coreapi_set_ver());
 
 
   // We'll start off with the "download" image displayed in the splash

+ 14 - 0
direct/src/plugin/p3dInstanceManager.I

@@ -282,6 +282,20 @@ get_coreapi_timestamp() const {
   return _coreapi_timestamp;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: P3DInstanceManager::get_coreapi_set_ver
+//       Access: Public
+//  Description: Returns the version number associated with the Core
+//               API, if provided.  Some early versions of the Core
+//               API, and some early versions of the plugin, did not
+//               provide a number here.  If provided, this will be a
+//               string of dot-separated integers.
+////////////////////////////////////////////////////////////////////
+inline const string &P3DInstanceManager::
+get_coreapi_set_ver() const {
+  return _coreapi_set_ver;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: P3DInstanceManager::get_super_mirror
 //       Access: Public

+ 4 - 1
direct/src/plugin/p3dInstanceManager.cxx

@@ -283,7 +283,8 @@ void P3DInstanceManager::
 set_plugin_version(int major, int minor, int sequence,
                    bool official, const string &distributor,
                    const string &coreapi_host_url,
-                   time_t coreapi_timestamp) {
+                   time_t coreapi_timestamp,
+                   const string &coreapi_set_ver) {
   reconsider_runtime_environment();
   _plugin_major_version = major;
   _plugin_minor_version = minor;
@@ -292,6 +293,7 @@ set_plugin_version(int major, int minor, int sequence,
   _plugin_distributor = distributor;
   _coreapi_host_url = coreapi_host_url;
   _coreapi_timestamp = coreapi_timestamp;
+  _coreapi_set_ver = coreapi_set_ver;
 
   nout << "Plugin version: "
        << _plugin_major_version << "."
@@ -303,6 +305,7 @@ set_plugin_version(int major, int minor, int sequence,
   nout << "\n";
   nout << "Plugin distributor: " << _plugin_distributor << "\n";
   nout << "Core API host URL: " <<  _coreapi_host_url << "\n";
+  nout << "Core API version: " << _coreapi_set_ver << "\n";
   nout << "Core API date: " << ctime(&_coreapi_timestamp) << "\n";
 }
 

+ 4 - 1
direct/src/plugin/p3dInstanceManager.h

@@ -78,7 +78,8 @@ public:
   void set_plugin_version(int major, int minor, int sequence,
                           bool official, const string &distributor,
                           const string &coreapi_host_url,
-                          time_t coreapi_timestamp);
+                          time_t coreapi_timestamp,
+                          const string &coreapi_set_ver);
   inline int get_plugin_major_version() const;
   inline int get_plugin_minor_version() const;
   inline int get_plugin_sequence_version() const;
@@ -86,6 +87,7 @@ public:
   inline const string &get_plugin_distributor() const;
   inline const string &get_coreapi_host_url() const;
   inline time_t get_coreapi_timestamp() const;
+  inline const string &get_coreapi_set_ver() const;
 
   void set_super_mirror(const string &super_mirror_url);
   inline const string &get_super_mirror() const;
@@ -178,6 +180,7 @@ private:
   string _plugin_distributor;
   string _coreapi_host_url;
   time_t _coreapi_timestamp;
+  string _coreapi_set_ver;
   string _super_mirror_url;
 
   P3D_object *_undefined_object;

+ 9 - 3
direct/src/plugin/p3d_plugin.cxx

@@ -80,7 +80,7 @@ P3D_initialize(int api_version, const char *contents_filename,
     log_basename = "";
   }
   
-  if (P3D_API_VERSION < 12 || root_dir == NULL) {
+  if (api_version < 12 || root_dir == NULL) {
     root_dir = "";
   }
 
@@ -104,7 +104,8 @@ void
 P3D_set_plugin_version(int major, int minor, int sequence,
                        bool official, const char *distributor,
                        const char *coreapi_host_url,
-                       time_t coreapi_timestamp) {
+                       time_t coreapi_timestamp,
+                       const char *coreapi_set_ver) {
   assert(P3DInstanceManager::get_global_ptr()->is_initialized());
   if (distributor == NULL) {
     distributor = "";
@@ -115,8 +116,13 @@ P3D_set_plugin_version(int major, int minor, int sequence,
 
   ACQUIRE_LOCK(_api_lock);
   P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
+  if (inst_mgr->get_api_version() < 14 || coreapi_set_ver == NULL) {
+    coreapi_set_ver = "";
+  }
+
   inst_mgr->set_plugin_version(major, minor, sequence, official, distributor,
-                               coreapi_host_url, coreapi_timestamp);
+                               coreapi_host_url, coreapi_timestamp,
+                               coreapi_set_ver);
   RELEASE_LOCK(_api_lock);
 }
 

+ 3 - 2
direct/src/plugin/p3d_plugin.h

@@ -79,7 +79,7 @@ extern "C" {
    (below). This number will be incremented whenever there are changes
    to any of the interface specifications defined in this header
    file. */
-#define P3D_API_VERSION 13
+#define P3D_API_VERSION 14
 
 /************************ GLOBAL FUNCTIONS **************************/
 
@@ -168,7 +168,8 @@ typedef void
 P3D_set_plugin_version_func(int major, int minor, int sequence,
                             bool official, const char *distributor,
                             const char *coreapi_host_url,
-                            time_t coreapi_timestamp);
+                            time_t coreapi_timestamp,
+                            const char *coreapi_set_ver);
 
 /* This function defines a "super mirror" URL: a special URL that is
    consulted first whenever downloading any package referenced by a

+ 4 - 3
direct/src/plugin_activex/PPInstance.cpp

@@ -510,9 +510,10 @@ int PPInstance::LoadPlugin( const std::string& dllFilename )
         static const bool official = false;
 #endif
         P3D_set_plugin_version_ptr(P3D_PLUGIN_MAJOR_VERSION, P3D_PLUGIN_MINOR_VERSION,
-                               P3D_PLUGIN_SEQUENCE_VERSION, official,
-                               PANDA_DISTRIBUTOR,
-                               PANDA_PACKAGE_HOST_URL, _core_api_dll.get_timestamp());
+                                   P3D_PLUGIN_SEQUENCE_VERSION, official,
+                                   PANDA_DISTRIBUTOR,
+                                   PANDA_PACKAGE_HOST_URL, _core_api_dll.get_timestamp(),
+                                   "");
 
       }
     }

+ 19 - 13
direct/src/plugin_npapi/ppInstance.cxx

@@ -1210,13 +1210,18 @@ read_contents_file(const string &contents_filename, bool fresh_download) {
     find_host(xcontents);
 
     // Now look for the core API package.
+    _coreapi_set_ver = "";
     TiXmlElement *xpackage = xcontents->FirstChildElement("package");
     while (xpackage != NULL) {
       const char *name = xpackage->Attribute("name");
       if (name != NULL && strcmp(name, "coreapi") == 0) {
         const char *platform = xpackage->Attribute("platform");
         if (platform != NULL && strcmp(platform, DTOOL_PLATFORM) == 0) {
-          _core_api_dll.load_xml(xpackage);
+          _coreapi_dll.load_xml(xpackage);
+          const char *set_ver = xpackage->Attribute("set_ver");
+          if (set_ver != NULL) {
+            _coreapi_set_ver = set_ver;
+          }
           found_core_package = true;
           break;
         }
@@ -1428,7 +1433,7 @@ send_p3d_temp_file_data() {
 ////////////////////////////////////////////////////////////////////
 void PPInstance::
 get_core_api() {
-  if (_core_api_dll.quick_verify(_root_dir)) {
+  if (_coreapi_dll.quick_verify(_root_dir)) {
     // The DLL file is good.  Just load it.
     do_load_plugin();
 
@@ -1440,7 +1445,7 @@ get_core_api() {
     // Our last act of desperation: hit the original host, with a
     // query uniquifier, to break through any caches.
     ostringstream strm;
-    strm << _download_url_prefix << _core_api_dll.get_filename()
+    strm << _download_url_prefix << _coreapi_dll.get_filename()
          << "?" << time(NULL);
     url = strm.str();
     _core_urls.push_back(url);
@@ -1448,7 +1453,7 @@ get_core_api() {
     // Before we try that, we'll hit the original host, without a
     // uniquifier.
     url = _download_url_prefix;
-    url += _core_api_dll.get_filename();
+    url += _coreapi_dll.get_filename();
     _core_urls.push_back(url);
 
     // And before we try that, we'll try two mirrors, at random.
@@ -1457,7 +1462,7 @@ get_core_api() {
     for (vector<string>::iterator si = mirrors.begin();
          si != mirrors.end(); 
          ++si) {
-      url = (*si) + _core_api_dll.get_filename();
+      url = (*si) + _coreapi_dll.get_filename();
       _core_urls.push_back(url);
     }
 
@@ -1492,8 +1497,8 @@ downloaded_plugin(const string &filename) {
   }
 
   // Make sure the DLL was correctly downloaded before continuing.
-  if (!_core_api_dll.quick_verify_pathname(filename)) {
-    nout << "After download, " << _core_api_dll.get_filename() << " is no good.\n";
+  if (!_coreapi_dll.quick_verify_pathname(filename)) {
+    nout << "After download, " << _coreapi_dll.get_filename() << " is no good.\n";
 
     // That DLL came out wrong.  Try the next URL.
     if (!_core_urls.empty()) {
@@ -1510,14 +1515,14 @@ downloaded_plugin(const string &filename) {
   }
 
   // Copy the file onto the target.
-  string pathname = _core_api_dll.get_pathname(_root_dir);
+  string pathname = _coreapi_dll.get_pathname(_root_dir);
   if (!copy_file(filename, pathname)) {
     nout << "Couldn't copy " << pathname << "\n";
     set_failed();
     return;
   }
 
-  if (!_core_api_dll.quick_verify(_root_dir)) {
+  if (!_coreapi_dll.quick_verify(_root_dir)) {
     nout << "After copying, " << pathname << " is no good.\n";
     set_failed();
     return;
@@ -1537,7 +1542,7 @@ downloaded_plugin(const string &filename) {
 ////////////////////////////////////////////////////////////////////
 void PPInstance::
 do_load_plugin() {
-  string pathname = _core_api_dll.get_pathname(_root_dir);
+  string pathname = _coreapi_dll.get_pathname(_root_dir);
 
 #ifdef P3D_PLUGIN_P3D_PLUGIN
   // This is a convenience macro for development.  If defined and
@@ -1567,9 +1572,10 @@ do_load_plugin() {
   static const bool official = false;
 #endif
   P3D_set_plugin_version_ptr(P3D_PLUGIN_MAJOR_VERSION, P3D_PLUGIN_MINOR_VERSION,
-                         P3D_PLUGIN_SEQUENCE_VERSION, official,
-                         PANDA_DISTRIBUTOR,
-                         PANDA_PACKAGE_HOST_URL, _core_api_dll.get_timestamp());
+                             P3D_PLUGIN_SEQUENCE_VERSION, official,
+                             PANDA_DISTRIBUTOR,
+                             PANDA_PACKAGE_HOST_URL, _coreapi_dll.get_timestamp(),
+                             _coreapi_set_ver.c_str());
 
   create_instance();
 }

+ 2 - 1
direct/src/plugin_npapi/ppInstance.h

@@ -139,7 +139,8 @@ private:
   typedef vector<string> CoreUrls;
   CoreUrls _core_urls;
 
-  FileSpec _core_api_dll;
+  string _coreapi_set_ver;
+  FileSpec _coreapi_dll;
   time_t _contents_expiration;
   bool _failed;
   bool _started;

+ 16 - 10
direct/src/plugin_standalone/panda3d.cxx

@@ -508,13 +508,18 @@ read_contents_file(const Filename &contents_filename, bool fresh_download) {
     find_host(xcontents);
 
     // Now look for the core API package.
+    _coreapi_set_ver = "";
     TiXmlElement *xpackage = xcontents->FirstChildElement("package");
     while (xpackage != NULL) {
       const char *name = xpackage->Attribute("name");
       if (name != NULL && strcmp(name, "coreapi") == 0) {
         const char *platform = xpackage->Attribute("platform");
         if (platform != NULL && _this_platform == string(platform)) {
-          _core_api_dll.load_xml(xpackage);
+          _coreapi_dll.load_xml(xpackage);
+          const char *set_ver = xpackage->Attribute("set_ver");
+          if (set_ver != NULL) {
+            _coreapi_set_ver = set_ver;
+          }
           found_core_package = true;
           break;
         }
@@ -684,7 +689,7 @@ choose_random_mirrors(vector_string &result, int num_mirrors) {
 ////////////////////////////////////////////////////////////////////
 bool Panda3D::
 get_core_api() {
-  if (!_core_api_dll.quick_verify(_root_dir)) {
+  if (!_coreapi_dll.quick_verify(_root_dir)) {
     // The DLL file needs to be downloaded.  Build up our list of
     // URL's to attempt to download it from, in reverse order.
     string url;
@@ -693,7 +698,7 @@ get_core_api() {
     // Our last act of desperation: hit the original host, with a
     // query uniquifier, to break through any caches.
     ostringstream strm;
-    strm << _download_url_prefix << _core_api_dll.get_filename()
+    strm << _download_url_prefix << _coreapi_dll.get_filename()
          << "?" << time(NULL);
     url = strm.str();
     core_urls.push_back(url);
@@ -701,7 +706,7 @@ get_core_api() {
     // Before we try that, we'll hit the original host, without a
     // uniquifier.
     url = _download_url_prefix;
-    url += _core_api_dll.get_filename();
+    url += _coreapi_dll.get_filename();
     core_urls.push_back(url);
 
     // And before we try that, we'll try two mirrors, at random.
@@ -710,20 +715,20 @@ get_core_api() {
     for (vector_string::iterator si = mirrors.begin();
          si != mirrors.end(); 
          ++si) {
-      url = (*si) + _core_api_dll.get_filename();
+      url = (*si) + _coreapi_dll.get_filename();
       core_urls.push_back(url);
     }
 
     // The very first thing we'll try is the super_mirror, if we have
     // one.
     if (!_super_mirror_url_prefix.empty()) {
-      url = _super_mirror_url_prefix + _core_api_dll.get_filename();
+      url = _super_mirror_url_prefix + _coreapi_dll.get_filename();
       core_urls.push_back(url);
     }
 
     // Now pick URL's off the list, and try them, until we have
     // success.
-    Filename pathname = Filename::from_os_specific(_core_api_dll.get_pathname(_root_dir));
+    Filename pathname = Filename::from_os_specific(_coreapi_dll.get_pathname(_root_dir));
     pathname.make_dir();
     HTTPClient *http = HTTPClient::get_global_ptr();
 
@@ -736,7 +741,7 @@ get_core_api() {
       if (!channel->download_to_file(pathname)) {
         cerr << "Unable to download " << url << "\n";
 
-      } else if (!_core_api_dll.full_verify(_root_dir)) {
+      } else if (!_coreapi_dll.full_verify(_root_dir)) {
         cerr << "Mismatched download for " << url << "\n";
 
       } else {
@@ -759,7 +764,7 @@ get_core_api() {
   }
 
   // Now we've got the DLL.  Load it.
-  string pathname = _core_api_dll.get_pathname(_root_dir);
+  string pathname = _coreapi_dll.get_pathname(_root_dir);
 
 #ifdef P3D_PLUGIN_P3D_PLUGIN
   // This is a convenience macro for development.  If defined and
@@ -793,7 +798,8 @@ get_core_api() {
   P3D_set_plugin_version_ptr(P3D_PLUGIN_MAJOR_VERSION, P3D_PLUGIN_MINOR_VERSION,
                              P3D_PLUGIN_SEQUENCE_VERSION, official,
                              PANDA_DISTRIBUTOR,
-                             _host_url.c_str(), _core_api_dll.get_timestamp());
+                             _host_url.c_str(), _coreapi_dll.get_timestamp(),
+                             _coreapi_set_ver.c_str());
 
   return true;
 }

+ 2 - 1
direct/src/plugin_standalone/panda3d.h

@@ -54,7 +54,8 @@ protected:
   typedef pvector<string> Mirrors;
   Mirrors _mirrors;
   
-  FileSpec _core_api_dll;
+  string _coreapi_set_ver;
+  FileSpec _coreapi_dll;
 };
 
 #include "panda3d.I"