feat: 完成基础框架搭建

This commit is contained in:
橙子
2024-10-15 21:50:31 +08:00
parent e8fcab4c6b
commit a0ef3af155
9 changed files with 181 additions and 28 deletions

View File

@@ -0,0 +1,54 @@
namespace Yi.Framework.DigitalCollectibles.Domain.Dtos;
/// <summary>
/// 矿池内容
/// </summary>
public class MiningPoolContent
{
public MiningPoolContent(DateTime startTime, DateTime endTime)
{
StartTime = startTime;
EndTime = endTime;
}
/// <summary>
/// 普通藏品剩余数量
/// </summary>
public int I0_OrdinaryNumber { get; set; }
/// <summary>
/// 高级藏品剩余数量
/// </summary>
public int I1_SeniorNumber { get; set; }
/// <summary>
/// 稀有藏品剩余数量
/// </summary>
public int I2_RareNumber { get; set; }
/// <summary>
/// 珍品藏品剩余数量
/// </summary>
public int I3_GemNumber { get; set; }
/// <summary>
/// 传说藏品剩余数量
/// </summary>
public int I4_LegendNumber { get; set; }
/// <summary>
/// 开始时间
/// </summary>
public DateTime StartTime{ get; set; }
/// <summary>
/// 结束时间
/// </summary>
public DateTime EndTime{ get; set; }
/// <summary>
/// 总共剩余藏品数量
/// </summary>
public int TotalNumber => I0_OrdinaryNumber + I1_SeniorNumber + I2_RareNumber + I3_GemNumber + I4_LegendNumber;
}

View File

@@ -0,0 +1,11 @@
using Yi.Framework.DigitalCollectibles.Domain.Entities;
using Yi.Framework.DigitalCollectibles.Domain.Shared.Enums;
namespace Yi.Framework.DigitalCollectibles.Domain.Dtos;
public class MiningPoolResult
{
public MiningResultEnum Result { get; set; }
public CollectiblesAggregateRoot? Collectibles { get; set; }
}

View File

