mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Fix Warden module parsing and DBC loading for Classic expansion
Warden: copy/skip pair order was reversed — format is [copy][data][skip] per MaNGOS/TrinityCore, not [skip][copy][data]. All copy sizes read as 0, causing module load failure and server disconnect. DBC: when binary DBCs aren't available (no MPQ extraction), fall back to expansion CSV files even for visual DBCs (CreatureDisplayInfo, CharSections, ItemDisplayInfo, etc.) instead of failing with "DBC not found".
This commit is contained in:
parent
60c26a17aa
commit
d045c1215a
2 changed files with 49 additions and 24 deletions
|
|
@ -529,34 +529,23 @@ bool WardenModule::parseExecutableFormat(const std::vector<uint8_t>& exeData) {
|
|||
std::cout << "[WardenModule] Allocated " << moduleSize_ << " bytes of executable memory at "
|
||||
<< moduleMemory_ << '\n';
|
||||
|
||||
// Parse skip/copy pairs
|
||||
// Format: repeated [2B skip_count][2B copy_count][copy_count bytes data]
|
||||
// Skip = advance dest pointer (zeros), Copy = copy from source to dest
|
||||
// Terminates when skip_count == 0
|
||||
// Parse copy/skip pairs (MaNGOS/TrinityCore format)
|
||||
// Format: repeated [2B copy_count][copy_count bytes data][2B skip_count]
|
||||
// Copy = copy from source to dest, Skip = advance dest pointer (zeros)
|
||||
// Terminates when copy_count == 0
|
||||
size_t pos = 4; // Skip 4-byte size header
|
||||
size_t destOffset = 0;
|
||||
int pairCount = 0;
|
||||
|
||||
while (pos + 2 <= exeData.size()) {
|
||||
// Read skip count (2 bytes LE)
|
||||
uint16_t skipCount = exeData[pos] | (exeData[pos + 1] << 8);
|
||||
pos += 2;
|
||||
|
||||
if (skipCount == 0) {
|
||||
break; // End of skip/copy pairs
|
||||
}
|
||||
|
||||
// Advance dest pointer by skipCount (gaps are zero-filled from memset)
|
||||
destOffset += skipCount;
|
||||
|
||||
// Read copy count (2 bytes LE)
|
||||
if (pos + 2 > exeData.size()) {
|
||||
std::cerr << "[WardenModule] Unexpected end of data reading copy count" << '\n';
|
||||
break;
|
||||
}
|
||||
uint16_t copyCount = exeData[pos] | (exeData[pos + 1] << 8);
|
||||
pos += 2;
|
||||
|
||||
if (copyCount == 0) {
|
||||
break; // End of copy/skip pairs
|
||||
}
|
||||
|
||||
if (copyCount > 0) {
|
||||
if (pos + copyCount > exeData.size()) {
|
||||
std::cerr << "[WardenModule] Copy section extends beyond data bounds" << '\n';
|
||||
|
|
@ -589,9 +578,19 @@ bool WardenModule::parseExecutableFormat(const std::vector<uint8_t>& exeData) {
|
|||
destOffset += copyCount;
|
||||
}
|
||||
|
||||
// Read skip count (2 bytes LE)
|
||||
uint16_t skipCount = 0;
|
||||
if (pos + 2 <= exeData.size()) {
|
||||
skipCount = exeData[pos] | (exeData[pos + 1] << 8);
|
||||
pos += 2;
|
||||
}
|
||||
|
||||
// Advance dest pointer by skipCount (gaps are zero-filled from memset)
|
||||
destOffset += skipCount;
|
||||
|
||||
pairCount++;
|
||||
std::cout << "[WardenModule] Pair " << pairCount << ": skip " << skipCount
|
||||
<< ", copy " << copyCount << " (dest offset=" << destOffset << ")" << '\n';
|
||||
std::cout << "[WardenModule] Pair " << pairCount << ": copy " << copyCount
|
||||
<< ", skip " << skipCount << " (dest offset=" << destOffset << ")" << '\n';
|
||||
}
|
||||
|
||||
// Save position — remaining decompressed data contains relocation entries
|
||||
|
|
|
|||
|
|
@ -294,10 +294,36 @@ std::shared_ptr<DBCFile> AssetManager::loadDBC(const std::string& name) {
|
|||
if (dbcData.empty()) {
|
||||
std::string dbcPath = "DBFilesClient\\" + name;
|
||||
dbcData = readFile(dbcPath);
|
||||
if (dbcData.empty()) {
|
||||
LOG_WARNING("DBC not found: ", name);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// If binary DBC not found and we skipped CSV earlier (forceBinaryForVisualDbc),
|
||||
// try CSV as a last resort — better than no data at all (e.g. Classic expansion
|
||||
// where binary DBCs come from MPQ extraction the user may not have done).
|
||||
if (dbcData.empty() && forceBinaryForVisualDbc && !expansionDataPath_.empty()) {
|
||||
std::string baseName = name;
|
||||
auto dot = baseName.rfind('.');
|
||||
if (dot != std::string::npos) {
|
||||
baseName = baseName.substr(0, dot);
|
||||
}
|
||||
std::string csvPath = expansionDataPath_ + "/db/" + baseName + ".csv";
|
||||
if (std::filesystem::exists(csvPath)) {
|
||||
std::ifstream f(csvPath, std::ios::binary | std::ios::ate);
|
||||
if (f) {
|
||||
auto size = f.tellg();
|
||||
if (size > 0) {
|
||||
f.seekg(0);
|
||||
dbcData.resize(static_cast<size_t>(size));
|
||||
f.read(reinterpret_cast<char*>(dbcData.data()), size);
|
||||
LOG_INFO("Binary DBC not found, using CSV fallback: ", csvPath);
|
||||
loadedFromCSV = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dbcData.empty()) {
|
||||
LOG_WARNING("DBC not found: ", name);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto dbc = std::make_shared<DBCFile>();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue