gamespy_query 0.0.5 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|