├── accounts.txt
├── database
├── logs.txt
├── app.ico
├── sim.ico
├── proxy.ico
├── stats.ico
├── captcha.ico
├── plus-blue.ico
├── tmplcounters
├── imap-hosts.json
├── interface_states.json
└── userdata.txt
├── steampy
├── __init__.py
├── .DS_Store
├── __pycache__
│ ├── client.cpython-38.pyc
│ ├── client.cpython-39.pyc
│ ├── guard.cpython-38.pyc
│ ├── guard.cpython-39.pyc
│ ├── login.cpython-38.pyc
│ ├── login.cpython-39.pyc
│ ├── utils.cpython-38.pyc
│ ├── utils.cpython-39.pyc
│ ├── __init__.cpython-38.pyc
│ ├── __init__.cpython-39.pyc
│ ├── confirmation.cpython-38.pyc
│ └── confirmation.cpython-39.pyc
├── build.bat
├── guard.py
├── confirmation.py
├── utils.py
├── login.py
└── client.py
├── start.bat
├── .vscode
└── settings.json
├── .DS_Store
├── .idea
├── .gitignore
├── .DS_Store
├── dictionaries
│ └── shamanovsky.xml
├── vcs.xml
├── modules.xml
├── misc.xml
├── steamreg.iml
└── inspectionProfiles
│ └── Project_Default.xml
├── webserver
├── .DS_Store
├── website
│ ├── Beard.png
│ ├── telegram-group.png
│ ├── telegram-logo.png
│ ├── templates
│ │ └── payment.html
│ └── index.html
└── server.py
├── __pycache__
├── enums.cpython-38.pyc
├── enums.cpython-39.pyc
├── controller.cpython-38.pyc
├── controller.cpython-39.pyc
├── steamreg.cpython-38.pyc
├── steamreg.cpython-39.pyc
├── sms_services.cpython-38.pyc
└── sms_services.cpython-39.pyc
├── .gitignore
├── enums.py
├── README.md
├── requirements.txt
├── Pipfile
├── .github
└── workflows
│ └── codeql.yml
├── captcha_snippet.py
├── sms_services.py
├── controller.py
└── steamreg.py
/accounts.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/database/logs.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/steampy/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/start.bat:
--------------------------------------------------------------------------------
1 | python3 main.py
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "python.formatting.provider": "yapf"
3 | }
--------------------------------------------------------------------------------
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sbaisarov/steam-autoreg/HEAD/.DS_Store
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sbaisarov/steam-autoreg/HEAD/.idea/.DS_Store
--------------------------------------------------------------------------------
/database/app.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sbaisarov/steam-autoreg/HEAD/database/app.ico
--------------------------------------------------------------------------------
/database/sim.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sbaisarov/steam-autoreg/HEAD/database/sim.ico
--------------------------------------------------------------------------------
/steampy/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sbaisarov/steam-autoreg/HEAD/steampy/.DS_Store
--------------------------------------------------------------------------------
/database/proxy.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sbaisarov/steam-autoreg/HEAD/database/proxy.ico
--------------------------------------------------------------------------------
/database/stats.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sbaisarov/steam-autoreg/HEAD/database/stats.ico
--------------------------------------------------------------------------------
/webserver/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sbaisarov/steam-autoreg/HEAD/webserver/.DS_Store
--------------------------------------------------------------------------------
/database/captcha.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sbaisarov/steam-autoreg/HEAD/database/captcha.ico
--------------------------------------------------------------------------------
/database/plus-blue.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sbaisarov/steam-autoreg/HEAD/database/plus-blue.ico
--------------------------------------------------------------------------------
/database/tmplcounters:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sbaisarov/steam-autoreg/HEAD/database/tmplcounters
--------------------------------------------------------------------------------
/database/imap-hosts.json:
--------------------------------------------------------------------------------
1 | {"imap.yandex.ru":["yandex.ru","yandex.ua","yandex.com","yandex.by","ya.ru","yandex.kz"]}
--------------------------------------------------------------------------------
/webserver/website/Beard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sbaisarov/steam-autoreg/HEAD/webserver/website/Beard.png
--------------------------------------------------------------------------------
/__pycache__/enums.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sbaisarov/steam-autoreg/HEAD/__pycache__/enums.cpython-38.pyc
--------------------------------------------------------------------------------
/__pycache__/enums.cpython-39.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sbaisarov/steam-autoreg/HEAD/__pycache__/enums.cpython-39.pyc
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | __pycache__
2 | .idea
3 | .vscode
4 | webserver
5 | Pipfile.lock
6 | *.txt
7 | .DS_Store
8 | database/tmplcounters
9 |
--------------------------------------------------------------------------------
/.idea/dictionaries/shamanovsky.xml:
--------------------------------------------------------------------------------
1 |
Ваш ключ продукта: {{ key }}
11 | {% else %} 12 |Похоже, что вы неверно ввели ключ продукта. Обратитесь к разработчику с номером вашего счета оплаты для того, 13 | чтобы получить новый ключ продукта и использовать оплаченную квоту
14 | {% endif %} 15 | 16 | -------------------------------------------------------------------------------- /.idea/steamreg.iml: -------------------------------------------------------------------------------- 1 | 2 |Автоматизированное решение для твоей коммерческой деятельности в Steam
218 |224 | Изначально, авторегистратор аккаунтов Steam делался для личных нужд. Я использовал его для 225 | регистрации новых, личных аккаунтов Steam, которые использовались для закупки гифтов. 226 | Больше я не переживал за то, что мои ценности на аккаунтах будут 227 | украдены из-за купленных у кого-то саморегов. К тому же, я экономил деньги. 228 |
229 |230 | Позже, я обнаружил потребность в авторегере Steam у фермеров карточек и вещей. Несколько месяцев 231 | я упорно работал над тем, чтобы придать ей удобный интерфейс, а также наладить бесперебойную и непрерывную регистрацию и привязку. 232 |
233 |
О разработчике программы
Telegram
Telegram Группаkey=parameter' 195 | return msg in str(response) 196 | 197 | @login_required 198 | def get_my_inventory(self, game: GameOptions, merge: bool = True) -> dict: 199 | url = self.COMMUNITY_URL + '/my/inventory/json/' + \ 200 | game.app_id + '/' + \ 201 | game.context_id 202 | result = {} 203 | start = 0 204 | more = True 205 | while more: 206 | try: 207 | response_dict = self._session.get(url, params={'start': start}, timeout=60).json() 208 | if not response_dict['success']: 209 | logger.info("No items found for appid %s: %s", game.app_id, response_dict) 210 | return result 211 | more = response_dict['more'] 212 | if merge: 213 | result.update(merge_items_with_descriptions_from_inventory(response_dict, game)) 214 | else: 215 | result.update(response_dict['rgInventory']) 216 | except (json.decoder.JSONDecodeError, KeyError, TypeError) as err: 217 | logger.error('%s error while getting my inventory', err) 218 | time.sleep(5) 219 | continue 220 | 221 | start += 2000 222 | 223 | return result 224 | 225 | @login_required 226 | def get_partner_inventory(self, partner_steam_id: str, game: GameOptions, merge: bool = True) -> dict: 227 | params = {'sessionid': self.get_session_id(), 228 | 'partner': partner_steam_id, 229 | 'appid': int(game.app_id), 230 | 'contextid': game.context_id} 231 | partner_account_id = steam_id_to_account_id(partner_steam_id) 232 | headers = {'X-Requested-With': 'XMLHttpRequest', 233 | 'Referer': self.COMMUNITY_URL + '/tradeoffer/new/?partner=' + partner_account_id, 234 | 'X-Prototype-Version': '1.7'} 235 | response_dict = self._session.get(self.COMMUNITY_URL + '/tradeoffer/new/partnerinventory/', 236 | params=params, 237 | headers=headers).json() 238 | if merge: 239 | return merge_items_with_descriptions_from_inventory(response_dict, game) 240 | return response_dict 241 | 242 | def get_session_id(self) -> str: 243 | return self._session.cookies.get('sessionid', domain='steamcommunity.com') 244 | 245 | def get_trade_offers_summary(self) -> requests.Response: 246 | params = {'key': self._api_key} 247 | return self.api_call('GET', 'IEconService', 'GetTradeOffersSummary', 'v1', params) 248 | 249 | def get_trade_offers(self, merge, get_descriptions=1): 250 | params = {'key': self._api_key, 251 | 'get_sent_offers': 1, 252 | 'get_received_offers': 1, 253 | 'get_descriptions': get_descriptions, 254 | 'language': 'english', 255 | 'active_only': 1, 256 | 'historical_only': 0, 257 | 'time_historical_cutoff': ''} 258 | response = self.api_call('GET', 'IEconService', 'GetTradeOffers', 'v1', params).json() 259 | response = self._filter_non_active_offers(response) 260 | if merge: 261 | response = merge_items_with_descriptions_from_offers(response) 262 | return response 263 | 264 | @staticmethod 265 | def _filter_non_active_offers(offers_response): 266 | offers_received = offers_response['response'].get('trade_offers_received', []) 267 | offers_sent = offers_response['response'].get('trade_offers_sent', []) 268 | offers_response['response']['trade_offers_received'] = list( 269 | filter(lambda offer: offer['trade_offer_state'] == TradeOfferState.Active, offers_received)) 270 | offers_response['response']['trade_offers_sent'] = list( 271 | filter(lambda offer: offer['trade_offer_state'] == TradeOfferState.Active, offers_sent)) 272 | return offers_response 273 | 274 | def get_trade_offer(self, trade_offer_id: str, merge: bool = True) -> dict: 275 | params = {'key': self._api_key, 276 | 'tradeofferid': trade_offer_id, 277 | 'language': 'english'} 278 | response = self.api_call('GET', 'IEconService', 'GetTradeOffer', 'v1', params).json() 279 | if merge: 280 | descriptions = {get_description_key(offer): offer for offer in response['response']['descriptions']} 281 | offer = response['response']['offer'] 282 | response['response']['offer'] = merge_items_with_descriptions_from_offer(offer, descriptions) 283 | return response 284 | 285 | @login_required 286 | def accept_trade_offer(self, trade_offer_id: str, partner: str): 287 | session_id = self.get_session_id() 288 | accept_url = self.COMMUNITY_URL + '/tradeoffer/' + trade_offer_id + '/accept' 289 | params = {'sessionid': session_id, 290 | 'tradeofferid': trade_offer_id, 291 | 'serverid': '1', 292 | 'partner': partner, 293 | 'captcha': ''} 294 | headers = {'Referer': self._get_trade_offer_url(trade_offer_id)} 295 | try: 296 | response = self._session.post(accept_url, data=params, headers=headers, timeout=60).json() 297 | if response.get('needs_mobile_confirmation', False): 298 | return self._confirm_transaction(trade_offer_id) 299 | except (AttributeError, json.decoder.JSONDecodeError) as err: 300 | logger.error("%s %s", err, accept_url) 301 | return None 302 | 303 | return response 304 | 305 | def _get_trade_offer_url(self, trade_offer_id: str) -> str: 306 | return self.COMMUNITY_URL + '/tradeoffer/' + trade_offer_id 307 | 308 | def _confirm_transaction(self, trade_offer_id: str) -> dict: 309 | confirmation_executor = ConfirmationExecutor(trade_offer_id, 310 | self.mafile['identity_secret'], 311 | str(self.mafile['Session']['SteamID']), 312 | self._session) 313 | return confirmation_executor.send_trade_allow_request() 314 | 315 | def confirm_transactions(self): 316 | confirmation_executor = ConfirmationExecutor('', self.mafile['identity_secret'], 317 | str(self.mafile['Session']['SteamID']), 318 | self._session) 319 | return confirmation_executor.send_markettrans_allow_request() 320 | 321 | def decline_trade_offer(self, trade_offer_id: str) -> dict: 322 | params = {'key': self._api_key, 323 | 'tradeofferid': trade_offer_id} 324 | return self.api_call('POST', 'IEconService', 'DeclineTradeOffer', 'v1', params).json() 325 | 326 | def cancel_trade_offer(self, trade_offer_id: str) -> dict: 327 | params = {'key': self._api_key, 328 | 'tradeofferid': trade_offer_id} 329 | return self.api_call('POST', 'IEconService', 'CancelTradeOffer', 'v1', params).json() 330 | 331 | @login_required 332 | def make_offer(self, token: str, items_from_me: List[Asset], items_from_them: List[Asset], partner_steam_id: str, 333 | message: str = '') -> dict: 334 | offer = { 335 | 'newversion': True, 336 | 'version': 4, 337 | 'me': { 338 | 'assets': [asset.to_dict() for asset in items_from_me], 339 | 'currency': [], 340 | 'ready': False 341 | }, 342 | 'them': { 343 | 'assets': [asset.to_dict() for asset in items_from_them], 344 | 'currency': [], 345 | 'ready': False 346 | } 347 | } 348 | 349 | session_id = self.get_session_id() 350 | url = self.COMMUNITY_URL + '/tradeoffer/new/send' 351 | server_id = 1 352 | params = { 353 | 'sessionid': session_id, 354 | 'serverid': server_id, 355 | 'partner': partner_steam_id, 356 | 'tradeoffermessage': message, 357 | 'json_tradeoffer': json.dumps(offer), 358 | 'captcha': '', 359 | 'trade_offer_create_params': json.dumps({"trade_offer_access_token": token}) 360 | } 361 | partner_account_id = steam_id_to_account_id(partner_steam_id) 362 | headers = {'Referer': self.COMMUNITY_URL + '/tradeoffer/new/?partner=' + partner_account_id + '&token=' + token, 363 | 'Origin': self.COMMUNITY_URL} 364 | while True: 365 | try: 366 | response = self._session.post(url, data=params, headers=headers, timeout=60).json() 367 | break 368 | except json.decoder.JSONDecodeError as err: 369 | logger.error("%s %s", err, url) 370 | time.sleep(3) 371 | 372 | if response.get('needs_mobile_confirmation'): 373 | response = self._confirm_transaction(response['tradeofferid']) 374 | return response 375 | 376 | def fetch_price(self, item_hash_name: str, game: GameOptions, currency: int = Currency.USD) -> dict: 377 | url = self.COMMUNITY_URL + '/market/priceoverview/' 378 | params = {'country': 'PL', 379 | 'currency': currency, 380 | 'appid': game.app_id, 381 | 'market_hash_name': item_hash_name} 382 | return self._session.get(url, params=params, timeout=60).json() 383 | 384 | def create_market_listing(self, assetid, price, appid, context_id=2): 385 | def send_marketform(): 386 | store_sessionid = self._session.cookies.get('sessionid', domain='store.steampowered.com') 387 | data = { 388 | 'sessionid': store_sessionid, 389 | 'full_name': self.login_name, 390 | 'permanent_address1': 'City', 391 | 'permanent_state': '', 392 | 'permanent_address2': '', 393 | 'permanent_postalcode': '', 394 | 'mailing_address1': '', 395 | 'mailing_address2': '', 396 | 'mailing_city': '', 397 | 'mailing_state': '', 398 | 'mailing_postalcode': '', 399 | 'permanent_city': 'City', 400 | 'permanent_country': 'RU', 401 | 'mailing_state_select': 'AE', 402 | 'mailing_country': 'RU', 403 | 'full_name_signed': self.login_name 404 | } 405 | store_headers = { 406 | 'Host': 'store.steampowered.com', 407 | 'Origin': 'https://store.steampowered.com', 408 | 'Referer': 'https://store.steampowered.com/account/forms/6050w/' 409 | } 410 | self._session.get('https://store.steampowered.com/account/forms/6050w/') 411 | self._session.post('https://store.steampowered.com/account/forms/submit_6050w_non_us/', 412 | data=data, headers=store_headers) 413 | print('marketform sent') 414 | 415 | sessionid = self.get_session_id() 416 | headers = { 417 | 'Origin': 'https://steamcommunity.com', 418 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 419 | 'Referer': 'https://steamcommunity.com/my/inventory/', 420 | 'Accept-Encoding': 'gzip, deflate', 421 | "X-Requested-With": "XMLHttpRequest" 422 | } 423 | payload = { 424 | 'sessionid': sessionid, 425 | 'appid': appid, 426 | 'contextid': context_id, 427 | 'assetid': assetid, 428 | 'amount': 1, 429 | 'price': price 430 | } 431 | 432 | response = None 433 | while True: 434 | try: 435 | response = self._session.post('https://steamcommunity.com/market/sellitem/', 436 | data=payload, headers=headers, timeout=10).json() 437 | except json.decoder.JSONDecodeError as err: 438 | logger.error('json decode error while putting item on sale: %s', err) 439 | continue 440 | error_msg = response.get('message', None) 441 | if error_msg: 442 | logger.error(str(error_msg)) 443 | if 'You are not allowed to sell more than 200 items' in error_msg: 444 | send_marketform() 445 | time.sleep(900) 446 | continue 447 | elif 'We were unable to contact' in error_msg: 448 | continue 449 | break 450 | 451 | return response 452 | 453 | 454 | class SevenDaysHoldException(Exception): 455 | pass 456 | -------------------------------------------------------------------------------- /controller.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import time 3 | import string 4 | import random 5 | import re 6 | import json 7 | import io 8 | import logging 9 | import shelve 10 | import imaplib 11 | 12 | from requests.exceptions import Timeout, ConnectionError, ProxyError 13 | from python_anticaptcha import AnticaptchaClient, ImageToTextTask, NoCaptchaTaskProxylessTask 14 | 15 | from steampy.client import SteamClient 16 | from steampy.login import CaptchaRequired 17 | from steampy.utils import convert_edomain_to_imap 18 | from steampy import guard 19 | 20 | from enums import CaptchaService, SelectionType 21 | 22 | logger = logging.getLogger('__main__') 23 | 24 | 25 | class SteamAuthError(Exception): pass 26 | 27 | 28 | class RuCaptchaError(Exception): pass 29 | 30 | 31 | class LimitReached(Exception): pass 32 | 33 | 34 | class InvalidEmail(Exception): pass 35 | 36 | 37 | class AddPhoneError(Exception): pass 38 | 39 | 40 | class Controller: 41 | 42 | def __init__(self, client): 43 | self.client = client 44 | self.failed_captchas_counter = 0 45 | self.sucessfull_captchas_counter = 0 46 | self.captchas_expenses_total = 0 47 | 48 | self.captcha_service = self.client.captcha_service_type.get() 49 | 50 | self.counters_db = shelve.open("database/tmplcounters", writeback=True) 51 | 52 | for key in ("login_counters", "password_counters", "nickname_counters"): 53 | if self.counters_db.get(key) is None: 54 | self.counters_db[key] = {} 55 | 56 | def set_captcha_service(self): 57 | api_key = self.client.captcha_api_key.get() 58 | captcha_host = self.client.captcha_host.get() 59 | if self.client.captcha_service_type.get() == CaptchaService.RuCaptcha: 60 | self.captcha_service = RuCaptcha(api_key, captcha_host) 61 | elif self.client.captcha_service_type.get() == CaptchaService.AntiCaptcha: 62 | self.captcha_service = AntiCaptcha(api_key, captcha_host) 63 | 64 | @staticmethod 65 | def request_post(session, url, data=None, headers=None, timeout=30): 66 | if headers is None: 67 | headers = {} 68 | if data is None: 69 | data = {} 70 | while True: 71 | try: 72 | resp = session.post(url, data=data, timeout=timeout, headers=headers, attempts=3).json() 73 | return resp 74 | except json.decoder.JSONDecodeError as err: 75 | logger.error('%s %s', err, url) 76 | except (Timeout, ConnectionError, ProxyError) as err: 77 | logger.error('%s %s', err, url) 78 | if session.proxies: 79 | raise err 80 | 81 | @staticmethod 82 | def request_get(session, url, headers=None, params=None, timeout=30, is_json=False): 83 | if params is None: 84 | params = {} 85 | if headers is None: 86 | headers = {} 87 | while True: 88 | try: 89 | resp = session.get(url, headers=headers, params=params, timeout=timeout, attempts=3) 90 | if is_json: 91 | resp = resp.json() 92 | return resp 93 | except json.decoder.JSONDecodeError as err: 94 | logger.error('%s %s', err, url) 95 | except (Timeout, ConnectionError, ProxyError) as err: 96 | logger.error('%s %s', err, url) 97 | if session.proxies: 98 | raise err 99 | 100 | def login(self, login_name, password, proxy=None, email=None, email_passwd=None, pass_login_captcha=False): 101 | steam_client = SteamClient() 102 | if proxy is not None: 103 | proxy_uri = self.build_uri(proxy) 104 | proxy = { 105 | 'http': proxy_uri, 106 | 'https': proxy_uri, 107 | } 108 | steam_client.session.proxies.update(proxy) 109 | captcha_gid, captcha_text = '-1', '' 110 | while True: 111 | try: 112 | resp = steam_client.login(login_name, password, None, email, email_passwd, captcha_gid, captcha_text) 113 | break 114 | except CaptchaRequired as err: 115 | if pass_login_captcha: 116 | raise err 117 | captcha_gid = str(err) 118 | captcha_id = self.generate_captcha(steam_client.session, captcha_gid, 'COMMUNITY') 119 | captcha_text = self.resolve_captcha(captcha_id) 120 | self.failed_captchas_counter += 1 121 | self.client.captchas_failed_stat.set("Капч не удалось решить: %d" % self.failed_captchas_counter) 122 | 123 | self.sucessfull_captchas_counter += 1 124 | self.client.captchas_resolved_stat.set("Капч решено успешно: %d" % self.sucessfull_captchas_counter) 125 | 126 | resp_message = resp.get('message', '') 127 | 128 | if 'name or password that you have entered is incorrect' in resp_message: 129 | raise SteamAuthError('Неверный логин или пароль: ' + login_name) 130 | 131 | if resp['requires_twofactor']: 132 | raise SteamAuthError('К аккаунту уже привязан Guard: ' + login_name) 133 | 134 | if resp.get('emailauth_needed', None): 135 | raise SteamAuthError('К аккаунту привязан Mail Guard. ' 136 | 'Почта и пароль от него не предоставлены') 137 | 138 | return steam_client 139 | 140 | def mobile_login(self, login_name, password, proxy=None, email=None, email_passwd=None, pass_login_captcha=False): 141 | steam_client = SteamClient() 142 | if proxy: 143 | proxy_uri = self.build_uri(proxy) 144 | proxy = { 145 | 'http': proxy_uri, 146 | 'https': proxy_uri, 147 | } 148 | steam_client.session.proxies.update(proxy) 149 | captcha_gid, captcha_text = '-1', '' 150 | while True: 151 | try: 152 | resp = steam_client.mobile_login(login_name, password, None, email, email_passwd, captcha_gid, 153 | captcha_text) 154 | break 155 | except CaptchaRequired as err: 156 | if pass_login_captcha: 157 | raise err 158 | captcha_gid = str(err) 159 | captcha_id = self.generate_captcha(steam_client.session, captcha_gid, 'COMMUNITY') 160 | captcha_text = self.resolve_captcha(captcha_id) 161 | 162 | resp_message = resp.get('message', '') 163 | 164 | if 'name or password that you have entered is incorrect' in resp_message: 165 | raise SteamAuthError('Неверный логин или пароль: ' + login_name) 166 | 167 | if resp['requires_twofactor']: 168 | raise SteamAuthError('К аккаунту уже привязан Guard: ' + login_name) 169 | 170 | if resp.get('emailauth_needed', None): 171 | raise SteamAuthError('К аккаунту привязан Mail Guard. ' 172 | 'Почта и пароль от него не предоставлены') 173 | 174 | if not steam_client.oauth: 175 | error = 'Не удалось залогиниться в аккаунт: {}:{}'.format( 176 | login_name, password) 177 | raise SteamAuthError(error) 178 | 179 | steam_client.session.get("https://store.steampowered.com") # get store cookies 180 | 181 | return steam_client 182 | 183 | def validate_phone(self, steam_client, phone_num): 184 | sessionid = steam_client.session.cookies.get( 185 | 'sessionid', domain='store.steampowered.com') 186 | url = "https://store.steampowered.com/phone/validate" 187 | data = {"sessionID": sessionid, "phoneNumber": phone_num} 188 | response = self.request_post(steam_client.session, 189 | url, data=data) 190 | if not response.get("is_valid", True): 191 | raise AddPhoneError("Недопустимый номер") 192 | 193 | def addphone_request(self, steam_client, phone_num): 194 | sessionid = steam_client.session.cookies.get( 195 | 'sessionid', domain='steamcommunity.com') 196 | data = { 197 | 'op': 'add_phone_number', 198 | 'arg': phone_num, 199 | 'sessionid': sessionid 200 | } 201 | response = self.request_post(steam_client.session, 202 | 'https://steamcommunity.com/steamguard/phoneajax', data=data) 203 | logger.info(response) 204 | return response["success"] 205 | 206 | def fetch_email_code(self, email, email_password, steam_client): 207 | server = self.authorize_email(email, email_password) 208 | attempts = 0 209 | success = False 210 | while attempts < 5: 211 | attempts += 1 212 | result, data = server.uid('search', '', 'ALL') 213 | uid = data[0].split()[-1] 214 | result, data = server.uid("fetch", uid, '(UID BODY[TEXT])') 215 | try: 216 | mail = data[0][1].decode('utf-8') 217 | link = re.search(r'https://.+ConfirmEmailForAdd.+?"', mail) 218 | if link is not None: 219 | link = link.group().rstrip('"') 220 | steam_client.session.get(link) 221 | success = True 222 | break 223 | except AttributeError: 224 | time.sleep(5) 225 | continue 226 | server.close() 227 | return success 228 | 229 | def email_confirmation(self, steam_client): 230 | sessionid = steam_client.session.cookies.get( 231 | 'sessionid', domain='steamcommunity.com') 232 | data = { 233 | 'op': 'email_confirmation', 234 | 'arg': None, 235 | 'sessionid': sessionid 236 | } 237 | response = self.request_post(steam_client.session, 238 | 'https://steamcommunity.com/steamguard/phoneajax', data=data) 239 | return response["success"] 240 | 241 | def is_phone_attached(self, steam_client): 242 | sessionid = steam_client.session.cookies.get( 243 | 'sessionid', domain='steamcommunity.com') 244 | data = { 245 | 'op': 'has_phone', 246 | 'arg': None, 247 | 'sessionid': sessionid 248 | } 249 | response = self.request_post(steam_client.session, 250 | 'https://steamcommunity.com/steamguard/phoneajax', data=data) 251 | 252 | return response['has_phone'] 253 | 254 | def checksms_request(self, steam_client, sms_code): 255 | sessionid = steam_client.session.cookies.get( 256 | 'sessionid', domain='steamcommunity.com') 257 | data = { 258 | 'op': 'check_sms_code', 259 | 'arg': sms_code, 260 | 'sessionid': sessionid 261 | } 262 | response = self.request_post( 263 | steam_client.session, 'https://steamcommunity.com/steamguard/phoneajax', data=data) 264 | logger.info(response) 265 | return response["success"] 266 | 267 | def add_authenticator_request(self, steam_client): 268 | device_id = guard.generate_device_id(steam_client.oauth['steamid']) 269 | attempts = 0 270 | mobguard_data = None 271 | while attempts < 3: 272 | try: 273 | mobguard_data = self.request_post(steam_client.session, 274 | 'https://api.steampowered.com/ITwoFactorService/AddAuthenticator/v0001/', 275 | data={ 276 | "access_token": steam_client.oauth['oauth_token'], 277 | "steamid": steam_client.oauth['steamid'], 278 | "authenticator_type": 1, 279 | "device_identifier": device_id, 280 | "sms_phone_id": 1 281 | })['response'] 282 | except json.decoder.JSONDecodeError: 283 | time.sleep(3) 284 | attempts += 1 285 | continue 286 | logger.info(str(mobguard_data)) 287 | if mobguard_data['status'] not in (1, 2): 288 | time.sleep(5) 289 | attempts += 1 290 | continue 291 | if not mobguard_data.get("shared_secret", None): 292 | time.sleep(5) 293 | attempts += 1 294 | continue 295 | break 296 | 297 | if mobguard_data is None or not mobguard_data.get("shared_secret", None): 298 | raise SteamAuthError("Steam отвечает ошибкой") 299 | 300 | mobguard_data['device_id'] = device_id 301 | mobguard_data['Session'] = {} 302 | mobguard_data['Session']['WebCookie'] = None 303 | for mafile_key, resp_key in (('SteamID', 'steamid'), ('OAuthToken', 'oauth_token')): 304 | mobguard_data['Session'][mafile_key] = steam_client.oauth[resp_key] 305 | 306 | for mafile_key, resp_key in ( 307 | ('SessionID', 'sessionid'), 308 | ('SteamLogin', 'steamLogin'), 309 | ('SteamLoginSecure', 'steamLoginSecure')): 310 | try: 311 | mobguard_data['Session'][mafile_key] = steam_client.session.cookies.get( 312 | "sessionid", domain="steamcommunity.com") 313 | except KeyError: 314 | mobguard_data['Session'][mafile_key] = '' 315 | 316 | return mobguard_data 317 | 318 | def finalize_authenticator_request(self, steam_client, mobguard_data, sms_code): 319 | one_time_code = guard.generate_one_time_code(mobguard_data['shared_secret'], int(time.time())) 320 | data = { 321 | "steamid": steam_client.oauth['steamid'], 322 | "activation_code": sms_code, 323 | "access_token": steam_client.oauth['oauth_token'], 324 | 'authenticator_time': int(time.time()), 325 | 'authenticator_code': one_time_code 326 | } 327 | attempts = 0 328 | fin_resp = None 329 | while attempts < 5: 330 | try: 331 | fin_resp = self.request_post( 332 | steam_client.session, 333 | 'https://api.steampowered.com/ITwoFactorService/FinalizeAddAuthenticator/v0001/', 334 | data=data, headers={'User-Agent': 'Steam App / Android / 2.3.11 / 5379038'})['response'] 335 | except json.decoder.JSONDecodeError: 336 | logger.error("json error in the FinalizeAddAuthenticator request") 337 | time.sleep(3) 338 | attempts += 1 339 | continue 340 | logger.info(str(fin_resp)) 341 | if fin_resp['status'] not in (1, 2): 342 | time.sleep(5) 343 | attempts += 1 344 | continue 345 | break 346 | 347 | if fin_resp is None or fin_resp['status'] not in (1, 2): 348 | raise SteamAuthError("Steam отвечает ошибкой") 349 | 350 | return fin_resp['success'] 351 | 352 | @staticmethod 353 | def make_account_unlimited(mobguard_data, wallet_code, get_api_key=False): 354 | steam_client = SteamClient() 355 | steam_client.login(mobguard_data['account_name'], mobguard_data['account_password'], mobguard_data) 356 | data = { 357 | 'wallet_code': wallet_code, 358 | 'CreateFromAddress': '1', 359 | 'Address': 'Russia', 360 | 'City': 'Russia', 361 | 'Country': 'RU', 362 | 'State': '', 363 | 'PostCode': '0001' 364 | } 365 | steam_client.session.post('https://store.steampowered.com/account/validatewalletcode/', 366 | data={'wallet_code': wallet_code}) 367 | steam_client.session.post('https://store.steampowered.com/account/createwalletandcheckfunds/', 368 | data=data) 369 | steam_client.session.post('https://store.steampowered.com/account/confirmredeemwalletcode/', 370 | data={'wallet_code': wallet_code}) 371 | 372 | if get_api_key: 373 | sessionid = steam_client.session.cookies.get( 374 | 'sessionid', domain='steamcommunity.com') 375 | data = { 376 | 'domain': 'domain.com', 377 | 'agreeToTerms': 'agreed', 378 | 'sessionid': sessionid, 379 | 'Submit': 'Register' 380 | } 381 | time.sleep(10) 382 | r = steam_client.session.post('https://steamcommunity.com/dev/registerkey', data=data) 383 | key = re.search('Key: (.+)