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
@@ -1,17 +1,16 @@
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 'cgi'
7
- require 'open-uri'
8
- require 'rexml/document'
9
7
 
10
8
  require 'errors/steam_condenser_error'
11
9
  require 'steam/community/cacheable'
12
10
  require 'steam/community/game_stats'
13
11
  require 'steam/community/steam_game'
14
12
  require 'steam/community/steam_group'
13
+ require 'steam/community/xml_data'
15
14
 
16
15
  # The SteamId class represents a Steam Community profile (also called Steam ID)
17
16
  #
@@ -21,6 +20,8 @@ class SteamId
21
20
  include Cacheable
22
21
  cacheable_with_ids :custom_url, :steam_id64
23
22
 
23
+ include XMLData
24
+
24
25
  # Returns the custom URL of this Steam ID
25
26
  #
26
27
  # The custom URL is a user specified unique string that can be used instead
@@ -126,6 +127,11 @@ class SteamId
126
127
  # @return [String] This user's summary
127
128
  attr_reader :summary
128
129
 
130
+ # Returns this user's ban state in Steam's trading system
131
+ #
132
+ # @return [String] This user's trading ban state
133
+ attr_reader :trade_ban_state
134
+
129
135
  # Returns the visibility state of this Steam ID
130
136
  #
131
137
  # @return [Fixnum] This Steam ID's visibility State
@@ -138,7 +144,7 @@ class SteamId
138
144
  # Community
139
145
  # @raise [SteamCondenserError] if the community ID is to small
140
146
  # @return [String] The converted SteamID, like `STEAM_0:0:12345`
141
- def self.convert_community_id_to_steam_id(community_id)
147
+ def self.community_id_to_steam_id(community_id)
142
148
  steam_id1 = community_id % 2
143
149
  steam_id2 = community_id - 76561197960265728
144
150
 
@@ -159,7 +165,7 @@ class SteamId
159
165
  # @raise [SteamCondenserError] if the SteamID doesn't have the correct
160
166
  # format
161
167
  # @return [Fixnum] The converted 64bit numeric SteamID
162
- def self.convert_steam_id_to_community_id(steam_id)
168
+ def self.steam_id_to_community_id(steam_id)
163
169
  if steam_id == 'STEAM_ID_LAN' || steam_id == 'BOT'
164
170
  raise SteamCondenserError, "Cannot convert SteamID \"#{steam_id}\" to a community ID."
165
171
  elsif steam_id.match(/^STEAM_[0-1]:[0-1]:[0-9]+$/).nil?
@@ -171,6 +177,11 @@ class SteamId
171
177
  steam_id[1] + steam_id[2] * 2 + 76561197960265728
172
178
  end
173
179
 
180
+ class << self
181
+ alias_method :convert_community_id_to_steam_id, :community_id_to_steam_id
182
+ alias_method :convert_steam_id_to_community_id, :steam_id_to_community_id
183
+ end
184
+
174
185
  # Creates a new `SteamId` instance using a SteamID as used on servers
175
186
  #
176
187
  # The SteamID from the server is converted into a 64bit numeric SteamID first
@@ -192,19 +203,23 @@ class SteamId
192
203
  # @param [Boolean] fetch if `true` the Steam ID's data is loaded into the
193
204
  # object
194
205
  def initialize(id, fetch = true)
195
- begin
196
- if id.is_a? Numeric
197
- @steam_id64 = id
198
- else
199
- @custom_url = id.downcase
200
- end
201
-
202
- super(fetch)
203
- rescue REXML::ParseException
204
- raise SteamCondenserError, 'SteamID could not be loaded.'
206
+ if id.is_a? Numeric
207
+ @steam_id64 = id
208
+ else
209
+ @custom_url = id.downcase
205
210
  end
211
+
212
+ super fetch
206
213
  end
207
214
 
215
+ # Returns whether the owner of this SteamID is VAC banned
216
+ #
217
+ # @return [Boolean] `true` if the user has been banned by VAC
218
+ def banned?
219
+ @vac_banned
220
+ end
221
+ alias_method :is_banned?, :banned?
222
+
208
223
  # Returns the base URL for this Steam ID
209
224
  #
210
225
  # This URL is different for Steam IDs having a custom URL.
@@ -212,9 +227,9 @@ class SteamId
212
227
  # @return [String] The base URL for this SteamID
