mirror of
https://github.com/Jylpah/blitz-tools.git
synced 2026-10-24 19:49:52 +02:00
Compare commits
122
Commits
dev
..
55a1eb65c5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55a1eb65c5 | ||
|
|
4ca2ad5b69 | ||
|
|
becc608f0c | ||
|
|
97e9cf5a54 | ||
|
|
f5e67798b4 | ||
|
|
2eced2eda0 | ||
|
|
025a786bdd | ||
|
|
bca474218e | ||
|
|
e48759ce79 | ||
|
|
5c694fd721 | ||
|
|
1f41901042 | ||
|
|
d275914b32 | ||
|
|
9f8c82f434 | ||
|
|
3a8f065f35 | ||
|
|
0cac200f06 | ||
|
|
342b90bcf9 | ||
|
|
a9845b6fbb | ||
|
|
ee36e9192f | ||
|
|
5d5821564e | ||
|
|
3c6f9dcae3 | ||
|
|
433e2295c2 | ||
|
|
3dc9533c6a | ||
|
|
83456ae150 | ||
|
|
0c25c781a9 | ||
|
|
244ae314d8 | ||
|
|
33b0efb48d | ||
|
|
574fb95f00 | ||
|
|
fdc5db966e | ||
|
|
65e4fd83d8 | ||
|
|
e9451c7f5d | ||
|
|
fa65872ad2 | ||
|
|
b2f37ebcf5 | ||
|
|
d323f11662 | ||
|
|
d847a394a9 | ||
|
|
8514e9db17 | ||
|
|
521986adf1 | ||
|
|
7e39fdc442 | ||
|
|
14ee570ee5 | ||
|
|
e0228a4bf1 | ||
|
|
2a93cfbce3 | ||
|
|
78a959224c | ||
|
|
ae24ab35f7 | ||
|
|
ba6b4781e5 | ||
|
|
050bd99488 | ||
|
|
eb39c9ce84 | ||
|
|
24547763e9 | ||
|
|
28347e1653 | ||
|
|
ffe5afbf1e | ||
|
|
17ac09afde | ||
|
|
9117963085 | ||
|
|
dc8f9a233d | ||
|
|
ce3f9993c5 | ||
|
|
fd7eb8261d | ||
|
|
748ed7806b | ||
|
|
1ada279728 | ||
|
|
57cbc5b233 | ||
|
|
43842dc140 | ||
|
|
170a801652 | ||
|
|
210e943157 | ||
|
|
b3b7b81eb4 | ||
|
|
446e289041 | ||
|
|
f8a0fdfbe1 | ||
|
|
4c0de49077 | ||
|
|
07aa7af32f | ||
|
|
ea3306ee6c | ||
|
|
e4882d70af | ||
|
|
433c26d2f8 | ||
|
|
f6b1b1353f | ||
|
|
36fb53f0e7 | ||
|
|
b19a2169a7 | ||
|
|
67aeaddf36 | ||
|
|
763f205175 | ||
|
|
d97c0cabd8 | ||
|
|
e6ff2f438d | ||
|
|
f4f153a175 | ||
|
|
829e03f644 | ||
|
|
53b2f62817 | ||
|
|
804a4a6483 | ||
|
|
47a1f96c4e | ||
|
|
7a1272c4eb | ||
|
|
9601177ff6 | ||
|
|
ff4396a3b1 | ||
|
|
1aaa197fac | ||
|
|
abf15c2b35 | ||
|
|
c8e219ab45 | ||
|
|
c640747a0a | ||
|
|
daf0db7382 | ||
|
|
7d46ce46a0 | ||
|
|
44d1d6deb9 | ||
|
|
64a520a845 | ||
|
|
f4f0afec08 | ||
|
|
9e05683f98 | ||
|
|
4ea29439b0 | ||
|
|
40c313d408 | ||
|
|
3364834f3e | ||
|
|
175150b901 | ||
|
|
c18a23258c | ||
|
|
257ba190c2 | ||
|
|
970c24072d | ||
|
|
111c1801e6 | ||
|
|
9f91ef85b6 | ||
|
|
d5cd5f5b12 | ||
|
|
2e1aeea9b8 | ||
|
|
be0e43ad1c | ||
|
|
19bc93405b | ||
|
|
e567be2b93 | ||
|
|
ef657ca6cb | ||
|
|
1f293872e2 | ||
|
|
3e27bd995e | ||
|
|
c9745fcf5c | ||
|
|
18609cd361 | ||
|
|
4196e0f395 | ||
|
|
f1799ff346 | ||
|
|
383e4c1dac | ||
|
|
058d3ad88a | ||
|
|
5c19f4f5a6 | ||
|
|
31d9a32de2 | ||
|
|
8adc0aa561 | ||
|
|
90f2844749 | ||
|
|
fda015abdb | ||
|
|
99f9d5ee7d | ||
|
|
2a8b123a83 |
No files matched your search
Executable
+15
@@ -0,0 +1,15 @@
|
|||||||
|
__pycache__/
|
||||||
|
BlitzApp
|
||||||
|
tmp/
|
||||||
|
ssl/
|
||||||
|
*.ini
|
||||||
|
*.swp
|
||||||
|
*.code-workspace
|
||||||
|
*.sqlite3
|
||||||
|
.vscode/
|
||||||
|
*.sqlite3-journal
|
||||||
|
.gitattributes
|
||||||
|
export*
|
||||||
|
*.csv
|
||||||
|
!/stats/*.csv
|
||||||
|
!*.py
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# blitz-tools
|
# blitz-tools
|
||||||
Python scripts to analyze WoT Blitz replays and stats. All the scripts require [Python 3.7](https://www.python.org/downloads/) or higher. I am using 3.8 myself so you may have to change the Python interpreter version in the scripts' first line.
|
Python scripts to analyze WoT Blitz replays and stats. All the scripts require [Python 3.7](https://www.python.org/downloads/) or later.
|
||||||
|
|
||||||
### Replays
|
### Replays
|
||||||
* [upload_wotb_replays.py](upload_wotb_replays.py): An asynchronous replay uploader.
|
* [upload_wotb_replays.py](upload_wotb_replays.py): An asynchronous replay uploader.
|
||||||
@@ -13,46 +13,48 @@ Python scripts to analyze WoT Blitz replays and stats. All the scripts require [
|
|||||||
* [blitzutils.py](blitzutils.py): A utils class for various Blitz related to functions. *Other scripts use this*, so you need to place it to the same folder with the other scripts
|
* [blitzutils.py](blitzutils.py): A utils class for various Blitz related to functions. *Other scripts use this*, so you need to place it to the same folder with the other scripts
|
||||||
|
|
||||||
### Data
|
### Data
|
||||||
* [tanks.json](tanks.json): Tankopedia in WG JSON format extracted from the Blitz app files with [extract_tankopedia.py]](extractTankopedia.py]). Contains only limited information required by the scripts.
|
* [tanks.json](tanks.json): Tankopedia in WG JSON format extracted from the Blitz app files with [extract_tankopedia.py](extractTankopedia.py). Contains only limited information required by the scripts.
|
||||||
* [maps.json](maps.json): Blitz map names extracted from the Blitz app files with [extract_tankopedia.py]](extract_tankopedia.py]).
|
* [maps.json](maps.json): Blitz map names extracted from the Blitz app files with [extract_tankopedia.py](extract_tankopedia.py).
|
||||||
|
|
||||||
### Quick instructions
|
### Quick instructions
|
||||||
|
|
||||||
1. Install [Python 3.8](https://www.python.org/downloads/) on to your computer/laptop
|
1. Install [Python 3.8](https://www.python.org/downloads/) or later to your computer/laptop
|
||||||
2. Install the required Python modules: motor, aiohttp, aioconsole, aiofiles, aiosqlite, beautifulsoup4, lxml, xmltodict, progress
|
2. Install the required Python modules (see [requirements.txt](requirements.txt): motor, aiohttp, aioconsole, aiofiles, aiosqlite, beautifulsoup4, lxml, xmltodict, progress
|
||||||
```
|
```
|
||||||
# Remember to run the command with a Python interpreter >= 3.7
|
python -m pip install -r requirements.txt
|
||||||
python -m pip install motor aiohttp aioconsole aiofiles aiosqlite beautifulsoup4 lxml xmltodict progress
|
|
||||||
```
|
```
|
||||||
3. Download all the files including the [maps.json](maps.json) and [tanks.json](tanks.json) files. **The recommened way** is to install the scipts via `git clone`: [GitHub Desktop](https://desktop.github.com/) is an excellent GUI for git. This makes it easy to receive the updates via `git pull`.
|
3. Clone the repository. [GitHub Desktop](https://desktop.github.com/) is an excellent GUI for `git`. This makes it easy to receive the updates via `git pull`.
|
||||||
|
|
||||||
4. Upload your replays.
|
|
||||||
```
|
```
|
||||||
# Windows, run directly from Command Prompt or Powershell
|
git clone https://github.com/Jylpah/blitz-tools.git
|
||||||
# Check the options
|
```
|
||||||
|
4. Upload your replays with `upload_wotb_replays.py`
|
||||||
|
```
|
||||||
|
## Check the options
|
||||||
|
# Windows Command Prompt or Powershell
|
||||||
python.exe .\upload_wotb_replays.py --help
|
python.exe .\upload_wotb_replays.py --help
|
||||||
|
|
||||||
# Syntax
|
# Linux or Windows Subsystem for Linux (WSL)
|
||||||
python.exe .\upload_wotb_replays.py REPLAY_FILE.wotbreplay
|
./upload_wotb_replays.py --help
|
||||||
|
|
||||||
|
# Upload replays (Windows)
|
||||||
|
python.exe .\upload_wotb_replays.py REPLAY_FILE.wotbreplay DIR_WITH_REPLAYS
|
||||||
|
|
||||||
# example
|
# example
|
||||||
python.exe .\upload_wotb_replays.py 20200223_0122__jylpah_T-54_grossberg.wotbreplay
|
python.exe .\upload_wotb_replays.py 20200223_0122__jylpah_T-54_grossberg.wotbreplay
|
||||||
|
|
||||||
# Linux
|
|
||||||
./upload_wotb_replays.py --help
|
|
||||||
```
|
```
|
||||||
5. Analyze replays.
|
5. Analyze replays with `analyze_wotb_replays.py`
|
||||||
```
|
```
|
||||||
# Windows, run directly from Command Prompt or Powershell
|
## Check options
|
||||||
|
# Windows Command Prompt or Powershell
|
||||||
python.exe .\analyze_wotb_replays.py --help
|
python.exe .\analyze_wotb_replays.py --help
|
||||||
|
|
||||||
# Syntax
|
# Syntax (Windows)
|
||||||
python.exe .\analyze_wotb_replays.py REPLAY_FILE.wotbreplay.json
|
python.exe .\analyze_wotb_replays.py REPLAY_FILE.wotbreplay.json [DIR_WITH_REPLAYS ...]
|
||||||
|
|
||||||
# Example
|
# Example (Windows)
|
||||||
python.exe .\analyze_wotb_replays.py 20200223_0122__jylpah_T-54_grossberg.wotbreplay.json
|
python.exe .\analyze_wotb_replays.py 20200223_0122__jylpah_T-54_grossberg.wotbreplay.json
|
||||||
|
|
||||||
# Linux
|
# Linux or Windows Subsystem for Linux (WSL)
|
||||||
./analyze_wotb_replays.py --help
|
./analyze_wotb_replays.py --help
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
+811
-301
File diff suppressed because it is too large.
Load diff
+347
-201
File diff suppressed because it is too large.
Load diff
+49
-20
@@ -1,7 +1,9 @@
|
|||||||
#!/usr/bin/env python3.8
|
#!/usr/bin/env python3
|
||||||
|
## PYTHON VERSION MUST BE 3.7 OR HIGHER
|
||||||
|
|
||||||
# Extract tankopedia data in WG API JSON format from Blitz app files (Android APK unzipped)
|
# Extract tankopedia data in WG API JSON format from Blitz app files (Android APK unzipped)
|
||||||
|
|
||||||
|
from os import path
|
||||||
import sys, argparse, json, os, inspect, aiohttp, asyncio, aiofiles, re, logging, time, xmltodict, collections, configparser
|
import sys, argparse, json, os, inspect, aiohttp, asyncio, aiofiles, re, logging, time, xmltodict, collections, configparser
|
||||||
import blitzutils as bu
|
import blitzutils as bu
|
||||||
from blitzutils import WG
|
from blitzutils import WG
|
||||||
@@ -10,9 +12,11 @@ logging.getLogger("asyncio").setLevel(logging.DEBUG)
|
|||||||
|
|
||||||
FILE_CONFIG = 'blitzstats.ini'
|
FILE_CONFIG = 'blitzstats.ini'
|
||||||
|
|
||||||
BLITZAPP_STRINGS='/assets/Data/Strings/en.yaml'
|
# BLITZAPP_STRINGS='/assets/Data/Strings/en.yaml'
|
||||||
BLITZAPP_VEHICLES_DIR='/assets/Data/XML/item_defs/vehicles/'
|
# BLITZAPP_VEHICLES_DIR='/assets/Data/XML/item_defs/vehicles/'
|
||||||
BLITZAPP_VEHICLE_FILE='/list.xml'
|
BLITZAPP_STRINGS='Data/Strings/en.yaml'
|
||||||
|
BLITZAPP_VEHICLES_DIR='Data/XML/item_defs/vehicles/'
|
||||||
|
BLITZAPP_VEHICLE_FILE='list.xml'
|
||||||
|
|
||||||
wg = None
|
wg = None
|
||||||
|
|
||||||
@@ -78,9 +82,10 @@ async def main(argv):
|
|||||||
tankopedia = collections.OrderedDict()
|
tankopedia = collections.OrderedDict()
|
||||||
tankopedia['status'] = 'ok'
|
tankopedia['status'] = 'ok'
|
||||||
tankopedia['meta'] = { "count": len(tanks) }
|
tankopedia['meta'] = { "count": len(tanks) }
|
||||||
tankopedia['data'] = tanks
|
tankopedia['data'] = bu.sort_dict(tanks, number=True)
|
||||||
tankopedia['userStr'] = userStrs
|
tankopedia['userStr'] = bu.sort_dict(userStrs)
|
||||||
bu.verbose_std('New tankopedia \'' + args.tanks + '\' contains ' + str(len(tanks)) + ' tanks')
|
bu.verbose_std('New tankopedia \'' + args.tanks + '\' contains ' + str(len(tanks)) + ' tanks')
|
||||||
|
bu.verbose_std('New tankopedia \'' + args.tanks + '\' contains ' + str(len(userStrs)) + ' tank strings')
|
||||||
await outfile.write(json.dumps(tankopedia, ensure_ascii=False, indent=4, sort_keys=False))
|
await outfile.write(json.dumps(tankopedia, ensure_ascii=False, indent=4, sort_keys=False))
|
||||||
|
|
||||||
if args.maps != None:
|
if args.maps != None:
|
||||||
@@ -102,8 +107,11 @@ async def main(argv):
|
|||||||
async def extract_tanks(blitz_app_base : str, nation: str):
|
async def extract_tanks(blitz_app_base : str, nation: str):
|
||||||
|
|
||||||
tanks = []
|
tanks = []
|
||||||
list_xml_file = blitz_app_base + BLITZAPP_VEHICLES_DIR + nation + BLITZAPP_VEHICLE_FILE
|
# WG has changed the location of Data directory - at least in steam client
|
||||||
if not os.path.isfile(list_xml_file):
|
if path.isdir(path.join(blitz_app_base, 'assets')):
|
||||||
|
blitz_app_base = path.join(blitz_app_base, 'assets')
|
||||||
|
list_xml_file = path.join(blitz_app_base, BLITZAPP_VEHICLES_DIR ,nation ,BLITZAPP_VEHICLE_FILE)
|
||||||
|
if not path.isfile(list_xml_file):
|
||||||
print('ERROR: cannot open ' + list_xml_file)
|
print('ERROR: cannot open ' + list_xml_file)
|
||||||
return None
|
return None
|
||||||
bu.debug('Opening file: ' + list_xml_file + ' (Nation: ' + nation + ')')
|
bu.debug('Opening file: ' + list_xml_file + ' (Nation: ' + nation + ')')
|
||||||
@@ -112,14 +120,14 @@ async def extract_tanks(blitz_app_base : str, nation: str):
|
|||||||
tankList = xmltodict.parse(await f.read())
|
tankList = xmltodict.parse(await f.read())
|
||||||
for data in tankList['root'].keys():
|
for data in tankList['root'].keys():
|
||||||
tank_xml = tankList['root'][data]
|
tank_xml = tankList['root'][data]
|
||||||
tank = {}
|
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['is_premium'] = issubclass(type(tank_xml['price']), dict)
|
||||||
tank['type'] = await get_tank_type(tank_xml['tags'])
|
tank['nation'] = nation
|
||||||
|
tank['tank_id'] = get_tank_id(nation, int(tank_xml['id']))
|
||||||
|
tank['tier'] = int(tank_xml['level'])
|
||||||
|
tank['type'] = get_tank_type(tank_xml['tags'])
|
||||||
|
tank['userStr'] = tank_xml['userString']
|
||||||
|
#bu.debug('Reading tank string: ' + tank['userStr'], force=True)
|
||||||
tanks.append(tank)
|
tanks.append(tank)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
bu.error(err)
|
bu.error(err)
|
||||||
@@ -130,7 +138,7 @@ async def read_user_strs(blitz_app_base : str) -> dict:
|
|||||||
"""Read user strings to convert map and tank names"""
|
"""Read user strings to convert map and tank names"""
|
||||||
tank_strs = {}
|
tank_strs = {}
|
||||||
map_strs = {}
|
map_strs = {}
|
||||||
filename = blitz_app_base + BLITZAPP_STRINGS
|
filename = path.join(blitz_app_base, BLITZAPP_STRINGS)
|
||||||
bu.debug('Opening file: ' + filename + ' for reading UserStrings')
|
bu.debug('Opening file: ' + filename + ' for reading UserStrings')
|
||||||
try:
|
try:
|
||||||
async with aiofiles.open(filename, 'r', encoding="utf8") as f:
|
async with aiofiles.open(filename, 'r', encoding="utf8") as f:
|
||||||
@@ -160,9 +168,27 @@ async def convert_tank_names(tanklist : list, tank_strs: dict) -> dict:
|
|||||||
try:
|
try:
|
||||||
for tank in tanklist:
|
for tank in tanklist:
|
||||||
tank['name'] = tank_strs[tank['userStr']]
|
tank['name'] = tank_strs[tank['userStr']]
|
||||||
userStrs[tank['userStr'].split(':')[1]] = tank['name']
|
#userStrs[tank['userStr'].split(':')[1]] = tank['name']
|
||||||
tank.pop('userStr', None)
|
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
|
||||||
|
key = tank_str.split(':')[1]
|
||||||
|
bu.debug('Tank string: ' + key + ' = ' + tank_strs[tank_str])
|
||||||
|
re_strs = [r'^Chassis_', r'^Turret_', r'^_', r'_short$' ]
|
||||||
|
for re_str in re_strs:
|
||||||
|
p = re.compile(re_str)
|
||||||
|
if p.match(key):
|
||||||
|
skip = True
|
||||||
|
break
|
||||||
|
if skip:
|
||||||
|
continue
|
||||||
|
|
||||||
|
userStrs[key] = tank_strs[tank_str]
|
||||||
|
|
||||||
# sorting
|
# sorting
|
||||||
tankopedia_sorted = collections.OrderedDict()
|
tankopedia_sorted = collections.OrderedDict()
|
||||||
@@ -172,6 +198,7 @@ async def convert_tank_names(tanklist : list, tank_strs: dict) -> dict:
|
|||||||
userStrs_sorted = collections.OrderedDict()
|
userStrs_sorted = collections.OrderedDict()
|
||||||
for userStr in sorted(userStrs.keys()):
|
for userStr in sorted(userStrs.keys()):
|
||||||
userStrs_sorted[userStr] = userStrs[userStr]
|
userStrs_sorted[userStr] = userStrs[userStr]
|
||||||
|
# bu.debug('Tank strings: ' + str(len(userStrs_sorted)))
|
||||||
|
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
bu.error(err)
|
bu.error(err)
|
||||||
@@ -179,10 +206,12 @@ async def convert_tank_names(tanklist : list, tank_strs: dict) -> dict:
|
|||||||
|
|
||||||
return tankopedia_sorted, userStrs_sorted
|
return tankopedia_sorted, userStrs_sorted
|
||||||
|
|
||||||
async def get_tank_id(nation: str, tank_id : int) -> int:
|
|
||||||
|
def get_tank_id(nation: str, tank_id : int) -> int:
|
||||||
return (tank_id << 8) + (wg.NATION_ID[nation] << 4) + 1
|
return (tank_id << 8) + (wg.NATION_ID[nation] << 4) + 1
|
||||||
|
|
||||||
async def get_tank_type(tagstr : str):
|
|
||||||
|
def get_tank_type(tagstr : str):
|
||||||
tags = tagstr.split(' ')
|
tags = tagstr.split(' ')
|
||||||
for t_type in wg.TANK_TYPE:
|
for t_type in wg.TANK_TYPE:
|
||||||
if tags[0] == t_type:
|
if tags[0] == t_type:
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
#!/usr/local/bin/python3.7
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
# Get Tankpedia from WoTinspector.com
|
# Get Tankpedia from WoTinspector.com
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,9 @@
|
|||||||
"fort": "Fort Despair",
|
"fort": "Fort Despair",
|
||||||
"grossberg": "Dynasty's Pearl",
|
"grossberg": "Dynasty's Pearl",
|
||||||
"himmelsdorf": "Himmelsdorf",
|
"himmelsdorf": "Himmelsdorf",
|
||||||
|
"holland": "Molendijk",
|
||||||
"holmeisk": "Wasteland",
|
"holmeisk": "Wasteland",
|
||||||
|
"iceworld": "Everfrost",
|
||||||
"idle": "Yukon",
|
"idle": "Yukon",
|
||||||
"italy": "Vineyards",
|
"italy": "Vineyards",
|
||||||
"karelia": "Rockfield",
|
"karelia": "Rockfield",
|
||||||
@@ -42,11 +44,15 @@
|
|||||||
"neptune_02": "Normandy - Beach",
|
"neptune_02": "Normandy - Beach",
|
||||||
"north": "North",
|
"north": "North",
|
||||||
"ordeal": "Trial by Fire",
|
"ordeal": "Trial by Fire",
|
||||||
|
"plant": "Ghost Factory",
|
||||||
"pliego": "Castilla",
|
"pliego": "Castilla",
|
||||||
"port": "Port Bay",
|
"port": "Port Bay",
|
||||||
"rift": "Hellas",
|
"rift": "Hellas",
|
||||||
"rock": "Mayan Ruins",
|
"rock": "Mayan Ruins",
|
||||||
"rudniki": "Mines",
|
"rudniki": "Mines",
|
||||||
|
"rudniki_01": "Mines - Hill",
|
||||||
|
"rudniki_02": "Mines - Village",
|
||||||
|
"rudniki_03": "Mines - Center",
|
||||||
"savanna": "Oasis Palms",
|
"savanna": "Oasis Palms",
|
||||||
"skit": "Naval Frontier",
|
"skit": "Naval Frontier",
|
||||||
"test": "World of Ducks",
|
"test": "World of Ducks",
|
||||||
|
|||||||
+101
-76
@@ -1,78 +1,103 @@
|
|||||||
# WoT Blitz releases
|
# WoT Blitz releases
|
||||||
|
|
||||||
| Release | Date | Notes | Inaccurate? |
|
| Release | Date | Content updates |
|
||||||
|:-------:|:--------:|-------------|-----|
|
|:-------:|:--------:|-------------|
|
||||||
| 7.4 | 2020-11-12 | TD buffs, Clan missions | |
|
| 9.8 | 2023-03-22 | F\*cked up The Quick Commands Wheel, camos |
|
||||||
| 7.3 | 2020-10-08 | Swedish HT line | |
|
| 9.7 | 2023-02-15 | Chinese light tanks |
|
||||||
| 7.2 | 2020-08-19 | Balance changes, added tier X ammo capa, new aiming reticles | |
|
| 9.6 | 2023-01-11 | Finally fixing game sounds for players with Genelec studio monitors, more gold camos |
|
||||||
| 7.1 | 2020-07-15 | New Yukon map, IS-6, KV-4, Patton 48 armor buff, Grille DPM buff, SP IC, AMZ 13 75, M41 Bulldog mobility buff | |
|
| 9.5 | 2022-12-14 | Camos and ?|
|
||||||
| 7.0 | 2020-06-17 | British LTs, graphics improvements, ATGM nerf, Sheridan nerf, map fixes | |
|
| 9.4 | 2022-11-09 | Italian TD line |
|
||||||
| 6.10 | 2020-04-29 | T92E1 nerf, Tier V-IX heavy HP buff, Battle Pass, map fixes | |
|
| 9.3 | 2022-10-04 | Nothing, except legandary camos and utterly incomprehensible shell icons |
|
||||||
| 6.9 | 2020-03-25 | Japanese TDs, Tier X heavy HP buff | |
|
| 9.2 | 2022-08-17 | New shot sounds and shell hit marks, vehicle restoration from the game client |
|
||||||
| 6.8 | 2020-02-19 | ATGM nerf, Hellas map | |
|
| 9.1 | 2022-07-14 | Releases updated via DLC, graphics updates for Object 140, Patton 46 |
|
||||||
| 6.7 | 2020-01-15 | ATGM US Lights | |
|
| 9.0 | 2022-06-08 | Japanies heavies, Castilla graphics update, new garage |
|
||||||
| 6.6 | 2019-12-18 | T-62A + Leo buffs | |
|
| 8.10 | 2022-04-28 | New battle results screen, new "Operation" mechanics |
|
||||||
| 6.5 | 2019-11-21 | New UI | |
|
| 8.9 | 2022-03-23 | "Free" camo resupply, VK 72.01 supplies |
|
||||||
| 6.4 | 2019-10-16 | Halloween map, mid-tier HT buff... | |
|
| 8.8 | 2022-02-16 | Molendijk map |
|
||||||
| 6.3 | 2019-09-18 | European line | |
|
| 8.7 | 2022-01-19 | Soviet Light Tanks |
|
||||||
| 6.2 | 2019-08-14 | New MM | |
|
| 8.6 | 2021-12-15 | Joining Light and Medium Tank classes in MM |
|
||||||
| 6.1 | 2019-07-10 | Autoloader buff | |
|
| 8.5 | 2021-11-17 | New national crew voices, economy update |
|
||||||
| 6.0 | 2019-06-05 | UK TD line #2 | |
|
| 8.4 | 2021-10-20 | Polish heavy tanks |
|
||||||
| 5.10 | 2019-04-24 | new missions | |
|
| 8.3 | 2021-09-16 | FV4005, FV4022, VK 91.01 (P) and WZ-121 legendary camos, -5 deg gun depression to WZ-120 |
|
||||||
| 5.9 | 2019-03-27 | New shell tracers, minor fixes | |
|
| 8.2 | 2021-08-18 | Ghost Factory map, XP/credits nerf for inactive players, new store UI |
|
||||||
| 5.8 | 2019-02-21 | Chinese TD line | |
|
| 8.1 | 2021-07-15 | Armor highlighting updated |
|
||||||
| 5.7 | 2019-01-16 | Avatars | |
|
| 8.0 | 2021-06-08 | American experimental heavies (Yoh-line), PBR camos |
|
||||||
| 5.6 | 2018-12-05 | Normandy map | |
|
| 7.9 | 2021-04-27 | Mines rework, new tutorial, colorblind mode, JgPz E100 legendary camo |
|
||||||
| 5.5 | 2018-11-13 | Low-tier clean-up | |
|
| 7.8 | 2021-03-24 | Mid-tier balance changes, Grille line new consumables |
|
||||||
| 5.4 | 2018-10-10 | MM "rigging" adjusted | |
|
| 7.7 | 2021-02-24 | Czechoslovakian medium tanks |
|
||||||
| 5.3 | 2018-09-12 | MM "rigging" started, Newbie queue added | |
|
| 7.6 | 2021-01-27 | AMC 13 90, TOG II buffs, free replay camera |
|
||||||
| 5.2 | 2018-08-22 | Faust map | |
|
| 7.5 | 2020-12-09 | ATGM removal, Batchat, Kpz70, T-2020 buff |
|
||||||
| 5.1 | 2018-07-31 | New MM: vehicle class matching | |
|
| 7.4 | 2020-11-12 | TD buffs, Clan missions |
|
||||||
| 5.0 | 2018-06-30 | Vineyeards map update, Spare Parts killed | |
|
| 7.3 | 2020-10-08 | Swedish HT line |
|
||||||
| 4.10 | 2018-05-24 | Alpenstadt map | |
|
| 7.2 | 2020-08-19 | Balance changes, added tier X ammo capa, new aiming reticles |
|
||||||
| 4.9 | 2018-04-25 | Chinese heavy tanks | |
|
| 7.1 | 2020-07-15 | New Yukon map, IS-6, KV-4, Patton 48 armor buff, Grille DPM buff, SP IC, AMZ 13 75, M41 Bulldog mobility buff |
|
||||||
| 4.8 | 2018-03-28 | Choice of battle modes, crew skills accelerator | |
|
| 7.0 | 2020-06-17 | British LTs, graphics improvements, ATGM nerf, Sheridan nerf, map fixes |
|
||||||
| 4.7 | 2018-02-28 | New minimap | |
|
| 6.10 | 2020-04-29 | T92E1 nerf, Tier V-IX heavy HP buff, Battle Pass, map fixes |
|
||||||
| 4.6 | 2018-01-31 | Chinese nation | |
|
| 6.9 | 2020-03-25 | Japanese TDs, Tier X heavy HP buff |
|
||||||
| 4.5 | 2017-12-19 | Dynasty's Pearl map | |
|
| 6.8 | 2020-02-19 | ATGM nerf, Hellas map |
|
||||||
| 4.4 | 2017-11-09 | New British tanks | |
|
| 6.7 | 2020-01-15 | ATGM US Lights |
|
||||||
| 4.3 | 2017-10-10 | Level 7 screw skills | |
|
| 6.6 | 2019-12-18 | T-62A + Leo buffs |
|
||||||
| 4.2 | 2017-09-12 | French LTs, Naval Frontier map | |
|
| 6.5 | 2019-11-21 | New UI |
|
||||||
| 4.1 | 2017-08-16 | New markers | |
|
| 6.4 | 2019-10-16 | Halloween map, mid-tier HT buff... |
|
||||||
| 4.0 | 2017-07-13 | Rating battles | Y |
|
| 6.3 | 2019-09-18 | European line |
|
||||||
| 3.10 | 2017-06-15 | Fixes | Y |
|
| 6.2 | 2019-08-14 | New MM |
|
||||||
| 3.9 | 2017-05-19 | Military Honor, Mayan Ruins | Y |
|
| 6.1 | 2019-07-10 | Autoloader buff |
|
||||||
| 3.8 | 2017-04-24 | Spare Parts, New 9-slot Equipment system | Y |
|
| 6.0 | 2019-06-05 | UK TD line #2 |
|
||||||
| 3.7 | 2017-03-22 | Balance changes, Tournaments | Y |
|
| 5.10 | 2019-04-24 | new missions |
|
||||||
| 3.6 | 2017-02-16 | Vehicle Enrichment | Y |
|
| 5.9 | 2019-03-27 | New shell tracers, minor fixes |
|
||||||
| 3.5 | 2017-01-13 | Boosters, Dead rail update | Y |
|
| 5.8 | 2019-02-21 | Chinese TD line |
|
||||||
| 3.4 | 2016-11-28 | Canyon map, USA T57 line | |
|
| 5.7 | 2019-01-16 | Avatars |
|
||||||
| 3.3 | 2016-11-01 | Updated Mines map | |
|
| 5.6 | 2018-12-05 | Normandy map |
|
||||||
| 3.2 | 2016-10-04 | Copperfield update | |
|
| 5.5 | 2018-11-13 | Low-tier clean-up :-( |
|
||||||
| 3.1 | 2016-09-03 | Clan tournaments, Yamato Harbor map | Y |
|
| 5.4 | 2018-10-10 | MM "rigging" adjusted |
|
||||||
| 3.0 | 2016-07-20 | Supremacy mode, Falls Creek update | Y |
|
| 5.3 | 2018-09-12 | MM "rigging" started, Newbie queue added |
|
||||||
| 2.11 | 2016-06-28 | Vineyeards map, Oasis Palms update, German paper TDs | |
|
| 5.2 | 2018-08-22 | Faust map |
|
||||||
| 2.10 | 2016-06-07 | Rockfield map update, Tank birthdays, high-pen gun for IS-6 | |
|
| 5.1 | 2018-07-31 | New MM: vehicle class matching |
|
||||||
| 2.9 | 2016-05-03 | Training rooms, +/-1 Matchmaker | Y |
|
| 5.0 | 2018-06-30 | Vineyeards map update, Spare Parts removed ! |
|
||||||
| 2.8 | 2016-04-04 | New Russian TD line, new consumables system | Y |
|
| 4.10 | 2018-05-24 | Replays, Alpenstadt map |
|
||||||
| 2.7 | 2016-03-07 | Mirage map | Y |
|
| 4.9 | 2018-04-25 | Chinese heavy tanks |
|
||||||
| 2.6 | 2016-02-10 | German LTs, shooting through obstacles | Y |
|
| 4.8 | 2018-03-28 | Choice of battle modes, crew skills accelerator |
|
||||||
| 2.5 | 2016-01-11 | Camouflages, Clan supply | Y |
|
| 4.7 | 2018-02-28 | New minimap |
|
||||||
| 2.4 | 2015-12-09 | Additional Japanese tanks, windows version | Y |
|
| 4.6 | 2018-01-31 | Chinese nation |
|
||||||
| 2.3 | 2015-11-12 | Canal map | Y |
|
| 4.5 | 2017-12-19 | Dynasty's Pearl map |
|
||||||
| 2.2 | 2015-10-05 | Desert Sands map update | Y |
|
| 4.4 | 2017-11-09 | New British tanks |
|
||||||
| 2.1 | 2015-09-07 | UK TDs, Clan Chat | Y |
|
| 4.3 | 2017-10-10 | Level 7 screw skills |
|
||||||
| 2.0 | 2015-08-05 | Clans, Oasis Palms updated | |
|
| 4.2 | 2017-09-12 | French LTs, Naval Frontier map |
|
||||||
| 1.11 | 2015-07-13 | KV-2, KV-13, Sherman Jumbo | Y |
|
| 4.1 | 2017-08-16 | New markers |
|
||||||
| 1.10 | 2015-06-11 | Port Bay map | Y |
|
| 4.0 | 2017-07-13 | Rating battles (date uncertain) |
|
||||||
| 1.9 | 2015-05-13 | New German medium tanks (Leo) | Y |
|
| 3.10 | 2017-06-15 | Fixes (date uncertain) |
|
||||||
| 1.8 | 2015-04-14 | Game tutorial, Bot map for new players | Y |
|
| 3.9 | 2017-05-19 | Military Honor, Mayan Ruins (date uncertain) |
|
||||||
| 1.7 | 2015-02-16 | US Turreted TDs | Y |
|
| 3.8 | 2017-04-24 | Spare Parts, New 9-slot Equipment system (date uncertain) |
|
||||||
| 1.6 | 2015-01-19 | Castilla map, UK HT line | Y |
|
| 3.7 | 2017-03-22 | Balance changes, Tournaments (date uncertain) |
|
||||||
| 1.5 | 2014-12-01 | UK Nation | Y |
|
| 3.6 | 2017-02-16 | Vehicle Enrichment (date uncertain) |
|
||||||
| 1.4 | 2014-10-29 | German HT line (Maus) | Y |
|
| 3.5 | 2017-01-13 | Boosters, Dead rail update (date uncertain) |
|
||||||
| 1.3 | 2014-10-02 | USSR IS-4 line, Lost Temple, Black Goldville maps | Y |
|
| 3.4 | 2016-11-28 | Canyon map, USA T57 line |
|
||||||
| 1.2 | 2014-08-20 | Oasis Palms map | Y |
|
| 3.3 | 2016-11-01 | Updated Mines map |
|
||||||
| 1.1.1 | 2014-07-23 | Fixes :-) | |
|
| 3.2 | 2016-10-04 | Copperfield update |
|
||||||
| 1.0 | 2014-06-26 | Worldwide launch | |
|
| 3.1 | 2016-09-03 | Clan tournaments, Yamato Harbor map (date uncertain) |
|
||||||
| 0.9 | 2014-05-05 | Nordic soft launch | |
|
| 3.0 | 2016-07-20 | Supremacy mode, Falls Creek update (date uncertain) |
|
||||||
|
| 2.11 | 2016-06-28 | Vineyeards map, Oasis Palms update, German paper TDs |
|
||||||
|
| 2.10 | 2016-06-07 | Rockfield map update, Tank birthdays, high-pen gun for IS-6 |
|
||||||
|
| 2.9 | 2016-05-03 | Training rooms, +/-1 Matchmaker (date uncertain) |
|
||||||
|
| 2.8 | 2016-04-04 | New Russian TD line, new consumables system (date uncertain) |
|
||||||
|
| 2.7 | 2016-03-07 | Mirage map (date uncertain) |
|
||||||
|
| 2.6 | 2016-02-10 | German LTs, shooting through obstacles (date uncertain) |
|
||||||
|
| 2.5 | 2016-01-11 | Camouflages, Clan supply (date uncertain) |
|
||||||
|
| 2.4 | 2015-12-09 | Additional Japanese tanks, windows version (date uncertain) |
|
||||||
|
| 2.3 | 2015-11-12 | Canal map (date uncertain) |
|
||||||
|
| 2.2 | 2015-10-05 | Desert Sands map update (date uncertain) |
|
||||||
|
| 2.1 | 2015-09-07 | UK TDs, Clan Chat (date uncertain) |
|
||||||
|
| 2.0 | 2015-08-05 | Clans, Oasis Palms updated |
|
||||||
|
| 1.11 | 2015-07-13 | KV-2, KV-13, Sherman Jumbo (date uncertain) |
|
||||||
|
| 1.10 | 2015-06-11 | Port Bay map (date uncertain) |
|
||||||
|
| 1.9 | 2015-05-13 | New German medium tanks (Leo) (date uncertain) |
|
||||||
|
| 1.8 | 2015-04-14 | Game tutorial, Bot map for new players (date uncertain) |
|
||||||
|
| 1.7 | 2015-02-16 | US Turreted TDs (date uncertain) |
|
||||||
|
| 1.6 | 2015-01-19 | Castilla map, UK HT line (date uncertain) |
|
||||||
|
| 1.5 | 2014-12-01 | UK Nation (date uncertain) |
|
||||||
|
| 1.4 | 2014-10-29 | German HT line (Maus) (date uncertain) |
|
||||||
|
| 1.3 | 2014-10-02 | USSR IS-4 line, Lost Temple, Black Goldville maps (date uncertain) |
|
||||||
|
| 1.2 | 2014-08-20 | Oasis Palms map (date uncertain) |
|
||||||
|
| 1.1.1 | 2014-07-23 | Fixes :-) |
|
||||||
|
| 1.0 | 2014-06-26 | Worldwide launch |
|
||||||
|
| 0.9 | 2014-05-05 | Nordic soft launch |
|
||||||
@@ -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%
|
||||||
|
+6277
-3445
File diff suppressed because it is too large.
Load diff
+34
-33
@@ -1,7 +1,8 @@
|
|||||||
#!/usr/bin/env python3.8
|
#!/usr/bin/env python3
|
||||||
|
## PYTHON VERSION MUST BE 3.7 OR HIGHER
|
||||||
|
|
||||||
import json, argparse, inspect, sys, os, io, base64, aiohttp, urllib, asyncio, aiofiles, aioconsole
|
import json, argparse, sys, os, io, asyncio, aiofiles, aioconsole
|
||||||
import logging, re, concurrent.futures, configparser, motor.motor_asyncio, ssl, zipfile
|
import logging, re, configparser, zipfile
|
||||||
import blitzutils as bu
|
import blitzutils as bu
|
||||||
from blitzutils import WG
|
from blitzutils import WG
|
||||||
from blitzutils import WoTinspector
|
from blitzutils import WoTinspector
|
||||||
@@ -20,17 +21,17 @@ SKIPPED_N = 0
|
|||||||
ERROR_N = 0
|
ERROR_N = 0
|
||||||
WIurl='https://wotinspector.com/api/replay/upload?'
|
WIurl='https://wotinspector.com/api/replay/upload?'
|
||||||
WG_appID = '81381d3f45fa4aa75b78a7198eb216ad'
|
WG_appID = '81381d3f45fa4aa75b78a7198eb216ad'
|
||||||
wg = None
|
wg : WG | None = None
|
||||||
wi = None
|
wi : WoTinspector | None = None
|
||||||
|
|
||||||
async def main(argv):
|
async def main(argv) -> int:
|
||||||
global wg, wi
|
global wg, wi
|
||||||
current_dir = os.getcwd()
|
current_dir = os.getcwd()
|
||||||
# set the directory for the script
|
# set the directory for the script
|
||||||
os.chdir(os.path.dirname(sys.argv[0]))
|
os.chdir(os.path.dirname(sys.argv[0]))
|
||||||
|
|
||||||
# options defaults
|
# options defaults
|
||||||
OPT_WORKERS_N = 5
|
OPT_WORKERS_N = 2
|
||||||
WG_ID = None
|
WG_ID = None
|
||||||
WG_ACCOUNT = None # format: nick@server, where server is either 'eu', 'ru', 'na', 'asia' or 'china'.
|
WG_ACCOUNT = None # format: nick@server, where server is either 'eu', 'ru', 'na', 'asia' or 'china'.
|
||||||
# China is not supported since WG API stats are not available there
|
# China is not supported since WG API stats are not available there
|
||||||
@@ -42,12 +43,6 @@ async def main(argv):
|
|||||||
bu.debug('Reading config file: ' + FILE_CONFIG)
|
bu.debug('Reading config file: ' + FILE_CONFIG)
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
config.read(FILE_CONFIG)
|
config.read(FILE_CONFIG)
|
||||||
try:
|
|
||||||
if 'UPLOADER' in config.sections():
|
|
||||||
configUploader = config['UPLOADER']
|
|
||||||
OPT_WORKERS_N = configUploader.getint('opt_workers', OPT_WORKERS_N)
|
|
||||||
except (KeyError, configparser.NoSectionError) as err:
|
|
||||||
bu.error(exception=err)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if 'WG' in config.sections():
|
if 'WG' in config.sections():
|
||||||
@@ -81,18 +76,19 @@ async def main(argv):
|
|||||||
bu.set_log_level(args.silent, args.verbose, args.debug)
|
bu.set_log_level(args.silent, args.verbose, args.debug)
|
||||||
|
|
||||||
wg = WG(WG_appID, args.tankopedia, args.mapfile)
|
wg = WG(WG_appID, args.tankopedia, args.mapfile)
|
||||||
wi = WoTinspector(rate_limit=WG_RATE_LIMIT)
|
wi = WoTinspector()
|
||||||
|
|
||||||
if args.account != None:
|
if args.account is not None:
|
||||||
args.accountID = await wg.get_account_id(args.account)
|
args.accountID = await wg.get_account_id(args.account)
|
||||||
bu.debug('WG account_id: ' + str(args.accountID))
|
bu.debug('WG account_id: ' + str(args.accountID))
|
||||||
|
|
||||||
if args.accountID == None:
|
if args.accountID is None:
|
||||||
args.accountID = 0
|
args.accountID = 0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
queue = asyncio.Queue()
|
queue : asyncio.Queue = asyncio.Queue()
|
||||||
# rebase file arguments due to moving the working directory to the script location
|
# rebase file arguments due to moving the working directory to the script location
|
||||||
|
bu.verbose_std("replays.wotinspector.com rate limits replays to 6 / minute")
|
||||||
args.files = bu.rebase_file_args(current_dir, args.files)
|
args.files = bu.rebase_file_args(current_dir, args.files)
|
||||||
|
|
||||||
tasks = []
|
tasks = []
|
||||||
@@ -122,7 +118,7 @@ async def main(argv):
|
|||||||
await wg.session.close()
|
await wg.session.close()
|
||||||
await wi.close()
|
await wi.close()
|
||||||
|
|
||||||
return None
|
return 0
|
||||||
|
|
||||||
|
|
||||||
async def mkReplayQ(queue : asyncio.Queue, files : list, title : str):
|
async def mkReplayQ(queue : asyncio.Queue, files : list, title : str):
|
||||||
@@ -136,13 +132,13 @@ async def mkReplayQ(queue : asyncio.Queue, files : list, title : str):
|
|||||||
if not line:
|
if not line:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
if (p_replayfile.match(line) != None):
|
if (p_replayfile.match(line) is not None):
|
||||||
await queue.put(await mkQueueItem(line, title))
|
await queue.put(await mkQueueItem(line, title))
|
||||||
else:
|
else:
|
||||||
for fn in files:
|
for fn in files:
|
||||||
if fn.endswith('"'):
|
if fn.endswith('"'):
|
||||||
fn = fn[:-1]
|
fn = fn[:-1]
|
||||||
if os.path.isfile(fn) and (p_replayfile.match(fn) != None):
|
if os.path.isfile(fn) and (p_replayfile.match(fn) is not None):
|
||||||
await queue.put(await mkQueueItem(fn, title))
|
await queue.put(await mkQueueItem(fn, title))
|
||||||
bu.debug('File added to queue: ' + fn)
|
bu.debug('File added to queue: ' + fn)
|
||||||
elif os.path.isdir(fn):
|
elif os.path.isdir(fn):
|
||||||
@@ -150,7 +146,7 @@ async def mkReplayQ(queue : asyncio.Queue, files : list, title : str):
|
|||||||
for entry in dirEntry:
|
for entry in dirEntry:
|
||||||
try:
|
try:
|
||||||
bu.debug('Found: ' + entry.name)
|
bu.debug('Found: ' + entry.name)
|
||||||
if entry.is_file() and (p_replayfile.match(entry.name) != None):
|
if entry.is_file() and (p_replayfile.match(entry.name) is not None):
|
||||||
bu.debug(entry.name)
|
bu.debug(entry.name)
|
||||||
await queue.put(await mkQueueItem(entry.path, title))
|
await queue.put(await mkQueueItem(entry.path, title))
|
||||||
bu.debug('File added to queue: ' + entry.path)
|
bu.debug('File added to queue: ' + entry.path)
|
||||||
@@ -174,6 +170,9 @@ async def replayWorker(queue: asyncio.Queue, workerID: int, account_id: int, pri
|
|||||||
"""Async Worker to process the replay queue"""
|
"""Async Worker to process the replay queue"""
|
||||||
global SKIPPED_N
|
global SKIPPED_N
|
||||||
global ERROR_N
|
global ERROR_N
|
||||||
|
global wi
|
||||||
|
|
||||||
|
assert wi is not None, "wi cannot be None"
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
item = await queue.get()
|
item = await queue.get()
|
||||||
@@ -194,7 +193,7 @@ async def replayWorker(queue: asyncio.Queue, workerID: int, account_id: int, pri
|
|||||||
bu.verbose_std(msg_str + title + ' has already been posted. Skipping.' )
|
bu.verbose_std(msg_str + title + ' has already been posted. Skipping.' )
|
||||||
else:
|
else:
|
||||||
os.remove(replay_json_fn)
|
os.remove(replay_json_fn)
|
||||||
bu.debug(msg_str + "Replay JSON not valid: Deleting " + replay_json_fn, id=workerID)
|
bu.debug(msg_str + "Replay JSON not valid/complete: Deleting " + replay_json_fn, id=workerID)
|
||||||
SKIPPED_N += 1
|
SKIPPED_N += 1
|
||||||
queue.task_done()
|
queue.task_done()
|
||||||
continue
|
continue
|
||||||
@@ -209,19 +208,19 @@ async def replayWorker(queue: asyncio.Queue, workerID: int, account_id: int, pri
|
|||||||
filename = os.path.basename(filename)
|
filename = os.path.basename(filename)
|
||||||
bu.debug(msg_str + 'File: ' + filename)
|
bu.debug(msg_str + 'File: ' + filename)
|
||||||
json_resp = await wi.post_replay(await fp.read(), filename, account_id, title, priv, N)
|
json_resp = await wi.post_replay(await fp.read(), filename, account_id, title, priv, N)
|
||||||
if json_resp != None:
|
if json_resp is not None:
|
||||||
if (await bu.save_JSON(replay_json_fn,json_resp)):
|
if (await bu.save_JSON(replay_json_fn,json_resp)):
|
||||||
if wi.chk_JSON_replay(json_resp):
|
if wi.chk_JSON_replay(json_resp):
|
||||||
if not bu.debug(msg_str + 'Replay saved OK: ' + filename):
|
if not bu.debug(msg_str + 'Replay saved OK: ' + filename):
|
||||||
bu.verbose_std(msg_str + title + ' posted')
|
bu.verbose_std(msg_str + title + ' posted')
|
||||||
else:
|
else:
|
||||||
bu.warning(msg_str +'Replay file is not valid: ' + filename)
|
bu.warning(msg_str +'Replay file is not valid/complete: ' + filename)
|
||||||
ERROR_N += 1
|
ERROR_N += 1
|
||||||
else:
|
else:
|
||||||
bu.error(msg_str + 'Error saving replay: ' + filename)
|
bu.error(msg_str + 'Error saving replay: ' + filename)
|
||||||
ERROR_N += 1
|
ERROR_N += 1
|
||||||
else:
|
else:
|
||||||
bu.error(msg_str + 'Replay file is not valid: ' + filename)
|
bu.error(msg_str + 'Replay file is not valid/complete: ' + filename)
|
||||||
ERROR_N += 1
|
ERROR_N += 1
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
bu.error(msg_str + 'Unexpected Exception: ' + str(type(err)) + ' : ' + str(err) )
|
bu.error(msg_str + 'Unexpected Exception: ' + str(type(err)) + ' : ' + str(err) )
|
||||||
@@ -234,7 +233,7 @@ async def replayWorker(queue: asyncio.Queue, workerID: int, account_id: int, pri
|
|||||||
def getTitle_old(replayfile: str, title: str, i : int) -> str:
|
def getTitle_old(replayfile: str, title: str, i : int) -> str:
|
||||||
global wg
|
global wg
|
||||||
|
|
||||||
if title == None:
|
if title is None:
|
||||||
try:
|
try:
|
||||||
filename = os.path.basename(replayfile)
|
filename = os.path.basename(replayfile)
|
||||||
bu.debug(filename)
|
bu.debug(filename)
|
||||||
@@ -246,8 +245,8 @@ def getTitle_old(replayfile: str, title: str, i : int) -> str:
|
|||||||
p = re.compile('\\d{8}_\\d{4}_.*?(' + '|'.join(tank_userStrs) + ')_(' + '|'.join(map_usrStrs) + ')(?:-\\d)?\\.wotbreplay$')
|
p = re.compile('\\d{8}_\\d{4}_.*?(' + '|'.join(tank_userStrs) + ')_(' + '|'.join(map_usrStrs) + ')(?:-\\d)?\\.wotbreplay$')
|
||||||
|
|
||||||
m = p.match(filename)
|
m = p.match(filename)
|
||||||
if (m != None):
|
if (m is not None):
|
||||||
if wg.tanks != None:
|
if wg.tanks is not None:
|
||||||
tank = m.group(1)
|
tank = m.group(1)
|
||||||
if tank in wg.tanks['userStr']:
|
if tank in wg.tanks['userStr']:
|
||||||
tank = wg.tanks['userStr'][tank]
|
tank = wg.tanks['userStr'][tank]
|
||||||
@@ -272,7 +271,9 @@ def getTitle_old(replayfile: str, title: str, i : int) -> str:
|
|||||||
|
|
||||||
def getTitle(replayfile: str, title: str = None, i : int = 0) -> str:
|
def getTitle(replayfile: str, title: str = None, i : int = 0) -> str:
|
||||||
global wg
|
global wg
|
||||||
if title == None:
|
assert wg is not None, "wg must not be None"
|
||||||
|
|
||||||
|
if title is None:
|
||||||
try:
|
try:
|
||||||
filename = os.path.basename(replayfile)
|
filename = os.path.basename(replayfile)
|
||||||
bu.debug(filename)
|
bu.debug(filename)
|
||||||
@@ -286,13 +287,13 @@ def getTitle(replayfile: str, title: str = None, i : int = 0) -> str:
|
|||||||
try:
|
try:
|
||||||
metadata_json = json.load(meta)
|
metadata_json = json.load(meta)
|
||||||
#player = metadata_json['playerName']
|
#player = metadata_json['playerName']
|
||||||
tank = wg.tank_str2name(metadata_json['playerVehicleName'])
|
tank_name = wg.get_tank_name(metadata_json['vehicleCompDescriptor'])
|
||||||
map_name = wg.get_map(metadata_json['mapName'])
|
map_name = wg.get_map(metadata_json['mapName'])
|
||||||
bu.debug('Tank: ' + tank + ' Map: ' + map_name)
|
bu.debug('Tank: ' + tank_name if tank_name is not None else "NOT FOUND IN tanks.json" + ' Map: ' + map_name)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
bu.error(exception = err)
|
bu.error(exception = err)
|
||||||
if (tank != None) and (map_name != None):
|
if (tank_name is not None) and (map_name is not None):
|
||||||
title = tank + ' @ ' + map_name
|
title = tank_name + ' @ ' + map_name
|
||||||
else:
|
else:
|
||||||
title = re.sub('\\.wotbreplay$', '', filename)
|
title = re.sub('\\.wotbreplay$', '', filename)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
|
|||||||
Reference in new issue
Block a user