koraktor / steam-condenser

A multi-language library for querying the Steam Community, Source, GoldSrc servers and Steam master servers
https://koraktor.de/steam-condenser
Other
356 stars 67 forks source link

RCon Exec Timeout Exception #287

Open crazedmeph opened 8 years ago

crazedmeph commented 8 years ago

I am trying to just run a basic rcon to my server with this code

try { GameServer server = new SourceServer("MyExternalIp", 11111); server.rconAuth("servPass01"); String output = server.rconExec("status"); System.out.println(); }catch(Exception e){ e.printStackTrace(); }

Note MyExternalIp was removed, and port was changed to a random number.

I know everything is set up correctly because I can use ARKon perfectly fine... But as soon as I try to use this java code I get a timeout exception.

Jan 16, 2016 1:20:37 PM com.github.koraktor.steamcondenser.steam.sockets.RCONSocket getReply INFO: Received packet of type "class com.github.koraktor.steamcondenser.steam.packets.rcon.RCONAuthResponse".

java.util.concurrent.TimeoutException at com.github.koraktor.steamcondenser.steam.sockets.SteamSocket.receivePacket(SteamSocket.java:112) at com.github.koraktor.steamcondenser.steam.sockets.RCONSocket.getReply(RCONSocket.java:99) at com.github.koraktor.steamcondenser.steam.servers.SourceServer.rconAuth(SourceServer.java:152) at Test.main(Test.java:11)

My ports opened should not be a problem because again ARKon works perfect without any issues using the same exact ip/port/pass. But the ports that are opened are the RCon port (11111 in this example) The server port and query port. I am also using this branch steam-condenser-java-1.3.9

Am I doing something incorrect? This seems way too simple for me to mess up....

koraktor commented 8 years ago

Is this an ARK server? If so, the RCON port might be different from the game port.

crazedmeph commented 8 years ago

This is an Ark Server I set the RCon port manually so it is correct and I can also use another program to query the RCon on that same port. So I am not sure what the issue is.

koraktor commented 8 years ago

Maybe ARK’s RCON implementation differs from vanilla Source servers. Is there a free dedicated server that I might use for testing?

crazedmeph commented 8 years ago

Ill set something up on my server for you to use for testing. Is there a email or something that I can PM you the details (IP/Port/Password) once its ready to use? I do not want to put my info on here.

koraktor commented 8 years ago

Thanks, but I'm currently installing the dedicated server on one of my machines. Please note that ARK is a Unreal engine game, so I don´t think, that it will work at all.

JinHadah commented 7 years ago

TL;DR: For the Java library, remove the second occurence of ' reply = this.rconSocket.getReply(); ' after the ban check in SourceServer::rconAuth(). For PHP, do the same but also change the -2 position check in SourceServer::rconExec() to true if not empty.

Now for the details...

I've had this same problem using the PHP library. The first cause was found in SourceServer::rconAuth() as demonstrated in this snippet:

$reply = $this->rconSocket->getReply();
        if ($reply == null) {
            throw new RCONBanException();
        }
$reply = $this->rconSocket->getReply();

The second call to getReply() times out, probably because there isn't a second server response waiting. I commented out the second call to getReply() since the data should be unchanged and authentication went fine.

Now SteamSocket::recievePacket() is throwing a TimeoutException on rconExec(). This is odd since the exception is thrown after an RCONTerminate packet is sent. The server executes the command sent and returns data, but for reasons that I have not been able to ascertain RCONSocket is calling SteamSocket::receivePacket() one more time and a TimeoutException is thrown.

The culprit, as it turns out, it in the exit condition for the rconAuth loop in SourceServer. I'm not sure how a true Source server responds, but on the nth round of the loop, the Ark server has nothing else to say, and responds with "Server received, But no response!! ", so the second condition of the do-wile loop is unsatisfied, causing a third round of the loop even though there is no packet to be received, which causes the timeout.

I've changed the second condition for the loop exit and I no longer receive timeout exceptions, but I haven't tested it with server response data that exceeds 4096 bytes.

This is quick and dirty, but it seems to work. Ark seems to employ the Source RCON protocol imperfectly, so there is probably some condition which will break everything again. Good luck!

koraktor commented 7 years ago

@JinHadah Thanks for having a look at this.

I think the main problem is probably that ARK does not have this – rather quirky – way of terminating RCON communication. After not being able to figuring it out for quite a while I finally came up with the terminator idea. The duplicated packets seem to unsupported by ARK.

Currently, I don’t see the library supporting non-Source/-GoldSrc games. But I would happily accept patches that fix this in a good, backwards compatible version.

byroot commented 7 years ago

I think I have the same issue with the Ruby library against Squad servers.

Any command that returns more than a few dozen bytes end up timing out.

koraktor commented 7 years ago

@byroot Any chance you could test if Squad also does not send a second reply (and getReply() fails in the way described above). Most importantly, how does the server send big replies spanning over multiple packets.

I could imagine some sort of flag that allows to switch compatibility with third-party server that use this – somewhat different – Source RCON protocol.

byroot commented 7 years ago

Squad also does not send a second reply

So I managed to make it work by heavily modifying: https://github.com/ONWT/Rcon/blob/master/lib/rcon.rb

What happens is not that the squad server send 2 replies, it's more subtle.

The command I had problems with is ListPlayers, the others were fine.

Turns out he responses normally are in ASCII, but if one of the players has a non-ASCII character in it's name, the the whole response turn into UTF16, but the SIZE header is not updated in consequence.

I managed to handle that with the following (very ugly) code:

        if IO.select([@socket], nil, nil, 2)
          tmp = @socket.recv(14)
          if tmp.nil?
            return nil
          end
          size, request_id, type, message = tmp.unpack("VVVa*")

          total_size = size
          # the 'size - 10' here accounts for the fact that we've snarfed 14 bytes,
          # the size (which is 4 bytes) is not counted, yet represents the rest
          # of the packet (which we have already taken 10 bytes from)
          2.times do |i|
            expected_size = size - 10

            # special case for authentication
            unless message.sub! /\x00\x00$/, ""
              response << message

              while expected_size > 0
                tmp = @socket.recv(expected_size)
                response << tmp
                expected_size -= tmp.bytesize
              end

              if response.sub! /\x00\x00$/, ""
                if i == 0
                  break
                else
                  response = response.force_encoding(Encoding::UTF_16LE).encode(Encoding::UTF_8)
                end
              end
            end
          end
        end

I'll see if I can add Squad support to steam-condenser.

Minidoracat commented 6 years ago

@JinHadah @koraktor
How to fix it? ARK RCON

unknown

koraktor commented 6 years ago

@Minidoracat You should probably start with using the SourceServer class. This should get ARK RCON working (with the limitations mentioned above).

Minidoracat commented 6 years ago

@koraktor I used SourceServer ,bug Timeout
:'(

tim 20171228180221

koraktor commented 6 years ago

@Minidoracat See the comment by @JinHadah above.

JinHadah commented 6 years ago

@Minidocrat that looks like the exact issue which I described above. I suspect that it's caused by SourceServer waiting for that non-existent terminating response from the Ark server. I included a messy solution in my post, look in the last paragraph. Someday I'll have free time again and I'll submit a cleaner solution.