[Help][SL 9.2.7] CGPlayer Auras menu

Shout-Out

User Tag List

Results 1 to 12 of 12
  1. #1
    Trogg's Avatar Member
    Reputation
    1
    Join Date
    Feb 2024
    Posts
    18
    Thanks G/R
    12/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [Help][SL 9.2.7] CGPlayer Auras

    Hi, i trying to find all auras, my research of npc:
    first table offset 0x6F8, 0xC0 is aura size
    Code:
    typedef struct {
    	int AuraId; // + 0
    	char unknown1[8];
    	int Duration; // + 12
    	int EndTime; // + 16
    	uint64_t CreatorGuid; // + 20
    	char unknown2[4]; // 
    	int StackCount; // + 28
    } AuraRec;
    when auras more than 16 we can read low = pm.read_int(start_address+0x6F8-0x
    Code:
    if low > 0:
        high = pm.read_int(start_address+0x6F8-0x4)
        shifted_20f = high << 32
        result = shifted_20f | low
    
        for offset in range(num_auras): #num_auras  random number, didnt found actual
            try:
                spellid = pm.read_int(result+offset*0xC0+0x98) # 0x98 is spellid offset
    so, i can read auras on npc by this method, but i tryed to get auras on players by the same method, and it didnt work
    i found 2 tables, with auras list with 0x8 offset and list with 0xC0 offset, but i cant found actual offset from start_address to pointer of that lists
    also tryed to decompile UnitAura/UnitBuff/UnitDebuff but its broken
    Just a moment... UnitBuff
    Just a moment... UnitDebuff
    Just a moment... UnitAura

    thanks for any information that would help me figure this out

    PS i using py.mem to fast debugging before implement it on c++

    [Help][SL 9.2.7] CGPlayer Auras
  2. #2
    scizzydo's Avatar Contributor
    Reputation
    137
    Join Date
    Oct 2019
    Posts
    99
    Thanks G/R
    5/57
    Trade Feedback
    0 (0%)
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Trogg View Post
    Hi, i trying to find all auras, my research of npc:
    first table offset 0x6F8, 0xC0 is aura size
    Code:
    typedef struct {
    	int AuraId; // + 0
    	char unknown1[8];
    	int Duration; // + 12
    	int EndTime; // + 16
    	uint64_t CreatorGuid; // + 20
    	char unknown2[4]; // 
    	int StackCount; // + 28
    } AuraRec;
    when auras more than 16 we can read low = pm.read_int(start_address+0x6F8-0x
    Code:
    if low > 0:
        high = pm.read_int(start_address+0x6F8-0x4)
        shifted_20f = high << 32
        result = shifted_20f | low
    
        for offset in range(num_auras): #num_auras  random number, didnt found actual
            try:
                spellid = pm.read_int(result+offset*0xC0+0x98) # 0x98 is spellid offset
    so, i can read auras on npc by this method, but i tryed to get auras on players by the same method, and it didnt work
    i found 2 tables, with auras list with 0x8 offset and list with 0xC0 offset, but i cant found actual offset from start_address to pointer of that lists
    also tryed to decompile UnitAura/UnitBuff/UnitDebuff but its broken
    Just a moment... UnitBuff
    Just a moment... UnitDebuff
    Just a moment... UnitAura

    thanks for any information that would help me figure this out

    PS i using py.mem to fast debugging before implement it on c++
    I think you have a few values off. I did a quick dump of the binary and looked, this is the part in particular where you'd use it in your stuff:
    Code:
    v8 = v3 + 0x6E8;
    if ( *(_DWORD *)(v3 + 0x12E8) == -1 )
        v8 = *(_QWORD *)(v3 + 0x6F0);
    v9 = *(_DWORD *)(0xC0i64 * (unsigned int)v6 + v8 + 0x98);
    The auras start at 0x6E8, however if 0x12E8 == -1 then you instead start at 0x6F0. The v9 assignment in this example you can see that 0xC0 is in fact the right size of each Aura struct, and 0x98 being the ID (like you mentioned)

    It's worth noting that this is still the way things are done in Retail, and have been done for some time. Here's an example structure if you do it in C++:
    Code:
    // Should be defining base classes, but for this purpose w/e
    struct CGUnit_C {
        char pad_0000[1768];
        union {
            struct {
                CGAuraStrc Auras[16]; //0x06E8
                int32_t AuraCount; //0x12E8
                char pad_12EC[4];
            };
            struct {
                int32_t AuraCount2; //0x06E8
                char pad_06EC[4];
                CGAuraStrc* Auras2; //0x06F0
            };
        };
        CGAuraStrc* GetAuraStrc(uint32_t idx) {
            auto count = AuraCount;
            if (count == -1) count = AuraCount2;
            if (!(idx < count)) return nullptr;
            return (AuraCount == -1 ? &Auras2[idx] : &Auras[idx]);
        };
    };
    Last edited by scizzydo; 02-13-2024 at 06:54 PM.

  3. Thanks Trogg (1 members gave Thanks to scizzydo for this useful post)
  4. #3
    Trogg's Avatar Member
    Reputation
    1
    Join Date
    Feb 2024
    Posts
    18
    Thanks G/R
    12/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks, it works, i made a mistake in type (not int, longlong)
    There is a way to find flag or what else of chaied group for example in The Council of Blood by Dark Recital - Spell - World of Warcraft ?
    dr_chained.png

  5. #4
    scizzydo's Avatar Contributor
    Reputation
    137
    Join Date
    Oct 2019
    Posts
    99
    Thanks G/R
    5/57
    Trade Feedback
    0 (0%)
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Trogg View Post
    Thanks, it works, i made a mistake in type (not int, longlong)
    There is a way to find flag or what else of chaied group for example in The Council of Blood by Dark Recital - Spell - World of Warcraft ?
    dr_chained.png
    I personally didn't raid during that to give you an answer there, but the link shows it's a debuff. With the method I showed before you iterate all auras, debuff, buff, visible and invisible. There are a lot of auras on units for things that aren't visible. For example, morchie on retail for the fight on Dawn of the infinites, the correct morchie has a different aura. On court of stars, the imposter also does. For event times, like Christmas, the mobs wearing the Christmas hats have auras. Other auras can be like 4pc, etc. not just these auras on yourself, but others.

  6. #5
    Trogg's Avatar Member
    Reputation
    1
    Join Date
    Feb 2024
    Posts
    18
    Thanks G/R
    12/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The source of debuff is a player in chained group

    Code:
    for (const auto& u : playerData.players)
       for (const auto& aura : u->auras) {
    	if (aura->id == 331636 || aura->id == 331637) {
    		auto caster = aura->CasterGuid();
    		if (caster==playerData.me->Guid())
    		//our target
                    stuff
    	}
    }

  7. #6
    Trogg's Avatar Member
    Reputation
    1
    Join Date
    Feb 2024
    Posts
    18
    Thanks G/R
    12/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    How to get field 16 (270) from UnitBuff? Cant view from what it come.
    Dump: value=UnitBuff("player",1)
    [1]="Primordial Arcanic Pulsar",
    [2]=135730,
    [3]=1,
    [5]=0,
    [6]=0,
    [7]="player",
    [8]=false,
    [9]=false,
    [10]=338825,
    [11]=false,
    [12]=false,
    [13]=true,
    [14]=false,
    [15]=1,
    [16]=270

    i can find it by CE, it is double but it is out of range aura table
    Last edited by Trogg; 04-05-2024 at 04:49 AM.

  8. #7
    scizzydo's Avatar Contributor
    Reputation
    137
    Join Date
    Oct 2019
    Posts
    99
    Thanks G/R
    5/57
    Trade Feedback
    0 (0%)
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Trogg View Post
    How to get field 16 (270) from UnitBuff? Cant view from what it come.
    Dump: value=UnitBuff("player",1)
    [1]="Primordial Arcanic Pulsar",
    [2]=135730,
    [3]=1,
    [5]=0,
    [6]=0,
    [7]="player",
    [8]=false,
    [9]=false,
    [10]=338825,
    [11]=false,
    [12]=false,
    [13]=true,
    [14]=false,
    [15]=1,
    [16]=270

    i can find it by CE, it is double but it is out of range aura table
    Those are the attributes. It behaves just like the aura tables, where you read at 0x20 to see if it's -1 (if it is, then the attributes count starts at 0x0), and then there is an array of attributes at either 0x8 or 0x00, depending on that return value.

  9. Thanks Trogg (1 members gave Thanks to scizzydo for this useful post)
  10. #8
    Trogg's Avatar Member
    Reputation
    1
    Join Date
    Feb 2024
    Posts
    18
    Thanks G/R
    12/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    pointer to array of attributes must be in start of the aura table pointer or spell?

  11. #9
    scizzydo's Avatar Contributor
    Reputation
    137
    Join Date
    Oct 2019
    Posts
    99
    Thanks G/R
    5/57
    Trade Feedback
    0 (0%)
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Trogg View Post
    pointer to array of attributes must be in start of the aura table pointer or spell?
    They're the first fields in the CGAura struct

    This is the count of attributes. a2 in this pseudocode is the CGAuraStrc (in ida an int*, so 0x20 & 0x0 accordingly for count)
    Code:
      v11 = a2[8];
      if ( v11 == -1 )
        v11 = *a2;
    This is the bottom of the function where it pushes the values to the lua state.
    Code:
      for ( i = 0i64; (unsigned int)i < v11; i = (unsigned int)(i + 1) )
      {
        v36 = a2[8];
        if ( v36 == -1 )
          v37 = *a2;
        else
          v37 = a2[8];
        if ( (unsigned int)i < v37 )
        {
          if ( v36 == -1 )
            v39 = (unsigned int *)*((_QWORD *)a2 + 1);
          else
            v39 = a2;
          v40 = *(float *)&v39[i];
          if ( v40 <= 0.0 )
            v38 = -(int)(float)-v40;
          else
            v38 = (int)v40;
        }
        else
        {
          v38 = 0;
        }
        sub_1402C6DE0((__int64)a3, (double)v38);
      }

  12. Thanks Trogg (1 members gave Thanks to scizzydo for this useful post)
  13. #10
    Trogg's Avatar Member
    Reputation
    1
    Join Date
    Feb 2024
    Posts
    18
    Thanks G/R
    12/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ready function:
    Code:
    void Aura::GetAttrubutes(DWORD_PTR addr)
    {
    	int count = *(int*)(addr + 0x20);
    	if (count == -1)
    		count = *(int*)(addr);
    
    	int v36 = 0;
    	int v37 = 0;
    	int v38 = 0;
    	uint64_t v39 = 0;
    	int v40 = 0;
    	for (int i = 0; i < count; i++)
    	{
    		v36 = *(int*)(addr + 0x20);
    		if (v36 == -1)
    			v37 = *(int*)(addr);
    		else
    			v37 = v36;
    		if (i < v37)
    		{
    			if (v36 == -1) {
    				v39 = *(uint64_t*)(addr + 8);
    				v40 = *(float*)(v39 + i * 4);
    			}
    			else
    				v40 = *(float*)(addr + i * 4);
    			if (v40 <= 0.0)
    				v38 = -(int)(float)-v40;
    			else
    				v38 = (int)v40;
    		}
    		else
    		{
    			v38 = 0;
    		}
    		attributes.push_back(v38);
    	}
    	return;
    }

  14. #11
    scizzydo's Avatar Contributor
    Reputation
    137
    Join Date
    Oct 2019
    Posts
    99
    Thanks G/R
    5/57
    Trade Feedback
    0 (0%)
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Trogg View Post
    Ready function:
    Code:
    void Aura::GetAttrubutes(DWORD_PTR addr)
    {
    	int count = *(int*)(addr + 0x20);
    	if (count == -1)
    		count = *(int*)(addr);
    
    	int v36 = 0;
    	int v37 = 0;
    	int v38 = 0;
    	uint64_t v39 = 0;
    	int v40 = 0;
    	for (int i = 0; i < count; i++)
    	{
    		v36 = *(int*)(addr + 0x20);
    		if (v36 == -1)
    			v37 = *(int*)(addr);
    		else
    			v37 = v36;
    		if (i < v37)
    		{
    			if (v36 == -1) {
    				v39 = *(uint64_t*)(addr + 8);
    				v40 = *(float*)(v39 + i * 4);
    			}
    			else
    				v40 = *(float*)(addr + i * 4);
    			if (v40 <= 0.0)
    				v38 = -(int)(float)-v40;
    			else
    				v38 = (int)v40;
    		}
    		else
    		{
    			v38 = 0;
    		}
    		attributes.push_back(v38);
    	}
    	return;
    }
    Question about your code... are you iterating everything and storing the results in new containers? Do you have a reason? If you go the route of defining structs, and custom iterators, you can avoid new allocations and just use the games data that already exists (much less overhead)

  15. #12
    Trogg's Avatar Member
    Reputation
    1
    Join Date
    Feb 2024
    Posts
    18
    Thanks G/R
    12/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This is due to a lack of understanding of how it works. In my head it sounds like this:
    do you want to use something? find, save, use, every time searching by reading the aura, if necessary, accessing it several times in my understanding already creates a load, the same with objects, I iterate them and distribute them in a container for further use, apparently I just can’t imagine how it’s possible do differently.

Similar Threads

  1. [Question] an Aura that will increase NPC damage, thank for helping
    By WoW_Learner in forum WoW EMU Questions & Requests
    Replies: 1
    Last Post: 02-03-2021, 01:19 PM
  2. [help][8.3] How to handle Aura? my old code not working?
    By chlycooper in forum WoW Memory Editing
    Replies: 9
    Last Post: 01-18-2020, 02:20 AM
  3. Replies: 6
    Last Post: 03-26-2011, 02:30 AM
  4. [help] Moonkin -> Night Elf Female + natural aura
    By Cyberworg in forum WoW ME Questions and Requests
    Replies: 2
    Last Post: 05-28-2009, 03:46 PM
  5. bot help
    By xwhitedeathx in forum World of Warcraft General
    Replies: 3
    Last Post: 05-01-2006, 03:50 AM
All times are GMT -5. The time now is 08:24 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search