Files
Steam-Panel-Simple/app/services/steam_checker.py
T
Manchik 68433b74c0 v3.1.0
2026-05-19 18:28:43 +03:00

326 lines
13 KiB
Python

"""Validation service for log:pass accounts (no mafile)."""
from pathlib import Path
from bs4 import BeautifulSoup
from loguru import logger
from app.services.steam_auth import _resolve_proxy, ProxyRequestStrategy, close_steam, extract_session_cookies
from app.services.steam_ban import check_ban
from app.services.steam_profile import fetch_profile
from app.services.steam_vac_checker import check_vac_and_limit
from app.core.proxy_manager import proxy_manager
from app.core.task_manager import task_manager
async def check_logpass_account(account: dict, params: dict, *, task_id: str) -> None:
"""Login with login:pass only, get steamid/nickname, check ban, update DB row."""
try:
from pysteamauth.auth import Steam
except ImportError:
raise RuntimeError("pysteamauth not installed")
acc_id = account["id"]
proxy = await _resolve_proxy(account)
request_strategy = None
if proxy:
connector = proxy_manager.get_connector(proxy)
request_strategy = ProxyRequestStrategy(connector)
logger.debug(f"[checker] Using proxy for {account['login']}")
steam = Steam(
login=account["login"],
password=account["password"],
request_strategy=request_strategy,
)
try:
await task_manager.set_step(task_id, 1, 3, "Авторизация", acc_id)
# Pre-validate password before attempting RSA encryption (Steam RSA-2048 max 245 bytes)
password = account.get("password") or ""
if len(password.encode("utf-8")) > 245:
raise ValueError(
f"Password is too long ({len(password)} chars) — possible mafile data imported as password. "
"Re-import the account in login:password format."
)
await steam.login_to_steam()
# Save session cookies right after login
try:
session_cookies_json = extract_session_cookies(steam)
if session_cookies_json:
from app.database import get_db as _get_db
_db = await _get_db()
await _db.execute(
"UPDATE logpass_accounts SET session_cookies = ? WHERE id = ?",
(session_cookies_json, acc_id),
)
await _db.commit()
logger.debug(f"[checker] {account['login']}: saved session cookies")
except Exception as cookie_err:
logger.warning(f"[checker] {account['login']}: failed to save cookies — {cookie_err}")
from app.config import read_validation_settings
val_settings = read_validation_settings()
steam_id = str(steam.steamid)
ban_status = ""
vac_status = ""
limit_status = ""
vac_games: list[str] = []
if val_settings.get("check_ban"):
await task_manager.set_step(task_id, 2, 4, "Проверка бана", acc_id)
ban_status = await check_ban(steam)
vac_status, limit_status, vac_games = await check_vac_and_limit(steam)
await task_manager.set_step(task_id, 3, 4, "Баланс / Страна", acc_id)
from app.services.steam_store_checker import fetch_balance_and_country
balance, country = await fetch_balance_and_country(steam)
logger.info(f"[checker] {account['login']}: balance={balance or 'none'}, country={country or 'none'}")
nickname = None
steam_level = None
avatar_url = None
last_online = None
if steam_id and steam_id != "0" and val_settings.get("fetch_profile"):
await task_manager.set_step(task_id, 4, 4, "Получение профиля", acc_id)
profile = await fetch_profile(steam_id, steam=steam)
if profile:
nickname = profile.get("nickname")
steam_level = profile.get("steam_level")
avatar_url = profile.get("avatar_url")
last_online = profile.get("last_online")
import json as _json
from app.database import get_db
db = await get_db()
await db.execute(
"""UPDATE logpass_accounts
SET steam_id = ?, nickname = ?, steam_level = ?, avatar_url = ?, last_online = ?,
ban_status = ?, vac_status = ?, limit_status = ?, vac_games = ?,
balance = ?, country = ?,
status = 'valid', updated_at = datetime('now')
WHERE id = ?""",
(steam_id, nickname, steam_level, avatar_url, last_online,
ban_status, vac_status, limit_status,
_json.dumps(vac_games) if vac_games else None,
balance or None, country or None, acc_id),
)
await db.commit()
logger.success(f"[checker] {account['login']} → valid, ban={ban_status}")
except Exception as exc:
from app.database import get_db
db = await get_db()
await db.execute(
"UPDATE logpass_accounts SET status = 'invalid', updated_at = datetime('now') WHERE id = ?",
(acc_id,),
)
await db.commit()
logger.error(f"[checker] {account['login']}{exc}")
raise
finally:
await close_steam(steam)
async def _check_cs2_prime(steam, steam_id: str) -> str:
"""Check CS2 Prime status."""
try:
url = f"https://steamcommunity.com/profiles/{steam_id}/gcpd/730/?tab=primeaccount"
resp = await steam.request(url, method="GET")
html = resp if isinstance(resp, str) else resp.decode("utf-8", errors="ignore")
if "no_personal_data_stored_message" in html:
return "Disabled"
if "personaldata_elements_container" in html and "Enabled" in html:
return "Enabled"
return "Disabled"
except Exception as e:
logger.debug(f"[full_parse] prime check error: {e}")
return "Disabled"
async def _check_dota_trophy(steam, steam_id: str) -> str | None:
"""Check Dota 2 Trophy Score."""
try:
url = f"https://steamcommunity.com/profiles/{steam_id}/gcpd/570/?category=Stats&tab=Trophy"
resp = await steam.request(url, method="GET")
html = resp if isinstance(resp, str) else resp.decode("utf-8", errors="ignore")
if "no_personal_data_stored_message" in html:
return None
if "personaldata_elements_container" in html:
soup = BeautifulSoup(html, "html.parser")
for row in soup.find_all("tr"):
cells = row.find_all("td")
if len(cells) >= 3:
try:
int(cells[0].get_text(strip=True))
score = cells[1].get_text(strip=True)
if score.isdigit():
return score
except (ValueError, AttributeError):
continue
return None
except Exception as e:
logger.debug(f"[full_parse] trophy check error: {e}")
return None
async def _check_dota_behavior(steam, steam_id: str) -> str | None:
"""Check Dota 2 Behavior Score."""
try:
url = f"https://steamcommunity.com/profiles/{steam_id}/gcpd/570/?category=Account&tab=MatchPlayerReportIncoming"
resp = await steam.request(url, method="GET")
html = resp if isinstance(resp, str) else resp.decode("utf-8", errors="ignore")
if "no_personal_data_stored_message" in html:
return None
if "personaldata_elements_container" in html:
soup = BeautifulSoup(html, "html.parser")
for row in soup.find_all("tr"):
cells = row.find_all("td")
if cells:
last_cell = cells[-1].get_text(strip=True)
if last_cell.isdigit():
return last_cell
return None
except Exception as e:
logger.debug(f"[full_parse] behavior check error: {e}")
return None
async def _check_licenses(steam) -> str:
"""Get list of licenses (games) from Steam account."""
try:
resp = await steam.request("https://store.steampowered.com/account/licenses/", method="GET")
html = resp if isinstance(resp, str) else resp.decode("utf-8", errors="ignore")
soup = BeautifulSoup(html, "html.parser")
table = soup.find("table", class_="account_table")
if not table:
return ""
licenses = []
rows = table.find_all("tr")
for row in rows[1:]:
cells = row.find_all("td")
if len(cells) >= 2:
game_cell = cells[1]
remove_div = game_cell.find("div", class_="free_license_remove_link")
if remove_div:
remove_div.decompose()
name = game_cell.get_text(strip=True)
if name:
licenses.append(name)
return ", ".join(licenses)
except Exception as e:
logger.debug(f"[full_parse] licenses check error: {e}")
return ""
async def full_parse_logpass_account(account: dict, params: dict, *, task_id: str) -> None:
"""Full parse: login, ban, profile, prime, trophy, behavior, licenses."""
try:
from pysteamauth.auth import Steam
except ImportError:
raise RuntimeError("pysteamauth not installed")
acc_id = account["id"]
proxy = await _resolve_proxy(account)
request_strategy = None
if proxy:
connector = proxy_manager.get_connector(proxy)
request_strategy = ProxyRequestStrategy(connector)
steam = Steam(
login=account["login"],
password=account["password"],
request_strategy=request_strategy,
)
try:
await task_manager.set_step(task_id, 1, 7, "Авторизация", acc_id)
await steam.login_to_steam()
# Save session cookies
try:
session_cookies_json = extract_session_cookies(steam)
if session_cookies_json:
from app.database import get_db as _get_db
_db = await _get_db()
await _db.execute(
"UPDATE logpass_accounts SET session_cookies = ? WHERE id = ?",
(session_cookies_json, acc_id),
)
await _db.commit()
except Exception as cookie_err:
logger.warning(f"[full_parse] {account['login']}: failed to save cookies — {cookie_err}")
steam_id = str(steam.steamid)
await task_manager.set_step(task_id, 2, 7, "Проверка бана", acc_id)
ban_status = await check_ban(steam)
vac_status, limit_status, vac_games = await check_vac_and_limit(steam)
nickname = avatar_url = last_online = None
steam_level = None
if steam_id and steam_id != "0":
await task_manager.set_step(task_id, 3, 7, "Профиль", acc_id)
profile = await fetch_profile(steam_id, steam=steam)
if profile:
nickname = profile.get("nickname")
steam_level = profile.get("steam_level")
avatar_url = profile.get("avatar_url")
last_online = profile.get("last_online")
await task_manager.set_step(task_id, 4, 7, "Баланс / Страна", acc_id)
from app.services.steam_store_checker import fetch_balance_and_country
balance, country = await fetch_balance_and_country(steam)
logger.info(f"[full_parse] {account['login']}: balance={balance or 'none'}, country={country or 'none'}")
prime = "Disabled"
trophy = None
behavior = None
if steam_id and steam_id != "0":
await task_manager.set_step(task_id, 5, 7, "Prime / Trophy", acc_id)
prime = await _check_cs2_prime(steam, steam_id)
trophy = await _check_dota_trophy(steam, steam_id)
behavior = await _check_dota_behavior(steam, steam_id)
await task_manager.set_step(task_id, 6, 7, "Лицензии", acc_id)
license_str = await _check_licenses(steam)
import json as _json
await task_manager.set_step(task_id, 7, 7, "Сохранение", acc_id)
from app.database import get_db
db = await get_db()
await db.execute(
"""UPDATE logpass_accounts
SET steam_id = ?, nickname = ?, steam_level = ?, avatar_url = ?, last_online = ?,
ban_status = ?, vac_status = ?, limit_status = ?, vac_games = ?,
balance = ?, country = ?,
prime = ?, trophy = ?, behavior = ?, license = ?,
status = 'valid', updated_at = datetime('now')
WHERE id = ?""",
(steam_id, nickname, steam_level, avatar_url, last_online,
ban_status, vac_status, limit_status,
_json.dumps(vac_games) if vac_games else None,
balance or None, country or None,
prime, trophy, behavior, license_str, acc_id),
)
await db.commit()
logger.success(f"[full_parse] {account['login']} → valid, ban={ban_status}, prime={prime}, trophy={trophy}, behavior={behavior}, licenses={len(license_str.split(', ')) if license_str else 0}")
except Exception as exc:
from app.database import get_db
db = await get_db()
await db.execute(
"UPDATE logpass_accounts SET status = 'invalid', updated_at = datetime('now') WHERE id = ?",
(acc_id,),
)
await db.commit()
logger.error(f"[full_parse] {account['login']}{exc}")
raise
finally:
await close_steam(steam)