@@ -2,9 +2,13 @@
using Volo.Abp.Caching;
using Volo.Abp.Domain.Services;
using Volo.Abp.Settings;
using Volo.Abp.Threading;
using Yi.Framework.DigitalCollectibles.Domain.Dtos;
using Yi.Framework.DigitalCollectibles.Domain.Entities;
using Yi.Framework.DigitalCollectibles.Domain.Shared.Consts;
using Yi.Framework.DigitalCollectibles.Domain.Shared.Dtos;
using Yi.Framework.DigitalCollectibles.Domain.Shared.Enums;
using Yi.Framework.SettingManagement.Domain;
using Yi.Framework.SqlSugarCore.Abstractions;
namespace Yi.Framework.DigitalCollectibles.Domain.Managers;
@@ -14,55 +18,138 @@ namespace Yi.Framework.DigitalCollectibles.Domain.Managers;
/// </summary>
public class MiningPoolManager : DomainService
{
/// <summary>
/// 每次挖矿概率,每天根据特定算法计算
/// </summary>
private static decimal CurrentMiningProbability { get; set; }
private readonly ISqlSugarRepository<CollectiblesAggregateRoot> _collectiblesRepository;
private readonly ISqlSugarRepository<OnHookAggregateRoot> _onHookRepository;
private readonly ISettingProvider _settingProvider;
private readonly IDistributedCache<MiningPoolContent> _cache;
private readonly ISqlSugarRepository<CollectiblesUserStoreAggregateRoot> _userStoreRepository;
public MiningPoolManager(ISettingProvider settingProvider, IDistributedCache<MiningPoolContent> cache)
public MiningPoolManager(ISettingProvider settingProvider, IDistributedCache<MiningPoolContent> cache,
ISqlSugarRepository<CollectiblesAggregateRoot> collectiblesRepository,
ISqlSugarRepository<OnHookAggregateRoot> onHookRepository,
ISqlSugarRepository<CollectiblesUserStoreAggregateRoot> userStoreRepository)
{
_settingProvider = settingProvider;
this._cache = cache;
_collectiblesRepository = collectiblesRepository;
_onHookRepository = onHookRepository;
_userStoreRepository = userStoreRepository;
}
/// <summary>
/// 最后一次计算挖矿概率的时间如果时间跨了早上10点重新计算
/// 每次挖矿概率,每天根据特定算法计算
/// </summary>
private static DateTime LastComputeMiningProbabilityTime { get; set; }
private static decimal CurrentMiningProbability => AsyncHelper.RunSync(async () =>
{
return await ComputeMiningProbabilityAsync();
});
/// <summary>
/// 用户进行一次挖矿
/// </summary>
/// <returns></returns>
public Task MiningAsync(Guid userId)
public async Task<MiningPoolResult> MiningAsync(Guid userId)
{
//从矿池中开挖
var result = new MiningPoolResult();
//从矿池中开挖,判断矿池是否还有矿
//根据挖矿概率,进行挖掘
//挖到了放到用户仓库即可
//如果概率是挖到了矿,再从矿物中随机选择一个稀有度,再在当前稀有度中的矿物列表,随机选择一个具体的矿物
var pool = await _cache.GetAsync(CacheConst.MiningPoolContent);
if (pool.TotalNumber == 0)
{
result.Result = MiningResultEnum.PoolIsEmpty;
return result;
}
throw new NotImplementedException();
// 生成一个 0 到 1 之间的随机数
double randomValue = new Random().NextDouble();
//如果随机的概率在当前概率内,成功
if (randomValue.To<decimal>() < CurrentMiningProbability)
{
//成功后在藏品中根据稀有度概率必定获取一个
var probabilityArray = RarityEnumExtensions.GetProbabilityArray();
var index = GetRandomIndex(probabilityArray);
var rarityType = (RarityEnum)Enum.GetValues(typeof(RarityEnum)).GetValue(index);
var collectiblesList =
await _collectiblesRepository._DbQueryable.Where(x => x.Rarity == rarityType).ToListAsync();
int randomIndex = new Random().Next(collectiblesList.Count);
var currentCollectibles = collectiblesList[randomIndex];
result.Result = MiningResultEnum.Success;
result.Collectibles = currentCollectibles;
//使用结果新增给对应的用户
await _userStoreRepository.InsertAsync(new CollectiblesUserStoreAggregateRoot
{
UserId = userId,
CollectiblesId = result.Collectibles.Id,
IsRead = false
});
return result;
}
result.Result = MiningResultEnum.Empty;
return result;
}
/// <summary>
/// 挂机挖矿
/// </summary>
public async Task OnHookMiningAsync()
{
//获取当前激活的挂机挖矿
var currentOnHook = await _onHookRepository._DbQueryable.Where(x => x.IsActive == true)
.Where(x => x.EndTime <= DateTime.Now).ToListAsync();
//根据用户对挂机卡hash关系
var userOnHookDic = currentOnHook.GroupBy(x => x.UserId).ToDictionary(x => x.Key, y => y.First());
foreach (var onHookItem in userOnHookDic)
{
await MiningAsync(onHookItem.Value.UserId);
}
}
private int GetRandomIndex(decimal[] probabilities)
{
// 生成0到1之间的随机数
Random random = new Random();
decimal randomValue = random.NextDouble().To<decimal>();
decimal cumulativeProbability = 0.0m;
for (int i = 0; i < probabilities.Length; i++)
{
cumulativeProbability += probabilities[i];
// 判断随机数是否小于当前的累积概率
if (randomValue < cumulativeProbability)
{
return i; // 返回中标的索引
}
}
//剩余情况都是普通
return 0;
}
/// <summary>
/// 计算当前挖矿概率
/// </summary>
/// <returns></returns>
public Task ComputeMiningProbabilityAsync()
public static Task<decimal> ComputeMiningProbabilityAsync()
{
//当前的挖矿期望:当天的所有藏品能被刚好挖完
//保底概率最大不能高过一个值百分之10
//手动挖矿1天可挖10次每次至少间隔6秒
//自动挖矿1天可以挖24次 每次间隔60分钟需要使用自动挖矿卡
//可影响因素:剩余手动挖矿次数+剩余自动挖矿次数
//所有能够挖掘次数
throw new NotImplementedException();
//简单模式1/15
return Task.FromResult(1m / 15);
}
/// <summary>
@@ -76,7 +163,7 @@ public class MiningPoolManager : DomainService
DateTime startTime = DateTime.Today.AddHours(10);
DateTime endTime = startTime.AddDays(1);
var probabilityValues = RarityEnumExtensions.GetProbabilityValues();
var probabilityValues = RarityEnumExtensions.GetProbabilityArray();
var result = GenerateDistribution(maximumPoolLimit, probabilityValues);
//根据配置,将不同比例的矿,塞入矿池,