-
Notifications
You must be signed in to change notification settings - Fork 0
/
turbo.py
195 lines (152 loc) · 6.13 KB
/
turbo.py
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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
import json
import time
import base64
import logging
import requests
from Cryptodome.PublicKey import RSA
from Cryptodome.Cipher import PKCS1_v1_5
log = logging.getLogger(__name__)
class Turbo:
def __init__(self):
# Initialize the session for requests and the API key
self.session = requests.Session()
self.apikey = None
def login(self, username, password, **kwargs):
""" Login to Steam
:param username: the user's Steam username
:param password: the user's Steam password
kwargs:
:param emailauth: the email authentication code received after a login attempt
:param captchagid: the GID for the CAPTCHA attempted after a login attempt
:param captchatext: the CAPTCHA text from the user after a login attempt
:param twofactorcode: 2FA from Steam guard to allow the user to login """
# Set the user-agent to be like a browser
self.session.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6'
payload = {
'donotcache': round(time.time() * 1000),
'username': username
}
# Get the RSA key for our username at the current time, so we can encrypt our password
resp = self.session.post('https://steamcommunity.com/login/getrsakey/', data=payload)
if resp.status_code != 200:
return False
rsa_data = resp.json()
mod = int(rsa_data['publickey_mod'], 16)
exp = int(rsa_data['publickey_exp'], 16)
rsa = RSA.construct((mod, exp))
cipher = PKCS1_v1_5.new(rsa)
payload = {
'username': username,
'password': base64.b64encode(cipher.encrypt(password.encode('utf-8'))),
'rsatimestamp': rsa_data['timestamp'],
'remember_login': True,
'emailauth': kwargs.get('emailauth'),
'captchagid': kwargs.get('captchagid'),
'captcha_text': kwargs.get('captchatext'),
'twofactorcode': kwargs.get('twofactorcode'),
'donotcache': time.time() * 1000
}
# Attempt to log in to Steam
resp = self.session.post('https://steamcommunity.com/login/dologin/', data=payload)
login_result = resp.json()
# Handle different possibilities for the login
if not login_result['success']:
if login_result.get('captcha_needed'):
log.info("CAPTCHA is needed")
gid = login_result['captcha_gid']
self.login(username, password, captchagid=gid, captchatext=self.captcha(gid))
elif login_result.get('requires_twofactor'):
log.info("2FA code is needed")
self.login(username, password, twofactorcode=input('Enter your 2FA: '))
else:
return False
else:
log.info("Logged in successfully")
self.session.get('https://steamcommunity.com')
return True
def captcha(self, gid):
""" Saves a CAPTCHA image to the folder so that the user can solve it
:param gid: the GID of the CAPTCHA """
# Get the rendered CAPTCHA from Steam
resp = self.session.get('https://steamcommunity.com/login/rendercaptcha/?gid=' + gid)
# Write the content of the response to a new file
with open('captcha.png', 'wb') as file:
file.write(resp.content)
# Get the user to input the CAPTCHA's text
captcha_text = input('Enter CAPTCHA: ')
return captcha_text
def get_apikey(self):
""" Generates a new Steam API key """
payload = {
'Revoke': 'Revoke My Steam Web API Key',
'sessionid': self.session.cookies['sessionid']
}
# Revoke the old Steam API key
self.session.post('https://steamcommunity.com/dev/revokekey', data=payload)
payload = {
'domain': 'github.com/Shoot',
'agreeToTerms': 'agreed',
'sessionid': self.session.cookies['sessionid'],
'Submit': 'Register'
}
# Sign up for a new one, then parse the response text to get the key
resp = self.session.post('https://steamcommunity.com/dev/registerkey', data=payload)
self.apikey = resp.text.split('<p>Key: ')[-1].split('</p>')[0]
log.info("Got a new API key: " + self.apikey)
def convert_vanity_urls(self, list):
""" Converts vanity URLs into SteamID64 format
:param list: array of vanity URLs """
if not self.apikey:
log.error("An API key is necessary for this function")
return False
steam64_list = []
# Convert each vanity to SteamID64 format
for vanity in list:
payload = {
'key': self.apikey,
'vanityurl': vanity
}
# Get the owner's information
resp = requests.get('http://api.steampowered.com/ISteamUser/ResolveVanityUrl/v0001/', params=payload)
steam_user = resp.json()
# Append it to the array
steam64_list.append(steam_user['response']['steamid'])
log.info("Converted " + str(len(steam64_list)) + " vanity URLs")
return steam64_list
def target(self, s64list, vanitylist):
""" Checks to see if the vanity URL is no longer in the list of Steam profiles
:param s64list: the list of SteamID64 addresses (from convert_vanity_urls())
:param vanitylist: the list of vanity URLs to check """
if not self.apikey:
return False
# Get the users who own the vanity URLs
resp = self.session.get('http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=' + self.apikey + '&steamids=' + ','.join(s64list))
# Handle some possible issues
if resp.status_code != 200:
return False
if not resp.json().get('response'):
return False
if not resp.json()["response"].get("players"):
return False
# Check if the vanity URL is not longer present
for vanity in vanitylist:
if not 'steamcommunity.com/id/' + vanity + '/' in resp.text.lower():
log.info("Got a target: " + vanity)
return vanity
def claim(self, vanity):
""" Attempt to claim the vanity URL
:param vanity: the vanity URL to try and claim """
payload = {
'sessionID': self.session.cookies['sessionid'],
'type': 'profileSave',
'customURL': vanity
}
# Attempt to change our Steam vanity URL
self.session.get('https://steamcommunity.com/my/edit/', params=payload)
resp = self.session.get('https://steamcommunity.com/my/edit')
if '/id/' + vanity + '/home' in resp.text:
log.info("Successfully claimed " + target)
return True
else:
log.info("Failed to claim " + target)
return False