1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
use super::enums::{Difficulty, EnemyType, GameMap, MatchRule};
use super::AttrMap;
use log::debug;
#[derive(Debug, PartialEq, Eq)]
pub enum MatchRules {
Map(GameMap),
Enemy(EnemyType),
Difficulty(Difficulty),
}
impl MatchRules {
pub fn parse(key: &str, value: &str) -> Option<Self> {
Some(match key {
GameMap::RULE => Self::Map(GameMap::from_value(value)),
EnemyType::RULE => Self::Enemy(EnemyType::from_value(value)),
Difficulty::RULE => Self::Difficulty(Difficulty::from_value(value)),
_ => return None,
})
}
pub fn attr(&self) -> &'static str {
match self {
Self::Map(_) => GameMap::ATTR,
Self::Enemy(_) => EnemyType::ATTR,
Self::Difficulty(_) => Difficulty::ATTR,
}
}
pub fn try_compare(&self, value: &str) -> bool {
match self {
Self::Map(a) => a.try_compare(value),
Self::Enemy(a) => a.try_compare(value),
Self::Difficulty(a) => a.try_compare(value),
}
}
}
pub struct RuleSet {
values: Vec<MatchRules>,
}
impl RuleSet {
const PRIVACY_KEY: &str = "ME3privacy";
pub fn new(values: Vec<MatchRules>) -> Self {
Self { values }
}
pub fn matches(&self, attributes: &AttrMap) -> bool {
if let Some(privacy) = attributes.get(Self::PRIVACY_KEY) {
if privacy != "PUBLIC" {
return false;
}
}
for rule in &self.values {
let attr = rule.attr();
if let Some(value) = attributes.get(attr) {
debug!("Comparing {rule:?} {attr} {value}");
if !rule.try_compare(value) {
debug!("Doesn't Match");
return false;
} else {
debug!("Matches")
}
} else {
debug!("Game didn't have attr {rule:?} {attr}");
}
}
true
}
}