Skip to content

Commit 156be9a

Browse files
committed
ok
1 parent 46a6188 commit 156be9a

7 files changed

Lines changed: 410 additions & 1 deletion

File tree

README.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,24 @@
1-
# SimpleLauncher
1+
<img src="./Xunkong.SimpleLauncher/Icon.png" style="float: left;" />
2+
3+
# 原神 简单启动器
4+
5+
> 寻空的右键快速启动在 Win11 上不能用了
6+
7+
正如其名,这是一个简单启动器,直接运行时会打开原神游戏本体,以管理员权限运行时会打开原神启动器。
8+
9+
如果设置了米游社Cookie,启动成功后自动检查洞天宝钱和参量质变仪的状态,可收取或可用则会发送系统通知,否则无事发生。
10+
11+
压缩包内有一个设置文件 `Config.txt`,以下设置均**可不填写**
12+
13+
| 名称 | 可填内容 | 备注 |
14+
| --- | --- | --- |
15+
| GenshinGamePath | `string` | 原神本体位置,不要有引号 |
16+
| GenshinLauncherPath | `string` | 原神启动器位置,不要有引号 |
17+
| IsPopupWindow | `bool` | 是否以无边框窗口启动 |
18+
| IsFullScreen | `bool` | 是否以全屏模式启动 |
19+
| Width | `uint` | 启动时窗口宽,以全屏模式启动时忽略此项 |
20+
| Height |`uint` | 启动时窗口高,以全屏模式启动时忽略此项 |
21+
| Cookie | `string` | 米游社Cookie,不要换行 |
22+
| HomeCoinNotifyRatio | `double` | 洞天宝钱提醒阈值,0到1之间 |
23+
24+
> 顶级语句非常适合写面向过程

