steam-condenser 1.3.2 → 1.3.3

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.
@@ -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) 2009-2011, Sebastian Staudt
4
+ # Copyright (c) 2009-2013, Sebastian Staudt
5
5
 
6
6
  require 'steam/community/l4d/abstract_l4d_stats'
7
7
  require 'steam/community/l4d/l4d2_map'
@@ -34,11 +34,13 @@ class L4D2Stats < GameStats
34
34
  def initialize(steam_id)
35
35
  super steam_id, 'l4d2'
36
36
 
37
+ weapons_data = @xml_data['stats']['weapons']
38
+
37
39
  @damage_percentages = {
38
- :melee => @xml_data['stats']['weapons']['meleepctdmg'].to_f,
39
- :pistols => @xml_data['stats']['weapons']['pistolspctdmg'].to_f,
40
- :rifles => @xml_data['stats']['weapons']['bulletspctdmg'].to_f,
41
- :shotguns => @xml_data['stats']['weapons']['shellspctdmg'].to_f
40
+ :melee => weapons_data['meleepctdmg'].to_f,
41
+ :pistols => weapons_data['pistolspctdmg'].to_f,
42
+ :rifles => weapons_data['bulletspctdmg'].to_f,
43
+ :shotguns => weapons_data['shellspctdmg'].to_f
42
44
  }
43
45
  end
44
46
 
@@ -58,9 +60,11 @@ class L4D2Stats < GameStats
58
60
 
59
61
  if @lifetime_stats.nil?
60
62
  super
61
- @lifetime_stats[:avg_adrenaline_shared] = @xml_data['stats']['lifetime']['adrenalineshared'].to_f
62
- @lifetime_stats[:avg_adrenaline_used] = @xml_data['stats']['lifetime']['adrenalineused'].to_f
63
- @lifetime_stats[:avg_defibrillators_used] = @xml_data['stats']['lifetime']['defibrillatorsused'].to_f
63
+
64
+ lifetime_data = @xml_data['stats']['lifetime']
65
+ @lifetime_stats[:avg_adrenaline_shared] = lifetime_data['adrenalineshared'].to_f
66
+ @lifetime_stats[:avg_adrenaline_used] = lifetime_data['adrenalineused'].to_f
67
+ @lifetime_stats[:avg_defibrillators_used] = lifetime_data['defibrillatorsused'].to_f
64
68
  end
65
69
 
66
70
  @lifetime_stats
@@ -77,33 +81,36 @@ class L4D2Stats < GameStats
77
81
  return unless public?
78
82
 
79
83
  if @scavenge_stats.nil?
84
+ scavange_data = @xml_data['stats']['scavenge']
85
+
80
86
  @scavenge_stats = {}
81
- @scavenge_stats[:avg_cans_per_round] = @xml_data['stats']['scavenge']['avgcansperround'].to_f
82
- @scavenge_stats[:perfect_rounds] = @xml_data['stats']['scavenge']['perfect16canrounds'].to_i
83
- @scavenge_stats[:rounds_lost] = @xml_data['stats']['scavenge']['roundslost'].to_i
84
- @scavenge_stats[:rounds_played] = @xml_data['stats']['scavenge']['roundsplayed'].to_i
85
- @scavenge_stats[:rounds_won] = @xml_data['stats']['scavenge']['roundswon'].to_i
86
- @scavenge_stats[:total_cans] = @xml_data['stats']['scavenge']['totalcans'].to_i
87
+ @scavenge_stats[:avg_cans_per_round] = scavange_data['avgcansperround'].to_f
88
+ @scavenge_stats[:perfect_rounds] = scavange_data['perfect16canrounds'].to_i
89
+ @scavenge_stats[:rounds_lost] = scavange_data['roundslost'].to_i
90
+ @scavenge_stats[:rounds_played] = scavange_data['roundsplayed'].to_i
91
+ @scavenge_stats[:rounds_won] = scavange_data['roundswon'].to_i
92
+ @scavenge_stats[:total_cans] = scavange_data['totalcans'].to_i
87
93
 
