LuaRCON instances should persist!

Things that we aren't going to implement
Post Reply
User avatar
smartguy1196
Inserter
Inserter
Posts: 22
Joined: Tue Nov 10, 2020 6:09 am
Contact:

LuaRCON instances should persist!

Post by smartguy1196 »

relevant thread: viewtopic.php?f=23&t=93545&p=528996#p528996
LuaRCON objects should be allowed to print() after calling it
Currently, if you send this to RCON...

Code: Select all


/c local remote = rcon
script.on_event( defines.events.on_console_chat, function ( event )
	remote.print( "this does not work." )
end)
rcon.print( "this works" )

and calling LuaRCON.print() after the console command finishes (by sending a chat message to the server), it does nothing, and sends no packets to the calling rcon interface

It should, this allows third party developers such as modders and server hosting companies to make advanced rcon utilities for factorio

without having to be connected to the stdout stream of the factorio executable process

or using workarounds like clusterio
Suggestion:
instead of disabling the LuaRCON object after call, set `rcon` -> `nil`
as mentioned here: viewtopic.php?f=23&t=93545&p=528996#p528996
EDIT 1: (more info for the suggestion)
In regards to the ( Valve/Source ) RCON protocol:
boskid wrote: ↑
Sat Dec 26, 2020 8:19 am
smartguy1196 wrote: ↑
Sat Dec 26, 2020 8:14 am
FYI, you can send the same ID more than one, as long as it is a Response and it is sent back to the originating (request) socket, so in this example "socket information" would also contain the response id to the originating request that defined the LuaRCON instance.
Do you have any protocol description references for that claim? responses should arrive in the same order as the commands they requested them, so sending responses in order ID=1 (for request 1), ID=2 (for request 2) then ID=1 (unsolicited) would violate the order preserving property.
...
From the original Source RCON protocol spec (https://developer.valvesoftware.com/wik ... #Packet_ID):
The packet id field is a 32-bit little endian integer chosen by the client for each request. It may be set to any positive integer. When the server responds to the request, the response packet will have the same packet id as the original request (unless it is a failed SERVERDATA_AUTH_RESPONSE packet - see below.)

It need not be unique, but if a unique packet id is assigned, it can be used to match incoming responses to their corresponding requests.
Last edited by smartguy1196 on Sat Dec 26, 2020 9:37 am, edited 7 times in total.

Hornwitser
Fast Inserter
Fast Inserter
Posts: 204
Joined: Fri Oct 05, 2018 4:34 pm
Contact:

Re: LuaRCON instances should persist!

Post by Hornwitser »

This is certainly interesting as a method for doing Factorio to outside world communication. A neat idea. But if this was added I wouldn't call it RCON any more, there's no mechanism in RCON to send data from the server to the client outside the response to a command. I also don't quite see how this would work. Factorio can have multiple RCON connections active at the same time. How does Factorio know which connection to send to when doing rcon.print outside a command? The rcon object would have to remember which connection it's from and be script data serializable. And then there's the question of what happens when the rcon connection is closed but the Lua code tries to write data to it?

EIther way, making this work is a lot more involved than just not disabling rcon while outside a command.

User avatar
smartguy1196
Inserter
Inserter
Posts: 22
Joined: Tue Nov 10, 2020 6:09 am
Contact:

Re: LuaRCON instances should persist!

Post by smartguy1196 »

Hornwitser wrote: ↑
Sat Dec 26, 2020 7:25 am
But if this was added I wouldn't call it RCON any more, there's no mechanism in RCON to send data from the server to the client outside the response to a command. I also don't quite see how this would work. Factorio can have multiple RCON connections active at the same time. How does Factorio know which connection to send to when doing rcon.print outside a command? The rcon object would have to remember which connection it's from and be script data serializable. And then there's the question of what happens when the rcon connection is closed but the Lua code tries to write data to it?

EIther way, making this work is a lot more involved than just not disabling rcon while outside a command.
Store the connected socket/socket info as a private and inaccessible variable on the LuaRCON object.

RCON does have a way to receive communication from the server, because Factorio's RCON is simply a regular TCP connection using a specific buffer spec.

You can send multiple response packets back for a single request packet, if the RCON application on the client is configured/programmed correctly.

RCON also disconnects like any other TCP/UDP connection, so if the RCON interface isn't connected anymore, the socket on both the server and client will emit an "end"/"disconnect" event.

If you look at the source code for rcon-ts or node-rcon on NPM (nodejs Package Manager), you can see how this works in the this._send() and this._handleResponse() functions (NOTE: tcp connection is setup in the this.connect() function using net.createconnection() )
Last edited by smartguy1196 on Sat Dec 26, 2020 8:02 am, edited 1 time in total.

User avatar
boskid
Factorio Staff
Factorio Staff
Posts: 2227
Joined: Thu Dec 14, 2017 6:56 pm
Contact:

Re: LuaRCON instances should persist!

Post by boskid »

Wont implement.

RCON is specified to be request-response based. Unsolicited responses would confuse some rcon clients and there would be no specific value to be placed in the ID field of the response.


BTW 1: abusing text size tags as in first post is a bad idea.
BTW 2: using `script.on_event` inside of the `/c` is really bad idea because it is not save-load stable and will desync.
BTW 3: "reeeeee" or other meme are straight way to getting a warning.

User avatar
smartguy1196
Inserter
Inserter
Posts: 22
Joined: Tue Nov 10, 2020 6:09 am
Contact:

Re: LuaRCON instances should persist!

Post by smartguy1196 »

boskid wrote: ↑
Sat Dec 26, 2020 8:02 am
Wont implement.
Understood.
boskid wrote: ↑
Sat Dec 26, 2020 8:02 am
RCON is specified to be request-response based. Unsolicited responses would confuse some rcon clients and there would be no specific value to be placed in the ID field of the response.
FYI, you can send the same ID more than one, as long as it is a Response and it is sent back to the originating (request) socket, so in this example "socket information" would also contain the response id to the originating request that defined the LuaRCON instance.
boskid wrote: ↑
Sat Dec 26, 2020 8:02 am
BTW 1: abusing text size tags as in first post is a bad idea.
BTW 2: using `script.on_event` inside of the `/c` is really bad idea because it is not save-load stable and will desync.
BTW 3: "reeeeee" or other meme are straight way to getting a warning.
#1 -> apologies, reformatted to headers = sections, large-text = major points, small-text = amplifying information
#2 -> noted.
#3 -> apologies, removed.

User avatar
boskid
Factorio Staff
Factorio Staff
Posts: 2227
Joined: Thu Dec 14, 2017 6:56 pm
Contact:

Re: LuaRCON instances should persist!

Post by boskid »

smartguy1196 wrote: ↑
Sat Dec 26, 2020 8:14 am
FYI, you can send the same ID more than one, as long as it is a Response and it is sent back to the originating (request) socket, so in this example "socket information" would also contain the response id to the originating request that defined the LuaRCON instance.
Do you have any protocol description references for that claim? responses should arrive in the same order as the commands they requested them, so sending responses in order ID=1 (for request 1), ID=2 (for request 2) then ID=1 (unsolicited) would violate the order preserving property.

User avatar
smartguy1196
Inserter
Inserter
Posts: 22
Joined: Tue Nov 10, 2020 6:09 am
Contact:

Re: LuaRCON instances should persist!

Post by smartguy1196 »

boskid wrote: ↑
Sat Dec 26, 2020 8:19 am

Do you have any protocol description references for that claim? responses should arrive in the same order as the commands they requested them, so sending responses in order ID=1 (for request 1), ID=2 (for request 2) then ID=1 (unsolicited) would violate the order preserving property.
Hmm... no, but I've done it before, and it worked. I'll look into it and get back to you.

What I can tell you now, is that the socket doesn't reject the packets on its own as far as I am aware, the program parsing them usually does.

User avatar
smartguy1196
Inserter
Inserter
Posts: 22
Joined: Tue Nov 10, 2020 6:09 am
Contact:

Re: LuaRCON instances should persist!

Post by smartguy1196 »

boskid wrote: ↑
Sat Dec 26, 2020 8:19 am

Do you have any protocol description references for that claim? responses should arrive in the same order as the commands they requested them, so sending responses in order ID=1 (for request 1), ID=2 (for request 2) then ID=1 (unsolicited) would violate the order preserving property.
Actually, I just found it:

From the original Source RCON protocol spec (https://developer.valvesoftware.com/wik ... #Packet_ID):
The packet id field is a 32-bit little endian integer chosen by the client for each request. It may be set to any positive integer. When the server responds to the request, the response packet will have the same packet id as the original request (unless it is a failed SERVERDATA_AUTH_RESPONSE packet - see below.)

It need not be unique, but if a unique packet id is assigned, it can be used to match incoming responses to their corresponding requests.
Last edited by smartguy1196 on Sat Dec 26, 2020 8:57 am, edited 1 time in total.

Hornwitser
Fast Inserter
Fast Inserter
Posts: 204
Joined: Fri Oct 05, 2018 4:34 pm
Contact:

Re: LuaRCON instances should persist!

Post by Hornwitser »

boskid wrote: ↑
Sat Dec 26, 2020 8:19 am
Do you have any protocol description references for that claim? responses should arrive in the same order as the commands they requested them, so sending responses in order ID=1 (for request 1), ID=2 (for request 2) then ID=1 (unsolicited) would violate the order preserving property.
You already violate the order preserving property of RCON. If you send a large command followed by a small command you'll get the response back from the small command first. But why do you even care about the RCON "specification" though? What's implemented deviates so much from the "specification" that a standard RCON client doesn't work with Factorio. Since we already have to write our RCON clients to conform to Factorio's dialect there's little in the way for deviating more from it.

User avatar
smartguy1196
Inserter
Inserter
Posts: 22
Joined: Tue Nov 10, 2020 6:09 am
Contact:

Re: LuaRCON instances should persist!

Post by smartguy1196 »

What's implemented deviates so much from the "specification" that a standard RCON client doesn't work with Factorio. Since we already have to write our RCON clients to conform to Factorio's dialect there's little in the way for deviating more from it.
I'm pretty sure this still is in spec with the original TCP-based RCON protocol from Valve. Unless I missed something.

I know that a good amount of RCON interfaces were written for UDP-based RCON specs, and that makes them unusable with Factorio

User avatar
boskid
Factorio Staff
Factorio Staff
Posts: 2227
Joined: Thu Dec 14, 2017 6:56 pm
Contact:

Re: LuaRCON instances should persist!

Post by boskid »

smartguy1196 wrote: ↑
Sat Dec 26, 2020 8:32 am
Actually, I just found it:

From the original Source RCON protocol spec (https://developer.valvesoftware.com/wik ... #Packet_ID):
The packet id field is a 32-bit little endian integer chosen by the client for each request. It may be set to any positive integer. When the server responds to the request, the response packet will have the same packet id as the original request (unless it is a failed SERVERDATA_AUTH_RESPONSE packet - see below.)

It need not be unique, but if a unique packet id is assigned, it can be used to match incoming responses to their corresponding requests.
It is not even close to what i asked. Quoted part says that rcon client has full freedom of choosing ID values, up to using non unique ID's which means server cannot use request ID's for its own purposes (for example it cannot use it for request duplicate removal because client could reuse old values). There is nothing here saying that server can reuse ID from request to send unsolicited responses.

User avatar
smartguy1196
Inserter
Inserter
Posts: 22
Joined: Tue Nov 10, 2020 6:09 am
Contact:

Re: LuaRCON instances should persist!

Post by smartguy1196 »

boskid wrote: ↑
Sat Dec 26, 2020 12:34 pm
It is not even close to what i asked. Quoted part says that rcon client has full freedom of choosing ID values, up to using non unique ID's which means server cannot use request ID's for its own purposes (for example it cannot use it for request duplicate removal because client could reuse old values). There is nothing here saying that server can reuse ID from request to send unsolicited responses.
That quoted text was from the multiple response packet paragraph of the RCON protocol. I also wasn't talking about the server sending a request packet, but a second response packet with same ID, but different body.

That's literally how that paragraph is intended to be used.

However, I am beginning to notice that the real flaw is that the protocol was designed for Synchronous request handling. As Hornwitser said, Factorio uses Asynchronous, which is why he believes it deviates from the protocol spec (asynchronous calls do not respect order preservation).

However, this is where I disagree with Hornwitser. I disagree, because response-order preservation and synchronous request handling is NOT a requirement from the spec, rather a guarantee from how the Source Dedicated Server was designed. The source engine handles RCON requests synchronously, which means it is impossible to send response packets out of order.

Given this conversation, I am going make an edit to the Source page documenting the problem with asynchronous implementations of this protocol
Last edited by smartguy1196 on Sat Dec 26, 2020 10:14 pm, edited 1 time in total.

User avatar
smartguy1196
Inserter
Inserter
Posts: 22
Joined: Tue Nov 10, 2020 6:09 am
Contact:

Re: LuaRCON instances should persist!

Post by smartguy1196 »

boskid wrote: ↑
Sat Dec 26, 2020 12:34 pm
smartguy1196 wrote: ↑
Sat Dec 26, 2020 8:32 am
Actually, I just found it:

From the original Source RCON protocol spec (https://developer.valvesoftware.com/wik ... #Packet_ID):
The packet id field is a 32-bit little endian integer chosen by the client for each request. It may be set to any positive integer. When the server responds to the request, the response packet will have the same packet id as the original request (unless it is a failed SERVERDATA_AUTH_RESPONSE packet - see below.)

It need not be unique, but if a unique packet id is assigned, it can be used to match incoming responses to their corresponding requests.
It is not even close to what i asked. Quoted part says that rcon client has full freedom of choosing ID values, up to using non unique ID's which means server cannot use request ID's for its own purposes (for example it cannot use it for request duplicate removal because client could reuse old values). There is nothing here saying that server can reuse ID from request to send unsolicited responses.
Actually I see your confusion now. Here, this is the entire paragraph - https://developer.valvesoftware.com/wik ... _Responses:
Multiple-packet Responses

Most responses are small enough to fit within the maximum possible packet size of 4096 bytes. However, a few commands such as cvarlist and, occasionally, status produce responses too long to be sent in one response packet. When this happens, the server will split the response into multiple SERVERDATA_RESPONSE_VALUE packets. Unfortunately, it can be difficult to accurately determine from the first packet alone whether the response has been split.

One common workaround is for the client to send an empty SERVERDATA_RESPONSE_VALUE packet after every SERVERDATA_EXECCOMMAND request. Rather than throwing out the erroneous request, SRCDS mirrors it back to the client, followed by another RESPONSE_VALUE packet containing 0x0000 0001 0000 0000 in the packet body field. Because SRCDS always responds to requests in the order it receives them, receiving a response packet with an empty packet body guarantees that all of the meaningful response packets have already been received. Then, the response bodies can simply be concatenated to build the full response.

Special thanks to Koraktor for discovering this trick.
and here is more details about how the ID attribute should work:
SERVERDATA_RESPONSE_VALUE

A SERVERDATA_RESPONSE_VALUE packet is the response to a SERVERDATA_EXECCOMMAND request.

Field Contains
ID:
  • The ID assigned by the original request
Type:
  • 0
Body
  • The server's response to the original command. May be empty string (0x00) in some cases.
Note that particularly long responses may be sent in multiple SERVERDATA_RESPONSE_VALUE packets - see "Multiple-packet Responses" [...]
RCON can send more than one response to one request using the same ID as documented above

Post Reply

Return to β€œWon't implement”