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.
Files changed (62) hide show
  1. data/Gemfile.lock +30 -0
  2. data/LICENSE +1 -1
  3. data/README.md +4 -3
  4. data/lib/steam-condenser/version.rb +2 -2
  5. data/lib/steam/community/alien_swarm/alien_swarm_mission.rb +24 -22
  6. data/lib/steam/community/alien_swarm/alien_swarm_stats.rb +66 -65
  7. data/lib/steam/community/alien_swarm/alien_swarm_weapon.rb +6 -6
  8. data/lib/steam/community/app_news.rb +2 -2
  9. data/lib/steam/community/css/css_map.rb +4 -4
  10. data/lib/steam/community/css/css_stats.rb +43 -43
  11. data/lib/steam/community/css/css_weapon.rb +5 -5
  12. data/lib/steam/community/defense_grid/defense_grid_stats.rb +36 -35
  13. data/lib/steam/community/dods/dods_class.rb +14 -14
  14. data/lib/steam/community/dods/dods_stats.rb +5 -4
  15. data/lib/steam/community/dods/dods_weapon.rb +6 -6
  16. data/lib/steam/community/game_achievement.rb +38 -31
  17. data/lib/steam/community/game_inventory.rb +6 -6
  18. data/lib/steam/community/game_leaderboard.rb +34 -32
  19. data/lib/steam/community/game_leaderboard_entry.rb +6 -6
  20. data/lib/steam/community/game_stats.rb +39 -65
  21. data/lib/steam/community/game_weapon.rb +2 -2
  22. data/lib/steam/community/l4d/abstract_l4d_stats.rb +54 -49
  23. data/lib/steam/community/l4d/abstract_l4d_weapon.rb +7 -6
  24. data/lib/steam/community/l4d/l4d2_map.rb +10 -10
  25. data/lib/steam/community/l4d/l4d2_stats.rb +33 -33
  26. data/lib/steam/community/l4d/l4d2_weapon.rb +8 -7
  27. data/lib/steam/community/l4d/l4d_explosive.rb +5 -4
  28. data/lib/steam/community/l4d/l4d_map.rb +8 -7
  29. data/lib/steam/community/l4d/l4d_stats.rb +7 -7
  30. data/lib/steam/community/l4d/l4d_weapon.rb +5 -4
  31. data/lib/steam/community/portal2/portal2_stats.rb +3 -3
  32. data/lib/steam/community/steam_game.rb +106 -16
  33. data/lib/steam/community/steam_group.rb +51 -40
  34. data/lib/steam/community/steam_id.rb +119 -87
  35. data/lib/steam/community/tf2/tf2_class.rb +14 -14
  36. data/lib/steam/community/tf2/tf2_class_factory.rb +2 -2
  37. data/lib/steam/community/tf2/tf2_engineer.rb +5 -7
  38. data/lib/steam/community/tf2/tf2_golden_wrench.rb +1 -1
  39. data/lib/steam/community/tf2/tf2_medic.rb +4 -6
  40. data/lib/steam/community/tf2/tf2_sniper.rb +3 -5
  41. data/lib/steam/community/tf2/tf2_spy.rb +10 -6
  42. data/lib/steam/community/tf2/tf2_stats.rb +15 -7
  43. data/lib/steam/community/web_api.rb +15 -1
  44. data/lib/steam/community/xml_data.rb +17 -0
  45. data/lib/steam/servers/game_server.rb +4 -4
  46. data/lib/steam/servers/master_server.rb +2 -2
  47. data/lib/steam/servers/source_server.rb +0 -2
  48. data/lib/steam/sockets/goldsrc_socket.rb +2 -2
  49. data/lib/steam/steam_player.rb +2 -2
  50. data/steam-condenser.gemspec +3 -2
  51. data/test/helper.rb +10 -2
  52. data/test/steam/communtiy/test_steam_group.rb +4 -4
  53. data/test/steam/communtiy/test_steam_id.rb +28 -2
  54. data/test/steam/communtiy/test_web_api.rb +2 -2
  55. data/test/steam/packets/test_steam_packet.rb +37 -0
  56. data/test/steam/servers/test_game_server.rb +296 -308
  57. data/test/steam/servers/test_goldsrc_server.rb +59 -59
  58. data/test/steam/servers/test_master_server.rb +131 -131
  59. data/test/steam/servers/test_server.rb +72 -72
  60. data/test/steam/servers/test_source_server.rb +126 -140
  61. data/test/steam/sockets/test_master_server_socket.rb +1 -0
  62. metadata +39 -19
