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
use crate::util::{
    generic_json::{Property, Raw},
    utils,
};
use serde::{Deserialize, Serialize};
use serde_json::Value;

#[derive(Serialize, Deserialize, Debug)]
pub struct PlayerResponse {
    pub success: bool,
    pub player: Value,
}

impl Raw for PlayerResponse {
    fn raw(&self) -> &Value {
        &self.player
    }
}

impl PlayerResponse {
    pub fn get_uuid(&self) -> Option<&str> {
        self.get_str_property("uuid")
    }

    pub fn get_name(&self) -> Option<&str> {
        match self.get_str_property("displayname") {
            Some(name) => Some(name),
            None => {
                match self
                    .get_array_property("knownAliases")
                    .and_then(|aliases| aliases.last())
                    .and_then(serde_json::Value::as_str)
                {
                    Some(alias) => Some(alias),
                    None => {
                        return self
                            .get_str_property("playername")
                            .or_else(|| self.get_str_property("username"))
                    }
                }
            }
        }
    }

    pub fn get_network_exp(&self) -> i64 {
        self.get_int_property("networkExp").unwrap_or(0)
            + (utils::get_total_exp_to_full_level(
                (self.get_int_property("networkLevel").unwrap_or(0) + 1) as f64,
            ) as i64)
    }

    pub fn get_network_level(&self) -> f64 {
        utils::get_exact_level(self.get_network_exp() as f64)
    }

    pub fn get_karma(&self) -> i64 {
        self.get_int_property("karma").unwrap_or(0)
    }

    pub fn get_rank(&self) -> &str {
        if self.has_rank_in_field("rank") {
            return self.get_str_property("rank").unwrap_or("NONE");
        } else if self.has_rank_in_field("monthlyPackageRank") {
            return self
                .get_str_property("monthlyPackageRank")
                .unwrap_or("NONE");
        } else if self.has_rank_in_field("newPackageRank") {
            return self.get_str_property("newPackageRank").unwrap_or("NONE");
        } else if self.has_rank_in_field("packageRank") {
            return self.get_str_property("packageRank").unwrap_or("NONE");
        }

        "NONE"
    }

    pub fn has_rank(&self) -> bool {
        self.get_rank() != "NONE"
    }

    fn has_rank_in_field(&self, name: &str) -> bool {
        let value = self.get_str_property(name).unwrap_or("NONE");
        !value.is_empty() && value != "NONE" && value != "NORMAL"
    }
}