KWMv2/酷我 mflac 支持 #35
@ -17,10 +17,22 @@ import { ExternalLinkIcon } from '@chakra-ui/icons';
|
||||
import { Light as SyntaxHighlighter } from 'react-syntax-highlighter';
|
||||
import hljsStyleGitHub from 'react-syntax-highlighter/dist/esm/styles/hljs/github';
|
||||
|
||||
import PowerShellAdbDumpCommand from './adb_dump.ps1?raw';
|
||||
import ShellAdbDumpCommand from './adb_dump.sh?raw';
|
||||
import PowerShellAdbDumpCommandTemplate from './adb_dump.ps1?raw';
|
||||
import ShellAdbDumpCommandTemplate from './adb_dump.sh?raw';
|
||||
|
||||
const applyTemplate = (tpl: string, values: Record<string, unknown>) => {
|
||||
return tpl.replace(/\{\{\s*(\w+)\s*\}\}/g, (_, key) => (Object.hasOwn(values, key) ? String(values[key]) : '<nil>'));
|
||||
};
|
||||
|
||||
export interface AndroidADBPullInstructionProps {
|
||||
dir: string;
|
||||
file: string;
|
||||
}
|
||||
|
||||
export function AndroidADBPullInstruction({ dir, file }: AndroidADBPullInstructionProps) {
|
||||
const psAdbDumpCommand = applyTemplate(PowerShellAdbDumpCommandTemplate, { dir, file });
|
||||
const shAdbDumpCommand = applyTemplate(ShellAdbDumpCommandTemplate, { dir, file });
|
||||
|
||||
export function InstructionsAndroid() {
|
||||
return (
|
||||
<>
|
||||
<Text>
|
||||
@ -50,12 +62,12 @@ export function InstructionsAndroid() {
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Text>
|
||||
访问 <Code>/data/data/com.tencent.qqmusic/databases/</Code> 目录。
|
||||
访问 <Code>{dir}/</Code> 目录。
|
||||
</Text>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Text>
|
||||
将文件 <Code>player_process_db</Code> 复制到浏览器可访问的目录。
|
||||
将文件 <Code>{file}</Code> 复制到浏览器可访问的目录。
|
||||
<br />
|
||||
(例如下载目录)
|
||||
</Text>
|
||||
@ -99,12 +111,12 @@ export function InstructionsAndroid() {
|
||||
<ListItem>
|
||||
<Text>粘贴执行下述代码。若设备提示「超级用户请求」请允许:</Text>
|
||||
<SyntaxHighlighter language="ps1" style={hljsStyleGitHub}>
|
||||
{PowerShellAdbDumpCommand}
|
||||
{psAdbDumpCommand}
|
||||
</SyntaxHighlighter>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Text>
|
||||
提交当前目录下的 <Code>player_process_db</Code> 文件。
|
||||
提交当前目录下的 <Code>{file}</Code> 文件。
|
||||
</Text>
|
||||
</ListItem>
|
||||
</OrderedList>
|
||||
@ -128,12 +140,12 @@ export function InstructionsAndroid() {
|
||||
<ListItem>
|
||||
<Text>粘贴执行下述代码。若设备提示「超级用户请求」请允许:</Text>
|
||||
<SyntaxHighlighter language="bash" style={hljsStyleGitHub}>
|
||||
{ShellAdbDumpCommand}
|
||||
{shAdbDumpCommand}
|
||||
</SyntaxHighlighter>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Text>
|
||||
提交当前目录下的 <Code>player_process_db</Code> 文件。
|
||||
提交当前目录下的 <Code>{file}</Code> 文件。
|
||||
</Text>
|
||||
</ListItem>
|
||||
</OrderedList>
|
@ -1,8 +1,8 @@
|
||||
try {
|
||||
$gz_b64 = adb shell su -c "cat '/data/data/com.tencent.qqmusic/databases/player_process_db' | gzip | base64" | Out-String
|
||||
$gz_b64 = adb shell su -c "cat '{{ dir }}/{{ file }}' | gzip | base64" | Out-String
|
||||
$bStream = New-Object System.IO.MemoryStream(,[System.Convert]::FromBase64String($gz_b64))
|
||||
$decoded = New-Object System.IO.Compression.GzipStream($bStream, [System.IO.Compression.CompressionMode]::Decompress)
|
||||
$outFile = New-Object System.IO.FileStream("player_process_db", [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write)
|
||||
$outFile = New-Object System.IO.FileStream("{{ file }}", [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write)
|
||||
$decoded.CopyTo($outFile)
|
||||
} finally {
|
||||
if ($outFile -ne $null) { $outFile.Dispose() }
|
2
src/components/AndroidADBPullInstruction/adb_dump.sh
Normal file
2
src/components/AndroidADBPullInstruction/adb_dump.sh
Normal file
@ -0,0 +1,2 @@
|
||||
sh adb shell su -c "cat '{{ dir }}/{{ file }}' | gzip | base64" \
|
||||
| base64 -d | gzip -d '{{ file }}'
|
9
src/features/settings/panels/KWMv2/InstructionsPC.tsx
Normal file
9
src/features/settings/panels/KWMv2/InstructionsPC.tsx
Normal file
@ -0,0 +1,9 @@
|
||||
import { Text } from '@chakra-ui/react';
|
||||
|
||||
export function InstructionsPC() {
|
||||
return (
|
||||
<>
|
||||
<Text>使用 Windows 客户端下载的文件不需要导入密钥。</Text>
|
||||
</>
|
||||
);
|
||||
}
|
@ -14,6 +14,10 @@ import {
|
||||
MenuDivider,
|
||||
MenuItem,
|
||||
MenuList,
|
||||
Tab,
|
||||
TabList,
|
||||
TabPanel,
|
||||
TabPanels,
|
||||
Text,
|
||||
useToast,
|
||||
} from '@chakra-ui/react';
|
||||
@ -28,6 +32,8 @@ import { kwm2AddKey, kwm2ClearKeys, kwm2ImportKeys } from '../settingsSlice';
|
||||
import { selectStagingKWMv2Keys } from '../settingsSelector';
|
||||
import { KWMv2EKeyItem } from './KWMv2/KWMv2EKeyItem';
|
||||
import type { StagingKWMv2Key } from '../keyFormats';
|
||||
import { InstructionsPC } from './KWMv2/InstructionsPC';
|
||||
import { AndroidADBPullInstruction } from '~/components/AndroidADBPullInstruction/AndroidADBPullInstruction';
|
||||
|
||||
export function PanelKWMv2Key() {
|
||||
const toast = useToast();
|
||||
@ -39,7 +45,7 @@ export function PanelKWMv2Key() {
|
||||
const clearAll = () => dispatch(kwm2ClearKeys());
|
||||
const handleSecretImport = async (file: File) => {
|
||||
let keys: Omit<StagingKWMv2Key, 'id'>[] | null = null;
|
||||
if (/cn\.kuwo\.player\.mmkv\.defaultconfig/i.test(file.name)) {
|
||||
if (/cn\.kuwo\.player\.mmkv/i.test(file.name)) {
|
||||
const fileBuffer = await file.arrayBuffer();
|
||||
keys = MMKVParser.parseKuwoEKey(new DataView(fileBuffer));
|
||||
}
|
||||
@ -108,7 +114,21 @@ export function PanelKWMv2Key() {
|
||||
onClose={() => setShowImportModal(false)}
|
||||
onImport={handleSecretImport}
|
||||
>
|
||||
文档缺失
|
||||
<TabList>
|
||||
<Tab>安卓</Tab>
|
||||
<Tab>Windows</Tab>
|
||||
</TabList>
|
||||
<TabPanels flex={1} overflow="auto">
|
||||
<TabPanel>
|
||||
<AndroidADBPullInstruction
|
||||
dir="/data/data/cn.kuwo.player/files/mmkv"
|
||||
file="cn.kuwo.player.mmkv.defaultconfig"
|
||||
/>
|
||||
</TabPanel>
|
||||
<TabPanel>
|
||||
<InstructionsPC />
|
||||
</TabPanel>
|
||||
</TabPanels>
|
||||
</ImportSecretModal>
|
||||
</Flex>
|
||||
);
|
||||
|
@ -34,10 +34,10 @@ import { StagingQMCv2Key } from '../keyFormats';
|
||||
import { DatabaseKeyExtractor } from '~/util/DatabaseKeyExtractor';
|
||||
import { MMKVParser } from '~/util/MMKVParser';
|
||||
import { getFileName } from '~/util/pathHelper';
|
||||
import { InstructionsAndroid } from './QMCv2/InstructionsAndroid';
|
||||
import { InstructionsIOS } from './QMCv2/InstructionsIOS';
|
||||
import { InstructionsMac } from './QMCv2/InstructionsMac';
|
||||
import { InstructionsPC } from './QMCv2/InstructionsPC';
|
||||
import { AndroidADBPullInstruction } from '~/components/AndroidADBPullInstruction/AndroidADBPullInstruction';
|
||||
|
||||
export function PanelQMCv2Key() {
|
||||
const toast = useToast();
|
||||
@ -172,7 +172,7 @@ export function PanelQMCv2Key() {
|
||||
</TabList>
|
||||
<TabPanels flex={1} overflow="auto">
|
||||
<TabPanel>
|
||||
<InstructionsAndroid />
|
||||
<AndroidADBPullInstruction dir="/data/data/com.tencent.qqmusic/databases" file="player_process_db" />
|
||||
</TabPanel>
|
||||
<TabPanel>
|
||||
<InstructionsIOS />
|
||||
|
@ -1,2 +0,0 @@
|
||||
sh adb shell su -c "cat '/data/data/com.tencent.qqmusic/databases/player_process_db' | gzip | base64" \
|
||||
| base64 -d | gzip -d player_process_db
|
Loading…
Reference in New Issue
Block a user