88
94
  @scavenge_stats[:maps] = {}
89
- @xml_data['stats']['scavenge']['mapstats']['map'].each do |map_data|
90
- map_id = map_data['name']
91
- @scavenge_stats[:maps][map_id] = {}
92
- @scavenge_stats[:maps][map_id]['avg_round_score'] = map_data['avgscoreperround'].to_i
93
- @scavenge_stats[:maps][map_id]['highest_game_score'] = map_data['highgamescore'].to_i
94
- @scavenge_stats[:maps][map_id]['highest_round_score'] = map_data['highroundscore'].to_i
95
- @scavenge_stats[:maps][map_id]['name'] = map_data['fullname']
96
- @scavenge_stats[:maps][map_id]['rounds_played'] = map_data['roundsplayed'].to_i
97
- @scavenge_stats[:maps][map_id]['rounds_won'] = map_data['roundswon'].to_i
95
+ scavange_data['mapstats']['map'].each do |map_data|
96
+ map_stats = {}
97
+ map_stats['avg_round_score'] = map_data['avgscoreperround'].to_i
98
+ map_stats['highest_game_score'] = map_data['highgamescore'].to_i
99
+ map_stats['highest_round_score'] = map_data['highroundscore'].to_i
100
+ map_stats['name'] = map_data['fullname']
101
+ map_stats['rounds_played'] = map_data['roundsplayed'].to_i
102
+ map_stats['rounds_won'] = map_data['roundswon'].to_i
103
+ @scavenge_stats[:maps][map_data['name']] = map_stats
104
+
98
105
  end
99
106
 
100
107
  @scavenge_stats[:infected] = {}
101
- @xml_data['stats']['scavenge']['infectedstats']['special'].each do |infected_data|
102
- infected_id = infected_data['name']
103
- @scavenge_stats[:infected][infected_id] = {}
104
- @scavenge_stats[:infected][infected_id]['max_damage_per_life'] = infected_data['maxdmg1life'].to_i
105
- @scavenge_stats[:infected][infected_id]['max_pours_interrupted'] = infected_data['maxpoursinterrupted'].to_i
106
- @scavenge_stats[:infected][infected_id]['special_attacks'] = infected_data['specialattacks'].to_i
108
+ scavange_data['infectedstats']['special'].each do |infected_data|
109
+ infected_stats = {}
110
+ infected_stats['max_damage_per_life'] = infected_data['maxdmg1life'].to_i
111
+ infected_stats['max_pours_interrupted'] = infected_data['maxpoursinterrupted'].to_i
112
+ infected_stats['special_attacks'] = infected_data['specialattacks'].to_i
113
+ @scavenge_stats[:infected][infected_data['name']] = infected_stats
107
114
  end
108
115
  end
109
116
 
@@ -112,19 +112,17 @@ class SteamGroup
112
112
  def fetch_page(page)
113
113
  member_data = parse "#{base_url}/memberslistxml?p=#{page}"
114
114
 
115
- begin
116
- @group_id64 = member_data['groupID64'].to_i if page == 1
117
- @member_count = member_data['memberCount'].to_i
118
- total_pages = member_data['totalPages'].to_i
119
-
120
- member_data['members']['steamID64'].each do |member|
121
- @members << SteamId.new(member.to_i, false)
122
- end
123
- rescue
124
- raise SteamCondenserError, 'XML data could not be parsed.', $!.backtrace
115
+ @group_id64 = member_data['groupID64'].to_i if page == 1
116
+ @member_count = member_data['memberCount'].to_i
117
+ total_pages = member_data['totalPages'].to_i
118
+
119
+ member_data['members']['steamID64'].each do |member|
120
+ @members << SteamId.new(member.to_i, false)
125
121
  end
126
122
 
127
123
  total_pages
124
+ rescue
125
+ raise SteamCondenserError, 'XML data could not be parsed.'
128
126
  end
129
127
 
130
128
  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-2012, Sebastian Staudt
