mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 16:15:43 +00:00
110 lines
3.6 KiB
C++
110 lines
3.6 KiB
C++
#include "IwdCreator.h"
|
|
|
|
#include "Utils/FileToZlibWrapper.h"
|
|
|
|
#include <chrono>
|
|
#include <format>
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <zip.h>
|
|
|
|
IwdToCreate::IwdToCreate(std::string name)
|
|
: m_name(std::move(name))
|
|
{
|
|
}
|
|
|
|
void IwdToCreate::AddFile(std::string filePath)
|
|
{
|
|
m_file_paths.emplace_back(std::move(filePath));
|
|
}
|
|
|
|
void IwdToCreate::Build(ISearchPath& searchPath, IOutputPath& outPath)
|
|
{
|
|
const auto fileName = std::format("{}.iwd", m_name);
|
|
const auto file = outPath.Open(fileName);
|
|
if (!file)
|
|
{
|
|
std::cerr << std::format("Failed to open file for iwd {}\n", m_name);
|
|
return;
|
|
}
|
|
|
|
auto functions = FileToZlibWrapper::CreateFunctions32ForFile(file.get());
|
|
|
|
const auto zipFile = zipOpen2(fileName.c_str(), APPEND_STATUS_CREATE, nullptr, &functions);
|
|
if (!zipFile)
|
|
{
|
|
std::cerr << std::format("Failed to open file as zip for iwd {}\n", m_name);
|
|
return;
|
|
}
|
|
|
|
for (const auto& filePath : m_file_paths)
|
|
{
|
|
auto readFile = searchPath.Open(filePath);
|
|
if (!readFile.IsOpen())
|
|
{
|
|
std::cerr << std::format("Failed to open file for iwd: {}\n", filePath);
|
|
continue;
|
|
}
|
|
|
|
auto localNow = std::chrono::zoned_time{std::chrono::current_zone(), std::chrono::system_clock::now()}.get_local_time();
|
|
auto nowDays = std::chrono::floor<std::chrono::days>(localNow);
|
|
std::chrono::year_month_day ymd(std::chrono::floor<std::chrono::days>(localNow));
|
|
std::chrono::hh_mm_ss hms(std::chrono::floor<std::chrono::milliseconds>(localNow - nowDays));
|
|
|
|
zip_fileinfo fileInfo{};
|
|
fileInfo.dosDate = 0u;
|
|
fileInfo.tmz_date.tm_year = static_cast<int>(ymd.year());
|
|
fileInfo.tmz_date.tm_mon = static_cast<int>(static_cast<unsigned>(ymd.month()) - static_cast<unsigned>(std::chrono::January));
|
|
fileInfo.tmz_date.tm_mday = static_cast<int>(static_cast<unsigned>(ymd.day()));
|
|
fileInfo.tmz_date.tm_hour = static_cast<int>(hms.hours().count());
|
|
fileInfo.tmz_date.tm_min = static_cast<int>(hms.minutes().count());
|
|
fileInfo.tmz_date.tm_sec = static_cast<int>(hms.seconds().count());
|
|
zipOpenNewFileInZip(zipFile, filePath.c_str(), &fileInfo, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
|
|
|
|
char tempBuffer[0x1000];
|
|
|
|
do
|
|
{
|
|
readFile.m_stream->read(tempBuffer, sizeof(tempBuffer));
|
|
const auto readCount = readFile.m_stream->gcount();
|
|
if (readCount > 0)
|
|
zipWriteInFileInZip(zipFile, tempBuffer, static_cast<unsigned>(readCount));
|
|
} while (!readFile.m_stream->eof());
|
|
|
|
zipCloseFileInZip(zipFile);
|
|
}
|
|
|
|
zipClose(zipFile, nullptr);
|
|
|
|
std::cout << std::format("Created iwd {} with {} entries\n", m_name, m_file_paths.size());
|
|
}
|
|
|
|
const std::vector<std::string>& IwdToCreate::GetFilePaths() const
|
|
{
|
|
return m_file_paths;
|
|
}
|
|
|
|
IwdToCreate* IwdCreator::GetOrAddIwd(const std::string& iwdName)
|
|
{
|
|
const auto existingIwd = m_iwd_lookup.find(iwdName);
|
|
if (existingIwd != m_iwd_lookup.end())
|
|
return existingIwd->second;
|
|
|
|
auto newIwd = std::make_unique<IwdToCreate>(iwdName);
|
|
auto* result = newIwd.get();
|
|
m_iwd_lookup.emplace(iwdName, result);
|
|
m_iwds.emplace_back(std::move(newIwd));
|
|
|
|
return result;
|
|
}
|
|
|
|
void IwdCreator::Finalize(ISearchPath& searchPath, IOutputPath& outPath)
|
|
{
|
|
std::cout << std::format("Writing {} iwd files to disk\n", m_iwds.size());
|
|
for (const auto& iwdToCreate : m_iwds)
|
|
iwdToCreate->Build(searchPath, outPath);
|
|
|
|
m_iwds.clear();
|
|
m_iwd_lookup.clear();
|
|
}
|