# Net-Games API 接口文档 > **版本**: v2.0 > **更新日期**: 2026-04-09 > **服务端**: Flask-SocketIO on port 8900 --- ## 1. HTTP REST API ### 1.1 认证相关 #### `GET /api/auth/status` - 检查登录状态 **响应:** ```json { "authenticated": true, "user": { "id": 1, "username": "caixianming", "nickname": "蔡叔叔", "created_at": "2026-04-01T10:00:00", "role": "user", "is_admin": false } } ``` #### `POST /api/auth/login` - 用户登录 **请求:** ```json { "username": "caixianming", "password": "cxm123456" } ``` **响应:** ```json { "success": true, "message": "登录成功", "user": { "id": 1, "username": "caixianming", "nickname": "蔡叔叔", "role": "user", "is_admin": false } } ``` #### `POST /api/auth/register` - 用户注册 **请求:** ```json { "username": "newuser", "password": "password123" } ``` **响应:** ```json { "success": true, "message": "注册成功", "user": {...} } ``` #### `POST /api/auth/logout` - 用户登出 **响应:** ```json { "success": true, "message": "已登出" } ``` ### 1.2 用户相关 #### `GET /api/user/profile` - 获取个人资料 **响应:** ```json { "success": true, "user": { "id": 1, "username": "caixianming", "nickname": "蔡叔叔", "created_at": "2026-04-01T10:00:00" } } ``` #### `PUT /api/user/profile` - 更新昵称 **请求:** ```json { "nickname": "新昵称" } ``` #### `PUT /api/user/password` - 修改密码 **请求:** ```json { "old_password": "旧密码", "new_password": "新密码" } ``` #### `GET /api/user/scores` - 获取各游戏积分 **响应:** ```json { "success": true, "scores": { "doudizhu": 100, "chinese_chess": 50 } } ``` ### 1.3 房间相关 #### `GET /api/rooms` - 获取房间列表 **查询参数:** - `game_type` - 游戏类型过滤 (可选) - `status` - 状态过滤: waiting/playing (默认: waiting) **响应:** ```json { "success": true, "rooms": [ { "id": "room_xxx", "code": "A1B2C3", "game_type": "doudizhu", "status": "waiting", "max_players": 3, "player_count": 1, "host_id": "player_xxx", "created_at": 1234567890, "players": [...] } ] } ``` #### `GET /api/rooms/` - 获取房间信息 **响应:** ```json { "success": true, "room": { "id": "room_xxx", "code": "A1B2C3", "game_type": "doudizhu", "status": "playing", "players": [...], "game": {...} } } ``` ### 1.4 统计相关 #### `GET /api/stats` - 获取服务统计(公开) **响应:** ```json { "success": true, "stats": { "total_rooms": 10, "waiting_rooms": 3, "playing_rooms": 7, "total_players": 21 } } ``` #### `GET /api/admin/stats` - 管理员详细统计 **响应:** ```json { "success": true, "stats": { "total_rooms": 10, "waiting_rooms": 3, "playing_rooms": 7, "total_players": 21, "online_users": 15, "by_game": { "doudizhu": {...} }, "rooms": [...] } } ``` #### `DELETE /api/admin/rooms/` - 强制关闭房间 **响应:** ```json { "success": true, "message": "房间 A1B2C3 已关闭" } ``` --- ## 2. Socket.IO 事件 ### 2.1 连接管理 #### `connect` - 客户端连接 **服务端响应:** ```json { "event": "connected", "data": { "socket_id": "xxx", "message": "欢迎连接到 Net-Games", "has_active_game": true, "room_code": "A1B2C3", "room_id": "room_xxx" } } ``` #### `disconnect` - 客户端断开 - 服务端自动处理,标记玩家为离线 - 30秒后启用AI托管 #### `ping` / `pong` - 心跳 **客户端发送:** ```json { "event": "ping", "data": {"timestamp": 1234567890} } ``` **服务端响应:** ```json { "event": "pong", "data": { "timestamp": 1234567890, "server_time": 1234567890 } } ``` ### 2.2 房间管理事件 #### `create_room` - 创建房间 **客户端发送:** ```json { "game_type": "doudizhu", "player_name": "蔡叔叔", "config": { "max_players": 3 }, "ai_players": [ {"name": "AI-规则", "ai_type": "rule"}, {"name": "AI-DeepSeek", "ai_type": "deepseek"} ] } ``` **服务端响应 (创建者):** ```json { "event": "room_created", "data": { "success": true, "room": { "id": "room_xxx", "code": "A1B2C3", "game_type": "doudizhu", "status": "waiting", "max_players": 3, "player_count": 3, "host_id": "player_xxx", "players": [...] }, "player": { "id": "player_xxx", "name": "蔡叔叔", "seat_number": 0, "is_ready": false } } } ``` **错误响应:** ```json { "event": "error", "data": { "code": "ALREADY_ONLINE", "message": "账号 \"蔡叔叔\" 已在游戏中" } } ``` #### `join_room` - 加入房间 **客户端发送:** ```json { "room_code": "A1B2C3", "player_name": "玩家B" } ``` **服务端响应 (加入者):** ```json { "event": "room_joined", "data": { "success": true, "room": {...}, "player": {...} } } ``` **广播 (其他玩家):** ```json { "event": "player_joined", "data": { "player": { "id": "player_yyy", "name": "玩家B", "seat_number": 1, "is_ready": false } } } ``` #### `leave_room` - 离开房间 **服务端响应 (离开者):** ```json { "event": "room_left", "data": {"success": true} } ``` **广播 (其他玩家):** ```json { "event": "player_left", "data": { "player_id": "player_xxx", "player_name": "蔡叔叔" } } ``` #### `reconnect_room` - 断线重连 **客户端发送:** ```json { "room_code": "A1B2C3", "player_id": "player_xxx", "player_name": "蔡叔叔" } ``` **服务端响应 (重连者):** ```json { "event": "reconnect_success", "data": { "player_id": "player_xxx", "player": {...}, "room": {...}, "was_ai_controlled": true, "message": "重连成功,欢迎回到游戏!" } } ``` **广播 (其他玩家):** ```json { "event": "player_reconnected", "data": { "player_id": "player_xxx", "player_name": "蔡叔叔", "was_ai_controlled": true, "message": "蔡叔叔 已回到游戏" } } ``` ### 2.3 游戏准备事件 #### `set_ready` - 设置准备状态 **客户端发送:** ```json { "ready": true } ``` **广播 (所有人):** ```json { "event": "room_updated", "data": { "room": {...} } } ``` #### `start_game` - 开始游戏(仅房主) **广播 (所有人):** ```json { "event": "game_started", "data": { "room": { "id": "room_xxx", "status": "playing", "game": { "state": { "phase": "playing", "current_turn": "player_xxx", "data": { "phase": "calling", "lord_id": null, "bottom_cards": [], "player_cards_count": {"player_xxx": 17, ...} } } } } } } ``` ### 2.4 游戏操作事件 #### `game_action` - 游戏操作 **客户端发送:** ```json { "action": "call", "data": {"want": true} } ``` **action 类型:** - `call` - 叫地主 (data: `{want: true/false}`) - `play` - 出牌 (data: `{card_ids: [...]}`) - `pass` - 不出/过 (data: `{}`) - `toggle_trustee` - 切换托管状态 **成功广播 (所有人):** ```json { "event": "state_update", "data": { "action": "play", "player_id": "player_xxx", "result": { "success": true, "message": "出牌成功", "played_cards": [...], "card_type": {"type": "pair", "name": "对子"} }, "game_state": {...} } } ``` **失败响应 (仅操作者):** ```json { "event": "action_failed", "data": { "action": "play", "message": "牌型不合法" } } ``` ### 2.5 游戏结束事件 #### `game_ended` - 游戏结束广播 ```json { "event": "game_ended", "data": { "winner": { "id": "player_xxx", "player_id": "player_xxx", "name": "蔡叔叔", "is_lord": true }, "winner_id": "player_xxx", "room": {...}, "scores": { "player_xxx": { "name": "蔡叔叔", "change": 6, "total": 106, "is_lord": true, "is_winner": true, "is_ai": false }, "player_yyy": { "name": "AI-规则", "change": 0, "total": 0, "is_ai": true } } } } ``` ### 2.6 托管与超时事件 #### `trustee_changed` - 托管状态变更 ```json { "event": "trustee_changed", "data": { "player_id": "player_xxx", "player_name": "蔡叔叔", "is_trustee": true, "message": "蔡叔叔 进入了托管模式" } } ``` #### `player_ai_controlled` - 玩家被AI托管 ```json { "event": "player_ai_controlled", "data": { "player_id": "player_xxx", "player_name": "蔡叔叔", "reason": "timeout", "message": "蔡叔叔 超时3次,已启用AI托管" } } ``` #### `player_disconnected` - 玩家断开连接 ```json { "event": "player_disconnected", "data": { "player_id": "player_xxx", "player_name": "蔡叔叔", "will_ai_control": true } } ``` #### `turn_timeout_auto` - 超时自动操作 ```json { "event": "turn_timeout_auto", "data": { "player_id": "player_xxx", "player_name": "蔡叔叔", "action": "pass", "action_name": "不要", "timeout_count": 1, "game_state": {...}, "message": "蔡叔叔 超时,自动不要 (1/3)" } } ``` ### 2.7 错误事件 #### `error` - 错误通知 ```json { "event": "error", "data": { "code": "NOT_YOUR_TURN", "message": "不是你的回合" } } ``` **常见错误码:** | 错误码 | 说明 | |--------|------| | `NOT_IN_ROOM` | 不在任何房间中 | | `ROOM_NOT_FOUND` | 房间不存在 | | `ROOM_FULL` | 房间已满 | | `GAME_NOT_STARTED` | 游戏未开始 | | `NOT_HOST` | 只有房主可以开始游戏 | | `NOT_YOUR_TURN` | 不是你的回合 | | `ALREADY_ONLINE` | 已在其他游戏中 | | `INVALID_CARDS` | 牌型不合法 | | `CANNOT_BEAT` | 管不起上家的牌 | | `AI_PLAYER` | AI玩家不能进行此操作 | --- ## 3. 游戏状态结构 ### 3.1 斗地主游戏状态 ```json { "room_id": "room_xxx", "game_type": "doudizhu", "min_players": 3, "max_players": 3, "player_count": 3, "is_started": true, "is_ended": false, "state": { "game_type": "doudizhu", "room_id": "room_xxx", "phase": "playing", "round": 1, "turn_count": 5, "current_turn": "player_xxx", "winner": null, "player_states": { "player_xxx": { "name": "蔡叔叔", "is_ai": false, "seat": 0, "cards": [...], "card_count": 17 } }, "data": { "phase": "playing", "current_turn": "player_xxx", "lord_id": "player_xxx", "bottom_cards": [...], "desktop_cards": { "type": "pair", "value": 5, "name": "对子" }, "last_played_id": "player_yyy", "pass_count": 0, "player_cards_count": { "player_xxx": 17, "player_yyy": 15, "player_zzz": 16 } }, "history": [...] }, "players": { "player_xxx": { "id": "player_xxx", "name": "蔡叔叔", "type": "human", "is_ai": false, "is_connected": true, "is_ai_controlled": false, "seat_number": 0, "is_ready": true, "role": "landlord" } } } ``` ### 3.2 玩家视角 (Player View) 客户端通过 `player_view` 字段只能看到自己的手牌: ```json { "my_cards": [ {"id": "card_1", "suit": "spade", "rank": "A", "value": 14}, {"id": "card_2", "suit": "heart", "rank": "K", "value": 13} ], "my_cards_count": 17 } ``` --- ## 4. AI 接口 ### 4.1 AI 适配器基类 ```python class AIAdapter(ABC): @abstractmethod async def make_decision(self, game_state: dict, available_actions: list, player_context: dict) -> dict: """ 返回决策结果 { "action": "play" | "pass" | "call", "data": {...}, "reasoning": "决策理由" } """ pass ``` ### 4.2 AI 类型 | AI类型 | 说明 | 适用游戏 | |--------|------|----------| | `rule` | 基于规则的贪心策略 | 斗地主 | | `deepseek` | DeepSeek 大模型 | 通用 | | `minimax` | Minimax + Alpha-Beta | 象棋 | ### 4.3 AI 输入格式 ```json { "game_state": { "status": "playing", "current_turn": "ai_player_1", "phase": "playing", "desktop_cards": {...}, "player_cards_count": {...} }, "available_actions": ["play", "pass"], "player_context": { "cards": [...], "is_lord": false, "teammate_cards": 17 } } ``` --- ## 5. 游戏流程时序图 ### 5.1 创建房间并游戏 ``` ┌─────────┐ ┌──────────┐ ┌──────────┐ │ Client │ │ Server │ │ AI │ └────┬────┘ └────┬─────┘ └────┬─────┘ │ │ │ │ create_room │ │ │ ─────────────>│ │ │ │ create room │ │ │ add AI players │ │ room_created │ │ │ <─────────────│ │ │ │ │ │ start_game │ │ │ ─────────────>│ │ │ │ start game │ │ game_started │ │ │ <─────────────│ │ │ │ │ │ state_update │ │ │ <─────────────│ │ │ │ │ │ │ ──────────────>│ │ │ AI decision │ │ │ <──────────────│ │ │ │ │ state_update │ │ │ <─────────────│ (broadcast) │ ``` ### 5.2 断线重连流程 ``` ┌─────────┐ ┌──────────┐ ┌──────────┐ │ Client │ │ Server │ │ Room │ └────┬────┘ └────┬─────┘ └────┬─────┘ │ │ │ │ disconnect │ │ │ ────────X │ │ │ │ mark offline │ │ │ start 30s timer│ │ │ │ │ reconnect │ │ │ ─────────────>│ │ │ │ find player │ │ │ ──────────────>│ │ │ <──────────────│ │ │ │ │ reconnect_success │ │ <─────────────│ │ │ │ cancel timer │ │ │ │ │ (30s后如果没有重连) │ │ │ enable AI ctrl │ │ │ │ │ player_ai_controlled │ │ <─────────────│ (broadcast) │ ``` --- ## 6. 配置说明 ### 6.1 环境变量 | 变量名 | 默认值 | 说明 | |--------|--------|------| | `NET_GAMES_HOST` | `0.0.0.0` | 服务监听地址 | | `NET_GAMES_PORT` | `8900` | 服务端口 | | `NET_GAMES_DEBUG` | `true` | 调试模式 | | `DATABASE_URL` | `sqlite:///./netgames.db` | 数据库连接 | | `DEEPSEEK_API_KEY` | - | DeepSeek API 密钥 | | `LOG_LEVEL` | `INFO` | 日志级别 | ### 6.2 游戏配置 (config.py) ```python ROOM_MAX_PLAYERS = { 'doudizhu': 3, 'chinese_chess': 2, } ROOM_CODE_LENGTH = 6 ROOM_INACTIVE_TIMEOUT_MINUTES = 30 AI_TIMEOUT_SECONDS = 30 TURN_TIMEOUT_SECONDS = 30 # 回合超时 MAX_TIMEOUT_COUNT = 3 # 最大超时次数 ``` --- ## 7. 更新日志 | 日期 | 版本 | 变更内容 | |------|------|----------| | 2026-04-09 | v2.0 | 更新为实际实现版本,添加认证API、托管机制、超时处理 | | 2026-04-08 | v1.0 | 初始设计文档 | --- *文档版本: v2.0* *最后更新: 2026-04-09*