Xunkong.SimpleLauncher.sln

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.2.32602.215
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xunkong.SimpleLauncher", "Xunkong.SimpleLauncher\Xunkong.SimpleLauncher.csproj", "{A4E12812-AA3E-4482-8B81-39E89CF86C1A}"
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+
{A4E12812-AA3E-4482-8B81-39E89CF86C1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{A4E12812-AA3E-4482-8B81-39E89CF86C1A}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{A4E12812-AA3E-4482-8B81-39E89CF86C1A}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{A4E12812-AA3E-4482-8B81-39E89CF86C1A}.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 = {C9D8302D-C890-4C01-A064-8CDD65BCB140}
24+
EndGlobalSection
25+
EndGlobal

Xunkong.SimpleLauncher/Config.txt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# ԭ�� �������� v0.1.0
2+
# by Scighost
3+
# ��Ŀ��ַ: https://github.com/xunkong/SimpleLauncher
4+
# ͼƬ��Դ: https://twitter.com/shenhedailys/status/1479312855518236675
5+
6+
# ����
7+
# ��������������һ������������ֱ������ʱ���ԭ����Ϸ���壬�Թ���ԱȨ������ʱ���ԭ����������
8+
# ���������������Cookie�������ɹ����Զ�������Ѷ��챦Ǯ�Ͳ����ʱ��ǵ�״̬������ȡ�������ᷢ��ϵͳ֪ͨ���������·�����
9+
10+
11+
# �������þ��ɲ���д
12+
13+
# ԭ����λ�ã���Ҫ������
14+
GenshinGamePath=C:\Program Files\Genshin Impact\Genshin Impact Game\YuanShen.exe
15+
16+
# ԭ��������λ�ã���Ҫ������
17+
GenshinLauncherPath=C:\Program Files\Genshin Impact\launcher.exe
18+
19+
# �Ƿ����ޱ߿򴰿����� ��true | false��
20+
IsPopupWindow=
21+
22+
# �Ƿ���ȫ��ģʽ���� ��true | false��
23+
IsFullScreen=
24+
25+
# ����ʱ���ڿ��ߣ���ȫ��ģʽ����ʱ���Դ��� ����������
26+
Width=
27+
Height=
28+
29+
# ������Cookie����Ҫ����
30+
# ��λ�ȡ������Cookie����ο� https://xunkong.cc/help/desktop/account.html
31+
Cookie=
32+
33+
# ���챦Ǯ������ֵ ��0��1֮�䣩
34+
HomeCoinNotifyRatio=0.8

Xunkong.SimpleLauncher/Icon.ico

208 KB
Binary file not shown.

Xunkong.SimpleLauncher/Icon.png

40.4 KB
Loading

Xunkong.SimpleLauncher/Program.cs

Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
using Microsoft.Win32;
2+
using System.ComponentModel;
3+
using System.Diagnostics;
4+
using System.Security.Principal;
5+
using System.Text;
6+
using System.Text.RegularExpressions;
7+
using Windows.Data.Xml.Dom;
8+
using Windows.UI.Notifications;
9+
using Xunkong.Hoyolab;
10+
11+
12+
13+
14+
string? genshinGamePath = null;
15+
string? genshinLauncherPath = null;
16+
bool? popupWindow = null;
17+
bool? fullScreen = null;
18+
uint? width = null;
19+
uint? height = null;
20+
string? cookie = null;
21+
double homeCoinNotifyRatio = 0.8;
22+
23+
const string REG_PATH = @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\原神\";
24+
const string REG_KEY = "InstallPath";
25+
26+
27+
28+
29+
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
30+
var timer = new System.Timers.Timer(30000);
31+
timer.Elapsed += Timer_Elapsed;
32+
33+
var ps = Process.GetProcessesByName("YuanShen").Concat(Process.GetProcessesByName("GenshinImpact"));
34+
if (ps.Any())
35+
{
36+
await SendNotificationAsync("出错了", "已有游戏进程在运行");
37+
return;
38+
}
39+
40+
41+
42+
// 加载配置
43+
var baseDir = AppContext.BaseDirectory;
44+
var configPath = Path.Combine(baseDir, "Config.txt");
45+
if (File.Exists(configPath))
46+
{
47+
var configLines = await File.ReadAllLinesAsync(configPath);
48+
foreach (var configLine in configLines)
49+
{
50+
if (configLine.StartsWith("#"))
51+
{
52+
continue;
53+
}
54+
var key = configLine.Split("=").FirstOrDefault();
55+
var value = configLine.Replace($"{key}=", "");
56+
switch (key)
57+
{
58+
case "GenshinGamePath":
59+
genshinGamePath = value;
60+
break;
61+
case "GenshinLauncherPath":
62+
genshinLauncherPath = value;
63+
break;
64+
case "IsPopupWindow":
65+
if (bool.TryParse(value, out var result1))
66+
{
67+
popupWindow = result1;
68+
}
69+
break;
70+
case "IsFullScreen":
71+
if (bool.TryParse(value, out var result2))
72+
{
73+
fullScreen = result2;
74+
}
75+
break;
76+
case "Width":
77+
if (uint.TryParse(value, out var result3))
78+
{
79+
width = result3;
80+
}
81+
break;
82+
case "Height":
83+
if (uint.TryParse(value, out var result4))
84+
{
85+
height = result4;
86+
}
87+
break;
88+
case "Cookie":
89+
cookie = value;
90+
break;
91+
case "HomeCoinNotifyRatio":
92+
if (double.TryParse(value, out var result5))
93+
{
94+
homeCoinNotifyRatio = result5;
95+
}
96+
break;
97+
default:
98+
break;
99+
}
100+
}
101+
}
102+
103+
104+
105+
if (IsAdministrator())
106+
{
107+
// 运行原神启动器
108+
if (!File.Exists(genshinLauncherPath))
109+
{
110+
genshinLauncherPath = Registry.GetValue(REG_PATH, REG_KEY, null) as string;
111+
}
112+
if (File.Exists(genshinLauncherPath))
113+
{
114+
Process.Start(new ProcessStartInfo
115+
{
116+
FileName = genshinLauncherPath,
117+
UseShellExecute = true,
118+
Verb = "runas",
119+
});
120+
}
121+
else
122+
{
123+
await SendNotificationAsync("出错了", "无法找到原神启动器文件");
124+
return;
125+
}
126+
}
127+
else
128+
{
129+
// 运行原神游戏
130+
if (!File.Exists(genshinGamePath))
131+
{
132+
genshinLauncherPath = Registry.GetValue(REG_PATH, REG_KEY, null) as string;
133+
if (!string.IsNullOrWhiteSpace(genshinLauncherPath))
134+
{
135+
var genshinConfigPath = Path.Combine(genshinLauncherPath, "config.ini");
136+
if (File.Exists(configPath))
137+
{
138+
var str = await File.ReadAllTextAsync(genshinConfigPath);
139+
var gamePath = Regex.Match(str, @"game_install_path=(.+)").Groups[1].Value.Trim();
140+
if (!string.IsNullOrWhiteSpace(gamePath))
141+
{
142+
genshinGamePath = Path.Combine(gamePath, "YuanShen.exe");
143+
}
144+
}
145+
}
146+
}
147+
if (File.Exists(genshinGamePath))
148+
{
149+
var sb = new StringBuilder();
150+
if (fullScreen ?? false)
151+
{
152+
sb.Append("-screen-fullscreen ");
153+
}
154+
else if (popupWindow ?? false)
155+
{
156+
sb.Append("-popupwindow ");
157+
if (width is not null && height is not null && width * height > 0)
158+
{
159+
sb.Append($"-screen-width {width} -screen-height {height}");
160+
}
161+
}
162+
Process.Start(new ProcessStartInfo
163+
{
164+
FileName = genshinGamePath,
165+
UseShellExecute = true,
166+
Arguments = sb.ToString(),
167+
Verb = "runas",
168+
});
169+
}
170+
else
171+
{
172+
await SendNotificationAsync("出错了", "无法找到原神游戏文件");
173+
return;
174+
}
175+
}
176+
177+
178+
if (!string.IsNullOrWhiteSpace(cookie))
179+
{
180+
var client = new HoyolabClient();
181+
var roles = await client.GetGenshinRoleInfosAsync(cookie);
182+
bool showNotification = false;
183+
var sb = new StringBuilder();
184+
foreach (var role in roles)
185+
{
186+
bool homeCoin = false, transformer = false;
187+
var dailyNote = await client.GetDailyNoteAsync(role);
188+
if (dailyNote.CurrentHomeCoin > dailyNote.MaxHomeCoin * homeCoinNotifyRatio)
189+
{
190+
homeCoin = true;
191+
}
192+
if (dailyNote.Transformer?.RecoveryTime?.Reached ?? false)
193+
{
194+
transformer = true;
195+
}
196+
if (homeCoin || transformer)
197+
{
198+
showNotification = true;
199+
sb.AppendLine($"{role.Nickname}{(homeCoin ? "洞天宝钱 " : "")}{(transformer ? "参量质变仪" : "")}");
200+
}
201+
}
202+
if (showNotification)
203+
{
204+
await SendNotificationAsync("注意了", sb.ToString());
205+
}
206+
}
207+
208+
209+
210+
211+
212+
213+
214+
215+
async void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
216+
{
217+
if (e.ExceptionObject is Win32Exception win32Ex)
218+
{
219+
if (win32Ex.NativeErrorCode == 1223)
220+
{
221+
return;
222+
}
223+
}
224+
if (e.ExceptionObject is Exception ex)
225+
{
226+
await SendNotificationAsync("出错了", $"{ex.GetType().Name}\n{ex.Message}");
227+
}
228+
else
229+
{
230+
await SendNotificationAsync("出错了", "不知道什么错误");
231+
}
232+
}
233+
234+
235+
async void Timer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
236+
{
237+
await SendNotificationAsync("出错了", "执行超时");
238+
Environment.Exit(1);
239+
}
240+
241+
242+
243+
244+
245+
246+
static bool IsAdministrator()
247+
{
248+
WindowsIdentity identity = WindowsIdentity.GetCurrent();
249+
WindowsPrincipal principal = new WindowsPrincipal(identity);
250+
return principal.IsInRole(WindowsBuiltInRole.Administrator);
251+
}
252+
253+
254+
255+
256+
static async Task SendNotificationAsync(string title, string? message = null)
257+
{
258+
try
259+
{
260+
var icon = Path.Combine(AppContext.BaseDirectory, "Icon.png");
261+
const string key = @"HKEY_CURRENT_USER\Software\Classes\AppUserModelId\Xunkong.SimpleLauncher";
262+
Registry.SetValue(key, "DisplayName", "简单启动器", RegistryValueKind.String);
263+
Registry.SetValue(key, "IconBackgroundColor", "FFDDDDDD", RegistryValueKind.String);
264+
Registry.SetValue(key, "IconUri", icon, RegistryValueKind.String);
265+
var toastContent = $"""
266+
<toast>
267+
<visual>
268+
<binding template="ToastGeneric">
269+
<text>{title}</text>
270+
<text>{message}</text>
271+
</binding>
272+
</visual>
273+
</toast>
274+
""";
275+
var doc = new XmlDocument();
276+
doc.LoadXml(toastContent);
277+
var noti = new ToastNotification(doc);
278+
ToastNotificationManager.CreateToastNotifier("Xunkong.SimpleLauncher").Show(noti);
279+
}
280+
finally
281+
{
282+
// 等通知发出去
283+
await Task.Delay(1000);
284+
}
285+
}

0 commit comments

Comments
 (0)