using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using ChessGameDomain; using ChessGameService.Param; using Common.Redis; using CommonDomain; using CommonDomain.BaseModel; using CommonDomain.Enum; using DotNetCore.CAP; using Microsoft.Extensions.Logging; using RedisHelper; using RedisService; using UserDomain.Enum; using UserService; using UserService.Param; using UserService.User; namespace ChessGameService { public class ChessGameService : IChessGameService { private readonly IRedisService _redisService; private readonly ILogger _logger; private readonly IDistributedLock _distributedLock; private readonly IUserService _userService; private readonly ICapPublisher _capPublisher; public ChessGameService(IRedisService redisService, ILogger logger, IDistributedLock distributedLock, IUserService userService, ICapPublisher capPublisher) { _redisService = redisService; _logger = logger; _distributedLock = distributedLock; _userService = userService; _capPublisher = capPublisher; } public async Task<(bool isok, string msg, ChessGameRoom room)> CreateRoomAsync(CreateRoomParam param, string cid) { var user = await _userService.GetUser(param.userId); if (user == null) return (false, "用户不存在", null); var gameConfig = _redisService.GetGameConfig(); if (gameConfig == null) return (false, "游戏配置不存在", null); return await _distributedLock.TryExecuteAsync( $"{RedisKey.DistributedLockPrefix}chess:room:{param.roomId}", () => { var room = _redisService.GetChessRoom(param.roomId); if (room == null) { return Task.FromResult<(bool isok, string msg, ChessGameRoom room)>((false, "房间不存在", null)); } var allRooms = _redisService.GetAllChessRooms(); if (allRooms != null) { foreach (var oldRoom in allRooms) { if (oldRoom.RoomId == param.roomId) continue; var oldUser = oldRoom.users?.FirstOrDefault(u => u.userId == param.userId); if (oldUser != null) { if (oldRoom.createUserId == param.userId) { oldRoom.users = new List(); oldRoom.state = 3; oldRoom.password = ""; oldRoom.createUserId = ""; oldRoom.gold = 0; oldRoom.gameType = 0; oldRoom.robotCount = 0; oldRoom.IsGameEnded = false; oldRoom.EndGameRequests?.Clear(); oldRoom.PendingWinUserId = null; oldRoom.TimeoutLoserUserId = ""; oldRoom.LastActiveTime = 0; } else { oldRoom.users.Remove(oldUser); if (oldRoom.users.Count == 0) { oldRoom.state = 3; oldRoom.password = ""; oldRoom.createUserId = ""; oldRoom.gold = 0; oldRoom.gameType = 0; oldRoom.robotCount = 0; oldRoom.IsGameEnded = false; } else { oldRoom.gold = 0; } } _redisService.SetChessRoom(oldRoom); } } } if ((room.state == 3 && room.users.Count == 0) || room.state == 0) { bool isCreareRoom = false; if (gameConfig.ChessConfig.CreateRoomLimit.Any(c=>c==3)) isCreareRoom = true; if (gameConfig.ChessConfig.CreateRoomLimit.Any(c => c == 1) && user.Assets.VipLevel > 0) { var vipLevels = gameConfig.ChessConfig.CreateRoomVipLevels ?? new List(); if (vipLevels.Count == 0 || vipLevels.Contains(user.Assets.VipLevel)) isCreareRoom = true; } if (gameConfig.ChessConfig.CreateRoomLimit.Any(c => c == 2) && user.UserType==2) isCreareRoom = true; if (!isCreareRoom) { var roles = new List(); if (gameConfig.ChessConfig.CreateRoomLimit.Any(c => c == 1)) roles.Add("VIP"); if (gameConfig.ChessConfig.CreateRoomLimit.Any(c => c == 2)) roles.Add("代理"); var msg = roles.Count > 0 ? $"只有{string.Join("/", roles)}才能配置密码" : "没有权限配置密码"; return Task.FromResult<(bool isok, string msg, ChessGameRoom room)>((false, msg, null)); } room.users = new List() { new RedisChessGameUser { Cid = cid, userId = param.userId, userName = user.BaseInfo.UserName, userAvatar = user.BaseInfo.AvatarUrl, Gold = user.Assets.Gold, type = param.gameType, IsLeave = false, IsReady = false }}; room.gameType = param.gameType; room.password = param.password; room.createUserId = param.userId; room.gold = param.gold; room.state = 1; room.robotCount = 0; room.IsGameEnded = false; } else if (room.users.Any(c => c.userId == param.userId)) { var existing = room.users.First(c => c.userId == param.userId); existing.Cid = cid; existing.IsLeave = false; existing.DisconnectTime = 0; room.robotCount = Math.Clamp(room.robotCount, 0, Math.Max(0, 2 - room.users.Count)); _redisService.SetChessRoom(room); return Task.FromResult<(bool isok, string msg, ChessGameRoom room)>((true, "", room)); } else if (room.state == 3) return Task.FromResult<(bool isok, string msg, ChessGameRoom room)>((false, "上一局玩家尚未退出", room)); else if (room.users.Count + room.robotCount >= 2 || room.state == 2) return Task.FromResult<(bool isok, string msg, ChessGameRoom room)>((false, "当前房间已有玩家", room)); else { var firstPlayerType = room.gameType; var secondPlayerType = firstPlayerType == 1 ? 2 : 1; room.users.Add(new RedisChessGameUser { Cid = cid, userId = param.userId, userName = user.BaseInfo.UserName, userAvatar = user.BaseInfo.AvatarUrl, Gold = user.Assets.Gold, type = secondPlayerType, IsLeave = false, IsReady = false }); room.state = 1; } _redisService.SetChessRoom(room); return Task.FromResult<(bool isok, string msg, ChessGameRoom room)>((true, "", room)); }, expiry: 10 ); } public async Task<(bool success, string message, ChessGameRoom room)> JoinGameAsync(string gameId, string pwd, string userId, string cid) { var user = await _userService.GetUser(userId); if (user == null) return (false, "用户不存在", null); return await _distributedLock.TryExecuteAsync( $"{RedisKey.DistributedLockPrefix}chess:room:{gameId}", () => { var room = _redisService.GetChessRoom(gameId); if (room == null || room.state == 3) { return Task.FromResult((false, "房间不存在", (ChessGameRoom)null)); } if (string.IsNullOrEmpty(room.password)) { return Task.FromResult((false, "房间未设置密码,无法进入", (ChessGameRoom)null)); } if (room.password != pwd) { return Task.FromResult((false, "密码错误", (ChessGameRoom)null)); } if (room.users.Any(c => c.userId == userId)) { var existing = room.users.First(c => c.userId == userId); existing.Cid = cid; existing.IsLeave = false; existing.DisconnectTime = 0; room.robotCount = Math.Clamp(room.robotCount, 0, Math.Max(0, 2 - room.users.Count)); _redisService.SetChessRoom(room); return Task.FromResult((true, "", room)); } if (room.state == 3 && room.IsGameEnded && room.users.Count < 2) { var secondPlayerType = room.gameType == 1 ? 2 : 1; room.users.Add(new RedisChessGameUser { Cid = cid, userId = userId, Gold = user.Assets.Gold, userName = user.BaseInfo.UserName, userAvatar = user.BaseInfo.AvatarUrl, type = secondPlayerType, IsLeave = false, IsReady = false }); room.robotCount = 0; room.state = 1; room.IsGameEnded = false; room.gold = 0; _redisService.SetChessRoom(room); return Task.FromResult((true, "", room)); } if (room.users.Count + room.robotCount >= 2) { return Task.FromResult((false, "房间已满", (ChessGameRoom)null)); } room.users.Add(new RedisChessGameUser { Cid = cid, userId = userId, Gold = user.Assets.Gold, userName = user.BaseInfo.UserName, userAvatar = user.BaseInfo.AvatarUrl, type = room.gameType == 1 ? 2 : 1, IsLeave = false, IsReady = false }); room.robotCount = 0; _redisService.SetChessRoom(room); return Task.FromResult((true, "", room)); }, expiry: 10 ); } public List GetRoomList(int partition, int maxRooms = 100) { var existingRooms = _redisService.GetAllChessRooms(); if (existingRooms == null || existingRooms.Count == 0) return new List(); return existingRooms .Where(c => c != null && (partition <= 0 || GetChessRoomPartition(c.RoomId) == partition) && !(c.state == 1 && string.IsNullOrWhiteSpace(c.createUserId) && (c.users == null || c.users.Count == 0))) .OrderBy(c => c.RoomId) .Take(maxRooms) .ToList(); } private static int GetChessRoomPartition(string roomId) { if (string.IsNullOrWhiteSpace(roomId) || roomId.Length < 4) return 0; var partitionText = roomId.Substring(1, roomId.Length - 3); return int.TryParse(partitionText, out var partition) ? partition : 0; } public (bool success, string message, ChessGameRoom room) StartGame(string gameId, string userId) { var room = _redisService.GetChessRoom(gameId); if (room == null || room.state == 3) return (false, "房间不存在", null); if (room.state != 1) return (false, "游戏已开始", null); if (room.createUserId != userId) return (false, "只有房主才能开始游戏", null); if (room.users.Count < 2) return (false, "人数不足,无法开始", null); return (true, "", room); } public (bool success, string message, bool allReady) GameReady(string gameId, string userId) { if (string.IsNullOrWhiteSpace(gameId) || string.IsNullOrWhiteSpace(userId)) return (false, "房间或玩家参数不能为空", false); return _distributedLock.TryExecute( $"{RedisKey.DistributedLockPrefix}chess:room:{gameId}", () => { var room = _redisService.GetChessRoom(gameId); if (room == null || room.state == 3) return (false, "房间不存在", false); var user = room.users.FirstOrDefault(c => c.userId == userId); if (user == null) return (false, "玩家不存在", false); if (room.gold == 0) return (false, "未设置金币", false); user.IsReady = true; var allReady = room.users.Count >= 2 && room.users.All(c => c.IsReady); if (allReady) room.state = 2; _redisService.SetChessRoom(room); return (true, "", allReady); }, expiry: 10, retry: true, retryDelay: 20); } public async Task<(bool success, string message, ChessGameRoom room)> EndGame(string gameId, string winUserId) { return await _distributedLock.TryExecuteAsync( $"{RedisKey.DistributedLockPrefix}chess:room:{gameId}", async () => { var room = _redisService.GetChessRoom(gameId); if (room == null) return (false, "房间不存在", null); if (room.state != 2 || room.IsGameEnded) return (true, "游戏已结束", room); if (!string.IsNullOrWhiteSpace(winUserId) && !room.users.Any(u => u.userId == winUserId)) return (false, "胜者不在房间中", (ChessGameRoom)null); room.state = 3; room.IsGameEnded = true; _redisService.SetChessRoom(room); if (!string.IsNullOrWhiteSpace(winUserId)) { var loser = room.users.FirstOrDefault(u => u.userId != winUserId); var winner = room.users.FirstOrDefault(u => u.userId == winUserId); var winnerName = winner?.userName ?? ""; var loserName = loser?.userName ?? ""; var loserId = loser?.userId ?? ""; var winnerEntity = winner != null ? await _userService.GetUser(winner.userId) : null; var loserEntity = loser != null ? await _userService.GetUser(loser.userId) : null; var realLoserGold = loserEntity?.Assets.Gold ?? 0; var actualBet = Math.Min(room.gold, realLoserGold); if (actualBet > 0) { if (loserEntity != null) { var deductRemark = $"房间号({room.RoomId}) {winnerName}({winner?.userId})赢得对局 {loserName}({loserId})输 金额{actualBet}"; var deductResult = await _userService.UpdateAssets(new UserAssetParam() { ChangeType = UserAssetChangeTypeEnum.减少, Gold = actualBet, TotalRechargeGoldDelta = -actualBet, Remark = deductRemark, Source = RewardSource.象棋, UserId = loserEntity.Id, RoomInfo = room.RoomId, OtherUserId = winUserId }); if (!deductResult.isok) { room.state = 2; room.IsGameEnded = false; _redisService.SetChessRoom(room); return (false, "结算失败:" + deductResult.msg, room); } loser.Gold = Math.Max(0, realLoserGold - actualBet); } if (winnerEntity != null) { var winRemark = $"房间号({room.RoomId}) {winnerName}({winner?.userId})赢得对局 {loserName}({loserId})输 金额{actualBet}"; var winResult = await _userService.UpdateAssets(new UserAssetParam() { ChangeType = UserAssetChangeTypeEnum.增加, Gold = actualBet, TotalRechargeGoldDelta = actualBet, Remark = winRemark, Source = RewardSource.象棋, UserId = winnerEntity.Id, RoomInfo = room.RoomId, OtherUserId = loserId }); if (!winResult.isok) { if (loserEntity != null) { await _userService.UpdateAssets(new UserAssetParam() { ChangeType = UserAssetChangeTypeEnum.增加, Gold = actualBet, TotalRechargeGoldDelta = actualBet, Remark = $"房间号({room.RoomId}) 结算异常回退 {winnerName}({winner?.userId}) 金额{actualBet}", Source = RewardSource.象棋, UserId = loserEntity.Id, RoomInfo = room.RoomId, OtherUserId = winUserId }); } } winner.Gold = winnerEntity.Assets.Gold + actualBet; } var newWinnerEntity = winnerEntity != null ? await _userService.GetUser(winnerEntity.Id) : null; var newLoserEntity = loserEntity != null ? await _userService.GetUser(loserEntity.Id) : null; if (winnerEntity != null) { var newWinnerGold = newWinnerEntity?.Assets.Gold ?? winnerEntity.Assets.Gold; _capPublisher.Publish("BackgroundOperation.NotifyUser", new BackgroundOperationNotifyMessage { UserId = winnerEntity.Id, CurrencyType = 1, ChangeType = 1, Amount = actualBet, NewGold = newWinnerGold, Source = "象棋对局胜利", Remark = $"房间号({room.RoomId})赢得{actualBet}金币" }); } if (loserEntity != null) { var newLoserGold = newLoserEntity?.Assets.Gold ?? loser.Gold; _capPublisher.Publish("BackgroundOperation.NotifyUser", new BackgroundOperationNotifyMessage { UserId = loserEntity.Id, CurrencyType = 1, ChangeType = 2, Amount = actualBet, NewGold = newLoserGold, Source = "象棋对局失败", Remark = $"房间号({room.RoomId})输掉{actualBet}金币" }); } } } var userIds = room.users?.Select(u => u.userId).Where(id => !string.IsNullOrWhiteSpace(id)).ToList() ?? new List(); room.gold = 0; room.gameType = 0; room.robotCount = 0; room.EndGameRequests?.Clear(); room.PendingWinUserId = null; room.TimeoutLoserUserId = ""; room.LastActiveTime = 0; room.users.Clear(); _redisService.SetChessRoom(room); foreach (var userId in userIds) { try { await UpdateUserGameType(userId, 0); } catch (Exception ex) { _logger.LogError(ex, "[象棋] EndGame 清除游戏状态失败 userId={UserId}", userId); } } return (true, "", room); }, expiry: 30, retry: false); } public (bool success, string message, ChessGameRoom room) RestartGame(string gameId, string userId) { var room = _redisService.GetChessRoom(gameId); if (room == null) { return (false, "房间不存在", null); } if (room.state == 3 && room.IsGameEnded) { room.state = 1; room.IsGameEnded = false; room.gold = 0; room.robotCount = 0; room.EndGameRequests?.Clear(); room.PendingWinUserId = null; room.TimeoutLoserUserId = ""; room.LastActiveTime = 0; if (room.users == null) room.users = new List(); var existingUser = room.users.FirstOrDefault(u => u.userId == userId); if (existingUser == null) { room.users.Add(new RedisChessGameUser { userId = userId, userName = "", type = room.gameType, IsLeave = false, IsReady = false }); } else { existingUser.IsReady = false; existingUser.IsLeave = false; existingUser.DisconnectTime = 0; } _redisService.SetChessRoom(room); return (true, "", room); } if (!room.IsGameEnded) { return (false, "对局尚未结束,无法重新开始", null); } var user = room.users.FirstOrDefault(u => u.userId == userId); if (user == null) { return (false, "对局已结束,房间已释放,请重新创建房间", null); } room.state = 1; room.IsGameEnded = false; room.gold = 0; room.EndGameRequests?.Clear(); room.PendingWinUserId = null; room.TimeoutLoserUserId = ""; room.LastActiveTime = 0; foreach (var u in room.users) { u.IsReady = false; } _redisService.SetChessRoom(room); return (true, "", room); } public async Task<(bool success, string message, ChessGameRoom room, bool allConfirmed)> RequestEndGame(string gameId, string userId, string winUserId) { var room = _redisService.GetChessRoom(gameId); if (room == null || room.state == 3) { return (false, "房间不存在", null, false); } if (room.state != 2) { return (false, "游戏未开始", null, false); } var user = room.users.FirstOrDefault(u => u.userId == userId); if (user == null) { return (false, "参数异常", null, false); } if (!string.IsNullOrWhiteSpace(winUserId) && !room.users.Any(u => u.userId == winUserId)) return (false, "胜者不在房间中", null, false); if (room.EndGameRequests == null) room.EndGameRequests = new Dictionary(); room.EndGameRequests[userId] = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); if (!string.IsNullOrEmpty(winUserId) && string.IsNullOrEmpty(room.PendingWinUserId)) { room.PendingWinUserId = winUserId; } _redisService.SetChessRoom(room); var roomUserIds = room.users.Select(u => u.userId).ToHashSet(); var confirmedCount = room.EndGameRequests.Keys.Count(roomUserIds.Contains); if (confirmedCount >= room.users.Count && room.users.Count >= 2) { string finalWinUserId = room.PendingWinUserId ?? ""; room.EndGameRequests.Clear(); room.PendingWinUserId = null; _redisService.SetChessRoom(room); var result = await EndGame(gameId, finalWinUserId); return (result.success, result.message, result.room, true); } return (true, "等待对方确认结束", room, false); } public async Task<(bool isTimeout, string loserUserId)> CheckRoomTimeout(string gameId) { var room = _redisService.GetChessRoom(gameId); if (room == null || room.state != 2) { return (false, ""); } var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); var timeout = room.TimeoutSeconds > 0 ? room.TimeoutSeconds : 60; foreach (var user in room.users) { if (user.IsLeave && user.DisconnectTime > 0 && (now - user.DisconnectTime) > timeout) { var winUserId = room.users.FirstOrDefault(u => u.userId != user.userId)?.userId ?? ""; room.TimeoutLoserUserId = user.userId; _redisService.SetChessRoom(room); await EndGame(gameId, winUserId); return (true, user.userId); } } return (false, ""); } public async Task<(bool isTimeout, string loserUserId)> CheckRoomAfkTimeout(string gameId) { var room = _redisService.GetChessRoom(gameId); if (room == null || room.state != 2 || room.users.Count < 2) { return (false, ""); } var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); var afkUsers = room.users.Where(u => u.IsAfk && u.AfkTime > 0).OrderBy(u => u.AfkTime).ToList(); if (afkUsers.Count == 2) { var firstAfkUser = afkUsers[0]; var winUserId = room.users.FirstOrDefault(u => u.userId != firstAfkUser.userId)?.userId ?? ""; await EndGame(gameId, winUserId); return (true, firstAfkUser.userId); } if (afkUsers.Count == 1) { var afkUser = afkUsers[0]; var timeout = room.AfkTimeoutSeconds > 0 ? room.AfkTimeoutSeconds : 120; if ((now - afkUser.AfkTime) > timeout) { var winUserId = room.users.FirstOrDefault(u => u.userId != afkUser.userId)?.userId ?? ""; await EndGame(gameId, winUserId); return (true, afkUser.userId); } } return (false, ""); } public async Task UpdateUserActiveTime(string gameId, string userId) { var room = _redisService.GetChessRoom(gameId); if (room == null || room.state != 2) { return; } var user = room.users.FirstOrDefault(u => u.userId == userId); if (user == null) { return; } room.LastActiveTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); _redisService.SetChessRoom(room); } public async Task SetPlayerAfk(string gameId, string userId) { var room = string.IsNullOrWhiteSpace(gameId) ? null : _redisService.GetChessRoom(gameId); var user = room?.users?.FirstOrDefault(u => u.userId == userId); if (user == null) { return; } user.IsAfk = true; user.AfkTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); _redisService.SetChessRoom(room); await Task.CompletedTask; } public async Task CancelPlayerAfk(string gameId, string userId) { var room = string.IsNullOrWhiteSpace(gameId) ? null : _redisService.GetChessRoom(gameId); var user = room?.users?.FirstOrDefault(u => u.userId == userId); if (user == null) { return; } user.IsAfk = false; user.AfkTime = 0; _redisService.SetChessRoom(room); await Task.CompletedTask; } public bool ExitRoom(ChessGameRoom room) { room.users = new List(); room.state = 3; room.password = ""; room.createUserId = ""; room.gold = 0; room.gameType = 0; room.robotCount = 0; room.IsGameEnded = false; room.EndGameRequests?.Clear(); room.PendingWinUserId = null; room.TimeoutLoserUserId = ""; room.LastActiveTime = 0; _redisService.SetChessRoom(room); return true; } public (bool isok, string msg, ChessGameRoom room) ExitRoom(string gameId, string userId) { var room = _redisService.GetChessRoom(gameId); if (room == null) { return (false, "房间不存在", null); } if (room.state == 3 && (room.users == null || room.users.Count == 0)) { ExitRoom(room); return (true, "房间已清空", room); } var user = room.users.FirstOrDefault(c => c.userId == userId); if (user == null) { return (false, "玩家不存在", null); } if (room.state == 2) { user.IsLeave = true; user.DisconnectTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); user.Cid = string.Empty; if (room.users.All(u => u.IsLeave)) { ExitRoom(room); return (true, "所有玩家已退出,房间已重置", room); } _redisService.SetChessRoom(room); return (true, "玩家已退出,等待其他玩家", room); } if (room.createUserId == userId) { ExitRoom(room); return (true, "房主退出,房间已清空", room); } room.users.Remove(user); if (room.users.Count == 0 || (room.state == 3 && room.users.Count <= 1)) { ExitRoom(room); return (true, "房间已清空", room); } room.gold = 0; room.robotCount = Math.Clamp(room.robotCount, 0, Math.Max(0, 2 - room.users.Count)); _redisService.SetChessRoom(room); return (true, "", room); } public (bool isok, string msg, ChessGameRoom room) AdminKickPlayer(string gameId, string userId) { var room = _redisService.GetChessRoom(gameId); if (room == null) return (false, "房间不存在", null); if (room.state == 2) return (false, "游戏进行中不能直接踢人,请先结束对局", room); var user = room.users?.FirstOrDefault(c => c.userId == userId); if (user == null) return (false, "玩家不存在", room); room.users.Remove(user); if (room.users.Count == 0) { ExitRoom(room); return (true, "玩家已踢出,房间已重置", room); } if (room.createUserId == userId) room.createUserId = room.users[0].userId; room.state = 1; room.gold = 0; room.IsGameEnded = false; room.EndGameRequests?.Clear(); room.PendingWinUserId = null; room.TimeoutLoserUserId = string.Empty; room.LastActiveTime = 0; room.robotCount = Math.Clamp(room.robotCount, 0, Math.Max(0, 2 - room.users.Count)); foreach (var remainingUser in room.users) remainingUser.IsReady = false; _redisService.SetChessRoom(room); return (true, "玩家已踢出", room); } public async Task UpdateUserGameType(string userId, int gameType, string roomNumber = "") { try { var user = await _userService.GetUser(userId); if (user != null) { user.Static.CurrentGameType = gameType; user.Static.RoomNumber = gameType > 0 ? (roomNumber ?? string.Empty) : string.Empty; await _userService.UpdateUser(user); } } catch (Exception ex) { _logger.LogError(ex, "更新用户当前游戏类型失败 userId={UserId} gameType={GameType} roomNumber={RoomNumber}", userId, gameType, roomNumber); } } public (bool success, string message, ChessGameRoom room) GoldConfig(string gameId, long gold, string userId) { var room = _redisService.GetChessRoom(gameId); if (room == null || room.state == 3) { return (false, "房间不存在", null); } var gameconfig= _redisService.GetGameConfig(); if (gameconfig==null) { return (false, "游戏配置不存在", null); } if(gold c.type == 2 && c.userId == userId)) return (false, "只有红方才可以配置金币", null); var redPlayer = room.users.FirstOrDefault(c => c.type == 2); if (redPlayer != null && redPlayer.Gold < gold) return (false, "金币不足", null); room.gold = gold; _redisService.SetChessRoom(room); return (true, "", room); } public ChessGameRoom GetUserRoom(string cid) { var rooms = _redisService.GetAllChessRooms(); if (rooms == null) return null; return rooms.FirstOrDefault(c => c.users.Any(d => d.Cid == cid && (c.state == 1 || c.state == 2))); } public ChessGameRoom GetRoom(string gameId) { return _redisService.GetChessRoom(gameId); } public List GetAllPlayingRooms() { var allRooms = _redisService.GetAllChessRooms(); if (allRooms == null) return new List(); return allRooms.Where(r => r != null && r.state == 2).ToList(); } } }