Console / stdin especially on windows

Anything related to the content on our wiki (https://wiki.factorio.com/)

Moderator: Bilka

Gweneph
Inserter
Inserter
Posts: 44
Joined: Thu Nov 14, 2019 11:51 pm
Contact:

Console / stdin especially on windows

Post by Gweneph »

I've been debugging an issue with communicating to stdin on windows for a few days now and would love some insight.

I was surprised to learn that the in-game console commands are available over stdin while running a headless server. I haven't really found much official documentation on it other than some mentions in the changelog.

On Linux everything seems to work without any fuss. I can start a headless server from the terminal and type in commands. I can automate it from every language I've tried.

On Windows using the same command to start a server:

Code: Select all

factorio.exe --start-server-load-latest
when I try to type /h I get that '/h' is not recognized as an internal or external command, operable program or batch file.

However, when I run the node program:

Code: Select all

exe_loc="C:\\Program Files\\Factorio\\bin\\x64\\factorio.exe"
args=["--start-server-load-scenario","base/freeplay"]
f = require('child_process').spawn(exe_loc,args)
f.stdout.pipe(process.stdout)
I can type /h, /quit etc. into the console that I'm running the node program in and I'll get all the expected interactivity that I get on Linux.

Unfortunately, I can't seem to use node itself to write to Factorio's STDIN without it crashing. Adding the code below results in a crash

Code: Select all

setTimeout(()=>{
    f.stdin.write('/h')
},3000)
I have similar results when attempting in python.
According to some research the same seems to be true for C#.

However, I know FMTK successfully writes to Factorio's stdin using the same function calls that I tried in node. I've also heard of successes with Go and PowerShell.

So I guess I'd love some documentation on how Factorio opens it's STDIN on windows and ideally the conditions required to actually be able to communicate with it.
Bilka
Factorio Staff
Factorio Staff
Posts: 3309
Joined: Sat Aug 13, 2016 9:20 am
Contact:

Re: Console / stdin especially on windows

Post by Bilka »

If you're looking for modding help in the near future, I can move this post to that subforum.

Otherwise: This information is unlikely to be documented in the API docs, at most it might find a place on the wiki. There it would be a low prio project to find a place for information on stdin on different OS's and likely also its interaction with Steam.
I'm an admin over at https://wiki.factorio.com. Feel free to contact me if there's anything wrong (or right) with it.
Gweneph
Inserter
Inserter
Posts: 44
Joined: Thu Nov 14, 2019 11:51 pm
Contact:

Re: Console / stdin especially on windows

Post by Gweneph »

Thanks. I thought it would be a better fit for the wiki, but I didn't really know how to submit a request for information on the wiki.
vadcx
Long Handed Inserter
Long Handed Inserter
Posts: 51
Joined: Fri Apr 19, 2024 4:12 pm
Contact:

Re: Console / stdin especially on windows

Post by vadcx »

Yes this should be in the modding forum. As for adding to wiki if you Gweneph don't have an account there (I made one) and only want this one occasion written down, I can put it in for you.
I get that '/h' is not recognized as an internal or external command, operable program or batch file.
This sounds like you have dropped back to CMD.exe, it's not Factorio that received your input. This is usually called detaching, as detached from STDIN/console. Maybe due to a child process spawning. This is what unknown command to Factorio looks like:
/he
Unknown command "he". Type /h or /help for more help about commands.
---

I quickly wrote the following Lua code that runs Factorio and sends commands to it on STDIN. Works on Linux and there should be very few differences to run on Windows. I remember CMD not liking the "./factorio.exe" syntax among other things. I hope Windows doesn't turn LF into CRLF on pipes, but it already mangles binary data sometimes encoding it as UCS-2 (UTF-16) so who knows.

Code: Select all

#!/usr/bin/env lua

-- Open Shell, cd into Factorio's bin directory on your own please.
-- Steam/steamapps/common/Factorio/bin/x64/
-- or $HOME/.steam/steam/steamapps...
command = "./factorio --start-server-load-latest"

local pipe = io.popen(command .. " > ./stdout.txt 2> ./stderr.txt", "w")

print("Please wait a couple seconds, press Enter when Factorio is done loading")
print("You should run 'tail -f stdout.txt' in another console to see Factorio's output")

print()
print("waiting for you...")
io.read()

print("OK, entering command input mode. Anything you send will be relayed to Factorio's console")
print("if you want to stop the server, it says /quit works."
print("... and I found CTRL+C does too :) Pay attention if Factorio's process exists")
print("send 'q!' if you want the Lua script itself to quit")
print()
print("Start writing and then press ENTER:")
while true do
	local line = io.read()
	if not line then break end

	print("You entered line: '".. line .."'")
	pipe:write(line, "\n")
	-- you MUST flush the line for Factorio to receive it
	-- or make sure you are in line-buffered mode if provided by your library
	pipe:flush()
end

print("Quitting Lua script. Bye!")
Gweneph
Inserter
Inserter
Posts: 44
Joined: Thu Nov 14, 2019 11:51 pm
Contact:

Re: Console / stdin especially on windows

Post by Gweneph »

vadcx wrote: Sat Apr 27, 2024 4:32 amthere should be very few differences to run on Windows
Therein lies the problem.

My python and node programs worked fine on Linux, but crashed on windows if they attempted to write to the stdin pipe after Factorio was running for about 80ms. So, I think that's when Factorio does something confusing with its stdin on windows. When launched as a subprocess of a console program, it switches from the stdin that it was handed, and instead attaches to the console input buffer of the parent process. From my testing it seemed like my program and Factorio would alternate who consumed the chars from the buffer. So, while I couldn't use the console directly from CMD.exe, I could use it when I shouldn't be able to as my console input buffer was supposed to just be going to my program not Factorio.

In any case, I got my python program working by running it with pythonw.exe instead of python.exe so there was no console input buffer for Factorio to attach to.

At this point I'm not sure if this should just be documented as the expected behavior, or if this is a bug.
vadcx
Long Handed Inserter
Long Handed Inserter
Posts: 51
Joined: Fri Apr 19, 2024 4:12 pm
Contact:

Re: Console / stdin especially on windows

Post by vadcx »

You are right. This thing intercepts parent's STDIN and ignores the pipe that opened between parent and Factorio (stdout -> stdin). Only affects Windows.
I will post in this thread shortly: posting.php?mode=reply&f=58&t=75627

UPDATE: Aaaaand it's not a bug. Really isn't. viewtopic.php?f=58&p=609406#p609406
Buuuut I don't want to compile a C application on Windows just to showcase with Win32 API to document this on the wiki :mrgreen: I am sure this AllocConsole stuff would work as suggested.
Post Reply

Return to “Wiki Talk”