diff --git a/BetterGenshinImpact/GameTask/AutoWood/AutoWoodTask.cs b/BetterGenshinImpact/GameTask/AutoWood/AutoWoodTask.cs
index 3f5e685c..072a1f8a 100644
--- a/BetterGenshinImpact/GameTask/AutoWood/AutoWoodTask.cs
+++ b/BetterGenshinImpact/GameTask/AutoWood/AutoWoodTask.cs
@@ -7,6 +7,8 @@ using BetterGenshinImpact.View.Drawable;
using BetterGenshinImpact.ViewModel.Pages;
using Microsoft.Extensions.Logging;
using System;
+using System.Diagnostics;
+using System.Threading;
using System.Windows;
using WindowsInput;
using static BetterGenshinImpact.GameTask.Common.TaskControl;
@@ -39,6 +41,12 @@ public class AutoWoodTask
try
{
Logger.LogInformation("→ {Text} 设置伐木总次数:{Cnt}", "自动伐木,启动!", taskParam.WoodRoundNum);
+
+ _login3rdParty.RefreshAvailabled();
+ if (_login3rdParty.Type == Login3rdParty.The3rdPartyType.Bilibili)
+ {
+ Logger.LogInformation("自动伐木启用B服模式");
+ }
SystemControl.ActivateWindow();
for (var i = 0; i < taskParam.WoodRoundNum; i++)
{
@@ -48,11 +56,6 @@ public class AutoWoodTask
break;
}
- _login3rdParty.RefreshAvailabled();
- if (_login3rdParty.Type == Login3rdParty.The3rdPartyType.Bilibili)
- {
- Logger.LogInformation("自动伐木启用B服模式");
- }
Felling(taskParam);
VisionContext.Instance().DrawContent.ClearAll();
Sleep(500, taskParam.Cts);
@@ -90,17 +93,28 @@ public class AutoWoodTask
private void PressZ(WoodTaskParam taskParam)
{
+ // IMPORTANT: MUST try focus before press Z
+ SystemControl.Focus(TaskContext.Instance().GameHandle);
+
if (_first)
{
var content = CaptureToContent(taskParam.Dispatcher.GameCapture);
var ra = content.CaptureRectArea.Find(_assets.TheBoonOfTheElderTreeRo);
if (ra.IsEmpty())
{
+#if TEST_WITHOUT_Z_ITEM
throw new NormalEndException("请先装备小道具「王树瑞佑」!");
+#else
+ Thread.Sleep(2000);
+ Simulation.SendInput.Keyboard.KeyPress(VirtualKeyCode.VK_Z);
+ Debug.WriteLine("[AutoWood] Z");
+ _first = false;
+#endif
}
else
{
Simulation.SendInput.Keyboard.KeyPress(VirtualKeyCode.VK_Z);
+ Debug.WriteLine("[AutoWood] Z");
_first = false;
}
}
@@ -113,10 +127,16 @@ public class AutoWoodTask
var ra = content.CaptureRectArea.Find(_assets.TheBoonOfTheElderTreeRo);
if (ra.IsEmpty())
{
+#if TEST_WITHOUT_Z_ITEM
throw new RetryException("未找到「王树瑞佑」");
+#else
+ Thread.Sleep(15000);
+#endif
}
Simulation.SendInput.Keyboard.KeyPress(VirtualKeyCode.VK_Z);
+ Debug.WriteLine("[AutoWood] Z");
+ Sleep(500, taskParam.Cts);
}, TimeSpan.FromSeconds(1), 120);
}
@@ -126,6 +146,7 @@ public class AutoWoodTask
private void PressEsc(WoodTaskParam taskParam)
{
Simulation.SendInput.Keyboard.KeyPress(VirtualKeyCode.ESCAPE);
+ Debug.WriteLine("[AutoWood] Esc");
Sleep(800, taskParam.Cts);
// 确认在菜单界面
try
@@ -147,31 +168,35 @@ public class AutoWoodTask
Logger.LogInformation("仍旧点击退出按钮");
}
-
// 点击退出
var captureArea = TaskContext.Instance().SystemInfo.CaptureAreaRect;
var assetScale = TaskContext.Instance().SystemInfo.AssetScale;
_clickOffset.Click((int)(50 * assetScale), captureArea.Height - (int)(50 * assetScale));
+ Debug.WriteLine("[AutoWood] Click exit button");
Sleep(500, taskParam.Cts);
// 点击确认
var content = CaptureToContent(taskParam.Dispatcher.GameCapture);
- content.CaptureRectArea.Find(_assets.ConfirmRo, ra => { ra.ClickCenter(); });
+ content.CaptureRectArea.Find(_assets.ConfirmRo, ra =>
+ {
+ ra.ClickCenter();
+ Debug.WriteLine("[AutoWood] Click confirm button");
+ });
}
private void EnterGame(WoodTaskParam taskParam)
{
+ if (_login3rdParty.IsAvailabled)
+ {
+ Sleep(1, taskParam.Cts);
+ _login3rdParty.Login(taskParam.Cts);
+ }
+
NewRetry.Do(() =>
{
Sleep(1, taskParam.Cts);
- if (_login3rdParty.IsAvailabled)
- {
- _login3rdParty.Login(taskParam.Cts);
- Sleep(2000, taskParam.Cts);
- }
-
var content = CaptureToContent(taskParam.Dispatcher.GameCapture);
var ra = content.CaptureRectArea.Find(_assets.EnterGameRo);
if (ra.IsEmpty())
@@ -182,6 +207,7 @@ public class AutoWoodTask
{
Simulation.SendInput.Mouse.LeftButtonClick();
Sleep(5000, taskParam.Cts);
+ Debug.WriteLine("[AutoWood] Click entry text");
}
}, TimeSpan.FromSeconds(1), 50);
}
diff --git a/BetterGenshinImpact/GameTask/AutoWood/Utils/Login3rdParty.cs b/BetterGenshinImpact/GameTask/AutoWood/Utils/Login3rdParty.cs
index c0c387e4..326aece7 100644
--- a/BetterGenshinImpact/GameTask/AutoWood/Utils/Login3rdParty.cs
+++ b/BetterGenshinImpact/GameTask/AutoWood/Utils/Login3rdParty.cs
@@ -7,7 +7,6 @@ using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
-using System.Threading.Tasks;
using Vanara.PInvoke;
using static BetterGenshinImpact.GameTask.Common.TaskControl;
@@ -77,15 +76,23 @@ internal sealed class Login3rdParty
}
}
- public async void Login(CancellationTokenSource cts)
+ public void Login(CancellationTokenSource cts)
{
- await Task.Run(() =>
+ int failCount = default;
+
+ while (!LoginPrivate(cts))
{
- while (!LoginPrivate(cts))
+ // It is necessary to support exitable trying.
+ // Can exit trying when over than 10s.
+ if (++failCount > 20)
{
- Sleep(500, cts);
+ Debug.WriteLine("[AutoWood] Give up to check login button and don't try again.");
+ break;
}
- }, cts.Token);
+ Debug.WriteLine($"[AutoWood] Fail to check login button {failCount} time(s).");
+ Sleep(500, cts);
+ }
+ Debug.WriteLine("[AutoWood] Exit while check login button.");
}
private bool LoginPrivate(CancellationTokenSource cts)
@@ -127,10 +134,11 @@ internal sealed class Login3rdParty
}
// Just for login WebUI chattering
- Sleep(400, cts);
+ Sleep(2000, cts);
var p = TaskContext.Instance().SystemInfo.CaptureAreaRect.GetCenterPoint();
p.Add(new(0, 125)).Click();
+ Debug.WriteLine("[AutoWood] Click login button for the B one");
return true;
}
return false;
diff --git a/BetterGenshinImpact/GameTask/SystemControl.cs b/BetterGenshinImpact/GameTask/SystemControl.cs
index 9d60b678..cdc9f193 100644
--- a/BetterGenshinImpact/GameTask/SystemControl.cs
+++ b/BetterGenshinImpact/GameTask/SystemControl.cs
@@ -1,15 +1,10 @@
using BetterGenshinImpact.Core.Simulator;
-using Fischless.GameCapture;
-using Microsoft.Xaml.Behaviors.Media;
using System;
using System.Diagnostics;
-using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Vanara.PInvoke;
-using WindowsInput;
-using Wpf.Ui.Appearance;
namespace BetterGenshinImpact.GameTask;
@@ -51,9 +46,9 @@ public class SystemControl
return hWnd == TaskContext.Instance().GameHandle;
}
- public static IntPtr GetForegroundWindowHandle()
+ public static nint GetForegroundWindowHandle()
{
- return (IntPtr)User32.GetForegroundWindow();
+ return (nint)User32.GetForegroundWindow();
}
public static nint FindHandleByProcessName(params string[] names)
@@ -85,7 +80,7 @@ public class SystemControl
}
}
- public static Process? GetProcessByHandle(IntPtr hWnd)
+ public static Process? GetProcessByHandle(nint hWnd)
{
try
{
@@ -105,7 +100,7 @@ public class SystemControl
///
///
///
- public static RECT GetWindowRect(IntPtr hWnd)
+ public static RECT GetWindowRect(nint hWnd)
{
// User32.GetWindowRect(hWnd, out var windowRect);
DwmApi.DwmGetWindowAttribute(hWnd, DwmApi.DWMWINDOWATTRIBUTE.DWMWA_EXTENDED_FRAME_BOUNDS, out var windowRect);
@@ -117,7 +112,7 @@ public class SystemControl
///
///
///
- public static RECT GetGameScreenRect(IntPtr hWnd)
+ public static RECT GetGameScreenRect(nint hWnd)
{
User32.GetClientRect(hWnd, out var clientRect);
return clientRect;
@@ -128,7 +123,7 @@ public class SystemControl
///
///
///
- public static RECT GetCaptureRect(IntPtr hWnd)
+ public static RECT GetCaptureRect(nint hWnd)
{
var windowRect = GetWindowRect(hWnd);
var gameScreenRect = GetGameScreenRect(hWnd);
@@ -139,7 +134,7 @@ public class SystemControl
return new RECT(left, top, right, bottom);
}
- public static void ActivateWindow(IntPtr hWnd)
+ public static void ActivateWindow(nint hWnd)
{
User32.ShowWindow(hWnd, ShowWindowCommand.SW_RESTORE);
User32.SetForegroundWindow(hWnd);
@@ -154,6 +149,20 @@ public class SystemControl
ActivateWindow(TaskContext.Instance().GameHandle);
}
+ public static void Focus(nint hWnd)
+ {
+ if (User32.IsWindow(hWnd))
+ {
+ _ = User32.SendMessage(hWnd, User32.WindowMessage.WM_SYSCOMMAND, User32.SysCommand.SC_RESTORE, 0);
+ _ = User32.SetForegroundWindow(hWnd);
+ while (User32.IsIconic(hWnd))
+ {
+ continue;
+ }
+ _ = User32.BringWindowToTop(hWnd);
+ }
+ }
+
public static bool IsFullScreenMode(IntPtr hWnd)
{
if (hWnd == IntPtr.Zero)