Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: Kxnrl/NetEase-Cloud-Music-DiscordRPC
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 3.0
Choose a base ref
...
head repository: Kxnrl/NetEase-Cloud-Music-DiscordRPC
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
  • 1 commit
  • 1 file changed
  • 1 contributor

Commits on Dec 11, 2024

  1. QQ音乐歌曲id+更稳定地获取专辑封面url (#37)

    * QQ音乐歌曲id+更稳定的专辑封面url
    
    * 注释
    Nukoooo authored Dec 11, 2024
    Copy the full SHA
    d3b77c6 View commit details
Showing with 58 additions and 56 deletions.
  1. +58 −56 Vanessa/Players/Tencent.cs
114 changes: 58 additions & 56 deletions Vanessa/Players/Tencent.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Diagnostics;
using System.Text;
using Kxnrl.Vanessa.Models;
@@ -8,18 +8,35 @@ namespace Kxnrl.Vanessa.Players;

internal sealed class Tencent : IMusicPlayer
{
private const string CurrentSOngInfoPattern
= "B9 ? ? ? ? C7 05 ? ? ? ? ? ? ? ? E8 ? ? ? ? B9";

private const string AlbumThumbnailPattern
= "A1 ? ? ? ? 6A ? 51 8B CC 51 89 01 8B C4 8D 4D ? C7 00 ? ? ? ? FF 15 ? ? ? ? A1 ? ? ? ? 6A ? 51 8B CC 51 89 01 8B C4 8D 4D ? C7 00 ? ? ? ? FF 15 ? ? ? ? 6A ? FF 35 ? ? ? ? 51 8B C4 8D 4D ? C7 00 ? ? ? ? FF 15 ? ? ? ? 6A ? FF 35 ? ? ? ? 51 8B C4 8D 4D ? C7 00 ? ? ? ? FF 15 ? ? ? ? 6A ? FF 35 ? ? ? ? 51 8B C4 C7 00";

private const string IsPausedPattern
= "0F 29 05 ? ? ? ? C7 05 ? ? ? ? ? ? ? ? C7 05 ? ? ? ? ? ? ? ? C7 05 ? ? ? ? ? ? ? ? E8";
/*
版本 20.43 结构
struct CurrentSongInfo {
std::string m_szSong; // 0x0
std::string m_szArtist; // 0x18
std::string m_szAlbum; // 0x30
std::string m_szAlbumThumbnailUrl; // 0x48
uint32_t m_nSongId; // 0x60
private: char pad_64[0x4]; public:
uint32_t m_nSongDuration; // 0x68
uint32_t m_nSongSchedule; // 0x6c
uint32_t m_nPlayStatus; // 0x70
}; // Size: 0x74
*/

// 如何更新Pattern:
// 1. 在 QQMusic.dll 里搜字符串 "Tencent Technology (Shenzhen) Company Limited", 并且找到引用的函数(理论上只有一个引用)
// 2. 引用到字符串的是一个初始化的函数,在引用到字符串的地方往上找类似这样的伪代码,理论上来讲这个伪代码会重复3次
// byte_xxxxx = 0;
// dword_xxxxx+0x10 = 0;
// dword_xxxxx+0x14 = 15;
// 这个是初始化 std::string, 我们要找的是第一个,这个是当前播放的歌的名字
// 3. 选中然后在汇编页面生成Pattern
private const string CurrentSongInfoPattern
= "A2 ? ? ? ? A3 ? ? ? ? C7 05 ? ? ? ? ? ? ? ? A2 ? ? ? ? A3 ? ? ? ? C7 05 ? ? ? ? ? ? ? ? A2 ? ? ? ? A3";

private const int StdStringSize = 0x18;

private readonly nint _currentSongInfoAddress;
private readonly nint _isPausedAddress;
private readonly nint _albumThumbnailAddress;

private readonly int _pid;
private readonly ProcessMemory _process;
@@ -39,24 +56,12 @@ public Tencent(int pid)
var process = new ProcessMemory(pid);
var address = module.BaseAddress;

if (Memory.FindPattern(CurrentSOngInfoPattern, pid, address, out var patternAddress))
if (Memory.FindPattern(CurrentSongInfoPattern, pid, address, out var patternAddress))
{
var currentSongAddress = process.ReadInt32(patternAddress, 1);
_currentSongInfoAddress = currentSongAddress;
}

if (Memory.FindPattern(IsPausedPattern, pid, address, out patternAddress))
{
var isPausedAddress = process.ReadInt32(patternAddress, 3);
_isPausedAddress = isPausedAddress + 4;
}

if (Memory.FindPattern(AlbumThumbnailPattern, pid, address, out patternAddress))
{
var albumThumbnailAddress = process.ReadInt32(patternAddress, 1);
_albumThumbnailAddress = albumThumbnailAddress;
}

_process = process;

break;
@@ -69,7 +74,7 @@ public Tencent(int pid)

if (_currentSongInfoAddress == 0)
{
throw new EntryPointNotFoundException("_currentSongAddress is 0");
throw new EntryPointNotFoundException("_currentSongInfoAddress is 0");
}
}

@@ -102,54 +107,51 @@ public bool Validate(int pid)
}

