steam-trade 0.2.1 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a0bd2f1adc5cad7bf56acff4e6f8e19548d8c302
4
- data.tar.gz: 3a8c9e35440d23c3db1f44ae05d328b0644d816e
3
+ metadata.gz: a214ab20a7c1cba3c0147c74099425a334b28ec3
4
+ data.tar.gz: 7b7d54c1e6b45ceb7097a9c5d9e3b19d03a1f89b
5
5
  SHA512:
6
- metadata.gz: ea1ac8bc6445fd8d90267e8c817ca717ba4eab9812d656d0a646353a8f5e6b9d7ef0bfaa56b27661aa343243c412285cb135f03c2ae80037756baae49e9acb52
7
- data.tar.gz: 71202a2e7c02caa910271880e75eafc8cee5ab1426779a0410aaddce19b9047177a95f258f29c5a6c6512d54385ceccb47719f148010744889b79e20cfe29adf
6
+ metadata.gz: 83c85b9d9f2ffe433820c37bf7258d99363229cc0ff151e01cb00e678b897b23238739bed86fe3a79377fed71aa2c14317df4c65e98325451c02b36ffbd00484
7
+ data.tar.gz: a6045c9e2fbc067bc8db2b1c9af4c3a032bee4fcd6a5a4d1d1cd0b954809357c760b71c27798523f9b4458b08ce7eacdca6965b493f6a589958d6bcb1988693b
data/README.md CHANGED
@@ -1,4 +1,7 @@
1
- # steam-trade V0.2.0
1
+ # steam-trade V0.2.3
2
+
3
+ **PLEASE IF SOMETHING DOES NOT WORK PROPERLY MAKE A GITHUB ISSUE**
4
+
2
5
  Please check constantly for updates cause i'm still making this gem.
3
6
 
4
7
  This gem simplifes/allows sending steam trade offers programmatically.
@@ -7,6 +10,16 @@ this gem is primarly for trading cards, tho can be used to CS:GO and other games
7
10
 
8
11
  # Changelog
9
12
  ```
13
+ 0.2.3:
14
+ - hotfix
15
+
16
+ 0.2.2:
17
+ - fixed issues with ruby 2.4+
18
+ - added class methods for fa(), normal_get_inventory(), raw_get_inventory, sets_count()
19
+
20
+ 0.2.1:
21
+ - many many bugs fixed
22
+
10
23
  0.2.0:
11
24
  - hotfix
12
25
 
@@ -50,7 +63,7 @@ this gem is primarly for trading cards, tho can be used to CS:GO and other games
50
63
  - [Logging-in](#logging-in)
51
64
  - [Hander.new() (this is how you login)](#handlernew)
52
65
  - [Handler.new() (normal login)](#handlernewusername-passwordshared_secrettime_differenceremember_me)
53
- - [Handler.new() (cookies login)](#handlernewcookies_hash)
66
+ - [Handler.new() (cookies login)](#handlernewcookies_hashshared_secrettime_differenceremember_me)
54
67
  - [get_auth_cookies()](#get_auth_cookies)
55
68
  - [mobile_info()](#mobile_infoidentity_secret)
56
69
  - [Getting someone's inventory](#getting-someones-inventory)
@@ -125,13 +138,19 @@ puts account.fa('v3dWNq2Ncutc7RelwRVXswT8CJX=v3dWNq2Ncutc7WelwRVXswT8CJk=') => r
125
138
 
126
139
  ```
127
140
 
128
- ##### `Handler.new(cookies_hash)`
141
+ ##### `Handler.new(cookies_hash,shared_secret,time_difference,remember_me)`
129
142
  - `cookies_hash` is hash containing `steamLogin`, `steamLoginSecure` and `steamMachineAuth` cookies.
130
143
  this can be used with `get_auth_cookies()` for faster login.
144
+ - `shared_secret` is used to generate steam authentication codes so you won't have to write them manually each time you login.
145
+ - `time_difference`is the difference between your time and steam servers, this affects how 2FA codes are generated (**this MUST BE an integer**)
146
+ - `remember_me` is a boolean used to indicate whether you want cookies which expire shortly if set to **false** or stay valid for weeks if set to **true**
147
+
131
148
 
132
149
  ```ruby
133
150
  require 'steam-trade'
134
151
  account = Handler.new(JSON.parse(File.read('./creds.json'))) # creds.json is created by get_auth_cookies()
152
+
153
+ account = Handler.new(JSON.parse(File.read('./creds.json')), 'shared_secret', 50)
135
154
  ```
136
155
 
137
156
  #### `get_auth_cookies()`