213
228
  def base_url
214
229
  if @custom_url.nil?
215
- "http://steamcommunity.com/profiles/#{@steam_id64}"
230
+ "http://steamcommunity.com/profiles/#@steam_id64"
216
231
  else
217
- "http://steamcommunity.com/id/#{@custom_url}"
232
+ "http://steamcommunity.com/id/#@custom_url"
218
233
  end
219
234
  end
220
235
 
@@ -225,68 +240,70 @@ class SteamId
225
240
  # when it is private
226
241
  # @see Cacheable#fetch
227
242
  def fetch
228
- profile_url = open(base_url + '?xml=1', {:proxy => true})
229
- profile = REXML::Document.new(profile_url.read).root
243
+ begin
244
+ profile = parse "#{base_url}?xml=1"
230
245
 
231
- unless REXML::XPath.first(profile, 'error').nil?
232
- raise SteamCondenserError, profile.elements['error'].text
233
- end
246
+ if profile.key? 'error'
247
+ raise SteamCondenserError, profile['error']
248
+ end
234
249
 
235
- unless REXML::XPath.first(profile, 'privacyMessage').nil?
236
- raise SteamCondenserError, profile.elements['privacyMessage'].text
237
- end
238
-
239
- begin
240
- @nickname = CGI.unescapeHTML profile.elements['steamID'].text
241
- @steam_id64 = profile.elements['steamID64'].text.to_i
242
- @vac_banned = (profile.elements['vacBanned'].text == 1)
243
-
244
- @image_url = profile.elements['avatarIcon'].text[0..-5]
245
- @online_state = profile.elements['onlineState'].text
246
- @privacy_state = profile.elements['privacyState'].text
247
- @state_message = profile.elements['stateMessage'].text
248
- @visibility_state = profile.elements['visibilityState'].text.to_i
249
-
250
- if @privacy_state == 'public'
251
- @custom_url = profile.elements['customURL'].text.downcase
252
- @custom_url = nil if @custom_url.empty?
253
-
254
- unless REXML::XPath.first(profile, 'favoriteGame').nil?
255
- @favorite_game = profile.elements['favoriteGame/name'].text
256
- @favorite_game_hours_played = profile.elements['favoriteGame/hoursPlayed2wk'].text
250
+ if profile.key? 'privacyMessage'
251
+ raise SteamCondenserError, profile['privacyMessage']
252
+ end
253
+
254
+ @nickname = CGI.unescapeHTML profile['steamID']
255
+ @steam_id64 = profile['steamID64'].to_i
256
+ @limited = (profile['isLimitedAccount'].to_i == 1)
257
+ @trade_ban_state = profile['tradeBanState']
258
+ @vac_banned = (profile['vacBanned'].to_i == 1)
259
+
260
+ @image_url = profile['avatarIcon'][0..-5]
261
+ @online_state = profile['onlineState']
262
+ @privacy_state = profile['privacyState']
263
+ @state_message = profile['stateMessage']
264
+ @visibility_state = profile['visibilityState'].to_i
265
+
266
+ if public?
267
+ @custom_url = profile['customURL'].downcase
268
+ @custom_url = nil if @custom_url.empty?
269
+
270
+ if profile.key? 'favoriteGame'
271
+ @favorite_game = profile['favoriteGame']['name']
272
+ @favorite_game_hours_played = profile['favoriteGame']['hoursPlayed2wk']
257
273
  end
258
274
 
259
- @head_line = CGI.unescapeHTML profile.elements['headline'].text
260
- @hours_played = profile.elements['hoursPlayed2Wk'].text.to_f
261
- @location = profile.elements['location'].text
262
- @member_since = Time.parse(profile.elements['memberSince'].text)
263
- @real_name = CGI.unescapeHTML profile.elements['realname'].text
264
- @steam_rating = profile.elements['steamRating'].text.to_f
265
- @summary = CGI.unescapeHTML profile.elements['summary'].text
275
+ @head_line = CGI.unescapeHTML profile['headline'] || ''
276
+ @hours_played = profile['hoursPlayed2Wk'].to_f
277
+ @location = profile['location']
278
+ @member_since = Time.parse profile['memberSince']
279
+ @real_name = CGI.unescapeHTML profile['realname'] || ''
280
+ @steam_rating = profile['steamRating'].to_f
281
+ @summary = CGI.unescapeHTML profile['summary'] || ''
266
282
 
