Class: GamespyQuery::Master

Inherits:
Base
  • Object
show all
Defined in:
lib/gamespy_query/master.rb

Constant Summary collapse

PARAMS =
[:hostname, :gamever, :gametype, :gamemode, :numplayers, :maxplayers, :password, :equalModRequired, :mission, :mapname,
:mod, :signatures, :verifysignatures, :gamestate, :dedicated, :platform, :sv_battleeye, :language, :difficulty]
RX_ADDR_LINE =
/^[\s\t]*([\d\.]+)[\s\t:]*(\d+)[\s\t]*(.*)$/
DELIMIT =
case RUBY_PLATFORM
  when /-mingw32$/, /-mswin32$/
    "\\"
  else
    "\\\\"
end
RX_H =
/\A([\.0-9]*):([0-9]*) *\\(.*)/
STR_SPLIT =
"\\"

Constants included from Funcs

Funcs::RX_F, Funcs::RX_I, Funcs::RX_S

Instance Method Summary collapse

Methods included from Funcs

#clean, #clean_string, #get_string, #handle_chr, #strip_tags

Constructor Details

#initialize(geo = nil, game = "arma2oapc") ⇒ Master

Returns a new instance of Master.



28
29
30
# File 'lib/gamespy_query/master.rb', line 28

def initialize(geo = nil, game = "arma2oapc")
  @geo, @game = geo, game
end

Instance Method Details

#geoip_pathObject



17
18
19
20
21
22
23
24
25
26
# File 'lib/gamespy_query/master.rb', line 17

def geoip_path
  return File.join(Dir.pwd, "config") unless defined?(Rails)

  case RUBY_PLATFORM
  when /-mingw32$/, /-mswin32$/
    File.join(Rails.root, "config").gsub("/", "\\")
  else
    File.join(Rails.root, "config")
  end
end

#get_paramsObject



36
37
38
# File 'lib/gamespy_query/master.rb', line 36

def get_params
  PARAMS.clone.map{|e| "#{DELIMIT}#{e}"}.join("")
end

#get_server_list(list = nil, include_data = false, geo = nil) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/gamespy_query/master.rb', line 40

def get_server_list list = nil, include_data = false, geo = nil
  addrs = []
  list = %x[gslist -p "#{geoip_path}"#{" #{geo}-X #{get_params}" if include_data} -n #{@game}] if list.nil?
  if include_data
    addrs = handle_data(list, geo)
  else
    list.split("\n").each do |line|
      addrs << "#{$1}:#{$2}" if line =~ RX_ADDR_LINE
    end
  end
  addrs
end

#handle_data(reply, geo = nil) ⇒ Object



62
63
64
65
# File 'lib/gamespy_query/master.rb', line 62

def handle_data(reply, geo = nil)
  reply = reply.gsub("\\\\\\", "") if geo
  reply.split("\n").select{|line| line =~ RX_ADDR_LINE }
end

#process(list = self.read) ⇒ Object



32
33
34
# File 'lib/gamespy_query/master.rb', line 32

def process list = self.read
  self.to_hash list
end

#readObject



53
54
55
56
57
58
59
60
# File 'lib/gamespy_query/master.rb', line 53

def read
  geo = @geo ? @geo : "-Q 11 "
  unless geo.nil? || geo.empty? || File.exists?(File.join(geoip_path, "GeoIP.dat"))
    Tools.logger.warn "Warning: GeoIP.dat database missing. Can't parse countries. #{geoip_path}"
    geo = nil
  end
  get_server_list(nil, true, geo)
end

#to_hash(ar) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/gamespy_query/master.rb', line 69

def to_hash(ar)
  list = Hash.new
  ar.each_with_index do |entry, index|
    str = entry[RX_H]
    next unless str
    ip, port, content = $1, $2, $3
    content = content.split(STR_SPLIT)
    content << "" unless (content.size % 2 == 0)
    i = 0
    content.map! do |e|
      i += 1
      i % 2 == 0 ? e : clean_string(e)
    end
    addr = "#{ip}:#{port}"
    if list.has_key?(addr)
      e = list[addr]
    else
      e = Hash.new
      e[:ip] = ip
      e[:port] = port
      list[addr] = e
    end
    if e[:gamedata]
      e[:gamedata].merge!(Hash[*content])
    else
      e[:gamedata] = Hash[*content]
    end
  end
  list
end