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.
- 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
|