steam-condenser 1.1.0 → 1.2.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/Gemfile.lock +30 -0
- data/LICENSE +1 -1
- data/README.md +4 -3
- data/lib/steam-condenser/version.rb +2 -2
- data/lib/steam/community/alien_swarm/alien_swarm_mission.rb +24 -22
- data/lib/steam/community/alien_swarm/alien_swarm_stats.rb +66 -65
- data/lib/steam/community/alien_swarm/alien_swarm_weapon.rb +6 -6
- data/lib/steam/community/app_news.rb +2 -2
- data/lib/steam/community/css/css_map.rb +4 -4
- data/lib/steam/community/css/css_stats.rb +43 -43
- data/lib/steam/community/css/css_weapon.rb +5 -5
- data/lib/steam/community/defense_grid/defense_grid_stats.rb +36 -35
- data/lib/steam/community/dods/dods_class.rb +14 -14
- data/lib/steam/community/dods/dods_stats.rb +5 -4
- data/lib/steam/community/dods/dods_weapon.rb +6 -6
- data/lib/steam/community/game_achievement.rb +38 -31
- data/lib/steam/community/game_inventory.rb +6 -6
- data/lib/steam/community/game_leaderboard.rb +34 -32
- data/lib/steam/community/game_leaderboard_entry.rb +6 -6
- data/lib/steam/community/game_stats.rb +39 -65
- data/lib/steam/community/game_weapon.rb +2 -2
- data/lib/steam/community/l4d/abstract_l4d_stats.rb +54 -49
- data/lib/steam/community/l4d/abstract_l4d_weapon.rb +7 -6
- data/lib/steam/community/l4d/l4d2_map.rb +10 -10
- data/lib/steam/community/l4d/l4d2_stats.rb +33 -33
- data/lib/steam/community/l4d/l4d2_weapon.rb +8 -7
- data/lib/steam/community/l4d/l4d_explosive.rb +5 -4
- data/lib/steam/community/l4d/l4d_map.rb +8 -7
- data/lib/steam/community/l4d/l4d_stats.rb +7 -7
- data/lib/steam/community/l4d/l4d_weapon.rb +5 -4
- data/lib/steam/community/portal2/portal2_stats.rb +3 -3
- data/lib/steam/community/steam_game.rb +106 -16
- data/lib/steam/community/steam_group.rb +51 -40
- data/lib/steam/community/steam_id.rb +119 -87
- data/lib/steam/community/tf2/tf2_class.rb +14 -14
- data/lib/steam/community/tf2/tf2_class_factory.rb +2 -2
- data/lib/steam/community/tf2/tf2_engineer.rb +5 -7
- data/lib/steam/community/tf2/tf2_golden_wrench.rb +1 -1
- data/lib/steam/community/tf2/tf2_medic.rb +4 -6
- data/lib/steam/community/tf2/tf2_sniper.rb +3 -5
- data/lib/steam/community/tf2/tf2_spy.rb +10 -6
- data/lib/steam/community/tf2/tf2_stats.rb +15 -7
- data/lib/steam/community/web_api.rb +15 -1
- data/lib/steam/community/xml_data.rb +17 -0
- data/lib/steam/servers/game_server.rb +4 -4
- data/lib/steam/servers/master_server.rb +2 -2
- data/lib/steam/servers/source_server.rb +0 -2
- data/lib/steam/sockets/goldsrc_socket.rb +2 -2
- data/lib/steam/steam_player.rb +2 -2
- data/steam-condenser.gemspec +3 -2
- data/test/helper.rb +10 -2
- data/test/steam/communtiy/test_steam_group.rb +4 -4
- data/test/steam/communtiy/test_steam_id.rb +28 -2
- data/test/steam/communtiy/test_web_api.rb +2 -2
- data/test/steam/packets/test_steam_packet.rb +37 -0
- data/test/steam/servers/test_game_server.rb +296 -308
- data/test/steam/servers/test_goldsrc_server.rb +59 -59
- data/test/steam/servers/test_master_server.rb +131 -131
- data/test/steam/servers/test_server.rb +72 -72
- data/test/steam/servers/test_source_server.rb +126 -140
- data/test/steam/sockets/test_master_server_socket.rb +1 -0
- metadata +39 -19
@@ -8,9 +8,7 @@ require 'steam/community/tf2/tf2_class'
|
|
8
8
|
# Represents the stats for the Team Fortress 2 Sniper class for a specific user
|
9
9
|
#
|
10
10
|
# @author Sebastian Staudt
|
11
|
-
class TF2Sniper
|
12
|
-
|
13
|
-
include TF2Class
|
11
|
+
class TF2Sniper < TF2Class
|
14
12
|
|
15
13
|
# Returns the maximum number enemies killed with a headshot by the player in
|
16
14
|
# a single life as a Sniper
|
@@ -20,11 +18,11 @@ class TF2Sniper
|
|
20
18
|
|
21
19
|
# Creates a new instance of the Sniper class based on the given XML data
|
22
20
|
#
|
23
|
-
# @param [
|
21
|
+
# @param [Hash<String, Object>] class_data The XML data for this Sniper
|
24
22
|
def initialize(class_data)
|
25
23
|
super class_data
|
26
24
|
|
27
|
-
@max_headshots = class_data
|
25
|
+
@max_headshots = class_data['iheadshots'].to_i
|
28
26
|
end
|
29
27
|
|
30
28
|
end
|
@@ -8,9 +8,7 @@ require 'steam/community/tf2/tf2_class'
|
|
8
8
|
# Represents the stats for the Team Fortress 2 Spy class for a specific user
|
9
9
|
#
|
10
10
|
# @author Sebastian Staudt
|
11
|
-
class TF2Spy
|
12
|
-
|
13
|
-
include TF2Class
|
11
|
+
class TF2Spy < TF2Class
|
14
12
|
|
15
13
|
# Returns the maximum number enemies killed with a backstab by the player in
|
16
14
|
# a single life as a Spy
|
@@ -18,6 +16,11 @@ class TF2Spy
|
|
18
16
|
# @return [Fixnum] Maximum number of buildings built
|
19
17
|
attr_reader :max_backstabs
|
20
18
|
|
19
|
+
# Returns the head shots by the player in a single life as a Spy
|
20
|
+
#
|
21
|
+
# @return [Fixnum] Maximum number of head shots
|
22
|
+
attr_reader :max_head_shots
|
23
|
+
|
21
24
|
# Returns the maximum health leeched from enemies by the player in a single
|
22
25
|
# life as a Spy
|
23
26
|
#
|
@@ -26,12 +29,13 @@ class TF2Spy
|
|
26
29
|
|
27
30
|
# Creates a new instance of the Spy class based on the given XML data
|
28
31
|
#
|
29
|
-
# @param [
|
32
|
+
# @param [Hash<String, Object>] class_data The XML data for this Spy
|
30
33
|
def initialize(class_data)
|
31
34
|
super class_data
|
32
35
|
|
33
|
-
@max_backstabs = class_data
|
34
|
-
@
|
36
|
+
@max_backstabs = class_data['ibackstabs'].to_i
|
37
|
+
@max_head_shots = class_data['iheadshots'].to_i
|
38
|
+
@max_health_leeched = class_data['ihealthpointsleached'].to_i
|
35
39
|
end
|
36
40
|
|
37
41
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# This code is free software; you can redistribute it and/or modify it under
|
2
2
|
# the terms of the new BSD License.
|
3
3
|
#
|
4
|
-
# Copyright (c) 2008-
|
4
|
+
# Copyright (c) 2008-2012, Sebastian Staudt
|
5
5
|
|
6
6
|
require 'steam/community/game_stats'
|
7
7
|
require 'steam/community/tf2/tf2_beta_inventory'
|
@@ -19,6 +19,11 @@ class TF2Stats < GameStats
|
|
19
19
|
# @return [Fixnum] This player's accumulated points
|
20
20
|
attr_reader :accumulated_points
|
21
21
|
|
22
|
+
# Returns the accumulated number of seconds this player has spent playing as a TF2 class
|
23
|
+
#
|
24
|
+
# @return [Fixnum] total seconds played as a TF2 class
|
25
|
+
attr_reader :total_playtime
|
26
|
+
|
22
27
|
# Creates a `TF2Stats` instance by calling the super constructor with the
|
23
28
|
# game name `'tf2'`
|
24
29
|
#
|
@@ -28,8 +33,11 @@ class TF2Stats < GameStats
|
|
28
33
|
def initialize(steam_id, beta = false)
|
29
34
|
super steam_id, (beta ? '520' : 'tf2')
|
30
35
|
|
31
|
-
if public? && !@xml_data
|
32
|
-
@accumulated_points = @xml_data
|
36
|
+
if public? && !@xml_data['stats']['accumulatedPoints'].nil?
|
37
|
+
@accumulated_points = @xml_data['stats']['accumulatedPoints'].to_i
|
38
|
+
end
|
39
|
+
if public? && !@xml_data['stats']['secondsPlayedAllClassesLifetime'].nil?
|
40
|
+
@total_playtime = @xml_data['stats']['secondsPlayedAllClassesLifetime']
|
33
41
|
end
|
34
42
|
end
|
35
43
|
|
@@ -44,8 +52,8 @@ class TF2Stats < GameStats
|
|
44
52
|
|
45
53
|
if @class_stats.nil?
|
46
54
|
@class_stats = Hash.new
|
47
|
-
@xml_data
|
48
|
-
@class_stats[class_data
|
55
|
+
@xml_data['stats']['classData'].each do |class_data|
|
56
|
+
@class_stats[class_data['className']] = TF2ClassFactory.tf2_class(class_data)
|
49
57
|
end
|
50
58
|
end
|
51
59
|
|
@@ -58,8 +66,8 @@ class TF2Stats < GameStats
|
|
58
66
|
# @return [TF2Inventory] This player's TF2 backpack
|
59
67
|
def inventory
|
60
68
|
if @inventory.nil?
|
61
|
-
inventory_class = (
|
62
|
-
@inventory = inventory_class.new(steam_id64) if @inventory.nil?
|
69
|
+
inventory_class = (game.short_name == 'tf2') ? TF2Inventory : TF2BetaInventory
|
70
|
+
@inventory = inventory_class.new(user.steam_id64) if @inventory.nil?
|
63
71
|
end
|
64
72
|
|
65
73
|
@inventory
|
@@ -16,6 +16,8 @@ require 'errors/web_api_error'
|
|
16
16
|
# @author Sebastian
|
17
17
|
module WebApi
|
18
18
|
|
19
|
+
@@api_key = nil
|
20
|
+
|
19
21
|
# Returns the Steam Web API key currently used by Steam Condenser
|
20
22
|
#
|
21
23
|
# @return [String] The currently active Steam Web API key
|
@@ -37,6 +39,18 @@ module WebApi
|
|
37
39
|
@@api_key = api_key
|
38
40
|
end
|
39
41
|
|
42
|
+
# Returns a raw list of interfaces and their methods that are available in
|
43
|
+
# Steam's Web API
|
44
|
+
#
|
45
|
+
# This can be used for reference when accessing interfaces and methods that
|
46
|
+
# have not yet been implemented by Steam Condenser.
|
47
|
+
#
|
48
|
+
# @return [Array<Hash>] The list of interfaces and methods
|
49
|
+
def self.interfaces
|
50
|
+
data = json 'ISteamWebAPIUtil', 'GetSupportedAPIList'
|
51
|
+
MultiJson.load(data, { :symbolize_keys => true })[:apilist][:interfaces]
|
52
|
+
end
|
53
|
+
|
40
54
|
# Fetches JSON data from Steam Web API using the specified interface, method
|
41
55
|
# and version. Additional parameters are supplied via HTTP GET.
|
42
56
|
# Data is returned as a JSON-encoded string.
|
@@ -67,7 +81,7 @@ module WebApi
|
|
67
81
|
# @return [Hash<Symbol, Object>] The JSON data replied to the request
|
68
82
|
def self.json!(interface, method, version = 1, params = nil)
|
69
83
|
data = json(interface, method, version, params)
|
70
|
-
result = MultiJson.
|
84
|
+
result = MultiJson.load(data, { :symbolize_keys => true })[:result]
|
71
85
|
|
72
86
|
status = result[:status]
|
73
87
|
if status != 1
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# This code is free software; you can redistribute it and/or modify it under
|
2
|
+
# the terms of the new BSD License.
|
3
|
+
#
|
4
|
+
# Copyright (c) 2011, Sebastian Staudt
|
5
|
+
|
6
|
+
require 'open-uri'
|
7
|
+
|
8
|
+
require 'multi_xml'
|
9
|
+
|
10
|
+
module XMLData
|
11
|
+
|
12
|
+
def parse(url)
|
13
|
+
data = open(url, { :proxy => true })
|
14
|
+
@xml_data = MultiXml.parse(data).values.first
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# This code is free software; you can redistribute it and/or modify it under
|
2
2
|
# the terms of the new BSD License.
|
3
3
|
#
|
4
|
-
# Copyright (c) 2008-
|
4
|
+
# Copyright (c) 2008-2012, Sebastian Staudt
|
5
5
|
|
6
6
|
require 'errors/steam_condenser_error'
|
7
7
|
require 'errors/timeout_error'
|
@@ -203,7 +203,7 @@ module GameServer
|
|
203
203
|
def handle_response_for_request(request_type, repeat_on_failure = true)
|
204
204
|
case request_type
|
205
205
|
when :challenge then
|
206
|
-
request_packet =
|
206
|
+
request_packet = A2S_PLAYER_Packet.new
|
207
207
|
expected_response = S2C_CHALLENGE_Packet
|
208
208
|
when :info then
|
209
209
|
request_packet = A2S_INFO_Packet.new
|
@@ -346,8 +346,8 @@ module GameServer
|
|
346
346
|
def to_s
|
347
347
|
return_string = ''
|
348
348
|
|
349
|
-
return_string << "Ping:
|
350
|
-
return_string << "Challenge number:
|
349
|
+
return_string << "Ping: #@ping\n"
|
350
|
+
return_string << "Challenge number: #@challenge_number\n"
|
351
351
|
|
352
352
|
unless @info_hash.nil?
|
353
353
|
return_string << "Info:\n"
|
@@ -28,7 +28,7 @@ class MasterServer
|
|
28
28
|
# The master server address to query for GoldSrc game servers
|
29
29
|
GOLDSRC_MASTER_SERVER = 'hl1master.steampowered.com', 27010
|
30
30
|
|
31
|
-
# The master server address to query for
|
31
|
+
# The master server address to query for Source game servers
|
32
32
|
SOURCE_MASTER_SERVER = 'hl2master.steampowered.com', 27011
|
33
33
|
|
34
34
|
# The region code for the US east coast
|
@@ -103,7 +103,7 @@ class MasterServer
|
|
103
103
|
# * `\map\[mapname]`: Request only servers running a specific map
|
104
104
|
# * `\linux\1`: Request only linux servers
|
105
105
|
# * `\emtpy\1`: Request only **non**-empty servers
|
106
|
-
# * `\full
|
106
|
+
# * `\full\1`: Request only servers **not** full
|
107
107
|
# * `\proxy\1`: Request only spectator proxy servers
|
108
108
|
#
|
109
109
|
# @note Receiving all servers from the master server is taking quite some
|
@@ -90,8 +90,8 @@ class GoldSrcSocket
|
|
90
90
|
def rcon_exec(password, command)
|
91
91
|
rcon_challenge if @rcon_challenge.nil? || @is_hltv
|
92
92
|
|
93
|
-
rcon_send "rcon
|
94
|
-
rcon_send "rcon
|
93
|
+
rcon_send "rcon #@rcon_challenge #{password} #{command}"
|
94
|
+
rcon_send "rcon #@rcon_challenge #{password}"
|
95
95
|
if @is_hltv
|
96
96
|
begin
|
97
97
|
response = reply.response
|
data/lib/steam/steam_player.rb
CHANGED
@@ -134,9 +134,9 @@ class SteamPlayer
|
|
134
134
|
# @return [String] A string representing this player
|
135
135
|
def to_s
|
136
136
|
if @extended
|
137
|
-
"
|
137
|
+
"\##@real_id \"#@name\", SteamID: #@steam_id, Score: #@score, Time: #@connect_time"
|
138
138
|
else
|
139
|
-
"
|
139
|
+
"\##@id \"#@name\", Score: #@score, Time: #@connect_time"
|
140
140
|
end
|
141
141
|
end
|
142
142
|
|
data/steam-condenser.gemspec
CHANGED
@@ -11,9 +11,10 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.description = 'A multi-language library for querying the Steam Community, Source, GoldSrc servers and Steam master servers'
|
12
12
|
|
13
13
|
s.add_dependency 'bzip2-ruby', '~> 0.2.7'
|
14
|
-
s.add_dependency 'multi_json', '~> 1.
|
14
|
+
s.add_dependency 'multi_json', '~> 1.3.1'
|
15
|
+
s.add_dependency 'multi_xml', '~> 0.4.1'
|
15
16
|
|
16
|
-
s.add_development_dependency 'mocha', '~> 0.
|
17
|
+
s.add_development_dependency 'mocha', '~> 0.11.1'
|
17
18
|
s.add_development_dependency 'rake', '~> 0.9.2'
|
18
19
|
s.add_development_dependency 'shoulda-context', '~> 1.0.0'
|
19
20
|
s.add_development_dependency 'yard', '~> 0.7.2'
|
data/test/helper.rb
CHANGED
@@ -26,12 +26,20 @@ class Test::Unit::TestCase
|
|
26
26
|
assert !boolean, message
|
27
27
|
end
|
28
28
|
|
29
|
-
# Reads a file
|
29
|
+
# Reads the contents of a fixture file from `./test/`
|
30
30
|
#
|
31
31
|
# @param [String] name The name of the fixtures file
|
32
32
|
# @return [String] The contents of the file
|
33
33
|
def fixture(name)
|
34
|
-
|
34
|
+
fixture_io(name).read
|
35
|
+
end
|
36
|
+
|
37
|
+
# Opens a file with fixtures from `./test/`
|
38
|
+
#
|
39
|
+
# @param [String] name The name of the fixtures file
|
40
|
+
# @return [File] The file handle
|
41
|
+
def fixture_io(name)
|
42
|
+
File.open File.join(File.dirname(__FILE__), 'fixtures', name)
|
35
43
|
end
|
36
44
|
|
37
45
|
end
|
@@ -29,7 +29,7 @@ class TestSteamGroup < Test::Unit::TestCase
|
|
29
29
|
end
|
30
30
|
|
31
31
|
should 'be able to fetch its members' do
|
32
|
-
url =
|
32
|
+
url = fixture_io 'valve-members.xml'
|
33
33
|
SteamGroup.any_instance.expects(:open).with('http://steamcommunity.com/groups/valve/memberslistxml?p=1', { :proxy => true }).returns url
|
34
34
|
|
35
35
|
group = SteamGroup.new 'valve'
|
@@ -58,7 +58,7 @@ class TestSteamGroup < Test::Unit::TestCase
|
|
58
58
|
|
59
59
|
should 'raise an exception when parsing invalid XML' do
|
60
60
|
error = assert_raises SteamCondenserError do
|
61
|
-
url =
|
61
|
+
url = fixture_io 'invalid.xml'
|
62
62
|
SteamGroup.any_instance.expects(:open).with('http://steamcommunity.com/groups/valve/memberslistxml?p=1', { :proxy => true }).returns url
|
63
63
|
|
64
64
|
SteamGroup.new 'valve'
|
@@ -67,8 +67,8 @@ class TestSteamGroup < Test::Unit::TestCase
|
|
67
67
|
end
|
68
68
|
|
69
69
|
should 'be able to parse just the member count' do
|
70
|
-
url =
|
71
|
-
SteamGroup.any_instance.expects(:open).with('http://steamcommunity.com/groups/valve/memberslistxml', { :proxy => true }).returns url
|
70
|
+
url = fixture_io 'valve-members.xml'
|
71
|
+
SteamGroup.any_instance.expects(:open).with('http://steamcommunity.com/groups/valve/memberslistxml?p=1', { :proxy => true }).returns url
|
72
72
|
|
73
73
|
group = SteamGroup.new 'valve', false
|
74
74
|
assert_equal 221, group.member_count
|
@@ -42,14 +42,40 @@ class TestSteamId < Test::Unit::TestCase
|
|
42
42
|
assert SteamId.cached? 'son_of_Thor'
|
43
43
|
end
|
44
44
|
|
45
|
+
should 'have an ID' do
|
46
|
+
steam_id1 = SteamId.new 76561197983311154, false
|
47
|
+
steam_id2 = SteamId.new 'Son_of_Thor', false
|
48
|
+
|
49
|
+
assert_equal 76561197983311154, steam_id1.id
|
50
|
+
assert_equal 'son_of_thor', steam_id2.id
|
51
|
+
end
|
52
|
+
|
45
53
|
should 'be able to fetch its data' do
|
46
|
-
url =
|
54
|
+
url = fixture_io 'sonofthor.xml'
|
47
55
|
SteamId.any_instance.expects(:open).with('http://steamcommunity.com/id/son_of_thor?xml=1', { :proxy => true }).returns url
|
48
56
|
|
49
57
|
steam_id = SteamId.new 'Son_of_Thor'
|
50
58
|
|
51
59
|
assert_equal 76561197983311154, steam_id.steam_id64
|
60
|
+
assert_equal 'son_of_thor', steam_id.custom_url
|
61
|
+
assert_equal 'Bellevue, Washington, United States', steam_id.location
|
62
|
+
assert_equal 'Dad serious.', steam_id.head_line
|
63
|
+
assert_equal 'Son of Thor', steam_id.nickname
|
64
|
+
assert_equal 'Torsten Zabka', steam_id.real_name
|
65
|
+
assert_equal 'Last Online: 3 days ago', steam_id.state_message
|
66
|
+
assert_equal 'We jump that fence when we get to it.', steam_id.summary
|
67
|
+
assert_equal 'None', steam_id.trade_ban_state
|
68
|
+
|
69
|
+
assert_equal 'http://media.steampowered.com/steamcommunity/public/images/avatars/b8/b8438d91481295b7cc8da9578004cd63a2c3b2e4_full.jpg', steam_id.full_avatar_url
|
70
|
+
assert_equal 'http://media.steampowered.com/steamcommunity/public/images/avatars/b8/b8438d91481295b7cc8da9578004cd63a2c3b2e4.jpg', steam_id.icon_url
|
71
|
+
assert_equal 'http://media.steampowered.com/steamcommunity/public/images/avatars/b8/b8438d91481295b7cc8da9578004cd63a2c3b2e4_medium.jpg', steam_id.medium_avatar_url
|
72
|
+
|
73
|
+
assert_not steam_id.banned?
|
74
|
+
assert_not steam_id.limited?
|
75
|
+
assert_not steam_id.online?
|
52
76
|
assert steam_id.fetched?
|
77
|
+
|
78
|
+
assert steam_id.public?
|
53
79
|
end
|
54
80
|
|
55
81
|
should 'be found by the 64bit SteamID' do
|
@@ -68,7 +94,7 @@ class TestSteamId < Test::Unit::TestCase
|
|
68
94
|
|
69
95
|
should 'raise an exception when parsing invalid XML' do
|
70
96
|
error = assert_raises SteamCondenserError do
|
71
|
-
url =
|
97
|
+
url = fixture_io 'invalid.xml'
|
72
98
|
SteamId.any_instance.expects(:open).with('http://steamcommunity.com/id/son_of_thor?xml=1', { :proxy => true }).returns url
|
73
99
|
|
74
100
|
SteamId.new 'Son_of_Thor'
|
@@ -41,7 +41,7 @@ class TestWebApi < Test::Unit::TestCase
|
|
41
41
|
data = mock
|
42
42
|
WebApi.expects(:json).with('interface', 'method', 2, { :test => 'param' }).
|
43
43
|
returns data
|
44
|
-
MultiJson.expects(:
|
44
|
+
MultiJson.expects(:load).with(data, { :symbolize_keys => true }).
|
45
45
|
returns({ :result => { :status => 1 }})
|
46
46
|
|
47
47
|
assert_equal({ :status => 1 }, WebApi.json!('interface', 'method', 2, { :test => 'param' }))
|
@@ -51,7 +51,7 @@ class TestWebApi < Test::Unit::TestCase
|
|
51
51
|
data = mock
|
52
52
|
WebApi.expects(:json).with('interface', 'method', 2, { :test => 'param' }).
|
53
53
|
returns data
|
54
|
-
MultiJson.expects(:
|
54
|
+
MultiJson.expects(:load).with(data, { :symbolize_keys => true }).
|
55
55
|
returns({ :result => { :status => 2, :statusDetail => 'error' } })
|
56
56
|
|
57
57
|
error = assert_raises WebApiError do
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# This code is free software; you can redistribute it and/or modify it under
|
2
|
+
# the terms of the new BSD License.
|
3
|
+
#
|
4
|
+
# Copyright (c) 2012, Sebastian Staudt
|
5
|
+
|
6
|
+
require 'helper'
|
7
|
+
require 'steam/packets/steam_packet'
|
8
|
+
|
9
|
+
class TestSteamPacket < Test::Unit::TestCase
|
10
|
+
|
11
|
+
class GenericSteamPacket
|
12
|
+
include SteamPacket
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'A packet' do
|
16
|
+
|
17
|
+
setup do
|
18
|
+
@packet = GenericSteamPacket.new 0x61, 'test'
|
19
|
+
end
|
20
|
+
|
21
|
+
should 'have a data buffer' do
|
22
|
+
data = @packet.instance_variable_get(:@content_data)
|
23
|
+
assert_instance_of StringIO, data
|
24
|
+
assert_equal 'test', data.string
|
25
|
+
end
|
26
|
+
|
27
|
+
should 'know its header' do
|
28
|
+
assert_equal 0x61, @packet.instance_variable_get(:@header_data)
|
29
|
+
end
|
30
|
+
|
31
|
+
should 'have a valid byte representation' do
|
32
|
+
assert_equal "\xFF\xFF\xFF\xFFatest", @packet.to_s
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -1,308 +1,296 @@
|
|
1
|
-
# This code is free software; you can redistribute it and/or modify it under
|
2
|
-
# the terms of the new BSD License.
|
3
|
-
#
|
4
|
-
# Copyright (c) 2011, Sebastian Staudt
|
5
|
-
|
6
|
-
require 'helper'
|
7
|
-
require 'steam/servers/game_server'
|
8
|
-
|
9
|
-
class TestGameServer < Test::Unit::TestCase
|
10
|
-
|
11
|
-
context 'A generic game server' do
|
12
|
-
|
13
|
-
class GenericGameServer
|
14
|
-
include GameServer
|
15
|
-
end
|
16
|
-
|
17
|
-
setup do
|
18
|
-
Socket.stubs(:getaddrinfo).
|
19
|
-
with('game', 27015, Socket::AF_INET, Socket::SOCK_DGRAM).
|
20
|
-
returns [[nil, nil, 'game', '127.0.0.1']]
|
21
|
-
@socket = mock
|
22
|
-
|
23
|
-
@server = GenericGameServer.new 'game', 27015
|
24
|
-
@server.instance_variable_set :@socket, @socket
|
25
|
-
end
|
26
|
-
|
27
|
-
should 'send packets using its client socket' do
|
28
|
-
packet = mock
|
29
|
-
@socket.expects(:send).with packet
|
30
|
-
|
31
|
-
@server.send :send_request, packet
|
32
|
-
end
|
33
|
-
|
34
|
-
should 'get replies using its client socket' do
|
35
|
-
packet = mock
|
36
|
-
@socket.expects(:reply).returns packet
|
37
|
-
|
38
|
-
assert_equal packet, @server.send(:reply)
|
39
|
-
end
|
40
|
-
|
41
|
-
should 'be able to calculate the latency of the server' do
|
42
|
-
@server.expects(:send_request).with do |packet|
|
43
|
-
packet.is_a? A2S_INFO_Packet
|
44
|
-
end
|
45
|
-
@server.expects(:reply).with { || sleep 0.05 }
|
46
|
-
|
47
|
-
@server.update_ping
|
48
|
-
assert_operator @server.instance_variable_get(:@ping), :>=, 50
|
49
|
-
end
|
50
|
-
|
51
|
-
should 'be able to get a challenge from the server' do
|
52
|
-
@server.expects(:handle_response_for_request).with :challenge
|
53
|
-
|
54
|
-
@server.update_challenge_number
|
55
|
-
end
|
56
|
-
|
57
|
-
should 'be able to get information about server' do
|
58
|
-
@server.expects(:handle_response_for_request).with :info
|
59
|
-
|
60
|
-
@server.update_server_info
|
61
|
-
end
|
62
|
-
|
63
|
-
should 'be able to get the server rules' do
|
64
|
-
@server.expects(:handle_response_for_request).with :rules
|
65
|
-
|
66
|
-
@server.update_rules
|
67
|
-
end
|
68
|
-
|
69
|
-
should 'be able to get the players on the server' do
|
70
|
-
@server.expects(:handle_response_for_request).with :players
|
71
|
-
|
72
|
-
@server.update_players
|
73
|
-
end
|
74
|
-
|
75
|
-
should 'provide a convenience wrapper for basic server methods' do
|
76
|
-
@server.expects :update_ping
|
77
|
-
@server.expects :update_server_info
|
78
|
-
@server.expects :update_challenge_number
|
79
|
-
|
80
|
-
@server.init
|
81
|
-
end
|
82
|
-
|
83
|
-
should 'know if its RCON connection is authenticated' do
|
84
|
-
assert_equal @server.instance_variable_get(:@rcon_authenticated),
|
85
|
-
@server.rcon_authenticated?
|
86
|
-
end
|
87
|
-
|
88
|
-
should 'cache the ping of the server' do
|
89
|
-
@server.expects :update_ping
|
90
|
-
|
91
|
-
@server.ping
|
92
|
-
|
93
|
-
@server.instance_variable_set :@ping, 0
|
94
|
-
|
95
|
-
@server.ping
|
96
|
-
end
|
97
|
-
|
98
|
-
should 'cache the players on the server' do
|
99
|
-
@server.expects :update_players
|
100
|
-
|
101
|
-
@server.players
|
102
|
-
|
103
|
-
@server.instance_variable_set :@player_hash, 0
|
104
|
-
|
105
|
-
@server.players
|
106
|
-
end
|
107
|
-
|
108
|
-
should 'cache the server rules' do
|
109
|
-
@server.expects :update_rules
|
110
|
-
|
111
|
-
@server.rules
|
112
|
-
|
113
|
-
@server.instance_variable_set :@rules_hash, 0
|
114
|
-
|
115
|
-
@server.rules
|
116
|
-
end
|
117
|
-
|
118
|
-
should 'cache the server information' do
|
119
|
-
@server.expects :update_server_info
|
120
|
-
|
121
|
-
@server.server_info
|
122
|
-
|
123
|
-
@server.instance_variable_set :@info_hash, 0
|
124
|
-
|
125
|
-
@server.server_info
|
126
|
-
end
|
127
|
-
|
128
|
-
context 'be able to get additional information about the players on a Source server' do
|
129
|
-
|
130
|
-
setup do
|
131
|
-
status = fixture 'status_source'
|
132
|
-
|
133
|
-
@someone = mock
|
134
|
-
@somebody = mock
|
135
|
-
player_hash = { 'someone' => @someone, 'somebody' => @somebody }
|
136
|
-
@server.instance_variable_set :@player_hash, player_hash
|
137
|
-
|
138
|
-
@server.expects(:handle_response_for_request).with :players
|
139
|
-
@server.expects(:rcon_exec).with('status').returns status
|
140
|
-
|
141
|
-
someone_data = { :name => 'someone', :userid => '1', :uniqueid => 'STEAM_0:0:123456', :score => '10', :time => '3:52', :ping => '12', :loss => '0', :state => 'active' }
|
142
|
-
somebody_data = { :name => 'somebody', :userid => '2', :uniqueid => 'STEAM_0:0:123457', :score => '3', :time => '2:42', :ping => '34', :loss => '0', :state => 'active' }
|
143
|
-
|
144
|
-
attributes = mock
|
145
|
-
GameServer.expects(:player_status_attributes).
|
146
|
-
with('userid name uniqueid score connected ping loss state').
|
147
|
-
returns attributes
|
148
|
-
GameServer.expects(:split_player_status).
|
149
|
-
with(attributes, '1 "someone" STEAM_0:0:123456 10 3:52 12 0 active').
|
150
|
-
returns somebody_data
|
151
|
-
GameServer.expects(:split_player_status).
|
152
|
-
with(attributes, '2 "somebody" STEAM_0:0:123457 3 2:42 34 0 active').
|
153
|
-
returns someone_data
|
154
|
-
|
155
|
-
@somebody.expects(:add_info).with somebody_data
|
156
|
-
@someone.expects(:add_info).with someone_data
|
157
|
-
end
|
158
|
-
|
159
|
-
should 'with the RCON password' do
|
160
|
-
@server.expects(:rcon_auth).with 'password'
|
161
|
-
|
162
|
-
@server.update_players 'password'
|
163
|
-
end
|
164
|
-
|
165
|
-
should 'if the RCON connection is authenticated' do
|
166
|
-
@server.instance_variable_set :@rcon_authenticated, true
|
167
|
-
|
168
|
-
@server.update_players
|
169
|
-
end
|
170
|
-
|
171
|
-
end
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
@server.
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
@server.expects(:
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
packet2.expects(:player_hash).returns({ :test => 'test2' })
|
298
|
-
@server.expects(:reply).twice.returns(packet1).returns packet2
|
299
|
-
|
300
|
-
@server.handle_response_for_request :players
|
301
|
-
|
302
|
-
assert_equal({ :test => 'test1' }, @server.instance_variable_get(:@info_hash))
|
303
|
-
assert_equal({ :test => 'test2' }, @server.instance_variable_get(:@player_hash))
|
304
|
-
end
|
305
|
-
|
306
|
-
end
|
307
|
-
|
308
|
-
end
|
1
|
+
# This code is free software; you can redistribute it and/or modify it under
|
2
|
+
# the terms of the new BSD License.
|
3
|
+
#
|
4
|
+
# Copyright (c) 2011, Sebastian Staudt
|
5
|
+
|
6
|
+
require 'helper'
|
7
|
+
require 'steam/servers/game_server'
|
8
|
+
|
9
|
+
class TestGameServer < Test::Unit::TestCase
|
10
|
+
|
11
|
+
context 'A generic game server' do
|
12
|
+
|
13
|
+
class GenericGameServer
|
14
|
+
include GameServer
|
15
|
+
end
|
16
|
+
|
17
|
+
setup do
|
18
|
+
Socket.stubs(:getaddrinfo).
|
19
|
+
with('game', 27015, Socket::AF_INET, Socket::SOCK_DGRAM).
|
20
|
+
returns [[nil, nil, 'game', '127.0.0.1']]
|
21
|
+
@socket = mock
|
22
|
+
|
23
|
+
@server = GenericGameServer.new 'game', 27015
|
24
|
+
@server.instance_variable_set :@socket, @socket
|
25
|
+
end
|
26
|
+
|
27
|
+
should 'send packets using its client socket' do
|
28
|
+
packet = mock
|
29
|
+
@socket.expects(:send).with packet
|
30
|
+
|
31
|
+
@server.send :send_request, packet
|
32
|
+
end
|
33
|
+
|
34
|
+
should 'get replies using its client socket' do
|
35
|
+
packet = mock
|
36
|
+
@socket.expects(:reply).returns packet
|
37
|
+
|
38
|
+
assert_equal packet, @server.send(:reply)
|
39
|
+
end
|
40
|
+
|
41
|
+
should 'be able to calculate the latency of the server' do
|
42
|
+
@server.expects(:send_request).with do |packet|
|
43
|
+
packet.is_a? A2S_INFO_Packet
|
44
|
+
end
|
45
|
+
@server.expects(:reply).with { || sleep 0.05 }
|
46
|
+
|
47
|
+
@server.update_ping
|
48
|
+
assert_operator @server.instance_variable_get(:@ping), :>=, 50
|
49
|
+
end
|
50
|
+
|
51
|
+
should 'be able to get a challenge from the server' do
|
52
|
+
@server.expects(:handle_response_for_request).with :challenge
|
53
|
+
|
54
|
+
@server.update_challenge_number
|
55
|
+
end
|
56
|
+
|
57
|
+
should 'be able to get information about server' do
|
58
|
+
@server.expects(:handle_response_for_request).with :info
|
59
|
+
|
60
|
+
@server.update_server_info
|
61
|
+
end
|
62
|
+
|
63
|
+
should 'be able to get the server rules' do
|
64
|
+
@server.expects(:handle_response_for_request).with :rules
|
65
|
+
|
66
|
+
@server.update_rules
|
67
|
+
end
|
68
|
+
|
69
|
+
should 'be able to get the players on the server' do
|
70
|
+
@server.expects(:handle_response_for_request).with :players
|
71
|
+
|
72
|
+
@server.update_players
|
73
|
+
end
|
74
|
+
|
75
|
+
should 'provide a convenience wrapper for basic server methods' do
|
76
|
+
@server.expects :update_ping
|
77
|
+
@server.expects :update_server_info
|
78
|
+
@server.expects :update_challenge_number
|
79
|
+
|
80
|
+
@server.init
|
81
|
+
end
|
82
|
+
|
83
|
+
should 'know if its RCON connection is authenticated' do
|
84
|
+
assert_equal @server.instance_variable_get(:@rcon_authenticated),
|
85
|
+
@server.rcon_authenticated?
|
86
|
+
end
|
87
|
+
|
88
|
+
should 'cache the ping of the server' do
|
89
|
+
@server.expects :update_ping
|
90
|
+
|
91
|
+
@server.ping
|
92
|
+
|
93
|
+
@server.instance_variable_set :@ping, 0
|
94
|
+
|
95
|
+
@server.ping
|
96
|
+
end
|
97
|
+
|
98
|
+
should 'cache the players on the server' do
|
99
|
+
@server.expects :update_players
|
100
|
+
|
101
|
+
@server.players
|
102
|
+
|
103
|
+
@server.instance_variable_set :@player_hash, 0
|
104
|
+
|
105
|
+
@server.players
|
106
|
+
end
|
107
|
+
|
108
|
+
should 'cache the server rules' do
|
109
|
+
@server.expects :update_rules
|
110
|
+
|
111
|
+
@server.rules
|
112
|
+
|
113
|
+
@server.instance_variable_set :@rules_hash, 0
|
114
|
+
|
115
|
+
@server.rules
|
116
|
+
end
|
117
|
+
|
118
|
+
should 'cache the server information' do
|
119
|
+
@server.expects :update_server_info
|
120
|
+
|
121
|
+
@server.server_info
|
122
|
+
|
123
|
+
@server.instance_variable_set :@info_hash, 0
|
124
|
+
|
125
|
+
@server.server_info
|
126
|
+
end
|
127
|
+
|
128
|
+
context 'be able to get additional information about the players on a Source server' do
|
129
|
+
|
130
|
+
setup do
|
131
|
+
status = fixture 'status_source'
|
132
|
+
|
133
|
+
@someone = mock
|
134
|
+
@somebody = mock
|
135
|
+
player_hash = { 'someone' => @someone, 'somebody' => @somebody }
|
136
|
+
@server.instance_variable_set :@player_hash, player_hash
|
137
|
+
|
138
|
+
@server.expects(:handle_response_for_request).with :players
|
139
|
+
@server.expects(:rcon_exec).with('status').returns status
|
140
|
+
|
141
|
+
someone_data = { :name => 'someone', :userid => '1', :uniqueid => 'STEAM_0:0:123456', :score => '10', :time => '3:52', :ping => '12', :loss => '0', :state => 'active' }
|
142
|
+
somebody_data = { :name => 'somebody', :userid => '2', :uniqueid => 'STEAM_0:0:123457', :score => '3', :time => '2:42', :ping => '34', :loss => '0', :state => 'active' }
|
143
|
+
|
144
|
+
attributes = mock
|
145
|
+
GameServer.expects(:player_status_attributes).
|
146
|
+
with('userid name uniqueid score connected ping loss state').
|
147
|
+
returns attributes
|
148
|
+
GameServer.expects(:split_player_status).
|
149
|
+
with(attributes, '1 "someone" STEAM_0:0:123456 10 3:52 12 0 active').
|
150
|
+
returns somebody_data
|
151
|
+
GameServer.expects(:split_player_status).
|
152
|
+
with(attributes, '2 "somebody" STEAM_0:0:123457 3 2:42 34 0 active').
|
153
|
+
returns someone_data
|
154
|
+
|
155
|
+
@somebody.expects(:add_info).with somebody_data
|
156
|
+
@someone.expects(:add_info).with someone_data
|
157
|
+
end
|
158
|
+
|
159
|
+
should 'with the RCON password' do
|
160
|
+
@server.expects(:rcon_auth).with 'password'
|
161
|
+
|
162
|
+
@server.update_players 'password'
|
163
|
+
end
|
164
|
+
|
165
|
+
should 'if the RCON connection is authenticated' do
|
166
|
+
@server.instance_variable_set :@rcon_authenticated, true
|
167
|
+
|
168
|
+
@server.update_players
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
should 'be able to get additional information about the players on a GoldSrc server with the RCON password' do
|
174
|
+
status = fixture 'status_goldsrc'
|
175
|
+
|
176
|
+
@someone = mock
|
177
|
+
@somebody = mock
|
178
|
+
player_hash = { 'someone' => @someone, 'somebody' => @somebody }
|
179
|
+
@server.instance_variable_set :@player_hash, player_hash
|
180
|
+
|
181
|
+
@server.expects(:handle_response_for_request).with :players
|
182
|
+
@server.expects(:rcon_exec).with('status').returns status
|
183
|
+
|
184
|
+
someone_data = { :name => 'someone', :userid => '1', :uniqueid => 'STEAM_0:0:123456', :score => '10', :time => '3:52', :ping => '12', :loss => '0', :adr => '0' }
|
185
|
+
somebody_data = { :name => 'somebody', :userid => '2', :uniqueid => 'STEAM_0:0:123457', :score => '3', :time => '2:42', :ping => '34', :loss => '0', :adr => '0' }
|
186
|
+
|
187
|
+
attributes = mock
|
188
|
+
GameServer.expects(:player_status_attributes).
|
189
|
+
with('name userid uniqueid frag time ping loss adr').
|
190
|
+
returns attributes
|
191
|
+
GameServer.expects(:split_player_status).
|
192
|
+
with(attributes, '1 "someone" 1 STEAM_0:0:123456 10 3:52 12 0 0').
|
193
|
+
returns somebody_data
|
194
|
+
GameServer.expects(:split_player_status).
|
195
|
+
with(attributes, '2 "somebody" 2 STEAM_0:0:123457 3 2:42 34 0 0').
|
196
|
+
returns someone_data
|
197
|
+
|
198
|
+
@somebody.expects(:add_info).with somebody_data
|
199
|
+
@someone.expects(:add_info).with someone_data
|
200
|
+
|
201
|
+
@server.expects(:rcon_auth).with 'password'
|
202
|
+
|
203
|
+
@server.update_players 'password'
|
204
|
+
end
|
205
|
+
|
206
|
+
should 'handle challenge requests' do
|
207
|
+
@server.expects(:send_request).with do |packet|
|
208
|
+
packet.is_a? A2S_PLAYER_Packet
|
209
|
+
end
|
210
|
+
|
211
|
+
packet = mock
|
212
|
+
packet.expects(:kind_of?).with(S2A_INFO_BasePacket).returns false
|
213
|
+
packet.expects(:kind_of?).with(S2A_PLAYER_Packet).returns false
|
214
|
+
packet.expects(:kind_of?).with(S2A_RULES_Packet).returns false
|
215
|
+
packet.expects(:kind_of?).with(S2C_CHALLENGE_Packet).twice.returns true
|
216
|
+
|
217
|
+
packet.expects(:challenge_number).returns 1234
|
218
|
+
@server.expects(:reply).returns packet
|
219
|
+
|
220
|
+
@server.handle_response_for_request :challenge
|
221
|
+
|
222
|
+
assert_equal 1234, @server.instance_variable_get(:@challenge_number)
|
223
|
+
end
|
224
|
+
|
225
|
+
should 'handle info requests' do
|
226
|
+
@server.expects(:send_request).with do |packet|
|
227
|
+
packet.is_a? A2S_INFO_Packet
|
228
|
+
end
|
229
|
+
|
230
|
+
packet = mock
|
231
|
+
packet.expects(:kind_of?).with(S2A_INFO_BasePacket).twice.returns true
|
232
|
+
packet.expects(:info_hash).returns({ :test => 'test' })
|
233
|
+
@server.expects(:reply).returns packet
|
234
|
+
|
235
|
+
@server.handle_response_for_request :info
|
236
|
+
|
237
|
+
assert_equal({ :test => 'test' }, @server.instance_variable_get(:@info_hash))
|
238
|
+
end
|
239
|
+
|
240
|
+
should 'handle rule requests' do
|
241
|
+
@server.expects(:send_request).with do |packet|
|
242
|
+
packet.is_a? A2S_RULES_Packet
|
243
|
+
end
|
244
|
+
|
245
|
+
packet = mock
|
246
|
+
packet.expects(:kind_of?).with(S2A_INFO_BasePacket).returns false
|
247
|
+
packet.expects(:kind_of?).with(S2A_PLAYER_Packet).returns false
|
248
|
+
packet.expects(:kind_of?).with(S2A_RULES_Packet).twice.returns true
|
249
|
+
packet.expects(:rules_hash).returns({ :test => 'test' })
|
250
|
+
@server.expects(:reply).returns packet
|
251
|
+
|
252
|
+
@server.handle_response_for_request :rules
|
253
|
+
|
254
|
+
assert_equal({ :test => 'test' }, @server.instance_variable_get(:@rules_hash))
|
255
|
+
end
|
256
|
+
|
257
|
+
should 'handle player requests' do
|
258
|
+
@server.expects(:send_request).with do |packet|
|
259
|
+
packet.is_a? A2S_PLAYER_Packet
|
260
|
+
end
|
261
|
+
|
262
|
+
packet = mock
|
263
|
+
packet.expects(:kind_of?).with(S2A_INFO_BasePacket).returns false
|
264
|
+
packet.expects(:kind_of?).with(S2A_PLAYER_Packet).twice.returns true
|
265
|
+
packet.expects(:player_hash).returns({ :test => 'test' })
|
266
|
+
@server.expects(:reply).returns packet
|
267
|
+
|
268
|
+
@server.handle_response_for_request :players
|
269
|
+
|
270
|
+
assert_equal({ :test => 'test' }, @server.instance_variable_get(:@player_hash))
|
271
|
+
end
|
272
|
+
|
273
|
+
should 'handle unexpected answers and retry' do
|
274
|
+
@server.expects(:send_request).twice.with do |packet|
|
275
|
+
packet.is_a? A2S_PLAYER_Packet
|
276
|
+
end
|
277
|
+
|
278
|
+
packet1 = mock
|
279
|
+
packet1.expects(:kind_of?).with(S2A_INFO_BasePacket).returns true
|
280
|
+
packet1.expects(:kind_of?).with(S2A_PLAYER_Packet).returns false
|
281
|
+
packet1.expects(:info_hash).returns({ :test => 'test1' })
|
282
|
+
packet2 = mock
|
283
|
+
packet2.expects(:kind_of?).with(S2A_INFO_BasePacket).returns false
|
284
|
+
packet2.expects(:kind_of?).with(S2A_PLAYER_Packet).twice.returns true
|
285
|
+
packet2.expects(:player_hash).returns({ :test => 'test2' })
|
286
|
+
@server.expects(:reply).twice.returns(packet1).returns packet2
|
287
|
+
|
288
|
+
@server.handle_response_for_request :players
|
289
|
+
|
290
|
+
assert_equal({ :test => 'test1' }, @server.instance_variable_get(:@info_hash))
|
291
|
+
assert_equal({ :test => 'test2' }, @server.instance_variable_get(:@player_hash))
|
292
|
+
end
|
293
|
+
|
294
|
+
end
|
295
|
+
|
296
|
+
end
|