[C++] Simple object filtering menu

Shout-Out

User Tag List

Results 1 to 5 of 5
  1. #1
    flo8464's Avatar Active Member
    Reputation
    30
    Join Date
    Apr 2009
    Posts
    434
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [C++] Simple object filtering

    Hey!

    Recently a took a look at some public/private MMO bots, most of them written in C++.
    Most of them shared a ugly problem: Their objectlist filtering was pretty dirty and non-reusable.

    So I thought I might help someone if I show you how I do it in my bot, which I currently develope.

    The heart is a templated class 'Filter' (It doesn't need to be templated, but that's obviously the best way).

    Code:
    template<class Object>
    class Filter
    { };
    This class aims to store a set of filters and apply them to a list of objects.

    But in which form are we going to store our filters?
    That question should be answered with std::function, as it allows us to use almost everything as a filter (with boost:ython you can even register Python functions as filters, cool eh? )
    So lets typedef a common type for filters, which shall take an object as argument and return true if the object is acceptable:

    Code:
    typedef std::function<bool (Object)> ObjectFilter;
    Internally we use a std::vector to store those filters. The dynamic memory allocation is no problem, as it only should be once.

    Code:
    std::vector<ObjectFilter> m_filters;
    Next, implement two constructors. A defaulted default-constructor and another constructor taking an initializer-list for more comfortable usage:

    Code:
    Filter() = default;
      
    Filter(std::initializer_list<ObjectFilter> list)
      : m_filters(list)
    { }
    Not really necessary, but sometimes really helpfull (I started creating Filters dynamically from XML-Files):

    Code:
    void addFilter(ObjectFilter filter)
    {
      m_filters.push_back(filter);
    }
    Here comes the function which does all the magic:

    Code:
    template<typename InputIterator>
    std::pair<InputIterator, InputIterator>
      apply(InputIterator begin, InputIterator end) const
    {
      InputIterator removed = std::remove_if(begin, end, [&](Object cur)
      {
        for(ObjectFilter filter : this->m_filters)
          if(!filter(cur))
            return true;
      });
    
      return std::pair<InputIterator, InputIterator>(begin, removed);
    }
    We simply take a range as argument, apply the filters on it, move every unsuitable object to the end and return the range containing all left elements.
    This is pretty performant as no copies/memory allocations are made but it alters the input range (which shouldn't be a problem).

    Thats it !

    Here's an example, similar to what I use to determine gatherable veins/herbs:

    Code:
    class DistanceLessThan
    {
    private:
      float m_distance;
    
    public:
      DistanceLessThan(float distance)
        : m_distance(distance)
      { }
       
      bool operator(WoW::Object obj) const
      {
        auto playerPos = WoW::ObjectManager::get()->getActivePlayer().position();
        return (playerPos.distanceTo(obj.position()) < m_distance);
      }
    };
    
    void printGatherableObjects()
    {
      static Filter<WoW::Object> IsGatherable = { &WoW::canGather, DistanceLessThan(30.0) };
    
      WoW::ObjectManager* mgr = WoW::ObjectManager::get();
      auto filtered = IsGatherable.apply(mgr->first, mgr->last);
    
      std::copy(filtered.first, filtered.second, std::ostream_iterator<WoW::Object>(std::cout));
    }

    And here's the complete Filter-class:

    Code:
    #include <vector>
    #include <utility>
    #include <functional>
    #include <algorithm>
    
    template<class Object>
    class Filter
    {
    public:
      typedef std::function<bool (Object)> ObjectFilter;
      
    private:
      std::vector<ObjectFilter> m_filters;
    
    public:
      Filter() = default;
      
      Filter(std::initializer_list<ObjectFilter> list)
        : m_filters(list)
      { }
    
      void addFilter(ObjectFilter filter)
      {
        m_filters.push_back(filter);
      }
    
      template<typename InputIterator>
      std::pair<InputIterator, InputIterator>
        apply(InputIterator begin, InputIterator end) const
      {
        InputIterator removed = std::remove_if(begin, end, [&](Object cur)
        {
          for(ObjectFilter filter : this->m_filters)
            if(!filter(cur))
              return true;
        });
    
        return std::pair<InputIterator, InputIterator>(begin, removed);
      }
    };
    Seems to be pretty obvious, but as many people fail at it, I thought it might help.

    Regards,
    Flo
    Hey, it compiles! Ship it!

    [C++] Simple object filtering
  2. #2
    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)
    Although I'm coding in C# for the most part, this is cool stuff and will definitely help those public bots to catch up :P.
    As a side note: You can use [this] as the lambda capture instead of [&] in case you didn't know...

    This is where LINQ really shines... not really performance wise, but regarding ease of coding.
    Simply appending a Where() clause is superior to subclassing (in my eyes).

  3. #3
    Seifer's Avatar Site Donator
    Reputation
    129
    Join Date
    Apr 2007
    Posts
    270
    Thanks G/R
    1/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Bananenbrot View Post
    Although I'm coding in C# for the most part, this is cool stuff and will definitely help those public bots to catch up :P.
    As a side note: You can use [this] as the lambda capture instead of [&] in case you didn't know...

    This is where LINQ really shines... not really performance wise, but regarding ease of coding.
    Simply appending a Where() clause is superior to subclassing (in my eyes).
    Pretty sure LINQ shines on the performance part as well!

  4. #4
    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 Seifer View Post
    Pretty sure LINQ shines on the performance part as well!
    Pretty sure this is not the case.

  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)
    LINQ is actually pretty slow compared to manual foreach loops.

Similar Threads

  1. [C#][Source] BlackRain - Simple Object Manager Library
    By Seifer in forum WoW Memory Editing
    Replies: 195
    Last Post: 04-08-2015, 03:02 PM
  2. [Tool] Simple idea to help filter out junk with fishing bots :)
    By mhollier117 in forum World of Warcraft Bots and Programs
    Replies: 5
    Last Post: 06-13-2011, 06:22 PM
  3. Replies: 0
    Last Post: 02-15-2011, 11:58 AM
  4. May someone give a simple analogy about Ascent Game Object Adding?
    By tyman2006 in forum World of Warcraft Emulator Servers
    Replies: 4
    Last Post: 12-16-2007, 02:13 PM
  5. SOMETHING simple like syndrome
    By case in forum World of Warcraft General
    Replies: 1
    Last Post: 03-20-2006, 11:01 PM
All times are GMT -5. The time now is 10:48 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