steam-condenser 0.9.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/README.md +2 -0
- data/Rakefile +0 -2
- data/VERSION.yml +1 -1
- data/lib/abstract_class.rb +1 -3
- data/lib/exceptions/buffer_underflow_exception.rb +1 -3
- data/lib/exceptions/packet_format_exception.rb +1 -3
- data/lib/exceptions/rcon_no_auth_exception.rb +1 -3
- data/lib/exceptions/timeout_exception.rb +0 -2
- data/lib/steam/community/game_stats.rb +5 -3
- data/lib/steam/community/l4d/abstract_l4d_stats.rb +143 -0
- data/lib/steam/community/l4d/abstract_l4d_weapon.rb +26 -0
- data/lib/steam/community/l4d/l4d2_map.rb +65 -0
- data/lib/steam/community/l4d/l4d2_stats.rb +125 -0
- data/lib/steam/community/l4d/l4d2_weapon.rb +21 -0
- data/lib/steam/community/l4d/l4d_map.rb +2 -0
- data/lib/steam/community/l4d/l4d_stats.rb +5 -115
- data/lib/steam/community/l4d/l4d_weapon.rb +3 -7
- data/lib/steam/community/steam_id.rb +28 -19
- data/lib/steam/community/tf2/tf2_class_factory.rb +1 -3
- data/lib/steam/community/tf2/tf2_engineer.rb +2 -4
- data/lib/steam/community/tf2/tf2_medic.rb +1 -3
- data/lib/steam/community/tf2/tf2_sniper.rb +1 -3
- data/lib/steam/community/tf2/tf2_spy.rb +1 -3
- data/lib/steam/packets/a2a_ack_packet.rb +1 -3
- data/lib/steam/packets/a2a_ping_packet.rb +1 -3
- data/lib/steam/packets/a2m_get_servers_batch2_packet.rb +0 -2
- data/lib/steam/packets/a2s_info_packet.rb +0 -2
- data/lib/steam/packets/a2s_player_packet.rb +1 -3
- data/lib/steam/packets/a2s_rules_packet.rb +1 -3
- data/lib/steam/packets/a2s_serverquery_getchallenge_packet.rb +1 -3
- data/lib/steam/packets/m2a_server_batch_packet.rb +1 -3
- data/lib/steam/packets/rcon/rcon_auth_request.rb +1 -3
- data/lib/steam/packets/rcon/rcon_auth_response.rb +1 -3
- data/lib/steam/packets/rcon/rcon_exec_request.rb +1 -3
- data/lib/steam/packets/rcon/rcon_goldsrc_request.rb +1 -3
- data/lib/steam/packets/rcon/rcon_goldsrc_response.rb +1 -3
- data/lib/steam/packets/rcon/rcon_packet.rb +1 -3
- data/lib/steam/packets/rcon/rcon_packet_factory.rb +1 -3
- data/lib/steam/packets/request_with_challenge.rb +1 -3
- data/lib/steam/packets/s2a_info2_packet.rb +1 -3
- data/lib/steam/packets/s2a_info_base_packet.rb +2 -0
- data/lib/steam/packets/s2a_rules_packet.rb +1 -1
- data/lib/steam/packets/s2c_challenge_packet.rb +1 -3
- data/lib/steam/packets/steam_packet.rb +15 -16
- data/lib/steam/servers/master_server.rb +0 -2
- data/lib/steam/servers/source_server.rb +3 -1
- data/lib/steam-condenser.rb +2 -0
- metadata +21 -19
data/LICENSE
CHANGED
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
data/lib/abstract_class.rb
CHANGED
@@ -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
|
|
@@ -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
|
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
|