@@ -168,6 +187,8 @@ you might want to read this [guide](https://dev.doctormckay.com/topic/332-identi
168
187
 
169
188
  ```ruby
170
189
  require 'steam-trade'
190
+ inventory = Handler.normal_get_inventory("nomg3r")
191
+
171
192
 
172
193
  logged = Handler.new('username','password','shared_secret')
173
194
  logged.mobile_info('identity_secret')
@@ -213,6 +234,9 @@ This command will return a hash nearly identitical to the one received from stea
213
234
 
214
235
  ```ruby
215
236
  require 'steam-trade'
237
+ inv = Handler.raw_get_inventory("nomg3r")
238
+
239
+
216
240
  logged = Handler.new('username','password','shared_secret')
217
241
  inv = logged.raw_get_inventory() #works
218
242
  inv = logged.raw_get_inventory(false) # returns non trimmed
@@ -422,6 +446,8 @@ polling = Thread.new(logged) { |logged|
422
446
  - `'totalcards'` is an integer equals to the number of non-foil cards account for
423
447
  ```ruby
424
448
  require 'steam-trade'
449
+ data = Handler.sets_count("CardExchange")
450
+
425
451
 
426
452
  logged = Handler.new('username','password','shared_secret')
427
453
  logged.mobile_info('identity_secret')
@@ -459,6 +485,8 @@ handler.update_blueprint()
459
485
  **NOTE**: using this command with a new shared_secret will not change/set the current saved shared_secret for the account
460
486
  ```ruby
461
487
  require 'steam-trade'
488
+ puts Hander.fa('random_shared_secret')
489
+
462
490
 
463
491
  logged = Handler.new('username','password','inital_shared_secret')
464
492
  puts logged.fa() #=> random code for your account
data/lib/Badge.rb CHANGED
@@ -27,6 +27,7 @@ module BadgeCommands
27
27
  targetname = ''
28
28
  end
29
29
  }
30
+
30
31
  hash = raw_get_inventory(steamid)
31
32
  sorted = {}
32
33
  classxinstance = {}
@@ -198,6 +199,7 @@ module BadgeCommands
198
199
  w_title = bigdata[appid]['title']
199
200
  text << " #{w_title}, sets = #{sets}, appid = #{appid}"
200
201
  hashofcards[appid].each { |cardname, owned|
202
+ next if !owned.is_a(Numeric)
201
203
  text << "#{cardname} xxx #{owned}"
202
204
  }
203
205
  text << ""
@@ -207,6 +209,203 @@ module BadgeCommands
207
209
  output "badges.txt has been created"
208
210
  end
209
211
 
212
+ def self.included(base)
213
+ base.extend(BadgeCommands_ClassMethods)
214
+ end
215
+
216
+ module BadgeCommands_ClassMethods
217
+ @@libdir = Util.gem_libdir
218
+ def sets_count(steamid, use_nonmarketable = true)
219
+
220
+
221
+
222
+
223
+ steamid,token = verify_profileid_or_trade_link_or_steamid(steamid)
224
+
225
+ hash = raw_get_inventory(steamid)
226
+ sorted = {}
227
+ classxinstance = {}
228
+
229
+ hash["descriptions"].delete_if {|desc|
230
+ conc = desc["classid"] + "_" + desc["instanceid"]
231
+ classxinstance[conc] = desc
232
+ true
233
+ }
234
+
235
+
236
+
237
+ hash["assets"].each { |asset|
238
+ identity = asset["classid"] + "_" + asset["instanceid"]
239
+ assetdesc = classxinstance[identity]
240
+ if use_nonmarketable == false
241
+ if assetdesc["marketable"] == 0 || assetdesc["tags"][-1]["localized_tag_name"] != "Trading Card" || assetdesc["tags"][-2]["localized_tag_name"] == "Foil"
242
+ next
243
+ end
244
+ else
245
+ if assetdesc["tags"][-1]["localized_tag_name"] != "Trading Card" ||assetdesc["tags"][-2]["localized_tag_name"] == "Foil"
246
+ next
247
+ end
248
+ end
249
+
250
+ name = assetdesc["name"].sub(" (Trading Card)", "")
251
+ appid =assetdesc["market_fee_app"].to_s
252
+ if sorted.has_key?(appid) == true
253
+ if sorted[appid].has_key?(name) == true
254
+ sorted[appid][name] = sorted[appid][name] + 1
255
+ elsif sorted[appid].has_key?(name) == false
256
+ sorted[appid][name] = 1
257
+ end
258
+ elsif sorted.has_key?(appid) == false
259
+ sorted[appid] = {}
260
+ sorted[appid][name] = 1
261
+ end
262
+ }
263
+
264
+ bigdata = JSON.parse(File.read("#{@@libdir}blueprints/byappid.json",:external_encoding => 'utf-8',:internal_encoding => 'utf-8'))
265
+
266
+ counted = {}
267
+
268
+ sorted.each { |appid,cards|
269
+ begin
270
+ counted[appid.to_s] = bigdata[appid].merge(cards)
271
+ rescue
272
+ output "badges blueprint does not include #{appid}"
273
+ end
274
+ }
275
+
276
+ setsowned = {}
277
+ numberofsets = 0
278
+ total_non_foil = 0
279
+
280
+ counted.each { |appid,cards|
281
+ lowest = 9999
282
+ cards.each { |cardname, amount|
283
+ next if amount.class == String # apptitle
284
+ if amount < lowest then lowest = amount end
285
+ total_non_foil = total_non_foil + amount
286
+ }
287
+ setsowned[appid.to_s] = lowest
288
+ numberofsets = numberofsets + lowest
289
+ }
290
+
291
+ persona = ''
292
+ write_badges(counted,setsowned,numberofsets,total_non_foil, use_nonmarketable,persona,steamid)
293
+ if use_nonmarketable == false
294
+ return {'sets' => counted, 'appxsets' => setsowned, 'totalsets' => numberofsets, 'totalcards' => total_non_foil, 'marketable' => false}
295
+ else
296
+ return {'sets' => counted, 'appxsets' => setsowned, 'totalsets' => numberofsets, 'totalcards' => total_non_foil, 'marketable' => true}
297
+ end
298
+ end
299
+
300
+
301
+
302
+
303
+ def update_blueprint()
304
+ session = Mechanize.new
305
+
306
+ session.pre_connect_hooks << lambda do |agent, request|
307
+ request['Origin'] = 'http://steam.tools'
308
+ request['Referer'] = 'http://steam.tools/cards/'
309
+ request['User-Agent'] ='Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36 OPR/52.0.2871.99'
310
+ end
311
+
312
+
313
+ pag = session.get('http://cdn.steam.tools/data/set_data.json')
314
+ data = JSON.parse(pag.content)
315
+ old = JSON.parse(File.read("#{@@libdir}blueprints/byappid.json" ,:external_encoding => 'utf-8',:internal_encoding => 'utf-8'))
316
+
317
+ newapps = []
318
+ data["sets"].each { |set|
319
+ newapps << set['appid']
320
+ }
321
+ get = []
322
+ haveapps = old.keys
323
+ newapps.each { |app|
324
+ get << app if haveapps.include?(app) == false
325
+ }
326
+
327
+ progress = 0
328
+ error = 0
329
+ (output("your blueprint is up-to-date");return) if get.length.zero?
330
+ get.each {|app|
331
+ begin
332
+ card = {}
333
+ steam_nokogiri = Nokogiri::HTML(session.get("http://www.steamcardexchange.net/index.php?inventorygame-appid-#{app}").content)
334
+ title = steam_nokogiri.css('h2[class=empty]').text.force_encoding(Encoding::UTF_8)
335
+ steam_nokogiri.css('div[class=name-image-container]').css('span').each do |e|
336
+ card[e.text.force_encoding(Encoding::UTF_8)] = 0
337
+ end
338
+ card['title'] = title
339
+ full_data = card
340
+
341
+ old[app] = full_data
342
+ File.open("#{@@libdir}blueprints/byappid.json", 'w:UTF-8') {|f| f.puts old.to_json}
343
+
344
+ progress = progress + 1
345
+ output "#{progress} / #{get.length} done, error = #{error}"
346
+ rescue Exception => e
347
+ File.open("#{@@libdir}blueprints/byappid.json", 'w:UTF-8') {|f| f.puts old.to_json}
348
+ error = error + 1
349
+ progress = progress + 1
350
+ output "#{progress} / #{get.length} done, error = #{error}"
351
+ output "error occured saved data"
352
+ raise e
353
+ end
354
+ }
355
+
356
+
357
+ end
358
+
359
+
360
+
361
+
362
+
363
+ private
364
+ def write_badges(hashofcards,eachappidsets,totalsets,total_non_foil,use_nonmarketable,persona,steamid)
365
+ if persona == ''
366
+ filename = steamid
367
+ else
368
+ filename = persona
369
+ end
370
+
371
+
372
+ bigdata = JSON.parse(File.read("#{@@libdir}blueprints/byappid.json",:external_encoding => 'utf-8',:internal_encoding => 'utf-8'))
373
+ eachappidsets = eachappidsets.sort_by do |k,v|
374
+ v
375
+ end
376
+ eachappidsets.reverse!
377
+ output "Writing the badges to #{filename}_badges.txt "
378
+ text = []
379
+ text << "for #{persona}(#{steamid})"
380
+ if use_nonmarketable == false
381
+ text << "only marketable cards are counted"
382
+ text << "total non-foil trading cards #{total_non_foil}"
383
+ else
384
+ text << "total non-foil trading cards #{total_non_foil}"
385
+ text << "all cards counted including non-marketable"
386
+ end
387
+
388
+
389
+ text << "total sets in target account #{totalsets}"
390
+ text << ""
391
+ text << ""
392
+ eachappidsets.each { |appid, sets|
393
+ w_title = bigdata[appid]['title']
394
+ text << " #{w_title}, sets = #{sets}, appid = #{appid}"
395
+ hashofcards[appid].each { |cardname, owned|
396
+ next if !owned.is_a?(Numeric)
397
+ text << "#{cardname} xxx #{owned}"
398
+ }
399
+ text << ""
400
+ text << ""
401
+ }
402
+ File.open("./#{filename}_badges.txt",'w:UTF-8') {|f| f.puts text}
403
+ output "badges.txt has been created"
404
+ end
405
+
406
+
407
+
408
+ end
210
409
 
211
410
 
212
411
  end
data/lib/Guard.rb CHANGED
@@ -30,6 +30,40 @@ module GuardCommands
30
30
 
31
31
  end
32
32
 
33
+ def self.included(base)
34
+ base.extend(Guard_ClassMethods)
35
+ end
36
+
37
+ module Guard_ClassMethods
38
+ def fa(shared_secret,time_difference = 0)
39
+ raise "No shared_secret given" if shared_secret == nil # cause upon initialization @secret = nil
40
+ timestamp = Time.new.to_i + time_difference
41
+ math = timestamp.to_i / 30
42
+ math = math.to_i
43
+ time_buffer =[math].pack('Q>')
44
+
45
+ hmac = OpenSSL::HMAC.digest('sha1', Base64.decode64(shared_secret), time_buffer)
46
+
47
+ start = hmac[19].ord & 0xf
48
+ last = start + 4
49
+ pre = hmac[start..last]
50
+ fullcode = pre.unpack('I>')[0] & 0x7fffffff
51
+
52
+ chars = '23456789BCDFGHJKMNPQRTVWXY'
53
+ code= ''
54
+ for looper in 0..4 do
55
+ copy = fullcode #divmod
56
+ i = copy % chars.length #divmod
57
+ fullcode = copy / chars.length #divmod
58
+ code = code + chars[i]
59
+ end
60
+ return code
61
+
62
+ end
63
+
64
+
65
+ end
66
+
33
67
  private
34
68
  def generate_confirmation_key(tag_string, time_stamp)
35
69
  buffer = [time_stamp].pack('Q>') + tag_string.encode('ascii')
data/lib/Inventory.rb CHANGED
@@ -300,5 +300,204 @@ module InventoryCommands
300
300
  end
301
301
 
302
302
 
303
+ def self.included(base)
304
+ base.extend(Inventory_ClassMethods)
305
+ end
306
+
307
+ module Inventory_ClassMethods
308
+ @@libdir = Util.gem_libdir
309
+ @@session = Mechanize.new
310
+ def normal_get_inventory(steamid ,appid = 753)
311
+ appid = appid.to_s
312
+ context = 6
313
+ e
314
+ if appid.to_s != "753"
315
+ context = 2
316
+ end
317
+ #end verify given another game
318
+ # end verify given appid only
319
+ #verify trade link
320
+ steamid,token = verify_profileid_or_trade_link_or_steamid(steamid)
321
+ raise "invalid steamid : #{steamid}, length of received :: #{steamid.to_s.length}, normal is 17" if steamid.to_s.length != 17
322
+ ## verify appid
323
+ if ["753","730",'570','440'].include?(appid.to_s) == false
324
+ allgames = JSON.parse(File.read("#{@@libdir}blueprints/game_inv_list.json"))
325
+ raise "invalid appid: #{appid}" if allgames.include?(appid.to_s) == false
326
+ end
327
+ ## end verify appid
328
+
329
+ items = []
330
+ last_id = 0
331
+ until last_id == false
332
+ received = get_inventory_chunk_normal_way(appid,context,steamid,last_id)
333
+ last_id = received['new_last_id']
334
+ items = items + received['assets']
335
+ output "loaded #{items.length}"
336
+ end
337
+
338
+ output "total loaded #{items.length} asset"
339
+
340
+
341
+ return items
342
+ end ##end normal get
343
+
344
+ ###
345
+
346
+
347
+ def get_inventory_chunk_normal_way(appid,context,steamid,last_id)
348
+ html = ''
349
+ tries = 1
350
+
351
+ until html != ''
352
+ begin
353
+ html = @@session.get("https://steamcommunity.com/inventory/#{steamid}/#{appid}/#{context}?start_assetid=#{last_id}&count=5000").content
354
+ rescue
355
+ raise "Cannot get inventory, tried 3 times" if tries == 3
356
+ tries = tries + 1
357
+ sleep(0.5)
358
+ end
359
+ end
360
+
361
+
362
+ get = JSON.parse(html)
363
+ raise "something totally unexpected happened while getting inventory with appid #{appid} of steamid #{steamid} with contextid #{context}" if get.key?("error") == true
364
+ if get["total_inventory_count"] == 0
365
+ output "EMPTY :: inventory with appid #{appid} of steamid #{steamid} with contextid #{context}"
366
+ return {'assets' => [], 'new_last_id' =>false}
367
+ end
368
+ if get.keys[3].to_s == "last_assetid"
369
+
370
+ new_last_id = get.values[3].to_s
371
+
372
+ else
373
+ new_last_id = false
374
+
375
+ end
376
+
377
+ assets = get["assets"]
378
+ descriptions = get["descriptions"]
379
+
380
+
381
+ descriptions_classids = {} ###sorting descriptions by key value || key is classid of the item's description
382
+ descriptions.each {|description|
383
+ classidxinstance = description["classid"] + '_' + description["instanceid"] # some items has the same classid but different instane id
384
+ descriptions_classids[classidxinstance] = description
385
+ }
386
+
387
+ assets.each { |asset| ## merging assets with names
388
+ classidxinstance = asset["classid"] + '_' + asset["instanceid"]
389
+ asset.replace(asset.merge(descriptions_classids[classidxinstance]))
390
+ }
391
+
392
+
393
+ return {'assets' => assets, 'new_last_id' =>new_last_id}
394
+
395
+ end ## end inventory get normal
396
+
397
+
398
+
399
+ def raw_get_inventory(steamid, *params)#steamid = @steamid ,appid = 753, trim = true
400
+ raise "expected 2 paramters, given #{params.length}"if params.length > 2
401
+ appid = 753
402
+ trim = true
403
+ context = 6
404
+ v = params.length
405
+ if params.length == 2
406
+ (appid = params[0]; v= v - 1;) if (3..6).to_a.include?(params[0].to_i.to_s.length)
407
+ (trim = params[1]; v= v - 1;) if [TrueClass,FalseClass].include?(params[1].class)
408
+ elsif params.length == 1
409
+ (appid = params[0]; v= v - 1;) if (3..6).to_a.include?(params[0].to_i.to_s.length)
410
+ (trim = params[0]; v= v - 1;) if [TrueClass,FalseClass].include?(params[0].class)
411
+ end
412
+ raise "invalid params given" if v != 0
413
+
414
+ steamid,token = verify_profileid_or_trade_link_or_steamid(steamid)
415
+ raise "invalid steamid : #{steamid}, length of received :: #{steamid.to_s.length}, normal is 17" if steamid.to_s.length != 17
416
+ ## verify appid
417
+ if ["753","730",'570','440'].include?(appid.to_s) == false
418
+ allgames = JSON.parse(File.read("#{@libdir}blueprints/game_inv_list.json"))
419
+ raise "invalid appid: #{appid}" if allgames.include?(appid.to_s) == false
420
+ end
421
+ ## end verify appid
422
+
423
+ if appid.to_s != "753"
424
+ context = 2
425
+ end
426
+
427
+
428
+ last_id = 0
429
+ hash = {"assets" => [], "descriptions" => []}
430
+ until last_id == false
431
+ received = get_inventory_chunk_raw_way(appid,context,steamid,last_id,trim)
432
+ last_id = received['new_last_id']
433
+ hash["assets"] = hash["assets"] + received['assets']
434
+ hash["descriptions"] = hash["descriptions"] + received["descriptions"]
435
+ output "loaded #{hash["assets"].length}"
436
+ end
437
+
438
+ output "total loaded #{hash["assets"].length} asset"
439
+
440
+
441
+ return hash
442
+ end
443
+
444
+
445
+
446
+
447
+ def get_inventory_chunk_raw_way(appid,context,steamid,last_id,trim)
448
+
449
+
450
+ html = ''
451
+ tries = 1
452
+
453
+ until html != ''
454
+ begin
455
+ html = @@session.get("https://steamcommunity.com/inventory/#{steamid}/#{appid}/#{context}?start_assetid=#{last_id}&count=5000").content
456
+ rescue
457
+ raise "Cannot get inventory, tried 3 times" if tries == 3
458
+ tries = tries + 1
459
+ sleep(0.5)
460
+ end
461
+ end
462
+
463
+ get = JSON.parse(html)
464
+ raise "something totally unexpected happened while getting inventory with appid #{appid} of steamid #{steamid} with contextid #{context}" if get.key?("error") == true
465
+ if get["total_inventory_count"] == 0
466
+ output "EMPTY :: inventory with appid #{appid} of steamid #{steamid} with contextid #{context}"
467
+ return {'assets' => [], "descriptions" => [], 'new_last_id' =>false}
468
+ end
469
+ if get.keys[3].to_s == "last_assetid"
470
+
471
+ new_last_id = get.values[3].to_s
472
+
473
+ else
474
+ new_last_id = false
475
+
476
+ end
477
+
478
+ assets = get["assets"]
479
+ descriptions = get["descriptions"]
480
+ if trim == true
481
+ descriptions.each { |desc|
482
+ desc.delete_if {|key, value| key != "appid" && key != "classid" && key != "instanceid" && key != "tags" && key != "type" && key != "market_fee_app" && key != "marketable" &&key != "name" }
483
+ desc["tags"].delete_at(0)
484
+ desc["tags"].delete_at(0)
485
+ }
486
+ end
487
+
488
+ return {'assets' => get["assets"], "descriptions" => get["descriptions"], 'new_last_id' =>new_last_id}
489
+
490
+ end
491
+
492
+
493
+ end
494
+
495
+
496
+
497
+
498
+
499
+
500
+
501
+
303
502
 
304
503
  end
data/lib/LoginExecutor.rb CHANGED
@@ -8,45 +8,79 @@ module LoginCommands
8
8
  encrypted_password = data["password"]
9
9
  timestamp = data["timestamp"]
10
10
  repeater = 0
11
- until repeater == true
12
- if @secret != nil
13
- guardcode = fa(@secret,@time_difference)
14
- else
15
- puts "please write your 2FA code"
16
- guardcode = gets.chomp
17
- end
18
11
 
19
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
+
20
61
  send = {
21
62
  'password' => encrypted_password,
22
63
  'username' => @username,
23
- 'twofactorcode' =>guardcode, #update
24
- 'emailauth' => '',
64
+ 'twofactorcode' => facode, #update
65
+ 'emailauth' => emailauth,
25
66
  'loginfriendlyname' => '',
26
- 'captchagid' => '-1',
27
- 'captcha_text' => '',
28
- 'emailsteamid' => '',
67
+ 'captchagid' => gid,
68
+ 'captcha_text' => cap,
69
+ 'emailsteamid' => emailsteamid,
29
70
  'rsatimestamp' => timestamp,
30
71
  'remember_login' => @remember
31
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
+
32
81
 
33
- login = @session.post('https://store.steampowered.com/login/dologin', send )
34
- response = JSON::parse(login.body)
35
- output "logging-in"
36
- if response["success"] == true
37
- repeater = true
38
- elsif repeater == 3
39
- raise "Login failed username: #{@username}, password: #{@password}, shared_scret: #{@secret} tried 3 times"
40
- else
41
- print response
42
- puts "re-trying to login"
43
- puts "sleeping for 6 seconds"
44
- sleep(6)
45
- repeater = repeater + 1
46
- end
47
82
 
48
83
 
49
- end
50
84
  if @steamid != nil && @steamid != response["transfer_parameters"]["steamid"]
51
85
  puts "the steamid you provided does not belong to the account you entered"
52
86
  puts "steamid will be overwritten"
@@ -73,8 +107,11 @@ module LoginCommands
73
107
  cookie = Mechanize::Cookie.new :domain => 'steamcommunity.com', :name =>'sessionid', :value =>steampowered_sessionid, :path => '/'
74
108
  @session.cookie_jar << cookie
75
109
  @loggedin = true
76
- @api_key = Nokogiri::HTML(@session.get("https://steamcommunity.com/dev/apikey").content).css('#bodyContents_ex').css('p').first.text.sub('Key: ','')
77
-
110
+ begin
111
+ @api_key = Nokogiri::HTML(@session.get("https://steamcommunity.com/dev/apikey").content).css('#bodyContents_ex').css('p').first.text.sub('Key: ','')
112
+ rescue
113
+ output "Could not retrieve api_key"
114
+ end
78
115
  data = get_player_summaries(@steamid)
79
116
  data.each { |element|
80
117
  if element["steamid"].to_s == @steamid.to_s
@@ -83,7 +120,7 @@ module LoginCommands
83
120
  }
84
121
  output "logged in as #{@persona}"
85
122
  output "your steamid is #{@steamid}"
86
- output "loaded API_KEY : #{@api_key}"
123
+ output "loaded API_KEY : #{@api_key}" if !@api_key.nil?
87
124
  end
88
125
  ########################################################################################
89
126
 
@@ -97,8 +134,13 @@ module LoginCommands
97
134
  timestamp = data["timestamp"]
98
135
 
99
136
  key = OpenSSL::PKey::RSA.new
100
- key.e = OpenSSL::BN.new(exp)
101
- key.n = OpenSSL::BN.new(mod)
137
+ if RUBY_VERSION.to_f <= 2.3
138
+ key.e = OpenSSL::BN.new(exp)
139
+ key.n = OpenSSL::BN.new(mod)
140
+ elsif RUBY_VERSION.to_f >= 2.4
141
+ #key.set_key(n, e, d)
142
+ key.set_key(OpenSSL::BN.new(mod), OpenSSL::BN.new(exp),nil)
143
+ end
102
144
  ep = Base64.encode64(key.public_encrypt(password.force_encoding("utf-8"))).gsub("\n", '')
103
145
  return {'password' => ep, 'timestamp' => timestamp }
104
146
  end
data/lib/Misc.rb CHANGED
@@ -34,7 +34,7 @@ module MiscCommands
34
34
 
35
35
 
36
36
 
37
- private
37
+
38
38
  def partner_id_to_steam_id(account_id)
39
39
  unknown_constant = 17825793 # or 0x1100001 idk wtf is this but ....
40
40
  first_bytes = [account_id.to_i].pack('i>')
@@ -43,10 +43,11 @@ module MiscCommands
43
43
  return collect.unpack('Q>')[0].to_s
44
44
  end
45
45
 
46
+
46
47
  def output(message)
47
48
  time = Time.new
48
49
  add = time.strftime("%d-%m-%Y %H:%M:%S")
49
- puts "#{add} :: #{message}" if @messages == true
50
+ puts "#{add} :: #{message}" if message != ''
50
51
  end
51
52
 
52
53
  def verify_profileid_or_trade_link_or_steamid(steamid)
@@ -74,22 +75,18 @@ module MiscCommands
74
75
  begin
75
76
  value = @session.cookie_jar.jar["steamcommunity.com"]["/"]["sessionid"].value
76
77
  rescue
77
- value = nil
78
- end
79
- if value == nil
80
- begin
81
- value = @session.cookie_jar.jar["store.steampowered.com"]["/"]["sessionid"].value
82
- rescue
83
- value = nil
84
- end
78
+ @session.get('http://steamcommunity.com')
79
+ value = @session.cookie_jar.jar["steamcommunity.com"]["/"]["sessionid"].value
85
80
  end
81
+ return value
82
+ end
86
83
 
87
- if value == nil
88
- @session.cookies.each { |c|
89
- if c.name == "sessionid"
90
- value = c.value
91
- end
92
- }
84
+ def store_cookie()
85
+ begin
86
+ value = @session.cookie_jar.jar["store.steampowered.com"]["/"]["sessionid"].value
87
+ rescue
88
+ @session.get('http://store.steampowered.com')
89
+ value = @session.cookie_jar.jar["store.steampowered.com"]["/"]["sessionid"].value
93
90
  end
94
91
  return value
95
92
  end
@@ -110,6 +107,52 @@ module MiscCommands
110
107
  end
111
108
 
112
109
 
110
+
111
+
112
+ def self.included(base)
113
+ base.extend(Misc_ClassMethods)
114
+ end
115
+
116
+ module Misc_ClassMethods
117
+ def partner_id_to_steam_id(account_id)
118
+ unknown_constant = 17825793 # or 0x1100001 idk wtf is this but ....
119
+ first_bytes = [account_id.to_i].pack('i>')
120
+ last_bytes = [unknown_constant].pack('i>')
121
+ collect = last_bytes + first_bytes
122
+ return collect.unpack('Q>')[0].to_s
123
+ end
124
+
125
+ private
126
+ def output(message)
127
+ time = Time.new
128
+ add = time.strftime("%d-%m-%Y %H:%M:%S")
129
+ puts "#{add} :: #{message}"
130
+ end
131
+
132
+ def verify_profileid_or_trade_link_or_steamid(steamid)
133
+ if steamid.to_i == 0 && steamid.include?("?partner=") ##supplied trade link
134
+ partner_raw = steamid.split('partner=',2)[1].split('&',2)[0]
135
+ token = steamid.split('token=', 2)[1]
136
+ steamid = partner_id_to_steam_id(partner_raw)
137
+ return [steamid,token]
138
+ elsif steamid.to_i == 0
139
+ session = Mechanize.new
140
+ parser = Nokogiri::XML(session.get("https://steamcommunity.com/id/#{steamid}?xml=1").content)
141
+ if parser.xpath('//error').text == ('The specified profile could not be found.')
142
+ raise "No profile with #{steamid} as profileid"
143
+ end
144
+ steamid = parser.xpath('//steamID64').text
145
+ return steamid
146
+ elsif steamid.to_s.length == 17
147
+ return steamid
148
+ else
149
+ raise "invalid steamid : #{steamid}, length of received :: #{steamid.to_s.length}, normal is 17" if steamid.to_s.length != 17
150
+ end
151
+ end
152
+
153
+ end ## end module
154
+
155
+
113
156
  end
114
157
 
115
158
  module Util
data/lib/meta/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Meta
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.3"
3
3
  GEM_NAME = "steam-trade"
4
4
  end
data/lib/steam-trade.rb CHANGED
@@ -80,18 +80,18 @@ class Handler
80
80
 
81
81
  if params.length == 3
82
82
  raise "shared_secret must be string, received #{parasm[0].class}" if params[0].class != String
83
- raise "time difference must be an integer(Fixnum), received #{params[1].class}" if params[1].class != Fixnum
83
+ raise "time difference must be a Numeric, received #{params[1].class}" if !params[1].is_a?(Numeric)
84
84
  raise "remember_me must be a boolean, received #{params[2].class}" if !([TrueClass,FalseClass].include?(params[2].class))
85
85
  @secret = params[0] if params[0].class == String
86
- @time_difference = params[1] if params[1].class == Fixnum
86
+ @time_difference = params[1] if params[1].is_a?(Numeric)
87
87
  @remember = params[2] if [TrueClass,FalseClass].include?(params[2].class)
88
88
  elsif params.length == 2
89
89
  if params[0].class == String
90
- raise "invalid fourth parameter type, received #{params[1].class}" if !([TrueClass,FalseClass].include?(params[1].class)) && params[1].class != Fixnum
90
+ raise "invalid fourth parameter type, received #{params[1].class}" if !([TrueClass,FalseClass].include?(params[1].class)) && !params[1].is_a?(Numeric)
91
91
  @secret = params[0]
92
- @time_difference = params[1] if params[1].class == Fixnum
92
+ @time_difference = params[1] if params[1].is_a?(Numeric)
93
93
  @remember = params[1] if [TrueClass,FalseClass].include?(params[1].class)
94
- elsif params[0].class == Fixnum
94
+ elsif params[0].is_a?(Numeric)
95
95
  raise "remember_me must be a boolean, received #{params[1].class}" if !([TrueClass,FalseClass].include?(params[1].class))
96
96
  @time_difference = params[0]
97
97
  @remember = params[1]
@@ -99,9 +99,9 @@ class Handler
99
99
  raise "invalid third parameter type"
100
100
  end
101
101
  elsif params.length == 1
102
- raise "invalid third parameter type, received #{params[0].class}" if !([TrueClass,FalseClass].include?(params[0].class)) && params[0].class != Fixnum && params[0].class != String
102
+ raise "invalid third parameter type, received #{params[0].class}" if !([TrueClass,FalseClass].include?(params[0].class)) && !params[0].is_a?(Numeric) && params[0].class != String
103
103
  @secret = params[0] if params[0].class == String
104
- @time_difference = params[0] if params[0].class == Fixnum
104
+ @time_difference = params[0] if params[0].is_a?(Numeric)
105
105
  @remember = params[0] if [TrueClass,FalseClass].include?(params[0].class)
106
106
  end
107
107
 
@@ -113,9 +113,9 @@ class Handler
113
113
  if params.length == 0
114
114
 
115
115
 
116
- raise "invalid parameter type, received #{password.class}" if !(password.class == String || password.class == Fixnum || [TrueClass,FalseClass].include?(password.class) )
116
+ raise "invalid parameter type, received #{password.class}" if !(password.class == String || params[0].is_a?(Numeric) || [TrueClass,FalseClass].include?(password.class) )
117
117
  @secret = password if password.class == String
118
- @time_difference = password if password.class == Fixnum
118
+ @time_difference = password if password.is_a?(Numeric)
119
119
  @remember = password if [TrueClass,FalseClass].include?(password.class)
120
120
 
121
121
 
@@ -124,10 +124,10 @@ class Handler
124
124
 
125
125
  if password.class == String
126
126
  @secret = password
127
- raise "invalid paramter type, received #{params[0].class}" if !([TrueClass,FalseClass].include?(params[0].class) || params[0].class == Fixnum )
128
- @time_difference = params[0] if params[0].class == Fixnum
127
+ raise "invalid paramter type, received #{params[0].class}" if !([TrueClass,FalseClass].include?(params[0].class) || params[0].is_a?(Numeric) )
128
+ @time_difference = params[0] if params[0].is_a?(Numeric)
129
129
  @remember = params[0] if [TrueClass,FalseClass].include?(params[0].class)
130
- elsif password.class == Fixnum
130
+ elsif password.is_a?(Numeric)
131
131
  @time_difference = password
132
132
  raise "invalid paramter type, received #{params[0].class}" if !([TrueClass,FalseClass].include?(params[0].class))
133
133
  @remember = params[0] if [TrueClass,FalseClass].include?(params[0].class)
@@ -139,8 +139,8 @@ class Handler
139
139
  elsif params.length == 2
140
140
  raise "shared_secret must be a string, recieved #{password.class}" if password.class != String
141
141
  @secret = password if password.class == String
142
- raise "time difference must be an integer (Fixnum), received #{params[0].class}" if params[0].class != Fixnum
143
- @time_difference = params[0] if params[0].class == Fixnum
142
+ raise "time difference must be a Numeric, received #{params[0].class}" if !params[0].is_a?(Numeric)
143
+ @time_difference = params[0] if params[0].is_a?(Numeric)
144
144
  raise "remeber_me must be a boolean, recieved #{params[1].class}" if !([TrueClass,FalseClass].include?(params[1].class))
145
145
  @remember = params[1] if [TrueClass,FalseClass].include?(params[1].class)
146
146
 
@@ -161,9 +161,7 @@ class Handler
161
161
  end
162
162
 
163
163
  def set_inventory_cache(timer = 120)
164
- integer = 5
165
- float = 5.5
166
- if timer.class == integer.class || timer.class == float.class
164
+ if timer.is_a?(Numeric)
167
165
  @inventory_validity = timer.to_i
168
166
  output "inventory validity set to #{timer}"
169
167
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: steam-trade
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - OmG3r
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-05-26 00:00:00.000000000 Z
11
+ date: 2018-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler