mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-04-26 16:46:31 +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 "dZoneManager.h"
|
||||||
#include "Mail.h"
|
#include "Mail.h"
|
||||||
#include "MissionPrerequisites.h"
|
#include "MissionPrerequisites.h"
|
||||||
|
#include "AchievementCacheKey.h"
|
||||||
|
|
||||||
// MARK: Mission Component
|
// 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
|
//! Initializer
|
||||||
MissionComponent::MissionComponent(Entity* parent) : Component(parent) {
|
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) {
|
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
|
// Create a hash which represent this query for achievements
|
||||||
size_t hash = 0;
|
AchievementCacheKey toFind;
|
||||||
GeneralUtils::hash_combine(hash, type);
|
toFind.SetType(type);
|
||||||
GeneralUtils::hash_combine(hash, value);
|
toFind.SetValue(value);
|
||||||
GeneralUtils::hash_combine(hash, targets);
|
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
|
// Check if this query is cached
|
||||||
if (iter != m_AchievementCache.end()) {
|
if (iter != m_AchievementCache.end()) {
|
||||||
@ -447,11 +448,9 @@ const std::vector<uint32_t>& MissionComponent::QueryAchievements(MissionTaskType
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert into cache
|
// Insert into cache
|
||||||
m_AchievementCache.insert_or_assign(hash, result);
|
m_AchievementCache.insert_or_assign(toFind, result);
|
||||||
|
return m_AchievementCache.find(toFind)->second;
|
||||||
return m_AchievementCache.find(hash)->second;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MissionComponent::RequiresItem(const LOT lot) {
|
bool MissionComponent::RequiresItem(const LOT lot) {
|
||||||
|
@ -17,11 +17,13 @@
|
|||||||
#include "CDMissionsTable.h"
|
#include "CDMissionsTable.h"
|
||||||
#include "Component.h"
|
#include "Component.h"
|
||||||
|
|
||||||
/**
|
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).
|
/**
|
||||||
*/
|
* The mission inventory of an entity. Tracks mission state for each mission that can be accepted and allows for
|
||||||
class MissionComponent : public Component
|
* progression of each of the mission task types (see MissionTaskType).
|
||||||
|
*/
|
||||||
|
class MissionComponent: public Component
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static const uint32_t ComponentType = COMPONENT_TYPE_MISSION;
|
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
|
* 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
|
* 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
|
* Order of missions in the UI. This value is incremented by 1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user