4
+ # Copyright (c) 2008-2013, Sebastian Staudt
5
5
 
6
6
  require 'cgi'
7
7
 
@@ -244,64 +244,55 @@ class SteamId
244
244
  # when it is private
245
245
  # @see Cacheable#fetch
246
246
  def fetch
247
- begin
248
- profile = parse "#{base_url}?xml=1"
247
+ profile = parse "#{base_url}?xml=1"
249
248
 
250
- raise SteamCondenserError, profile['error'] unless profile['error'].nil?
249
+ raise SteamCondenserError, profile['error'] unless profile['error'].nil?
251
250
 
252
- unless profile['privacyMessage'].nil?
253
- raise SteamCondenserError, profile['privacyMessage']
251
+ unless profile['privacyMessage'].nil?
252
+ raise SteamCondenserError, profile['privacyMessage']
253
+ end
254
+
255
+ @nickname = CGI.unescapeHTML profile['steamID']
256
+ @steam_id64 = profile['steamID64'].to_i
257
+ @limited = (profile['isLimitedAccount'].to_i == 1)
258
+ @trade_ban_state = profile['tradeBanState']
259
+ @vac_banned = (profile['vacBanned'].to_i == 1)
260
+
261
+ @image_url = profile['avatarIcon'][0..-5]
262
+ @online_state = profile['onlineState']
263
+ @privacy_state = profile['privacyState']
264
+ @state_message = profile['stateMessage']
265
+ @visibility_state = profile['visibilityState'].to_i
266
+
267
+ if public?
268
+ @custom_url = (profile['customURL'] || '').downcase
269
+ @custom_url = nil if @custom_url.empty?
270
+
271
+ @head_line = CGI.unescapeHTML profile['headline'] || ''
272
+ @hours_played = profile['hoursPlayed2Wk'].to_f
273
+ @location = profile['location']
274
+ @member_since = Time.parse profile['memberSince']
275
+ @real_name = CGI.unescapeHTML profile['realname'] || ''
276
+ @steam_rating = profile['steamRating'].to_f
277
+ @summary = CGI.unescapeHTML profile['summary'] || ''
278
+
279
+ @most_played_games = {}
280
+ [(profile['mostPlayedGames'] || {})['mostPlayedGame']].compact.flatten.each do |most_played_game|
281
+ @most_played_games[most_played_game['gameName']] = most_played_game['hoursPlayed'].to_f
282
+ end
283
+
284
+ @groups = []
285
+ [(profile['groups'] || {})['group']].compact.flatten.each do |group|
286
+ @groups << SteamGroup.new(group['groupID64'].to_i, false)
254
287
  end
255
288
 
256
- @nickname = CGI.unescapeHTML profile['steamID']
257
- @steam_id64 = profile['steamID64'].to_i
258
- @limited = (profile['isLimitedAccount'].to_i == 1)
259
- @trade_ban_state = profile['tradeBanState']
260
- @vac_banned = (profile['vacBanned'].to_i == 1)
261
-
262
- @image_url = profile['avatarIcon'][0..-5]
263
- @online_state = profile['onlineState']
264
- @privacy_state = profile['privacyState']
265
- @state_message = profile['stateMessage']
266
- @visibility_state = profile['visibilityState'].to_i
267
-
268
- if public?
269
- @custom_url = profile['customURL'].downcase rescue ''
270
- @custom_url = nil if @custom_url.empty?
271
-
272
- @head_line = CGI.unescapeHTML profile['headline'] || ''
273
- @hours_played = profile['hoursPlayed2Wk'].to_f
274
- @location = profile['location']
275
- @member_since = Time.parse profile['memberSince']
276
- @real_name = CGI.unescapeHTML profile['realname'] || ''
277
- @steam_rating = profile['steamRating'].to_f
278
- @summary = CGI.unescapeHTML profile['summary'] || ''
279
-
280
- @most_played_games = {}
281
- unless profile['mostPlayedGames'].to_s.strip.empty?
282
- [profile['mostPlayedGames']['mostPlayedGame']].flatten.each do |most_played_game|
283
- @most_played_games[most_played_game['gameName']] = most_played_game['hoursPlayed'].to_f
284
- end
285
- end
286
-
287
- @groups = []
288
- unless profile['groups'].to_s.strip.empty?
289
- [profile['groups']['group']].flatten.each do |group|
290
- @groups << SteamGroup.new(group['groupID64'].to_i, false)
291
- end
292
- end
293
-
294
- @links = {}
295
- unless profile['weblinks'].to_s.strip.empty?
296
- [profile['weblinks']['weblink']].flatten.each do |link|
297
- @links[CGI.unescapeHTML link['title']] = link['link']
298
- end
299
- end
289
+ @links = {}
290
+ [(profile['weblinks'] || {})['weblink']].compact.flatten.each do |link|
291
+ @links[CGI.unescapeHTML link['title']] = link['link']
300
292
  end
