[5.0.5 16057][OOP] Reading completed quests out of memory... menu

User Tag List

Results 1 to 13 of 13
  1. #1
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [5.0.5 16057][OOP] Reading completed quests out of memory...

    Didn't have a great time on this one, so thought I'd post it. I miss when it was just an array

    MyWoW.Resources.Offsets.Questing.QuestsCompleted is 0xD0BDA8 (rebased)

    I'm open to suggestions to optimize this (besides copying the entire table to local memory), it has to loop through ALL rows of the table, which kind of sucks!

    Code:
            public static List<UInt32> GetQuestsCompleted
            {
                get
                {
                    var Info = MyWoW.Helpers.ClientDB.Functions.ClientDB_GetInfo(MyWoW.Memory.WowBaseAddress + (uint)MyWoW.Resources.Offsets.DBCs.QuestV2);
    
                    List<UInt32> CompletedQuests = new List<UInt32>();
    
                    for (uint i = 0; i < Info.NumRows; i++)
                    {
                        uint quest_id = MyWoW.Memory.ReadUInt(Info.FirstRows + 8 * i);
    
                        if (quest_id > 0)
                        {
                            uint Row = MyWoW.Helpers.ClientDB.Functions.ClientDB__GetRow(MyWoW.Memory.WowBaseAddress + (uint)MyWoW.Resources.Offsets.DBCs.QuestV2, (uint)quest_id);
    
                            if (Row > 0)
                            {
                                uint quest_index = MyWoW.Memory.ReadUInt(Row + 0x4);
    
                                if (quest_index > 0)
                                {
                                    uint Array = MyWoW.Memory.WowBaseAddress + (uint)MyWoW.Resources.Offsets.Questing.QuestsCompleted;
                                    uint ArrayIndex = ((quest_index - 1) >> 3);
    
                                    Byte UnkFlag1 = MyWoW.Memory.ReadByte(Array + ArrayIndex);
                                    Byte UnkFlag2 = (Byte)(1 << (((int)quest_index - 1) & 7));
    
                                    if ((UnkFlag1 & UnkFlag2) > 0)
                                    {
                                        CompletedQuests.Add(quest_id);
                                    }
                                }
                            }
                        }
                    }
    
                    return CompletedQuests;
                }
            }
    https://tanaris4.com

    [5.0.5 16057][OOP] Reading completed quests out of memory...
  2. #2
    guizmows's Avatar Banned
    Reputation
    57
    Join Date
    Feb 2008
    Posts
    414
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I do it like that

    PHP Code:
                    var current WowMem.ReadRebased<uint>(MemEnums.QuestOffsets.FirstQuestDone);
                    while (((
    current 1) == 0) && (current != 0))
                    {
                        var 
    id WowMem.Read<uint>(current 2*4u);
                        
    _lQuestIds.Add(id);
                        
    current WowMem.Read<uint>(current 1*4u);
                    } 
    MemEnums.QuestOffsets.FirstQuestDone = 0xBBB90C

    this list is populated by QueryQuestsCompleted() API QueryQuestsCompleted - WoWWiki - Your guide to the World of Warcraft
    Last edited by guizmows; 09-28-2012 at 11:05 AM.

  3. #3
    Tanaris4's Avatar Contributor Authenticator enabled
    Reputation
    148
    Join Date
    Oct 2008
    Posts
    646
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yea that version doesn't work anymore :/ It's not just an array

    Here is a new version which copies the data into memory once, still slow when you call it, but faster than before!

    Code:
            #region Previously completed quests
    
            private static Dictionary<UInt32, UInt32> QuestIDToIndex = new Dictionary<uint, uint>();
            private static Thread Thread_UpdateQuestIDCache = new Thread(UpdateQuestIDCache);
    
            private static void UpdateQuestIDCache()
            {
                while (true)
                {
                    try
                    {
                        int StartTime = Environment.TickCount;
    
                        // only try to update if it's 0!
                        if (QuestIDToIndex.Count == 0)
                        {
                            var Info = MyWoW.Helpers.ClientDB.Functions.ClientDB_GetInfo(MyWoW.Memory.WowBaseAddress + (uint)MyWoW.Resources.Offsets.DBCs.QuestV2);
    
                            Dictionary<UInt32, UInt32> Result = new Dictionary<UInt32, UInt32>();
    
                            for (uint i = 0; i < Info.NumRows; i++)
                            {
                                uint quest_id = MyWoW.Memory.ReadUInt(Info.FirstRows + 8 * i);
    
                                if (quest_id > 0)
                                {
                                    uint Row = MyWoW.Helpers.ClientDB.Functions.ClientDB__GetRow(MyWoW.Memory.WowBaseAddress + (uint)MyWoW.Resources.Offsets.DBCs.QuestV2, (uint)quest_id);
    
                                    if (Row > 0)
                                    {
                                        uint quest_index = MyWoW.Memory.ReadUInt(Row + 0x4);
    
                                        Result.Add(quest_id, quest_index);
                                    }
                                }
                            }
    
                            if (Result.Count > 0)
                            {
                                Console.WriteLine("[DEBUG] Loaded quest index cache in {0} seconds ({1} items)", (Environment.TickCount - StartTime) / 1000, Result.Count);
                            }
    
                            QuestIDToIndex = Result;
                        }
                        // done - only need to load it once!
                        else {
                            break;
                        }
                    }
                    catch { }
    
                    System.Threading.Thread.Sleep(500);
                }
            }
    
            internal static void UpdateQuestIndexCache()
            {
                if (Thread_UpdateQuestIDCache.IsAlive)
                {
                    Thread_UpdateQuestIDCache.Abort();
                }
    
                Thread_UpdateQuestIDCache = new Thread(UpdateQuestIDCache);
                Thread_UpdateQuestIDCache.Priority = ThreadPriority.BelowNormal;
                Thread_UpdateQuestIDCache.Start();
            }
    
            public static List<UInt32> GetQuestsCompleted
            {
                get
                {
                    #region Wait for quest cache to populate...
                    if (QuestIDToIndex.Count == 0)
                    {
                        while (Thread_UpdateQuestIDCache.IsAlive && QuestIDToIndex.Count == 0)
                        {
                            Thread.Sleep(10);
                        }
    
                        if (QuestIDToIndex.Count == 0)
                        {
                            throw new Exception("Unable to load quest id/index cache!");
                        }
                    }
                    #endregion
    
                    List<UInt32> CompletedQuests = new List<UInt32>();
    
                    foreach (KeyValuePair<UInt32, UInt32> entry in QuestIDToIndex)
                    {
                        uint quest_id = entry.Key;
                        uint quest_index = entry.Value;
    
                        if ( quest_id > 0 && quest_index > 0 ){
    
                            uint Array = MyWoW.Memory.WowBaseAddress + (uint)MyWoW.Resources.Offsets.Questing.QuestsCompleted;
                            uint ArrayIndex = ((quest_index - 1) >> 3);
    
                            Byte UnkFlag1 = MyWoW.Memory.ReadByte(Array + ArrayIndex);
                            Byte UnkFlag2 = (Byte)(1 << (((int)quest_index - 1) & 7));
    
                            if ((UnkFlag1 & UnkFlag2) > 0)
                            {
                                CompletedQuests.Add(quest_id);
                            }
                        }
                    }
    
                    return CompletedQuests;
                }
            }
    
            #endregion
    https://tanaris4.com

  4. #4
    guizmows's Avatar Banned
    Reputation
    57
    Join Date
    Feb 2008
    Posts
    414
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    thx tanaris, I'll check that once home.

  5. #5
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code:
            static IEnumerable<uint> GetQuestsCompleted()
            {
                var questBitPtr = StyxWoW.Offsets.Statics.QuestsFlaggedCompletedList;
                WoWDb.DbTable questDb = StyxWoW.Db[ClientDb.QuestV2];
    
    
                // Iterate over every quest in this list
                foreach (var row in questDb)
                {
                    int index = row.GetField<int>(1);
                    uint id = row.GetField<uint>(0);
    
    
                    if (index > 0)
                    {
                        // Get the bit to test
                        byte b = StyxWoW.Memory.Read<byte>(questBitPtr + ((index - 1) >> 3));
                        if (((1 << ((index - 1) & 7)) & b) != 0)
                        {
                            yield return id;
                        }
                    }
                }
            }
    Keep in mind, the list is only populated *once*, when you log into the game. After that, it doesn't receive any new updates. You'll need to keep track of any quests you complete while you're logged in. (We use a simple cache which gets refreshed when we restart, then just add new completed quest IDs to the list once we complete a quest)

    There's no point in calling this function more than once in a blue moon. (Technically, you only need to call it once, best place might be bot "startup" ?)

  6. #6
    Jadd's Avatar 🐸 Premium Seller
    Reputation
    1515
    Join Date
    May 2008
    Posts
    2,433
    Thanks G/R
    81/336
    Trade Feedback
    1 (100%)
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Apoc View Post
    There's no point in calling this function more than once in a blue moon. (Technically, you only need to call it once, best place might be bot "startup" ?)
    So what happens if the player completes a quest before the bot starts? Can you 'lose' quests?

  7. #7
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Jadd View Post
    So what happens if the player completes a quest before the bot starts? Can you 'lose' quests?
    Yes. It's a stupid move on Blizz's part. Any questing addons that don't keep track of completed state are kind of screwed.

  8. #8
    _Mike's Avatar Contributor
    Reputation
    310
    Join Date
    Apr 2008
    Posts
    531
    Thanks G/R
    0/2
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Maybe I'm misunderstanding what you are saying but the API function GetQuestsCompleted() does keep track of quests completed during gameplay.

  9. #9
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by _Mike View Post
    Maybe I'm misunderstanding what you are saying but the API function GetQuestsCompleted() does keep track of quests completed during gameplay.
    I found just the opposite. We had to implement a file-based cache to keep track of completed quests, or things would bug out. That list wasn't being updated until we logged in again.

  10. #10
    _Mike's Avatar Contributor
    Reputation
    310
    Join Date
    Apr 2008
    Posts
    531
    Thanks G/R
    0/2
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hmm, strange. Maybe it's some client bug that causes it to not update every time. I only did a brief in-game test myself but I didn't notice any problems.

  11. #11
    Pandu91's Avatar Member
    Reputation
    1
    Join Date
    Oct 2012
    Posts
    41
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I have a question, I have found many code with using the styx class, is this a free class? And if yes, where to get it?

    (I guess it is a private honorbuddy class?)

    Best regards

  12. #12
    FinnX's Avatar Banned
    Reputation
    40
    Join Date
    Aug 2009
    Posts
    82
    Thanks G/R
    0/0
    Trade Feedback
    1 (100%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    QueryQuestsCompleted = the list is only populated *once*, when you log into the game
    GetQuestsCompleted = Always populated with the current finished quests.

    Why are some of you using QueryQuestsCompleted then? Is there a different? I don't think so.
    Last edited by FinnX; 03-25-2014 at 03:12 AM.

  13. #13
    _Mike's Avatar Contributor
    Reputation
    310
    Join Date
    Apr 2008
    Posts
    531
    Thanks G/R
    0/2
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Seeing as QueryQuestsCompleted has been removed I doubt it returns anything useful at all

Similar Threads

  1. !Complete quest [There and Back Again] very fast !
    By mindblast in forum World of Warcraft Exploits
    Replies: 4
    Last Post: 09-20-2011, 12:25 PM
  2. [ArcEmu] Upon completing quest teleport to XYZ
    By Fumi in forum WoW EMU Questions & Requests
    Replies: 1
    Last Post: 07-08-2011, 05:00 AM
  3. Recommend blizzlike release with most complete quests?
    By Poker4Living in forum World of Warcraft Emulator Servers
    Replies: 5
    Last Post: 08-13-2010, 04:09 AM
  4. Reading quest info out of memory
    By nvthiele in forum WoW Memory Editing
    Replies: 9
    Last Post: 02-24-2009, 07:51 AM
All times are GMT -5. The time now is 12:24 PM. 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