diff --git a/cheat-library/src/user/cheat/world/AutoTreeFarm.cpp b/cheat-library/src/user/cheat/world/AutoTreeFarm.cpp index ab22d3c..c1e7874 100644 --- a/cheat-library/src/user/cheat/world/AutoTreeFarm.cpp +++ b/cheat-library/src/user/cheat/world/AutoTreeFarm.cpp @@ -116,12 +116,48 @@ namespace cheat::feature } }; + template > + class lra_map { + using key_value_pair = std::pair; + using list_iterator = typename std::list::iterator; + public: + void put(const KeyT& key, const ValT& val) { + auto it = elem_map.find(key); + // if element already in the map, don't modify it. + if (it != elem_map.end()) + return; + + items_list.push_front(key_value_pair(key, val)); + elem_map[key] = items_list.begin(); + + if (Size < elem_map.size()) { + { + const KeyT& last_key = items_list.back().first; + elem_map.erase(last_key); + } + items_list.pop_back(); + } + } + + ValT& get(const KeyT& key) { + auto it = elem_map.find(key); + if (it == elem_map.end()) + throw std::runtime_error("Tried to access key not present in map"); + return it->second->second; + } + + bool exists(const KeyT& key) const { + return elem_map.find(key) != elem_map.end(); + } + protected: + std::list items_list; + std::unordered_map elem_map; + }; void AutoTreeFarm::OnGameUpdate() { - static std::unordered_map s_AttackCountMap; - + static lra_map s_AttackCountMap; static std::queue s_AttackQueue; static std::unordered_set s_AttackQueueSet; static uint64_t s_LastAttackTimestamp = 0; @@ -142,7 +178,7 @@ namespace cheat::feature if (s_AttackQueueSet.count(tree) > 0) continue; - if (tree->fields._lastTreeDropTimeStamp + m_RepeatDelay > timestamp) + if (s_LastAttackTimestamp + m_RepeatDelay > timestamp) continue; auto position = tree->fields._.realBounds.m_Center; @@ -173,22 +209,20 @@ namespace cheat::feature if (m_AttackPerTree > 0) { - if (s_AttackCountMap.count(position) == 0) - s_AttackCountMap[position] = 0; + if (!s_AttackCountMap.exists(position)) + s_AttackCountMap.put(position, 0); - auto& attackCount = s_AttackCountMap[position]; + auto& attackCount = s_AttackCountMap.get(position); attackCount++; + if (attackCount > static_cast(m_AttackPerTree)) continue; } - tree->fields._lastTreeDropTimeStamp = timestamp; + s_LastAttackTimestamp = timestamp; app::MoleMole_NetworkManager_RequestHitTreeDropNotify(networkManager, position, position, treeType, nullptr); break; } - - if (s_AttackCountMap.size() > 1000) - s_AttackCountMap.clear(); } }