Explorar o código

uninstall wip, utf-8

David Rose %!s(int64=16) %!d(string=hai) anos
pai
achega
1d7fd44214

+ 3 - 3
direct/src/distributed/ConnectionRepository.py

@@ -641,9 +641,9 @@ class ConnectionRepository(
         # Zero-length datagrams might freak out the server.  No point
         # in sending them, anyway.
         if datagram.getLength() > 0:
-            if self.notify.getDebug():
-                print "ConnectionRepository sending datagram:"
-                datagram.dumpHex(ostream)
+##             if self.notify.getDebug():
+##                 print "ConnectionRepository sending datagram:"
+##                 datagram.dumpHex(ostream)
 
             self.sendDatagram(datagram)
 

+ 3 - 3
direct/src/distributed/ServerRepository.py

@@ -340,7 +340,7 @@ class ServerRepository:
         if self.notify.getDebug():
             self.notify.debug(
                 "ServerRepository received datagram from %s:" % (client.doIdBase))
-            datagram.dumpHex(ostream)
+            #datagram.dumpHex(ostream)
 
         if not client:
             # This shouldn't be possible.
@@ -689,7 +689,7 @@ class ServerRepository:
         if self.notify.getDebug():
             self.notify.debug(
                 "ServerRepository sending to all in zone %s except %s:" % (zoneId, map(lambda c: c.doIdBase, exceptionList)))
-            datagram.dumpHex(ostream)
+            #datagram.dumpHex(ostream)
 
         for client in self.zonesToClients.get(zoneId, []):
             if client not in exceptionList:
@@ -706,7 +706,7 @@ class ServerRepository:
         if self.notify.getDebug():
             self.notify.debug(
                 "ServerRepository sending to all except %s:" % (map(lambda c: c.doIdBase, exceptionList),))
-            datagram.dumpHex(ostream)
+            #datagram.dumpHex(ostream)
 
         for client in self.clientsByConnection.values():
             if client not in exceptionList:

+ 21 - 0
direct/src/plugin/p3dInstance.cxx

@@ -1315,6 +1315,27 @@ auth_finished_main_thread() {
   check_p3d_signature();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: P3DInstance::uninstall
+//       Access: Public
+//  Description: Stops the instance (if it is running) and deletes any
+//               packages referenced by the instance.  This is
+//               normally called by JavaScript, via
+//               P3DMainObject::call_uninstall().
+////////////////////////////////////////////////////////////////////
+void P3DInstance::
+uninstall() {
+  if (_session != NULL) {
+    _session->shutdown();
+  }
+
+  Packages::const_iterator pi;
+  for (pi = _packages.begin(); pi != _packages.end(); ++pi) {
+    P3DPackage *package = (*pi);
+    package->uninstall();
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: P3DInstance::priv_set_p3d_filename
 //       Access: Private

+ 2 - 0
direct/src/plugin/p3dInstance.h

@@ -116,6 +116,8 @@ public:
   void auth_finished_sub_thread();
   void auth_finished_main_thread();
 
+  void uninstall();
+
 private:
   class ImageDownload : public P3DFileDownload {
   public:

+ 12 - 7
direct/src/plugin/p3dInstanceManager.cxx

@@ -1067,10 +1067,11 @@ scan_directory(const string &dirname, vector<string> &contents) {
 ////////////////////////////////////////////////////////////////////
 //     Function: P3DInstanceManager::scan_directory_recursively
 //       Access: Public, Static
-//  Description: Fills up the indicated vector with the list of all
-//               files (but not directories) rooted at the indicated
-//               dirname and below.  The filenames generated are
-//               relative to the root of the dirname, with slashes
+//  Description: Fills up filename_contents with the list of all
+//               files (but not directories), and dirname_contents
+//               with the list of all directories, rooted at the
+//               indicated dirname and below.  The filenames generated
+//               are relative to the root of the dirname, with slashes
 //               (not backslashes) as the directory separator
 //               character.
 //
@@ -1078,7 +1079,9 @@ scan_directory(const string &dirname, vector<string> &contents) {
 //               dirname wasn't a directory or something like that.
 ////////////////////////////////////////////////////////////////////
 bool P3DInstanceManager::
-scan_directory_recursively(const string &dirname, vector<string> &contents,
+scan_directory_recursively(const string &dirname, 
+                           vector<string> &filename_contents,
+                           vector<string> &dirname_contents,
                            const string &prefix) {
   vector<string> dir_contents;
   if (!scan_directory(dirname, dir_contents)) {
@@ -1093,14 +1096,16 @@ scan_directory_recursively(const string &dirname, vector<string> &contents,
     // directory, or is it a regular file?
     string pathname = dirname + "/" + (*si);
     string rel_filename = prefix + (*si);
-    if (scan_directory_recursively(pathname, contents, rel_filename + "/")) {
+    if (scan_directory_recursively(pathname, filename_contents, 
+                                   dirname_contents, rel_filename + "/")) {
       // It's a directory, and it's just added its results to the
       // contents.
+      dirname_contents.push_back(rel_filename);
 
     } else {
       // It's not a directory, so assume it's an ordinary file, and
       // add it to the contents.
-      contents.push_back(rel_filename);
+      filename_contents.push_back(rel_filename);
     }
   }
 

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

@@ -131,7 +131,9 @@ public:
 
   static inline char encode_hexdigit(int c);
   static bool scan_directory(const string &dirname, vector<string> &contents);
-  static bool scan_directory_recursively(const string &dirname, vector<string> &contents,
+  static bool scan_directory_recursively(const string &dirname, 
+                                         vector<string> &filename_contents,
+                                         vector<string> &dirname_contents,
                                          const string &prefix = "");
   static bool remove_file_from_list(vector<string> &contents, const string &filename);
 

+ 25 - 0
direct/src/plugin/p3dMainObject.cxx

@@ -191,6 +191,8 @@ has_method(const string &method_name) {
     return true;
   } else if (method_name == "read_system_log") {
     return true;
+  } else if (method_name == "uninstall") {
+    return true;
   }
 
   if (_pyobj == NULL) {
@@ -225,6 +227,8 @@ call(const string &method_name, bool needs_response,
     return call_read_game_log(params, num_params);
   } else if (method_name == "read_system_log") {
     return call_read_system_log(params, num_params);
+  } else if (method_name == "uninstall") {
+    return call_uninstall(params, num_params);
   }
 
   if (_pyobj == NULL) {
@@ -435,3 +439,24 @@ read_log(const string &log_pathname, P3D_object *params[], int num_params) {
 
   return result;
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DMainObject::call_uninstall
+//       Access: Private
+//  Description: Implements the uninstall() plugin method, which
+//               removes all Panda installed files for a particular
+//               host, or referenced by a particular p3d file.
+////////////////////////////////////////////////////////////////////
+P3D_object *P3DMainObject::
+call_uninstall(P3D_object *params[], int num_params) {
+  P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
+
+  if (_inst != NULL) {
+    nout << "uninstall for " << _inst << "\n";
+    _inst->uninstall();
+    return inst_mgr->new_bool_object(true);
+  }
+
+  nout << "couldn't uninstall; no instance.\n";
+  return inst_mgr->new_bool_object(false);
+}

+ 1 - 0
direct/src/plugin/p3dMainObject.h

@@ -73,6 +73,7 @@ private:
   P3D_object *call_read_system_log(P3D_object *params[], int num_params);
   P3D_object *read_log(const string &log_pathname, 
                        P3D_object *params[], int num_params);
+  P3D_object *call_uninstall(P3D_object *params[], int num_params);
 
 private:
   P3D_object *_pyobj;

+ 81 - 7
direct/src/plugin/p3dPackage.cxx

@@ -206,6 +206,78 @@ remove_instance(P3DInstance *inst) {
   begin_info_download();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: P3DPackage::uninstall
+//       Access: Public
+//  Description: Removes the package directory and all its contents
+//               from the user's hard disk.
+////////////////////////////////////////////////////////////////////
+void P3DPackage::
+uninstall() {
+  if (_package_dir.empty()) {
+    nout << "Cannot uninstall " << _package_name << ": package directory not yet known.\n";
+    return;
+  }
+
+  nout << "Uninstalling package " << _package_name << " from " << _package_dir << "\n";
+
+  P3DInstanceManager *inst_mgr = P3DInstanceManager::get_global_ptr();
+  vector<string> contents, dirname_contents;
+  inst_mgr->scan_directory_recursively(_package_dir, contents,
+                                       dirname_contents);
+
+  vector<string>::iterator ci;
+  for (ci = contents.begin(); ci != contents.end(); ++ci) {
+    string filename = (*ci);
+    string pathname = _package_dir + "/" + filename;
+
+#ifdef _WIN32
+    // Windows can't delete a file if it's read-only.
+    chmod(pathname.c_str(), 0644);
+#endif
+    int result = unlink(pathname.c_str());
+    if (result == 0) {
+      nout << "  Deleted " << filename << "\n";
+    } else {
+      nout << "  Could not delete " << filename << "\n";
+    }
+  }
+
+  // Now delete all of the directories too.  Go in reverse order so we
+  // remove deeper directories first.
+  vector<string>::reverse_iterator rci;
+  for (rci = dirname_contents.rbegin(); rci != dirname_contents.rend(); ++rci) {
+    string filename = (*rci);
+    string pathname = _package_dir + "/" + filename;
+
+#ifdef _WIN32
+    chmod(pathname.c_str(), 0755);
+#endif
+    int result = rmdir(pathname.c_str());
+    if (result == 0) {
+      nout << "  Removed directory " << filename << "\n";
+    } else {
+      nout << "  Could not remove directory " << filename << "\n";
+    }
+  }
+
+  // Finally, delete the package directory itself.
+  string pathname = _package_dir;
+#ifdef _WIN32
+  chmod(pathname.c_str(), 0755);
+#endif
+  int result = rmdir(pathname.c_str());
+  if (result == 0) {
+    nout << "Removed directory " << _package_dir << "\n";
+  } else {
+    nout << "Could not remove directory " << _package_dir << "\n";
+  }
+
+  _info_ready = false;
+  _ready = false;
+  _failed = false;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: P3DPackage::make_xml
 //       Access: Public
@@ -442,7 +514,7 @@ contents_file_redownload_finished(bool success) {
 //               rest of the download process.
 ////////////////////////////////////////////////////////////////////
 void P3DPackage::
-host_got_contents_file() {
+host_got_contents_file(bool continue_download) {
   if (!_alt_host.empty()) {
     // If we have an alt host specification, maybe we need to change
     // the host now.
@@ -476,10 +548,12 @@ host_got_contents_file() {
     _package_dir += string("/") + _package_version;
   }
 
-  // Ensure the package directory exists; create it if it does not.
-  mkdir_complete(_package_dir, nout);
-
-  download_desc_file();
+  if (continue_download) {
+    // Ensure the package directory exists; create it if it does not.
+    mkdir_complete(_package_dir, nout);
+    
+    download_desc_file();
+  }
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -658,8 +732,8 @@ got_desc_file(TiXmlDocument *doc, bool freshly_downloaded) {
 
   // Get a list of all of the files in the directory, so we can remove
   // files that don't belong.
-  vector<string> contents;
-  inst_mgr->scan_directory_recursively(_package_dir, contents);
+  vector<string> contents, dirname_contents;
+  inst_mgr->scan_directory_recursively(_package_dir, contents, dirname_contents);
 
   inst_mgr->remove_file_from_list(contents, _desc_file_basename);
   inst_mgr->remove_file_from_list(contents, _uncompressed_archive.get_filename());

+ 3 - 1
direct/src/plugin/p3dPackage.h

@@ -69,6 +69,8 @@ public:
   void add_instance(P3DInstance *inst);
   void remove_instance(P3DInstance *inst);
 
+  void uninstall();
+
   TiXmlElement *make_xml();
 
 private:
@@ -192,7 +194,7 @@ private:
   void contents_file_download_finished(bool success);
   void redownload_contents_file(Download *download);
   void contents_file_redownload_finished(bool success);
-  void host_got_contents_file();
+  void host_got_contents_file(bool continue_download = true);
 
   void download_desc_file();
   void desc_file_download_finished(bool success);

+ 19 - 7
direct/src/plugin/p3dPythonRun.cxx

@@ -1531,14 +1531,26 @@ pyobj_to_xml(PyObject *value) {
     }
 
   } else if (PyString_Check(value)) {
-    // A string value.
+    // A string value.  Insist that it is utf-8 encoded, by decoding
+    // it first using the standard encoding, then re-encoding it.
     xvalue->SetAttribute("type", "string");
 
-    char *buffer;
-    Py_ssize_t length;
-    if (PyString_AsStringAndSize(value, &buffer, &length) != -1) {
-      string str(buffer, length);
-      xvalue->SetAttribute("value", str);
+    PyObject *ustr = PyUnicode_FromEncodedObject(value, NULL, NULL);
+    if (ustr == NULL) {
+      PyErr_Print();
+      return xvalue;
+    } else {
+      PyObject *as_str = PyUnicode_AsUTF8String(ustr);
+      if (as_str != NULL) {
+        char *buffer;
+        Py_ssize_t length;
+        if (PyString_AsStringAndSize(as_str, &buffer, &length) != -1) {
+          string str(buffer, length);
+          xvalue->SetAttribute("value", str);
+        }
+        Py_DECREF(as_str);
+      }
+      Py_DECREF(ustr);
     }
 
   } else if (PyTuple_Check(value)) {
@@ -1685,7 +1697,7 @@ xml_to_pyobj(TiXmlElement *xvalue) {
     // don't get tripped up on embedded null characters.
     const string *value = xvalue->Attribute(string("value"));
     if (value != NULL) {
-      return PyString_FromStringAndSize(value->data(), value->length());
+      return PyUnicode_DecodeUTF8(value->data(), value->length(), NULL);
     }
 
   } else if (strcmp(type, "undefined") == 0) {

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

@@ -470,8 +470,9 @@ P3D_object_get_float_method(P3D_object *object);
    return value is larger than buffer_size, the string has been
    truncated.  If it is equal, there is no null character written to
    the buffer (like strncpy).  You may call this method first with
-   buffer = NULL and buffer_size = 0 to return just the required
-   size of the buffer. */
+   buffer = NULL and buffer_size = 0 to return just the required size
+   of the buffer.  Note that P3D_object string data is internally
+   encoded using utf-8, by convention. */
 typedef int
 P3D_object_get_string_method(P3D_object *object, 
                              char *buffer, int buffer_size);
@@ -676,7 +677,8 @@ typedef P3D_object *
 P3D_new_float_object_func(double value);
 
 /* Returns a new-reference P3D_object of type string.  The supplied
-   string is copied into the object and stored internally. */
+   string should be already encoded in utf-8.  It is copied into the
+   object and stored internally. */
 typedef P3D_object *
 P3D_new_string_object_func(const char *string, int length);
 

+ 1 - 0
direct/src/showbase/ShowBase.py

@@ -861,6 +861,7 @@ class ShowBase(DirectObject.DirectObject):
 
     def sleepCycleTask(self, task):
         Thread.sleep(self.clientSleep)
+        #time.sleep(self.clientSleep)
         return Task.cont
 
     def setFrameRateMeter(self, flag):