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

451 lines
15 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using ChessGameDomain;
using Common.Redis;
using CommonDomain;
using CommonDomain.BaseModel;
using RedisHelper;
using RedisService.Param;
using UserDomain.Entity;
namespace RedisService
{
public class RedisService : IRedisService
{
private readonly ICache _cache;
private static readonly ConcurrentDictionary<string, RoomCacheEntry> GameRoomCache = new();
private static readonly TimeSpan GameRoomReadCacheDuration = TimeSpan.FromSeconds(3);
public RedisService(ICache cache)
{
_cache = cache;
}
public RedisUserCid GetRedisUserCId(string userId)
{
return _cache.Get<RedisUserCid>(string.Format(RedisKey.UserCIDGID, userId));
}
public void SetRedisUserCId(RedisUserCid redisUser)
{
_cache.Insert(string.Format(RedisKey.UserCIDGID, redisUser.UserId), redisUser);
}
public void RemoveRedisUserCId(string userId)
{
_cache.Remove(string.Format(RedisKey.UserCIDGID, userId));
}
private static readonly ConcurrentDictionary<string, string> UserIdCache = new();
public string GetUserId(string cid)
{
UserIdCache.TryGetValue(cid, out var userId);
return userId;
}
public void SetUserId(string cid, string userId)
{
UserIdCache[cid] = userId;
}
public void RemoveUserId(string cid)
{
UserIdCache.TryRemove(cid, out _);
}
public string GetLoginUserId(string cid)
{
return _cache.Get<string>(string.Format(RedisKey.LoginCIDUser, cid));
}
public void SetLoginUserId(string cid, string userId)
{
_cache.Insert(string.Format(RedisKey.LoginCIDUser, cid), userId);
}
public IEnumerable<string> GetAllLoginUserIds()
{
var list = _cache.GetPatternList<string>(string.Format(RedisKey.LoginCIDUser, "*"), 100000);
return list;
}
public void RemoveGameConfig()
{
_cache.Remove(RedisKey.GameConfig);
}
public void SetActivityConfig(ActivityConfig config)
{
_cache.Insert<ActivityConfig>(RedisKey.ActivityConfig, config);
}
public ActivityConfig GetActivityConfig()
{
return _cache.Get<ActivityConfig>(RedisKey.ActivityConfig);
}
public void RemoveActivityConfig()
{
_cache.Remove(RedisKey.ActivityConfig);
}
private static string PlayerGoldKey(string roomId, string userId) => $"gold:{roomId}:{userId}";
private static string PlayerBulletsKey(string roomId, string userId) => $"bullets:{roomId}:{userId}";
private static string PlayerFactorKey(string roomId, string userId) => $"factor:{roomId}:{userId}";
private static string RoomKillFishKey(string roomId) => $"killfish:{roomId}";
private static string FishingTaskCountKey(string roomId, string userId, int taskEvent) => $"fishing:tasks:{roomId}:{userId}:{taskEvent}";
private static string FishingConsumeKey(string roomId, string userId) => $"fishing:consume:runtime:{roomId}:{userId}";
private static string FishingExpKey(string roomId, string userId) => $"fishing:exp:runtime:{roomId}:{userId}";
public long GetPlayerGold(string roomId, string userId)
{
return _cache.Get<long>(PlayerGoldKey(roomId, userId));
}
public void SetPlayerGold(string roomId, string userId, long gold)
{
_cache.Insert(PlayerGoldKey(roomId, userId), gold);
}
public bool AddBulletId(string roomId, string userId, string bulletId)
{
return _cache.SetAdd(PlayerBulletsKey(roomId, userId), bulletId);
}
public bool ExistsBulletId(string roomId, string userId, string bulletId)
{
return _cache.SetContains(PlayerBulletsKey(roomId, userId), bulletId);
}
public bool RemoveBulletId(string roomId, string userId, string bulletId)
{
return _cache.SetRemove(PlayerBulletsKey(roomId, userId), bulletId);
}
public long GetBulletCount(string roomId, string userId)
{
return _cache.SetCount(PlayerBulletsKey(roomId, userId));
}
public void ClearBulletIds(string roomId, string userId)
{
_cache.Remove(PlayerBulletsKey(roomId, userId));
}
public void ClearPlayerRuntimeData(string roomId, string userId)
{
_cache.Remove(PlayerGoldKey(roomId, userId));
_cache.Remove(PlayerBulletsKey(roomId, userId));
_cache.Remove(PlayerFactorKey(roomId, userId));
}
public void AddFishingTaskProgress(string roomId, string userId, int taskEvent, long count)
{
if (count <= 0) return;
_cache.IncrBy(FishingTaskCountKey(roomId, userId, taskEvent), count);
}
public Dictionary<int, long> GetFishingTaskProgress(string roomId, string userId, IEnumerable<int> taskEvents)
{
var result = new Dictionary<int, long>();
foreach (var taskEvent in taskEvents.Distinct())
{
var count = _cache.Get<long>(FishingTaskCountKey(roomId, userId, taskEvent));
if (count > 0) result[taskEvent] = count;
}
return result;
}
public void ClearFishingTaskProgress(string roomId, string userId, IEnumerable<int> taskEvents)
{
foreach (var taskEvent in taskEvents.Distinct())
_cache.Remove(FishingTaskCountKey(roomId, userId, taskEvent));
}
public void AddFishingConsumeProgress(string roomId, string userId, long count)
{
if (count > 0) _cache.IncrBy(FishingConsumeKey(roomId, userId), count);
}
public long GetFishingConsumeProgress(string roomId, string userId) => _cache.Get<long>(FishingConsumeKey(roomId, userId));
public void AddFishingExpProgress(string roomId, string userId, long count)
{
if (count > 0) _cache.IncrBy(FishingExpKey(roomId, userId), count);
}
public long GetFishingExpProgress(string roomId, string userId) => _cache.Get<long>(FishingExpKey(roomId, userId));
public void ClearFishingRuntimeProgress(string roomId, string userId)
{
_cache.Remove(FishingConsumeKey(roomId, userId));
_cache.Remove(FishingExpKey(roomId, userId));
}
public PlayerFactor GetPlayerFactor(string roomId, string userId)
{
return _cache.Get<PlayerFactor>(PlayerFactorKey(roomId, userId));
}
public void SetPlayerFactor(string roomId, string userId, PlayerFactor factor)
{
_cache.Insert(PlayerFactorKey(roomId, userId), factor);
}
public void RemovePlayerFactor(string roomId, string userId)
{
_cache.Remove(PlayerFactorKey(roomId, userId));
}
public List<string> GetKillFishIds(string roomId)
{
return _cache.SetMembers<string>(RoomKillFishKey(roomId));
}
public void AddKillFishId(string roomId, string fishId)
{
_cache.SetAdd(RoomKillFishKey(roomId), fishId);
}
public bool ContainsKillFishId(string roomId, string fishId)
{
return _cache.SetContains(RoomKillFishKey(roomId), fishId);
}
public List<ChessGameRoom> GetAllPlayingChessRooms()
{
var allRooms = GetAllChessRooms();
if (allRooms == null)
return new List<ChessGameRoom>();
return allRooms.Where(r => r.state == 2).ToList();
}
public void SetFishingKillConfig(FishingKillConfig config)
{
_cache.Insert(RedisKey.FishingKillConfig, config);
}
public FishingKillConfig GetFishingKillConfig()
{
return _cache.Get<FishingKillConfig>(RedisKey.FishingKillConfig);
}
public void SetFishSpawnConfig(string json)
{
_cache.Insert(RedisKey.FishSpawnConfig, json);
}
public string GetFishSpawnConfig()
{
return _cache.Get<string>(RedisKey.FishSpawnConfig);
}
public void SetGameRoom(RedisGameRoom gameRoom)
{
string Partition = $"{(int)gameRoom.GameType}{gameRoom.RoomLevel}{gameRoom.RoomPartition}";
_cache.Insert<RedisGameRoom>(string.Format(RedisKey.GameRoomIdKey, Partition, gameRoom.RoomId), gameRoom);
GameRoomCache[gameRoom.RoomId] = new RoomCacheEntry(gameRoom, DateTime.UtcNow, true);
}
public RedisGameRoom GetGameRoom(string roomId)
{
if (string.IsNullOrWhiteSpace(roomId))
return null;
var partition = roomId.Length >= 3 ? roomId.Substring(0, 3) : roomId.PadRight(3, '0');
var room = _cache.Get<RedisGameRoom>(string.Format(RedisKey.GameRoomIdKey, partition, roomId));
if (room != null)
GameRoomCache[roomId] = new RoomCacheEntry(room, DateTime.UtcNow, false);
else
GameRoomCache.TryRemove(roomId, out _);
return room;
}
public IEnumerable<RedisGameRoom> GetGameRoomList(string partition)
{
var list = _cache.GetPatternList<RedisGameRoom>(string.Format(RedisKey.GameRoomIdKey, partition, "*"), 100);
return list;
}
public IEnumerable<RedisGameRoom> GetGameRoomAllList()
{
var list = _cache.GetPatternList<RedisGameRoom>(string.Format(RedisKey.GameRoomIdKey, "*", "*"), 10000);
return list;
}
public string GetPendingFishRoomId(string userId)
{
if (string.IsNullOrWhiteSpace(userId))
return string.Empty;
var rooms = GetGameRoomAllList();
if (rooms == null)
return string.Empty;
var room = rooms.FirstOrDefault(r =>
r != null && r.Players != null && r.Players.Any(p => p.UserId == userId && !p.IsBot));
return room?.RoomId ?? string.Empty;
}
public void RemoveGameRoom(string partition)
{
_cache.Clear(string.Format(RedisKey.GameRoomIdKey, partition, "*"));
foreach (var roomId in GameRoomCache.Keys.Where(id => id.StartsWith(partition, StringComparison.Ordinal)))
GameRoomCache.TryRemove(roomId, out _);
}
public void RemoveGameRoomAll()
{
_cache.Clear(string.Format(RedisKey.GameRoomIdKey, "*", "*"), 50000);
GameRoomCache.Clear();
}
private sealed record RoomCacheEntry(RedisGameRoom Room, DateTime CachedAt, bool IsLocallyOwned);
public void SetGameConfig(GameConfig gameConfig)
{
_cache.Insert<GameConfig>(RedisKey.GameConfig, gameConfig);
}
public GameConfig GetGameConfig()
{
return _cache.Get<GameConfig>(RedisKey.GameConfig);
}
public void SetSystemGoldDay(long amount)
{
_cache.Insert<long>(RedisKey.SystemGoldDayKey, amount);
}
public void AddSystemGoldDay(long gold)
{
_cache.IncrBy(RedisKey.SystemGoldDayKey, gold);
}
public long GetSystemGoldDay()
{
return _cache.Get<long>(RedisKey.SystemGoldDayKey);
}
public void SetChessRoom(ChessGameRoom room)
{
string key = string.Format(RedisKey.ChessRoomKey, room.RoomId);
_cache.Insert<ChessGameRoom>(key, room);
}
public ChessGameRoom GetChessRoom(string roomId)
{
string key = string.Format(RedisKey.ChessRoomKey, roomId);
return _cache.Get<ChessGameRoom>(key);
}
public List<ChessGameRoom> GetAllChessRooms()
{
var pattern = RedisKeyGenerator.GameKey("chess:room:*");
return _cache.GetPatternList<ChessGameRoom>(pattern, 10000)
?.Select(r => r ?? new ChessGameRoom())
.ToList() ?? new List<ChessGameRoom>();
}
public string GetPendingChessRoomId(string userId)
{
if (string.IsNullOrWhiteSpace(userId))
return string.Empty;
var rooms = GetAllChessRooms();
if (rooms == null || rooms.Count == 0)
return string.Empty;
var room = rooms.FirstOrDefault(r =>
r != null && r.state == 2 && !r.IsGameEnded
&& r.users != null && r.users.Any(u => u.userId == userId));
return room?.RoomId ?? string.Empty;
}
public void RemoveChessRoom(string roomId)
{
string key = string.Format(RedisKey.ChessRoomKey, roomId);
_cache.Remove(key);
}
public void ClearAllChessRooms()
{
var pattern = RedisKeyGenerator.GameKey("chess:room:*");
_cache.Clear(pattern, 50000);
}
public void ClearAllGameRooms()
{
var pattern = RedisKeyGenerator.GameKey("room:model:*");
_cache.Clear(pattern, 50000);
}
public void ClearAllUserMappings()
{
var cidPattern = RedisKeyGenerator.UserKey("cid:*");
var uidPattern = RedisKeyGenerator.UserKey("uid:*");
_cache.Clear(cidPattern, 50000);
_cache.Clear(uidPattern, 50000);
}
public void ClearAllLoginUserIds()
{
var cidPattern = RedisKeyGenerator.UserKey("cid:*");
var uidPattern = RedisKeyGenerator.UserKey("uid:*");
_cache.Clear(cidPattern, 100000);
_cache.Clear(uidPattern, 100000);
}
public void RemoveLoginUserId(string cid)
{
_cache.Remove(RedisKey.LoginCIDUser.Replace("{0}", cid));
}
public void SetVerificationCode(string phone, string code)
{
_cache.Insert<string>(RedisKey.VerificationCode.Replace("{0}", phone), code, TimeSpan.FromMinutes(5));
}
public string GetVerificationCode(string phone)
{
return _cache.Get<string>(RedisKey.VerificationCode.Replace("{0}", phone));
}
public void RemoveVerificationCode(string phone)
{
_cache.Remove(RedisKey.VerificationCode.Replace("{0}", phone));
}
public long IncrBy(string key, long value)
{
return _cache.IncrBy(key, value);
}
public string GetString(string key)
{
return _cache.Get<string>(key);
}
public void SetString(string key, string value)
{
_cache.Insert(key, value);
}
}
}