|
|
|
@ -91,9 +91,9 @@ MpqWriter::MpqWriter(const char *path) |
|
|
|
const std::string dir = std::string(Dirname(path)); |
|
|
|
const std::string dir = std::string(Dirname(path)); |
|
|
|
RecursivelyCreateDir(dir.c_str()); |
|
|
|
RecursivelyCreateDir(dir.c_str()); |
|
|
|
LogVerbose("Opening {}", path); |
|
|
|
LogVerbose("Opening {}", path); |
|
|
|
|
|
|
|
bool isNewFile = false; |
|
|
|
std::string error; |
|
|
|
std::string error; |
|
|
|
bool exists = FileExists(path); |
|
|
|
if (!FileExists(path)) { |
|
|
|
if (!exists) { |
|
|
|
|
|
|
|
// FileExists() may return false in the case of an error
|
|
|
|
// FileExists() may return false in the case of an error
|
|
|
|
// so we use "ab" instead of "wb" to avoid accidentally
|
|
|
|
// so we use "ab" instead of "wb" to avoid accidentally
|
|
|
|
// truncating an existing file
|
|
|
|
// truncating an existing file
|
|
|
|
@ -112,6 +112,7 @@ MpqWriter::MpqWriter(const char *path) |
|
|
|
goto on_error; |
|
|
|
goto on_error; |
|
|
|
} |
|
|
|
} |
|
|
|
size_ = static_cast<uint32_t>(fileSize); |
|
|
|
size_ = static_cast<uint32_t>(fileSize); |
|
|
|
|
|
|
|
isNewFile = size_ == 0; |
|
|
|
LogVerbose("GetFileSize(\"{}\") = {}", path, size_); |
|
|
|
LogVerbose("GetFileSize(\"{}\") = {}", path, size_); |
|
|
|
|
|
|
|
|
|
|
|
if (!stream_.Open(path, "r+b")) { |
|
|
|
if (!stream_.Open(path, "r+b")) { |
|
|
|
@ -124,7 +125,7 @@ MpqWriter::MpqWriter(const char *path) |
|
|
|
|
|
|
|
|
|
|
|
if (blockTable_ == nullptr || hashTable_ == nullptr) { |
|
|
|
if (blockTable_ == nullptr || hashTable_ == nullptr) { |
|
|
|
MpqFileHeader fhdr; |
|
|
|
MpqFileHeader fhdr; |
|
|
|
if (!exists) { |
|
|
|
if (isNewFile) { |
|
|
|
InitDefaultMpqHeader(&fhdr); |
|
|
|
InitDefaultMpqHeader(&fhdr); |
|
|
|
} else if (!ReadMPQHeader(&fhdr)) { |
|
|
|
} else if (!ReadMPQHeader(&fhdr)) { |
|
|
|
error = "Failed to read MPQ header"; |
|
|
|
error = "Failed to read MPQ header"; |
|
|
|
@ -162,7 +163,7 @@ MpqWriter::MpqWriter(const char *path) |
|
|
|
|
|
|
|
|
|
|
|
// Write garbage header and tables because some platforms cannot `Seekp` beyond EOF.
|
|
|
|
// Write garbage header and tables because some platforms cannot `Seekp` beyond EOF.
|
|
|
|
// The data is incorrect at this point, it will be overwritten on Close.
|
|
|
|
// The data is incorrect at this point, it will be overwritten on Close.
|
|
|
|
if (!exists) |
|
|
|
if (isNewFile) |
|
|
|
WriteHeaderAndTables(); |
|
|
|
WriteHeaderAndTables(); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
|