private uint GetSongIdentity()
=> _process.ReadUInt32(_currentSongInfoAddress);
=> _process.ReadUInt32(_currentSongInfoAddress, StdStringSize * 4);

private int GetSongDuration()
=> _process.ReadInt32(_currentSongInfoAddress, 0x10);
=> _process.ReadInt32(_currentSongInfoAddress, (StdStringSize * 4) + 8 /*跳过Id跟一个4字节大小的玩意*/);

private int GetSongSchedule()
=> _process.ReadInt32(_currentSongInfoAddress, 0xC);
=> _process.ReadInt32(_currentSongInfoAddress, (StdStringSize * 4) + 12);

private string GetSongName()
{
var address = _process.ReadInt32(_currentSongInfoAddress);
var bytes = _process.ReadBytes(address, 512);

var result = Encoding.Unicode.GetString(bytes);

return result[..result.IndexOf('\0')];
}
=> ReadStdString(_currentSongInfoAddress);

private string GetArtistName()
{
var address = _process.ReadInt32(_currentSongInfoAddress, 4);
var bytes = _process.ReadBytes(address, 512);
=> ReadStdString(_currentSongInfoAddress + StdStringSize);

var result = Encoding.Unicode.GetString(bytes);
private string GetAlbumName()
=> ReadStdString(_currentSongInfoAddress + (StdStringSize * 2));

return result[..result.IndexOf('\0')];
}
private string GetAlbumThumbnailUrl()
=> ReadStdString(_currentSongInfoAddress + (StdStringSize * 3));

private string GetAlbumName()
private string ReadStdString(nint address)
{
var address = _process.ReadInt32(_currentSongInfoAddress, 8);
var bytes = _process.ReadBytes(address, 512);
var strLength = _process.ReadInt32(address, 0x10);

var result = Encoding.Unicode.GetString(bytes);
if (strLength == 0)
{
return string.Empty;
} // small string optimization

return result[..result.IndexOf('\0')];
}
byte[] strBuffer;

private string GetAlbumThumbnailUrl()
{
var address = _process.ReadInt32(_albumThumbnailAddress);
var bytes = _process.ReadBytes(address, 512);

var result = Encoding.Unicode.GetString(bytes);
if (strLength <= 15)
{
strBuffer = _process.ReadBytes(address, strLength);
}
else
{
var strAddress = _process.ReadInt32(address);
strBuffer = _process.ReadBytes(strAddress, strLength);
}

return result[..result.IndexOf('\0')];
return Encoding.UTF8.GetString(strBuffer);
}

// 0 暂停, 1播放, 3缓冲
private bool IsPaused()
=> _process.ReadInt32(_isPausedAddress) == 1;
=> _process.ReadInt32(_currentSongInfoAddress, (StdStringSize * 4) + 16) == 0;
}