eupak: Fix creation timestamps

Also, PakWriter will now write a proper creation time. For unit testing/etc, I may
instead have it just take in a system_clock::time_point, but idk.
This commit is contained in:
Lily Tsuru 2025-01-07 17:56:30 -05:00
parent 3786b760fe
commit f7b80326ff
5 changed files with 21 additions and 14 deletions

View file

@ -180,7 +180,7 @@ namespace europa::io {
} }
template <class Visitor> template <class Visitor>
auto Visit(Visitor&& cb) { auto VisitTocEntry(Visitor&& cb) {
return std::visit(cb, toc); return std::visit(cb, toc);
} }

View file

@ -7,6 +7,7 @@
// //
#include <algorithm> #include <algorithm>
#include <chrono>
#include <europa/io/PakWriter.hpp> #include <europa/io/PakWriter.hpp>
#include <europa/util/TupleElement.hpp> #include <europa/util/TupleElement.hpp>
#include <filesystem> #include <filesystem>
@ -61,7 +62,7 @@ namespace europa::io {
// Sort the flattened array. // Sort the flattened array.
std::ranges::sort(sortedFiles, std::greater {}, [](const FlattenedType& elem) { std::ranges::sort(sortedFiles, std::greater {}, [](const FlattenedType& elem) {
return elem.second.GetCreationUnixTime(); return elem.second.GetSize();
}); });
// Leave space for the header // Leave space for the header
@ -85,7 +86,7 @@ namespace europa::io {
filename }); filename });
// Update the offset to where we currently are, since we will be writing the file there // Update the offset to where we currently are, since we will be writing the file there
file.Visit([&](auto& tocEntry) { file.VisitTocEntry([&](auto& tocEntry) {
tocEntry.offset = os.tellp(); tocEntry.offset = os.tellp();
}); });
@ -128,12 +129,19 @@ namespace europa::io {
sink.OnEvent({ PakProgressReportSink::PakEvent::EventCode::WritingToc }); sink.OnEvent({ PakProgressReportSink::PakEvent::EventCode::WritingToc });
#if 0
// Sort for toc stuff? idk
std::ranges::sort(sortedFiles, std::less {}, [](const FlattenedType& elem) {
return elem.second.GetCreationUnixTime();
});
#endif
// Write the TOC // Write the TOC
for(auto& [filename, file] : sortedFiles) { for(auto& [filename, file] : sortedFiles) {
// Write the filename Pascal string. // Write the filename Pascal string.
impl::WritePString(os, filename); impl::WritePString(os, filename);
file.Visit([&](auto& tocEntry) { file.VisitTocEntry([&](auto& tocEntry) {
impl::WriteStreamType(os, tocEntry); impl::WriteStreamType(os, tocEntry);
}); });
} }
@ -143,7 +151,10 @@ namespace europa::io {
// Fill out the rest of the header. // Fill out the rest of the header.
pakHeader.fileCount = sortedFiles.size(); pakHeader.fileCount = sortedFiles.size();
pakHeader.tocSize = static_cast<std::uint32_t>(os.tellp()) - (pakHeader.tocOffset - 1); pakHeader.tocSize = static_cast<std::uint32_t>(os.tellp()) - (pakHeader.tocOffset - 1);
pakHeader.creationUnixTime = 132890732;
// Timestamp.
auto now = std::chrono::system_clock::now();
pakHeader.creationUnixTime = static_cast<std::uint32_t>(std::chrono::time_point_cast<std::chrono::seconds>(now).time_since_epoch().count());
sink.OnEvent({ PakProgressReportSink::PakEvent::EventCode::WritingHeader }); sink.OnEvent({ PakProgressReportSink::PakEvent::EventCode::WritingHeader });

View file

@ -132,10 +132,10 @@ namespace eupak::tasks {
file.SetData(std::move(pakData)); file.SetData(std::move(pakData));
// Setup other stuff like modtime // Setup other stuff like modtime
file.Visit([&](auto& tocEntry) { file.VisitTocEntry([&](auto& tocEntry) {
// Need to figure out why this is broken and fucked up // Kinda stupid but works
// auto casted = std::chrono::clock_cast<std::chrono::system_clock>(lastModified); auto sys = std::chrono::file_clock::to_sys(lastModified);
auto seconds = std::chrono::time_point_cast<std::chrono::seconds>(lastModified); auto seconds = std::chrono::time_point_cast<std::chrono::seconds>(sys);
tocEntry.creationUnixTime = static_cast<std::uint32_t>(seconds.time_since_epoch().count()); tocEntry.creationUnixTime = static_cast<std::uint32_t>(seconds.time_since_epoch().count());
}); });

View file

@ -14,8 +14,6 @@
#include <stdexcept> #include <stdexcept>
#include <tasks/ExtractTask.hpp> #include <tasks/ExtractTask.hpp>
// this actually is pretty fast so maybe I won't bother doing crazy thread optimizations..
namespace eupak::tasks { namespace eupak::tasks {
int ExtractTask::Run(Arguments&& args) { int ExtractTask::Run(Arguments&& args) {
@ -67,8 +65,6 @@ namespace eupak::tasks {
if(!fs::exists(outpath.parent_path())) if(!fs::exists(outpath.parent_path()))
fs::create_directories(outpath.parent_path()); fs::create_directories(outpath.parent_path());
std::ofstream ofs(outpath.string(), std::ofstream::binary); std::ofstream ofs(outpath.string(), std::ofstream::binary);
if(!ofs) { if(!ofs) {

View file

@ -55,7 +55,7 @@ namespace eupak::tasks {
if(args.verbose) { if(args.verbose) {
for(auto& [filename, file] : reader.GetFiles()) { for(auto& [filename, file] : reader.GetFiles()) {
std::cout << "File \"" << filename << "\":\n"; std::cout << "File \"" << filename << "\":\n";
file.Visit([&](auto& tocEntry) { file.VisitTocEntry([&](auto& tocEntry) {
std::cout << " Created: " << FormatUnixTimestamp(tocEntry.creationUnixTime, DATE_FORMAT) << '\n'; std::cout << " Created: " << FormatUnixTimestamp(tocEntry.creationUnixTime, DATE_FORMAT) << '\n';
std::cout << " Size: " << FormatUnit(tocEntry.size) << '\n'; std::cout << " Size: " << FormatUnit(tocEntry.size) << '\n';
}); });