steam-condenser 0.8.0 → 0.9.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/Rakefile +10 -7
- data/VERSION.yml +4 -0
- data/lib/byte_buffer.rb +28 -28
- data/lib/datagram_channel.rb +5 -4
- data/lib/exceptions/rcon_ban_exception.rb +12 -0
- data/lib/socket_channel.rb +21 -14
- data/lib/steam-condenser.rb +11 -0
- data/lib/steam/community/cacheable.rb +95 -0
- data/lib/steam/community/defense_grid/defense_grid_stats.rb +124 -0
- data/lib/steam/community/game_stats.rb +44 -26
- data/lib/steam/community/l4d/l4d_map.rb +3 -3
- data/lib/steam/community/steam_group.rb +77 -6
- data/lib/steam/community/steam_id.rb +127 -101
- data/lib/steam/community/tf2/tf2_stats.rb +5 -5
- data/lib/steam/packets/rcon/rcon_exec_response.rb +6 -8
- data/lib/steam/packets/s2a_rules_packet.rb +15 -8
- data/lib/steam/servers/game_server.rb +2 -4
- data/lib/steam/servers/goldsrc_server.rb +5 -5
- data/lib/steam/servers/source_server.rb +11 -11
- data/lib/steam/sockets/rcon_socket.rb +18 -17
- data/lib/steam/sockets/steam_socket.rb +5 -8
- data/lib/steam/steam_player.rb +5 -5
- data/test/byte_buffer_tests.rb +76 -0
- data/test/datagram_channel_tests.rb +42 -0
- data/test/query_tests.rb +1 -3
- data/test/rcon_tests.rb +1 -3
- data/test/socket_channel_tests.rb +43 -0
- data/test/steam/communtiy/steam_community_test_suite.rb +9 -0
- data/test/steam/communtiy/steam_group_tests.rb +43 -0
- data/test/steam/communtiy/steam_id_tests.rb +48 -0
- data/test/steam_community_tests.rb +17 -9
- metadata +27 -10
@@ -11,50 +11,59 @@ require "steam/community/game_achievement"
|
|
11
11
|
class GameStats
|
12
12
|
end
|
13
13
|
|
14
|
-
require
|
14
|
+
require 'steam/community/defense_grid/defense_grid_stats'
|
15
15
|
require "steam/community/dods/dods_stats"
|
16
|
+
require "steam/community/l4d/l4d_stats"
|
16
17
|
require "steam/community/tf2/tf2_stats"
|
17
18
|
|
18
19
|
# The GameStats class represents the game statistics for a single user and a
|
19
20
|
# specific game
|
20
21
|
class GameStats
|
21
|
-
|
22
|
+
|
22
23
|
protected :initialize
|
23
24
|
|
24
|
-
attr_reader :app_id, :
|
25
|
-
:privacy_state, :
|
25
|
+
attr_reader :app_id, :custom_url, :game_friendly_name, :game_name,
|
26
|
+
:hours_played, :privacy_state, :steam_id64
|
26
27
|
|
27
28
|
# Creates a GameStats (or one of its subclasses) object for the given user
|
28
29
|
# depending on the game selected
|
29
30
|
def self.create_game_stats(steam_id, game_name)
|
30
31
|
case game_name
|
31
|
-
when
|
32
|
+
when 'defensegrid:awakening'
|
33
|
+
DefenseGridStats.new(steam_id)
|
34
|
+
when 'dod:s'
|
32
35
|
DoDSStats.new(steam_id)
|
33
|
-
when
|
36
|
+
when 'l4d'
|
34
37
|
L4DStats.new(steam_id)
|
35
|
-
when
|
38
|
+
when 'tf2'
|
36
39
|
TF2Stats.new(steam_id)
|
37
40
|
else
|
38
41
|
new(steam_id, game_name)
|
39
42
|
end
|
40
43
|
end
|
41
|
-
|
44
|
+
|
42
45
|
# Creates a GameStats object and fetchs data from Steam Community for the
|
43
46
|
# given user and game
|
44
|
-
def initialize(
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
def initialize(id, game_name)
|
48
|
+
if id.is_a? Numeric
|
49
|
+
@steam_id64 = id
|
50
|
+
else
|
51
|
+
@custom_url = id.downcase
|
52
|
+
end
|
53
|
+
@game_friendly_name = game_name
|
54
|
+
|
55
|
+
url = base_url + '?xml=1'
|
56
|
+
@xml_data = REXML::Document.new(open(url, {:proxy => true}).read).root
|
57
|
+
|
58
|
+
@privacy_state = @xml_data.elements['privacyState'].text
|
50
59
|
if public?
|
51
|
-
@app_id = @xml_data.elements[
|
52
|
-
@game_friendly_name = @xml_data.elements[
|
53
|
-
@game_name = @xml_data.elements[
|
54
|
-
@hours_played = @xml_data.elements[
|
60
|
+
@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
|
+
@game_name = @xml_data.elements['game/gameName'].text
|
63
|
+
@hours_played = @xml_data.elements['stats/hoursPlayed'].text
|
55
64
|
end
|
56
65
|
end
|
57
|
-
|
66
|
+
|
58
67
|
# Returns the achievements for this stats' user and game. If the achievements
|
59
68
|
# haven't been parsed already, parsing is done now.
|
60
69
|
def achievements
|
@@ -62,16 +71,16 @@ class GameStats
|
|
62
71
|
|
63
72
|
if @achievements.nil?
|
64
73
|
@achievements = Array.new
|
65
|
-
@xml_data.elements
|
66
|
-
@achievements << GameAchievement.new(@steam_id, @app_id, achievement.elements[
|
74
|
+
@xml_data.elements.each('achievements/achievement') do |achievement|
|
75
|
+
@achievements << GameAchievement.new(@steam_id, @app_id, achievement.elements['name'].text, (achievement.attributes['closed'].to_i == 1))
|
67
76
|
end
|
68
77
|
|
69
78
|
@achievements_done = @achievements.reject{ |a| !a.done? }.size
|
70
79
|
end
|
71
|
-
|
72
|
-
|
80
|
+
|
81
|
+
@achievements
|
73
82
|
end
|
74
|
-
|
83
|
+
|
75
84
|
# Returns the count of achievements done by this player. If achievements
|
76
85
|
# haven't been parsed yet, parsing is done now.
|
77
86
|
def achievements_done
|
@@ -85,8 +94,17 @@ class GameStats
|
|
85
94
|
achievements_done.to_f / @achievements.size
|
86
95
|
end
|
87
96
|
|
97
|
+
# Returns the base URL for this Steam Communtiy object
|
98
|
+
def base_url
|
99
|
+
if @custom_url.nil?
|
100
|
+
"http://steamcommunity.com/profiles/#{@steam_id64}/stats/#{@game_friendly_name}"
|
101
|
+
else
|
102
|
+
"http://steamcommunity.com/id/#{@custom_url}/stats/#{@game_friendly_name}"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
88
106
|
def public?
|
89
107
|
@privacy_state == 'public'
|
90
108
|
end
|
91
|
-
|
92
|
-
end
|
109
|
+
|
110
|
+
end
|
@@ -20,11 +20,11 @@ class L4DMap
|
|
20
20
|
@times_played = map_data.elements['timesplayed'].text.to_i
|
21
21
|
|
22
22
|
case map_data.elements['medal'].text
|
23
|
-
when 'gold'
|
23
|
+
when 'gold'
|
24
24
|
@medal = L4DMap::GOLD
|
25
|
-
when 'silver'
|
25
|
+
when 'silver'
|
26
26
|
@medal = L4DMap::SILVER
|
27
|
-
when 'bronze'
|
27
|
+
when 'bronze'
|
28
28
|
@medal = L4DMap::BRONZE
|
29
29
|
else
|
30
30
|
@medal = L4DMap::NONE
|
@@ -1,16 +1,87 @@
|
|
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
|
-
|
4
|
+
# Copyright (c) 2008-2009, Sebastian Staudt
|
5
|
+
|
6
|
+
require 'open-uri'
|
7
|
+
require 'rexml/document'
|
8
|
+
|
9
|
+
require 'steam/community/cacheable'
|
10
|
+
require 'steam/community/steam_id'
|
7
11
|
|
8
12
|
# The SteamGroup class represents a group in the Steam Community
|
9
13
|
class SteamGroup
|
10
|
-
|
14
|
+
|
15
|
+
include Cacheable
|
16
|
+
cacheable_with_ids :custom_url, :group_id64
|
17
|
+
|
18
|
+
attr_reader :custom_url, :group_id64
|
19
|
+
|
11
20
|
# Creates a SteamGroup object with the given group ID
|
12
|
-
def initialize(id)
|
13
|
-
|
21
|
+
def initialize(id, fetch = true)
|
22
|
+
begin
|
23
|
+
if id.is_a? Numeric
|
24
|
+
@group_id64 = id
|
25
|
+
else
|
26
|
+
@custom_url = id.downcase
|
27
|
+
end
|
28
|
+
|
29
|
+
super(fetch)
|
30
|
+
rescue REXML::ParseException
|
31
|
+
raise SteamCondenserException.new('Group could not be loaded.')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns the URL to the group's Steam Community page
|
36
|
+
def base_url
|
37
|
+
if @custom_url.nil?
|
38
|
+
"http://steamcommunity.com/gid/#{@group_id64}"
|
39
|
+
else
|
40
|
+
"http://steamcommunity.com/groups/#{@custom_url}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Parses the data about this groups members
|
45
|
+
def fetch
|
46
|
+
@members = []
|
47
|
+
page = 0
|
48
|
+
|
49
|
+
begin
|
50
|
+
page += 1
|
51
|
+
url = open("#{base_url}/memberslistxml?p=#{page}", {:proxy => true})
|
52
|
+
member_data = REXML::Document.new(url.read).root
|
53
|
+
|
54
|
+
if page == 1
|
55
|
+
@group_id64 = member_data.elements['groupID64'].text.to_i
|
56
|
+
end
|
57
|
+
total_pages = member_data.elements['totalPages'].text.to_i
|
58
|
+
|
59
|
+
member_data.elements['members'].elements.each do |member|
|
60
|
+
@members << SteamId.new(member.text.to_i, false)
|
61
|
+
end
|
62
|
+
end while page < total_pages
|
63
|
+
|
64
|
+
super
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns the number of members this group has.
|
68
|
+
# If the members have already been fetched with +fetch_members+ the size of
|
69
|
+
# the member array is returned. Otherwise the group size is separately
|
70
|
+
# fetched.
|
71
|
+
def member_count
|
72
|
+
if @members.nil?
|
73
|
+
url = open("#{base_url}/memberslistxml", {:proxy => true})
|
74
|
+
REXML::Document.new(url.read).root.elements['memberCount'].text.to_i
|
75
|
+
else
|
76
|
+
@members.size
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Returns the members of this group
|
81
|
+
# Calls +fetch_members+ if the members haven't been fetched already.
|
82
|
+
def members
|
83
|
+
fetch_members if @members.nil? or @members[0].nil?
|
84
|
+
@members
|
14
85
|
end
|
15
86
|
|
16
87
|
end
|
@@ -3,55 +3,60 @@
|
|
3
3
|
#
|
4
4
|
# Copyright (c) 2008-2009, Sebastian Staudt
|
5
5
|
|
6
|
-
require
|
7
|
-
require
|
6
|
+
require 'open-uri'
|
7
|
+
require 'rexml/document'
|
8
8
|
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
9
|
+
require 'exceptions/steam_condenser_exception'
|
10
|
+
require 'steam/community/cacheable'
|
11
|
+
require 'steam/community/game_stats'
|
12
|
+
require 'steam/community/steam_group'
|
12
13
|
|
13
14
|
# The SteamId class represents a Steam Community profile (also called Steam ID)
|
14
15
|
class SteamId
|
15
|
-
|
16
|
+
|
17
|
+
include Cacheable
|
18
|
+
cacheable_with_ids :custom_url, :steam_id64
|
19
|
+
|
16
20
|
attr_reader :custom_url, :favorite_game, :favorite_game_hours_played,
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:real_name, :state_message, :
|
20
|
-
:summary, :vac_banned, :visibility_state
|
21
|
+
:groups, :head_line, :hours_played, :image_url, :links, :location,
|
22
|
+
:member_since, :most_played_games, :nickname, :privacy_state,
|
23
|
+
:real_name, :state_message, :steam_id64, :steam_rating,
|
24
|
+
:steam_rating_text, :summary, :vac_banned, :visibility_state
|
21
25
|
|
22
|
-
# Converts
|
26
|
+
# Converts the SteamID +steam_id+ as reported by game servers to a 64bit
|
27
|
+
# SteamID
|
23
28
|
def self.convert_steam_id_to_community_id(steam_id)
|
24
|
-
if steam_id ==
|
25
|
-
raise SteamCondenserException.new("Cannot convert SteamID \"
|
26
|
-
elsif steam_id.match(
|
29
|
+
if steam_id == 'STEAM_ID_LAN' or steam_id == 'BOT'
|
30
|
+
raise SteamCondenserException.new("Cannot convert SteamID \"#{steam_id}\" to a community ID.")
|
31
|
+
elsif steam_id.match(/^STEAM_[0-1]:[0-1]:[0-9]+$/).nil?
|
27
32
|
raise SteamCondenserException.new("SteamID \"#{steam_id}\" doesn't have the correct format.")
|
28
33
|
end
|
29
|
-
|
30
|
-
steam_id = steam_id[6..-1].split(
|
31
|
-
|
32
|
-
|
34
|
+
|
35
|
+
steam_id = steam_id[6..-1].split(':').map!{|s| s.to_i}
|
36
|
+
|
37
|
+
steam_id[1] + steam_id[2] * 2 + 76561197960265728
|
33
38
|
end
|
34
39
|
|
35
|
-
# Creates a new SteamId object using
|
36
|
-
# SteamID
|
40
|
+
# Creates a new SteamId object using the SteamID64 converted from a server
|
41
|
+
# SteamID given by +steam_id+
|
37
42
|
def self.get_from_steam_id(steam_id)
|
38
|
-
|
43
|
+
self.new(self.convert_steam_id_to_community_id(steam_id))
|
39
44
|
end
|
40
45
|
|
41
|
-
# Creates a new SteamId object for the given SteamID
|
42
|
-
# custom URL specified by the user. If +fetch+ is +true+ (default),
|
43
|
-
# is used to load data into the object.
|
46
|
+
# Creates a new SteamId object for the given SteamID +id+, either numeric or
|
47
|
+
# the custom URL specified by the user. If +fetch+ is +true+ (default),
|
48
|
+
# fetch_data is used to load data into the object.
|
44
49
|
def initialize(id, fetch = true)
|
45
|
-
if id.is_a? Numeric
|
46
|
-
@steam_id64 = id
|
47
|
-
else
|
48
|
-
@custom_url = id
|
49
|
-
end
|
50
|
-
|
51
50
|
begin
|
52
|
-
|
51
|
+
if id.is_a? Numeric
|
52
|
+
@steam_id64 = id
|
53
|
+
else
|
54
|
+
@custom_url = id.downcase
|
55
|
+
end
|
56
|
+
|
57
|
+
super(fetch)
|
53
58
|
rescue REXML::ParseException
|
54
|
-
raise SteamCondenserException.new(
|
59
|
+
raise SteamCondenserException.new('SteamID could not be loaded.')
|
55
60
|
end
|
56
61
|
end
|
57
62
|
|
@@ -63,78 +68,92 @@ class SteamId
|
|
63
68
|
"http://steamcommunity.com/id/#{@custom_url}"
|
64
69
|
end
|
65
70
|
end
|
66
|
-
|
71
|
+
|
67
72
|
# Fetchs data from the Steam Community by querying the XML version of the
|
68
73
|
# profile specified by the ID of this SteamID
|
69
|
-
def
|
70
|
-
|
74
|
+
def fetch
|
75
|
+
profile_url = open(base_url + '?xml=1', {:proxy => true})
|
76
|
+
profile = REXML::Document.new(profile_url.read).root
|
71
77
|
|
72
|
-
|
73
|
-
|
74
|
-
profile_url = open(profile_url.base_uri.to_s + "?xml=1", {:proxy => true})
|
78
|
+
unless REXML::XPath.first(profile, 'error').nil?
|
79
|
+
raise SteamCondenserException.new(profile.elements['error'].text)
|
75
80
|
end
|
76
|
-
|
77
|
-
profile = REXML::Document.new(profile_url.read).elements["profile"]
|
78
|
-
|
79
|
-
@image_url = profile.elements["avatarIcon"].text[0..-5]
|
80
|
-
@online_state = profile.elements["onlineState"].text
|
81
|
-
@privacy_state = profile.elements["privacyState"].text
|
82
|
-
@state_message = profile.elements["stateMessage"].text
|
83
|
-
@steam_id = profile.elements["steamID"].text
|
84
|
-
@steam_id64 = profile.elements["steamID64"].text.to_i
|
85
|
-
@vac_banned = (profile.elements["vacBanned"].text == 1)
|
86
|
-
@visibility_state = profile.elements["visibilityState"].text.to_i
|
87
|
-
|
88
|
-
# Only public profiles can be scanned for further information
|
89
|
-
if @privacy_state == "public"
|
90
|
-
@custom_url = profile.elements["customURL"].text
|
91
81
|
|
92
|
-
|
93
|
-
|
94
|
-
|
82
|
+
@image_url = profile.elements['avatarIcon'].text[0..-5]
|
83
|
+
@online_state = profile.elements['onlineState'].text
|
84
|
+
@privacy_state = profile.elements['privacyState'].text
|
85
|
+
@state_message = profile.elements['stateMessage'].text
|
86
|
+
@nickname = profile.elements['steamID'].text
|
87
|
+
@steam_id64 = profile.elements['steamID64'].text.to_i
|
88
|
+
@vac_banned = (profile.elements['vacBanned'].text == 1)
|
89
|
+
@visibility_state = profile.elements['visibilityState'].text.to_i
|
90
|
+
|
91
|
+
# Only public profiles can be scanned for further information
|
92
|
+
if @privacy_state == 'public'
|
93
|
+
@custom_url = profile.elements['customURL'].text.downcase
|
94
|
+
|
95
|
+
# The favorite game cannot be set since 10/10/2008, but old profiles
|
96
|
+
# still have this. May be removed in a future version.
|
97
|
+
unless REXML::XPath.first(profile, 'favoriteGame').nil?
|
98
|
+
@favorite_game = profile.elements['favoriteGame/name'].text
|
99
|
+
@favorite_game_hours_played = profile.elements['favoriteGame/hoursPlayed2wk'].text
|
95
100
|
end
|
96
101
|
|
97
|
-
@head_line = profile.elements[
|
98
|
-
@hours_played = profile.elements[
|
99
|
-
@location = profile.elements[
|
100
|
-
@member_since = Time.parse
|
101
|
-
@real_name = profile.elements[
|
102
|
-
@steam_rating = profile.elements[
|
103
|
-
@summary = profile.elements[
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
102
|
+
@head_line = profile.elements['headline'].text
|
103
|
+
@hours_played = profile.elements['hoursPlayed2Wk'].text.to_f
|
104
|
+
@location = profile.elements['location'].text
|
105
|
+
@member_since = Time.parse(profile.elements['memberSince'].text)
|
106
|
+
@real_name = profile.elements['realname'].text
|
107
|
+
@steam_rating = profile.elements['steamRating'].text.to_f
|
108
|
+
@summary = profile.elements['summary'].text
|
109
|
+
|
110
|
+
# The most played games only exist if a user played at least one game in
|
111
|
+
# the last two weeks
|
112
|
+
@most_played_games = {}
|
113
|
+
unless REXML::XPath.first(profile, 'mostPlayedGames').nil?
|
114
|
+
profile.elements.each('mostPlayedGames/mostPlayedGame') do |most_played_game|
|
115
|
+
@most_played_games[most_played_game.elements['gameName'].text] = most_played_game.elements['hoursPlayed'].text.to_f
|
109
116
|
end
|
110
117
|
end
|
111
|
-
|
112
|
-
@
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
@groups = Array.new
|
118
|
-
profile.elements["groups"].elements.each("group") do |group|
|
119
|
-
@groups << SteamGroup.new(group.elements["groupID64"].text.to_i)
|
118
|
+
|
119
|
+
@groups = []
|
120
|
+
unless REXML::XPath.first(profile, 'groups').nil?
|
121
|
+
profile.elements.each('groups/group') do |group|
|
122
|
+
@groups << SteamGroup.new(group.elements['groupID64'].text.to_i, false)
|
123
|
+
end
|
120
124
|
end
|
121
|
-
|
122
|
-
@links =
|
123
|
-
|
124
|
-
|
125
|
+
|
126
|
+
@links = {}
|
127
|
+
unless REXML::XPath.first(profile, 'mostPlayedGames').nil?
|
128
|
+
profile.elements.each('weblinks/weblink') do |link|
|
129
|
+
@links[link.elements['title'].text] = link.elements['link'].text
|
130
|
+
end
|
125
131
|
end
|
126
132
|
end
|
133
|
+
|
134
|
+
super
|
135
|
+
end
|
136
|
+
|
137
|
+
# Fetches the friends of this user
|
138
|
+
def fetch_friends
|
139
|
+
url = "#{base_url}/friends?xml=1"
|
140
|
+
|
141
|
+
@friends = []
|
142
|
+
friends_data = REXML::Document.new(open(url, {:proxy => true}).read).root
|
143
|
+
friends_data.elements.each('friends/friend') do |friend|
|
144
|
+
@friends << SteamId.new(friend.text.to_i, false)
|
145
|
+
end
|
127
146
|
end
|
128
147
|
|
129
148
|
# Fetches the games this user owns
|
130
149
|
def fetch_games
|
131
150
|
require 'rubygems'
|
132
|
-
require '
|
151
|
+
require 'hpricot'
|
133
152
|
|
134
|
-
url = base_url
|
153
|
+
url = "#{base_url}/games"
|
135
154
|
|
136
155
|
@games = {}
|
137
|
-
games_data = Hpricot(open(url).read).at('div#mainContents')
|
156
|
+
games_data = Hpricot(open(url, {:proxy => true}).read).at('div#mainContents')
|
138
157
|
|
139
158
|
games_data.traverse_some_element('h4') do |game|
|
140
159
|
game_name = game.inner_html
|
@@ -153,18 +172,18 @@ class SteamId
|
|
153
172
|
end
|
154
173
|
end
|
155
174
|
|
156
|
-
|
175
|
+
true
|
157
176
|
end
|
158
|
-
|
159
|
-
# Returns the URL of the full version of this user's avatar
|
177
|
+
|
178
|
+
# Returns the URL of the full-sized version of this user's avatar
|
160
179
|
def full_avatar_url
|
161
|
-
|
180
|
+
"#{@image_url}_full.jpg"
|
162
181
|
end
|
163
|
-
|
182
|
+
|
164
183
|
# Returns a GameStats object for the given game for the owner of this SteamID
|
165
184
|
def game_stats(game_name)
|
166
185
|
game_name.downcase!
|
167
|
-
|
186
|
+
|
168
187
|
if games.has_value? game_name
|
169
188
|
friendly_name = game_name
|
170
189
|
elsif games.has_key? game_name
|
@@ -176,6 +195,13 @@ class SteamId
|
|
176
195
|
GameStats.create_game_stats(@custom_url || @steam_id64, friendly_name)
|
177
196
|
end
|
178
197
|
|
198
|
+
# Returns an Array of SteamId representing all Steam Community friends of this
|
199
|
+
# user.
|
200
|
+
def friends
|
201
|
+
fetch_friends if @friends.nil?
|
202
|
+
@friends
|
203
|
+
end
|
204
|
+
|
179
205
|
# Returns a Hash with the games this user owns. The keys are the games' names
|
180
206
|
# and the values are the "friendly names" used for stats or +false+ if the
|
181
207
|
# games has no stats.
|
@@ -183,30 +209,30 @@ class SteamId
|
|
183
209
|
fetch_games if @games.nil?
|
184
210
|
@games
|
185
211
|
end
|
186
|
-
|
212
|
+
|
187
213
|
# Returns the URL of the icon version of this user's avatar
|
188
214
|
def icon_url
|
189
|
-
|
215
|
+
"#{@image_url}.jpg"
|
190
216
|
end
|
191
|
-
|
217
|
+
|
192
218
|
# Returns whether the owner of this SteamID is VAC banned
|
193
219
|
def is_banned?
|
194
|
-
|
220
|
+
@vac_banned
|
195
221
|
end
|
196
|
-
|
222
|
+
|
197
223
|
# Returns whether the owner of this SteamId is playing a game
|
198
224
|
def is_in_game?
|
199
|
-
|
225
|
+
@online_state == 'in-game'
|
200
226
|
end
|
201
|
-
|
227
|
+
|
202
228
|
# Returns whether the owner of this SteamID is currently logged into Steam
|
203
229
|
def is_online?
|
204
|
-
|
230
|
+
@online_state != 'offline'
|
205
231
|
end
|
206
|
-
|
207
|
-
# Returns the URL of the medium version of this user's avatar
|
232
|
+
|
233
|
+
# Returns the URL of the medium-sized version of this user's avatar
|
208
234
|
def medium_avatar_url
|
209
|
-
|
235
|
+
"#{@image_url}_medium.jpg"
|
210
236
|
end
|
211
237
|
|
212
238
|
end
|