diff --git a/BetterGenshinImpact/GameTask/GameLoading/Assets/1920x1080/choose_enter_game.png b/BetterGenshinImpact/GameTask/GameLoading/Assets/1920x1080/choose_enter_game.png new file mode 100644 index 00000000..3048f513 Binary files /dev/null and b/BetterGenshinImpact/GameTask/GameLoading/Assets/1920x1080/choose_enter_game.png differ diff --git a/BetterGenshinImpact/GameTask/GameLoading/Assets/GameLoadingAssets.cs b/BetterGenshinImpact/GameTask/GameLoading/Assets/GameLoadingAssets.cs index b2383b9d..8e1435a4 100644 --- a/BetterGenshinImpact/GameTask/GameLoading/Assets/GameLoadingAssets.cs +++ b/BetterGenshinImpact/GameTask/GameLoading/Assets/GameLoadingAssets.cs @@ -1,4 +1,4 @@ -using BetterGenshinImpact.Core.Recognition; +using BetterGenshinImpact.Core.Recognition; using BetterGenshinImpact.GameTask.Model; using OpenCvSharp; @@ -6,11 +6,21 @@ namespace BetterGenshinImpact.GameTask.GameLoading.Assets; public class GameLoadingAssets : BaseAssets { + public RecognitionObject ChooseEnterGameRo; public RecognitionObject EnterGameRo; public RecognitionObject WelkinMoonRo; private GameLoadingAssets() { + ChooseEnterGameRo = new RecognitionObject + { + Name = "ChooseEnterGame", + RecognitionType = RecognitionTypes.TemplateMatch, + TemplateImageMat = GameTaskManager.LoadAssetImage("GameLoading", "choose_enter_game.png"), + RegionOfInterest = new Rect(0, CaptureRect.Height / 2, CaptureRect.Width, CaptureRect.Height - CaptureRect.Height / 2), + DrawOnWindow = false + }.InitTemplate(); + EnterGameRo = new RecognitionObject { Name = "EnterGame", diff --git a/BetterGenshinImpact/GameTask/GameLoading/GameLoading.cs b/BetterGenshinImpact/GameTask/GameLoading/GameLoading.cs index 7b5f3cdf..88a3ac14 100644 --- a/BetterGenshinImpact/GameTask/GameLoading/GameLoading.cs +++ b/BetterGenshinImpact/GameTask/GameLoading/GameLoading.cs @@ -1,4 +1,4 @@ -using BetterGenshinImpact.Core.Config; +using BetterGenshinImpact.Core.Config; using BetterGenshinImpact.GameTask.GameLoading.Assets; using System; using System.Diagnostics; @@ -13,8 +13,13 @@ using System.Text.RegularExpressions; using System.Threading.Channels; using Microsoft.Win32; using System.Windows.Documents; - - +using System.Linq; +using System.Threading; +using System.Runtime.InteropServices; +using System.Text; +using BetterGenshinImpact.Core.Recognition.OpenCv; +using BetterGenshinImpact.Helpers.Extensions; +using Vanara.PInvoke; namespace BetterGenshinImpact.GameTask.GameLoading; @@ -49,6 +54,8 @@ public class GameLoadingTrigger : ITaskTrigger private string FileName = ""; + private bool biliLoginClicked = false; + public GameLoadingTrigger() { GameLoadingAssets.DestroyInstance(); @@ -57,8 +64,6 @@ public class GameLoadingTrigger : ITaskTrigger public void Init() { - - IsEnabled = _config.AutoEnterGameEnabled; // // 前面没有联动启动原神,这个任务也不用启动 @@ -68,9 +73,6 @@ public class GameLoadingTrigger : ITaskTrigger // } if (_config.RecordGameTimeEnabled) { - - - FileName = Path.GetFileName(_config.InstallPath); if (FileName == "GenshinImpact.exe") { GameServer = "hk4e_global"; @@ -78,7 +80,6 @@ public class GameLoadingTrigger : ITaskTrigger } if (FileName == "YuanShen.exe") { - string iniPath = Path.GetDirectoryName(_config.InstallPath) + "//config.ini"; string iniContent; string pattern = @" @@ -98,11 +99,6 @@ public class GameLoadingTrigger : ITaskTrigger { } - - - - - // channelValue = 1 : 官服 // channelValue = 14 : B服 if (channelValue == "1") @@ -117,7 +113,6 @@ public class GameLoadingTrigger : ITaskTrigger } - Debug.WriteLine($"[GameLoading] 从文件读取到游戏区服:{GameServer}"); // 这里注册表的优先级要比读取文件低,因为使用starward安装原神不会写入注册表 if (GameServer == null) @@ -126,9 +121,10 @@ public class GameLoadingTrigger : ITaskTrigger Debug.WriteLine($"[GameLoading] 从注册表读取到游戏区服:{GameServer}"); StartStarward(); } - } - } } + } + } + public bool StartStarward() { try @@ -147,12 +143,11 @@ public class GameLoadingTrigger : ITaskTrigger } catch (Exception ex) { - - Debug.WriteLine("[GameLoading] Starward记录时间失败"); return false; } } + public string GetGameServerRegistry() { try @@ -188,6 +183,7 @@ public class GameLoadingTrigger : ITaskTrigger } return ""; } + public bool IsStarwardProtocolRegistered() { try @@ -216,6 +212,7 @@ public class GameLoadingTrigger : ITaskTrigger // 如果键不存在或不符合条件,返回 false return false; } + public void OnCapture(CaptureContent content) { // 2s 一次 @@ -237,12 +234,81 @@ public class GameLoadingTrigger : ITaskTrigger return; } + // B服判断逻辑 + bool isBili = false; + try + { + var exePath = _config.InstallPath; + if (!string.IsNullOrEmpty(exePath)) + { + var configIni = Path.Combine(Path.GetDirectoryName(exePath)!, "config.ini"); + if (File.Exists(configIni)) + { + var lines = File.ReadAllLines(configIni); + foreach (var line in lines) + { + var kv = line.Trim(); + if (kv.StartsWith("channel=") && kv.EndsWith("14")) + { + isBili = true; + break; + } + } + } + } + } + catch (Exception ex) + { + TaskControl.Logger.LogWarning("B服判断异常: " + ex.Message); + } + // 官服流程:先识别并点击顶号或切号的后一次“进入游戏”弹窗按钮 + if (!isBili) + { + var extraEnterGameBtn = content.CaptureRectArea.Find(_assets.ChooseEnterGameRo); + if (!extraEnterGameBtn.IsEmpty()) + { + extraEnterGameBtn.Click(); + return; + } + } using var ra = content.CaptureRectArea.Find(_assets.EnterGameRo); if (!ra.IsEmpty()) { - // 随便找个相对点击的位置 - TaskContext.Instance().PostMessageSimulator.LeftButtonClickBackground(); - // TaskControl.Logger.LogInformation("自动开门"); + if (isBili) + { + if (!biliLoginClicked) + { + int failCount = 0; + while (true) + { + var process = Process.GetProcessesByName("YuanShen").FirstOrDefault(); + if (process != null && GetBiliLoginWindow(process) != IntPtr.Zero) + { + GameCaptureRegion.GameRegion1080PPosClick(960, 630); + TaskControl.Sleep(3000, CancellationToken.None); + if (GetBiliLoginWindow(process) != IntPtr.Zero) + { + GameCaptureRegion.GameRegion1080PPosClick(960, 630); + } + biliLoginClicked = true; + break; + } + failCount++; + if (failCount > 20) + { + break; + } + TaskControl.Sleep(500, CancellationToken.None); + } + } + // B服登录点击后,等待一小段时间再执行官服点击逻辑 + TaskControl.Sleep(5000, CancellationToken.None); + ClickEnterGameButton(); + } + else + { + ClickEnterGameButton(); + } return; } @@ -265,4 +331,36 @@ public class GameLoadingTrigger : ITaskTrigger return; } } -}; \ No newline at end of file + + // B服登录窗口检测(参考Login3rdParty) + private static IntPtr GetBiliLoginWindow(Process process) + { + IntPtr bHWnd = IntPtr.Zero; + User32.EnumWindows((hWnd, lParam) => + { + try + { + User32.GetWindowThreadProcessId(hWnd, out uint pid); + if (pid == process.Id) + { + int capacity = User32.GetWindowTextLength(hWnd); + StringBuilder title = new(capacity + 1); + User32.GetWindowText(hWnd, title, title.Capacity); + if (title.ToString().Contains("bilibili", StringComparison.OrdinalIgnoreCase)) + { + bHWnd = hWnd.DangerousGetHandle(); + return false; + } + } + } + catch { } + return true; + }, IntPtr.Zero); + return bHWnd; + } + + private void ClickEnterGameButton() + { + TaskContext.Instance().PostMessageSimulator.LeftButtonClickBackground(); + } +};