├── .gitignore
├── GenshinBalladsOfBreezeAider
├── App.config
├── obj
│ └── Debug
│ │ └── .NETFramework,Version=v4.5.AssemblyAttributes.cs
├── Properties
│ ├── Settings.settings
│ ├── Settings.Designer.cs
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ └── Resources.resx
├── Program.cs
├── GenshinBalladsOfBreezeAider.csproj
├── frmMain.resx
├── frmMain.Designer.cs
└── frmMain.cs
├── README.md
└── GenshinBalladsOfBreezeAider.sln
/.gitignore:
--------------------------------------------------------------------------------
1 | .vs/
2 | *.cache
3 | GenshinBalladsOfBreezeAider/obj/
4 | GenshinBalladsOfBreezeAider/bin/
5 |
--------------------------------------------------------------------------------
/GenshinBalladsOfBreezeAider/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/GenshinBalladsOfBreezeAider/obj/Debug/.NETFramework,Version=v4.5.AssemblyAttributes.cs:
--------------------------------------------------------------------------------
1 | //
2 | using System;
3 | using System.Reflection;
4 | [assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
5 |
--------------------------------------------------------------------------------
/GenshinBalladsOfBreezeAider/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # GenshinBalladsOfBreezeAider
2 |
3 | ### 2022.06.29(荒泷极上盛世豪鼓大祭典版本)说明
4 |
5 | 支持了自动点按
6 |
7 | 由于命中特效变大变华丽了导致影响了下一拍的识别, 以及长按弹起的图层放到了判定点标志的下面所以长按识别非常不稳定, 干脆砍掉了
8 |
9 | 我直接摆烂用自动点按+手动长按过任务拿奖励就算了, 不调参了
10 |
11 | ### 2021.10.21(镜花听世版本)说明
12 |
13 | 现已支持镜花听世活动的长按操作
14 |
15 | 添加F10快捷键开启自动演奏
16 |
17 | ### 以下是风物之歌版本的说明:
18 |
19 | 原神风花节风物之歌音游辅助程序, 能够自动演奏, 1920*1080分辨率下自测大师难度能全连
20 |
21 | 只是用简单的屏幕像素颜色识别和模拟按键实现的, 判断黄圈挡住黑圈的时候模拟按下对应的键, 低分辨率下识别率会比较低
22 |
23 | "更改文本、应用等项目的大小"不是100%的时候可能会由于换算小数结果不在预期导致识别位置偏差
24 |
25 | 食用方法:
26 |
27 | 1.以管理员身份运行本程序
28 |
29 | 2.打开原神到风物之歌选择难度界面
30 |
31 | 3.切换到桌面, 点击本程序的开始自动演奏
32 |
33 | 4.切换回原神, 点击开始演奏
34 |
--------------------------------------------------------------------------------
/GenshinBalladsOfBreezeAider/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // 此代码由工具生成。
4 | // 运行时版本:4.0.30319.42000
5 | //
6 | // 对此文件的更改可能会导致不正确的行为,并且如果
7 | // 重新生成代码,这些更改将会丢失。
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace GenshinBalladsOfBreezeAider.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/GenshinBalladsOfBreezeAider/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // 有关程序集的一般信息由以下
6 | // 控制。更改这些特性值可修改
7 | // 与程序集关联的信息。
8 | [assembly: AssemblyTitle("GenshinBalladsOfBreezeAider")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("GenshinBalladsOfBreezeAider")]
13 | [assembly: AssemblyCopyright("Copyright © 2021")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // 将 ComVisible 设置为 false 会使此程序集中的类型
18 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
19 | //请将此类型的 ComVisible 特性设置为 true。
20 | [assembly: ComVisible(false)]
21 |
22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
23 | [assembly: Guid("8f757167-5c25-4d6f-af68-5940dd1f2021")]
24 |
25 | // 程序集的版本信息由下列四个值组成:
26 | //
27 | // 主版本
28 | // 次版本
29 | // 生成号
30 | // 修订号
31 | //
32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
33 | //通过使用 "*",如下所示:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/GenshinBalladsOfBreezeAider.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.31005.135
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GenshinBalladsOfBreezeAider", "GenshinBalladsOfBreezeAider\GenshinBalladsOfBreezeAider.csproj", "{8F757167-5C25-4D6F-AF68-5940DD1F2021}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {8F757167-5C25-4D6F-AF68-5940DD1F2021}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {8F757167-5C25-4D6F-AF68-5940DD1F2021}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {8F757167-5C25-4D6F-AF68-5940DD1F2021}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {8F757167-5C25-4D6F-AF68-5940DD1F2021}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {A0BD4C93-75E0-4AB4-9436-C14D7E6081CB}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/GenshinBalladsOfBreezeAider/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Linq;
5 | using System.Security.Principal;
6 | using System.Threading.Tasks;
7 | using System.Windows.Forms;
8 |
9 | namespace GenshinBalladsOfBreezeAider
10 | {
11 | static class Program
12 | {
13 | ///
14 | /// 应用程序的主入口点。
15 | ///
16 | [STAThread]
17 | static void Main()
18 | {
19 | Application.EnableVisualStyles();
20 | Application.SetCompatibleTextRenderingDefault(false);
21 | WindowsIdentity identity = WindowsIdentity.GetCurrent();
22 | WindowsPrincipal principal = new WindowsPrincipal(identity);
23 | if (principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator))
24 | {
25 | Application.Run(new frmMain());
26 | }
27 | else
28 | {
29 | ProcessStartInfo startInfo = new ProcessStartInfo();
30 | startInfo.FileName = Application.ExecutablePath;
31 | startInfo.Arguments = string.Join(" ", "");
32 | startInfo.Verb = "runas";
33 | Process.Start(startInfo);
34 | Application.Exit();
35 | }
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/GenshinBalladsOfBreezeAider/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // 此代码由工具生成。
4 | // 运行时版本:4.0.30319.42000
5 | //
6 | // 对此文件的更改可能会导致不正确的行为,并且如果
7 | // 重新生成代码,这些更改将会丢失。
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace GenshinBalladsOfBreezeAider.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// 一个强类型的资源类,用于查找本地化的字符串等。
17 | ///
18 | // 此类是由 StronglyTypedResourceBuilder
19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
20 | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
21 | // (以 /str 作为命令选项),或重新生成 VS 项目。
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// 返回此类使用的缓存的 ResourceManager 实例。
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GenshinBalladsOfBreezeAider.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// 重写当前线程的 CurrentUICulture 属性,对
51 | /// 使用此强类型资源类的所有资源查找执行重写。
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/GenshinBalladsOfBreezeAider/GenshinBalladsOfBreezeAider.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {8F757167-5C25-4D6F-AF68-5940DD1F2021}
8 | WinExe
9 | GenshinBalladsOfBreezeAider
10 | GenshinBalladsOfBreezeAider
11 | v4.7.2
12 | 8.0
13 | 512
14 | true
15 |
16 |
17 |
18 | AnyCPU
19 | true
20 | full
21 | false
22 | bin\Debug\
23 | DEBUG;TRACE
24 | prompt
25 | 4
26 |
27 |
28 | AnyCPU
29 | pdbonly
30 | true
31 | bin\Release\
32 | TRACE
33 | prompt
34 | 4
35 |
36 |
37 |
38 |
39 |
40 |
41 | false
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | Form
61 |
62 |
63 | frmMain.cs
64 |
65 |
66 |
67 |
68 | frmMain.cs
69 |
70 |
71 | ResXFileCodeGenerator
72 | Resources.Designer.cs
73 | Designer
74 |
75 |
76 | True
77 | Resources.resx
78 | True
79 |
80 |
81 | SettingsSingleFileGenerator
82 | Settings.Designer.cs
83 |
84 |
85 | True
86 | Settings.settings
87 | True
88 |
89 |
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/GenshinBalladsOfBreezeAider/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/GenshinBalladsOfBreezeAider/frmMain.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/GenshinBalladsOfBreezeAider/frmMain.Designer.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace GenshinBalladsOfBreezeAider
3 | {
4 | partial class frmMain
5 | {
6 | ///
7 | /// 必需的设计器变量。
8 | ///
9 | private System.ComponentModel.IContainer components = null;
10 |
11 | ///
12 | /// 清理所有正在使用的资源。
13 | ///
14 | /// 如果应释放托管资源,为 true;否则为 false。
15 | protected override void Dispose(bool disposing)
16 | {
17 | if (disposing && (components != null))
18 | {
19 | components.Dispose();
20 | }
21 | base.Dispose(disposing);
22 | }
23 |
24 | #region Windows 窗体设计器生成的代码
25 |
26 | ///
27 | /// 设计器支持所需的方法 - 不要修改
28 | /// 使用代码编辑器修改此方法的内容。
29 | ///
30 | private void InitializeComponent()
31 | {
32 | this.btnStart = new System.Windows.Forms.Button();
33 | this.lblStatus = new System.Windows.Forms.Label();
34 | this.lblStatusTitle = new System.Windows.Forms.Label();
35 | this.groupGenshinProcess = new System.Windows.Forms.GroupBox();
36 | this.lblWarring = new System.Windows.Forms.Label();
37 | this.lblDpi = new System.Windows.Forms.Label();
38 | this.lblRatio = new System.Windows.Forms.Label();
39 | this.lblDpiTitle = new System.Windows.Forms.Label();
40 | this.lblRatioTitle = new System.Windows.Forms.Label();
41 | this.btnDebugScreenshot = new System.Windows.Forms.Button();
42 | this.lblWindowSize = new System.Windows.Forms.Label();
43 | this.lblWindowSizeTitle = new System.Windows.Forms.Label();
44 | this.lblWindowLocation = new System.Windows.Forms.Label();
45 | this.lblWindowLocationTitle = new System.Windows.Forms.Label();
46 | this.lblWindowType = new System.Windows.Forms.Label();
47 | this.lblWindowTypeTitle = new System.Windows.Forms.Label();
48 | this.debugTextBox = new System.Windows.Forms.TextBox();
49 | this.groupGenshinProcess.SuspendLayout();
50 | this.SuspendLayout();
51 | //
52 | // btnStart
53 | //
54 | this.btnStart.Enabled = false;
55 | this.btnStart.Location = new System.Drawing.Point(122, 241);
56 | this.btnStart.Name = "btnStart";
57 | this.btnStart.Size = new System.Drawing.Size(120, 30);
58 | this.btnStart.TabIndex = 0;
59 | this.btnStart.Text = "开始自动演奏(F10)";
60 | this.btnStart.UseVisualStyleBackColor = true;
61 | this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
62 | //
63 | // lblStatus
64 | //
65 | this.lblStatus.AutoSize = true;
66 | this.lblStatus.ForeColor = System.Drawing.Color.Red;
67 | this.lblStatus.Location = new System.Drawing.Point(120, 23);
68 | this.lblStatus.Name = "lblStatus";
69 | this.lblStatus.Size = new System.Drawing.Size(89, 12);
70 | this.lblStatus.TabIndex = 1;
71 | this.lblStatus.Text = "未找到原神进程";
72 | //
73 | // lblStatusTitle
74 | //
75 | this.lblStatusTitle.AutoSize = true;
76 | this.lblStatusTitle.Location = new System.Drawing.Point(49, 23);
77 | this.lblStatusTitle.Name = "lblStatusTitle";
78 | this.lblStatusTitle.Size = new System.Drawing.Size(65, 12);
79 | this.lblStatusTitle.TabIndex = 2;
80 | this.lblStatusTitle.Text = "程序状态:";
81 | //
82 | // groupGenshinProcess
83 | //
84 | this.groupGenshinProcess.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
85 | | System.Windows.Forms.AnchorStyles.Right)));
86 | this.groupGenshinProcess.Controls.Add(this.lblWarring);
87 | this.groupGenshinProcess.Controls.Add(this.lblDpi);
88 | this.groupGenshinProcess.Controls.Add(this.lblRatio);
89 | this.groupGenshinProcess.Controls.Add(this.lblDpiTitle);
90 | this.groupGenshinProcess.Controls.Add(this.lblRatioTitle);
91 | this.groupGenshinProcess.Controls.Add(this.btnDebugScreenshot);
92 | this.groupGenshinProcess.Controls.Add(this.lblWindowSize);
93 | this.groupGenshinProcess.Controls.Add(this.lblWindowSizeTitle);
94 | this.groupGenshinProcess.Controls.Add(this.lblWindowLocation);
95 | this.groupGenshinProcess.Controls.Add(this.lblWindowLocationTitle);
96 | this.groupGenshinProcess.Controls.Add(this.lblWindowType);
97 | this.groupGenshinProcess.Controls.Add(this.lblWindowTypeTitle);
98 | this.groupGenshinProcess.Location = new System.Drawing.Point(22, 53);
99 | this.groupGenshinProcess.Name = "groupGenshinProcess";
100 | this.groupGenshinProcess.Size = new System.Drawing.Size(304, 181);
101 | this.groupGenshinProcess.TabIndex = 4;
102 | this.groupGenshinProcess.TabStop = false;
103 | this.groupGenshinProcess.Text = "原神窗口信息";
104 | //
105 | // lblWarring
106 | //
107 | this.lblWarring.ForeColor = System.Drawing.Color.Red;
108 | this.lblWarring.Location = new System.Drawing.Point(6, 140);
109 | this.lblWarring.Name = "lblWarring";
110 | this.lblWarring.Size = new System.Drawing.Size(283, 38);
111 | this.lblWarring.TabIndex = 9;
112 | //
113 | // lblDpi
114 | //
115 | this.lblDpi.AutoSize = true;
116 | this.lblDpi.Location = new System.Drawing.Point(126, 117);
117 | this.lblDpi.Name = "lblDpi";
118 | this.lblDpi.Size = new System.Drawing.Size(29, 12);
119 | this.lblDpi.TabIndex = 8;
120 | this.lblDpi.Text = "未知";
121 | //
122 | // lblRatio
123 | //
124 | this.lblRatio.AutoSize = true;
125 | this.lblRatio.Location = new System.Drawing.Point(126, 93);
126 | this.lblRatio.Name = "lblRatio";
127 | this.lblRatio.Size = new System.Drawing.Size(29, 12);
128 | this.lblRatio.TabIndex = 8;
129 | this.lblRatio.Text = "未知";
130 | //
131 | // lblDpiTitle
132 | //
133 | this.lblDpiTitle.AutoSize = true;
134 | this.lblDpiTitle.Location = new System.Drawing.Point(7, 117);
135 | this.lblDpiTitle.Name = "lblDpiTitle";
136 | this.lblDpiTitle.Size = new System.Drawing.Size(35, 12);
137 | this.lblDpiTitle.TabIndex = 7;
138 | this.lblDpiTitle.Text = "DPI:";
139 | //
140 | // lblRatioTitle
141 | //
142 | this.lblRatioTitle.AutoSize = true;
143 | this.lblRatioTitle.Location = new System.Drawing.Point(6, 93);
144 | this.lblRatioTitle.Name = "lblRatioTitle";
145 | this.lblRatioTitle.Size = new System.Drawing.Size(53, 12);
146 | this.lblRatioTitle.TabIndex = 7;
147 | this.lblRatioTitle.Text = "长宽比:";
148 | //
149 | // btnDebugScreenshot
150 | //
151 | this.btnDebugScreenshot.Location = new System.Drawing.Point(216, 41);
152 | this.btnDebugScreenshot.Name = "btnDebugScreenshot";
153 | this.btnDebugScreenshot.Size = new System.Drawing.Size(75, 23);
154 | this.btnDebugScreenshot.TabIndex = 6;
155 | this.btnDebugScreenshot.Text = "显示位置";
156 | this.btnDebugScreenshot.UseVisualStyleBackColor = true;
157 | this.btnDebugScreenshot.Visible = false;
158 | this.btnDebugScreenshot.Click += new System.EventHandler(this.btnDebugScreenshot_Click);
159 | //
160 | // lblWindowSize
161 | //
162 | this.lblWindowSize.AutoSize = true;
163 | this.lblWindowSize.Location = new System.Drawing.Point(126, 69);
164 | this.lblWindowSize.Name = "lblWindowSize";
165 | this.lblWindowSize.Size = new System.Drawing.Size(29, 12);
166 | this.lblWindowSize.TabIndex = 0;
167 | this.lblWindowSize.Text = "未知";
168 | //
169 | // lblWindowSizeTitle
170 | //
171 | this.lblWindowSizeTitle.AutoSize = true;
172 | this.lblWindowSizeTitle.Location = new System.Drawing.Point(6, 69);
173 | this.lblWindowSizeTitle.Name = "lblWindowSizeTitle";
174 | this.lblWindowSizeTitle.Size = new System.Drawing.Size(53, 12);
175 | this.lblWindowSizeTitle.TabIndex = 0;
176 | this.lblWindowSizeTitle.Text = "分辨率:";
177 | //
178 | // lblWindowLocation
179 | //
180 | this.lblWindowLocation.AutoSize = true;
181 | this.lblWindowLocation.Location = new System.Drawing.Point(126, 45);
182 | this.lblWindowLocation.Name = "lblWindowLocation";
183 | this.lblWindowLocation.Size = new System.Drawing.Size(29, 12);
184 | this.lblWindowLocation.TabIndex = 0;
185 | this.lblWindowLocation.Text = "未知";
186 | //
187 | // lblWindowLocationTitle
188 | //
189 | this.lblWindowLocationTitle.AutoSize = true;
190 | this.lblWindowLocationTitle.Location = new System.Drawing.Point(6, 45);
191 | this.lblWindowLocationTitle.Name = "lblWindowLocationTitle";
192 | this.lblWindowLocationTitle.Size = new System.Drawing.Size(77, 12);
193 | this.lblWindowLocationTitle.TabIndex = 0;
194 | this.lblWindowLocationTitle.Text = "左上角坐标:";
195 | //
196 | // lblWindowType
197 | //
198 | this.lblWindowType.AutoSize = true;
199 | this.lblWindowType.Location = new System.Drawing.Point(126, 21);
200 | this.lblWindowType.Name = "lblWindowType";
201 | this.lblWindowType.Size = new System.Drawing.Size(29, 12);
202 | this.lblWindowType.TabIndex = 0;
203 | this.lblWindowType.Text = "未知";
204 | //
205 | // lblWindowTypeTitle
206 | //
207 | this.lblWindowTypeTitle.AutoSize = true;
208 | this.lblWindowTypeTitle.Location = new System.Drawing.Point(7, 21);
209 | this.lblWindowTypeTitle.Name = "lblWindowTypeTitle";
210 | this.lblWindowTypeTitle.Size = new System.Drawing.Size(65, 12);
211 | this.lblWindowTypeTitle.TabIndex = 0;
212 | this.lblWindowTypeTitle.Text = "窗口状态:";
213 | //
214 | // debugTextBox
215 | //
216 | this.debugTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
217 | | System.Windows.Forms.AnchorStyles.Left)
218 | | System.Windows.Forms.AnchorStyles.Right)));
219 | this.debugTextBox.Location = new System.Drawing.Point(11, 275);
220 | this.debugTextBox.Margin = new System.Windows.Forms.Padding(2);
221 | this.debugTextBox.Multiline = true;
222 | this.debugTextBox.Name = "debugTextBox";
223 | this.debugTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
224 | this.debugTextBox.Size = new System.Drawing.Size(315, 6);
225 | this.debugTextBox.TabIndex = 5;
226 | this.debugTextBox.Visible = false;
227 | //
228 | // frmMain
229 | //
230 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
231 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
232 | this.ClientSize = new System.Drawing.Size(348, 283);
233 | this.Controls.Add(this.debugTextBox);
234 | this.Controls.Add(this.groupGenshinProcess);
235 | this.Controls.Add(this.lblStatusTitle);
236 | this.Controls.Add(this.lblStatus);
237 | this.Controls.Add(this.btnStart);
238 | this.MaximizeBox = false;
239 | this.MinimizeBox = false;
240 | this.Name = "frmMain";
241 | this.Text = "原神风物之歌/镜花听世辅助程序";
242 | this.groupGenshinProcess.ResumeLayout(false);
243 | this.groupGenshinProcess.PerformLayout();
244 | this.ResumeLayout(false);
245 | this.PerformLayout();
246 |
247 | }
248 |
249 | #endregion
250 |
251 | private System.Windows.Forms.Button btnStart;
252 | private System.Windows.Forms.Label lblStatus;
253 | private System.Windows.Forms.Label lblStatusTitle;
254 | private System.Windows.Forms.GroupBox groupGenshinProcess;
255 | private System.Windows.Forms.Label lblWindowSize;
256 | private System.Windows.Forms.Label lblWindowSizeTitle;
257 | private System.Windows.Forms.Label lblWindowLocation;
258 | private System.Windows.Forms.Label lblWindowLocationTitle;
259 | private System.Windows.Forms.Label lblWindowType;
260 | private System.Windows.Forms.Label lblWindowTypeTitle;
261 | private System.Windows.Forms.TextBox debugTextBox;
262 | private System.Windows.Forms.Button btnDebugScreenshot;
263 | private System.Windows.Forms.Label lblRatio;
264 | private System.Windows.Forms.Label lblRatioTitle;
265 | private System.Windows.Forms.Label lblDpi;
266 | private System.Windows.Forms.Label lblDpiTitle;
267 | private System.Windows.Forms.Label lblWarring;
268 | }
269 | }
270 |
271 |
--------------------------------------------------------------------------------
/GenshinBalladsOfBreezeAider/frmMain.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Diagnostics;
5 | using System.Drawing;
6 | using System.Reflection;
7 | using System.Runtime.InteropServices;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 |
11 | namespace GenshinBalladsOfBreezeAider
12 | {
13 | public partial class frmMain : Form
14 | {
15 | private int genshinWindowX = 0;
16 | private int genshinWindowY = 0;
17 | private int genshinWindowWdith = 0;
18 | private int genshinWindowHeight = 0;
19 | private bool working = false;
20 |
21 | #region -- 按键钩子 --
22 | [DllImport("user32.dll", EntryPoint = "keybd_event")]
23 | public static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
24 | #endregion --按键钩子 --
25 |
26 | #region -- 窗口钩子 --
27 | [DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)]
28 | private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
29 |
30 | [DllImport("user32.dll")]
31 | private static extern int GetWindowRect(IntPtr hwnd, out Rectangle lpRect);
32 |
33 | [DllImport("user32.dll")]
34 | private static extern bool GetClientRect(IntPtr hwnd, out Rectangle lpRect);
35 |
36 | [DllImport("user32.dll")]
37 | private static extern IntPtr GetDC(IntPtr ptr);
38 | [DllImport("gdi32.dll")]
39 | private static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
40 | [DllImport("user32.dll", EntryPoint = "ReleaseDC")]
41 | private static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);
42 |
43 | const int HORZRES = 8;
44 | const int VERTRES = 10;
45 | const int DESKTOPVERTRES = 117;
46 | const int DESKTOPHORZRES = 118;
47 |
48 | private IntPtr hwndGenshin = IntPtr.Zero;
49 | #endregion -- 窗口钩子 --
50 |
51 | #region -- 按键监听钩子 --
52 | protected delegate int HookProc(int nCode, int wParam, IntPtr lParam);
53 |
54 | [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
55 | protected static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, int dwThreadId);
56 |
57 | [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
58 | protected static extern int UnhookWindowsHookEx(int idHook);
59 |
60 | [StructLayout(LayoutKind.Sequential)]
61 | protected class KeyboardHookStruct
62 | {
63 | public int vkCode;
64 | public int scanCode;
65 | public int flags;
66 | public int time;
67 | public int dwExtraInfo;
68 | }
69 |
70 | protected int _handleToHook;
71 | protected HookProc _hookCallback;
72 | #endregion -- 按键监听钩子 --
73 |
74 | public static float DpiScaleX
75 | {
76 | get
77 | {
78 | IntPtr hdc = GetDC(IntPtr.Zero);
79 | float ScaleX = (float)GetDeviceCaps(hdc, DESKTOPHORZRES) / (float)GetDeviceCaps(hdc, HORZRES);
80 | ReleaseDC(IntPtr.Zero, hdc);
81 | return ScaleX;
82 | }
83 | }
84 |
85 | public static float DpiScaleY
86 | {
87 | get
88 | {
89 | IntPtr hdc = GetDC(IntPtr.Zero);
90 | float ScaleY = (float)(float)GetDeviceCaps(hdc, DESKTOPVERTRES) / (float)GetDeviceCaps(hdc, VERTRES);
91 | ReleaseDC(IntPtr.Zero, hdc);
92 | return ScaleY;
93 | }
94 | }
95 |
96 | public frmMain() => InitializeComponent();
97 |
98 | protected override void OnShown(EventArgs e)
99 | {
100 | base.OnShown(e);
101 | #if DEBUG
102 | btnDebugScreenshot.Visible = true;
103 | debugTextBox.Visible = true;
104 | #endif
105 | _hookCallback = new HookProc(HookCallbackProcedure);
106 | _handleToHook = SetWindowsHookEx(13, _hookCallback, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
107 |
108 | FindGenshinProcess();
109 | }
110 |
111 | protected override void OnClosing(CancelEventArgs e)
112 | {
113 | UnhookWindowsHookEx(_handleToHook);
114 | Process.GetCurrentProcess().Kill();
115 | base.OnClosing(e);
116 | }
117 |
118 | private int HookCallbackProcedure(int nCode, int wParam, IntPtr lParam)
119 | {
120 | KeyboardHookStruct keyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
121 | if (wParam == 0x100 || wParam == 0x104) //KeyDown事件
122 | {
123 | switch (keyboardHookStruct.vkCode)
124 | {
125 | case (int)Keys.F12:
126 | SaveDebugImage();
127 | break;
128 | case (int)Keys.F11:
129 | Invoke(new Action(() => debugTextBox.AppendText($"{DateTime.Now.ToString("HH:mm:ss fff")}\r\n")));
130 | break;
131 | case (int)Keys.F10:
132 | Start();
133 | break;
134 | }
135 | }
136 | return 0;
137 | }
138 |
139 | private void FindGenshinProcess()
140 | {
141 | lblStatus.Text = $"未找到原神进程";
142 | lblStatus.ForeColor = Color.Red;
143 | Task.Run(() =>
144 | {
145 | while (!working)
146 | {
147 | while (hwndGenshin == IntPtr.Zero)
148 | {
149 | hwndGenshin = FindWindow("UnityWndClass", "原神");
150 | Task.Delay(100).Wait();
151 | }
152 |
153 | GetWindowRect(hwndGenshin, out Rectangle windowRect);
154 | GetClientRect(hwndGenshin, out Rectangle clientRect);
155 |
156 | Invoke(new Action(() =>
157 | {
158 | try
159 | {
160 | if (!working)
161 | {
162 | lblStatus.Text = $"已找到原神进程,未开始自动演奏";
163 | lblStatus.ForeColor = Color.Black;
164 | }
165 |
166 | if (windowRect.X < -16000 || (windowRect.X == 0 && windowRect.Y == 0 && windowRect.Width == Screen.PrimaryScreen.Bounds.Width && windowRect.Height == Screen.PrimaryScreen.Bounds.Height)) //全屏
167 | {
168 | genshinWindowX = 0;
169 | genshinWindowY = 0;
170 | genshinWindowWdith = (int)Math.Round(Screen.PrimaryScreen.Bounds.Width * DpiScaleX);
171 | genshinWindowHeight = (int)Math.Round(Screen.PrimaryScreen.Bounds.Height * DpiScaleY);
172 |
173 | lblWindowType.Text = "全屏";
174 | lblWindowLocation.Text = $"(0,0)";
175 | }
176 | else //窗口化
177 | {
178 | Rectangle tempRect = new Rectangle(windowRect.X, windowRect.Y, windowRect.Width - windowRect.X, windowRect.Height - windowRect.Y);
179 | Rectangle rect = new Rectangle(tempRect.X + (tempRect.Width - clientRect.Width) - 3, tempRect.Y + (tempRect.Height - clientRect.Height) - 3, clientRect.Width, clientRect.Height);
180 |
181 | if (DpiScaleX > 1 || DpiScaleY > 1)
182 | rect = new Rectangle((int)Math.Round(rect.X * DpiScaleX), (int)Math.Round(rect.Y * DpiScaleY), (int)Math.Round(rect.Width * DpiScaleX), (int)Math.Round(rect.Height * DpiScaleY));
183 |
184 | genshinWindowX = rect.X;
185 | genshinWindowY = rect.Y;
186 | genshinWindowWdith = rect.Width;
187 | genshinWindowHeight = rect.Height;
188 |
189 | lblWindowType.Text = "窗口化";
190 | lblWindowLocation.Text = $"({genshinWindowX},{genshinWindowY})";
191 | }
192 |
193 | lblDpi.Text = $"{DpiScaleX * 100}%";
194 |
195 | if (genshinWindowWdith / 16 * 9 == genshinWindowHeight)
196 | {
197 | lblRatio.Text = "16:9";
198 | lblRatio.ForeColor = Color.Black;
199 | lblWarring.Text = "";
200 |
201 | if (DpiScaleX != 1)
202 | lblWarring.Text = "您显示设置-更改文本、应用等项目的大小不是100%,可能在坐标换算中产生偏移。";
203 | }
204 | else
205 | {
206 | if (genshinWindowWdith / 16 * 10 == genshinWindowHeight)
207 | lblRatio.Text = "16:10";
208 | else if (genshinWindowWdith / 4 * 3 == genshinWindowHeight)
209 | lblRatio.Text = "4:3";
210 | else if (genshinWindowWdith / 5 * 4 == genshinWindowHeight)
211 | lblRatio.Text = "5:4";
212 | else
213 | lblRatio.Text = "未知";
214 | lblRatio.ForeColor = Color.Red;
215 | lblWarring.Text = "尚未适配当前分辨率,请切换到长宽比为16:9的分辨率";
216 | }
217 |
218 | lblWindowSize.Text = $"{genshinWindowWdith}×{genshinWindowHeight}";
219 |
220 | btnStart.Enabled = true;
221 | }
222 | catch
223 | {
224 | }
225 | }));
226 | Task.Delay(100).Wait();
227 | }
228 | });
229 | }
230 |
231 | private void btnStart_Click(object sender, EventArgs e) => Start();
232 |
233 | private void Start()
234 | {
235 | if (working)
236 | {
237 | working = false;
238 | btnStart.Text = "开始自动演奏(F10)";
239 | lblStatus.Text = $"已找到原神进程,未开始自动演奏";
240 | lblStatus.ForeColor = Color.Black;
241 | FindGenshinProcess();
242 | return;
243 | }
244 | else
245 | {
246 | debugIndex = 1;
247 | working = true;
248 | lblStatus.Text = $"已开始自动演奏";
249 | lblStatus.ForeColor = Color.Green;
250 | btnStart.Text = "停止自动演奏(F10)";
251 | }
252 | Task.Run(() =>
253 | {
254 | Dictionary dicKeysNextPressTime = new Dictionary();
255 |
256 | int width = (int)Math.Round(Screen.PrimaryScreen.Bounds.Width * DpiScaleX);
257 | int height = (int)Math.Round(Screen.PrimaryScreen.Bounds.Height * DpiScaleY);
258 |
259 | bool wHolding = false, sHolding = false, aHolding = false, dHolding = false, iHolding = false, kHolding = false, jHolding = false, lHolding = false;
260 |
261 | double aScaleX = 376 / 1920.0;
262 | double sScaleX = 573 / 1920.0;
263 | double dScaleX = 787 / 1920.0;
264 | double jScaleX = 1133 / 1920.0;
265 | double kScaleX = 1347 / 1920.0;
266 | double lScaleX = 1545 / 1920.0;
267 | double aScaleY = 731 / 1080.0;
268 | double sScaleY = 819 / 1080.0;
269 | double dScaleY = 870 / 1080.0;
270 | double jScaleY = 870 / 1080.0;
271 | double kScaleY = 819 / 1080.0;
272 | double lScaleY = 731 / 1080.0;
273 |
274 | //(double aTailX, double aTailY) = Rotate(376 + 190, 731, 376, 731, -45);
275 | //(double sTailX, double sTailY) = Rotate(573 + 190, 819, 573, 819, -60);
276 | //(double dTailX, double dTailY) = Rotate(787 + 190, 870, 787, 870, -75);
277 | //(double jTailX, double jTailY) = Rotate(1133 + 190, 870, 1133, 870, -105);
278 | //(double kTailX, double kTailY) = Rotate(1347 + 190, 819, 1347, 819, -120);
279 | //(double lTailX, double lTailY) = Rotate(1545 + 190, 731, 1545, 731, -135);
280 |
281 | //double aScaleTailX = aTailX / 1920.0;
282 | //double sScaleTailX = sTailX / 1920.0;
283 | //double dScaleTailX = dTailX / 1920.0;
284 | //double jScaleTailX = jTailX / 1920.0;
285 | //double kScaleTailX = kTailX / 1920.0;
286 | //double lScaleTailX = lTailX / 1920.0;
287 |
288 | //double aScaleTailY = aTailY / 1080.0;
289 | //double sScaleTailY = sTailY / 1080.0;
290 | //double dScaleTailY = dTailY / 1080.0;
291 | //double jScaleTailY = jTailY / 1080.0;
292 | //double kScaleTailY = kTailY / 1080.0;
293 | //double lScaleTailY = lTailY / 1080.0;
294 |
295 | while (working)
296 | {
297 | Bitmap memoryImage = new Bitmap(width, height);
298 | Graphics memoryGraphics = Graphics.FromImage(memoryImage);
299 | memoryGraphics.CopyFromScreen(0, 0, 0, 0, new Size(width, height));
300 |
301 | #region -- 镜花听世/风物之歌 --
302 | //StartAutoPressKeyAndRecordCD(dicKeysNextPressTime, memoryImage, 0.253125, 0.37685, Keys.W, 0.2526, 0.461, ref wHolding);
303 | //StartAutoPressKeyAndRecordCD(dicKeysNextPressTime, memoryImage, 0.253125, 0.823148, Keys.S, 0.253125, 0.773, ref sHolding);
304 | //StartAutoPressKeyAndRecordCD(dicKeysNextPressTime, memoryImage, 0.127083, 0.6, Keys.A, 0.165625, 0.616, ref aHolding);
305 | //StartAutoPressKeyAndRecordCD(dicKeysNextPressTime, memoryImage, 0.378125, 0.6, Keys.D, 0.340625, 0.616, ref dHolding);
306 | //StartAutoPressKeyAndRecordCD(dicKeysNextPressTime, memoryImage, 0.74739583, 0.37685, Keys.I, 0.7475, 0.461, ref iHolding);
307 | //StartAutoPressKeyAndRecordCD(dicKeysNextPressTime, memoryImage, 0.74739583, 0.823148, Keys.K, 0.7475, 0.773, ref kHolding);
308 | //StartAutoPressKeyAndRecordCD(dicKeysNextPressTime, memoryImage, 0.62135416, 0.6, Keys.J, 0.659, 0.616, ref jHolding);
309 | //StartAutoPressKeyAndRecordCD(dicKeysNextPressTime, memoryImage, 0.872917, 0.6, Keys.L, 0.835, 0.616, ref lHolding);
310 | #endregion -- 镜花听世/风物之歌 --
311 |
312 | #region -- 荒 泷 极 上 盛 世 豪 鼓 大 祭 典 --
313 | StartAutoPressKeyAndRecordCD2(dicKeysNextPressTime, memoryImage, aScaleX, aScaleY, Keys.A, ref aHolding);
314 | StartAutoPressKeyAndRecordCD2(dicKeysNextPressTime, memoryImage, sScaleX, sScaleY, Keys.S, ref sHolding);
315 | StartAutoPressKeyAndRecordCD2(dicKeysNextPressTime, memoryImage, dScaleX, dScaleY, Keys.D, ref dHolding);
316 | StartAutoPressKeyAndRecordCD2(dicKeysNextPressTime, memoryImage, jScaleX, jScaleY, Keys.J, ref jHolding);
317 | StartAutoPressKeyAndRecordCD2(dicKeysNextPressTime, memoryImage, kScaleX, kScaleY, Keys.K, ref kHolding);
318 | StartAutoPressKeyAndRecordCD2(dicKeysNextPressTime, memoryImage, lScaleX, lScaleY, Keys.L, ref lHolding);
319 | #endregion -- 荒 泷 极 上 盛 世 豪 鼓 大 祭 典 --
320 |
321 | memoryGraphics.Dispose();
322 | memoryImage.Dispose();
323 | }
324 | });
325 | }
326 |
327 | private void btnDebugScreenshot_Click(object sender, EventArgs e) => SaveDebugImage();
328 |
329 | [Obsolete]
330 | private void StartAutoPressKeyAndRecordCD(Dictionary dicKeysNextPressTime, Bitmap bmp, double scaleX, double scaleY, Keys key, double scaleHoldX, double scaleHoldY, ref bool holding)
331 | {
332 | if (dicKeysNextPressTime.ContainsKey(key))
333 | {
334 | if (dicKeysNextPressTime[key] < DateTime.Now)
335 | dicKeysNextPressTime[key] = StartAutoPressKey(bmp, scaleX, scaleY, key, scaleHoldX, scaleHoldY, ref holding);
336 | }
337 | else
338 | dicKeysNextPressTime.Add(key, StartAutoPressKey(bmp, scaleX, scaleY, key, scaleHoldX, scaleHoldY, ref holding));
339 | }
340 |
341 | private void StartAutoPressKeyAndRecordCD2(Dictionary dicKeysNextPressTime, Bitmap bmp, double scaleX, double scaleY, Keys key, ref bool holding)
342 | {
343 | if (dicKeysNextPressTime.ContainsKey(key))
344 | {
345 | if (dicKeysNextPressTime[key] < DateTime.Now)
346 | dicKeysNextPressTime[key] = StartAutoPressKey2(bmp, scaleX, scaleY, key, ref holding);
347 | }
348 | else
349 | dicKeysNextPressTime.Add(key, StartAutoPressKey2(bmp, scaleX, scaleY, key, ref holding));
350 | }
351 |
352 | private (double x, double y) Rotate(double targetX, double targetY, double centerX, double centerY, double angle)
353 | {
354 | double x = (targetX - centerX) * Math.Cos(Math.PI / 180.0 * angle) - (targetY - centerY) * Math.Sin(Math.PI / 180.0 * angle) + centerX;
355 | double y = (targetX - centerX) * Math.Sin(Math.PI / 180.0 * angle) + (targetY - centerY) * Math.Cos(Math.PI / 180.0 * angle) + centerY;
356 | return (x, y);
357 | }
358 |
359 | private int debugIndex = 1;
360 | private void SaveDebugImage()
361 | {
362 | int width = (int)Math.Round(Screen.PrimaryScreen.Bounds.Width * DpiScaleX);
363 | int height = (int)Math.Round(Screen.PrimaryScreen.Bounds.Height * DpiScaleY);
364 | Size size = new Size(width, height);
365 | Bitmap memoryImage = new Bitmap(width, height);
366 | Graphics memoryGraphics = Graphics.FromImage(memoryImage);
367 | memoryGraphics.CopyFromScreen(0, 0, 0, 0, size);
368 |
369 | #region -- 镜花听世/风物之歌 --
370 | #region -- 点按判定位置 --
371 | //DrawDebugLine(0.253125, 0.37685, memoryImage, Keys.W);
372 | //DrawDebugLine(0.253125, 0.823148, memoryImage, Keys.S);
373 | //DrawDebugLine(0.127083, 0.6, memoryImage, Keys.A);
374 | //DrawDebugLine(0.378125, 0.6, memoryImage, Keys.D);
375 | //DrawDebugLine(0.74739583, 0.37685, memoryImage, Keys.I);
376 | //DrawDebugLine(0.74739583, 0.823148, memoryImage, Keys.J);
377 | //DrawDebugLine(0.62135416, 0.6, memoryImage, Keys.K);
378 | //DrawDebugLine(0.872917, 0.6, memoryImage, Keys.L);
379 | #endregion -- 点按判定位置 --
380 |
381 | #region -- 长按判定位置 --
382 | //DrawDebugLine(0.2526, 0.461 - 0.15, memoryImage, Keys.W);
383 | //DrawDebugLine(0.165625, 0.616 - 0.15, memoryImage, Keys.S);
384 | //DrawDebugLine(0.253125, 0.773 - 0.15, memoryImage, Keys.A);
385 | //DrawDebugLine(0.340625, 0.616 - 0.15, memoryImage, Keys.D);
386 | //DrawDebugLine(0.7475, 0.461 - 0.15, memoryImage, Keys.I);
387 | //DrawDebugLine(0.659, 0.616 - 0.15, memoryImage, Keys.J);
388 | //DrawDebugLine(0.7475, 0.773 - 0.15, memoryImage, Keys.K);
389 | //DrawDebugLine(0.835, 0.616 - 0.15, memoryImage, Keys.L);
390 | #endregion -- 长按判定位置 --
391 | #endregion -- 镜花听世/风物之歌 --
392 |
393 | #region -- 荒 泷 极 上 盛 世 豪 鼓 大 祭 典 --
394 | DrawDebugLine(376 / 1920.0, 731 / 1080.0, memoryImage, Keys.A);
395 | DrawDebugLine(573 / 1920.0, 819 / 1080.0, memoryImage, Keys.S);
396 | DrawDebugLine(787 / 1920.0, 870 / 1080.0, memoryImage, Keys.D);
397 | DrawDebugLine(1133 / 1920.0, 870 / 1080.0, memoryImage, Keys.J);
398 | DrawDebugLine(1347 / 1920.0, 819 / 1080.0, memoryImage, Keys.K);
399 | DrawDebugLine(1545 / 1920.0, 731 / 1080.0, memoryImage, Keys.L);
400 |
401 | //(double aX, double aY) = Rotate(376 + 190, 731, 376, 731, -45);
402 | //(double sX, double sY) = Rotate(573 + 190, 819, 573, 819, -60);
403 | //(double dX, double dY) = Rotate(787 + 190, 870, 787, 870, -75);
404 | //(double jX, double jY) = Rotate(1133 + 190, 870, 1133, 870, -105);
405 | //(double kX, double kY) = Rotate(1347 + 190, 819, 1347, 819, -120);
406 | //(double lX, double lY) = Rotate(1545 + 190, 731, 1545, 731, -135);
407 |
408 | //DrawDebugLine(aX / 1920.0, aY / 1080.0, memoryImage, Keys.A);
409 | //DrawDebugLine(sX / 1920.0, sY / 1080.0, memoryImage, Keys.S);
410 | //DrawDebugLine(dX / 1920.0, dY / 1080.0, memoryImage, Keys.D);
411 | //DrawDebugLine(jX / 1920.0, jY / 1080.0, memoryImage, Keys.J);
412 | //DrawDebugLine(kX / 1920.0, kY / 1080.0, memoryImage, Keys.K);
413 | //DrawDebugLine(lX / 1920.0, lY / 1080.0, memoryImage, Keys.L);
414 | #endregion -- 荒 泷 极 上 盛 世 豪 鼓 大 祭 典 --
415 |
416 | memoryImage.Save(Application.StartupPath + @$"\Screenshot{debugIndex++}.jpg");
417 |
418 | void DrawDebugLine(double scaleX, double scaleY, Bitmap highDpiScreenshot, Keys key)
419 | {
420 | int xw = (int)Math.Round(genshinWindowWdith * scaleX) + genshinWindowX;
421 | int yw = (int)Math.Round(genshinWindowHeight * scaleY) + genshinWindowY;
422 | for (int i = xw - 25; i < xw + 25; i++)
423 | highDpiScreenshot.SetPixel(i, yw, Color.Red);
424 | for (int i = yw - 25; i < yw + 25; i++)
425 | highDpiScreenshot.SetPixel(xw, i, Color.Red);
426 | Graphics g = Graphics.FromImage(highDpiScreenshot);
427 | g.DrawString(key.ToString(), new Font("宋体", 12), Brushes.Red, xw, yw);
428 | g.Dispose();
429 | }
430 | }
431 |
432 | [Obsolete]
433 | private DateTime StartAutoPressKey(Bitmap bmp, double scaleX, double scaleY, Keys key, double scaleHoldX, double scaleHoldY, ref bool holding)
434 | {
435 | byte byteKey = (byte)key;
436 | byte code = key switch
437 | {
438 | Keys.W => Convert.ToByte(0x11),
439 | Keys.S => Convert.ToByte(0x1F),
440 | Keys.A => Convert.ToByte(0x1E),
441 | Keys.D => Convert.ToByte(0x20),
442 | Keys.I => Convert.ToByte(0x17),
443 | Keys.K => Convert.ToByte(0x25),
444 | Keys.J => Convert.ToByte(0x24),
445 | Keys.L => Convert.ToByte(0x26),
446 | _ => throw new Exception()
447 | };
448 |
449 | if (holding)
450 | {
451 | //弹起
452 | int xHold = (int)Math.Round(genshinWindowWdith * scaleHoldX) + genshinWindowX;
453 | int yHold = (int)Math.Round(genshinWindowHeight * scaleHoldY) + genshinWindowY;
454 | int yTail = (int)Math.Round(genshinWindowHeight * (scaleHoldY - 0.15)) + genshinWindowY;
455 |
456 | var colorHold = bmp.GetPixel(xHold, yHold);
457 | var colorTail = bmp.GetPixel(xHold, yTail);
458 |
459 | if (colorHold.R > 240 && colorHold.G > 210 && colorHold.B > 210 && colorTail.B < 250)
460 | {
461 | Task.Run(() => keybd_event(byteKey, code, 2, 0));
462 | holding = false;
463 | if (debugTextBox.Visible)
464 | BeginInvoke(new Action(() => debugTextBox.AppendText($"弹起按键:{key} ----{DateTime.Now}\r\n")));
465 | //SaveDebugImage()");
466 | return DateTime.Now;
467 | }
468 | }
469 | else
470 | {
471 | //点按
472 | int x = (int)Math.Round(genshinWindowWdith * scaleX) + genshinWindowX;
473 | int y = (int)Math.Round(genshinWindowHeight * scaleY) + genshinWindowY;
474 |
475 | Color color = bmp.GetPixel(x, y);
476 | if (color.R > 240 && color.G > 210 && color.G < 240 && color.B > 50 && color.B < 80)
477 | {
478 | keybd_event(byteKey, code, 0, 0);
479 | if (debugTextBox.Visible)
480 | BeginInvoke(new Action(() => debugTextBox.AppendText($"点按按键{key}----{DateTime.Now}\r\n")));
481 | Task.Delay(50).ContinueWith(_ => keybd_event(byteKey, code, 2, 0));
482 | //SaveDebugImage();
483 | return DateTime.Now.AddMilliseconds(200);
484 | }
485 |
486 | //长按
487 | int xHold = (int)Math.Round(genshinWindowWdith * scaleHoldX) + genshinWindowX;
488 | int yHold = (int)Math.Round(genshinWindowHeight * scaleHoldY) + genshinWindowY;
489 | int yTail = (int)Math.Round(genshinWindowHeight * (scaleHoldY - 0.15)) + genshinWindowY;
490 |
491 | var colorHold = bmp.GetPixel(xHold, yHold);
492 | var colorTail = bmp.GetPixel(xHold, yTail);
493 |
494 | if (colorHold.R > 240 && colorHold.G > 240 && colorHold.B > 230 && colorTail.B == 255)
495 | {
496 | keybd_event(byteKey, code, 1, 0);
497 | holding = true;
498 |
499 | if (debugTextBox.Visible)
500 | BeginInvoke(new Action(() => debugTextBox.AppendText($"按住按键:{key} ----{DateTime.Now}\r\n")));
501 | //SaveDebugImage();
502 | return DateTime.Now.AddMilliseconds(500);
503 | }
504 | }
505 | return DateTime.Now;
506 | }
507 |
508 |
509 | private DateTime StartAutoPressKey2(Bitmap bmp, double scaleX, double scaleY, Keys key, ref bool holding)
510 | {
511 | byte byteKey = (byte)key;
512 | byte code = key switch
513 | {
514 | Keys.W => Convert.ToByte(0x11),
515 | Keys.S => Convert.ToByte(0x1F),
516 | Keys.A => Convert.ToByte(0x1E),
517 | Keys.D => Convert.ToByte(0x20),
518 | Keys.I => Convert.ToByte(0x17),
519 | Keys.K => Convert.ToByte(0x25),
520 | Keys.J => Convert.ToByte(0x24),
521 | Keys.L => Convert.ToByte(0x26),
522 | _ => throw new Exception()
523 | };
524 |
525 | //点按
526 | int x = (int)Math.Round(genshinWindowWdith * scaleX) + genshinWindowX;
527 | int y = (int)Math.Round(genshinWindowHeight * scaleY) + genshinWindowY;
528 |
529 | Color color = bmp.GetPixel(x, y);
530 | if (color.B < 200)
531 | {
532 | keybd_event(byteKey, code, 0, 0);
533 | if (debugTextBox.Visible)
534 | BeginInvoke(new Action(() => debugTextBox.AppendText($"点按按键{key}----{DateTime.Now}\r\n")));
535 | Task.Delay(20).ContinueWith(_ => keybd_event(byteKey, code, 2, 0));
536 | //SaveDebugImage();
537 | return DateTime.Now.AddMilliseconds(100);
538 | }
539 | return DateTime.Now;
540 | }
541 | }
542 | }
543 |
--------------------------------------------------------------------------------