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
359 stars 65 forks source link

Support for Modern Warfare 3 (CS:Source protocol) #139

Closed bawNg closed 12 years ago

bawNg commented 12 years ago

MW3 uses Valve's CS:Source protocol for server queries, it appears that servers that use game port 27015 use 27017 as a query port.

Since it uses the same protocol, implementation should be trivial and it would be a great addition.

koraktor commented 12 years ago

Sounds good.

Did you try using the SourceServer class with a MW3 server? Maybe that already works to some extent.

bawNg commented 12 years ago

I did and it does not work at all, no matter what port I use, it simply times out. I did a quick manual test by sending the getchallenge packet "\xFF\xFF\xFF\xFF\x55\xFF\xFF\xFF\xFF" to a servers port 27017 and I got S2C_CHALLENGE response which I used to send A2S_PLAYER and the server responded accordingly.

koraktor commented 12 years ago

Hmm... seems like MW3 doesn't like the implicit challenging that normal Source servers are using now, i.e. the first A2S_PLAYER request will cause a S2C_CHALLENGE reply, the second request (with the correct challenge) will cause a S2A_PLAYER reply.

koraktor commented 12 years ago

Sorry for the delay, do you have some servers I can test against? (I don't own MW3)

koraktor commented 12 years ago

I was able to find some servers using GameTracker and I was also able to query those servers (including challenges). I think that MW3 might feature the newer protocol after an update.

@DeFirence Can you confirm this?

bawNg commented 12 years ago

I too do not own MW3, but I don't know of any updates to the protocol. My implementation is still working fine.

koraktor commented 12 years ago

Could you test using an unmodified version, either 1.1.0 or master? If this works without problems I will close this issue.

bawNg commented 12 years ago

I get a SteamCondenser::TimeoutError on both the servers I have been using with my implementation for the past few months. This happens both when using the game port and the game port incremented by 2, which is how I got my implementation working.

Here are the servers:

koraktor commented 12 years ago

I even get a timeout for this servers when just getting the server info (so no challenge). Seems like they're down.

PS: You're using Ruby right? Because there was a bug in the Java implementation that caused just this behavior.

bawNg commented 12 years ago

Yes I am using Ruby, and no they are not down, since my implementation queries them successfully.

I just queried the following from the first server:

{"header_data"=>73, "protocol_version"=>1, "server_name"=>"Modern Warfare 3", "map_name"=>"Mission", "game_directory"=>"modernwarfare3", "game_description"=>"MW3 Game Description", "app_id"=>42690, "number_of_players"=>0, "max_players"=>16, "number_of_bots"=>0, "dedicated"=>"d", "operating_system"=>"w", "password_needed"=>false, "secure"=>true, "game_version"=>"1.0.0.0", "server_port"=>27016, "server_id"=>90084543435591680, "server_tags"=>"gn\IW5\gt\jugg\hc\0\pu\1\m\mp_bravo\px\pn\mr\pc\0\ff\0\fg\md\kc\1\ac\0\d\2\qp\27017\vo\2\", :status=>:online, :players=>{}}

koraktor commented 12 years ago

Sorry, I can query other servers successfully, but your two don't even respond to one single request. Seems like some sort of filter is active.

nmap -p 27000-27100 152.111.192.252    
Starting Nmap 5.51 ( http://nmap.org ) at 2012-04-08 11:11 CEST
Nmap scan report for 152.111.192.252
Host is up (0.25s latency).
All 101 scanned ports on 152.111.192.252 are filtered

Nmap done: 1 IP address (1 host up) scanned in 9.69 seconds
bawNg commented 12 years ago

Yeah, nmap shows me the exact same output. The game servers seem to hide their query ports unless you make a valid query. This behavior confused me for a while because most of my initial attempts to query the servers failed and I assumed the ports were not open at all.

bawNg commented 12 years ago

Try using the following for the challenge request: "\xFF\xFF\xFF\xFF\x55\xFF\xFF\xFF\xFF"

koraktor commented 12 years ago

That's exactly what my code is producing.

Unmodified code from Ruby master plus one modification:

module SteamSocket
  def send(data_packet)
    puts "Sending #{data_packet.inspect}"
    puts "Sending #{data_packet.to_s.bytes.map { |c| "\\x#{c.to_s(16).upcase}" }}"

    @socket.send data_packet.to_s, 0
  end
end

Code:

s = SourceServer.new '152.111.192.252:27015'
s.update_challenge_number

Result:

Sending #<A2S_PLAYER_Packet:0x103bfd020 @content_data=#<StringIO:0x103bfcc88>, @header_data=85>
Sending \xFF\xFF\xFF\xFF\x55\xFF\xFF\xFF\xFF
./steam/sockets/steam_socket.rb:56:in `receive_packet': The operation timed out. (SteamCondenser::TimeoutError)
    from ./steam/sockets/source_socket.rb:27:in `reply'
    from ./steam/servers/game_server.rb:382:in `reply'
    from ./steam/servers/game_server.rb:222:in `handle_response_for_request'
    from ./steam/servers/game_server.rb:323:in `update_challenge_number'
    from /Users/koraktor/open-source/steam-condenser/ruby/lib/test.rb:16
    from -e:1:in `load'
    from -e:1
bawNg commented 12 years ago

Here is my debug log:

[15:27:15] Loaded module: SourceServer [15:27:20] [SourceServer] Requesting challenge... [15:27:20] 197.80.200.22:27023 <- "\xFF\xFF\xFF\xFFU\xFF\xFF\xFF\xFF" [15:27:20] [SourceServer] Got reply: S2C_CHALLENGE_Packet [15:27:28] [SourceServer] Requesting info... [15:27:28] 197.80.200.22:27023 <- "\xFF\xFF\xFF\xFFTSource Engine Query\x00" [15:27:28] [SourceServer] Got reply: S2A_INFO2_Packet [15:27:35] Unloaded module: SourceServer

koraktor commented 12 years ago

That server (197.80.200.22:27023) works for me, too. So I guess you can safely switch back to master (or wait for 1.2.0 which will be released soon). I'd close this issue, if you're fine with that. But feel free to test the current code before.

bawNg commented 12 years ago

As I mentioned, I had to increment the game server port by 2, that is actually 197.80.200.22:27021. I have since written my own source server query and RCON implementation for EventMachine since my projects are completely asynchronous.

You can close the issue whenever you like, but if the implementation stays as is, I suggest you add a note to the documentation that the port may have to be incremented for MW3 servers.

koraktor commented 12 years ago

Ah, that's it. Didn't notice that the ports weren't the query ports. So they're working like expected on master.

So I'm closing this.

PS: If your EventMachine based implementation is still based on Steam Condenser, feel free to share you code / open pull request(s). I'd love to base a future Ruby version (maybe 2.0.0) of Steam Condenser on EventMachine.