Merge pull request #29 from Jylpah/merge-master-dev-datetime

Backport master
This commit is contained in:
Jylpah authored and GitHub committed 2021-05-03 19:09:21 +03:00
commit b34a061c9d
7 files changed
+2941 -2471

No files matched your search

+95 -105
View File
@@ -134,7 +134,7 @@ replay_details_flds = [
## Syntax: key == stat field in https://api.wotblitz.eu/wotb/tanks/stats/ (all.KEY)
## Value array [ 'Stat Title', [ 0, data buckets ....], scaling_factor_for_bucket_values, 'print_format' ]
histogram_fields = {
'wins' : [ 'Win rate', [0, .35, .40, .45, .48, .5, .52, .55, .60, .65, .70, 1], 100, '{:2.0%}' ],
'wins' : [ 'Win rate', [0, .35, .40, .45, .48, .5, .52, .55, .60, .65, .70, 1], 1, '{:2.0%}' ],
'damage_dealt' : [ 'Avg. Dmg.', [0, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1750, 2000, 2250, 2500, 2750, 3000, 100e3], 1, '{:3.0f}' ],
'battles' : [ 'Battles', [0, 1000, 2500, 5000, 7000, 10e3, 15e3, 25e3, 50e3, 5e7], .001, '{:.0f}k'] # battles is a mandatory stat to include
}
@@ -1515,7 +1515,7 @@ class BattleCategorySingle(BattleCategory):
class PlayerHistogram():
def __init__(self, field: str, name: str, fields : list, factor: float, format: str ):
def __init__(self, field: str, name: str, fields : list, factor: float, cat_format: str ):
self.field = field
if self.field == 'wins':
self.name = StatFunc.get_title()
@@ -1523,7 +1523,7 @@ class PlayerHistogram():
self.name = name
self.fields = fields
self.cat_factor = factor
self.cat_format = format
self.cat_format = cat_format
self.ncat = len(self.fields) - 1
self.allies = [0] * self.ncat
self.enemies = [0] * self.ncat
@@ -1613,7 +1613,7 @@ class PlayerHistogram():
print("\n{:12s} | {:13s} | {:13s} | {:13s}".format(self.name, "Allies", "Enemies", "TOTAL"))
for cat in self.results:
stat = self.results[cat]
print("{:12s} | {:5d} ({:4.1%}) | {:5d} ({:4.1%}) | {:5d} ({:4.1%})".format(cat, stat['allies'], stat['allies%']*100, stat['enemies'], stat['enemies%']*100, stat['total'], stat['total%']*100 ))
print("{:12s} | {:5d} ({:5.1%}) | {:5d} ({:5.1%}) | {:5d} ({:5.1%})".format(cat, stat['allies'], stat['allies%'], stat['enemies'], stat['enemies%'], stat['total'], stat['total%'] ))
else:
bu.error('Results have not been calculated yet.')
except Exception as err:
@@ -1621,7 +1621,6 @@ class PlayerHistogram():
return None
class ErrorCatchingArgumentParser(argparse.ArgumentParser):
def exit(self, status=0, message=None):
if status:
@@ -1677,14 +1676,14 @@ async def main(argv):
try:
if 'ANALYZER' in config.sections():
configAnalyzer = config['ANALYZER']
OPT_MODE_DEFAULT= configAnalyzer.getboolean('mode', OPT_MODE_DEFAULT)
OPT_HIST = configAnalyzer.getboolean('histograms', OPT_HIST)
OPT_STAT_FUNC = configAnalyzer.get('stat_func', fallback=OPT_STAT_FUNC)
OPT_WORKERS_N = configAnalyzer.getint('workers', OPT_WORKERS_N)
OPT_EXPORT_CSV_FILE = configAnalyzer.get('csv_file', OPT_EXPORT_CSV_FILE)
OPT_EXPORT_JSON_FILE = configAnalyzer.get('json_file', OPT_EXPORT_JSON_FILE)
res_categorizations = configAnalyzer.get('categorizations', None)
configAnalyzer = config['ANALYZER']
OPT_MODE_DEFAULT = configAnalyzer.getboolean('mode', OPT_MODE_DEFAULT)
OPT_HIST = configAnalyzer.getboolean('histograms', OPT_HIST)
OPT_STAT_FUNC = configAnalyzer.get('stat_func', fallback=OPT_STAT_FUNC)
OPT_WORKERS_N = configAnalyzer.getint('workers', OPT_WORKERS_N)
OPT_EXPORT_CSV_FILE = configAnalyzer.get('csv_file', OPT_EXPORT_CSV_FILE)
OPT_EXPORT_JSON_FILE= configAnalyzer.get('json_file', OPT_EXPORT_JSON_FILE)
res_categorizations = configAnalyzer.get('categorizations', None)
if res_categorizations != None:
res_categorizations.replace(' ','')
BattleCategorizationList.set_categorizations_default(res_categorizations.split(','))
@@ -1744,7 +1743,7 @@ async def main(argv):
parser.add_argument('--csv', action='store_true', default=False, help='Export data in CSV format')
parser.add_argument('-o','--outfile', type=str, default='-', metavar="OUTPUT", help='File to write results. Default STDOUT')
parser.add_argument('--db', action='store_true', default=OPT_DB, help='Use DB - You are unlikely to have it')
parser.add_argument('--filters', type=str, default=None, help='Filter replays based on categories. Filters given in JSON format.\nUse array "[]" for multiple filters/values. see --mode help.\nExample: : [ {"tier" : [8,9,20] }, { "player_wins" : 5 }]')
parser.add_argument('--filters', type=str, default=None, help='Filter replays based on categories. Filters given in JSON format.\nUse array "[]" for multiple filters/values. see --mode help.\nExample: : [ {"tier" : [8,9,10] }, { "player_wins" : 5 }]')
parser.add_argument('--filters_db', type=str, default=None, help='[only for DB setup] Filter replays in DB based on categories. Filters given in MongoDB JSON format. See --mode help')
parser.add_argument('--min', type=int, default=None, help='Only select replays from players with minimum number of replays in the dataset')
argverbosity = parser.add_mutually_exclusive_group()
@@ -1765,7 +1764,7 @@ async def main(argv):
# res_categories = BattleCategorization.get_categorizations(OPT_CATEGORIZATIONS, args)
bu.set_log_level(args.silent, args.verbose, args.debug)
bu.set_progress_step(250) # Set the frequency of the progress dots.
# bu.set_progress_step(250) # Set the frequency of the progress dots.
#### Connect to MongoDB. You are unlikely to have this set up...
bu.debug('DB_SERVER: ' + DB_SERVER)
@@ -1815,7 +1814,7 @@ async def main(argv):
# Make replay Queue
scanner_task = asyncio.create_task(mk_replayQ(replayQ, args, db))
bu.debug('Replay scanner started')
bu.set_counter('Reading replays', 10)
# Start tasks to process the Queue
for i in range(OPT_WORKERS_N):
reader_tasks.append(asyncio.create_task(replay_reader(replayQ, i, args)))
@@ -2111,7 +2110,7 @@ async def process_player_stats(players, N_workers: int, args : argparse.Namespac
try:
statsQ = asyncio.Queue()
bu.debug('Create player stats queue: ' + str(len(players)) + ' players')
stat_id_map = {}
stat_id_map = dict()
stat_ids = set()
stat_id_map_func = globals()[StatFunc.get_stat_id_func()]
@@ -2137,8 +2136,8 @@ async def process_player_stats(players, N_workers: int, args : argparse.Namespac
bu.debug('Cancelling stats workers')
for task in stats_tasks:
task.cancel()
player_stats = {}
stat_id_remap = {}
player_stats = dict()
stat_id_remap = dict()
bu.debug('Gathering stats worker outputs')
for (stats, id_remap) in await asyncio.gather(*stats_tasks):
@@ -2245,8 +2244,8 @@ def calc_team_stats(results: list, player_stats : dict, stat_id_map : dict, arg
async def stat_worker(queue : asyncio.Queue, workerID: int, args : argparse.Namespace, db : motor.motor_asyncio.AsyncIOMotorDatabase) -> list:
"""Worker thread to find stats for player / tank pairs"""
# global wg
stats = {}
stat_id_remap = {}
stats = dict()
stat_id_remap = dict()
stat_db_func = globals()[StatFunc.get_db_func()]
stat_wg_func = globals()[StatFunc.get_wg_func()]
@@ -2258,42 +2257,38 @@ async def stat_worker(queue : asyncio.Queue, workerID: int, args : argparse.Name
try:
bu.debug('Stat_id: ' + stat_id, id=workerID)
bu.print_progress()
# Analysing player performance based on their stats on the tier tanks they are playing
stats_tmp = None
# Try cache first
if (stat_id not in stats):
stats_tmp = None
pruned_stat_id = prune_stat_id(stat_id)
if (pruned_stat_id not in stats):
stats_tmp = await stat_wg_func(pruned_stat_id, cache_only = True)
else:
stat_id_remap[stat_id] = pruned_stat_id
queue.task_done()
continue
pruned_stat_id = prune_stat_id(stat_id)
if (pruned_stat_id not in stats):
stats_tmp = await stat_wg_func(pruned_stat_id, cache_only = True)
else:
stat_id_remap[stat_id] = pruned_stat_id
continue
if (stats_tmp != None):
stats[pruned_stat_id] = stats_tmp
stat_id_remap[stat_id] = pruned_stat_id
queue.task_done()
continue
# try DB
stats[stat_id] = await stat_db_func(db, stat_id)
bu.debug('get_db_' + args.stat_func + '_stats returned: account_id=' + str(get_account_id_f_stat_id(stat_id)) + ': ' + str(stats[stat_id]), workerID)
if (stats_tmp != None):
stats[pruned_stat_id] = stats_tmp
stat_id_remap[stat_id] = pruned_stat_id
continue
# try DB
stats[stat_id] = await stat_db_func(db, stat_id)
bu.debug('get_db_' + args.stat_func + '_stats returned: account_id=' + str(get_account_id_f_stat_id(stat_id)) + ': ' + str(stats[stat_id]), workerID)
# no DB stats found, trying WG AP
if (stats[stat_id] == None):
stats[pruned_stat_id] = await stat_wg_func(pruned_stat_id)
stat_id_remap[stat_id] = pruned_stat_id
del stats[stat_id]
bu.debug('get_wg_' + args.stat_func + '_stats returned: account_id=' + str(get_account_id_f_stat_id(pruned_stat_id)) + ': ' + str(stats[pruned_stat_id]), workerID)
# no DB stats found, trying WG AP
if (stats[stat_id] == None):
stats[pruned_stat_id] = await stat_wg_func(pruned_stat_id)
stat_id_remap[stat_id] = pruned_stat_id
del stats[stat_id]
bu.debug('get_wg_' + args.stat_func + '_stats returned: account_id=' + str(get_account_id_f_stat_id(pruned_stat_id)) + ': ' + str(stats[pruned_stat_id]), workerID)
except KeyError as err:
bu.error('Key not found', err, id=workerID)
except Exception as err:
bu.error('Unexpected error', err, id=workerID)
queue.task_done()
finally:
queue.task_done()
except (asyncio.CancelledError, concurrent.futures.CancelledError):
bu.debug('Stats queue is empty', id=workerID)
@@ -2327,7 +2322,7 @@ async def get_wg_tank_stats(stat_id_str: str, cache_only = False) -> dict:
player_stats = await wg.get_player_tank_stats(account_id, [ tank_id ], hist_stats, cache_only = cache_only)
#bu.debug('account_id: ' + str(account_id) + ' ' + str(player_stats))
return await tank_stats_helper(player_stats)
return tank_stats_helper(player_stats)
except KeyError as err:
bu.error('account_id: ' + str(account_id) + ' tank_id:' + str(tank_id) +' : Key not found', err)
@@ -2353,8 +2348,8 @@ async def get_db_tank_stats(db : motor.motor_asyncio.AsyncIOMotorDatabase, stat_
for stat in hist_stats:
project[stat] = True
project['_id'] = False
cursor = dbc.find({ '$and': [ { 'account_id': account_id }, { 'last_battle_time': { '$gte': battletime - time_buffer }}, { 'tank_id' : tank_id } ] }, projection=project).sort('last_battle_time',-1).limit(1)
bu.debug('find(): tank_id={} account_id={} last_battle_time>={}'.format(tank_id, account_id, battletime - time_buffer))
cursor = dbc.find({ '$and': [ { 'tank_id' : tank_id }, { 'account_id': account_id }, { 'last_battle_time': { '$gte': battletime - time_buffer }} ] }, projection=project).sort('last_battle_time',-1).limit(1)
# pipeline = [ { '$match': { '$and': [ { 'account_id': account_id }, { 'last_battle_time': { '$lte': battletime + time_buffer }}, { 'tank_id' : tank_id } ]}},
# { '$sort': { 'last_battle_time': -1 }},
@@ -2365,7 +2360,11 @@ async def get_db_tank_stats(db : motor.motor_asyncio.AsyncIOMotorDatabase, stat_
# cursor = dbc.aggregate(pipeline, allowDiskUse=True)
#cursor = dbc.aggregate(pipeline)
return await tank_stats_helper(await cursor.to_list(1))
stats = await cursor.to_list(1)
# store cache
# await wg.save_tank_stats(account_id, [tank_id], stats)
return tank_stats_helper(stats)
except Exception as err:
bu.error('account_id: ' + str(account_id) + ' Error', err)
@@ -2386,7 +2385,7 @@ async def get_wg_tank_tier_stats(stat_id_str: str, cache_only = False) -> dict:
player_stats = await wg.get_player_tank_stats(account_id, tier_tanks, hist_stats, cache_only = cache_only)
#bu.debug('account_id: ' + str(account_id) + ' ' + str(player_stats))
return await tank_stats_helper(player_stats)
return tank_stats_helper(player_stats)
except KeyError as err:
bu.error('account_id: ' + str(account_id) + ' Key not found', err)
@@ -2409,7 +2408,7 @@ async def get_wg_tier_x_stats(stat_id_str: str, cache_only = False) -> dict:
player_stats = await wg.get_player_tank_stats(account_id, tier_tanks, hist_stats, cache_only = cache_only)
#bu.debug('account_id: ' + str(account_id) + ' ' + str(player_stats))
return await tank_stats_helper(player_stats)
return tank_stats_helper(player_stats)
except KeyError as err:
bu.error('account_id: ' + str(account_id) + ' Key not found', err)
@@ -2437,8 +2436,10 @@ async def get_db_tank_tier_stats(db : motor.motor_asyncio.AsyncIOMotorDatabase,
# cursor = dbc.aggregate(pipeline, allowDiskUse=True)
cursor = dbc.aggregate(pipeline)
return await tank_stats_helper(await cursor.to_list(1000))
stats = await cursor.to_list(1000)
# await wg.save_tank_stats(account_id, tier_tanks, stats)
return tank_stats_helper(stats)
except Exception as err:
bu.error('account_id: ' + str(account_id) + ' Error', err)
return None
@@ -2448,23 +2449,9 @@ async def get_db_tier_x_stats(db : motor.motor_asyncio.AsyncIOMotorDatabase, sta
"""Get player stats from MongoDB (you are very unlikely to have it, unless you have set it up)"""
if db == None:
return None
try:
dbc = db[DB_C_TANK_STATS]
try:
( account_id, battletime ) = str2ints(stat_id_str)
tier_tanks = wg.get_tanks_by_tier(10)
time_buffer = 2*7*24*3600
pipeline = [ { '$match': { '$and': [ { 'account_id': account_id }, { 'last_battle_time': { '$lte': battletime + time_buffer }}, { 'tank_id' : {'$in': tier_tanks} } ]}},
{ '$sort': { 'last_battle_time': -1 }},
{ '$group': { '_id': '$tank_id', 'doc': { '$first': '$$ROOT' }}},
{ '$replaceRoot': { 'newRoot': '$doc' }},
{ '$project': { '_id': 0 }} ]
# cursor = dbc.aggregate(pipeline, allowDiskUse=True)
cursor = dbc.aggregate(pipeline)
return await tank_stats_helper(await cursor.to_list(1000))
return await get_db_tank_tier_stats(db,get_stat_id(account_id, 10, battletime) )
except Exception as err:
bu.error('account_id: ' + str(account_id) + ' Error', err)
return None
@@ -2482,14 +2469,16 @@ async def get_db_player_stats(db : motor.motor_asyncio.AsyncIOMotorDatabase, sta
pipeline = [ { '$match': { '$and': [ { 'account_id': account_id }, { 'last_battle_time': { '$lte': battletime + time_buffer }} ]}},
{ '$sort': { 'last_battle_time': -1 }},
{ '$group': { '_id': '$tank_id', 'doc': { '$first': '$$ROOT' }}},
{ '$group': { '_id': { 'tank_id':'$tank_id'}, 'doc': { '$first': '$$ROOT' }}},
{ '$replaceRoot': { 'newRoot': '$doc' }},
{ '$project': { '_id': 0 }} ]
# cursor = dbc.aggregate(pipeline, allowDiskUse=True)
cursor = dbc.aggregate(pipeline)
return await tank_stats_helper(await cursor.to_list(1000))
stats = await cursor.to_list(1000)
# await wg.save_tank_stats(account_id, [], stats)
return tank_stats_helper(stats)
except Exception as err:
bu.error('account_id: ' + str(account_id) + ' Error', err)
@@ -2517,20 +2506,17 @@ async def get_wg_player_stats(stat_id_str: str, cache_only = False) -> dict:
return None
async def tank_stats_helper(stat_list: list):
def tank_stats_helper(stat_list: list):
"""Helpher func got get_db_tank_tier_stats() and get_wg_tank_tier_stats()"""
try:
if stat_list == None:
return None
stats = {}
stats = collections.defaultdict(def_value_zero)
hist_fields = histogram_fields.keys()
if 'battles' not in hist_fields:
bu.error('\'battles\' must be defined in \'histogram_fields\'')
return None
for field in hist_fields:
stats[field] = 0
for tank_stat in stat_list:
tank_stat = tank_stat['all']
for field in hist_fields:
@@ -2554,7 +2540,7 @@ async def player_stats_helper(player_stats: dict):
try:
if player_stats == None:
return None
stats = {}
stats = dict()
hist_fields = histogram_fields.keys()
if 'battles' not in hist_fields:
bu.error('\'battles\' must be defined in \'histogram_fields\'')
@@ -2595,12 +2581,12 @@ async def mk_replayQ(queue : asyncio.Queue, args : argparse.Namespace, db : moto
cursor = dbc.find(filters)
else:
# select all
cursor = dbc.find({})
cursor = dbc.find(dict())
bu.debug('Reading replays...')
async for replay_json in cursor:
_id = replay_json['_id']
#del(replay_json['_id'])
await queue.put(await mk_readerQ_item(replay_json, 'DB: _id = ' + _id))
await queue.put(await mk_readerQ_item(replay_json, _id=_id))
Nreplays += 1
bu.debug('All the matching replays have been read from the DB')
except Exception as err:
@@ -2616,7 +2602,7 @@ async def mk_replayQ(queue : asyncio.Queue, args : argparse.Namespace, db : moto
if (p_replayfile.match(line) != None):
replay_json = await bu.open_JSON(line, wi.chk_JSON_replay)
await queue.put(await mk_readerQ_item(replay_json, line))
await queue.put(await mk_readerQ_item(replay_json, filename=line))
except Exception as err:
bu.error(exception=err)
else:
@@ -2627,7 +2613,7 @@ async def mk_replayQ(queue : asyncio.Queue, args : argparse.Namespace, db : moto
fn = fn[:-1]
if os.path.isfile(fn) and (p_replayfile.match(fn) != None):
replay_json = await bu.open_JSON(fn, wi.chk_JSON_replay)
await queue.put(await mk_readerQ_item(replay_json, fn))
await queue.put(await mk_readerQ_item(replay_json, filename=fn))
bu.debug('File added to queue: ' + fn)
Nreplays += 1
elif os.path.isdir(fn):
@@ -2636,7 +2622,7 @@ async def mk_replayQ(queue : asyncio.Queue, args : argparse.Namespace, db : moto
if entry.is_file() and (p_replayfile.match(entry.name) != None):
bu.debug(entry.name)
replay_json = await bu.open_JSON(entry.path, wi.chk_JSON_replay)
await queue.put(await mk_readerQ_item(replay_json, entry.name))
await queue.put(await mk_readerQ_item(replay_json, filename=entry.name))
bu.debug('File added to queue: ' + entry.path)
Nreplays += 1
except Exception as err:
@@ -2645,22 +2631,26 @@ async def mk_replayQ(queue : asyncio.Queue, args : argparse.Namespace, db : moto
return Nreplays
async def mk_readerQ_item(replay_json, filename : str = None) -> list:
async def mk_readerQ_item(replay_json, filename : str = None, _id: str = None) -> list:
"""Make an item to replay queue"""
global REPLAY_N
REPLAY_N +=1
try:
if not '_id' in replay_json:
id = wi.read_replay_id(replay_json)
replay_json['_id'] = id
if wi.chk_JSON_replay(replay_json):
if not '_id' in replay_json:
_id = wi.read_replay_id(replay_json)
replay_json['_id'] = _id
else:
replay_json = None # mark error
except Exception as err:
bu.error(exception=err)
if filename == None:
return [replay_json, REPLAY_N, '' ]
elif RE_SRC_IS_DB.match(filename) != None:
return [replay_json, REPLAY_N, filename ]
else:
if filename != None:
return [replay_json, REPLAY_N, os.path.basename(filename) ]
elif _id != None:
return [replay_json, REPLAY_N, 'DB: ' + _id ]
else:
return None
async def replay_reader(queue: asyncio.Queue, readerID: int, args : argparse.Namespace):
@@ -2676,9 +2666,9 @@ async def replay_reader(queue: asyncio.Queue, readerID: int, args : argparse.Nam
replay_file = item[2]
try:
msg_str = 'Replay[' + str(replayID) + ']: '
# msg_str = 'Replay[' + str(replayID) + ']: '
if replay_json == None:
bu.warning(msg_str + 'Invalid replay. Skipping: ' + (replay_file if replay_file != None else '') )
bu.warning('Invalid replay. Skipping: ' + (replay_file if replay_file != None else '') )
queue.task_done()
continue
@@ -2687,7 +2677,7 @@ async def replay_reader(queue: asyncio.Queue, readerID: int, args : argparse.Nam
result = await read_replay_JSON(replay_json, args)
bu.print_progress()
if result == None:
bu.warning(msg_str + 'Invalid replay ' + (replay_file if replay_file != None else '') )
bu.warning('Invalid replay ' + (replay_file if replay_file != None else '') )
queue.task_done()
continue
@@ -2696,7 +2686,7 @@ async def replay_reader(queue: asyncio.Queue, readerID: int, args : argparse.Nam
playerstanks.update(set([result['player']]))
results.append(result)
bu.debug('Marking task ' + str(replayID) + ' done')
bu.debug('Marking replay [' + str(replayID) + '] done', id=readerID)
except Exception as err:
bu.error(exception=err)
@@ -2713,7 +2703,7 @@ async def read_replay_JSON(replay_json: dict, args : argparse.Namespace) -> dict
account_id = args.account_id
url = args.url
#db = args.db
result = {}
result = dict()
try:
# bu.debug(str(replay_json))
if not wi.chk_JSON_replay(replay_json):
@@ -2778,7 +2768,7 @@ async def read_replay_JSON(replay_json: dict, args : argparse.Namespace) -> dict
if player['dbid'] == account_id:
# player itself is not put in results['allies']
tmp = {}
tmp = dict()
tmp['account_id'] = account_id
tmp['tank_id'] = player['vehicle_descr']
tmp['tank_tier'] = player_tank_tier
@@ -2879,8 +2869,8 @@ def prune_stat_id(stat_id_str: str) -> str:
return ':'.join(stat_id)
def get_stat_id(account_id: int, tank_id: int, battletime: int) -> str:
return ':'.join([ str(account_id), str(tank_id), str(battletime)])
def get_stat_id(account_id: int, tank_id: int, battle_time: int) -> str:
return ':'.join(map(str, [account_id, tank_id, battle_time ]))
def get_stat_id_tank_tier(stat_id_str: str) -> str:
@@ -2890,7 +2880,7 @@ def get_stat_id_tank_tier(stat_id_str: str) -> str:
account_id = stat_id[0]
tank_tier = wg.get_tank_tier(stat_id[1])
battle_time = (stat_id[2] // BATTLE_TIME_BUCKET) * BATTLE_TIME_BUCKET
return ':'.join(map(str, [account_id, tank_tier, battle_time ]))
return get_stat_id(account_id, tank_tier, battle_time)
except Exception as err:
bu.error('Stats_id: ' + stat_id_str, exception=err)
return None
@@ -2903,7 +2893,7 @@ def get_stat_id_tank(stat_id_str: str) -> str:
account_id = stat_id[0]
tank_id = stat_id[1]
battle_time = (stat_id[2] // BATTLE_TIME_BUCKET) * BATTLE_TIME_BUCKET
return ':'.join(map(str, [account_id, tank_id, battle_time ]))
return get_stat_id(account_id, tank_id, battle_time)
except Exception as err:
bu.error('Stats_id: ' + stat_id_str, exception=err)
return None
+59 -21
View File
@@ -22,6 +22,11 @@ _log_level = NORMAL
LOG = False
LOGGER = None
MODE_TANK_STATS = 'tank_stats'
MODE_PLAYER_STATS = 'player_stats'
MODE_PLAYER_ACHIEVEMENTS= 'player_achievements'
MODE_TANKOPEDIA = 'tankopedia'
# Progress display
_progress_N = 100
_progress_i = 0
@@ -311,7 +316,7 @@ def verbose_std(msg="", id=None) -> bool:
def warning(msg="", id=None, force: bool = False) -> bool:
"""Print a warning message"""
return _print_log_msg('Warning', msg, None, id, print_msg=(force or (_log_level >= NORMAL)))
return _print_log_msg('', 'Warning: ' + msg, None, id, print_msg=(force or (_log_level >= NORMAL)))
def debug(msg="", id=None, exception=None, force: bool = False) -> bool:
@@ -418,12 +423,14 @@ def set_progress_bar(heading: str, max_value: int, step: int = None, slow: bool
return
def set_counter(heading: str):
def set_counter(heading: str, step = None):
global _progress_obj, _progress_i
_progress_i = 0
if _progress_obj != None:
finish_progress_bar()
_progress_obj = Counter(heading)
_progress_obj = Counter(heading + ': ')
if step != None:
set_progress_step(step)
return
@@ -649,8 +656,6 @@ class StatsNotFound(Exception):
pass
# -----------------------------------------------------------
# Class WG
# -----------------------------------------------------------
@@ -686,7 +691,7 @@ class WG:
# WHERE account_id = {} AND stat = {}
# AND date >= {} LIMIT 1;"""
# TANK_STATS
SQL_TANK_STATS_TBL = 'tank_stats'
SQL_TANK_STATS_CREATE_TBL = 'CREATE TABLE IF NOT EXISTS ' + SQL_TANK_STATS_TBL + \
@@ -700,6 +705,7 @@ class WG:
SQL_TANK_STATS_UPDATE = 'REPLACE INTO ' + SQL_TANK_STATS_TBL + '(account_id, tank_id, update_time, stats) VALUES(?,?,?,?)'
# PLAYER_STATS
SQL_PLAYER_STATS_TBL = 'player_stats'
SQL_PLAYER_STATS_CREATE_TBL = 'CREATE TABLE IF NOT EXISTS ' + SQL_PLAYER_STATS_TBL + \
@@ -713,6 +719,7 @@ class WG:
SQL_PLAYER_STATS_CACHED = 'SELECT * FROM ' + SQL_PLAYER_STATS_TBL + ' WHERE account_id = ? AND update_time > ?'
# PLAYER_ACHIEVEMENTS
SQL_PLAYER_ACHIEVEMENTS_TBL = 'player_achievements'
SQL_PLAYER_ACHIEVEMENTS_CREATE_TBL = 'CREATE TABLE IF NOT EXISTS ' + SQL_PLAYER_ACHIEVEMENTS_TBL + \
@@ -720,12 +727,13 @@ class WG:
update_time INTEGER NOT NULL,
stats TEXT)"""
SQL_PLAYER_ACHIEVEMENTS_COUNT = 'SELECT COUNT(*) FROM ' + SQL_PLAYER_ACHIEVEMENTS_TBL
SQL_PLAYER_ACHIEVEMENTS_CACHED = 'SELECT * FROM ' + SQL_PLAYER_ACHIEVEMENTS_TBL + ' WHERE account_id = ? AND update_time > ?'
SQL_PLAYER_ACHIEVEMENTS_UPDATE = 'REPLACE INTO ' + SQL_PLAYER_ACHIEVEMENTS_TBL + '(account_id, update_time, stats) VALUES(?,?,?)'
SQL_PLAYER_ACHIEVEMENTS_COUNT = 'SELECT COUNT(*) FROM ' + SQL_PLAYER_ACHIEVEMENTS_TBL
SQL_TABLES = [ SQL_PLAYER_STATS_TBL, SQL_TANK_STATS_TBL, SQL_PLAYER_ACHIEVEMENTS_TBL ]
SQL_CHECK_TABLE_EXITS = """SELECT name FROM sqlite_master WHERE type='table' AND name=?"""
@@ -1261,7 +1269,7 @@ class WG:
# debug('JSON Response received: ' + str(json_data))
stats = json_data['data'][str(account_id)]
if cache:
await self.put_2_statsQ('tank_stats', [account_id, tank_ids], stats)
await self.save_tank_stats(account_id, tank_ids, stats)
return stats
except Exception as err:
error(exception=err)
@@ -1294,7 +1302,7 @@ class WG:
# debug('JSON Response received: ' + str(json_data))
stats = json_data['data'][str(account_id)]
if cache:
await self.put_2_statsQ('player_stats', [account_id], stats)
await self.save_player_stats(account_id, stats)
return stats
except Exception as err:
error(exception=err)
@@ -1333,7 +1341,7 @@ class WG:
for account_id in json_data['data'].keys():
stats[account_id] = json_data['data'][account_id]
if cache:
await self.put_2_statsQ('player_achievements', [int(account_id)], json_data['data'][account_id])
await self.save_player_achievements(int(account_id), json_data['data'][account_id])
return stats
except Exception as err:
error(exception=err)
@@ -1440,7 +1448,7 @@ class WG:
return None
async def put_2_statsQ(self, statsType: str, key: list, stats: list):
async def save_stats(self, statsType: str, key: list, stats: list):
"""Save stats to a async queue to be saved by the stat_saver -task"""
if self.statsQ == None:
return False
@@ -1449,6 +1457,30 @@ class WG:
return True
async def save_player_stats(self, account_id: int, stats: dict):
try:
await self.save_stats(MODE_PLAYER_STATS, [int(account_id)], stats)
except Exception as err:
error(exception=err)
return None
async def save_player_achievements(self, account_id: int, stats: dict):
try:
await self.save_stats(MODE_PLAYER_ACHIEVEMENTS, [int(account_id)], stats)
except Exception as err:
error(exception=err)
return None
async def save_tank_stats(self, account_id: int, tank_ids: list, stats: dict):
try:
await self.save_stats(MODE_TANK_STATS, [int(account_id), tank_ids], stats)
except Exception as err:
error(exception=err)
return None
async def stat_saver(self):
"""Async task for saving stats into cache in background"""
@@ -1464,8 +1496,13 @@ class WG:
await self.cache.commit()
async with self.cache.execute(WG.SQL_TANK_STATS_COUNT) as cursor:
debug('Cache contains: ' + str((await cursor.fetchone())[0]) + ' cached player tank stat records' )
if is_debug():
async with self.cache.execute(WG.SQL_PLAYER_STATS_COUNT) as cursor:
debug('Cache contains: ' + str((await cursor.fetchone())[0]) + ' player stat records' )
async with self.cache.execute(WG.SQL_PLAYER_ACHIEVEMENTS_COUNT) as cursor:
debug('Cache contains: ' + str((await cursor.fetchone())[0]) + ' player achievement records' )
async with self.cache.execute(WG.SQL_TANK_STATS_COUNT) as cursor:
debug('Cache contains: ' + str((await cursor.fetchone())[0]) + ' player tank stat records' )
except Exception as err:
error(exception=err)
sys.exit(1)
@@ -1474,19 +1511,20 @@ class WG:
try:
stats = await self.statsQ.get()
stats_type = stats[0]
stat_type = stats[0]
key = stats[1]
stats_data = stats[2]
update_time = stats[3]
if stats_type == 'tank_stats':
#debug('stat_type: ' + stat_type + ', key: ' + str(key))
if stat_type == MODE_TANK_STATS:
await self.store_tank_stats(key, stats_data, update_time)
elif stats_type == 'player_stats':
elif stat_type == MODE_PLAYER_STATS:
await self.store_player_stats(key, stats_data, update_time)
elif stats_type == 'player_achievements':
elif stat_type == MODE_PLAYER_ACHIEVEMENTS:
await self.store_player_achievements(key, stats_data, update_time)
else:
error('Function to saves stats type \'' + stats_type + '\' is not implemented yet')
error('Function to saves stats type \'' + stat_type + '\' is not implemented yet')
except asyncio.CancelledError:
# this is an eternal loop that will wait until cancelled
@@ -1521,7 +1559,7 @@ class WG:
for stat in stats_data:
tank_id = stat['tank_id']
await self.cache.execute(WG.SQL_TANK_STATS_UPDATE, (account_id, tank_id, update_time, json.dumps(stat)))
tank_ids.remove(tank_id)
tank_ids.discard(tank_id)
# no stats found => Add None to mark that
for tank_id in tank_ids:
await self.cache.execute(WG.SQL_TANK_STATS_UPDATE, (account_id, tank_id, update_time, None))
@@ -1852,7 +1890,7 @@ class WoTinspector:
# FIX The replay can have allies/enemies i.e. be useful for
# team composition analysis, but does not have player contribution
if ('status' in json_resp) and json_resp['status'] == 'ok' and \
(get_JSON_value(json_resp, key='data.summary.allies') != None) :
(get_JSON_value(json_resp, key='data.summary.winner_team') != None) :
debug("JSON check OK")
return True
except KeyError as err:
+8 -6
View File
@@ -115,13 +115,12 @@ async def extract_tanks(blitz_app_base : str, nation: str):
for data in tankList['root'].keys():
tank_xml = tankList['root'][data]
tank = dict()
tank['tank_id'] = await get_tank_id(nation, int(tank_xml['id']))
tank['userStr'] = tank_xml['userString']
tank['nation'] = nation
tank['tier'] = int(tank_xml['level'])
#debug(tank_xml['price'])
tank['is_premium'] = issubclass(type(tank_xml['price']), dict)
tank['nation'] = nation
tank['tank_id'] = await get_tank_id(nation, int(tank_xml['id']))
tank['tier'] = int(tank_xml['level'])
tank['type'] = await get_tank_type(tank_xml['tags'])
tank['userStr'] = tank_xml['userString']
#bu.debug('Reading tank string: ' + tank['userStr'], force=True)
tanks.append(tank)
except Exception as err:
@@ -165,7 +164,10 @@ async def convert_tank_names(tanklist : list, tank_strs: dict) -> dict:
tank['name'] = tank_strs[tank['userStr']]
#userStrs[tank['userStr'].split(':')[1]] = tank['name']
tank.pop('userStr', None)
tankopedia[str(tank['tank_id'])] = tank
tank_tmp = collections.OrderedDict()
for key in sorted(tank.keys()):
tank_tmp[key] = tank[key]
tankopedia[str(tank['tank_id'])] = tank_tmp
for tank_str in tank_strs:
skip = False
+3
View File
@@ -48,6 +48,9 @@
"rift": "Hellas",
"rock": "Mayan Ruins",
"rudniki": "Mines",
"rudniki_01": "Mines - Hill",
"rudniki_02": "Mines - Village",
"rudniki_03": "Mines - Center",
"savanna": "Oasis Palms",
"skit": "Naval Frontier",
"test": "World of Ducks",
+3
View File
@@ -2,6 +2,9 @@
| Release | Date | Notes | Inaccurate? |
|:-------:|:--------:|-------------|-----|
| 7.9 | 2021-04-27 | Mines rework, new tutorial, colorblind mode, JgPz E100 legendary camo | |
| 7.8 | 2021-03-24 | Mid-tier balance changes, Grille line new consumables | |
| 7.7 | 2021-02-24 | Czechoslovakian medium tanks | |
| 7.6 | 2021-01-27 | AMC 13 90, TOG II buffs, free replay camera | |
| 7.5 | 2020-12-09 | ATGM removal, Batchat, Kpz70, T-2020 buff | |
| 7.4 | 2020-11-12 | TD buffs, Clan missions | |
+172
View File
@@ -0,0 +1,172 @@
,TOTAL,Battles,% Battles,WR,DPB,KPB,Spot,Top tier,DR,KDR,Hit rate,Pen rate,Surv%,Share live,Player WR,Allies WR,Enemies WR,No stats
,Total,6942,100%,71.80%,2058,1.86,1.4,64%,2.3,5.4,86.10%,90.80%,65.30%,90%,57.08%,50.15%,50.12%,0.20%
,,,,,,,,,,,,,,,,,,
,Result,Battles,% Battles,WR,DPB,KPB,Spot,Top tier,DR,KDR,Hit rate,Pen rate,Surv%,Share live,Player WR,Allies WR,Enemies WR,No stats
,Loss,1959,28%,0.00%,1715,1.12,1.3,61%,1.3,1.3,84.70%,88.60%,13.40%,78%,56.47%,49.56%,50.92%,0.10%
,Win,4983,72%,100.00%,2193,2.16,1.4,65%,3,15.1,86.50%,91.40%,85.70%,95%,57.32%,50.39%,49.80%,0.20%
,,,,,,,,,,,,,,,,,,
,Battle Type,Battles,% Battles,WR,DPB,KPB,Spot,Top tier,DR,KDR,Hit rate,Pen rate,Surv%,Share live,Player WR,Allies WR,Enemies WR,No stats
,Encounter,4652,67%,73.00%,1969,1.98,1.4,67%,2.5,6,85.70%,90.70%,66.80%,91%,57.43%,50.41%,50.33%,0.30%
,Supremacy,2290,33%,69.30%,2238,1.63,1.2,60%,2,4.3,87.10%,91.20%,62.20%,89%,56.37%,49.63%,49.69%,0.00%
,,,,,,,,,,,,,,,,,,
,Tier,Battles,% Battles,WR,DPB,KPB,Spot,Top tier,DR,KDR,Hit rate,Pen rate,Surv%,Share live,Player WR,Allies WR,Enemies WR,No stats
,Bottom tier,2480,36%,69.50%,1750,1.53,1.2,0%,2.2,3.9,85.40%,89.20%,60.70%,88%,56.91%,50.13%,49.99%,0.10%
,Top tier,4462,64%,73.10%,2229,2.05,1.5,100%,2.4,6.4,86.50%,91.60%,67.90%,91%,57.18%,50.16%,50.19%,0.20%
,,,,,,,,,,,,,,,,,,
,Tank Tier,Battles,% Battles,WR,DPB,KPB,Spot,Top tier,DR,KDR,Hit rate,Pen rate,Surv%,Share live,Player WR,Allies WR,Enemies WR,No stats
,1,89,1%,80.90%,678,1.89,1.9,40%,3,7.6,86.20%,91.80%,75.30%,95%,55.40%,48.80%,48.40%,0.00%
,2,180,3%,77.80%,970,2.64,1.6,73%,3.3,9.1,82.90%,90.60%,71.10%,93%,56.04%,49.36%,49.46%,0.90%
,3,540,8%,75.70%,1099,2.15,1.4,36%,3.1,7,83.60%,90.00%,69.10%,93%,57.55%,51.15%,50.16%,1.90%
,4,628,9%,75.20%,1256,2.21,1.3,73%,3.1,7.4,85.00%,91.60%,70.20%,94%,55.72%,51.76%,51.65%,0.00%
,5,626,9%,80.20%,1503,2.29,1.3,71%,3.2,8.3,86.90%,89.50%,72.20%,93%,55.69%,50.38%,49.95%,0.00%
,6,1064,15%,74.20%,1801,1.97,1.4,62%,2.4,5.8,86.70%,92.20%,65.90%,90%,56.82%,49.24%,49.31%,0.00%
,7,1141,16%,71.80%,2143,1.69,1.3,50%,2.5,4.9,85.70%,90.10%,65.80%,90%,58.48%,49.62%,49.60%,0.00%
,8,1222,18%,68.20%,2371,1.59,1.4,67%,2.1,4.2,87.40%,90.90%,61.80%,89%,56.84%,49.80%,49.99%,0.00%
,9,598,9%,64.70%,2806,1.61,1.2,49%,2.1,4,89.10%,91.90%,59.50%,87%,56.58%,50.13%,50.32%,0.00%
,10,854,12%,65.60%,3270,1.62,1.5,100%,2,4,88.30%,90.20%,59.60%,88%,58.37%,50.83%,51.16%,0.00%
,,,,,,,,,,,,,,,,,,
,Tank Class,Battles,% Battles,WR,DPB,KPB,Spot,Top tier,DR,KDR,Hit rate,Pen rate,Surv%,Share live,Player WR,Allies WR,Enemies WR,No stats
,Light Tank,1337,19%,74.40%,1589,1.88,1.9,59%,2.3,5.9,83.70%,89.20%,68.40%,90%,57.15%,50.20%,49.90%,0.70%
,Medium Tank,1957,28%,73.10%,2181,1.99,1.7,67%,2.4,5.9,88.20%,91.40%,66.40%,90%,57.23%,50.26%,50.12%,0.10%
,Heavy Tank,2032,29%,70.00%,2180,1.75,1.2,70%,1.9,5,87.20%,90.70%,65.20%,91%,56.72%,50.16%,50.23%,0.00%
,Tank Destroyer,1616,23%,70.30%,2144,1.84,0.7,59%,3,4.8,85.10%,92.60%,61.50%,91%,57.31%,49.98%,50.16%,0.00%
,,,,,,,,,,,,,,,,,,
,Player WR,Battles,% Battles,WR,DPB,KPB,Spot,Top tier,DR,KDR,Hit rate,Pen rate,Surv%,Share live,Player WR,Allies WR,Enemies WR,No stats
,35 - 45%,80,1%,43.80%,1255,0.93,1,55%,1.1,1.5,84.00%,87.10%,37.50%,82%,44.52%,49.84%,51.14%,0.00%
,45 - 50%,584,8%,69.20%,1397,1.46,1.1,62%,1.8,3.8,81.20%,87.40%,61.30%,89%,47.86%,49.84%,49.86%,0.00%
,50 - 55%,1970,28%,69.00%,1861,1.73,1.3,63%,2.1,4.3,85.40%,90.20%,60.20%,88%,53.06%,50.10%,49.99%,0.00%
,55 - 65%,3677,53%,73.50%,2249,2.01,1.4,66%,2.5,6.3,87.50%,91.50%,68.10%,92%,58.78%,50.13%,50.14%,0.00%
,65 - %,631,9%,76.40%,2274,1.95,1.4,61%,2.8,7,84.60%,91.40%,72.10%,91%,69.92%,50.79%,50.51%,1.90%
,,,,,,,,,,,,,,,,,,
,Player Hit Rate,Battles,% Battles,WR,DPB,KPB,Spot,Top tier,DR,KDR,Hit rate,Pen rate,Surv%,Share live,Player WR,Allies WR,Enemies WR,No stats
, 0 - 25%,32,0%,43.80%,1,0,1.6,47%,0,0,0.00%, inf%,25.00%,57%,54.55%,50.15%,51.14%,0.00%
,25 - 50%,47,1%,44.70%,693,0.34,1.3,51%,0.6,0.5,38.70%,90.50%,36.20%,77%,55.05%,50.14%,51.15%,0.00%
,50 - 60%,172,2%,56.40%,876,0.6,1.2,58%,0.8,1.1,54.70%,87.80%,44.80%,81%,56.38%,50.61%,50.48%,0.00%
,60 - 70%,461,7%,58.80%,1254,1.08,1.2,61%,1.4,2.4,65.40%,87.70%,54.20%,87%,56.29%,50.18%,50.50%,0.00%
,70 - 80%,941,14%,70.50%,1691,1.59,1.3,63%,2,4.6,75.50%,89.10%,65.70%,91%,56.92%,50.36%,50.24%,0.00%
,80 - 90%,2091,30%,74.00%,2071,1.98,1.4,66%,2.5,6.3,85.00%,90.60%,68.50%,93%,57.00%,50.10%,50.08%,0.10%
,90 - 95%,1258,18%,81.00%,2561,2.52,1.5,66%,3.3,11,92.30%,92.00%,77.10%,96%,57.73%,50.08%,49.85%,0.30%
,95 - %,1940,28%,69.60%,2259,1.82,1.4,64%,2.2,4.5,99.00%,91.70%,59.80%,86%,57.17%,50.12%,50.11%,0.40%
,,,,,,,,,,,,,,,,,,
,Player Pen Rate,Battles,% Battles,WR,DPB,KPB,Spot,Top tier,DR,KDR,Hit rate,Pen rate,Surv%,Share live,Player WR,Allies WR,Enemies WR,No stats
, 0 - 25%,49,1%,38.80%,6,0,1.5,39%,0,0,45.80%,10.50%,22.40%,56%,55.11%,49.96%,50.47%,0.00%
,25 - 50%,43,1%,30.20%,447,0.19,1.7,44%,0.3,0.2,82.30%,38.40%,20.90%,66%,55.41%,50.75%,51.06%,0.00%
,50 - 60%,110,2%,41.80%,642,0.27,1.5,60%,0.5,0.4,77.50%,53.10%,32.70%,70%,54.44%,50.46%,50.61%,0.00%
,60 - 70%,210,3%,52.40%,1085,0.63,1.3,56%,0.9,1.1,81.00%,65.10%,40.00%,79%,55.71%,50.58%,50.39%,0.00%
,70 - 80%,469,7%,65.00%,1669,1.33,1.4,61%,1.6,3.1,83.50%,75.40%,57.60%,89%,56.39%,50.24%,50.30%,0.00%
,80 - 90%,1544,22%,71.60%,2076,1.86,1.4,61%,2.3,5.5,86.00%,85.30%,66.30%,92%,57.35%,50.17%,50.03%,0.20%
,90 - 95%,1210,17%,79.30%,2509,2.53,1.5,66%,3.3,11,87.80%,92.40%,77.00%,96%,57.57%,50.00%,50.09%,0.20%
,95 - %,3307,48%,73.30%,2100,1.88,1.3,67%,2.4,5.5,86.30%,99.30%,65.60%,90%,57.11%,50.14%,50.10%,0.20%
,,,,,,,,,,,,,,,,,,
Server,account_id_anon,Battles,% Battles,WR,DPB,KPB,Spot,Top tier,DR,KDR,Hit rate,Pen rate,Surv%,Share live,Player WR,Allies WR,Enemies WR,No stats
RU,1,33,0%,78.80%,3112,1.91,1.6,67%,2.5,7.9,89.60%,90.20%,75.80%,87%,71.43%,50.74%,51.07%,0.00%
RU,2,23,0%,87.00%,3525,2.78,1.7,74%,4.3,32,90.40%,94.40%,91.30%,100%,59.39%,48.07%,48.75%,0.00%
RU,3,81,1%,66.70%,1927,1.47,1,75%,1.9,3.1,82.30%,89.60%,53.10%,86%,69.59%,50.23%,50.85%,0.00%
EU,4,26,0%,80.80%,4082,2.62,1.2,62%,4.1,17,91.10%,93.80%,84.60%,98%,53.92%,48.75%,49.31%,0.00%
EU,5,79,1%,59.50%,1920,0.97,1.4,75%,1.4,2,80.20%,87.10%,50.60%,84%,59.06%,50.12%,51.22%,0.00%
EU,6,92,1%,60.90%,1685,0.99,1.5,65%,1.3,1.8,87.80%,88.50%,45.70%,83%,57.79%,50.30%,50.77%,0.00%
EU,7,50,1%,78.00%,2787,2.92,1.9,52%,4,16.2,90.60%,92.70%,82.00%,99%,64.87%,50.49%,50.50%,0.00%
EU,8,69,1%,60.90%,1695,1.48,1.9,55%,1.5,3,87.80%,92.10%,50.70%,77%,54.73%,50.06%,49.81%,0.10%
EU,9,33,0%,63.60%,1529,1.55,1.9,64%,2,3.6,82.10%,91.30%,57.60%,85%,52.48%,49.85%,50.92%,0.00%
EU,10,22,0%,90.90%,2990,3.82,1,59%,3.6,42,85.60%,93.00%,90.90%,100%,57.27%,48.97%,49.67%,0.00%
EU,11,35,1%,62.90%,1197,0.97,1.1,66%,1.3,2,85.20%,88.10%,51.40%,81%,55.89%,50.71%,49.97%,0.00%
EU,12,20,0%,95.00%,4854,3.95,1.2,25%,4.9,79,94.40%,95.60%,95.00%,99%,56.71%,49.15%,49.81%,0.00%
EU,13,80,1%,73.80%,2228,2.65,1.4,69%,3.3,8.5,92.10%,92.70%,68.80%,95%,58.83%,49.43%,49.21%,0.00%
EU,14,30,0%,83.30%,2167,3.93,2,63%,4.2,19.7,87.90%,92.00%,80.00%,98%,62.43%,50.39%,49.69%,0.00%
EU,15,305,4%,55.40%,2126,1.21,1.3,78%,1.6,2.4,85.80%,90.90%,49.50%,87%,58.91%,50.46%,50.47%,0.00%
EU,16,49,1%,69.40%,2362,2.47,1.5,43%,4,7.1,90.20%,93.30%,65.30%,94%,62.94%,49.43%,49.50%,0.00%
EU,17,22,0%,86.40%,1898,4.41,1.4,95%,4.8,48.5,90.60%,94.80%,90.90%,100%,57.61%,48.11%,49.25%,0.00%
EU,18,96,1%,76.00%,1764,2.19,0.9,67%,3.2,7.2,89.40%,95.00%,69.80%,94%,56.39%,50.00%,49.58%,0.00%
EU,19,23,0%,95.70%,1997,2.09,1.3,65%,3.8,16,90.70%,94.20%,87.00%,98%,70.96%,48.51%,49.66%,0.00%
EU,20,256,4%,54.30%,1081,0.58,1.5,55%,0.9,0.8,81.10%,83.80%,28.10%,68%,52.29%,50.31%,49.81%,0.00%
EU,21,73,1%,82.20%,1025,1.9,1.5,55%,2.7,6.3,84.20%,92.30%,69.90%,94%,58.95%,51.61%,50.45%,0.00%
EU,22,53,1%,79.20%,1415,1.98,0.9,47%,3.2,7,87.40%,90.40%,71.70%,95%,57.15%,50.10%,49.76%,0.00%
EU,23,70,1%,81.40%,2224,2.5,1.8,47%,4,9.7,89.20%,90.20%,74.30%,96%,61.99%,50.85%,50.17%,0.00%
EU,24,83,1%,73.50%,3049,2.1,2,73%,3.2,7.2,89.60%,91.70%,71.10%,96%,60.48%,49.78%,49.51%,0.00%
EU,25,127,2%,68.50%,1609,1.86,1.3,52%,2.4,4.5,83.40%,89.50%,59.10%,89%,54.64%,49.76%,49.35%,0.00%
EU,26,52,1%,80.80%,2669,2.62,2.2,50%,3,11.3,87.80%,91.00%,76.90%,95%,62.66%,49.60%,49.65%,0.20%
EU,27,30,0%,86.70%,4246,3.17,1.4,57%,3.6,23.8,88.10%,95.30%,86.70%,99%,56.38%,49.10%,49.54%,0.00%
EU,28,24,0%,83.30%,2823,2.96,1.8,62%,4.9,17.8,89.30%,91.20%,83.30%,98%,64.91%,50.25%,51.06%,0.00%
EU,29,29,0%,75.90%,1750,1.62,1.3,59%,2.2,3.6,88.10%,93.60%,55.20%,91%,54.39%,49.78%,49.34%,0.00%
EU,30,26,0%,92.30%,2631,3.12,1.8,69%,3.1,27,92.90%,93.80%,88.50%,97%,57.57%,49.93%,49.96%,0.00%
EU,31,31,0%,90.30%,2126,2.16,1.2,61%,3.4,13.4,85.20%,91.20%,83.90%,98%,52.31%,50.24%,49.30%,0.00%
EU,32,44,1%,77.30%,1848,2.91,0.7,77%,3.4,14.2,85.40%,91.70%,79.50%,96%,50.22%,50.67%,50.91%,0.00%
EU,33,74,1%,94.60%,1811,3.24,1.5,59%,4.1,48,86.80%,86.30%,93.20%,99%,56.08%,49.98%,49.17%,0.00%
EU,34,158,2%,77.80%,1290,1.66,0.9,53%,2.4,4.4,78.40%,90.70%,62.70%,93%,49.45%,49.80%,50.05%,0.00%
EU,35,21,0%,61.90%,1796,1.19,1.4,86%,1.5,2.5,77.00%,86.60%,52.40%,82%,48.99%,50.98%,50.38%,0.00%
EU,36,120,2%,55.80%,1730,1.1,1.6,68%,1.3,2.2,85.30%,85.90%,49.20%,83%,60.61%,50.43%,49.95%,0.10%
EU,37,25,0%,88.00%,5110,3.6,1.5,96%,3.7,45,94.90%,91.70%,92.00%,100%,60.44%,50.29%,51.16%,0.00%
EU,38,350,5%,62.00%,1159,1.09,1.3,63%,1.2,2.3,83.10%,89.70%,52.30%,84%,52.65%,50.37%,50.42%,0.00%
EU,39,25,0%,84.00%,4965,2.72,1.5,84%,3.6,13.6,89.40%,91.30%,80.00%,97%,54.95%,49.64%,50.59%,0.00%
EU,40,22,0%,90.90%,4394,3.09,2.3,64%,4.2,34,92.60%,90.30%,90.90%,98%,52.49%,50.46%,50.63%,0.00%
EU,41,57,1%,63.20%,3078,1.63,2.3,96%,2,3.3,85.40%,86.30%,50.90%,85%,60.62%,51.59%,52.10%,0.00%
EU,42,22,0%,68.20%,2270,0.95,1.3,91%,1.6,1.9,85.20%,88.90%,50.00%,85%,59.46%,50.97%,50.61%,0.00%
EU,43,45,1%,64.40%,1482,0.93,1.6,62%,1.2,1.8,83.00%,91.60%,48.90%,79%,50.40%,51.15%,50.79%,0.00%
EU,44,56,1%,96.40%,1927,2.79,1.6,77%,5.4,31.2,85.60%,90.20%,91.10%,98%,54.95%,49.96%,49.62%,0.00%
EU,45,28,0%,96.40%,4659,3.5,1.4,64%,3.8,49,89.00%,91.70%,92.90%,100%,54.81%,49.56%,49.85%,0.00%
EU,46,134,2%,70.90%,1291,1.99,1,49%,3.3,5.6,82.90%,91.80%,64.20%,94%,55.71%,51.75%,51.64%,0.00%
EU,47,51,1%,72.50%,1119,1.43,0.9,78%,1.9,3.8,89.20%,89.20%,62.70%,89%,52.58%,52.04%,52.06%,0.00%
EU,48,45,1%,86.70%,2756,2.71,2.2,64%,4.1,12.2,90.10%,91.50%,77.80%,97%,63.68%,49.88%,49.92%,0.00%
EU,49,35,1%,97.10%,5932,3.57,1.1,94%,5.7,41.7,88.10%,96.30%,91.40%,99%,70.46%,49.51%,50.42%,0.00%
EU,50,186,3%,60.80%,1169,1.02,1.2,49%,1.2,2.1,80.20%,89.20%,52.20%,84%,56.65%,50.14%,50.07%,0.00%
EU,51,25,0%,92.00%,2194,4.68,2.3,60%,4.9,117,86.20%,92.00%,96.00%,100%,70.74%,52.26%,51.76%,0.00%
EU,52,93,1%,62.40%,1444,1.1,1.1,54%,1.7,2.9,88.00%,92.30%,62.40%,85%,72.96%,49.89%,50.29%,0.00%
EU,53,25,0%,80.00%,2374,2.8,1.5,68%,3.5,11.7,86.80%,90.50%,76.00%,95%,60.96%,49.42%,48.68%,0.00%
EU,54,30,0%,53.30%,2384,1.27,1.7,73%,1.6,2.5,85.00%,86.50%,50.00%,81%,54.58%,49.33%,50.27%,0.00%
EU,55,29,0%,79.30%,2219,1.93,1.6,69%,2.1,5.1,88.30%,86.10%,62.10%,89%,47.58%,50.43%,49.39%,0.00%
EU,56,73,1%,69.90%,2036,2.33,0.9,64%,3.2,8.5,90.80%,94.00%,72.60%,95%,52.47%,49.24%,49.05%,0.10%
EU,57,26,0%,96.20%,949,3.08,2,50%,3.2,26.7,83.20%,87.10%,88.50%,97%,46.64%,49.42%,48.36%,0.00%
EU,58,20,0%,65.00%,344,0.45,0.9,45%,0.7,1.3,75.50%,73.80%,65.00%,83%,45.36%,49.30%,49.03%,0.00%
EU,59,149,2%,34.90%,1105,0.8,1.1,60%,0.9,1.1,82.80%,85.80%,28.90%,78%,45.21%,50.08%,51.28%,0.00%
EU,60,22,0%,63.60%,1108,0.91,1,91%,1.3,1.4,78.70%,85.00%,36.40%,81%,54.54%,49.66%,49.03%,0.00%
EU,61,36,1%,94.40%,2794,3.81,2.5,83%,6.2,45.7,85.30%,92.10%,91.70%,100%,63.28%,50.37%,50.28%,0.00%
EU,62,32,0%,31.20%,1786,1.19,0.9,75%,1.8,2,90.60%,91.90%,40.60%,88%,61.60%,49.13%,50.35%,0.00%
EU,63,21,0%,85.70%,2476,3.33,2,76%,4.8,35,91.50%,95.70%,90.50%,99%,53.93%,50.29%,49.74%,0.00%
NA,64,23,0%,91.30%,2371,3.57,0.9,70%,4.8,20.5,86.10%,92.50%,82.60%,99%,58.19%,49.00%,50.44%,0.30%
NA,65,25,0%,96.00%,4281,2.56,1.8,72%,4.1,64,90.20%,91.40%,96.00%,100%,62.10%,51.41%,50.28%,0.00%
NA,66,238,3%,76.10%,2183,1.56,1.5,50%,2.8,5.7,79.70%,89.90%,72.70%,92%,68.48%,50.75%,50.57%,0.00%
NA,67,56,1%,73.20%,2022,1.88,1.3,68%,2.5,6.6,85.20%,90.40%,71.40%,93%,55.31%,49.88%,49.73%,0.10%
NA,68,25,0%,92.00%,6141,3.36,1.2,100%,3.5,28,92.20%,93.80%,88.00%,99%,62.64%,49.81%,50.96%,0.00%
NA,69,44,1%,77.30%,4178,1.93,1.5,77%,3,12.1,92.10%,91.60%,84.10%,98%,53.67%,50.20%,50.23%,0.00%
NA,70,26,0%,96.20%,3412,3.46,1.8,69%,3.6,90,92.20%,93.90%,96.20%,100%,65.85%,48.95%,49.25%,0.00%
NA,71,58,1%,77.60%,1642,1.93,0.9,60%,2.2,5.6,86.00%,94.60%,65.50%,87%,46.03%,49.73%,50.08%,0.00%
NA,72,197,3%,78.20%,2416,2.37,1.2,64%,3.3,10.8,86.30%,92.80%,78.20%,97%,56.68%,49.22%,49.50%,0.00%
NA,73,23,0%,60.90%,3932,1.91,2,87%,3,4.9,89.50%,90.70%,60.90%,89%,60.65%,48.75%,50.51%,0.00%
NA,74,42,1%,78.60%,1431,2.45,0.7,36%,2.2,6.9,84.50%,89.30%,64.30%,90%,50.81%,49.26%,49.33%,0.00%
NA,75,21,0%,81.00%,3748,3.29,1.3,57%,4,17.2,91.90%,92.50%,81.00%,100%,61.77%,48.23%,48.98%,0.00%
NA,76,34,0%,88.20%,2707,2.59,1.4,68%,3,44,84.50%,90.50%,94.10%,96%,55.79%,50.34%,49.42%,0.00%
NA,77,115,2%,74.80%,2171,2.19,1.4,74%,2.9,8.4,89.00%,91.40%,73.90%,95%,59.53%,49.65%,49.88%,0.00%
NA,78,23,0%,65.20%,1958,1.96,0.5,61%,2.3,5.6,89.80%,93.30%,65.20%,92%,62.10%,50.31%,49.85%,0.00%
NA,79,218,3%,74.30%,1860,2.16,1.5,65%,2.6,7.2,85.90%,91.60%,70.20%,95%,53.76%,50.11%,49.84%,0.00%
NA,80,35,1%,57.10%,3142,1.71,1.9,80%,2.3,3.2,90.00%,93.10%,45.70%,86%,56.23%,50.16%,51.49%,0.00%
NA,81,32,0%,90.60%,3407,2.62,1.2,62%,3.6,16.8,85.80%,91.90%,84.40%,97%,54.91%,49.20%,49.43%,0.00%
NA,82,20,0%,90.00%,4472,3.4,2.2,75%,4.1,34,86.20%,83.10%,90.00%,100%,50.16%,50.67%,50.02%,0.00%
NA,83,51,1%,72.50%,1023,2.08,1.1,76%,2.2,5.6,88.30%,93.20%,62.70%,91%,73.85%,56.05%,50.69%,23.20%
NA,84,47,1%,80.90%,3820,2.45,1.4,85%,3.7,12.8,93.20%,94.90%,80.90%,98%,61.01%,50.73%,50.39%,0.00%
NA,85,71,1%,91.50%,3159,2.73,0.9,65%,3.9,27.7,89.40%,92.40%,90.10%,99%,55.39%,49.64%,50.01%,0.00%
NA,86,28,0%,85.70%,4249,2.46,1.3,79%,3.1,23,91.90%,93.70%,89.30%,95%,61.07%,50.13%,50.15%,0.00%
NA,87,24,0%,75.00%,3048,2.17,1.9,75%,2.7,10.4,85.40%,90.00%,79.20%,98%,55.74%,49.79%,50.05%,0.00%
NA,88,34,0%,67.60%,3317,2.21,2.1,65%,3.6,6.8,90.50%,91.30%,67.60%,96%,61.83%,49.97%,49.88%,0.00%
NA,89,23,0%,30.40%,1399,0.52,1.3,91%,0.9,0.8,87.30%,85.40%,30.40%,71%,49.58%,50.38%,51.69%,0.00%
NA,90,20,0%,75.00%,1305,0.6,1.4,60%,1.1,1.7,88.10%,80.10%,65.00%,91%,48.23%,49.76%,49.40%,0.00%
NA,91,24,0%,79.20%,2554,2.96,1.2,50%,5.6,17.8,93.30%,95.50%,83.30%,98%,58.79%,50.82%,51.10%,0.00%
NA,92,48,1%,56.20%,1707,0.69,0.7,92%,0.8,1.4,81.30%,86.80%,52.10%,87%,55.85%,53.43%,53.97%,0.00%
NA,93,130,2%,62.30%,1912,1.31,1.3,70%,1.3,2.9,89.00%,91.70%,55.40%,86%,59.63%,49.95%,50.11%,0.00%
NA,94,35,1%,77.10%,3875,2.74,1.8,57%,3.6,12,89.60%,94.40%,77.10%,95%,59.73%,49.60%,50.04%,0.00%
NA,95,23,0%,73.90%,2688,3.17,1,74%,3.4,14.6,92.50%,93.20%,78.30%,96%,51.21%,49.86%,50.33%,0.00%
NA,96,26,0%,61.50%,1796,1.19,1.2,31%,1.6,2.8,75.60%,84.20%,57.70%,91%,54.00%,50.02%,50.03%,0.00%
NA,97,21,0%,90.50%,1869,2.52,2.3,76%,3.2,17.7,85.40%,89.60%,85.70%,96%,56.43%,49.38%,49.01%,0.00%
NA,98,101,1%,71.30%,1499,2,0.7,58%,2.7,5.3,83.30%,91.50%,62.40%,93%,52.60%,49.80%,49.63%,0.10%
NA,99,20,0%,60.00%,1368,1,0.9,45%,1.4,2.9,83.50%,87.90%,65.00%,84%,54.73%,50.49%,50.26%,0.00%
NA,100,24,0%,79.20%,1998,2.54,1.6,75%,3.4,20.3,85.30%,83.70%,87.50%,98%,53.43%,50.95%,50.42%,0.30%
NA,101,26,0%,42.30%,1170,0.77,1.7,73%,1.3,1.2,75.50%,86.50%,34.60%,81%,46.59%,49.31%,50.13%,0.00%
NA,102,26,0%,53.80%,1013,0.85,0.8,62%,1.1,1.2,74.20%,82.40%,26.90%,83%,52.75%,49.08%,49.42%,0.00%
NA,103,23,0%,91.30%,3980,3,1.4,83%,3.1,34.5,86.00%,90.80%,91.30%,97%,63.72%,49.86%,49.82%,0.00%
NA,104,57,1%,71.90%,1694,1.49,0.6,74%,2.8,4.7,82.80%,86.80%,68.40%,92%,46.26%,49.48%,48.84%,0.00%
ASIA,105,330,5%,82.40%,2195,2.01,1.7,63%,2.7,7.5,89.80%,92.70%,73.00%,94%,57.98%,49.95%,49.71%,0.00%
ASIA,106,132,2%,77.30%,1268,1.31,0.8,58%,2.2,3.5,82.20%,92.40%,62.10%,85%,62.78%,49.79%,50.26%,0.00%
ASIA,107,21,0%,90.50%,3749,3.67,1.8,81%,4.1,38.5,90.70%,93.70%,90.50%,97%,53.77%,49.37%,50.06%,0.00%
ASIA,108,35,1%,85.70%,4501,2.6,1.6,74%,4,15.2,89.10%,91.20%,82.90%,99%,54.47%,49.39%,49.24%,0.00%
ASIA,109,67,1%,73.10%,1278,1.7,1.5,54%,2.8,5.7,83.80%,88.00%,70.10%,93%,55.23%,51.01%,50.11%,0.10%
ASIA,110,70,1%,91.40%,1525,1.54,1.1,54%,3.5,54,78.50%,86.10%,97.10%,99%,49.45%,49.53%,48.75%,0.00%
ASIA,111,49,1%,67.30%,2050,1.96,0.7,73%,2.7,5.3,85.70%,91.40%,63.30%,93%,52.58%,49.79%,49.79%,0.00%
1 TOTAL Battles % Battles WR DPB KPB Spot Top tier DR KDR Hit rate Pen rate Surv% Share live Player WR Allies WR Enemies WR No stats
2 Total 6942 100% 71.80% 2058 1.86 1.4 64% 2.3 5.4 86.10% 90.80% 65.30% 90% 57.08% 50.15% 50.12% 0.20%
3
4 Result Battles % Battles WR DPB KPB Spot Top tier DR KDR Hit rate Pen rate Surv% Share live Player WR Allies WR Enemies WR No stats
5 Loss 1959 28% 0.00% 1715 1.12 1.3 61% 1.3 1.3 84.70% 88.60% 13.40% 78% 56.47% 49.56% 50.92% 0.10%
6 Win 4983 72% 100.00% 2193 2.16 1.4 65% 3 15.1 86.50% 91.40% 85.70% 95% 57.32% 50.39% 49.80% 0.20%
7
8 Battle Type Battles % Battles WR DPB KPB Spot Top tier DR KDR Hit rate Pen rate Surv% Share live Player WR Allies WR Enemies WR No stats
9 Encounter 4652 67% 73.00% 1969 1.98 1.4 67% 2.5 6 85.70% 90.70% 66.80% 91% 57.43% 50.41% 50.33% 0.30%
10 Supremacy 2290 33% 69.30% 2238 1.63 1.2 60% 2 4.3 87.10% 91.20% 62.20% 89% 56.37% 49.63% 49.69% 0.00%
11
12 Tier Battles % Battles WR DPB KPB Spot Top tier DR KDR Hit rate Pen rate Surv% Share live Player WR Allies WR Enemies WR No stats
13 Bottom tier 2480 36% 69.50% 1750 1.53 1.2 0% 2.2 3.9 85.40% 89.20% 60.70% 88% 56.91% 50.13% 49.99% 0.10%
14 Top tier 4462 64% 73.10% 2229 2.05 1.5 100% 2.4 6.4 86.50% 91.60% 67.90% 91% 57.18% 50.16% 50.19% 0.20%
15
16 Tank Tier Battles % Battles WR DPB KPB Spot Top tier DR KDR Hit rate Pen rate Surv% Share live Player WR Allies WR Enemies WR No stats
17 1 89 1% 80.90% 678 1.89 1.9 40% 3 7.6 86.20% 91.80% 75.30% 95% 55.40% 48.80% 48.40% 0.00%
18 2 180 3% 77.80% 970 2.64 1.6 73% 3.3 9.1 82.90% 90.60% 71.10% 93% 56.04% 49.36% 49.46% 0.90%
19 3 540 8% 75.70% 1099 2.15 1.4 36% 3.1 7 83.60% 90.00% 69.10% 93% 57.55% 51.15% 50.16% 1.90%
20 4 628 9% 75.20% 1256 2.21 1.3 73% 3.1 7.4 85.00% 91.60% 70.20% 94% 55.72% 51.76% 51.65% 0.00%
21 5 626 9% 80.20% 1503 2.29 1.3 71% 3.2 8.3 86.90% 89.50% 72.20% 93% 55.69% 50.38% 49.95% 0.00%
22 6 1064 15% 74.20% 1801 1.97 1.4 62% 2.4 5.8 86.70% 92.20% 65.90% 90% 56.82% 49.24% 49.31% 0.00%
23 7 1141 16% 71.80% 2143 1.69 1.3 50% 2.5 4.9 85.70% 90.10% 65.80% 90% 58.48% 49.62% 49.60% 0.00%
24 8 1222 18% 68.20% 2371 1.59 1.4 67% 2.1 4.2 87.40% 90.90% 61.80% 89% 56.84% 49.80% 49.99% 0.00%
25 9 598 9% 64.70% 2806 1.61 1.2 49% 2.1 4 89.10% 91.90% 59.50% 87% 56.58% 50.13% 50.32% 0.00%
26 10 854 12% 65.60% 3270 1.62 1.5 100% 2 4 88.30% 90.20% 59.60% 88% 58.37% 50.83% 51.16% 0.00%
27
28 Tank Class Battles % Battles WR DPB KPB Spot Top tier DR KDR Hit rate Pen rate Surv% Share live Player WR Allies WR Enemies WR No stats
29 Light Tank 1337 19% 74.40% 1589 1.88 1.9 59% 2.3 5.9 83.70% 89.20% 68.40% 90% 57.15% 50.20% 49.90% 0.70%
30 Medium Tank 1957 28% 73.10% 2181 1.99 1.7 67% 2.4 5.9 88.20% 91.40% 66.40% 90% 57.23% 50.26% 50.12% 0.10%
31 Heavy Tank 2032 29% 70.00% 2180 1.75 1.2 70% 1.9 5 87.20% 90.70% 65.20% 91% 56.72% 50.16% 50.23% 0.00%
32 Tank Destroyer 1616 23% 70.30% 2144 1.84 0.7 59% 3 4.8 85.10% 92.60% 61.50% 91% 57.31% 49.98% 50.16% 0.00%
33
34 Player WR Battles % Battles WR DPB KPB Spot Top tier DR KDR Hit rate Pen rate Surv% Share live Player WR Allies WR Enemies WR No stats
35 35 - 45% 80 1% 43.80% 1255 0.93 1 55% 1.1 1.5 84.00% 87.10% 37.50% 82% 44.52% 49.84% 51.14% 0.00%
36 45 - 50% 584 8% 69.20% 1397 1.46 1.1 62% 1.8 3.8 81.20% 87.40% 61.30% 89% 47.86% 49.84% 49.86% 0.00%
37 50 - 55% 1970 28% 69.00% 1861 1.73 1.3 63% 2.1 4.3 85.40% 90.20% 60.20% 88% 53.06% 50.10% 49.99% 0.00%
38 55 - 65% 3677 53% 73.50% 2249 2.01 1.4 66% 2.5 6.3 87.50% 91.50% 68.10% 92% 58.78% 50.13% 50.14% 0.00%
39 65 - % 631 9% 76.40% 2274 1.95 1.4 61% 2.8 7 84.60% 91.40% 72.10% 91% 69.92% 50.79% 50.51% 1.90%
40
41 Player Hit Rate Battles % Battles WR DPB KPB Spot Top tier DR KDR Hit rate Pen rate Surv% Share live Player WR Allies WR Enemies WR No stats
42 0 - 25% 32 0% 43.80% 1 0 1.6 47% 0 0 0.00% inf% 25.00% 57% 54.55% 50.15% 51.14% 0.00%
43 25 - 50% 47 1% 44.70% 693 0.34 1.3 51% 0.6 0.5 38.70% 90.50% 36.20% 77% 55.05% 50.14% 51.15% 0.00%
44 50 - 60% 172 2% 56.40% 876 0.6 1.2 58% 0.8 1.1 54.70% 87.80% 44.80% 81% 56.38% 50.61% 50.48% 0.00%
45 60 - 70% 461 7% 58.80% 1254 1.08 1.2 61% 1.4 2.4 65.40% 87.70% 54.20% 87% 56.29% 50.18% 50.50% 0.00%
46 70 - 80% 941 14% 70.50% 1691 1.59 1.3 63% 2 4.6 75.50% 89.10% 65.70% 91% 56.92% 50.36% 50.24% 0.00%
47 80 - 90% 2091 30% 74.00% 2071 1.98 1.4 66% 2.5 6.3 85.00% 90.60% 68.50% 93% 57.00% 50.10% 50.08% 0.10%
48 90 - 95% 1258 18% 81.00% 2561 2.52 1.5 66% 3.3 11 92.30% 92.00% 77.10% 96% 57.73% 50.08% 49.85% 0.30%
49 95 - % 1940 28% 69.60% 2259 1.82 1.4 64% 2.2 4.5 99.00% 91.70% 59.80% 86% 57.17% 50.12% 50.11% 0.40%
50
51 Player Pen Rate Battles % Battles WR DPB KPB Spot Top tier DR KDR Hit rate Pen rate Surv% Share live Player WR Allies WR Enemies WR No stats
52 0 - 25% 49 1% 38.80% 6 0 1.5 39% 0 0 45.80% 10.50% 22.40% 56% 55.11% 49.96% 50.47% 0.00%
53 25 - 50% 43 1% 30.20% 447 0.19 1.7 44% 0.3 0.2 82.30% 38.40% 20.90% 66% 55.41% 50.75% 51.06% 0.00%
54 50 - 60% 110 2% 41.80% 642 0.27 1.5 60% 0.5 0.4 77.50% 53.10% 32.70% 70% 54.44% 50.46% 50.61% 0.00%
55 60 - 70% 210 3% 52.40% 1085 0.63 1.3 56% 0.9 1.1 81.00% 65.10% 40.00% 79% 55.71% 50.58% 50.39% 0.00%
56 70 - 80% 469 7% 65.00% 1669 1.33 1.4 61% 1.6 3.1 83.50% 75.40% 57.60% 89% 56.39% 50.24% 50.30% 0.00%
57 80 - 90% 1544 22% 71.60% 2076 1.86 1.4 61% 2.3 5.5 86.00% 85.30% 66.30% 92% 57.35% 50.17% 50.03% 0.20%
58 90 - 95% 1210 17% 79.30% 2509 2.53 1.5 66% 3.3 11 87.80% 92.40% 77.00% 96% 57.57% 50.00% 50.09% 0.20%
59 95 - % 3307 48% 73.30% 2100 1.88 1.3 67% 2.4 5.5 86.30% 99.30% 65.60% 90% 57.11% 50.14% 50.10% 0.20%
60
61 Server account_id_anon Battles % Battles WR DPB KPB Spot Top tier DR KDR Hit rate Pen rate Surv% Share live Player WR Allies WR Enemies WR No stats
62 RU 1 33 0% 78.80% 3112 1.91 1.6 67% 2.5 7.9 89.60% 90.20% 75.80% 87% 71.43% 50.74% 51.07% 0.00%
63 RU 2 23 0% 87.00% 3525 2.78 1.7 74% 4.3 32 90.40% 94.40% 91.30% 100% 59.39% 48.07% 48.75% 0.00%
64 RU 3 81 1% 66.70% 1927 1.47 1 75% 1.9 3.1 82.30% 89.60% 53.10% 86% 69.59% 50.23% 50.85% 0.00%
65 EU 4 26 0% 80.80% 4082 2.62 1.2 62% 4.1 17 91.10% 93.80% 84.60% 98% 53.92% 48.75% 49.31% 0.00%
66 EU 5 79 1% 59.50% 1920 0.97 1.4 75% 1.4 2 80.20% 87.10% 50.60% 84% 59.06% 50.12% 51.22% 0.00%
67 EU 6 92 1% 60.90% 1685 0.99 1.5 65% 1.3 1.8 87.80% 88.50% 45.70% 83% 57.79% 50.30% 50.77% 0.00%
68 EU 7 50 1% 78.00% 2787 2.92 1.9 52% 4 16.2 90.60% 92.70% 82.00% 99% 64.87% 50.49% 50.50% 0.00%
69 EU 8 69 1% 60.90% 1695 1.48 1.9 55% 1.5 3 87.80% 92.10% 50.70% 77% 54.73% 50.06% 49.81% 0.10%
70 EU 9 33 0% 63.60% 1529 1.55 1.9 64% 2 3.6 82.10% 91.30% 57.60% 85% 52.48% 49.85% 50.92% 0.00%
71 EU 10 22 0% 90.90% 2990 3.82 1 59% 3.6 42 85.60% 93.00% 90.90% 100% 57.27% 48.97% 49.67% 0.00%
72 EU 11 35 1% 62.90% 1197 0.97 1.1 66% 1.3 2 85.20% 88.10% 51.40% 81% 55.89% 50.71% 49.97% 0.00%
73 EU 12 20 0% 95.00% 4854 3.95 1.2 25% 4.9 79 94.40% 95.60% 95.00% 99% 56.71% 49.15% 49.81% 0.00%
74 EU 13 80 1% 73.80% 2228 2.65 1.4 69% 3.3 8.5 92.10% 92.70% 68.80% 95% 58.83% 49.43% 49.21% 0.00%
75 EU 14 30 0% 83.30% 2167 3.93 2 63% 4.2 19.7 87.90% 92.00% 80.00% 98% 62.43% 50.39% 49.69% 0.00%
76 EU 15 305 4% 55.40% 2126 1.21 1.3 78% 1.6 2.4 85.80% 90.90% 49.50% 87% 58.91% 50.46% 50.47% 0.00%
77 EU 16 49 1% 69.40% 2362 2.47 1.5 43% 4 7.1 90.20% 93.30% 65.30% 94% 62.94% 49.43% 49.50% 0.00%
78 EU 17 22 0% 86.40% 1898 4.41 1.4 95% 4.8 48.5 90.60% 94.80% 90.90% 100% 57.61% 48.11% 49.25% 0.00%
79 EU 18 96 1% 76.00% 1764 2.19 0.9 67% 3.2 7.2 89.40% 95.00% 69.80% 94% 56.39% 50.00% 49.58% 0.00%
80 EU 19 23 0% 95.70% 1997 2.09 1.3 65% 3.8 16 90.70% 94.20% 87.00% 98% 70.96% 48.51% 49.66% 0.00%
81 EU 20 256 4% 54.30% 1081 0.58 1.5 55% 0.9 0.8 81.10% 83.80% 28.10% 68% 52.29% 50.31% 49.81% 0.00%
82 EU 21 73 1% 82.20% 1025 1.9 1.5 55% 2.7 6.3 84.20% 92.30% 69.90% 94% 58.95% 51.61% 50.45% 0.00%
83 EU 22 53 1% 79.20% 1415 1.98 0.9 47% 3.2 7 87.40% 90.40% 71.70% 95% 57.15% 50.10% 49.76% 0.00%
84 EU 23 70 1% 81.40% 2224 2.5 1.8 47% 4 9.7 89.20% 90.20% 74.30% 96% 61.99% 50.85% 50.17% 0.00%
85 EU 24 83 1% 73.50% 3049 2.1 2 73% 3.2 7.2 89.60% 91.70% 71.10% 96% 60.48% 49.78% 49.51% 0.00%
86 EU 25 127 2% 68.50% 1609 1.86 1.3 52% 2.4 4.5 83.40% 89.50% 59.10% 89% 54.64% 49.76% 49.35% 0.00%
87 EU 26 52 1% 80.80% 2669 2.62 2.2 50% 3 11.3 87.80% 91.00% 76.90% 95% 62.66% 49.60% 49.65% 0.20%
88 EU 27 30 0% 86.70% 4246 3.17 1.4 57% 3.6 23.8 88.10% 95.30% 86.70% 99% 56.38% 49.10% 49.54% 0.00%
89 EU 28 24 0% 83.30% 2823 2.96 1.8 62% 4.9 17.8 89.30% 91.20% 83.30% 98% 64.91% 50.25% 51.06% 0.00%
90 EU 29 29 0% 75.90% 1750 1.62 1.3 59% 2.2 3.6 88.10% 93.60% 55.20% 91% 54.39% 49.78% 49.34% 0.00%
91 EU 30 26 0% 92.30% 2631 3.12 1.8 69% 3.1 27 92.90% 93.80% 88.50% 97% 57.57% 49.93% 49.96% 0.00%
92 EU 31 31 0% 90.30% 2126 2.16 1.2 61% 3.4 13.4 85.20% 91.20% 83.90% 98% 52.31% 50.24% 49.30% 0.00%
93 EU 32 44 1% 77.30% 1848 2.91 0.7 77% 3.4 14.2 85.40% 91.70% 79.50% 96% 50.22% 50.67% 50.91% 0.00%
94 EU 33 74 1% 94.60% 1811 3.24 1.5 59% 4.1 48 86.80% 86.30% 93.20% 99% 56.08% 49.98% 49.17% 0.00%
95 EU 34 158 2% 77.80% 1290 1.66 0.9 53% 2.4 4.4 78.40% 90.70% 62.70% 93% 49.45% 49.80% 50.05% 0.00%
96 EU 35 21 0% 61.90% 1796 1.19 1.4 86% 1.5 2.5 77.00% 86.60% 52.40% 82% 48.99% 50.98% 50.38% 0.00%
97 EU 36 120 2% 55.80% 1730 1.1 1.6 68% 1.3 2.2 85.30% 85.90% 49.20% 83% 60.61% 50.43% 49.95% 0.10%
98 EU 37 25 0% 88.00% 5110 3.6 1.5 96% 3.7 45 94.90% 91.70% 92.00% 100% 60.44% 50.29% 51.16% 0.00%
99 EU 38 350 5% 62.00% 1159 1.09 1.3 63% 1.2 2.3 83.10% 89.70% 52.30% 84% 52.65% 50.37% 50.42% 0.00%
100 EU 39 25 0% 84.00% 4965 2.72 1.5 84% 3.6 13.6 89.40% 91.30% 80.00% 97% 54.95% 49.64% 50.59% 0.00%
101 EU 40 22 0% 90.90% 4394 3.09 2.3 64% 4.2 34 92.60% 90.30% 90.90% 98% 52.49% 50.46% 50.63% 0.00%
102 EU 41 57 1% 63.20% 3078 1.63 2.3 96% 2 3.3 85.40% 86.30% 50.90% 85% 60.62% 51.59% 52.10% 0.00%
103 EU 42 22 0% 68.20% 2270 0.95 1.3 91% 1.6 1.9 85.20% 88.90% 50.00% 85% 59.46% 50.97% 50.61% 0.00%
104 EU 43 45 1% 64.40% 1482 0.93 1.6 62% 1.2 1.8 83.00% 91.60% 48.90% 79% 50.40% 51.15% 50.79% 0.00%
105 EU 44 56 1% 96.40% 1927 2.79 1.6 77% 5.4 31.2 85.60% 90.20% 91.10% 98% 54.95% 49.96% 49.62% 0.00%
106 EU 45 28 0% 96.40% 4659 3.5 1.4 64% 3.8 49 89.00% 91.70% 92.90% 100% 54.81% 49.56% 49.85% 0.00%
107 EU 46 134 2% 70.90% 1291 1.99 1 49% 3.3 5.6 82.90% 91.80% 64.20% 94% 55.71% 51.75% 51.64% 0.00%
108 EU 47 51 1% 72.50% 1119 1.43 0.9 78% 1.9 3.8 89.20% 89.20% 62.70% 89% 52.58% 52.04% 52.06% 0.00%
109 EU 48 45 1% 86.70% 2756 2.71 2.2 64% 4.1 12.2 90.10% 91.50% 77.80% 97% 63.68% 49.88% 49.92% 0.00%
110 EU 49 35 1% 97.10% 5932 3.57 1.1 94% 5.7 41.7 88.10% 96.30% 91.40% 99% 70.46% 49.51% 50.42% 0.00%
111 EU 50 186 3% 60.80% 1169 1.02 1.2 49% 1.2 2.1 80.20% 89.20% 52.20% 84% 56.65% 50.14% 50.07% 0.00%
112 EU 51 25 0% 92.00% 2194 4.68 2.3 60% 4.9 117 86.20% 92.00% 96.00% 100% 70.74% 52.26% 51.76% 0.00%
113 EU 52 93 1% 62.40% 1444 1.1 1.1 54% 1.7 2.9 88.00% 92.30% 62.40% 85% 72.96% 49.89% 50.29% 0.00%
114 EU 53 25 0% 80.00% 2374 2.8 1.5 68% 3.5 11.7 86.80% 90.50% 76.00% 95% 60.96% 49.42% 48.68% 0.00%
115 EU 54 30 0% 53.30% 2384 1.27 1.7 73% 1.6 2.5 85.00% 86.50% 50.00% 81% 54.58% 49.33% 50.27% 0.00%
116 EU 55 29 0% 79.30% 2219 1.93 1.6 69% 2.1 5.1 88.30% 86.10% 62.10% 89% 47.58% 50.43% 49.39% 0.00%
117 EU 56 73 1% 69.90% 2036 2.33 0.9 64% 3.2 8.5 90.80% 94.00% 72.60% 95% 52.47% 49.24% 49.05% 0.10%
118 EU 57 26 0% 96.20% 949 3.08 2 50% 3.2 26.7 83.20% 87.10% 88.50% 97% 46.64% 49.42% 48.36% 0.00%
119 EU 58 20 0% 65.00% 344 0.45 0.9 45% 0.7 1.3 75.50% 73.80% 65.00% 83% 45.36% 49.30% 49.03% 0.00%
120 EU 59 149 2% 34.90% 1105 0.8 1.1 60% 0.9 1.1 82.80% 85.80% 28.90% 78% 45.21% 50.08% 51.28% 0.00%
121 EU 60 22 0% 63.60% 1108 0.91 1 91% 1.3 1.4 78.70% 85.00% 36.40% 81% 54.54% 49.66% 49.03% 0.00%
122 EU 61 36 1% 94.40% 2794 3.81 2.5 83% 6.2 45.7 85.30% 92.10% 91.70% 100% 63.28% 50.37% 50.28% 0.00%
123 EU 62 32 0% 31.20% 1786 1.19 0.9 75% 1.8 2 90.60% 91.90% 40.60% 88% 61.60% 49.13% 50.35% 0.00%
124 EU 63 21 0% 85.70% 2476 3.33 2 76% 4.8 35 91.50% 95.70% 90.50% 99% 53.93% 50.29% 49.74% 0.00%
125 NA 64 23 0% 91.30% 2371 3.57 0.9 70% 4.8 20.5 86.10% 92.50% 82.60% 99% 58.19% 49.00% 50.44% 0.30%
126 NA 65 25 0% 96.00% 4281 2.56 1.8 72% 4.1 64 90.20% 91.40% 96.00% 100% 62.10% 51.41% 50.28% 0.00%
127 NA 66 238 3% 76.10% 2183 1.56 1.5 50% 2.8 5.7 79.70% 89.90% 72.70% 92% 68.48% 50.75% 50.57% 0.00%
128 NA 67 56 1% 73.20% 2022 1.88 1.3 68% 2.5 6.6 85.20% 90.40% 71.40% 93% 55.31% 49.88% 49.73% 0.10%
129 NA 68 25 0% 92.00% 6141 3.36 1.2 100% 3.5 28 92.20% 93.80% 88.00% 99% 62.64% 49.81% 50.96% 0.00%
130 NA 69 44 1% 77.30% 4178 1.93 1.5 77% 3 12.1 92.10% 91.60% 84.10% 98% 53.67% 50.20% 50.23% 0.00%
131 NA 70 26 0% 96.20% 3412 3.46 1.8 69% 3.6 90 92.20% 93.90% 96.20% 100% 65.85% 48.95% 49.25% 0.00%
132 NA 71 58 1% 77.60% 1642 1.93 0.9 60% 2.2 5.6 86.00% 94.60% 65.50% 87% 46.03% 49.73% 50.08% 0.00%
133 NA 72 197 3% 78.20% 2416 2.37 1.2 64% 3.3 10.8 86.30% 92.80% 78.20% 97% 56.68% 49.22% 49.50% 0.00%
134 NA 73 23 0% 60.90% 3932 1.91 2 87% 3 4.9 89.50% 90.70% 60.90% 89% 60.65% 48.75% 50.51% 0.00%
135 NA 74 42 1% 78.60% 1431 2.45 0.7 36% 2.2 6.9 84.50% 89.30% 64.30% 90% 50.81% 49.26% 49.33% 0.00%
136 NA 75 21 0% 81.00% 3748 3.29 1.3 57% 4 17.2 91.90% 92.50% 81.00% 100% 61.77% 48.23% 48.98% 0.00%
137 NA 76 34 0% 88.20% 2707 2.59 1.4 68% 3 44 84.50% 90.50% 94.10% 96% 55.79% 50.34% 49.42% 0.00%
138 NA 77 115 2% 74.80% 2171 2.19 1.4 74% 2.9 8.4 89.00% 91.40% 73.90% 95% 59.53% 49.65% 49.88% 0.00%
139 NA 78 23 0% 65.20% 1958 1.96 0.5 61% 2.3 5.6 89.80% 93.30% 65.20% 92% 62.10% 50.31% 49.85% 0.00%
140 NA 79 218 3% 74.30% 1860 2.16 1.5 65% 2.6 7.2 85.90% 91.60% 70.20% 95% 53.76% 50.11% 49.84% 0.00%
141 NA 80 35 1% 57.10% 3142 1.71 1.9 80% 2.3 3.2 90.00% 93.10% 45.70% 86% 56.23% 50.16% 51.49% 0.00%
142 NA 81 32 0% 90.60% 3407 2.62 1.2 62% 3.6 16.8 85.80% 91.90% 84.40% 97% 54.91% 49.20% 49.43% 0.00%
143 NA 82 20 0% 90.00% 4472 3.4 2.2 75% 4.1 34 86.20% 83.10% 90.00% 100% 50.16% 50.67% 50.02% 0.00%
144 NA 83 51 1% 72.50% 1023 2.08 1.1 76% 2.2 5.6 88.30% 93.20% 62.70% 91% 73.85% 56.05% 50.69% 23.20%
145 NA 84 47 1% 80.90% 3820 2.45 1.4 85% 3.7 12.8 93.20% 94.90% 80.90% 98% 61.01% 50.73% 50.39% 0.00%
146 NA 85 71 1% 91.50% 3159 2.73 0.9 65% 3.9 27.7 89.40% 92.40% 90.10% 99% 55.39% 49.64% 50.01% 0.00%
147 NA 86 28 0% 85.70% 4249 2.46 1.3 79% 3.1 23 91.90% 93.70% 89.30% 95% 61.07% 50.13% 50.15% 0.00%
148 NA 87 24 0% 75.00% 3048 2.17 1.9 75% 2.7 10.4 85.40% 90.00% 79.20% 98% 55.74% 49.79% 50.05% 0.00%
149 NA 88 34 0% 67.60% 3317 2.21 2.1 65% 3.6 6.8 90.50% 91.30% 67.60% 96% 61.83% 49.97% 49.88% 0.00%
150 NA 89 23 0% 30.40% 1399 0.52 1.3 91% 0.9 0.8 87.30% 85.40% 30.40% 71% 49.58% 50.38% 51.69% 0.00%
151 NA 90 20 0% 75.00% 1305 0.6 1.4 60% 1.1 1.7 88.10% 80.10% 65.00% 91% 48.23% 49.76% 49.40% 0.00%
152 NA 91 24 0% 79.20% 2554 2.96 1.2 50% 5.6 17.8 93.30% 95.50% 83.30% 98% 58.79% 50.82% 51.10% 0.00%
153 NA 92 48 1% 56.20% 1707 0.69 0.7 92% 0.8 1.4 81.30% 86.80% 52.10% 87% 55.85% 53.43% 53.97% 0.00%
154 NA 93 130 2% 62.30% 1912 1.31 1.3 70% 1.3 2.9 89.00% 91.70% 55.40% 86% 59.63% 49.95% 50.11% 0.00%
155 NA 94 35 1% 77.10% 3875 2.74 1.8 57% 3.6 12 89.60% 94.40% 77.10% 95% 59.73% 49.60% 50.04% 0.00%
156 NA 95 23 0% 73.90% 2688 3.17 1 74% 3.4 14.6 92.50% 93.20% 78.30% 96% 51.21% 49.86% 50.33% 0.00%
157 NA 96 26 0% 61.50% 1796 1.19 1.2 31% 1.6 2.8 75.60% 84.20% 57.70% 91% 54.00% 50.02% 50.03% 0.00%
158 NA 97 21 0% 90.50% 1869 2.52 2.3 76% 3.2 17.7 85.40% 89.60% 85.70% 96% 56.43% 49.38% 49.01% 0.00%
159 NA 98 101 1% 71.30% 1499 2 0.7 58% 2.7 5.3 83.30% 91.50% 62.40% 93% 52.60% 49.80% 49.63% 0.10%
160 NA 99 20 0% 60.00% 1368 1 0.9 45% 1.4 2.9 83.50% 87.90% 65.00% 84% 54.73% 50.49% 50.26% 0.00%
161 NA 100 24 0% 79.20% 1998 2.54 1.6 75% 3.4 20.3 85.30% 83.70% 87.50% 98% 53.43% 50.95% 50.42% 0.30%
162 NA 101 26 0% 42.30% 1170 0.77 1.7 73% 1.3 1.2 75.50% 86.50% 34.60% 81% 46.59% 49.31% 50.13% 0.00%
163 NA 102 26 0% 53.80% 1013 0.85 0.8 62% 1.1 1.2 74.20% 82.40% 26.90% 83% 52.75% 49.08% 49.42% 0.00%
164 NA 103 23 0% 91.30% 3980 3 1.4 83% 3.1 34.5 86.00% 90.80% 91.30% 97% 63.72% 49.86% 49.82% 0.00%
165 NA 104 57 1% 71.90% 1694 1.49 0.6 74% 2.8 4.7 82.80% 86.80% 68.40% 92% 46.26% 49.48% 48.84% 0.00%
166 ASIA 105 330 5% 82.40% 2195 2.01 1.7 63% 2.7 7.5 89.80% 92.70% 73.00% 94% 57.98% 49.95% 49.71% 0.00%
167 ASIA 106 132 2% 77.30% 1268 1.31 0.8 58% 2.2 3.5 82.20% 92.40% 62.10% 85% 62.78% 49.79% 50.26% 0.00%
168 ASIA 107 21 0% 90.50% 3749 3.67 1.8 81% 4.1 38.5 90.70% 93.70% 90.50% 97% 53.77% 49.37% 50.06% 0.00%
169 ASIA 108 35 1% 85.70% 4501 2.6 1.6 74% 4 15.2 89.10% 91.20% 82.90% 99% 54.47% 49.39% 49.24% 0.00%
170 ASIA 109 67 1% 73.10% 1278 1.7 1.5 54% 2.8 5.7 83.80% 88.00% 70.10% 93% 55.23% 51.01% 50.11% 0.10%
171 ASIA 110 70 1% 91.40% 1525 1.54 1.1 54% 3.5 54 78.50% 86.10% 97.10% 99% 49.45% 49.53% 48.75% 0.00%
172 ASIA 111 49 1% 67.30% 2050 1.96 0.7 73% 2.7 5.3 85.70% 91.40% 63.30% 93% 52.58% 49.79% 49.79% 0.00%
+2601 -2339
View File
File diff suppressed because it is too large. Load diff