Merge pull request #36 from Jylpah/master

Mix fixes
This commit is contained in:
Jylpah authored and GitHub committed 2023-09-10 17:48:11 +03:00
commit da8efce128
4 files changed
+2427 -1985

No files matched your search

+1
View File
@@ -13,3 +13,4 @@ export*
*.csv
!/stats/*.csv
!*.py
/.venv
+1809 -1803
View File
File diff suppressed because it is too large. Load diff
+190 -175
View File
@@ -4,7 +4,11 @@
# 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 aiofiles # type: ignore
import xmltodict # type: ignore
from asyncio import set_event_loop_policy, run, create_task, get_event_loop_policy
import sys, argparse, json, os, inspect, asyncio, re, logging, time, configparser
from collections import OrderedDict
import blitzutils as bu
from blitzutils import WG
@@ -18,216 +22,227 @@ BLITZAPP_STRINGS='Data/Strings/en.yaml'
BLITZAPP_VEHICLES_DIR='Data/XML/item_defs/vehicles/'
BLITZAPP_VEHICLE_FILE='list.xml'
wg = None
wg : WG | None = None
## main() -------------------------------------------------------------
async def main(argv):
global wg
# set the directory for the script
os.chdir(os.path.dirname(sys.argv[0]))
async def main() -> None:
global wg
# set the directory for the script
os.chdir(os.path.dirname(sys.argv[0]))
## Read config
BLITZAPP_FOLDER = '.'
try:
if os.path.isfile(FILE_CONFIG):
config = configparser.ConfigParser()
config.read(FILE_CONFIG)
## Read config
BLITZAPP_FOLDER = '.'
try:
if os.path.isfile(FILE_CONFIG):
config = configparser.ConfigParser()
config.read(FILE_CONFIG)
configOptions = config['EXTRACT_TANKOPEDIA']
BLITZAPP_FOLDER = configOptions.get('blitz_app_dir', BLITZAPP_FOLDER)
except:
pass
configOptions = config['EXTRACT_TANKOPEDIA']
BLITZAPP_FOLDER = configOptions.get('blitz_app_dir', BLITZAPP_FOLDER)
except:
pass
parser = argparse.ArgumentParser(description='Extract Tankopedia data from Blitz game files')
parser.add_argument('blitz_app_base', type=str, nargs='?', metavar="BLITZAPP_FOLDER", default=BLITZAPP_FOLDER, help='Base dir of the Blitz App files')
parser.add_argument('tanks', type=str, default='tanks.json', nargs='?', metavar="TANKS_FILE", help='File to write Tankopedia')
parser.add_argument('maps', type=str, default='maps.json', nargs='?', metavar='MAPS_FILE', help='File to write map names')
arggroup = parser.add_mutually_exclusive_group()
arggroup.add_argument('-d', '--debug', action='store_true', default=False, help='Debug mode')
arggroup.add_argument('-v', '--verbose', action='store_true', default=False, help='Verbose mode')
arggroup.add_argument('-s', '--silent', action='store_true', default=False, help='Silent mode')
parser = argparse.ArgumentParser(description='Extract Tankopedia data from Blitz game files')
parser.add_argument('blitz_app_base', type=str, nargs='?', metavar="BLITZAPP_FOLDER", default=BLITZAPP_FOLDER, help='Base dir of the Blitz App files')
parser.add_argument('tanks', type=str, default='tanks.json', nargs='?', metavar="TANKS_FILE", help='File to write Tankopedia')
parser.add_argument('maps', type=str, default='maps.json', nargs='?', metavar='MAPS_FILE', help='File to write map names')
arggroup = parser.add_mutually_exclusive_group()
arggroup.add_argument('-d', '--debug', action='store_true', default=False, help='Debug mode')
arggroup.add_argument('-v', '--verbose', action='store_true', default=False, help='Verbose mode')
arggroup.add_argument('-s', '--silent', action='store_true', default=False, help='Silent mode')
args = parser.parse_args()
bu.set_log_level(args.silent, args.verbose, args.debug)
args = parser.parse_args()
bu.set_log_level(args.silent, args.verbose, args.debug)
wg = WG()
wg = WG()
tasks = []
for nation in wg.NATION:
tasks.append(asyncio.create_task(extract_tanks(args.blitz_app_base, nation)))
tasks = []
for nation in wg.NATION:
tasks.append(asyncio.create_task(extract_tanks(args.blitz_app_base, nation)))
tanklist = []
for tanklist_tmp in await asyncio.gather(*tasks):
tanklist.extend(tanklist_tmp)
tanklist = []
for tanklist_tmp in await asyncio.gather(*tasks):
tanklist.extend(tanklist_tmp)
tank_strs, map_strs = await read_user_strs(args.blitz_app_base)
tank_strs, map_strs = await read_user_strs(args.blitz_app_base)
json_data = None
userStrs = {}
tanks = {}
if os.path.exists(args.tanks):
try:
async with aiofiles.open(args.tanks) as infile:
json_data = json.loads(await infile.read())
userStrs = json_data['userStr']
tanks = json_data['data']
except Exception as err:
bu.error('Unexpected error when reading file: ' + args.tanks + ' : ' + str(err))
json_data = None
userStrs = {}
tanks = {}
if os.path.exists(args.tanks):
try:
async with aiofiles.open(args.tanks) as infile:
json_data = json.loads(await infile.read())
userStrs = json_data['userStr']
tanks = json_data['data']
except Exception as err:
bu.error('Unexpected error when reading file: ' + args.tanks + ' : ' + str(err))
async with aiofiles.open(args.tanks, 'w', encoding="utf8") as outfile:
new_tanks, new_userStrs = await convert_tank_names(tanklist, tank_strs)
# merge old and new tankopedia
tanks.update(new_tanks)
userStrs.update(new_userStrs)
tankopedia = collections.OrderedDict()
tankopedia['status'] = 'ok'
tankopedia['meta'] = { "count": len(tanks) }
tankopedia['data'] = bu.sort_dict(tanks, number=True)
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(userStrs)) + ' tank strings')
await outfile.write(json.dumps(tankopedia, ensure_ascii=False, indent=4, sort_keys=False))
async with aiofiles.open(args.tanks, 'w', encoding="utf8") as outfile:
new_tanks, new_userStrs = await convert_tank_names(tanklist, tank_strs)
# merge old and new tankopedia
tanks.update(new_tanks)
userStrs.update(new_userStrs)
tankopedia : OrderedDict[str, str| int | dict ]= OrderedDict()
tankopedia['status'] = 'ok'
tankopedia['meta'] = { "count": len(tanks) }
tankopedia['data'] = bu.sort_dict(tanks, number=True)
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(userStrs)) + ' tank strings')
await outfile.write(json.dumps(tankopedia, ensure_ascii=False, indent=4, sort_keys=False))
if args.maps != None:
maps = {}
if os.path.exists(args.maps):
try:
async with aiofiles.open(args.maps) as infile:
maps = json.loads(await infile.read())
except Exception as err:
bu.error('Unexpected error when reading file: ' + args.maps + ' : ' + str(err))
# merge old and new map data
maps.update(map_strs)
async with aiofiles.open(args.maps, 'w', encoding="utf8") as outfile:
bu.verbose_std('New maps file \'' + args.maps + '\' contains ' + str(len(maps)) + ' maps')
await outfile.write(json.dumps(maps, ensure_ascii=False, indent=4, sort_keys=True))
if args.maps is not None:
maps = {}
if os.path.exists(args.maps):
try:
async with aiofiles.open(args.maps) as infile:
maps = json.loads(await infile.read())
except Exception as err:
bu.error('Unexpected error when reading file: ' + args.maps + ' : ' + str(err))
# merge old and new map data
maps.update(map_strs)
async with aiofiles.open(args.maps, 'w', encoding="utf8") as outfile:
bu.verbose_std('New maps file \'' + args.maps + '\' contains ' + str(len(maps)) + ' maps')
await outfile.write(json.dumps(maps, ensure_ascii=False, indent=4, sort_keys=True))
return None
return None
async def extract_tanks(blitz_app_base : str, nation: str):
tanks = []
# WG has changed the location of Data directory - at least in steam client
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)
return None
bu.debug('Opening file: ' + list_xml_file + ' (Nation: ' + nation + ')')
async with aiofiles.open(list_xml_file, 'r', encoding="utf8") as f:
try:
tankList = xmltodict.parse(await f.read())
for data in tankList['root'].keys():
tank_xml = tankList['root'][data]
tank = dict()
tank['is_premium'] = issubclass(type(tank_xml['price']), dict)
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)
except Exception as err:
bu.error(err)
sys.exit(2)
return tanks
tanks = []
# WG has changed the location of Data directory - at least in steam client
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)
return None
bu.debug('Opening file: ' + list_xml_file + ' (Nation: ' + nation + ')')
async with aiofiles.open(list_xml_file, 'r', encoding="utf8") as f:
try:
tankList = xmltodict.parse(await f.read())
for data in tankList['root'].keys():
tank_xml = tankList['root'][data]
tank : dict[str, bool | int | str]= dict()
tank['is_premium'] = issubclass(type(tank_xml['price']), dict)
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)
except Exception as err:
bu.error(err)
sys.exit(2)
return tanks
async def read_user_strs(blitz_app_base : str) -> dict:
"""Read user strings to convert map and tank names"""
tank_strs = {}
map_strs = {}
filename = path.join(blitz_app_base, BLITZAPP_STRINGS)
bu.debug('Opening file: ' + filename + ' for reading UserStrings')
try:
async with aiofiles.open(filename, 'r', encoding="utf8") as f:
p_tank = re.compile('^"(#\\w+?_vehicles:.+?)": "(.+)"$')
p_map = re.compile('^"#maps:(.+?):.+?: "(.+?)"$')
async def read_user_strs(blitz_app_base : str) -> tuple[dict, dict]:
"""Read user strings to convert map and tank names"""
tank_strs = {}
map_strs = {}
filename = path.join(blitz_app_base, BLITZAPP_STRINGS)
bu.debug('Opening file: ' + filename + ' for reading UserStrings')
try:
async with aiofiles.open(filename, 'r', encoding="utf8") as f:
p_tank = re.compile('^"(#\\w+?_vehicles:.+?)": "(.+)"$')
p_map = re.compile('^"#maps:(.+?):.+?: "(.+?)"$')
async for l in f:
m = p_tank.match(l)
if m != None:
tank_strs[m.group(1)] = m.group(2)
async for l in f:
m = p_tank.match(l)
if m is not None:
tank_strs[m.group(1)] = m.group(2)
m = p_map.match(l)
if m != None and m.group(2) != 'Macragge':
map_strs[m.group(1)] = m.group(2)
m = p_map.match(l)
if m is not None and m.group(2) != 'Macragge':
map_strs[m.group(1)] = m.group(2)
except Exception as err:
bu.error(err)
sys.exit(1)
except Exception as err:
bu.error(err)
sys.exit(1)
return tank_strs, map_strs
return tank_strs, map_strs
async def convert_tank_names(tanklist : list, tank_strs: dict) -> dict:
"""Convert tank names for Tankopedia"""
tankopedia = {}
userStrs = {}
async def convert_tank_names(tanklist : list, tank_strs: dict) -> tuple[dict, dict]:
"""Convert tank names for Tankopedia"""
tankopedia = {}
userStrs = {}
try:
for tank in tanklist:
tank['name'] = tank_strs[tank['userStr']]
#userStrs[tank['userStr'].split(':')[1]] = tank['name']
tank.pop('userStr', None)
tank_tmp = collections.OrderedDict()
for key in sorted(tank.keys()):
tank_tmp[key] = tank[key]
tankopedia[str(tank['tank_id'])] = tank_tmp
bu.debug(f'tank_strs:')
for key, value in tank_strs.items():
bu.debug(f'{key}: {value}')
bu.debug('---------')
try:
for tank in tanklist:
try:
bu.debug(f'tank: {tank}')
if tank['userStr'] in tank_strs:
tank['name'] = tank_strs[tank['userStr']]
else:
tank['name'] = tank['userStr'].split(':')[1]
tank.pop('userStr', None)
tank_tmp = OrderedDict()
for key in sorted(tank.keys()):
tank_tmp[key] = tank[key]
tankopedia[str(tank['tank_id'])] = tank_tmp
except:
bu.error(f'Could not process tank: {tank}')
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
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]
userStrs[key] = tank_strs[tank_str]
# sorting
tankopedia_sorted = collections.OrderedDict()
for tank_id in sorted(tankopedia.keys(), key=int):
tankopedia_sorted[str(tank_id)] = tankopedia[str(tank_id)]
# sorting
tankopedia_sorted = OrderedDict()
for tank_id in sorted(tankopedia.keys(), key=int):
tankopedia_sorted[str(tank_id)] = tankopedia[str(tank_id)]
userStrs_sorted = collections.OrderedDict()
for userStr in sorted(userStrs.keys()):
userStrs_sorted[userStr] = userStrs[userStr]
# bu.debug('Tank strings: ' + str(len(userStrs_sorted)))
userStrs_sorted = OrderedDict()
for userStr in sorted(userStrs.keys()):
userStrs_sorted[userStr] = userStrs[userStr]
# bu.debug('Tank strings: ' + str(len(userStrs_sorted)))
except Exception as err:
bu.error(err)
sys.exit(1)
except Exception as err:
bu.error(err)
sys.exit(1)
return tankopedia_sorted, userStrs_sorted
return tankopedia_sorted, userStrs_sorted
def get_tank_id(nation: str, tank_id : int) -> int:
return (tank_id << 8) + (wg.NATION_ID[nation] << 4) + 1
assert wg is not None, "wg has to be set"
return (tank_id << 8) + (wg.NATION_ID[nation] << 4) + 1
def get_tank_type(tagstr : str):
tags = tagstr.split(' ')
for t_type in wg.TANK_TYPE:
if tags[0] == t_type:
return t_type
return None
assert wg is not None, "wg has to be set"
tags = tagstr.split(' ')
for t_type in wg.TANK_TYPE:
if tags[0] == t_type:
return t_type
return None
### main()
if __name__ == "__main__":
# To avoid 'Event loop is closed' RuntimeError due to compatibility issue with aiohttp
if sys.platform.startswith("win") and sys.version_info >= (3, 8):
try:
from asyncio import WindowsSelectorEventLoopPolicy
except ImportError:
pass
else:
if not isinstance(asyncio.get_event_loop_policy(), WindowsSelectorEventLoopPolicy):
asyncio.set_event_loop_policy(WindowsSelectorEventLoopPolicy())
#asyncio.run(main(sys.argv[1:]), debug=True)
asyncio.run(main(sys.argv[1:]))
# To avoid 'Event loop is closed' RuntimeError due to compatibility issue with aiohttp
if sys.platform.startswith("win") and sys.version_info >= (3, 8):
try:
from asyncio import WindowsSelectorEventLoopPolicy
except ImportError:
pass
else:
if not isinstance(get_event_loop_policy(), WindowsSelectorEventLoopPolicy):
set_event_loop_policy(WindowsSelectorEventLoopPolicy())
run(main())
+427 -7
View File
@@ -1,7 +1,7 @@
{
"status": "ok",
"meta": {
"count": 564
"count": 592
},
"data": {
"1": {
@@ -788,6 +788,14 @@
"tier": 5,
"type": "heavyTank"
},
"3377": {
"is_premium": false,
"name": "WZ-131",
"nation": "china",
"tank_id": 3377,
"tier": 7,
"type": "lightTank"
},
"3425": {
"is_premium": false,
"name": "Type 61",
@@ -876,6 +884,14 @@
"tier": 7,
"type": "heavyTank"
},
"3889": {
"is_premium": false,
"name": "WZ-132",
"nation": "china",
"tank_id": 3889,
"tier": 8,
"type": "lightTank"
},
"3905": {
"is_premium": false,
"name": "AMX 50 120",
@@ -1092,6 +1108,14 @@
"tier": 3,
"type": "mediumTank"
},
"4913": {
"is_premium": false,
"name": "59-16",
"nation": "china",
"tank_id": 4913,
"tier": 6,
"type": "lightTank"
},
"4929": {
"is_premium": false,
"name": "AMX 13 90",
@@ -2172,6 +2196,14 @@
"tier": 6,
"type": "lightTank"
},
"9777": {
"is_premium": true,
"name": "WZ-114",
"nation": "china",
"tank_id": 9777,
"tier": 9,
"type": "heavyTank"
},
"9793": {
"is_premium": false,
"name": "Somua SAu 40",
@@ -2228,6 +2260,14 @@
"tier": 6,
"type": "mediumTank"
},
"10033": {
"is_premium": false,
"name": "WZ-132A",
"nation": "china",
"tank_id": 10033,
"tier": 9,
"type": "lightTank"
},
"10049": {
"is_premium": false,
"name": "S35 CA",
@@ -2284,6 +2324,14 @@
"tier": 4,
"type": "AT-SPG"
},
"10289": {
"is_premium": false,
"name": "WZ-132-1",
"nation": "china",
"tank_id": 10289,
"tier": 10,
"type": "lightTank"
},
"10353": {
"is_premium": true,
"name": "Pharaoh",
@@ -2293,7 +2341,7 @@
"type": "heavyTank"
},
"10369": {
"is_premium": true,
"is_premium": false,
"name": "Controcarro 3 Minotauro",
"nation": "european",
"tank_id": 10369,
@@ -2324,6 +2372,22 @@
"tier": 5,
"type": "AT-SPG"
},
"10545": {
"is_premium": true,
"name": "Wind",
"nation": "china",
"tank_id": 10545,
"tier": 6,
"type": "lightTank"
},
"10625": {
"is_premium": false,
"name": "Controcarro 1 Mk. 2",
"nation": "european",
"tank_id": 10625,
"tier": 9,
"type": "AT-SPG"
},
"10753": {
"is_premium": false,
"name": "ST-I",
@@ -2348,6 +2412,14 @@
"tier": 10,
"type": "heavyTank"
},
"10801": {
"is_premium": true,
"name": "Panlong",
"nation": "china",
"tank_id": 10801,
"tier": 6,
"type": "AT-SPG"
},
"10817": {
"is_premium": false,
"name": "AMX AC mle. 46",
@@ -2356,6 +2428,14 @@
"tier": 7,
"type": "AT-SPG"
},
"10881": {
"is_premium": false,
"name": "Semovente Controcarro mod. 1964",
"nation": "european",
"tank_id": 10881,
"tier": 8,
"type": "AT-SPG"
},
"11009": {
"is_premium": false,
"name": "KV-4",
@@ -2388,6 +2468,14 @@
"tier": 9,
"type": "AT-SPG"
},
"11137": {
"is_premium": false,
"name": "Semovente Controcarro mod. 1956",
"nation": "european",
"tank_id": 11137,
"tier": 7,
"type": "AT-SPG"
},
"11265": {
"is_premium": true,
"name": "T-150",
@@ -2412,6 +2500,14 @@
"tier": 8,
"type": "AT-SPG"
},
"11393": {
"is_premium": false,
"name": "Semovente M43 Bassotto",
"nation": "european",
"tank_id": 11393,
"tier": 6,
"type": "AT-SPG"
},
"11521": {
"is_premium": false,
"name": "IS-8",
@@ -2444,6 +2540,14 @@
"tier": 6,
"type": "AT-SPG"
},
"11649": {
"is_premium": false,
"name": "Semovente M41",
"nation": "european",
"tank_id": 11649,
"tier": 5,
"type": "AT-SPG"
},
"11777": {
"is_premium": false,
"name": "KV-1",
@@ -2532,6 +2636,14 @@
"tier": 4,
"type": "mediumTank"
},
"12417": {
"is_premium": true,
"name": "Bisonte C45",
"nation": "european",
"tank_id": 12417,
"tier": 8,
"type": "heavyTank"
},
"12545": {
"is_premium": true,
"name": "K-91",
@@ -2540,6 +2652,14 @@
"tier": 9,
"type": "heavyTank"
},
"12673": {
"is_premium": true,
"name": "Bofors Tornvagn",
"nation": "european",
"tank_id": 12673,
"tier": 8,
"type": "heavyTank"
},
"13073": {
"is_premium": true,
"name": "Pz.Kpfw. II Ausf. G",
@@ -2556,6 +2676,14 @@
"tier": 10,
"type": "AT-SPG"
},
"13185": {
"is_premium": true,
"name": "Vz. 55",
"nation": "european",
"tank_id": 13185,
"tier": 10,
"type": "heavyTank"
},
"13329": {
"is_premium": true,
"name": "Durchbruchswagen 2",
@@ -3140,6 +3268,14 @@
"tier": 8,
"type": "AT-SPG"
},
"19521": {
"is_premium": true,
"name": "Bat-Chat-25CL",
"nation": "france",
"tank_id": 19521,
"tier": 9,
"type": "lightTank"
},
"19537": {
"is_premium": false,
"name": "Vickers Light 105",
@@ -3212,6 +3348,14 @@
"tier": 9,
"type": "lightTank"
},
"20033": {
"is_premium": true,
"name": "Char Futur 4",
"nation": "france",
"tank_id": 20033,
"tier": 9,
"type": "mediumTank"
},
"20049": {
"is_premium": false,
"name": "FV301",
@@ -3750,7 +3894,7 @@
},
"25361": {
"is_premium": true,
"name": "Waffenträger Camelot",
"name": "Waffenträger Ritter",
"nation": "germany",
"tank_id": 25361,
"tier": 9,
@@ -3772,6 +3916,14 @@
"tier": 7,
"type": "heavyTank"
},
"25617": {
"is_premium": true,
"name": "HWK 30",
"nation": "germany",
"tank_id": 25617,
"tier": 8,
"type": "lightTank"
},
"25633": {
"is_premium": true,
"name": "M-IV-Y",
@@ -3780,6 +3932,14 @@
"tier": 8,
"type": "heavyTank"
},
"25857": {
"is_premium": true,
"name": "Object 777 Version II",
"nation": "ussr",
"tank_id": 25857,
"tier": 10,
"type": "heavyTank"
},
"25889": {
"is_premium": true,
"name": "Ranger",
@@ -3788,6 +3948,22 @@
"tier": 6,
"type": "lightTank"
},
"26113": {
"is_premium": true,
"name": "Object 452K",
"nation": "ussr",
"tank_id": 26113,
"tier": 9,
"type": "heavyTank"
},
"26129": {
"is_premium": true,
"name": "Epsilon",
"nation": "germany",
"tank_id": 26129,
"tier": 6,
"type": "AT-SPG"
},
"26145": {
"is_premium": true,
"name": "High Score",
@@ -3812,6 +3988,54 @@
"tier": 8,
"type": "mediumTank"
},
"26913": {
"is_premium": true,
"name": "Frosty",
"nation": "usa",
"tank_id": 26913,
"tier": 6,
"type": "lightTank"
},
"27169": {
"is_premium": true,
"name": "Cyborg",
"nation": "usa",
"tank_id": 27169,
"tier": 6,
"type": "heavyTank"
},
"27425": {
"is_premium": false,
"name": "TL-7-120",
"nation": "usa",
"tank_id": 27425,
"tier": 9,
"type": "heavyTank"
},
"27681": {
"is_premium": true,
"name": "Pawlack Tank",
"nation": "usa",
"tank_id": 27681,
"tier": 6,
"type": "heavyTank"
},
"27937": {
"is_premium": true,
"name": "T49 Fearless",
"nation": "usa",
"tank_id": 27937,
"tier": 8,
"type": "lightTank"
},
"28449": {
"is_premium": true,
"name": "T42",
"nation": "usa",
"tank_id": 28449,
"tier": 7,
"type": "mediumTank"
},
"51201": {
"is_premium": true,
"name": "KV-220 Beta-Test",
@@ -4520,6 +4744,7 @@
"userStr": {
"1_test": "#germany_vehicles:1_test",
"1_test_short": "#germany_vehicles:1_test_short",
"85mm_D5T-85BML": "85 mm D-5T-85BML",
"8V135-2": "8V135-2",
"A-20": "A-20",
"A-20_mod_1938": "A-20 mod. 1938",
@@ -4532,6 +4757,8 @@
"A100_T49": "T49",
"A100_T49_Custom": "T49 Hornet",
"A100_T49_Custom_short": "T49 Hornet",
"A100_T49_Custom_short_v2": "T49 Guanlong",
"A100_T49_Custom_v2": "T49 Guanlong",
"A100_T49_short": "T49",
"A102_T28_concept": "T28 Concept",
"A102_T28_concept_Custom": "T28 HTC Independence",
@@ -4582,13 +4809,25 @@
"A132_T77_Custom": "T77 Cannonball",
"A132_T77_Custom_short": "T77 Cannonball",
"A132_T77_short": "T77",
"A136_T42": "T42",
"A136_T42_short": "T42",
"A140_ASTRON_REX_105": "ASTRON Rex 105 mm",
"A140_ASTRON_REX_105_Custom": "ASTRON Rex Ayame",
"A140_ASTRON_REX_105_Custom_short": "ASTRON Rex Ayame",
"A140_ASTRON_REX_105_short": "ASTRON Rex",
"A141_M-4-Y": "M-IV-Y",
"A141_M-4-Y_Custom": "M-IV-Y Stalker",
"A141_M-4-Y_Custom_short": "M-IV-Y Stalker",
"A141_M-4-Y_short": "M-IV-Y",
"A142_Pawlack_Tank": "Pawlack Tank",
"A142_Pawlack_Tank_short": "Pawlack Tank",
"A146_TL_7_120": "TL-7-120",
"A146_TL_7_120_Custom": "TL-7-120 Arachnid",
"A146_TL_7_120_Custom_short": "TL-7-120 Arachnid",
"A146_TL_7_120_short": "TL-7-120",
"A68_T28D": "T28 Defender",
"A68_T28D_Custom": "Defender D-Gunner",
"A68_T28D_Custom_short": "Defender D-Gunner",
"A68_T28D_short": "T28 Defender",
"A77_T6M": "T6E1 Grizzly",
"A77_T6M_short": "T6E1 Grizzly",
@@ -4647,6 +4886,7 @@
"AMX_dracula_short": "Dracula",
"AOI-1490": "Continental AOI-1490",
"AOI-1490A": "Continental AOI-1490-A",
"AOI_695": "AOI-695",
"AOSI_1490-1": "Continental AOSI-1490-1",
"AOS_895": "AOS-895",
"APCNR": "Pzgr. 41 HK",
@@ -4718,6 +4958,8 @@
"Bat_Chatillon25t": "Bat.-Châtillon 25 t",
"Bat_Chatillon25t_Custom": "Bat.-Châtillon 25 t Musketeer",
"Bat_Chatillon25t_Custom_short": "B-C 25 t Musketeer",
"Bat_Chatillon25t_Custom_short_v2": "B-C 25 t Runner",
"Bat_Chatillon25t_Custom_v2": "B-C 25 t Runner",
"Bat_Chatillon25t_short": "B-C 25 t",
"Bedford_Twin-Six": "Bedford Twin-Six",
"Berliet_MDP": "Berliet MDP",
@@ -4731,6 +4973,7 @@
"CH38_WZ113G_FT_Custom": "WZ-113G FT Lucky",
"CH38_WZ113G_FT_Custom_short": "WZ-113G FT Lucky",
"CKD_AXK": "ČKD AXK",
"CKD_AXL": "ČKD AXL",
"Cadillac_V8": "3xCadillacV8",
"Cannone_da_105_51_M68": "Cannone da 105/51 M68",
"Cannone_da_105_51_M68_short": "Cannone da 105/51 M68",
@@ -4772,6 +5015,12 @@
"Ch12_111_1_2_3_short": "WZ-111 1-4",
"Ch14_T34_3": "T-34-3",
"Ch14_T34_3_short": "T-34-3",
"Ch15_59_16": "59-16",
"Ch15_59_16_BP": "Wind",
"Ch15_59_16_BP_Custom": "Free Wind",
"Ch15_59_16_BP_Custom_short": "Free Wind",
"Ch15_59_16_BP_short": "Wind",
"Ch16_WZ_131": "WZ-131",
"Ch17_WZ131_1_WZ132": "WZ-132",
"Ch18_WZ-120": "WZ-120",
"Ch19_121": "WZ-121",
@@ -4782,6 +5031,8 @@
"Ch22_113": "WZ-113",
"Ch22_113_Custom": "WZ-113 Bronze Warrior",
"Ch22_113_Custom_short": "WZ-113 Bronze Warrior",
"Ch22_113_Custom_short_v2": "WZ-113 Nine-Colors",
"Ch22_113_Custom_v2": "WZ-113 Nine-Colors",
"Ch23_112": "112 Glacial",
"Ch24_Type64": "Type 64",
"Ch24_Type64_short": "Type 64",
@@ -4791,7 +5042,17 @@
"Ch26_59_Patton_Custom": "59-Patton Aratinga",
"Ch26_59_Patton_Custom_short": "59-Patton Aratinga",
"Ch26_59_Patton_short": "59-Patton",
"Ch28_WZ_132A": "WZ-132A",
"Ch28_WZ_132A_short": "WZ-132A",
"Ch29_Type_62C_prot": "WZ-132-1",
"Ch29_Type_62C_prot_Custom": "WZ-132-1 Futuro",
"Ch29_Type_62C_prot_Custom_short": "WZ-132-1 Futuro",
"Ch29_Type_62C_prot_short": "WZ-132-1",
"Ch34_WZ-131G_FT": "WZ-131G FT",
"Ch34_WZ-131G_FT_BP": "Panlong",
"Ch34_WZ-131G_FT_BP_Custom": "Panlong Immortal",
"Ch34_WZ-131G_FT_BP_Custom_short": "Panlong Immortal",
"Ch34_WZ-131G_FT_BP_short": "Panlong",
"Ch34_WZ-131G_FT_short": "WZ-131G FT",
"Ch35_T-34-2G_FT": "T-34-2G FT",
"Ch35_T-34-2G_FT_short": "T-34-2G FT",
@@ -4815,6 +5076,10 @@
"Ch42_M41D_short": "M41D",
"Ch43_WZ-122_2": "WZ-122 TM",
"Ch43_WZ-122_2_short": "WZ-122 TM",
"Ch45_WZ_114": "WZ-114",
"Ch45_WZ_114_Custom": "WZ-114 Zhulong",
"Ch45_WZ_114_Custom_short": "WZ-114 Zhulong",
"Ch45_WZ_114_short": "WZ-114",
"Ch_LT_vz38": "LT vz. 38",
"Ch_LT_vz38_short": "LT vz. 38",
"Ch_WZ-112v2": "WZ-112-2",
@@ -4823,18 +5088,64 @@
"Ch_WZ_112v2_Custom_short": "WZ-112-2 Celestial",
"Chassis1_A140_ASTRON_REX_105": "Rex",
"Chassis1_A140_ASTRON_REX_105_short": "Rex",
"Chassis1_Ch16_WZ_131": "WZ-131",
"Chassis1_Ch16_WZ_131_short": "WZ-131",
"Chassis1_Ch17_WZ131_1_WZ132": "WZ-131-1",
"Chassis1_Ch17_WZ131_1_WZ132_short": "WZ-131-1",
"Chassis1_Ch28_WZ_132A": "WZ-132A",
"Chassis1_Ch28_WZ_132A_short": "WZ-132A",
"Chassis1_Ch29_Type_62C_prot": "WZ-132-1",
"Chassis1_Ch29_Type_62C_prot_short": "WZ-132-1",
"Chassis1_Ch45_WZ_114": "WZ-114",
"Chassis1_Ch45_WZ_114_short": "WZ-114",
"Chassis1_F117_Alt_Proto_AMX_30": "AltProto AMX 30",
"Chassis1_F117_Alt_Proto_AMX_30_short": "A.P. AMX 30",
"Chassis1_GB09_Churchill_VII_BP": "Churchill W",
"Chassis1_GB09_Churchill_VII_BP_short": "Churchill W",
"Chassis1_It10_P43_bis_BP": "Shadowhunter",
"Chassis1_It10_P43_bis_BP_short": "Shadowhunter",
"Chassis1_It15_Semovente_M41": "Semovente M41",
"Chassis1_It15_Semovente_M41_short": "Semovente M41",
"Chassis1_It16_Bassoto": "Semovente M43",
"Chassis1_It16_Bassoto_short": "Semovente M43",
"Chassis1_It17_Semovente_mod_56": "CC mod. 56",
"Chassis1_It17_Semovente_mod_56_short": "CC mod. 56",
"Chassis1_It18_Semovente_mod_64": "CC-64 tipo A",
"Chassis1_It18_Semovente_mod_64_short": "CC-64 tipo A",
"Chassis1_It19_Controcarro_1MK2_Ciclope": "Controcarro 1 Mk. 2 tipo A",
"Chassis1_It19_Controcarro_1MK2_Ciclope_short": "CC 1 Mk. 2 tipo A",
"Chassis1_It22_Progetto_C45_mod_71": "Bisonte C45",
"Chassis1_It22_Progetto_C45_mod_71_short": "Bisonte C45",
"Chassis1_M24_Chaffee_BP": "Frosty",
"Chassis1_M24_Chaffee_BP_short": "Frosty",
"Chassis1_M6E2V2_BP": "Cyborg",
"Chassis1_M6E2V2_BP_short": "Cyborg",
"Chassis1_Oth34_PanzerMummy": "Royal Tread",
"Chassis1_Oth34_PanzerMummy_short": "Royal Tread",
"Chassis1_Oth35_PanzerMejai": "Desert Wanderer",
"Chassis1_Oth35_PanzerMejai_short": "Desert Wanderer",
"Chassis1_R119_Object_777": "Object 777 Version II",
"Chassis1_R119_Object_777_short": "Obj. 777 II",
"Chassis1_S31_Strv_K": "Stridsvagn KRV",
"Chassis1_S31_Strv_K_short": "Stridsvagn KRV",
"Chassis1_S32_Bofors_Tornvagn": "Bofors Tornvagn",
"Chassis1_S32_Bofors_Tornvagn_short": "Tornvagn",
"Chassis2_Ch16_WZ_131": "WZ-131 model 2",
"Chassis2_Ch16_WZ_131_short": "WZ-131 model 2",
"Chassis2_Ch17_WZ131_1_WZ132": "WZ-132",
"Chassis2_Ch17_WZ131_1_WZ132_short": "WZ-132",
"Chassis2_Ch28_WZ_132A": "WZ-132B",
"Chassis2_Ch28_WZ_132A_short": "WZ-132B",
"Chassis2_It15_Semovente_M41": "Semovente M42",
"Chassis2_It15_Semovente_M41_short": "Semovente M42",
"Chassis2_It16_Bassoto": "Semovente M44",
"Chassis2_It16_Bassoto_short": "Semovente M44",
"Chassis2_It17_Semovente_mod_56": "CC mod. 57",
"Chassis2_It17_Semovente_mod_56_short": "CC mod. 57",
"Chassis2_It18_Semovente_mod_64": "CC-64 tipo B",
"Chassis2_It18_Semovente_mod_64_short": "CC-64 tipo B",
"Chassis2_It19_Controcarro_1MK2_Ciclope": "Controcarro 1 Mk. 2 tipo B",
"Chassis2_It19_Controcarro_1MK2_Ciclope_short": "CC 1 Mk. 2 tipo B",
"Chi_Ha": "Type 97 Chi-Ha",
"Chi_Ha_short": "Chi-Ha",
"Chi_He": "Type 1 Chi-He",
@@ -4866,16 +5177,20 @@
"Continental_AOI-628-2": "Continental AOI-628-2",
"Continental_AOI-628-2A": "Continental AOI-628-2A",
"Continental_AOI-628-2_short": "Continental\\nAOI-628-2",
"Continental_AOI_1490": "Continental AOI-1490",
"Continental_AOI_1490M": "Continental AOI-1490-M",
"Continental_AOI_1490_1": "Continental AOI-1490-1",
"Continental_AOS-895-1": "Continental AOS-895-1",
"Continental_AOS-895-1_short": "Continental\\nAOS-895-1",
"Continental_AOS-895-3": "AN/GRC-8",
"Continental_AOS-895-3M": "Continental AOS-895-3M",
"Continental_AOS-895-3V2": "Continental AOS-895-3-2",
"Continental_AOS-895-3_short": "AN/GRC-8",
"Continental_AOSI-1195-1": "Continental AOSI 1195-1",
"Continental_AOSI-1195-1A": "Continental AOSI-1195-1A",
"Continental_AOSI-1195-5": "Continental AOSI-1195-5",
"Continental_AOSI-895-5": "Continental AOSI-895-5",
"Continental_AOSI-895-5FR": "Continental AOSI-895-5",
"Continental_AOSI-895-5_short": "Continental\\nAOSI-895-5",
"Continental_AOSI_1195_5A": "Continental AOSI-1195-5 Y IV",
"Continental_AOSI_895_5_Prem": "Continental AOSI-895-5",
@@ -4956,6 +5271,8 @@
"Cz15_Skoda_T-45_Custom": "Škoda T 45 Skvělý",
"Cz15_Skoda_T-45_Custom_short": "Škoda T 45 Skvělý",
"Cz15_Skoda_T-45_short": "Škoda T 45",
"Cz17_Vz_55": "Vz. 55",
"Cz17_Vz_55_short": "Vz. 55",
"D-744": "D-744",
"D1": "D1",
"D1_short": "D1",
@@ -5006,21 +5323,28 @@
"E50_Ausf_M_Custom": "E 50 M Roaring",
"E50_Ausf_M_Custom_short": "E 50 M Roaring",
"E50_Ausf_M_Custom_short_v2": "E 50 M Monster",
"E50_Ausf_M_Custom_short_v3": "E 50 M Monster Evo.",
"E50_Ausf_M_Custom_v2": "E 50 Ausf. M Monster",
"E50_Ausf_M_Custom_v3": "E 50 M Monster Evo.",
"E50_Ausf_M_short": "E 50 M",
"ELC_AMX": "AMX ELC bis",
"ELC_AMX_short": "AMX ELC bis",
"E_9": "E-9",
"Engine_1_test": "#germany_vehicles:Engine_1_test",
"Engine_1_test_short": "#germany_vehicles:Engine_1_test_short",
"F01_Vickers_MkF": "Vickers Mk. F",
"F01_Vickers_MkF_short": "Vickers Mk. F",
"F113_PzV_FR": "Bretagne Panther",
"F113_PzV_FR_short": "Bretagne Panther",
"F114_Projet_4_1": "Char Futur 4",
"F114_Projet_4_1_short": "Char Futur 4",
"F116_Bat_Chat_Bourrasque": "Bat.-Châtillon Bourrasque",
"F116_Bat_Chat_Bourrasque_Custom": "Bourrasque Noir",
"F116_Bat_Chat_Bourrasque_Custom_short": "Bourrasque Noir",
"F116_Bat_Chat_Bourrasque_short": "B-C Bourrasque",
"F117_Alt_Proto_AMX_30": "AltProto AMX 30",
"F117_Alt_Proto_AMX_30_Custom": "A.P. AMX 30 Disruptor",
"F117_Alt_Proto_AMX_30_Custom_short": "A.P. AMX 30 Disruptor",
"F117_Alt_Proto_AMX_30_short": "A.P. AMX 30",
"F19_Lorraine40t": "Lorraine 40 t",
"F19_Lorraine40t_Com": "Lorraine 40 t Fearless",
@@ -5078,6 +5402,7 @@
"Ferdinandstandardketten": "Ferdinand",
"Ferdinandturm": "Ferdinand",
"Ferdinandvetstaerktketten": "Elefant",
"Fiat_V10": "Fiat V-10",
"Firefly_GuP": "Firefly Saunders SP",
"Firefly_GuP_short": "Firefly Saunders SP",
"First_april": "#other_vehicles:First_april",
@@ -5107,6 +5432,8 @@
"G100_Gtraktor_Krupp": "Großtraktor - Krupp",
"G100_Gtraktor_Krupp_short": "Großtraktor",
"G103_RU_251": "Spähpanzer Ru 251",
"G103_RU_251_Custom": "Ru 251 Breakneck",
"G103_RU_251_Custom_short": "Ru 251 Breakneck",
"G103_RU_251_short": "Ru 251",
"G106_PzKpfwPanther_AusfF": "Panther mit 8,8 cm L/71",
"G106_PzKpfwPanther_AusfF_short": "Panther 8,8",
@@ -5138,11 +5465,15 @@
"G121_Grille_15_L63": "Grille 15",
"G121_Grille_15_L63_Custom": "Grille 15 RA1DER",
"G121_Grille_15_L63_Custom_short": "Grille 15 RA1DER",
"G121_Grille_15_L63_Custom_short_v3": "Grille 15 Förster",
"G121_Grille_15_L63_Custom_v3": "Grille 15 Förster",
"G121_Grille_15_L63_short": "Grille 15",
"G136_Tiger_131": "Tiger 131",
"G136_Tiger_131_short": "Tiger 131",
"G138_VK16801P": "VK 168.01 (P)",
"G138_VK16801P_short": "VK 168.01 (P)",
"G140_HWK_30": "HWK 30",
"G140_HWK_30_short": "HWK 30",
"G142_M48RPz": "M48A2 Räumpanzer",
"G142_M48RPz_Custom": "Räumpanzer Rhino",
"G142_M48RPz_Custom_short": "Räumpanzer Rhino",
@@ -5150,6 +5481,8 @@
"G144_Kpz_50t": "Kampfpanzer 50 t",
"G144_Kpz_50t_Custom": "Kpz 50 t König",
"G144_Kpz_50t_Custom_short": "Kpz 50 t König",
"G144_Kpz_50t_Custom_short_v2": "Kpz 50 t Jäger",
"G144_Kpz_50t_Custom_v2": "Kpz 50 t Jäger",
"G144_Kpz_50t_short": "Kpz 50 t",
"G147_mPanzer_64": "Kunze Panzer",
"G147_mPanzer_64_Custom": "Kunze Pz. Daredevil",
@@ -5347,12 +5680,15 @@
"GMC_Allison_V1710-E32_short": "GMC Allison\\nV1710-E32",
"GMS-6046B": "GMS 6046B",
"GM_6-71_M": "GM 6062 6-71M",
"GM_DIESEL_P_V2": "GM Diesel P V2",
"GM_X-11": "GM X-11",
"GM_X-12": "GM X-12",
"GTD": "GTD",
"GT_101": "GT 101",
"G_E": "G.W. E 100",
"G_E-75RT": "Keiler",
"G_E-75RT_Custom": "Keiler Exterminator",
"G_E-75RT_Custom_short": "Keiler Exterminator",
"G_E-75RT_short": "Keiler",
"G_E-75TS": "E 75 TS",
"G_E-75TS_short": "E 75 TS",
@@ -5459,6 +5795,8 @@
"IS_4_Custom_short": "IS-4 Skilled",
"IS_6_Custom": "IS-6 Legend",
"IS_6_Custom_short": "IS-6 Legend",
"IS_Custom": "IS Steppe",
"IS_Custom_short": "IS Steppe",
"Indien_Panzer": "Indien-Panzer",
"Indien_Panzer_short": "Indien-Pz.",
"It08_Progetto_M40_mod65": "Progetto M40 mod. 65",
@@ -5485,12 +5823,28 @@
"It14_P44_Pantera_Custom": "P.44 Pantera Furious",
"It14_P44_Pantera_Custom_short": "P.44 Pantera Furious",
"It14_P44_Pantera_short": "P.44 Pantera",
"It15_Semovente_M41": "Semovente M41",
"It15_Semovente_M41_short": "Semovente M41",
"It16_Bassoto": "Semovente M43 Bassotto",
"It16_Bassoto_short": "Bassotto",
"It17_Semovente_mod_56": "Semovente Controcarro mod. 1956",
"It17_Semovente_mod_56_short": "SMV CC-56",
"It18_Semovente_mod_64": "Semovente Controcarro mod. 1964",
"It18_Semovente_mod_64_short": "SMV CC-64",
"It19_Controcarro_1MK2_Ciclope": "Controcarro 1 Mk. 2",
"It19_Controcarro_1MK2_Ciclope_short": "CC 1 Mk. 2",
"It20_Car_Comb_45t": "Carro da Combattimento 45t",
"It20_Car_Comb_45t_Custom": "Carro 45t Glitch",
"It20_Car_Comb_45t_Custom_short": "Carro 45t Glitch",
"It20_Car_Comb_45t_short": "Carro 45t",
"It21_Controcarro3_Minotauro": "Controcarro 3 Minotauro",
"It21_Controcarro3_Minotauro_Custom": "Minotauro Moderno",
"It21_Controcarro3_Minotauro_Custom_short": "Minotauro Moderno",
"It21_Controcarro3_Minotauro_short": "Minotauro",
"It22_Progetto_C45_mod_71": "Bisonte C45",
"It22_Progetto_C45_mod_71_Custom": "Bisonte Unbreakable",
"It22_Progetto_C45_mod_71_Custom_short": "Bisonte Unbreakable",
"It22_Progetto_C45_mod_71_short": "Bisonte C45",
"J12_Shinobi": "Shinobi",
"J12_Shinobi_short": "Shinobi",
"J20_Ho_Ri_type3": "Ho-Ri Type III",
@@ -5572,6 +5926,8 @@
"KV1": "KV-1",
"KV1S_mod_42": "KV-1S mod. 1942",
"KV1S_mod_43": "KV-85",
"KV1_Custom": "KV-1 Ghost",
"KV1_Custom_short": "KV-1 Ghost",
"KV1s_bear": "KV-1S Football",
"KV1s_bear_short": "KV-1S Football",
"KV2": "KV-2",
@@ -5607,6 +5963,8 @@
"Leopard1": "Leopard 1",
"Leopard1_Custom": "Leopard 1 Wild",
"Leopard1_Custom_short": "Leopard 1 Wild",
"Leopard1_Custom_short_v2": "Leopard 1 Irbis",
"Leopard1_Custom_v2": "Leopard 1 Irbis",
"Leopard1_short": "Leopard 1",
"Leopardketten_Ausf_A": "VK 16.02 Leopard",
"Leopardketten_Ausf_B": "VK 16.02 Leopard verstärkteketten",
@@ -5618,7 +5976,9 @@
"Licoming_0-435t": "Lycoming O-435T",
"Lowe": "Löwe",
"Lowe_Custom": "Löwe Reliant",
"Lowe_Custom_2": "Löwe Colossus",
"Lowe_Custom_short": "Löwe Reliant",
"Lowe_Custom_short_2": "Löwe Colossus",
"Ltraktor": "Leichttraktor",
"Ltraktor_short": "L.Tr.",
"Luchsketten_Ausf_A": "Luchs",
@@ -5644,9 +6004,13 @@
"M-5-Y_short": "M-V-Yoh",
"M-50T": "M-50T",
"M-50TD": "M-50TD",
"M-50TV2": "M-50TV2",
"M-50TV2K": "M-50TV2K",
"M-6-Y": "M-VI-Yoh",
"M-6-Y_Custom": "M-VI-Yoh Pride",
"M-6-Y_Custom_short": "M-VI-Yoh Pride",
"M-6-Y_Custom_short_v2": "M-VI-Yoh Ankylosaurus",
"M-6-Y_Custom_v2": "M-VI-Yoh Ankylosaurus",
"M-6-Y_short": "M-VI-Yoh",
"M-7-Y": "M-VII-Yoh",
"M-7-Y_short": "M-VII-Yoh",
@@ -5665,6 +6029,10 @@
"M22_Locust_short": "Locust",
"M24A1": "M24A1",
"M24_Chaffee": "M24 Chaffee",
"M24_Chaffee_BP": "Frosty",
"M24_Chaffee_BP_Custom": "Frosty Jinglebell",
"M24_Chaffee_BP_Custom_short": "Frosty Jinglebell",
"M24_Chaffee_BP_short": "Frosty",
"M24_Chaffee_short": "Chaffee",
"M2D27810": "M2D27810",
"M2D27812": "M2D27812",
@@ -5727,6 +6095,10 @@
"M6D2": "M6D2",
"M6E2BP": "Magnus",
"M6E2BP_short": "Magnus",
"M6E2V2_BP": "Cyborg",
"M6E2V2_BP_Custom": "Cyborg T-800",
"M6E2V2_BP_Custom_short": "Cyborg T-800",
"M6E2V2_BP_short": "Cyborg",
"M7": "M5A1",
"M7D1": "M7D1",
"M7_Priest": "M7 Priest",
@@ -5743,6 +6115,7 @@
"MB-837-Ea-600": "MB 837 Ea 600",
"MB-837A": "MTU MB 837 A",
"MB-837A_short": "MB 837 A",
"MB-837M": "MB 837 M",
"MB-838_CAM-500": "MTU MB 838 CaM 500",
"MB-838_CAM-500_1": "MTU MB 838 CaM 500A",
"MB-838_CAM-500_1_short": "MB 838 CaM 500A",
@@ -5765,6 +6138,10 @@
"MTLS-1G14": "MTLS-1G14",
"MTLS_D1": "MTLS D1",
"MTLS_T1": "MTLS T1",
"MTU_870": "MTU 870",
"MTU_870M": "MTU 870M",
"MTU_970": "MTU 970",
"MTU_970M": "MTU 970M",
"MTU_MB-838_Ca_M-500": "MTU MB 838 CaM 500B",
"MT_50_T": "MT-50T",
"M_40": "M-40",
@@ -5806,6 +6183,7 @@
"Maybach_HL_120_TRM_BT": "Maybach HL 120 TRM",
"Maybach_HL_120_TRM_C": "Maybach HL 120 TRM V12",
"Maybach_HL_120_TRM_R": "Maybach HL 120 TRM R",
"Maybach_HL_120_TRM_RBP": "Maybach HL 120 TRM R",
"Maybach_HL_120_TR_A": "Maybach HL 120 TRM 112",
"Maybach_HL_120_TR_R": "Maybach HL 120 TR R",
"Maybach_HL_120_WH": "Dark Soul",
@@ -5827,6 +6205,7 @@
"Maybach_HL_210_TRM_P30": "Maybach HL 210 TRM P30",
"Maybach_HL_210_TRM_P30_A": "Maybach HL 210 TRM P30",
"Maybach_HL_210_TRM_P30_short": "Maybach\\nHL 210 TRM P30",
"Maybach_HL_210_TRM_P30v2": "Maybach HL 210 TRM P30 V2",
"Maybach_HL_210_TRM_P45": "Maybach HL 210 TRM P45",
"Maybach_HL_210_TRM_P45TU": "Maybach HL 210 TRM P45",
"Maybach_HL_210_TRM_P45_BP": "Maybach HL 210 TRM P45 B",
@@ -5841,8 +6220,10 @@
"Maybach_HL_230P45_short": "Maybach HL 230\\nP45F",
"Maybach_HL_230_F": "Maybach HL 230 F",
"Maybach_HL_230_TRM_P30": "Maybach HL 230 TRM P30 pl.",
"Maybach_HL_230_TRM_P30V2": "Maybach HL 230 TRM P30 V2",
"Maybach_HL_230_TRM_P30_FR": "Maybach HL 230 TRM P30 fr.",
"Maybach_HL_230_TRM_P30_short": "Maybach\\nHL 230 TRM P30",
"Maybach_HL_230_TRM_P30v3": "Maybach HL 230 TRM P30 V3",
"Maybach_HL_230_TRM_P45": "Maybach HL 230 TRM P45",
"Maybach_HL_230_TRM_P45A": "Maybach HL 230 TRM P45 A",
"Maybach_HL_230_TRM_P45_short": "Maybach HL 230\\nTRM P45",
@@ -5892,6 +6273,10 @@
"NVSS_T66": "HVSS T66",
"NVSS_T80": "HVSS T80",
"Nashorn": "Nashorn",
"Nashorn_BP": "Epsilon",
"Nashorn_BP_Custom": "Epsilon Sagittarius",
"Nashorn_BP_Custom_short": "Epsilon Sagittarius",
"Nashorn_BP_short": "Epsilon",
"Nashorn_short": "Nashorn",
"Nuffield_liberty_MKII": "Nuffield Liberty Mk. II",
"Nuffield_liberty_MKIV": "Nuffield Liberty Mk. III",
@@ -5946,7 +6331,6 @@
"Oe_mle._1932A": "HE Shell",
"Ordnance_QF_2pdr_AT_Gun_Mk.X": "QF Mk. IX",
"Ordnance_QF_2pdr_AT_Gun_Mk.X_short": "QF Mk. IX",
"Oth06_Sega_Lupus": "Lupus",
"Oth08_WH_Vindicator": "Vindicator Ultramarines",
"Oth08_WH_Vindicator_Dark_Angels_Custom": "Vindicator Dark Angels",
"Oth08_WH_Vindicator_Dark_Angels_Custom_short": "Vindicator DA",
@@ -6201,6 +6585,8 @@
"PzVI_Porsche_Turm_short": "Pz.Kpfw. Tiger\\nAusf. E",
"PzVI_Standardketten": "Pz.Kpfw. VI H Ausf. H1",
"PzVI_Tiger_P": "Tiger (P)",
"PzVI_Tiger_P_Custom": "Tiger (P) Sandsturm",
"PzVI_Tiger_P_Custom_short": "Tiger (P) Sandsturm",
"PzVI_Tiger_P_short": "Tiger (P)",
"PzVI_Vetstaerktketten": "Pz.Kpfw. Tiger Ausf. E",
"PzVI_skin_gamescom": "Tiger I Gamescom",
@@ -6267,6 +6653,8 @@
"R115_IS-3_auto": "IS-3 Defender",
"R115_IS-3_auto_short": "IS-3 Defender",
"R116_ISU122C_Berlin": "ISU-122S",
"R119_Object_777": "Object 777 Version II",
"R119_Object_777_short": "Obj. 777 II",
"R120_T22SR": "T-22 medium",
"R120_T22SR_Custom": "T-22 Uncatchable",
"R120_T22SR_Custom_short": "T-22 Uncatchable",
@@ -6290,6 +6678,8 @@
"R146_STG_Custom_short": "STG Guard",
"R146_STG_short": "STG",
"R149_Object_268_4": "Object 268 Version 4",
"R149_Object_268_4_Custom": "Object 268/4 Chronos",
"R149_Object_268_4_Custom_short": "Object 268/4 Chronos",
"R149_Object_268_4_short": "Object 268/4",
"R154_T-34E-43": "T-34 shielded",
"R154_T-34E-43_short": "T-34 shielded",
@@ -6313,6 +6703,8 @@
"R180_Object_274A_Custom": "Object 274a Leshy",
"R180_Object_274A_Custom_short": "Object 274a Leshy",
"R180_Object_274A_short": "Object 274a",
"R181_Object_452K": "Object 452K",
"R181_Object_452K_short": "Object 452K",
"R43_T-70_57": "T-70/57",
"R43_T-70_57_short": "T-70/57",
"R63_ST_IBD": "T-2020",
@@ -6357,6 +6749,8 @@
"Renault_T14": "Renault T14",
"Renault_V4": "Renault V4",
"RhB_Waffentrager": "Rhm.-Borsig Waffenträger",
"RhB_Waffentrager_Custom": "Rhm.-B. WT Tarnkappe",
"RhB_Waffentrager_Custom_short": "Rhm.-B. WT Tarnkappe",
"RhB_Waffentrager_short": "Rhm.-B. WT",
"Rolls_Royce_Griffon": "Rolls-Royce Griffon",
"Rolls_Royce_Griffon-Mk2": "Rolls-Royce Griffon A",
@@ -6416,7 +6810,13 @@
"S26_Lancen_C_Custom_short": "Lansen Moose",
"S26_Lancen_C_short": "Lansen C",
"S31_Strv_K": "Strv K",
"S31_Strv_K_Custom": "Strv K Konung",
"S31_Strv_K_Custom_short": "Strv K Konung",
"S31_Strv_K_short": "Strv K",
"S32_Bofors_Tornvagn": "Bofors Tornvagn",
"S32_Bofors_Tornvagn_Custom": "Tornvagn Stegosaurus",
"S32_Bofors_Tornvagn_Custom_short": "Tornvagn Stegosaurus",
"S32_Bofors_Tornvagn_short": "Tornvagn",
"S35_captured": "Pz.Kpfw. S35 739 (f)",
"S35_captured_short": "Pz. S35",
"SA35_4": "SA35 mle. 4",
@@ -6430,15 +6830,21 @@
"SOFAM_12_58": "SOFAM 12 58",
"SOFAM_8Gxb": "SOFAM 8 Gxb",
"SOFAM_8Gxb_A": "SOFAM 8 Gxb",
"SPA_15TB": "SPA 15TB",
"SPA_17TB": "SPA 17TB",
"SPA_242": "SPA 242",
"SPA_343": "SPA 343",
"SPA_344": "SPA 344",
"SPA_mod_15": "SPA mod. 15",
"SPA_mod_17": "SPA mod. 17",
"STA_1": "STA-1",
"STA_1_Rin": "STA-1 Rin",
"STA_1_short": "STA-1",
"ST_B1": "STB-1",
"ST_B1_Custom": "STB-1 Adamant",
"ST_B1_Custom_short": "STB-1 Adamant",
"ST_B1_Custom_short_v2": "STB-1 Spinosaurus",
"ST_B1_Custom_v2": "STB-1 Spinosaurus",
"ST_B1_short": "STB-1",
"ST_I": "ST-I",
"SU-100": "SU-100",
@@ -6452,7 +6858,7 @@
"SU-152": "SU-152",
"SU-152_01": "SU-152",
"SU-152_Custom": "SU-152 Taiga",
"SU-152_Custom_short": "SU-152 Тaiga",
"SU-152_Custom_short": "SU-152 Taiga",
"SU-152_mod_1943": "SU-152",
"SU-152_mod_1944": "SU-152M",
"SU-18": "SU-18",
@@ -6660,6 +7066,8 @@
"T34_hvy": "T34",
"T34_hvy_Custom": "T34 Falcon",
"T34_hvy_Custom_short": "T34 Falcon",
"T34_hvy_Custom_short_v2": "T34 H-Combat",
"T34_hvy_Custom_v2": "T34 H-Combat",
"T34_hvy_Freedom": "T34 Independence",
"T34_hvy_Freedom_short": "T34 (1776)",
"T37": "T37",
@@ -6669,6 +7077,8 @@
"T42": "T42",
"T48": "T48",
"T49": "T67",
"T49_Fearless": "T49 Fearless",
"T49_Fearless_short": "T49 Fearless",
"T49_Rocket": "T49 ATM",
"T49_Rocket_short": "T49 A",
"T51D1": "T51D1",
@@ -6677,6 +7087,8 @@
"T57_58": "T57 Heavy Tank",
"T57_58_Custom": "T57 Heavy Tireless",
"T57_58_Custom_short": "T57 Heavy Tireless",
"T57_58_Custom_short_v2": "T57 Heavy Ammoel",
"T57_58_Custom_v2": "T57 Heavy Ammoel",
"T57_58_short": "T57 Heavy",
"T62A": "T-62A",
"T62A_Custom": "T-62A Fearless",
@@ -6703,6 +7115,8 @@
"T95": "T95",
"T95E2": "T95E2",
"T95E2_short": "T95E2",
"T95_Custom": "T95 Turtle",
"T95_Custom_short": "T95 Turtle",
"T99E2": "T99E2",
"TD-12": "TD-12",
"TD-12S": "TD-12S",
@@ -6773,6 +7187,7 @@
"V-2-54IS": "V-2-54IS",
"V-2-54IS_2": "V-2-54-IS/2",
"V-2-54IS_GuP": "V-2-54 GuP",
"V-2-54SC": "V-2-54SC",
"V-2IS": "V-2IS",
"V-2IS_B": "V-2IS",
"V-2IS_B_2": "V-2IS-2",
@@ -6794,6 +7209,7 @@
"V-54-6": "V-54-6",
"V-54I": "V-54I",
"V-54K": "V-54K",
"V-54KML": "V-54K-ML",
"V-54K_TU": "V-54K",
"V-55": "V-55",
"V-55U": "V-14",
@@ -6917,8 +7333,10 @@
"W_12_5_B": "W12-5B",
"W_12_5_P": "W12-5P",
"Waffentrager_IV": "Waffenträger auf Pz. IV",
"Waffentrager_IV_CL": "Waffenträger Camelot",
"Waffentrager_IV_CL_short": "WT Camelot",
"Waffentrager_IV_CL": "Waffenträger Ritter",
"Waffentrager_IV_CL_short": "WT Ritter",
"Waffentrager_IV_Custom": "WT auf Pz. IV Darkwing",
"Waffentrager_IV_Custom_short": "WT auf Pz. IV Darkwing",
"Waffentrager_IV_short": "WT auf Pz. IV",
"Waterspit_1": "Waterspit",
"Wespe": "Wespe",
@@ -6927,6 +7345,7 @@
"Wespeketten_ausf_B": "Wespe verstärkteketten",
"Wespeturm": "Wespe",
"Wright_Continental_R-975C1": "Wright Continental R-975C1",
"Wright_Continental_R-975C1_BP": "Wright Continental R-975C1 B",
"Wright_Continental_R-975C1_GuP": "Wright Continental R-975C1 GuP",
"Wright_Continental_R-975C1_short": "Wright C. R-975C1",
"Wright_Continental_R-975C2": "Wright Continental R-975C2",
@@ -6940,6 +7359,7 @@
"Wright_Continental_R-975EC2_short": "Wright C. R-975EC2",
"Wright_Continental_R_975_C4_858": "Wright Continental\\nR-975-C4 (858)",
"Wright_G200_m_781C9GC1": "Wright G200 M781C9GC1",
"Wright_G200_m_781C9GC1V2_BP": "Wright G200 M781C9GC1",
"Wright_G200_m_781C9GC5": "Wright G200 M781C9GC5",
"Wright_G200_m_781C9GC5_short": "Wright G200\\nM781C9GC5",
"Wright_G200_m_795C9GC1": "Wright G200 M795C9GC1",