From bfc703b6f7e0f4cbc4c97bea0a9d2dbd7dbf4729 Mon Sep 17 00:00:00 2001 From: Alex Macocian Date: Mon, 13 Nov 2023 14:50:46 +0100 Subject: [PATCH] Setup libzippp archive loading --- CMakeLists.txt | 4 +- cmake/libzippp.cmake | 3 ++ header/gMod_FileLoader.h | 73 ++++++----------------------------- source/gMod_FileLoader.cpp | 71 ++++++++++++++++++++++++++++++++++ source/uMod_TextureServer.cpp | 14 +++---- 5 files changed, 93 insertions(+), 72 deletions(-) create mode 100644 source/gMod_FileLoader.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9178828..b72c886 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.16) +cmake_minimum_required(VERSION 3.16) set(CMAKE_GENERATOR_PLATFORM win32) @@ -51,7 +51,7 @@ file(GLOB SOURCES "source/*.cpp" ${VERSION_RC} ) - +target_compile_features(gMod PRIVATE cxx_std_23) target_link_libraries(gMod PRIVATE ${D3D9_LIB} ${D3DX9_LIB} diff --git a/cmake/libzippp.cmake b/cmake/libzippp.cmake index 7c11c42..f651c74 100644 --- a/cmake/libzippp.cmake +++ b/cmake/libzippp.cmake @@ -25,6 +25,9 @@ endif() FetchContent_Populate(libzippp) add_library(libzippp) + +set(LIBZIPPP_ENABLE_ENCRYPTION ON) + set(SOURCES "${libzippp_SOURCE_DIR}/src/libzippp.h" "${libzippp_SOURCE_DIR}/src/libzippp.cpp" diff --git a/header/gMod_FileLoader.h b/header/gMod_FileLoader.h index 98edc21..34afcd4 100644 --- a/header/gMod_FileLoader.h +++ b/header/gMod_FileLoader.h @@ -1,21 +1,23 @@ -#pragma once +#pragma once #include #include #include #include #include - +#include #include struct TpfEntry { std::string Name; std::string Entry; // Assuming ZipEntry is a string in your original code uint32_t CrcHash; + void* Data; + unsigned long long Size; }; class gMod_FileLoader { - const std::string _fileName; + std::string _fileName; std::ifstream _stream; const std::vector _tpfPassword{ 0x73, 0x2A, 0x63, 0x7D, 0x5F, 0x0A, 0xA6, 0xBD, @@ -25,72 +27,21 @@ class gMod_FileLoader { 0x77, 0x6E, 0x46, 0x47, 0x77, 0x49, 0x0C, 0x4B, 0x46, 0x6F }; + const std::string encodedPassword = std::string(_tpfPassword.begin(), _tpfPassword.end()); std::vector entryCache; bool loaded; public: - gMod_FileLoader(const std::string& fileName) - : _fileName(std::filesystem::absolute(fileName).string()), _stream(_fileName, std::ios::binary), loaded(false) { - if (!_stream) { - throw std::runtime_error("Failed to open file: " + _fileName); - } - } + gMod_FileLoader(const std::string& fileName); - std::vector Load() { - if (!loaded) { - entryCache = GetContents(); - loaded = true; - } - - return entryCache; - } + std::vector Load(); private: - std::vector GetContents() { - if (_fileName.ends_with(".tpf")) { - return GetTpfContents(); - } else { - return GetFileContents(); - } - } + std::vector GetContents(); - std::vector GetTpfContents() { - std::vector entries; + std::vector GetTpfContents(); - try { - // Open the zip file using libzippp - libzippp::ZipArchive zipArchive(_fileName); + std::vector GetFileContents(); - // Iterate over the files in the zip archive - for (auto entry : zipArchive) { - if (entry.isFile()) { - entries.push_back({ entry.getName(), entry.getName(), 0 }); // Assuming ZipEntry is a string - } - } - } catch (const std::exception& e) { - throw std::runtime_error("Failed to open zip file: " + _fileName); - } - - return entries; - } - - std::vector GetFileContents() { - std::vector entries; - - try { - // Open the zip file using libzippp - libzippp::ZipArchive zipArchive(_fileName); - - // Iterate over the files in the zip archive - for (auto entry : zipArchive) { - if (entry.isFile()) { - entries.push_back({ entry.getName(), entry.getName(), 0 }); // Assuming ZipEntry is a string - } - } - } catch (const std::exception& e) { - throw std::runtime_error("Failed to open zip file: " + _fileName); - } - - return entries; - } + void LoadEntries(libzippp::ZipArchive& archive, std::vector& entries); }; diff --git a/source/gMod_FileLoader.cpp b/source/gMod_FileLoader.cpp new file mode 100644 index 0000000..5e2dc4f --- /dev/null +++ b/source/gMod_FileLoader.cpp @@ -0,0 +1,71 @@ +#include "../header/gMod_FileLoader.h" +#include + +gMod_FileLoader::gMod_FileLoader(const std::string& fileName) { + _fileName = std::filesystem::absolute(fileName).string(); + _stream = std::ifstream(_fileName, std::ios::binary); + loaded = false; + if (!_stream) { + throw std::runtime_error("Failed to open file: " + _fileName); + } +} + +std::vector gMod_FileLoader::Load() { + if (!loaded) { + entryCache = GetContents(); + loaded = true; + } + + return entryCache; +} + +std::vector gMod_FileLoader::GetContents() { + if (_fileName.ends_with(".tpf")) { + return GetTpfContents(); + } + else { + return GetFileContents(); + } +} + +std::vector gMod_FileLoader::GetTpfContents() { + std::vector entries; + try { + // Open the zip file using libzippp + libzippp::ZipArchive zipArchive(_fileName, encodedPassword); + zipArchive.open(); //ReadOnly and no consistency checks + LoadEntries(zipArchive, entries); + } + catch (const std::exception& e) { + throw std::runtime_error("Failed to open zip file: " + _fileName); + } + + return entries; +} + +std::vector gMod_FileLoader::GetFileContents() { + std::vector entries; + + try { + // Open the zip file using libzippp + libzippp::ZipArchive zipArchive(_fileName); + zipArchive.open(); + LoadEntries(zipArchive, entries); + } + catch (const std::exception& e) { + throw std::runtime_error("Failed to open zip file: " + _fileName); + } + + return entries; +} + +void gMod_FileLoader::LoadEntries(libzippp::ZipArchive& archive, std::vector& entries) { + // Iterate over the files in the zip archive + for (const auto& entry : archive.getEntries()) { + if (entry.isFile()) { + const auto dataPtr = entry.readAsBinary(); + const auto size = entry.getSize(); + entries.push_back({ entry.getName(), entry.getName(), 0, dataPtr, size }); // Assuming ZipEntry is a string + } + } +} diff --git a/source/uMod_TextureServer.cpp b/source/uMod_TextureServer.cpp index 0556b8c..6ee5351 100644 --- a/source/uMod_TextureServer.cpp +++ b/source/uMod_TextureServer.cpp @@ -625,15 +625,11 @@ void uMod_TextureServer::LoadModsFromFile(char* source) } const auto file = new gMod_FileLoader(line); - const auto result = file->GetContent(); - if (!file->Textures.empty()) { - if (!result) { - Message("MainLoop: WARNING! GetContent returned failure, but some textures have been loaded for %s\n", line); - } - - Message("MainLoop: Texture count %d %s\n", file->Textures.size(), line); - for (auto& texture : file->Textures) { - AddFile(texture.data.data(), texture.data.size(), texture.hash, true); + const auto entries = file->Load(); + if (!entries.empty()) { + Message("MainLoop: Texture count %d %s\n", entries.size(), line); + for (const auto& entry : entries) { + //AddFile(static_cast(entry.Data), static_cast(entry.Size), ) } PropagateUpdate(nullptr);