mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
fix problems patching
This commit is contained in:
parent
892a01a4cf
commit
67d32fc172
@ -149,6 +149,12 @@ const int patchfile_buffer_size =
|
|||||||
const int patchfile_zone_size =
|
const int patchfile_zone_size =
|
||||||
config_express.GetInt("patchfile-zone-size", 10000);
|
config_express.GetInt("patchfile-zone-size", 10000);
|
||||||
|
|
||||||
|
// Set this true to keep around the temporary files from downloading,
|
||||||
|
// decompressing, and patching, or false (the default) to delete
|
||||||
|
// these. Mainly useful for debugging when the process goes wrong.
|
||||||
|
const bool keep_temporary_files =
|
||||||
|
config_express.GetBool("keep-temporary-files", false);
|
||||||
|
|
||||||
// Set this true to use the VirtualFileSystem mechanism for loading
|
// Set this true to use the VirtualFileSystem mechanism for loading
|
||||||
// models, etc. Since the VirtualFileSystem maps to the same as the
|
// models, etc. Since the VirtualFileSystem maps to the same as the
|
||||||
// actual file system by default, there is probably no reason to set
|
// actual file system by default, there is probably no reason to set
|
||||||
|
@ -46,6 +46,8 @@ extern const int patchfile_increment_size;
|
|||||||
extern const int patchfile_buffer_size;
|
extern const int patchfile_buffer_size;
|
||||||
extern const int patchfile_zone_size;
|
extern const int patchfile_zone_size;
|
||||||
|
|
||||||
|
extern const bool keep_temporary_files;
|
||||||
|
|
||||||
extern EXPCL_PANDAEXPRESS const bool use_vfs;
|
extern EXPCL_PANDAEXPRESS const bool use_vfs;
|
||||||
|
|
||||||
// Expose the Config variable for Python access.
|
// Expose the Config variable for Python access.
|
||||||
|
@ -41,6 +41,16 @@ operator == (const HashVal &other) const {
|
|||||||
hv[3] == other.hv[3]);
|
hv[3] == other.hv[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: HashVal::operator !=
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool HashVal::
|
||||||
|
operator != (const HashVal &other) const {
|
||||||
|
return !operator == (other);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: HashVal::get_value
|
// Function: HashVal::get_value
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -31,6 +31,7 @@ class EXPCL_PANDAEXPRESS HashVal {
|
|||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
INLINE HashVal();
|
INLINE HashVal();
|
||||||
INLINE bool operator == (const HashVal &other) const;
|
INLINE bool operator == (const HashVal &other) const;
|
||||||
|
INLINE bool operator != (const HashVal &other) const;
|
||||||
INLINE uint get_value(int val) const;
|
INLINE uint get_value(int val) const;
|
||||||
INLINE void set_value(int val, uint hash);
|
INLINE void set_value(int val, uint hash);
|
||||||
INLINE void output(ostream &out) const;
|
INLINE void output(ostream &out) const;
|
||||||
|
@ -18,10 +18,12 @@
|
|||||||
|
|
||||||
#include "config_express.h"
|
#include "config_express.h"
|
||||||
#include "error_utils.h"
|
#include "error_utils.h"
|
||||||
#include <stdio.h> // for tempnam
|
|
||||||
|
|
||||||
#include "patchfile.h"
|
#include "patchfile.h"
|
||||||
#include "crypto_utils.h" // MD5 stuff
|
#include "crypto_utils.h" // MD5 stuff
|
||||||
|
#include "streamReader.h"
|
||||||
|
#include "streamWriter.h"
|
||||||
|
|
||||||
|
#include <stdio.h> // for tempnam
|
||||||
|
|
||||||
// PROFILING ///////////////////////////////////////////////////////
|
// PROFILING ///////////////////////////////////////////////////////
|
||||||
//#define PROFILE_PATCH_BUILD
|
//#define PROFILE_PATCH_BUILD
|
||||||
@ -108,8 +110,6 @@ init(PT(Buffer) buffer) {
|
|||||||
_buffer = buffer;
|
_buffer = buffer;
|
||||||
|
|
||||||
reset_footprint_length();
|
reset_footprint_length();
|
||||||
|
|
||||||
_datagram.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -198,11 +198,11 @@ initiate(Filename &patch_file, Filename &file) {
|
|||||||
<< "Patchfile::initiate() - Failed to create temp file name, using default" << endl;
|
<< "Patchfile::initiate() - Failed to create temp file name, using default" << endl;
|
||||||
_temp_file = "patcher_temp_file";
|
_temp_file = "patcher_temp_file";
|
||||||
} else {
|
} else {
|
||||||
//cout << tempfilename << endl;
|
|
||||||
_temp_file = tempfilename;
|
_temp_file = tempfilename;
|
||||||
free(tempfilename);
|
free(tempfilename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_temp_file.set_binary();
|
_temp_file.set_binary();
|
||||||
if (!_temp_file.open_write(_write_stream)) {
|
if (!_temp_file.open_write(_write_stream)) {
|
||||||
express_cat.error()
|
express_cat.error()
|
||||||
@ -210,16 +210,19 @@ initiate(Filename &patch_file, Filename &file) {
|
|||||||
return get_write_error();
|
return get_write_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (express_cat.is_debug()) {
|
||||||
|
express_cat.debug()
|
||||||
|
<< "Using temporary file " << _temp_file << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
/////////////
|
/////////////
|
||||||
// read header, make sure the patch file is valid
|
// read header, make sure the patch file is valid
|
||||||
|
|
||||||
|
StreamReader patch_reader(_patch_stream);
|
||||||
|
|
||||||
// check the magic number
|
// check the magic number
|
||||||
nassertr(_buffer->get_length() >= _header_length, false);
|
nassertr(_buffer->get_length() >= _header_length, false);
|
||||||
_patch_stream.read(_buffer->_buffer, _header_length);
|
PN_uint32 magic_number = patch_reader.get_uint32();
|
||||||
_datagram.clear();
|
|
||||||
_datagram.append_data(_buffer->_buffer, _header_length);
|
|
||||||
DatagramIterator di(_datagram);
|
|
||||||
PN_uint32 magic_number = di.get_uint32();
|
|
||||||
if (magic_number != _magic_number) {
|
if (magic_number != _magic_number) {
|
||||||
express_cat.error()
|
express_cat.error()
|
||||||
<< "Patchfile::initiate() - invalid patch file: " << _patch_file << endl;
|
<< "Patchfile::initiate() - invalid patch file: " << _patch_file << endl;
|
||||||
@ -227,20 +230,16 @@ initiate(Filename &patch_file, Filename &file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get the length of the patched result file
|
// get the length of the patched result file
|
||||||
_result_file_length = di.get_uint32();
|
_result_file_length = patch_reader.get_uint32();
|
||||||
|
|
||||||
// get the MD5 of the resultant patched file
|
// get the MD5 of the resultant patched file
|
||||||
_MD5_ofResult.set_value(0, di.get_uint32());
|
_MD5_ofResult.set_value(0, patch_reader.get_uint32());
|
||||||
_MD5_ofResult.set_value(1, di.get_uint32());
|
_MD5_ofResult.set_value(1, patch_reader.get_uint32());
|
||||||
_MD5_ofResult.set_value(2, di.get_uint32());
|
_MD5_ofResult.set_value(2, patch_reader.get_uint32());
|
||||||
_MD5_ofResult.set_value(3, di.get_uint32());
|
_MD5_ofResult.set_value(3, patch_reader.get_uint32());
|
||||||
|
|
||||||
express_cat.debug()
|
express_cat.debug()
|
||||||
<< "Patchfile::initiate() - valid patchfile" << endl;
|
<< "Patchfile::initiate() - valid patchfile" << endl;
|
||||||
/*
|
|
||||||
express_cat.debug()
|
|
||||||
<< "Patchfile::initiate() - valid patchfile for file: " << name << endl;
|
|
||||||
*/
|
|
||||||
|
|
||||||
_total_bytes_processed = 0;
|
_total_bytes_processed = 0;
|
||||||
|
|
||||||
@ -270,6 +269,8 @@ run(void) {
|
|||||||
return EU_error_abort;
|
return EU_error_abort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StreamReader patch_reader(_patch_stream);
|
||||||
|
|
||||||
buflen = _buffer->get_length();
|
buflen = _buffer->get_length();
|
||||||
bytes_read = 0;
|
bytes_read = 0;
|
||||||
|
|
||||||
@ -277,11 +278,7 @@ run(void) {
|
|||||||
///////////
|
///////////
|
||||||
// read # of ADD bytes
|
// read # of ADD bytes
|
||||||
nassertr(_buffer->get_length() >= (int)sizeof(ADD_length), false);
|
nassertr(_buffer->get_length() >= (int)sizeof(ADD_length), false);
|
||||||
_patch_stream.read(_buffer->_buffer, sizeof(ADD_length));
|
ADD_length = patch_reader.get_uint16();
|
||||||
_datagram.clear();
|
|
||||||
_datagram.append_data(_buffer->_buffer, sizeof(ADD_length));
|
|
||||||
DatagramIterator di(_datagram);
|
|
||||||
ADD_length = di.get_uint16();
|
|
||||||
|
|
||||||
bytes_read += (int)ADD_length;
|
bytes_read += (int)ADD_length;
|
||||||
_total_bytes_processed += (int)ADD_length;
|
_total_bytes_processed += (int)ADD_length;
|
||||||
@ -290,7 +287,10 @@ run(void) {
|
|||||||
if (0 != ADD_length) {
|
if (0 != ADD_length) {
|
||||||
PN_uint32 bytes_left = (PN_uint32)ADD_length;
|
PN_uint32 bytes_left = (PN_uint32)ADD_length;
|
||||||
|
|
||||||
//cout << "ADD: " << ADD_length << endl;
|
if (express_cat.is_spam()) {
|
||||||
|
express_cat.spam()
|
||||||
|
<< "ADD: " << ADD_length << endl;
|
||||||
|
}
|
||||||
|
|
||||||
while (bytes_left > 0) {
|
while (bytes_left > 0) {
|
||||||
PN_uint32 bytes_this_time = (PN_uint32) min(bytes_left, (PN_uint32) buflen);
|
PN_uint32 bytes_this_time = (PN_uint32) min(bytes_left, (PN_uint32) buflen);
|
||||||
@ -303,11 +303,7 @@ run(void) {
|
|||||||
///////////
|
///////////
|
||||||
// read # of COPY bytes
|
// read # of COPY bytes
|
||||||
nassertr(_buffer->get_length() >= (int)sizeof(COPY_length), false);
|
nassertr(_buffer->get_length() >= (int)sizeof(COPY_length), false);
|
||||||
_patch_stream.read(_buffer->_buffer, sizeof(COPY_length));
|
COPY_length = patch_reader.get_uint16();
|
||||||
_datagram.clear();
|
|
||||||
_datagram.append_data(_buffer->_buffer, sizeof(COPY_length));
|
|
||||||
DatagramIterator di2(_datagram);
|
|
||||||
COPY_length = di2.get_uint16();
|
|
||||||
|
|
||||||
bytes_read += (int)COPY_length;
|
bytes_read += (int)COPY_length;
|
||||||
_total_bytes_processed += (int)COPY_length;
|
_total_bytes_processed += (int)COPY_length;
|
||||||
@ -316,13 +312,13 @@ run(void) {
|
|||||||
if (0 != COPY_length) {
|
if (0 != COPY_length) {
|
||||||
// read copy offset
|
// read copy offset
|
||||||
nassertr(_buffer->get_length() >= (int)sizeof(COPY_offset), false);
|
nassertr(_buffer->get_length() >= (int)sizeof(COPY_offset), false);
|
||||||
_patch_stream.read(_buffer->_buffer, sizeof(COPY_offset));
|
COPY_offset = patch_reader.get_uint32();
|
||||||
_datagram.clear();
|
|
||||||
_datagram.append_data(_buffer->_buffer, sizeof(COPY_offset));
|
|
||||||
DatagramIterator di(_datagram);
|
|
||||||
COPY_offset = di.get_uint32();
|
|
||||||
|
|
||||||
//cout << "COPY: " << COPY_length << " bytes at offset " << COPY_offset << endl;
|
if (express_cat.is_spam()) {
|
||||||
|
express_cat.spam()
|
||||||
|
<< "COPY: " << COPY_length << " bytes at offset " << COPY_offset
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
// seek to the offset
|
// seek to the offset
|
||||||
_origfile_stream.seekg(COPY_offset, ios::beg);
|
_origfile_stream.seekg(COPY_offset, ios::beg);
|
||||||
@ -342,24 +338,46 @@ run(void) {
|
|||||||
if ((0 == ADD_length) && (0 == COPY_length)) {
|
if ((0 == ADD_length) && (0 == COPY_length)) {
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
//cout << _result_file_length << " " << _total_bytes_processed << endl;
|
if (express_cat.is_spam()) {
|
||||||
|
express_cat.spam()
|
||||||
|
<< "result file = " << _result_file_length
|
||||||
|
<< " total bytes = " << _total_bytes_processed << endl;
|
||||||
|
}
|
||||||
|
|
||||||
// check the MD5 from the patch file against the newly patched file
|
// check the MD5 from the patch file against the newly patched file
|
||||||
{
|
{
|
||||||
HashVal MD5_actual;
|
HashVal MD5_actual;
|
||||||
md5_a_file(_temp_file, MD5_actual);
|
md5_a_file(_temp_file, MD5_actual);
|
||||||
if (memcmp((const void*)&_MD5_ofResult, (const void*)&MD5_actual, sizeof(HashVal))) {
|
if (_MD5_ofResult != MD5_actual) {
|
||||||
|
express_cat.info()
|
||||||
|
<< "Patching produced incorrect checksum. Got:\n"
|
||||||
|
<< " " << MD5_actual
|
||||||
|
<< "\nExpected:\n"
|
||||||
|
<< " " << _MD5_ofResult
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
// delete the temp file and the patch file
|
// delete the temp file and the patch file
|
||||||
_temp_file.unlink();
|
if (!keep_temporary_files) {
|
||||||
_patch_file.unlink();
|
_temp_file.unlink();
|
||||||
|
_patch_file.unlink();
|
||||||
|
}
|
||||||
// return "invalid checksum"
|
// return "invalid checksum"
|
||||||
return EU_error_invalid_checksum;
|
return EU_error_invalid_checksum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete the patch file and the original file
|
// delete the patch file and the original file
|
||||||
_patch_file.unlink();
|
if (!keep_temporary_files) {
|
||||||
_orig_file.unlink();
|
_patch_file.unlink();
|
||||||
|
_orig_file.unlink();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// If we're keeping temporary files, rename the orig file to a
|
||||||
|
// backup.
|
||||||
|
Filename orig_backup = _orig_file.get_fullpath() + ".orig";
|
||||||
|
orig_backup.unlink();
|
||||||
|
_orig_file.rename_to(orig_backup);
|
||||||
|
}
|
||||||
|
|
||||||
// rename the temp file to the original file name
|
// rename the temp file to the original file name
|
||||||
if (!_temp_file.rename_to(_orig_file)) {
|
if (!_temp_file.rename_to(_orig_file)) {
|
||||||
@ -618,17 +636,12 @@ emit_ADD(ofstream &write_stream, PN_uint16 length, const char* buffer) {
|
|||||||
//cout << "ADD: " << length << " bytes" << endl;
|
//cout << "ADD: " << length << " bytes" << endl;
|
||||||
|
|
||||||
// write ADD length
|
// write ADD length
|
||||||
_datagram.clear();
|
StreamWriter patch_writer(write_stream);
|
||||||
_datagram.add_uint16(length);
|
patch_writer.add_uint16(length);
|
||||||
string msg = _datagram.get_message();
|
|
||||||
write_stream.write((char *)msg.data(), msg.length());
|
|
||||||
|
|
||||||
// if there are bytes to add, add them
|
// if there are bytes to add, add them
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
_datagram.clear();
|
patch_writer.append_data(buffer, length);
|
||||||
_datagram.append_data(buffer, length);
|
|
||||||
string msg = _datagram.get_message();
|
|
||||||
write_stream.write((char *)msg.data(), msg.length());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -642,17 +655,12 @@ emit_COPY(ofstream &write_stream, PN_uint16 length, PN_uint32 offset) {
|
|||||||
//cout << "COPY: " << length << " bytes at offset " << offset << endl;
|
//cout << "COPY: " << length << " bytes at offset " << offset << endl;
|
||||||
|
|
||||||
// write COPY length
|
// write COPY length
|
||||||
_datagram.clear();
|
StreamWriter patch_writer(write_stream);
|
||||||
_datagram.add_uint16(length);
|
patch_writer.add_uint16(length);
|
||||||
string msg = _datagram.get_message();
|
|
||||||
write_stream.write((char *)msg.data(), msg.length());
|
|
||||||
|
|
||||||
if(length > 0) {
|
if(length > 0) {
|
||||||
// write COPY offset
|
// write COPY offset
|
||||||
_datagram.clear();
|
patch_writer.add_uint32(offset);
|
||||||
_datagram.add_uint32(offset);
|
|
||||||
string msg2 = _datagram.get_message();
|
|
||||||
write_stream.write((char *)msg2.data(), msg2.length());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -744,21 +752,19 @@ build(Filename &file_orig, Filename &file_new) {
|
|||||||
START_PROFILE(writeHeader);
|
START_PROFILE(writeHeader);
|
||||||
|
|
||||||
// write the patch file header
|
// write the patch file header
|
||||||
_datagram.clear();
|
StreamWriter patch_writer(write_stream);
|
||||||
_datagram.add_uint32(_magic_number);
|
patch_writer.add_uint32(_magic_number);
|
||||||
_datagram.add_uint32(length_new);
|
patch_writer.add_uint32(length_new);
|
||||||
{
|
{
|
||||||
// calc MD5 of resultant patched file
|
// calc MD5 of resultant patched file
|
||||||
HashVal md5New;
|
HashVal md5New;
|
||||||
md5_a_buffer((const unsigned char*)buffer_new, (int)length_new, md5New);
|
md5_a_buffer((const unsigned char*)buffer_new, (int)length_new, md5New);
|
||||||
// add it to the header
|
// add it to the header
|
||||||
_datagram.add_uint32(md5New.get_value(0));
|
patch_writer.add_uint32(md5New.get_value(0));
|
||||||
_datagram.add_uint32(md5New.get_value(1));
|
patch_writer.add_uint32(md5New.get_value(1));
|
||||||
_datagram.add_uint32(md5New.get_value(2));
|
patch_writer.add_uint32(md5New.get_value(2));
|
||||||
_datagram.add_uint32(md5New.get_value(3));
|
patch_writer.add_uint32(md5New.get_value(3));
|
||||||
}
|
}
|
||||||
string msg = _datagram.get_message();
|
|
||||||
write_stream.write((char *)msg.data(), msg.length());
|
|
||||||
|
|
||||||
END_PROFILE(writeHeader, "writing patch file header");
|
END_PROFILE(writeHeader, "writing patch file header");
|
||||||
|
|
||||||
|
@ -113,8 +113,6 @@ protected:
|
|||||||
Filename _orig_file;
|
Filename _orig_file;
|
||||||
Filename _temp_file;
|
Filename _temp_file;
|
||||||
|
|
||||||
Datagram _datagram; // used to eliminate endian problems
|
|
||||||
|
|
||||||
static const PN_uint32 _magic_number;
|
static const PN_uint32 _magic_number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user