mirror of
https://github.com/brues-code/nampower.git
synced 2026-10-19 11:30:50 +00:00
add ability to get nameplate guid using getName(1)
This commit is contained in:
@@ -131,6 +131,17 @@ Examples:
|
||||
```
|
||||
|
||||
|
||||
### CSimpleFrame:GetName() Enhancement
|
||||
The built-in `CSimpleFrame:GetName()` method is hooked to support an optional argument for retrieving the GUID of the unit associated with a nameplate frame.
|
||||
|
||||
- `frame:GetName()` - Returns the frame name (original behavior).
|
||||
- `frame:GetName(1)` - Returns the GUID string (e.g., `"0x0000000000000001"`) of the unit associated with the nameplate frame.
|
||||
|
||||
Example:
|
||||
```
|
||||
/run local f = GetMouseFocus(); if f then DEFAULT_CHAT_FRAME:AddMessage(f:GetName(1) or "no guid") end
|
||||
```
|
||||
|
||||
## Custom Lua Functions
|
||||
|
||||
For complete documentation of all custom Lua functions added by Nampower, see **[SCRIPTS.md](SCRIPTS.md)**.
|
||||
|
||||
+9734
-9719
File diff suppressed because it is too large
Load Diff
@@ -29,6 +29,7 @@ namespace Nampower {
|
||||
lua_newtableT lua_newtable = reinterpret_cast<lua_newtableT>(Offsets::lua_newtable);
|
||||
lua_settableT lua_settable = reinterpret_cast<lua_settableT>(Offsets::lua_settable);
|
||||
luaL_refT luaL_ref = reinterpret_cast<luaL_refT>(Offsets::luaL_ref);
|
||||
lua_touserdataT lua_touserdata = reinterpret_cast<lua_touserdataT>(Offsets::lua_touserdata);
|
||||
lua_rawgetiT lua_rawgeti = reinterpret_cast<lua_rawgetiT>(Offsets::lua_rawgeti);
|
||||
luaL_unrefT luaL_unref = reinterpret_cast<luaL_unrefT>(Offsets::luaL_unref);
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace Nampower {
|
||||
extern lua_newtableT lua_newtable;
|
||||
extern lua_settableT lua_settable;
|
||||
extern luaL_refT luaL_ref;
|
||||
extern lua_touserdataT lua_touserdata;
|
||||
extern lua_rawgetiT lua_rawgeti;
|
||||
extern luaL_unrefT luaL_unref;
|
||||
|
||||
|
||||
@@ -150,6 +150,8 @@ namespace Nampower {
|
||||
|
||||
std::unique_ptr<hadesmem::PatchDetour<GetSpellSlotFromLuaT> > gGetSpellSlotFromLuaDetour;
|
||||
|
||||
std::unique_ptr<hadesmem::PatchDetour<LuaScriptT> > gCSimpleFrame_GetNameDetour;
|
||||
|
||||
// Flags for one-time initialization
|
||||
std::once_flag loadFlag;
|
||||
std::once_flag initHooksFlag;
|
||||
@@ -1385,6 +1387,8 @@ namespace Nampower {
|
||||
&UnitCombatLogUnitDeadHook);
|
||||
gAttackRoundInfo_ReadPacketDetour = createHook<AttackRoundInfo_ReadPacketT>(process, Offsets::AttackRoundInfo_ReadPacket,
|
||||
&AttackRoundInfo_ReadPacketHook);
|
||||
gCSimpleFrame_GetNameDetour = createHook<LuaScriptT>(process, Offsets::CSimpleFrame_GetName,
|
||||
&CSimpleFrame_GetNameHook);
|
||||
gLoadScriptFunctionsDetour = createHook<LoadScriptFunctionsT>(process, Offsets::LoadScriptFunctions,
|
||||
&LoadScriptFunctionsHook);
|
||||
gCreateEventsDetour = createHook<FrameScript_CreateEventsT>(process, Offsets::FrameScript_CreateEvents,
|
||||
|
||||
+3
-2
@@ -25,8 +25,8 @@ namespace Nampower {
|
||||
constexpr uint32_t DISENCHANT_QUALITY_PURPLE = 0x04; // Epic
|
||||
|
||||
constexpr uint32_t MAJOR_VERSION = 2;
|
||||
constexpr uint32_t MINOR_VERSION = 27;
|
||||
constexpr uint32_t PATCH_VERSION = 2;
|
||||
constexpr uint32_t MINOR_VERSION = 28;
|
||||
constexpr uint32_t PATCH_VERSION = 0;
|
||||
|
||||
constexpr int32_t LUA_REGISTRYINDEX = -10000;
|
||||
constexpr int32_t LUA_GLOBALSINDEX = -10001;
|
||||
@@ -141,6 +141,7 @@ namespace Nampower {
|
||||
using lua_newtableT = void (__fastcall *)(uintptr_t *);
|
||||
using lua_settableT = void (__fastcall *)(uintptr_t *, int);
|
||||
using luaL_refT = int (__fastcall *)(uintptr_t *, int);
|
||||
using lua_touserdataT = void *(__fastcall *)(uintptr_t *, int);
|
||||
using lua_rawgetiT = void (__fastcall *)(uintptr_t *, int, int);
|
||||
using luaL_unrefT = void (__fastcall *)(uintptr_t *, int, int);
|
||||
|
||||
|
||||
@@ -841,4 +841,70 @@ namespace Nampower {
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t CSimpleFrame_GetNameHook(hadesmem::PatchDetourBase *detour, uintptr_t *luaState) {
|
||||
luaState = GetLuaStatePtr();
|
||||
|
||||
// Type ID lazy initialization (mirrors original at 0x00CF0C3C / 0x00CEEF6C)
|
||||
static auto typeIdCounter = reinterpret_cast<uint32_t *>(0x00CEEF6C);
|
||||
static auto nameplateTypeId = reinterpret_cast<uint32_t *>(0x00CF0C3C);
|
||||
|
||||
if (*nameplateTypeId == 0) {
|
||||
*typeIdCounter = *typeIdCounter + 1;
|
||||
*nameplateTypeId = *typeIdCounter;
|
||||
}
|
||||
uint32_t typeId = *nameplateTypeId;
|
||||
|
||||
uintptr_t *frameObj = nullptr;
|
||||
|
||||
int luaArgType = lua_type(luaState, 1);
|
||||
if (luaArgType == LUA_TTABLE) {
|
||||
lua_rawgeti(luaState, 1, 0);
|
||||
|
||||
frameObj = reinterpret_cast<uintptr_t *>(lua_touserdata(luaState, -1));
|
||||
lua_settop(luaState, -2);
|
||||
|
||||
if (frameObj == nullptr) {
|
||||
lua_error(luaState, "Attempt to find 'this' in non-frame table");
|
||||
} else {
|
||||
// Type check via vtable[4] (offset 0x10)
|
||||
using IsTypeT = char (__thiscall *)(uintptr_t *thisPtr, uint32_t typeId);
|
||||
auto vtable = reinterpret_cast<uintptr_t *>(*frameObj);
|
||||
auto isType = reinterpret_cast<IsTypeT>(vtable[4]);
|
||||
if (isType(frameObj, typeId) == 0) {
|
||||
lua_error(luaState, "Wrong object type for member function");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
lua_error(luaState, "Attempt to find 'this' in non-table value");
|
||||
}
|
||||
|
||||
// Check if second arg is passed (e.g. nameplate:GetName(1) to get GUID)
|
||||
if (lua_isnumber(luaState, 2) && static_cast<int>(lua_tonumber(luaState, 2)) != 0) {
|
||||
// Return GUID string from frame object at offset 0x4E8/0x4EC
|
||||
uint32_t guidLow = frameObj[0x13a];
|
||||
uint32_t guidHigh = frameObj[0x13b];
|
||||
uint64_t guid = (static_cast<uint64_t>(guidHigh) << 32) | guidLow;
|
||||
|
||||
DEBUG_LOG(guid);
|
||||
|
||||
char guidStr[21] = {0};
|
||||
std::snprintf(guidStr, sizeof(guidStr), "0x%016llX", static_cast<unsigned long long>(guid));
|
||||
lua_pushstring(luaState, guidStr);
|
||||
} else {
|
||||
// GetName via vtable[1] (offset 0x4)
|
||||
using GetNameT = char *(__thiscall *)(uintptr_t *thisPtr);
|
||||
auto vtable = reinterpret_cast<uintptr_t *>(*frameObj);
|
||||
auto getName = reinterpret_cast<GetNameT>(vtable[1]);
|
||||
char *name = getName(frameObj);
|
||||
|
||||
if (name != nullptr && name[0] != '\0') {
|
||||
lua_pushstring(luaState, name);
|
||||
} else {
|
||||
lua_pushnil(luaState);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,4 +39,6 @@ namespace Nampower {
|
||||
uint32_t Script_GetSpellIconTexture(uintptr_t *luaState);
|
||||
|
||||
bool RunQueuedScript(int priority);
|
||||
|
||||
uint32_t CSimpleFrame_GetNameHook(hadesmem::PatchDetourBase *detour, uintptr_t *luaState);
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ enum class Offsets : std::uint32_t {
|
||||
|
||||
lua_state_ptr = 0x7040D0,
|
||||
|
||||
lua_type = 0x006F3460,
|
||||
lua_type = 0X006F3400,
|
||||
lua_isstring = 0x006F3510,
|
||||
lua_isnumber = 0X006F34D0,
|
||||
lua_tostring = 0x006F3690,
|
||||
@@ -168,6 +168,7 @@ enum class Offsets : std::uint32_t {
|
||||
lua_pushboolean = 0x006F39F0,
|
||||
lua_rawseti = 0x006f3f60,
|
||||
lua_rawgeti = 0x006f3bc0,
|
||||
lua_touserdata = 0x006F3740,
|
||||
lua_gettop = 0x006F3070,
|
||||
luaL_ref = 0x006F5310,
|
||||
luaL_unref = 0x006F5400,
|
||||
@@ -226,4 +227,6 @@ enum class Offsets : std::uint32_t {
|
||||
CursorSetCursorMode = 0x00523d20,
|
||||
CursorModelSetSequence = 0x00523c20,
|
||||
CGGameUI_DisplayError = 0x00496720,
|
||||
|
||||
CSimpleFrame_GetName = 0x007a1390,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user