| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478 |
- #!/usr/bin/env python3
- """
- Steam 订单确认 Python 客户端
- 使用说明:
- 1. 首次使用需要先登录(调用 login 函数)
- 2. 登录后会保存 session 到本地文件
- 3. 之后可以直接查询确认列表或执行确认操作
- 依赖安装:
- pip install requests
- 示例:
- python steam_confirmation.py
- """
- import json
- import os
- import sys
- import requests
- from typing import Optional
- # ============ 配置区域 ============
- API_BASE_URL = "http://localhost:5000"
- MA_FILE_PATH = r"C:\Users\Administrator\AppData\Local\steam-msg\tku24068.maFile"
- # 如果需要代理,取消下面这行的注释并填写
- # PROXY_URL = "http://127.0.0.1:7890"
- PROXY_URL = None
- # Session 保存路径
- SESSION_FILE = "steam_session.json"
- # ============ 配置区域结束 ============
- def load_session() -> Optional[dict]:
- """从文件加载保存的 session"""
- if os.path.exists(SESSION_FILE):
- try:
- with open(SESSION_FILE, 'r', encoding='utf-8') as f:
- return json.load(f)
- except Exception as e:
- print(f"加载 session 失败: {e}")
- return None
- def save_session(session_data: dict):
- """保存 session 到文件"""
- try:
- with open(SESSION_FILE, 'w', encoding='utf-8') as f:
- json.dump(session_data, f, indent=2, ensure_ascii=False)
- print("Session 已保存")
- except Exception as e:
- print(f"保存 session 失败: {e}")
- def login(username: str, password: str) -> Optional[dict]:
- """
- 登录 Steam 账号
- Args:
- username: Steam 用户名
- password: Steam 密码
- Returns:
- session 数据,包含 steamId, accessToken, refreshToken, sessionId
- """
- print(f"\n{'='*50}")
- print("正在登录 Steam...")
- print(f"用户名: {username}")
- print(f"MaFile: {MA_FILE_PATH}")
- print(f"{'='*50}\n")
- url = f"{API_BASE_URL}/login"
- payload = {
- "Username": username,
- "Password": password,
- "MaFilePath": MA_FILE_PATH
- }
- if PROXY_URL:
- payload["ProxyUrl"] = PROXY_URL
- try:
- response = requests.post(url, json=payload, timeout=60)
- print(f"响应状态码: {response.status_code}")
- if response.status_code == 200:
- data = response.json()
- session = data.get("session", {})
- print(f"\n登录成功!")
- print(f"SteamID: {session.get('steamId')}")
- print(f"SessionID: {session.get('sessionId', 'N/A')[:20]}...")
- # 保存 session
- save_session(session)
- return session
- else:
- print(f"登录失败: {response.text}")
- return None
- except requests.exceptions.ConnectionError:
- print(f"\n错误: 无法连接到 steamAPI 服务")
- print(f"请确保 steamAPI 服务正在运行 (默认: http://localhost:5000)")
- return None
- except requests.exceptions.Timeout:
- print("\n错误: 请求超时,请检查网络连接")
- return None
- except Exception as e:
- print(f"\n错误: {e}")
- return None
- def get_confirmation_list(session: dict) -> Optional[list]:
- """
- 获取待确认的交易/市场订单列表
- Args:
- session: 登录后获取的 session 数据
- Returns:
- 确认列表
- """
- print(f"\n{'='*50}")
- print("正在获取待确认列表...")
- print(f"{'='*50}\n")
- url = f"{API_BASE_URL}/trade-confirmations/list"
- payload = {
- "MaFilePath": MA_FILE_PATH,
- "Session": {
- "SteamId": session["steamId"],
- "AccessToken": session["accessToken"],
- "RefreshToken": session["refreshToken"],
- "SessionId": session.get("sessionId")
- }
- }
- if PROXY_URL:
- payload["ProxyUrl"] = PROXY_URL
- try:
- response = requests.post(url, json=payload, timeout=30)
- print(f"响应状态码: {response.status_code}")
- if response.status_code == 200:
- data = response.json()
- confirmations = data.get("confirmations", [])
- print(f"\n找到 {len(confirmations)} 个待确认项:")
- # 更新 session
- if "session" in data:
- save_session(data["session"])
- if confirmations:
- print("\n" + "-" * 60)
- for i, conf in enumerate(confirmations, 1):
- print(f"\n[{i}] 类型: {conf.get('type', 'Unknown')}")
- print(f" ID: {conf.get('id')}")
- print(f" Key: {conf.get('key')}")
- print(f" 标题: {conf.get('headline', 'N/A')}")
- print(f" 摘要: {conf.get('summary', 'N/A')}")
- print("\n" + "-" * 60)
- else:
- print("没有待确认的订单")
- return confirmations
- elif response.status_code == 401:
- print("Session 已过期,需要重新登录")
- return None
- else:
- print(f"获取失败: {response.text}")
- return None
- except requests.exceptions.ConnectionError:
- print(f"\n错误: 无法连接到 steamAPI 服务")
- return None
- except Exception as e:
- print(f"\n错误: {e}")
- return None
- def operate_confirmation(
- session: dict,
- confirmation_id: int,
- operation: str = "accept",
- confirmation_key: Optional[int] = None
- ) -> bool:
- """
- 执行确认操作(确认或取消)
- Args:
- session: 登录后获取的 session 数据
- confirmation_id: 确认项 ID(支持传入 creator_id 自动匹配)
- operation: 操作类型,"accept" 或 "cancel"
- confirmation_key: 可选,手动指定确认 key
- Returns:
- 操作是否成功
- """
- if operation not in ("accept", "cancel"):
- print("操作类型错误,只能是 'accept' 或 'cancel'")
- return False
- op_text = "确认" if operation == "accept" else "取消"
- print(f"\n{'='*50}")
- print(f"正在执行 {op_text} 操作...")
- print(f"确认项 ID: {confirmation_id}")
- print(f"{'='*50}\n")
- url = f"{API_BASE_URL}/trade-confirmations/operate"
- payload = {
- "MaFilePath": MA_FILE_PATH,
- "Session": {
- "SteamId": session["steamId"],
- "AccessToken": session["accessToken"],
- "RefreshToken": session["refreshToken"],
- "SessionId": session.get("sessionId")
- },
- "ConfirmationId": confirmation_id,
- "Operation": operation
- }
- if confirmation_key:
- payload["ConfirmationKey"] = confirmation_key
- if PROXY_URL:
- payload["ProxyUrl"] = PROXY_URL
- try:
- response = requests.post(url, json=payload, timeout=30)
- print(f"响应状态码: {response.status_code}")
- if response.status_code == 200:
- data = response.json()
- success = data.get("success", False)
- print(f"\n{'='*50}")
- if success:
- print(f"{op_text}成功!")
- else:
- print(f"{op_text}失败!")
- print(f"{'='*50}")
- print(f"操作类型: {data.get('operation')}")
- print(f"确认ID: {data.get('confirmationId')}")
- print(f"Key: {data.get('confirmationKey')}")
- print(f"Key来源: {'列表匹配' if data.get('keyResolvedFromList') else '手动指定'}")
- print(f"ID来源: {data.get('matchedBy', 'N/A')}")
- # 更新 session
- if "session" in data:
- save_session(data["session"])
- return success
- elif response.status_code == 404:
- print("未找到对应的确认项,可能已过期或被处理")
- return False
- elif response.status_code == 401:
- print("Session 已过期,需要重新登录")
- return False
- else:
- print(f"操作失败: {response.text}")
- return False
- except requests.exceptions.ConnectionError:
- print(f"\n错误: 无法连接到 steamAPI 服务")
- return False
- except Exception as e:
- print(f"\n错误: {e}")
- return False
- def confirm_all(session: dict) -> int:
- """
- 确认所有待确认的订单
- Returns:
- 成功确认的数量
- """
- confirmations = get_confirmation_list(session)
- if not confirmations:
- print("没有待确认的订单")
- return 0
- success_count = 0
- for conf in confirmations:
- conf_id = conf.get("id")
- conf_type = conf.get("type", "Unknown")
- headline = conf.get("headline", "N/A")
- print(f"\n正在确认: {headline} (类型: {conf_type})")
- if operate_confirmation(session, conf_id, "accept"):
- success_count += 1
- return success_count
- def interactive_mode():
- """交互式模式"""
- print("\n" + "=" * 60)
- print(" Steam 订单确认工具 - 交互式模式")
- print("=" * 60)
- # 尝试加载已保存的 session
- session = load_session()
- while True:
- print("\n" + "-" * 40)
- print("请选择操作:")
- print("1. 查看待确认列表")
- print("2. 确认指定订单")
- print("3. 确认所有订单")
- print("4. 取消指定订单")
- print("5. 重新登录")
- print("0. 退出")
- print("-" * 40)
- choice = input("请输入选项 (0-5): ").strip()
- if choice == "0":
- print("退出程序")
- break
- if choice == "1":
- if not session:
- print("请先登录!")
- continue
- get_confirmation_list(session)
- # 更新 session
- new_session = load_session()
- if new_session:
- session = new_session
- elif choice == "2":
- if not session:
- print("请先登录!")
- continue
- confirm_id = input("请输入要确认的订单 ID: ").strip()
- try:
- confirm_id = int(confirm_id)
- except ValueError:
- print("ID 必须是数字")
- continue
- operate_confirmation(session, confirm_id, "accept")
- # 更新 session
- new_session = load_session()
- if new_session:
- session = new_session
- elif choice == "3":
- if not session:
- print("请先登录!")
- continue
- confirm("确认所有待确认的订单? (y/N): ")
- if confirm.lower() == 'y':
- success_count = confirm_all(session)
- print(f"\n成功确认 {success_count} 个订单")
- # 更新 session
- new_session = load_session()
- if new_session:
- session = new_session
- elif choice == "4":
- if not session:
- print("请先登录!")
- continue
- confirm_id = input("请输入要取消的订单 ID: ").strip()
- try:
- confirm_id = int(confirm_id)
- except ValueError:
- print("ID 必须是数字")
- continue
- operate_confirmation(session, confirm_id, "cancel")
- # 更新 session
- new_session = load_session()
- if new_session:
- session = new_session
- elif choice == "5":
- username = input("请输入 Steam 用户名: ").strip()
- password = input("请输入 Steam 密码: ").strip()
- if username and password:
- session = login(username, password)
- else:
- print("用户名和密码不能为空")
- else:
- print("无效的选项")
- def confirm(prompt: str) -> str:
- """简单的确认提示"""
- return input(prompt)
- if __name__ == "__main__":
- # 检查 maFile 是否存在
- if not os.path.exists(MA_FILE_PATH):
- print(f"\n错误: MaFile 文件不存在!")
- print(f"路径: {MA_FILE_PATH}")
- print("\n请检查配置文件中的 MA_FILE_PATH 是否正确")
- sys.exit(1)
- # 检查 API 服务是否可用
- try:
- response = requests.get(f"{API_BASE_URL}/", timeout=5)
- except requests.exceptions.ConnectionError:
- print(f"\n警告: 无法连接到 steamAPI 服务 (http://localhost:5000)")
- print("请确保 steamAPI 服务正在运行")
- print("\n启动 steamAPI 的方法:")
- print(" cd steam-client/steamAPI")
- print(" dotnet run")
- print("\n如果需要指定端口:")
- print(" dotnet run --urls \"http://localhost:5000\"")
- print()
- # 检查命令行参数
- if len(sys.argv) > 1:
- if sys.argv[1] == "--login" and len(sys.argv) >= 4:
- # python steam_confirmation.py --login username password
- session = login(sys.argv[2], sys.argv[3])
- if session:
- print("\n登录成功,现在可以执行其他操作")
- confirmations = get_confirmation_list(session)
- if confirmations:
- print(f"\n找到 {len(confirmations)} 个待确认订单")
- elif sys.argv[1] == "--list":
- session = load_session()
- if session:
- get_confirmation_list(session)
- else:
- print("没有保存的 session,请先登录")
- elif sys.argv[1] == "--confirm" and len(sys.argv) >= 3:
- session = load_session()
- if session:
- confirm_id = int(sys.argv[2])
- operate_confirmation(session, confirm_id, "accept")
- else:
- print("没有保存的 session,请先登录")
- elif sys.argv[1] == "--confirm-all":
- session = load_session()
- if session:
- success_count = confirm_all(session)
- print(f"\n成功确认 {success_count} 个订单")
- else:
- print("没有保存的 session,请先登录")
- else:
- print_usage()
- else:
- # 默认进入交互式模式
- interactive_mode()
- def print_usage():
- """打印使用说明"""
- print("""
- 使用说明:
- 1. 登录 (需要用户名和密码):
- python steam_confirmation.py --login <username> <password>
- 2. 查看待确认列表:
- python steam_confirmation.py --list
- 3. 确认指定订单:
- python steam_confirmation.py --confirm <confirmation_id>
- 4. 确认所有订单:
- python steam_confirmation.py --confirm-all
- 5. 进入交互式模式 (不带参数):
- python steam_confirmation.py
- 注意事项:
- - 首次使用必须先登录
- - Session 会保存到 steam_session.json
- - 如果 session 过期,需要重新登录
- """)
|