-
Posts
220 -
Joined
-
Last visited
Content Type
Profiles
Forums
Events
Everything posted by Actium
-
TL;DR: WebConsole.lua is an experimental, interactive, browser-based Lua console with syntax highlighting for scripting in all of DCS' scripting environments. It explicitly supports mission scripting to accelerate otherwise slow mission development cycles (edit DO SCRIPT code, start mission, test, stop mission, repeat). Install by downloading WebConsole.lua into your %USERPROFILE%\Saved Games\DCS.*\Scripts\Hooks\ folder, start a DCS mission, and open the console in your web browser. Script return values are automatically serialized as human- and machine-readable JSON. Also supports non-interactive use through an HTTP API to issue DCS scripting commands from any programming language. Read below security advisory before installing! I'm publishing it in its current state, because I already use it productively for mission scripting and I'm looking for feedback from the community. As it is experimental, there are no support or compatibility guarantees. Use at your own risk, feel free to break it, and don't hesitate to report any issues in this thread! Features Easily run arbitrary code in all of DCS' scripting environments (called Lua states, accessed via net.dostring_in()). Currently, these include config, export, gui, mission, and server. Let me know if anything is missing. Access to the separate mission scripting environment (dubbed *a_do_script), where all DO SCRIPT code from the mission editor runs, is supported out of the box since DCS 2.9.13 (no modification of MissionScripting.lua required). UPDATE: Broken since 2.9.15.9408, but workaround available. Supports both clients and (dedicated) servers. Clients not also serving missions, e.g., from the mission editor, are restricted to the gui environment. Lua syntax highlighting and checking via an embedded code editor (ACE). Secure integration into mission scripting: Unlike other consoles, WebConsole.lua does not require disabling the sanitization in MissionScripting.lua. Serialization of complex return values into human- and machine-readable JSON. Interactive inspection of returned JSON objects (see screenshot). The serialization format is a work-in-progress, i.e., not stable. Beware of arrays starting with null. Alternatively serializing to Lua is feasible, but currently missing. Feel free to implement and contribute it. HTTP API for non-interactive use from a programming language of your choice. Includes error handling and translation into appropriate HTTP status codes (Success -> 200 OK; Error -> 500 Internal Server Error). Note that the API is not stable and may change without notice. Security Advisory All DCS Lua consoles, e.g., dcs-witchcraft, DCS-BIOS, DCS Fiddle, DCS Lua Runner, DCS Code Injector, and my WebConsole.lua, use a socket bound to localhost (127.0.0.1) to issue scripting commands to DCS. This socket is not accessible remotely, neither from the internet, nor from your local area network. However, the socket is open to any user or program on your local computer. Without authentication or a firewall in place, other users (and whatever software they run) can use the socket and Lua's os.execute() to escape the DCS Lua scripting environment, enabling arbitrary code execution with user permissions. This is a potential security vulnerability that could be exploited to access/steal your files, install malware, etc. Single-user computers are generally safe. However, multi-user systems are vulnerable, unless properly authenticated (password protected), firewalled, or all co-users are absolutely trustworthy. Do **NOT EVER** modify any Lua console to bind its socket to 0.0.0.0 to enable remote scripting access, as this would enable remote code execution for anyone. Password protection via HTTP Basic authentication is unencrypted and generally insecure. If you want to use any Lua console remotely you could, e.g.: Set up a reverse HTTP(S) proxy that authenticates and encrypts all web console requests. Use encrypted and authenticated port forwarding, e.g., via Secure Shell: ssh -L 8089:127.0.0.1:8089 user@server (also possible on Windows) Set up a VPN and bind the socket to the VPN interface IP address. Note that everyone on the VPN will be allowed access, unless firewall rules are in place. Installation Download WebConsole.lua and copy it into your Scripts/Hooks folder, e.g., %USERPROFILE%\Saved Games\DCS.*\Scripts\Hooks\WebConsole.lua. Optionally, configure port and password in your %USERPROFILE%\Saved Games\DCS.*\Config\autoexec.cfg as follows. If left unconfigured, port defaults to 8089 and authentication is disabled. -- configure Scripts/Hooks/WebConsole.lua: -- WARNING: the web console is not remote-accessible via network. however, it -- enables arbitrary code execution with user privileges to anyone -- with access to its socket. -- this is a potential security vulnerability on multi-user systems, -- enabling other local users to run arbitary code from your user -- account, access your files, install malware, etc. -- enable HTTP authentication with a strong password below or use an -- appropriately configured firewall on multi-user systems! -- web console HTTP port (number: -1 to disable | >1023 to enable | nil: 8089) webconsole_port = 8089 -- base64-encoded "username:password" string for optional HTTP Basic -- authentication or nil to disable authentication. on Windows PowerShell use -- `[Convert]::ToBase64String([char[]] "username:password")` and on Linux use -- `echo -n "username:password" | base64` for base64-encoding. example value -- for "username:password": webconsole_auth = "dXNlcm5hbWU6cGFzc3dvcmQ=" webconsole_auth = nil Interactive Use After installing as instructed below, start a mission (e.g., from the mission editor or on a server). Open http://127.0.0.1:8089/ (if using the default port) in your browser while the mission is running. Type code, press Execute, and check its return value. Rinse, repeat. The console does not work while the mission/server is paused. Non-Interactive Use Exemplary curl command line to fetch server logs: curl "http://127.0.0.1:8089/execute" -X POST \ -H "Accept: application/json" -H "Content-Type: application/lua" -H "X-Lua-State: gui" \ --data-raw "return {DCS.getLogHistory()}" Exemplary Windows PowerShell code to fetch list of currently connected players from a server: (Invoke-WebRequest ` -Uri http://127.0.0.1:8089/execute -Method POST ` -Headers @{"Accept" = "application/json"; "X-Lua-State" = "gui"} ` -ContentType "application/lua" ` -Body "local players = {} for _, id in ipairs(net.get_player_list()) do players[#players + 1] = net.get_player_info(id) end return players").Content Screenshots Web console used to retrieve and display the contents of the global variable world in the mission scripting environment: The web console can also be used to recursively dump all global variables via return _G. Note that doing so will freeze the server until serialization and HTTP transfer have completed. To avoid browser performance issues, the result display is truncated. The entire result can be saved to a local file via the Save button. Serializing to JSON has the benefit of being able to use web development tools, like the interactive JSON inspectors included in, e.g., Firefox and Chrome. Click the Open button to open the result in a new window:
-
Recommended spec for dedicated server?
Actium replied to Lace's topic in Multiplayer Server Administration
AFAICT, the DCS server loads all required assets while loading the mission, incurring significantly longer load times from an HDD. However, short of a developer confirming that no load will ever occur while a mission runs, no one knows for sure. If you run into performance issues later on, you'll always wonder whether these are caused by the HDD. Writing Tacview logs onto an HDD may very well affect the server performance. So, personally, I'd invest into an NVMe SSD. Half a TB costs around 50 bucks these days. IMHO, well worth the peace of mind. -
Migrate Squadron Server to Proxmox, best practise OS
Actium replied to MarkP's topic in Multiplayer Server Administration
With "only" 32 GB RAM on the Proxmox host, you may run out of RAM with a Windows VM in addition to – presumably – a few more Linux VMs (or containers?) running the other services you mentioned. A single DCS_server.exe process with an empty Caucasus map loaded allocates around 10 GB. Add a Windows VM with 20~24 GB of RAM on top and you're already almost out of RAM. Of course, your mileage may vary. As you're using Proxmox, you may be comfortable with using Wine to run your DCS server on Linux, obviating the RAM overhead of a Windows (Server) VM. Here's a forum post on how to run the DCS server via Docker. I run a DCS server on Debian stable with Wine 8.0 without problems, using self-written systemd user services to administer multiple server instances. If you do opt for Wine: A Proxmox container will likely yield better performance (and less RAM usage) than a VM. I have no hard data on this, but I have read post on the forum that state this, corroborated by my own gut feeling. If you want to dive even deeper, using a recent Linux Kernel with NTSYNC support as well as a Wine version with the NTSYNC patch might deliver performance on par with Windows. I haven't had the time to try it, so take this with a huge grain of salt! However, judging from the server's mediocre multi-threading performance, I would not be surprised if NTSYNC actually delivers noteworthy performance improvements. -
Thanks @cfrag and @DD_Friar! I had a gut feeling I had exhausted DCS' limited scripting options and wanted to confirm that. The one trigger per unit kludge is not a viable option for me, because >100 units are involved. I guess I'll opt for just 'sploding the deserting units. I tend to agree . I've read dozens of his forum posts, typically including justified yet entertaining criticism of DCS' desolate mission scripting state. Today's post did not disappoint I come from the very first ArmA, which was also painful to script with, but DCS appears to play in a wholly different league.
-
I'm looking for a way to immersively take an (aerial) unit off the board via mission scripting. By immersive I mean killing the crew/pilot, ejecting the crew/pilot, crashing the unit into the ground, stopping its engines (e.g., by removing all fuel), or -- as a last resort -- exploding it mid-air. My application is the removal of units that aborted their mission to keep them from returning home. Example code run via a MISSION START trigger DO SCRIPT action (NOTE: only use a single removal method at a time): local eh = {} function eh:onEvent(event) if event.id == world.event.S_EVENT_AI_ABORT_MISSION then -- FIXME: unit vanishes into thin air -> lame event.initiator:destroy() -- FIXME: brute force approach. will it work reliably in multiplayer with desync/lag? trigger.action.explosion(event.initiator:getPoint(), 10) -- FIXME: not available from the mission scripting environment (i.e., a_do_script()) a_unit_set_life_percentage(event.initiator:getID(), 0) a_explosion_unit(event.initiator:getID(), 10) end end world.addEventHandler(eh) I do not want to vanish the unit via :destroy() and trigger.action.explosion() feels very brutal and prone to fail in multiplayer. DCS actually comes with ways to kill the unit by setting its life to 0% (forces crew ejection) and selectively exploding it via trigger actions: However, neither is available from the mission scripting environment via trigger.action.*(). Digging inside the mission_file.miz/mission lua code reveals the two functions a_unit_set_life_percentage(2, 0) and a_explosion_unit(2, 10). Unfortunately, neither is available from the mission scripting environment (i.e., a_do_script()), with above code resulting in: 2025-02-01 04:56:11.955 ERROR SCRIPTING (Main): Mission script error: ... attempt to call global 'a_unit_set_life_percentage' (a nil value) Is anyone aware of a way to access the UNIT AI SET LIFE and/or EXPLODE UNIT trigger actions via mission scripting, e.g., above event handler?
-
The hooks are not accessible from the mission scripting environment. You have to create a DCS Control API hook script, e.g. %USERPROFILE%\Saved Games\DCS.dcs_serverrelease\Scripts\Hooks\ProhibitNamePlayer.lua with the following content (untested code, but shouldTM be working) : -- SPDX-License-Identifier: MIT -- callback object, see DCS API documentation for details: -- * file:///C:/DCS_INSTALL_PATH/API/DCS_ControlAPI.html -- * https://wiki.hoggitworld.com/view/Hoggit_DCS_World_Wiki local myhook = {} function myhook.onPlayerTryConnect(addr, name, ucid, id) if name == "Player" then return false, "Name 'Player' not permitted. Please change your name!" end end -- register callback if this is a server instance if DCS.isServer() then DCS.setUserCallbacks(myhook) end
-
This makes perfect sense. Thank you for the explanation!
-
The ILS of Tbilisi-Lochini runway 31L appears to be broken. Tuning to its frequency (108.90 MHz) on an F16 ILS/PLS results in receiving in static/noise* instead of morse code. The DED T-ILS page also does not indicate an ILS lock. Tuning to the ILS frequency of the opposite runway (110.30 MHz) results in receiving morse and an immediate ILS lock, albeit nonsensical. Screenshots and example mission attached. *) Curiously, tuning to other valid frequencies (e.g., 108.70 MHz) does not result in static, but silence and an unlocked ILS. Update: This is with the most recent DCS version (2.9.11.4686). Tbilisi_No_ILS_Rwy_31L.miz
-
Likely, that's a bug in DCS' handling of the default value for the so-called writedir, which is set through the DCS_server.exe -w INSERT_NAME_HERE command line parameter. When not set, I presume, it defaults to both DCS.release_server and DCS.dcs_serverrelease. The latter, you can see in the dedicated server window title, so I'd assume that to be the main directory. While I'd expect QA to detect such basic issues, this has been around since at least DCS 2.9.9, which was when I first stumbled over it. To mitigate this bug, start the dedicated server with a valid -w parameter, e.g., by creating a shortcut (via right click > new > shortcut), editing it (right click > properties), and adding -w DCS.server1 to the very end of the target field (after the final quote).
-
TL;DR: FPSmon.lua sends warnings messages to global chat if the server simulation frame rate or peak frame time falls below or exceeds configurable thresholds to help identify situations where low server performance may cause excessive lag. The simulation frame rate of the DCS server may deteriorate rapidly when the server is overloaded. Particularly missions with many actively engaged units exchanging shots may cause extreme frame times (far) in excess of 1 second. Low server simulation frame rates will limit the update rate of units other than the own on every client. While DCS clients extrapolate server frames for smooth movement of other units, extrapolation has its limits. When the DCS extrapolator is pushed beyond its limits, units move smoothly (on a continuously differentiable line), then jump suddenly, only to move smoothly again afterwards. Reasons include network issues (high ping or packet loss) or excessive server simulation frame times. Whereas ping is shown in the player list, DCS includes no metric or mechanism to warn about server performance issues (low frame rate or high frame times). The WebGUI does not issue direct warnings either. However, it does serve as a canary by updating/responding sluggishly if the server is extremely overloaded. This script periodically checks the average server simulation frame rate and peak frame time within a configurable interval (defaults to 30 seconds). If the frame rate falls below or the frame time exceeds their respective, configurable threshold, a warning message including both values is sent to global chat and also logged to the default DCS log file (Logs/dcs.log). The chat messages are also visible in the WebGUI. The following example screenshot illustrates chat output of three frame time outliers despite good average frame rate. The final warning message indicates a low average frame rate and therefore an overloaded server. Optionally, every periodic measurement can be logged by setting fpsmon_verbose = true in autoexec.cfg (see below). When enabled, this results in the following dcs.log content (when disabled, no INFO messages will be logged): 2024-12-19 16:10:46.310 INFO FPSmon.lua (Main): avg_fps=111.10 peak_frame_time=0.013 2024-12-19 16:11:16.315 INFO FPSmon.lua (Main): avg_fps=111.08 peak_frame_time=0.011 2024-12-19 16:11:46.316 INFO FPSmon.lua (Main): avg_fps=111.09 peak_frame_time=0.014 2024-12-19 16:12:16.325 INFO FPSmon.lua (Main): avg_fps=111.10 peak_frame_time=0.010 2024-12-19 16:12:46.329 INFO FPSmon.lua (Main): avg_fps=111.09 peak_frame_time=0.010 2024-12-19 16:13:16.332 INFO FPSmon.lua (Main): avg_fps=110.82 peak_frame_time=0.077 2024-12-19 16:13:46.337 WARNING FPSmon.lua (Main): avg_fps=108.35 peak_frame_time=0.756 2024-12-19 16:14:16.341 WARNING FPSmon.lua (Main): avg_fps=103.02 peak_frame_time=0.757 2024-12-19 16:14:46.348 INFO FPSmon.lua (Main): avg_fps=111.07 peak_frame_time=0.013 2024-12-19 16:15:16.352 INFO FPSmon.lua (Main): avg_fps=111.12 peak_frame_time=0.010 The intention behind this script is to help both mission development and deployment. During development, mission designers and server administrators can identify performance bottlenecks early on. If frame times grow too high, the mission should be simplified or the server hardware upgraded. In deployment, the script transparently informs and warns players of server performance issues, to faciliate pinpointing the cause of laggy units. Install by downloading FPSmon.lua into the DCS Scripts/Hooks folder, e.g.: %USERPROFILE%\Saved Games\DCS.dcs_serverrelease\Scripts\Hooks Optionally, the script can be configured via your autoexec.cfg. Without configuration, the script will use default values. If desired, add the following to %USERPROFILE%\Saved Games\DCS.*\Config\autoexec.cfg and modify the values to suit your needs: -- configure Scripts/Hooks/FPSmon.lua: -- interval of FPS log and chat messages (seconds), use zero (0) to disable (number) fpsmon_interval = 30 -- always log frame rate and peak frame time at every interval even if tresholds are not exceeded (boolean: true|false) fpsmon_verbose = false -- FPS (Hz) and frame time (seconds) thresholds to send warning messages to global chat (number: >0) fpsmon_warn_fps = 5 fpsmon_warn_time = 0.5
-
How Do I Disable 'Mission Script Error' Pop-ups?
Actium replied to Rex's topic in Scripting Tips, Tricks & Issues
Myself annoyed by the error popups (which will also happily freeze a dedicated server), I've written a hook script that will automatically disable the popups. However, to aid in debugging, it will send the logged error message to global chat, so errors are less likely to go unnoticed. -
TL;DR: NoErrPopup.lua disables the mission scripting error message popups on servers to prevent a potentially irrecoverable server-only freeze. By default, it will send error messages to global chat. DCS World defaults to open error message popups if an error occurs in the mission scripting environment. These popups freeze the simulation until each popup is closed manually. The dedicated server DCS_server.exe is also affected. A mission scripting error triggers a popup on the server, which stalls the server. From a client perspective, this freezes all units except for the local client. As no client-side error messages are displayed, the frozen/stalled server condition cannot be detected by clients. The WebGUI will also be unresponsive. Without direct or remote (RDP/VNC) access to the server, which is not available for most if not all managed servers, this issue is irrecoverable without support intervention or a server restart. The error popups can be disabled via env.setErrorMessageBoxEnabled(false) in the mission editor. However, this must be done in each mission with an appropriate MISSION START trigger. As this approach hampers debugging, it would necessitate separate mission files for production and debugging. NoErrPopup.lua runs env.setErrorMessageBoxEnabled(false) inside the mission scripting environment after a mission has been loaded via a server-side hook script, obviating the need to explicitly disable the popups in each mission. By default, mission scripting error messages will be sent to global chat to facilitate debugging and/or to notify clients that a server-side scripting error has occurred, as it may or may not affect the playability of the current mission. When disabling this feature, mission scripting errors will only be logged to Logs/dcs.log (default DCS behavior). If enabled, error error chat messages will be visible to clients and inside the WebGUI as follows: Install NoErrPopup.lua by downloading it into the DCS Scripts/Hooks folder, e.g.: %USERPROFILE%\Saved Games\DCS.dcs_serverrelease\Scripts\Hooks Optionally, the script can be configured via your autoexec.cfg. Without configuration, the script will use default values. If desired, add the following to %USERPROFILE%\Saved Games\DCS.*\Config\autoexec.cfg and modify the values to suit your needs: -- configure Scripts/Hooks/NoErrPopup.lua: -- do not send error messages to global chat (boolean: true|false) noerrpopup_mute = false
- 1 reply
-
- 1
-
