mirror of
https://github.com/brues-code/nampower.git
synced 2026-09-27 17:26:03 +00:00
handle unicode filenames in import/export
This commit is contained in:
+9593
-9545
File diff suppressed because it is too large
Load Diff
@@ -132,8 +132,34 @@ namespace Nampower {
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::wstring Utf8ToWide(const std::string &utf8) {
|
||||
if (utf8.empty()) {
|
||||
return {};
|
||||
}
|
||||
const int len = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), static_cast<int>(utf8.size()), nullptr, 0);
|
||||
if (len <= 0) {
|
||||
return {};
|
||||
}
|
||||
std::wstring wide(len, L'\0');
|
||||
MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), static_cast<int>(utf8.size()), &wide[0], len);
|
||||
return wide;
|
||||
}
|
||||
|
||||
static std::string WideToUtf8(const std::wstring &wide) {
|
||||
if (wide.empty()) {
|
||||
return {};
|
||||
}
|
||||
const int len = WideCharToMultiByte(CP_UTF8, 0, wide.c_str(), static_cast<int>(wide.size()), nullptr, 0, nullptr, nullptr);
|
||||
if (len <= 0) {
|
||||
return {};
|
||||
}
|
||||
std::string utf8(len, '\0');
|
||||
WideCharToMultiByte(CP_UTF8, 0, wide.c_str(), static_cast<int>(wide.size()), &utf8[0], len, nullptr, nullptr);
|
||||
return utf8;
|
||||
}
|
||||
|
||||
static bool EnsureDirectoryExists(const char *baseDir) {
|
||||
if (CreateDirectoryA(baseDir, nullptr) != 0) {
|
||||
if (CreateDirectoryW(Utf8ToWide(baseDir).c_str(), nullptr) != 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -155,13 +181,14 @@ namespace Nampower {
|
||||
}
|
||||
|
||||
static bool TryGetFullPath(const std::string &inputPath, std::string &outFullPath) {
|
||||
char buffer[MAX_PATH] = {};
|
||||
const DWORD result = GetFullPathNameA(inputPath.c_str(), MAX_PATH, buffer, nullptr);
|
||||
const std::wstring wideInput = Utf8ToWide(inputPath);
|
||||
wchar_t buffer[MAX_PATH] = {};
|
||||
const DWORD result = GetFullPathNameW(wideInput.c_str(), MAX_PATH, buffer, nullptr);
|
||||
if (result == 0 || result >= MAX_PATH) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outFullPath.assign(buffer, result);
|
||||
outFullPath = WideToUtf8(std::wstring(buffer, result));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -213,7 +240,8 @@ namespace Nampower {
|
||||
|
||||
DEBUG_LOG("Attempting to read file from " << baseDir << ": " << fullPath);
|
||||
|
||||
const DWORD attributes = GetFileAttributesA(fullPath.c_str());
|
||||
const std::wstring wideFullPath = Utf8ToWide(fullPath);
|
||||
const DWORD attributes = GetFileAttributesW(wideFullPath.c_str());
|
||||
if (attributes == INVALID_FILE_ATTRIBUTES) {
|
||||
const DWORD errorCode = GetLastError();
|
||||
if (returnNilIfMissing && (errorCode == ERROR_FILE_NOT_FOUND || errorCode == ERROR_PATH_NOT_FOUND)) {
|
||||
@@ -229,7 +257,7 @@ namespace Nampower {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::ifstream in(fullPath);
|
||||
std::ifstream in(wideFullPath);
|
||||
if (!in) {
|
||||
lua_error(luaState, "Failed to open file for reading.");
|
||||
return 0;
|
||||
@@ -273,7 +301,7 @@ namespace Nampower {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::ofstream out(fullPath, openMode);
|
||||
std::ofstream out(Utf8ToWide(fullPath), openMode);
|
||||
if (!out) {
|
||||
lua_error(luaState, "Failed to open file for writing.");
|
||||
return 0;
|
||||
@@ -362,7 +390,7 @@ namespace Nampower {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const DWORD attributes = GetFileAttributesA(fullPath.c_str());
|
||||
const DWORD attributes = GetFileAttributesW(Utf8ToWide(fullPath).c_str());
|
||||
if (attributes == INVALID_FILE_ATTRIBUTES) {
|
||||
const DWORD errorCode = GetLastError();
|
||||
if (errorCode == ERROR_FILE_NOT_FOUND || errorCode == ERROR_PATH_NOT_FOUND) {
|
||||
|
||||
+18
-15
@@ -72,7 +72,7 @@ namespace Nampower {
|
||||
uint32_t gBufferTimeMs; // adjusts dynamically depending on errors
|
||||
|
||||
uint32_t gDisenchantItemId = 0;
|
||||
uint32_t gDisenchantQuality = 0; // 0 = unset
|
||||
uint32_t gDisenchantQuality = 0; // 0 = unset
|
||||
bool gDisenchantIncludeSoulbound = false;
|
||||
uint32_t gNextDisenchantTimeMs = 0;
|
||||
|
||||
@@ -182,6 +182,7 @@ namespace Nampower {
|
||||
|
||||
// Forward declarations for hook functions
|
||||
void Player_LoadScriptFunctionsHook(hadesmem::PatchDetourBase *detour);
|
||||
|
||||
void Glue_LoadScriptFunctionsHook(hadesmem::PatchDetourBase *detour);
|
||||
|
||||
void FrameScript_CreateEventsHook(hadesmem::PatchDetourBase *detour, int param_1, uint32_t maxEventId);
|
||||
@@ -1424,7 +1425,7 @@ namespace Nampower {
|
||||
}
|
||||
|
||||
return detour;
|
||||
} catch (const hadesmem::Error& e) {
|
||||
} catch (const hadesmem::Error &e) {
|
||||
lastError = e.what();
|
||||
|
||||
if (attempt == 0) {
|
||||
@@ -1433,7 +1434,7 @@ namespace Nampower {
|
||||
}
|
||||
|
||||
if (attempt < maxRetries - 1) {
|
||||
Sleep(10); // Wait 10ms before retry
|
||||
Sleep(10); // Wait 10ms before retry
|
||||
continue;
|
||||
} else {
|
||||
// Out of retries
|
||||
@@ -1442,7 +1443,7 @@ namespace Nampower {
|
||||
<< "): " << lastError);
|
||||
throw;
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
} catch (const std::exception &e) {
|
||||
lastError = e.what();
|
||||
|
||||
if (attempt == 0) {
|
||||
@@ -1452,7 +1453,7 @@ namespace Nampower {
|
||||
}
|
||||
|
||||
if (attempt < maxRetries - 1) {
|
||||
Sleep(10); // Wait 10ms before retry
|
||||
Sleep(10); // Wait 10ms before retry
|
||||
continue;
|
||||
} else {
|
||||
DEBUG_LOG(" FAILED after " << maxRetries << " attempts (offset 0x"
|
||||
@@ -1479,7 +1480,7 @@ namespace Nampower {
|
||||
}
|
||||
|
||||
if (attempt < maxRetries - 1) {
|
||||
Sleep(10); // Wait 10ms before retry
|
||||
Sleep(10); // Wait 10ms before retry
|
||||
continue;
|
||||
} else {
|
||||
DEBUG_LOG(" FAILED after " << maxRetries << " attempts (offset 0x"
|
||||
@@ -1526,13 +1527,13 @@ namespace Nampower {
|
||||
gSpellEnergizeLogHandlerDetour = createHook<PacketHandlerT>(process, Offsets::SpellEnergizeLogHandler,
|
||||
&SpellEnergizeLogHandlerHook);
|
||||
gProcResistHandlerDetour = createHook<PacketHandlerT>(process, Offsets::ProcResistHandler,
|
||||
&ProcResistHandlerHook);
|
||||
&ProcResistHandlerHook);
|
||||
gSpellLogMissHandlerDetour = createHook<PacketHandlerT>(process, Offsets::SpellLogMissHandler,
|
||||
&SpellLogMissHandlerHook);
|
||||
&SpellLogMissHandlerHook);
|
||||
gSpellOrDamageImmuneHandlerDetour = createHook<PacketHandlerT>(process, Offsets::SpellOrDamageImmuneHandler,
|
||||
&SpellOrDamageImmuneHandlerHook);
|
||||
&SpellOrDamageImmuneHandlerHook);
|
||||
gUnitCombatLogDispelledDetour = createHook<UnitCombatLogDispelledT>(process, Offsets::UnitCombatLogDispelled,
|
||||
&UnitCombatLogDispelledHook);
|
||||
&UnitCombatLogDispelledHook);
|
||||
gSpellFailedOtherHandlerDetour = createHook<PacketHandlerT>(process, Offsets::SpellFailedOtherHandler,
|
||||
&SpellFailedOtherHandlerHook);
|
||||
gSpellFailedDetour = createHook<Spell_C_SpellFailedT>(process, Offsets::Spell_C_SpellFailed,
|
||||
@@ -1571,12 +1572,14 @@ namespace Nampower {
|
||||
&CGUnit_C_OnAuraStacksChangedHook);
|
||||
gUnitCombatLogUnitDeadDetour = createHook<UnitCombatLogUnitDeadT>(process, Offsets::UnitCombatLogUnitDead,
|
||||
&UnitCombatLogUnitDeadHook);
|
||||
gCGBuffBar_UpdateDurationDetour = createHook<CGBuffBar_UpdateDurationT>(process, Offsets::CGBuffBar_UpdateDuration,
|
||||
&CGBuffBar_UpdateDurationHook);
|
||||
gAttackRoundInfo_ReadPacketDetour = createHook<AttackRoundInfo_ReadPacketT>(process, Offsets::AttackRoundInfo_ReadPacket,
|
||||
&AttackRoundInfo_ReadPacketHook);
|
||||
gCGBuffBar_UpdateDurationDetour = createHook<CGBuffBar_UpdateDurationT>(
|
||||
process, Offsets::CGBuffBar_UpdateDuration,
|
||||
&CGBuffBar_UpdateDurationHook);
|
||||
gAttackRoundInfo_ReadPacketDetour = createHook<AttackRoundInfo_ReadPacketT>(
|
||||
process, Offsets::AttackRoundInfo_ReadPacket,
|
||||
&AttackRoundInfo_ReadPacketHook);
|
||||
gCSimpleFrame_GetNameDetour = createHook<LuaScriptT>(process, Offsets::CSimpleFrame_GetName,
|
||||
&CSimpleFrame_GetNameHook);
|
||||
&CSimpleFrame_GetNameHook);
|
||||
gCGUnit_C_AddChatBubbleDetour = createHook<CGUnit_C_AddChatBubbleT>(
|
||||
process, Offsets::CGUnit_C_AddChatBubble, &CGUnit_C_AddChatBubbleHook);
|
||||
gCSimpleTop_OnKeyDownDetour = createHook<CSimpleTop_OnKeyDownT>(
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ namespace Nampower {
|
||||
|
||||
constexpr uint32_t MAJOR_VERSION = 4;
|
||||
constexpr uint32_t MINOR_VERSION = 1;
|
||||
constexpr uint32_t PATCH_VERSION = 0;
|
||||
constexpr uint32_t PATCH_VERSION = 1;
|
||||
|
||||
constexpr int32_t LUA_REGISTRYINDEX = -10000;
|
||||
constexpr int32_t LUA_GLOBALSINDEX = -10001;
|
||||
|
||||
@@ -46,4 +46,6 @@ namespace Nampower {
|
||||
float Spell_C_GetSpellRadiusHook(hadesmem::PatchDetourBase *detour);
|
||||
|
||||
void SendCastHook(hadesmem::PatchDetourBase *detour, game::SpellCast *cast, char unk);
|
||||
|
||||
void TriggerQuickcast();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user