Files
Ubuntu 32b43f85bd a
2026-07-03 16:58:28 +08:00

16 KiB

Net-Games API 接口文档

版本: v2.0
更新日期: 2026-04-09
服务端: Flask-SocketIO on port 8900


1. HTTP REST API

1.1 认证相关

GET /api/auth/status - 检查登录状态

响应:

{
  "authenticated": true,
  "user": {
    "id": 1,
    "username": "caixianming",
    "nickname": "蔡叔叔",
    "created_at": "2026-04-01T10:00:00",
    "role": "user",
    "is_admin": false
  }
}

POST /api/auth/login - 用户登录

请求:

{
  "username": "caixianming",
  "password": "cxm123456"
}

响应:

{
  "success": true,
  "message": "登录成功",
  "user": {
    "id": 1,
    "username": "caixianming",
    "nickname": "蔡叔叔",
    "role": "user",
    "is_admin": false
  }
}

POST /api/auth/register - 用户注册

请求:

{
  "username": "newuser",
  "password": "password123"
}

响应:

{
  "success": true,
  "message": "注册成功",
  "user": {...}
}

POST /api/auth/logout - 用户登出

响应:

{
  "success": true,
  "message": "已登出"
}

1.2 用户相关

GET /api/user/profile - 获取个人资料

响应:

{
  "success": true,
  "user": {
    "id": 1,
    "username": "caixianming",
    "nickname": "蔡叔叔",
    "created_at": "2026-04-01T10:00:00"
  }
}

PUT /api/user/profile - 更新昵称

请求:

{
  "nickname": "新昵称"
}

PUT /api/user/password - 修改密码

请求:

{
  "old_password": "旧密码",
  "new_password": "新密码"
}

GET /api/user/scores - 获取各游戏积分

响应:

{
  "success": true,
  "scores": {
    "doudizhu": 100,
    "chinese_chess": 50
  }
}

1.3 房间相关

GET /api/rooms - 获取房间列表

查询参数:

  • game_type - 游戏类型过滤 (可选)
  • status - 状态过滤: waiting/playing (默认: waiting)

响应:

{
  "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/<room_code> - 获取房间信息

响应:

{
  "success": true,
  "room": {
    "id": "room_xxx",
    "code": "A1B2C3",
    "game_type": "doudizhu",
    "status": "playing",
    "players": [...],
    "game": {...}
  }
}

1.4 统计相关

GET /api/stats - 获取服务统计(公开)

响应:

{
  "success": true,
  "stats": {
    "total_rooms": 10,
    "waiting_rooms": 3,
    "playing_rooms": 7,
    "total_players": 21
  }
}

GET /api/admin/stats - 管理员详细统计

响应:

{
  "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/<room_code> - 强制关闭房间

响应:

{
  "success": true,
  "message": "房间 A1B2C3 已关闭"
}

2. Socket.IO 事件

2.1 连接管理

connect - 客户端连接

服务端响应:

{
  "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 - 心跳

客户端发送:

{
  "event": "ping",
  "data": {"timestamp": 1234567890}
}

服务端响应:

{
  "event": "pong",
  "data": {
    "timestamp": 1234567890,
    "server_time": 1234567890
  }
}

2.2 房间管理事件

create_room - 创建房间

客户端发送:

{
  "game_type": "doudizhu",
  "player_name": "蔡叔叔",
  "config": {
    "max_players": 3
  },
  "ai_players": [
    {"name": "AI-规则", "ai_type": "rule"},
    {"name": "AI-DeepSeek", "ai_type": "deepseek"}
  ]
}

服务端响应 (创建者):

{
  "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
    }
  }
}

错误响应:

{
  "event": "error",
  "data": {
    "code": "ALREADY_ONLINE",
    "message": "账号 \"蔡叔叔\" 已在游戏中"
  }
}

join_room - 加入房间

客户端发送:

{
  "room_code": "A1B2C3",
  "player_name": "玩家B"
}

服务端响应 (加入者):

{
  "event": "room_joined",
  "data": {
    "success": true,
    "room": {...},
    "player": {...}
  }
}

广播 (其他玩家):

{
  "event": "player_joined",
  "data": {
    "player": {
      "id": "player_yyy",
      "name": "玩家B",
      "seat_number": 1,
      "is_ready": false
    }
  }
}

leave_room - 离开房间

服务端响应 (离开者):

{
  "event": "room_left",
  "data": {"success": true}
}

广播 (其他玩家):

{
  "event": "player_left",
  "data": {
    "player_id": "player_xxx",
    "player_name": "蔡叔叔"
  }
}

reconnect_room - 断线重连

客户端发送:

{
  "room_code": "A1B2C3",
  "player_id": "player_xxx",
  "player_name": "蔡叔叔"
}

服务端响应 (重连者):

{
  "event": "reconnect_success",
  "data": {
    "player_id": "player_xxx",
    "player": {...},
    "room": {...},
    "was_ai_controlled": true,
    "message": "重连成功,欢迎回到游戏!"
  }
}

广播 (其他玩家):

{
  "event": "player_reconnected",
  "data": {
    "player_id": "player_xxx",
    "player_name": "蔡叔叔",
    "was_ai_controlled": true,
    "message": "蔡叔叔 已回到游戏"
  }
}

2.3 游戏准备事件

set_ready - 设置准备状态

客户端发送:

{
  "ready": true
}

广播 (所有人):

{
  "event": "room_updated",
  "data": {
    "room": {...}
  }
}

start_game - 开始游戏(仅房主)

广播 (所有人):

{
  "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 - 游戏操作

客户端发送:

{
  "action": "call",
  "data": {"want": true}
}

action 类型:

  • call - 叫地主 (data: {want: true/false})
  • play - 出牌 (data: {card_ids: [...]})
  • pass - 不出/过 (data: {})
  • toggle_trustee - 切换托管状态

成功广播 (所有人):

{
  "event": "state_update",
  "data": {
    "action": "play",
    "player_id": "player_xxx",
    "result": {
      "success": true,
      "message": "出牌成功",
      "played_cards": [...],
      "card_type": {"type": "pair", "name": "对子"}
    },
    "game_state": {...}
  }
}

失败响应 (仅操作者):

{
  "event": "action_failed",
  "data": {
    "action": "play",
    "message": "牌型不合法"
  }
}

2.5 游戏结束事件

game_ended - 游戏结束广播

{
  "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 - 托管状态变更

{
  "event": "trustee_changed",
  "data": {
    "player_id": "player_xxx",
    "player_name": "蔡叔叔",
    "is_trustee": true,
    "message": "蔡叔叔 进入了托管模式"
  }
}

player_ai_controlled - 玩家被AI托管

{
  "event": "player_ai_controlled",
  "data": {
    "player_id": "player_xxx",
    "player_name": "蔡叔叔",
    "reason": "timeout",
    "message": "蔡叔叔 超时3次,已启用AI托管"
  }
}

player_disconnected - 玩家断开连接

{
  "event": "player_disconnected",
  "data": {
    "player_id": "player_xxx",
    "player_name": "蔡叔叔",
    "will_ai_control": true
  }
}

turn_timeout_auto - 超时自动操作

{
  "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 - 错误通知

{
  "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 斗地主游戏状态

{
  "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 字段只能看到自己的手牌:

{
  "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 适配器基类

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 输入格式

{
  "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)

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