diff --git a/NetEaseMusic-DiscordRPC/MemoryUtil.cs b/NetEaseMusic-DiscordRPC/MemoryUtil.cs index 20c1b21..3c637f7 100644 --- a/NetEaseMusic-DiscordRPC/MemoryUtil.cs +++ b/NetEaseMusic-DiscordRPC/MemoryUtil.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; @@ -7,9 +8,12 @@ namespace NetEaseMusic_DiscordRPC { static class MemoryUtil { - private static int ProcessId; + private static int ProcessId; private static IntPtr EntryPoint; private static IntPtr BaseAddress; + private static string Version; + + public static List Offsets; public static void LoadMemory(int pid, ref double rate, ref double lens) { @@ -28,10 +32,14 @@ public static void LoadMemory(int pid, ref double rate, ref double lens) if ("cloudmusic.dll".Equals(module.ModuleName)) { BaseAddress = module.BaseAddress; + //Debug.Print($"Match module address {module.BaseAddress}"); break; } } + + Version = process.MainModule?.FileVersionInfo.ProductVersion; + //Debug.Print($"Match application version {Version}"); } if (EntryPoint == IntPtr.Zero || BaseAddress == IntPtr.Zero) @@ -40,8 +48,23 @@ public static void LoadMemory(int pid, ref double rate, ref double lens) return; } + if (string.IsNullOrEmpty(Version)) + { + //Debug.Print($"Null version"); + return; + } + ProcessId = pid; + var offset = Offsets.FirstOrDefault(x => x.Version == Version); + if (offset == null) + { + ///Debug.Print($"Offset not found"); + return; + } + + //Debug.Print($"Offset -> {offset.Offsets.Length} | {offset.Offsets.Schedule}"); + var buffer = new byte[sizeof(double) + 1]; // offset 2.7.1 -> 0x8ADA70 @@ -49,9 +72,10 @@ public static void LoadMemory(int pid, ref double rate, ref double lens) // offset 2.7.6 -> 0x8BEAD8 // offset 2.8.0 -> 0x939B50 // offset 2.9.2 -> 0x93EB38 - if (!ReadProcessMemory(EntryPoint, BaseAddress + 0x93EB38, buffer, sizeof(double), IntPtr.Zero)) + // 0ffset 2.9.5 -> 0x955F60 + if (!ReadProcessMemory(EntryPoint, BaseAddress + offset.Offsets.Schedule, buffer, sizeof(double), IntPtr.Zero)) { - Debug.Print($"Failed to load memory at 0x{(BaseAddress + 0x939B48).ToString("X")}"); + Debug.Print($"Failed to load memory at 0x{(BaseAddress + offset.Offsets.Schedule).ToString("X")}"); return; } var current = BitConverter.ToDouble(buffer, 0); @@ -61,14 +85,15 @@ public static void LoadMemory(int pid, ref double rate, ref double lens) // offset 2.7.6 -> 0x8DFC080 // offset 2.8.0 -> 0x961D98 // offset 2.9.2 -> 0x967DA8 - if (!ReadProcessMemory(EntryPoint, BaseAddress + 0x967DA8, buffer, sizeof(double), IntPtr.Zero)) + // offset 2.9.5 -> 0x97F588 + if (!ReadProcessMemory(EntryPoint, BaseAddress + offset.Offsets.Length, buffer, sizeof(double), IntPtr.Zero)) { - Debug.Print($"Failed to load memory at 0x{(BaseAddress + 0x961DA8).ToString("X")}"); + Debug.Print($"Failed to load memory at 0x{(BaseAddress + offset.Offsets.Length).ToString("X")}"); return; } var maxlens = BitConverter.ToDouble(buffer, 0); - //Debug.Print($"Current value {current} | {maxlens} | {process.MainWindowTitle}"); + //Debug.Print($"Current value {current} | {maxlens}"); rate = current; lens = maxlens; diff --git a/NetEaseMusic-DiscordRPC/NetEaseMusic-DiscordRPC.csproj b/NetEaseMusic-DiscordRPC/NetEaseMusic-DiscordRPC.csproj index 2fa30c0..8ad1845 100644 --- a/NetEaseMusic-DiscordRPC/NetEaseMusic-DiscordRPC.csproj +++ b/NetEaseMusic-DiscordRPC/NetEaseMusic-DiscordRPC.csproj @@ -11,6 +11,8 @@ v4.8 512 true + false + publish\ true Disk @@ -23,10 +25,8 @@ true 0 1.0.0.%2a - false false true - x86 @@ -77,6 +77,7 @@ + diff --git a/NetEaseMusic-DiscordRPC/Program.cs b/NetEaseMusic-DiscordRPC/Program.cs index 2045265..04f1fe2 100644 --- a/NetEaseMusic-DiscordRPC/Program.cs +++ b/NetEaseMusic-DiscordRPC/Program.cs @@ -1,17 +1,21 @@ using DiscordRPC; +using Newtonsoft.Json; using System; +using System.Collections.Generic; using System.Diagnostics; +using System.Net.Http; +using System.Net.Http.Headers; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace NetEaseMusic_DiscordRPC { - internal class Program + static class Program { private const string ApplicationId = "481562643958595594"; - private static void Main() + private static async Task Main() { // check run once _ = new Mutex(true, "NetEase Cloud Music DiscordRPC", out var allow); @@ -30,7 +34,9 @@ private static void Main() Properties.Settings.Default.Save(); } - Task.Run(() => + await GetOffsetsAsync(); + + _ = Task.Run(() => { using var discord = new DiscordRpcClient(ApplicationId); discord.Initialize(); @@ -110,7 +116,7 @@ private static void Main() update: // update #if DEBUG - if (!playerState) + if (!playerState) #else if (Win32Api.User32.IsFullscreenAppRunning() || Win32Api.User32.IsWhitelistAppRunning() || !playerState) @@ -154,7 +160,6 @@ private static void Main() } }); - Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); @@ -192,5 +197,39 @@ private static void Main() Application.Run(); } + + private static async Task GetOffsetsAsync() + { + retry: + try + { + using var client = new HttpClient() + { + BaseAddress = new Uri("https://api.kxnrl.com/NCM-Rpc/"), + Timeout = TimeSpan.FromMinutes(1) + }; + + client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + + var response = await client.GetAsync("GetOffsets/v1/"); + + response.EnsureSuccessStatusCode(); + + var json = await response.Content.ReadAsStringAsync(); + + MemoryUtil.Offsets = JsonConvert.DeserializeObject>(json); + } + catch (Exception e) + { + var r = MessageBox.Show(e.Message, "Failed to get offsets", MessageBoxButtons.RetryCancel, + MessageBoxIcon.Error); + if (r == DialogResult.Retry) + goto retry; + +#if !DEBUG + Environment.Exit(-1); +#endif + } + } } } \ No newline at end of file diff --git a/NetEaseMusic-DiscordRPC/Properties/AssemblyInfo.cs b/NetEaseMusic-DiscordRPC/Properties/AssemblyInfo.cs index 9696748..111520e 100644 --- a/NetEaseMusic-DiscordRPC/Properties/AssemblyInfo.cs +++ b/NetEaseMusic-DiscordRPC/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.0.3")] -[assembly: AssemblyFileVersion("2.0.3")] +[assembly: AssemblyVersion("2.1.0")] +[assembly: AssemblyFileVersion("2.1.0")] diff --git a/NetEaseMusic-DiscordRPC/json.cs b/NetEaseMusic-DiscordRPC/json.cs new file mode 100644 index 0000000..4b3b577 --- /dev/null +++ b/NetEaseMusic-DiscordRPC/json.cs @@ -0,0 +1,21 @@ +using Newtonsoft.Json; + +namespace NetEaseMusic_DiscordRPC +{ + public class MemoryOffset + { + [JsonProperty("version")] + public string Version { get; set; } + [JsonProperty("offsets")] + public Offset Offsets { get; set; } + } + + public struct Offset + { + [JsonProperty("length")] + public int Length { get; set; } + [JsonProperty("schedule")] + public int Schedule { get; set; } + } + +} diff --git a/NetEaseMusic-DiscordRPC/win32Api.cs b/NetEaseMusic-DiscordRPC/win32Api.cs index dd91795..c37845c 100644 --- a/NetEaseMusic-DiscordRPC/win32Api.cs +++ b/NetEaseMusic-DiscordRPC/win32Api.cs @@ -1,7 +1,6 @@ using System; using System.Diagnostics; using System.IO; -using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; @@ -148,7 +147,7 @@ public static bool GetWindowTitle(string match, out string text, out int pid) if (match.Equals(classname) && GetWindowThreadProcessId(handle, out var xpid) != 0 && xpid != 0) { - title = GetWindowTitle(handle); + title = GetWindowTitle(handle); processId = xpid; }