From c812f19a058055faf5510e370605b207d34970e1 Mon Sep 17 00:00:00 2001 From: avitasia Date: Tue, 4 Nov 2025 17:10:48 -0800 Subject: [PATCH] refactors --- nampower/main.cpp | 34 ++++++++++++++++++++++++++++++++++ nampower/main.hpp | 13 ++++++++++++- nampower/offsets.hpp | 3 +++ nampower/spellcast.cpp | 33 ++++++++++----------------------- nampower/spellevents.cpp | 10 +++++++++- nampower/spellevents.hpp | 3 +++ nampower/types.h | 2 +- 7 files changed, 72 insertions(+), 26 deletions(-) diff --git a/nampower/main.cpp b/nampower/main.cpp index 58176bf..21acb81 100644 --- a/nampower/main.cpp +++ b/nampower/main.cpp @@ -128,6 +128,8 @@ namespace Nampower { std::unique_ptr> gPeriodicAuraLogHandlerDetour; std::unique_ptr> gSpellNonMeleeDmgLogHandlerDetour; + std::unique_ptr> gCGPlayer_C_OnAttackIconPressedDetour; + uint32_t GetTime() { return static_cast(std::chrono::duration_cast( std::chrono::high_resolution_clock::now().time_since_epoch()).count()) - gStartTime; @@ -163,6 +165,34 @@ namespace Nampower { return p_GetContext(); } + void SetTarget(uint64_t target) { + auto setTargetFn = reinterpret_cast(Offsets::ScriptTargetUnit); + setTargetFn(&target); + } + + void SetSelectionTarget(uint64_t target) { + auto dataStore = CDataStore(); + uint32_t opcode = 317; // CMSG_SET_SELECTION + dataStore.Put(opcode); + dataStore.Put(target); + + dataStore.Finalize(); + + auto const clientServicesSend = reinterpret_cast(Offsets::ClientServices_Send); + clientServicesSend(&dataStore); + } + + void SetAttackTarget(uint64_t target) { + auto dataStore = CDataStore(); + uint32_t opcode = 0x141; // CMSG_ATTACKSWING + dataStore.Put(opcode); + dataStore.Put(target); + + dataStore.Finalize(); + + auto const clientServicesSend = reinterpret_cast(Offsets::ClientServices_Send); + clientServicesSend(&dataStore); + } void RegisterLuaFunction(char *name, uintptr_t *func) { DEBUG_LOG("Registering " << name << " to " << func); @@ -1109,6 +1139,10 @@ namespace Nampower { Script_GetNampowerVersion); gGetItemLevelDetour = createHook(process, Offsets::Script_GetItemLevel, Script_GetItemLevel); gIEndSceneDetour = createHook(process, Offsets::ISceneEndPtr, &ISceneEndHook); + + // gCGPlayer_C_OnAttackIconPressedDetour = createHook(process, + // Offsets::CGPlayer_C_OnAttackIconPressed, + // &CGPlayer_C_OnAttackIconPressedHook); } void SpellVisualsInitializeHook(hadesmem::PatchDetourBase *detour) { diff --git a/nampower/main.hpp b/nampower/main.hpp index 2827492..a1f2425 100644 --- a/nampower/main.hpp +++ b/nampower/main.hpp @@ -31,7 +31,7 @@ namespace Nampower { constexpr uint32_t MAJOR_VERSION = 2; constexpr uint32_t MINOR_VERSION = 11; - constexpr uint32_t PATCH_VERSION = 1; + constexpr uint32_t PATCH_VERSION = 2; constexpr int32_t LUA_REGISTRYINDEX = -10000; constexpr int32_t LUA_GLOBALSINDEX = -10001; @@ -94,6 +94,8 @@ namespace Nampower { uint32_t *duration, uint64_t *startTime, uint32_t *enable); using Spell_C_IsSpellUsableT = int (__fastcall *)(const game::SpellRec *spellRec, uint32_t *usesManaReturn); + using CGPlayer_C_OnAttackIconPressedT = int (__fastcall *)(uintptr_t *this_ptr, void *dummy_edx, uint64_t guid); + using GetSpellSlotAndTypeT = int (__fastcall *)(const char *, uint32_t *); using GetTimeMsT = uint64_t (__stdcall *)(); @@ -137,6 +139,8 @@ namespace Nampower { using GetBuffByIndexT = uintptr_t *(__fastcall *)(int index); + using TargetUnitT = void (__fastcall *)(uint64_t *guid); + using CVarLookupT = uintptr_t *(__fastcall *)(const char *); using SetCVarT = int (__fastcall *)(uintptr_t *luaPtr); using CVarRegisterT = int *(__fastcall *)(char *name, char *help, int unk1, const char *defaultValuePtr, @@ -170,4 +174,11 @@ namespace Nampower { bool processQueues(); uint32_t EffectiveCastEndMs(); + + void SetTarget(uint64_t target); + + void SetSelectionTarget(uint64_t target); + + void SetAttackTarget(uint64_t target); + } \ No newline at end of file diff --git a/nampower/offsets.hpp b/nampower/offsets.hpp index 11e330a..063cf97 100644 --- a/nampower/offsets.hpp +++ b/nampower/offsets.hpp @@ -76,6 +76,7 @@ enum class Offsets : std::uint32_t { LockedTargetGuid = 0x00B4E2D8, OnSpriteRightClick = 0x00492820, CGGameUI_Target = 0X00493540, + ScriptTargetUnit = 0X00489A40, SpellVisualsHandleCastStart = 0X006EC220, PlaySpellVisualHandler = 0X006E98D0, @@ -174,4 +175,6 @@ enum class Offsets : std::uint32_t { CGUnit_C_ClearCastingSpell = 0x0060d040, CGUnit_C_ClearSpellEffect = 0x00614150, + + CGPlayer_C_OnAttackIconPressed = 0X006131A0, }; diff --git a/nampower/spellcast.cpp b/nampower/spellcast.cpp index f38a8d4..1242d15 100644 --- a/nampower/spellcast.cpp +++ b/nampower/spellcast.cpp @@ -108,8 +108,6 @@ namespace Nampower { } gLastCastData.startTimeMs = currentTime; - - // if queued cast, simulate spellcast start } void CastQueuedNonGcdSpell() { @@ -120,7 +118,7 @@ namespace Nampower { gCastData.castingQueuedSpell = true; gCastData.numRetries = nonGcdCastParams.numRetries; - Spell_C_CastSpellHook(castSpellDetour, nonGcdCastParams.playerUnit, nonGcdCastParams.spellId, + Spell_C_CastSpellHook(castSpellDetour, nonGcdCastParams.casterUnit, nonGcdCastParams.spellId, nonGcdCastParams.item, nonGcdCastParams.guid); gLastCastData.wasQueued = true; } else { @@ -140,7 +138,7 @@ namespace Nampower { DEBUG_LOG("Triggering queued cast of " << game::GetSpellName(gLastNormalCastParams.spellId)); gCastData.castingQueuedSpell = true; gCastData.numRetries = gLastNormalCastParams.numRetries; - Spell_C_CastSpellHook(castSpellDetour, gLastNormalCastParams.playerUnit, gLastNormalCastParams.spellId, + Spell_C_CastSpellHook(castSpellDetour, gLastNormalCastParams.casterUnit, gLastNormalCastParams.spellId, gLastNormalCastParams.item, gLastNormalCastParams.guid); gLastCastData.wasQueued = true; } else { @@ -163,7 +161,7 @@ namespace Nampower { } void SaveCastParams(CastSpellParams *params, - uint32_t *playerUnit, + uint32_t *casterUnit, uint32_t spellId, uintptr_t *item, std::uint64_t guid, @@ -172,7 +170,7 @@ namespace Nampower { uint32_t castStartTimeMs, CastType castType, uint32_t numRetries) { - params->playerUnit = playerUnit; + params->casterUnit = casterUnit; params->spellId = spellId; params->item = item; params->guid = guid; @@ -218,18 +216,6 @@ namespace Nampower { } } - void setSelectionTarget(uint64_t target) { - auto dataStore = CDataStore(); - uint32_t opcode = 317; // CMSG_SET_SELECTION - dataStore.Put(opcode); - dataStore.Put(target); - - dataStore.Finalize(); - - auto const clientServicesSend = reinterpret_cast(Offsets::ClientServices_Send); - clientServicesSend(&dataStore); - } - bool Spell_C_CastSpellHook(hadesmem::PatchDetourBase *detour, uint32_t *casterUnit, uint32_t spellId, uintptr_t *item, std::uint64_t guid) { @@ -257,14 +243,14 @@ namespace Nampower { auto const isSpecialSpell = SpellIsAttackTradeskillOrEnchant(spell); auto const currentTargetGuid = game::GetCurrentTargetGuid(); - if(spellIsChanneling) { + if (spellIsChanneling) { auto casterGuid = game::UnitGetGuid(casterUnit); if (casterGuid == game::ClntObjMgrGetActivePlayerGuid()) { // check that locked target guid matches our unit target guid auto unitTargetGuid = game::UnitGetTargetGuid(casterUnit); if (unitTargetGuid != currentTargetGuid) { DEBUG_LOG("Updating selection target to " << currentTargetGuid << " from " << unitTargetGuid); - setSelectionTarget(currentTargetGuid); + SetSelectionTarget(currentTargetGuid); } } } @@ -299,7 +285,8 @@ namespace Nampower { itemId = game::GetItemId((game::CGItem_C *) item); } - DEBUG_LOG("Attempt cast " << spellName << " item " << item << " on guid " << guid << " target " << currentTargetGuid + DEBUG_LOG("Attempt cast " << spellName << " item " << item << " on guid " << guid << " target " + << currentTargetGuid << ", time since last cast " << currentTime - gLastCastData.startTimeMs); // clear cooldown queue if we are casting a spell @@ -522,7 +509,7 @@ namespace Nampower { // otherwise can break cooldown in the client and cause unnecessary errors if (castTime == 0 || spell->Attributes & game::SPELL_ATTR_DISABLED_WHILE_ACTIVE) { // check if spam protection is enabled - if(gUserSettings.spamProtectionEnabled) { + if (gUserSettings.spamProtectionEnabled) { auto castParams = gCastHistory.findNewestWaitingForServerSpellId(spellId); if (castParams && currentTime - castParams->castStartTimeMs < 500) { @@ -643,7 +630,7 @@ namespace Nampower { TriggerSpellQueuedEvent(ON_SWING_QUEUE_POPPED, gLastOnSwingCastParams.spellId); - Spell_C_CastSpellHook(castSpellDetour, gLastOnSwingCastParams.playerUnit, + Spell_C_CastSpellHook(castSpellDetour, gLastOnSwingCastParams.casterUnit, gLastOnSwingCastParams.spellId, gLastOnSwingCastParams.item, gLastOnSwingCastParams.guid); gCastData.onSwingQueued = false; diff --git a/nampower/spellevents.cpp b/nampower/spellevents.cpp index bafb6ad..300dba0 100644 --- a/nampower/spellevents.cpp +++ b/nampower/spellevents.cpp @@ -277,7 +277,6 @@ namespace Nampower { return spellDelayed(opCode, packet); } - int CastResultHandlerHook(hadesmem::PatchDetourBase *detour, uint32_t *opCode, CDataStore *packet) { auto const castResultHandler = detour->GetTrampolineT(); @@ -705,4 +704,13 @@ namespace Nampower { return 1; } + + int CGPlayer_C_OnAttackIconPressedHook(hadesmem::PatchDetourBase *detour, uintptr_t *this_ptr, void *dummy_edx, + uint64_t guid) { + auto const onAttackIconPressed = detour->GetTrampolineT(); + + DEBUG_LOG("Attack icon pressed for guid " << guid); + + return onAttackIconPressed(this_ptr, dummy_edx, 0); + } } \ No newline at end of file diff --git a/nampower/spellevents.hpp b/nampower/spellevents.hpp index 44fed0c..00898b0 100644 --- a/nampower/spellevents.hpp +++ b/nampower/spellevents.hpp @@ -35,4 +35,7 @@ namespace Nampower { CDataStore *packet); int PlaySpellVisualHandlerHook(hadesmem::PatchDetourBase *detour, uint32_t *opCode, CDataStore *packet); + + int CGPlayer_C_OnAttackIconPressedHook(hadesmem::PatchDetourBase *detour, uintptr_t *this_ptr, void *dummy_edx, + uint64_t guid); } \ No newline at end of file diff --git a/nampower/types.h b/nampower/types.h index 14052d3..237b992 100644 --- a/nampower/types.h +++ b/nampower/types.h @@ -71,7 +71,7 @@ struct CastSpellParams { /* Original cast spell function arguments */ uint64_t castId; - uint32_t *playerUnit; + uint32_t *casterUnit; uint32_t spellId; uintptr_t *item; uint64_t guid;