@@ -32,16 +32,16 @@ class CSSWeapon
32
32
  # given XML data
33
33
  #
34
34
  # @param [String] weapon_name The name of the weapon
35
- # @param [REXML::Element] weapons_data The XML data of all weapons
35
+ # @param [Hash<String, Object>] weapons_data The XML data of all weapons
36
36
  def initialize(weapon_name, weapons_data)
37
37
  @name = weapon_name
38
38
 
39
- @favorite = (weapons_data.elements['favorite'].text == @name)
40
- @kills = weapons_data.elements["#{@name}_kills"].text.to_i
39
+ @favorite = (weapons_data['favorite'] == @name)
40
+ @kills = weapons_data["#{@name}_kills"].to_i
41
41
 
42
42
  if @name != 'grenade' && @name != 'knife'
43
- @hits = weapons_data.elements["#{@name}_hits"].text.to_i
44
- @shots = weapons_data.elements["#{@name}_shots"].text.to_i
43
+ @hits = weapons_data["#{@name}_hits"].to_i
44
+ @shots = weapons_data["#{@name}_shots"].to_i
45
45
  end
46
46
  end
47
47
 
@@ -130,30 +130,30 @@ class DefenseGridStats < GameStats
130
130
  super(steam_id, 'defensegrid:awakening')
131
131
 
132
132
  if public?
133
- general_data = @xml_data.elements['stats/general']
134
-
135
- @bronze_medals = general_data.elements['bronze_medals_won/value'].text.to_i
136
- @silver_medals = general_data.elements['silver_medals_won/value'].text.to_i
137
- @gold_medals = general_data.elements['gold_medals_won/value'].text.to_i
138
- @levels_played = general_data.elements['levels_played_total/value'].text.to_i
139
- @levels_played_campaign = general_data.elements['levels_played_campaign/value'].text.to_i
140
- @levels_played_challenge = general_data.elements['levels_played_challenge/value'].text.to_i
141
- @levels_won = general_data.elements['levels_won_total/value'].text.to_i
142
- @levels_won_campaign = general_data.elements['levels_won_campaign/value'].text.to_i
143
- @levels_won_challenge = general_data.elements['levels_won_challenge/value'].text.to_i
144
- @encountered = general_data.elements['total_aliens_encountered/value'].text.to_i
145
- @killed = general_data.elements['total_aliens_killed/value'].text.to_i
146
- @killed_campaign = general_data.elements['total_aliens_killed_campaign/value'].text.to_i
147
- @killed_challenge = general_data.elements['total_aliens_killed_challenge/value'].text.to_i
148
- @resources = general_data.elements['resources_recovered/value'].text.to_i
149
- @heat_damage = general_data.elements['heatdamage/value'].text.to_f
150
- @time_played = general_data.elements['time_played/value'].text.to_f
151
- @interest = general_data.elements['interest_gained/value'].text.to_f
152
- @damage_done = general_data.elements['tower_damage_total/value'].text.to_f
153
- @damage_campaign = general_data.elements['tower_damage_total_campaign/value'].text.to_f
154
- @damage_challenge = general_data.elements['tower_damage_total_challenge/value'].text.to_f
155
- @orbital_laser_fired = @xml_data.elements['stats/orbitallaser/fired/value'].text.to_i
156
- @orbital_laser_damage = @xml_data.elements['stats/orbitallaser/damage/value'].text.to_f
133
+ general_data = @xml_data['stats']['general']
134
+
135
+ @bronze_medals = general_data['bronze_medals_won']['value'].to_i
136
+ @silver_medals = general_data['silver_medals_won']['value'].to_i
137
+ @gold_medals = general_data['gold_medals_won']['value'].to_i
138
+ @levels_played = general_data['levels_played_total']['value'].to_i
139
+ @levels_played_campaign = general_data['levels_played_campaign']['value'].to_i
140
+ @levels_played_challenge = general_data['levels_played_challenge']['value'].to_i
141
+ @levels_won = general_data['levels_won_total']['value'].to_i
142
+ @levels_won_campaign = general_data['levels_won_campaign']['value'].to_i
143
+ @levels_won_challenge = general_data['levels_won_challenge']['value'].to_i
144
+ @encountered = general_data['total_aliens_encountered']['value'].to_i
145
+ @killed = general_data['total_aliens_killed']['value'].to_i
146
+ @killed_campaign = general_data['total_aliens_killed_campaign']['value'].to_i
147
+ @killed_challenge = general_data['total_aliens_killed_challenge']['value'].to_i
148
+ @resources = general_data['resources_recovered']['value'].to_i
149
+ @heat_damage = general_data['heatdamage']['value'].to_f
150
+ @time_played = general_data['time_played']['value'].to_f
151
+ @interest = general_data['interest_gained']['value'].to_f
152
+ @damage_done = general_data['tower_damage_total']['value'].to_f
153
+ @damage_campaign = general_data['tower_damage_total_campaign']['value'].to_f
154
+ @damage_challenge = general_data['tower_damage_total_challenge']['value'].to_f
155
+ @orbital_laser_fired = @xml_data['stats']['orbitallaser']['fired']['value'].to_i
156
+ @orbital_laser_damage = @xml_data['stats']['orbitallaser']['damage']['value'].to_f
157
157
  end
