steam-trade 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/LICENSE +674 -674
- data/README.md +621 -621
- data/lib/Confirmation.rb +1 -1
- data/lib/EventCards.rb +89 -1
- data/lib/Guard.rb +7 -3
- data/lib/LoginExecutor.rb +156 -156
- data/lib/Trade.rb +36 -0
- data/lib/blueprints/byappid.json +1 -1
- data/lib/meta/version.rb +1 -1
- data/lib/steam-trade.rb +29 -7
- metadata +3 -4
- data/.gitignore +0 -10
data/lib/Confirmation.rb
CHANGED
@@ -86,7 +86,7 @@ module ConfirmationCommands
|
|
86
86
|
|
87
87
|
def send_confirmation(confirmationhash) ## tenth
|
88
88
|
tag = 'allow'
|
89
|
-
params = create_confirmation_params(
|
89
|
+
params = create_confirmation_params('conf') ## EXISTS
|
90
90
|
params['op'] = tag
|
91
91
|
params['cid'] = confirmationhash["data_confid"]
|
92
92
|
params['ck'] = confirmationhash["data_key"]
|
data/lib/EventCards.rb
CHANGED
@@ -106,7 +106,7 @@ module EventCommands
|
|
106
106
|
'origin' => 'https://steamcommunity.com',
|
107
107
|
'referer' => 'https://steamcommunity.com/saliengame/play/'
|
108
108
|
}
|
109
|
-
|
109
|
+
|
110
110
|
params = {
|
111
111
|
'gameid' => active_game,
|
112
112
|
'access_token' => game_token
|
@@ -154,4 +154,92 @@ module EventCommands
|
|
154
154
|
end
|
155
155
|
|
156
156
|
|
157
|
+
def cottage()
|
158
|
+
raise "must be logged in to use the command" if @logged == false
|
159
|
+
|
160
|
+
door_ids = []
|
161
|
+
Nokogiri::HTML(@session.get('https://store.steampowered.com/promotion/cottage_2018/').content).css('#alldoors_container').css('.cottage_doorset').each { |door|
|
162
|
+
next if door["class"].include?('cottage_door_open')
|
163
|
+
door_ids << door['data-door-id']
|
164
|
+
}
|
165
|
+
|
166
|
+
if door_ids.empty?
|
167
|
+
puts "There are no door to open for #{@username}"
|
168
|
+
return
|
169
|
+
end
|
170
|
+
|
171
|
+
|
172
|
+
door_ids.each { |id|
|
173
|
+
|
174
|
+
|
175
|
+
timestamp = Time.new.strftime("%Y-%m-%dT%H:%M:%S")
|
176
|
+
|
177
|
+
post_params = {
|
178
|
+
'sessionid' => store_cookie(),
|
179
|
+
'door_index' => id,
|
180
|
+
't' => timestamp,
|
181
|
+
'open_door' => true
|
182
|
+
}
|
183
|
+
|
184
|
+
post_headers = {
|
185
|
+
'Origin' => 'https://store.steampowered.com',
|
186
|
+
'Referer' => 'https://store.steampowered.com/promotion/cottage_2018/',
|
187
|
+
'User-Agent' => 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 OPR/57.0.3098.102',
|
188
|
+
'X-Requested-With' => 'XMLHttpRequest'
|
189
|
+
}
|
190
|
+
|
191
|
+
@session.post('https://store.steampowered.com/promotion/opencottagedoorajax' , post_params, post_headers)
|
192
|
+
|
193
|
+
}
|
194
|
+
|
195
|
+
end
|
196
|
+
|
197
|
+
def vote_2018()
|
198
|
+
text = @session.get('https://store.steampowered.com/SteamAwards/2018/').content
|
199
|
+
Nokogiri::HTML(text).css('.steamaward_categories_ctn')[0].css('.vote_category_bg').each { |container|
|
200
|
+
container['']
|
201
|
+
title = container.css(".category_title")[0].text.downcase
|
202
|
+
voteid = container.css(".category_nominations_ctn")[0]["data-voteid"]
|
203
|
+
|
204
|
+
nominees = []
|
205
|
+
voted = false
|
206
|
+
i = 1
|
207
|
+
container.css(".category_nomination").each { |nom|
|
208
|
+
(voted = true; break;) if nom["class"].include?('grayed_out_nomination')
|
209
|
+
|
210
|
+
nominees << nom["data-vote-appid"]
|
211
|
+
}
|
212
|
+
next if voted
|
213
|
+
(File.open('./error.html', 'w') {|f| f.puts text}; raise "no nominees selected if";) if nominees.compact!.empty?
|
214
|
+
appid = nominees[rand(nominees.length - 1)]
|
215
|
+
|
216
|
+
|
217
|
+
params = {
|
218
|
+
'voteid' => voteid,
|
219
|
+
'sessionid' => store_cookie(),
|
220
|
+
}
|
221
|
+
puts "voting for #{title}"
|
222
|
+
if title.include?('developer')
|
223
|
+
puts "switching sides"
|
224
|
+
params['appid'] = 0
|
225
|
+
params['developerid'] = appid
|
226
|
+
else
|
227
|
+
params['appid'] = appid
|
228
|
+
params['developerid'] = 0
|
229
|
+
end
|
230
|
+
post_headers = {
|
231
|
+
'Origin' => 'https://store.steampowered.com',
|
232
|
+
'Referer' => 'https://store.steampowered.com/SteamAwards/2018/',
|
233
|
+
'User-Agent' => 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 OPR/57.0.3098.102',
|
234
|
+
'X-Requested-With' => 'XMLHttpRequest'
|
235
|
+
}
|
236
|
+
@session.post('https://store.steampowered.com/salevote', params, post_headers)
|
237
|
+
puts "voted for #{title}"
|
238
|
+
sleep(2)
|
239
|
+
|
240
|
+
}
|
241
|
+
|
242
|
+
|
243
|
+
end
|
244
|
+
|
157
245
|
end
|
data/lib/Guard.rb
CHANGED
@@ -72,9 +72,13 @@ module GuardCommands
|
|
72
72
|
|
73
73
|
|
74
74
|
def generate_device_id()
|
75
|
-
|
76
|
-
|
77
|
-
|
75
|
+
if @android_id.nil?
|
76
|
+
hexed = Digest::SHA1.hexdigest(@steamid.to_s)
|
77
|
+
res = 'android:' + [hexed[0..7],hexed[8..11],hexed[12..15],hexed[16..19],hexed[20..31]].join('-')
|
78
|
+
return res
|
79
|
+
else
|
80
|
+
return @android_id
|
81
|
+
end
|
78
82
|
end
|
79
83
|
|
80
84
|
end
|
data/lib/LoginExecutor.rb
CHANGED
@@ -1,156 +1,156 @@
|
|
1
|
-
module LoginCommands
|
2
|
-
|
3
|
-
########################################################################################
|
4
|
-
private
|
5
|
-
def login()
|
6
|
-
response = @session.post('https://store.steampowered.com/login/getrsakey/', {'username' => @username}).content
|
7
|
-
data = pass_stamp(response,@password)
|
8
|
-
encrypted_password = data["password"]
|
9
|
-
timestamp = data["timestamp"]
|
10
|
-
repeater = 0
|
11
|
-
|
12
|
-
|
13
|
-
send = {
|
14
|
-
'password' => encrypted_password,
|
15
|
-
'username' => @username,
|
16
|
-
'twofactorcode' =>'', #update
|
17
|
-
'emailauth' => '',
|
18
|
-
'loginfriendlyname' => '',
|
19
|
-
'captchagid' => '-1',
|
20
|
-
'captcha_text' => '',
|
21
|
-
'emailsteamid' => '',
|
22
|
-
'rsatimestamp' => timestamp,
|
23
|
-
'remember_login' => @remember
|
24
|
-
}
|
25
|
-
login = @session.post('https://store.steampowered.com/login/dologin', send ).content
|
26
|
-
firstreq = JSON.parse(login)
|
27
|
-
|
28
|
-
raise "Incorrect username or password" if firstreq["message"] == "The account name or password that you have entered is incorrect."
|
29
|
-
|
30
|
-
|
31
|
-
until firstreq["success"] == true
|
32
|
-
sleep(0.3)
|
33
|
-
gid = '-1'
|
34
|
-
cap = ''
|
35
|
-
if firstreq['captcha_needed'] == true
|
36
|
-
gid = firstreq['captcha_needed']
|
37
|
-
File.delete("./#{username}_captcha.png") if File.exist?("./#{username}_captcha.png")
|
38
|
-
@session.get("https://store.steampowered.com/login/rendercaptcha?gid=#{gid}").save "./#{@username}_captcha.png"
|
39
|
-
puts "you need to write a captcha to continue"
|
40
|
-
puts "there is an image named #{@username}_captcha in the script directory"
|
41
|
-
puts "open it and write the captha here"
|
42
|
-
cap = gets.chomp
|
43
|
-
end
|
44
|
-
emailauth = ''
|
45
|
-
facode = ''
|
46
|
-
emailsteamid = ''
|
47
|
-
if firstreq['requires_twofactor'] == true
|
48
|
-
if @secret.nil?
|
49
|
-
puts "write 2FA code"
|
50
|
-
facode = gets.chomp
|
51
|
-
else
|
52
|
-
facode = fa(@secret,@time_difference)
|
53
|
-
end
|
54
|
-
elsif firstreq['emailauth_needed'] == true
|
55
|
-
emailsteamid = firstreq['emailsteamid']
|
56
|
-
puts "Guard code was sent to your email"
|
57
|
-
puts "write the code"
|
58
|
-
emailauth = gets.chomp
|
59
|
-
end
|
60
|
-
|
61
|
-
send = {
|
62
|
-
'password' => encrypted_password,
|
63
|
-
'username' => @username,
|
64
|
-
'twofactorcode' => facode, #update
|
65
|
-
'emailauth' => emailauth,
|
66
|
-
'loginfriendlyname' => '',
|
67
|
-
'captchagid' => gid,
|
68
|
-
'captcha_text' => cap,
|
69
|
-
'emailsteamid' => emailsteamid,
|
70
|
-
'rsatimestamp' => timestamp,
|
71
|
-
'remember_login' => @remember
|
72
|
-
}
|
73
|
-
output "attempting to login"
|
74
|
-
login = @session.post('https://store.steampowered.com/login/dologin', send ).content
|
75
|
-
firstreq = JSON.parse(login)
|
76
|
-
|
77
|
-
end
|
78
|
-
response = firstreq
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
if @steamid != nil && @steamid != response["transfer_parameters"]["steamid"]
|
85
|
-
puts "the steamid you provided does not belong to the account you entered"
|
86
|
-
puts "steamid will be overwritten"
|
87
|
-
@steamid = response["transfer_parameters"]["steamid"]
|
88
|
-
|
89
|
-
else
|
90
|
-
@steamid = response["transfer_parameters"]["steamid"]
|
91
|
-
end
|
92
|
-
|
93
|
-
|
94
|
-
response["transfer_urls"].each { |url|
|
95
|
-
@session.post(url, response["transfer_parameters"])
|
96
|
-
}
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
steampowered_sessionid = ''
|
101
|
-
@session.cookies.each { |c|
|
102
|
-
if c.name == "sessionid"
|
103
|
-
steampowered_sessionid = c.value
|
104
|
-
end
|
105
|
-
}
|
106
|
-
|
107
|
-
cookie = Mechanize::Cookie.new :domain => 'steamcommunity.com', :name =>'sessionid', :value =>steampowered_sessionid, :path => '/'
|
108
|
-
@session.cookie_jar << cookie
|
109
|
-
@loggedin = true
|
110
|
-
begin
|
111
|
-
text = Nokogiri::HTML(@session.get("https://steamcommunity.com/dev/apikey").content).css('#bodyContents_ex').css('p').first.text.
|
112
|
-
if text.include?('Registering for a Steam Web API Key will enable you to access many Steam features from your own website') == false
|
113
|
-
@api_key = text
|
114
|
-
end
|
115
|
-
rescue
|
116
|
-
output "Could not retrieve api_key"
|
117
|
-
end
|
118
|
-
|
119
|
-
if !@api_key.nil?
|
120
|
-
data = get_player_summaries(@steamid) if !@api_key.nil?
|
121
|
-
data.each { |element|
|
122
|
-
if element["steamid"].to_s == @steamid.to_s
|
123
|
-
@persona = element["personaname"]
|
124
|
-
end
|
125
|
-
}
|
126
|
-
end
|
127
|
-
output "logged in as #{@persona}"
|
128
|
-
output "your steamid is #{@steamid}"
|
129
|
-
output "loaded API_KEY : #{@api_key}" if !@api_key.nil?
|
130
|
-
end
|
131
|
-
########################################################################################
|
132
|
-
|
133
|
-
|
134
|
-
########################################################################################
|
135
|
-
def pass_stamp(give,password)
|
136
|
-
|
137
|
-
data = JSON::parse(give)
|
138
|
-
mod = data["publickey_mod"].hex
|
139
|
-
exp = data["publickey_exp"].hex
|
140
|
-
timestamp = data["timestamp"]
|
141
|
-
|
142
|
-
key = OpenSSL::PKey::RSA.new
|
143
|
-
if RUBY_VERSION.to_f <= 2.3
|
144
|
-
key.e = OpenSSL::BN.new(exp)
|
145
|
-
key.n = OpenSSL::BN.new(mod)
|
146
|
-
elsif RUBY_VERSION.to_f >= 2.4
|
147
|
-
#key.set_key(n, e, d)
|
148
|
-
key.set_key(OpenSSL::BN.new(mod), OpenSSL::BN.new(exp),nil)
|
149
|
-
end
|
150
|
-
ep = Base64.encode64(key.public_encrypt(password.force_encoding("utf-8"))).gsub("\n", '')
|
151
|
-
return {'password' => ep, 'timestamp' => timestamp }
|
152
|
-
end
|
153
|
-
########################################################################################
|
154
|
-
|
155
|
-
|
156
|
-
end
|
1
|
+
module LoginCommands
|
2
|
+
|
3
|
+
########################################################################################
|
4
|
+
private
|
5
|
+
def login()
|
6
|
+
response = @session.post('https://store.steampowered.com/login/getrsakey/', {'username' => @username}).content
|
7
|
+
data = pass_stamp(response,@password)
|
8
|
+
encrypted_password = data["password"]
|
9
|
+
timestamp = data["timestamp"]
|
10
|
+
repeater = 0
|
11
|
+
|
12
|
+
|
13
|
+
send = {
|
14
|
+
'password' => encrypted_password,
|
15
|
+
'username' => @username,
|
16
|
+
'twofactorcode' =>'', #update
|
17
|
+
'emailauth' => '',
|
18
|
+
'loginfriendlyname' => '',
|
19
|
+
'captchagid' => '-1',
|
20
|
+
'captcha_text' => '',
|
21
|
+
'emailsteamid' => '',
|
22
|
+
'rsatimestamp' => timestamp,
|
23
|
+
'remember_login' => @remember
|
24
|
+
}
|
25
|
+
login = @session.post('https://store.steampowered.com/login/dologin', send ).content
|
26
|
+
firstreq = JSON.parse(login)
|
27
|
+
|
28
|
+
raise "Incorrect username or password" if firstreq["message"] == "The account name or password that you have entered is incorrect."
|
29
|
+
|
30
|
+
|
31
|
+
until firstreq["success"] == true
|
32
|
+
sleep(0.3)
|
33
|
+
gid = '-1'
|
34
|
+
cap = ''
|
35
|
+
if firstreq['captcha_needed'] == true
|
36
|
+
gid = firstreq['captcha_needed']
|
37
|
+
File.delete("./#{username}_captcha.png") if File.exist?("./#{username}_captcha.png")
|
38
|
+
@session.get("https://store.steampowered.com/login/rendercaptcha?gid=#{gid}").save "./#{@username}_captcha.png"
|
39
|
+
puts "you need to write a captcha to continue"
|
40
|
+
puts "there is an image named #{@username}_captcha in the script directory"
|
41
|
+
puts "open it and write the captha here"
|
42
|
+
cap = gets.chomp
|
43
|
+
end
|
44
|
+
emailauth = ''
|
45
|
+
facode = ''
|
46
|
+
emailsteamid = ''
|
47
|
+
if firstreq['requires_twofactor'] == true
|
48
|
+
if @secret.nil?
|
49
|
+
puts "write 2FA code"
|
50
|
+
facode = gets.chomp
|
51
|
+
else
|
52
|
+
facode = fa(@secret,@time_difference)
|
53
|
+
end
|
54
|
+
elsif firstreq['emailauth_needed'] == true
|
55
|
+
emailsteamid = firstreq['emailsteamid']
|
56
|
+
puts "Guard code was sent to your email"
|
57
|
+
puts "write the code"
|
58
|
+
emailauth = gets.chomp
|
59
|
+
end
|
60
|
+
|
61
|
+
send = {
|
62
|
+
'password' => encrypted_password,
|
63
|
+
'username' => @username,
|
64
|
+
'twofactorcode' => facode, #update
|
65
|
+
'emailauth' => emailauth,
|
66
|
+
'loginfriendlyname' => '',
|
67
|
+
'captchagid' => gid,
|
68
|
+
'captcha_text' => cap,
|
69
|
+
'emailsteamid' => emailsteamid,
|
70
|
+
'rsatimestamp' => timestamp,
|
71
|
+
'remember_login' => @remember
|
72
|
+
}
|
73
|
+
output "attempting to login"
|
74
|
+
login = @session.post('https://store.steampowered.com/login/dologin', send ).content
|
75
|
+
firstreq = JSON.parse(login)
|
76
|
+
|
77
|
+
end
|
78
|
+
response = firstreq
|
79
|
+
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
if @steamid != nil && @steamid != response["transfer_parameters"]["steamid"]
|
85
|
+
puts "the steamid you provided does not belong to the account you entered"
|
86
|
+
puts "steamid will be overwritten"
|
87
|
+
@steamid = response["transfer_parameters"]["steamid"]
|
88
|
+
|
89
|
+
else
|
90
|
+
@steamid = response["transfer_parameters"]["steamid"]
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
response["transfer_urls"].each { |url|
|
95
|
+
@session.post(url, response["transfer_parameters"])
|
96
|
+
}
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
steampowered_sessionid = ''
|
101
|
+
@session.cookies.each { |c|
|
102
|
+
if c.name == "sessionid"
|
103
|
+
steampowered_sessionid = c.value
|
104
|
+
end
|
105
|
+
}
|
106
|
+
|
107
|
+
cookie = Mechanize::Cookie.new :domain => 'steamcommunity.com', :name =>'sessionid', :value =>steampowered_sessionid, :path => '/'
|
108
|
+
@session.cookie_jar << cookie
|
109
|
+
@loggedin = true
|
110
|
+
begin
|
111
|
+
text = Nokogiri::HTML(@session.get("https://steamcommunity.com/dev/apikey").content).css('#bodyContents_ex').css('p').first.text.split(' ')
|
112
|
+
if text.include?('Registering for a Steam Web API Key will enable you to access many Steam features from your own website') == false
|
113
|
+
@api_key = text[1]
|
114
|
+
end
|
115
|
+
rescue
|
116
|
+
output "Could not retrieve api_key"
|
117
|
+
end
|
118
|
+
|
119
|
+
if !@api_key.nil?
|
120
|
+
data = get_player_summaries(@steamid) if !@api_key.nil?
|
121
|
+
data.each { |element|
|
122
|
+
if element["steamid"].to_s == @steamid.to_s
|
123
|
+
@persona = element["personaname"]
|
124
|
+
end
|
125
|
+
}
|
126
|
+
end
|
127
|
+
output "logged in as #{@persona}"
|
128
|
+
output "your steamid is #{@steamid}"
|
129
|
+
output "loaded API_KEY : #{@api_key}" if !@api_key.nil?
|
130
|
+
end
|
131
|
+
########################################################################################
|
132
|
+
|
133
|
+
|
134
|
+
########################################################################################
|
135
|
+
def pass_stamp(give,password)
|
136
|
+
|
137
|
+
data = JSON::parse(give)
|
138
|
+
mod = data["publickey_mod"].hex
|
139
|
+
exp = data["publickey_exp"].hex
|
140
|
+
timestamp = data["timestamp"]
|
141
|
+
|
142
|
+
key = OpenSSL::PKey::RSA.new
|
143
|
+
if RUBY_VERSION.to_f <= 2.3
|
144
|
+
key.e = OpenSSL::BN.new(exp)
|
145
|
+
key.n = OpenSSL::BN.new(mod)
|
146
|
+
elsif RUBY_VERSION.to_f >= 2.4
|
147
|
+
#key.set_key(n, e, d)
|
148
|
+
key.set_key(OpenSSL::BN.new(mod), OpenSSL::BN.new(exp),nil)
|
149
|
+
end
|
150
|
+
ep = Base64.encode64(key.public_encrypt(password.force_encoding("utf-8"))).gsub("\n", '')
|
151
|
+
return {'password' => ep, 'timestamp' => timestamp }
|
152
|
+
end
|
153
|
+
########################################################################################
|
154
|
+
|
155
|
+
|
156
|
+
end
|
data/lib/Trade.rb
CHANGED
@@ -65,9 +65,11 @@ module TradeCommands
|
|
65
65
|
sleep(0.6)
|
66
66
|
responsehash = response.merge(send_trade_allow_request(response["tradeofferid"]))
|
67
67
|
output "offer confirmed " + response["tradeofferid"]
|
68
|
+
return responsehash
|
68
69
|
else
|
69
70
|
output "cannot confirm trade automatically, no shared secret given"
|
70
71
|
output "Manual confirmation is needed"
|
72
|
+
return nil
|
71
73
|
end
|
72
74
|
end
|
73
75
|
|
@@ -90,8 +92,42 @@ module TradeCommands
|
|
90
92
|
|
91
93
|
|
92
94
|
|
95
|
+
def sell_items(items, price)
|
96
|
+
raise "no account logged in, #{self} " if @loggedin == false
|
97
|
+
raise "Must given array" if items.class != Array
|
93
98
|
|
94
99
|
|
100
|
+
headers = {
|
101
|
+
'Origin' => 'https://steamcommunity.com',
|
102
|
+
'Referer' => 'https://steamcommunity.com/id/SimplifiedPact/inventory/',
|
103
|
+
'User-Agent' => 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36 OPR/54.0.2952.54',
|
104
|
+
}
|
105
|
+
|
106
|
+
items.each { |asset|
|
107
|
+
|
108
|
+
asset['sessionid'] = sessionid_cookie()
|
109
|
+
asset['price'] = price
|
110
|
+
verd = {'sucess' => false}
|
111
|
+
tries = 0
|
112
|
+
i = 0
|
113
|
+
until verd['success'] == true || tries == 2
|
114
|
+
resp = @session.post('https://steamcommunity.com/market/sellitem/', asset, headers)
|
115
|
+
|
116
|
+
verd = JSON.parse(resp.content)
|
117
|
+
|
118
|
+
if verd['success'] == false
|
119
|
+
break if verd['message'].include?('You already have a listing for this') || verd['message'].include?('We were unable to contact')
|
120
|
+
tries += 1
|
121
|
+
sleep(10)
|
122
|
+
else
|
123
|
+
i += 1
|
124
|
+
puts "#{i} / #{items.length} sold"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
sleep(1)
|
128
|
+
}
|
129
|
+
end
|
130
|
+
|
95
131
|
|
96
132
|
|
97
133
|
|