class MinecraftServerStatus::Query
Attributes
host[R]
port[R]
Public Class Methods
new(host, port=25565)
click to toggle source
# File lib/minecraft_server_status/query.rb, line 8 def initialize(host, port=25565) raise ArgumentError.new('host is required') if host.nil? @host = host @port = port end
Public Instance Methods
execute(options={})
click to toggle source
# File lib/minecraft_server_status/query.rb, line 14 def execute(options={}) timeout_sec = options.fetch(:timeout_sec, 1) retry_limit = options.fetch(:retry_limit, 1) retry_count = 0 errors = [] while retry_count < retry_limit begin response = "" Timeout.timeout(timeout_sec) do begin # Connect socket = TCPSocket.open(host, port) # Send request socket.write(pack_data("\x00\x00" + pack_data(host.encode("UTF-8")) + pack_port(port) + "\x01")) socket.write(pack_data("\x00")) # Read response unpack_varint(socket) unpack_varint(socket) l = unpack_varint(socket) while response.length < l response += socket.recv(1024) end ensure # Close socket.close if socket end end response.force_encoding("UTF-8") json_response = JSON.parse(response.gsub(/\xC2\xA7./, '')) return Result.new(json_response, true, errors) rescue Exception => e errors << e retry_count += 1 end end return Result.new(nil, false, errors) end
Private Instance Methods
pack_data(d)
click to toggle source
# File lib/minecraft_server_status/query.rb, line 81 def pack_data(d) return pack_varint(d.length) + d end
pack_port(i)
click to toggle source
# File lib/minecraft_server_status/query.rb, line 85 def pack_port(i) return [i].pack('n*') end
pack_varint(d)
click to toggle source
# File lib/minecraft_server_status/query.rb, line 68 def pack_varint(d) o = "" while true b = d & 0x7F d >>= 7 o += [ b | (d > 0 ? 0x80 : 0) ].pack('C*') if d == 0 break end end return o end
unpack_varint(s)
click to toggle source
# File lib/minecraft_server_status/query.rb, line 56 def unpack_varint(s) d = 0 for i in 0..4 b = s.recv(1).ord d |= (b & 0x7F) << 7*i if (b & 0x80).zero? break end end return d end