301
- rescue
302
- raise $! if $!.is_a? SteamCondenserError
303
- raise SteamCondenserError, 'XML data could not be parsed.', $!.backtrace
304
293
  end
294
+ rescue
295
+ raise SteamCondenserError, 'XML data could not be parsed.'
305
296
  end
306
297
 
307
298
  # Fetches the friends of this user
@@ -328,17 +319,18 @@ class SteamId
328
319
  # @see #games
329
320
  def fetch_games
330
321
  games_data = parse "#{base_url}/games?xml=1"
331
- @games = {}
332
- @playtimes = {}
322
+ @games = {}
323
+ @recent_playtimes = {}
324
+ @total_playtimes = {}
333
325
  games_data['games']['game'].each do |game_data|
334
326
  app_id = game_data['appID'].to_i
335
- game = SteamGame.new app_id, game_data
336
- @games[app_id] = game
327
+ @games[app_id] = SteamGame.new app_id, game_data
337
328
 
338
329
  recent = game_data['hoursLast2Weeks'].to_f
339
330
  total = (game_data['hoursOnRecord'] || '').delete(',').to_f
340
331
 
341
- @playtimes[app_id] = [(recent * 60).to_i, (total * 60).to_i]
332
+ @recent_playtimes[app_id] = (recent * 60).to_i
333
+ @total_playtimes[app_id] = (total * 60).to_i
342
334
  end
343
335
 
344
336
  true
@@ -408,7 +400,7 @@ class SteamId
408
400
  #
409
401
  # @return [Fixnum, String] The 64bit numeric SteamID or the custom URL
410
402
  def id
411
- @custom_url.nil? ? @steam_id64 : @custom_url
403
+ @custom_url || @steam_id64
412
404
  end
413
405
 
414
406
  # Returns whether the owner of this SteamId is playing a game
@@ -457,7 +449,7 @@ class SteamId
457
449
  # the last two weeks
458
450
  def recent_playtime(id)
459
451
  game = find_game id
460
- @playtimes[game.app_id][0]
452
+ @recent_playtimes[game.app_id]
461
453
  end
462
454
 
463
455
  # Returns the total time in minutes this user has played this game
@@ -468,7 +460,7 @@ class SteamId
468
460
  # game
469
461
  def total_playtime(id)
470
462
  game = find_game id
471
- @playtimes[game.app_id][1]
463
+ @total_playtimes[game.app_id]
472
464
  end
473
465
 
474
466
  private
@@ -16,9 +16,12 @@ module XMLData
16
16
  #
17
17
  # @param [String] url The URL to parse
18
18
  # @return [Hash<String, Object>] The data parsed from the XML document
19
+ # @raise [SteamCondenserError] if an error occurs while parsing the XML data
19
20
  def parse(url)
20
21
  data = open(url, { :proxy => true })
21
22
  @xml_data = MultiXml.parse(data).values.first
23
+ rescue
24
+ raise SteamCondenserError.new "XML data could not be parsed: #{$!.message}", $!
22
25
  end
23
26
 
24
27
  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-2011, Sebastian Staudt
