EnriqCG / rcon-srcds

A zero-dependency Typescript library for the Source/Minecraft RCON Protocol
https://www.npmjs.com/package/rcon-srcds
MIT License
61 stars 20 forks source link

Not all commands give a response & another EventEmitter memory leak #7

Open bakapear opened 4 years ago

bakapear commented 4 years ago

It seems that only responses following this if-condition will return a message. This has some issues though:

server.execute('woof').then(console.log) // Unknown command "woof"
server.execute('echo hello').then(console.log) // Nothing?

Furthermore if you keep repeating the commands that don't respond, it will create a memory leak.

setInterval(() => server.execute('echo hello'), 1000)
// After 10 seconds: 
// Possible EventEmitter memory leak detected. 11 data listeners added to [Socket]. Use emitter.setMaxListeners() to increase limit
PhlexPlexico commented 4 years ago

So I think this is still an issue. It's not because of just some commands not returning this, but more along the lines of what the server sends back.

For example, I have two CS:GO servers. One hosted on a custom platform, one on DatHost. If I send status to both servers, one response looks like this:

hostname: DatHost server
version : 1.37.7.0/13770 1187/8012 secure  [G:1:*******]
udp/ip  : ***.***.***.***:27296  (public ip: ***.***.***.***)
os      :  Linux
type    :  community dedicated
map     : de_dust2
players : 0 humans, 0 bots (15/0 max) (hibernating)

# userid name uniqueid connected ping loss state rate adr
#end
L 11/02/2020 - 00:07:52: rcon from "***.***.***.***:50863": command "status"

And here's the response from the server that I've been working on setting up:

hostname: Counter-Strike: Global Offensive
version : 1.37.7.0/13770 1187/8012 secure  [G:1:*******]
udp/ip  : 0.0.0.0:25597  (public ip: ***.***.***.***)
os      :  Linux
type    :  community dedicated
map     : de_dust2
gotv[0]:  port 27020, delay 30.0s, rate 32.0
players : 0 humans, 1 bots (20/0 max) (hibernating)

# userid name uniqueid connected ping loss state rate adr
# 2 "SKLTV" BOT active 32
#end

It's missing that last line, and I'm still trying to figure out why, but is it possible that it is a server configuration issue as well?

Taraman17 commented 4 years ago

It seems that only responses following this if-condition will return a message. This has some issues though:

That is correct, since this is the workaround for valve not flagging answers with multiple packets in any way.

PhlexPlexico commented 4 years ago

Wouldn't it be possible to do much like they note in the Valve Dev Wiki and just send an empty response value right after you send your request?

https://developer.valvesoftware.com/wiki/Source_RCON_Protocol#Multiple-packet_Responses

Or is it not possible within the given implementation?

Taraman17 commented 4 years ago

As I added this part of the code, I can say it looked more elegant to me than the empty response workaround.

But if this does not work in all cases, maybe this should be changed.

PhlexPlexico commented 4 years ago

Unfortunately it does not, since I have a handful of servers that seem to give that last line response as it's "end packet" :( It seems DatHost servers are very constant, but from a setup from a friend (on pterodactyl), and fhost, I found that the line that includes a timestamp happens less often than I've seen.

Taraman17 commented 4 years ago

As I just found out, the server cvar "sv_logecho" is responsible. If it is set to 1, the message is logged at the end of the transmission. "sv_logecho" = "1" archive - Echo log information to the console.

So for now, this should be a workaround.

PhlexPlexico commented 4 years ago

This would also require log on for server logging as well, I believe.

E: Also, it appears that it isn't quite fixed, as calling certain things like map de_dust2 causes the same issue.

c43721 commented 3 years ago

I'm looking into why map and changelevel in source does not resolve with a value, since I believe it's a timeout error from the gameserver.

My initial thought was it just doesn't respond with anything, but the docs never mention that, rather "some commands may not respond", but map should respond with something like "Changing level to ...".

EnriqCG commented 3 years ago

When you execute map, the server sort of "restarts" itself to load the specified map - all players are kicked from the server (and clients are instructed to try and reconnect), all Sourcemod plugins have to be reloaded, and game configs are executed again. The GOTV instance is also instantly restarted. Valve calls this behavior a hard change. I can see how this operation ends up with the server not responding to anything and just going ahead with the reset.

According to Valve, changelevel is more of a "soft change" that doesn't kick players out from the server. But it looks like the reset behavior happens here too.

Taraman17 commented 3 years ago

To check for the success of a mapchange, I look for the following in the logs:

L 12/29/2005 - 13:33:49: Started map "cs_italy" (CRC "1940414799")

Until now, I did not find another way...

EnriqCG commented 3 years ago

I look for the following in the logs:

Sadly, that requires listening to UDP logs created by the server, which is out of the library's scope.

I had a look at how eBot (an old match manager for CS:GO running through rcon commands) handles map changes and it just sends a changelevel command expecting no response back: https://github.com/deStrO/eBot-CSGO/blob/179db02043bfb1ee775c70c6f23d0553f0536332/src/eBot/Match/Match.php#L642

Taraman17 commented 1 year ago

With the latest pullrequest, this should also be closable.