267
283
  @most_played_games = {}
268
- unless REXML::XPath.first(profile, 'mostPlayedGames').nil?
269
- profile.elements.each('mostPlayedGames/mostPlayedGame') do |most_played_game|
270
- @most_played_games[most_played_game.elements['gameName'].text] = most_played_game.elements['hoursPlayed'].text.to_f
284
+ if profile.key? 'mostPlayedGames'
285
+ [profile['mostPlayedGames']['mostPlayedGame']].flatten.each do |most_played_game|
286
+ @most_played_games[most_played_game['gameName']] = most_played_game['hoursPlayed'].to_f
271
287
  end
272
288
  end
273
289
 
274
290
  @groups = []
275
- unless REXML::XPath.first(profile, 'groups').nil?
276
- profile.elements.each('groups/group') do |group|
277
- @groups << SteamGroup.new(group.elements['groupID64'].text.to_i, false)
291
+ if profile.key? 'groups'
292
+ [profile['groups']['group']].flatten.each do |group|
293
+ @groups << SteamGroup.new(group['groupID64'].to_i, false)
278
294
  end
279
295
  end
280
296
 
281
297
  @links = {}
282
- unless REXML::XPath.first(profile, 'weblinks').nil?
283
- profile.elements.each('weblinks/weblink') do |link|
284
- @links[CGI.unescapeHTML link.elements['title'].text] = link.elements['link'].text
298
+ if profile.key? 'weblinks'
299
+ [profile['weblinks']['weblink']].flatten.each do |link|
300
+ @links[CGI.unescapeHTML link['title']] = link['link']
285
301
  end
286
302
  end
287
303
  end
288
304
  rescue
289
- raise SteamCondenserError, 'XML data could not be parsed.'
305
+ raise $! if $!.is_a? SteamCondenserError
306
+ raise SteamCondenserError, 'XML data could not be parsed.', $!.backtrace
290
307
  end
291
308
 
292
309
  super
@@ -300,12 +317,10 @@ class SteamId
300
317
  # @see #friends
301
318
  # @see #initialize
302
319
  def fetch_friends
303
- url = "#{base_url}/friends?xml=1"
304
-
305
320
  @friends = []
306
- friends_data = REXML::Document.new(open(url, {:proxy => true}).read).root
307
- friends_data.elements.each('friends/friend') do |friend|
308
- @friends << SteamId.new(friend.text.to_i, false)
321
+ friends_data = parse "#{base_url}/friends?xml=1"
322
+ friends_data['friends']['friend'].each do |friend|
323
+ @friends << SteamId.new(friend.to_i, false)
309
324
  end
310
325
  end
311
326
 
@@ -317,22 +332,21 @@ class SteamId
317
332
  #
318
333
  # @see #games
319
334
  def fetch_games
320
- url = "#{base_url}/games?xml=1"
321
-
322
335
  @games = {}
323
336
  @playtimes = {}
324
- games_data = REXML::Document.new(open(url, {:proxy => true}).read).root
325
- games_data.elements.each('games/game') do |game_data|
326
- game = SteamGame.new(game_data)
327
- @games[game.app_id] = game
337
+ games_data = parse "#{base_url}/games?xml=1"
338
+ [games_data['games']['game']].flatten.each do |game_data|
339
+ app_id = game_data['appID'].to_i
340
+ game = SteamGame.new app_id, game_data
341
+ @games[app_id] = game
328
342
  recent = total = 0
329
- unless game_data.elements['hoursLast2Weeks'].nil?
330
- recent = game_data.elements['hoursLast2Weeks'].text.to_f
343
+ if game_data.key? 'hoursLast2Weeks'
344
+ recent = game_data['hoursLast2Weeks'].to_f
331
345
  end
332
- unless game_data.elements['hoursOnRecord'].nil?
333
- total = game_data.elements['hoursOnRecord'].text.to_f
346
+ if game_data.key? 'hoursOnRecord'
347
+ total = game_data['hoursOnRecord'].to_f
334
348
  end
335
- @playtimes[game.app_id] = [(recent * 60).to_i, (total * 60).to_i]
349
+ @playtimes[app_id] = [(recent * 60).to_i, (total * 60).to_i]
336
350
  end
337
351
 
338
352
  true
