Files
BuYuHouDuan/FishRoomService/RoomService/FishingRoomService.cs
T
2026-10-12 16:22:04 +08:00

186 lines
7.4 KiB
C#

using System.Collections.Concurrent;
using System.Text.Json;
using AutoMapper;
using CommonDomain.BaseModel;
using CommonDomain;
using CommonDomain.Enum;
using CommonService;
using DotNetCore.CAP;
using FishRoomService.Hubs;
using FishRoomService.RoomSend;
using MongoRepository;
using RedisHelper;
using RedisService;
using RedisService.Param;
using UserService.User;
namespace FishRoomService.RoomService
{
public class FishingRoomService : IFishingRoomService
{
private readonly ICapPublisher _capPublisher;
private readonly IRedisService _redisService;
private readonly IHubSend<FishRoomHub> _hubRoom;
private readonly IFishingRoomSendService _sendResult;
private GameConfig _gameConfig;
private readonly IUserService _userService;
private readonly IMapper _mapper;
private readonly IDistributedLock _distributedLock;
private readonly IMongoBaseRepository<BotProfileEntity> _botProfileRepo;
private readonly IMongoBaseRepository<EmptyRoomRateConfig> _emptyRoomRateRepo;
private List<BotProfileEntity> _initBotProfiles;
public FishingRoomService(ICapPublisher capPublisher, IRedisService redisService, IHubSend<FishRoomHub> hubRoom, IFishingRoomSendService sendResult, IUserService userService, IMapper mapper, IDistributedLock distributedLock, IMongoBaseRepository<BotProfileEntity> botProfileRepo, IMongoBaseRepository<EmptyRoomRateConfig> emptyRoomRateRepo)
{
_capPublisher = capPublisher;
_redisService = redisService;
_hubRoom = hubRoom;
_sendResult = sendResult;
_userService = userService;
_botProfileRepo = botProfileRepo;
_emptyRoomRateRepo = emptyRoomRateRepo;
_gameConfig = redisService.GetGameConfig();
if (_gameConfig == null)
{
var jsonPath = Path.Combine("Config", "gameconfig.json");
if (File.Exists(jsonPath))
{
var json = File.ReadAllText(jsonPath);
_gameConfig = JsonSerializer.Deserialize<GameConfig>(json);
}
if (_gameConfig == null)
{
_gameConfig = new GameConfig { RoomConfigs = new List<RoomConfig>() };
}
}
_mapper = mapper;
_distributedLock = distributedLock;
}
public async Task GetRoomList(string cid, string userId, GameTypeEnum gameType, int roomLevel, int roomPartition)
{
string partition = $"{(int)gameType}{roomLevel}{roomPartition}";
var userRedid = _redisService.GetRedisUserCId(userId);
if (userRedid != null)
{
if (!string.IsNullOrWhiteSpace(userRedid.PartitionId))
_hubRoom.RemoveGroup(cid, userRedid.PartitionId);
userRedid.PartitionId = partition;
userRedid.FishRoomCId = cid;
if (string.IsNullOrWhiteSpace(userRedid.RoomId))
userRedid.CId = cid;
}
else
{
userRedid = new RedisUserCid() { UserId = userId, PartitionId = partition, CId = cid, FishRoomCId = cid };
}
_redisService.SetRedisUserCId(userRedid);
_hubRoom.AddGroup(cid, partition);
var roomList = _redisService.GetGameRoomList(partition);
if (roomList == null || roomList.Count() == 0)
{
await InitRoom(gameType, roomLevel, _gameConfig);
roomList = _redisService.GetGameRoomList(partition);
}
_sendResult.GetRoomListResult(cid, roomList.ToList());
}
public async Task<List<RedisGameRoom>> InitRoom(GameTypeEnum gameType = GameTypeEnum.None, int roomLevel = 0, GameConfig gameConfig = null)
{
gameConfig ??= _gameConfig;
List<RedisGameRoom> result = new List<RedisGameRoom>();
gameConfig ??= _gameConfig;
_initBotProfiles = RoomBotFactory.FixedBotSeatsEnabled
? _botProfileRepo.FilterBy(p => true).ToList()
: null;
var roomConfig = gameConfig?.RoomConfigs ?? new List<RoomConfig>();
if (gameType != GameTypeEnum.None)
roomConfig = roomConfig.Where(c => c.GameType == gameType).ToList();
if (roomLevel > 0)
roomConfig = roomConfig.Where(c => c.RoomLevel == roomLevel).ToList();
if (roomConfig == null || roomConfig.Count() == 0)
return result;
foreach (var item in roomConfig)
{
var rateConfig = _emptyRoomRateRepo
.FilterBy(c => c.GameType == item.GameType && c.RoomLevel == item.RoomLevel && !c.IsDelete)
.FirstOrDefault();
var botsEnabled = gameConfig.BotConfig?.Enabled == true;
var emptyRate = botsEnabled ? Math.Clamp(rateConfig?.EmptyRoomRate ?? 0, 0, 100) : 100;
var totalRoomCount = item.RoomPartitionNum * item.RoomCount;
var roomsWithBots = emptyRate > 0
? (int)Math.Floor(totalRoomCount * (100 - emptyRate) / 100.0)
: totalRoomCount;
var botRoomIndexes = Enumerable.Range(0, totalRoomCount)
.OrderBy(_ => global::System.Random.Shared.Next())
.Take(roomsWithBots)
.ToHashSet();
for (var i = 1; i <= item.RoomPartitionNum; i++)
{
_redisService.RemoveGameRoom($"{(int)item.GameType}{item.RoomLevel}{i}");
for (int c = 0; c < item.RoomCount; c++)
{
RedisGameRoom room = new RedisGameRoom()
{
RoomName = item.RoomName,
GameType = item.GameType,
RoomLevel = item.RoomLevel,
RoomPartition = i,
RoomNumber = c,
MaxPlayerCount = (item.GameType == GameTypeEnum.星际迷航 || item.GameType == GameTypeEnum.中国象棋) ? 2 : 4,
CurrentOnlinePlayerCount = 0,
};
var roomIndex = (i - 1) * item.RoomCount + c;
room.RobotCount = botsEnabled && botRoomIndexes.Contains(roomIndex)
? global::System.Random.Shared.Next(1, room.MaxPlayerCount)
: 0;
room.RoomId = $"{(int)room.GameType}{room.RoomLevel}{room.RoomPartition}{c.ToString("00")}";
if (room.RobotCount > 0 && RoomBotFactory.FixedBotSeatsEnabled)
{
var fixedBots = RoomBotFactory.CreateFixedSeatBots(room, item, gameConfig, _initBotProfiles);
if (fixedBots.Count > 0)
{
room.Players.AddRange(fixedBots);
room.RobotCount = fixedBots.Count;
}
}
result.Add(room);
}
}
}
foreach (var item in result)
{
_redisService.SetGameRoom(item);
}
return result;
}
}
}