-
Notifications
You must be signed in to change notification settings - Fork 41
/
game_stats.rb
177 lines (154 loc) · 5.73 KB
/
game_stats.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# This code is free software; you can redistribute it and/or modify it under
# the terms of the new BSD License.
#
# Copyright (c) 2008-2012, Sebastian Staudt
require 'steam/community/game_achievement'
require 'steam/community/game_leaderboard'
require 'steam/community/xml_data'
# This class represents the game statistics for a single user and a specific
# game
#
# It is subclassed for individual games if the games provide special statistics
# that are unique to this game.
#
# @author Sebastian Staudt
class GameStats
include XMLData
# Returns the game these stats belong to
#
# @return [SteamGame] The game object
attr_reader :game
# Returns the number of hours this game has been played by the player
#
# @return [String] The number of hours this game has been played
attr_reader :hours_played
# Returns the privacy setting of the Steam ID profile
#
# @return [String] The privacy setting of the Steam ID
attr_reader :privacy_state
# Returns the Steam ID of the player these stats belong to
#
# @return [SteamId] The Steam ID instance of the player
attr_reader :user
# Returns the base Steam Communtiy URL for the given player and game IDs
#
# @param [Fixnum, String] user_id The 64bit SteamID or custom URL of the user
# @param [Fixnum, String] game_id The application ID or short name of the
# game
# @return The base URL used for the given stats IDs
def self.base_url(user_id, game_id)
game_url = game_id.is_a?(Fixnum) ? "appid/#{game_id}" : game_id
if user_id.is_a? Fixnum
"http://steamcommunity.com/profiles/#{user_id}/stats/#{game_url}"
else
"http://steamcommunity.com/id/#{user_id}/stats/#{game_url}"
end
end
# Creates a `GameStats` (or one of its subclasses) instance for the given
# user and game
#
# @param [String, Fixnum] steam_id The custom URL or the 64bit Steam ID of
# the user
# @param [String] game_name The friendly name of the game
# @return [GameStats] The game stats object for the given user and game
def self.create_game_stats(steam_id, game_name)
case game_name
when 'alienswarm'
require 'steam/community/alien_swarm/alien_swarm_stats'
AlienSwarmStats.new(steam_id)
when 'cs:s'
require 'steam/community/css/css_stats'
CSSStats.new(steam_id)
when 'defensegrid:awakening'
require 'steam/community/defense_grid/defense_grid_stats'
DefenseGridStats.new(steam_id)
when 'dod:s'
require 'steam/community/dods/dods_stats'
DoDSStats.new(steam_id)
when 'l4d'
require 'steam/community/l4d/l4d_stats'
L4DStats.new(steam_id)
when 'l4d2'
require 'steam/community/l4d/l4d2_stats'
L4D2Stats.new(steam_id)
when 'portal2'
require 'steam/community/portal2/portal2_stats'
Portal2Stats.new steam_id
when 'tf2'
require 'steam/community/tf2/tf2_stats'
TF2Stats.new(steam_id)
else
new(steam_id, game_name)
end
end
# Creates a `GameStats` object and fetches data from the Steam Community for
# the given user and game
#
# @param [String, Fixnum] user_id The custom URL or the 64bit Steam ID of the
# user
# @param [String] game_id The application ID or friendly name of the game
# @raise [SteamCondenserError] if the stats cannot be fetched
def initialize(user_id, game_id)
@xml_data = parse "#{self.class.base_url(user_id, game_id)}?xml=all"
@user = SteamId.new user_id, false
error = @xml_data['error']
raise SteamCondenserError, error unless error.nil?
@privacy_state = @xml_data['privacyState']
if public?
app_id = @xml_data['game']['gameLink'].match(/http:\/\/store.steampowered.com\/app\/([1-9][0-9]+)/)[1].to_i
@game = SteamGame.new app_id, @xml_data['game']
@custom_url = @xml_data['player']['customURL'] if @custom_url.nil?
@hours_played = @xml_data['stats']['hoursPlayed'] unless @xml_data['stats']['hoursPlayed'].nil?
@steam_id64 = @xml_data['player']['steamID64'].to_i if @steam_id64.nil?
end
end
# Returns the achievements for this stats' user and game
#
# If the achievements' data hasn't been parsed yet, parsing is done now.
#
# @return [Array<GameAchievement>] All achievements belonging to this game
def achievements
return unless public?
if @achievements.nil?
@achievements = Array.new
@xml_data['achievements']['achievement'].each do |achievement|
@achievements << GameAchievement.new(@steam_id64, @game.app_id, achievement)
end
@achievements_done = @achievements.reject{ |a| !a.unlocked? }.size
end
@achievements
end
# Returns the number of achievements done by this player
#
# If achievements haven't been parsed yet for this player and this game,
# parsing is done now.
#
# @return [Fixnum] The number of achievements completed
# @see #achievements
def achievements_done
achievements if @achievements_done.nil?
@achievements_done
end
# Returns the percentage of achievements done by this player
#
# If achievements haven't been parsed yet for this player and this game,
# parsing is done now.
#
# @return [Float] The percentage of achievements completed
# @see #achievements_done
def achievements_percentage
achievements_done.to_f / @achievements.size
end
# Returns the base Steam Communtiy URL for the stats contained in this object
#
# @return [String] The base URL used for queries on these stats
def base_url
self.class.base_url @custom_url || @steam_id64, @game.short_name || @game.app_id
end
# Returns whether this Steam ID is publicly accessible
#
# @return [Boolean] `true` if this Steam ID is publicly accessible
def public?
@privacy_state == 'public'
end
end