mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Fix all remaining build warnings and eliminate UB in binary parsers
Resolve 57 compiler warnings (unused params/vars, ignored return values, enum mismatch) and replace undefined-behavior reinterpret_cast with memcpy in DBC, BLP, and Warden module loaders for ARM64 portability.
This commit is contained in:
parent
22518f0936
commit
aaab2115d1
12 changed files with 112 additions and 101 deletions
|
|
@ -92,8 +92,8 @@ inline ProcessHandle spawnProcess(const std::vector<std::string>& args) {
|
|||
if (pid == 0) {
|
||||
// Child process
|
||||
setpgid(0, 0);
|
||||
freopen("/dev/null", "w", stdout);
|
||||
freopen("/dev/null", "w", stderr);
|
||||
if (!freopen("/dev/null", "w", stdout)) { _exit(1); }
|
||||
if (!freopen("/dev/null", "w", stderr)) { _exit(1); }
|
||||
|
||||
// Build argv for exec
|
||||
std::vector<const char*> argv;
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ void ActivitySoundManager::shutdown() {
|
|||
assetManager = nullptr;
|
||||
}
|
||||
|
||||
void ActivitySoundManager::update(float deltaTime) {
|
||||
void ActivitySoundManager::update([[maybe_unused]] float deltaTime) {
|
||||
reapProcesses();
|
||||
|
||||
// Play swimming stroke sounds periodically when swimming and moving
|
||||
|
|
@ -168,7 +168,7 @@ void ActivitySoundManager::rebuildJumpClipsForProfile(const std::string& raceFol
|
|||
}
|
||||
}
|
||||
|
||||
void ActivitySoundManager::rebuildSwimLoopClipsForProfile(const std::string& raceFolder, const std::string& raceBase, bool male) {
|
||||
void ActivitySoundManager::rebuildSwimLoopClipsForProfile([[maybe_unused]] const std::string& raceFolder, [[maybe_unused]] const std::string& raceBase, [[maybe_unused]] bool male) {
|
||||
swimLoopClips.clear();
|
||||
|
||||
// WoW 3.3.5a doesn't have dedicated swim loop sounds
|
||||
|
|
|
|||
|
|
@ -117,10 +117,10 @@ bool AmbientSoundManager::initialize(pipeline::AssetManager* assets) {
|
|||
bool forestNightLoaded = loadSound("Sound\\Ambience\\ZoneAmbience\\ForestNormalNight.wav", forestNormalNightSounds_[0], assets);
|
||||
|
||||
forestSnowDaySounds_.resize(1);
|
||||
bool forestSnowDayLoaded = loadSound("Sound\\Ambience\\ZoneAmbience\\ForestSnowDay.wav", forestSnowDaySounds_[0], assets);
|
||||
loadSound("Sound\\Ambience\\ZoneAmbience\\ForestSnowDay.wav", forestSnowDaySounds_[0], assets);
|
||||
|
||||
forestSnowNightSounds_.resize(1);
|
||||
bool forestSnowNightLoaded = loadSound("Sound\\Ambience\\ZoneAmbience\\ForestSnowNight.wav", forestSnowNightSounds_[0], assets);
|
||||
loadSound("Sound\\Ambience\\ZoneAmbience\\ForestSnowNight.wav", forestSnowNightSounds_[0], assets);
|
||||
|
||||
beachDaySounds_.resize(1);
|
||||
bool beachDayLoaded = loadSound("Sound\\Ambience\\ZoneAmbience\\BeachDay.wav", beachDaySounds_[0], assets);
|
||||
|
|
@ -129,34 +129,34 @@ bool AmbientSoundManager::initialize(pipeline::AssetManager* assets) {
|
|||
bool beachNightLoaded = loadSound("Sound\\Ambience\\ZoneAmbience\\BeachNight.wav", beachNightSounds_[0], assets);
|
||||
|
||||
grasslandsDaySounds_.resize(1);
|
||||
bool grasslandsDayLoaded = loadSound("Sound\\Ambience\\ZoneAmbience\\GrasslandsDay.wav", grasslandsDaySounds_[0], assets);
|
||||
loadSound("Sound\\Ambience\\ZoneAmbience\\GrasslandsDay.wav", grasslandsDaySounds_[0], assets);
|
||||
|
||||
grasslandsNightSounds_.resize(1);
|
||||
bool grasslandsNightLoaded = loadSound("Sound\\Ambience\\ZoneAmbience\\GrassLandsNight.wav", grasslandsNightSounds_[0], assets);
|
||||
loadSound("Sound\\Ambience\\ZoneAmbience\\GrassLandsNight.wav", grasslandsNightSounds_[0], assets);
|
||||
|
||||
jungleDaySounds_.resize(1);
|
||||
bool jungleDayLoaded = loadSound("Sound\\Ambience\\ZoneAmbience\\JungleDay.wav", jungleDaySounds_[0], assets);
|
||||
loadSound("Sound\\Ambience\\ZoneAmbience\\JungleDay.wav", jungleDaySounds_[0], assets);
|
||||
|
||||
jungleNightSounds_.resize(1);
|
||||
bool jungleNightLoaded = loadSound("Sound\\Ambience\\ZoneAmbience\\JungleNight.wav", jungleNightSounds_[0], assets);
|
||||
loadSound("Sound\\Ambience\\ZoneAmbience\\JungleNight.wav", jungleNightSounds_[0], assets);
|
||||
|
||||
marshDaySounds_.resize(1);
|
||||
bool marshDayLoaded = loadSound("Sound\\Ambience\\ZoneAmbience\\MarshDay.wav", marshDaySounds_[0], assets);
|
||||
loadSound("Sound\\Ambience\\ZoneAmbience\\MarshDay.wav", marshDaySounds_[0], assets);
|
||||
|
||||
marshNightSounds_.resize(1);
|
||||
bool marshNightLoaded = loadSound("Sound\\Ambience\\ZoneAmbience\\MarshNight.wav", marshNightSounds_[0], assets);
|
||||
loadSound("Sound\\Ambience\\ZoneAmbience\\MarshNight.wav", marshNightSounds_[0], assets);
|
||||
|
||||
desertCanyonDaySounds_.resize(1);
|
||||
bool desertCanyonDayLoaded = loadSound("Sound\\Ambience\\ZoneAmbience\\CanyonDesertDay.wav", desertCanyonDaySounds_[0], assets);
|
||||
|
||||
desertCanyonNightSounds_.resize(1);
|
||||
bool desertCanyonNightLoaded = loadSound("Sound\\Ambience\\ZoneAmbience\\CanyonDesertNight.wav", desertCanyonNightSounds_[0], assets);
|
||||
loadSound("Sound\\Ambience\\ZoneAmbience\\CanyonDesertNight.wav", desertCanyonNightSounds_[0], assets);
|
||||
|
||||
desertPlainsDaySounds_.resize(1);
|
||||
bool desertPlainsDayLoaded = loadSound("Sound\\Ambience\\ZoneAmbience\\PlainsDesertDay.wav", desertPlainsDaySounds_[0], assets);
|
||||
|
||||
desertPlainsNightSounds_.resize(1);
|
||||
bool desertPlainsNightLoaded = loadSound("Sound\\Ambience\\ZoneAmbience\\PlainsDesertNight.wav", desertPlainsNightSounds_[0], assets);
|
||||
loadSound("Sound\\Ambience\\ZoneAmbience\\PlainsDesertNight.wav", desertPlainsNightSounds_[0], assets);
|
||||
|
||||
// Load city ambience sounds (day and night where available)
|
||||
stormwindDaySounds_.resize(1);
|
||||
|
|
@ -169,10 +169,10 @@ bool AmbientSoundManager::initialize(pipeline::AssetManager* assets) {
|
|||
bool ironforgeLoaded = loadSound("Sound\\Ambience\\WMOAmbience\\Ironforge.wav", ironforgeSounds_[0], assets);
|
||||
|
||||
darnassusDaySounds_.resize(1);
|
||||
bool darnassusDayLoaded = loadSound("Sound\\Ambience\\WMOAmbience\\DarnassusDay.wav", darnassusDaySounds_[0], assets);
|
||||
loadSound("Sound\\Ambience\\WMOAmbience\\DarnassusDay.wav", darnassusDaySounds_[0], assets);
|
||||
|
||||
darnassusNightSounds_.resize(1);
|
||||
bool darnassusNightLoaded = loadSound("Sound\\Ambience\\WMOAmbience\\DarnassusNight.wav", darnassusNightSounds_[0], assets);
|
||||
loadSound("Sound\\Ambience\\WMOAmbience\\DarnassusNight.wav", darnassusNightSounds_[0], assets);
|
||||
|
||||
orgrimmarDaySounds_.resize(1);
|
||||
bool orgrimmarDayLoaded = loadSound("Sound\\Ambience\\WMOAmbience\\OrgrimmarDay.wav", orgrimmarDaySounds_[0], assets);
|
||||
|
|
@ -181,13 +181,13 @@ bool AmbientSoundManager::initialize(pipeline::AssetManager* assets) {
|
|||
bool orgrimmarNightLoaded = loadSound("Sound\\Ambience\\WMOAmbience\\OrgrimmarNight.wav", orgrimmarNightSounds_[0], assets);
|
||||
|
||||
undercitySounds_.resize(1);
|
||||
bool undercityLoaded = loadSound("Sound\\Ambience\\WMOAmbience\\Undercity.wav", undercitySounds_[0], assets);
|
||||
loadSound("Sound\\Ambience\\WMOAmbience\\Undercity.wav", undercitySounds_[0], assets);
|
||||
|
||||
thunderbluffDaySounds_.resize(1);
|
||||
bool thunderbluffDayLoaded = loadSound("Sound\\Ambience\\WMOAmbience\\ThunderBluffDay.wav", thunderbluffDaySounds_[0], assets);
|
||||
loadSound("Sound\\Ambience\\WMOAmbience\\ThunderBluffDay.wav", thunderbluffDaySounds_[0], assets);
|
||||
|
||||
thunderbluffNightSounds_.resize(1);
|
||||
bool thunderbluffNightLoaded = loadSound("Sound\\Ambience\\WMOAmbience\\ThunderBluffNight.wav", thunderbluffNightSounds_[0], assets);
|
||||
loadSound("Sound\\Ambience\\WMOAmbience\\ThunderBluffNight.wav", thunderbluffNightSounds_[0], assets);
|
||||
|
||||
// Load bell toll sounds
|
||||
bellAllianceSounds_.resize(1);
|
||||
|
|
|
|||
|
|
@ -295,7 +295,7 @@ void CombatSoundManager::playWeaponMiss(bool twoHanded) {
|
|||
}
|
||||
}
|
||||
|
||||
void CombatSoundManager::playImpact(WeaponSize weaponSize, ImpactType impactType, bool isCrit) {
|
||||
void CombatSoundManager::playImpact([[maybe_unused]] WeaponSize weaponSize, ImpactType impactType, bool isCrit) {
|
||||
// Select appropriate impact sound library
|
||||
const std::vector<CombatSample>* normalLibrary = nullptr;
|
||||
const std::vector<CombatSample>* critLibrary = nullptr;
|
||||
|
|
|
|||
|
|
@ -34,16 +34,16 @@ bool UiSoundManager::initialize(pipeline::AssetManager* assets) {
|
|||
bool charSheetCloseLoaded = loadSound("Sound\\Interface\\iAbilitiesCloseA.wav", characterSheetCloseSounds_[0], assets);
|
||||
|
||||
auctionOpenSounds_.resize(1);
|
||||
bool auctionOpenLoaded = loadSound("Sound\\Interface\\AuctionWindowOpen.wav", auctionOpenSounds_[0], assets);
|
||||
loadSound("Sound\\Interface\\AuctionWindowOpen.wav", auctionOpenSounds_[0], assets);
|
||||
|
||||
auctionCloseSounds_.resize(1);
|
||||
bool auctionCloseLoaded = loadSound("Sound\\Interface\\AuctionWindowClose.wav", auctionCloseSounds_[0], assets);
|
||||
loadSound("Sound\\Interface\\AuctionWindowClose.wav", auctionCloseSounds_[0], assets);
|
||||
|
||||
guildBankOpenSounds_.resize(1);
|
||||
bool guildBankOpenLoaded = loadSound("Sound\\Interface\\GuildVaultOpen.wav", guildBankOpenSounds_[0], assets);
|
||||
loadSound("Sound\\Interface\\GuildVaultOpen.wav", guildBankOpenSounds_[0], assets);
|
||||
|
||||
guildBankCloseSounds_.resize(1);
|
||||
bool guildBankCloseLoaded = loadSound("Sound\\Interface\\GuildVaultClose.wav", guildBankCloseSounds_[0], assets);
|
||||
loadSound("Sound\\Interface\\GuildVaultClose.wav", guildBankCloseSounds_[0], assets);
|
||||
|
||||
// Load button sounds
|
||||
buttonClickSounds_.resize(1);
|
||||
|
|
@ -63,7 +63,7 @@ bool UiSoundManager::initialize(pipeline::AssetManager* assets) {
|
|||
bool questFailedLoaded = loadSound("Sound\\Interface\\igQuestFailed.wav", questFailedSounds_[0], assets);
|
||||
|
||||
questUpdateSounds_.resize(1);
|
||||
bool questUpdateLoaded = loadSound("Sound\\Interface\\iQuestUpdate.wav", questUpdateSounds_[0], assets);
|
||||
loadSound("Sound\\Interface\\iQuestUpdate.wav", questUpdateSounds_[0], assets);
|
||||
|
||||
// Load loot sounds
|
||||
lootCoinSmallSounds_.resize(1);
|
||||
|
|
@ -86,13 +86,13 @@ bool UiSoundManager::initialize(pipeline::AssetManager* assets) {
|
|||
bool pickupBookLoaded = loadSound("Sound\\Interface\\PickUp\\PickUpBook.wav", pickupBookSounds_[0], assets);
|
||||
|
||||
pickupClothSounds_.resize(1);
|
||||
bool pickupClothLoaded = loadSound("Sound\\Interface\\PickUp\\PickUpCloth_Leather01.wav", pickupClothSounds_[0], assets);
|
||||
loadSound("Sound\\Interface\\PickUp\\PickUpCloth_Leather01.wav", pickupClothSounds_[0], assets);
|
||||
|
||||
pickupFoodSounds_.resize(1);
|
||||
bool pickupFoodLoaded = loadSound("Sound\\Interface\\PickUp\\PickUpFoodGeneric.wav", pickupFoodSounds_[0], assets);
|
||||
loadSound("Sound\\Interface\\PickUp\\PickUpFoodGeneric.wav", pickupFoodSounds_[0], assets);
|
||||
|
||||
pickupGemSounds_.resize(1);
|
||||
bool pickupGemLoaded = loadSound("Sound\\Interface\\PickUp\\PickUpGems.wav", pickupGemSounds_[0], assets);
|
||||
loadSound("Sound\\Interface\\PickUp\\PickUpGems.wav", pickupGemSounds_[0], assets);
|
||||
|
||||
// Load eating/drinking sounds
|
||||
eatingSounds_.resize(1);
|
||||
|
|
@ -107,13 +107,13 @@ bool UiSoundManager::initialize(pipeline::AssetManager* assets) {
|
|||
|
||||
// Load error/feedback sounds
|
||||
errorSounds_.resize(1);
|
||||
bool errorLoaded = loadSound("Sound\\Interface\\Error.wav", errorSounds_[0], assets);
|
||||
loadSound("Sound\\Interface\\Error.wav", errorSounds_[0], assets);
|
||||
|
||||
selectTargetSounds_.resize(1);
|
||||
bool selectTargetLoaded = loadSound("Sound\\Interface\\iSelectTarget.wav", selectTargetSounds_[0], assets);
|
||||
loadSound("Sound\\Interface\\iSelectTarget.wav", selectTargetSounds_[0], assets);
|
||||
|
||||
deselectTargetSounds_.resize(1);
|
||||
bool deselectTargetLoaded = loadSound("Sound\\Interface\\iDeselectTarget.wav", deselectTargetSounds_[0], assets);
|
||||
loadSound("Sound\\Interface\\iDeselectTarget.wav", deselectTargetSounds_[0], assets);
|
||||
|
||||
LOG_INFO("UISoundManager: Window sounds - Bag: ", (bagOpenLoaded && bagCloseLoaded) ? "YES" : "NO",
|
||||
", QuestLog: ", (questLogOpenLoaded && questLogCloseLoaded) ? "YES" : "NO",
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ bool WardenEmulator::initialize(const void* moduleCode, size_t moduleSize, uint3
|
|||
|
||||
uint32_t WardenEmulator::hookAPI(const std::string& dllName,
|
||||
const std::string& functionName,
|
||||
std::function<uint32_t(WardenEmulator&, const std::vector<uint32_t>&)> handler) {
|
||||
[[maybe_unused]] std::function<uint32_t(WardenEmulator&, const std::vector<uint32_t>&)> handler) {
|
||||
// Allocate address for this API stub
|
||||
static uint32_t nextStubAddr = API_STUB_BASE;
|
||||
uint32_t stubAddr = nextStubAddr;
|
||||
|
|
@ -239,7 +239,7 @@ std::string WardenEmulator::readString(uint32_t address, size_t maxLen) {
|
|||
return std::string(buffer.data());
|
||||
}
|
||||
|
||||
uint32_t WardenEmulator::allocateMemory(size_t size, uint32_t protection) {
|
||||
uint32_t WardenEmulator::allocateMemory(size_t size, [[maybe_unused]] uint32_t protection) {
|
||||
// Align to 4KB
|
||||
size = (size + 0xFFF) & ~0xFFF;
|
||||
|
||||
|
|
@ -315,7 +315,7 @@ uint32_t WardenEmulator::apiVirtualFree(WardenEmulator& emu, const std::vector<u
|
|||
return emu.freeMemory(lpAddress) ? 1 : 0;
|
||||
}
|
||||
|
||||
uint32_t WardenEmulator::apiGetTickCount(WardenEmulator& emu, const std::vector<uint32_t>& args) {
|
||||
uint32_t WardenEmulator::apiGetTickCount([[maybe_unused]] WardenEmulator& emu, [[maybe_unused]] const std::vector<uint32_t>& args) {
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
|
||||
uint32_t ticks = static_cast<uint32_t>(ms & 0xFFFFFFFF);
|
||||
|
|
@ -324,7 +324,7 @@ uint32_t WardenEmulator::apiGetTickCount(WardenEmulator& emu, const std::vector<
|
|||
return ticks;
|
||||
}
|
||||
|
||||
uint32_t WardenEmulator::apiSleep(WardenEmulator& emu, const std::vector<uint32_t>& args) {
|
||||
uint32_t WardenEmulator::apiSleep([[maybe_unused]] WardenEmulator& emu, const std::vector<uint32_t>& args) {
|
||||
if (args.size() < 1) return 0;
|
||||
uint32_t dwMilliseconds = args[0];
|
||||
|
||||
|
|
@ -333,12 +333,12 @@ uint32_t WardenEmulator::apiSleep(WardenEmulator& emu, const std::vector<uint32_
|
|||
return 0;
|
||||
}
|
||||
|
||||
uint32_t WardenEmulator::apiGetCurrentThreadId(WardenEmulator& emu, const std::vector<uint32_t>& args) {
|
||||
uint32_t WardenEmulator::apiGetCurrentThreadId([[maybe_unused]] WardenEmulator& emu, [[maybe_unused]] const std::vector<uint32_t>& args) {
|
||||
std::cout << "[WinAPI] GetCurrentThreadId() = 1234" << '\n';
|
||||
return 1234; // Fake thread ID
|
||||
}
|
||||
|
||||
uint32_t WardenEmulator::apiGetCurrentProcessId(WardenEmulator& emu, const std::vector<uint32_t>& args) {
|
||||
uint32_t WardenEmulator::apiGetCurrentProcessId([[maybe_unused]] WardenEmulator& emu, [[maybe_unused]] const std::vector<uint32_t>& args) {
|
||||
std::cout << "[WinAPI] GetCurrentProcessId() = 5678" << '\n';
|
||||
return 5678; // Fake process ID
|
||||
}
|
||||
|
|
@ -347,7 +347,7 @@ uint32_t WardenEmulator::apiReadProcessMemory(WardenEmulator& emu, const std::ve
|
|||
// ReadProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead)
|
||||
if (args.size() < 5) return 0;
|
||||
|
||||
uint32_t hProcess = args[0];
|
||||
[[maybe_unused]] uint32_t hProcess = args[0];
|
||||
uint32_t lpBaseAddress = args[1];
|
||||
uint32_t lpBuffer = args[2];
|
||||
uint32_t nSize = args[3];
|
||||
|
|
@ -377,13 +377,11 @@ uint32_t WardenEmulator::apiReadProcessMemory(WardenEmulator& emu, const std::ve
|
|||
// Unicorn Callbacks
|
||||
// ============================================================================
|
||||
|
||||
void WardenEmulator::hookCode(uc_engine* uc, uint64_t address, uint32_t size, void* userData) {
|
||||
WardenEmulator* emu = static_cast<WardenEmulator*>(userData);
|
||||
void WardenEmulator::hookCode([[maybe_unused]] uc_engine* uc, uint64_t address, [[maybe_unused]] uint32_t size, [[maybe_unused]] void* userData) {
|
||||
std::cout << "[Trace] 0x" << std::hex << address << std::dec << '\n';
|
||||
}
|
||||
|
||||
void WardenEmulator::hookMemInvalid(uc_engine* uc, int type, uint64_t address, int size, int64_t value, void* userData) {
|
||||
WardenEmulator* emu = static_cast<WardenEmulator*>(userData);
|
||||
void WardenEmulator::hookMemInvalid([[maybe_unused]] uc_engine* uc, int type, uint64_t address, int size, [[maybe_unused]] int64_t value, [[maybe_unused]] void* userData) {
|
||||
|
||||
const char* typeStr = "UNKNOWN";
|
||||
switch (type) {
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ bool WardenModule::load(const std::vector<uint8_t>& moduleData,
|
|||
}
|
||||
|
||||
bool WardenModule::processCheckRequest(const std::vector<uint8_t>& checkData,
|
||||
std::vector<uint8_t>& responseOut) {
|
||||
[[maybe_unused]] std::vector<uint8_t>& responseOut) {
|
||||
if (!loaded_) {
|
||||
std::cerr << "[WardenModule] Module not loaded, cannot process checks" << '\n';
|
||||
return false;
|
||||
|
|
@ -198,7 +198,7 @@ bool WardenModule::processCheckRequest(const std::vector<uint8_t>& checkData,
|
|||
return false;
|
||||
}
|
||||
|
||||
uint32_t WardenModule::tick(uint32_t deltaMs) {
|
||||
uint32_t WardenModule::tick([[maybe_unused]] uint32_t deltaMs) {
|
||||
if (!loaded_ || !funcList_.tick) {
|
||||
return 0; // No tick needed
|
||||
}
|
||||
|
|
@ -209,7 +209,7 @@ uint32_t WardenModule::tick(uint32_t deltaMs) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void WardenModule::generateRC4Keys(uint8_t* packet) {
|
||||
void WardenModule::generateRC4Keys([[maybe_unused]] uint8_t* packet) {
|
||||
if (!loaded_ || !funcList_.generateRC4Keys) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -633,9 +633,11 @@ bool WardenModule::applyRelocations() {
|
|||
currentOffset += delta;
|
||||
|
||||
if (currentOffset + 4 <= moduleSize_) {
|
||||
uint32_t* ptr = reinterpret_cast<uint32_t*>(
|
||||
static_cast<uint8_t*>(moduleMemory_) + currentOffset);
|
||||
*ptr += moduleBase_;
|
||||
uint8_t* addr = static_cast<uint8_t*>(moduleMemory_) + currentOffset;
|
||||
uint32_t val;
|
||||
std::memcpy(&val, addr, sizeof(uint32_t));
|
||||
val += moduleBase_;
|
||||
std::memcpy(addr, &val, sizeof(uint32_t));
|
||||
relocCount++;
|
||||
} else {
|
||||
std::cerr << "[WardenModule] Relocation offset " << currentOffset
|
||||
|
|
@ -755,16 +757,16 @@ bool WardenModule::initializeModule() {
|
|||
void (*logMessage)(const char* msg);
|
||||
};
|
||||
|
||||
// Setup client callbacks
|
||||
ClientCallbacks callbacks = {};
|
||||
// Setup client callbacks (used when calling module entry point below)
|
||||
[[maybe_unused]] ClientCallbacks callbacks = {};
|
||||
|
||||
// Stub callbacks (would need real implementations)
|
||||
callbacks.sendPacket = [](uint8_t* data, size_t len) {
|
||||
callbacks.sendPacket = []([[maybe_unused]] uint8_t* data, size_t len) {
|
||||
std::cout << "[WardenModule Callback] sendPacket(" << len << " bytes)" << '\n';
|
||||
// TODO: Send CMSG_WARDEN_DATA packet
|
||||
};
|
||||
|
||||
callbacks.validateModule = [](uint8_t* hash) {
|
||||
callbacks.validateModule = []([[maybe_unused]] uint8_t* hash) {
|
||||
std::cout << "[WardenModule Callback] validateModule()" << '\n';
|
||||
// TODO: Validate module hash
|
||||
};
|
||||
|
|
@ -779,7 +781,7 @@ bool WardenModule::initializeModule() {
|
|||
free(ptr);
|
||||
};
|
||||
|
||||
callbacks.generateRC4 = [](uint8_t* seed) {
|
||||
callbacks.generateRC4 = []([[maybe_unused]] uint8_t* seed) {
|
||||
std::cout << "[WardenModule Callback] generateRC4()" << '\n';
|
||||
// TODO: Re-key RC4 cipher
|
||||
};
|
||||
|
|
|
|||
|
|
@ -30,34 +30,39 @@ BLPImage BLPLoader::load(const std::vector<uint8_t>& blpData) {
|
|||
}
|
||||
|
||||
BLPImage BLPLoader::loadBLP1(const uint8_t* data, size_t size) {
|
||||
// BLP1 header has all uint32 fields (different layout from BLP2)
|
||||
const BLP1Header* header = reinterpret_cast<const BLP1Header*>(data);
|
||||
// Copy header to stack to avoid unaligned reinterpret_cast (UB on strict platforms)
|
||||
if (size < sizeof(BLP1Header)) {
|
||||
LOG_ERROR("BLP1 data too small for header");
|
||||
return BLPImage();
|
||||
}
|
||||
BLP1Header header;
|
||||
std::memcpy(&header, data, sizeof(BLP1Header));
|
||||
|
||||
BLPImage image;
|
||||
image.format = BLPFormat::BLP1;
|
||||
image.width = header->width;
|
||||
image.height = header->height;
|
||||
image.width = header.width;
|
||||
image.height = header.height;
|
||||
image.channels = 4;
|
||||
image.mipLevels = header->hasMips ? 16 : 1;
|
||||
image.mipLevels = header.hasMips ? 16 : 1;
|
||||
|
||||
// BLP1 compression: 0=JPEG (not used in WoW), 1=palette/indexed
|
||||
// BLP1 does NOT support DXT — only palette with optional alpha
|
||||
if (header->compression == 1) {
|
||||
if (header.compression == 1) {
|
||||
image.compression = BLPCompression::PALETTE;
|
||||
} else if (header->compression == 0) {
|
||||
} else if (header.compression == 0) {
|
||||
LOG_WARNING("BLP1 JPEG compression not supported");
|
||||
return BLPImage();
|
||||
} else {
|
||||
LOG_WARNING("BLP1 unknown compression: ", header->compression);
|
||||
LOG_WARNING("BLP1 unknown compression: ", header.compression);
|
||||
return BLPImage();
|
||||
}
|
||||
|
||||
LOG_DEBUG("Loading BLP1: ", image.width, "x", image.height, " ",
|
||||
getCompressionName(image.compression), " alpha=", header->alphaBits);
|
||||
getCompressionName(image.compression), " alpha=", header.alphaBits);
|
||||
|
||||
// Get first mipmap (full resolution)
|
||||
uint32_t offset = header->mipOffsets[0];
|
||||
uint32_t mipSize = header->mipSizes[0];
|
||||
uint32_t offset = header.mipOffsets[0];
|
||||
uint32_t mipSize = header.mipSizes[0];
|
||||
|
||||
if (offset + mipSize > size) {
|
||||
LOG_ERROR("BLP1 mipmap data out of bounds (offset=", offset, " size=", mipSize, " fileSize=", size, ")");
|
||||
|
|
@ -70,45 +75,50 @@ BLPImage BLPLoader::loadBLP1(const uint8_t* data, size_t size) {
|
|||
int pixelCount = image.width * image.height;
|
||||
image.data.resize(pixelCount * 4); // RGBA8
|
||||
|
||||
decompressPalette(mipData, image.data.data(), header->palette,
|
||||
image.width, image.height, static_cast<uint8_t>(header->alphaBits));
|
||||
decompressPalette(mipData, image.data.data(), header.palette,
|
||||
image.width, image.height, static_cast<uint8_t>(header.alphaBits));
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
BLPImage BLPLoader::loadBLP2(const uint8_t* data, size_t size) {
|
||||
// BLP2 header has uint8 fields for compression/alpha/encoding
|
||||
const BLP2Header* header = reinterpret_cast<const BLP2Header*>(data);
|
||||
// Copy header to stack to avoid unaligned reinterpret_cast (UB on strict platforms)
|
||||
if (size < sizeof(BLP2Header)) {
|
||||
LOG_ERROR("BLP2 data too small for header");
|
||||
return BLPImage();
|
||||
}
|
||||
BLP2Header header;
|
||||
std::memcpy(&header, data, sizeof(BLP2Header));
|
||||
|
||||
BLPImage image;
|
||||
image.format = BLPFormat::BLP2;
|
||||
image.width = header->width;
|
||||
image.height = header->height;
|
||||
image.width = header.width;
|
||||
image.height = header.height;
|
||||
image.channels = 4;
|
||||
image.mipLevels = header->hasMips ? 16 : 1;
|
||||
image.mipLevels = header.hasMips ? 16 : 1;
|
||||
|
||||
// BLP2 compression types:
|
||||
// 1 = palette/uncompressed
|
||||
// 2 = DXTC (DXT1/DXT3/DXT5 based on alphaDepth + alphaEncoding)
|
||||
// 3 = plain A8R8G8B8
|
||||
if (header->compression == 1) {
|
||||
if (header.compression == 1) {
|
||||
image.compression = BLPCompression::PALETTE;
|
||||
} else if (header->compression == 2) {
|
||||
} else if (header.compression == 2) {
|
||||
// BLP2 DXTC format selection based on alphaDepth + alphaEncoding:
|
||||
// alphaDepth=0 → DXT1 (no alpha)
|
||||
// alphaDepth>0, alphaEncoding=0 → DXT1 (1-bit alpha)
|
||||
// alphaDepth>0, alphaEncoding=1 → DXT3 (explicit 4-bit alpha)
|
||||
// alphaDepth>0, alphaEncoding=7 → DXT5 (interpolated alpha)
|
||||
if (header->alphaDepth == 0 || header->alphaEncoding == 0) {
|
||||
if (header.alphaDepth == 0 || header.alphaEncoding == 0) {
|
||||
image.compression = BLPCompression::DXT1;
|
||||
} else if (header->alphaEncoding == 1) {
|
||||
} else if (header.alphaEncoding == 1) {
|
||||
image.compression = BLPCompression::DXT3;
|
||||
} else if (header->alphaEncoding == 7) {
|
||||
} else if (header.alphaEncoding == 7) {
|
||||
image.compression = BLPCompression::DXT5;
|
||||
} else {
|
||||
image.compression = BLPCompression::DXT1;
|
||||
}
|
||||
} else if (header->compression == 3) {
|
||||
} else if (header.compression == 3) {
|
||||
image.compression = BLPCompression::ARGB8888;
|
||||
} else {
|
||||
image.compression = BLPCompression::ARGB8888;
|
||||
|
|
@ -116,13 +126,13 @@ BLPImage BLPLoader::loadBLP2(const uint8_t* data, size_t size) {
|
|||
|
||||
LOG_DEBUG("Loading BLP2: ", image.width, "x", image.height, " ",
|
||||
getCompressionName(image.compression),
|
||||
" (comp=", (int)header->compression, " alphaDepth=", (int)header->alphaDepth,
|
||||
" alphaEnc=", (int)header->alphaEncoding, " mipOfs=", header->mipOffsets[0],
|
||||
" mipSize=", header->mipSizes[0], ")");
|
||||
" (comp=", (int)header.compression, " alphaDepth=", (int)header.alphaDepth,
|
||||
" alphaEnc=", (int)header.alphaEncoding, " mipOfs=", header.mipOffsets[0],
|
||||
" mipSize=", header.mipSizes[0], ")");
|
||||
|
||||
// Get first mipmap (full resolution)
|
||||
uint32_t offset = header->mipOffsets[0];
|
||||
uint32_t mipSize = header->mipSizes[0];
|
||||
uint32_t offset = header.mipOffsets[0];
|
||||
uint32_t mipSize = header.mipSizes[0];
|
||||
|
||||
if (offset + mipSize > size) {
|
||||
LOG_ERROR("BLP2 mipmap data out of bounds");
|
||||
|
|
@ -149,8 +159,8 @@ BLPImage BLPLoader::loadBLP2(const uint8_t* data, size_t size) {
|
|||
break;
|
||||
|
||||
case BLPCompression::PALETTE:
|
||||
decompressPalette(mipData, image.data.data(), header->palette,
|
||||
image.width, image.height, header->alphaDepth);
|
||||
decompressPalette(mipData, image.data.data(), header.palette,
|
||||
image.width, image.height, header.alphaDepth);
|
||||
break;
|
||||
|
||||
case BLPCompression::ARGB8888:
|
||||
|
|
|
|||
|
|
@ -42,19 +42,20 @@ bool DBCFile::load(const std::vector<uint8_t>& dbcData) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Read header
|
||||
const DBCHeader* header = reinterpret_cast<const DBCHeader*>(dbcData.data());
|
||||
// Read header safely (avoid unaligned reinterpret_cast — UB on strict platforms)
|
||||
DBCHeader header;
|
||||
std::memcpy(&header, dbcData.data(), sizeof(DBCHeader));
|
||||
|
||||
// Verify magic
|
||||
if (std::memcmp(header->magic, "WDBC", 4) != 0) {
|
||||
LOG_ERROR("Invalid DBC magic: ", std::string(header->magic, 4));
|
||||
if (std::memcmp(header.magic, "WDBC", 4) != 0) {
|
||||
LOG_ERROR("Invalid DBC magic: ", std::string(header.magic, 4));
|
||||
return false;
|
||||
}
|
||||
|
||||
recordCount = header->recordCount;
|
||||
fieldCount = header->fieldCount;
|
||||
recordSize = header->recordSize;
|
||||
stringBlockSize = header->stringBlockSize;
|
||||
recordCount = header.recordCount;
|
||||
fieldCount = header.fieldCount;
|
||||
recordSize = header.recordSize;
|
||||
stringBlockSize = header.stringBlockSize;
|
||||
|
||||
// Validate sizes
|
||||
uint32_t expectedSize = sizeof(DBCHeader) + (recordCount * recordSize) + stringBlockSize;
|
||||
|
|
@ -111,8 +112,9 @@ uint32_t DBCFile::getUInt32(uint32_t recordIndex, uint32_t fieldIndex) const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
const uint32_t* field = reinterpret_cast<const uint32_t*>(record + (fieldIndex * 4));
|
||||
return *field;
|
||||
uint32_t value;
|
||||
std::memcpy(&value, record + (fieldIndex * 4), sizeof(uint32_t));
|
||||
return value;
|
||||
}
|
||||
|
||||
int32_t DBCFile::getInt32(uint32_t recordIndex, uint32_t fieldIndex) const {
|
||||
|
|
@ -129,8 +131,9 @@ float DBCFile::getFloat(uint32_t recordIndex, uint32_t fieldIndex) const {
|
|||
return 0.0f;
|
||||
}
|
||||
|
||||
const float* field = reinterpret_cast<const float*>(record + (fieldIndex * 4));
|
||||
return *field;
|
||||
float value;
|
||||
std::memcpy(&value, record + (fieldIndex * 4), sizeof(float));
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string DBCFile::getString(uint32_t recordIndex, uint32_t fieldIndex) const {
|
||||
|
|
|
|||
|
|
@ -1456,9 +1456,7 @@ bool M2Loader::loadSkin(const std::vector<uint8_t>& skinData, M2Model& model) {
|
|||
if (header.nSubmeshes > 0 && header.ofsSubmeshes > 0) {
|
||||
submeshes = readArray<M2SkinSubmesh>(skinData, header.ofsSubmeshes, header.nSubmeshes);
|
||||
core::Logger::getInstance().debug(" Submeshes: ", submeshes.size());
|
||||
for (size_t i = 0; i < submeshes.size(); i++) {
|
||||
const auto& sm = submeshes[i];
|
||||
}
|
||||
(void)submeshes;
|
||||
}
|
||||
|
||||
// Read batches with proper submesh references
|
||||
|
|
|
|||
|
|
@ -1610,7 +1610,7 @@ glm::mat4 CharacterRenderer::getBoneTransform(const pipeline::M2Bone& bone, floa
|
|||
|
||||
// --- Rendering ---
|
||||
|
||||
void CharacterRenderer::render(VkCommandBuffer cmd, VkDescriptorSet perFrameSet, const Camera& camera) {
|
||||
void CharacterRenderer::render(VkCommandBuffer cmd, VkDescriptorSet perFrameSet, [[maybe_unused]] const Camera& camera) {
|
||||
if (instances.empty() || !opaquePipeline_) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ bool VkRenderTarget::create(VkContext& ctx, uint32_t width, uint32_t height,
|
|||
|
||||
// Create color image (multisampled if MSAA)
|
||||
colorImage_ = createImage(device, allocator, width, height, format,
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | (useMSAA ? VkImageUsageFlags(0) : VK_IMAGE_USAGE_SAMPLED_BIT),
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | (useMSAA ? static_cast<VkImageUsageFlags>(0) : static_cast<VkImageUsageFlags>(VK_IMAGE_USAGE_SAMPLED_BIT)),
|
||||
msaaSamples);
|
||||
|
||||
if (!colorImage_.image) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue