align API response format with maqt.top real specs: weapon-categories, weapons, schemes, schemes_aob, favorites check, encryption key derivation

This commit is contained in:
2026-05-24 01:47:08 +08:00
parent ea4e0f6e07
commit 8bcb6c7e7a
13 changed files with 1861 additions and 366 deletions

316
origet/api_spec.py Normal file
View File

@@ -0,0 +1,316 @@
"""
码枪堂 原版 (maqt.top) API 接口规格
来源: app.asar v7.0.4, dist/weapon-tuner.html + dist/assets/CfKCgw5l.js
"""
import hashlib
import base64
import json
from dataclasses import dataclass, field
from typing import Optional, Any
BASE_URL = "https://maqt.top"
ENCRYPTION_KEY = "maqt-delta-force-2024-secret-key-32"
AES_KEY = hashlib.sha256(ENCRYPTION_KEY.encode("utf-8")).digest() # 32 bytes
CATEGORY_MAP = {
"AR": "突击步枪",
"SMG": "冲锋枪",
"SR": "狙击步枪",
"LMG": "轻机枪",
"SG": "霰弹枪",
"Pistol": "手枪",
"Launcher": "发射器",
}
# ---- Data Models ----
@dataclass
class WeaponCategory:
category: str # 实际返回中文名 e.g. "突击步枪"
scheme_count: int = 0
@dataclass
class Weapon:
id: int
weapon_name: str # e.g. "M4A1"
display_name: str # e.g. "M4A1突击步枪"
category: str # 中文分类名
use_count: int = 0
@dataclass
class SchemeItem:
id: int
user_id: int
username: str
avatar: str
description: str
scheme_content: str # 含武器名+模式前缀,如 "M4A1突击步枪-烽火地带-..."
category: str
weapon_name: str
price: Optional[str] # 实际是字符串 e.g. "97W"
tags: list[str]
uses: int
total_historical_uses: int
status: Optional[str]
source: Optional[int] # 1:自行 2:别人分享 3:工具生成
created_at: str
updated_at: str
# 合作方字段
partner_type: Optional[str] # "club" | "none"
partner_level: Optional[str] # "bronze" | "gold" | "none"
partner_badge: Optional[str]
partner_logo: Optional[str]
social_link: Optional[str]
@dataclass
class Pagination:
page: int
limit: int
hasMore: bool
@dataclass
class SchemeListResponse:
success: bool
data: list[SchemeItem]
pagination: Pagination
@dataclass
class AdvertItem:
id: str
author: str
avatar: str
shareTime: str
title: str
description: str
image_url: Optional[str]
link_url: str
isVip: bool
@dataclass
class UserInfo:
id: int
username: str
avatar: Optional[str] = None
email: Optional[str] = None
status: str = "active"
isVip: int = 0
vipExpireAt: Optional[str] = None
freezeUntil: Optional[str] = None
@dataclass
class LoginResponse:
success: bool
message: str
token: Optional[str] = None
user: Optional[UserInfo] = None
@dataclass
class SessionStatusResponse:
success: bool
loggedIn: bool
user: Optional[UserInfo] = None
message: Optional[str] = None
@dataclass
class VipStatusData:
success: bool
isVip: bool
vipExpireAt: Optional[str]
daysRemaining: int
activatedAt: Optional[str]
activatedCardKey: Optional[str]
expired: bool
message: Optional[str]
# ---- Endpoints ----
ENDPOINTS = {
"weapon_categories": {
"method": "GET",
"path": "/api/weapon-categories",
"auth": False,
"params": None,
"returns": "list[WeaponCategory]",
},
"weapons": {
"method": "GET",
"path": "/api/weapons",
"auth": False,
"params": {"category": "武器分类代码, optional"},
"returns": "list[Weapon]",
},
"schemes": {
"method": "GET",
"path": "/api/schemes",
"auth": False,
"params": {
"sort": "hot | new",
"page": "页码 (1-based)",
"limit": "固定 12",
"weaponCategory": "中文分类名, optional",
"weaponName": "武器中文名, optional",
"minPrice": "最低价格, optional",
"maxPrice": "最高价格, optional",
"search": "搜索关键词, optional",
},
"returns": "SchemeListResponse (可能加密)",
},
"schemes_aob": {
"method": "GET",
"path": "/api/schemes_aob",
"auth": False,
"params": { # 同上
"sort": "hot | new",
"page": "页码 (1-based)",
"limit": "固定 12",
},
"returns": "SchemeListResponse (可能加密)",
},
"favorites": {
"method": "GET",
"path": "/api/favorites",
"auth": True,
"params": {"sort": "", "page": "", "limit": "12"},
"returns": "SchemeListResponse",
},
"login": {
"method": "POST",
"path": "/api/login",
"auth": False,
"body": {
"username": "string",
"password": "string",
"installId": "string, optional",
"deviceHash": "string, optional",
"platform": "string, optional",
"osVersion": "string, optional",
"appVersion": "string, optional",
},
"returns": "LoginResponse",
},
"register": {
"method": "POST",
"path": "/api/register",
"auth": False,
"body": {"username": "", "password": "", "email": ""},
"returns": "LoginResponse (with token)",
},
"session_status": {
"method": "GET",
"path": "/api/session-status",
"auth": True,
"params": None,
"returns": "SessionStatusResponse",
},
"vip_status": {
"method": "GET",
"path": "/api/vip-status",
"auth": True,
"params": None,
"returns": "VipStatusData (可能加密)",
},
"activate_vip": {
"method": "POST",
"path": "/api/activate-vip",
"auth": True,
"body": {"cardKey": "VIP卡密"},
},
"favorites_add": {
"method": "POST",
"path": "/api/favorites",
"auth": True,
"body": {"schemeId": "", "source": "烽火地带"},
},
"favorites_remove": {
"method": "DELETE",
"path": "/api/favorites/{schemeId}?source={source}",
"auth": True,
},
"favorites_check": {
"method": "GET",
"path": "/api/favorites/check?schemeId={id}&source={source}",
"auth": True,
},
"favorites_count": {
"method": "GET",
"path": "/api/favorites/count",
"auth": True,
},
"scheme_use": {
"method": "POST",
"path": "/api/{mode}/{schemeId}/use",
"auth": False,
},
"scheme_report": {
"method": "POST",
"path": "/api/{mode}/{schemeId}/report",
"auth": True,
"body": {"reason": "invalid|inappropriate", "description": ""},
},
"scheme_share": {
"method": "POST",
"path": "/api/schemes", # or /api/schemes_aob
"auth": False,
"headers": {"x-user-info": "base64(json({id,username}))"},
"body": {
"description": "方案描述 <=50字",
"category": "武器分类中文名",
"weaponName": "武器中文名",
"scheme": "配置代码",
"tags": [],
"price": 15, # 烽火模式必填
},
},
"adverts_list": {
"method": "GET",
"path": "/api/adverts/list",
"auth": False,
},
"adverts_click": {
"method": "POST",
"path": "/api/adverts/{advertId}/click",
"auth": False,
},
"user_stats": {
"method": "GET",
"path": "/api/user/stats/{userId}",
"auth": False,
},
"user_schemes": {
"method": "GET",
"path": "/api/user/schemes/{userId}",
"auth": False,
},
"user_favorited_count": {
"method": "GET",
"path": "/api/user/favorited-count/{userId}",
"auth": True,
},
"filter_share_categories": {
"method": "GET",
"path": "/api/filter-share/categories",
"auth": False,
},
"filter_shares": {
"method": "GET",
"path": "/api/filter-shares",
"auth": False,
},
"filter_share_copy": {
"method": "POST",
"path": "/api/filter-shares/{id}/copy",
"auth": False,
"body": {"slot": "primary"},
},
"activity_ping": {
"method": "GET",
"path": "/api/activity/ping",
"auth": True,
},
"game_map_password": {
"method": "GET",
"path": "/api/game/map-password",
"auth": False,
},
}