|
24 | 24 | using BetterGenshinImpact.Core.Recognition.OCR; |
25 | 25 | using BetterGenshinImpact.GameTask.Common; |
26 | 26 | using BetterGenshinImpact.GameTask.Common.Job; |
| 27 | +using GameTask.Model.GameUI; |
27 | 28 |
|
28 | 29 | namespace BetterGenshinImpact.GameTask.AutoArtifactSalvage; |
29 | 30 |
|
@@ -210,119 +211,43 @@ public async Task Start(CancellationToken ct) |
210 | 211 | private async Task Salvage5Star(string regularExpression, int maxNumToCheck) |
211 | 212 | { |
212 | 213 | int count = maxNumToCheck; |
213 | | - Queue<string> checkedArtifactAffixesQueue = new Queue<string>(); |
214 | | - int duplicateSum = 0; |
215 | | - while (count > 0 && duplicateSum < 3) |
216 | | - { |
217 | | - // VisionContext.Instance().DrawContent.ClearAll(); |
218 | | - // await Delay(400, this.ct); |
219 | | - |
220 | | - using var ra = CaptureToRectArea(); |
221 | | - using ImageRegion grid = ra.DeriveCrop(new Rect((int)(ra.Width * 0.025), (int)(ra.Width * 0.055), (int)(ra.Width * 0.66), (int)(ra.Width * 0.4))); |
222 | | - IEnumerable<Rect> gridItems = GetArtifactGridItems(grid.SrcMat); |
223 | 214 |
|
224 | | - //foreach (Rect item in gridItems) |
225 | | - //{ |
226 | | - // grid.DrawRect(item, item.GetHashCode().ToString(), new System.Drawing.Pen(System.Drawing.Color.Blue)); |
227 | | - //} |
228 | | - |
229 | | - bool anyItemChecked = false; |
230 | | - foreach (Rect item in gridItems) |
231 | | - { |
232 | | - using ImageRegion itemRegion = grid.DeriveCrop(item); |
233 | | - if (GetArtifactStatus(itemRegion.SrcMat) == ArtifactStatus.None) |
234 | | - { |
235 | | - anyItemChecked = true; |
236 | | - itemRegion.Click(); |
237 | | - await Delay(300, ct); |
238 | | - |
239 | | - using var ra1 = CaptureToRectArea(); |
240 | | - using ImageRegion grid1 = ra1.DeriveCrop(new Rect((int)(ra1.Width * 0.025), (int)(ra1.Width * 0.055), (int)(ra1.Width * 0.66), (int)(ra1.Width * 0.4))); |
241 | | - using ImageRegion itemRegion1 = grid1.DeriveCrop(item); |
242 | | - if (GetArtifactStatus(itemRegion1.SrcMat) == ArtifactStatus.Selected) |
243 | | - { |
244 | | - using ImageRegion card = ra1.DeriveCrop(new Rect((int)(ra1.Width * 0.70), (int)(ra1.Width * 0.055), (int)(ra1.Width * 0.24), (int)(ra1.Width * 0.29))); |
245 | | - string affixes = GetArtifactAffixes(card.SrcMat, OcrFactory.Paddle); |
246 | | - |
247 | | - if (checkedArtifactAffixesQueue.Any(c => c == affixes)) |
248 | | - { |
249 | | - duplicateSum++; |
250 | | - logger.LogInformation($"重复检查了该圣遗物"); |
251 | | - } |
252 | | - if (checkedArtifactAffixesQueue.Count >= 36) // 一个grid最多能看到36个完整的圣遗物 |
253 | | - { |
254 | | - checkedArtifactAffixesQueue.Dequeue(); |
255 | | - } |
256 | | - checkedArtifactAffixesQueue.Enqueue(affixes); |
257 | | - |
258 | | - if (IsMatchRegularExpression(affixes, regularExpression, out string msg)) |
259 | | - { |
260 | | - logger.LogInformation(message: msg); |
261 | | - } |
262 | | - else |
263 | | - { |
264 | | - itemRegion.Click(); |
265 | | - await Delay(100, ct); |
266 | | - } |
267 | | - if (duplicateSum >= 3) |
268 | | - { |
269 | | - break; |
270 | | - } |
271 | | - } |
272 | | - count--; |
273 | | - if (count <= 0) |
274 | | - { |
275 | | - break; |
276 | | - } |
277 | | - } |
278 | | - } |
279 | | - if (count <= 0 || duplicateSum >= 3) |
280 | | - { |
281 | | - break; |
282 | | - } |
283 | | - if (anyItemChecked) |
| 215 | + using var ra0 = CaptureToRectArea(); |
| 216 | + Rect gridRoi = new Rect((int)(ra0.Width * 0.025), (int)(ra0.Width * 0.055), (int)(ra0.Width * 0.66), (int)(ra0.Width * 0.4)); |
| 217 | + GridScreen gridScreen = new GridScreen(gridRoi, 3, 40, 28, 0.018, this.logger, this.ct); // 圣遗物分解Grid有4行9列 |
| 218 | + await foreach (ImageRegion itemRegion in gridScreen) |
| 219 | + { |
| 220 | + Rect gridRect = itemRegion.ToRect(); |
| 221 | + if (GetArtifactStatus(itemRegion.SrcMat) == ArtifactStatus.None) |
284 | 222 | { |
285 | | - for (int i = 0; i < 32; i++) // 先滚动大约三行半 |
286 | | - { |
287 | | - input.Mouse.VerticalScroll(-2); |
288 | | - await Delay(40, ct); |
289 | | - } |
| 223 | + itemRegion.Click(); |
| 224 | + await Delay(300, ct); |
290 | 225 |
|
291 | | - DateTimeOffset rollingEndTime = DateTime.Now.AddSeconds(2); |
292 | | - while (DateTime.Now < rollingEndTime) |
| 226 | + using var ra1 = CaptureToRectArea(); |
| 227 | + using ImageRegion itemRegion1 = ra1.DeriveCrop(gridRect + new Point(gridRoi.X, gridRoi.Y)); |
| 228 | + if (GetArtifactStatus(itemRegion1.SrcMat) == ArtifactStatus.Selected) |
293 | 229 | { |
294 | | - await Delay(60, ct); |
295 | | - using var ra2 = CaptureToRectArea(); |
296 | | - using ImageRegion grid2 = ra2.DeriveCrop(new Rect((int)(ra2.Width * 0.025), (int)(ra2.Width * 0.055), (int)(ra2.Width * 0.66), (int)(ra2.Width * 0.4))); |
297 | | - IEnumerable<Rect> gridItems2 = GetArtifactGridItems(grid2.SrcMat); |
298 | | - if (gridItems2.Min(i => i.Y) > (ra2.Width * 0.018)) // 精细滚动,保证完整地显示四行 |
| 230 | + using ImageRegion card = ra1.DeriveCrop(new Rect((int)(ra1.Width * 0.70), (int)(ra1.Width * 0.055), (int)(ra1.Width * 0.24), (int)(ra1.Width * 0.29))); |
| 231 | + string affixes = GetArtifactAffixes(card.SrcMat, OcrFactory.Paddle); |
| 232 | + |
| 233 | + if (IsMatchRegularExpression(affixes, regularExpression, out string msg)) |
299 | 234 | { |
300 | | - input.Mouse.VerticalScroll(-1); |
| 235 | + logger.LogInformation(message: msg); |
301 | 236 | } |
302 | 237 | else |
303 | 238 | { |
304 | | - break; |
| 239 | + itemRegion.Click(); |
| 240 | + await Delay(100, ct); |
305 | 241 | } |
306 | 242 | } |
307 | | - |
308 | | - grid.MoveTo(grid.Width, grid.Height); |
309 | | - await Delay(500, ct); |
310 | | - } |
311 | | - else |
312 | | - { |
313 | | - await Delay(400, ct); |
314 | | - logger.LogInformation("找不到可检查的圣遗物了"); |
315 | | - break; |
| 243 | + count--; |
| 244 | + if (count <= 0) |
| 245 | + { |
| 246 | + logger.LogInformation("检查次数已耗尽"); |
| 247 | + break; |
| 248 | + } |
316 | 249 | } |
317 | 250 | } |
318 | | - if (count <= 0) |
319 | | - { |
320 | | - logger.LogInformation("检查次数已耗尽"); |
321 | | - } |
322 | | - if (duplicateSum >= 3) |
323 | | - { |
324 | | - logger.LogInformation("重复检查次数过多,推断为找不到可检查的了"); |
325 | | - } |
326 | 251 | } |
327 | 252 |
|
328 | 253 | public static bool IsMatchRegularExpression(string affixes, string regularExpression, out string msg) |
@@ -352,33 +277,6 @@ public static string GetArtifactAffixes(Mat src, IOcrService ocrService) |
352 | 277 | return ocrResult.Text; |
353 | 278 | } |
354 | 279 |
|
355 | | - public static IEnumerable<Rect> GetArtifactGridItems(Mat src) |
356 | | - { |
357 | | - using Mat grey = src.CvtColor(ColorConversionCodes.BGR2GRAY); |
358 | | - |
359 | | - using Mat canny = grey.Canny(20, 40); |
360 | | - |
361 | | - Cv2.FindContours(canny, out var contours, out _, RetrievalModes.External, |
362 | | - ContourApproximationModes.ApproxSimple, null); |
363 | | - |
364 | | - IEnumerable<Rect> boxes = contours.Where(c => Cv2.MinAreaRect(c).Angle % 90 <= 1) // 剔除倾斜 |
365 | | - .Select(Cv2.BoundingRect).Where(r => |
366 | | - { |
367 | | - if (r.Height == 0) |
368 | | - { |
369 | | - return false; |
370 | | - } |
371 | | - return Math.Abs((float)r.Width / r.Height - 0.8) < 0.05; // 按形状筛选 |
372 | | - }).ToList(); |
373 | | - |
374 | | - //src.DrawContours(contours, -1, Scalar.Red); |
375 | | - |
376 | | - int biggestRectHeight = boxes.Max(b => b.Height); |
377 | | - boxes = boxes.Where(b => (float)b.Height / biggestRectHeight > 0.88); // 剔除太小的 |
378 | | - |
379 | | - return boxes.ToArray(); |
380 | | - } |
381 | | - |
382 | 280 | public static ArtifactStatus GetArtifactStatus(Mat src) |
383 | 281 | { |
384 | 282 | using Mat upperLine = new Mat(src, new Rect(0, 0, src.Width, (int)(src.Height * 0.19))); |
|
0 commit comments