steam-trade 0.2.1 → 0.2.3

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.
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