158
158
  end
159
159
 
@@ -168,15 +168,15 @@ class DefenseGridStats < GameStats
168
168
  return unless public?
169
169
 
170
170
  if @alien_stats.nil?
171
- alien_data = @xml_data.elements['stats/aliens']
171
+ alien_data = @xml_data['stats']['aliens']
172
172
  @alien_stats = {}
173
173
  aliens = %w{swarmer juggernaut crasher spire grunt bulwark drone manta dart
174
174
  decoy rumbler seeker turtle walker racer stealth}
175
175
 
176
176
  aliens.each do |alien|
177
177
  @alien_stats[alien] = [
178
- alien_data.elements["#{alien}/encountered/value"].text.to_i,
179
- alien_data.elements["#{alien}/killed/value"].text.to_i
178
+ alien_data[alien]['encountered']['value'].to_i,
179
+ alien_data[alien]['killed']['value'].to_i
180
180
  ]
181
181
  end
182
182
  end
@@ -200,33 +200,34 @@ class DefenseGridStats < GameStats
200
200
  return unless public?
201
201
 
202
202
  if @tower_stats.nil?
203
- tower_data = @xml_data.elements['stats/towers']
203
+ tower_data = @xml_data['stats']['towers']
204
204
  @tower_stats = {}
205
205
  towers = %w{cannon flak gun inferno laser meteor missile tesla}
206
206
 
207
207
  towers.each do |tower|
208
208
  @tower_stats[tower] = {}
209
209
  (1..3).each do |i|
210
+ tower_level = tower_data[tower].detect { |t| t['level'].to_i == i }
210
211
  @tower_stats[tower][i] = [
211
- tower_data.elements["#{tower}[@level=#{i}]/built/value"].text.to_i,
212
- tower_data.elements["#{tower}[@level=#{i}]/damage/value"].text.to_f
212
+ tower_level['built']['value'].to_i,
213
+ tower_level['damage']['value'].to_f
213
214
  ]
214
215
  end
215
216
  end
216
217
 
217
218
  @tower_stats['command'] = {}
218
219
  (1..3).each do |i|
220
+ tower_level = tower_data['command'].detect { |t| t['level'].to_i == i }
219
221
  @tower_stats['command'][i] = [
220
- tower_data.elements["command[@level=#{i}]/built/value"].text.to_i,
221
- tower_data.elements["command[@level=#{i}]/resource/value"].text.to_f
222
+ tower_level['built']['value'].to_i,
223
+ tower_level['resource']['value'].to_f
222
224
  ]
223
225
  end
224
226
 
225
227
  @tower_stats['temporal'] = {}
226
228
  (1..3).each do |i|
227
- @tower_stats['temporal'][i] = [
228
- tower_data.elements["temporal[@level=#{i}]/built/value"].text.to_i,
229
- ]
229
+ tower_level = tower_data['temporal'].detect { |t| t['level'].to_i == i }
230
+ @tower_stats['temporal'][i] = [ tower_level['built']['value'].to_i ]
230
231
  end
231
232
  end
232
233
 
@@ -70,21 +70,21 @@ class DoDSClass
70
70
  # Creates a new instance of a Day of Defeat: Source class based on the given
71
71
  # XML data
72
72
  #
73
- # @param [REXML::Element] class_data The XML data of the class
73
+ # @param [Hash<String, Object>] class_data The XML data of the class
74
74
  def initialize(class_data)
75
- @blocks = class_data.elements['blocks'].text.to_i
76
- @bombs_defused = class_data.elements['bombsdefused'].text.to_i
77
- @bombs_planted = class_data.elements['bombsplanted'].text.to_i
78
- @captures = class_data.elements['captures'].text.to_i
79
- @deaths = class_data.elements['deaths'].text.to_i
80
- @dominations = class_data.elements['dominations'].text.to_i
81
- @key = class_data.attributes['key']
82
- @kills = class_data.elements['kills'].text.to_i
83
- @name = class_data.elements['name'].text
84
- @play_time = class_data.elements['playtime'].text.to_i
85
- @rounds_lost = class_data.elements['roundslost'].text.to_i
86
- @rounds_won = class_data.elements['roundswon'].text.to_i
87
- @revenges = class_data.elements['revenges'].text.to_i
75
+ @blocks = class_data['blocks'].to_i
76
+ @bombs_defused = class_data['bombsdefused'].to_i
77
+ @bombs_planted = class_data['bombsplanted'].to_i
78
+ @captures = class_data['captures'].to_i
79
+ @deaths = class_data['deaths'].to_i
80
+ @dominations = class_data['dominations'].to_i
81
+ @key = class_data['key']
82
+ @kills = class_data['kills'].to_i
83
+ @name = class_data['name']
84
+ @play_time = class_data['playtime'].to_i
85
+ @rounds_lost = class_data['roundslost'].to_i
86
+ @rounds_won = class_data['roundswon'].to_i
87
+ @revenges = class_data['revenges'].to_i
88
88
  end
89
89
 
90
90
  end
@@ -3,6 +3,7 @@
3
3
  #
4
4
  # Copyright (c) 2009-2011, Sebastian Staudt
5
5
 
6
+ require 'steam/community/dods/dods_class'
6
7
  require 'steam/community/dods/dods_weapon'
7
8
  require 'steam/community/game_stats'
8
9
 
@@ -31,8 +32,8 @@ class DoDSStats < GameStats
31
32
 
32
33
  if @class_stats.nil?
33
34
  @class_stats = {}
34
- @xml_data.elements.each('stats/classes/class') do |class_data|
35
- @class_stats[class_data.attributes['key']] = DoDSClass.new class_data
35
+ @xml_data['stats']['classes']['class'].each do |class_data|
36
+ @class_stats[class_data['key']] = DoDSClass.new class_data
36
37
  end
37
38
  end
38
39
 
@@ -49,8 +50,8 @@ class DoDSStats < GameStats
49
50
 
50
51
  if @weapon_stats.nil?
51
52
  @weapon_stats = {}
52
- @xml_data.elements.each('stats/weapons/weapon') do |weapon_data|
53
- @weapon_stats[weapon_data.attributes['key']] = DoDSWeapon.new(weapon_data)
53
+ @xml_data['stats']['weapons']['weapon'].each do |weapon_data|
54
+ @weapon_stats[weapon_data['key']] = DoDSWeapon.new weapon_data
54
55
  end
55
56
  end
56
57
 
@@ -30,15 +30,15 @@ class DoDSWeapon
30
30
  # Creates a new instance of a Day of Defeat: Source weapon based on the
31
31
  # given XML data
32
32
  #
33
- # @param [REXML::Element] weapon_data The XML data of the class
33
+ # @param [Hash<String, Object>] weapon_data The XML data of the class
34
34
  def initialize(weapon_data)
35
35
  super weapon_data
36
36
 
37
- @headshots = weapon_data.elements['headshots'].text.to_i
38
- @id = weapon_data.attributes['key']
39
- @name = weapon_data.elements['name'].text
40
- @shots = weapon_data.elements['shotsfired'].text.to_i
41
- @hits = weapon_data.elements['shotshit'].text.to_i
37
+ @headshots = weapon_data['headshots'].to_i
38
+ @id = weapon_data['key']
39
+ @name = weapon_data['name']
40
+ @shots = weapon_data['shotsfired'].to_i
41
+ @hits = weapon_data['shotshit'].to_i
42
42
  end
43
43
 
44
44
  # Returns the average number of hits needed for a kill with this weapon
@@ -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-2011, Sebastian Staudt
4
+ # Copyright (c) 2008-2012, Sebastian Staudt
5
5
 
6
6
  require 'multi_json'
7
7
 
@@ -21,32 +21,41 @@ class GameAchievement
21
21
  # @return [String] The API name of this achievement
22
22
  attr_reader :api_name
23
23
 
24
- # Return the unique Steam Application ID of the game this achievement
25
- # belongs to
26
- #
27
- # @return [Fixnum] The Steam Application ID of this achievement's game
28
- attr_reader :app_id
29
-
30
24
  # Returns the description of this achievement
31
25
  #
32
26
  # @return [String] The description of this achievement
33
27
  attr_reader :description
34
28
 
29
+ # Return the game this achievement belongs to
30
+ #
31
+ # @return [Steam] The game this achievement belongs to
32
+ attr_reader :game
33
+
34
+ # Returns the url for the closed icon of this achievement
35
+ #
36
+ # @return [String] The url of the closed achievement icon
37
+ attr_reader :icon_closed_url
38
+
39
+ # Returns the url for the open icon of this achievement
40
+ #
41
+ # @return [String] The url of the open achievement icon
42
+ attr_reader :icon_open_url
43
+
35
44
  # Returns the name of this achievement
36
45
  #
37
46
  # @return [String] The name of this achievement
38
47
  attr_reader :name
39
48
 
40
- # Returns the 64bit SteamID of the user who owns this achievement
41
- #
42
- # @return [Fixnum] The 64bit SteamID of this achievement's owner
43
- attr_reader :steam_id64
44
-
45
49
  # Returns the time this achievement has been unlocked by its owner
46
50
  #
47
51
  # @return [Time] The time this achievement has been unlocked
48
52
  attr_reader :timestamp
49
53
 
54
+ # Returns the SteamID of the user who owns this achievement
55
+ #
56
+ # @return [Fixnum] The SteamID of this achievement's owner
57
+ attr_reader :user
58
+
50
59
  # Loads the global unlock percentages of all achievements for the game with
51
60
  # the given Steam Application ID
52
61
  #
@@ -61,7 +70,7 @@ class GameAchievement
61
70
  percentages = {}
62
71
 
63
72
  data = WebApi.json('ISteamUserStats', 'GetGlobalAchievementPercentagesForApp', 2, { :gameid => app_id })
64
- MultiJson.decode(data, { :symbolize_keys => true })[:achievementpercentages][:achievements].each do |percentage|
73
+ MultiJson.load(data, { :symbolize_keys => true })[:achievementpercentages][:achievements].each do |percentage|
65
74
  percentages[percentage[:name].to_sym] = percentage[:percent]
66
75
  end
67
76
 
@@ -71,24 +80,22 @@ class GameAchievement
71
80
  # Creates the achievement with the given name for the given user and game
72
81
  # and achievement data
73
82
  #
74
- # @param [Fixnum] steam_id64 The 64bit SteamID of the player this achievement
75
- # belongs to
76
- # @param [Fixnum] app_id The unique Steam Application ID of the game (e.g.
77
- # `440` for Team Fortress 2). See
78
- # http://developer.valvesoftware.com/wiki/Steam_Application_IDs for
79
- # all application IDs
80
- # @param [REXML::Element] achievement_data The achievement data extracted
81
- # from XML
82
- def initialize(steam_id64, app_id, achievement_data)
83
- @api_name = achievement_data.elements['apiname'].text
84
- @app_id = app_id
85
- @description = achievement_data.elements['description'].text
86
- @name = achievement_data.elements['name'].text
87
- @steam_id64 = steam_id64
88
- @unlocked = (achievement_data.attributes['closed'].to_i == 1)
89
-
90
- if @unlocked && !achievement_data.elements['unlockTimestamp'].nil?
91
- @timestamp = Time.at(achievement_data.elements['unlockTimestamp'].text.to_i)
83
+ # @param [SteamId] user The SteamID of the player this achievement belongs to
84
+ # @param [SteamGame] game The game this achievement belongs to
85
+ # @param [Hash<String, Object>] achievement_data The achievement data
86
+ # extracted from XML
87
+ def initialize(user, game, achievement_data)
88
+ @api_name = achievement_data['apiname']
89
+ @description = achievement_data['description']
90
+ @game = game
91
+ @icon_closed_url = achievement_data['iconClosed']
92
+ @icon_open_url = achievement_data['iconOpen']
93
+ @name = achievement_data['name']
94
+ @unlocked = (achievement_data['closed'].to_i == 1)
95
+ @user = user
96
+
97
+ if @unlocked && !achievement_data['unlockTimestamp'].nil?
98
+ @timestamp = Time.at(achievement_data['unlockTimestamp'].to_i)
92
99
  end
93
100
  end
94
101
 
@@ -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) 2011, Sebastian Staudt
4
+ # Copyright (c) 2011-2012, Sebastian Staudt
5
5
 
6
6
  require 'steam/community/cacheable'
7
7
  require 'steam/community/game_item'
@@ -17,10 +17,10 @@ module GameInventory
17
17
  # @return [Array<GameItem>] All items in the backpack
18
18
  attr_reader :items
19
19
 
20
- # Returns the 64bit SteamID of the player owning this inventory
20
+ # Returns the Steam ID of the player owning this inventory
21
21
  #
22
- # @return [String] The 64bit SteamID
23
- attr_reader :steam_id64
22
+ # @return [SteamId] The Steam ID of the owner of this inventory
23
+ attr_reader :user
24
24
 
25
25
  @@attribute_schema = {}
26
26
 
@@ -45,7 +45,7 @@ module GameInventory
45
45
  # inventory for
46
46
  # @param [Boolean] fetch_now if `true` the data will be fetched immediately
47
47
  def initialize(steam_id64, fetch_now = true)
48
- @steam_id64 = steam_id64
48
+ @user = SteamId.new steam_id64, false
49
49
 
50
50
  super fetch_now
51
51
  end
@@ -80,7 +80,7 @@ module GameInventory
80
80
 
81
81
  # Updates the contents of the inventory using Steam Web API
82
82
  def fetch
83
- result = WebApi.json!("IEconItems_#{app_id}", 'GetPlayerItems', 1, { :SteamID => @steam_id64 })
83
+ result = WebApi.json!("IEconItems_#{app_id}", 'GetPlayerItems', 1, { :SteamID => @user.steam_id64 })
84
84
  item_class = self.class.send :class_variable_get, :@@item_class
85
85
 
86
86
  @items = []
@@ -1,10 +1,12 @@
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) 2011, Sebastian Staudt
4
+ # Copyright (c) 2011-2012, Sebastian Staudt
5
5
 
6
- require 'steam/community/game_leaderboard_entry';
7
- require 'steam/community/steam_id';
6
+ require 'multi_xml'
7
+
8
+ require 'steam/community/game_leaderboard_entry'
9
+ require 'steam/community/steam_id'
8
10
 
9
11
  # The GameLeaderboard class represents a single leaderboard for a specific game
10
12
  #
@@ -84,14 +86,14 @@ class GameLeaderboard
84
86
  def entry_for_steam_id(steam_id)
85
87
  steam_id = steam_id.steam_id64 if steam_id.is_a? SteamId
86
88
 
87
- url = "#{@url}&steamid=#{steam_id}"
88
- xml = REXML::Document.new(open(url, {:proxy => true}).read).root
89
+ url = "#@url&steamid=#{steam_id}"
90
+ xml_data = MultiXml.parse(open(url, {:proxy => true})).values.first
89
91
 
90
- error = @xml_data.elements['error']
91
- raise SteamCondenserError, error.text unless error.nil?
92
+ error = xml_data['error']
93
+ raise SteamCondenserError, error unless error.nil?
92
94
 
93
- boards_data.elements.each('entries/entry') do |entry_data|
94
- if entry_data.elements['steamid'].text.to_i == steam_id
95
+ xml_data['entries']['entry'].each do |entry_data|
96
+ if entry_data['steamid'].to_i == steam_id
95
97
  return GameLeaderboardEntry.new entry_data, self
96
98
  end
97
99
  end
@@ -111,15 +113,15 @@ class GameLeaderboard
111
113
  def entry_for_steam_id_friends(steam_id)
