steam-condenser 0.9.0 → 0.10.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 (49) hide show
  1. data/LICENSE +1 -1
  2. data/README.md +2 -0
  3. data/Rakefile +0 -2
  4. data/VERSION.yml +1 -1
  5. data/lib/abstract_class.rb +1 -3
  6. data/lib/exceptions/buffer_underflow_exception.rb +1 -3
  7. data/lib/exceptions/packet_format_exception.rb +1 -3
  8. data/lib/exceptions/rcon_no_auth_exception.rb +1 -3
  9. data/lib/exceptions/timeout_exception.rb +0 -2
  10. data/lib/steam/community/game_stats.rb +5 -3
  11. data/lib/steam/community/l4d/abstract_l4d_stats.rb +143 -0
  12. data/lib/steam/community/l4d/abstract_l4d_weapon.rb +26 -0
  13. data/lib/steam/community/l4d/l4d2_map.rb +65 -0
  14. data/lib/steam/community/l4d/l4d2_stats.rb +125 -0
  15. data/lib/steam/community/l4d/l4d2_weapon.rb +21 -0
  16. data/lib/steam/community/l4d/l4d_map.rb +2 -0
  17. data/lib/steam/community/l4d/l4d_stats.rb +5 -115
  18. data/lib/steam/community/l4d/l4d_weapon.rb +3 -7
  19. data/lib/steam/community/steam_id.rb +28 -19
  20. data/lib/steam/community/tf2/tf2_class_factory.rb +1 -3
  21. data/lib/steam/community/tf2/tf2_engineer.rb +2 -4
  22. data/lib/steam/community/tf2/tf2_medic.rb +1 -3
  23. data/lib/steam/community/tf2/tf2_sniper.rb +1 -3
  24. data/lib/steam/community/tf2/tf2_spy.rb +1 -3
  25. data/lib/steam/packets/a2a_ack_packet.rb +1 -3
  26. data/lib/steam/packets/a2a_ping_packet.rb +1 -3
  27. data/lib/steam/packets/a2m_get_servers_batch2_packet.rb +0 -2
  28. data/lib/steam/packets/a2s_info_packet.rb +0 -2
  29. data/lib/steam/packets/a2s_player_packet.rb +1 -3
  30. data/lib/steam/packets/a2s_rules_packet.rb +1 -3
  31. data/lib/steam/packets/a2s_serverquery_getchallenge_packet.rb +1 -3
  32. data/lib/steam/packets/m2a_server_batch_packet.rb +1 -3
  33. data/lib/steam/packets/rcon/rcon_auth_request.rb +1 -3
  34. data/lib/steam/packets/rcon/rcon_auth_response.rb +1 -3
  35. data/lib/steam/packets/rcon/rcon_exec_request.rb +1 -3
  36. data/lib/steam/packets/rcon/rcon_goldsrc_request.rb +1 -3
  37. data/lib/steam/packets/rcon/rcon_goldsrc_response.rb +1 -3
  38. data/lib/steam/packets/rcon/rcon_packet.rb +1 -3
  39. data/lib/steam/packets/rcon/rcon_packet_factory.rb +1 -3
  40. data/lib/steam/packets/request_with_challenge.rb +1 -3
  41. data/lib/steam/packets/s2a_info2_packet.rb +1 -3
  42. data/lib/steam/packets/s2a_info_base_packet.rb +2 -0
  43. data/lib/steam/packets/s2a_rules_packet.rb +1 -1
  44. data/lib/steam/packets/s2c_challenge_packet.rb +1 -3
  45. data/lib/steam/packets/steam_packet.rb +15 -16
  46. data/lib/steam/servers/master_server.rb +0 -2
  47. data/lib/steam/servers/source_server.rb +3 -1
  48. data/lib/steam-condenser.rb +2 -0
  49. metadata +21 -19
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2008, Sebastian Staudt
1
+ Copyright (c) 2008-2009, Sebastian Staudt
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without modification,
data/README.md CHANGED
@@ -28,3 +28,5 @@ file.
28
28
  * [GitHub project page](http://github.com/koraktor/steam-condenser)
29
29
  * [Google group](http://groups.google.com/group/steam-condenser)
30
30
  * [Ohloh profile](http://www.ohloh.net/projects/steam-condenser)
31
+
32
+ Follow Steam Condenser on Twitter [@steamcondenser](http://twitter.com/steamcondenser).
data/Rakefile CHANGED
@@ -23,8 +23,6 @@ Jeweler::Tasks.new do |s|
23
23
 
24
24
  s.files = %w(README.md Rakefile LICENSE VERSION.yml) + src_files + test_files
25
25
  s.rdoc_options = ["--all", "--inline-source", "--line-numbers", "--charset=utf-8", "--webcvs=http://github.com/koraktor/steam-condenser/source/blob/master/ruby/%s"]
26
-
27
- s.add_dependency('hpricot', '>= 0.6')
28
26
  end
29
27
 
30
28
  # Create a rake task +:rdoc+ to build the documentation
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 0
3
- :minor: 9
3
+ :minor: 10
4
4
  :patch: 0
@@ -1,9 +1,7 @@
1
1
  # This code is free software; you can redistribute it and/or modify it under the
2
2
  # terms of the new BSD License.
3
3
  #
4
- # Copyright (c) 2008, Sebastian Staudt
5
- #
6
- # $Id$
4
+ # Copyright (c) 2008-2009, Sebastian Staudt
7
5
 
8
6
  # This module is used to mimic the behavior of abstract classes known from other
9
7
  # object-oriented programming languages
@@ -1,9 +1,7 @@
1
1
  # This code is free software; you can redistribute it and/or modify it under the
2
2
  # terms of the new BSD License.
3
3
  #
4
- # Copyright (c) 2008, Sebastian Staudt
5
- #
6
- # $Id$
4
+ # Copyright (c) 2008-2009, Sebastian Staudt
7
5
 
8
6
  class BufferUnderflowException < Exception
9
7
 
@@ -1,9 +1,7 @@
1
1
  # This code is free software; you can redistribute it and/or modify it under the
2
2
  # terms of the new BSD License.
3
3
  #
4
- # Copyright (c) 2008, Sebastian Staudt
5
- #
6
- # $Id$
4
+ # Copyright (c) 2008-2009, Sebastian Staudt
7
5
 
8
6
  require "exceptions/steam_condenser_exception"
9
7
 
@@ -1,9 +1,7 @@
1
1
  # This code is free software; you can redistribute it and/or modify it under the
2
2
  # terms of the new BSD License.
3
3
  #
4
- # Copyright (c) 2008, Sebastian Staudt
5
- #
6
- # $Id$
4
+ # Copyright (c) 2008-2009, Sebastian Staudt
7
5
 
8
6
  class RCONNoAuthException < Exception
9
7
 
@@ -2,8 +2,6 @@
2
2
  # terms of the new BSD License.
3
3
  #
4
4
  # Copyright (c) 2008-2009, Sebastian Staudt
5
- #
6
- # $Id$
7
5
 
8
6
  class TimeoutException < StandardError
9
7
 
@@ -14,6 +14,7 @@ end
14
14
  require 'steam/community/defense_grid/defense_grid_stats'
15
15
  require "steam/community/dods/dods_stats"
16
16
  require "steam/community/l4d/l4d_stats"
17
+ require "steam/community/l4d/l4d2_stats"
17
18
  require "steam/community/tf2/tf2_stats"
18
19
 
19
20
  # The GameStats class represents the game statistics for a single user and a
@@ -35,6 +36,8 @@ class GameStats
35
36
  DoDSStats.new(steam_id)
36
37
  when 'l4d'
37
38
  L4DStats.new(steam_id)
39
+ when 'l4d2'
40
+ L4D2Stats.new(steam_id)
38
41
  when 'tf2'
39
42
  TF2Stats.new(steam_id)
40
43
  else
@@ -42,8 +45,8 @@ class GameStats
42
45
  end
43
46
  end
44
47
 
45
- # Creates a GameStats object and fetchs data from Steam Community for the
46
- # given user and game
48
+ # Creates a GameStats object and fetches data from the Steam Community for
49
+ # the given user and game
47
50
  def initialize(id, game_name)
48
51
  if id.is_a? Numeric
49
52
  @steam_id64 = id
@@ -58,7 +61,6 @@ class GameStats
58
61
  @privacy_state = @xml_data.elements['privacyState'].text
59
62
  if public?
60
63
  @app_id = @xml_data.elements['game/gameLink'].text.match(/http:\/\/store.steampowered.com\/app\/([1-9][0-9]+)/)[1]
61
- @game_friendly_name = @xml_data.elements['game/gameFriendlyName'].text
62
64
  @game_name = @xml_data.elements['game/gameName'].text
63
65
  @hours_played = @xml_data.elements['stats/hoursPlayed'].text
64
66
  end
@@ -0,0 +1,143 @@
1
+ # This code is free software; you can redistribute it and/or modify it under the
2
+ # terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2009, Sebastian Staudt
5
+
6
+ require 'abstract_class'
7
+ require 'steam/community/game_stats'
8
+
9
+ # AbstractL4DStats is an abstract base class for statistics for Left4Dead and
10
+ # Left4Dead 2. As both games have more or less the same statistics available in
11
+ # the Steam Community the code for both is pretty much the same.
12
+ class AbstractL4DStats < GameStats
13
+
14
+ include AbstractClass
15
+
16
+ SPECIAL_INFECTED = %w(boomer hunter smoker tank)
17
+
18
+ def initialize(steam_id, game_name)
19
+ super steam_id, game_name
20
+
21
+ if public?
22
+ @most_recent_game = {}
23
+ if @xml_data.elements['stats/mostrecentgame'].has_elements?
24
+ @most_recent_game['difficulty'] = @xml_data.elements['stats/mostrecentgame/difficulty'].text
25
+ @most_recent_game['escaped'] = (@xml_data.elements['stats/mostrecentgame/bEscaped'].text == 1)
26
+ @most_recent_game['movie'] = @xml_data.elements['stats/mostrecentgame/movie'].text
27
+ @most_recent_game['time_played'] = @xml_data.elements['stats/mostrecentgame/time'].text
28
+ end
29
+ end
30
+ end
31
+
32
+ # Returns a Hash of favorites for this user like weapons and character.
33
+ # If the favorites haven't been parsed already, parsing is done now.
34
+ def favorites
35
+ return unless public?
36
+
37
+ if @favorites.nil?
38
+ @favorites = {}
39
+ @favorites['campaign'] = @xml_data.elements['stats/favorites/campaign'].text
40
+ @favorites['campaign_percentage'] = @xml_data.elements['stats/favorites/campaignpct'].text.to_i
41
+ @favorites['character'] = @xml_data.elements['stats/favorites/character'].text
42
+ @favorites['character_percentage'] = @xml_data.elements['stats/favorites/characterpct'].text.to_i
43
+ @favorites['level1_weapon'] = @xml_data.elements['stats/favorites/weapon1'].text
44
+ @favorites['level1_weapon_percentage'] = @xml_data.elements['stats/favorites/weapon1pct'].text.to_i
45
+ @favorites['level2_weapon'] = @xml_data.elements['stats/favorites/weapon2'].text
46
+ @favorites['level2_weapon_percentage'] = @xml_data.elements['stats/favorites/weapon2pct'].text.to_i
47
+ end
48
+
49
+ @favorites
50
+ end
51
+
52
+ # Returns a Hash of lifetime statistics for this user like the time played.
53
+ # If the lifetime statistics haven't been parsed already, parsing is done now.
54
+ def lifetime_stats
55
+ return unless public?
56
+
57
+ if @lifetime_stats.nil?
58
+ @lifetime_stats = {}
59
+ @lifetime_stats['finales_survived'] = @xml_data.elements['stats/lifetime/finales'].text.to_i
60
+ @lifetime_stats['games_played'] = @xml_data.elements['stats/lifetime/gamesplayed'].text.to_i
61
+ @lifetime_stats['finales_survived_percentage'] = @lifetime_stats['finales_survived'].to_f / @lifetime_stats['games_played']
62
+ @lifetime_stats['infected_killed'] = @xml_data.elements['stats/lifetime/infectedkilled'].text.to_i
63
+ @lifetime_stats['kills_per_hour'] = @xml_data.elements['stats/lifetime/killsperhour'].text.to_f
64
+ @lifetime_stats['avg_kits_shared'] = @xml_data.elements['stats/lifetime/kitsshared'].text.to_f
65
+ @lifetime_stats['avg_kits_used'] = @xml_data.elements['stats/lifetime/kitsused'].text.to_f
66
+ @lifetime_stats['avg_pills_shared'] = @xml_data.elements['stats/lifetime/pillsshared'].text.to_f
67
+ @lifetime_stats['avg_pills_used'] = @xml_data.elements['stats/lifetime/pillsused'].text.to_f
68
+ @lifetime_stats['time_played'] = @xml_data.elements['stats/lifetime/timeplayed'].text
69
+ end
70
+
71
+ @lifetime_stats
72
+ end
73
+
74
+ # Returns a Hash of Survival statistics for this user like revived teammates.
75
+ # If the Survival statistics haven't been parsed already, parsing is done now.
76
+ def survival_stats
77
+ return unless public?
78
+
79
+ if @survival_stats.nil?
80
+ @survival_stats = {}
81
+ @survival_stats['gold_medals'] = @xml_data.elements['stats/survival/goldmedals'].text.to_i
82
+ @survival_stats['silver_medals'] = @xml_data.elements['stats/survival/silvermedals'].text.to_i
83
+ @survival_stats['bronze_medals'] = @xml_data.elements['stats/survival/bronzemedals'].text.to_i
84
+ @survival_stats['rounds_played'] = @xml_data.elements['stats/survival/roundsplayed'].text.to_i
85
+ @survival_stats['best_time'] = @xml_data.elements['stats/survival/besttime'].text.to_f
86
+ end
87
+
88
+ @survival_stats
89
+ end
90
+
91
+ # Returns a Hash of teamplay statistics for this user like revived teammates.
92
+ # If the teamplay statistics haven't been parsed already, parsing is done now.
93
+ def teamplay_stats
94
+ return unless public?
95
+
96
+ if @teamplay_stats.nil?
97
+ @teamplay_stats = {}
98
+ @teamplay_stats['revived'] = @xml_data.elements['stats/teamplay/revived'].text.to_i
99
+ @teamplay_stats['most_revived_difficulty'] = @xml_data.elements['stats/teamplay/reviveddiff'].text
100
+ @teamplay_stats['avg_revived'] = @xml_data.elements['stats/teamplay/revivedavg'].text.to_f
101
+ @teamplay_stats['avg_was_revived'] = @xml_data.elements['stats/teamplay/wasrevivedavg'].text.to_f
102
+ @teamplay_stats['protected'] = @xml_data.elements['stats/teamplay/protected'].text.to_i
103
+ @teamplay_stats['most_protected_difficulty'] = @xml_data.elements['stats/teamplay/protecteddiff'].text
104
+ @teamplay_stats['avg_protected'] = @xml_data.elements['stats/teamplay/protectedavg'].text.to_f
105
+ @teamplay_stats['avg_was_protected'] = @xml_data.elements['stats/teamplay/wasprotectedavg'].text.to_f
106
+ @teamplay_stats['friendly_fire_damage'] = @xml_data.elements['stats/teamplay/ffdamage'].text.to_i
107
+ @teamplay_stats['most_friendly_fire_difficulty'] = @xml_data.elements['stats/teamplay/ffdamagediff'].text
108
+ @teamplay_stats['avg_friendly_fire_damage'] = @xml_data.elements['stats/teamplay/ffdamageavg'].text.to_f
109
+ end
110
+
111
+ @teamplay_stats
112
+ end
113
+
114
+ # Returns a Hash of Versus statistics for this user like percentage of rounds
115
+ # won.
116
+ # If the Versus statistics haven't been parsed already, parsing is done now.
117
+ def versus_stats
118
+ return unless public?
119
+
120
+ if @versus_stats.nil?
121
+ @versus_stats = {}
122
+ @versus_stats['games_played'] = @xml_data.elements['stats/versus/gamesplayed'].text.to_i
123
+ @versus_stats['games_completed'] = @xml_data.elements['stats/versus/gamescompleted'].text.to_i
124
+ @versus_stats['finales_survived'] = @xml_data.elements['stats/versus/finales'].text.to_i
125
+ @versus_stats['finales_survived_percentage'] = @versus_stats['finales_survived'].to_f / @versus_stats['games_played']
126
+ @versus_stats['points'] = @xml_data.elements['stats/versus/points'].text.to_i
127
+ @versus_stats['most_points_infected'] = @xml_data.elements['stats/versus/pointsas'].text
128
+ @versus_stats['games_won'] = @xml_data.elements['stats/versus/gameswon'].text.to_i
129
+ @versus_stats['games_lost'] = @xml_data.elements['stats/versus/gameslost'].text.to_i
130
+ @versus_stats['highest_survivor_score'] = @xml_data.elements['stats/versus/survivorscore'].text.to_i
131
+
132
+ self.class.const_get(:SPECIAL_INFECTED).each do |infected|
133
+ @versus_stats[infected] = {}
134
+ @versus_stats[infected]['special_attacks'] = @xml_data.elements["stats/versus/#{infected}special"].text.to_i
135
+ @versus_stats[infected]['most_damage'] = @xml_data.elements["stats/versus/#{infected}dmg"].text.to_i
136
+ @versus_stats[infected]['avg_lifespan'] = @xml_data.elements["stats/versus/#{infected}lifespan"].text.to_i
137
+ end
138
+ end
139
+
140
+ @versus_stats
141
+ end
142
+
143
+ end
@@ -0,0 +1,26 @@
1
+ # This code is free software; you can redistribute it and/or modify it under the
2
+ # terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2009-2010, Sebastian Staudt
5
+
6
+ require 'abstract_class'
7
+ require 'steam/community/game_weapon'
8
+
9
+ class AbstractL4DWeapon < GameWeapon
10
+
11
+ include AbstractClass
12
+
13
+ attr_reader :accuracy, :headshots_percentage, :kill_percentage
14
+
15
+ # Abstract base constructor which parses common data for both, L4DWeapon and
16
+ # L4D2Weapon
17
+ def initialize(weapon_data)
18
+ super weapon_data
19
+
20
+ @accuracy = weapon_data.elements['accuracy'].text
21
+ @headshots_percentage = weapon_data.elements['headshots'].text
22
+ @id = weapon_data.name
23
+ @shots = weapon_data.elements['shots'].text.to_i
24
+ end
25
+
26
+ end
@@ -0,0 +1,65 @@
1
+ # This code is free software; you can redistribute it and/or modify it under the
2
+ # terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2009-2010, Sebastian Staudt
5
+
6
+ require 'steam/community/steam_id'
7
+ require 'steam/community/l4d/l4d_map'
8
+
9
+ # L4D2Map holds statistical information about maps played by a player in
10
+ # Survival mode of Left4Dead 2. The basic information provided is more or less
11
+ # the same for Left4Dead and Left4Dead 2, but parsing has to be done
12
+ # differently.
13
+ class L4D2Map < L4DMap
14
+
15
+ attr_reader :items, :kills, :teammates
16
+
17
+ INFECTED = %w{boomer charger common hunter jockey smoker spitter tank}
18
+ ITEMS = %w{adrenaline defibs medkits pills}
19
+
20
+ # Creates a new instance of L4D2Map based on the assigned XML data
21
+ #
22
+ # The map statistics for the Survival mode of Left4Dead 2 hold much more
23
+ # information than those for Left4Dead, e.g. the teammates and items are
24
+ # listed.
25
+ def initialize(map_data)
26
+ @id = map_data.elements['img'].text.match(/http:\/\/steamcommunity\.com\/public\/images\/gamestats\/550\/(.*).jpg/)[1]
27
+ @name = map_data.elements['name'].text
28
+ @played = (map_data.elements['hasPlayed'].text.to_i == 1)
29
+
30
+ if @played
31
+ @best_time = map_data.elements['besttimemilliseconds'].text.to_f / 1000
32
+
33
+ @teammates = []
34
+ map_data.elements.each('teammates/steamID64') do |teammate|
35
+ @teammates << SteamId.new(teammate.text, false)
36
+ end
37
+
38
+ @items = {}
39
+ ITEMS.each do |item|
40
+ @items[item] = map_data.elements["items_#{item}"].text.to_i
41
+ end
42
+
43
+ @kills = {}
44
+ INFECTED.each do |infected|
45
+ @kills[infected] = map_data.elements["kills_#{infected}"].text.to_i
46
+ end
47
+
48
+ case map_data.elements['medal'].text
49
+ when 'gold'
50
+ @medal = L4D2Map::GOLD
51
+ when 'silver'
52
+ @medal = L4D2Map::SILVER
53
+ when 'bronze'
54
+ @medal = L4D2Map::BRONZE
55
+ else
56
+ @medal = L4D2Map::NONE
57
+ end
58
+ end
59
+ end
60
+
61
+ def played?
62
+ @played
63
+ end
64
+
65
+ end
@@ -0,0 +1,125 @@
1
+ # This code is free software; you can redistribute it and/or modify it under the
2
+ # terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2009-2010, Sebastian Staudt
5
+
6
+ require 'steam/community/l4d/abstract_l4d_stats'
7
+ require 'steam/community/l4d/l4d2_map'
8
+ require 'steam/community/l4d/l4d2_weapon'
9
+
10
+ class L4D2Stats < AbstractL4DStats
11
+
12
+ SPECIAL_INFECTED = SPECIAL_INFECTED + %w{charger jockey spitter}
13
+
14
+ # Creates a L4D2Stats object by calling the super constructor with the game
15
+ # name "l4d2"
16
+ def initialize(steam_id)
17
+ super steam_id, 'l4d2'
18
+ end
19
+
20
+ # Returns a Hash of lifetime statistics for this user like the time played.
21
+ # If the lifetime statistics haven't been parsed already, parsing is done now.
22
+ #
23
+ # There are only a few additional lifetime statistics for Left4Dead 2 which
24
+ # are not generated for Left4Dead, so this calls
25
+ # AbstractL4DStats#lifetime_stats first and adds some additional stats.
26
+ def lifetime_stats
27
+ return unless public?
28
+
29
+ if @lifetime_stats.nil?
30
+ super
31
+ @lifetime_stats['avg_adrenaline_shared'] = @xml_data.elements['stats/lifetime/adrenalineshared'].text.to_f
32
+ @lifetime_stats['avg_adrenaline_used'] = @xml_data.elements['stats/lifetime/adrenalineused'].text.to_f
33
+ @lifetime_stats['avg_defibrillators_used'] = @xml_data.elements['stats/lifetime/defibrillatorsused'].text.to_f
34
+ end
35
+
36
+ @lifetime_stats
37
+ end
38
+
39
+ # Returns a Hash of Scavenge statistics for this user like the number of
40
+ # Scavenge rounds played.
41
+ # If the Scavenge statistics haven't been parsed already, parsing is done now.
42
+ def scavenge_stats
43
+ return unless public?
44
+
45
+ if @scavenge_stats.nil?
46
+ @scavenge_stats = {}
47
+ @scavenge_stats['avg_cans_per_round'] = @xml_data.elements['stats/scavenge/avgcansperround'].text.to_f
48
+ @scavenge_stats['perfect_rounds'] = @xml_data.elements['stats/scavenge/perfect16canrounds'].text.to_i
49
+ @scavenge_stats['rounds_lost'] = @xml_data.elements['stats/scavenge/roundslost'].text.to_i
50
+ @scavenge_stats['rounds_played'] = @xml_data.elements['stats/scavenge/roundsplayed'].text.to_i
51
+ @scavenge_stats['rounds_won'] = @xml_data.elements['stats/scavenge/roundswon'].text.to_i
52
+ @scavenge_stats['total_cans'] = @xml_data.elements['stats/scavenge/totalcans'].text.to_i
53
+
54
+ @scavenge_stats['maps'] = {}
55
+ @xml_data.elements.each('stats/scavenge/mapstats/map') do |map_data|
56
+ map_id = map_data.elements['name'].text
57
+ @scavenge_stats['maps'][map_id] = {}
58
+ @scavenge_stats['maps'][map_id]['avg_round_score'] = map_data.elements['avgscoreperround'].text.to_i
59
+ @scavenge_stats['maps'][map_id]['highest_game_score'] = map_data.elements['highgamescore'].text.to_i
60
+ @scavenge_stats['maps'][map_id]['highest_round_score'] = map_data.elements['highroundscore'].text.to_i
61
+ @scavenge_stats['maps'][map_id]['name'] = map_data.elements['fullname'].text
62
+ @scavenge_stats['maps'][map_id]['rounds_played'] = map_data.elements['roundsplayed'].text.to_i
63
+ @scavenge_stats['maps'][map_id]['rounds_won'] = map_data.elements['roundswon'].text.to_i
64
+ end
65
+
66
+ @scavenge_stats['infected'] = {}
67
+ @xml_data.elements.each('stats/scavenge/infectedstats/special') do |infected_data|
68
+ infected_id = infected_data.elements['name'].text
69
+ @scavenge_stats['infected'][infected_id] = {}
70
+ @scavenge_stats['infected'][infected_id]['max_damage_per_life'] = infected_data.elements['maxdmg1life'].text.to_i
71
+ @scavenge_stats['infected'][infected_id]['max_pours_interrupted'] = infected_data.elements['maxpoursinterrupted'].text.to_i
72
+ @scavenge_stats['infected'][infected_id]['special_attacks'] = infected_data.elements['specialattacks'].text.to_i
73
+ end
74
+ end
75
+
76
+ @scavenge_stats
77
+ end
78
+
79
+ # Returns a Hash of Survival statistics for this user like revived teammates.
80
+ # If the Survival statistics haven't been parsed already, parsing is done now.
81
+ #
82
+ # The XML layout for the Survival statistics for Left4Dead 2 differs a bit
83
+ # from Left4Dead's Survival statistics. So we have to use a different way of
84
+ # parsing for the maps and we use a different map class (L4D2Map) which holds
85
+ # the additional information provided in Left4Dead 2's statistics.
86
+ def survival_stats
87
+ return unless public?
88
+
89
+ if @survival_stats.nil?
90
+ super
91
+ @survival_stats['maps'] = {}
92
+ @xml_data.elements.each('stats/survival/maps/map') do |map_data|
93
+ map = L4D2Map.new(map_data)
94
+ @survival_stats['maps'][map.id] = map
95
+ end
96
+ end
97
+
98
+ @survival_stats
99
+ end
100
+
101
+ # Returns a Hash of L4D2Weapon for this user containing all Left4Dead 2
102
+ # weapons.
103
+ # If the weapons haven't been parsed already, parsing is done now.
104
+ def weapon_stats
105
+ return unless public?
106
+
107
+ if @weapon_stats.nil?
108
+ @weapon_stats = {}
109
+ @xml_data.elements.each('stats/weapons/*') do |weapon_data|
110
+ next unless weapon_data.has_elements?
111
+
112
+ unless %w{bilejars molotov pipes}.include? weapon_data.name
113
+ weapon = L4D2Weapon.new(weapon_data)
114
+ else
115
+ weapon = L4DExplosive.new(weapon_data)
116
+ end
117
+
118
+ @weapon_stats[weapon_data.name] = weapon
119
+ end
120
+ end
121
+
122
+ @weapon_stats
123
+ end
124
+
125
+ end
@@ -0,0 +1,21 @@
1
+ # This code is free software; you can redistribute it and/or modify it under the
2
+ # terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2009, Sebastian Staudt
5
+
6
+ require 'steam/community/l4d/abstract_l4d_weapon'
7
+
8
+ class L4D2Weapon < AbstractL4DWeapon
9
+
10
+ attr_reader :damage, :weapon_group
11
+
12
+ # Creates a new instance of L4D2Weapon based on the assigned XML data
13
+ def initialize(weapon_data)
14
+ super weapon_data
15
+
16
+ @damage = weapon_data.elements['damage'].text.to_i
17
+ @kill_percentage = weapon_data.elements['pctkills'].text
18
+ @weapon_group = weapon_data.attribute('group')
19
+ end
20
+
21
+ end
@@ -3,6 +3,8 @@
3
3
  #
4
4
  # Copyright (c) 2009, Sebastian Staudt
5
5
 
6
+ # L4DMap holds statistical information about maps played by a player in
7
+ # Survival mode of Left4Dead.
6
8
  class L4DMap
7
9
 
8
10
  attr_reader :best_time, :id, :medal, :name, :times_played