mirror of
https://github.com/izzy2lost/libultraship.git
synced 2026-06-19 01:16:13 -07:00
o2r zip (#450)
* start refactoring, legacy load still working * account for path in meta file * meta * clang format * zip stuff * clang format * remove a space * libzip * zipcmp * zipmerge * ziptool * do it in tidyformat too * merge? * call it * open/close as names * error thing * auto * fix build * indexfile
This commit is contained in:
@@ -11,7 +11,7 @@ jobs:
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
brew install sdl2 libpng glew ninja
|
||||
brew install sdl2 libpng glew ninja libzip
|
||||
- uses: actions/checkout@v2
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libsdl2-dev libpng-dev libglew-dev ninja-build
|
||||
sudo apt-get install -y libsdl2-dev libpng-dev libglew-dev libzip-dev zipcmp zipmerge ziptool ninja-build
|
||||
- uses: actions/checkout@v2
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
|
||||
@@ -10,7 +10,7 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libsdl2-dev libpng-dev libglew-dev ninja-build clang-tidy clang-format-12
|
||||
sudo apt-get install -y libsdl2-dev libpng-dev libglew-dev libzip-dev zipcmp zipmerge ziptool ninja-build clang-tidy clang-format-12
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows" AND USE_AUTO_VCPKG)
|
||||
endif()
|
||||
|
||||
vcpkg_bootstrap()
|
||||
vcpkg_install_packages(zlib bzip2 sdl2 glew)
|
||||
vcpkg_install_packages(zlib bzip2 sdl2 glew libzip)
|
||||
endif()
|
||||
|
||||
add_subdirectory("extern")
|
||||
|
||||
@@ -470,6 +470,9 @@ target_link_libraries(libultraship
|
||||
PUBLIC ZAPDUtils ImGui tinyxml2 nlohmann_json::nlohmann_json
|
||||
)
|
||||
|
||||
find_package(libzip REQUIRED)
|
||||
target_link_libraries(libultraship PRIVATE libzip::zip)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR CMAKE_SYSTEM_NAME STREQUAL "NintendoSwitch")
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
@@ -26,7 +26,7 @@ Archive::~Archive() {
|
||||
}
|
||||
|
||||
void Archive::Load() {
|
||||
bool opened = LoadRaw();
|
||||
bool opened = Open();
|
||||
|
||||
auto t = LoadFileRaw("version");
|
||||
bool isGameVersionValid = false;
|
||||
@@ -53,6 +53,7 @@ void Archive::Load() {
|
||||
}
|
||||
|
||||
void Archive::Unload() {
|
||||
Close();
|
||||
SetLoaded(false);
|
||||
}
|
||||
|
||||
@@ -103,9 +104,9 @@ void Archive::SetGameVersion(uint32_t gameVersion) {
|
||||
mGameVersion = gameVersion;
|
||||
}
|
||||
|
||||
void Archive::AddFile(const std::string& filePath) {
|
||||
void Archive::IndexFile(const std::string& filePath) {
|
||||
if (filePath.length() > 5 && filePath.substr(filePath.length() - 5) == ".meta") {
|
||||
AddFile(filePath.substr(0, filePath.length() - 5));
|
||||
IndexFile(filePath.substr(0, filePath.length() - 5));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,15 +34,15 @@ class Archive {
|
||||
const std::string& GetPath();
|
||||
bool IsLoaded();
|
||||
|
||||
virtual bool LoadRaw() = 0;
|
||||
virtual bool UnloadRaw() = 0;
|
||||
virtual bool Open() = 0;
|
||||
virtual bool Close() = 0;
|
||||
virtual std::shared_ptr<File> LoadFileRaw(const std::string& filePath) = 0;
|
||||
virtual std::shared_ptr<File> LoadFileRaw(uint64_t hash) = 0;
|
||||
|
||||
protected:
|
||||
void SetLoaded(bool isLoaded);
|
||||
void SetGameVersion(uint32_t gameVersion);
|
||||
void AddFile(const std::string& filePath);
|
||||
void IndexFile(const std::string& filePath);
|
||||
|
||||
private:
|
||||
static std::shared_ptr<ResourceInitData> CreateDefaultResourceInitData();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "O2rArchive.h"
|
||||
|
||||
#include "Context.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace LUS {
|
||||
@@ -11,18 +12,76 @@ O2rArchive::~O2rArchive() {
|
||||
}
|
||||
|
||||
std::shared_ptr<File> O2rArchive::LoadFileRaw(uint64_t hash) {
|
||||
return nullptr;
|
||||
const std::string& filePath =
|
||||
*Context::GetInstance()->GetResourceManager()->GetArchiveManager()->HashToString(hash);
|
||||
return LoadFileRaw(filePath);
|
||||
}
|
||||
|
||||
std::shared_ptr<File> O2rArchive::LoadFileRaw(const std::string& filePath) {
|
||||
return nullptr;
|
||||
if (mZipArchive == nullptr) {
|
||||
SPDLOG_TRACE("Failed to open file {} from zip archive {}. Archive not open.", filePath, GetPath());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto zipEntryIndex = zip_name_locate(mZipArchive, filePath.c_str(), 0);
|
||||
if (zipEntryIndex < 0) {
|
||||
SPDLOG_TRACE("Failed to find file {} in zip archive {}.", filePath, GetPath());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct zip_stat zipEntryStat;
|
||||
zip_stat_init(&zipEntryStat);
|
||||
if (zip_stat_index(mZipArchive, zipEntryIndex, 0, &zipEntryStat) != 0) {
|
||||
SPDLOG_TRACE("Failed to get entry information for file {} in zip archive {}.", filePath, GetPath());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct zip_file* zipEntryFile = zip_fopen_index(mZipArchive, zipEntryIndex, 0);
|
||||
if (!zipEntryFile) {
|
||||
SPDLOG_TRACE("Failed to open file {} in zip archive {}.", filePath, GetPath());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto fileToLoad = std::make_shared<File>();
|
||||
fileToLoad->Buffer = std::make_shared<std::vector<char>>(zipEntryStat.size);
|
||||
|
||||
if (zip_fread(zipEntryFile, fileToLoad->Buffer->data(), zipEntryStat.size) < 0) {
|
||||
SPDLOG_TRACE("Error reading file {} in zip archive {}.", filePath, GetPath());
|
||||
}
|
||||
|
||||
if (zip_fclose(zipEntryFile) != 0) {
|
||||
SPDLOG_TRACE("Error closing file {} in zip archive {}.", filePath, GetPath());
|
||||
}
|
||||
|
||||
fileToLoad->Parent = dynamic_pointer_cast<Archive>(std::make_shared<O2rArchive>(std::move(*this)));
|
||||
fileToLoad->IsLoaded = true;
|
||||
|
||||
return fileToLoad;
|
||||
}
|
||||
|
||||
bool O2rArchive::LoadRaw() {
|
||||
return false;
|
||||
bool O2rArchive::Open() {
|
||||
mZipArchive = zip_open(GetPath().c_str(), ZIP_RDONLY, nullptr);
|
||||
if (mZipArchive == nullptr) {
|
||||
SPDLOG_ERROR("Failed to load zip file \"{}\"", GetPath());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto zipNumEntries = zip_get_num_entries(mZipArchive, 0);
|
||||
for (auto i = 0; i < zipNumEntries; i++) {
|
||||
auto zipEntryName = zip_get_name(mZipArchive, i, 0);
|
||||
|
||||
IndexFile(zipEntryName);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool O2rArchive::UnloadRaw() {
|
||||
return false;
|
||||
bool O2rArchive::Close() {
|
||||
if (zip_close(mZipArchive) == -1) {
|
||||
SPDLOG_ERROR("Failed to close zip file \"{}\"", GetPath());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace LUS
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
#include "zip.h"
|
||||
|
||||
#include "resource/File.h"
|
||||
#include "resource/Resource.h"
|
||||
#include "resource/archive/Archive.h"
|
||||
@@ -18,12 +20,13 @@ class O2rArchive : virtual public Archive {
|
||||
O2rArchive(const std::string& archivePath);
|
||||
~O2rArchive();
|
||||
|
||||
bool LoadRaw();
|
||||
bool UnloadRaw();
|
||||
bool Open();
|
||||
bool Close();
|
||||
std::shared_ptr<File> LoadFileRaw(const std::string& filePath);
|
||||
std::shared_ptr<File> LoadFileRaw(uint64_t hash);
|
||||
|
||||
protected:
|
||||
private:
|
||||
zip_t* mZipArchive;
|
||||
};
|
||||
} // namespace LUS
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
namespace LUS {
|
||||
OtrArchive::OtrArchive(const std::string& archivePath) : Archive(archivePath) {
|
||||
mHandle = nullptr;
|
||||
}
|
||||
|
||||
OtrArchive::~OtrArchive() {
|
||||
@@ -16,6 +17,11 @@ OtrArchive::~OtrArchive() {
|
||||
}
|
||||
|
||||
std::shared_ptr<File> OtrArchive::LoadFileRaw(const std::string& filePath) {
|
||||
if (mHandle == nullptr) {
|
||||
SPDLOG_TRACE("Failed to open file {} from mpq archive {}. Archive not open.", filePath, GetPath());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
HANDLE fileHandle;
|
||||
bool attempt = SFileOpenFileEx(mHandle, filePath.c_str(), 0, &fileHandle);
|
||||
if (!attempt) {
|
||||
@@ -56,7 +62,7 @@ std::shared_ptr<File> OtrArchive::LoadFileRaw(uint64_t hash) {
|
||||
return LoadFileRaw(filePath);
|
||||
}
|
||||
|
||||
bool OtrArchive::LoadRaw() {
|
||||
bool OtrArchive::Open() {
|
||||
const bool opened = SFileOpenArchive(GetPath().c_str(), 0, MPQ_OPEN_READ_ONLY, &mHandle);
|
||||
if (opened) {
|
||||
SPDLOG_INFO("Opened mpq file \"{}\"", GetPath());
|
||||
@@ -79,13 +85,13 @@ bool OtrArchive::LoadRaw() {
|
||||
std::string_view line = lines[i].substr(0, lines[i].length() - 1); // Trim \r
|
||||
std::string lineStr = std::string(line);
|
||||
|
||||
AddFile(lineStr);
|
||||
IndexFile(lineStr);
|
||||
}
|
||||
|
||||
return opened;
|
||||
}
|
||||
|
||||
bool OtrArchive::UnloadRaw() {
|
||||
bool OtrArchive::Close() {
|
||||
bool closed = SFileCloseArchive(mHandle);
|
||||
if (!closed) {
|
||||
SPDLOG_ERROR("({}) Failed to close mpq {}", GetLastError(), mHandle);
|
||||
|
||||
@@ -24,8 +24,8 @@ class OtrArchive : virtual public Archive {
|
||||
OtrArchive(const std::string& archivePath);
|
||||
~OtrArchive();
|
||||
|
||||
bool LoadRaw();
|
||||
bool UnloadRaw();
|
||||
bool Open();
|
||||
bool Close();
|
||||
std::shared_ptr<File> LoadFileRaw(const std::string& filePath);
|
||||
std::shared_ptr<File> LoadFileRaw(uint64_t hash);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user