186 lines
7.4 KiB
C#
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|