LotATC support
rurounijones opened this issue · comments
DArt, the creator of LotATC is interested in potentially using DCS-gRPC as an alternative back-end to get data out of, and commands into, DCS.
He did a bit of searching in his codebase and determined he uses the following APIs. If we want to enable DCS-gRPC as a back-end for LotATC then we would need to provide these APIs or an equivalent of. Some of them we already provide or have alternatives to; and some of them I have never heard of.
- DCS.getATCradiosData - TODO
- DCS.getAvailableCoalitions - TODO (?). Always seems to return red & blue.
- DCS.getAvailableSlots - TODO
- DCS.getCurrentMission - Returns a huge table, most of the info is available via other APIs. Need to know what is needed
- DCS.getMissionDescription
- DCS.getMissionFilename
- DCS.getMissionName
- DCS.getMissionOptions - Not sure what used for
- DCS.getModelTime - Handled by
Timer.GetTime
DCS-gRPC API - DCS.getPause
- DCS.getRealTime - No idea what this returns
- DCS.isServer
- DCS.reloadOptions - Not sure if applicable
- DCS.setPause
- DCS.stopMission
- DCS.getUnitProperty -- Should be covered by the Unit Stream
- DCS.getUnitType -- Should be covered by the Unit Stream
- Export.GetDevice -- Not sure what used for and not accessible from DCS-gRPC accessible environments
- Export.LoGeoCoordinatesToLoCoordinates - Not sure needed with unit stream.
- Export.LoGetModelTime - Not sure needed with unit stream.
- Export.LoGetObjectById - Not sure needed with unit stream.
- Export.LoGetSelfData - Not sure needed with unit stream.
- Export.LoGetWorldObjects - Not sure needed with unit stream.
- Export.LoLoCoordinatesToGeoCoordinates - Not sure needed with unit stream.
- Export.LoLoCoordinatesroGeoCoordinates - Not sure needed with unit stream.
- net.get_my_player_id - Always returns 0
- net.get_player_info - Returned as a detailed response with compounded
get_player_list
- net.get_player_list - Returned as a detailed response with compounded
get_player_list
- net.get_server_id - Always returns 0
- net.missionlist_get - TODO
- net.missionlist_run - TODO
- net.recv_chat - Using the
PlayerSendChatEvent
message in the event stream - net.send_chat
- net.send_chat_to
The following are temporarily assessed as probably not needed if using DCS-gRPC:
- net.dostring_in
- DCS.setUserCallbacks
- net.log
- net.lua2json
- DCS.setUserCallbacks
- net.dostring_in
- net.log
- net.lua2json
I wouldn't be surprised if those are only necessary for the custom RPC of LotATC. So potentially not necessary anymore when the communication goes through gRPC.
- net.recv_chat
Maybe covered by the PlayerSendChatEvent
event.
Thanks. Updated
DCS.getCurrentMission
returns
{
"mission": {
"coalition": {
"blue": {
"bullseye": {
"x": -291014,
"y": 617414
},
"country": [{
"id": 2,
"name": "USA",
"plane": {
"group": [{
"communication": true,
"frequency": 251,
"groupId": 3,
"hidden": false,
"modulation": 0,
"name": "Aerial-1",
"radioSet": false,
"route": {
"points": [{
"ETA": 0,
"ETA_locked": true,
"action": "From Parking Area",
"airdromeId": 23,
"alt": 13,
"alt_type": "BARO",
"formation_template": "",
"properties": {
"angle": 0,
"scale": 0,
"steer": 2,
"vangle": 0,
"vnav": 1
},
"speed": 138.88888888889,
"speed_locked": true,
"task": {
"id": "ComboTask",
"params": {
"tasks": [{
"auto": true,
"enabled": true,
"id": "EngageTargets",
"key": "CAS",
"number": 1,
"params": {
"priority": 0,
"targetTypes": ["Helicopters", "Ground Units", "Light armed ships"]
}
}, {
"auto": true,
"enabled": true,
"id": "WrappedAction",
"number": 2,
"params": {
"action": {
"id": "Option",
"params": {
"name": 1,
"value": 2
}
}
}
}, {
"auto": true,
"enabled": true,
"id": "WrappedAction",
"number": 3,
"params": {
"action": {
"id": "Option",
"params": {
"name": 3,
"value": 1
}
}
}
}, {
"auto": true,
"enabled": true,
"id": "WrappedAction",
"number": 4,
"params": {
"action": {
"id": "Option",
"params": {
"formationIndex": 2,
"name": 5,
"value": 131074,
"variantIndex": 2
}
}
}
}, {
"auto": true,
"enabled": true,
"id": "WrappedAction",
"number": 5,
"params": {
"action": {
"id": "Option",
"params": {
"name": 15,
"value": true
}
}
}
}, {
"auto": true,
"enabled": true,
"id": "WrappedAction",
"number": 6,
"params": {
"action": {
"id": "Option",
"params": {
"name": 21,
"noTargetTypes": ["Fighters", "Multirole fighters", "Bombers", "Helicopters", "Infantry", "Fortifications", "Tanks", "IFV", "APC", "Artillery", "Unarmed vehicles", "AAA", "SR SAM", "MR SAM", "LR SAM", "Aircraft Carriers", "Cruisers", "Destroyers", "Frigates", "Corvettes", "Light armed ships", "Unarmed ships", "Submarines", "Cruise missiles", "Antiship Missiles", "AA Missiles", "AG Missiles", "SA Missiles"],
"targetTypes": {},
"value": "none;"
}
}
}
}, {
"auto": true,
"enabled": true,
"id": "WrappedAction",
"number": 7,
"params": {
"action": {
"id": "Option",
"params": {
"name": 19,
"value": true
}
}
}
}, {
"auto": true,
"enabled": true,
"id": "WrappedAction",
"number": 8,
"params": {
"action": {
"id": "EPLRS",
"params": {
"groupId": 1,
"value": true
}
}
}
}]
}
},
"type": "TakeOffParking",
"x": -281607.28417614,
"y": 646373.17498617
}]
},
"start_time": 0,
"task": "CAS",
"tasks": {},
"uncontrollable": false,
"uncontrolled": false,
"units": [{
"AddPropAircraft": {},
"alt": 13,
"alt_type": "BARO",
"callsign": [1, 1, 1],
"heading": 0,
"livery_id": "25th FS Osan AB, Korea (OS)",
"name": "Aerial-1-1",
"onboard_num": "010",
"parking": 2,
"parking_id": "01",
"payload": {
"ammo_type": 1,
"chaff": 240,
"flare": 240,
"fuel": 5029,
"gun": 100,
"pylons": {}
},
"psi": 0,
"skill": "Client",
"speed": 138.88888888889,
"type": "A-10C_2",
"unitId": 3,
"x": -281607.28417614,
"y": 646373.17498617
}],
"x": -281607.28417614,
"y": 646373.17498617
}]
},
"ship": {
"group": [{
"groupId": 1,
"hidden": false,
"name": "Naval-1",
"route": {
"points": [{
"ETA": 0,
"ETA_locked": true,
"action": "Turning Point",
"alt": 0,
"alt_type": "BARO",
"formation_template": "",
"speed": 0,
"speed_locked": true,
"task": {
"id": "ComboTask",
"params": {
"tasks": [{
"auto": true,
"enabled": true,
"id": "WrappedAction",
"number": 1,
"params": {
"action": {
"id": "ActivateBeacon",
"params": {
"AA": false,
"bearing": true,
"callsign": "TKR",
"channel": 1,
"frequency": 962000000,
"modeChannel": "X",
"system": 3,
"type": 4
}
}
}
}]
}
},
"type": "Turning Point",
"x": -335535.1908507,
"y": 564134.67683634
}]
},
"start_time": 0,
"tasks": {},
"uncontrollable": false,
"units": [{
"frequency": 127500000,
"heading": 5.4885388525494,
"modulation": 0,
"name": "Naval-1-1",
"skill": "Average",
"type": "CVN_73",
"unitId": 1,
"x": -335535.1908507,
"y": 564134.67683634
}],
"visible": false,
"x": -335535.1908507,
"y": 564134.67683634
}]
}
}],
"name": "blue",
"nav_points": {}
},
"neutrals": {
"bullseye": {
"x": 0,
"y": 0
},
"country": {},
"name": "neutrals",
"nav_points": {}
},
"red": {
"bullseye": {
"x": 11557,
"y": 371700
},
"country": [{
"id": 0,
"name": "Russia",
"ship": {
"group": [{
"groupId": 2,
"hidden": false,
"name": "Naval-2",
"route": {
"points": [{
"ETA": 0,
"ETA_locked": true,
"action": "Turning Point",
"alt": 0,
"alt_type": "BARO",
"formation_template": "",
"speed": 0,
"speed_locked": true,
"task": {
"id": "ComboTask",
"params": {
"tasks": {}
}
},
"type": "Turning Point",
"x": -66396.909595474,
"y": 269989.3543495
}]
},
"start_time": 0,
"tasks": {},
"uncontrollable": false,
"units": [{
"frequency": 127500000,
"heading": 0,
"modulation": 0,
"name": "Naval-2-1",
"skill": "Average",
"type": "CV_1143_5",
"unitId": 2,
"x": -66396.909595474,
"y": 269989.3543495
}],
"visible": false,
"x": -66396.909595474,
"y": 269989.3543495
}]
}
}],
"name": "red",
"nav_points": {}
}
},
"coalitions": {
"blue": [21, 11, 8, 80, 28, 26, 13, 5, 16, 6, 15, 20, 12, 40, 45, 9, 46, 10, 3, 4, 1, 2],
"neutrals": [70, 83, 23, 65, 86, 64, 25, 63, 76, 84, 29, 62, 30, 78, 87, 31, 61, 32, 33, 60, 17, 35, 69, 36, 59, 71, 79, 58, 57, 56, 55, 88, 73, 39, 89, 54, 77, 72, 41, 42, 44, 85, 75, 53, 22, 52, 66, 51, 74, 82, 7, 68, 50, 49, 48, 67],
"red": [18, 24, 27, 81, 34, 37, 38, 0, 43, 19, 47]
},
"currentKey": 331,
"date": {
"Day": 21,
"Month": 6,
"Year": 2016
},
"descriptionBlueTask": "DictKey_descriptionBlueTask_3",
"descriptionNeutralsTask": "DictKey_descriptionNeutralsTask_4",
"descriptionRedTask": "DictKey_descriptionRedTask_2",
"descriptionText": "DictKey_descriptionText_1",
"failures": {},
"forcedOptions": {},
"goals": {},
"groundControl": {
"isPilotControlVehicles": false,
"passwords": {
"artillery_commander": {},
"forward_observer": {},
"instructor": {},
"observer": {}
},
"roles": {
"artillery_commander": {
"blue": 1,
"neutrals": 0,
"red": 1
},
"forward_observer": {
"blue": 1,
"neutrals": 0,
"red": 1
},
"instructor": {
"blue": 1,
"neutrals": 0,
"red": 1
},
"observer": {
"blue": 1,
"neutrals": 0,
"red": 1
}
}
},
"map": {
"centerX": -282347.42612338,
"centerY": 647025.05197987,
"zoom": 21725.381275432
},
"maxDictId": 5,
"pictureFileNameB": {},
"pictureFileNameN": {},
"pictureFileNameR": {},
"requiredModules": {},
"result": {
"blue": {
"actions": {},
"conditions": {},
"func": {}
},
"offline": {
"actions": {},
"conditions": {},
"func": {}
},
"red": {
"actions": {},
"conditions": {},
"func": {}
},
"total": 0
},
"sortie": "DictKey_sortie_5",
"start_time": 28800,
"theatre": "Caucasus",
"trig": {
"actions": {},
"conditions": {},
"custom": {},
"customStartup": {},
"events": {},
"flag": {},
"func": {},
"funcStartup": {}
},
"triggers": {
"zones": {}
},
"trigrules": {},
"version": 20,
"weather": {
"atmosphere_type": 0,
"clouds": {
"base": 2500,
"density": 0,
"iprecptns": 0,
"preset": "Preset2",
"thickness": 200
},
"cyclones": {},
"dust_density": 0,
"enable_dust": false,
"enable_fog": false,
"fog": {
"thickness": 0,
"visibility": 0
},
"groundTurbulence": 0,
"modifiedTime": false,
"name": "Winter, clean sky",
"qnh": 760,
"season": {
"temperature": 20
},
"type_weather": 0,
"visibility": {
"distance": 80000
},
"wind": {
"at2000": {
"dir": 0,
"speed": 0
},
"at8000": {
"dir": 0,
"speed": 0
},
"atGround": {
"dir": 0,
"speed": 0
}
}
}
}
}
Need to investigate to see if this is covered by other APIs
DCS.GetMissionOptions()
returns
{
"VR": {
"bloom": true,
"box_mouse_cursor": true,
"custom_IPD": 63.5,
"custom_IPD_enable": false,
"enable": true,
"hand_controllers": true,
"hand_controllers_debug_draw": false,
"hand_controllers_use_stick": true,
"hand_controllers_use_throttle": true,
"interaction_with_grip_only": false,
"mirror_crop": false,
"mirror_source": 0,
"mirror_use_DCS_resolution": false,
"msaaMaskSize": 0.42,
"pixel_density": 1,
"prefer_built_in_audio": true,
"use_mouse": false
},
"difficulty": {
"RBDAI": true,
"autoTrimmer": false,
"avionicsLanguage": "english",
"birds": 0,
"cockpitStatusBarAllowed": false,
"cockpitVisualRM": false,
"controlsIndicator": true,
"easyCommunication": true,
"easyFlight": false,
"easyRadar": false,
"externalViews": true,
"fuel": false,
"geffect": "realistic",
"hideStick": true,
"iconsTheme": "nato",
"immortal": false,
"labels": 3,
"map": true,
"miniHUD": true,
"optionsView": "optview_all",
"padlock": true,
"permitCrash": true,
"radio": false,
"reports": true,
"setGlobal": true,
"spectatorExternalViews": true,
"tips": true,
"units": "imperial",
"unrestrictedSATNAV": false,
"userMarks": true,
"userSnapView": true,
"wakeTurbulence": true,
"weapons": false
},
"format": 1,
"graphics": {
"DOF": 0,
"LensEffects": 0,
"MSAA": 0,
"SSAA": 0,
"SSAO": 0,
"SSLR": 0,
"anisotropy": 1,
"aspect": 1.777777777777,
"box_mouse_cursor": false,
"chimneySmokeDensity": 5,
"civTraffic": "low",
"clouds": 1,
"clutterMaxDistance": 0,
"cockpitGI": 1,
"effects": 3,
"flatTerrainShadows": 0,
"forestDetailsFactor": 1,
"forestDistanceFactor": 1,
"fullScreen": false,
"heatBlr": 1,
"height": 2520,
"lights": 2,
"messagesFontScale": 1,
"motionBlur": 0,
"multiMonitorSetup": "jonesnew",
"outputGamma": 2.2,
"preloadRadius": 100300,
"rainDroplets": 1,
"scaleGui": 1,
"sceneryDetailsFactor": 1,
"secondaryShadows": 0,
"shadowTree": false,
"shadows": 4,
"sync": false,
"terrainTextures": "max",
"textures": 1,
"useDeferredShading": 1,
"visibRange": "High",
"water": 0,
"width": 2560
},
"miscellaneous": {
"Coordinate_Display": "MGRS",
"F2_view_effects": 1,
"TrackIR_external_views": true,
"accidental_failures": false,
"allow_server_screenshots": true,
"autologin": true,
"backup": false,
"backupTime": 5,
"chat_window_at_start": true,
"collect_stat": false,
"f10_awacs": true,
"f11_free_camera": true,
"f5_nearest_ac": true,
"force_feedback_enabled": true,
"headmove": false,
"show_pilot_body": false,
"synchronize_controls": false
},
"playerName": "New callsign",
"plugins": {
"A-10C": {
"CPLocalList": "default"
},
"A-10C_2": {
"CPLocalList": "aged",
"defaultGunMode": 0,
"hmdEye": 1
},
"AV8BNA": {
"CPLocalList": "default",
"INS_Alignment": 1,
"INS_GYROHasNAV": false,
"MPCD_EXPORT": false,
"USE_REAL_TDC": false
},
"CA": {
"ground_aim_helper": true,
"ground_automatic": true,
"ground_engine_autostart": true,
"ground_isometric": true,
"ground_platform_shake": false,
"ground_target_info": true,
"kompass_options": 1
},
"CaptoGlove": {
"armBending": 60,
"enable": false,
"forearmLength_Left": 30,
"forearmLength_Right": 30,
"mouseClickSrc": 0,
"pitchOffsetGlove_Left": 0,
"pitchOffsetGlove_Right": 0,
"pitchOffsetShoulder_Left": 0,
"pitchOffsetShoulder_Right": 0,
"set_attach": false,
"set_debug": false,
"set_symmetrically": false,
"shoulderJointX_Left": -15,
"shoulderJointX_Right": -15,
"shoulderJointY_Left": -23,
"shoulderJointY_Right": -23,
"shoulderJointZ_Left": 23,
"shoulderJointZ_Right": 23,
"shoulderLength_Left": 40,
"shoulderLength_Right": 40,
"useBending": false,
"yawOffsetGlove_Left": 0,
"yawOffsetGlove_Right": 0,
"yawOffsetShoulder_Left": 0,
"yawOffsetShoulder_Right": 0
},
"DCS-SRS": {
"srsAutoLaunchEnabled": true,
"srsOverlayCompactModeEnabled": false,
"srsOverlayEnabled": false,
"srsOverlayHelpTextEnabled": true
},
"F-5E-3": {
"CPLocalList": "default",
"JoystickMode": 0,
"SightCamera": 0,
"aiHelper": false
},
"F/A-18C": {
"CPLocalList": "default",
"F18RealisticTDC": true,
"abDetent": 0,
"canopyReflections": 0,
"hmdEye": 1,
"mfdReflections": 0
},
"FC3": {
"CPLocalList_A-10A": "default",
"CPLocalList_F-15C": "default",
"CPLocalList_J-11A": "default",
"CPLocalList_MiG-29A": "default",
"CPLocalList_MiG-29G": "default",
"CPLocalList_MiG-29S": "default",
"CPLocalList_Su-25": "default",
"CPLocalList_Su-27": "default",
"CPLocalList_Su-33": "default"
},
"LeapMotion": {
"enable": false,
"handUseStick": false,
"handUseThrottle": false,
"mouseClickSrc": 0,
"pointerUseType": 0,
"set_debug": false
},
"M-2000C": {
"CPLocalList": "default",
"EZ_LAUNCH_ALERT": false,
"FUEL_DETOT_AUTO": false,
"MW_KNOBS_SPEED": 0,
"PCN_DIGIT_MSG": true,
"RADAR_CLUTTERQMC": true,
"RADAR_FULLASYNC": true,
"RADAR_MAPOBJECTS": true,
"RADIO_PTTMENU": true,
"RAND_RDR_CHANNEL": false,
"REAL_FREQ_REP": true,
"REFUEL_HACK": false,
"THROTTLE_AB_DETENT": 90,
"THROTTLE_CO_DETENT": 15,
"UNI_ALIGNED": false,
"UNI_NODRIFT": false,
"VTB_ENLARGE": 0,
"VTB_FOV_ENABLE": true,
"VTB_FOV_HEIGHT": 150,
"VTB_FOV_SIZE": 130
},
"Su-25T": {
"CPLocalList": "default"
},
"Supercarrier": {
"Use_native_ATC_text": false,
"enable_FLOLS_overlay": true
},
"TF-51D": {
"CPLocalList": "default",
"assistance": 100,
"autoRudder": false
},
"Tacview": {
"tacviewAutoDiscardFlights": 10,
"tacviewBookmarkShortcut": 0,
"tacviewDebugMode": 0,
"tacviewExportPath": "",
"tacviewFlightDataRecordingEnabled": true,
"tacviewModuleEnabled": true,
"tacviewMultiplayerFlightsAsClient": 2,
"tacviewMultiplayerFlightsAsHost": 2,
"tacviewRealTimeTelemetryEnabled": true,
"tacviewRealTimeTelemetryPassword": "",
"tacviewRealTimeTelemetryPort": "42674",
"tacviewRemoteControlEnabled": false,
"tacviewRemoteControlPassword": "",
"tacviewRemoteControlPort": "42675",
"tacviewSinglePlayerFlights": 2,
"tacviewTerrainExport": 0
},
"UH-1H": {
"CPLocalList": "default",
"UH1HCockpitShake": 50,
"UHRudderTrimmer": false,
"UHTrimmingMethod": 0,
"autoPilot": false,
"weapTooltips": false
},
"VRFree": {
"enable": false,
"handUseStick": false,
"handUseThrottle": false,
"mouseClickSrc": 0,
"set_debug": false
}
},
"sound": {
"FakeAfterburner": false,
"GBreathEffect": true,
"cockpit": 78,
"gui": 0,
"headphones": 78,
"headphones_on_external_views": true,
"hear_in_helmet": true,
"hp_output": "{0.0.0.00000000}.{919554ed-6903-4291-8723-07528106d9a7}",
"main_layout": "",
"main_output": "{0.0.0.00000000}.{919554ed-6903-4291-8723-07528106d9a7}",
"microphone_use": 2,
"music": 0,
"play_audio_while_minimized": false,
"radioSpeech": true,
"subtitles": true,
"switches": 100,
"voice_chat": false,
"voice_chat_input": "{0.0.1.00000000}.{0712f303-37f8-4b4d-aa84-9edd57920ed0}",
"voice_chat_output": "{0.0.0.00000000}.{919554ed-6903-4291-8723-07528106d9a7}",
"volume": 59,
"world": 76
},
"views": {
"cockpit": {
"avionics": 3,
"mirrors": false,
"reflections": false
}
}
}
I think we have implemented enough for DArt to implement a decent chunk of the LotATC
features via DCS-gRPC
. There are some with open questions where I am not sure what the API is used for or what values in a huge return table are used. There are some other things that we still need to implement.
However, with the UnitStream
, EventStream
and the synchronous APIs so far I think we have enough to get the main display and update units on the radar map / player lists / unit information feature going and then identifying the actual API gaps during implementation.
@rurounijones great stuff ! Thx, I will try to start a prototype in the next weeks using gRPC for LotAtc. I will certainly have some questions and feedback at this time ! :)