File size: 6,584 Bytes
8cdbae1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
from datetime import datetime
from typing import Any

from pydantic import AliasPath, BaseModel, Field, field_validator
from pytz import UTC

from bot.core.api_js_helpers.upgrader import Calculator


class SkillLevel(BaseModel):
    level: int
    title: str
    requiredSkills: dict | list
    requiredHeroLevel: int
    requiredFriends: int
    desc: str


class DbSkill(BaseModel):
    key: str
    title: str
    category: str
    subCategory: str
    priceBasic: int
    priceFormula: str
    priceFormulaK: int
    profitBasic: int
    profitFormula: str
    profitFormulaK: int
    maxLevel: int
    timeBasic: str
    timeFormula: str
    timeFormulaK: str
    desc: str
    special: str
    levels: list[SkillLevel]
    next_level: int = 1
    skill_profit: int = 0
    skill_price: int = 0
    weight: int = 0
    progress_time: datetime | None = None

    def __init__(self, /, **data: Any) -> None:
        super().__init__(**data)
        self._calculator = Calculator()

    def get_level_by_skill_level(self, level: int) -> SkillLevel | None:
        if not self.levels or self.levels[0].level > level:
            return None

        for index, skill_level in enumerate(self.levels):
            if skill_level.level <= level:
                if index + 1 == len(self.levels):
                    return skill_level
                if self.levels[index + 1].level > level:
                    return skill_level

        return None

    def calculate_profit(self, level: int) -> int:
        return self._calculator.get_profit(self, level)

    def price_for_level(self, level: int) -> int:
        return self._calculator.get_price(self, level)

    def get_skill_time(self, data_after: "UserDataAfter") -> None | datetime:
        if finish_time := data_after.skills.get(self.key, {}).get("finishUpgradeDate"):
            return datetime.strptime(finish_time, "%Y-%m-%d %H:%M:%S").replace(tzinfo=UTC)
        return None


class DbSkills(BaseModel):
    dbSkills: list[DbSkill]


class ProfileData(BaseModel):
    user_id: int = Field(validation_alias=AliasPath("profile", "id"))
    money: int = Field(validation_alias=AliasPath("hero", "money"))
    level: int = Field(validation_alias=AliasPath("hero", "level"))
    money_per_hour: int = Field(validation_alias=AliasPath("hero", "moneyPerHour"))
    offline_bonus: int = Field(validation_alias=AliasPath("hero", "offlineBonus"))


class UserDataAfter(BaseModel):
    daily_rewards: dict = Field(validation_alias=AliasPath("dailyRewards"))
    quests: list = Field(validation_alias=AliasPath("quests"))
    friends: list = Field(validation_alias=AliasPath("friends"))
    skills: dict | list = Field(
        description="all user learned skills",
        examples=[
            {"desks": {"level": 6, "lastUpgradeDate": "2024-07-30 19:20:32", "finishUpgradeDate": None}},
            {
                "empathy": {
                    "level": 6,
                    "lastUpgradeDate": "2024-07-30 19:21:36",
                    "finishUpgradeDate": "2024-07-30 19:22:13",
                }
            },
        ],
    )

    @field_validator("skills")
    @classmethod
    def check_skills(cls, v: Any) -> dict:
        return v or {}


class Profile(BaseModel):
    money_per_tap: int = Field(validation_alias=AliasPath("hero", "earns", "task", "moneyPerTap"))
    limit: int = Field(validation_alias=AliasPath("hero", "earns", "task", "limit"))
    energy: int = Field(validation_alias=AliasPath("hero", "earns", "task", "energy"))
    energy_recovery: int = Field(validation_alias=AliasPath("hero", "earns", "task", "recoveryPerSecond"))

    money: int = Field(validation_alias=AliasPath("hero", "money"))
    level: int = Field(validation_alias=AliasPath("hero", "level"))
    money_per_hour: int = Field(validation_alias=AliasPath("hero", "moneyPerHour"))


class Fight(BaseModel):
    league: str
    moneyProfit: int
    player1: int
    moneyContract: int
    player1Strategy: str
    player1Level: int
    player1Rewarded: bool
    player2: int
    player2Strategy: str
    player2Rewarded: bool
    winner: int


class PvpData(BaseModel):
    opponent: dict | None
    fight: Fight | None


class FundHelper(BaseModel):
    funds: set = Field(default_factory=set)
    youtube: dict


class Skills(BaseModel):
    skills: dict


if __name__ == "__main__":
    data = {
        "hero": {
            "id": 1092379081,
            "level": 12,
            "exp": 207156950,
            "money": 8154952,
            "moneyUpdateDate": "2024-08-05 07:02:28",
            "lastOfflineBonusDate": "2024-08-05 07:02:28",
            "moneyPerHour": 7943050,
            "energyUpdateDate": "2024-08-05 07:02:28",
            "tax": 20,
            "pvpMatch": 1143,
            "pvpWin": 646,
            "pvpLose": 497,
            "pvpMatchesDaily": 123,
            "pvpMatchesDailyDay": "2024-08-04",
            "earns": {
                "task": {"moneyPerTap": 21, "limit": 9500, "energy": 9500, "recoveryPerSecond": 14},
                "sell": {"moneyPerTap": 20, "limit": 6600, "energy": 6600, "recoveryPerSecond": 14},
            },
            "dailyRewardLastDate": "2024-08-04 11:15:56",
            "dailyRewardLastIndex": 7,
            "onboarding": [
                "9040",
                "41",
                "30",
                "40",
                "9000",
                "90",
                "70",
                "10720",
                "9020",
                "10015",
                "9010",
                "80",
                "50",
                "10700",
                "60",
                "9030",
                "20",
                "51",
                "1",
            ],
            "updateDate": "2024-07-19 16:39:56.91573",
            "userId": 1092379081,
        },
        "fight": {
            "id": "08999015-6835-44ed-b00e-3ac529b62285",
            "league": "bronze",
            "moneyContract": 6600,
            "moneyProfit": None,
            "searchTime": None,
            "player1": 1092379081,
            "player1Strategy": "aggressive",
            "player1Level": 12,
            "player1Rewarded": False,
            "player2": None,
            "player2Strategy": None,
            "player2Rewarded": False,
            "winner": None,
            "draw": [],
            "updateDate": None,
            "creationDate": "2024-08-05 07:02:35",
        },
        "opponent": None,
    }
    PvpData(**data)


class SessionData(BaseModel):
    user_agent: str = Field(validation_alias="User-Agent")
    proxy: str | None = None