gamespy_query 0.0.5 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +0 -0
- data/Gemfile +0 -0
- data/README.md +0 -0
- data/Rakefile +0 -0
- data/gamespy_query.gemspec +0 -0
- data/lib/gamespy_query/base.rb +87 -55
- data/lib/gamespy_query/master.rb +90 -81
- data/lib/gamespy_query/parser.rb +234 -234
- data/lib/gamespy_query/socket.rb +325 -266
- data/lib/gamespy_query/socket_master.rb +78 -0
- data/lib/gamespy_query/version.rb +1 -1
- data/lib/gamespy_query.rb +1 -0
- metadata +3 -2
data/.gitignore
CHANGED
File without changes
|
data/Gemfile
CHANGED
File without changes
|
data/README.md
CHANGED
File without changes
|
data/Rakefile
CHANGED
File without changes
|
data/gamespy_query.gemspec
CHANGED
File without changes
|
data/lib/gamespy_query/base.rb
CHANGED
@@ -1,55 +1,87 @@
|
|
1
|
-
#require 'six/tools'
|
2
|
-
require 'action_controller'
|
3
|
-
require 'logger'
|
4
|
-
|
5
|
-
module GamespyQuery
|
6
|
-
STR_X0, STR_X1, STR_X2 = "\x00", "\x01", "\x02"
|
7
|
-
RX_X0, RX_X0_S, RX_X0_E = /\x00/, /^\x00/, /\x00$/
|
8
|
-
RX_X0_SPEC = /^\x00|[^\x00]+\x00?/
|
9
|
-
STR_EMPTY = ""
|
10
|
-
|
11
|
-
DEBUG = false
|
12
|
-
|
13
|
-
module Tools
|
14
|
-
STR_EMPTY = ""
|
15
|
-
|
16
|
-
module_function
|
17
|
-
def logger
|
18
|
-
@logger ||= ActionController::Base.logger || Logger.new("logger.log")
|
19
|
-
end
|
20
|
-
|
21
|
-
def debug(&block)
|
22
|
-
return unless DEBUG
|
23
|
-
logger.debug yield
|
24
|
-
rescue Exception => e
|
25
|
-
puts "Error: #{e.class} #{e.message}, #{e.backtrace.join("\n")}"
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
|
30
|
-
class TimeOutError < StandardError
|
31
|
-
end
|
32
|
-
|
33
|
-
def strip_tags(str)
|
34
|
-
# TODO: Strip tags!!
|
35
|
-
str
|
36
|
-
end
|
37
|
-
|
38
|
-
RX_F = /\A\-?[0-9][0-9]*\.[0-9]*\Z/
|
39
|
-
RX_I = /\A\-?[0-9][0-9]*\Z/
|
40
|
-
RX_S = /\A\-?0[0-9]+.*\Z/
|
41
|
-
|
42
|
-
def clean(value) # TODO: Force String, Integer, Float etc?
|
43
|
-
case value
|
44
|
-
when STR_X0
|
45
|
-
nil
|
46
|
-
when RX_F
|
47
|
-
value =~ RX_S ? strip_tags(value) : value.to_f
|
48
|
-
when RX_I
|
49
|
-
value =~ RX_S ? strip_tags(value) : value.to_i
|
50
|
-
else
|
51
|
-
strip_tags(value)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
|
1
|
+
#require 'six/tools'
|
2
|
+
require 'action_controller'
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
module GamespyQuery
|
6
|
+
STR_X0, STR_X1, STR_X2 = "\x00", "\x01", "\x02"
|
7
|
+
RX_X0, RX_X0_S, RX_X0_E = /\x00/, /^\x00/, /\x00$/
|
8
|
+
RX_X0_SPEC = /^\x00|[^\x00]+\x00?/
|
9
|
+
STR_EMPTY = ""
|
10
|
+
|
11
|
+
DEBUG = false
|
12
|
+
|
13
|
+
module Tools
|
14
|
+
STR_EMPTY = ""
|
15
|
+
|
16
|
+
module_function
|
17
|
+
def logger
|
18
|
+
@logger ||= ActionController::Base.logger || Logger.new("logger.log")
|
19
|
+
end
|
20
|
+
|
21
|
+
def debug(&block)
|
22
|
+
return unless DEBUG
|
23
|
+
logger.debug yield
|
24
|
+
rescue Exception => e
|
25
|
+
puts "Error: #{e.class} #{e.message}, #{e.backtrace.join("\n")}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
module Funcs
|
30
|
+
class TimeOutError < StandardError
|
31
|
+
end
|
32
|
+
|
33
|
+
def strip_tags(str)
|
34
|
+
# TODO: Strip tags!!
|
35
|
+
str
|
36
|
+
end
|
37
|
+
|
38
|
+
RX_F = /\A\-?[0-9][0-9]*\.[0-9]*\Z/
|
39
|
+
RX_I = /\A\-?[0-9][0-9]*\Z/
|
40
|
+
RX_S = /\A\-?0[0-9]+.*\Z/
|
41
|
+
|
42
|
+
def clean(value) # TODO: Force String, Integer, Float etc?
|
43
|
+
case value
|
44
|
+
when STR_X0
|
45
|
+
nil
|
46
|
+
when RX_F
|
47
|
+
value =~ RX_S ? strip_tags(value) : value.to_f
|
48
|
+
when RX_I
|
49
|
+
value =~ RX_S ? strip_tags(value) : value.to_i
|
50
|
+
else
|
51
|
+
strip_tags(value)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def handle_chr(number)
|
56
|
+
number = ((number % 256)+256) if number < 0
|
57
|
+
number = number % 256 if number > 255
|
58
|
+
number
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_string(*params)
|
62
|
+
puts "Getting string #{params}"
|
63
|
+
_get_string(*params)
|
64
|
+
end
|
65
|
+
|
66
|
+
if RUBY_PLATFORM =~ /mswin32/
|
67
|
+
include System::Net
|
68
|
+
include System::Net::Sockets
|
69
|
+
|
70
|
+
def _get_string(str)
|
71
|
+
str.map {|e| e.chr}.join # begin; System::Text::Encoding.USASCII.GetString(reply[0]).to_s; rescue nil, Exception => e; Tools.log_exception(e); reply[0].map {|e| e.chr}.join; end
|
72
|
+
end
|
73
|
+
else
|
74
|
+
require 'socket'
|
75
|
+
require 'timeout'
|
76
|
+
|
77
|
+
def _get_string(str)
|
78
|
+
str
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
class Base
|
85
|
+
include Funcs
|
86
|
+
end
|
87
|
+
end
|
data/lib/gamespy_query/master.rb
CHANGED
@@ -1,81 +1,90 @@
|
|
1
|
-
require_relative 'base'
|
2
|
-
|
3
|
-
module GamespyQuery
|
4
|
-
class Master < Base
|
5
|
-
PARAMS = [:hostname, :gamever, :gametype, :gamemode, :numplayers, :maxplayers, :password, :equalModRequired, :mission, :mapname,
|
6
|
-
:mod, :signatures, :verifysignatures, :gamestate, :dedicated, :platform, :sv_battleeye, :language, :difficulty]
|
7
|
-
|
8
|
-
# TODO: Gspy v3 multipacket
|
9
|
-
|
10
|
-
DELIMIT = case RUBY_PLATFORM
|
11
|
-
when /-mingw32$/, /-mswin32$/
|
12
|
-
"\\"
|
13
|
-
else
|
14
|
-
"\\\\"
|
15
|
-
end
|
16
|
-
|
17
|
-
def geoip_path
|
18
|
-
return File.join(Dir.pwd, "config") unless defined?(Rails)
|
19
|
-
|
20
|
-
case RUBY_PLATFORM
|
21
|
-
when /-mingw32$/, /-mswin32$/
|
22
|
-
File.join(Rails.root, "config").gsub("/", "\\")
|
23
|
-
else
|
24
|
-
File.join(Rails.root, "config")
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def initialize(geo = nil, game = "arma2oapc")
|
29
|
-
@geo, @game = geo, game
|
30
|
-
end
|
31
|
-
|
32
|
-
def process
|
33
|
-
@list = Hash.new
|
34
|
-
self.to_hash(self.read)
|
35
|
-
end
|
36
|
-
|
37
|
-
def
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
end
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module GamespyQuery
|
4
|
+
class Master < Base
|
5
|
+
PARAMS = [:hostname, :gamever, :gametype, :gamemode, :numplayers, :maxplayers, :password, :equalModRequired, :mission, :mapname,
|
6
|
+
:mod, :signatures, :verifysignatures, :gamestate, :dedicated, :platform, :sv_battleeye, :language, :difficulty]
|
7
|
+
|
8
|
+
# TODO: Gspy v3 multipacket
|
9
|
+
|
10
|
+
DELIMIT = case RUBY_PLATFORM
|
11
|
+
when /-mingw32$/, /-mswin32$/
|
12
|
+
"\\"
|
13
|
+
else
|
14
|
+
"\\\\"
|
15
|
+
end
|
16
|
+
|
17
|
+
def geoip_path
|
18
|
+
return File.join(Dir.pwd, "config") unless defined?(Rails)
|
19
|
+
|
20
|
+
case RUBY_PLATFORM
|
21
|
+
when /-mingw32$/, /-mswin32$/
|
22
|
+
File.join(Rails.root, "config").gsub("/", "\\")
|
23
|
+
else
|
24
|
+
File.join(Rails.root, "config")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize(geo = nil, game = "arma2oapc")
|
29
|
+
@geo, @game = geo, game
|
30
|
+
end
|
31
|
+
|
32
|
+
def process
|
33
|
+
@list = Hash.new
|
34
|
+
self.to_hash(self.read)
|
35
|
+
end
|
36
|
+
|
37
|
+
def get_server_list list = nil
|
38
|
+
addrs = []
|
39
|
+
list = %x[gslist -n #{@game}] if list.nil?
|
40
|
+
list.split("\n").each do |line|
|
41
|
+
addrs << "#{$1}:#{$2}" if line =~ /([\d\.]+)[\s\t]*(\d+)/
|
42
|
+
end
|
43
|
+
addrs
|
44
|
+
end
|
45
|
+
|
46
|
+
def read
|
47
|
+
geo = @geo ? @geo : "-Q 11 "
|
48
|
+
unless File.exists?(File.join(geoip_path, "GeoIP.dat"))
|
49
|
+
puts
|
50
|
+
puts "Warning: GeoIP.dat database missing. Can't parse countries. #{geoip_path}"
|
51
|
+
geo = nil
|
52
|
+
end
|
53
|
+
reply = %x[gslist -p "#{geoip_path}" -n #{@game} #{geo}-X #{PARAMS.clone.map{|e| "#{DELIMIT}#{e}"}.join("")}]
|
54
|
+
reply.gsub!("\\\\\\", "") if geo
|
55
|
+
reply.split("\n")
|
56
|
+
end
|
57
|
+
|
58
|
+
RX_H = /\A([\.0-9]*):([0-9]*) *\\(.*)/
|
59
|
+
STR_SPLIT = "\\"
|
60
|
+
def to_hash(ar)
|
61
|
+
ar.each_with_index do |entry, index|
|
62
|
+
str = entry[RX_H]
|
63
|
+
next unless str
|
64
|
+
ip, port, content = $1, $2, $3
|
65
|
+
content = content.split(STR_SPLIT)
|
66
|
+
content << "" unless (content.size % 2 == 0)
|
67
|
+
i = 0
|
68
|
+
content.map! do |e|
|
69
|
+
i += 1
|
70
|
+
i % 2 == 0 ? e : clean(e)
|
71
|
+
end
|
72
|
+
addr = "#{ip}:#{port}"
|
73
|
+
if @list.has_key?(addr)
|
74
|
+
e = @list[addr]
|
75
|
+
else
|
76
|
+
e = Hash.new
|
77
|
+
e[:ip] = ip
|
78
|
+
e[:port] = port
|
79
|
+
@list[addr] = e
|
80
|
+
end
|
81
|
+
if e[:gamedata]
|
82
|
+
e[:gamedata].merge!(Hash[*content])
|
83
|
+
else
|
84
|
+
e[:gamedata] = Hash[*content]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
@list
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|