4
+ # Copyright (c) 2008-2013, Sebastian Staudt
5
5
 
6
6
  require 'steam/packets/s2a_info_base_packet'
7
7
 
@@ -17,6 +17,12 @@ class S2A_INFO2_Packet
17
17
 
18
18
  include S2A_INFO_BasePacket
19
19
 
20
+ EDF_GAME_ID = 0x01
21
+ EDF_GAME_PORT = 0x80
22
+ EDF_SERVER_ID = 0x10
23
+ EDF_SERVER_TAGS = 0x20
24
+ EDF_SOURCE_TV = 0x40
25
+
20
26
  # Creates a new S2A_INFO2 response object based on the given data
21
27
  #
22
28
  # @param [String] data The raw packet data replied from the server
@@ -24,39 +30,45 @@ class S2A_INFO2_Packet
24
30
  def initialize(data)
25
31
  super S2A_INFO2_HEADER, data
26
32
 
27
- @protocol_version = @content_data.byte
28
- @server_name = @content_data.cstring
29
- @map_name = @content_data.cstring
30
- @game_directory = @content_data.cstring
31
- @game_description = @content_data.cstring
32
- @app_id = @content_data.short
33
- @number_of_players = @content_data.byte
34
- @max_players = @content_data.byte
35
- @number_of_bots = @content_data.byte
36
- @dedicated = @content_data.byte.chr
37
- @operating_system = @content_data.byte.chr
38
- @password_needed = @content_data.byte == 1
39
- @secure = @content_data.byte == 1
40
- @game_version = @content_data.cstring
33
+ info[:protocol_version] = @content_data.byte
34
+ info[:server_name] = @content_data.cstring
35
+ info[:map_name] = @content_data.cstring
36
+ info[:game_directory] = @content_data.cstring
37
+ info[:game_description] = @content_data.cstring
38
+ info[:app_id] = @content_data.short
39
+ info[:number_of_players] = @content_data.byte
40
+ info[:max_players] = @content_data.byte
41
+ info[:number_of_bots] = @content_data.byte
42
+ info[:dedicated] = @content_data.byte.chr
43
+ info[:operating_system] = @content_data.byte.chr
44
+ info[:password_needed] = @content_data.byte == 1
45
+ info[:secure] = @content_data.byte == 1
46
+ info[:game_version] = @content_data.cstring
41
47
 
42
48
  if @content_data.remaining > 0
43
49
  extra_data_flag = @content_data.byte
44
50
 
45
- @server_port = @content_data.short unless extra_data_flag & 0x80 == 0
51
+ if extra_data_flag & EDF_GAME_PORT != 0
52
+ info[:server_port] = @content_data.short
53
+ end
46
54
 
47
- unless extra_data_flag & 0x10 == 0
48
- @server_id = @content_data.long | (@content_data.long << 32)
55
+ if extra_data_flag & EDF_SERVER_ID != 0
56
+ info[:server_id] = @content_data.long | (@content_data.long << 32)
49
57
  end
50
58
 
51
- unless extra_data_flag & 0x40 == 0
52
- @tv_port = @content_data.short
53
- @tv_name = @content_data.cstring
59
+ if extra_data_flag & EDF_SOURCE_TV != 0
60
+ info[:tv_port] = @content_data.short
61
+ info[:tv_name] = @content_data.cstring
54
62
  end
55
63
 
56
- @server_tags = @content_data.cstring unless extra_data_flag & 0x20 == 0
57
- end
64
+ if extra_data_flag & EDF_SERVER_TAGS != 0
65
+ info[:server_tags] = @content_data.cstring
66
+ end
58
67
 
59
- generate_info_hash
68
+ if extra_data_flag & EDF_GAME_ID != 0
69
+ info[:game_id] = @content_data.long | (@content_data.long << 32)
70
+ end
71
+ end
60
72
  end
61
73
 
62
74
  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-2011, Sebastian Staudt
4
+ # Copyright (c) 2008-2013, Sebastian Staudt
5
5
 
