steam-condenser 0.8.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 +25 -0
- data/README.md +30 -0
- data/Rakefile +42 -0
- data/lib/abstract_class.rb +40 -0
- data/lib/byte_buffer.rb +126 -0
- data/lib/datagram_channel.rb +70 -0
- data/lib/exceptions/buffer_underflow_exception.rb +10 -0
- data/lib/exceptions/packet_format_exception.rb +12 -0
- data/lib/exceptions/rcon_no_auth_exception.rb +14 -0
- data/lib/exceptions/steam_condenser_exception.rb +8 -0
- data/lib/exceptions/timeout_exception.rb +10 -0
- data/lib/socket_channel.rb +54 -0
- data/lib/steam-condenser.rb +3 -0
- data/lib/steam/community/dods/dods_class.rb +32 -0
- data/lib/steam/community/dods/dods_stats.rb +47 -0
- data/lib/steam/community/dods/dods_weapon.rb +54 -0
- data/lib/steam/community/game_achievement.rb +26 -0
- data/lib/steam/community/game_class.rb +15 -0
- data/lib/steam/community/game_stats.rb +92 -0
- data/lib/steam/community/game_weapon.rb +29 -0
- data/lib/steam/community/l4d/l4d_explosive.rb +23 -0
- data/lib/steam/community/l4d/l4d_map.rb +34 -0
- data/lib/steam/community/l4d/l4d_stats.rb +166 -0
- data/lib/steam/community/l4d/l4d_weapon.rb +23 -0
- data/lib/steam/community/steam_group.rb +16 -0
- data/lib/steam/community/steam_id.rb +212 -0
- data/lib/steam/community/tf2/tf2_class.rb +31 -0
- data/lib/steam/community/tf2/tf2_class_factory.rb +38 -0
- data/lib/steam/community/tf2/tf2_engineer.rb +25 -0
- data/lib/steam/community/tf2/tf2_medic.rb +22 -0
- data/lib/steam/community/tf2/tf2_sniper.rb +20 -0
- data/lib/steam/community/tf2/tf2_spy.rb +23 -0
- data/lib/steam/community/tf2/tf2_stats.rb +39 -0
- data/lib/steam/packets/a2a_ack_packet.rb +21 -0
- data/lib/steam/packets/a2a_ping_packet.rb +18 -0
- data/lib/steam/packets/a2m_get_servers_batch2_packet.rb +25 -0
- data/lib/steam/packets/a2s_info_packet.rb +18 -0
- data/lib/steam/packets/a2s_player_packet.rb +22 -0
- data/lib/steam/packets/a2s_rules_packet.rb +21 -0
- data/lib/steam/packets/a2s_serverquery_getchallenge_packet.rb +18 -0
- data/lib/steam/packets/m2a_server_batch_packet.rb +37 -0
- data/lib/steam/packets/rcon/rcon_auth_request.rb +16 -0
- data/lib/steam/packets/rcon/rcon_auth_response.rb +16 -0
- data/lib/steam/packets/rcon/rcon_exec_request.rb +16 -0
- data/lib/steam/packets/rcon/rcon_exec_response.rb +20 -0
- data/lib/steam/packets/rcon/rcon_goldsrc_request.rb +20 -0
- data/lib/steam/packets/rcon/rcon_goldsrc_response.rb +20 -0
- data/lib/steam/packets/rcon/rcon_packet.rb +36 -0
- data/lib/steam/packets/rcon/rcon_packet_factory.rb +37 -0
- data/lib/steam/packets/request_with_challenge.rb +16 -0
- data/lib/steam/packets/s2a_info2_packet.rb +48 -0
- data/lib/steam/packets/s2a_info_base_packet.rb +29 -0
- data/lib/steam/packets/s2a_info_detailed_packet.rb +50 -0
- data/lib/steam/packets/s2a_player_packet.rb +32 -0
- data/lib/steam/packets/s2a_rules_packet.rb +33 -0
- data/lib/steam/packets/s2c_challenge_packet.rb +23 -0
- data/lib/steam/packets/steam_packet.rb +48 -0
- data/lib/steam/packets/steam_packet_factory.rb +90 -0
- data/lib/steam/servers/game_server.rb +222 -0
- data/lib/steam/servers/goldsrc_server.rb +36 -0
- data/lib/steam/servers/master_server.rb +60 -0
- data/lib/steam/servers/source_server.rb +65 -0
- data/lib/steam/sockets/goldsrc_socket.rb +108 -0
- data/lib/steam/sockets/master_server_socket.rb +20 -0
- data/lib/steam/sockets/rcon_socket.rb +50 -0
- data/lib/steam/sockets/source_socket.rb +72 -0
- data/lib/steam/sockets/steam_socket.rb +63 -0
- data/lib/steam/steam_player.rb +51 -0
- data/test/query_tests.rb +71 -0
- data/test/rcon_tests.rb +79 -0
- data/test/steam_community_tests.rb +36 -0
- metadata +132 -0
@@ -0,0 +1,32 @@
|
|
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/game_class'
|
7
|
+
|
8
|
+
# Represents the stats for a DoD:S class for a specific user
|
9
|
+
class DoDSClass < GameClass
|
10
|
+
|
11
|
+
attr_reader :blocks, :bombs_defused, :bombs_planted, :captures, :deaths,
|
12
|
+
:dominations, :key, :kills, :name, :rounds_lost, :rounds_won,
|
13
|
+
:revenges
|
14
|
+
|
15
|
+
# Creates a new instance of DoDSClass based on the assigned XML data
|
16
|
+
def initialize(class_data)
|
17
|
+
@blocks = class_data.elements['blocks'].text.to_i
|
18
|
+
@bombs_defused = class_data.elements['bombsdefused'].text.to_i
|
19
|
+
@bombs_planted = class_data.elements['bombsplanted'].text.to_i
|
20
|
+
@captures = class_data.elements['captures'].text.to_i
|
21
|
+
@deaths = class_data.elements['deaths'].text.to_i
|
22
|
+
@dominations = class_data.elements['dominations'].text.to_i
|
23
|
+
@key = class_data.attributes['key']
|
24
|
+
@kills = class_data.elements['kills'].text.to_i
|
25
|
+
@name = class_data.elements["name"].text
|
26
|
+
@play_time = class_data.elements["playtime"].text.to_i
|
27
|
+
@rounds_lost = class_data.elements['roundslost'].text.to_i
|
28
|
+
@rounds_won = class_data.elements['roundswon'].text.to_i
|
29
|
+
@revenges = class_data.elements['revenges'].text.to_i
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,47 @@
|
|
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/dods/dods_weapon'
|
7
|
+
require 'steam/community/game_stats'
|
8
|
+
|
9
|
+
class DoDSStats < GameStats
|
10
|
+
|
11
|
+
# Creates a DoDSStats object by calling the super constructor with the game
|
12
|
+
# name "DoD:S"
|
13
|
+
def initialize(steam_id)
|
14
|
+
super steam_id, 'DoD:S'
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns a Hash of DoDSClass for this user containing all DoD:S classes.
|
18
|
+
# If the classes haven't been parsed already, parsing is done now.
|
19
|
+
def class_stats
|
20
|
+
return unless public?
|
21
|
+
|
22
|
+
if @class_stats.nil?
|
23
|
+
@class_stats = {}
|
24
|
+
@xml_data.elements.each('stats/classes/class') do |class_data|
|
25
|
+
@class_stats[class_data.attributes["key"]] = DoDSClass.new class_data
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
@class_stats
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns a Hash of DoDSWeapon for this user containing all DoD:S weapons.
|
33
|
+
# If the weapons haven't been parsed already, parsing is done now.
|
34
|
+
def weapon_stats
|
35
|
+
return unless public?
|
36
|
+
|
37
|
+
if @weapon_stats.nil?
|
38
|
+
@weapon_stats = {}
|
39
|
+
@xml_data.elements.each('stats/weapons/weapon') do |weapon_data|
|
40
|
+
@weapon_stats[weapon_data.attributes['key']] = DoDSWeapon.new(weapon_data)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
@weapon_stats
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,54 @@
|
|
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/game_weapon'
|
7
|
+
|
8
|
+
# Represents the stats for a Day of Defeat: Source weapon for a specific user
|
9
|
+
class DoDSWeapon < GameWeapon
|
10
|
+
|
11
|
+
attr_reader :headshots, :name, :hits
|
12
|
+
|
13
|
+
# Creates a new instance of DoDSWeapon based on the assigned XML data
|
14
|
+
def initialize(weapon_data)
|
15
|
+
super weapon_data
|
16
|
+
|
17
|
+
@headshots = weapon_data.elements['headshots'].text.to_i
|
18
|
+
@id = weapon_data.attributes['key']
|
19
|
+
@name = weapon_data.elements['name'].text
|
20
|
+
@shots = weapon_data.elements['shotsfired'].text.to_i
|
21
|
+
@hits = weapon_data.elements['shotshit'].text.to_i
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns the average number of hits needed for a kill with this weapon.
|
25
|
+
# Calculates the value if needed.
|
26
|
+
def avg_hits_per_kill
|
27
|
+
if @avg_hits_per_kill.nil?
|
28
|
+
@avg_hits_per_kill = @hits.to_f / @kills
|
29
|
+
end
|
30
|
+
|
31
|
+
@avg_hits_per_kill
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns the percentage of headshots relative to the shots hit with this
|
35
|
+
# weapon. Calculates the value if needed.
|
36
|
+
def headshot_percentage
|
37
|
+
if @headshot_percentage.nil?
|
38
|
+
@headshot_percentage = @headshots.to_f / @hits
|
39
|
+
end
|
40
|
+
|
41
|
+
@headshot_percentage
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns the percentage of hits relative to the shots fired with this
|
45
|
+
# weapon. Calculates the value if needed.
|
46
|
+
def hit_percentage
|
47
|
+
if @hit_percentage.nil?
|
48
|
+
@hit_percentage = @hits.to_f / @shots
|
49
|
+
end
|
50
|
+
|
51
|
+
@hit_percentage
|
52
|
+
end
|
53
|
+
|
54
|
+
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) 2008-2009, Sebastian Staudt
|
5
|
+
|
6
|
+
# The GameAchievement class represents a specific achievement for a single game
|
7
|
+
# and for a single user
|
8
|
+
class GameAchievement
|
9
|
+
|
10
|
+
attr_reader :app_id, :name, :steam_id
|
11
|
+
|
12
|
+
# Creates the achievement with the given name for the given user and game and
|
13
|
+
# marks it as already done if set to true
|
14
|
+
def initialize(steam_id, app_id, name, done)
|
15
|
+
@app_id = app_id
|
16
|
+
@done = done
|
17
|
+
@name = name
|
18
|
+
@steam_id = steam_id
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns whether this achievement has been done by its owner
|
22
|
+
def done?
|
23
|
+
@done
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,15 @@
|
|
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
|
+
|
8
|
+
# Super class for classes representing player classes
|
9
|
+
class GameClass
|
10
|
+
|
11
|
+
include AbstractClass
|
12
|
+
|
13
|
+
attr_reader :name, :play_time
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,92 @@
|
|
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) 2008-2009, Sebastian Staudt
|
5
|
+
|
6
|
+
require "open-uri"
|
7
|
+
require "rexml/document"
|
8
|
+
|
9
|
+
require "steam/community/game_achievement"
|
10
|
+
|
11
|
+
class GameStats
|
12
|
+
end
|
13
|
+
|
14
|
+
require "steam/community/l4d/l4d_stats"
|
15
|
+
require "steam/community/dods/dods_stats"
|
16
|
+
require "steam/community/tf2/tf2_stats"
|
17
|
+
|
18
|
+
# The GameStats class represents the game statistics for a single user and a
|
19
|
+
# specific game
|
20
|
+
class GameStats
|
21
|
+
|
22
|
+
protected :initialize
|
23
|
+
|
24
|
+
attr_reader :app_id, :game_friendly_name, :game_name, :hours_played,
|
25
|
+
:privacy_state, :steam_id
|
26
|
+
|
27
|
+
# Creates a GameStats (or one of its subclasses) object for the given user
|
28
|
+
# depending on the game selected
|
29
|
+
def self.create_game_stats(steam_id, game_name)
|
30
|
+
case game_name
|
31
|
+
when "DoD:S":
|
32
|
+
DoDSStats.new(steam_id)
|
33
|
+
when "L4D":
|
34
|
+
L4DStats.new(steam_id)
|
35
|
+
when "TF2":
|
36
|
+
TF2Stats.new(steam_id)
|
37
|
+
else
|
38
|
+
new(steam_id, game_name)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Creates a GameStats object and fetchs data from Steam Community for the
|
43
|
+
# given user and game
|
44
|
+
def initialize(steam_id, game_name)
|
45
|
+
@steam_id = steam_id
|
46
|
+
|
47
|
+
@xml_data = REXML::Document.new(open("http://www.steamcommunity.com/id/#{@steam_id}/stats/#{game_name}?xml=1", {:proxy => true}).read).elements["playerstats"]
|
48
|
+
|
49
|
+
@privacy_state = @xml_data.elements["privacyState"].text
|
50
|
+
if public?
|
51
|
+
@app_id = @xml_data.elements["game"].elements["gameLink"].text.match("http://store.steampowered.com/app/([1-9][0-9]+)")[1]
|
52
|
+
@game_friendly_name = @xml_data.elements["game"].elements["gameFriendlyName"].text
|
53
|
+
@game_name = @xml_data.elements["game"].elements["gameName"].text
|
54
|
+
@hours_played = @xml_data.elements["stats"].elements["hoursPlayed"].text
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Returns the achievements for this stats' user and game. If the achievements
|
59
|
+
# haven't been parsed already, parsing is done now.
|
60
|
+
def achievements
|
61
|
+
return unless public?
|
62
|
+
|
63
|
+
if @achievements.nil?
|
64
|
+
@achievements = Array.new
|
65
|
+
@xml_data.elements["achievements"].elements.each("achievement") do |achievement|
|
66
|
+
@achievements << GameAchievement.new(@steam_id, @app_id, achievement.elements["name"].text, (achievement.attributes["closed"].to_i == 1))
|
67
|
+
end
|
68
|
+
|
69
|
+
@achievements_done = @achievements.reject{ |a| !a.done? }.size
|
70
|
+
end
|
71
|
+
|
72
|
+
return @achievements
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns the count of achievements done by this player. If achievements
|
76
|
+
# haven't been parsed yet, parsing is done now.
|
77
|
+
def achievements_done
|
78
|
+
achievements if @achievements_done.nil?
|
79
|
+
@achievements_done
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns a float value representing the percentage of achievements done by
|
83
|
+
# this player.
|
84
|
+
def achievements_percentage
|
85
|
+
achievements_done.to_f / @achievements.size
|
86
|
+
end
|
87
|
+
|
88
|
+
def public?
|
89
|
+
@privacy_state == 'public'
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
@@ -0,0 +1,29 @@
|
|
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
|
+
|
8
|
+
# Super class for classes representing game weapons
|
9
|
+
class GameWeapon
|
10
|
+
|
11
|
+
include AbstractClass
|
12
|
+
|
13
|
+
attr_reader :kills, :id, :shots
|
14
|
+
|
15
|
+
def initialize(weapon_data)
|
16
|
+
@kills = weapon_data.elements['kills'].text.to_i
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns the average number of shots needed for a kill with this weapon.
|
20
|
+
# Calculates the value if needed.
|
21
|
+
def avg_shots_per_kill
|
22
|
+
if @avg_shots_per_kill.nil?
|
23
|
+
@avg_shots_per_kill = @shots.to_f / @kills
|
24
|
+
end
|
25
|
+
|
26
|
+
@avg_shots_per_kill
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,23 @@
|
|
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/game_weapon'
|
7
|
+
|
8
|
+
class L4DExplosive < GameWeapon
|
9
|
+
|
10
|
+
# Creates a new instance of L4DExplosive based on the assigned XML data
|
11
|
+
def initialize(weapon_data)
|
12
|
+
super weapon_data
|
13
|
+
|
14
|
+
@id = weapon_data.name
|
15
|
+
@shots = weapon_data.elements['thrown'].text.to_i
|
16
|
+
end
|
17
|
+
|
18
|
+
# Returns the average number of kills for one shot of this explosive.
|
19
|
+
def avg_kills_per_shot
|
20
|
+
1 / avg_shots_per_kill
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,34 @@
|
|
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
|
+
class L4DMap
|
7
|
+
|
8
|
+
attr_reader :best_time, :id, :medal, :name, :times_played
|
9
|
+
|
10
|
+
GOLD = 1
|
11
|
+
SILVER = 2
|
12
|
+
BRONZE = 3
|
13
|
+
NONE = 0
|
14
|
+
|
15
|
+
# Creates a new instance of L4DMap based on the assigned XML data
|
16
|
+
def initialize(map_data)
|
17
|
+
@best_time = map_data.elements['besttimeseconds'].text.to_f
|
18
|
+
@id = map_data.name
|
19
|
+
@name = map_data.elements['name'].text
|
20
|
+
@times_played = map_data.elements['timesplayed'].text.to_i
|
21
|
+
|
22
|
+
case map_data.elements['medal'].text
|
23
|
+
when 'gold':
|
24
|
+
@medal = L4DMap::GOLD
|
25
|
+
when 'silver':
|
26
|
+
@medal = L4DMap::SILVER
|
27
|
+
when 'bronze':
|
28
|
+
@medal = L4DMap::BRONZE
|
29
|
+
else
|
30
|
+
@medal = L4DMap::NONE
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,166 @@
|
|
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/game_stats'
|
7
|
+
require 'steam/community/l4d/l4d_explosive'
|
8
|
+
require 'steam/community/l4d/l4d_map'
|
9
|
+
require 'steam/community/l4d/l4d_weapon'
|
10
|
+
|
11
|
+
class L4DStats < GameStats
|
12
|
+
|
13
|
+
attr_reader :xml_data
|
14
|
+
|
15
|
+
# Creates a L4DStats object by calling the super constructor with the game
|
16
|
+
# name "l4d"
|
17
|
+
def initialize(steam_id)
|
18
|
+
super steam_id, 'l4d'
|
19
|
+
|
20
|
+
if public?
|
21
|
+
@most_recent_game = {}
|
22
|
+
@most_recent_game['difficulty'] = @xml_data.elements['stats/mostrecentgame/difficulty'].text
|
23
|
+
@most_recent_game['escaped'] = (@xml_data.elements['stats/mostrecentgame/bEscaped'].text == 1)
|
24
|
+
@most_recent_game['movie'] = @xml_data.elements['stats/mostrecentgame/movie'].text
|
25
|
+
@most_recent_game['time_played'] = @xml_data.elements['stats/mostrecentgame/time'].text
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns a Hash of favorites for this user like weapons and character.
|
30
|
+
# If the favorites haven't been parsed already, parsing is done now.
|
31
|
+
def favorites
|
32
|
+
return unless public?
|
33
|
+
|
34
|
+
if @favorites.nil?
|
35
|
+
@favorites = {}
|
36
|
+
@favorites['campaign'] = @xml_data.elements['stats/favorites/campaign'].text
|
37
|
+
@favorites['campaign_percentage'] = @xml_data.elements['stats/favorites/campaignpct'].text.to_i
|
38
|
+
@favorites['character'] = @xml_data.elements['stats/favorites/character'].text
|
39
|
+
@favorites['character_percentage'] = @xml_data.elements['stats/favorites/characterpct'].text.to_i
|
40
|
+
@favorites['level1_weapon'] = @xml_data.elements['stats/favorites/weapon1'].text
|
41
|
+
@favorites['level1_weapon_percentage'] = @xml_data.elements['stats/favorites/weapon1pct'].text.to_i
|
42
|
+
@favorites['level2_weapon'] = @xml_data.elements['stats/favorites/weapon2'].text
|
43
|
+
@favorites['level2_weapon_percentage'] = @xml_data.elements['stats/favorites/weapon2pct'].text.to_i
|
44
|
+
end
|
45
|
+
|
46
|
+
@favorites
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returns a Hash of lifetime statistics for this user like the time played.
|
50
|
+
# If the lifetime statistics haven't been parsed already, parsing is done now.
|
51
|
+
def lifetime_stats
|
52
|
+
return unless public?
|
53
|
+
|
54
|
+
if @lifetime_stats.nil?
|
55
|
+
@lifetime_stats = {}
|
56
|
+
@lifetime_stats['finales_survived'] = @xml_data.elements['stats/lifetime/finales'].text.to_i
|
57
|
+
@lifetime_stats['games_played'] = @xml_data.elements['stats/lifetime/gamesplayed'].text.to_i
|
58
|
+
@lifetime_stats['finales_survived_percentage'] = @lifetime_stats['finales_survived'].to_f / @lifetime_stats['games_played']
|
59
|
+
@lifetime_stats['infected_killed'] = @xml_data.elements['stats/lifetime/infectedkilled'].text.to_i
|
60
|
+
@lifetime_stats['kills_per_hour'] = @xml_data.elements['stats/lifetime/killsperhour'].text.to_f
|
61
|
+
@lifetime_stats['avg_kits_shared'] = @xml_data.elements['stats/lifetime/kitsshared'].text.to_f
|
62
|
+
@lifetime_stats['avg_kits_used'] = @xml_data.elements['stats/lifetime/kitsused'].text.to_f
|
63
|
+
@lifetime_stats['avg_pills_shared'] = @xml_data.elements['stats/lifetime/pillsshared'].text.to_f
|
64
|
+
@lifetime_stats['avg_pills_used'] = @xml_data.elements['stats/lifetime/pillsused'].text.to_f
|
65
|
+
@lifetime_stats['time_played'] = @xml_data.elements['stats/lifetime/timeplayed'].text
|
66
|
+
end
|
67
|
+
|
68
|
+
@lifetime_stats
|
69
|
+
end
|
70
|
+
|
71
|
+
# Returns a Hash of Survival statistics for this user like revived teammates.
|
72
|
+
# If the Survival statistics haven't been parsed already, parsing is done now.
|
73
|
+
def survival_stats
|
74
|
+
return unless public?
|
75
|
+
|
76
|
+
if @survival_stats.nil?
|
77
|
+
@survival_stats = {}
|
78
|
+
@survival_stats['gold_medals'] = @xml_data.elements['stats/survival/goldmedals'].text.to_i
|
79
|
+
@survival_stats['silver_medals'] = @xml_data.elements['stats/survival/silvermedals'].text.to_i
|
80
|
+
@survival_stats['bronze_medals'] = @xml_data.elements['stats/survival/bronzemedals'].text.to_i
|
81
|
+
@survival_stats['rounds_played'] = @xml_data.elements['stats/survival/roundsplayed'].text.to_i
|
82
|
+
@survival_stats['best_time'] = @xml_data.elements['stats/survival/besttime'].text.to_f
|
83
|
+
|
84
|
+
@survival_stats['maps'] = {}
|
85
|
+
@xml_data.elements.each('stats/survival/maps/*') do |map_data|
|
86
|
+
@survival_stats['maps'][map_data.name] = L4DMap.new(map_data)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
@survival_stats
|
91
|
+
end
|
92
|
+
|
93
|
+
# Returns a Hash of teamplay statistics for this user like revived teammates.
|
94
|
+
# If the teamplay statistics haven't been parsed already, parsing is done now.
|
95
|
+
def teamplay_stats
|
96
|
+
return unless public?
|
97
|
+
|
98
|
+
if @teamplay_stats.nil?
|
99
|
+
@teamplay_stats = {}
|
100
|
+
@teamplay_stats['revived'] = @xml_data.elements['stats/teamplay/revived'].text.to_i
|
101
|
+
@teamplay_stats['most_revived_difficulty'] = @xml_data.elements['stats/teamplay/reviveddiff'].text
|
102
|
+
@teamplay_stats['avg_revived'] = @xml_data.elements['stats/teamplay/revivedavg'].text.to_f
|
103
|
+
@teamplay_stats['avg_was_revived'] = @xml_data.elements['stats/teamplay/wasrevivedavg'].text.to_f
|
104
|
+
@teamplay_stats['protected'] = @xml_data.elements['stats/teamplay/protected'].text.to_i
|
105
|
+
@teamplay_stats['most_protected_difficulty'] = @xml_data.elements['stats/teamplay/protecteddiff'].text
|
106
|
+
@teamplay_stats['avg_protected'] = @xml_data.elements['stats/teamplay/protectedavg'].text.to_f
|
107
|
+
@teamplay_stats['avg_was_protected'] = @xml_data.elements['stats/teamplay/wasprotectedavg'].text.to_f
|
108
|
+
@teamplay_stats['friendly_fire_damage'] = @xml_data.elements['stats/teamplay/ffdamage'].text.to_i
|
109
|
+
@teamplay_stats['most_friendly_fire_difficulty'] = @xml_data.elements['stats/teamplay/ffdamagediff'].text
|
110
|
+
@teamplay_stats['avg_friendly_fire_damage'] = @xml_data.elements['stats/teamplay/ffdamageavg'].text.to_f
|
111
|
+
end
|
112
|
+
|
113
|
+
@teamplay_stats
|
114
|
+
end
|
115
|
+
|
116
|
+
# Returns a Hash of Versus statistics for this user like percentage of rounds
|
117
|
+
# won.
|
118
|
+
# If the Versus statistics haven't been parsed already, parsing is done now.
|
119
|
+
def versus_stats
|
120
|
+
return unless public?
|
121
|
+
|
122
|
+
if @versus_stats.nil?
|
123
|
+
@versus_stats = {}
|
124
|
+
@versus_stats['games_played'] = @xml_data.elements['stats/versus/gamesplayed'].text.to_i
|
125
|
+
@versus_stats['games_completed'] = @xml_data.elements['stats/versus/gamescompleted'].text.to_i
|
126
|
+
@versus_stats['finales_survived'] = @xml_data.elements['stats/versus/finales'].text.to_i
|
127
|
+
@versus_stats['finales_survived_percentage'] = @versus_stats['finales_survived'].to_f / @versus_stats['games_played']
|
128
|
+
@versus_stats['points'] = @xml_data.elements['stats/versus/points'].text.to_i
|
129
|
+
@versus_stats['most_points_infected'] = @xml_data.elements['stats/versus/pointsas'].text
|
130
|
+
@versus_stats['games_won'] = @xml_data.elements['stats/versus/gameswon'].text.to_i
|
131
|
+
@versus_stats['games_lost'] = @xml_data.elements['stats/versus/gameslost'].text.to_i
|
132
|
+
@versus_stats['highest_survivor_score'] = @xml_data.elements['stats/versus/survivorscore'].text.to_i
|
133
|
+
|
134
|
+
%w(boomer hunter smoker tank).each do |infected|
|
135
|
+
@versus_stats[infected] = {}
|
136
|
+
@versus_stats[infected]['special'] = @xml_data.elements["stats/versus/#{infected}special"].text.to_i
|
137
|
+
@versus_stats[infected]['most_damage'] = @xml_data.elements["stats/versus/#{infected}dmg"].text.to_i
|
138
|
+
@versus_stats[infected]['avg_lifespan'] = @xml_data.elements["stats/versus/#{infected}lifespan"].text.to_i
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
@versus_stats
|
143
|
+
end
|
144
|
+
|
145
|
+
# Returns a Hash of L4DWeapon for this user containing all Left4Dead weapons.
|
146
|
+
# If the weapons haven't been parsed already, parsing is done now.
|
147
|
+
def weapon_stats
|
148
|
+
return unless public?
|
149
|
+
|
150
|
+
if @weapon_stats.nil?
|
151
|
+
@weapon_stats = {}
|
152
|
+
@xml_data.elements.each('stats/weapons/*') do |weapon_data|
|
153
|
+
unless weapon_data.name == 'molotov' or weapon_data.name == 'pipes'
|
154
|
+
weapon = L4DWeapon.new(weapon_data)
|
155
|
+
else
|
156
|
+
weapon = L4DExplosive.new(weapon_data)
|
157
|
+
end
|
158
|
+
|
159
|
+
@weapon_stats[weapon_data.name] = weapon
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
@weapon_stats
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|