/
mod_recent_stat_loader.py
223 lines (167 loc) · 7.39 KB
/
mod_recent_stat_loader.py
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
221
222
223
# -*- coding: utf-8 -*-
# https://www.apache.org/licenses/LICENSE-2.0.html
import sys
from threading import Thread
import time
import traceback
from mod_recent_stat_config_format import ConfigFormat
from mod_recent_stat_config_main import ConfigMain
from mod_recent_stat_config_wg_id import ConfigWgId
from mod_recent_stat_converter import isPlayerFake
from mod_recent_stat_constant import BADGE_TYPE
from mod_recent_stat_logging import logInfo, logError
from mod_recent_stat_wg_stats import WgStats
class ModRecentStat:
notificationsShowed = False
def __init__(self, configFormat=None, configMain=None, configWgId=None):
# type: (ConfigFormat, ConfigMain, ConfigWgId) -> None
logInfo("Mod loading is started.")
logInfo("Python version: %s." % sys.version)
self._configFormat = configFormat or ConfigFormat()
self._configMain = configMain or ConfigMain()
self._configWgId = configWgId or ConfigWgId()
self._playerIdToData = dict()
self._wgStats = WgStats(self._configMain, self._configWgId)
self._welcomeMessage = self._loadWelcomeMessage()
self._infoMessage = self._loadInfoMessage()
self._isAnonymousHost = False
logInfo("Mod loading is finished: main = %s, format = %s." % (self._configMain, self._configFormat))
def getWelcomeMessage(self):
# type: () -> str
return self._welcomeMessage
def getInfoMessage(self):
# type: () -> str
return self._infoMessage
@staticmethod
def _loadWelcomeMessage():
# type: () -> str
defaultMessage = "The Recent Stat of You<br>" + \
"Info: <a href='event:https://github.com/SerVB/TheRecentStatOfYou'>https://github.com/SerVB/TheRecentStatOfYou</a><br>" + \
"Donate: <a href='event:https://github.com/SerVB/donate'>https://github.com/SerVB/donate</a>"
return defaultMessage
def _loadInfoMessage(self):
# type: () -> str
return (
"Configs:<br>" +
"<br>" +
"main = %s<br>" +
"<br>" +
"format = %s"
) % (self._configMain, self._configFormat)
def _checkIfHostIsAnonymous(self, vehicles):
# type: (dict) -> None
try:
for _vehicleID, vehicleData in vehicles.items():
if vehicleData["name"] != vehicleData["fakeName"]:
self._isAnonymousHost = True
except BaseException:
logError("Can't check if host is anonymous.", traceback.format_exc())
def loadPlayerDataByVehicleList(self, vehicles):
# type: (dict) -> None
self._checkIfHostIsAnonymous(vehicles)
startTime = time.time()
self._wgStats.loadPlayerDataByVehicleList(vehicles, self._playerIdToData)
try:
vehicleInfoTasks = set()
for _vehicleID, vehicleData in vehicles.items():
if "name" in vehicleData and "accountDBID" in vehicleData:
playerName = vehicleData["name"]
playerId = vehicleData["accountDBID"]
if playerId in self._playerIdToData and self._playerIdToData[playerId].hasRecentStat:
continue
for provider in self._configMain.recentStatProviders:
task = Thread(
target=provider.getStatistics,
args=(self._configMain.region, playerName, playerId, self._playerIdToData)
)
vehicleInfoTasks.add(task)
task.start()
logInfo("Vehicle info task count: %d." % len(vehicleInfoTasks))
for task in vehicleInfoTasks:
task.join()
logInfo("Tasks are joined.")
except BaseException:
logError("Can't load recent stats by vehicle list.", traceback.format_exc())
withStat = 0
withRecentStat = 0
withoutStat = 0
for _vehicleID, vehicleData in vehicles.items():
if "accountDBID" in vehicleData:
playerId = vehicleData["accountDBID"]
if playerId in self._playerIdToData:
withStat += 1 # TODO if all nulls then withoutStat
if self._playerIdToData[playerId].hasRecentStat:
withRecentStat += 1
else:
withoutStat += 1
logInfo("Stats loaded in %s ms. With stats: %s, with recent stats: %s, without stats: %s." %
(int(round((time.time() - startTime) * 1000)), withStat, withRecentStat, withoutStat))
def formatPlayerName(self, accountDBID, playerName):
# type: (int, str) -> str
if self._isAnonymousHost:
return "? %s" % playerName # TODO move to config_format
if isPlayerFake(accountDBID):
return "? %s" % playerName # TODO move to config_format
playerInfo = self._playerIdToData.get(accountDBID, None)
if playerInfo is not None:
try:
formattedPlayerStat = self._configFormat.playerName.format(**playerInfo.createDict(self._configFormat))
newPlayerName = formattedPlayerStat + playerName
return newPlayerName
except BaseException:
logError("Can't format player name", traceback.format_exc())
return playerName
return playerName
def getPlayerBadgeIcon(self, accountDBID):
if self._configMain.badgeType == BADGE_TYPE.BOB2020_TEAM_COLOR:
teamId = self._getPlayerBob2020TeamId(accountDBID)
if teamId is None:
return None
return "badge_%s" % (20 + teamId)
colorId = self._getPlayerColorId(accountDBID)
if colorId is None:
return None
return "badge_%s" % (10 + colorId)
def _getPlayerColorId(self, accountDBID):
# type: (int) -> [int, None]
"""the worst is 0 and the best is 5"""
if self._isAnonymousHost:
return None # todo: don't clear badges in such situation
playerInfo = self._playerIdToData.get(accountDBID, None)
if playerInfo is None:
return None
xwn8 = playerInfo.xwn8
if xwn8 is None:
return None
# https://modxvm.com/en/ratings/xvm-scale/colors/ june 19, 2019:
if xwn8 < 17:
return 0
if xwn8 < 34:
return 1
if xwn8 < 53:
return 2
if xwn8 < 76:
return 3
if xwn8 < 93:
return 4
return 5
def _getPlayerBob2020TeamId(self, accountDBID):
# type: (int) -> [int, None]
if self._isAnonymousHost:
return None # todo: don't clear badges in such situation
playerInfo = self._playerIdToData.get(accountDBID, None)
if playerInfo is None:
return None
achievements = playerInfo.achievements
if achievements is None:
return None
# the numbers are in sync with badges modifier:
if "medalBobKorbenDallas" in achievements.keys():
return 0
if "medalBobAmway921" in achievements.keys():
return 1
if "medalBobLebwa" in achievements.keys():
return 2
if "medalBobYusha" in achievements.keys():
return 3
return None