class MCQuery::Query

Public Class Methods

new(opts = {}) click to toggle source
# File lib/mc_query/connect.rb, line 9
def initialize(opts = {})
  # Merge in the default options
  opts = {:ip => 'localhost', :port => '25565', :timeout => 8}.merge(opts)

  @ip      = opts[:ip]
  @port    = opts[:port]
  @timeout = opts[:timeout]

  # Connect to the server socket (based on the options)
  @socket = TCPSocket.new(@ip, @port)

  # Generate a session id and store it off
  @session_id = get_session_id
end

Public Instance Methods

get_challenge_key() click to toggle source
# File lib/mc_query/connect.rb, line 60
def get_challenge_key
  timeout @timeout do
    # Send the magic bytes, the handshake bytes, and the session id
    send_data("#{@@HANDSHAKE}#{@session_id}")

    # Get the raw data (splice out the headers, and convert to an int32)
    raw_key = recieve_data.to_i

    # Pack it as big endian and return it
    [raw_key].pack("N")
  end
end
simple_query() click to toggle source

Public: Do the Minecraft dance (according to the protocol) and

send back a hash of the result

Examples

simple_query
# => {
       :name => "My Server",
       :gametype => "SMP",
       :world_name => "world",
       :online_players => "0",
       :max_players => "150",
       :ip => "10.0.0.1",
     }

Returns the named hash of the data contained in the simple query

# File lib/mc_query/connect.rb, line 40
def simple_query
  # Store off the challenge key (we'll need this for querying)
  @challenge = get_challenge_key

  timeout @timeout do
    query  = @socket.send(encode_data("#{@@REQUEST}#{@session_id}") + @challenge.to_s, 0)
    buffer = recieve_data
    parsed = buffer.split("\0", 6)
    puts parsed
    {
        :name           => parsed[0],
        :gametype       => parsed[1],
        :world_name     => parsed[2],
        :online_players => parsed[3],
        :max_players    => parsed[4],
        :ip             => parsed[5]
    }
  end
end

Private Instance Methods

encode_data(data) click to toggle source
# File lib/mc_query/connect.rb, line 83
def encode_data(data)
  data.force_encoding(Encoding::ASCII_8BIT)
end
get_session_id() click to toggle source
# File lib/mc_query/connect.rb, line 75
def get_session_id
  [(rand(32) + 1) & 0x0F0F0F0F].pack("N")
end
recieve_data() click to toggle source
# File lib/mc_query/connect.rb, line 87
def recieve_data
  # Recieve the data, splicing out the headers
  @socket.recvfrom(1460)[0][5...-1]
end
send_data(data) click to toggle source
# File lib/mc_query/connect.rb, line 79
def send_data(data)
  @socket.send(encode_data(data), 0)
end