[![GitHub version](https://badge.fury.io/gh/PowerBroker2%2FWarThunder.svg)](https://badge.fury.io/gh/PowerBroker2%2FWarThunder) [![PyPI version](https://badge.fury.io/py/WarThunder.svg)](https://badge.fury.io/py/WarThunder)
# Overview
Python package to access vehicle telemetry and match data in real-time while in War Thunder air battles (NOT tanks). Here are some things you can access/do with this package:
- Get telemetry information on your vehicle and others identified on user's mini map
- Data available for both user and other match player's vehicles:
- Location in latitude/longitude (DD)
- Heading angle
- Airspeed
- Data avilable only for user's vehicle:
- Pitch angle
- Roll angle
- Flap state
- Gear state
- Altitude
- Data on other objects identified on user's mini map
- Object's location in latitude/longitude (DD)
- Airfields have 2 locations, one for each end of the runway
- Object's faction (friendly or enemy)
- Object's type (fighter, bomber, heavy tank, etc)
- Map name
- Chat comments (anything typed into chat)
- Match events (death, crash, etc)
- Log data in an [ACMI format](https://www.tacview.net/documentation/acmi/en/) compatible with [Tacview](https://www.tacview.net/)
This library makes use of War Thunder's localhost server pages (http://localhost:8111/indicators, http://localhost:8111/state, http://localhost:8111/map.img, http://localhost:8111/map_obj.json, and http://localhost:8111/map_info.json, and more!) that the game automatically serves when you launch a game match. If it is an air battle, these pages will include JSON formatted data with valid airplane telemetry. This telemetry is then converted and returned to the calling function/user.
The data can then be easily used for any custom application (i.e. telemetry datalogger and grapher).
# Example Use-Case:
https://github.com/PowerBroker2/Thunder_Viewer
# To Install
`pip install WarThunder`
# Example Python Script
```python
from WarThunder import telemetry
from WarThunder import mapinfo
from pprint import pprint
def find_map_info():
print('------------------------------------------------------')
print('Map Info:')
print('\tName:\t\t\t\t\t{}'.format(telem.map_info.grid_info['name']))
print('\tUpper Left Hand Corner Coordinate:\t[{}, {}]'.format(telem.map_info.grid_info['ULHC_lat'], telem.map_info.grid_info['ULHC_lon']))
print('\tSize:\t\t\t\t\t{}km x {}km'.format(telem.map_info.grid_info['size_km'], telem.map_info.grid_info['size_km']))
print('')
def find_all_bomb_points():
print('------------------------------------------------------')
find_bomb_points(True)
find_bomb_points(False)
def find_all_airfields():
print('------------------------------------------------------')
find_airfields(True)
find_airfields(False)
def find_all_planes():
print('------------------------------------------------------')
find_planes(True)
find_planes(False)
def find_all_tanks():
print('------------------------------------------------------')
find_tanks(True)
find_tanks(False)
def find_all_AAAs():
print('------------------------------------------------------')
find_AAAs(True)
find_AAAs(False)
def find_basic_telemetry():
print('------------------------------------------------------')
print('Basic Telemetry:')
pprint(telem.basic_telemetry)
print('')
def find_comments():
print('------------------------------------------------------')
print('Comments:')
comments = telem.get_comments()
if comments:
pprint(comments)
else:
print('\tNone')
print('')
def find_events():
print('------------------------------------------------------')
print('Events:')
events = telem.get_events()
if events:
pprint(events)
else:
print('\tNone')
print('')
def find_bomb_points(friendly=True):
if friendly:
print('Friendly Bomb Points:')
bomb_points = [obj for obj in telem.map_info.defend_points() if obj.friendly]
else:
print('Enemy Bomb Points:')
bomb_points = [obj for obj in telem.map_info.bombing_points() if not obj.friendly]
if bomb_points:
for bomb_point in bomb_points:
print('\tBombing Point: {}'.format(bomb_point.position_ll))
else:
print('\tNone')
print(' ')
def find_airfields(friendly=True):
if friendly:
print('Friendly Airfields:')
airfields = [obj for obj in telem.map_info.airfields() if obj.friendly]
else:
print('Enemy Airfields:')
airfields = [obj for obj in telem.map_info.airfields() if not obj.friendly]
if airfields:
for airfield in airfields:
print('\tEast Coordinate:\t{}'.format(airfield.east_end_ll))
print('\tSouth Coordinate:\t{}'.format(airfield.south_end_ll))
print('\tRunway Heading:\t\t{} °'.format(airfield.runway_dir))
print('\tRunway Length:\t\t{} km'.format(mapinfo.coord_dist(*airfield.east_end_ll, *airfield.south_end_ll)))
print('')
else:
print('\tNone')
print('')
def find_planes(friendly=True):
if friendly:
print('Friendly Planes:')
planes = [obj for obj in telem.map_info.planes() if obj.friendly]
else:
print('Enemy Planes:')
planes = [obj for obj in telem.map_info.planes() if not obj.friendly]
if planes:
for plane in planes:
print('\tPosition:\t{}'.format(plane.position_ll))
print('\tHeading:\t{}'.format(plane.hdg))
print('')
else:
print('\tNone')
print('')
def find_tanks(friendly=True):
if friendly:
print('Friendly Tanks:')
tanks = [obj for obj in telem.map_info.tanks() if obj.friendly]
else:
print('Enemy Tanks:')
tanks = [obj for obj in telem.map_info.tanks() if not obj.friendly]
if tanks:
for tank in tanks:
print('\tPosition:\t{}'.format(tank.position_ll))
print('\tHeading:\t{}'.format(tank.hdg))
print('')
else:
print('\tNone')
print('')
def find_AAAs(friendly=True):
if friendly:
print('Friendly AAAs:')
AAAs = [obj for obj in telem.map_info.AAAs() if obj.friendly]
else:
print('Enemy AAAs:')
AAAs = [obj for obj in telem.map_info.AAAs() if not obj.friendly]
if AAAs:
for AAA in AAAs:
print('\tPosition:\t{}'.format(AAA.position_ll))
else:
print('\tNone')
print('')
if __name__ == '__main__':
try:
telem = telemetry.TelemInterface()
while not telem.get_telemetry():
pass
find_map_info()
find_all_airfields()
find_all_planes()
find_all_tanks()
find_all_bomb_points()
find_all_AAAs()
find_basic_telemetry()
find_comments()
find_events()
except KeyboardInterrupt:
print('Closing')
```
# Example Output:
```
------------------------------------------------------
Map Info:
Name: Ruhr
Upper Left Hand Corner Coordinate: [51.73829303094487, 6.437537416826182]
Size: 65km x 65km
------------------------------------------------------
Friendly Airfields:
East Coordinate: [51.43642186048186, 6.930164507472621]
South Coordinate: [51.42827500146132, 6.9187980201946795]
Runway Heading: 41.012963528358455 °
Runway Length: 1.2019773371283782 km
Enemy Airfields:
None
------------------------------------------------------
Friendly Planes:
Position: [51.44442707177771, 6.9048435542278]
Heading: 191.7501316630443
Position: [51.444117867741056, 6.904189278772745]
Heading: 191.7327479963323
Position: [51.44454697658904, 6.904059699788993]
Heading: 191.73257970022075
Position: [51.44424583467913, 6.903432678896212]
Heading: 191.73146722121177
Enemy Planes:
None
------------------------------------------------------
Friendly Tanks:
None
Enemy Tanks:
Position: [51.448172861547235, 6.883101199222394]
Heading: 0
------------------------------------------------------
Friendly Bomb Points:
None
Enemy Bomb Points:
None
------------------------------------------------------
Friendly AAAs:
Position: [51.43844836391245, 6.925201117152168]
Position: [51.43829338882834, 6.9249774559908275]
Position: [51.438609103385076, 6.925442639430436]
Position: [51.4276199323936, 6.924573106340005]
Position: [51.42778836500274, 6.924790301773768]
Position: [51.427463714376124, 6.924367280891929]
Position: [51.438792600079246, 6.9392408728402595]
Enemy AAAs:
None
------------------------------------------------------
Basic Telemetry:
{'IAS': 0,
'airframe': 'bf_110g_4',
'altitude': 59.221455,
'flapState': 0,
'gearState': 100,
'heading': 40.639851,
'lat': 51.428588129131136,
'lon': 6.919188108689251,
'pitch': 10.894329,
'roll': 0.010828}
------------------------------------------------------
Comments:
None
------------------------------------------------------
Events:
{'events': [], 'damage': [{'id': 1, 'msg': 'yn1/error/82220002', 'sender': '', 'enemy': False, 'mode': ''}]}
{'damage': [{'enemy': False,
'id': 1,
'mode': '',
'msg': 'yn1/error/82220002',
'sender': ''}],
'events': []}
```
Raw data
{
"_id": null,
"home_page": "https://github.com/PowerBroker2/WarThunder",
"name": "WarThunder",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "War Thunder",
"author": "Power_Broker",
"author_email": "gitstuff2@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/3b/5a/f9c9d2eb251342462f489efa8a7b7cc00c7d6a40ca344adc04fb7f365afc/WarThunder-2.3.4.tar.gz",
"platform": null,
"description": "[![GitHub version](https://badge.fury.io/gh/PowerBroker2%2FWarThunder.svg)](https://badge.fury.io/gh/PowerBroker2%2FWarThunder) [![PyPI version](https://badge.fury.io/py/WarThunder.svg)](https://badge.fury.io/py/WarThunder)\r\n\r\n# Overview\r\nPython package to access vehicle telemetry and match data in real-time while in War Thunder air battles (NOT tanks). Here are some things you can access/do with this package:\r\n- Get telemetry information on your vehicle and others identified on user's mini map\r\n - Data available for both user and other match player's vehicles:\r\n - Location in latitude/longitude (DD)\r\n - Heading angle\r\n - Airspeed\r\n - Data avilable only for user's vehicle:\r\n - Pitch angle\r\n - Roll angle\r\n - Flap state\r\n - Gear state\r\n - Altitude\r\n- Data on other objects identified on user's mini map\r\n - Object's location in latitude/longitude (DD)\r\n - Airfields have 2 locations, one for each end of the runway\r\n - Object's faction (friendly or enemy)\r\n - Object's type (fighter, bomber, heavy tank, etc)\r\n- Map name\r\n- Chat comments (anything typed into chat)\r\n- Match events (death, crash, etc)\r\n- Log data in an [ACMI format](https://www.tacview.net/documentation/acmi/en/) compatible with [Tacview](https://www.tacview.net/)\r\n\r\nThis library makes use of War Thunder's localhost server pages (http://localhost:8111/indicators, http://localhost:8111/state, http://localhost:8111/map.img, http://localhost:8111/map_obj.json, and http://localhost:8111/map_info.json, and more!) that the game automatically serves when you launch a game match. If it is an air battle, these pages will include JSON formatted data with valid airplane telemetry. This telemetry is then converted and returned to the calling function/user.\r\n\r\nThe data can then be easily used for any custom application (i.e. telemetry datalogger and grapher).\r\n\r\n# Example Use-Case:\r\nhttps://github.com/PowerBroker2/Thunder_Viewer\r\n\r\n# To Install\r\n`pip install WarThunder`\r\n\r\n# Example Python Script\r\n```python\r\nfrom WarThunder import telemetry\r\nfrom WarThunder import mapinfo\r\nfrom pprint import pprint\r\n\r\n\r\ndef find_map_info():\r\n print('------------------------------------------------------')\r\n print('Map Info:')\r\n print('\\tName:\\t\\t\\t\\t\\t{}'.format(telem.map_info.grid_info['name']))\r\n print('\\tUpper Left Hand Corner Coordinate:\\t[{}, {}]'.format(telem.map_info.grid_info['ULHC_lat'], telem.map_info.grid_info['ULHC_lon']))\r\n print('\\tSize:\\t\\t\\t\\t\\t{}km x {}km'.format(telem.map_info.grid_info['size_km'], telem.map_info.grid_info['size_km']))\r\n print('')\r\n\r\ndef find_all_bomb_points():\r\n print('------------------------------------------------------')\r\n find_bomb_points(True)\r\n find_bomb_points(False)\r\n\r\ndef find_all_airfields():\r\n print('------------------------------------------------------')\r\n find_airfields(True)\r\n find_airfields(False)\r\n\r\ndef find_all_planes():\r\n print('------------------------------------------------------')\r\n find_planes(True)\r\n find_planes(False)\r\n\r\ndef find_all_tanks():\r\n print('------------------------------------------------------')\r\n find_tanks(True)\r\n find_tanks(False)\r\n\r\ndef find_all_AAAs():\r\n print('------------------------------------------------------')\r\n find_AAAs(True)\r\n find_AAAs(False)\r\n \r\ndef find_basic_telemetry():\r\n print('------------------------------------------------------')\r\n print('Basic Telemetry:')\r\n pprint(telem.basic_telemetry)\r\n print('')\r\n \r\ndef find_comments():\r\n print('------------------------------------------------------')\r\n print('Comments:')\r\n comments = telem.get_comments()\r\n \r\n if comments:\r\n pprint(comments)\r\n else:\r\n print('\\tNone')\r\n print('')\r\n \r\ndef find_events():\r\n print('------------------------------------------------------')\r\n print('Events:')\r\n events = telem.get_events()\r\n \r\n if events:\r\n pprint(events)\r\n else:\r\n print('\\tNone')\r\n print('')\r\n\r\ndef find_bomb_points(friendly=True):\r\n if friendly:\r\n print('Friendly Bomb Points:')\r\n bomb_points = [obj for obj in telem.map_info.defend_points() if obj.friendly]\r\n else:\r\n print('Enemy Bomb Points:')\r\n bomb_points = [obj for obj in telem.map_info.bombing_points() if not obj.friendly]\r\n \r\n if bomb_points:\r\n for bomb_point in bomb_points:\r\n print('\\tBombing Point: {}'.format(bomb_point.position_ll))\r\n else:\r\n print('\\tNone')\r\n print(' ')\r\n\r\ndef find_airfields(friendly=True):\r\n if friendly:\r\n print('Friendly Airfields:')\r\n airfields = [obj for obj in telem.map_info.airfields() if obj.friendly]\r\n else:\r\n print('Enemy Airfields:')\r\n airfields = [obj for obj in telem.map_info.airfields() if not obj.friendly]\r\n \r\n if airfields:\r\n for airfield in airfields:\r\n print('\\tEast Coordinate:\\t{}'.format(airfield.east_end_ll))\r\n print('\\tSouth Coordinate:\\t{}'.format(airfield.south_end_ll))\r\n print('\\tRunway Heading:\\t\\t{} \u00c2\u00b0'.format(airfield.runway_dir))\r\n print('\\tRunway Length:\\t\\t{} km'.format(mapinfo.coord_dist(*airfield.east_end_ll, *airfield.south_end_ll)))\r\n print('')\r\n else:\r\n print('\\tNone')\r\n print('')\r\n\r\ndef find_planes(friendly=True):\r\n if friendly:\r\n print('Friendly Planes:')\r\n planes = [obj for obj in telem.map_info.planes() if obj.friendly]\r\n else:\r\n print('Enemy Planes:')\r\n planes = [obj for obj in telem.map_info.planes() if not obj.friendly]\r\n \r\n if planes:\r\n for plane in planes:\r\n print('\\tPosition:\\t{}'.format(plane.position_ll))\r\n print('\\tHeading:\\t{}'.format(plane.hdg))\r\n print('')\r\n else:\r\n print('\\tNone')\r\n print('')\r\n \r\n\r\ndef find_tanks(friendly=True):\r\n if friendly:\r\n print('Friendly Tanks:')\r\n tanks = [obj for obj in telem.map_info.tanks() if obj.friendly]\r\n else:\r\n print('Enemy Tanks:')\r\n tanks = [obj for obj in telem.map_info.tanks() if not obj.friendly]\r\n \r\n if tanks:\r\n for tank in tanks:\r\n print('\\tPosition:\\t{}'.format(tank.position_ll))\r\n print('\\tHeading:\\t{}'.format(tank.hdg))\r\n print('')\r\n else:\r\n print('\\tNone')\r\n print('')\r\n\r\ndef find_AAAs(friendly=True):\r\n if friendly:\r\n print('Friendly AAAs:')\r\n AAAs = [obj for obj in telem.map_info.AAAs() if obj.friendly]\r\n else:\r\n print('Enemy AAAs:')\r\n AAAs = [obj for obj in telem.map_info.AAAs() if not obj.friendly]\r\n \r\n if AAAs:\r\n for AAA in AAAs:\r\n print('\\tPosition:\\t{}'.format(AAA.position_ll))\r\n else:\r\n print('\\tNone')\r\n print('')\r\n\r\n\r\nif __name__ == '__main__':\r\n try:\r\n telem = telemetry.TelemInterface()\r\n \r\n while not telem.get_telemetry():\r\n pass\r\n \r\n find_map_info()\r\n find_all_airfields()\r\n find_all_planes()\r\n find_all_tanks()\r\n find_all_bomb_points()\r\n find_all_AAAs()\r\n find_basic_telemetry()\r\n find_comments()\r\n find_events()\r\n \r\n except KeyboardInterrupt:\r\n print('Closing')\r\n```\r\n\r\n# Example Output:\r\n\r\n```\r\n------------------------------------------------------\r\nMap Info:\r\n Name: Ruhr\r\n Upper Left Hand Corner Coordinate: [51.73829303094487, 6.437537416826182]\r\n Size: 65km x 65km\r\n\r\n------------------------------------------------------\r\nFriendly Airfields:\r\n East Coordinate: [51.43642186048186, 6.930164507472621]\r\n South Coordinate: [51.42827500146132, 6.9187980201946795]\r\n Runway Heading: 41.012963528358455 \u00c2\u00b0\r\n Runway Length: 1.2019773371283782 km\r\n\r\n\r\nEnemy Airfields:\r\n None\r\n\r\n------------------------------------------------------\r\nFriendly Planes:\r\n Position: [51.44442707177771, 6.9048435542278]\r\n Heading: 191.7501316630443\r\n\r\n Position: [51.444117867741056, 6.904189278772745]\r\n Heading: 191.7327479963323\r\n\r\n Position: [51.44454697658904, 6.904059699788993]\r\n Heading: 191.73257970022075\r\n\r\n Position: [51.44424583467913, 6.903432678896212]\r\n Heading: 191.73146722121177\r\n\r\n\r\nEnemy Planes:\r\n None\r\n\r\n------------------------------------------------------\r\nFriendly Tanks:\r\n None\r\n\r\nEnemy Tanks:\r\n Position: [51.448172861547235, 6.883101199222394]\r\n Heading: 0\r\n\r\n\r\n------------------------------------------------------\r\nFriendly Bomb Points:\r\n None\r\n \r\nEnemy Bomb Points:\r\n None\r\n \r\n------------------------------------------------------\r\nFriendly AAAs:\r\n Position: [51.43844836391245, 6.925201117152168]\r\n Position: [51.43829338882834, 6.9249774559908275]\r\n Position: [51.438609103385076, 6.925442639430436]\r\n Position: [51.4276199323936, 6.924573106340005]\r\n Position: [51.42778836500274, 6.924790301773768]\r\n Position: [51.427463714376124, 6.924367280891929]\r\n Position: [51.438792600079246, 6.9392408728402595]\r\n\r\nEnemy AAAs:\r\n None\r\n\r\n------------------------------------------------------\r\nBasic Telemetry:\r\n{'IAS': 0,\r\n 'airframe': 'bf_110g_4',\r\n 'altitude': 59.221455,\r\n 'flapState': 0,\r\n 'gearState': 100,\r\n 'heading': 40.639851,\r\n 'lat': 51.428588129131136,\r\n 'lon': 6.919188108689251,\r\n 'pitch': 10.894329,\r\n 'roll': 0.010828}\r\n\r\n------------------------------------------------------\r\nComments:\r\n None\r\n\r\n------------------------------------------------------\r\nEvents:\r\n{'events': [], 'damage': [{'id': 1, 'msg': 'yn1/error/82220002', 'sender': '', 'enemy': False, 'mode': ''}]}\r\n{'damage': [{'enemy': False,\r\n 'id': 1,\r\n 'mode': '',\r\n 'msg': 'yn1/error/82220002',\r\n 'sender': ''}],\r\n 'events': []}\r\n ```\r\n",
"bugtrack_url": null,
"license": "",
"summary": "Python package used to access air vehicle telemetry while in War Thunder air battles",
"version": "2.3.4",
"project_urls": {
"Download": "https://github.com/PowerBroker2/WarThunder/archive/2.3.4.tar.gz",
"Homepage": "https://github.com/PowerBroker2/WarThunder"
},
"split_keywords": [
"war",
"thunder"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "3c90a0f1c53ad021beee7c3f3446c166c43ded77d7d07994e2a8d3082409591c",
"md5": "d86caf9fbce3f9c3c443b53129274b48",
"sha256": "76eb1237629f77b1f5c1a5e0a205f257887ca037854033df3a7a01ab1e841c90"
},
"downloads": -1,
"filename": "WarThunder-2.3.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "d86caf9fbce3f9c3c443b53129274b48",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 16156,
"upload_time": "2023-05-28T02:54:49",
"upload_time_iso_8601": "2023-05-28T02:54:49.414837Z",
"url": "https://files.pythonhosted.org/packages/3c/90/a0f1c53ad021beee7c3f3446c166c43ded77d7d07994e2a8d3082409591c/WarThunder-2.3.4-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "3b5af9c9d2eb251342462f489efa8a7b7cc00c7d6a40ca344adc04fb7f365afc",
"md5": "de4e0d173aeef0efd097c95e1e30ccd2",
"sha256": "4424ce6047d9b682dde5fceff808db8e71b3d460f0a8aa1c7ef4c45e8b84eb88"
},
"downloads": -1,
"filename": "WarThunder-2.3.4.tar.gz",
"has_sig": false,
"md5_digest": "de4e0d173aeef0efd097c95e1e30ccd2",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 18284,
"upload_time": "2023-05-28T02:54:51",
"upload_time_iso_8601": "2023-05-28T02:54:51.401824Z",
"url": "https://files.pythonhosted.org/packages/3b/5a/f9c9d2eb251342462f489efa8a7b7cc00c7d6a40ca344adc04fb7f365afc/WarThunder-2.3.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-05-28 02:54:51",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "PowerBroker2",
"github_project": "WarThunder",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "warthunder"
}