6
6
  require 'steam/packets/steam_packet'
7
7
 
@@ -18,18 +18,8 @@ module S2A_INFO_BasePacket
18
18
  # Returns the information provided by the server
19
19
  #
20
20
  # @return [Hash<String, Object>] The information provided by the server
21
- attr_reader :info_hash
22
-
23
- protected
24
-
25
- # Generates a hash of server properties from the instance variables of the
26
- # including packet object
27
- def generate_info_hash
28
- @info_hash = Hash[
29
- *instance_variables.map { |var|
30
- [var[1..-1].to_sym, instance_variable_get(var)] if var != '@content_data' && var != '@header_data'
31
- }.compact.flatten
32
- ]
21
+ def info
22
+ @info ||= {}
33
23
  end
34
24
 
35
25
  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-2011 Sebastian Staudt
4
+ # Copyright (c) 2008-2013, Sebastian Staudt
5
5
 
6
6
  require 'steam/packets/s2a_info_base_packet'
7
7
 
@@ -24,38 +24,36 @@ class S2A_INFO_DETAILED_Packet
24
24
  def initialize(data)
25
25
  super S2A_INFO_DETAILED_HEADER, data
26
26
 
27
- @game_ip = @content_data.cstring
28
- @server_name = @content_data.cstring
29
- @map_name = @content_data.cstring
30
- @game_directory = @content_data.cstring
31
- @game_description = @content_data.cstring
32
- @number_of_players = @content_data.byte
33
- @max_players = @content_data.byte
34
- @network_version = @content_data.byte
35
- @dedicated = @content_data.byte.chr
36
- @operating_system = @content_data.byte.chr
37
- @password_needed = @content_data.byte == 1
38
- @is_mod = @content_data.byte == 1
39
-
40
- if @is_mod
41
- @mod_info = {}
42
- @mod_info[:url_info] = @content_data.cstring
43
- @mod_info[:url_dl] = @content_data.cstring
27
+ info[:game_ip] = @content_data.cstring
28
+ info[:server_name] = @content_data.cstring
29
+ info[:map_name] = @content_data.cstring
30
+ info[:game_directory] = @content_data.cstring
31
+ info[:game_description] = @content_data.cstring
32
+ info[:number_of_players] = @content_data.byte
33
+ info[:max_players] = @content_data.byte
34
+ info[:network_version] = @content_data.byte
35
+ info[:dedicated] = @content_data.byte.chr
36
+ info[:operating_system] = @content_data.byte.chr
37
+ info[:password_needed] = @content_data.byte == 1
38
+ info[:is_mod] = @content_data.byte == 1
39
+
40
+ if info[:is_mod]
41
+ info[:mod_info] = {}
42
+ info[:mod_info][:url_info] = @content_data.cstring
43
+ info[:mod_info][:url_dl] = @content_data.cstring
44
44
  @content_data.byte
45
45
  if @content_data.remaining == 12
46
- @mod_info[:mod_version] = @content_data.long
47
- @mod_info[:mod_size] = @content_data.long
48
- @mod_info[:sv_only] = @content_data.byte == 1
49
- @mod_info[:cl_dll] = @content_data.byte == 1
50
- @secure = @content_data.byte == 1
51
- @number_of_bots = @content_data.byte
46
+ info[:mod_info][:mod_version] = @content_data.long
47
+ info[:mod_info][:mod_size] = @content_data.long
48
+ info[:mod_info][:sv_only] = @content_data.byte == 1
49
+ info[:mod_info][:cl_dll] = @content_data.byte == 1
50
+ info[:secure] = @content_data.byte == 1
51
+ info[:number_of_bots] = @content_data.byte
52
52
  end
53
53
  else
54
- @secure = @content_data.byte == 1
55
- @number_of_bots = @content_data.byte
54
+ info[:secure] = @content_data.byte == 1
55
+ info[:number_of_bots] = @content_data.byte
56
56
  end
57
-
58
- generate_info_hash
59
57
  end
60
58
 
61
59
  end