Kelsidavis-WoWee/tools/asset_extract/extractor.hpp
Kelsi 5ed2008621 feat(extract): emit open-format side-files (BLP→PNG, DBC→JSON)
The asset_extract tool now optionally writes wowee open-format
copies next to each extracted proprietary file:
  --emit-png      foo.blp → foo.png
  --emit-json-dbc foo.dbc → foo.json
  --emit-open     shortcut for both

Originals are left untouched, so private servers (AzerothCore,
TrinityCore) that load from the manifest's .blp/.dbc paths
continue to work unchanged. The wowee runtime / editor can now
consume the open formats directly without an extra conversion pass.

Implementation:
- New tools/asset_extract/open_format_emitter.{hpp,cpp} encapsulates
  the post-extract walk + per-file conversion.
- BLP→PNG uses BLPLoader::load + stbi_write_png with the same
  dimension/buffer-size sanity guards the editor's texture exporter
  applies.
- DBC→JSON mirrors the editor's DBCExporter::exportAsJson schema
  (string/float/uint heuristic) so the runtime DBC overlay loader
  can consume the output drop-in.
2026-05-06 10:23:32 -07:00

70 lines
2.7 KiB
C++

#pragma once
#include <string>
#include <vector>
#include <atomic>
#include <cstdint>
namespace wowee {
namespace tools {
/**
* Extraction pipeline: MPQ archives → loose files + manifest
*/
class Extractor {
public:
struct Options {
std::string mpqDir; // Path to WoW Data directory
std::string outputDir; // Output directory for extracted assets
std::string expansion; // "classic", "tbc", "wotlk", or "" for auto-detect
std::string locale; // "enUS", "deDE", etc., or "" for auto-detect
int threads = 0; // 0 = auto-detect
bool verify = false; // CRC32 verify after extraction
bool verbose = false; // Verbose logging
bool generateDbcCsv = false; // Convert selected DBFilesClient/*.dbc to CSV for committing
bool skipDbcExtraction = false; // Extract visual assets only (recommended when CSV DBCs are in repo)
bool onlyUsedDbcs = false; // Extract only the DBC files wowee uses (implies DBFilesClient/*.dbc filter)
std::string dbcCsvOutputDir; // When set, write CSVs into this directory instead of outputDir/expansions/<exp>/db
std::string referenceManifest; // If set, only extract files NOT in this manifest (delta extraction)
std::string listFile; // External listfile for MPQ enumeration (resolves unnamed hash entries)
// Open-format emission: post-extract pass that writes wowee
// open-format side-files (e.g. foo.blp → foo.png) without
// touching the original. Lets wowee's runtime/editor consume
// the open formats while keeping the proprietary copies that
// private servers (AzerothCore/TrinityCore) read from.
bool emitPng = false; // BLP → PNG side-files
bool emitJsonDbc = false; // DBC → JSON side-files
};
struct Stats {
std::atomic<uint64_t> filesExtracted{0};
std::atomic<uint64_t> bytesExtracted{0};
std::atomic<uint64_t> filesSkipped{0};
std::atomic<uint64_t> filesFailed{0};
};
/**
* Auto-detect expansion from files in mpqDir.
* @return "classic", "tbc", "wotlk", or "" if unknown
*/
static std::string detectExpansion(const std::string& mpqDir);
/**
* Auto-detect locale by scanning for locale subdirectories.
* @return locale string like "enUS", or "" if none found
*/
static std::string detectLocale(const std::string& mpqDir);
/**
* Run the extraction pipeline
* @return true on success
*/
static bool run(const Options& opts);
private:
static bool enumerateFiles(const Options& opts,
std::vector<std::string>& outFiles);
};
} // namespace tools
} // namespace wowee