import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { ValidationPipe } from '@nestjs/common'; import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; import { WsAdapter } from '@nestjs/platform-ws'; /** * 检查数据库配置是否完整 by angjustinl 2025-12-17 * * @returns 是否配置了数据库 */ function isDatabaseConfigured(): boolean { const requiredEnvVars = ['DB_HOST', 'DB_PORT', 'DB_USERNAME', 'DB_PASSWORD', 'DB_NAME']; return requiredEnvVars.every(varName => process.env[varName]); } /** * 打印启动横幅 */ function printBanner() { const isDatabaseMode = isDatabaseConfigured(); console.log('\n' + '='.repeat(70)); console.log('🎮 Pixel Game Server'); console.log('='.repeat(70)); console.log(`📦 存储模式: ${isDatabaseMode ? '数据库模式 (MySQL)' : '内存模式 (Memory)'}`); if (!isDatabaseMode) { console.log('⚠️ 警告: 未检测到数据库配置,使用内存存储'); console.log('💡 提示: 数据将在服务重启后丢失'); console.log('📝 配置: 请在 .env 文件中配置数据库连接信息'); } else { console.log('✅ 数据库: 已连接到 MySQL 数据库'); } console.log('='.repeat(70) + '\n'); } async function bootstrap() { // 打印启动横幅 printBanner(); const app = await NestFactory.create(AppModule, { logger: ['error', 'warn', 'log'], }); // 配置原生 WebSocket 适配器 app.useWebSocketAdapter(new WsAdapter(app)); // 允许前端后台(如Vite/React)跨域访问,包括WebSocket app.enableCors({ origin: [ 'http://localhost:3000', 'http://localhost:5173', // Vite默认端口 'https://whaletownend.xinghangee.icu', /^https:\/\/.*\.xinghangee\.icu$/ ], credentials: true, methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'], }); // 全局启用校验管道(核心配置) app.useGlobalPipes( new ValidationPipe({ whitelist: true, // 过滤掉 DTO 中未定义的字段(比如传了个 `age` 但 DTO 里没有,会自动忽略) forbidNonWhitelisted: true, // 若传了未定义的字段,直接报错(防止传多余参数) transform: true, // 自动把入参转为 DTO 对应的类型(比如前端传的字符串数字 `'1'` 转为数字 `1`) }), ); // 配置Swagger文档 const config = new DocumentBuilder() .setTitle('Pixel Game Server API') .setDescription(` 像素游戏服务器API文档 - 包含用户认证、聊天系统、Zulip集成等功能 ## 🚀 快速测试工具 ### 🔌 WebSocket 测试页面 **[点击这里打开 WebSocket 测试工具 →](/websocket-test)** 一键测试WebSocket连接、用户认证、消息发送等功能,无需额外工具! ### 📚 其他测试工具 - **[WebSocket API 文档](/websocket/docs)** - 详细的消息格式和示例 - **[WebSocket 连接信息](/chat/websocket/info)** - 连接配置和参数 --- ## 主要功能模块 ### 🔐 用户认证 (auth) - 用户注册、登录 - JWT Token 管理 - 邮箱验证和密码重置 - 验证码登录 ### 💬 聊天系统 (chat) - WebSocket 实时聊天 - 聊天历史记录 - 系统状态监控 - Zulip 集成状态 ### 🔌 WebSocket 接口 (websocket) - 实时消息传输 - 位置同步 - 地图房间管理 - 连接状态监控 ### 👑 管理员后台 (admin) - 用户管理 - 系统监控 - 日志查看 ## WebSocket 连接 游戏聊天功能主要通过 WebSocket 实现: **连接地址**: \`wss://whaletownend.xinghangee.icu/game\` (原生WebSocket) **重要变更**: 已从Socket.IO迁移到原生WebSocket,提升性能和稳定性 **连接路径**: \`/game\` - 统一的WebSocket入口 **支持的事件**: - \`login\`: 用户登录(需要 JWT Token) - \`chat\`: 发送聊天消息 - \`position\`: 位置更新 **JWT Token 要求**: - issuer: \`whale-town\` - audience: \`whale-town-users\` - type: \`access\` - 必需字段: \`sub\`, \`username\`, \`email\`, \`role\` ## Zulip 集成 系统集成了 Zulip 聊天服务,实现游戏内聊天与 Zulip 社群的双向同步。 **支持的地图**: - Whale Port (鲸鱼港) - Pumpkin Valley (南瓜谷) - Novice Village (新手村) ## 最近更新 (v2.1.0) ### 🚀 WebSocket 架构升级 - ✅ 移除Socket.IO依赖,使用原生WebSocket - ✅ 实现地图房间分组管理 - ✅ 支持本地和全局消息广播 - ✅ 新增实时连接监控 ### 📚 文档完善 - ✅ 新增WebSocket专用API文档 - ✅ 提供交互式消息格式展示 - ✅ 包含测试工具和示例代码 - ✅ 完整的开发者指南 ### 🔧 性能优化 - ✅ 更高效的消息路由机制 - ✅ 优化连接池管理 - ✅ 增强错误处理和日志记录 `) .setVersion('2.1.0') .addTag('auth', '🔐 用户认证相关接口') .addTag('chat', '💬 聊天系统相关接口') .addTag('websocket', '🔌 WebSocket接口文档和测试') .addTag('admin', '👑 管理员后台相关接口') .addBearerAuth( { type: 'http', scheme: 'bearer', bearerFormat: 'JWT', name: 'JWT', description: '请输入JWT token', in: 'header', }, 'JWT-auth', ) .addServer('http://localhost:3000', '开发环境 - REST API') .addServer('https://whaletownend.xinghangee.icu', '生产环境 - REST API') .addServer('wss://whaletownend.xinghangee.icu/game', '生产环境 - WebSocket') .addServer('ws://localhost:3001/game', '开发环境 - WebSocket') .build(); const document = SwaggerModule.createDocument(app, config); SwaggerModule.setup('api-docs', app, document, { swaggerOptions: { persistAuthorization: true, }, }); await app.listen(3000); console.log('Pixel Game Server is running on http://localhost:3000'); console.log('API Documentation is available at http://localhost:3000/api-docs'); } bootstrap();