123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534 |
- // 云函数入口文件
- 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,
- }
- }
- }
|