steam-condenser 1.3.2 → 1.3.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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