// 云函数入口文件 const cloud = require('wx-server-sdk') cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) const db = cloud.database() const _ = db.command const roomCollection = db.collection('rooms') const userCollection = db.collection('users') // 生成6位随机房间号 function generateRoomCode() { return Math.floor(100000 + Math.random() * 900000).toString() } // 云函数入口函数 exports.main = async (event, context) => { const wxContext = cloud.getWXContext() const openid = wxContext.OPENID if (!openid) { return { code: 401, message: '未能获取到用户OpenID', } } const { action, gameType, roomCode, roomId, maxPlayers } = event try { // 创建房间 if (action === 'create') { if (!gameType) { return { code: 400, message: '缺少必要参数:gameType', } } // 查询用户信息 const userResult = await userCollection.where({ userId: openid }).get() if (userResult.data.length === 0) { return { code: 404, message: '用户不存在', } } const user = userResult.data[0] // 生成房间号并确保唯一 let newRoomCode = generateRoomCode() let isUnique = false let attempts = 0 while (!isUnique && attempts < 10) { const existingRoom = await roomCollection.where({ roomCode: newRoomCode, status: _.neq('ended') }).get() if (existingRoom.data.length === 0) { isUnique = true } else { newRoomCode = generateRoomCode() attempts++ } } if (!isUnique) { return { code: 500, message: '无法生成唯一房间号,请稍后再试', } } // 创建新房间 const now = db.serverDate() const newRoom = { roomCode: newRoomCode, gameType, status: 'waiting', // waiting, playing, ended createdAt: now, updatedAt: now, hostId: openid, hostInfo: { userId: user.userId, nickName: user.nickName, avatarUrl: user.avatarUrl }, players: [{ userId: user.userId, nickName: user.nickName, avatarUrl: user.avatarUrl, isHost: true, joinedAt: now, status: 'active' // active, left }], maxPlayers: maxPlayers || 8, gameData: {}, gameResult: null } const roomResult = await roomCollection.add({ data: newRoom }) return { code: 200, message: '创建房间成功', data: { roomId: roomResult._id, roomCode: newRoomCode, gameType, status: 'waiting', hostId: openid, players: newRoom.players, createdAt: new Date(), maxPlayers: newRoom.maxPlayers } } } // 加入房间 else if (action === 'join') { if (!roomCode) { return { code: 400, message: '缺少必要参数:roomCode', } } // 查询用户信息 const userResult = await userCollection.where({ userId: openid }).get() if (userResult.data.length === 0) { return { code: 404, message: '用户不存在', } } const user = userResult.data[0] // 查询房间信息 const roomResult = await roomCollection.where({ roomCode: roomCode, status: _.neq('ended') }).get() if (roomResult.data.length === 0) { return { code: 404, message: '房间不存在或已结束', } } const room = roomResult.data[0] // 检查房间是否已满 const activePlayers = room.players.filter(p => p.status === 'active') if (activePlayers.length >= room.maxPlayers) { return { code: 403, message: '房间已满', } } // 检查用户是否已在房间中 const playerIndex = room.players.findIndex(p => p.userId === openid) const now = db.serverDate() if (playerIndex >= 0) { // 用户已经在房间中,更新状态为active await roomCollection.doc(room._id).update({ data: { [`players.${playerIndex}.status`]: 'active', [`players.${playerIndex}.joinedAt`]: now, updatedAt: now } }) } else { // 用户不在房间中,添加到players数组 await roomCollection.doc(room._id).update({ data: { players: _.push({ userId: user.userId, nickName: user.nickName, avatarUrl: user.avatarUrl, isHost: false, joinedAt: now, status: 'active' }), updatedAt: now } }) } // 获取更新后的房间信息 const updatedRoomResult = await roomCollection.doc(room._id).get() const updatedRoom = updatedRoomResult.data return { code: 200, message: '加入房间成功', data: { roomId: updatedRoom._id, roomCode: updatedRoom.roomCode, gameType: updatedRoom.gameType, status: updatedRoom.status, hostId: updatedRoom.hostId, players: updatedRoom.players, createdAt: updatedRoom.createdAt, maxPlayers: updatedRoom.maxPlayers, gameData: updatedRoom.gameData } } } // 获取房间信息 else if (action === 'getRoomInfo') { if (!roomId && !roomCode) { return { code: 400, message: '缺少必要参数:roomId或roomCode', } } let roomResult if (roomId) { roomResult = await roomCollection.doc(roomId).get() } else { roomResult = await roomCollection.where({ roomCode: roomCode, status: _.neq('ended') }).get() if (roomResult.data.length === 0) { return { code: 404, message: '房间不存在或已结束', } } roomResult = { data: roomResult.data[0] } } const room = roomResult.data return { code: 200, message: '获取房间信息成功', data: { roomId: room._id, roomCode: room.roomCode, gameType: room.gameType, status: room.status, hostId: room.hostId, players: room.players, createdAt: room.createdAt, maxPlayers: room.maxPlayers, gameData: room.gameData, gameResult: room.gameResult } } } // 开始游戏 else if (action === 'startGame') { if (!roomId) { return { code: 400, message: '缺少必要参数:roomId', } } // 查询房间信息 const roomResult = await roomCollection.doc(roomId).get() const room = roomResult.data // 检查是否是房主 if (room.hostId !== openid) { return { code: 403, message: '只有房主可以开始游戏', } } // 检查玩家数量 const activePlayers = room.players.filter(p => p.status === 'active') if (activePlayers.length < 2) { return { code: 400, message: '至少需要2名玩家才能开始游戏', } } // 更新房间状态 await roomCollection.doc(roomId).update({ data: { status: 'playing', updatedAt: db.serverDate(), startedAt: db.serverDate() } }) return { code: 200, message: '游戏已开始', data: { roomId, status: 'playing' } } } // 更新游戏数据 else if (action === 'updateGameData') { if (!roomId || !event.gameData) { return { code: 400, message: '缺少必要参数:roomId或gameData', } } // 检查房间是否存在 const roomResult = await roomCollection.doc(roomId).get() const room = roomResult.data // 检查权限(只有房主或玩家可以更新) const playerExists = room.players.some(p => p.userId === openid && p.status === 'active') if (!playerExists) { return { code: 403, message: '您不是该房间的成员', } } // 更新游戏数据 await roomCollection.doc(roomId).update({ data: { gameData: event.gameData, updatedAt: db.serverDate() } }) return { code: 200, message: '游戏数据已更新', data: { roomId, gameData: event.gameData } } } // 结束游戏 else if (action === 'endGame') { if (!roomId) { return { code: 400, message: '缺少必要参数:roomId', } } // 查询房间信息 const roomResult = await roomCollection.doc(roomId).get() const room = roomResult.data // 检查是否是房主 if (room.hostId !== openid) { return { code: 403, message: '只有房主可以结束游戏', } } // 更新房间状态和游戏结果 await roomCollection.doc(roomId).update({ data: { status: 'ended', updatedAt: db.serverDate(), endedAt: db.serverDate(), gameResult: event.gameResult || {} } }) // 更新所有玩家的游戏历史 for (const player of room.players) { if (player.status === 'active') { await userCollection.where({ userId: player.userId }).update({ data: { gameHistory: _.push({ gameType: room.gameType, roomId: room._id, roomCode: room.roomCode, playedAt: db.serverDate(), role: player.isHost ? 'host' : 'player', result: event.gameResult || {} }) } }) } } return { code: 200, message: '游戏已结束', data: { roomId, status: 'ended', gameResult: event.gameResult || {} } } } // 离开房间 else if (action === 'leaveRoom') { if (!roomId) { return { code: 400, message: '缺少必要参数:roomId', } } // 查询房间信息 const roomResult = await roomCollection.doc(roomId).get() const room = roomResult.data // 查找玩家在数组中的索引 const playerIndex = room.players.findIndex(p => p.userId === openid) if (playerIndex === -1) { return { code: 404, message: '您不在该房间中', } } // 如果是房主离开 if (room.hostId === openid) { // 如果还有其他玩家,选择一个新房主 const activePlayers = room.players.filter(p => p.userId !== openid && p.status === 'active') if (activePlayers.length > 0) { const newHost = activePlayers[0] // 更新房间信息,标记该玩家为离开状态,并更换房主 await roomCollection.doc(roomId).update({ data: { [`players.${playerIndex}.status`]: 'left', hostId: newHost.userId, [`players.${room.players.findIndex(p => p.userId === newHost.userId)}.isHost`]: true, hostInfo: { userId: newHost.userId, nickName: newHost.nickName, avatarUrl: newHost.avatarUrl }, updatedAt: db.serverDate() } }) return { code: 200, message: '您已离开房间,房主已转交', data: { roomId, newHostId: newHost.userId } } } else { // 如果没有其他玩家,直接结束房间 await roomCollection.doc(roomId).update({ data: { status: 'ended', [`players.${playerIndex}.status`]: 'left', updatedAt: db.serverDate(), endedAt: db.serverDate() } }) return { code: 200, message: '您已离开房间,房间已关闭', data: { roomId, status: 'ended' } } } } else { // 如果是普通玩家离开,只更新状态 await roomCollection.doc(roomId).update({ data: { [`players.${playerIndex}.status`]: 'left', updatedAt: db.serverDate() } }) return { code: 200, message: '您已离开房间', data: { roomId } } } } else { return { code: 400, message: '无效的action参数', } } } catch (error) { console.error('房间操作失败:', error) return { code: 500, message: '操作失败: ' + error.message, } } }