@@ -393,28 +407,31 @@ class SteamId
393
407
  #
394
408
  # @return [String] The URL of the icon-sized avatar
395
409
  def icon_url
396
- "#{@image_url}.jpg"
410
+ "#@image_url.jpg"
397
411
  end
398
412
 
399
- # Returns whether the owner of this SteamID is VAC banned
413
+ # Returns a unique identifier for this Steam ID
400
414
  #
401
- # @return [Boolean] `true` if the user has been banned by VAC
402
- def is_banned?
403
- @vac_banned
415
+ # This is either the 64bit numeric SteamID or custom URL
416
+ #
417
+ # @return [Fixnum, String] The 64bit numeric SteamID or the custom URL
418
+ def id
419
+ @custom_url.nil? ? @steam_id64 : @custom_url
404
420
  end
405
421
 
406
422
  # Returns whether the owner of this SteamId is playing a game
407
423
  #
408
424
  # @return [Boolean] `true` if the user is in-game
409
- def is_in_game?
425
+ def in_game?
410
426
  @online_state == 'in-game'
411
427
  end
428
+ alias_method :is_in_game?, :in_game?
412
429
 
413
- # Returns whether the owner of this SteamID is currently logged into Steam
430
+ # Returns whether this Steam account is limited
414
431
  #
415
- # @return [Boolean] `true` if the user is online
416
- def is_online?
417
- @online_state != 'offline'
432
+ # @return [Boolean] `true` if this account is limited
433
+ def limited?
434
+ @limited
418
435
  end
419
436
 
420
437
  # Returns the URL of the medium-sized version of this user's avatar
@@ -424,6 +441,21 @@ class SteamId
424
441
  "#{@image_url}_medium.jpg"
425
442
  end
426
443
 
444
+ # Returns whether the owner of this SteamID is currently logged into Steam
445
+ #
446
+ # @return [Boolean] `true` if the user is online
447
+ def online?
448
+ @online_state != 'offline'
449
+ end
450
+ alias_method :is_online?, :online?
451
+
452
+ # Returns whether this Steam ID is publicly accessible
453
+ #
454
+ # @return [Boolean] `true` if this Steam ID is public
455
+ def public?
456
+ @privacy_state == 'public'
457
+ end
458
+
427
459
  # Returns the time in minutes this user has played this game in the last two
428
460
  # weeks
429
461
  #
@@ -8,7 +8,7 @@ require 'steam/community/game_class'
8
8
  # Represents the stats for a Team Fortress 2 class for a specific user
9
9
  #
10
10
  # @author Sebastian Staudt
11
- module TF2Class
11
+ class TF2Class
12
12
 
13
13
  include GameClass
14
14
 
@@ -73,20 +73,20 @@ module TF2Class
73
73
 
74
74
  # Creates a new TF2 class instance based on the assigned XML data
75
75
  #
76
- # @param [REXML::Element] class_data The XML data for this class
76
+ # @param [Hash<String, Object>] class_data The XML data for this class
77
77
  def initialize(class_data)
78
- @name = class_data.elements['className'].text
79
- @max_buildings_destroyed = class_data.elements['ibuildingsdestroyed'].text.to_i
80
- @max_captures = class_data.elements['ipointcaptures'].text.to_i
81
- @max_damage = class_data.elements['idamagedealt'].text.to_i
82
- @max_defenses = class_data.elements['ipointdefenses'].text.to_i
83
- @max_dominations = class_data.elements['idominations'].text.to_i
84
- @max_kill_assists = class_data.elements['ikillassists'].text.to_i
85
- @max_kills = class_data.elements['inumberofkills'].text.to_i
86
- @max_revenges = class_data.elements['irevenge'].text.to_i
87
- @max_score = class_data.elements['ipointsscored'].text.to_i
88
- @max_time_alive = class_data.elements['iplaytime'].text.to_i
89
- @play_time = class_data.elements['playtimeSeconds'].text.to_i
78
+ @name = class_data['className']
79
+ @max_buildings_destroyed = class_data['ibuildingsdestroyed'].to_i
80
+ @max_captures = class_data['ipointcaptures'].to_i
81
+ @max_damage = class_data['idamagedealt'].to_i
82
+ @max_defenses = class_data['ipointdefenses'].to_i
83
+ @max_dominations = class_data['idominations'].to_i
84
+ @max_kill_assists = class_data['ikillassists'].to_i
85
+ @max_kills = class_data['inumberofkills'].to_i
86
+ @max_revenges = class_data['irevenge'].to_i
87
+ @max_score = class_data['ipointsscored'].to_i
88
+ @max_time_alive = class_data['iplaytime'].to_i
89
+ @play_time = class_data['playtimeSeconds'].to_i
90
90
  end
