-
Notifications
You must be signed in to change notification settings - Fork 894
新增基于精英经验值的战后材料聚集 #2406
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
新增基于精英经验值的战后材料聚集 #2406
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,15 +13,25 @@ | |
| using System.Linq; | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
| using BetterGenshinImpact.Core.Config; | ||
| using BetterGenshinImpact.Core.Recognition; | ||
| using static BetterGenshinImpact.GameTask.Common.TaskControl; | ||
| using BetterGenshinImpact.GameTask.Common.Job; | ||
| using OpenCvSharp; | ||
| using BetterGenshinImpact.Helpers; | ||
| using Vanara; | ||
| using Microsoft.Extensions.DependencyInjection; | ||
| using BetterGenshinImpact.GameTask.AutoPathing.Model; | ||
| using BetterGenshinImpact.GameTask.Common.Element.Assets; | ||
| using BetterGenshinImpact.GameTask.Common; | ||
| using BetterGenshinImpact.GameTask.AutoFight.Assets; | ||
| using BetterGenshinImpact.View.Drawable; | ||
| using BetterGenshinImpact.Core.Recognition.OpenCv; | ||
| using BetterGenshinImpact.GameTask.Common.BgiVision; | ||
| using Vanara.PInvoke; | ||
| using BetterGenshinImpact.GameTask.AutoPathing.Handler; | ||
| using BetterGenshinImpact.GameTask.AutoPick.Assets; | ||
| using BetterGenshinImpact.GameTask.AutoPathing.Model; | ||
| using BetterGenshinImpact.GameTask.AutoFight.Assets; | ||
|
|
||
| namespace BetterGenshinImpact.GameTask.AutoFight; | ||
|
|
||
|
|
@@ -44,6 +54,8 @@ public class AutoFightTask : ISoloTask | |
| public static bool FightStatusFlag { get; set; } = false; | ||
|
|
||
| private static readonly object PickLock = new object(); | ||
|
|
||
| private static bool _isExperiencePickup = false; | ||
|
|
||
| // 战斗点位 | ||
| public static WaypointForTrack? FightWaypoint {get; set;} = null; | ||
|
|
@@ -291,6 +303,10 @@ public async Task Start(CancellationToken ct) | |
| var guardianAvatar = string.IsNullOrWhiteSpace(_taskParam.GuardianAvatar) ? null : combatScenes.SelectAvatar(int.Parse(_taskParam.GuardianAvatar)); | ||
|
|
||
| AutoFightSeek.RotationCount= 0; // 重置旋转次数 | ||
|
|
||
| var avatarName = combatScenes.Avatars.Select(a => a.Name).ToArray(); | ||
| var requiredAvatars = new HashSet<string> { "枫原万叶", "琴" };//后续方便添加 | ||
| var findExpAvatar = requiredAvatars.Any(a => avatarName.Contains(a)); | ||
|
|
||
| // 战斗操作 | ||
| var fightTask = Task.Run(async () => | ||
|
|
@@ -299,6 +315,12 @@ public async Task Start(CancellationToken ct) | |
| { | ||
| FightStatusFlag = true; | ||
|
|
||
| #region 基于战斗检测经验值开关万叶拾取功能同步任务 | ||
|
|
||
| if (_taskParam.ExpKazuhaPickup && findExpAvatar) FindExp(cts2.Token); | ||
|
|
||
| #endregion | ||
|
|
||
| while (!cts2.Token.IsCancellationRequested) | ||
|
Comment on lines
+318
to
324
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FindExp 调用未管理生命周期;绘制清理时机错误
可按下方方式修改 FindExp(见对应方法处的完整 diff)。 🤖 Prompt for AI Agents |
||
| { | ||
| // 所有战斗角色都可以被取消 | ||
|
|
@@ -475,13 +497,22 @@ public async Task Start(CancellationToken ct) | |
| }, cts2.Token); | ||
|
|
||
| await fightTask; | ||
| if (_taskParam.BattleThresholdForLoot>=2 && countFight < _taskParam.BattleThresholdForLoot) | ||
|
|
||
| if (_taskParam.KazuhaPickupEnabled && _taskParam.ExpKazuhaPickup && !_isExperiencePickup)//可能刚死亡,等待经验显示 | ||
| { | ||
| TaskControl.Logger.LogInformation("基于怪物经验判断:{text} 经验值显示","等待"); | ||
| await Delay(1000, ct); | ||
| } | ||
|
|
||
| if ((_taskParam.BattleThresholdForLoot >= 2 && countFight < _taskParam.BattleThresholdForLoot) && (!_taskParam.ExpKazuhaPickup || !_isExperiencePickup)) | ||
| { | ||
| Logger.LogInformation($"战斗人次({countFight})低于配置人次({_taskParam.BattleThresholdForLoot}),跳过此次拾取!"); | ||
| return; | ||
| } | ||
|
|
||
| if(_taskParam.KazuhaPickupEnabled && _taskParam.ExpKazuhaPickup) Logger.LogInformation("基于怪物经验判断:{text} 聚集拾取", _isExperiencePickup? "执行" : "不执行"); | ||
|
|
||
| if (_taskParam.KazuhaPickupEnabled) | ||
| if (_taskParam.KazuhaPickupEnabled && (!_taskParam.ExpKazuhaPickup || _isExperiencePickup)) | ||
| { | ||
| // 队伍中存在万叶的时候使用一次长E | ||
| var picker = combatScenes.SelectAvatar("枫原万叶") ?? combatScenes.SelectAvatar("琴"); | ||
|
|
@@ -733,6 +764,85 @@ bool IsWhite(int r, int g, int b) | |
| (g >= 240 && g <= 255) && | ||
| (b >= 240 && b <= 255); | ||
| } | ||
|
|
||
| //基于万叶经验值判断是否拾取 | ||
| private static Task FindExp(CancellationToken cts2) | ||
| { | ||
| var autoFightAssets = AutoFightAssets.Instance; | ||
|
|
||
| try | ||
| { | ||
| Task.Run(() => | ||
| { | ||
| _isExperiencePickup = false; | ||
| var expLogo = false; | ||
|
|
||
| var experienceRas = new[] | ||
| { | ||
| autoFightAssets.InitializeRecognitionObject(60), | ||
| autoFightAssets.InitializeRecognitionObject(58), | ||
| autoFightAssets.InitializeRecognitionObject(57), | ||
| }; | ||
|
|
||
| while (!(_isExperiencePickup || !FightStatusFlag) && !cts2.IsCancellationRequested) | ||
| { | ||
| try | ||
| { | ||
| cts2.ThrowIfCancellationRequested(); | ||
|
|
||
| var result = NewRetry.WaitForAction(() => | ||
| { | ||
| using (var ra = CaptureToRectArea()) | ||
| { | ||
| _isExperiencePickup = experienceRas.Any(experienceRa => | ||
| { | ||
| var isExist = ra.Find(experienceRa); | ||
| if (!isExist.IsExist()) | ||
| { | ||
| return false; | ||
| } | ||
|
|
||
| var pixelValue1 = ra.SrcMat.At<Vec3b>(isExist.Y, isExist.X - 147); //经验值图标,在2K以上时匹配度0.6,这个经验值颜色尤为重要 | ||
| expLogo = pixelValue1[0] == 253 && pixelValue1[1] == 247 && pixelValue1[2] == 172; | ||
|
|
||
| return expLogo; | ||
| }); | ||
| } | ||
| return _isExperiencePickup; | ||
| }, cts2, 1, 100).Result; | ||
| } | ||
| catch (OperationCanceledException ex) | ||
| { | ||
| Console.WriteLine($"检测经验发生异常: {ex.Message}"); | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| // Console.WriteLine($"检测怪物经验发生异常: {ex.Message}"); | ||
| } | ||
|
|
||
| if (_isExperiencePickup) Logger.LogInformation("基于怪物经验判断:识别到 {text1} 经验值,{text2} 聚集拾取","精英","启用" ); | ||
|
|
||
| } | ||
|
|
||
| cts2.ThrowIfCancellationRequested(); | ||
|
|
||
| }, cts2); | ||
| } | ||
| catch (OperationCanceledException ex) | ||
| { | ||
| Console.WriteLine($"检测经验发生异常: {ex.Message}"); | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| Console.WriteLine($"检测怪物经验发生异常: {ex.Message}"); | ||
| } | ||
| finally | ||
| { | ||
| VisionContext.Instance().DrawContent.ClearAll(); | ||
| } | ||
|
|
||
| return Task.CompletedTask; | ||
| } | ||
|
Comment on lines
+768
to
+845
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major FindExp:将清理放入任务 finally,避免 .Result 阻塞并加入边界检查/色差容忍
建议变更: - private static Task FindExp(CancellationToken cts2)
- {
- var autoFightAssets = AutoFightAssets.Instance;
- try
- {
- Task.Run(() =>
- {
- _isExperiencePickup = false;
- var expLogo = false;
-
- var experienceRas = new[]
- {
- autoFightAssets.InitializeRecognitionObject(60),
- autoFightAssets.InitializeRecognitionObject(58),
- autoFightAssets.InitializeRecognitionObject(57),
- };
-
- while (!(_isExperiencePickup || !FightStatusFlag) && !cts2.IsCancellationRequested)
- {
- try
- {
- cts2.ThrowIfCancellationRequested();
-
- var result = NewRetry.WaitForAction(() =>
- {
- using (var ra = CaptureToRectArea())
- {
- _isExperiencePickup = experienceRas.Any(experienceRa =>
- {
- var isExist = ra.Find(experienceRa);
- if (!isExist.IsExist())
- {
- return false;
- }
-
- var pixelValue1 = ra.SrcMat.At<Vec3b>(isExist.Y, isExist.X - 147); //经验值图标,在2K以上时匹配度0.6,这个经验值颜色尤为重要
- expLogo = pixelValue1[0] == 253 && pixelValue1[1] == 247 && pixelValue1[2] == 172;
-
- return expLogo;
- });
- }
- return _isExperiencePickup;
- }, cts2, 1, 100).Result;
- }
- catch (OperationCanceledException ex)
- {
- Console.WriteLine($"检测经验发生异常: {ex.Message}");
- }
- catch (Exception ex)
- {
- // Console.WriteLine($"检测怪物经验发生异常: {ex.Message}");
- }
-
- if (_isExperiencePickup) Logger.LogInformation("基于怪物经验判断:识别到 {text1} 经验值,{text2} 聚集拾取","精英","启用" );
-
- }
-
- cts2.ThrowIfCancellationRequested();
-
- }, cts2);
- }
- catch (OperationCanceledException ex)
- {
- Console.WriteLine($"检测经验发生异常: {ex.Message}");
- }
- catch (Exception ex)
- {
- Console.WriteLine($"检测怪物经验发生异常: {ex.Message}");
- }
- finally
- {
- VisionContext.Instance().DrawContent.ClearAll();
- }
-
- return Task.CompletedTask;
- }
+ private static Task FindExp(CancellationToken token)
+ {
+ var assets = AutoFightAssets.Instance;
+ return Task.Run(async () =>
+ {
+ try
+ {
+ _isExperiencePickup = false;
+ var experienceRas = new[]
+ {
+ assets.InitializeRecognitionObject(60),
+ assets.InitializeRecognitionObject(58),
+ assets.InitializeRecognitionObject(57),
+ };
+
+ while (!_isExperiencePickup && FightStatusFlag && !token.IsCancellationRequested)
+ {
+ try
+ {
+ token.ThrowIfCancellationRequested();
+ var detected = await NewRetry.WaitForAction(() =>
+ {
+ using var ra = CaptureToRectArea();
+ foreach (var ro in experienceRas)
+ {
+ var match = ra.Find(ro);
+ if (!match.IsExist()) continue;
+ var sampleX = match.X - 147;
+ var sampleY = match.Y;
+ if (sampleX < 0 || sampleY < 0 || sampleX >= ra.SrcMat.Cols || sampleY >= ra.SrcMat.Rows)
+ {
+ continue;
+ }
+ var p = ra.SrcMat.At<Vec3b>(sampleY, sampleX);
+ // 颜色近似(±3)以提升鲁棒性
+ bool near = Math.Abs(p[0] - 253) <= 3 && Math.Abs(p[1] - 247) <= 3 && Math.Abs(p[2] - 172) <= 3;
+ if (near) return (_isExperiencePickup = true);
+ }
+ return _isExperiencePickup;
+ }, token, retryTimes: 1, delayMs: 100);
+
+ if (detected)
+ {
+ Logger.LogInformation("基于怪物经验判断:识别到 {text1} 经验值,{text2} 聚集拾取", "精英", "启用");
+ }
+ }
+ catch (OperationCanceledException) { /* ignore */ }
+ catch { /* ignore */ }
+ }
+ }
+ finally
+ {
+ VisionContext.Instance().DrawContent.ClearAll();
+ }
+ }, token);
+ }如需进一步稳妥,可将 FightStatusFlag 也以 volatile/Interlocked 保护(参见上一条评论)。 🤖 Prompt for AI Agents |
||
|
|
||
| static double FindMax(double[] numbers) | ||
| { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.