Class: MCQuery::Query

Inherits:
Object
  • Object
show all
Defined in:
lib/mc_query/query.rb,
lib/mc_query/connect.rb

Constant Summary collapse

@@MAGIC =
"\xFE\xFD"
@@REQUEST =
"#{@@MAGIC}\x00"
@@HANDSHAKE =
"#{@@MAGIC}\x09"

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ Query

Returns a new instance of Query.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/mc_query/query.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 = UDPSocket.new
  @socket.connect(@ip, @port)

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

Instance Method Details

#get_challenge_keyObject



61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/mc_query/query.rb', line 61

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_queryObject

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



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/mc_query/query.rb', line 41

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