Get Playernames only possible from Cache? menu

Shout-Out

User Tag List

Results 1 to 11 of 11
  1. #1
    Holico's Avatar Contributor
    Reputation
    85
    Join Date
    Jul 2009
    Posts
    114
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Get Playernames only possible from Cache?

    Hey,
    since 5.2 i have trouble getting the playernames.
    Because it seems i can only get them from the Cache and there i need to literate through the entire cache for every name.
    So there are 2 question.
    First i found in an old dump a offset from VesperCore

    DBCacheRow = 0x988

    But i dont realy know where exactly this is plus i dont know which datatype (thought off uint16 or uint32 but dont get any results)

    Second, is it realy the only way to get the name from cache?

    My solution at the moment:

    Code:
    private static String getPlayerName(ulong guid)
            {
                WDB<NameCache> nameCache = new WDB<NameCache>(proc.MainModule.BaseAddress + CacheOffsets.NameCache);
                String s = "Error";
                foreach (NameCache charName in nameCache)
                {
                    if (charName.Guid == guid)
                    {
                        s = charName.Name;
                        break;
                    }
                }
                return s;
            }
    Last edited by Holico; 04-01-2013 at 01:58 PM.

    Get Playernames only possible from Cache?
  2. #2
    TOM_RUS's Avatar Legendary
    Reputation
    914
    Join Date
    May 2008
    Posts
    699
    Thanks G/R
    0/52
    Trade Feedback
    0 (0%)
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    At least that's how client does that.

  3. #3
    miceiken's Avatar Contributor Authenticator enabled
    Reputation
    209
    Join Date
    Dec 2007
    Posts
    401
    Thanks G/R
    7/9
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Seems to be a clean way to do it. Could be optimized a bit though, such as this:
    Code:
    private static string getPlayerName(ulong guid)
    {
        var nameCache = new WDB<NameCache>(proc.MainModule.BaseAddress + CacheOffsets.NameCache);
        foreach (var charName in nameCache)
        {
            if (charName.Guid == guid)
                return charName.Name;
        }
        return "UNKNOWN";
    }

  4. #4
    Holico's Avatar Contributor
    Reputation
    85
    Join Date
    Jul 2009
    Posts
    114
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by TOM_RUS View Post
    At least that's how client does that.
    Could you tell me what exactly "DBCacheRow = 0x988" is then?
    i really hoped that i could just say unitObject.Descriptors + 0x988 (Something like this) and get the exact row and could then work with something like this:

    WDB<NameCache> nameCache = new WDB<NameCache>(proc.MainModule.BaseAddress + CacheOffsets.NameCache);
    nameCache[CacheRow].Name

    But yeah i guess i will use miceiken's snippet just because its a bit cleaner

    Originally Posted by miceiken View Post
    Seems to be a clean way to do it. Could be optimized a bit though, such as this:
    Code:
    private static string getPlayerName(ulong guid)
    {
        var nameCache = new WDB<NameCache>(proc.MainModule.BaseAddress + CacheOffsets.NameCache);
        foreach (var charName in nameCache)
        {
            if (charName.Guid == guid)
                return charName.Name;
        }
        return "UNKNOWN";
    }
    is there any positiv effect for using var instead of the correct type?
    Last edited by Holico; 04-01-2013 at 03:18 PM.

  5. #5
    Bananenbrot's Avatar Contributor
    Reputation
    153
    Join Date
    Nov 2009
    Posts
    384
    Thanks G/R
    1/3
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Holico View Post
    Could you tell me what exactly "DBCacheRow = 0x988" is then?
    i really hoped that i could just say unitObject.Descriptors + 0x988 (Something like this) and get the exact row and could then work with something like this:

    WDB<NameCache> nameCache = new WDB<NameCache>(proc.MainModule.BaseAddress + CacheOffsets.NameCache);
    nameCache[CacheRow].Name

    But yeah i guess i will use miceiken's snippet just because its a bit cleaner



    is there any positiv effect for using var instead of the correct type?
    I don't know about you, but not having to type WDB<NameCache> more often than really needed is reason enough to use var. If anonymous classes are present, you even have to.
    The first point really shines when doing linq... no one wants to type IEnumerable<...>.
    Just for completeness a linq version (though not everyone's favorite):
    Code:
    private static string getPlayerName(ulong guid)
    {
        // Throws an InvalidOperationException if not found, if you don't want to catch it, use FirstOrDefault() and check for null
        return new WDB<NameCache>(proc.MainModule.BaseAddress + CacheOffsets.NameCache)
            .Where(e => e.Guid == guid).Select(e => e.Name).First();
        // Like this:
        return new WDB<NameCache>(proc.MainModule.BaseAddress + CacheOffsets.NameCache)
            .Where(e => e.Guid == guid).Select(e => e.Name).FirstOrDefault() ?? "UNKNOWN";
    }

  6. #6
    Holico's Avatar Contributor
    Reputation
    85
    Join Date
    Jul 2009
    Posts
    114
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I guess with Linq i get a better perfomance? Would be nice!

  7. #7
    TOM_RUS's Avatar Legendary
    Reputation
    914
    Join Date
    May 2008
    Posts
    699
    Thanks G/R
    0/52
    Trade Feedback
    0 (0%)
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Holico View Post
    Could you tell me what exactly "DBCacheRow = 0x988" is then?
    No idea. But I guess that's offset of CreatureCache row pointer for Units.

    Code:
    void __thiscall CGUnit_C::RefreshDataPointers(CGUnit_C *this)
    {
    ...
      CreatureStats_C *pCreatureStats;
    ...
      pCreatureStats = DBCache_CreatureStats_C::GetRecord(&WDB_CACHE_CREATURE, *(v30 + 20), &v33, CreatureQueryCallback, 0, 0);
      sub_8D8380(pUnit, pCreatureStats);
    ...
    }
    
    void __thiscall sub_8D8380(CGUnit_C *this, CreatureStats_C *pCreatureStats)
    {
    ...
      *(this + 0x988) = pCreatureStats;
    ...
    }
    Last edited by TOM_RUS; 04-01-2013 at 06:17 PM.

  8. #8
    Holico's Avatar Contributor
    Reputation
    85
    Join Date
    Jul 2009
    Posts
    114
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by TOM_RUS View Post
    No idea. But I guess that's offset of CreatureCache row pointer for Units.

    Code:
    void __thiscall CGUnit_C::RefreshDataPointers(CGUnit_C *this)
    {
    ...
      CreatureStats_C *pCreatureStats;
    ...
      pCreatureStats = DBCache_CreatureStats_C::GetRecord(&WDB_CACHE_CREATURE, *(v30 + 20), &v33, CreatureQueryCallback, 0, 0);
      sub_8D8380(pUnit, pCreatureStats);
    ...
    }
    
    void __thiscall sub_8D8380(CGUnit_C *this, CreatureStats_C *pCreatureStats)
    {
    ...
      *(this + 0x988) = pCreatureStats;
    ...
    }
    Hmm I see.
    Thats a bit stupid...
    Its for my Radar Application which has a update rate ~100 MS.
    So if there are more then ~30-40 Players it starts lagging which is kinda stupid.
    Maybe i just need to adjust the update rate to 250ms or something.
    Thanks for your help anyway, i searched with IDA but i didnt find the offsets because IDA is a bit to much at once (Anyway thanks for providing databases!)

  9. #9
    TOM_RUS's Avatar Legendary
    Reputation
    914
    Join Date
    May 2008
    Posts
    699
    Thanks G/R
    0/52
    Trade Feedback
    0 (0%)
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Just cache player name inside your player class, so you don't read it every time you need it. Like:
    Code:
    class Player
    {
        private string _name;
    
        public string Name
        {
            get
            {
                if (_name == null)
                {
                    _name = <insert your code to get player name here>;
                }
    
                return _name;
            }
        }
    }

  10. #10
    Holico's Avatar Contributor
    Reputation
    85
    Join Date
    Jul 2009
    Posts
    114
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hmm my programm logic is something like this:

    Clear all Lists
    Fill Lists with Objects from Memory
    Litarate through lists and draw radar
    repeat.

    So i have no consistent player Object. It would be very hard to keep track of all objects (delete players who are not in range anymore, add new players).
    Its just easier to clear all, and reread everything. I will try to enhance somethings here and there to squeeze out some extra ms.
    I developed it originally for small BGs, but i thought i can share it here on ownedcore, because it works also everywhere else
    As long as it works flawless in small BGs and in non-croweded areas im happy with it
    Thanks for your help/time. I really appreciate it!!

    My Problem with consistency is following:
    i would fill my lists and check before i create a new GameOBject if there already is a object with the given GUID.
    IF there is object with the GUID i would just update my coordinates and keep playername/class.
    if there is no object with the GUID i would create a new Object and check nameCache for playername/class.
    To prevent a infinite big object list i would clear the list every 1/5/10 seconds.
    So but the Problem is, lets say i show a a rogue on the map and he stealthed AFTER i saw him once.
    so the rogue object is no longer in my memory so his point would stuck at his last position until
    a) i clear the list
    or
    b) he shows himself again.
    Last edited by Holico; 04-01-2013 at 10:40 PM.

  11. #11
    TOM_RUS's Avatar Legendary
    Reputation
    914
    Join Date
    May 2008
    Posts
    699
    Thanks G/R
    0/52
    Trade Feedback
    0 (0%)
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    You can then use some Dictionary<ulong, string> and store player names here.
    Code:
    ...
    Dictionary<ulong, string> playernames = new Dictionary<ulong, string>();
    ...
    
    string GetPlayerNameByGuid(ulong guid)
    {
        if(playernames.ContainsKey(guid))
            return playernames[guid];
        string lname = <insert your code to get player name by guid here>(guid);
        playernames.Add(guid, lname);
        return lname;
    }

Similar Threads

  1. [Selling] I'm selling a method to get unlimited pets & mounts from the blizzard store! 10e Only
    By MareBre in forum World of Warcraft Buy Sell Trade
    Replies: 0
    Last Post: 07-03-2013, 06:33 AM
  2. Replies: 4
    Last Post: 10-26-2012, 07:53 PM
  3. Keep getting scam e-mails from here!
    By Keden in forum World of Warcraft General
    Replies: 4
    Last Post: 08-16-2007, 08:04 AM
  4. how to get you account back from scamers
    By EliMob441 in forum World of Warcraft Guides
    Replies: 23
    Last Post: 06-13-2007, 11:30 AM
  5. Hunter: How To Get 35 Happines/sec from lvl 0 food
    By Hounro in forum World of Warcraft Guides
    Replies: 8
    Last Post: 12-01-2006, 10:34 AM
All times are GMT -5. The time now is 05:47 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search