Skip to content

Instantly share code, notes, and snippets.

@wedtm
Created February 25, 2012 04:35
Show Gist options
  • Save wedtm/1906478 to your computer and use it in GitHub Desktop.
Save wedtm/1906478 to your computer and use it in GitHub Desktop.
Ruby based Minecraft Vanilla Query Check
#
# Tested on 1.9.2-p290, Written by Miles Smith (WedTM)
#
require 'socket'
class MCQuery
MAGIC_PREFIX = "\xFE\xFD"
PACKET_TYPE_CHALLENGE = "\x09"
PACKET_TYPE_QUERY = "\x00"
ID = "\x00\x00\x00\x00"
DEFAULTS = {
host: "localhost",
port: 25565,
}
def initialize(opts = {})
@opts = DEFAULTS.merge! opts
@socket = UDPSocket.new
@socket.connect(@opts[:host], @opts[:port])
end
def start
@socket.send(MAGIC_PREFIX + PACKET_TYPE_CHALLENGE + ID, 0)
t = @socket.recvfrom(1460)[0]
key = t[5...-1].to_i
@key = Array(key).pack('N')
end
def simple
start
query = @socket.send(MAGIC_PREFIX + PACKET_TYPE_QUERY + ID + @key, 0)
data = @socket.recvfrom(1460)[0]
buffer = data[5...-1]
val = {}
val[:motd], val[:gametype], val[:map], val[:numplayers], val[:maxplayers], buf = buffer.split("\x00", 6)
val
end
def full
start
query = @socket.send(MAGIC_PREFIX + PACKET_TYPE_QUERY + ID + @key + ID, 0)
data = @socket.recvfrom(1460)[0]
buffer = data[11...-1]
items, players = buffer.split("\x00\x00\x01player_\x00\x00")
if items[0...8] == 'hostname'
items = 'motd' + items[8...-1]
end
vals = {}
items = items.split("\x00")
items.each_with_index do |key, idx|
next unless idx % 2 == 0
vals[key] = items[idx + 1]
end
vals["motd"] = vals["hostname"]
vals.delete("hostname")
vals.delete("um") if vals["um"]
players = players[0..-2]
if players
vals[:players] = players.split("\x00")
end
puts vals
vals["raw_plugins"] = vals["plugins"]
parts = vals["raw_plugins"].split(":")
server = parts[0].strip()
plugins = []
if parts.size == 2
plugins = parts[1].split(";").map {|value| value.strip() }
end
vals["plugins"] = plugins
vals["server"] = server
vals
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment