mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
added API descriptions
This commit is contained in:
parent
da0bf650fa
commit
059754fc28
565
Moose Development/Documentation/DCS_ControlAPI.txt
Normal file
565
Moose Development/Documentation/DCS_ControlAPI.txt
Normal file
@ -0,0 +1,565 @@
|
||||
DCS Simulation Control User Scripts
|
||||
====================================
|
||||
|
||||
The behaviour of the DCS can be altered using the *GameGUI.lua scripts.
|
||||
You define the hooks to the DCS events, and then do what you want using the provided API.
|
||||
===================================================================================================
|
||||
|
||||
When loading, DCS searches for Saved Games\DCS\Scripts\*GameGUI.lua files,
|
||||
sorts them by name and then loads into the GUI Lua-state.
|
||||
Each user script is loaded into an isolated environment, so the only
|
||||
thing they share is the state of the simulator.
|
||||
|
||||
Each script defines a set of callbacks to the DCS events and sets them with the call
|
||||
DCS.setUserCallbacks(cb_table)
|
||||
For each callback type the hooks of all user scripts will be called in order of loading.
|
||||
|
||||
For callbacks which are supposed to returning a value, currently there are 3 of them:
|
||||
onPlayerTryConnect
|
||||
onPlayerTrySendChat
|
||||
onPlayerTryChangeSlot
|
||||
returning a value means breaking the hook call chain.
|
||||
Returning nothing (or nil) means continuing the hook chain, which ends with the default allow-all handlers.
|
||||
|
||||
The example user script 'testGameGUI.lua':
|
||||
----------------------------------------------------------------------------------------------
|
||||
local test = {}
|
||||
|
||||
function test.onPlayerTryConnect(ipaddr, name, ucid, playerID)
|
||||
print('onPlayerTryConnect(%s, %s, %s, %d)', ipaddr, name, ucid, playerID)
|
||||
-- if you want to gently intercept the call, allowing other user scripts to get it,
|
||||
-- you better return nothing here
|
||||
return true -- allow the player to connect
|
||||
end
|
||||
|
||||
function test.onSimulationStart()
|
||||
print('Current mission is '..DCS.getMissionName())
|
||||
end
|
||||
|
||||
DCS.setUserCallbacks(test) -- here we set our callbacks
|
||||
----------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
The available API are documented below.
|
||||
The full list of the callbacks is at the end of this document.
|
||||
|
||||
In addition, all standard lua 5.1 libraries are available as well, namely:
|
||||
base api, like print, etc,
|
||||
math.*
|
||||
table.*
|
||||
string.*
|
||||
io.*
|
||||
os.*
|
||||
debug.*
|
||||
|
||||
===================================================================================================
|
||||
|
||||
|
||||
|
||||
Lua File System (lfs) API
|
||||
-------------------------------
|
||||
lfs.currentdir() -> string
|
||||
Returns the path of the DCS install folder
|
||||
|
||||
lfs.writedir() -> string
|
||||
Returns the path of the current 'Saved Games\DCS' folder.
|
||||
|
||||
lfs.tempdir() -> string
|
||||
Returns the pat of the DCS Temp folder (AppData\Local\Temp\DCS).
|
||||
|
||||
lfs.mkdir()
|
||||
lfs.rmdir()
|
||||
lfs.attributes()
|
||||
lfs.dir()
|
||||
lfs.normpath()
|
||||
lfs.realpath()
|
||||
|
||||
|
||||
|
||||
DCS Control API, table 'DCS.*'
|
||||
-------------------------------
|
||||
|
||||
DCS.setPause(bool)
|
||||
Pauses/resumes the simulation. Server-side only.
|
||||
|
||||
DCS.getPause() -> bool
|
||||
true if simulation is paused
|
||||
|
||||
DCS.stopMission()
|
||||
stops current mission
|
||||
|
||||
DCS.exitProcess()
|
||||
Exits the DCS process.
|
||||
|
||||
DCS.isMultiplayer() -> bool
|
||||
True when running in the multiplayer mode.
|
||||
|
||||
DCS.isServer() -> bool
|
||||
True when running as a server or in the single-player mode.
|
||||
|
||||
DCS.getModelTime() -> number
|
||||
returns current DCS simulation time in seconds.
|
||||
|
||||
DCS.getRealTime() -> number
|
||||
returns current DCS real time in seconds relative to the DCS start time.
|
||||
|
||||
DCS.getMissionOptions() -> table
|
||||
Returns the value of 'mission.options'
|
||||
|
||||
DCS.getMissionDescription() -> string
|
||||
translated mission.descriptionText string
|
||||
|
||||
DCS.getAvailableCoalitions() -> table {
|
||||
[coalition_id] = { name = "coalition name", }
|
||||
...
|
||||
}
|
||||
Returns a list of coalitions which have available slots.
|
||||
|
||||
DCS.getAvailableSlots(coalitionID) -> array of {unitId, type, role, callsign, groupName, country}
|
||||
Returns the list of available slots.
|
||||
NOTE: the returned unitID is actually a slotID, which for multi-seat units is 'unitID_seatID'
|
||||
|
||||
DCS.getCurrentMission() -> table with the currently loaded mission
|
||||
NOTE: to get valid mission.options use DCS.getMissionOptions()
|
||||
|
||||
DCS.getMissionName() -> string
|
||||
Returns the name of the current mission
|
||||
|
||||
DCS.getMissionFilename() -> string
|
||||
Returns the file name of the current mission (returns nil when acting as a multiplayer client).
|
||||
|
||||
DCS.getMissionResult(string side) -> integer [0, 100]
|
||||
Gets missin result for either 'red' or 'blue'
|
||||
|
||||
DCS.getUnitProperty(missionId, propertyId) -> string
|
||||
propertyId:
|
||||
DCS.UNIT_RUNTIME_ID, // unique within runtime mission. int
|
||||
DCS.UNIT_MISSION_ID, // unique within mission file. int>0
|
||||
DCS.UNIT_NAME, // unit name, as assigned by mission designer.
|
||||
DCS.UNIT_TYPE, // unit type (Ural, ZU-23, etc)
|
||||
DCS.UNIT_CATEGORY,
|
||||
DCS.UNIT_GROUP_MISSION_ID, // group ID, unique within mission file. int>0
|
||||
DCS.UNIT_GROUPNAME, // group name, as assigned by mission designer.
|
||||
DCS.UNIT_GROUPCATEGORY,
|
||||
DCS.UNIT_CALLSIGN,
|
||||
DCS.UNIT_HIDDEN,// ME hiding
|
||||
DCS.UNIT_COALITION,// "blue", "red" or "unknown"
|
||||
DCS.UNIT_COUNTRY_ID,
|
||||
DCS.UNIT_TASK, //"unit.group.task"
|
||||
DCS.UNIT_PLAYER_NAME, // valid for network "humanable" units
|
||||
DCS.UNIT_ROLE,//"artillery_commander", "instructor", etc
|
||||
DCS.UNIT_INVISIBLE_MAP_ICON,//ME invisible map icon
|
||||
|
||||
DCS.getUnitType(missionId) -> typeId
|
||||
a shortcut for DCS.getUnitProperty(missionId, DCS.UNIT_TYPE)
|
||||
|
||||
DCS.getUnitTypeAttribute(typeId, attr) -> string
|
||||
Returns a value from Database: Objects[typeId][attr],
|
||||
for example DCS.getUnitTypeAttribute("Ural", "DisplayName")
|
||||
|
||||
DCS.writeDebriefing(str)
|
||||
Writes a custom string to the debriefing file
|
||||
|
||||
DCS.setUserCallbacks(cb_table)
|
||||
Hooks the callbacks using the handlers from the provided table.
|
||||
See: "GameGUI scripts" section.
|
||||
|
||||
|
||||
|
||||
Logging API 'log.*'
|
||||
------------------------
|
||||
Logging works as follows:
|
||||
a) each log message is accompanied with 2 attributes: a subsystem, and level.
|
||||
b) after each messages gets into a logger it passes (asynchronously) through
|
||||
a series of output filters which decide where the message will be written to.
|
||||
|
||||
Writing to log is done by:
|
||||
|
||||
log.write(SUBSYSTEM_NAME, LOG_LEVEL, message, ...)
|
||||
if there are any arguments after 'message',
|
||||
the actual string is formed as string.format(message, ...)
|
||||
|
||||
SUBSYSTEM_NAME is a string
|
||||
LOG_LEVEL is one of the values, listed below
|
||||
see log.set_output()
|
||||
|
||||
log.set_output(log_file_name_wo_ext, rule_subsystem_name, rule_level_mask, rule_output_mode)
|
||||
|
||||
the args:
|
||||
log_file_name_wo_ext: resulting log will be written to $WRITE_DIR/Logs/<log_file_name_wo_ext>.log
|
||||
|
||||
rule_subsytem_name: the name of the subsystem whose messages to write or empty string to match all subsystems
|
||||
|
||||
rule_level_mask: a sum of log-level bit flags to match messages
|
||||
valid flags are:
|
||||
log.ALERT
|
||||
log.ERROR
|
||||
log.WARNING
|
||||
log.INFO
|
||||
log.DEBUG
|
||||
log.ALL - includes all of the above
|
||||
log.TRACE - a special level which is excluded from dcs.log file
|
||||
|
||||
rule_output_mode: a sum of output flags:
|
||||
log.MESSAGE
|
||||
log.TIME
|
||||
log.MODULE - this is a 'subsystem', not a dlc
|
||||
log.LEVEL
|
||||
log.FULL - all of the above
|
||||
|
||||
So, in order to save net.trace(msg) messages to a file, you should issue a call:
|
||||
log.set_output('lua-net', 'LuaNET', log.TRACE, log.MESSAGE + log.TIME)
|
||||
|
||||
This will write to a Logs/lua-net.log file
|
||||
|
||||
Or, to save everything lua-network-related:
|
||||
log.set_output('lua-net', 'LuaNET', log.TRACE + log.ALL, log.MESSAGE + log.TIME + log.LEVEL)
|
||||
|
||||
To close the log file, you must use
|
||||
log.set_output('lua-net', '', 0, 0)
|
||||
|
||||
log.* API is available in the 'Saved Games\DCS\Config\autoexec.cfg' file as well so you can control log output in you local machine.
|
||||
|
||||
|
||||
|
||||
Network specific API, available through the table 'net.'
|
||||
----------------------------------------------------------------
|
||||
|
||||
net.log(msg) -- equivalent to log.write('LuaNET', log.INFO, msg)
|
||||
net.trace(msg) -- equivalent to log.write('LuaNET', log.TRACE, msg)
|
||||
|
||||
What is the difference: log() always writes to dcs.log, but may lose messages if the output rate is too high.
|
||||
trace() output never appears in the dcs.log file, it must be explicitly directed to a log file.
|
||||
It never loses messages when there's an active output, but it may block if output rate is higher than writing to the log file.
|
||||
To control logger output you can use $WRITE_DIR/Config/autoexec.cfg file, or call this from your network script
|
||||
(log.* API, see above)
|
||||
|
||||
|
||||
net.dostring_in(state, string) -> string
|
||||
Executes a lua-string in a given internal lua-state and returns a string result
|
||||
Valid state names are:
|
||||
'config': the state in which $INSTALL_DIR/Config/main.cfg is executed, as well as $WRITE_DIR/Config/autoexec.cfg
|
||||
used for configuration settings
|
||||
'mission': holds current mission
|
||||
'export': runs $WRITE_DIR/Scripts/Export.lua and the relevant export API
|
||||
|
||||
net.send_chat(string message, bool all)
|
||||
Send chat message. If not all, then send to my coalition (side) only.
|
||||
|
||||
net.send_chat_to(string message, playerID to)
|
||||
Send direct chat message to a player
|
||||
Server-side only:
|
||||
net.send_chat_to(string message, playerID to[, playerID from])
|
||||
|
||||
net.recv_chat(message[, int from=0])
|
||||
Receive chat message locally[, pretending it was sent by another player].
|
||||
from = 0 means from the system
|
||||
|
||||
net.load_mission(miz_filename)
|
||||
Loads a specified mission, temporarily overriding the server mission list.
|
||||
SERVER ONLY
|
||||
|
||||
net.load_next_mission() -> bool
|
||||
Load the next mission from the server mission list. Returns false if list end is reached
|
||||
SERVER ONLY
|
||||
|
||||
net.get_player_list() -> array of playerID
|
||||
Returns the list of currently connected players
|
||||
|
||||
net.get_my_player_id() -> playerID
|
||||
Returns the playerID of the local player. Currently always 1 for the server.
|
||||
|
||||
net.get_server_id() -> playerID
|
||||
Returns playerID of the server. Currently, always 1.
|
||||
|
||||
net.get_player_info(playerID) -> table
|
||||
Returns a table of all player attributes or nil if playerID is invalid
|
||||
|
||||
net.get_player_info(playerID, attrName) -> value
|
||||
Returns a value of a given attribute for the playerID.
|
||||
|
||||
Currently defined attributes are:
|
||||
'id': playerID
|
||||
'name': player name
|
||||
'side': 0 - spectators, 1 - red, 2 - blue
|
||||
'slot': slotID of the player or ''
|
||||
'ping': ping of the player in ms
|
||||
'ipaddr': IP address of the player, SERVER ONLY
|
||||
'ucid': Unique Client Identifier, SERVER ONLY
|
||||
|
||||
net.kick(id, message)
|
||||
Kick a player.
|
||||
|
||||
net.get_stat(playerID, statID) -> integer
|
||||
Get statistics for player. statIDs are:
|
||||
net.PS_PING (0) - ping (in ms)
|
||||
net.PS_CRASH (1) - number of crashes
|
||||
net.PS_CAR (2) - number of destroyed vehicles
|
||||
net.PS_PLANE (3) - ... planes/helicopters
|
||||
net.PS_SHIP (4) - ... ships
|
||||
net.PS_SCORE (5) - total score
|
||||
net.PS_LAND (6) - number of landings
|
||||
net.PS_EJECT (7) - of ejects
|
||||
|
||||
|
||||
net.get_name(playerID) -> string
|
||||
The same as net.get_player_info(playerID, 'name')
|
||||
FIXME: implement in ServMan_compat.lua ?
|
||||
|
||||
net.get_slot(playerID) -> sideID, slotID
|
||||
The same as:
|
||||
net.get_player_info(playerID, 'side'), net.get_player_info(playerID, 'slot')
|
||||
FIXME: implement in ServMan_compat.lua ?
|
||||
|
||||
|
||||
|
||||
net.set_slot(sideID, slotID)
|
||||
Try to set the local player's slot. Empty slotID ('') puts the player into spectators.
|
||||
|
||||
net.force_player_slot(playerID, sideID, slotID) -> boolean
|
||||
Forces a player to occupy a set slot. Slot '' means no slot (moves player to spectators)
|
||||
SideID: 0 - spectators, 1 - red, 2 - blue
|
||||
|
||||
net.set_name(playerID, name) -- OBSOLETE, works only locally
|
||||
|
||||
|
||||
net.lua2json(value) -> string
|
||||
Convert a Lua value to JSON string
|
||||
|
||||
net.json2lua(json_string) -> value
|
||||
Convert JSON string to a Lua value
|
||||
|
||||
|
||||
LuaExport API 'Export.Lo*'
|
||||
----------------------------------------------------------------
|
||||
See Scripts/Export.lua for the documentation. Note that all export
|
||||
API functions are available here in the Export. namespace, not the global one.
|
||||
In multiplayer the availability of the API on clients depends on the server setting.
|
||||
|
||||
The calls to check export capabilities:
|
||||
Export.LoIsObjectExportAllowed() -- returns the value of server.advanced.allow_object_export
|
||||
Export.LoIsSensorExportAllowed() -- returns the value of server.advanced.allow_sensor_export
|
||||
Export.LoIsOwnshipExportAllowed() -- returns the value of server.advanced.allow_ownship_export
|
||||
|
||||
These calls are only available on clients when LoIsObjectExportAllowed() is true:
|
||||
Export.LoGetObjectById
|
||||
Export.LoGetWorldObjects
|
||||
|
||||
These calls are only available on clients when LoIsSensorExportAllowed() is true:
|
||||
Export.LoGetTWSInfo
|
||||
Export.LoGetTargetInformation
|
||||
Export.LoGetLockedTargetInformation
|
||||
Export.LoGetF15_TWS_Contacts
|
||||
Export.LoGetSightingSystemInfo
|
||||
Export.LoGetWingTargets
|
||||
|
||||
These calls are only available on clients when LoIsOwnshipExportAllowed() is true:
|
||||
Export.LoGetPlayerPlaneId
|
||||
Export.LoGetIndicatedAirSpeed
|
||||
Export.LoGetAngleOfAttack
|
||||
Export.LoGetAngleOfSideSlip
|
||||
Export.LoGetAccelerationUnits
|
||||
Export.LoGetVerticalVelocity
|
||||
Export.LoGetADIPitchBankYaw
|
||||
Export.LoGetTrueAirSpeed
|
||||
Export.LoGetAltitudeAboveSeaLevel
|
||||
Export.LoGetAltitudeAboveGroundLevel
|
||||
Export.LoGetMachNumber
|
||||
Export.LoGetRadarAltimeter
|
||||
Export.LoGetMagneticYaw
|
||||
Export.LoGetGlideDeviation
|
||||
Export.LoGetSideDeviation
|
||||
Export.LoGetSlipBallPosition
|
||||
Export.LoGetBasicAtmospherePressure
|
||||
Export.LoGetControlPanel_HSI
|
||||
Export.LoGetEngineInfo
|
||||
Export.LoGetSelfData
|
||||
Export.LoGetCameraPosition
|
||||
Export.LoSetCameraPosition
|
||||
Export.LoSetCommand
|
||||
Export.LoGetMCPState
|
||||
Export.LoGetRoute
|
||||
Export.LoGetNavigationInfo
|
||||
Export.LoGetPayloadInfo
|
||||
Export.LoGetWingInfo
|
||||
Export.LoGetMechInfo
|
||||
Export.LoGetRadioBeaconsStatus
|
||||
Export.LoGetVectorVelocity
|
||||
Export.LoGetVectorWindVelocity
|
||||
Export.LoGetSnares
|
||||
Export.LoGetAngularVelocity
|
||||
Export.LoGetHeightWithObjects
|
||||
Export.LoGetFMData
|
||||
|
||||
These functions are always available:
|
||||
Export.LoGetPilotName
|
||||
Export.LoGetAltitude
|
||||
Export.LoGetNameByType
|
||||
Export.LoGeoCoordinatesToLoCoordinates
|
||||
Export.LoCoordinatesToGeoCoordinates
|
||||
Export.LoGetVersionInfo
|
||||
Export.LoGetWindAtPoint
|
||||
Export.LoGetModelTime
|
||||
Export.LoGetMissionStartTime
|
||||
|
||||
These are not available in the *GameGUI state:
|
||||
-- Export.LoSetSharedTexture
|
||||
-- Export.LoRemoveSharedTexture
|
||||
-- Export.LoUpdateSharedTexture
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------------------
|
||||
--- The Callbacks.
|
||||
-------------------------------------------------------------------------------------------
|
||||
|
||||
function onMissionLoadBegin()
|
||||
end
|
||||
|
||||
function onMissionLoadProgress(progress, message)
|
||||
end
|
||||
|
||||
function onMissionLoadEnd()
|
||||
end
|
||||
|
||||
|
||||
function onSimulationStart()
|
||||
end
|
||||
|
||||
function onSimulationStop()
|
||||
end
|
||||
|
||||
function onSimulationFrame()
|
||||
end
|
||||
|
||||
function onSimulationPause()
|
||||
end
|
||||
|
||||
function onSimulationResume()
|
||||
end
|
||||
|
||||
|
||||
function onGameEvent(eventName,arg1,arg2,arg3,arg4)
|
||||
--"friendly_fire", playerID, weaponName, victimPlayerID
|
||||
--"mission_end", winner, msg
|
||||
--"kill", killerPlayerID, killerUnitType, killerSide, victimPlayerID, victimUnitType, victimSide, weaponName
|
||||
--"self_kill", playerID
|
||||
--"change_slot", playerID, slotID, prevSide
|
||||
--"connect", playerID, name
|
||||
--"disconnect", playerID, name, playerSide, reason_code
|
||||
--"crash", playerID, unit_missionID
|
||||
--"eject", playerID, unit_missionID
|
||||
--"takeoff", playerID, unit_missionID, airdromeName
|
||||
--"landing", playerID, unit_missionID, airdromeName
|
||||
--"pilot_death", playerID, unit_missionID
|
||||
end
|
||||
|
||||
function onNetConnect(localPlayerID)
|
||||
end
|
||||
|
||||
function onNetMissionChanged(newMissionName)
|
||||
end
|
||||
|
||||
function onNetDisconnect(reason_msg, err_code)
|
||||
end
|
||||
|
||||
-- disconnect reason codes:
|
||||
net.ERR_INVALID_ADDRESS
|
||||
net.ERR_CONNECT_FAILED
|
||||
net.ERR_WRONG_VERSION
|
||||
net.ERR_PROTOCOL_ERROR
|
||||
net.ERR_TAINTED_CLIENT
|
||||
net.ERR_INVALID_PASSWORD
|
||||
net.ERR_BANNED
|
||||
net.ERR_BAD_CALLSIGN
|
||||
|
||||
net.ERR_TIMEOUT
|
||||
net.ERR_KICKED
|
||||
|
||||
|
||||
function onPlayerConnect(id)
|
||||
end
|
||||
|
||||
function onPlayerDisconnect(id, err_code)
|
||||
-- this is never called for local playerID
|
||||
end
|
||||
|
||||
function onPlayerStart(id)
|
||||
-- a player entered the simulation
|
||||
-- this is never called for local playerID
|
||||
end
|
||||
|
||||
function onPlayerStop(id)
|
||||
-- a player left the simulation (happens right before a disconnect, if player exited by desire)
|
||||
-- this is never called for local playerID
|
||||
end
|
||||
|
||||
function onPlayerChangeSlot(id)
|
||||
-- a player successfully changed the slot
|
||||
-- this will also come as onGameEvent('change_slot', playerID, slotID),
|
||||
-- if allowed by server.advanced.event_Connect setting
|
||||
end
|
||||
|
||||
|
||||
--- These 3 functions are different from the rest:
|
||||
--- 1. they are called directly from the network code, so try to make them as fast as possible
|
||||
--- 2. they return a result
|
||||
-- The code shows the default implementations.
|
||||
|
||||
function onPlayerTryConnect(addr, name, ucid, playerID) --> true | false, "disconnect reason"
|
||||
return true
|
||||
end
|
||||
|
||||
function onPlayerTrySendChat(playerID, msg, all) -- -> filteredMessage | "" - empty string drops the message
|
||||
return msg
|
||||
end
|
||||
|
||||
function onPlayerTryChangeSlot(playerID, side, slotID) -- -> true | false
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- GUI callbacks
|
||||
function onChatMessage(message, from)
|
||||
-- this one may be useful for chat archiving
|
||||
end
|
||||
|
||||
function onShowRadioMenu(a_h)
|
||||
end
|
||||
|
||||
function onShowPool()
|
||||
end
|
||||
|
||||
function onShowGameMenu()
|
||||
end
|
||||
|
||||
function onShowBriefing()
|
||||
end
|
||||
|
||||
function onShowChatAll()
|
||||
end
|
||||
|
||||
function onShowChatTeam()
|
||||
end
|
||||
|
||||
function onShowChatRead()
|
||||
end
|
||||
|
||||
function onShowMessage(a_text, a_duration)
|
||||
end
|
||||
|
||||
function onTriggerMessage(message, duration, clearView)
|
||||
end
|
||||
|
||||
function onRadioMessage(message, duration)
|
||||
end
|
||||
|
||||
function onRadioCommand(command_message)
|
||||
end
|
||||
|
||||
===================================================================================================
|
||||
|
||||
Happy hacking!
|
||||
|
||||
Sincerely,
|
||||
dsb at eagle dot ru
|
||||
Loading…
x
Reference in New Issue
Block a user