XaiJu
cubecoders
cubecoders

patreon


What is the AMP Console Assistant (AMPCA), and why does it exist?

The AMP Console Assistant is possibly the weirdest and least understood component of AMP. It sits there hidden under the hood doing its own thing, mostly invisible and unnoticed. But surely it has some purpose. What does it do, and why does AMP need it?

This is first of a series where I talk about some of AMP's inner workings for the curious amongst you. While broadly AMP has a fairly simple design, there are some fairly whacky components in it to help it deal with the sheer variety of applications it has to support in a manner that’s consistent across both Windows and Linux all while doing this transparently to user.

A tale of two houses

On Windows, there exists a distinction between graphical and non-graphical applications that doesn’t exist on Linux. Applications can use either the GUI or the CLI subsystem, and the OS needs to know ahead of time which a program is. This is baked into its executable header.

The problems with this setup are twofold: First, GUI applications cannot write to a standard output stream, secondly CLI applications (while they can have a GUI) will always show a console window even if you don’t want it.

This by the way is why Java has two executables on Windows: Java.exe (the CLI version) and Javaw.exe (The GUI version) so that you can use whichever one you need at the time.

Lots of game server applications are in fact simply modified versions of the game itself. And thus this usually means they’re built as GUI subsystem applications (Especially when it comes to Unity-based apps)

So one of the ways that some applications get around the lack of a console when running as a GUI application is to create one. Windows lets programs allocate and then write to a console even if they’re nominally a GUI application. But herein lies the rub…

No standard output to be seen!

As mentioned earlier, GUI applications on Windows cannot write to standard output. This creates the really annoying experience where an application can look like and behave a lot like a CLI application in Windows but if you want to actually capture its output (either to redirect it to a file or to read it in real-time like AMP does) then you’re going to have a really bad time. So this is where AMPCA steps in and lends AMP a hand.

For reference you can spot applications that behave in this way because even when started from a command prompt, they’ll open up another console window separate from the one you started it from.

AMPCA is a fairly thin wrapper application that creates a virtual console off-screen, and then starts up the application requested by AMP in such a way that it’s forced to use this virtual off-screen console when it tries to create its own one. Then it monitors this virtual console for changes, and depending on the mode it’s operating in – either sends this data to standard output (since AMPCA is a true console application, and thus has a readable standard output) or sends it to a named pipe (also known as a FIFO buffer) which AMP can then read.

There are some limitations of doing this, mainly that it has to do some guesswork as to what constitutes a ‘line’ – since it’s scanning the console character by character it doesn’t necessarily know when it reaches the end if the line just happened to end there or if it wrapped around to the next line. Broadly speaking AMPCA is used for applications that have zero sane way of reading their log/output live.  

The biggest problem Some of this guess work can result in odd garbage-output that AMP must then filter out and make sense of before processing it or showing it to the user which creates additional work.

Why isn’t this a problem on Linux?

Linux has no distinction between CLI and GUI applications. GUI applications can write to standard output if anything is listening, but otherwise it doesn’t matter.

However AMP does still occasionally have to perform some trickery on Linux to deal with output buffering. Some applications (most notably: SteamCMD) buffer their output in 1KB chunks, which is occasionally unhelpful as it means you won’t see any output at all until 1KB is written. So AMP abuses the ‘socat’ tool to get around this by essentially making it un-buffer applications so that AMP can get their output live.

Which applications use this?

Right now the biggest user of this facility is the Factorio module. While Factorio has RCON support, it does not have any facility to send its log to connected RCON clients, so AMP must resort to other methods to extract information from the running process, which can be difficult sometimes. AMP also uses this fairly heavily with SteamCMD which uses the console in such a bizzare way sometimes that I could write an article just on that subject alone.

What’s the alternative?

Where possible I try and avoid using AMPCA because it can make modules difficult to maintain. One of my favourite tricks though (which I hope to work into the Factorio module soon) is using named pipes. This only works on applications that allow you to set the log file to whatever you like (since these named pipes have ‘filenames’ and can be written to like a normal file) – but if no such facility is available then sometimes I actually reach out to developers to suggest that they make certain changes, or sometimes I will go so far as to produce plugins/mods (such as the FiveMIntegrationServer plugin for FiveM which emulates the Source UDP logging protocol) to let AMP communicate with a given application without the use of AMPCA.


More Creators