diff --git a/res/App.Designer.cs b/res/App.Designer.cs index 5911284..095c6b1 100644 --- a/res/App.Designer.cs +++ b/res/App.Designer.cs @@ -87,16 +87,7 @@ namespace YaeAchievement.res { } /// - /// Looks up a localized string similar to If correct, input Y; otherwise input N. - /// - internal static string ConfigInitPathConfirm { - get { - return ResourceManager.GetString("ConfigInitPathConfirm", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to You need start genshin once before exporting.. + /// Looks up a localized string similar to You need to login genshin impact before exporting.. /// internal static string ConfigNeedStartGenshin { get { @@ -264,33 +255,6 @@ namespace YaeAchievement.res { } } - /// - /// Looks up a localized string similar to Operation canceled by user.. - /// - internal static string SelectCanceled { - get { - return ResourceManager.GetString("SelectCanceled", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Executable. - /// - internal static string SelectFilterName { - get { - return ResourceManager.GetString("SelectFilterName", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to GenshinPath. - /// - internal static string SelectTitle { - get { - return ResourceManager.GetString("SelectTitle", resourceCulture); - } - } - /// /// Looks up a localized string similar to Reward not taken. /// diff --git a/res/App.resx b/res/App.resx index 4d66260..161c9ab 100644 --- a/res/App.resx +++ b/res/App.resx @@ -68,10 +68,7 @@ Input a number (0-5): Reward not taken - You need start genshin once before exporting. - - - If correct, input Y; otherwise input N + You need to login genshin impact before exporting. Download: {0} @@ -91,15 +88,6 @@ Input a number (0-5): Please close game before run this application. ({0}) - - Operation canceled by user. - - - GenshinPath - - - Executable - Please close another instance. diff --git a/res/App.zh.resx b/res/App.zh.resx index 145b729..a01047f 100644 --- a/res/App.zh.resx +++ b/res/App.zh.resx @@ -62,10 +62,7 @@ 已完成 - 在导出前你需要先启动一次原神. - - - 如果确认路径无误,请按 Y ;若有误或需要自行选择,请按 N + 在导出前你需要先完成一次登入流程. 下载地址: {0} @@ -85,15 +82,6 @@ 原神正在运行,请关闭后重试 ({0}) - - 操作被取消 - - - 选择主程序 - - - 国服/国际服主程序 - 另一个实例正在运行,请关闭后重试 diff --git a/src/AppConfig.cs b/src/AppConfig.cs index 06b7b88..4d02fc4 100644 --- a/src/AppConfig.cs +++ b/src/AppConfig.cs @@ -8,25 +8,46 @@ public static class AppConfig { public static string GamePath { get; private set; } = null!; internal static void Load() { + var pathCacheFile = new CacheFile("genshin_impact_game_path"); + if (pathCacheFile.Exists()) { + var path = pathCacheFile.Read().Content.ToStringUtf8(); + if (path != null && File.Exists(path)) { + GamePath = path; + return; + } + } 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)) { throw new ApplicationException(App.ConfigNeedStartGenshin); } - string latestLogPath; + string finalLogPath; if (!File.Exists(osLogPath)) { - latestLogPath = cnLogPath; + finalLogPath = cnLogPath; } else if (!File.Exists(cnLogPath)) { - latestLogPath = osLogPath; + finalLogPath = osLogPath; } else { var cnLastWriteTime = File.GetLastWriteTime(cnLogPath); var osLastWriteTime = File.GetLastWriteTime(osLogPath); - latestLogPath = cnLastWriteTime > osLastWriteTime ? cnLogPath : osLogPath; + finalLogPath = cnLastWriteTime > osLastWriteTime ? cnLogPath : osLogPath; } - var content = File.ReadAllText(latestLogPath); + GamePath = GetGamePathFromLogFile(finalLogPath) + ?? GetGamePathFromLogFile($"{finalLogPath}.last") + ?? throw new ApplicationException(App.ConfigNeedStartGenshin); + pathCacheFile.Write(GamePath); + } + + private static string? GetGamePathFromLogFile(string path) { + if (!File.Exists(path)) { + return null; + } + var content = File.ReadAllText(path); var matchResult = Regex.Match(content, @"(?m).:/.+(GenshinImpact_Data|YuanShen_Data)"); - var entryName = $"{matchResult.Groups["1"].Value.Replace("_Data", null)}.exe"; - GamePath = Path.GetFullPath(entryName, $"{matchResult.Value}/../"); + if (!matchResult.Success) { + return null; + } + var entryName = matchResult.Groups["1"].Value.Replace("_Data", ".exe"); + return Path.GetFullPath(Path.Combine(matchResult.Value, "..", entryName)); } } diff --git a/src/CacheFile.cs b/src/CacheFile.cs index fc717de..c992b28 100644 --- a/src/CacheFile.cs +++ b/src/CacheFile.cs @@ -26,14 +26,18 @@ public class CacheFile { return _content; } - public void Write(byte[] data, string? etag = null) { + public void Write(string data, string? etag = null) => Write(ByteString.CopyFromUtf8(data), data.MD5Hash(), etag); + + public void Write(byte[] data, string? etag = null) => Write(ByteString.CopyFrom(data), data.MD5Hash(), etag); + + private void Write(ByteString data, string hash, string? etag = null) { using var fOut = File.OpenWrite(_cacheName); using var cOut = new GZipStream(fOut, CompressionLevel.SmallestSize); new CacheItem { Etag = etag ?? string.Empty, Version = 3, - Checksum = data.MD5Hash(), - Content = ByteString.CopyFrom(data) + Checksum = hash, + Content = data }.WriteTo(cOut); } } diff --git a/src/GlobalVars.cs b/src/GlobalVars.cs index 59d6729..b99b762 100644 --- a/src/GlobalVars.cs +++ b/src/GlobalVars.cs @@ -5,19 +5,20 @@ namespace YaeAchievement; // ReSharper disable InconsistentNaming // ReSharper disable ConvertToConstant.Global // ReSharper disable FieldCanBeMadeReadOnly.Global -#pragma warning disable CA2211 public static class GlobalVars { - public static bool DebugProxy = false; - public static bool CheckGamePath = true; - public static bool UnexpectedExit = true; - public static Version AppVersion = Assembly.GetEntryAssembly()!.GetName().Version!; + public static bool DebugProxy => false; + public static bool UnexpectedExit { get; set; }= true; + public static Version AppVersion { get; } = Assembly.GetEntryAssembly()!.GetName().Version!; + + private static readonly string DataDir = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); + public static readonly string LibPath = Path.Combine(DataDir, "YaeAchievement.dll"); public static readonly string AppPath = AppDomain.CurrentDomain.BaseDirectory; public const uint AppVersionCode = 29; public const string AppVersionName = "2.1"; - public const string LibName = "YaeLib.dll"; + public const string PipeName = "YaeAchievementPipe"; public const string BucketHost = "https://cn-cd-1259389942.file.myqcloud.com"; diff --git a/src/Utils.cs b/src/Utils.cs index f8f29e9..e5c7c51 100644 --- a/src/Utils.cs +++ b/src/Utils.cs @@ -90,7 +90,7 @@ public static class Utils { } } if (info.EnableLibDownload) { - File.WriteAllBytes(GlobalVars.LibName, GetBucketFileAsByteArray("schicksal/lib.dll")); + File.WriteAllBytes(GlobalVars.LibPath, GetBucketFileAsByteArray("schicksal/lib.dll")); } } @@ -106,6 +106,7 @@ public static class Utils { Process.LeaveDebugMode(); } + // ReSharper disable once UnusedMethodReturnValue.Global public static bool ShellOpen(string path) { try { return new Process { @@ -128,7 +129,10 @@ public static class Utils { public static void CheckGenshinIsRunning() { Process.EnterDebugMode(); foreach (var process in Process.GetProcesses()) { - if (process.ProcessName is "GenshinImpact" or "YuanShen" && !process.HasExited) { + if (process.ProcessName is "GenshinImpact" or "YuanShen" + && !process.HasExited + && process.MainWindowHandle != IntPtr.Zero + ) { Console.WriteLine(App.GenshinIsRunning, process.Id); Environment.Exit(301); } @@ -165,26 +169,23 @@ public static class Utils { Console.WriteLine(App.UploadError); AppCenter.TrackCrash((Exception) e.ExceptionObject); AppCenter.Upload(); - Environment.Exit(-1); break; } + Environment.Exit(-1); }; } // ReSharper disable once UnusedMethodReturnValue.Global public static Thread StartAndWaitResult(string exePath, Func onReceive) { - var dataDir = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); - var lib = Path.Combine(dataDir, "yae.dll"); - File.Copy(Path.GetFullPath(GlobalVars.LibName), lib, true); AppDomain.CurrentDomain.ProcessExit += (_, _) => { try { - File.Delete(lib); + File.Delete(GlobalVars.LibPath); } catch (Exception) { /* ignored */ } }; if (!Injector.CreateProcess(exePath, out var hProcess, out var hThread, out var pid)) { Environment.Exit(new Win32Exception().PrintMsgAndReturnErrCode("ICreateProcess fail")); } - if (Injector.LoadLibraryAndInject(hProcess, lib) != 0) { + if (Injector.LoadLibraryAndInject(hProcess, GlobalVars.LibPath) != 0) { if (!Native.TerminateProcess(hProcess, 0)) { Environment.Exit(new Win32Exception().PrintMsgAndReturnErrCode("TerminateProcess fail")); }