91
91
 
92
92
  end
@@ -20,10 +20,10 @@ module TF2ClassFactory
20
20
  # This returns an instance of `TF2Class` or its subclasses `TF2Engineer`,
21
21
  # `TF2Medic`, `TF2Sniper` or `TF2Spy` depending on the given XML data.
22
22
  #
23
- # @param [REXML::Element] class_data The XML data for the class
23
+ # @param [Hash<String, Object>] class_data The XML data for the class
24
24
  # @return [TF2Class] The statistics for the given class data
25
25
  def self.tf2_class(class_data)
26
- case class_data.elements['className'].text
26
+ case class_data['className']
27
27
  when 'Engineer' then
28
28
  return TF2Engineer.new(class_data)
29
29
  when 'Medic' then
@@ -9,9 +9,7 @@ require 'steam/community/tf2/tf2_class'
9
9
  # user
10
10
  #
11
11
  # @author Sebastian Staudt
12
- class TF2Engineer
13
-
14
- include TF2Class
12
+ class TF2Engineer < TF2Class
15
13
 
16
14
  # Returns the maximum number of buildings built by the player in a single
17
15
  # life as an Engineer
@@ -33,13 +31,13 @@ class TF2Engineer
33
31
 
34
32
  # Creates a new instance of the Engineer class based on the given XML data
35
33
  #
36
- # @param [REXML::Element] class_data The XML data for this Engineer
34
+ # @param [Hash<String, Object>] class_data The XML data for this Engineer
37
35
  def initialize(class_data)
38
36
  super class_data
39
37
 
40
- @max_buildings_built = class_data.elements['ibuildingsbuilt'].text.to_i
41
- @max_teleports = class_data.elements['inumteleports'].text.to_i
42
- @max_sentry_kills = class_data.elements['isentrykills'].text.to_i
38
+ @max_buildings_built = class_data['ibuildingsbuilt'].to_i
39
+ @max_teleports = class_data['inumteleports'].to_i
40
+ @max_sentry_kills = class_data['isentrykills'].to_i
43
41
  end
44
42
 
45
43
  end
@@ -46,7 +46,7 @@ class TF2GoldenWrench
46
46
  if @@golden_wrenches.nil?
47
47
  @@golden_wrenches = []
48
48
 
49
- data = MultiJson.decode(WebApi.json('ITFItems_440', 'GetGoldenWrenches', 2), { :symbolize_keys => true })
49
+ data = MultiJson.load(WebApi.json('ITFItems_440', 'GetGoldenWrenches', 2), { :symbolize_keys => true })
50
50
  data[:results][:wrenches].each do |wrench_data|
51
51
  @@golden_wrenches << TF2GoldenWrench.new(wrench_data)
52
52
  end
@@ -8,9 +8,7 @@ require 'steam/community/tf2/tf2_class'
8
8
  # Represents the stats for the Team Fortress 2 Medic class for a specific user
9
9
  #
10
10
  # @author Sebastian Staudt
11
- class TF2Medic
12
-
13
- include TF2Class
11
+ class TF2Medic < TF2Class
14
12
 
15
13
  # Returns the maximum health healed for teammates by the player in a
16
14
  # single life as a Medic
@@ -26,12 +24,12 @@ class TF2Medic
26
24
 
27
25
  # Creates a new instance of the Medic class based on the given XML data
28
26
  #
29
- # @param [REXML::Element] class_data The XML data for this Medic
27
+ # @param [Hash<String, Object>] class_data The XML data for this Medic
30
28
  def initialize(class_data)
31
29
  super class_data
32
30
 
33
- @max_health_healed = class_data.elements['ihealthpointshealed'].text.to_i
34
- @max_ubercharges = class_data.elements['inuminvulnerable'].text.to_i
31
+ @max_health_healed = class_data['ihealthpointshealed'].to_i
32
+ @max_ubercharges = class_data['inuminvulnerable'].to_i
35
33
  end
36
34
 
37
35
  end