From 07c3a912c5c40119aba8bc100e28240901e5fc6b Mon Sep 17 00:00:00 2001 From: zdAnQi <131591012+zaodonganqi@users.noreply.github.com> Date: Wed, 9 Jul 2025 23:20:13 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=BA=E5=8C=96=E8=87=AA=E5=8A=A8=E7=82=B9?= =?UTF-8?q?=E5=87=BB=E7=99=BB=E5=BD=95=20(#1853)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Assets/1920x1080/choose_enter_game.png | Bin 0 -> 2551 bytes .../GameLoading/Assets/GameLoadingAssets.cs | 12 +- .../GameTask/GameLoading/GameLoading.cs | 144 +++++++++++++++--- 3 files changed, 132 insertions(+), 24 deletions(-) create mode 100644 BetterGenshinImpact/GameTask/GameLoading/Assets/1920x1080/choose_enter_game.png 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 0000000000000000000000000000000000000000..3048f513ce5e5caf467ff51ea74856e98f528482 GIT binary patch literal 2551 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 { + 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(); + } +};