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