mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-11-09 09:48:20 +00:00
Fix hash collisions in achievements (#962)
This commit is contained in:
parent
c8cd51ef63
commit
cff94b6c22
43
dGame/dComponents/AchievementCacheKey.h
Normal file
43
dGame/dComponents/AchievementCacheKey.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef __ACHIEVEMENTCACHEKEY__H__
|
||||
#define __ACHIEVEMENTCACHEKEY__H__
|
||||
|
||||
class AchievementCacheKey {
|
||||
public:
|
||||
AchievementCacheKey() {
|
||||
targets = "";
|
||||
value = 0;
|
||||
type = MissionTaskType::MISSION_TASK_TYPE_UNKNOWN;
|
||||
};
|
||||
|
||||
bool operator==(const AchievementCacheKey& point) const {
|
||||
return this->targets == point.targets && this->value == point.value && this->type == point.type;
|
||||
};
|
||||
void SetTargets(const std::string value) { this->targets = value; };
|
||||
void SetValue(uint32_t value) { this->value = value; };
|
||||
void SetType(MissionTaskType value) { this->type = value; };
|
||||
|
||||
std::string GetTargets() const { return this->targets; };
|
||||
uint32_t GetValue() const { return this->value; };
|
||||
MissionTaskType GetType() const { return this->type; };
|
||||
private:
|
||||
std::string targets;
|
||||
uint32_t value;
|
||||
MissionTaskType type;
|
||||
|
||||
};
|
||||
|
||||
// Specialization of hash for the above class
|
||||
namespace std {
|
||||
template<>
|
||||
struct hash<AchievementCacheKey> {
|
||||
size_t operator()(const AchievementCacheKey& key) const {
|
||||
size_t hash = 0;
|
||||
GeneralUtils::hash_combine(hash, key.GetType());
|
||||
GeneralUtils::hash_combine(hash, key.GetValue());
|
||||
GeneralUtils::hash_combine(hash, key.GetTargets());
|
||||
return hash;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#endif //!__ACHIEVEMENTCACHEKEY__H__
|
@ -17,10 +17,11 @@
|
||||
#include "dZoneManager.h"
|
||||
#include "Mail.h"
|
||||
#include "MissionPrerequisites.h"
|
||||
#include "AchievementCacheKey.h"
|
||||
|
||||
// MARK: Mission Component
|
||||
|
||||
std::unordered_map<size_t, std::vector<uint32_t>> MissionComponent::m_AchievementCache = {};
|
||||
std::unordered_map<AchievementCacheKey, std::vector<uint32_t>> MissionComponent::m_AchievementCache = {};
|
||||
|
||||
//! Initializer
|
||||
MissionComponent::MissionComponent(Entity* parent) : Component(parent) {
|
||||
@ -391,12 +392,12 @@ bool MissionComponent::LookForAchievements(MissionTaskType type, int32_t value,
|
||||
|
||||
const std::vector<uint32_t>& MissionComponent::QueryAchievements(MissionTaskType type, int32_t value, const std::string targets) {
|
||||
// Create a hash which represent this query for achievements
|
||||
size_t hash = 0;
|
||||
GeneralUtils::hash_combine(hash, type);
|
||||
GeneralUtils::hash_combine(hash, value);
|
||||
GeneralUtils::hash_combine(hash, targets);
|
||||
AchievementCacheKey toFind;
|
||||
toFind.SetType(type);
|
||||
toFind.SetValue(value);
|
||||
toFind.SetTargets(targets);
|
||||
|
||||
const std::unordered_map<size_t, std::vector<uint32_t>>::iterator& iter = m_AchievementCache.find(hash);
|
||||
const auto& iter = m_AchievementCache.find(toFind);
|
||||
|
||||
// Check if this query is cached
|
||||
if (iter != m_AchievementCache.end()) {
|
||||
@ -447,11 +448,9 @@ const std::vector<uint32_t>& MissionComponent::QueryAchievements(MissionTaskType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Insert into cache
|
||||
m_AchievementCache.insert_or_assign(hash, result);
|
||||
|
||||
return m_AchievementCache.find(hash)->second;
|
||||
m_AchievementCache.insert_or_assign(toFind, result);
|
||||
return m_AchievementCache.find(toFind)->second;
|
||||
}
|
||||
|
||||
bool MissionComponent::RequiresItem(const LOT lot) {
|
||||
|
@ -17,11 +17,13 @@
|
||||
#include "CDMissionsTable.h"
|
||||
#include "Component.h"
|
||||
|
||||
/**
|
||||
* The mission inventory of an entity. Tracks mission state for each mission that can be accepted and allows for
|
||||
* progression of each of the mission task types (see MissionTaskType).
|
||||
*/
|
||||
class MissionComponent : public Component
|
||||
class AchievementCacheKey;
|
||||
|
||||
/**
|
||||
* The mission inventory of an entity. Tracks mission state for each mission that can be accepted and allows for
|
||||
* progression of each of the mission task types (see MissionTaskType).
|
||||
*/
|
||||
class MissionComponent: public Component
|
||||
{
|
||||
public:
|
||||
static const uint32_t ComponentType = COMPONENT_TYPE_MISSION;
|
||||
@ -192,7 +194,7 @@ private:
|
||||
* As achievements can be hard to query, we here store a list of all the mission IDs that can be unlocked for a
|
||||
* combination of tasks and values, so that they can be easily re-queried later
|
||||
*/
|
||||
static std::unordered_map<size_t, std::vector<uint32_t>> m_AchievementCache;
|
||||
static std::unordered_map<AchievementCacheKey, std::vector<uint32_t>> m_AchievementCache;
|
||||
|
||||
/**
|
||||
* Order of missions in the UI. This value is incremented by 1
|
||||
|
Loading…
Reference in New Issue
Block a user