This commit is contained in:
HolographicHat
2025-03-26 16:02:48 +08:00
parent 099c22e9e7
commit c87b8c976d
6 changed files with 77 additions and 85 deletions

View File

@@ -29,6 +29,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Spectre.Console" Version="0.49.1" />
</ItemGroup>
<ItemGroup>

View File

@@ -1,5 +1,6 @@
using System.Text.RegularExpressions;
using YaeAchievement.res;
using YaeAchievement.Utilities;
namespace YaeAchievement;
@@ -7,6 +8,8 @@ public static partial class AppConfig {
public static string GamePath { get; private set; } = null!;
private static readonly string[] ProductNames = [ "原神", "Genshin Impact" ];
internal static void Load(string argumentPath) {
if (argumentPath != "auto" && File.Exists(argumentPath)) {
GamePath = argumentPath;
@@ -21,25 +24,16 @@ public static partial class AppConfig {
}
}
var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
var cnLogPath = Path.Combine(appDataPath, @"..\LocalLow\miHoYo\原神\output_log.txt");
var osLogPath = Path.Combine(appDataPath, @"..\LocalLow\miHoYo\Genshin Impact\output_log.txt");
if (!File.Exists(cnLogPath) && !File.Exists(osLogPath)) {
var logPath = ProductNames
.Select(name => $"{appDataPath}/../LocalLow/miHoYo/{name}/output_log.txt")
.Where(File.Exists)
.MaxBy(File.GetLastWriteTime);
if (logPath == null) {
throw new ApplicationException(App.ConfigNeedStartGenshin);
}
string finalLogPath;
if (!File.Exists(osLogPath)) {
finalLogPath = cnLogPath;
} else if (!File.Exists(cnLogPath)) {
finalLogPath = osLogPath;
} else {
var cnLastWriteTime = File.GetLastWriteTime(cnLogPath);
var osLastWriteTime = File.GetLastWriteTime(osLogPath);
finalLogPath = cnLastWriteTime > osLastWriteTime ? cnLogPath : osLogPath;
}
GamePath = GetGamePathFromLogFile(finalLogPath)
?? GetGamePathFromLogFile($"{finalLogPath}.last")
GamePath = GetGamePathFromLogFile(logPath)
?? GetGamePathFromLogFile($"{logPath}.last")
?? throw new ApplicationException(App.ConfigNeedStartGenshin);
pathCacheFile.Write(GamePath);
}
private static string? GetGamePathFromLogFile(string path) {
@@ -51,7 +45,7 @@ public static partial class AppConfig {
var content = File.ReadAllText(copiedLogFilePath);
try {
File.Delete(copiedLogFilePath);
} catch (Exception) { /* ignore */}
} catch (Exception) { /* ignore */ }
var matchResult = GamePathRegex().Match(content);
if (!matchResult.Success) {
return null;

View File

@@ -1,6 +1,7 @@
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using Proto;
using YaeAchievement.Utilities;
namespace YaeAchievement;

View File

@@ -1,56 +1,76 @@
using System.Text;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Json;
using YaeAchievement;
using Windows.Win32;
using Windows.Win32.System.Console;
using YaeAchievement.Parsers;
using YaeAchievement.res;
using static YaeAchievement.Utils;
Console.InputEncoding = Encoding.UTF8;
Console.OutputEncoding = Encoding.UTF8;
namespace YaeAchievement;
TryDisableQuickEdit();
InstallExitHook();
InstallExceptionHook();
internal static class Program {
CheckSelfIsRunning();
CheckGenshinIsRunning();
public static async Task Main(string[] args) {
Console.WriteLine(@"----------------------------------------------------");
Console.WriteLine(App.AppBanner, GlobalVars.AppVersionName);
Console.WriteLine(@"https://github.com/HolographicHat/YaeAchievement");
Console.WriteLine(@"----------------------------------------------------");
if (!new Mutex(true, @"Global\YaeMiku~uwu").WaitOne(0, false)) {
Console.WriteLine(App.AnotherInstance);
Environment.Exit(302);
}
AppConfig.Load(args.GetOrNull(0) ?? "auto");
Export.ExportTo = ToUIntOrNull(args.GetOrNull(1)) ?? uint.MaxValue;
InstallExitHook();
InstallExceptionHook();
await CheckUpdate(ToBooleanOrFalse(args.GetOrNull(2)));
CheckGenshinIsRunning();
var historyCache = GlobalVars.AchievementDataCache;
Console.WriteLine(@"----------------------------------------------------");
Console.WriteLine(App.AppBanner, GlobalVars.AppVersionName);
Console.WriteLine(@"https://github.com/HolographicHat/YaeAchievement");
Console.WriteLine(@"----------------------------------------------------");
AchievementAllDataNotify? data = null;
try {
data = AchievementAllDataNotify.ParseFrom(historyCache.Read().Content.ToByteArray());
} catch (Exception) { /* ignored */ }
AppConfig.Load(args.GetOrNull(0) ?? "auto");
Export.ExportTo = ToUIntOrNull(args.GetOrNull(1)) ?? uint.MaxValue;
if (historyCache.LastWriteTime.AddMinutes(60) > DateTime.UtcNow && data != null) {
Console.WriteLine(App.UsePreviousData);
if (Console.ReadLine()?.ToUpper() is "Y" or "YES") {
Export.Choose(data);
return;
}
}
await CheckUpdate(ToBooleanOrFalse(args.GetOrNull(2)));
StartAndWaitResult(AppConfig.GamePath, new Dictionary<byte, Func<BinaryReader, bool>> {
{ 1, AchievementAllDataNotify.OnReceive },
{ 2, PlayerStoreNotify.OnReceive },
{ 100, PlayerPropNotify.OnReceive },
}, () => {
var historyCache = GlobalVars.AchievementDataCache;
AchievementAllDataNotify? data = null;
try {
data = AchievementAllDataNotify.ParseFrom(historyCache.Read().Content.ToByteArray());
} catch (Exception) { /* ignored */ }
if (historyCache.LastWriteTime.AddMinutes(60) > DateTime.UtcNow && data != null) {
Console.WriteLine(App.UsePreviousData);
if (Console.ReadLine()?.ToUpper() is "Y" or "YES") {
Export.Choose(data);
return;
}
}
StartAndWaitResult(AppConfig.GamePath, new Dictionary<byte, Func<BinaryReader, bool>> {
{ 1, AchievementAllDataNotify.OnReceive },
{ 2, PlayerStoreNotify.OnReceive },
{ 100, PlayerPropNotify.OnReceive },
}, () => {
#if DEBUG
PlayerPropNotify.OnFinish();
File.WriteAllText("store_data.json", JsonSerializer.Serialize(PlayerStoreNotify.Instance, new JsonSerializerOptions {
WriteIndented = true,
DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull
}));
PlayerPropNotify.OnFinish();
File.WriteAllText("store_data.json", JsonSerializer.Serialize(PlayerStoreNotify.Instance, new JsonSerializerOptions {
WriteIndented = true,
DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull
}));
#endif
AchievementAllDataNotify.OnFinish();
});
AchievementAllDataNotify.OnFinish();
});
}
[ModuleInitializer]
internal static unsafe void SetupConsole() {
var handle = Native.GetStdHandle(STD_HANDLE.STD_INPUT_HANDLE);
CONSOLE_MODE mode = default;
Native.GetConsoleMode(handle, &mode);
Native.SetConsoleMode(handle, mode & ~CONSOLE_MODE.ENABLE_QUICK_EDIT_MODE);
Console.InputEncoding = Console.OutputEncoding = Encoding.UTF8;
}
}

View File

@@ -2,7 +2,7 @@
using Google.Protobuf;
using Proto;
namespace YaeAchievement;
namespace YaeAchievement.Utilities;
public class CacheFile(string identifier) {

View File

@@ -7,9 +7,9 @@ using System.Net.Sockets;
using System.Runtime.InteropServices;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.System.Console;
using Proto;
using YaeAchievement.res;
using YaeAchievement.Utilities;
namespace YaeAchievement;
@@ -68,8 +68,7 @@ public static class Utils {
}
public static unsafe void CopyToClipboard(string text) {
if (Native.OpenClipboard(HWND.Null))
{
if (Native.OpenClipboard(HWND.Null)) {
Native.EmptyClipboard();
var hGlobal = (HGLOBAL) Marshal.AllocHGlobal((text.Length + 1) * 2);
var hPtr = (nint) Native.GlobalLock(hGlobal);
@@ -78,9 +77,7 @@ public static class Utils {
Native.SetClipboardData(13, new HANDLE(hPtr));
Marshal.FreeHGlobal(hGlobal);
Native.CloseClipboard();
}
else
{
} else {
throw new Win32Exception();
}
}
@@ -116,20 +113,6 @@ public static class Utils {
_updateInfo = info;
}
public static void CheckSelfIsRunning() {
try {
Process.EnterDebugMode();
var cur = Process.GetCurrentProcess();
foreach (var process in Process.GetProcesses().Where(process => process.Id != cur.Id)) {
if (process.ProcessName == cur.ProcessName) {
Console.WriteLine(App.AnotherInstance);
Environment.Exit(302);
}
}
Process.LeaveDebugMode();
} catch (Win32Exception) {}
}
// ReSharper disable once UnusedMethodReturnValue.Global
public static bool ShellOpen(string path, string? args = null) {
try {
@@ -148,13 +131,6 @@ public static class Utils {
}
}
// ReSharper disable once UnusedMethodReturnValue.Global
public static unsafe bool TryDisableQuickEdit() {
var handle = Native.GetStdHandle(STD_HANDLE.STD_INPUT_HANDLE);
CONSOLE_MODE mode = default;
return Native.GetConsoleMode(handle, &mode) && Native.SetConsoleMode(handle, mode & ~CONSOLE_MODE.ENABLE_QUICK_EDIT_MODE);
}
public static void CheckGenshinIsRunning() {
Process.EnterDebugMode();
foreach (var process in Process.GetProcesses()) {