diff --git a/.gitignore b/.gitignore index 7b6b2a964..6a25dffb9 100644 --- a/.gitignore +++ b/.gitignore @@ -368,4 +368,7 @@ krew/pkg/utils/fixtures kustomization.yaml # cookie config -**/Ray.BiliBiliTool.Console/cookies.json \ No newline at end of file +**/Ray.BiliBiliTool.Console/cookies.json + +# ut +coveragereport diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d118ecca..c0b04a622 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 2.1.3 +- Code refactory +- Fix[#791]:修复VipBigPoint任务异常导致终止的问题 ## 2.1.2 - Feature: enhancement CICD scripts - Fix[#728]: compatible with qinglong history versions diff --git a/Ray.BiliBiliTool.sln b/Ray.BiliBiliTool.sln index c27d5bed0..617db82c4 100644 --- a/Ray.BiliBiliTool.sln +++ b/Ray.BiliBiliTool.sln @@ -39,7 +39,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution .editorconfig = .editorconfig .gitignore = .gitignore CHANGELOG.md = CHANGELOG.md - clean.cmd = clean.cmd common.props = common.props Dockerfile = Dockerfile LICENSE = LICENSE @@ -139,6 +138,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InfrastructureTest", "test\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ray.BiliBiliTool.Agent.FunctionalTests", "test\Ray.BiliBiliTool.Agent.FunctionalTests\Ray.BiliBiliTool.Agent.FunctionalTests.csproj", "{16F315CF-056A-4B08-8C3C-A3177EA3CBB9}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{2B5FD099-CC28-4FBC-9F20-F20300C5DFD2}" + ProjectSection(SolutionItems) = preProject + scripts\clean.cmd = scripts\clean.cmd + scripts\publish.bat = scripts\publish.bat + scripts\publish.ps1 = scripts\publish.ps1 + scripts\publish.sh = scripts\publish.sh + scripts\ut.ps1 = scripts\ut.ps1 + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -233,6 +241,7 @@ Global {26B21C30-7358-4E7B-A73E-2272F10A6CA8} = {E9BDDCBE-A57D-4E3B-8252-708088386ADF} {90C1DB73-B3DB-4BE5-AD1A-5248FE47860E} = {E9BDDCBE-A57D-4E3B-8252-708088386ADF} {16F315CF-056A-4B08-8C3C-A3177EA3CBB9} = {E9BDDCBE-A57D-4E3B-8252-708088386ADF} + {2B5FD099-CC28-4FBC-9F20-F20300C5DFD2} = {F3DE0D72-426B-4AD9-B3ED-3343CF4223F1} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {197319DA-1148-4A99-847C-8B270B6A29AB} diff --git a/common.props b/common.props index 34810691c..e3a3f38b0 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ Ray - 2.1.2 + 2.1.3 $(NoWarn);CS1591;CS0436 diff --git a/docs/runInLocal.md b/docs/runInLocal.md index e7d3ed0df..c45da5b27 100644 --- a/docs/runInLocal.md +++ b/docs/runInLocal.md @@ -42,7 +42,7 @@ P.S.这里的运行环境指的是 `.NET Runtime 6.0.0` ,安装方法可详见 ``` wget https://github.com/RayWangQvQ/BiliBiliToolPro/releases/download/0.3.1/bilibili-tool-pro-v0.3.1-linux-x64.zip unzip bilibili-tool-pro-v0.3.1-linux-x64.zip -cd cd ./linux-x64/ +cd ./linux-x64/ ./Ray.BiliBiliTool.Console --runTasks=Login ``` diff --git a/scripts/ut.ps1 b/scripts/ut.ps1 new file mode 100644 index 000000000..5107aab08 --- /dev/null +++ b/scripts/ut.ps1 @@ -0,0 +1,19 @@ +Set-Location .. + +# 安装 ReportGenerator 工具 +Write-Output "Installing ReportGenerator tool..." +dotnet tool install -g dotnet-reportgenerator-globaltool + +# 运行单元测试并生成覆盖率报告 +Write-Output "Running unit tests and generating coverage report..." +dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:CoverletOutput=./TestResults/coverage.opencover.xml + +# 生成html报告 +$coverageFiles = Get-ChildItem -Path . -Recurse -Filter "coverage.cobertura.xml" +$coverageFiles | ForEach-Object { Write-Output $_.FullName } +$reportPaths = ($coverageFiles | ForEach-Object { $_.FullName }) -join ";" +reportgenerator "-reports:$reportPaths" "-targetdir:coveragereport" -reporttypes:Html + +# 检查生成的覆盖率报告文件是否存在 +Write-Output "Coverage report generated successfully." +Start-Process "coveragereport/index.htm" \ No newline at end of file diff --git a/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/Live/GetLiveRoomInfoResponse.cs b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/Live/GetLiveRoomInfoResponse.cs index 9a2a42e1a..c69e5f308 100644 --- a/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/Live/GetLiveRoomInfoResponse.cs +++ b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/Live/GetLiveRoomInfoResponse.cs @@ -14,6 +14,8 @@ public class GetLiveRoomInfoResponse public long Parent_area_id { get; set; } + public int Live_Status { get; set; } + public long Uid { get; set; } } -} +} \ No newline at end of file diff --git a/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/Live/LikeLiveRoomRequest.cs b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/Live/LikeLiveRoomRequest.cs index e7515ac31..18001fe40 100644 --- a/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/Live/LikeLiveRoomRequest.cs +++ b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/Live/LikeLiveRoomRequest.cs @@ -8,16 +8,32 @@ namespace Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos.Live { public class LikeLiveRoomRequest { - public LikeLiveRoomRequest(long roomid, string csrf) + public LikeLiveRoomRequest(long roomid, string csrf, int clickTime, long anchorId, string uid) { Roomid = roomid; - Csrf= csrf; + Csrf = csrf; + Click_Time = clickTime; + Anchor_Id = anchorId; + Uid = uid; } public long Roomid { get; set; } public string Csrf { get; set; } - public string Csrf_token => Csrf; + public string Csrf_Token => Csrf; + + public int Click_Time { get; set; } + + public long Anchor_Id { get; set; } + + public string Uid { get; set; } + + + public string RawTextBuild() + { + return + $"click_time={Click_Time.ToString()}&room_id={Roomid.ToString()}&uid={Uid}&anchor_id={Anchor_Id}&csrf_token={Csrf_Token}&csrf={Csrf}"; + } } -} +} \ No newline at end of file diff --git a/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Interfaces/ILiveApi.cs b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Interfaces/ILiveApi.cs index 0db0ae863..02c0fc52a 100644 --- a/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Interfaces/ILiveApi.cs +++ b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Interfaces/ILiveApi.cs @@ -144,8 +144,8 @@ public interface ILiveApi : IBiliBiliApi /// /// 点赞直播间 /// - [HttpPost("/xlive/web-ucenter/v1/interact/likeInteract")] + [HttpPost("/xlive/app-ucenter/v1/like_info_v3/like/likeReportV3")] [Header("Referer", "https://live.bilibili.com/")] [Header("Origin", "https://live.bilibili.com")] - Task LikeLiveRoom([FormContent] LikeLiveRoomRequest request); -} + Task LikeLiveRoom([RawFormContent] string request); +} \ No newline at end of file diff --git a/src/Ray.BiliBiliTool.Application/DailyTaskAppService.cs b/src/Ray.BiliBiliTool.Application/DailyTaskAppService.cs index f7e6ccc84..191c080f2 100644 --- a/src/Ray.BiliBiliTool.Application/DailyTaskAppService.cs +++ b/src/Ray.BiliBiliTool.Application/DailyTaskAppService.cs @@ -12,278 +12,263 @@ using Ray.BiliBiliTool.Config; using Ray.BiliBiliTool.Config.Options; using Ray.BiliBiliTool.DomainService.Interfaces; -using Ray.BiliBiliTool.Infrastructure; -using Ray.BiliBiliTool.Infrastructure.Cookie; using Ray.BiliBiliTool.Infrastructure.Enums; -namespace Ray.BiliBiliTool.Application +namespace Ray.BiliBiliTool.Application; + +public class DailyTaskAppService : AppService, IDailyTaskAppService { - public class DailyTaskAppService : AppService, IDailyTaskAppService + private readonly ILogger _logger; + private readonly IAccountDomainService _accountDomainService; + private readonly IVideoDomainService _videoDomainService; + private readonly IArticleDomainService _articleDomainService; + private readonly IDonateCoinDomainService _donateCoinDomainService; + private readonly IMangaDomainService _mangaDomainService; + private readonly ILiveDomainService _liveDomainService; + private readonly IVipPrivilegeDomainService _vipPrivilegeDomainService; + private readonly IChargeDomainService _chargeDomainService; + private readonly DailyTaskOptions _dailyTaskOptions; + private readonly ICoinDomainService _coinDomainService; + private readonly Dictionary _expDic; + private readonly ILoginDomainService _loginDomainService; + private readonly IConfiguration _configuration; + private readonly BiliCookie _biliCookie; + + public DailyTaskAppService( + ILogger logger, + IOptionsMonitor> dicOptions, + IAccountDomainService accountDomainService, + IVideoDomainService videoDomainService, + IArticleDomainService articleDomainService, + IDonateCoinDomainService donateCoinDomainService, + IMangaDomainService mangaDomainService, + ILiveDomainService liveDomainService, + IVipPrivilegeDomainService vipPrivilegeDomainService, + IChargeDomainService chargeDomainService, + IOptionsMonitor dailyTaskOptions, + ICoinDomainService coinDomainService, + ILoginDomainService loginDomainService, + IConfiguration configuration, + BiliCookie biliCookie) { - private readonly ILogger _logger; - private readonly IAccountDomainService _accountDomainService; - private readonly IVideoDomainService _videoDomainService; - private readonly IArticleDomainService _articleDomainService; - private readonly IDonateCoinDomainService _donateCoinDomainService; - private readonly IMangaDomainService _mangaDomainService; - private readonly ILiveDomainService _liveDomainService; - private readonly IVipPrivilegeDomainService _vipPrivilegeDomainService; - private readonly IChargeDomainService _chargeDomainService; - private readonly DailyTaskOptions _dailyTaskOptions; - private readonly ICoinDomainService _coinDomainService; - private readonly Dictionary _expDic; - private readonly ILoginDomainService _loginDomainService; - private readonly IConfiguration _configuration; - private readonly CookieStrFactory _cookieStrFactory; - private BiliCookie _biliCookie; - - public DailyTaskAppService( - ILogger logger, - IOptionsMonitor> dicOptions, - IAccountDomainService accountDomainService, - IVideoDomainService videoDomainService, - IArticleDomainService articleDomainService, - IDonateCoinDomainService donateCoinDomainService, - IMangaDomainService mangaDomainService, - ILiveDomainService liveDomainService, - IVipPrivilegeDomainService vipPrivilegeDomainService, - IChargeDomainService chargeDomainService, - IOptionsMonitor dailyTaskOptions, - ICoinDomainService coinDomainService, - ILoginDomainService loginDomainService, IConfiguration configuration, - CookieStrFactory cookieStrFactory, - BiliCookie biliCookie) - { - _logger = logger; - _expDic = dicOptions.Get(Constants.OptionsNames.ExpDictionaryName); - _accountDomainService = accountDomainService; - _videoDomainService = videoDomainService; - _articleDomainService = articleDomainService; - _donateCoinDomainService = donateCoinDomainService; - _mangaDomainService = mangaDomainService; - _liveDomainService = liveDomainService; - _vipPrivilegeDomainService = vipPrivilegeDomainService; - _chargeDomainService = chargeDomainService; - _dailyTaskOptions = dailyTaskOptions.CurrentValue; - _coinDomainService = coinDomainService; - _loginDomainService = loginDomainService; - _configuration = configuration; - _cookieStrFactory = cookieStrFactory; - _biliCookie = biliCookie; - } + _logger = logger; + _expDic = dicOptions.Get(Constants.OptionsNames.ExpDictionaryName); + _accountDomainService = accountDomainService; + _videoDomainService = videoDomainService; + _articleDomainService = articleDomainService; + _donateCoinDomainService = donateCoinDomainService; + _mangaDomainService = mangaDomainService; + _liveDomainService = liveDomainService; + _vipPrivilegeDomainService = vipPrivilegeDomainService; + _chargeDomainService = chargeDomainService; + _dailyTaskOptions = dailyTaskOptions.CurrentValue; + _coinDomainService = coinDomainService; + _loginDomainService = loginDomainService; + _configuration = configuration; + _biliCookie = biliCookie; + } - [TaskInterceptor("每日任务", TaskLevel.One)] - public override async Task DoTaskAsync(CancellationToken cancellationToken) - { - await SetCookiesAsync(_biliCookie, cancellationToken); + [TaskInterceptor("每日任务", TaskLevel.One)] + public override async Task DoTaskAsync(CancellationToken cancellationToken = default) + { + await SetCookiesAsync(_biliCookie, cancellationToken); - //每日任务赚经验: - UserInfo userInfo = await Login(); + //每日任务赚经验: + UserInfo userInfo = await Login(); - DailyTaskInfo dailyTaskInfo = await GetDailyTaskStatus(); - await WatchAndShareVideo(dailyTaskInfo); + DailyTaskInfo dailyTaskInfo = await GetDailyTaskStatus(); + await WatchAndShareVideo(dailyTaskInfo); - await AddCoins(userInfo); + await AddCoins(userInfo); - //签到: - await LiveSign(); - await MangaSign(); - await MangaRead(); - await ExchangeSilver2Coin(); + //签到: + await MangaSign(); + await MangaRead(); + await ExchangeSilver2Coin(); - //领福利: - await ReceiveVipPrivilege(userInfo); - await ReceiveMangaVipReward(userInfo); + //领福利: + await ReceiveVipPrivilege(userInfo); + await ReceiveMangaVipReward(userInfo); - await Charge(userInfo); - } + await Charge(userInfo); + } - [TaskInterceptor("Set Cookie", TaskLevel.Two)] - protected async Task SetCookiesAsync(BiliCookie biliCookie, CancellationToken cancellationToken) + [TaskInterceptor("Set Cookie", TaskLevel.Two)] + protected async Task SetCookiesAsync(BiliCookie biliCookie, CancellationToken cancellationToken) + { + //判断cookie是否完整 + if (biliCookie.Buvid.IsNotNullOrEmpty()) { - //判断cookie是否完整 - if (biliCookie.Buvid.IsNotNullOrEmpty()) - { - _logger.LogInformation("Cookie完整,不需要Set Cookie"); - return biliCookie; - } + _logger.LogInformation("Cookie完整,不需要Set Cookie"); + return biliCookie; + } - //Set - _logger.LogInformation("开始Set Cookie"); - var ck = await _loginDomainService.SetCookieAsync(biliCookie, cancellationToken); + //Set + _logger.LogInformation("开始Set Cookie"); + var ck = await _loginDomainService.SetCookieAsync(biliCookie, cancellationToken); - //持久化 - _logger.LogInformation("持久化Cookie"); - await SaveCookieAsync(ck, cancellationToken); + //持久化 + _logger.LogInformation("持久化Cookie"); + await SaveCookieAsync(ck, cancellationToken); - return ck; - } + return ck; + } - /// - /// 登录 - /// - /// - [TaskInterceptor("登录")] - private async Task Login() - { - UserInfo userInfo = await _accountDomainService.LoginByCookie(); - if (userInfo == null) throw new Exception("登录失败,请检查Cookie"); //终止流程 + /// + /// 登录 + /// + /// + [TaskInterceptor("登录")] + private async Task Login() + { + UserInfo userInfo = await _accountDomainService.LoginByCookie(); + if (userInfo == null) throw new Exception("登录失败,请检查Cookie"); //终止流程 - _expDic.TryGetValue("每日登录", out int exp); - _logger.LogInformation("登录成功,经验+{exp} √", exp); + _expDic.TryGetValue("每日登录", out int exp); + _logger.LogInformation("登录成功,经验+{exp} √", exp); - return userInfo; - } + return userInfo; + } - /// - /// 获取任务完成情况 - /// - /// - [TaskInterceptor(null, rethrowWhenException: false)] - private async Task GetDailyTaskStatus() + /// + /// 获取任务完成情况 + /// + /// + [TaskInterceptor(null, rethrowWhenException: false)] + private async Task GetDailyTaskStatus() + { + return await _accountDomainService.GetDailyTaskStatus(); + } + + /// + /// 观看、分享视频 + /// + [TaskInterceptor("观看、分享视频", rethrowWhenException: false)] + private async Task WatchAndShareVideo(DailyTaskInfo dailyTaskInfo) + { + if (!_dailyTaskOptions.IsWatchVideo && !_dailyTaskOptions.IsShareVideo) { - return await _accountDomainService.GetDailyTaskStatus(); + _logger.LogInformation("已配置为关闭,跳过任务"); + return; } - /// - /// 观看、分享视频 - /// - [TaskInterceptor("观看、分享视频", rethrowWhenException: false)] - private async Task WatchAndShareVideo(DailyTaskInfo dailyTaskInfo) - { - if (!_dailyTaskOptions.IsWatchVideo && !_dailyTaskOptions.IsShareVideo) - { - _logger.LogInformation("已配置为关闭,跳过任务"); - return; - } + await _videoDomainService.WatchAndShareVideo(dailyTaskInfo); + } - await _videoDomainService.WatchAndShareVideo(dailyTaskInfo); + /// + /// 投币任务 + /// + [TaskInterceptor("投币", rethrowWhenException: false)] + private async Task AddCoins(UserInfo userInfo) + { + if (_dailyTaskOptions.SaveCoinsWhenLv6 && userInfo.Level_info.Current_level >= 6) + { + _logger.LogInformation("已经为LV6大佬,开始白嫖"); + return; } - /// - /// 投币任务 - /// - [TaskInterceptor("投币", rethrowWhenException: false)] - private async Task AddCoins(UserInfo userInfo) + if (_dailyTaskOptions.IsDonateCoinForArticle) { - if (_dailyTaskOptions.SaveCoinsWhenLv6 && userInfo.Level_info.Current_level >= 6) - { - _logger.LogInformation("已经为LV6大佬,开始白嫖"); - return; - } + _logger.LogInformation("专栏投币已开启"); - if (_dailyTaskOptions.IsDonateCoinForArticle) - { - _logger.LogInformation("专栏投币已开启"); - - if (!await _articleDomainService.AddCoinForArticles()) - { - _logger.LogInformation("专栏投币结束,转入视频投币"); - await _donateCoinDomainService.AddCoinsForVideos(); - } - } - else + if (!await _articleDomainService.AddCoinForArticles()) { + _logger.LogInformation("专栏投币结束,转入视频投币"); await _donateCoinDomainService.AddCoinsForVideos(); } } - - /// - /// 直播中心签到 - /// - [TaskInterceptor("直播签到", rethrowWhenException: false)] - private async Task LiveSign() + else { - await _liveDomainService.LiveSign(); + await _donateCoinDomainService.AddCoinsForVideos(); } + } - /// - /// 直播中心的银瓜子兑换硬币 - /// - [TaskInterceptor("银瓜子兑换硬币", rethrowWhenException: false)] - private async Task ExchangeSilver2Coin() - { - var success = await _liveDomainService.ExchangeSilver2Coin(); - if (!success) return; + /// + /// 直播中心的银瓜子兑换硬币 + /// + [TaskInterceptor("银瓜子兑换硬币", rethrowWhenException: false)] + private async Task ExchangeSilver2Coin() + { + var success = await _liveDomainService.ExchangeSilver2Coin(); + if (!success) return; - //如果兑换成功,则打印硬币余额 - var coinBalance = _coinDomainService.GetCoinBalance(); - _logger.LogInformation("【硬币余额】 {coin}", coinBalance); - } + //如果兑换成功,则打印硬币余额 + var coinBalance = _coinDomainService.GetCoinBalance(); + _logger.LogInformation("【硬币余额】 {coin}", coinBalance); + } - /// - /// 每月领取大会员福利 - /// - [TaskInterceptor("领取大会员福利", rethrowWhenException: false)] - private async Task ReceiveVipPrivilege(UserInfo userInfo) - { - var suc = await _vipPrivilegeDomainService.ReceiveVipPrivilege(userInfo); + /// + /// 每月领取大会员福利 + /// + [TaskInterceptor("领取大会员福利", rethrowWhenException: false)] + private async Task ReceiveVipPrivilege(UserInfo userInfo) + { + var suc = await _vipPrivilegeDomainService.ReceiveVipPrivilege(userInfo); - //如果领取成功,需要刷新账户信息(比如B币余额) - if (suc) + //如果领取成功,需要刷新账户信息(比如B币余额) + if (suc) + { + try { - try - { - userInfo = await _accountDomainService.LoginByCookie(); - } - catch (Exception ex) - { - _logger.LogError("领取福利成功,但之后刷新用户信息时异常,信息:{msg}", ex.Message); - } + userInfo = await _accountDomainService.LoginByCookie(); + } + catch (Exception ex) + { + _logger.LogError("领取福利成功,但之后刷新用户信息时异常,信息:{msg}", ex.Message); } } + } - /// - /// 每月为自己充电 - /// - [TaskInterceptor("B币券充电", rethrowWhenException: false)] - private async Task Charge(UserInfo userInfo) - { - await _chargeDomainService.Charge(userInfo); - } - - /// - /// 漫画签到 - /// - [TaskInterceptor("漫画签到", rethrowWhenException: false)] - private async Task MangaSign() - { - await _mangaDomainService.MangaSign(); - } + /// + /// 每月为自己充电 + /// + [TaskInterceptor("B币券充电", rethrowWhenException: false)] + private async Task Charge(UserInfo userInfo) + { + await _chargeDomainService.Charge(userInfo); + } - /// - /// 漫画阅读 - /// - [TaskInterceptor("漫画阅读", rethrowWhenException: false)] - private async Task MangaRead() - { - await _mangaDomainService.MangaRead(); - } + /// + /// 漫画签到 + /// + [TaskInterceptor("漫画签到", rethrowWhenException: false)] + private async Task MangaSign() + { + await _mangaDomainService.MangaSign(); + } - /// - /// 每月获取大会员漫画权益 - /// - [TaskInterceptor("领取大会员漫画权益", rethrowWhenException: false)] - private async Task ReceiveMangaVipReward(UserInfo userInfo) - { - await _mangaDomainService.ReceiveMangaVipReward(1, userInfo); - } + /// + /// 漫画阅读 + /// + [TaskInterceptor("漫画阅读", rethrowWhenException: false)] + private async Task MangaRead() + { + await _mangaDomainService.MangaRead(); + } - private async Task SaveCookieAsync(BiliCookie ckInfo, CancellationToken cancellationToken) - { - var platformType = _configuration.GetSection("PlateformType").Get(); - _logger.LogInformation("当前运行平台:{platform}", platformType); + /// + /// 每月获取大会员漫画权益 + /// + [TaskInterceptor("领取大会员漫画权益", rethrowWhenException: false)] + private async Task ReceiveMangaVipReward(UserInfo userInfo) + { + await _mangaDomainService.ReceiveMangaVipReward(1, userInfo); + } - //更新cookie到青龙env - if (platformType == PlatformType.QingLong) - { - await _loginDomainService.SaveCookieToQinLongAsync(ckInfo, cancellationToken); - return; - } + private async Task SaveCookieAsync(BiliCookie ckInfo, CancellationToken cancellationToken) + { + var platformType = _configuration.GetSection("PlateformType").Get(); + _logger.LogInformation("当前运行平台:{platform}", platformType); - //更新cookie到json - await _loginDomainService.SaveCookieToJsonFileAsync(ckInfo, cancellationToken); + //更新cookie到青龙env + if (platformType == PlatformType.QingLong) + { + await _loginDomainService.SaveCookieToQinLongAsync(ckInfo, cancellationToken); + return; } + + //更新cookie到json + await _loginDomainService.SaveCookieToJsonFileAsync(ckInfo, cancellationToken); } -} +} \ No newline at end of file diff --git a/src/Ray.BiliBiliTool.Application/VipBigPointAppService.cs b/src/Ray.BiliBiliTool.Application/VipBigPointAppService.cs index bd8276b31..73979d46c 100644 --- a/src/Ray.BiliBiliTool.Application/VipBigPointAppService.cs +++ b/src/Ray.BiliBiliTool.Application/VipBigPointAppService.cs @@ -2,12 +2,10 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Ray.BiliBiliTool.Agent; using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos; -using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos.Video; using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos.ViewMall; using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos.VipTask; using Ray.BiliBiliTool.Agent.BiliBiliAgent.Interfaces; @@ -22,7 +20,6 @@ namespace Ray.BiliBiliTool.Application; public class VipBigPointAppService : AppService, IVipBigPointAppService { private readonly ILogger _logger; - private readonly IConfiguration _configuration; private readonly IVipBigPointApi _vipApi; private readonly IAccountDomainService _loginDomainService; private readonly IVideoDomainService _videoDomainService; @@ -33,7 +30,6 @@ public class VipBigPointAppService : AppService, IVipBigPointAppService private readonly VipBigPointOptions _vipBigPointOptions; public VipBigPointAppService( - IConfiguration configuration, ILogger logger, IVipBigPointApi vipApi, IAccountDomainService loginDomainService, @@ -44,7 +40,6 @@ public VipBigPointAppService( IVideoApi videoApi, IOptionsMonitor vipBigPointOptions) { - _configuration = configuration; _logger = logger; _vipApi = vipApi; _loginDomainService = loginDomainService; @@ -56,58 +51,8 @@ public VipBigPointAppService( _vipBigPointOptions = vipBigPointOptions.CurrentValue; } - /// - /// 领取大会员专属经验包 - /// - public async Task VipExpress() - { - _logger.LogInformation("大会员经验领取任务开始"); - var re = await _vipApi.GetVouchersInfoAsync(); - if (re.Code == 0) - { - var state = re.Data.List.Find(x => x.Type == 9).State; - - switch (state) - { - case 2: - _logger.LogInformation("大会员经验观看任务未完成"); - _logger.LogInformation("开始观看视频"); - // 观看视频,暂时没有好办法解决,先这样使着 - DailyTaskInfo dailyTaskInfo = await _accountDomainService.GetDailyTaskStatus(); - await _videoDomainService.WatchAndShareVideo(dailyTaskInfo); - // 跳转到未兑换,执行兑换任务 - goto case 0; - - case 1: - _logger.LogInformation("大会员经验已兑换"); - break; - - case 0: - _logger.LogInformation("大会员经验未兑换"); - //兑换api - var response = await _vipApi.ObtainVipExperienceAsync(new VipExperienceRequest() - { - csrf = _biliCookie.BiliJct - }); - if (response.Code != 0) - { - _logger.LogInformation("大会员经验领取失败,错误信息:{message}", response.Message); - break; - } - - _logger.LogInformation("领取成功,经验+10 √"); - break; - - default: - _logger.LogDebug("大会员经验领取失败,未知错误"); - break; - } - } - } - - [TaskInterceptor("大会员大积分", TaskLevel.One)] - public override async Task DoTaskAsync(CancellationToken cancellationToken) + public override async Task DoTaskAsync(CancellationToken cancellationToken = default) { // TODO 解决taskInfo在一个任务出错后,后续的任务均会报空引用错误 var ui = await GetUserInfo(); @@ -157,6 +102,55 @@ public override async Task DoTaskAsync(CancellationToken cancellationToken) taskInfo.LogInfo(_logger); } + /// + /// 领取大会员专属经验包 + /// + public async Task VipExpress() + { + _logger.LogInformation("大会员经验领取任务开始"); + var re = await _vipApi.GetVouchersInfoAsync(); + if (re.Code == 0) + { + var state = re.Data.List.Find(x => x.Type == 9).State; + + switch (state) + { + case 2: + _logger.LogInformation("大会员经验观看任务未完成"); + _logger.LogInformation("开始观看视频"); + // 观看视频,暂时没有好办法解决,先这样使着 + DailyTaskInfo dailyTaskInfo = await _accountDomainService.GetDailyTaskStatus(); + await _videoDomainService.WatchAndShareVideo(dailyTaskInfo); + // 跳转到未兑换,执行兑换任务 + goto case 0; + + case 1: + _logger.LogInformation("大会员经验已兑换"); + break; + + case 0: + _logger.LogInformation("大会员经验未兑换"); + //兑换api + var response = await _vipApi.ObtainVipExperienceAsync(new VipExperienceRequest() + { + csrf = _biliCookie.BiliJct + }); + if (response.Code != 0) + { + _logger.LogInformation("大会员经验领取失败,错误信息:{message}", response.Message); + break; + } + + _logger.LogInformation("领取成功,经验+10 √"); + break; + + default: + _logger.LogDebug("大会员经验领取失败,未知错误"); + break; + } + } + } + [TaskInterceptor("测试Cookie")] private async Task GetUserInfo() { @@ -195,7 +189,16 @@ private async Task Sign(VipTaskInfo info) [TaskInterceptor("福利任务", TaskLevel.Two, false)] private async Task Bonus(VipTaskInfo info) { - var bonusTask = GetTarget(info); + const string moduleCode = "福利任务"; + const string taskCode = "bonus"; + + var bonusTask = GetTarget(info, moduleCode, taskCode); + + if (bonusTask == null) + { + _logger.LogInformation("任务失效"); + return info; + } //如果状态不等于3,则做 if (bonusTask.state == 3) @@ -220,25 +223,27 @@ private async Task Bonus(VipTaskInfo info) var infoResult = await _vipApi.GetTaskListAsync(); if (infoResult.Code != 0) throw new Exception(infoResult.ToJsonStr()); info = infoResult.Data; - bonusTask = GetTarget(info); + bonusTask = GetTarget(info, moduleCode, taskCode); _logger.LogInformation("确认:{re}", bonusTask.state == 3 && bonusTask.complete_times >= 1); } return info; - - CommonTaskItem GetTarget(VipTaskInfo info) - { - return info.Task_info.Modules.First(x => x.module_title == "福利任务") - .common_task_item - .First(x => x.task_code == "bonus"); - } } [TaskInterceptor("体验任务", TaskLevel.Two, false)] private async Task Privilege(VipTaskInfo info) { - var privilegeTask = GetTarget(info); + const string moduleCode = "体验任务"; + const string taskCode = "privilege"; + + var privilegeTask = GetTarget(info, moduleCode, taskCode); + + if (privilegeTask == null) + { + _logger.LogInformation("任务失效"); + return info; + } //如果状态不等于3,则做 if (privilegeTask.state == 3) @@ -263,27 +268,29 @@ private async Task Privilege(VipTaskInfo info) var infoResult = await _vipApi.GetTaskListAsync(); if (infoResult.Code != 0) throw new Exception(infoResult.ToJsonStr()); info = infoResult.Data; - privilegeTask = GetTarget(info); + privilegeTask = GetTarget(info, moduleCode, taskCode); _logger.LogInformation("确认:{re}", privilegeTask.state == 3 && privilegeTask.complete_times >= 1); } - CommonTaskItem GetTarget(VipTaskInfo info) - { - return info.Task_info.Modules.First(x => x.module_title == "体验任务") - .common_task_item - .First(x => x.task_code == "privilege"); - } - return info; } [TaskInterceptor("浏览追番频道页10秒", TaskLevel.Two, false)] private async Task ViewAnimate(VipTaskInfo info) { + const string moduleCode = "日常任务"; + const string taskCode = "animatetab"; + var code = "jp_channel"; - CommonTaskItem targetTask = GetTarget(info); + CommonTaskItem targetTask = GetTarget(info, moduleCode, taskCode); + + if (targetTask == null) + { + _logger.LogInformation("任务失效"); + return info; + } //如果状态不等于3,则做 if (targetTask.state == 3) @@ -308,25 +315,27 @@ private async Task ViewAnimate(VipTaskInfo info) var infoResult = await _vipApi.GetTaskListAsync(); if (infoResult.Code != 0) throw new Exception(infoResult.ToJsonStr()); info = infoResult.Data; - targetTask = GetTarget(info); + targetTask = GetTarget(info, moduleCode, taskCode); _logger.LogInformation("确认:{re}", targetTask.state == 3 && targetTask.complete_times >= 1); } - CommonTaskItem GetTarget(VipTaskInfo info) - { - return info.Task_info.Modules.First(x => x.module_title == "日常任务") - .common_task_item - .First(x => x.task_code == "animatetab"); - } - return info; } [TaskInterceptor("浏览会员购页面10秒", TaskLevel.Two, false)] private async Task ViewVipMall(VipTaskInfo info) { - CommonTaskItem targetTask = GetTarget(info); + const string moduleCode = "日常任务"; + const string taskCode = "vipmallview"; + + CommonTaskItem targetTask = GetTarget(info, moduleCode, taskCode); + + if (targetTask == null) + { + _logger.LogInformation("任务失效"); + return info; + } //如果状态不等于3,则做 if (targetTask.state == 3) @@ -355,25 +364,27 @@ private async Task ViewVipMall(VipTaskInfo info) var infoResult = await _vipApi.GetTaskListAsync(); if (infoResult.Code != 0) throw new Exception(infoResult.ToJsonStr()); info = infoResult.Data; - targetTask = GetTarget(info); + targetTask = GetTarget(info, moduleCode, taskCode); _logger.LogInformation("确认:{re}", targetTask.state == 3 && targetTask.complete_times >= 1); } - CommonTaskItem GetTarget(VipTaskInfo info) - { - return info.Task_info.Modules.First(x => x.module_title == "日常任务") - .common_task_item - .First(x => x.task_code == "vipmallview"); - } - return info; } [TaskInterceptor("观看剧集内容", TaskLevel.Two, false)] private async Task ViewVideo(VipTaskInfo info) { - CommonTaskItem targetTask = GetTarget(info); + const string moduleCode = "日常任务"; + const string taskCode = "ogvwatchnew"; + + CommonTaskItem targetTask = GetTarget(info, moduleCode, taskCode); + + if (targetTask == null) + { + _logger.LogInformation("任务失效"); + return info; + } // 如果状态不等于3,则做 if (targetTask.state == 3) @@ -394,20 +405,22 @@ private async Task ViewVideo(VipTaskInfo info) // 观看剧集内容 _logger.LogInformation("api变更,暂未实现"); - CommonTaskItem GetTarget(VipTaskInfo info) - { - return info.Task_info.Modules.First(x => x.module_title == "日常任务") - .common_task_item - .First(x => x.task_code == "ogvwatchnew"); - } - return info; } [TaskInterceptor("购买单点付费影片(仅领取)", TaskLevel.Two, false)] private async Task BuyVipVideo(VipTaskInfo info) { - CommonTaskItem targetTask = GetTarget(info); + const string moduleCode = "日常任务"; + const string taskCode = "tvodbuy"; + + CommonTaskItem targetTask = GetTarget(info, moduleCode, taskCode); + + if (targetTask == null) + { + _logger.LogInformation("任务失效"); + return info; + } if (targetTask.state is 3 or 1) { @@ -424,19 +437,21 @@ private async Task BuyVipVideo(VipTaskInfo info) } return info; - - CommonTaskItem GetTarget(VipTaskInfo info) - { - return info.Task_info.Modules.First(x => x.module_title == "日常任务") - .common_task_item - .First(x => x.task_code == "tvodbuy"); - } } [TaskInterceptor("购买指定会员购商品(仅领取)", TaskLevel.Two, false)] private async Task BuyVipMall(VipTaskInfo info) { - CommonTaskItem targetTask = GetTarget(info); + const string moduleCode = "日常任务"; + const string taskCode = "vipmallbuy"; + + CommonTaskItem targetTask = GetTarget(info, moduleCode, taskCode); + + if (targetTask == null) + { + _logger.LogInformation("任务失效"); + return info; + } if (targetTask.state is 3 or 1) { @@ -453,22 +468,23 @@ private async Task BuyVipMall(VipTaskInfo info) } return info; - - CommonTaskItem GetTarget(VipTaskInfo info) - { - return info.Task_info.Modules.First(x => x.module_title == "日常任务") - .common_task_item - .First(x => x.task_code == "vipmallbuy"); - } } [TaskInterceptor("浏览装扮商城主页", TaskLevel.Two, false)] private async Task ViewDressMall(VipTaskInfo info) { + const string moduleCode = "日常任务"; + const string taskCode = "dress-view"; + //var code = "dress-view"; - CommonTaskItem targetTask = GetTarget(info); + CommonTaskItem targetTask = GetTarget(info, moduleCode, taskCode); + if (targetTask == null) + { + _logger.LogInformation("任务失效"); + return info; + } //如果状态不等于3,则做 if (targetTask.state == 3) @@ -493,21 +509,23 @@ private async Task ViewDressMall(VipTaskInfo info) var infoResult = await _vipApi.GetTaskListAsync(); if (infoResult.Code != 0) throw new Exception(infoResult.ToJsonStr()); info = infoResult.Data; - targetTask = GetTarget(info); + targetTask = GetTarget(info, moduleCode, taskCode); _logger.LogInformation("确认:{re}", targetTask.state == 3 && targetTask.complete_times >= 1); } - CommonTaskItem GetTarget(VipTaskInfo info) - { - return info.Task_info.Modules.First(x => x.module_title == "日常任务") - .common_task_item - .First(x => x.task_code == "dress-view"); - } - return info; } + #region private + + private static CommonTaskItem GetTarget(VipTaskInfo info, string moduleCode, string taskCode) + { + var module = info.Task_info.Modules.FirstOrDefault(x => x.module_title == moduleCode); + return module? + .common_task_item + .FirstOrDefault(x => x.task_code == taskCode); + } /// /// 领取任务 @@ -548,7 +566,6 @@ private async Task Complete(string taskCode) } } - private async Task CompleteV2(string taskCode) { var request = new ReceiveOrCompleteTaskRequest(taskCode); @@ -665,4 +682,6 @@ public async Task WatchBangumi() return null; } + + #endregion } diff --git a/src/Ray.BiliBiliTool.Config/Options/LiveFansMedalTaskOptions.cs b/src/Ray.BiliBiliTool.Config/Options/LiveFansMedalTaskOptions.cs index 88abea4c3..3581df1fc 100644 --- a/src/Ray.BiliBiliTool.Config/Options/LiveFansMedalTaskOptions.cs +++ b/src/Ray.BiliBiliTool.Config/Options/LiveFansMedalTaskOptions.cs @@ -35,5 +35,20 @@ public class LiveFansMedalTaskOptions //public const string UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"; public const int HeartBeatInterval = 60; + + /// + /// 点赞次数,默认值为30(用于点亮粉丝勋章) + /// + public int LikeNumber { get; set; } = 30; + + /// + /// 发送弹幕次数 + /// + public int SendDanmakuNumber { get; set; } = 1; + + /// + /// 弹幕发送失败多少次时放弃 + /// + public int SendDanmakugiveUpThreshold { get; set; } = 3; } -} +} \ No newline at end of file diff --git a/src/Ray.BiliBiliTool.DomainService/LiveDomainService.cs b/src/Ray.BiliBiliTool.DomainService/LiveDomainService.cs index 7acdc3ec3..93e438fff 100644 --- a/src/Ray.BiliBiliTool.DomainService/LiveDomainService.cs +++ b/src/Ray.BiliBiliTool.DomainService/LiveDomainService.cs @@ -15,416 +15,425 @@ using Ray.BiliBiliTool.Config.Options; using Ray.BiliBiliTool.DomainService.Dtos; using Ray.BiliBiliTool.DomainService.Interfaces; -using Ray.BiliBiliTool.Infrastructure.Cookie; -namespace Ray.BiliBiliTool.DomainService +namespace Ray.BiliBiliTool.DomainService; + +/// +/// 直播 +/// +public class LiveDomainService : ILiveDomainService { + private readonly ILogger _logger; + private readonly ILiveApi _liveApi; + private readonly IRelationApi _relationApi; + private readonly ILiveTraceApi _liveTraceApi; + private readonly IUserInfoApi _userInfoApi; + private readonly LiveLotteryTaskOptions _liveLotteryTaskOptions; + private readonly LiveFansMedalTaskOptions _liveFansMedalTaskOptions; + private readonly DailyTaskOptions _dailyTaskOptions; + private readonly SecurityOptions _securityOptions; + private readonly BiliCookie _biliCookie; + private readonly IWbiService _wbiService; + + public LiveDomainService(ILogger logger, + ILiveApi liveApi, + IRelationApi relationApi, + ILiveTraceApi liveTraceApi, + IUserInfoApi userInfoApi, + IOptionsMonitor dailyTaskOptions, + IOptionsMonitor liveLotteryTaskOptions, + IOptionsMonitor liveFansMedalTaskOptions, + IOptionsMonitor securityOptions, + IWbiService wbiService, + BiliCookie biliCookie) + { + _logger = logger; + _liveApi = liveApi; + _relationApi = relationApi; + _liveTraceApi = liveTraceApi; + _userInfoApi = userInfoApi; + _liveLotteryTaskOptions = liveLotteryTaskOptions.CurrentValue; + _dailyTaskOptions = dailyTaskOptions.CurrentValue; + _liveFansMedalTaskOptions = liveFansMedalTaskOptions.CurrentValue; + _securityOptions = securityOptions.CurrentValue; + _wbiService = wbiService; + _biliCookie = biliCookie; + } + /// - /// 直播 + /// 本次通过天选关注的主播 /// - public class LiveDomainService : ILiveDomainService + private List _tianXuanFollowed = new(); + + /// + /// 开始抽奖前最后一个关注的up + /// + private long _lastFollowUpId; + + /// + /// 直播签到 + /// + public async Task LiveSign() { - private readonly ILogger _logger; - private readonly ILiveApi _liveApi; - private readonly IRelationApi _relationApi; - private readonly ILiveTraceApi _liveTraceApi; - private readonly IUserInfoApi _userInfoApi; - private readonly LiveLotteryTaskOptions _liveLotteryTaskOptions; - private readonly LiveFansMedalTaskOptions _liveFansMedalTaskOptions; - private readonly DailyTaskOptions _dailyTaskOptions; - private readonly SecurityOptions _securityOptions; - private readonly BiliCookie _biliCookie; - private readonly IWbiService _wbiService; - - public LiveDomainService(ILogger logger, - ILiveApi liveApi, - IRelationApi relationApi, - ILiveTraceApi liveTraceApi, - IUserInfoApi userInfoApi, - IOptionsMonitor dailyTaskOptions, - IOptionsMonitor liveLotteryTaskOptions, - IOptionsMonitor liveFansMedalTaskOptions, - IOptionsMonitor securityOptions, - IWbiService wbiService, - BiliCookie biliCookie) + var response = await _liveApi.Sign(); + + if (response.Code == 0) { - _logger = logger; - _liveApi = liveApi; - _relationApi = relationApi; - _liveTraceApi = liveTraceApi; - _userInfoApi = userInfoApi; - _liveLotteryTaskOptions = liveLotteryTaskOptions.CurrentValue; - _dailyTaskOptions = dailyTaskOptions.CurrentValue; - _liveFansMedalTaskOptions = liveFansMedalTaskOptions.CurrentValue; - _securityOptions = securityOptions.CurrentValue; - _wbiService = wbiService; - _biliCookie = biliCookie; + _logger.LogInformation("【签到结果】成功"); + _logger.LogInformation("【本次获取】{text},{special}", response.Data.Text, response.Data.SpecialText); + } + else + { + _logger.LogInformation("【签到结果】失败"); + _logger.LogInformation("【原因】{msg}", response.Message); + } + } + /// + /// 直播中心银瓜子兑换B币 + /// + /// 兑换银瓜子后硬币余额 + public async Task ExchangeSilver2Coin() + { + var result = false; + + if (_dailyTaskOptions.DayOfExchangeSilver2Coin == 0) + { + _logger.LogInformation("已配置为关闭,跳过"); + return false; } - /// - /// 本次通过天选关注的主播 - /// - private List _tianXuanFollowed = new(); + int targetDay = _dailyTaskOptions.DayOfExchangeSilver2Coin == -2 + ? DateTime.Today.Day + : _dailyTaskOptions.DayOfExchangeSilver2Coin == -1 + ? DateTime.Today.LastDayOfMonth().Day + : _dailyTaskOptions.DayOfExchangeSilver2Coin; - /// - /// 开始抽奖前最后一个关注的up - /// - private long _lastFollowUpId; + _logger.LogInformation("【目标兑换日期】{targetDay}号", targetDay); + _logger.LogInformation("【今天】{day}号", DateTime.Today.Day); - /// - /// 直播签到 - /// - public async Task LiveSign() + if (DateTime.Today.Day != targetDay) { - var response = await _liveApi.Sign(); - - if (response.Code == 0) - { - _logger.LogInformation("【签到结果】成功"); - _logger.LogInformation("【本次获取】{text},{special}", response.Data.Text, response.Data.SpecialText); - } - else - { - _logger.LogInformation("【签到结果】失败"); - _logger.LogInformation("【原因】{msg}", response.Message); - } + _logger.LogInformation("跳过"); + return false; } - /// - /// 直播中心银瓜子兑换B币 - /// - /// 兑换银瓜子后硬币余额 - public async Task ExchangeSilver2Coin() + BiliApiResponse queryStatus = await _liveApi.GetLiveWalletStatus(); + _logger.LogInformation("【银瓜子余额】 {silver}", queryStatus.Data.Silver); + _logger.LogInformation("【硬币余额】 {coin}", queryStatus.Data.Coin); + _logger.LogInformation("【今日剩余兑换次数】 {left}", queryStatus.Data.Silver_2_coin_left); + + if (queryStatus.Data.Silver_2_coin_left <= 0) return false; + + _logger.LogInformation("开始尝试兑换..."); + Silver2CoinRequest request = new(_biliCookie.BiliJct); + var response = await _liveApi.Silver2Coin(request); + if (response.Code == 0) + { + result = true; + _logger.LogInformation("【兑换结果】成功兑换 {coin} 枚硬币", response.Data.Coin); + _logger.LogInformation("【银瓜子余额】 {silver}", response.Data.Silver); + } + else { - var result = false; + _logger.LogInformation("【兑换结果】失败"); + _logger.LogInformation("【原因】{reason}", response.Message); + } - if (_dailyTaskOptions.DayOfExchangeSilver2Coin == 0) - { - _logger.LogInformation("已配置为关闭,跳过"); - return false; - } + return result; + } - int targetDay = _dailyTaskOptions.DayOfExchangeSilver2Coin == -2 - ? DateTime.Today.Day - : _dailyTaskOptions.DayOfExchangeSilver2Coin == -1 - ? DateTime.Today.LastDayOfMonth().Day - : _dailyTaskOptions.DayOfExchangeSilver2Coin; + #region 天选时刻抽奖 - _logger.LogInformation("【目标兑换日期】{targetDay}号", targetDay); - _logger.LogInformation("【今天】{day}号", DateTime.Today.Day); + /// + /// 天选抽奖 + /// + public async Task TianXuan() + { + _tianXuanFollowed = new List(); - if (DateTime.Today.Day != targetDay) - { - _logger.LogInformation("跳过"); - return false; - } + if (_liveLotteryTaskOptions.AutoGroupFollowings) + { + //获取此时最后一个关注的up,此后再新增的关注,与参与成功的抽奖,取交集,就是本地新增的天选关注 + _lastFollowUpId = await GetLastFollowUpId(); + } - BiliApiResponse queryStatus = await _liveApi.GetLiveWalletStatus(); - _logger.LogInformation("【银瓜子余额】 {silver}", queryStatus.Data.Silver); - _logger.LogInformation("【硬币余额】 {coin}", queryStatus.Data.Coin); - _logger.LogInformation("【今日剩余兑换次数】 {left}", queryStatus.Data.Silver_2_coin_left); + //获取直播的分区 + List areaList = (await _liveApi.GetAreaList()).Data.Data; - if (queryStatus.Data.Silver_2_coin_left <= 0) return false; + //遍历分区 + int count = 0; + foreach (var area in areaList) + { + _logger.LogInformation("【扫描分区】{area}...{newLine}", area.Name, Environment.NewLine); - _logger.LogInformation("开始尝试兑换..."); - Silver2CoinRequest request = new(_biliCookie.BiliJct); - var response = await _liveApi.Silver2Coin(request); - if (response.Code == 0) - { - result = true; - _logger.LogInformation("【兑换结果】成功兑换 {coin} 枚硬币", response.Data.Coin); - _logger.LogInformation("【银瓜子余额】 {silver}", response.Data.Silver); - } - else + string defaultSort = ""; + //每个分区下搜索5页 + for (int i = 1; i < 6; i++) { - _logger.LogInformation("【兑换结果】失败"); - _logger.LogInformation("【原因】{reason}", response.Message); + var reData = (await _liveApi.GetList(area.Id, i, sortType: defaultSort)).Data; + foreach (var item in reData.List ?? new List()) + { + if (item.Pendant_info == null || item.Pendant_info.Count == 0) continue; + var suc = item.Pendant_info.TryGetValue("2", out var pendant); + if (!suc) continue; + if (pendant.Pendent_id != 504) continue; + count++; + + await TryJoinTianXuan(item); + } + + if (reData.Has_more != 1) break; + defaultSort = reData.New_tags.FirstOrDefault()?.Sort_type ?? ""; } - return result; + defaultSort = ""; } - #region 天选时刻抽奖 - /// - /// 天选抽奖 - /// - public async Task TianXuan() + if (count == 0) { - _tianXuanFollowed = new List(); + _logger.LogInformation("未搜索到直播间"); + return; + } + } - if (_liveLotteryTaskOptions.AutoGroupFollowings) + public async Task TryJoinTianXuan(ListItemDto target) + { + _logger.LogDebug("【房间】{name}", target.Title); + try + { + //黑名单 + if (_liveLotteryTaskOptions.DenyUidList.Contains(target.Uid.ToString())) { - //获取此时最后一个关注的up,此后再新增的关注,与参与成功的抽奖,取交集,就是本地新增的天选关注 - _lastFollowUpId = await GetLastFollowUpId(); + _logger.LogDebug("黑名单,跳过"); + return; } - //获取直播的分区 - List areaList = (await _liveApi.GetAreaList()).Data.Data; + CheckTianXuanDto check = (await _liveApi.CheckTianXuan(target.Roomid)).Data; - //遍历分区 - int count = 0; - foreach (var area in areaList) + if (check == null) { - _logger.LogInformation("【扫描分区】{area}...{newLine}", area.Name, Environment.NewLine); - - string defaultSort = ""; - //每个分区下搜索5页 - for (int i = 1; i < 6; i++) - { - var reData = (await _liveApi.GetList(area.Id, i, sortType: defaultSort)).Data; - foreach (var item in reData.List ?? new List()) - { - if (item.Pendant_info == null || item.Pendant_info.Count == 0) continue; - var suc = item.Pendant_info.TryGetValue("2", out var pendant); - if (!suc) continue; - if (pendant.Pendent_id != 504) continue; - count++; - - await TryJoinTianXuan(item); - } - if (reData.Has_more != 1) break; - defaultSort = reData.New_tags.FirstOrDefault()?.Sort_type ?? ""; - } - defaultSort = ""; + _logger.LogDebug("数据异常,跳过"); + return; } - if (count == 0) + if (check.Status != TianXuanStatus.Enable) { - _logger.LogInformation("未搜索到直播间"); + _logger.LogDebug("已开奖,跳过{newLine}", Environment.NewLine); return; } - } - public async Task TryJoinTianXuan(ListItemDto target) - { - _logger.LogDebug("【房间】{name}", target.Title); - try + //根据配置过滤 + if (!check.AwardNameIsSatisfied(_liveLotteryTaskOptions.IncludeAwardNameList, + _liveLotteryTaskOptions.ExcludeAwardNameList)) { - //黑名单 - if (_liveLotteryTaskOptions.DenyUidList.Contains(target.Uid.ToString())) - { - _logger.LogDebug("黑名单,跳过"); - return; - } - - CheckTianXuanDto check = (await _liveApi.CheckTianXuan(target.Roomid)).Data; - - if (check == null) - { - _logger.LogDebug("数据异常,跳过"); - return; - } - - if (check.Status != TianXuanStatus.Enable) - { - _logger.LogDebug("已开奖,跳过{newLine}", Environment.NewLine); - return; - } - - //根据配置过滤 - if (!check.AwardNameIsSatisfied(_liveLotteryTaskOptions.IncludeAwardNameList, _liveLotteryTaskOptions.ExcludeAwardNameList)) - { - _logger.LogDebug("不满足配置的筛选条件,跳过{newLine}", Environment.NewLine); - return; - } - - //是否需要赠礼 - if (check.Gift_price > 0) - { - _logger.LogDebug("【赠礼】{gift}", check.GiftDesc); - _logger.LogDebug("需赠送礼物,跳过{newLine}", Environment.NewLine); - return; - } - - //条件 - if (check.Require_type != RequireType.None && check.Require_type != RequireType.Follow) - { - _logger.LogDebug("【条件】{text}", check.Require_text); - _logger.LogDebug("要求粉丝勋章,跳过"); - return; - } - - _logger.LogInformation("【房间】{name}", target.ShortTitle); - _logger.LogInformation("【主播】{name}({id})", target.Uname, target.Uid); - _logger.LogInformation("【奖品】{name}【条件】{text}", check.Award_name, check.Require_text); - - var request = new JoinTianXuanRequest - { - Id = check.Id, - Gift_id = check.Gift_id, - Gift_num = check.Gift_num, - Csrf = _biliCookie.BiliJct - }; - var re = await _liveApi.Join(request); - if (re.Code == 0) - { - _logger.LogInformation("【抽奖】成功 √{newLine}", Environment.NewLine); - if (check.Require_type == RequireType.Follow) - _tianXuanFollowed.AddIfNotExist(target, x => x.Uid == target.Uid); - return; - } - - _logger.LogInformation("【抽奖】失败"); - _logger.LogInformation("【原因】{msg}{newLine}", re.Message, Environment.NewLine); - } - catch (Exception ex) - { - _logger.LogWarning("【异常】{msg},{detail}{newLine}", ex.Message, ex, Environment.NewLine); - //ignore + _logger.LogDebug("不满足配置的筛选条件,跳过{newLine}", Environment.NewLine); + return; } - } - /// - /// 将本次抽奖新增的关注统一转移到指定分组中 - /// - public async Task GroupFollowing() - { - if (!_tianXuanFollowed.Any()) + //是否需要赠礼 + if (check.Gift_price > 0) { - _logger.LogInformation("未关注主播"); + _logger.LogDebug("【赠礼】{gift}", check.GiftDesc); + _logger.LogDebug("需赠送礼物,跳过{newLine}", Environment.NewLine); return; } - _logger.LogInformation("【抽奖的主播】{ups}", - string.Join(",", _tianXuanFollowed.Select(x => x.Uname))); - - //目标分组up集合 - List targetUps = await GetNeedGroup(); - _logger.LogInformation("【将自动分组】{ups}", - string.Join(",", targetUps.Select(x => x.Uname))); - if (!targetUps.Any()) + //条件 + if (check.Require_type != RequireType.None && check.Require_type != RequireType.Follow) { + _logger.LogDebug("【条件】{text}", check.Require_text); + _logger.LogDebug("要求粉丝勋章,跳过"); return; } - //目标分组Id - long targetGroupId = await GetOrCreateTianXuanGroupId(); + _logger.LogInformation("【房间】{name}", target.ShortTitle); + _logger.LogInformation("【主播】{name}({id})", target.Uname, target.Uid); + _logger.LogInformation("【奖品】{name}【条件】{text}", check.Award_name, check.Require_text); - //执行批量分组 - var referer = string.Format(RelationApiConstant.CopyReferer, _biliCookie.UserId); - var req = new CopyUserToGroupRequest( - targetUps.Select(x => x.Uid).ToList(), - targetGroupId.ToString(), - _biliCookie.BiliJct); - var re = await _relationApi.CopyUpsToGroup(req, referer); - - if (re.Code == 0) + var request = new JoinTianXuanRequest { - _logger.LogInformation("【分组结果】全部成功"); - } - else + Id = check.Id, + Gift_id = check.Gift_id, + Gift_num = check.Gift_num, + Csrf = _biliCookie.BiliJct + }; + var re = await _liveApi.Join(request); + if (re.Code == 0) { - _logger.LogWarning("【分组结果】失败"); - _logger.LogWarning("【原因】{msg}", re.Message); + _logger.LogInformation("【抽奖】成功 √{newLine}", Environment.NewLine); + if (check.Require_type == RequireType.Follow) + _tianXuanFollowed.AddIfNotExist(target, x => x.Uid == target.Uid); + return; } + + _logger.LogInformation("【抽奖】失败"); + _logger.LogInformation("【原因】{msg}{newLine}", re.Message, Environment.NewLine); + } + catch (Exception ex) + { + _logger.LogWarning("【异常】{msg},{detail}{newLine}", ex.Message, ex, Environment.NewLine); + //ignore } + } + /// + /// 将本次抽奖新增的关注统一转移到指定分组中 + /// + public async Task GroupFollowing() + { + if (!_tianXuanFollowed.Any()) + { + _logger.LogInformation("未关注主播"); + return; + } + _logger.LogInformation("【抽奖的主播】{ups}", + string.Join(",", _tianXuanFollowed.Select(x => x.Uname))); - /// - /// 获取抽奖前最后一个关注的up - /// - /// - private async Task GetLastFollowUpId() + //目标分组up集合 + List targetUps = await GetNeedGroup(); + _logger.LogInformation("【将自动分组】{ups}", + string.Join(",", targetUps.Select(x => x.Uname))); + + if (!targetUps.Any()) { - var followings = await _relationApi - .GetFollowings(new GetFollowingsRequest(long.Parse(_biliCookie.UserId), FollowingsOrderType.TimeDesc)); - return followings.Data.List.FirstOrDefault()?.Mid ?? 0; + return; } - /// - /// 获取本次需要自动分组的主播 - /// - /// - private async Task> GetNeedGroup() + //目标分组Id + long targetGroupId = await GetOrCreateTianXuanGroupId(); + + //执行批量分组 + var referer = string.Format(RelationApiConstant.CopyReferer, _biliCookie.UserId); + var req = new CopyUserToGroupRequest( + targetUps.Select(x => x.Uid).ToList(), + targetGroupId.ToString(), + _biliCookie.BiliJct); + var re = await _relationApi.CopyUpsToGroup(req, referer); + + if (re.Code == 0) + { + _logger.LogInformation("【分组结果】全部成功"); + } + else { - List addUpIds = new(); + _logger.LogWarning("【分组结果】失败"); + _logger.LogWarning("【原因】{msg}", re.Message); + } + } - //获取最后一个upId之后关注的所有upId - var followings = await _relationApi - .GetFollowings(new GetFollowingsRequest(long.Parse(_biliCookie.UserId), FollowingsOrderType.TimeDesc)); - foreach (UpInfo item in followings.Data.List) - { - if (item.Mid == _lastFollowUpId) - { - break; - } + /// + /// 获取抽奖前最后一个关注的up + /// + /// + private async Task GetLastFollowUpId() + { + var followings = await _relationApi + .GetFollowings(new GetFollowingsRequest(long.Parse(_biliCookie.UserId), FollowingsOrderType.TimeDesc)); + return followings.Data.List.FirstOrDefault()?.Mid ?? 0; + } - addUpIds.Add(item.Mid); - } + /// + /// 获取本次需要自动分组的主播 + /// + /// + private async Task> GetNeedGroup() + { + List addUpIds = new(); - //和成功抽奖的主播取交集 - List target = new(); - foreach (var listItemDto in _tianXuanFollowed) + //获取最后一个upId之后关注的所有upId + var followings = await _relationApi + .GetFollowings(new GetFollowingsRequest(long.Parse(_biliCookie.UserId), FollowingsOrderType.TimeDesc)); + + foreach (UpInfo item in followings.Data.List) + { + if (item.Mid == _lastFollowUpId) { - if (addUpIds.Contains(listItemDto.Uid)) - target.Add(listItemDto); + break; } - return target; + addUpIds.Add(item.Mid); } - /// - /// 获取或创建天选时刻分组 - /// - /// - private async Task GetOrCreateTianXuanGroupId() + //和成功抽奖的主播取交集 + List target = new(); + foreach (var listItemDto in _tianXuanFollowed) { - //获取天选分组Id,没有就创建 - long groupId = 0; - string referer = string.Format(RelationApiConstant.GetTagsReferer, _biliCookie.UserId); - var groups = await _relationApi.GetTags(referer); - var tianXuanGroup = groups.Data.FirstOrDefault(x => x.Name == "天选时刻"); - if (tianXuanGroup == null) - { - _logger.LogInformation("“天选时刻”分组不存在,尝试创建..."); - //创建一个 - var createRe = await _relationApi.CreateTag(new CreateTagRequest { Tag = "天选时刻", Csrf = _biliCookie.BiliJct }); - groupId = createRe.Data.Tagid; - _logger.LogInformation("创建成功"); - } - else - { - _logger.LogInformation("“天选时刻”分组已存在"); - groupId = tianXuanGroup.Tagid; - } + if (addUpIds.Contains(listItemDto.Uid)) + target.Add(listItemDto); + } + + return target; + } - return groupId; + /// + /// 获取或创建天选时刻分组 + /// + /// + private async Task GetOrCreateTianXuanGroupId() + { + //获取天选分组Id,没有就创建 + long groupId = 0; + string referer = string.Format(RelationApiConstant.GetTagsReferer, _biliCookie.UserId); + var groups = await _relationApi.GetTags(referer); + var tianXuanGroup = groups.Data.FirstOrDefault(x => x.Name == "天选时刻"); + if (tianXuanGroup == null) + { + _logger.LogInformation("“天选时刻”分组不存在,尝试创建..."); + //创建一个 + var createRe = + await _relationApi.CreateTag(new CreateTagRequest { Tag = "天选时刻", Csrf = _biliCookie.BiliJct }); + groupId = createRe.Data.Tagid; + _logger.LogInformation("创建成功"); + } + else + { + _logger.LogInformation("“天选时刻”分组已存在"); + groupId = tianXuanGroup.Tagid; } - #endregion - public async Task SendDanmakuToFansMedalLive() + return groupId; + } + + #endregion + + public async Task SendDanmakuToFansMedalLive() + { + if (!await CheckLiveCookie()) return; + + var infoList = await GetFansMedalInfoList(); + + foreach (var info in infoList) { - if (!await CheckLiveCookie()) return; + var medal = info.MedalInfo; - (await GetFansMedalInfoList()).ForEach(async info => - { - var medal = info.MedalInfo; + _logger.LogInformation("【直播间】{liveRoomName}", medal.Target_name); + _logger.LogInformation("【粉丝牌】{medalName}", medal.Medal_info.Medal_name); + _logger.LogInformation("正在发送弹幕..."); - _logger.LogInformation("【直播间】{liveRoomName}", medal.Target_name); - _logger.LogInformation("【粉丝牌】{medalName}", medal.Medal_info.Medal_name); + // 通过空间主页信息获取直播间 id + var liveHostUserId = medal.Medal_info.Target_id; + var req = new GetSpaceInfoDto() { mid = liveHostUserId }; + await _wbiService.SetWridAsync(req); - _logger.LogInformation("正在发送弹幕..."); + var spaceInfo = await _userInfoApi.GetSpaceInfo(req); + if (spaceInfo.Code != 0) + { + _logger.LogError("【获取直播间信息】失败"); + _logger.LogError("【原因】{message}", spaceInfo.Message); + return; + } - // 通过空间主页信息获取直播间 id - var liveHostUserId = medal.Medal_info.Target_id; - var req = new GetSpaceInfoDto() - { - mid = liveHostUserId - }; - await _wbiService.SetWridAsync(req); + var successCount = 0; + var failedCount = 0; - var spaceInfo = await _userInfoApi.GetSpaceInfo(req); - if (spaceInfo.Code != 0) - { - _logger.LogError("【获取直播间信息】失败"); - _logger.LogError("【原因】{message}", spaceInfo.Message); - return; - } + // 发送弹幕 - // 发送弹幕 + while (successCount < _liveFansMedalTaskOptions.SendDanmakuNumber && + failedCount < _liveFansMedalTaskOptions.SendDanmakugiveUpThreshold) + { var sendResult = await _liveApi.SendLiveDanmuku(new SendLiveDanmukuRequest( _biliCookie.BiliJct, spaceInfo.Data.Live_room.Roomid, @@ -434,234 +443,256 @@ public async Task SendDanmakuToFansMedalLive() { _logger.LogError("【弹幕发送】失败"); _logger.LogError("【原因】{message}", sendResult.Message); - return; + failedCount++; } + else + successCount++; - _logger.LogInformation("【弹幕发送】成功~,你和主播 {name} 的亲密值增加了100!", spaceInfo.Data.Name); - }); + var delay = new Random().Next(2000, 4000); + await Task.Delay(delay); + } + + + _logger.LogInformation("【弹幕发送】发送情况:你向主播 {name} 发送弹幕{success}/{total}", spaceInfo.Data.Name, + successCount, successCount + failedCount); } + } - public async Task SendHeartBeatToFansMedalLive() - { - if (!await CheckLiveCookie()) return; + public async Task SendHeartBeatToFansMedalLive() + { + if (!await CheckLiveCookie()) return; - var infoList = new List(); - (await GetFansMedalInfoList()).ForEach(medal => - infoList.Add(new(medal.RoomId, medal.LiveRoomInfo, new(), 0, 0)) - ); + var infoList = new List(); + (await GetFansMedalInfoList()).FindAll(info => info.LiveRoomInfo.Live_Status != 0).ForEach(medal => + infoList.Add(new(medal.RoomId, medal.LiveRoomInfo, new(), 0, 0)) + ); - if (infoList.Count == 0) - { - _logger.LogInformation("【直播观看时长】跳过,未检测到符合条件的主播"); - return; - } + if (infoList.Count == 0) + { + _logger.LogInformation("【直播观看时长】跳过,未检测到符合条件的主播"); + return; + } - var Now = () => new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds(); + var Now = () => new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds(); - while (infoList.Min( - info => info.FailedTimes >= _liveFansMedalTaskOptions.HeartBeatSendGiveUpThreshold - ? int.MaxValue : - info.HeartBeatCount) - < _liveFansMedalTaskOptions.HeartBeatNumber) + while (infoList.Min( + info => info.FailedTimes >= _liveFansMedalTaskOptions.HeartBeatSendGiveUpThreshold + ? int.MaxValue + : info.HeartBeatCount) + < _liveFansMedalTaskOptions.HeartBeatNumber) + { + foreach (var info in infoList) { - foreach (var info in infoList) + // 忽略连续失败超过上限的直播间 + if (info.FailedTimes >= _liveFansMedalTaskOptions.HeartBeatSendGiveUpThreshold) continue; + + string uuid = Guid.NewGuid().ToString(); + var current = Now(); + if (current - info.LastBeatTime <= (LiveFansMedalTaskOptions.HeartBeatInterval + 5) * 1000) { - // 忽略连续失败超过上限的直播间 - if (info.FailedTimes >= _liveFansMedalTaskOptions.HeartBeatSendGiveUpThreshold) continue; - - string uuid = Guid.NewGuid().ToString(); - var current = Now(); - if (current - info.LastBeatTime <= (LiveFansMedalTaskOptions.HeartBeatInterval + 5) * 1000) - { - int sleepTime = (int)((LiveFansMedalTaskOptions.HeartBeatInterval + 5) * 1000 - (current - info.LastBeatTime)); - _logger.LogDebug("【休眠】{time} 毫秒", sleepTime); - Thread.Sleep(sleepTime); - } - - // Heart Beat 接口 - var timestamp = Now(); - BiliApiResponse heartBeatResult = null; - if (info.HeartBeatCount == 0) - { - heartBeatResult = await _liveTraceApi.EnterRoom( - new EnterRoomRequest( - info.RoomId, - info.RoomInfo.Parent_area_id, - info.RoomInfo.Area_id, - info.HeartBeatCount, - timestamp, - _securityOptions.UserAgent, - _biliCookie.BiliJct, - info.RoomInfo.Uid, - $"[\"{_biliCookie.LiveBuvid}\",\"{uuid}\"]") - ); - } - else - { - heartBeatResult = await _liveTraceApi.HeartBeat( - new HeartBeatRequest( - info.RoomId, - info.RoomInfo.Parent_area_id, - info.RoomInfo.Area_id, - info.HeartBeatCount, - _biliCookie.LiveBuvid, - timestamp, - info.HeartBeatInfo.Timestamp, - _securityOptions.UserAgent, - info.HeartBeatInfo.Secret_rule, - info.HeartBeatInfo.Secret_key, - _biliCookie.BiliJct, - uuid, - $"[\"{_biliCookie.LiveBuvid}\",\"{uuid}\"]") - ); - } - - info.LastBeatTime = Now(); - - if (heartBeatResult != null && heartBeatResult.Data != null) - { - info.HeartBeatInfo.Secret_key = heartBeatResult.Data.Secret_key; - info.HeartBeatInfo.Secret_rule = heartBeatResult.Data.Secret_rule; - info.HeartBeatInfo.Timestamp = heartBeatResult.Data.Timestamp; - } - - if (heartBeatResult == null || heartBeatResult.Code != 0) - { - _logger.LogError("【心跳包】直播间 {room} 发送失败", info.RoomId); - _logger.LogError("【原因】{message}", heartBeatResult != null ? heartBeatResult.Message : ""); - info.FailedTimes += 1; - continue; - } - - info.HeartBeatCount += 1; - info.FailedTimes = 0; - - _logger.LogInformation("【直播间】{roomId} 的第 {index} 个心跳包发送成功", info.RoomId, info.HeartBeatCount); + int sleepTime = (int)((LiveFansMedalTaskOptions.HeartBeatInterval + 5) * 1000 - + (current - info.LastBeatTime)); + _logger.LogDebug("【休眠】{time} 毫秒", sleepTime); + Thread.Sleep(sleepTime); } - } - - var successCount = infoList.Count(info => info.HeartBeatCount >= _liveFansMedalTaskOptions.HeartBeatNumber); - _logger.LogInformation("【直播观看时长】完成情况:{success}/{total} ", successCount, infoList.Count); - } - - public async Task LikeFansMedalLive() - { - if (!await CheckLiveCookie()) return; - (await GetFansMedalInfoList()).ForEach(async info => - { - var result = await _liveApi.LikeLiveRoom(new LikeLiveRoomRequest(info.RoomId, _biliCookie.BiliJct)); - if (result.Code == 0) + // Heart Beat 接口 + var timestamp = Now(); + BiliApiResponse heartBeatResult = null; + if (info.HeartBeatCount == 0) { - _logger.LogInformation("【点赞直播间】{roomId} 完成", info.RoomId); + heartBeatResult = await _liveTraceApi.EnterRoom( + new EnterRoomRequest( + info.RoomId, + info.RoomInfo.Parent_area_id, + info.RoomInfo.Area_id, + info.HeartBeatCount, + timestamp, + _securityOptions.UserAgent, + _biliCookie.BiliJct, + info.RoomInfo.Uid, + $"[\"{_biliCookie.LiveBuvid}\",\"{uuid}\"]") + ); } else { - _logger.LogError("【点赞直播间】{roomId} 时候出现错误", info.RoomId); - _logger.LogError("【原因】{message}", result.Message); + heartBeatResult = await _liveTraceApi.HeartBeat( + new HeartBeatRequest( + info.RoomId, + info.RoomInfo.Parent_area_id, + info.RoomInfo.Area_id, + info.HeartBeatCount, + _biliCookie.LiveBuvid, + timestamp, + info.HeartBeatInfo.Timestamp, + _securityOptions.UserAgent, + info.HeartBeatInfo.Secret_rule, + info.HeartBeatInfo.Secret_key, + _biliCookie.BiliJct, + uuid, + $"[\"{_biliCookie.LiveBuvid}\",\"{uuid}\"]") + ); } - }); - } - private async Task> GetFansMedalInfoList() - { - _logger.LogInformation("【获取直播列表】获取拥有粉丝牌的直播列表"); - var medalWallInfo = await _liveApi.GetMedalWall(_biliCookie.UserId); + info.LastBeatTime = Now(); - if (medalWallInfo.Code != 0) - { - _logger.LogError("【获取直播列表】失败"); - _logger.LogError("【原因】{message}", medalWallInfo.Message); - return null; - } - - var infoList = new List(); - foreach (var medal in medalWallInfo.Data.List) - { - _logger.LogInformation("【主播】{name} ", medal.Target_name); - if (_liveFansMedalTaskOptions.IsSkipLevel20Medal && medal.Medal_info.Level >= 20) + if (heartBeatResult != null && heartBeatResult.Data != null) { - _logger.LogInformation("粉丝牌等级为 {level},观看将不再增长亲密度,跳过", medal.Medal_info.Level); - continue; + info.HeartBeatInfo.Secret_key = heartBeatResult.Data.Secret_key; + info.HeartBeatInfo.Secret_rule = heartBeatResult.Data.Secret_rule; + info.HeartBeatInfo.Timestamp = heartBeatResult.Data.Timestamp; } - // 通过空间主页信息获取直播间 id - var liveHostUserId = medal.Medal_info.Target_id; - var req = new GetSpaceInfoDto() + if (heartBeatResult == null || heartBeatResult.Code != 0) { - mid = liveHostUserId - }; - await _wbiService.SetWridAsync(req); - - var spaceInfo = await _userInfoApi.GetSpaceInfo(req); - if (spaceInfo.Code != 0) - { - _logger.LogError("【获取空间信息】失败"); - _logger.LogError("【原因】{message}", spaceInfo.Message); + _logger.LogError("【心跳包】直播间 {room} 发送失败", info.RoomId); + _logger.LogError("【原因】{message}", heartBeatResult != null ? heartBeatResult.Message : ""); + info.FailedTimes += 1; continue; } - // 用以排除有牌子无直播间的up主 - if (spaceInfo.Data.Live_room is null) - { - _logger.LogInformation("【主播】{name} 直播间id获取失败,已跳过",medal.Target_name); - continue; - } - - - var roomId = spaceInfo.Data.Live_room.Roomid; + info.HeartBeatCount += 1; + info.FailedTimes = 0; - // 获取直播间详细信息 - var liveRoomInfo = await _liveApi.GetLiveRoomInfo(roomId); - if (liveRoomInfo.Code != 0) - { - _logger.LogError("【获取直播间信息】失败"); - _logger.LogError("【原因】{message}", liveRoomInfo.Message); - continue; - } + _logger.LogInformation("【直播间】{roomId} 的第 {index} 个心跳包发送成功", info.RoomId, info.HeartBeatCount); + } + } - infoList.Add(new FansMedalInfoDto(roomId, medal, liveRoomInfo.Data)); + var successCount = infoList.Count(info => info.HeartBeatCount >= _liveFansMedalTaskOptions.HeartBeatNumber); + _logger.LogInformation("【直播观看时长】完成情况:{success}/{total} ", successCount, infoList.Count); + } + + /// + /// 点赞直播间 + /// + public async Task LikeFansMedalLive() + { + if (!await CheckLiveCookie()) return; + + var infoList = await GetFansMedalInfoList(); + infoList = infoList.FindAll(info => info.LiveRoomInfo.Live_Status != 0); + _logger.LogInformation("当前开播直播间数量:{num}", infoList.Count); + foreach (var info in infoList) + { + // Clike_Time 暂时设置为等于设置的LikeNumber,不清楚是否会被风控,我自己抓包最大值为10 + var request = new LikeLiveRoomRequest(info.RoomId, _biliCookie.BiliJct, + _liveFansMedalTaskOptions.LikeNumber, + info.LiveRoomInfo.Uid, _biliCookie.UserId); + + var result = await _liveApi.LikeLiveRoom(request.RawTextBuild()); + if (result.Code == 0) + { + _logger.LogInformation("【点赞直播间】{roomId} 完成", info.RoomId); + } + else + { + _logger.LogError("【点赞直播间】{roomId} 时候出现错误", info.RoomId); + _logger.LogError("【原因】{message}", result.Message); } - return infoList; + var delay = new Random().Next(5000, 8000); + await Task.Delay(delay); + } + } + + private async Task> GetFansMedalInfoList() + { + _logger.LogInformation("【获取直播列表】获取拥有粉丝牌的直播列表"); + var medalWallInfo = await _liveApi.GetMedalWall(_biliCookie.UserId); + + if (medalWallInfo.Code != 0) + { + _logger.LogError("【获取直播列表】失败"); + _logger.LogError("【原因】{message}", medalWallInfo.Message); + return new List(); } - /// - /// 自动配置直播相关 Cookie,来兼容较低版本中保存的 Cookie 配置 - /// - /// - /// bool 成功配置 or not - /// - private async Task CheckLiveCookie() + var infoList = new List(); + foreach (var medal in medalWallInfo.Data.List) { - // 检测 _biliCookie 是否正确配置 - if (!string.IsNullOrWhiteSpace(_biliCookie.LiveBuvid)) return true; + _logger.LogInformation("【主播】{name} ", medal.Target_name); + if (_liveFansMedalTaskOptions.IsSkipLevel20Medal && medal.Medal_info.Level >= 20) + { + _logger.LogInformation("粉丝牌等级为 {level},观看将不再增长亲密度,跳过", medal.Medal_info.Level); + continue; + } + + // 通过空间主页信息获取直播间 id + var liveHostUserId = medal.Medal_info.Target_id; + var req = new GetSpaceInfoDto() { mid = liveHostUserId }; + await _wbiService.SetWridAsync(req); - try + var spaceInfo = await _userInfoApi.GetSpaceInfo(req); + if (spaceInfo.Code != 0) { - _logger.LogInformation("检测到直播 Cookie 未正确配置,尝试自动配置中..."); + _logger.LogError("【获取空间信息】失败"); + _logger.LogError("【原因】{message}", spaceInfo.Message); + continue; + } + + // 用以排除有牌子无直播间的up主 + if (spaceInfo.Data.Live_room is null) + { + _logger.LogInformation("【主播】{name} 直播间id获取失败,已跳过", medal.Target_name); + continue; + } - // 请求主播主页来正确配置 cookie - var liveHome = await _liveApi.GetLiveHome(); - var liveHomeContent = JsonConvert.DeserializeObject(await liveHome.Content.ReadAsStringAsync()); - if (liveHomeContent.Code != 0) - { - throw new Exception(liveHomeContent.Message); - } - List liveCookies = liveHome.Headers.SingleOrDefault(header => header.Key == "Set-Cookie").Value.ToList(); - _biliCookie.MergeCurrentCookie(liveCookies); + var roomId = spaceInfo.Data.Live_room.Roomid; - _logger.LogDebug("LiveBuvid {value}", _biliCookie.LiveBuvid); - _logger.LogInformation("直播 Cookie 配置成功!"); + // 获取直播间详细信息 + var liveRoomInfo = await _liveApi.GetLiveRoomInfo(roomId); + if (liveRoomInfo.Code != 0) + { + _logger.LogError("【获取直播间信息】失败"); + _logger.LogError("【原因】{message}", liveRoomInfo.Message); + continue; } - catch (Exception exception) + + infoList.Add(new FansMedalInfoDto(roomId, medal, liveRoomInfo.Data)); + } + + return infoList; + } + + /// + /// 自动配置直播相关 Cookie,来兼容较低版本中保存的 Cookie 配置 + /// + /// + /// bool 成功配置 or not + /// + private async Task CheckLiveCookie() + { + // 检测 _biliCookie 是否正确配置 + if (!string.IsNullOrWhiteSpace(_biliCookie.LiveBuvid)) return true; + + try + { + _logger.LogInformation("检测到直播 Cookie 未正确配置,尝试自动配置中..."); + + // 请求主播主页来正确配置 cookie + var liveHome = await _liveApi.GetLiveHome(); + var liveHomeContent = + JsonConvert.DeserializeObject(await liveHome.Content.ReadAsStringAsync()); + if (liveHomeContent.Code != 0) { - _logger.LogError("【配置直播Cookie】失败,放弃执行后续任务..."); - _logger.LogError("【原因】{message}", exception.Message); - return false; + throw new Exception(liveHomeContent.Message); } - return true; + + List liveCookies = liveHome.Headers.SingleOrDefault(header => header.Key == "Set-Cookie").Value + .ToList(); + _biliCookie.MergeCurrentCookie(liveCookies); + + _logger.LogDebug("LiveBuvid {value}", _biliCookie.LiveBuvid); + _logger.LogInformation("直播 Cookie 配置成功!"); } + catch (Exception exception) + { + _logger.LogError("【配置直播Cookie】失败,放弃执行后续任务..."); + _logger.LogError("【原因】{message}", exception.Message); + return false; + } + + return true; } -} +} \ No newline at end of file diff --git a/test/AppServiceTest/DailyTask/DonateCoinsTest.cs b/test/AppServiceTest/DailyTask/DonateCoinsTest.cs index 9b61f1e74..9c6cdbf8e 100644 --- a/test/AppServiceTest/DailyTask/DonateCoinsTest.cs +++ b/test/AppServiceTest/DailyTask/DonateCoinsTest.cs @@ -17,8 +17,6 @@ public void Test1() { using var scope = Global.ServiceProviderRoot.CreateScope(); var appService = scope.ServiceProvider.GetRequiredService(); - - } } } diff --git a/test/AppServiceTest/VipServiceTest.cs b/test/AppServiceTest/VipServiceTest.cs index ca5da50ce..216aea8a9 100644 --- a/test/AppServiceTest/VipServiceTest.cs +++ b/test/AppServiceTest/VipServiceTest.cs @@ -28,7 +28,6 @@ public async Task WatchVideo() using var scope = Global.ServiceProviderRoot.CreateScope(); var appService = scope.ServiceProvider.GetRequiredService(); var res = await appService.WatchBangumi(); - Assert.True(res); } diff --git a/test/BiliAgentTest/HomeApiTest.cs b/test/BiliAgentTest/HomeApiTest.cs deleted file mode 100644 index f953aea73..000000000 --- a/test/BiliAgentTest/HomeApiTest.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; -using Ray.BiliBiliTool.Agent; -using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos; -using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos.Live; -using Ray.BiliBiliTool.Agent.BiliBiliAgent.Interfaces; -using Ray.BiliBiliTool.Console; -using Ray.BiliBiliTool.Infrastructure; -using Ray.BiliBiliTool.Infrastructure.Helpers; -using Xunit; - -namespace BiliAgentTest -{ - public class HomeApiTest - { - public HomeApiTest() - { - Program.CreateHost(new[] { "--ENVIRONMENT=Development" }); - } - - [Fact] - public async Task WebHeartBeat_Normal_Success() - { - using var scope = Global.ServiceProviderRoot.CreateScope(); - - var ck = scope.ServiceProvider.GetRequiredService(); - var api = scope.ServiceProvider.GetRequiredService(); - - var re = await api.GetHomePageAsync(ck.ToString()); - - - } - } -} diff --git a/test/InfrastructureTest/WbiHelperTest.cs b/test/InfrastructureTest/WbiHelperTest.cs index 630d3f5f2..2b910dd29 100644 --- a/test/InfrastructureTest/WbiHelperTest.cs +++ b/test/InfrastructureTest/WbiHelperTest.cs @@ -15,7 +15,7 @@ public void Replace_Test() string output = Regex.Replace(input, pattern, replacement); Debug.WriteLine(output); - Assert.Equal(output, "һΰַ@#$%^&ַ"); + Assert.Equal("һΰַ@#$%^&ַ", output); } } } diff --git a/test/LogTest/LogTest.csproj b/test/LogTest/LogTest.csproj index 71444b237..90f0c86ed 100644 --- a/test/LogTest/LogTest.csproj +++ b/test/LogTest/LogTest.csproj @@ -4,6 +4,8 @@ net6.0 false + + 5bc79f80-380e-4bcf-9c0b-30e98db3b935 diff --git a/test/LogTest/TestCoolPush.cs b/test/LogTest/TestCoolPush.cs index 407e3f28e..848adf3a7 100644 --- a/test/LogTest/TestCoolPush.cs +++ b/test/LogTest/TestCoolPush.cs @@ -16,34 +16,32 @@ namespace LogTest { public class TestCoolPush { - private string _key; + //private string _key; - public TestCoolPush() - { - Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development"); - Program.CreateHost(new string[] { }); + //public TestCoolPush() + //{ + // Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development"); + // Program.CreateHost(new string[] { }); - _key = Global.ConfigurationRoot["Serilog:WriteTo:7:Args:sKey"]; - } + // _key = Global.ConfigurationRoot["Serilog:WriteTo:7:Args:sKey"]; + //} - [Fact] - public void Test2() - { - //var msg = "ℹ 版本号:\"1.0.18\"\r\n\r\nℹ 开源地址:\"https://github.com/RayWangQvQ/BiliBiliTool\"\r\n\r\nℹ 当前环境:\"Development\" \r\n\r\n\r\nℹ -----开始每日任务-----\r\n\r\n\r\nℹ ---开始【\"登录\"】---\r\n\r\nℹ 登录成功,用户名: \"在*楼\"\r\n\r\nℹ 硬币余额: 672.4\r\n\r\nℹ 距离升级到Lv6还有: 261天\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"观看、分享视频\"】---\r\n\r\nℹ 今天已经观看过了,不需要再看啦\r\n\r\nℹ 今天已经分享过了,不要再分享啦\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"投币\"】---\r\n\r\nℹ 今日已投5枚硬币,已完成投币任务,不需要再投啦~\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"漫画签到\"】---\r\n\r\nℹ 今日已签到过,无法重复签到\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"直播中心签到\"】---\r\n\r\nℹ 今日已签到过,无法重复签到\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"直播中心银瓜子兑换硬币\"】---\r\n\r\nℹ 银瓜子兑换硬币失败,原因:\"银瓜子余额不足\"\r\n\r\nℹ 当前银瓜子余额: 564\r\n\r\nℹ 当前硬币余额: 672.4\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"每月领取大会员福利\"】---\r\n\r\nℹ 目标领取日期为1号,今天是25号,跳过领取任务\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"每月领取大会员漫画权益\"】---\r\n\r\nℹ 目标领取日期为1号,今天是25号,跳过领取任务\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"每月为自己充电\"】---\r\n\r\nℹ 目标充电日期为31号,今天是25号,跳过充电任务\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ -----全部任务已执行结束-----\r\n\r\n\r\nℹ 开始推送\r\n\r\n"; - //var msg2 = "ℹ ---开始【\"登录\"】---\r\n\r\nℹ 登录成功,用户名: \"在*楼\"\r\n\r\nℹ 硬币余额: 672.4\r\n\r\nℹ 距离升级到Lv6还有: 261天\r\n\r\nℹ ---结束---\r\n\r\n\r\n"; - //var msg3 = "ℹ 版本号:\"1.0.18\"\r\n\r\nℹ 开源地址:\"https://github.com/RayWangQvQ/BiliBiliTool\"\r\n\r\nℹ 当前环境:\"Development\" \r\n\r\n\r\nℹ -----开始每日任务-----\r\n\r\n\r\nℹ ---开始【\"登录\"】---\r\n\r\nℹ 登录成功,用户名: \"在*楼\"\r\n\r\nℹ 硬币余额: 672.4\r\n\r\nℹ 距离升级到Lv6还有: 261天\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"观看、分享视频\"】---\r\n\r\nℹ 今天已经观看过了,不需要再看啦\r\n\r\nℹ 今天已经分享过了,不要再分享啦\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"投币\"】---\r\n\r\nℹ 今日已投5枚硬币,已完成投币任务,不需要再投啦~\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"漫画签到\"】---\r\n\r\nℹ 今日已签到过,无法重复签到\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"直播中心签到\"】---\r\n\r\nℹ 今日已签到过,无法重复签到\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"直播中心银瓜子兑换硬币\"】---\r\n\r\nℹ 银瓜子兑换硬币失败,原因:\"银瓜子余额不足\"\r\n\r\nℹ 当前银瓜子余额: 564\r\n\r\nℹ 当前硬币余额: 672.4\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"每月领取大会员福利\"】---\r\n\r\nℹ 目标领取日期为1号,今天是25号,跳过领取任务\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"每月领取大会员漫画权益\"】---\r\n\r\nℹ 目标领取日期为1号,今天是25号,跳过领取任务\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ"; - //var msg4 = "ℹ 版本号:\"1.0.18\"\r\n\r\nℹ 开源地址:\"https://github.com/RayWangQvQ/BiliBiliTool\"\r\n\r\nℹ 当前环境:\"Development\" \r\n\r\n\r\nℹ -----开始每日任务-----\r\n\r\n\r\nℹ ---开始【\"登录\"】---\r\n\r\nℹ 登录成功,用户名: \"在*楼\"\r\n\r\nℹ 硬币余额: 672.4\r\n\r\nℹ 距离升级到Lv6还有: 261天\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"观看、分享视频\"】---\r\n\r\nℹ 今天已经观看过了,不需要再看啦\r\n\r\nℹ 今天已经分享过了,不要再分享啦\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"投币\"】---\r\n\r\nℹ 今日已投5枚硬币,已完成投币任务,不需要再投啦~\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"漫画签到\"】---\r\n\r\nℹ 今日已签到过,无法重复签到\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"直播中心签到\"】---\r\n\r\nℹ 今日已签到过,无法重复签到\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"直播中心银瓜子兑换硬币\"】---\r\n\r\nℹ 银瓜子兑换硬币失败,原因:\"银瓜子余额不足\"\r\n\r\nℹ 当前银瓜子余额: 564\r\n\r\nℹ 当前硬币余额: 672.4\r\n\r\nℹ ---结束---\r\n\r\n\r\n"; - //var msg5 = "ℹ 版本号:\"1.0.18\"\r\n\r\nℹ 开源地址:\"https://github.com/RayWangQvQ/BiliBiliTool\"\r\n\r\nℹ 当前环境:\"Development\" \r\n\r\n\r\nℹ -----开始每日任务-----\r\n\r\n\r\nℹ ---开始【\"登录\"】---\r\n\r\nℹ 登录成功,用户名: \"在*楼\"\r\n\r\nℹ 硬币余额: 672.4\r\n\r\nℹ 距离升级到Lv6还有: 261天\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"观看、分享视频\"】---\r\n\r\nℹ 今天已经观看过了,不需要再看啦\r\n\r\nℹ 今天已经分享过了,不要再分享啦\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"投币\"】---\r\n\r\nℹ 今日已投5枚硬币,已完成投币任务,不需要再投啦~\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"漫画签到\"】---\r\n\r\nℹ 今日已签到过,无法重复签到\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"直播中心签到\"】---\r\n\r\nℹ 今日已签到过,无法重复签到\r\n\r\nℹ ---结束---\r\n\r\n\r\n"; - //var msg6 = "ℹ 版本号:\"1.0.18\"\r\n\r\nℹ 开源地址:\"https://github.com/RayWangQvQ/BiliBiliTool\"\r\n\r\nℹ 当前环境:\"Development\" \r\n\r\n\r\nℹ -----开始每日任务-----\r\n\r\n\r\nℹ ---开始【\"登录\"】---\r\n\r\nℹ 登录成功,用户名: \"在*楼\"\r\n\r\nℹ 硬币余额: 672.4\r\n\r\nℹ 距离升级到Lv6还有: 261天\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"观看、分享视频\"】---\r\n\r\nℹ 今天已经观看过了,不需要再看啦\r\n\r\nℹ 今天已经分享过了,不要再分享啦\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"投币\"】---\r\n\r\nℹ 今日已投5枚硬币,已完成投币任务,不需要再投啦~\r\n\r\nℹ ---结束---\r\n\r\n\r\n"; - //var msg7 = "ℹ 版本号:\"1.0.18\"\r\n\r\nℹ 开源地址:\"https://github.com/RayWangQvQ/BiliBiliTool\"\r\n\r\nℹ 当前环境:\"Development\" \r\n\r\n\r\nℹ -----开始每日任务-----\r\n\r\n\r\nℹ ---开始【\"登录\"】---\r\n\r\nℹ 登录成功,用户名: \"在*楼\"\r\n\r\nℹ 硬币余额: 672.4\r\n\r\nℹ 距离升级到Lv6还有: 261天\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"观看、分享视频\"】---\r\n\r\nℹ 今天已经观看过了,不需要再看啦\r\n\r\nℹ 今天已经分享过了,不要再分享啦\r\n\r\nℹ ---结束---\r\n\r\n\r\n"; - var msg8 = "ℹ 版本号:\"1.0.18\"\r\n\r\nℹ 开源地址:\"https://github.com/RayWangQvQ/BiliBiliTool\"\r\n\r\nℹ 当前环境:\"Development\" \r\n\r\n\r\nℹ -----开始每日任务-----\r\n\r\n\r\nℹ ---开始【\"登录\"】---\r\n\r\nℹ 登录成功,用户名: \"在*楼\"\r\n\r\nℹ 硬币余额: 672.4\r\n\r\nℹ 距离升级到Lv6还有: 261天\r\n\r\nℹ ---结束---\r\n\r\n\r\n"; - //var msg9 = "ℹ 版本号:\"1.0.18\"\r\n\r\nℹ 开源地址:\"https://github.com/RayWangQvQ/BiliBiliTool\"\r\n\r\nℹ 当前环境:\"Development\" \r\n\r\n\r\nℹ -----开始每日任务-----\r\n\r\n\r\nℹ ---开始【\"登录\"】---\r\n\r\nℹ 登录成功,用户名: \"在*楼\"\r\n\r\nℹ 硬币余额: 672.4\r\n\r\n"; + //[Fact] + //public void Test2() + //{ + // //var msg = "ℹ 版本号:\"1.0.18\"\r\n\r\nℹ 开源地址:\"https://github.com/RayWangQvQ/BiliBiliTool\"\r\n\r\nℹ 当前环境:\"Development\" \r\n\r\n\r\nℹ -----开始每日任务-----\r\n\r\n\r\nℹ ---开始【\"登录\"】---\r\n\r\nℹ 登录成功,用户名: \"在*楼\"\r\n\r\nℹ 硬币余额: 672.4\r\n\r\nℹ 距离升级到Lv6还有: 261天\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"观看、分享视频\"】---\r\n\r\nℹ 今天已经观看过了,不需要再看啦\r\n\r\nℹ 今天已经分享过了,不要再分享啦\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"投币\"】---\r\n\r\nℹ 今日已投5枚硬币,已完成投币任务,不需要再投啦~\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"漫画签到\"】---\r\n\r\nℹ 今日已签到过,无法重复签到\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"直播中心签到\"】---\r\n\r\nℹ 今日已签到过,无法重复签到\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"直播中心银瓜子兑换硬币\"】---\r\n\r\nℹ 银瓜子兑换硬币失败,原因:\"银瓜子余额不足\"\r\n\r\nℹ 当前银瓜子余额: 564\r\n\r\nℹ 当前硬币余额: 672.4\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"每月领取大会员福利\"】---\r\n\r\nℹ 目标领取日期为1号,今天是25号,跳过领取任务\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"每月领取大会员漫画权益\"】---\r\n\r\nℹ 目标领取日期为1号,今天是25号,跳过领取任务\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"每月为自己充电\"】---\r\n\r\nℹ 目标充电日期为31号,今天是25号,跳过充电任务\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ -----全部任务已执行结束-----\r\n\r\n\r\nℹ 开始推送\r\n\r\n"; + // //var msg2 = "ℹ ---开始【\"登录\"】---\r\n\r\nℹ 登录成功,用户名: \"在*楼\"\r\n\r\nℹ 硬币余额: 672.4\r\n\r\nℹ 距离升级到Lv6还有: 261天\r\n\r\nℹ ---结束---\r\n\r\n\r\n"; + // //var msg3 = "ℹ 版本号:\"1.0.18\"\r\n\r\nℹ 开源地址:\"https://github.com/RayWangQvQ/BiliBiliTool\"\r\n\r\nℹ 当前环境:\"Development\" \r\n\r\n\r\nℹ -----开始每日任务-----\r\n\r\n\r\nℹ ---开始【\"登录\"】---\r\n\r\nℹ 登录成功,用户名: \"在*楼\"\r\n\r\nℹ 硬币余额: 672.4\r\n\r\nℹ 距离升级到Lv6还有: 261天\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"观看、分享视频\"】---\r\n\r\nℹ 今天已经观看过了,不需要再看啦\r\n\r\nℹ 今天已经分享过了,不要再分享啦\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"投币\"】---\r\n\r\nℹ 今日已投5枚硬币,已完成投币任务,不需要再投啦~\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"漫画签到\"】---\r\n\r\nℹ 今日已签到过,无法重复签到\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"直播中心签到\"】---\r\n\r\nℹ 今日已签到过,无法重复签到\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"直播中心银瓜子兑换硬币\"】---\r\n\r\nℹ 银瓜子兑换硬币失败,原因:\"银瓜子余额不足\"\r\n\r\nℹ 当前银瓜子余额: 564\r\n\r\nℹ 当前硬币余额: 672.4\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"每月领取大会员福利\"】---\r\n\r\nℹ 目标领取日期为1号,今天是25号,跳过领取任务\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"每月领取大会员漫画权益\"】---\r\n\r\nℹ 目标领取日期为1号,今天是25号,跳过领取任务\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ"; + // //var msg4 = "ℹ 版本号:\"1.0.18\"\r\n\r\nℹ 开源地址:\"https://github.com/RayWangQvQ/BiliBiliTool\"\r\n\r\nℹ 当前环境:\"Development\" \r\n\r\n\r\nℹ -----开始每日任务-----\r\n\r\n\r\nℹ ---开始【\"登录\"】---\r\n\r\nℹ 登录成功,用户名: \"在*楼\"\r\n\r\nℹ 硬币余额: 672.4\r\n\r\nℹ 距离升级到Lv6还有: 261天\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"观看、分享视频\"】---\r\n\r\nℹ 今天已经观看过了,不需要再看啦\r\n\r\nℹ 今天已经分享过了,不要再分享啦\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"投币\"】---\r\n\r\nℹ 今日已投5枚硬币,已完成投币任务,不需要再投啦~\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"漫画签到\"】---\r\n\r\nℹ 今日已签到过,无法重复签到\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"直播中心签到\"】---\r\n\r\nℹ 今日已签到过,无法重复签到\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"直播中心银瓜子兑换硬币\"】---\r\n\r\nℹ 银瓜子兑换硬币失败,原因:\"银瓜子余额不足\"\r\n\r\nℹ 当前银瓜子余额: 564\r\n\r\nℹ 当前硬币余额: 672.4\r\n\r\nℹ ---结束---\r\n\r\n\r\n"; + // //var msg5 = "ℹ 版本号:\"1.0.18\"\r\n\r\nℹ 开源地址:\"https://github.com/RayWangQvQ/BiliBiliTool\"\r\n\r\nℹ 当前环境:\"Development\" \r\n\r\n\r\nℹ -----开始每日任务-----\r\n\r\n\r\nℹ ---开始【\"登录\"】---\r\n\r\nℹ 登录成功,用户名: \"在*楼\"\r\n\r\nℹ 硬币余额: 672.4\r\n\r\nℹ 距离升级到Lv6还有: 261天\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"观看、分享视频\"】---\r\n\r\nℹ 今天已经观看过了,不需要再看啦\r\n\r\nℹ 今天已经分享过了,不要再分享啦\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"投币\"】---\r\n\r\nℹ 今日已投5枚硬币,已完成投币任务,不需要再投啦~\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"漫画签到\"】---\r\n\r\nℹ 今日已签到过,无法重复签到\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"直播中心签到\"】---\r\n\r\nℹ 今日已签到过,无法重复签到\r\n\r\nℹ ---结束---\r\n\r\n\r\n"; + // //var msg6 = "ℹ 版本号:\"1.0.18\"\r\n\r\nℹ 开源地址:\"https://github.com/RayWangQvQ/BiliBiliTool\"\r\n\r\nℹ 当前环境:\"Development\" \r\n\r\n\r\nℹ -----开始每日任务-----\r\n\r\n\r\nℹ ---开始【\"登录\"】---\r\n\r\nℹ 登录成功,用户名: \"在*楼\"\r\n\r\nℹ 硬币余额: 672.4\r\n\r\nℹ 距离升级到Lv6还有: 261天\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"观看、分享视频\"】---\r\n\r\nℹ 今天已经观看过了,不需要再看啦\r\n\r\nℹ 今天已经分享过了,不要再分享啦\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"投币\"】---\r\n\r\nℹ 今日已投5枚硬币,已完成投币任务,不需要再投啦~\r\n\r\nℹ ---结束---\r\n\r\n\r\n"; + // //var msg7 = "ℹ 版本号:\"1.0.18\"\r\n\r\nℹ 开源地址:\"https://github.com/RayWangQvQ/BiliBiliTool\"\r\n\r\nℹ 当前环境:\"Development\" \r\n\r\n\r\nℹ -----开始每日任务-----\r\n\r\n\r\nℹ ---开始【\"登录\"】---\r\n\r\nℹ 登录成功,用户名: \"在*楼\"\r\n\r\nℹ 硬币余额: 672.4\r\n\r\nℹ 距离升级到Lv6还有: 261天\r\n\r\nℹ ---结束---\r\n\r\n\r\nℹ ---开始【\"观看、分享视频\"】---\r\n\r\nℹ 今天已经观看过了,不需要再看啦\r\n\r\nℹ 今天已经分享过了,不要再分享啦\r\n\r\nℹ ---结束---\r\n\r\n\r\n"; + // var msg8 = "ℹ 版本号:\"1.0.18\"\r\n\r\nℹ 开源地址:\"https://github.com/RayWangQvQ/BiliBiliTool\"\r\n\r\nℹ 当前环境:\"Development\" \r\n\r\n\r\nℹ -----开始每日任务-----\r\n\r\n\r\nℹ ---开始【\"登录\"】---\r\n\r\nℹ 登录成功,用户名: \"在*楼\"\r\n\r\nℹ 硬币余额: 672.4\r\n\r\nℹ 距离升级到Lv6还有: 261天\r\n\r\nℹ ---结束---\r\n\r\n\r\n"; + // //var msg9 = "ℹ 版本号:\"1.0.18\"\r\n\r\nℹ 开源地址:\"https://github.com/RayWangQvQ/BiliBiliTool\"\r\n\r\nℹ 当前环境:\"Development\" \r\n\r\n\r\nℹ -----开始每日任务-----\r\n\r\n\r\nℹ ---开始【\"登录\"】---\r\n\r\nℹ 登录成功,用户名: \"在*楼\"\r\n\r\nℹ 硬币余额: 672.4\r\n\r\n"; - CoolPushApiClient client = new CoolPushApiClient(_key); - var result = client.PushMessage(msg8); - Debug.WriteLine(result.Content.ReadAsStringAsync().Result); - - System.Console.ReadLine(); - } + // CoolPushApiClient client = new CoolPushApiClient(_key); + // var result = client.PushMessage(msg8); + // Debug.WriteLine(result.Content.ReadAsStringAsync().Result); + //} } } diff --git a/test/LogTest/TestDingTalk.cs b/test/LogTest/TestDingTalk.cs index ddeefd591..e59c93518 100644 --- a/test/LogTest/TestDingTalk.cs +++ b/test/LogTest/TestDingTalk.cs @@ -20,7 +20,7 @@ public class TestDingTalk public TestDingTalk() { Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development"); - Program.CreateHost(new string[] { }); + Program.CreateHost(new string[] { "ENVIRONMENT=Development" }); _key = Global.ConfigurationRoot["Serilog:WriteTo:5:Args:webHookUrl"]; } @@ -30,12 +30,11 @@ public void Test2() { var client = new DingTalkApiClient(_key); + var title = "这是标题"; var msg = LogConstants.Msg2 + "开始推送"; - var result = client.PushMessage(msg); + var result = client.PushMessage(msg, title); Debug.WriteLine(result.Content.ReadAsStringAsync().Result); - - System.Console.ReadLine(); } } } diff --git a/test/LogTest/TestMicrosoftTeams.cs b/test/LogTest/TestMicrosoftTeams.cs index 491098d7b..4e8083254 100644 --- a/test/LogTest/TestMicrosoftTeams.cs +++ b/test/LogTest/TestMicrosoftTeams.cs @@ -20,7 +20,7 @@ public class TestMicrosoftTeams public TestMicrosoftTeams() { Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development"); - Program.CreateHost(new string[] { }); + Program.CreateHost(new string[] { "ENVIRONMENT=Development" }); _webhook = Global.ConfigurationRoot["Serilog:WriteTo:10:Args:webhook"]; } diff --git a/test/LogTest/TestPushPlus.cs b/test/LogTest/TestPushPlus.cs index 4af77bdba..21932cce3 100644 --- a/test/LogTest/TestPushPlus.cs +++ b/test/LogTest/TestPushPlus.cs @@ -40,8 +40,6 @@ public void Test2() var result = client.PushMessage(msg); Debug.WriteLine(result.Content.ReadAsStringAsync().Result); - - System.Console.ReadLine(); } } } diff --git a/test/LogTest/TestWorkWeiXin.cs b/test/LogTest/TestWorkWeiXin.cs index 08c7b4f26..54de85c0d 100644 --- a/test/LogTest/TestWorkWeiXin.cs +++ b/test/LogTest/TestWorkWeiXin.cs @@ -16,8 +16,8 @@ public class TestWorkWeiXin public TestWorkWeiXin() { - Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development"); - Program.CreateHost(new string[] { }); + Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", "Development"); + Program.CreateHost(new string[] { "ENVIRONMENT=Development" }); _key = Global.ConfigurationRoot["Serilog:WriteTo:4:Args:webHookUrl"]; } @@ -25,7 +25,7 @@ public TestWorkWeiXin() [Fact] public void Test2() { - WorkWeiXinApiClient client = new WorkWeiXinApiClient(_key); + var client = new WorkWeiXinApiClient(_key); //string msg = LogConstants.Msg; string msg = LogConstants.Msg2; diff --git a/test/LogTest/UnitTest1.cs b/test/LogTest/UnitTest1.cs index 9f665ac88..a192b00a5 100644 --- a/test/LogTest/UnitTest1.cs +++ b/test/LogTest/UnitTest1.cs @@ -31,8 +31,6 @@ public void Test1() logger.LogDebug(null); logger.LogDebug("123{0}{1}", null, "haha"); - - System.Console.ReadLine(); } [Fact] @@ -53,7 +51,6 @@ public void Test2() logger.LogInformation("-----ȫִн-----\r\n"); logger.LogInformation("ʼ"); - System.Console.ReadLine(); } private ILogger CreateLogger() diff --git a/test/Ray.BiliBiliTool.Agent.FunctionalTests/ArticleApiTests.cs b/test/Ray.BiliBiliTool.Agent.FunctionalTests/ArticleApiTests.cs index 6f72ea60a..60c03f878 100644 --- a/test/Ray.BiliBiliTool.Agent.FunctionalTests/ArticleApiTests.cs +++ b/test/Ray.BiliBiliTool.Agent.FunctionalTests/ArticleApiTests.cs @@ -117,8 +117,10 @@ public async Task AddCoinForArticleAsync_Normal_Success() BiliBiliAgent.Dtos.BiliApiResponse re = await _api.AddCoinForArticleAsync(req); // Assert - re.Code.Should().Be(0); - re.Message.Should().BeEquivalentTo("0"); + re.Code.Should().BeOneOf( + 0,// 成功 + 34005 // 超过投币上限啦~ + ); } #endregion diff --git a/test/Ray.BiliBiliTool.Agent.FunctionalTests/ChargeApiTest.cs b/test/Ray.BiliBiliTool.Agent.FunctionalTests/ChargeApiTest.cs index 086a6e6b9..eb776dbe4 100644 --- a/test/Ray.BiliBiliTool.Agent.FunctionalTests/ChargeApiTest.cs +++ b/test/Ray.BiliBiliTool.Agent.FunctionalTests/ChargeApiTest.cs @@ -40,30 +40,16 @@ public async void ChargeV2Async_SendRequest_NotEnough() // Assert re.Code.Should().Be(0); - re.Data.Status.Should().Be(-4); - re.Data.Msg.Should().BeEquivalentTo("bp.to.battery http failed, invalid args, errNo=800409904: B "); + re.Data.Status.Should().BeOneOf( + -4,//bp.to.battery http failed, invalid args, errNo=800409904: B  + 4 + ); } #endregion #region ChargeCommentAsync - [Fact] - public async void ChargeCommentAsync_SendRequest_SetWridSuccess() - { - // Arrange - var upId = 220893216; - var req = new ChargeRequest(2, upId, _ck.BiliJct); - - // Act - BiliApiResponse re = await _target.ChargeV2Async(req); - - // Assert - re.Code.Should().Be(0); - re.Data.Status.Should().Be(-4); - re.Data.Msg.Should().BeEquivalentTo("bp.to.battery http failed, invalid args, errNo=800409904: B "); - } - #endregion } diff --git a/test/Ray.BiliBiliTool.Agent.FunctionalTests/DailyTaskApiTests.cs b/test/Ray.BiliBiliTool.Agent.FunctionalTests/DailyTaskApiTests.cs index f4cc92653..5d204b18f 100644 --- a/test/Ray.BiliBiliTool.Agent.FunctionalTests/DailyTaskApiTests.cs +++ b/test/Ray.BiliBiliTool.Agent.FunctionalTests/DailyTaskApiTests.cs @@ -61,10 +61,10 @@ public async Task ReceiveVipPrivilege_Normal_Success() // Arrange // Assert - re.Code.Should().BeOneOf(new List - { + re.Code.Should().BeOneOf( 0, 73319, //todo: sort out meannings - }); + 69801 //你已领取过该权益 + ); } } diff --git a/test/BiliAgentTest/LiveApiTest.cs b/test/Ray.BiliBiliTool.Agent.FunctionalTests/LiveApiTest.cs similarity index 97% rename from test/BiliAgentTest/LiveApiTest.cs rename to test/Ray.BiliBiliTool.Agent.FunctionalTests/LiveApiTest.cs index 6aabd4b27..320c24cf7 100644 --- a/test/BiliAgentTest/LiveApiTest.cs +++ b/test/Ray.BiliBiliTool.Agent.FunctionalTests/LiveApiTest.cs @@ -11,6 +11,7 @@ using Ray.BiliBiliTool.Infrastructure.Cookie; using Xunit; using Ray.BiliBiliTool.Agent.BiliBiliAgent.Services; +using FluentAssertions; namespace BiliAgentTest { @@ -116,11 +117,15 @@ public void WearMedalWall_Normal_Success() var biliCookie = scope.ServiceProvider.GetRequiredService(); // 猫雷粉丝牌 - var request = new WearMedalWallRequest(biliCookie.BiliJct, 365421); + var request = new WearMedalWallRequest(biliCookie.BiliJct, 365421); //todo BiliApiResponse re = api.WearMedalWall(request).Result; Assert.True(re.Code == 0); + re.Code.Should().BeOneOf( + 0, + 1500005 + ); } [Fact]