112
114
  steam_id = steam_id.steam_id64 if steam_id.is_a? SteamId
113
115
 
114
- url = "#{@url}&steamid=#{steam_id}"
115
- xml = REXML::Document.new(open(url, {:proxy => true}).read).root
116
+ url = "#@url&steamid=#{steam_id}"
117
+ xml_data = MultiXml.parse(open(url, {:proxy => true})).values.first
116
118
 
117
- error = @xml_data.elements['error']
118
- raise SteamCondenserError, error.text unless error.nil?
119
+ error = xml_data['error']
120
+ raise SteamCondenserError, error unless error.nil?
119
121
 
120
122
  entries = []
121
- boards_data.elements.each('entries/entry') do |entry_data|
122
- rank = entry_data.elements['rank'].text.to_i
123
+ xml_data['entries']['entry'].each do |entry_data|
124
+ rank = entry_data['rank'].to_i
123
125
  entries[rank] = GameLeaderboardEntry.new entry_data, self
124
126
  end
125
127
 
@@ -148,15 +150,15 @@ class GameLeaderboard
148
150
  'Leaderboard entry lookup is currently limited to a maximum of 5001 entries per request.'
149
151
  end
150
152
 
151
- url = "#{@url}&start=#{first}&end=#{last}"
152
- xml = REXML::Document.new(open(url, {:proxy => true}).read).root
153
+ url = "#@url&start=#{first}&end=#{last}"
154
+ xml_data = MultiXml.parse(open(url, {:proxy => true})).values.first
153
155
 
154
- error = @xml_data.elements['error']
155
- raise SteamCondenserError, error.text unless error.nil?
156
+ error = xml_data['error']
157
+ raise SteamCondenserError, error unless error.nil?
156
158
 
157
159
  entries = []
158
- boards_data.elements.each('entries/entry') do |entry_data|
159
- rank = entry_data.elements['rank'].text.to_i
160
+ xml_data['entries']['entry'].each do |entry_data|
161
+ rank = entry_data['rank'].to_i
160
162
  entries[rank] = GameLeaderboardEntry.new entry_data, self
161
163
  end
162
164
 
@@ -167,14 +169,14 @@ class GameLeaderboard
167
169
 
168
170
  # Creates a new leaderboard instance with the given XML data
169
171
  #
170
- # @param [REXML::Element] board_data The XML data of the leaderboard
172
+ # @param [Hash<String, Object>] board_data The XML data of the leaderboard
171
173
  def initialize(board_data)
172
- @url = board_data.elements['url'].text
173
- @id = board_data.elements['lbid'].text.to_i
174
- @name = board_data.elements['name'].text
175
- @entry_count = board_data.elements['entries'].text.to_i
176
- @sort_method = board_data.elements['sortmethod'].text.to_i
177
- @display_type = board_data.elements['displaytype'].text.to_i
174
+ @url = board_data['url']
175
+ @id = board_data['lbid'].to_i
176
+ @name = board_data['name']
177
+ @entry_count = board_data['entries'].to_i
178
+ @sort_method = board_data['sortmethod'].to_i
179
+ @display_type = board_data['displaytype'].to_i
178
180
  end
179
181
 
180
182
  # Loads the leaderboards of the specified games into the cache
@@ -184,13 +186,13 @@ class GameLeaderboard
184
186
  # leaderboards
185
187
  def self.load_leaderboards(game_name)
186
188
  url = "http://steamcommunity.com/stats/#{game_name}/leaderboards/?xml=1"
187
- boards_data = REXML::Document.new(open(url, {:proxy => true}).read).root
189
+ boards_data = MultiXml.parse(open(url, {:proxy => true})).values.first
188
190
 
189
- error = boards_data.elements['error']
190
- raise SteamCondenserError, error.text unless error.nil?
191
+ error = boards_data['error']
192
+ raise SteamCondenserError, error unless error.nil?
191
193
 
192
194
  @@leaderboards[game_name] = []
193
- boards_data.elements.each('leaderboard') do |board_data|
195
+ boards_data['leaderboard'].each do |board_data|
194
196
  leaderboard = GameLeaderboard.new board_data
195
197
  @@leaderboards[game_name][leaderboard.id] = leaderboard
196
198
  end