uninstall wip, utf-8

This commit is contained in:
David Rose 2009-12-18 23:42:09 +00:00
parent d477cf1615
commit 1d7fd44214
13 changed files with 179 additions and 32 deletions

View File

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

View File

@ -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:

View File

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

View File

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

View File

@ -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);
}
}

View File

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

View File

@ -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);
}

View File

@ -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;

View File

@ -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());

View File

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

View File

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

View File

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

View File

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