From a0ef3af1555643244c9a945149174da6b206c6cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com>
Date: Tue, 15 Oct 2024 21:50:31 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E5=9F=BA=E7=A1=80?=
=?UTF-8?q?=E6=A1=86=E6=9E=B6=E6=90=AD=E5=BB=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Jobs/AutoRefreshMiningPoolJob.cs | 26 +++-
.../Jobs/OnHookAutoMiningJob.cs | 29 ++++-
...ork.DigitalCollectibles.Application.csproj | 1 +
.../Consts/RarityEnum.cs | 2 +-
.../Enums/MiningResultEnum.cs | 8 ++
...k.DigitalCollectibles.Domain.Shared.csproj | 1 -
.../Dtos/MiningPoolContent.cs | 8 +-
.../Dtos/MiningPoolResult.cs | 11 ++
.../Managers/MiningPoolManager.cs | 123 +++++++++++++++---
9 files changed, 181 insertions(+), 28 deletions(-)
create mode 100644 Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Enums/MiningResultEnum.cs
rename Yi.Abp.Net8/module/digital-collectibles/{Yi.Framework.DigitalCollectibles.Domain.Shared => Yi.Framework.DigitalCollectibles.Domain}/Dtos/MiningPoolContent.cs (80%)
create mode 100644 Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Dtos/MiningPoolResult.cs
diff --git a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Application/Jobs/AutoRefreshMiningPoolJob.cs b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Application/Jobs/AutoRefreshMiningPoolJob.cs
index 8d895ee3..1563a531 100644
--- a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Application/Jobs/AutoRefreshMiningPoolJob.cs
+++ b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Application/Jobs/AutoRefreshMiningPoolJob.cs
@@ -1,9 +1,29 @@
-namespace Yi.Framework.DigitalCollectibles.Application.Jobs;
+using Quartz;
+using Volo.Abp.BackgroundWorkers.Quartz;
+using Yi.Framework.DigitalCollectibles.Domain.Managers;
+
+namespace Yi.Framework.DigitalCollectibles.Application.Jobs;
///
/// 自动刷新填满矿池
///
-public class AutoRefreshMiningPoolJob
+public class AutoRefreshMiningPoolJob : QuartzBackgroundWorkerBase
{
-
+ private readonly MiningPoolManager _miningPoolManager;
+
+ public AutoRefreshMiningPoolJob()
+ {
+ JobDetail = JobBuilder.Create().WithIdentity(nameof(AutoRefreshMiningPoolJob))
+ .Build();
+
+ //每天早上10点执行一次
+ Trigger = TriggerBuilder.Create().WithIdentity(nameof(AutoRefreshMiningPoolJob))
+ .WithCronSchedule("0 0 10 * * ?")
+ .Build();
+ }
+
+ public override async Task Execute(IJobExecutionContext context)
+ {
+ await _miningPoolManager.RefreshMiningPoolAsync();
+ }
}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Application/Jobs/OnHookAutoMiningJob.cs b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Application/Jobs/OnHookAutoMiningJob.cs
index 216ea04c..fe6f69f6 100644
--- a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Application/Jobs/OnHookAutoMiningJob.cs
+++ b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Application/Jobs/OnHookAutoMiningJob.cs
@@ -1,9 +1,32 @@
-namespace Yi.Framework.DigitalCollectibles.Application.Jobs;
+using Quartz;
+using Volo.Abp.BackgroundWorkers.Quartz;
+using Yi.Framework.DigitalCollectibles.Domain.Entities;
+using Yi.Framework.DigitalCollectibles.Domain.Managers;
+using Yi.Framework.SqlSugarCore.Abstractions;
+
+namespace Yi.Framework.DigitalCollectibles.Application.Jobs;
///
/// 处理挂机挖矿定时任务
///
-public class OnHookAutoMiningJob
+public class OnHookAutoMiningJob : QuartzBackgroundWorkerBase
{
-
+ private readonly MiningPoolManager _miningPoolManager;
+
+ public OnHookAutoMiningJob(MiningPoolManager miningPoolManager)
+ {
+ _miningPoolManager = miningPoolManager;
+ JobDetail = JobBuilder.Create().WithIdentity(nameof(AutoRefreshMiningPoolJob))
+ .Build();
+
+ //每小时执行一次
+ Trigger = TriggerBuilder.Create().WithIdentity(nameof(AutoRefreshMiningPoolJob))
+ .WithCronSchedule("0 0 * * * ?")
+ .Build();
+ }
+
+ public override async Task Execute(IJobExecutionContext context)
+ {
+ await _miningPoolManager.OnHookMiningAsync();
+ }
}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Application/Yi.Framework.DigitalCollectibles.Application.csproj b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Application/Yi.Framework.DigitalCollectibles.Application.csproj
index 3a010e50..57a561a8 100644
--- a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Application/Yi.Framework.DigitalCollectibles.Application.csproj
+++ b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Application/Yi.Framework.DigitalCollectibles.Application.csproj
@@ -6,6 +6,7 @@
+
diff --git a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Consts/RarityEnum.cs b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Consts/RarityEnum.cs
index 453aa212..2d988935 100644
--- a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Consts/RarityEnum.cs
+++ b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Consts/RarityEnum.cs
@@ -37,7 +37,7 @@ public static class RarityEnumExtensions
return display.Name!;
}
- public static decimal[] GetProbabilityValues()
+ public static decimal[] GetProbabilityArray()
{
List probabilityList = new List();
diff --git a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Enums/MiningResultEnum.cs b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Enums/MiningResultEnum.cs
new file mode 100644
index 00000000..2a94fd35
--- /dev/null
+++ b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Enums/MiningResultEnum.cs
@@ -0,0 +1,8 @@
+namespace Yi.Framework.DigitalCollectibles.Domain.Shared.Enums;
+
+public enum MiningResultEnum
+{
+ Success,
+ Empty,
+ PoolIsEmpty
+}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Yi.Framework.DigitalCollectibles.Domain.Shared.csproj b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Yi.Framework.DigitalCollectibles.Domain.Shared.csproj
index 1c8256fb..5a8191e1 100644
--- a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Yi.Framework.DigitalCollectibles.Domain.Shared.csproj
+++ b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Yi.Framework.DigitalCollectibles.Domain.Shared.csproj
@@ -10,7 +10,6 @@
-
diff --git a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Dtos/MiningPoolContent.cs b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Dtos/MiningPoolContent.cs
similarity index 80%
rename from Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Dtos/MiningPoolContent.cs
rename to Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Dtos/MiningPoolContent.cs
index 1ff8714b..b5094bc3 100644
--- a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain.Shared/Dtos/MiningPoolContent.cs
+++ b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Dtos/MiningPoolContent.cs
@@ -1,4 +1,4 @@
-namespace Yi.Framework.DigitalCollectibles.Domain.Shared.Dtos;
+namespace Yi.Framework.DigitalCollectibles.Domain.Dtos;
///
/// 矿池内容
@@ -45,6 +45,10 @@ public class MiningPoolContent
/// 结束时间
///
public DateTime EndTime{ get; set; }
-
+
+ ///
+ /// 总共剩余藏品数量
+ ///
+ public int TotalNumber => I0_OrdinaryNumber + I1_SeniorNumber + I2_RareNumber + I3_GemNumber + I4_LegendNumber;
}
diff --git a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Dtos/MiningPoolResult.cs b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Dtos/MiningPoolResult.cs
new file mode 100644
index 00000000..27be92c5
--- /dev/null
+++ b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Dtos/MiningPoolResult.cs
@@ -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; }
+}
\ No newline at end of file
diff --git a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Managers/MiningPoolManager.cs b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Managers/MiningPoolManager.cs
index 20105288..ce9d1402 100644
--- a/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Managers/MiningPoolManager.cs
+++ b/Yi.Abp.Net8/module/digital-collectibles/Yi.Framework.DigitalCollectibles.Domain/Managers/MiningPoolManager.cs
@@ -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;
///
public class MiningPoolManager : DomainService
{
- ///
- /// 每次挖矿概率,每天根据特定算法计算
- ///
- private static decimal CurrentMiningProbability { get; set; }
-
+ private readonly ISqlSugarRepository _collectiblesRepository;
+ private readonly ISqlSugarRepository _onHookRepository;
private readonly ISettingProvider _settingProvider;
private readonly IDistributedCache _cache;
+ private readonly ISqlSugarRepository _userStoreRepository;
- public MiningPoolManager(ISettingProvider settingProvider, IDistributedCache cache)
+ public MiningPoolManager(ISettingProvider settingProvider, IDistributedCache cache,
+ ISqlSugarRepository collectiblesRepository,
+ ISqlSugarRepository onHookRepository,
+ ISqlSugarRepository userStoreRepository)
{
_settingProvider = settingProvider;
this._cache = cache;
+ _collectiblesRepository = collectiblesRepository;
+ _onHookRepository = onHookRepository;
+ _userStoreRepository = userStoreRepository;
}
///
- /// 最后一次计算挖矿概率的时间,如果时间跨了早上10点,重新计算
+ /// 每次挖矿概率,每天根据特定算法计算
///
- private static DateTime LastComputeMiningProbabilityTime { get; set; }
+ private static decimal CurrentMiningProbability => AsyncHelper.RunSync(async () =>
+ {
+ return await ComputeMiningProbabilityAsync();
+ });
///
/// 用户进行一次挖矿
///
///
- public Task MiningAsync(Guid userId)
+ public async Task 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() < 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;
+ }
+
+ ///
+ /// 挂机挖矿
+ ///
+ 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 cumulativeProbability = 0.0m;
+
+ for (int i = 0; i < probabilities.Length; i++)
+ {
+ cumulativeProbability += probabilities[i];
+
+ // 判断随机数是否小于当前的累积概率
+ if (randomValue < cumulativeProbability)
+ {
+ return i; // 返回中标的索引
+ }
+ }
+
+ //剩余情况都是普通
+ return 0;
}
///
/// 计算当前挖矿概率
///
///
- public Task ComputeMiningProbabilityAsync()
+ public static Task ComputeMiningProbabilityAsync()
{
//当前的挖矿期望:当天的所有藏品能被刚好挖完
-
+
//保底概率:最大不能高过一个值,百分之10
//手动挖矿:1天可挖10次,每次至少间隔6秒
//自动挖矿:1天可以挖24次 每次间隔60分钟(需要使用自动挖矿卡)
//可影响因素:剩余手动挖矿次数+剩余自动挖矿次数
-
- //所有能够挖掘次数
- throw new NotImplementedException();
+
+ //简单模式,1/15
+ return Task.FromResult(1m / 15);
}
///
@@ -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);
//根据配置,将不同比例的矿,塞入矿池,